# HG changeset patch # User Michael Pavone # Date 1470003600 25200 # Node ID 8da9677797107cc18b62cc57ec6621a01c2f2d38 # Parent 266dc3f31f35319a18ca073087a35fb2a41e9a0f Added some hacky code to support a virtual root directory for selecting drives on Windows diff -r 266dc3f31f35 -r 8da967779710 menu.c --- a/menu.c Sat Jul 30 23:36:02 2016 -0700 +++ b/menu.c Sun Jul 31 15:20:00 2016 -0700 @@ -111,8 +111,49 @@ #ifdef _WIN32 #define localtime_r(a,b) localtime(a) +#undef N +#undef X +#include #endif +uint32_t copy_dir_entry_to_guest(uint32_t dst, m68k_context *m68k, char *name, uint8_t is_dir) +{ + uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); + if (!dest) { + return 0; + } + *(dest++) = is_dir; + *(dest++) = 1; + dst += 2; + uint8_t term = 0; + for (char *cpos = name; *cpos; cpos++) + { + dest[1] = *cpos; + dest[0] = cpos[1]; + if (cpos[1]) { + cpos++; + } else { + term = 1; + } + dst += 2; + if (!(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; + } + } else { + dest += 2; + } + } + if (!term) { + *(dest++) = 0; + *dest = 0; + dst += 2; + } + return dst; +} + void * menu_write_w(uint32_t address, void * context, uint16_t value) { m68k_context *m68k = context; @@ -136,6 +177,24 @@ switch (address >> 2) { case 0: { +#ifdef _WIN32 + //handle virtual "drives" directory + if (menu->curpath[0] == PATH_SEP[0]) { + char drivestrings[4096]; + if (sizeof(drivestrings) >= GetLogicalDriveStrings(sizeof(drivestrings), drivestrings)) { + for (char *cur = drivestrings; *cur; cur += strlen(cur) + 1) + { + dst = copy_dir_entry_to_guest(dst, m68k, cur, 1); + } + } + //terminate list + uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); + if (dest) { + *dest = dest[1] = 0; + } + break; + } +#endif size_t num_entries; dir_entry *entries = get_dir_list(menu->curpath, &num_entries); if (entries) { @@ -147,45 +206,18 @@ entries->is_dir = 1; num_entries = 1; } - uint8_t *dest; - for (size_t i = 0; i < num_entries; i++) +#ifdef _WIN32 + if (menu->curpath[1] == ':' && !menu->curpath[2]) { + //Add fake .. entry to allow navigation to virtual "drives" directory + dst = copy_dir_entry_to_guest(dst, m68k, "..", 1); + } +#endif + for (size_t i = 0; dst && i < num_entries; i++) { - dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); - if (!dest) { - break; - } - *(dest++) = entries[i].is_dir; - *(dest++) = 1; - dst += 2; - uint8_t term = 0; - for (char *cpos = entries[i].name; *cpos; cpos++) - { - dest[1] = *cpos; - dest[0] = cpos[1]; - if (cpos[1]) { - cpos++; - } else { - term = 1; - } - dst += 2; - if (!(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; - } - } else { - dest += 2; - } - } - if (!term) { - *(dest++) = 0; - *dest = 0; - dst += 2; - } + dst = copy_dir_entry_to_guest(dst, m68k, entries[i].name, entries[i].is_dir); } //terminate list - dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); + uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); if (dest) { *dest = dest[1] = 0; } @@ -196,6 +228,13 @@ char buf[4096]; copy_string_from_guest(m68k, dst, buf, sizeof(buf)); if (!strcmp(buf, "..")) { +#ifdef _WIN32 + if (menu->curpath[1] == ':' && !menu->curpath[2]) { + menu->curpath[0] = PATH_SEP[0]; + menu->curpath[1] = 0; + break; + } +#endif size_t len = strlen(menu->curpath); while (len > 0) { --len; @@ -211,6 +250,11 @@ } } else { char *tmp = menu->curpath; +#ifdef _WIN32 + if (menu->curpath[0] == PATH_SEP[0] && !menu->curpath[1]) { + menu->curpath = strdup(buf); + } else +#endif if (is_path_sep(menu->curpath[strlen(menu->curpath) - 1])) { menu->curpath = alloc_concat(menu->curpath, buf); } else {