arcade: add cheats menu.
This commit is contained in:
74
menu.cpp
74
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user