From 5b701192f9676c8bddfc7c2b28760a1946f1b3fd Mon Sep 17 00:00:00 2001 From: sorgelig Date: Mon, 31 May 2021 08:46:29 +0800 Subject: [PATCH] arcade: add cheats menu. --- menu.cpp | 74 ++++++++++++++--------- support/arcade/mra_loader.cpp | 109 ++++++++++++++++++++-------------- support/arcade/mra_loader.h | 8 +-- 3 files changed, 117 insertions(+), 74 deletions(-) diff --git a/menu.cpp b/menu.cpp index 5178ea1..81235f0 100644 --- a/menu.cpp +++ b/menu.cpp @@ -1020,7 +1020,7 @@ void HandleUI(void) static int has_fb_terminal = 0; static unsigned long flash_timer = 0; static int flash_state = 0; - static uint32_t dip_submenu; + static uint32_t dip_submenu, dip2_submenu, dipv; static int need_reset = 0; static int flat = 0; static int menusub_parent = 0; @@ -1571,6 +1571,7 @@ void HandleUI(void) else OsdSetTitle(title); dip_submenu = -1; + dip2_submenu = -1; int last_space = 0; @@ -1592,8 +1593,7 @@ void HandleUI(void) } else if (!strcmp(p, "DIP")) { - h = page; - if (!h && arcade_sw()->dip_num) + if (!h && arcade_sw(0)->dip_num) { dip_submenu = selentry; MenuWrite(entry, " DIP Switches \x16", menusub == selentry, 0); @@ -1601,6 +1601,20 @@ void HandleUI(void) selentry++; menumask = (menumask << 1) | 1; } + continue; + } + else if (!strcmp(p, "CHEAT")) + { + h = page; + if (!h && arcade_sw(1)->dip_num) + { + dip2_submenu = selentry; + MenuWrite(entry, " Cheats \x16", menusub == selentry, 0); + entry++; + selentry++; + menumask = (menumask << 1) | 1; + } + continue; } else { @@ -1907,8 +1921,9 @@ void HandleUI(void) } else if (select || recent || minus || plus) { - if (dip_submenu == menusub && select) + if ((dip_submenu == menusub || dip2_submenu == menusub) && select) { + dipv = (dip_submenu == menusub) ? 0 : 1; menustate = MENU_ARCADE_DIP1; menusub = 0; } @@ -1931,7 +1946,7 @@ void HandleUI(void) d = 0; inpage = !page; - if (strcmp(p, "DIP") && strncmp(p, "DEFMRA,", 7)) + if (strcmp(p, "DIP") && strcmp(p, "CHEAT") && strncmp(p, "DEFMRA,", 7)) { //Hide or Disable flag while ((p[0] == 'H' || p[0] == 'D' || p[0] == 'h' || p[0] == 'd') && strlen(p) > 2) @@ -1944,10 +1959,9 @@ void HandleUI(void) p += 2; } } - else if (!arcade_sw()->dip_num) - { - continue; - } + + if (!strcmp(p, "DIP") && (!arcade_sw(0)->dip_num || inpage)) continue; + if (!strcmp(p, "CHEAT") && (!arcade_sw(1)->dip_num || inpage)) continue; if (p[0] == 'P') { @@ -2598,7 +2612,7 @@ void HandleUI(void) case MENU_ARCADE_DIP1: helptext_idx = 0; menumask = 0; - OsdSetTitle("DIP Switches"); + OsdSetTitle(dipv ? "Cheats" : "DIP Switches"); menustate = MENU_ARCADE_DIP2; parentstate = MENU_ARCADE_DIP1; @@ -2611,7 +2625,7 @@ void HandleUI(void) uint32_t selentry = 0; menumask = 0; - sw_struct *sw = arcade_sw(); + sw_struct *sw = arcade_sw(dipv); int n = (sw->dip_num < OsdGetSize() - 1) ? (OsdGetSize() - 1 - sw->dip_num) / 2 : 0; for (; entry < n; entry++) MenuWrite(entry); @@ -2652,7 +2666,7 @@ void HandleUI(void) for (; entry < OsdGetSize() - 1; entry++) MenuWrite(entry, "", 0, 0); - MenuWrite(entry, " Reset to apply", menusub == selentry); + MenuWrite(entry, dipv ? " save" : " Reset to apply", menusub == selentry); menusub_last = selentry; menumask = (menumask << 1) | 1; @@ -2662,25 +2676,28 @@ void HandleUI(void) break; case MENU_ARCADE_DIP2: - if (menu) + if (menu || left) { menustate = MENU_GENERIC_MAIN1; - menusub = dip_submenu; - arcade_sw_save(); + menusub = dipv ? dip2_submenu : dip_submenu; + arcade_sw_save(0); } if (select) { if (menusub == menusub_last) { - arcade_sw_save(); - user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET); - user_io_8bit_set_status(0, UIO_STATUS_RESET); + arcade_sw_save(dipv); + if (!dipv) + { + user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET); + user_io_8bit_set_status(0, UIO_STATUS_RESET); + } menustate = MENU_NONE1; } else { - sw_struct *sw = arcade_sw(); + sw_struct *sw = arcade_sw(dipv); uint64_t status = sw->dip_cur & sw->dip[menusub].mask; int m = 0; for (int n = 0; n < sw->dip[menusub].num; n++) @@ -2695,7 +2712,7 @@ void HandleUI(void) m = (m + 1) % sw->dip[menusub].num; sw->dip_cur = (sw->dip_cur & ~sw->dip[menusub].mask) | sw->dip[menusub].val[m]; menustate = MENU_ARCADE_DIP1; - arcade_sw_send(); + arcade_sw_send(dipv); } } break; @@ -4708,15 +4725,18 @@ void HandleUI(void) printf("Saving config to %s\n", filename); FileSaveConfig(filename, status, 8); menustate = MENU_GENERIC_MAIN1; - if (arcade_sw()->dip_num) + for (int n = 0; n < 2; n++) { - arcade_sw()->dip_cur = arcade_sw()->dip_def; - arcade_sw_send(); - arcade_sw_save(); - user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET); - user_io_8bit_set_status(0, UIO_STATUS_RESET); - menustate = MENU_NONE1; + if (arcade_sw(n)->dip_num) + { + arcade_sw(n)->dip_cur = arcade_sw(n)->dip_def; + arcade_sw_send(n); + user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET); + user_io_8bit_set_status(0, UIO_STATUS_RESET); + arcade_sw_save(n); + } } + menustate = MENU_NONE1; menusub = 0; } } diff --git a/support/arcade/mra_loader.cpp b/support/arcade/mra_loader.cpp index e634fd6..326e437 100644 --- a/support/arcade/mra_loader.cpp +++ b/support/arcade/mra_loader.cpp @@ -49,7 +49,7 @@ static char arcade_error_msg[kBigTextSize] = {}; static char arcade_root[kBigTextSize]; static char mame_root[kBigTextSize]; -static sw_struct switches = {}; +static sw_struct switches[2] = {}; static int nvram_idx = 0; static int nvram_size = 0; @@ -104,41 +104,48 @@ static void arcade_nvm_load() } } -sw_struct *arcade_sw() +sw_struct *arcade_sw(int n) { - return &switches; + if (n > 1) n = 1; + if (n < 0) n = 0; + return &switches[n]; } -void arcade_sw_send() +void arcade_sw_send(int n) { - if (switches.dip_num) + sw_struct *sw = arcade_sw(n); + if (sw->dip_num) { - user_io_set_index(254); + user_io_set_index(254 + n); user_io_set_download(1); - user_io_file_tx_data((uint8_t*)&switches.dip_cur, sizeof(switches.dip_cur)); + user_io_file_tx_data((uint8_t*)&sw->dip_cur, sizeof(sw->dip_cur)); user_io_set_download(0); } } -void arcade_sw_save() +void arcade_sw_save(int n) { - if (switches.dip_saved != switches.dip_cur) + sw_struct *sw = arcade_sw(n); + if (sw->dip_num && sw->dip_saved != sw->dip_cur) { - char path[256] = CONFIG_DIR"/dips/"; + static char path[1024]; + strcpy(path, (n) ? CONFIG_DIR"/cheats/" : CONFIG_DIR"/dips/"); FileCreatePath(path); - strcat(path, switches.name); - if (FileSave(path, &switches.dip_cur, sizeof(switches.dip_cur))) + strcat(path, sw->name); + if (FileSave(path, &sw->dip_cur, sizeof(sw->dip_cur))) { - switches.dip_saved = switches.dip_cur; + sw->dip_saved = sw->dip_cur; } } } -void arcade_sw_load() +void arcade_sw_load(int n) { - char path[256] = "dips/"; - strcat(path, switches.name); - FileLoadConfig(path, &switches.dip_cur, sizeof(switches.dip_cur)); + sw_struct *sw = arcade_sw(n); + static char path[1024]; + strcpy(path, (n) ? CONFIG_DIR"/cheats/" : CONFIG_DIR"/dips/"); + strcat(path, sw->name); + FileLoadConfig(path, &sw->dip_cur, sizeof(sw->dip_cur)); } static void set_arcade_root(const char *path) @@ -463,10 +470,19 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons if (!strcasecmp(node->tag, "switches")) { arc_info->insidesw = 1; - switches.dip_cur = 0; - switches.dip_def = 0; - switches.dip_num = 0; - memset(&switches.dip, 0, sizeof(switches.dip)); + switches[0].dip_cur = 0; + switches[0].dip_def = 0; + switches[0].dip_num = 0; + memset(&switches[0].dip, 0, sizeof(switches[0].dip)); + } + + if (!strcasecmp(node->tag, "cheats")) + { + arc_info->insidesw = 2; + switches[1].dip_cur = 0; + switches[1].dip_def = 0; + switches[1].dip_num = 0; + memset(&switches[1].dip, 0, sizeof(switches[1].dip)); } if (!strcasecmp(node->tag, "interleave")) @@ -584,13 +600,14 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons } else if (arc_info->insidesw) { - if (!strcasecmp(node->tag, "switches")) + sw_struct* sw = &switches[arc_info->insidesw - 1]; + if (!strcasecmp(node->tag, "switches") || !strcasecmp(node->tag, "cheats")) { if (!strcasecmp(node->attributes[i].name, "default")) { size_t len = 0; unsigned char* binary = hexstr_to_char(node->attributes[i].value, &len); - for (size_t i = 0; i < len; i++) switches.dip_def |= binary[i] << (i * 8); + for (size_t i = 0; i < len; i++) sw->dip_def |= binary[i] << (i * 8); free(binary); } @@ -600,7 +617,7 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons { if (!strcasecmp(node->attributes[i].name, "name")) { - snprintf(switches.dip[switches.dip_num].name, sizeof(switches.dip[switches.dip_num].name), node->attributes[i].value); + snprintf(sw->dip[sw->dip_num].name, sizeof(sw->dip[sw->dip_num].name), node->attributes[i].value); } if (!strcasecmp(node->attributes[i].name, "bits")) @@ -615,10 +632,10 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons { uint64_t mask = 1; if (num == 1) e = b; - switches.dip[switches.dip_num].start = b; + sw->dip[sw->dip_num].start = b; for (int i = 0; i < (e - b); i++) mask = (mask << 1) | 1; - switches.dip[switches.dip_num].mask = mask << b; - switches.dip[switches.dip_num].size = e - b + 1; + sw->dip[sw->dip_num].mask = mask << b; + sw->dip[sw->dip_num].size = e - b + 1; } } @@ -631,13 +648,13 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons char *p = strchr(val, ','); size_t len = p ? p - val : strlen(val); size_t sz = len + 1; - if (sz > sizeof(switches.dip[0].id[0])) sz = sizeof(switches.dip[0].id[0]); - snprintf(switches.dip[switches.dip_num].id[n], sz, val); + if (sz > sizeof(sw->dip[0].id[0])) sz = sizeof(sw->dip[0].id[0]); + snprintf(sw->dip[sw->dip_num].id[n], sz, val); val += len; if (*val == ',') val++; n++; } - switches.dip[switches.dip_num].num = n; + sw->dip[sw->dip_num].num = n; } if (!strcasecmp(node->attributes[i].name, "values")) @@ -654,12 +671,12 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons break; } - switches.dip[switches.dip_num].val[n] = v; + sw->dip[sw->dip_num].val[n] = v; val = endp; while (*val && (*val == ' ' || *val == ',')) val++; n++; } - switches.dip[switches.dip_num].has_val = 1; + sw->dip[sw->dip_num].has_val = 1; } } } @@ -889,15 +906,17 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons } } - if (!strcasecmp(node->tag, "dip")) + if (arc_info->insidesw && !strcasecmp(node->tag, "dip")) { - int n = switches.dip_num; - for (int i = 0; i < switches.dip[n].num; i++) + sw_struct* sw = &switches[arc_info->insidesw - 1]; + + int n = sw->dip_num; + for (int i = 0; i < sw->dip[n].num; i++) { - switches.dip[n].val[i] = ((switches.dip[n].has_val) ? switches.dip[n].val[i] : i) << switches.dip[n].start; + sw->dip[n].val[i] = ((sw->dip[n].has_val) ? sw->dip[n].val[i] : i) << sw->dip[n].start; } - if (switches.dip_num < 63) switches.dip_num++; + if (sw->dip_num < 63) sw->dip_num++; } if (!strcasecmp(node->tag, "nvram")) arcade_nvm_load(); @@ -1012,9 +1031,10 @@ int arcade_send_rom(const char *xml) { const char *p = strrchr(xml, '/'); p = p ? p + 1 : xml; - snprintf(switches.name, sizeof(switches.name), p); - char *ext = strcasestr(switches.name, ".mra"); + snprintf(switches[0].name, sizeof(switches[0].name), "%s", p); + char *ext = strcasestr(switches[0].name, ".mra"); if (ext) strcpy(ext, ".dip"); + memcpy(switches[1].name, switches[0].name, sizeof(switches[1].name)); snprintf(nvram_name, sizeof(nvram_name), p); ext = strcasestr(nvram_name, ".mra"); @@ -1045,10 +1065,13 @@ int arcade_send_rom(const char *xml) } buffer_destroy(arc_info.data); - switches.dip_cur = switches.dip_def; - arcade_sw_load(); - switches.dip_saved = switches.dip_cur; - arcade_sw_send(); + for (int n = 0; n < 2; n++) + { + switches[n].dip_cur = switches[n].dip_def; + arcade_sw_load(n); + switches[n].dip_saved = switches[n].dip_cur; + arcade_sw_send(n); + } return 0; } diff --git a/support/arcade/mra_loader.h b/support/arcade/mra_loader.h index 8085d66..609f59d 100644 --- a/support/arcade/mra_loader.h +++ b/support/arcade/mra_loader.h @@ -27,10 +27,10 @@ struct sw_struct dip_struct dip[64]; }; -sw_struct *arcade_sw(); -void arcade_sw_send(); -void arcade_sw_save(); -void arcade_sw_load(); +sw_struct *arcade_sw(int n); +void arcade_sw_send(int n); +void arcade_sw_save(int n); +void arcade_sw_load(int n); void arcade_override_name(const char *xml); void arcade_nvm_save();