diff options
author | 2021-10-19 05:35:30 +1100 | |
---|---|---|
committer | 2021-10-19 05:35:30 +1100 | |
commit | 08ee39da702645560d9924b6d6ab4ee865b9e478 (patch) | |
tree | ef39e565cfc60889920238e8bb0e26ee50c122ec /src | |
parent | 5bea4a62929e67e693c8460341e205f3a60ab1a3 (diff) |
-debugger: Finished updating commands and documentation.
* Updated cheat commands to work with arbitrary devices and address
spaces. You can still only search RAM areas in a single address space
at a time, but any address space of any device can be used now.
* Made the cheatinit/cheatrange commands not affect current state if the
arguments are invalid. Also fixed some bugs in the cheat commands.
* Updated documentation for cheat commands, and added a simple worked
example. Also added single-sentence descriptions of what
(break|watch|register)points are to the top of the relevant pages.
-frontend improvements:
* Added a bit more info to the about box, moved the VCS revision to the
heading.
* Don't show "not" codes in prompts - they're not helpful.
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/debug/debugcmd.cpp | 244 | ||||
-rw-r--r-- | src/emu/debug/debugcmd.h | 14 | ||||
-rw-r--r-- | src/emu/debug/debughlp.cpp | 203 | ||||
-rw-r--r-- | src/frontend/mame/ui/about.cpp | 31 | ||||
-rw-r--r-- | src/frontend/mame/ui/about.h | 4 | ||||
-rw-r--r-- | src/frontend/mame/ui/ui.cpp | 17 |
6 files changed, 288 insertions, 225 deletions
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index bcebb63cf92..04cce880600 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -378,7 +378,7 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu if (name[0] != 0) m_console.source_script(name); - m_cheat.cpu[0] = m_cheat.cpu[1] = 0; + m_cheat.space = nullptr; } @@ -2859,82 +2859,84 @@ void debugger_commands::execute_strdump(int spacenum, const std::vector<std::str void debugger_commands::execute_cheatrange(bool init, const std::vector<std::string> ¶ms) { - cheat_region_map cheat_region[100]; - memset(cheat_region, 0, sizeof(cheat_region)); - - // validate parameters - address_space *space; - if (!validate_device_space_parameter((params.size() > 3) ? params[3] : std::string_view(), -1, space)) + address_space *space = m_cheat.space; + if (!space && !init) + { + m_console.printf("Use cheatinit before cheatrange\n"); return; + } + u8 width = (space || !init) ? m_cheat.width : 1; + bool signed_cheat = (space || !init) ? m_cheat.signed_cheat : false; + bool swapped_cheat = (space || !init) ? m_cheat.swapped_cheat : false; if (init) { - m_cheat.width = 1; - m_cheat.signed_cheat = false; - m_cheat.swapped_cheat = false; + // first argument is sign/size/swap flags if (!params.empty()) { - char const *srtpnt = params[0].c_str(); + std::string const &srtpnt = params[0]; + if (!srtpnt.empty()) + { + width = 1; + signed_cheat = false; + swapped_cheat = false; + } - char sspec = std::tolower((unsigned char)*srtpnt); - if (sspec == 's') - m_cheat.signed_cheat = true; - else if (sspec == 'u') - m_cheat.signed_cheat = false; - else + if (srtpnt.length() >= 1) { - m_console.printf("Invalid sign: expected s or u\n"); - return; + char const sspec = std::tolower((unsigned char)srtpnt[0]); + if (sspec == 's') + signed_cheat = true; + else if (sspec == 'u') + signed_cheat = false; + else + { + m_console.printf("Invalid sign: expected s or u\n"); + return; + } } - char wspec = std::tolower((unsigned char)*(++srtpnt)); - if (wspec == 'b') - m_cheat.width = 1; - else if (wspec == 'w') - m_cheat.width = 2; - else if (wspec == 'd') - m_cheat.width = 4; - else if (wspec == 'q') - m_cheat.width = 8; - else + if (srtpnt.length() >= 2) { - m_console.printf("Invalid width: expected b, w, d or q\n"); - return; + char const wspec = std::tolower((unsigned char)srtpnt[1]); + if (wspec == 'b') + width = 1; + else if (wspec == 'w') + width = 2; + else if (wspec == 'd') + width = 4; + else if (wspec == 'q') + width = 8; + else + { + m_console.printf("Invalid width: expected b, w, d or q\n"); + return; + } } - if (std::tolower((unsigned char)*(++srtpnt)) == 's') - m_cheat.swapped_cheat = true; - else - m_cheat.swapped_cheat = false; + if (srtpnt.length() >= 3) + { + if (std::tolower((unsigned char)srtpnt[2]) == 's') + swapped_cheat = true; + else + { + m_console.printf("Invalid swap: expected s\n"); + return; + } + } } - } - // initialize entire memory by default - u64 length = 0; - u8 region_count = 0; - if (params.size() <= 1) - { - for (address_map_entry &entry : space->map()->m_entrylist) - { - cheat_region[region_count].offset = entry.m_addrstart & space->addrmask(); - cheat_region[region_count].endoffset = entry.m_addrend & space->addrmask(); - cheat_region[region_count].share = entry.m_share; - cheat_region[region_count].disabled = (entry.m_write.m_type == AMH_RAM) ? false : true; - - // disable double share regions - if (entry.m_share != nullptr) - for (u8 i = 0; i < region_count; i++) - if (cheat_region[i].share != nullptr) - if (strcmp(cheat_region[i].share, entry.m_share) == 0) - cheat_region[region_count].disabled = true; - - region_count++; - } + // fourth argument is device/space + if (!validate_device_space_parameter((params.size() > 3) ? params[3] : std::string_view(), -1, space)) + return; } - else + + cheat_region_map cheat_region[100]; // FIXME: magic number + unsigned region_count = 0; + if (params.size() >= (init ? 3 : 2)) { // validate parameters - u64 offset; + u64 offset, length; if (!validate_number_parameter(params[init ? 1 : 0], offset)) return; if (!validate_number_parameter(params[init ? 2 : 1], length)) @@ -2947,61 +2949,76 @@ void debugger_commands::execute_cheatrange(bool init, const std::vector<std::str cheat_region[region_count].disabled = false; region_count++; } + else + { + // initialize to entire memory by default + for (address_map_entry &entry : space->map()->m_entrylist) + { + cheat_region[region_count].offset = entry.m_addrstart & space->addrmask(); + cheat_region[region_count].endoffset = entry.m_addrend & space->addrmask(); + cheat_region[region_count].share = entry.m_share; + cheat_region[region_count].disabled = entry.m_write.m_type != AMH_RAM; + + // disable duplicate share regions + if (entry.m_share) + for (unsigned i = 0; i < region_count; i++) + if (cheat_region[i].share && !strcmp(cheat_region[i].share, entry.m_share)) + cheat_region[region_count].disabled = true; + + if (!cheat_region[region_count].disabled) + region_count++; + } + } // determine the writable extent of each region in total u64 real_length = 0; - for (u8 i = 0; i < region_count; i++) - if (!cheat_region[i].disabled) - for (u64 curaddr = cheat_region[i].offset; curaddr <= cheat_region[i].endoffset; curaddr += m_cheat.width) - if (cheat_address_is_valid(*space, curaddr)) - real_length++; + for (unsigned i = 0; i < region_count; i++) + for (u64 curaddr = cheat_region[i].offset; curaddr <= cheat_region[i].endoffset; curaddr += width) + if (cheat_address_is_valid(*space, curaddr)) + real_length++; - if (real_length == 0) + if (!real_length) { m_console.printf("No writable bytes found in this area\n"); return; } - u32 active_cheat = 0; + size_t active_cheat = 0; if (init) { // initialize new cheat system - m_cheat.cheatmap.resize(real_length); + m_cheat.space = space; + m_cheat.width = width; m_cheat.undo = 0; - m_cheat.cpu[0] = params.size() > 3 ? params[3][0] : '0'; + m_cheat.signed_cheat = signed_cheat; + m_cheat.swapped_cheat = swapped_cheat; } else { - // add range to cheat system - if (m_cheat.cpu[0] == 0) - { - m_console.printf("Use cheatinit before cheatrange\n"); - return; - } - - if (!validate_device_space_parameter(m_cheat.cpu, -1, space)) - return; - active_cheat = m_cheat.cheatmap.size(); - m_cheat.cheatmap.resize(m_cheat.cheatmap.size() + real_length); } + m_cheat.cheatmap.resize(active_cheat + real_length); // initialize cheatmap in the selected space - for (u8 i = 0; i < region_count; i++) - if (!cheat_region[i].disabled) - for (u64 curaddr = cheat_region[i].offset; curaddr <= cheat_region[i].endoffset; curaddr += m_cheat.width) - if (cheat_address_is_valid(*space, curaddr)) - { - m_cheat.cheatmap[active_cheat].previous_value = cheat_read_extended(&m_cheat, *space, curaddr); - m_cheat.cheatmap[active_cheat].first_value = m_cheat.cheatmap[active_cheat].previous_value; - m_cheat.cheatmap[active_cheat].offset = curaddr; - m_cheat.cheatmap[active_cheat].state = 1; - m_cheat.cheatmap[active_cheat].undo = 0; - active_cheat++; - } + for (unsigned i = 0; i < region_count; i++) + for (u64 curaddr = cheat_region[i].offset; curaddr <= cheat_region[i].endoffset; curaddr += width) + if (cheat_address_is_valid(*space, curaddr)) + { + m_cheat.cheatmap[active_cheat].previous_value = cheat_read_extended(&m_cheat, *space, curaddr); + m_cheat.cheatmap[active_cheat].first_value = m_cheat.cheatmap[active_cheat].previous_value; + m_cheat.cheatmap[active_cheat].offset = curaddr; + m_cheat.cheatmap[active_cheat].state = 1; + m_cheat.cheatmap[active_cheat].undo = 0; + active_cheat++; + } - // give a detailed init message to avoid searches being mistakingly carried out on the wrong CPU - m_console.printf("%u cheat initialized for CPU index %s ( aka %s )\n", active_cheat, m_cheat.cpu, space->device().tag()); + // give a detailed init message to avoid searches being mistakenly carried out on the wrong CPU + m_console.printf( + "%u cheat locations initialized for %s '%s' %s space\n", + active_cheat, + space->device().type().fullname(), + space->device().tag(), + space->name()); } @@ -3029,16 +3046,13 @@ void debugger_commands::execute_cheatnext(bool initial, const std::vector<std::s CHEAT_CHANGEDBY }; - if (m_cheat.cpu[0] == 0) + address_space *const space = m_cheat.space; + if (!space) { m_console.printf("Use cheatinit before cheatnext\n"); return; } - address_space *space; - if (!validate_device_space_parameter(m_cheat.cpu, AS_PROGRAM, space)) - return; - u64 comp_value = 0; if (params.size() > 1 && !validate_number_parameter(params[1], comp_value)) return; @@ -3186,30 +3200,36 @@ void debugger_commands::execute_cheatnext(bool initial, const std::vector<std::s void debugger_commands::execute_cheatlist(const std::vector<std::string> ¶ms) { - if (m_cheat.cpu[0] == 0) + address_space *const space = m_cheat.space; + if (!space) { m_console.printf("Use cheatinit before cheatlist\n"); return; } - address_space *space; - if (!validate_device_space_parameter(m_cheat.cpu, -1, space)) - return; - - device_t &cpu = space->device(); - FILE *f = nullptr; if (params.size() > 0) + { f = fopen(params[0].c_str(), "w"); + if (!f) + { + m_console.printf("Error opening file '%s'\n", params[0]); + return; + } + } + std::string tag(space->device().tag()); char spaceletter; switch (space->spacenum()) { - default: case AS_PROGRAM: spaceletter = 'p'; break; case AS_DATA: spaceletter = 'd'; break; case AS_IO: spaceletter = 'i'; break; - case AS_OPCODES: spaceletter = 'o'; break; + case AS_OPCODES: spaceletter = '3'; break; + default: + tag.append(1, ':'); + tag.append(space->name()); + spaceletter = 'p'; } char sizeletter; @@ -3240,13 +3260,13 @@ void debugger_commands::execute_cheatlist(const std::vector<std::string> ¶ms output.rdbuf()->clear(); stream_format( output, - " <cheat desc=\"Possibility %d : %0*X (%0*X)\">\n" + " <cheat desc=\"Possibility %d: %0*X (%0*X)\">\n" " <script state=\"run\">\n" " <action>%s.p%c%c@%0*X=%0*X</action>\n" " </script>\n" " </cheat>\n\n", active_cheat, space->logaddrchars(), address, m_cheat.width * 2, value, - cpu.tag(), spaceletter, sizeletter, space->logaddrchars(), address, m_cheat.width * 2, cheat_byte_swap(&m_cheat, m_cheat.cheatmap[cheatindex].first_value) & sizemask); + tag, spaceletter, sizeletter, space->logaddrchars(), address, m_cheat.width * 2, cheat_byte_swap(&m_cheat, m_cheat.cheatmap[cheatindex].first_value) & sizemask); auto const &text(output.vec()); fprintf(f, "%.*s", int(unsigned(text.size())), &text[0]); } @@ -3273,7 +3293,7 @@ void debugger_commands::execute_cheatundo(const std::vector<std::string> ¶ms { if (m_cheat.undo > 0) { - u32 undo_count = 0; + u64 undo_count = 0; for (u64 cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) { if (m_cheat.cheatmap[cheatindex].undo == m_cheat.undo) @@ -3288,7 +3308,9 @@ void debugger_commands::execute_cheatundo(const std::vector<std::string> ¶ms m_console.printf("%u cheat reactivated\n", undo_count); } else + { m_console.printf("Maximum undo reached\n"); + } } @@ -4013,7 +4035,7 @@ void debugger_commands::execute_memdump(const std::vector<std::string> ¶ms) sp.dump_maps(entries[0], entries[1]); for (int mode = 0; mode < 2; mode ++) { - fprintf(file, " device %s space %s %s:\n", memory.device().tag(), sp.name(), mode ? "write" : "read"); + fprintf(file, " %s '%s' space %s %s:\n", memory.device().type().fullname(), memory.device().tag(), sp.name(), mode ? "write" : "read"); for (memory_entry &entry : entries[mode]) { if (octal) diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h index 0f85e80e705..6c82ca143c1 100644 --- a/src/emu/debug/debugcmd.h +++ b/src/emu/debug/debugcmd.h @@ -67,20 +67,20 @@ private: // TODO [RH 31 May 2016]: Move this cheat stuff into its own class struct cheat_system { - char cpu[2]; + address_space *space; u8 width; - std::vector<cheat_map> cheatmap; - u8 undo; u8 signed_cheat; u8 swapped_cheat; + std::vector<cheat_map> cheatmap; + u8 undo; }; struct cheat_region_map { - u64 offset; - u64 endoffset; - const char *share; - u8 disabled; + u64 offset = 0U; + u64 endoffset = 0U; + const char *share = nullptr; + u8 disabled = 0U; }; device_t &get_device_search_base(std::string_view ¶m); diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp index c62b7299ea7..87bf8f0f18f 100644 --- a/src/emu/debug/debughlp.cpp +++ b/src/emu/debug/debughlp.cpp @@ -246,8 +246,8 @@ const help_item f_static_help_list[] = "Cheat Commands\n" "Type help <command> for further details on each command\n" "\n" - " cheatinit [<sign><width>[<swap>],[<address>,<length>[,<CPU>]]] -- initialize the cheat search to the selected memory area\n" - " cheatrange <address>,<length> -- add to the cheat search the selected memory area\n" + " cheatinit [[<sign>[<width>[<swap>]]],[<address>,<length>[,<space>]]] -- initialize the cheat search to the selected memory area\n" + " cheatrange <address>,<length> -- add selected memory area to the cheat search\n" " cheatnext <condition>[,<comparisonvalue>] -- continue cheat search comparing with the previous value\n" " cheatnextf <condition>[,<comparisonvalue>] -- continue cheat search comparing with the first value\n" " cheatlist [<filename>] -- show the list of cheat search matches or save them to <filename>\n" @@ -1611,157 +1611,184 @@ const help_item f_static_help_list[] = { "cheatinit", "\n" - " cheatinit [<sign><width>[<swap>],[<address>,<length>[,<CPU>]]]\n" + " cheatinit [[<sign>[<width>[<swap>]]],[<address>,<length>[,<space>]]]\n" "\n" - "The cheatinit command initializes the cheat search to the selected memory area.\n" - "If no parameter is specified the cheat search is initialized to all changeable memory of the main CPU.\n" - "<sign> can be s(signed) or u(unsigned)\n" - "<width> can be b(8 bit), w(16 bit), d(32 bit) or q(64 bit)\n" - "<swap> append s for swapped search\n" + "The cheatinit command initializes the cheat search to writable RAM areas in the specified " + "address space. The device may be specified as a tag or a debugger CPU number; if no " + "device is specified, the CPU currently visible in the debugger is assumed. If an address " + "space is not specified, the first address space exposed by the device is used.\n" + "\n" + "The first argument specifies the data format to search for:\n" + " <sign>: 's' (signed), 'u' (unsigned)\n" + " <width>: 'b' (8-bit), 'w' (16-bit), 'd' (32-bit), 'q' (64-bit)\n" + " <swap>: 's' (reverse byte order)\n" + "If the first argument is omitted or empty, the format from the previous cheat search is " + "used, or unsigned 8-bit for the first cheat search.\n" + "\n" + "The <address> specifies the address to start searching from, and the <length> specifies " + "how much memory to search. If specified, writable RAM in the range <address> through " + "<address>+<length>-1, inclusive, will be searched; otherwise, all writable RAM in the " + "address space will be searched.\n" "\n" "Examples:\n" "\n" "cheatinit ub,0x1000,0x10\n" - " Initialize the cheat search from 0x1000 to 0x1010 of the first CPU.\n" + " Initialize the cheat search for unsigned 8-bit values in addresses 0x1000-0x100f in the " + "program space of the visible CPU.\n" "\n" "cheatinit sw,0x2000,0x1000,1\n" - " Initialize the cheat search with width of 2 byte in signed mode from 0x2000 to 0x3000 of the second CPU.\n" + " Initialize the cheat search for signed 16-bit values in addresses 0x2000-0x3000 in the " + "program space of CPU #1.\n" "\n" "cheatinit uds,0x0000,0x1000\n" - " Initialize the cheat search with width of 4 byte swapped from 0x0000 to 0x1000.\n" + " Initialize the cheat search for unsigned 32-bit values with reverse byte order in " + "addresses 0x0000-0x0fff of the program space of the visible CPU.\n" }, { "cheatrange", "\n" " cheatrange <address>,<length>\n" "\n" - "The cheatrange command adds the selected memory area to the cheat search.\n" - "Before using cheatrange it is necessary to initialize the cheat search with cheatinit.\n" + "The cheatrange command adds writable RAM areas in the range <address> through " + "through <address>+<length>-1, inclusive, to the cheat search. Before using cheatrange, " + "the cheatinit command must be used to initialize the cheat search.\n" "\n" "Examples:\n" "\n" "cheatrange 0x1000,0x10\n" - " Add the bytes from 0x1000 to 0x1010 to the cheat search.\n" + " Add addresses 0x1000-0x100f to the cheat search.\n" }, { "cheatnext", "\n" " cheatnext <condition>[,<comparisonvalue>]\n" "\n" - "The cheatnext command will make comparisons with the previous search matches.\n" + "The cheatnext command makes comparisons with the previous search matches.\n" "Possible <condition>:\n" " all\n" - " no <comparisonvalue> needed.\n" - " use to update the previous value without changing the current matches.\n" - " equal [eq]\n" - " without <comparisonvalue> search for all bytes that are equal to the previous search.\n" - " with <comparisonvalue> search for all bytes that are equal to the <comparisonvalue>.\n" - " notequal [ne]\n" - " without <comparisonvalue> search for all bytes that are not equal to the previous search.\n" - " with <comparisonvalue> search for all bytes that are not equal to the <comparisonvalue>.\n" - " decrease [de, +]\n" - " without <comparisonvalue> search for all bytes that have decreased since the previous search.\n" - " with <comparisonvalue> search for all bytes that have decreased by the <comparisonvalue> since the previous search.\n" - " increase [in, -]\n" - " without <comparisonvalue> search for all bytes that have increased since the previous search.\n" - " with <comparisonvalue> search for all bytes that have increased by the <comparisonvalue> since the previous search.\n" - " decreaseorequal [deeq]\n" - " no <comparisonvalue> needed.\n" - " search for all bytes that have decreased or have same value since the previous search.\n" - " increaseorequal [ineq]\n" - " no <comparisonvalue> needed.\n" - " search for all bytes that have decreased or have same value since the previous search.\n" - " smallerof [lt]\n" - " without <comparisonvalue> this condition is invalid\n" - " with <comparisonvalue> search for all bytes that are smaller than the <comparisonvalue>.\n" - " greaterof [gt]\n" - " without <comparisonvalue> this condition is invalid\n" - " with <comparisonvalue> search for all bytes that are larger than the <comparisonvalue>.\n" - " changedby [ch, ~]\n" - " without <comparisonvalue> this condition is invalid\n" - " with <comparisonvalue> search for all bytes that have changed by the <comparisonvalue> since the previous search.\n" + " Use to update the last value without changing the current matches.\n" + " The <comparisonvalue> is not used.\n" + " equal (eq)\n" + " Without <comparisonvalue>**, search for values that are equal to the previous " + "search.\n" + " With <comparisonvalue>, search for values that are equal to the <comparisonvalue>.\n" + " notequal (ne)\n" + " Without <comparisonvalue>, search for values that are not equal to the previous " + "search.\n" + " With <comparisonvalue>, search for values that are not equal to the <comparisonvalue>.\n" + " decrease (de, -)\n" + " Without <comparisonvalue>, search for values that have decreased since the previous " + "search.\n" + " With <comparisonvalue>, search for values that have decreased by the <comparisonvalue> " + "since the previous search.\n" + " increase (in, +)\n" + " Without <comparisonvalue>, search for values that have increased since the previous " + "search.\n" + " With <comparisonvalue>, search for values that have increased by the <comparisonvalue> " + "since the previous search.\n" + " decreaseorequal (deeq)\n" + " Search for values that have decreased or are unchanged since the previous search.\n" + " The <comparisonvalue> is not used.\n" + " increaseorequal (ineq)\n" + " Search for values that have increased or are unchanged since the previous search.\n" + " The <comparisonvalue> is not used.\n" + " smallerof (lt, <)\n" + " Search for values that are less than the <comparisonvalue>.\n" + " The <comparisonvalue> is required.\n" + " greaterof (gt, >)\n" + " Search for values that are greater than the <comparisonvalue>.\n" + " The <comparisonvalue> is required.\n" + " changedby (ch, ~)\n" + " Search for values that have changed by the <comparisonvalue> since the previous " + "search.\n" + " The <comparisonvalue> is required.\n" "\n" "Examples:\n" "\n" "cheatnext increase\n" - " search for all bytes that have increased since the previous search.\n" + " Search for all values that have increased since the previous search.\n" "\n" - "cheatnext decrease, 1\n" - " search for all bytes that have decreased by 1 since the previous search.\n" + "cheatnext decrease,1\n" + " Search for all values that have decreased by 1 since the previous search.\n" }, { "cheatnextf", "\n" " cheatnextf <condition>[,<comparisonvalue>]\n" "\n" - "The cheatnextf command will make comparisons with the initial search.\n" + "The cheatnextf command makes comparisons with the initial search matches.\n" "Possible <condition>:\n" " all\n" - " no <comparisonvalue> needed.\n" - " use to update the previous value without changing the current matches.\n" - " equal [eq]\n" - " without <comparisonvalue> search for all bytes that are equal to the initial search.\n" - " with <comparisonvalue> search for all bytes that are equal to the <comparisonvalue>.\n" - " notequal [ne]\n" - " without <comparisonvalue> search for all bytes that are not equal to the initial search.\n" - " with <comparisonvalue> search for all bytes that are not equal to the <comparisonvalue>.\n" - " decrease [de, +]\n" - " without <comparisonvalue> search for all bytes that have decreased since the initial search.\n" - " with <comparisonvalue> search for all bytes that have decreased by the <comparisonvalue> since the initial search.\n" - " increase [in, -]\n" - " without <comparisonvalue> search for all bytes that have increased since the initial search.\n" - " with <comparisonvalue> search for all bytes that have increased by the <comparisonvalue> since the initial search.\n" - " decreaseorequal [deeq]\n" - " no <comparisonvalue> needed.\n" - " search for all bytes that have decreased or have same value since the initial search.\n" - " increaseorequal [ineq]\n" - " no <comparisonvalue> needed.\n" - " search for all bytes that have decreased or have same value since the initial search.\n" - " smallerof [lt]\n" - " without <comparisonvalue> this condition is invalid.\n" - " with <comparisonvalue> search for all bytes that are smaller than the <comparisonvalue>.\n" - " greaterof [gt]\n" - " without <comparisonvalue> this condition is invalid.\n" - " with <comparisonvalue> search for all bytes that are larger than the <comparisonvalue>.\n" - " changedby [ch, ~]\n" - " without <comparisonvalue> this condition is invalid\n" - " with <comparisonvalue> search for all bytes that have changed by the <comparisonvalue> since the initial search.\n" + " Use to update the last value without changing the current matches.\n" + " The <comparisonvalue> is not used.\n" + " equal (eq)\n" + " Without <comparisonvalue>**, search for values that are equal to the initial search.\n" + " With <comparisonvalue>, search for values that are equal to the <comparisonvalue>.\n" + " notequal (ne)\n" + " Without <comparisonvalue>, search for values that are not equal to the initial search.\n" + " With <comparisonvalue>, search for values that are not equal to the <comparisonvalue>.\n" + " decrease (de, -)\n" + " Without <comparisonvalue>, search for values that have decreased since the initial " + "search.\n" + " With <comparisonvalue>, search for values that have decreased by the <comparisonvalue> " + "since the initial search.\n" + " increase (in, +)\n" + " Without <comparisonvalue>, search for values that have increased since the initial " + "search.\n" + " With <comparisonvalue>, search for values that have increased by the <comparisonvalue> " + "since the initial search.\n" + " decreaseorequal (deeq)\n" + " Search for values that have decreased or are unchanged since the initial search.\n" + " The <comparisonvalue> is not used.\n" + " increaseorequal (ineq)\n" + " Search for values that have increased or are unchanged since the initial search.\n" + " The <comparisonvalue> is not used.\n" + " smallerof (lt, <)\n" + " Search for values that are less than the <comparisonvalue>.\n" + " The <comparisonvalue> is required.\n" + " greaterof (gt, >)\n" + " Search for values that are greater than the <comparisonvalue>.\n" + " The <comparisonvalue> is required.\n" + " changedby (ch, ~)\n" + " Search for values that have changed by the <comparisonvalue> since the initial search.\n" + " The <comparisonvalue> is required.\n" "\n" "Examples:\n" "\n" "cheatnextf increase\n" - " search for all bytes that have increased since the initial search.\n" + " Search for all values that have increased since the initial search.\n" "\n" - "cheatnextf decrease, 1\n" - " search for all bytes that have decreased by 1 since the initial search.\n" + "cheatnextf decrease,1\n" + " Search for all values that have decreased by 1 since the initial search.\n" }, { "cheatlist", "\n" " cheatlist [<filename>]\n" "\n" - "Without <filename> show the list of matches in the debug console.\n" - "With <filename> save the list of matches in basic xml format to <filename>.\n" + "Without <filename>, show the current cheat matches in the debugger console; with " + "<filename>, save the current cheat matches in basic XML format to the specified file.\n" "\n" "Examples:\n" "\n" "cheatlist\n" - " Show the current matches in the debug console.\n" - "cheatlist cheat.txt\n" - " Save the current matches to cheat.txt.\n" + " Show the current matches in the console.\n" + "cheatlist cheat.xml\n" + " Save the current matches to cheat.xml in XML format.\n" }, { "cheatundo", "\n" " cheatundo\n" "\n" - "Undo the results of the last search.\n" - "The undo command has no effect on the last value.\n" + "Undo filtering of cheat candidates by the most recent cheatnext or cheatnextf command.\n" + "Note that the previous values ARE NOT rolled back.\n" "\n" "Examples:\n" "\n" "cheatundo\n" - " Undo the last search (state only).\n" + " Restore cheat candidates filtered out by the most recent cheatnext or cheatnextf " + "command.\n" }, { "images", diff --git a/src/frontend/mame/ui/about.cpp b/src/frontend/mame/ui/about.cpp index bac2c3b4bdc..ac38d9c08b7 100644 --- a/src/frontend/mame/ui/about.cpp +++ b/src/frontend/mame/ui/about.cpp @@ -39,8 +39,19 @@ namespace { menu_about::menu_about(mame_ui_manager &mui, render_container &container) : menu(mui, container) - , m_title(util::string_format(_("%1$s %2$s"), emulator_info::get_appname(), bare_build_version)) - , m_footer(util::string_format(_("Revision: %1$s"), bare_vcs_revision)) + , m_header{ + util::string_format( +#ifdef MAME_DEBUG + _("%1$s %2$s (%3$s%4$sP%5$s, debug)"), +#else + _("%1$s %2$s (%3$s%4$sP%5$s)"), +#endif + emulator_info::get_appname(), + bare_build_version, + (sizeof(int) == sizeof(void *)) ? "I" : "", + (sizeof(long) == sizeof(void *)) ? "L" : (sizeof(long long) == sizeof(void *)) ? "LL" : "", + sizeof(void *) * 8), + util::string_format(_("Revision: %1$s"), bare_vcs_revision) } { } @@ -60,23 +71,12 @@ menu_about::~menu_about() void menu_about::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) { - std::string_view tempbuf[1]; - // draw the title - tempbuf[0] = m_title; draw_text_box( - std::begin(tempbuf), std::end(tempbuf), + std::begin(m_header), std::end(m_header), origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(), text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false, ui().colors().text_color(), UI_GREEN_COLOR, 1.0f); - - // draw the footer - tempbuf[0] = m_footer; - draw_text_box( - std::begin(tempbuf), std::end(tempbuf), - origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom, - text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false, - ui().colors().text_color(), ui().colors().background_color(), 1.0f); } @@ -221,8 +221,7 @@ void menu_about::draw(uint32_t flags) void menu_about::populate(float &customtop, float &custombottom) { // make space for the title and revision - customtop = ui().get_line_height() + 3.0f * ui().box_tb_border(); - custombottom = ui().get_line_height() + 3.0f * ui().box_tb_border(); + customtop = (ui().get_line_height() * m_header.size()) + (ui().box_tb_border() * 3.0f); } diff --git a/src/frontend/mame/ui/about.h b/src/frontend/mame/ui/about.h index b96c7ee2055..8ef133c43c6 100644 --- a/src/frontend/mame/ui/about.h +++ b/src/frontend/mame/ui/about.h @@ -16,6 +16,7 @@ #include <optional> #include <string> +#include <vector> namespace ui { @@ -34,8 +35,7 @@ private: virtual void populate(float &customtop, float &custombottom) override; virtual void handle() override; - std::string const m_title; - std::string const m_footer; + std::vector<std::string> const m_header; std::optional<text_layout> m_layout; }; diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp index 9046431d1f6..8c8f44224a8 100644 --- a/src/frontend/mame/ui/ui.cpp +++ b/src/frontend/mame/ui/ui.cpp @@ -2268,7 +2268,22 @@ void mame_ui_manager::menu_reset() std::string mame_ui_manager::get_general_input_setting(ioport_type type, int player, input_seq_type seqtype) { - return machine().input().seq_name(machine().ioport().type_seq(type, player, seqtype)); + input_seq seq(machine().ioport().type_seq(type, player, seqtype)); + input_code codes[16]; // TODO: remove magic number + unsigned len(0U); + for (unsigned i = 0U; std::size(codes) > i; ++i) + { + if (input_seq::not_code == seq[i]) + ++i; + else + codes[len++] = seq[i]; + if (input_seq::end_code == seq[i]) + break; + } + seq.reset(); + for (unsigned i = 0U; len > i; ++i) + seq += codes[i]; + return machine().input().seq_name(seq); } |