Mercurial > repos > blastem
comparison menu.c @ 1059:8da967779710
Added some hacky code to support a virtual root directory for selecting drives on Windows
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 31 Jul 2016 15:20:00 -0700 |
parents | 2c8d76280e43 |
children | 22e87b739ad6 |
comparison
equal
deleted
inserted
replaced
1058:266dc3f31f35 | 1059:8da967779710 |
---|---|
109 } | 109 } |
110 #endif | 110 #endif |
111 | 111 |
112 #ifdef _WIN32 | 112 #ifdef _WIN32 |
113 #define localtime_r(a,b) localtime(a) | 113 #define localtime_r(a,b) localtime(a) |
114 #endif | 114 #undef N |
115 #undef X | |
116 #include <windows.h> | |
117 #endif | |
118 | |
119 uint32_t copy_dir_entry_to_guest(uint32_t dst, m68k_context *m68k, char *name, uint8_t is_dir) | |
120 { | |
121 uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); | |
122 if (!dest) { | |
123 return 0; | |
124 } | |
125 *(dest++) = is_dir; | |
126 *(dest++) = 1; | |
127 dst += 2; | |
128 uint8_t term = 0; | |
129 for (char *cpos = name; *cpos; cpos++) | |
130 { | |
131 dest[1] = *cpos; | |
132 dest[0] = cpos[1]; | |
133 if (cpos[1]) { | |
134 cpos++; | |
135 } else { | |
136 term = 1; | |
137 } | |
138 dst += 2; | |
139 if (!(dst & 0xFFFF)) { | |
140 //we may have walked off the end of a memory block, get a fresh native pointer | |
141 dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); | |
142 if (!dest) { | |
143 break; | |
144 } | |
145 } else { | |
146 dest += 2; | |
147 } | |
148 } | |
149 if (!term) { | |
150 *(dest++) = 0; | |
151 *dest = 0; | |
152 dst += 2; | |
153 } | |
154 return dst; | |
155 } | |
115 | 156 |
116 void * menu_write_w(uint32_t address, void * context, uint16_t value) | 157 void * menu_write_w(uint32_t address, void * context, uint16_t value) |
117 { | 158 { |
118 m68k_context *m68k = context; | 159 m68k_context *m68k = context; |
119 genesis_context *gen = m68k->system; | 160 genesis_context *gen = m68k->system; |
134 if (menu->state) { | 175 if (menu->state) { |
135 uint32_t dst = menu->latch << 16 | value; | 176 uint32_t dst = menu->latch << 16 | value; |
136 switch (address >> 2) | 177 switch (address >> 2) |
137 { | 178 { |
138 case 0: { | 179 case 0: { |
180 #ifdef _WIN32 | |
181 //handle virtual "drives" directory | |
182 if (menu->curpath[0] == PATH_SEP[0]) { | |
183 char drivestrings[4096]; | |
184 if (sizeof(drivestrings) >= GetLogicalDriveStrings(sizeof(drivestrings), drivestrings)) { | |
185 for (char *cur = drivestrings; *cur; cur += strlen(cur) + 1) | |
186 { | |
187 dst = copy_dir_entry_to_guest(dst, m68k, cur, 1); | |
188 } | |
189 } | |
190 //terminate list | |
191 uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); | |
192 if (dest) { | |
193 *dest = dest[1] = 0; | |
194 } | |
195 break; | |
196 } | |
197 #endif | |
139 size_t num_entries; | 198 size_t num_entries; |
140 dir_entry *entries = get_dir_list(menu->curpath, &num_entries); | 199 dir_entry *entries = get_dir_list(menu->curpath, &num_entries); |
141 if (entries) { | 200 if (entries) { |
142 qsort(entries, num_entries, sizeof(dir_entry), menu_dir_sort); | 201 qsort(entries, num_entries, sizeof(dir_entry), menu_dir_sort); |
143 } else { | 202 } else { |
145 entries = malloc(sizeof(dir_entry)); | 204 entries = malloc(sizeof(dir_entry)); |
146 entries->name = strdup(".."); | 205 entries->name = strdup(".."); |
147 entries->is_dir = 1; | 206 entries->is_dir = 1; |
148 num_entries = 1; | 207 num_entries = 1; |
149 } | 208 } |
150 uint8_t *dest; | 209 #ifdef _WIN32 |
151 for (size_t i = 0; i < num_entries; i++) | 210 if (menu->curpath[1] == ':' && !menu->curpath[2]) { |
211 //Add fake .. entry to allow navigation to virtual "drives" directory | |
212 dst = copy_dir_entry_to_guest(dst, m68k, "..", 1); | |
213 } | |
214 #endif | |
215 for (size_t i = 0; dst && i < num_entries; i++) | |
152 { | 216 { |
153 dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); | 217 dst = copy_dir_entry_to_guest(dst, m68k, entries[i].name, entries[i].is_dir); |
154 if (!dest) { | |
155 break; | |
156 } | |
157 *(dest++) = entries[i].is_dir; | |
158 *(dest++) = 1; | |
159 dst += 2; | |
160 uint8_t term = 0; | |
161 for (char *cpos = entries[i].name; *cpos; cpos++) | |
162 { | |
163 dest[1] = *cpos; | |
164 dest[0] = cpos[1]; | |
165 if (cpos[1]) { | |
166 cpos++; | |
167 } else { | |
168 term = 1; | |
169 } | |
170 dst += 2; | |
171 if (!(dst & 0xFFFF)) { | |
172 //we may have walked off the end of a memory block, get a fresh native pointer | |
173 dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); | |
174 if (!dest) { | |
175 break; | |
176 } | |
177 } else { | |
178 dest += 2; | |
179 } | |
180 } | |
181 if (!term) { | |
182 *(dest++) = 0; | |
183 *dest = 0; | |
184 dst += 2; | |
185 } | |
186 } | 218 } |
187 //terminate list | 219 //terminate list |
188 dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); | 220 uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); |
189 if (dest) { | 221 if (dest) { |
190 *dest = dest[1] = 0; | 222 *dest = dest[1] = 0; |
191 } | 223 } |
192 free_dir_list(entries, num_entries); | 224 free_dir_list(entries, num_entries); |
193 break; | 225 break; |
194 } | 226 } |
195 case 1: { | 227 case 1: { |
196 char buf[4096]; | 228 char buf[4096]; |
197 copy_string_from_guest(m68k, dst, buf, sizeof(buf)); | 229 copy_string_from_guest(m68k, dst, buf, sizeof(buf)); |
198 if (!strcmp(buf, "..")) { | 230 if (!strcmp(buf, "..")) { |
231 #ifdef _WIN32 | |
232 if (menu->curpath[1] == ':' && !menu->curpath[2]) { | |
233 menu->curpath[0] = PATH_SEP[0]; | |
234 menu->curpath[1] = 0; | |
235 break; | |
236 } | |
237 #endif | |
199 size_t len = strlen(menu->curpath); | 238 size_t len = strlen(menu->curpath); |
200 while (len > 0) { | 239 while (len > 0) { |
201 --len; | 240 --len; |
202 if (is_path_sep(menu->curpath[len])) { | 241 if (is_path_sep(menu->curpath[len])) { |
203 if (!len) { | 242 if (!len) { |
209 break; | 248 break; |
210 } | 249 } |
211 } | 250 } |
212 } else { | 251 } else { |
213 char *tmp = menu->curpath; | 252 char *tmp = menu->curpath; |
253 #ifdef _WIN32 | |
254 if (menu->curpath[0] == PATH_SEP[0] && !menu->curpath[1]) { | |
255 menu->curpath = strdup(buf); | |
256 } else | |
257 #endif | |
214 if (is_path_sep(menu->curpath[strlen(menu->curpath) - 1])) { | 258 if (is_path_sep(menu->curpath[strlen(menu->curpath) - 1])) { |
215 menu->curpath = alloc_concat(menu->curpath, buf); | 259 menu->curpath = alloc_concat(menu->curpath, buf); |
216 } else { | 260 } else { |
217 char const *pieces[] = {menu->curpath, PATH_SEP, buf}; | 261 char const *pieces[] = {menu->curpath, PATH_SEP, buf}; |
218 menu->curpath = alloc_concat_m(3, pieces); | 262 menu->curpath = alloc_concat_m(3, pieces); |