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);