diff menu.c @ 868:1bab7e01ae98

Allow directory navigation in menu. Sort directory entries
author Michael Pavone <pavone@retrodev.com>
date Fri, 06 Nov 2015 14:17:41 -0800
parents 69a6ec208111
children f173317ecdb4
line wrap: on
line diff
--- a/menu.c	Fri Nov 06 13:44:21 2015 -0800
+++ b/menu.c	Fri Nov 06 14:17:41 2015 -0800
@@ -17,6 +17,17 @@
 	return 0;
 }
 
+int menu_dir_sort(const void *a, const void *b)
+{
+	const dir_entry *da, *db;
+	da = a;
+	db = b;
+	if (da->is_dir != db->is_dir) {
+		return db->is_dir - da->is_dir;
+	}
+	return strcasecmp(((dir_entry *)a)->name, ((dir_entry *)b)->name);
+}
+
 void * menu_write_w(uint32_t address, void * context, uint16_t value)
 {
 	m68k_context *m68k = context;
@@ -33,9 +44,13 @@
 		case 0: {
 			size_t num_entries;
 			dir_entry *entries = get_dir_list(menu->curpath, &num_entries);
+			if (entries) {
+				qsort(entries, num_entries, sizeof(dir_entry), menu_dir_sort);
+			}
+			uint8_t *dest;
 			for (size_t i = 0; i < num_entries; i++)
 			{
-				uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen);
+				dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen);
 				if (!dest) {
 					break;
 				}
@@ -69,7 +84,36 @@
 					dst += 2;
 				}
 			}
-			free_dir_list(entries, num_entries);
+			//terminate list
+			dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen);
+			if (dest) {
+				*dest = dest[1] = 0;
+				free_dir_list(entries, num_entries);
+			}
+			break;
+		}
+		case 1: {
+			char buf[4096];
+			char *cur;
+			char * dest = NULL;
+			for (cur = buf; cur < buf+sizeof(buf); cur+=2, dst+=2, dest+=2)
+			{
+				if (!dest || !(dst & 0xFFFF)) {
+					//we may have walked off the end of a memory block, get a fresh native pointer
+					dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen);
+					if (!dest) {
+						break;
+					}
+				}
+				*cur = dest[1];
+				cur[1] = *dest;
+				if (!*dest || !dest[1]) {
+					break;
+				}
+			}
+			char *pieces[] = {menu->curpath, "/", buf};
+			menu->curpath = alloc_concat_m(3, pieces);
+			free(pieces[0]);
 			break;
 		}
 		default: