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, &ltime)); 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, &ltime));
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, &ltime));
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, &ltime));
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