Mercurial > repos > blastem
comparison menu.c @ 1478:da1dce39e846 nuklear_ui
Refactored save slot related logic to reduce duplication and allow reuse in new UI. Get state loading/saving mostly working in new UI
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 24 Nov 2017 12:04:02 -0800 |
parents | 152a60c6787e |
children | 77a401044935 |
comparison
equal
deleted
inserted
replaced
1477:1cdd7f492af8 | 1478:da1dce39e846 |
---|---|
7 #include "menu.h" | 7 #include "menu.h" |
8 #include "backend.h" | 8 #include "backend.h" |
9 #include "util.h" | 9 #include "util.h" |
10 #include "gst.h" | 10 #include "gst.h" |
11 #include "paths.h" | 11 #include "paths.h" |
12 #include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up | 12 #include "saves.h" |
13 | 13 |
14 static menu_context *get_menu(genesis_context *gen) | 14 static menu_context *get_menu(genesis_context *gen) |
15 { | 15 { |
16 menu_context *menu = gen->extra; | 16 menu_context *menu = gen->extra; |
17 if (!menu) { | 17 if (!menu) { |
91 *dst = cur[1]; | 91 *dst = cur[1]; |
92 } | 92 } |
93 } | 93 } |
94 | 94 |
95 #define SAVE_INFO_BUFFER_SIZE (11*40) | 95 #define SAVE_INFO_BUFFER_SIZE (11*40) |
96 | |
97 #ifdef _WIN32 | |
98 #define localtime_r(a,b) localtime(a) | |
99 //windows inclues seem not to like certain single letter defines from m68k_internal.h | |
100 //get rid of them here | |
101 #undef X | |
102 #undef N | |
103 #undef Z | |
104 #undef V | |
105 #undef C | |
106 #include <windows.h> | |
107 #endif | |
108 | 96 |
109 uint32_t copy_dir_entry_to_guest(uint32_t dst, m68k_context *m68k, char *name, uint8_t is_dir) | 97 uint32_t copy_dir_entry_to_guest(uint32_t dst, m68k_context *m68k, char *name, uint8_t is_dir) |
110 { | 98 { |
111 uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); | 99 uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); |
112 if (!dest) { | 100 if (!dest) { |
305 case 4: { | 293 case 4: { |
306 char *buffer = malloc(SAVE_INFO_BUFFER_SIZE); | 294 char *buffer = malloc(SAVE_INFO_BUFFER_SIZE); |
307 char *cur = buffer; | 295 char *cur = buffer; |
308 if (gen->header.next_context && gen->header.next_context->save_dir) { | 296 if (gen->header.next_context && gen->header.next_context->save_dir) { |
309 char *end = buffer + SAVE_INFO_BUFFER_SIZE; | 297 char *end = buffer + SAVE_INFO_BUFFER_SIZE; |
310 char slotfile[] = "slot_0.state"; | 298 uint32_t num_slots; |
311 char slotfilegst[] = "slot_0.gst"; | 299 save_slot_info *slots = get_slot_info(gen->header.next_context, &num_slots); |
312 char const * parts[3] = {gen->header.next_context->save_dir, PATH_SEP, slotfile}; | 300 for (uint32_t i = 0; i < num_slots; i++) |
313 char const * partsgst[3] = {gen->header.next_context->save_dir, PATH_SEP, slotfilegst}; | |
314 struct tm ltime; | |
315 char *fname; | |
316 time_t modtime; | |
317 for (int i = 0; i < 10 && cur < end; i++) | |
318 { | 301 { |
319 slotfile[5] = i + '0'; | 302 size_t desc_len = strlen(slots[i].desc) + 1;//+1 for string terminator |
320 fname = alloc_concat_m(3, parts); | 303 char *after = cur + desc_len + 1;//+1 for list terminator |
321 modtime = get_modification_time(fname); | 304 if (after > cur) { |
322 free(fname); | 305 desc_len -= after - cur; |
323 if (modtime) { | 306 } |
324 cur += snprintf(cur, end-cur, "Slot %d - ", i); | 307 memcpy(cur, slots[i].desc, desc_len); |
325 cur += strftime(cur, end-cur, "%c", localtime_r(&modtime, <ime)); | 308 cur = after; |
326 | 309 } |
327 } else { | 310 *cur = 0;//terminate list |
328 slotfilegst[5] = i + '0'; | |
329 fname = alloc_concat_m(3, partsgst); | |
330 modtime = get_modification_time(fname); | |
331 free(fname); | |
332 if (modtime) { | |
333 cur += snprintf(cur, end-cur, "Slot %d - ", i); | |
334 cur += strftime(cur, end-cur, "%c", localtime_r(&modtime, <ime)); | |
335 } else { | |
336 cur += snprintf(cur, end-cur, "Slot %d - EMPTY", i); | |
337 } | |
338 } | |
339 //advance past the null terminator for this entry | |
340 cur++; | |
341 } | |
342 if (cur < end) { | |
343 parts[2] = "quicksave.state"; | |
344 fname = alloc_concat_m(3, parts); | |
345 modtime = get_modification_time(fname); | |
346 free(fname); | |
347 if (modtime) { | |
348 cur += strftime(cur, end-cur, "Quick - %c", localtime_r(&modtime, <ime)); | |
349 } else { | |
350 parts[2] = "quicksave.gst"; | |
351 fname = alloc_concat_m(3, parts); | |
352 modtime = get_modification_time(fname); | |
353 free(fname); | |
354 if (modtime) { | |
355 cur += strftime(cur, end-cur, "Quick - %c", localtime_r(&modtime, <ime)); | |
356 } else if ((end-cur) > strlen("Quick - EMPTY")){ | |
357 cur += strlen(strcpy(cur, "Quick - EMPTY")); | |
358 } | |
359 } | |
360 //advance past the null terminator for this entry | |
361 cur++; | |
362 if (cur < end) { | |
363 //terminate the list | |
364 *(cur++) = 0; | |
365 } | |
366 } | |
367 } else { | 311 } else { |
368 *(cur++) = 0; | 312 *(cur++) = 0; |
369 *(cur++) = 0; | 313 *(cur++) = 0; |
370 } | 314 } |
371 copy_to_guest(m68k, dst, buffer, cur-buffer); | 315 copy_to_guest(m68k, dst, buffer, cur-buffer); |
381 case 6: | 325 case 6: |
382 //load state | 326 //load state |
383 if (gen->header.next_context && gen->header.next_context->save_dir) { | 327 if (gen->header.next_context && gen->header.next_context->save_dir) { |
384 if (!gen->header.next_context->load_state(gen->header.next_context, dst)) { | 328 if (!gen->header.next_context->load_state(gen->header.next_context, dst)) { |
385 break; | 329 break; |
386 }/* | 330 } |
387 char numslotname[] = "slot_0.state"; | |
388 char *slotname; | |
389 if (dst == QUICK_SAVE_SLOT) { | |
390 slotname = "quicksave.state"; | |
391 } else { | |
392 numslotname[5] = '0' + dst; | |
393 slotname = numslotname; | |
394 } | |
395 char const *parts[] = {gen->header.next_context->save_dir, PATH_SEP, slotname}; | |
396 char *statepath = alloc_concat_m(3, parts); | |
397 gen->header.next_context->load_state | |
398 genesis_context *next = (genesis_context *)gen->header.next_context; | |
399 deserialize_buffer state; | |
400 uint32_t pc = 0; | |
401 if (load_from_file(&state, statepath)) { | |
402 genesis_deserialize(&state, next); | |
403 free(state.data); | |
404 //HACK | |
405 pc = next->m68k->last_prefetch_address; | |
406 } else { | |
407 strcpy(statepath + strlen(statepath)-strlen("state"), "gst"); | |
408 pc = load_gst(next, statepath); | |
409 } | |
410 free(statepath); | |
411 if (!pc) { | |
412 break; | |
413 } | |
414 next->m68k->resume_pc = get_native_address_trans(next->m68k, pc); | |
415 */ | |
416 } | 331 } |
417 m68k->should_return = 1; | 332 m68k->should_return = 1; |
418 break; | 333 break; |
419 case 7: | 334 case 7: |
420 //read only port | 335 //read only port |