summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/config.cpp1
-rw-r--r--src/emu/crsshair.cpp1
-rw-r--r--src/emu/debug/debugcmd.cpp176
-rw-r--r--src/emu/debug/debugcmd.h5
-rw-r--r--src/emu/debug/debugcon.cpp246
-rw-r--r--src/emu/debug/debugcon.h18
-rw-r--r--src/emu/debug/debugcpu.cpp127
-rw-r--r--src/emu/debug/debugcpu.h21
-rw-r--r--src/emu/debug/debughlp.cpp71
-rw-r--r--src/emu/debug/debugvw.cpp4
-rw-r--r--src/emu/debug/dvmemory.cpp67
-rw-r--r--src/emu/debug/dvmemory.h1
-rw-r--r--src/emu/debug/express.cpp16
-rw-r--r--src/emu/debug/express.h9
-rw-r--r--src/emu/debug/points.cpp195
-rw-r--r--src/emu/debug/points.h6
-rw-r--r--src/emu/devcb.h66
-rw-r--r--src/emu/device.cpp36
-rw-r--r--src/emu/device.h23
-rw-r--r--src/emu/diexec.cpp12
-rw-r--r--src/emu/diexec.h2
-rw-r--r--src/emu/diimage.cpp243
-rw-r--r--src/emu/diimage.h99
-rw-r--r--src/emu/dinetwork.cpp15
-rw-r--r--src/emu/dinetwork.h7
-rw-r--r--src/emu/dinvram.h8
-rw-r--r--src/emu/dislot.cpp36
-rw-r--r--src/emu/dislot.h4
-rw-r--r--src/emu/drivers/empty.cpp2
-rw-r--r--src/emu/drivers/testcpu.cpp2
-rw-r--r--src/emu/emu.h13
-rw-r--r--src/emu/emucore.h42
-rw-r--r--src/emu/emufwd.h6
-rw-r--r--src/emu/emumem.cpp24
-rw-r--r--src/emu/emumem.h158
-rw-r--r--src/emu/emumem_aspace.cpp66
-rw-r--r--src/emu/emumem_hep.h12
-rw-r--r--src/emu/emumem_het.h8
-rw-r--r--src/emu/emumem_mview.cpp35
-rw-r--r--src/emu/emuopts.cpp4
-rw-r--r--src/emu/fileio.cpp31
-rw-r--r--src/emu/fileio.h2
-rw-r--r--src/emu/hashfile.cpp1
-rw-r--r--src/emu/http.cpp3
-rw-r--r--src/emu/http.h13
-rw-r--r--src/emu/image.cpp1
-rw-r--r--src/emu/image.h2
-rw-r--r--src/emu/inpttype.ipp888
-rw-r--r--src/emu/input.cpp4
-rw-r--r--src/emu/ioport.cpp290
-rw-r--r--src/emu/ioport.h128
-rw-r--r--src/emu/layout/nes_rob.lay63
-rw-r--r--src/emu/machine.cpp115
-rw-r--r--src/emu/machine.h8
-rw-r--r--src/emu/main.cpp10
-rw-r--r--src/emu/main.h4
-rw-r--r--src/emu/mconfig.cpp21
-rw-r--r--src/emu/mconfig.h2
-rw-r--r--src/emu/memarray.cpp5
-rw-r--r--src/emu/memarray.h2
-rw-r--r--src/emu/natkeyboard.cpp2
-rw-r--r--src/emu/natkeyboard.h2
-rw-r--r--src/emu/recording.cpp3
-rw-r--r--src/emu/render.cpp173
-rw-r--r--src/emu/render.h11
-rw-r--r--src/emu/rendertypes.h10
-rw-r--r--src/emu/rendfont.cpp123
-rw-r--r--src/emu/rendfont.h6
-rw-r--r--src/emu/rendlay.cpp84
-rw-r--r--src/emu/rendlay.h34
-rw-r--r--src/emu/rendutil.cpp176
-rw-r--r--src/emu/rendutil.h7
-rw-r--r--src/emu/romload.cpp18
-rw-r--r--src/emu/save.cpp9
-rw-r--r--src/emu/save.h6
-rw-r--r--src/emu/schedule.cpp35
-rw-r--r--src/emu/schedule.h25
-rw-r--r--src/emu/screen.cpp86
-rw-r--r--src/emu/screen.h20
-rw-r--r--src/emu/softlist_dev.cpp1
-rw-r--r--src/emu/sound.cpp4
-rw-r--r--src/emu/sound.h7
-rw-r--r--src/emu/validity.cpp22
-rw-r--r--src/emu/video.cpp17
-rw-r--r--src/emu/video.h4
-rw-r--r--src/emu/xtal.cpp10
86 files changed, 2390 insertions, 1985 deletions
diff --git a/src/emu/config.cpp b/src/emu/config.cpp
index 792da6f255d..c6b85bb6ae8 100644
--- a/src/emu/config.cpp
+++ b/src/emu/config.cpp
@@ -13,6 +13,7 @@
#include "drivenum.h"
#include "emuopts.h"
+#include "fileio.h"
#include "xmlfile.h"
diff --git a/src/emu/crsshair.cpp b/src/emu/crsshair.cpp
index 3c6a6b807f0..d90cc9a7f5e 100644
--- a/src/emu/crsshair.cpp
+++ b/src/emu/crsshair.cpp
@@ -13,6 +13,7 @@
#include "config.h"
#include "emuopts.h"
+#include "fileio.h"
#include "render.h"
#include "rendutil.h"
#include "screen.h"
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index 20431072cff..781ce93e9a5 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -21,8 +21,10 @@
#include "debugger.h"
#include "emuopts.h"
+#include "fileio.h"
#include "natkeyboard.h"
#include "render.h"
+#include "screen.h"
#include "softlist.h"
#include "corestr.h"
@@ -30,6 +32,7 @@
#include <algorithm>
#include <cctype>
#include <fstream>
+#include <sstream>
@@ -231,6 +234,9 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
m_console.register_command("gtime", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1));
m_console.register_command("gt", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1));
m_console.register_command("gp", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_privilege, this, _1));
+ m_console.register_command("gbt", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_branch, this, true, _1));
+ m_console.register_command("gbf", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_branch, this, false, _1));
+ m_console.register_command("gni", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_next_instruction, this, _1));
m_console.register_command("next", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_next, this, _1));
m_console.register_command("n", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_next, this, _1));
m_console.register_command("focus", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_focus, this, _1));
@@ -239,6 +245,7 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
m_console.register_command("suspend", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_suspend, this, _1));
m_console.register_command("resume", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_resume, this, _1));
m_console.register_command("cpulist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_cpulist, this, _1));
+ m_console.register_command("time", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_time, this, _1));
m_console.register_command("comadd", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1));
m_console.register_command("//", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1));
@@ -942,53 +949,51 @@ void debugger_commands::execute_print(const std::vector<std::string> &params)
mini_printf - safe printf to a buffer
-------------------------------------------------*/
-int debugger_commands::mini_printf(char *buffer, const char *format, int params, u64 *param)
+bool debugger_commands::mini_printf(std::ostream &stream, std::string_view format, int params, u64 *param)
{
- const char *f = format;
- char *p = buffer;
+ auto f = format.begin();
- /* parse the string looking for % signs */
- for (;;)
+ // parse the string looking for % signs
+ while (f != format.end())
{
char c = *f++;
- if (!c) break;
- /* escape sequences */
+ // escape sequences
if (c == '\\')
{
+ if (f == format.end()) break;
c = *f++;
- if (!c) break;
switch (c)
{
- case '\\': *p++ = c; break;
- case 'n': *p++ = '\n'; break;
+ case '\\': stream << c; break;
+ case 'n': stream << '\n'; break;
default: break;
}
continue;
}
- /* formatting */
+ // formatting
else if (c == '%')
{
int width = 0;
int zerofill = 0;
- /* parse out the width */
- for (;;)
+ // parse out the width
+ while (f != format.end() && *f >= '0' && *f <= '9')
{
c = *f++;
- if (!c || c < '0' || c > '9') break;
if (c == '0' && width == 0)
zerofill = 1;
width = width * 10 + (c - '0');
}
- if (!c) break;
+ if (f == format.end()) break;
- /* get the format */
+ // get the format
+ c = *f++;
switch (c)
{
case '%':
- *p++ = c;
+ stream << c;
break;
case 'X':
@@ -996,13 +1001,13 @@ int debugger_commands::mini_printf(char *buffer, const char *format, int params,
if (params == 0)
{
m_console.printf("Not enough parameters for format!\n");
- return 0;
+ return false;
}
if (u32(*param >> 32) != 0)
- p += sprintf(p, zerofill ? "%0*X" : "%*X", (width <= 8) ? 1 : width - 8, u32(*param >> 32));
+ util::stream_format(stream, zerofill ? "%0*X" : "%*X", (width <= 8) ? 1 : width - 8, u32(*param >> 32));
else if (width > 8)
- p += sprintf(p, zerofill ? "%0*X" : "%*X", width - 8, 0);
- p += sprintf(p, zerofill ? "%0*X" : "%*X", (width < 8) ? width : 8, u32(*param));
+ util::stream_format(stream, zerofill ? "%0*X" : "%*X", width - 8, 0);
+ util::stream_format(stream, zerofill ? "%0*X" : "%*X", (width < 8) ? width : 8, u32(*param));
param++;
params--;
break;
@@ -1012,23 +1017,23 @@ int debugger_commands::mini_printf(char *buffer, const char *format, int params,
if (params == 0)
{
m_console.printf("Not enough parameters for format!\n");
- return 0;
+ return false;
}
if (u32(*param >> 60) != 0)
{
- p += sprintf(p, zerofill ? "%0*o" : "%*o", (width <= 20) ? 1 : width - 20, u32(*param >> 60));
- p += sprintf(p, "%0*o", 10, u32(BIT(*param, 30, 30)));
+ util::stream_format(stream, zerofill ? "%0*o" : "%*o", (width <= 20) ? 1 : width - 20, u32(*param >> 60));
+ util::stream_format(stream, "%0*o", 10, u32(BIT(*param, 30, 30)));
}
else
{
if (width > 20)
- p += sprintf(p, zerofill ? "%0*o" : "%*o", width - 20, 0);
+ util::stream_format(stream, zerofill ? "%0*o" : "%*o", width - 20, 0);
if (u32(BIT(*param, 30, 30)) != 0)
- p += sprintf(p, zerofill ? "%0*o" : "%*o", (width <= 10) ? 1 : width - 10, u32(BIT(*param, 30, 30)));
+ util::stream_format(stream, zerofill ? "%0*o" : "%*o", (width <= 10) ? 1 : width - 10, u32(BIT(*param, 30, 30)));
else if (width > 10)
- p += sprintf(p, zerofill ? "%0*o" : "%*o", width - 10, 0);
+ util::stream_format(stream, zerofill ? "%0*o" : "%*o", width - 10, 0);
}
- p += sprintf(p, zerofill ? "%0*o" : "%*o", (width < 10) ? width : 10, u32(BIT(*param, 0, 30)));
+ util::stream_format(stream, zerofill ? "%0*o" : "%*o", (width < 10) ? width : 10, u32(BIT(*param, 0, 30)));
param++;
params--;
break;
@@ -1038,9 +1043,9 @@ int debugger_commands::mini_printf(char *buffer, const char *format, int params,
if (params == 0)
{
m_console.printf("Not enough parameters for format!\n");
- return 0;
+ return false;
}
- p += sprintf(p, zerofill ? "%0*d" : "%*d", width, u32(*param));
+ util::stream_format(stream, zerofill ? "%0*d" : "%*d", width, u32(*param));
param++;
params--;
break;
@@ -1049,9 +1054,9 @@ int debugger_commands::mini_printf(char *buffer, const char *format, int params,
if (params == 0)
{
m_console.printf("Not enough parameters for format!\n");
- return 0;
+ return false;
}
- p += sprintf(p, "%c", char(*param));
+ stream << char(*param);
param++;
params--;
break;
@@ -1059,14 +1064,12 @@ int debugger_commands::mini_printf(char *buffer, const char *format, int params,
}
}
- /* normal stuff */
+ // normal stuff
else
- *p++ = c;
+ stream << c;
}
- /* NULL-terminate and exit */
- *p = 0;
- return 1;
+ return true;
}
@@ -1114,9 +1117,9 @@ void debugger_commands::execute_printf(const std::vector<std::string> &params)
return;
/* then do a printf */
- char buffer[1024];
- if (mini_printf(buffer, params[0].c_str(), params.size() - 1, &values[1]))
- m_console.printf("%s\n", buffer);
+ std::ostringstream buffer;
+ if (mini_printf(buffer, params[0], params.size() - 1, &values[1]))
+ m_console.printf("%s\n", std::move(buffer).str());
}
@@ -1133,9 +1136,9 @@ void debugger_commands::execute_logerror(const std::vector<std::string> &params)
return;
/* then do a printf */
- char buffer[1024];
- if (mini_printf(buffer, params[0].c_str(), params.size() - 1, &values[1]))
- m_machine.logerror("%s", buffer);
+ std::ostringstream buffer;
+ if (mini_printf(buffer, params[0], params.size() - 1, &values[1]))
+ m_machine.logerror("%s", std::move(buffer).str());
}
@@ -1152,9 +1155,9 @@ void debugger_commands::execute_tracelog(const std::vector<std::string> &params)
return;
/* then do a printf */
- char buffer[1024];
- if (mini_printf(buffer, params[0].c_str(), params.size() - 1, &values[1]))
- m_console.get_visible_cpu()->debug()->trace_printf("%s", buffer);
+ std::ostringstream buffer;
+ if (mini_printf(buffer, params[0], params.size() - 1, &values[1]))
+ m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str().c_str());
}
@@ -1188,9 +1191,9 @@ void debugger_commands::execute_tracesym(const std::vector<std::string> &params)
}
// then do a printf
- char buffer[1024];
- if (mini_printf(buffer, format.str().c_str(), params.size(), values))
- m_console.get_visible_cpu()->debug()->trace_printf("%s", buffer);
+ std::ostringstream buffer;
+ if (mini_printf(buffer, format.str(), params.size(), values))
+ m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str().c_str());
}
@@ -1357,6 +1360,62 @@ void debugger_commands::execute_go_privilege(const std::vector<std::string> &par
m_console.get_visible_cpu()->debug()->go_privilege((condition.is_empty()) ? "1" : condition.original_string());
}
+
+/*-------------------------------------------------
+ execute_go_branch - execute gbt or gbf command
+-------------------------------------------------*/
+
+void debugger_commands::execute_go_branch(bool sense, const std::vector<std::string> &params)
+{
+ parsed_expression condition(m_console.visible_symtable());
+ if (params.size() > 0 && !debug_command_parameter_expression(params[0], condition))
+ return;
+
+ m_console.get_visible_cpu()->debug()->go_branch(sense, (condition.is_empty()) ? "1" : condition.original_string());
+}
+
+
+/*-------------------------------------------------
+ execute_go_next_instruction - execute gni command
+-------------------------------------------------*/
+
+void debugger_commands::execute_go_next_instruction(const std::vector<std::string> &params)
+{
+ u64 count = 1;
+ static constexpr u64 MAX_COUNT = 512;
+
+ // if we have a parameter, use it instead */
+ if (params.size() > 0 && !validate_number_parameter(params[0], count))
+ return;
+ if (count == 0)
+ return;
+ if (count > MAX_COUNT)
+ {
+ m_console.printf("Too many instructions (must be %d or fewer)\n", MAX_COUNT);
+ return;
+ }
+
+ device_state_interface *stateintf;
+ device_t *cpu = m_machine.debugger().console().get_visible_cpu();
+ if (!cpu->interface(stateintf))
+ {
+ m_console.printf("No state interface available for %s\n", cpu->name());
+ return;
+ }
+ u32 pc = stateintf->pcbase();
+
+ debug_disasm_buffer buffer(*cpu);
+ while (count-- != 0)
+ {
+ // disassemble the current instruction and get the length
+ u32 result = buffer.disassemble_info(pc);
+ pc = buffer.next_pc_wrap(pc, result & util::disasm_interface::LENGTHMASK);
+ }
+
+ cpu->debug()->go(pc);
+}
+
+
/*-------------------------------------------------
execute_next - execute the next command
-------------------------------------------------*/
@@ -1619,6 +1678,15 @@ void debugger_commands::execute_cpulist(const std::vector<std::string> &params)
}
}
+//-------------------------------------------------
+// execute_time - execute the time command
+//-------------------------------------------------
+
+void debugger_commands::execute_time(const std::vector<std::string> &params)
+{
+ m_console.printf("%s\n", m_machine.time().as_string());
+}
+
/*-------------------------------------------------
execute_comment - add a comment to a line
-------------------------------------------------*/
@@ -2190,8 +2258,7 @@ void debugger_commands::execute_rplist(const std::vector<std::string> &params)
void debugger_commands::execute_statesave(const std::vector<std::string> &params)
{
- const std::string &filename(params[0]);
- m_machine.immediate_save(filename.c_str());
+ m_machine.immediate_save(params[0]);
m_console.printf("State save attempted. Please refer to window message popup for results.\n");
}
@@ -2202,8 +2269,7 @@ void debugger_commands::execute_statesave(const std::vector<std::string> &params
void debugger_commands::execute_stateload(const std::vector<std::string> &params)
{
- const std::string &filename(params[0]);
- m_machine.immediate_load(filename.c_str());
+ m_machine.immediate_load(params[0]);
// clear all PC & memory tracks
for (device_t &device : device_enumerator(m_machine.root_device()))
@@ -3395,7 +3461,7 @@ void debugger_commands::execute_find(int spacenum, const std::vector<std::string
data_size[data_count++] |= 0x10;
// otherwise, validate as a number
- else if (!validate_number_parameter(params[i], data_to_find[data_count++]))
+ else if (!validate_number_parameter(pdata, data_to_find[data_count++]))
return;
}
}
@@ -4258,7 +4324,7 @@ void debugger_commands::execute_unmount(const std::vector<std::string> &params)
void debugger_commands::execute_input(const std::vector<std::string> &params)
{
- m_machine.natkeyboard().post_coded(params[0].c_str());
+ m_machine.natkeyboard().post_coded(params[0]);
}
diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h
index fd0bcea673a..f93276d5d8d 100644
--- a/src/emu/debug/debugcmd.h
+++ b/src/emu/debug/debugcmd.h
@@ -99,7 +99,7 @@ private:
u64 global_get(global_entry *global);
void global_set(global_entry *global, u64 value);
- int mini_printf(char *buffer, const char *format, int params, u64 *param);
+ bool mini_printf(std::ostream &stream, std::string_view format, int params, u64 *param);
template <typename T>
void execute_index_command(std::vector<std::string> const &params, T &&apply, char const *unused_message);
@@ -121,6 +121,8 @@ private:
void execute_go_exception(const std::vector<std::string> &params);
void execute_go_time(const std::vector<std::string> &params);
void execute_go_privilege(const std::vector<std::string> &params);
+ void execute_go_branch(bool sense, const std::vector<std::string> &params);
+ void execute_go_next_instruction(const std::vector<std::string> &params);
void execute_focus(const std::vector<std::string> &params);
void execute_ignore(const std::vector<std::string> &params);
void execute_observe(const std::vector<std::string> &params);
@@ -128,6 +130,7 @@ private:
void execute_resume(const std::vector<std::string> &params);
void execute_next(const std::vector<std::string> &params);
void execute_cpulist(const std::vector<std::string> &params);
+ void execute_time(const std::vector<std::string> &params);
void execute_comment_add(const std::vector<std::string> &params);
void execute_comment_del(const std::vector<std::string> &params);
void execute_comment_save(const std::vector<std::string> &params);
diff --git a/src/emu/debug/debugcon.cpp b/src/emu/debug/debugcon.cpp
index 32a4888c285..508c2377f54 100644
--- a/src/emu/debug/debugcon.cpp
+++ b/src/emu/debug/debugcon.cpp
@@ -16,6 +16,7 @@
#include "textbuf.h"
#include "debugger.h"
+#include "fileio.h"
#include "corestr.h"
@@ -86,10 +87,14 @@ debugger_console::debugger_console(running_machine &machine)
}
}
+debugger_console::~debugger_console()
+{
+}
-/*-------------------------------------------------
- exit - frees the console system
--------------------------------------------------*/
+
+//-------------------------------------------------
+// exit - frees the console system
+//-------------------------------------------------
void debugger_console::exit()
{
@@ -114,41 +119,39 @@ void debugger_console::exit()
inline bool debugger_console::debug_command::compare::operator()(const debug_command &a, const debug_command &b) const
{
- return core_stricmp(a.command.c_str(), b.command.c_str()) < 0;
+ return a.command < b.command;
}
inline bool debugger_console::debug_command::compare::operator()(const char *a, const debug_command &b) const
{
- return core_stricmp(a, b.command.c_str()) < 0;
+ return strcmp(a, b.command.c_str()) < 0;
}
inline bool debugger_console::debug_command::compare::operator()(const debug_command &a, const char *b) const
{
- return core_stricmp(a.command.c_str(), b) < 0;
+ return strcmp(a.command.c_str(), b) < 0;
}
-debugger_console::debug_command::debug_command(const char *_command, u32 _flags, int _minparams, int _maxparams, std::function<void (const std::vector<std::string> &)> &&_handler)
+debugger_console::debug_command::debug_command(std::string_view _command, u32 _flags, int _minparams, int _maxparams, std::function<void (const std::vector<std::string> &)> &&_handler)
: command(_command), params(nullptr), help(nullptr), handler(std::move(_handler)), flags(_flags), minparams(_minparams), maxparams(_maxparams)
{
}
-/*------------------------------------------------------------
- execute_help_custom - execute the helpcustom command
-------------------------------------------------------------*/
+//------------------------------------------------------------
+// execute_help_custom - execute the helpcustom command
+//------------------------------------------------------------
void debugger_console::execute_help_custom(const std::vector<std::string> &params)
{
- char buf[64];
for (const debug_command &cmd : m_commandlist)
{
if (cmd.flags & CMDFLAG_CUSTOM_HELP)
{
- snprintf(buf, 63, "%s help", cmd.command.c_str());
- buf[63] = 0;
- char *temp_params[1] = { buf };
- internal_execute_command(true, 1, &temp_params[0]);
+ std::string buf = cmd.command + " help";
+ std::vector<std::string_view> temp_params = { buf };
+ internal_execute_command(true, temp_params);
}
}
}
@@ -202,159 +205,145 @@ symbol_table &debugger_console::visible_symtable()
-/*-------------------------------------------------
- trim_parameter - executes a
- command
--------------------------------------------------*/
+//-------------------------------------------------
+// trim_parameter - trim spaces and quotes around
+// a command parameter
+//-------------------------------------------------
-void debugger_console::trim_parameter(char **paramptr, bool keep_quotes)
+std::string_view debugger_console::trim_parameter(std::string_view param, bool keep_quotes)
{
- char *param = *paramptr;
- size_t len = strlen(param);
+ std::string_view::size_type len = param.length();
bool repeat;
- /* loop until all adornments are gone */
+ // loop until all adornments are gone
do
{
repeat = false;
- /* check for begin/end quotes */
+ // check for begin/end quotes
if (len >= 2 && param[0] == '"' && param[len - 1] == '"')
{
if (!keep_quotes)
{
- param[len - 1] = 0;
- param++;
+ param = param.substr(1, len - 2);
len -= 2;
}
}
- /* check for start/end braces */
+ // check for start/end braces
else if (len >= 2 && param[0] == '{' && param[len - 1] == '}')
{
- param[len - 1] = 0;
- param++;
+ param = param.substr(1, len - 2);
len -= 2;
repeat = true;
}
- /* check for leading spaces */
+ // check for leading spaces
else if (len >= 1 && param[0] == ' ')
{
- param++;
+ param.remove_prefix(1);
len--;
repeat = true;
}
- /* check for trailing spaces */
+ // check for trailing spaces
else if (len >= 1 && param[len - 1] == ' ')
{
- param[len - 1] = 0;
+ param.remove_suffix(1);
len--;
repeat = true;
}
} while (repeat);
- *paramptr = param;
+ return param;
}
-/*-------------------------------------------------
- internal_execute_command - executes a
- command
--------------------------------------------------*/
+//-------------------------------------------------
+// internal_execute_command - executes a
+// command
+//-------------------------------------------------
-CMDERR debugger_console::internal_execute_command(bool execute, int params, char **param)
+CMDERR debugger_console::internal_execute_command(bool execute, std::vector<std::string_view> &params)
{
// no params is an error
- if (params == 0)
+ if (params.empty())
return CMDERR::none();
// the first parameter has the command and the real first parameter; separate them
- char *p, *command;
- for (p = param[0]; *p && isspace(u8(*p)); p++) { }
- for (command = p; *p && !isspace(u8(*p)); p++) { }
- if (*p != 0)
- {
- *p++ = 0;
- for ( ; *p && isspace(u8(*p)); p++) { }
- if (*p != 0)
- param[0] = p;
- else
- params = 0;
- }
+ std::string_view command_param = params[0];
+ std::string_view::size_type pos = 0;
+ while (pos < command_param.length() && !isspace(u8(command_param[pos])))
+ pos++;
+ const std::string command(strmakelower(command_param.substr(0, pos)));
+ while (pos < command_param.length() && isspace(u8(command_param[pos])))
+ pos++;
+ if (pos == command_param.length() && params.size() == 1)
+ params.clear();
else
- {
- params = 0;
- param[0] = nullptr;
- }
+ params[0].remove_prefix(pos);
// search the command list
- size_t const len = strlen(command);
- auto const found = m_commandlist.lower_bound(command);
+ auto const found = m_commandlist.lower_bound(command.c_str());
// error if not found
- if ((m_commandlist.end() == found) || core_strnicmp(command, found->command.c_str(), len))
+ if (m_commandlist.end() == found || std::string_view(command) != std::string_view(found->command).substr(0, command.length()))
return CMDERR::unknown_command(0);
- if (found->command.length() > len)
+ if (found->command.length() > command.length())
{
auto const next = std::next(found);
- if ((m_commandlist.end() != next) && !core_strnicmp(command, next->command.c_str(), len))
+ if (m_commandlist.end() != next && std::string_view(command) == std::string_view(next->command).substr(0, command.length()))
return CMDERR::ambiguous_command(0);
}
- // NUL-terminate and trim space around all the parameters
- for (int i = 1; i < params; i++)
- *param[i]++ = 0;
-
// now go back and trim quotes and braces and any spaces they reveal
- for (int i = 0; i < params; i++)
- trim_parameter(&param[i], found->flags & CMDFLAG_KEEP_QUOTES);
+ for (std::string_view &param : params)
+ param = trim_parameter(param, found->flags & CMDFLAG_KEEP_QUOTES);
// see if we have the right number of parameters
- if (params < found->minparams)
+ if (params.size() < found->minparams)
return CMDERR::not_enough_params(0);
- if (params > found->maxparams)
+ if (params.size() > found->maxparams)
return CMDERR::too_many_params(0);
// execute the handler
if (execute)
{
- std::vector<std::string> params_vec(param, param + params);
+ std::vector<std::string> params_vec(params.begin(), params.end());
found->handler(params_vec);
}
return CMDERR::none();
}
-/*-------------------------------------------------
- internal_parse_command - parses a command
- and either executes or just validates it
--------------------------------------------------*/
+//-------------------------------------------------
+// internal_parse_command - parses a command
+// and either executes or just validates it
+//-------------------------------------------------
-CMDERR debugger_console::internal_parse_command(const std::string &original_command, bool execute)
+CMDERR debugger_console::internal_parse_command(std::string_view command, bool execute)
{
- char command[MAX_COMMAND_LENGTH], parens[MAX_COMMAND_LENGTH];
- char *params[MAX_COMMAND_PARAMS] = { nullptr };
- char *command_start;
- char *p, c = 0;
+ std::string_view::size_type pos = 0;
+ std::string_view::size_type len = command.length();
- /* make a copy of the command */
- strcpy(command, original_command.c_str());
-
- /* loop over all semicolon-separated stuff */
- for (p = command; *p != 0; )
+ while (pos < len)
{
- int paramcount = 0, parendex = 0;
+ std::string parens;
+ std::vector<std::string_view> params;
bool foundend = false, instring = false, isexpr = false;
- /* find a semicolon or the end */
- for (params[paramcount++] = p; !foundend; p++)
+ // skip leading spaces
+ while (pos < len && isspace(u8(command[pos])))
+ pos++;
+ std::string_view::size_type startpos = pos;
+
+ // find a semicolon or the end
+ for (params.push_back(command.substr(pos)); !foundend && pos < len; pos++)
{
- c = *p;
+ char c = command[pos];
if (instring)
{
- if (c == '"' && p[-1] != '\\')
+ if (c == '"' && command[pos - 1] != '\\')
instring = false;
}
else
@@ -364,47 +353,42 @@ CMDERR debugger_console::internal_parse_command(const std::string &original_comm
case '"': instring = true; break;
case '(':
case '[':
- case '{': parens[parendex++] = c; break;
- case ')': if (parendex == 0 || parens[--parendex] != '(') return CMDERR::unbalanced_parens(p - command); break;
- case ']': if (parendex == 0 || parens[--parendex] != '[') return CMDERR::unbalanced_parens(p - command); break;
- case '}': if (parendex == 0 || parens[--parendex] != '{') return CMDERR::unbalanced_parens(p - command); break;
- case ',': if (parendex == 0) params[paramcount++] = p; break;
- case ';': if (parendex == 0) foundend = true; break;
- case '-': if (parendex == 0 && paramcount == 1 && p[1] == '-') isexpr = true; *p = c; break;
- case '+': if (parendex == 0 && paramcount == 1 && p[1] == '+') isexpr = true; *p = c; break;
- case '=': if (parendex == 0 && paramcount == 1) isexpr = true; *p = c; break;
- case 0: foundend = true; break;
- default: *p = c; break;
+ case '{': parens.push_back(c); break;
+ case ')': if (parens.empty() || parens.back() != '(') return CMDERR::unbalanced_parens(pos); parens.pop_back(); break;
+ case ']': if (parens.empty() || parens.back() != '[') return CMDERR::unbalanced_parens(pos); parens.pop_back(); break;
+ case '}': if (parens.empty() || parens.back() != '{') return CMDERR::unbalanced_parens(pos); parens.pop_back(); break;
+ case ',': if (parens.empty()) { params.back().remove_suffix(len - pos); params.push_back(command.substr(pos + 1)); } break;
+ case ';': if (parens.empty()) { params.back().remove_suffix(len - pos); foundend = true; } break;
+ case '-': if (parens.empty() && params.size() == 1 && pos > 0 && command[pos - 1] == '-') isexpr = true; break;
+ case '+': if (parens.empty() && params.size() == 1 && pos > 0 && command[pos - 1] == '+') isexpr = true; break;
+ case '=': if (parens.empty() && params.size() == 1) isexpr = true; break;
+ default: break;
}
}
}
- /* check for unbalanced parentheses or quotes */
+ // check for unbalanced parentheses or quotes
if (instring)
- return CMDERR::unbalanced_quotes(p - command);
- if (parendex != 0)
- return CMDERR::unbalanced_parens(p - command);
+ return CMDERR::unbalanced_quotes(pos);
+ if (!parens.empty())
+ return CMDERR::unbalanced_parens(pos);
- /* NULL-terminate if we ended in a semicolon */
- p--;
- if (c == ';') *p++ = 0;
+ // process the command
+ std::string_view command_or_expr = params[0];
- /* process the command */
- command_start = params[0];
-
- /* allow for "do" commands */
- if (tolower(u8(command_start[0])) == 'd' && tolower(u8(command_start[1])) == 'o' && isspace(u8(command_start[2])))
+ // allow for "do" commands
+ if (command_or_expr.length() > 3 && tolower(u8(command_or_expr[0])) == 'd' && tolower(u8(command_or_expr[1])) == 'o' && isspace(u8(command_or_expr[2])))
{
isexpr = true;
- command_start += 3;
+ command_or_expr.remove_prefix(3);
}
- /* if it smells like an assignment expression, treat it as such */
- if (isexpr && paramcount == 1)
+ // if it smells like an assignment expression, treat it as such
+ if (isexpr && params.size() == 1)
{
try
{
- parsed_expression(visible_symtable(), command_start).execute();
+ parsed_expression(visible_symtable(), command_or_expr).execute();
}
catch (expression_error &err)
{
@@ -413,29 +397,29 @@ CMDERR debugger_console::internal_parse_command(const std::string &original_comm
}
else
{
- const CMDERR result = internal_execute_command(execute, paramcount, &params[0]);
+ const CMDERR result = internal_execute_command(execute, params);
if (result.error_class() != CMDERR::NONE)
- return CMDERR(result.error_class(), command_start - command);
+ return CMDERR(result.error_class(), startpos);
}
}
return CMDERR::none();
}
-/*-------------------------------------------------
- execute_command - execute a command string
--------------------------------------------------*/
+//-------------------------------------------------
+// execute_command - execute a command string
+//-------------------------------------------------
-CMDERR debugger_console::execute_command(const std::string &command, bool echo)
+CMDERR debugger_console::execute_command(std::string_view command, bool echo)
{
- /* echo if requested */
+ // echo if requested
if (echo)
printf(">%s\n", command);
- /* parse and execute */
+ // parse and execute
const CMDERR result = internal_parse_command(command, true);
- /* display errors */
+ // display errors
if (result.error_class() != CMDERR::NONE)
{
if (!echo)
@@ -444,7 +428,7 @@ CMDERR debugger_console::execute_command(const std::string &command, bool echo)
printf("%s\n", cmderr_to_string(result));
}
- /* update all views */
+ // update all views
if (echo)
{
m_machine.debug_view().update_all();
@@ -454,11 +438,11 @@ CMDERR debugger_console::execute_command(const std::string &command, bool echo)
}
-/*-------------------------------------------------
- validate_command - validate a command string
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_command - validate a command string
+//-------------------------------------------------
-CMDERR debugger_console::validate_command(const char *command)
+CMDERR debugger_console::validate_command(std::string_view command)
{
return internal_parse_command(command, false);
}
@@ -468,7 +452,7 @@ CMDERR debugger_console::validate_command(const char *command)
register_command - register a command handler
-------------------------------------------------*/
-void debugger_console::register_command(const char *command, u32 flags, int minparams, int maxparams, std::function<void (const std::vector<std::string> &)> &&handler)
+void debugger_console::register_command(std::string_view command, u32 flags, int minparams, int maxparams, std::function<void (const std::vector<std::string> &)> &&handler)
{
if (m_machine.phase() != machine_phase::INIT)
throw emu_fatalerror("Can only call debugger_console::register_command() at init time!");
diff --git a/src/emu/debug/debugcon.h b/src/emu/debug/debugcon.h
index 5271b0e5ae5..974a43e656a 100644
--- a/src/emu/debug/debugcon.h
+++ b/src/emu/debug/debugcon.h
@@ -23,8 +23,7 @@
CONSTANTS
***************************************************************************/
-#define MAX_COMMAND_LENGTH 4096
-#define MAX_COMMAND_PARAMS 128
+constexpr int MAX_COMMAND_PARAMS = 128;
// flags for command parsing
constexpr u32 CMDFLAG_NONE = 0x0000;
@@ -79,11 +78,12 @@ class debugger_console
{
public:
debugger_console(running_machine &machine);
+ ~debugger_console();
// command handling
- CMDERR execute_command(const std::string &command, bool echo);
- CMDERR validate_command(const char *command);
- void register_command(const char *command, u32 flags, int minparams, int maxparams, std::function<void (const std::vector<std::string> &)> &&handler);
+ CMDERR execute_command(std::string_view command, bool echo);
+ CMDERR validate_command(std::string_view command);
+ void register_command(std::string_view command, u32 flags, int minparams, int maxparams, std::function<void (const std::vector<std::string> &)> &&handler);
void source_script(const char *file);
void process_source_file();
@@ -122,16 +122,16 @@ private:
void execute_help_custom(const std::vector<std::string> &params);
void execute_condump(const std::vector<std::string>& params);
- void trim_parameter(char **paramptr, bool keep_quotes);
- CMDERR internal_execute_command(bool execute, int params, char **param);
- CMDERR internal_parse_command(const std::string &original_command, bool execute);
+ [[nodiscard]] static std::string_view trim_parameter(std::string_view param, bool keep_quotes);
+ CMDERR internal_execute_command(bool execute, std::vector<std::string_view> &params);
+ CMDERR internal_parse_command(std::string_view command, bool execute);
void print_core(std::string_view text); // core text output
void print_core_wrap(std::string_view text, int wrapcol); // core text output
struct debug_command
{
- debug_command(const char *_command, u32 _flags, int _minparams, int _maxparams, std::function<void (const std::vector<std::string> &)> &&_handler);
+ debug_command(std::string_view _command, u32 _flags, int _minparams, int _maxparams, std::function<void (const std::vector<std::string> &)> &&_handler);
struct compare
{
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index 403d0b104ee..820d9e72688 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -19,6 +19,7 @@
#include "debugger.h"
#include "emuopts.h"
+#include "fileio.h"
#include "screen.h"
#include "uiinput.h"
@@ -426,6 +427,7 @@ device_debug::device_debug(device_t &device)
, m_instrhook(nullptr)
, m_stepaddr(0)
, m_stepsleft(0)
+ , m_delay_steps(0)
, m_stopaddr(0)
, m_stoptime(attotime::zero)
, m_stopirq(0)
@@ -458,14 +460,14 @@ device_debug::device_debug(device_t &device)
// set up notifiers and clear the passthrough handlers
if (m_memory) {
int count = m_memory->max_space_count();
- m_phw.resize(count, nullptr);
+ m_phw.resize(count);
for (int i=0; i != count; i++)
if (m_memory->has_space(i)) {
address_space &space = m_memory->space(i);
- m_notifiers.push_back(space.add_change_notifier([this, &space](read_or_write mode) { reinstall(space, mode); }));
+ m_notifiers.emplace_back(space.add_change_notifier([this, &space] (read_or_write mode) { reinstall(space, mode); }));
}
else
- m_notifiers.push_back(-1);
+ m_notifiers.emplace_back();
}
// set up state-related stuff
@@ -562,15 +564,14 @@ void device_debug::reinstall(address_space &space, read_or_write mode)
int id = space.spacenum();
if (u32(mode) & u32(read_or_write::WRITE))
{
- if (m_phw[id])
- m_phw[id]->remove();
+ m_phw[id].remove();
if (m_track_mem)
switch (space.data_width())
{
- case 8: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space](offs_t address, u8 &data, u8 ) { write_tracking(space, address, data); }, m_phw[id]); break;
- case 16: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space](offs_t address, u16 &data, u16) { write_tracking(space, address, data); }, m_phw[id]); break;
- case 32: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space](offs_t address, u32 &data, u32) { write_tracking(space, address, data); }, m_phw[id]); break;
- case 64: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space](offs_t address, u64 &data, u64) { write_tracking(space, address, data); }, m_phw[id]); break;
+ case 8: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space] (offs_t address, u8 &data, u8 ) { write_tracking(space, address, data); }, &m_phw[id]); break;
+ case 16: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space] (offs_t address, u16 &data, u16) { write_tracking(space, address, data); }, &m_phw[id]); break;
+ case 32: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space] (offs_t address, u32 &data, u32) { write_tracking(space, address, data); }, &m_phw[id]); break;
+ case 64: m_phw[id] = space.install_write_tap(0, space.addrmask(), "track_mem", [this, &space] (offs_t address, u64 &data, u64) { write_tracking(space, address, data); }, &m_phw[id]); break;
}
}
}
@@ -688,11 +689,11 @@ void device_debug::privilege_hook()
if ((m_flags & DEBUG_FLAG_STOP_PRIVILEGE) != 0)
{
bool matched = true;
- if (m_privilege_condition && !m_privilege_condition->is_empty())
+ if (m_stop_condition && !m_stop_condition->is_empty())
{
try
{
- matched = m_privilege_condition->execute();
+ matched = m_stop_condition->execute();
}
catch (expression_error &)
{
@@ -750,19 +751,53 @@ void device_debug::instruction_hook(offs_t curpc)
// handle single stepping
if (!debugcpu.is_stopped() && (m_flags & DEBUG_FLAG_STEPPING_ANY) != 0)
{
+ bool do_step = true;
+ if ((m_flags & (DEBUG_FLAG_CALL_IN_PROGRESS | DEBUG_FLAG_TEST_IN_PROGRESS)) != 0)
+ {
+ if (curpc == m_stepaddr)
+ {
+ if ((~m_flags & (DEBUG_FLAG_TEST_IN_PROGRESS | DEBUG_FLAG_STEPPING_BRANCH_FALSE)) == 0)
+ {
+ debugcpu.set_execution_stopped();
+ do_step = false;
+ }
+
+ // reset the breakpoint
+ m_flags &= ~(DEBUG_FLAG_CALL_IN_PROGRESS | DEBUG_FLAG_TEST_IN_PROGRESS);
+ m_delay_steps = 0;
+ }
+ else if (m_delay_steps != 0)
+ {
+ m_delay_steps--;
+ if (m_delay_steps == 0)
+ {
+ // branch taken or subroutine entered (TODO: interrupt acknowledgment or interleaved multithreading can falsely trigger this)
+ if ((m_flags & DEBUG_FLAG_TEST_IN_PROGRESS) != 0 && (m_flags & (DEBUG_FLAG_STEPPING_OUT | DEBUG_FLAG_STEPPING_BRANCH_TRUE)) != 0)
+ {
+ debugcpu.set_execution_stopped();
+ do_step = false;
+ }
+ if ((m_flags & DEBUG_FLAG_CALL_IN_PROGRESS) != 0)
+ do_step = false;
+ m_flags &= ~DEBUG_FLAG_TEST_IN_PROGRESS;
+ }
+ }
+ else
+ do_step = false;
+ }
+
// is this an actual step?
- if (m_stepaddr == ~0 || curpc == m_stepaddr)
+ if (do_step)
{
- // decrement the count and reset the breakpoint
+ // decrement the count
m_stepsleft--;
- m_stepaddr = ~0;
// if we hit 0, stop
if (m_stepsleft == 0)
debugcpu.set_execution_stopped();
// update every 100 steps until we are within 200 of the end
- else if ((m_flags & DEBUG_FLAG_STEPPING_OUT) == 0 && (m_stepsleft < 200 || m_stepsleft % 100 == 0))
+ else if ((m_flags & (DEBUG_FLAG_STEPPING_OUT | DEBUG_FLAG_STEPPING_BRANCH_TRUE | DEBUG_FLAG_STEPPING_BRANCH_FALSE)) == 0 && (m_stepsleft < 200 || m_stepsleft % 100 == 0))
{
machine.debug_view().update_all();
machine.debug_view().flush_osd_updates();
@@ -849,7 +884,7 @@ void device_debug::instruction_hook(offs_t curpc)
}
// handle step out/over on the instruction we are about to execute
- if ((m_flags & (DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT)) != 0 && m_stepaddr == ~0)
+ if ((m_flags & (DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT | DEBUG_FLAG_STEPPING_BRANCH)) != 0 && (m_flags & (DEBUG_FLAG_CALL_IN_PROGRESS | DEBUG_FLAG_TEST_IN_PROGRESS)) == 0)
prepare_for_step_overout(m_state->pcbase());
// no longer in debugger code
@@ -928,7 +963,7 @@ void device_debug::single_step(int numsteps)
m_device.machine().rewind_capture();
m_stepsleft = numsteps;
- m_stepaddr = ~0;
+ m_delay_steps = 0;
m_flags |= DEBUG_FLAG_STEPPING;
m_device.machine().debugger().cpu().set_execution_running();
}
@@ -945,7 +980,7 @@ void device_debug::single_step_over(int numsteps)
m_device.machine().rewind_capture();
m_stepsleft = numsteps;
- m_stepaddr = ~0;
+ m_delay_steps = 0;
m_flags |= DEBUG_FLAG_STEPPING_OVER;
m_device.machine().debugger().cpu().set_execution_running();
}
@@ -961,8 +996,9 @@ void device_debug::single_step_out()
assert(m_exec != nullptr);
m_device.machine().rewind_capture();
+ m_stop_condition.reset();
m_stepsleft = 100;
- m_stepaddr = ~0;
+ m_delay_steps = 0;
m_flags |= DEBUG_FLAG_STEPPING_OUT;
m_device.machine().debugger().cpu().set_execution_running();
}
@@ -1060,13 +1096,30 @@ void device_debug::go_privilege(const char *condition)
{
assert(m_exec != nullptr);
m_device.machine().rewind_invalidate();
- m_privilege_condition = std::make_unique<parsed_expression>(*m_symtable, condition);
+ m_stop_condition = std::make_unique<parsed_expression>(*m_symtable, condition);
m_flags |= DEBUG_FLAG_STOP_PRIVILEGE;
m_device.machine().debugger().cpu().set_execution_running();
}
//-------------------------------------------------
+// go_branch - execute until branch taken or
+// not taken
+//-------------------------------------------------
+
+void device_debug::go_branch(bool sense, const char *condition)
+{
+ assert(m_exec != nullptr);
+ m_device.machine().rewind_invalidate();
+ m_stop_condition = std::make_unique<parsed_expression>(*m_symtable, condition);
+ m_stepsleft = 100;
+ m_delay_steps = 0;
+ m_flags |= sense ? DEBUG_FLAG_STEPPING_BRANCH_TRUE : DEBUG_FLAG_STEPPING_BRANCH_FALSE;
+ m_device.machine().debugger().cpu().set_execution_running();
+}
+
+
+//-------------------------------------------------
// halt_on_next_instruction_impl - halt in the
// debugger on the next instruction, internal
// implementation which is necessary solely due
@@ -1385,7 +1438,6 @@ void device_debug::set_track_pc(bool value)
// track_pc_visited - returns a boolean stating
// if this PC has been visited or not. CRC32 is
// done in this function on currently active CPU.
-// TODO: Take a CPU context as input
//-------------------------------------------------
bool device_debug::track_pc_visited(offs_t pc) const
@@ -1399,7 +1451,6 @@ bool device_debug::track_pc_visited(offs_t pc) const
//-------------------------------------------------
// set_track_pc_visited - set this pc as visited.
-// TODO: Take a CPU context as input
//-------------------------------------------------
void device_debug::set_track_pc_visited(offs_t pc)
@@ -1625,12 +1676,32 @@ void device_debug::prepare_for_step_overout(offs_t pc)
// disassemble the current instruction and get the flags
u32 dasmresult = buffer.disassemble_info(pc);
+ if ((dasmresult & util::disasm_interface::SUPPORTED) == 0)
+ return;
+
+ bool step_out = (m_flags & DEBUG_FLAG_STEPPING_OUT) != 0 && (dasmresult & util::disasm_interface::STEP_OUT) != 0;
+ bool test_cond = (dasmresult & util::disasm_interface::STEP_COND) != 0 && ((m_flags & (DEBUG_FLAG_STEPPING_BRANCH_TRUE | DEBUG_FLAG_STEPPING_BRANCH_FALSE)) != 0 || step_out);
+ if (test_cond && m_stop_condition && !m_stop_condition->is_empty())
+ {
+ try
+ {
+ test_cond = m_stop_condition->execute();
+ }
+ catch (expression_error &)
+ {
+ test_cond = false;
+ }
+ }
// if flags are supported and it's a call-style opcode, set a temp breakpoint after that instruction
- if ((dasmresult & util::disasm_interface::SUPPORTED) != 0 && (dasmresult & util::disasm_interface::STEP_OVER) != 0)
+ // (TODO: this completely fails for subroutines that consume inline operands or use alternate returns)
+ if ((dasmresult & util::disasm_interface::STEP_OVER) != 0 || test_cond)
{
int extraskip = (dasmresult & util::disasm_interface::OVERINSTMASK) >> util::disasm_interface::OVERINSTSHIFT;
pc = buffer.next_pc_wrap(pc, dasmresult & util::disasm_interface::LENGTHMASK);
+ m_delay_steps = extraskip + 1;
+ if (m_stepsleft < m_delay_steps)
+ m_stepsleft = m_delay_steps;
// if we need to skip additional instructions, advance as requested
while (extraskip-- > 0) {
@@ -1638,13 +1709,17 @@ void device_debug::prepare_for_step_overout(offs_t pc)
pc = buffer.next_pc_wrap(pc, result & util::disasm_interface::LENGTHMASK);
}
m_stepaddr = pc;
+ if ((dasmresult & util::disasm_interface::STEP_OVER) != 0)
+ m_flags |= DEBUG_FLAG_CALL_IN_PROGRESS;
+ if (test_cond)
+ m_flags |= DEBUG_FLAG_TEST_IN_PROGRESS;
}
// if we're stepping out and this isn't a step out instruction, reset the steps until stop to a high number
- // (TODO: this doesn't work with conditional return instructions)
- if ((m_flags & DEBUG_FLAG_STEPPING_OUT) != 0)
+ if ((m_flags & (DEBUG_FLAG_STEPPING_OUT | DEBUG_FLAG_STEPPING_BRANCH_TRUE | DEBUG_FLAG_STEPPING_BRANCH_FALSE)) != 0)
{
- if ((dasmresult & util::disasm_interface::SUPPORTED) != 0 && (dasmresult & util::disasm_interface::STEP_OUT) == 0)
+ // make sure to also reset the number of steps for conditionals that may be single-instruction loops
+ if (test_cond || !step_out)
m_stepsleft = 100;
else
{
diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h
index 9e3d23d8d7f..d9fc3f64eae 100644
--- a/src/emu/debug/debugcpu.h
+++ b/src/emu/debug/debugcpu.h
@@ -82,6 +82,7 @@ public:
void go_exception(int exception, const char *condition);
void go_milliseconds(u64 milliseconds);
void go_privilege(const char *condition);
+ void go_branch(bool sense, const char *condition);
void go_next_device();
template <typename Format, typename... Params>
@@ -184,15 +185,16 @@ private:
debug_instruction_hook_func m_instrhook; // per-instruction callback hook
// stepping information
- offs_t m_stepaddr; // step target address for DEBUG_FLAG_STEPPING_OVER
+ offs_t m_stepaddr; // step target address for DEBUG_FLAG_STEPPING_OVER or DEBUG_FLAG_STEPPING_BRANCH
int m_stepsleft; // number of steps left until done
+ int m_delay_steps; // number of steps until target address check
// execution information
offs_t m_stopaddr; // stop address for DEBUG_FLAG_STOP_PC
attotime m_stoptime; // stop time for DEBUG_FLAG_STOP_TIME
int m_stopirq; // stop IRQ number for DEBUG_FLAG_STOP_INTERRUPT
int m_stopexception; // stop exception number for DEBUG_FLAG_STOP_EXCEPTION
- std::unique_ptr<parsed_expression> m_privilege_condition; // expression to evaluate on privilege change
+ std::unique_ptr<parsed_expression> m_stop_condition; // expression to evaluate on privilege change
std::unique_ptr<parsed_expression> m_exception_condition; // expression to evaluate on exception hit
attotime m_endexectime; // ending time of the current execution
u64 m_total_cycles; // current total cycles
@@ -239,10 +241,10 @@ private:
// (0 = not tracing over,
// ~0 = not currently tracing over)
};
- std::unique_ptr<tracer> m_trace; // tracer state
+ std::unique_ptr<tracer> m_trace; // tracer state
- std::vector<memory_passthrough_handler *> m_phw; // passthrough handler reference for each space, write mode
- std::vector<int> m_notifiers; // notifiers for each space
+ std::vector<memory_passthrough_handler> m_phw; // passthrough handler reference for each space, write mode
+ std::vector<util::notifier_subscription> m_notifiers; // notifiers for each space
// pc tracking
class dasm_pc_tag
@@ -322,12 +324,17 @@ private:
static constexpr u32 DEBUG_FLAG_SUSPENDED = 0x00004000; // CPU currently suspended
static constexpr u32 DEBUG_FLAG_LIVE_BP = 0x00010000; // there are live breakpoints for this CPU
static constexpr u32 DEBUG_FLAG_STOP_PRIVILEGE = 0x00020000; // run until execution level changes
+ static constexpr u32 DEBUG_FLAG_STEPPING_BRANCH_TRUE = 0x0040000; // run until true branch
+ static constexpr u32 DEBUG_FLAG_STEPPING_BRANCH_FALSE = 0x0080000; // run until false branch
+ static constexpr u32 DEBUG_FLAG_CALL_IN_PROGRESS = 0x01000000; // CPU is in the middle of a subroutine call
+ static constexpr u32 DEBUG_FLAG_TEST_IN_PROGRESS = 0x02000000; // CPU is performing a conditional test and branch
- static constexpr u32 DEBUG_FLAG_STEPPING_ANY = DEBUG_FLAG_STEPPING | DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT;
+ static constexpr u32 DEBUG_FLAG_STEPPING_BRANCH = DEBUG_FLAG_STEPPING_BRANCH_TRUE | DEBUG_FLAG_STEPPING_BRANCH_FALSE;
+ static constexpr u32 DEBUG_FLAG_STEPPING_ANY = DEBUG_FLAG_STEPPING | DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT | DEBUG_FLAG_STEPPING_BRANCH;
static constexpr u32 DEBUG_FLAG_TRACING_ANY = DEBUG_FLAG_TRACING | DEBUG_FLAG_TRACING_OVER;
static constexpr u32 DEBUG_FLAG_TRANSIENT = DEBUG_FLAG_STEPPING_ANY | DEBUG_FLAG_STOP_PC |
DEBUG_FLAG_STOP_INTERRUPT | DEBUG_FLAG_STOP_EXCEPTION | DEBUG_FLAG_STOP_VBLANK |
- DEBUG_FLAG_STOP_TIME | DEBUG_FLAG_STOP_PRIVILEGE;
+ DEBUG_FLAG_STOP_TIME | DEBUG_FLAG_STOP_PRIVILEGE | DEBUG_FLAG_CALL_IN_PROGRESS | DEBUG_FLAG_TEST_IN_PROGRESS;
};
//**************************************************************************
diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp
index 87bf8f0f18f..a62704c5472 100644
--- a/src/emu/debug/debughlp.cpp
+++ b/src/emu/debug/debughlp.cpp
@@ -81,6 +81,7 @@ const help_item f_static_help_list[] =
" stateload[sl] <filename> -- load a state file for the current driver\n"
" snap [<filename>] -- save a screen snapshot.\n"
" source <filename> -- reads commands from <filename> and executes them one by one\n"
+ " time -- prints current machine time to the console\n"
" cls -- clears the console text buffer\n"
" quit -- exits MAME and the debugger\n"
},
@@ -132,6 +133,9 @@ const help_item f_static_help_list[] =
" o[ver] [<count>=1] -- single steps over <count> instructions (F10)\n"
" out -- single steps until the current subroutine/exception handler is exited (Shift-F11)\n"
" g[o] [<address>] -- resumes execution, sets temp breakpoint at <address> (F5)\n"
+ " gbf [<condition>] -- resumes execution until next false branch\n"
+ " gbt [<condition>] -- resumes execution until next true branch\n"
+ " gn[i] [<count>] -- resumes execution, sets temp breakpoint <count> instructions ahead\n"
" ge[x] [<exception>[,<condition>]] -- resumes execution, setting temp breakpoint if <exception> is raised\n"
" gi[nt] [<irqline>] -- resumes execution, setting temp breakpoint if <irqline> is taken (F7)\n"
" gt[ime] <milliseconds> -- resumes execution until the given delay has elapsed\n"
@@ -578,6 +582,13 @@ const help_item f_static_help_list[] =
" Reads in debugger commands from break_and_trace.cmd and executes them.\n"
},
{
+ "time",
+ "\n"
+ " time\n"
+ "\n"
+ "The time command prints the current machine time to the console.\n"
+ },
+ {
"quit",
"\n"
" quit\n"
@@ -920,6 +931,66 @@ const help_item f_static_help_list[] =
" Resume execution, stopping at address 1234 unless something else stops us first.\n"
},
{
+ "gbf",
+ "\n"
+ " gbf [<condition>]\n"
+ "\n"
+ "The gbf command resumes execution of the current code. Control will not be returned to the "
+ "debugger until a conditional branch or skip instruction tests false and falls through to the "
+ "next instruction, or the instruction that follows its delay slot. The optional conditional "
+ "expression, if provided, will be evaluated at (not after) each conditional branch; execution "
+ "will not halt regardless of consequent program flow unless its result is true (non-zero).\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ "gbf\n"
+ " Resume execution until the next break/watchpoint or until the next false branch.\n"
+ "\n"
+ "gbf {pc != 1234}\n"
+ " Resume execution until the next false branch, disregarding the instruction at address 1234.\n"
+ },
+ {
+ "gbt",
+ "\n"
+ " gbt [<condition>]\n"
+ "\n"
+ "The gbt command resumes execution of the current code. Control will not be returned to the "
+ "debugger until a conditional branch or skip instruction tests true and program flow transfers "
+ "to any instruction other than the next one following the delay slot (if any). The optional "
+ "conditional expression, if provided, will be evaluated at (not after) each conditional "
+ "branch; execution will not halt regardless of consequent program flow unless its result is "
+ "true (non-zero).\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ "gbt\n"
+ " Resume execution until the next break/watchpoint or until the next true branch.\n"
+ "\n"
+ "gbt {pc != 1234}\n"
+ " Resume execution until the next true branch, disregarding the instruction at address 1234.\n"
+ },
+ {
+ "gni",
+ "\n"
+ " gn[i] [<count>]\n"
+ "\n"
+ "The gni command resumes execution of the current code. Control will not be returned to the "
+ "debugger until a breakpoint or watchpoint is hit, or until you manually break in using the "
+ "assigned key. Before executing, the gni command sets a temporary unconditional breakpoint "
+ "<count> instructions sequentially past the current one, which is automatically removed when "
+ "hit. If <count> is omitted, its default value is 1. If <count> is specified as zero, the "
+ "command does nothing. <count> is not permitted to exceed 512 decimal."
+ "\n"
+ "Examples:\n"
+ "\n"
+ "gni\n"
+ " Resume execution, stopping at the address of the next instruction unless something else "
+ "stops us first.\n"
+ "\n"
+ "gni 2\n"
+ " Resume execution, stopping at two instructions past the current one.\n"
+ },
+ {
"gex",
"\n"
" ge[x] [<exception>,[<condition>]]\n"
diff --git a/src/emu/debug/debugvw.cpp b/src/emu/debug/debugvw.cpp
index 5bcc3d057b8..54fe57ecf5a 100644
--- a/src/emu/debug/debugvw.cpp
+++ b/src/emu/debug/debugvw.cpp
@@ -503,11 +503,11 @@ bool debug_view_expression::recompute()
std::string oldstring(m_parsed.original_string());
try
{
- m_parsed.parse(m_string.c_str());
+ m_parsed.parse(m_string);
}
catch (expression_error &)
{
- m_parsed.parse(oldstring.c_str());
+ m_parsed.parse(oldstring);
}
}
diff --git a/src/emu/debug/dvmemory.cpp b/src/emu/debug/dvmemory.cpp
index 02fcde9cbc3..1f1adcb138d 100644
--- a/src/emu/debug/dvmemory.cpp
+++ b/src/emu/debug/dvmemory.cpp
@@ -20,6 +20,20 @@
//**************************************************************************
+// HELPER FUNCTIONS
+//**************************************************************************
+
+namespace {
+
+constexpr u8 sanitise_character(u8 ch)
+{
+ // assume ISO-8859-1 (low 256 Unicode codepoints) - tab, soft hyphen, C0 and C1 cause problems
+ return ('\t' == ch) ? ' ' : (0xadU == ch) ? '-' : ((' ' > ch) || (('~' < ch) && (0xa0U > ch))) ? '.' : ch;
+}
+
+} // anonymous namespace
+
+//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
@@ -301,7 +315,7 @@ void debug_view_memory::generate_row(debug_view_char *destmin, debug_view_char *
if (dest >= destmin && dest < destmax)
dest->byte = addrtext[ch];
- // generate the data and the ascii string
+ // generate the data and the ASCII string
std::string chunkascii;
if (m_shift_bits != 0)
{
@@ -323,7 +337,7 @@ void debug_view_memory::generate_row(debug_view_char *destmin, debug_view_char *
for (int i = 0; i < m_bytes_per_chunk; i++)
{
u8 chval = chunkdata >> (8 * (m_bytes_per_chunk - i - 1));
- chunkascii += char((ismapped && isprint(chval)) ? chval : '.');
+ chunkascii += char(ismapped ? sanitise_character(chval) : '.');
}
}
}
@@ -380,7 +394,7 @@ void debug_view_memory::generate_row(debug_view_char *destmin, debug_view_char *
for (int i = 0; i < m_bytes_per_chunk; i++)
{
u8 chval = chunkdata >> (8 * (m_bytes_per_chunk - i - 1));
- chunkascii += char((ismapped && isprint(chval)) ? chval : '.');
+ chunkascii += char(ismapped ? sanitise_character(chval) : '.');
}
}
}
@@ -526,16 +540,8 @@ void debug_view_memory::view_char(int chval)
if (hexchar == nullptr || (m_shift_bits == 3 && chval >= '8'))
break;
- const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
- offs_t address = (source.m_space != nullptr) ? source.m_space->byte_to_address(pos.m_address) : pos.m_address;
- u64 data;
- bool ismapped = read(m_bytes_per_chunk, address, data);
- if (!ismapped)
- break;
-
- data &= ~(util::make_bitmask<u64>(m_shift_bits) << pos.m_shift);
- data |= u64(hexchar - hexvals) << pos.m_shift;
- write(m_bytes_per_chunk, address, data);
+ if (!write_digit(pos.m_address, pos.m_shift, hexchar - hexvals))
+ break; // TODO: alert OSD?
}
// fall through to the right-arrow press
[[fallthrough]];
@@ -984,6 +990,41 @@ void debug_view_memory::write(u8 size, offs_t offs, u64 data)
//-------------------------------------------------
+// write_digit - write one hex or octal digit
+// at the given address and bit position
+//-------------------------------------------------
+
+bool debug_view_memory::write_digit(offs_t offs, u8 pos, u8 digit)
+{
+ const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
+ offs_t address = (source.m_space != nullptr) ? source.m_space->byte_to_address(offs) : offs;
+ u64 data;
+ bool ismapped = read(m_bytes_per_chunk, address, data);
+ if (!ismapped)
+ return false;
+
+ // clamp to chunk size
+ if (m_bytes_per_chunk * 8 < pos + m_shift_bits)
+ {
+ assert(m_bytes_per_chunk * 8 > pos);
+ digit &= util::make_bitmask<u8>(m_bytes_per_chunk * 8 - pos);
+ }
+
+ u64 write_data = (data & ~(util::make_bitmask<u64>(m_shift_bits) << pos)) | (u64(digit) << pos);
+ write(m_bytes_per_chunk, address, write_data);
+
+ // verify that data reads back as it was written
+ if (source.m_space != nullptr)
+ {
+ read(m_bytes_per_chunk, address, data);
+ return data == write_data;
+ }
+ else
+ return true;
+}
+
+
+//-------------------------------------------------
// set_expression - set the expression string
// describing the home address
//-------------------------------------------------
diff --git a/src/emu/debug/dvmemory.h b/src/emu/debug/dvmemory.h
index f2c738a6ff4..6f1ffab4e9e 100644
--- a/src/emu/debug/dvmemory.h
+++ b/src/emu/debug/dvmemory.h
@@ -127,6 +127,7 @@ private:
// memory access
bool read(u8 size, offs_t offs, u64 &data);
void write(u8 size, offs_t offs, u64 data);
+ bool write_digit(offs_t offs, u8 pos, u8 digit);
bool read(u8 size, offs_t offs, extFloat80_t &data);
bool read_chunk(offs_t address, int chunknum, u64 &chunkdata);
void generate_row(debug_view_char *destmin, debug_view_char *destmax, debug_view_char *destrow, offs_t address);
diff --git a/src/emu/debug/express.cpp b/src/emu/debug/express.cpp
index 8363928e5cb..f9074147b7b 100644
--- a/src/emu/debug/express.cpp
+++ b/src/emu/debug/express.cpp
@@ -387,10 +387,10 @@ void symbol_table::set_memory_modified_func(memory_modified_func modified)
// add - add a new u64 pointer symbol
//-------------------------------------------------
-void symbol_table::add(const char *name, read_write rw, u64 *ptr)
+symbol_entry &symbol_table::add(const char *name, read_write rw, u64 *ptr)
{
m_symlist.erase(name);
- m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, rw, ptr));
+ return *m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, rw, ptr)).first->second;
}
@@ -398,10 +398,10 @@ void symbol_table::add(const char *name, read_write rw, u64 *ptr)
// add - add a new value symbol
//-------------------------------------------------
-void symbol_table::add(const char *name, u64 value)
+symbol_entry &symbol_table::add(const char *name, u64 value)
{
m_symlist.erase(name);
- m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, value));
+ return *m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, value)).first->second;
}
@@ -409,10 +409,10 @@ void symbol_table::add(const char *name, u64 value)
// add - add a new register symbol
//-------------------------------------------------
-void symbol_table::add(const char *name, getter_func getter, setter_func setter, const std::string &format_string)
+symbol_entry &symbol_table::add(const char *name, getter_func getter, setter_func setter, const std::string &format_string)
{
m_symlist.erase(name);
- m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, getter, setter, format_string));
+ return *m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, getter, setter, format_string)).first->second;
}
@@ -420,10 +420,10 @@ void symbol_table::add(const char *name, getter_func getter, setter_func setter,
// add - add a new function symbol
//-------------------------------------------------
-void symbol_table::add(const char *name, int minparams, int maxparams, execute_func execute)
+symbol_entry &symbol_table::add(const char *name, int minparams, int maxparams, execute_func execute)
{
m_symlist.erase(name);
- m_symlist.emplace(name, std::make_unique<function_symbol_entry>(*this, name, minparams, maxparams, execute));
+ return *m_symlist.emplace(name, std::make_unique<function_symbol_entry>(*this, name, minparams, maxparams, execute)).first->second;
}
diff --git a/src/emu/debug/express.h b/src/emu/debug/express.h
index 23284193f47..74b52710959 100644
--- a/src/emu/debug/express.h
+++ b/src/emu/debug/express.h
@@ -175,15 +175,16 @@ public:
// getters
const std::unordered_map<std::string, std::unique_ptr<symbol_entry>> &entries() const { return m_symlist; }
symbol_table *parent() const { return m_parent; }
+ running_machine &machine() { return m_machine; }
// setters
void set_memory_modified_func(memory_modified_func modified);
// symbol access
- void add(const char *name, read_write rw, u64 *ptr = nullptr);
- void add(const char *name, u64 constvalue);
- void add(const char *name, getter_func getter, setter_func setter = nullptr, const std::string &format_string = "");
- void add(const char *name, int minparams, int maxparams, execute_func execute);
+ symbol_entry &add(const char *name, read_write rw, u64 *ptr = nullptr);
+ symbol_entry &add(const char *name, u64 constvalue);
+ symbol_entry &add(const char *name, getter_func getter, setter_func setter = nullptr, const std::string &format_string = "");
+ symbol_entry &add(const char *name, int minparams, int maxparams, execute_func execute);
symbol_entry *find(const char *name) const { if (name) { auto search = m_symlist.find(name); if (search != m_symlist.end()) return search->second.get(); else return nullptr; } else return nullptr; }
symbol_entry *find_deep(const char *name);
diff --git a/src/emu/debug/points.cpp b/src/emu/debug/points.cpp
index c44bc3f7563..a19f0ab5619 100644
--- a/src/emu/debug/points.cpp
+++ b/src/emu/debug/points.cpp
@@ -22,18 +22,19 @@
// debug_breakpoint - constructor
//-------------------------------------------------
-debug_breakpoint::debug_breakpoint(device_debug* debugInterface,
- symbol_table &symbols,
- int index,
- offs_t address,
- const char *condition,
- const char *action)
- : m_debugInterface(debugInterface),
- m_index(index),
- m_enabled(true),
- m_address(address),
- m_condition(symbols, (condition != nullptr) ? condition : "1"),
- m_action((action != nullptr) ? action : "")
+debug_breakpoint::debug_breakpoint(
+ device_debug *debugInterface,
+ symbol_table &symbols,
+ int index,
+ offs_t address,
+ const char *condition,
+ const char *action) :
+ m_debugInterface(debugInterface),
+ m_index(index),
+ m_enabled(true),
+ m_address(address),
+ m_condition(symbols, condition ? condition : "1"),
+ m_action(action ? action : "")
{
}
@@ -59,7 +60,7 @@ bool debug_breakpoint::hit(offs_t pc)
{
return (m_condition.execute() != 0);
}
- catch (expression_error &)
+ catch (expression_error const &)
{
return false;
}
@@ -78,27 +79,28 @@ bool debug_breakpoint::hit(offs_t pc)
// debug_watchpoint - constructor
//-------------------------------------------------
-debug_watchpoint::debug_watchpoint(device_debug* debugInterface,
- symbol_table &symbols,
- int index,
- address_space &space,
- read_or_write type,
- offs_t address,
- offs_t length,
- const char *condition,
- const char *action)
- : m_debugInterface(debugInterface),
- m_phr(nullptr),
- m_phw(nullptr),
- m_space(space),
- m_index(index),
- m_enabled(true),
- m_type(type),
- m_address(address & space.addrmask()),
- m_length(length),
- m_condition(symbols, (condition != nullptr) ? condition : "1"),
- m_action((action != nullptr) ? action : ""),
- m_installing(false)
+debug_watchpoint::debug_watchpoint(
+ device_debug* debugInterface,
+ symbol_table &symbols,
+ int index,
+ address_space &space,
+ read_or_write type,
+ offs_t address,
+ offs_t length,
+ const char *condition,
+ const char *action) :
+ m_debugInterface(debugInterface),
+ m_phr(nullptr),
+ m_phw(nullptr),
+ m_space(space),
+ m_index(index),
+ m_enabled(true),
+ m_type(type),
+ m_address(address & space.addrmask()),
+ m_length(length),
+ m_condition(symbols, condition ? condition : "1"),
+ m_action(action ? action : ""),
+ m_installing(false)
{
std::fill(std::begin(m_start_address), std::end(m_start_address), 0);
std::fill(std::begin(m_end_address), std::end(m_end_address), 0);
@@ -170,21 +172,21 @@ debug_watchpoint::debug_watchpoint(device_debug* debugInterface,
}
install(read_or_write::READWRITE);
- m_notifier = m_space.add_change_notifier([this](read_or_write mode) {
- if (m_enabled)
- {
- install(mode);
- }
- });
+ m_notifier = m_space.add_change_notifier(
+ [this] (read_or_write mode)
+ {
+ if (m_enabled)
+ {
+ install(mode);
+ }
+ });
}
debug_watchpoint::~debug_watchpoint()
{
- m_space.remove_change_notifier(m_notifier);
- if (m_phr)
- m_phr->remove();
- if (m_phw)
- m_phw->remove();
+ m_notifier.reset();
+ m_phr.remove();
+ m_phw.remove();
}
void debug_watchpoint::setEnabled(bool value)
@@ -197,10 +199,8 @@ void debug_watchpoint::setEnabled(bool value)
else
{
m_installing = true;
- if(m_phr)
- m_phr->remove();
- if(m_phw)
- m_phw->remove();
+ m_phr.remove();
+ m_phw.remove();
m_installing = false;
}
}
@@ -211,24 +211,28 @@ void debug_watchpoint::install(read_or_write mode)
if (m_installing)
return;
m_installing = true;
- if ((u32(mode) & u32(read_or_write::READ)) && m_phr)
- m_phr->remove();
- if ((u32(mode) & u32(read_or_write::WRITE)) && m_phw)
- m_phw->remove();
+ if (u32(mode) & u32(read_or_write::READ))
+ m_phr.remove();
+ if (u32(mode) & u32(read_or_write::WRITE))
+ m_phw.remove();
std::string name = util::string_format("wp@%x", m_address);
switch (m_space.data_width())
{
case 8:
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
- m_phr = m_space.install_read_tap(m_start_address[0], m_end_address[0], name,
- [this](offs_t offset, u8 &data, u8 mem_mask) {
- triggered(read_or_write::READ, offset, data, mem_mask);
- }, m_phr);
+ m_phr = m_space.install_read_tap(
+ m_start_address[0], m_end_address[0], name,
+ [this](offs_t offset, u8 &data, u8 mem_mask) {
+ triggered(read_or_write::READ, offset, data, mem_mask);
+ },
+ &m_phr);
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
- m_phw = m_space.install_write_tap(m_start_address[0], m_end_address[0], name,
- [this](offs_t offset, u8 &data, u8 mem_mask) {
- triggered(read_or_write::WRITE, offset, data, mem_mask);
- }, m_phw);
+ m_phw = m_space.install_write_tap(
+ m_start_address[0], m_end_address[0], name,
+ [this](offs_t offset, u8 &data, u8 mem_mask) {
+ triggered(read_or_write::WRITE, offset, data, mem_mask);
+ },
+ &m_phw);
break;
case 16:
@@ -237,17 +241,21 @@ void debug_watchpoint::install(read_or_write mode)
{
u16 mask = m_masks[i];
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
- m_phr = m_space.install_read_tap(m_start_address[i], m_end_address[i], name,
- [this, mask](offs_t offset, u16 &data, u16 mem_mask) {
- if (mem_mask & mask)
- triggered(read_or_write::READ, offset, data, mem_mask);
- }, m_phr);
+ m_phr = m_space.install_read_tap(
+ m_start_address[i], m_end_address[i], name,
+ [this, mask](offs_t offset, u16 &data, u16 mem_mask) {
+ if (mem_mask & mask)
+ triggered(read_or_write::READ, offset, data, mem_mask);
+ },
+ &m_phr);
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
- m_phw = m_space.install_write_tap(m_start_address[i], m_end_address[i], name,
- [this, mask](offs_t offset, u16 &data, u16 mem_mask) {
- if (mem_mask & mask)
- triggered(read_or_write::WRITE, offset, data, mem_mask);
- }, m_phw);
+ m_phw = m_space.install_write_tap(
+ m_start_address[i], m_end_address[i], name,
+ [this, mask](offs_t offset, u16 &data, u16 mem_mask) {
+ if (mem_mask & mask)
+ triggered(read_or_write::WRITE, offset, data, mem_mask);
+ },
+ &m_phw);
}
break;
@@ -257,17 +265,21 @@ void debug_watchpoint::install(read_or_write mode)
{
u32 mask = m_masks[i];
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
- m_phr = m_space.install_read_tap(m_start_address[i], m_end_address[i], name,
- [this, mask](offs_t offset, u32 &data, u32 mem_mask) {
- if (mem_mask & mask)
- triggered(read_or_write::READ, offset, data, mem_mask);
- }, m_phr);
+ m_phr = m_space.install_read_tap(
+ m_start_address[i], m_end_address[i], name,
+ [this, mask](offs_t offset, u32 &data, u32 mem_mask) {
+ if (mem_mask & mask)
+ triggered(read_or_write::READ, offset, data, mem_mask);
+ },
+ &m_phr);
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
- m_phw = m_space.install_write_tap(m_start_address[i], m_end_address[i], name,
- [this, mask](offs_t offset, u32 &data, u32 mem_mask) {
- if (mem_mask & mask)
- triggered(read_or_write::WRITE, offset, data, mem_mask);
- }, m_phw);
+ m_phw = m_space.install_write_tap(
+ m_start_address[i], m_end_address[i], name,
+ [this, mask](offs_t offset, u32 &data, u32 mem_mask) {
+ if (mem_mask & mask)
+ triggered(read_or_write::WRITE, offset, data, mem_mask);
+ },
+ &m_phw);
}
break;
@@ -277,17 +289,20 @@ void debug_watchpoint::install(read_or_write mode)
{
u64 mask = m_masks[i];
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
- m_phr = m_space.install_read_tap(m_start_address[i], m_end_address[i], name,
- [this, mask](offs_t offset, u64 &data, u64 mem_mask) {
- if (mem_mask & mask)
- triggered(read_or_write::READ, offset, data, mem_mask);
- }, m_phr);
+ m_phr = m_space.install_read_tap(
+ m_start_address[i], m_end_address[i], name,
+ [this, mask](offs_t offset, u64 &data, u64 mem_mask) {
+ if (mem_mask & mask)
+ triggered(read_or_write::READ, offset, data, mem_mask);
+ },
+ &m_phr);
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
m_phw = m_space.install_write_tap(m_start_address[i], m_end_address[i], name,
- [this, mask](offs_t offset, u64 &data, u64 mem_mask) {
- if (mem_mask & mask)
- triggered(read_or_write::WRITE, offset, data, mem_mask);
- }, m_phw);
+ [this, mask](offs_t offset, u64 &data, u64 mem_mask) {
+ if (mem_mask & mask)
+ triggered(read_or_write::WRITE, offset, data, mem_mask);
+ },
+ &m_phw);
}
break;
}
diff --git a/src/emu/debug/points.h b/src/emu/debug/points.h
index 84cdad7720b..62ad953626c 100644
--- a/src/emu/debug/points.h
+++ b/src/emu/debug/points.h
@@ -102,8 +102,8 @@ private:
void triggered(read_or_write type, offs_t address, u64 data, u64 mem_mask);
device_debug * m_debugInterface; // the interface we were created from
- memory_passthrough_handler *m_phr; // passthrough handler reference, read access
- memory_passthrough_handler *m_phw; // passthrough handler reference, write access
+ memory_passthrough_handler m_phr; // passthrough handler reference, read access
+ memory_passthrough_handler m_phw; // passthrough handler reference, write access
address_space & m_space; // address space
int m_index; // user reported index
bool m_enabled; // enabled?
@@ -112,7 +112,7 @@ private:
offs_t m_length; // length of watch area
parsed_expression m_condition; // condition
std::string m_action; // action
- int m_notifier; // address map change notifier id
+ util::notifier_subscription m_notifier; // address map change notifier ID
offs_t m_start_address[3]; // the start addresses of the checks to install
offs_t m_end_address[3]; // the end addresses
diff --git a/src/emu/devcb.h b/src/emu/devcb.h
index d27d3beb74d..7638f901296 100644
--- a/src/emu/devcb.h
+++ b/src/emu/devcb.h
@@ -82,16 +82,10 @@ protected:
template <typename T, typename U> using mask_t = std::make_unsigned_t<intermediate_t<T, U> >;
// Detecting candidates for transform functions
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form1 : public std::false_type { };
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form2 : public std::false_type { };
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form3 : public std::false_type { };
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form4 : public std::false_type { };
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form5 : public std::false_type { };
- template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form6 : public std::false_type { };
- template <typename Input, typename Result, typename Func> struct is_transform_form3<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t &, Input, std::make_unsigned_t<Input> &>, Result>::value> > : public std::true_type { };
- template <typename Input, typename Result, typename Func> struct is_transform_form4<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t &, Input>, Result>::value> > : public std::true_type { };
- template <typename Input, typename Result, typename Func> struct is_transform_form6<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, Input>, Result>::value> > : public std::true_type { };
- template <typename Input, typename Result, typename Func> struct is_transform : public std::bool_constant<is_transform_form1<Input, Result, Func>::value || is_transform_form2<Input, Result, Func>::value || is_transform_form3<Input, Result, Func>::value || is_transform_form4<Input, Result, Func>::value || is_transform_form5<Input, Result, Func>::value || is_transform_form6<Input, Result, Func>::value> { };
+ template <typename Input, typename Result, typename Func> using is_transform_form3 = std::is_invocable_r<Result, Func, offs_t &, Input, std::make_unsigned_t<Input> &>;
+ template <typename Input, typename Result, typename Func> using is_transform_form4 = std::is_invocable_r<Result, Func, offs_t &, Input>;
+ template <typename Input, typename Result, typename Func> using is_transform_form6 = std::is_invocable_r<Result, Func, Input>;
+ template <typename Input, typename Result, typename Func> using is_transform = std::bool_constant<is_transform_form3<Input, Result, Func>::value || is_transform_form4<Input, Result, Func>::value || is_transform_form6<Input, Result, Func>::value>;
// Determining the result type of a transform function
template <typename Input, typename Result, typename Func, typename Enable = void> struct transform_result;
@@ -137,12 +131,18 @@ protected:
auto rshift(unsigned val)
{
auto trans(static_cast<Impl &>(*this).transform([val] (offs_t offset, T data, std::make_unsigned_t<T> &mem_mask) { mem_mask >>= val; return data >> val; }));
- return inherited_mask() ? std::move(trans) : std::move(trans.mask(m_mask >> val));
+ if (inherited_mask())
+ return trans;
+ else
+ return std::move(trans.mask(m_mask >> val));
}
auto lshift(unsigned val)
{
auto trans(static_cast<Impl &>(*this).transform([val] (offs_t offset, T data, std::make_unsigned_t<T> &mem_mask) { mem_mask <<= val; return data << val; }));
- return inherited_mask() ? std::move(trans) : std::move(trans.mask(m_mask << val));
+ if (inherited_mask())
+ return trans;
+ else
+ return std::move(trans.mask(m_mask << val));
}
auto bit(unsigned val) { return std::move(rshift(val).mask(T(1U))); }
@@ -211,13 +211,10 @@ class devcb_read_base : public devcb_base
{
protected:
// Detecting candidates for read functions
- template <typename Result, typename Func, typename Enable = void> struct is_read_form1 : public std::false_type { };
- template <typename Result, typename Func, typename Enable = void> struct is_read_form2 : public std::false_type { };
- template <typename Result, typename Func, typename Enable = void> struct is_read_form3 : public std::false_type { };
- template <typename Result, typename Func> struct is_read_form1<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t, Result>, Result>::value> > : public std::true_type { };
- template <typename Result, typename Func> struct is_read_form2<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t>, Result>::value> > : public std::true_type { };
- template <typename Result, typename Func> struct is_read_form3<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func>, Result>::value> > : public std::true_type { };
- template <typename Result, typename Func> struct is_read : public std::bool_constant<is_read_form1<Result, Func>::value || is_read_form2<Result, Func>::value || is_read_form3<Result, Func>::value> { };
+ template <typename Result, typename Func> using is_read_form1 = std::is_invocable_r<Result, Func, offs_t, Result>;
+ template <typename Result, typename Func> using is_read_form2 = std::is_invocable_r<Result, Func, offs_t>;
+ template <typename Result, typename Func> using is_read_form3 = std::is_invocable_r<Result, Func>;
+ template <typename Result, typename Func> using is_read = std::bool_constant<is_read_form1<Result, Func>::value || is_read_form2<Result, Func>::value || is_read_form3<Result, Func>::value>;
// Determining the result type of a read function
template <typename Result, typename Func, typename Enable = void> struct read_result;
@@ -275,13 +272,10 @@ class devcb_write_base : public devcb_base
{
protected:
// Detecting candidates for write functions
- template <typename Input, typename Func, typename Enable = void> struct is_write_form1 : public std::false_type { };
- template <typename Input, typename Func, typename Enable = void> struct is_write_form2 : public std::false_type { };
- template <typename Input, typename Func, typename Enable = void> struct is_write_form3 : public std::false_type { };
- template <typename Input, typename Func> struct is_write_form1<Input, Func, void_t<std::invoke_result_t<Func, offs_t, Input, std::make_unsigned_t<Input>> > > : public std::true_type { };
- template <typename Input, typename Func> struct is_write_form2<Input, Func, void_t<std::invoke_result_t<Func, offs_t, Input> > > : public std::true_type { };
- template <typename Input, typename Func> struct is_write_form3<Input, Func, void_t<std::invoke_result_t<Func, Input> > > : public std::true_type { };
- template <typename Input, typename Func> struct is_write : public std::bool_constant<is_write_form1<Input, Func>::value || is_write_form2<Input, Func>::value || is_write_form3<Input, Func>::value> { };
+ template <typename Input, typename Func> using is_write_form1 = std::is_invocable<Func, offs_t, Input, std::make_unsigned_t<Input> >;
+ template <typename Input, typename Func> using is_write_form2 = std::is_invocable<Func, offs_t, Input>;
+ template <typename Input, typename Func> using is_write_form3 = std::is_invocable<Func, Input>;
+ template <typename Input, typename Func> using is_write = std::bool_constant<is_write_form1<Input, Func>::value || is_write_form2<Input, Func>::value || is_write_form3<Input, Func>::value>;
// Detecting candidates for write delegates
template <typename T, typename Enable = void> struct is_write_method : public std::false_type { };
@@ -494,7 +488,7 @@ private:
assert(this->m_consumed);
this->built();
chain(
- [src = std::forward<U>(f), cb = std::move(this->m_cb), exor = this->exor(), mask = this->mask()] (offs_t &offset, input_mask_t &mem_mask)
+ [src = std::forward<U>(f), cb = std::move(m_cb), exor = this->exor(), mask = this->mask()] (offs_t &offset, input_mask_t &mem_mask)
{
typename Source::input_mask_t source_mask(mem_mask);
auto const data(src(offset, source_mask));
@@ -549,7 +543,7 @@ private:
assert(this->m_consumed);
this->built();
chain(
- [cb = std::move(this->m_cb), exor = this->exor(), mask = this->mask()] (offs_t offset, input_mask_t mem_mask)
+ [cb = std::move(m_cb), exor = this->exor(), mask = this->mask()] (offs_t offset, input_mask_t mem_mask)
{ return (devcb_read::invoke_read<Result>(cb, offset, mem_mask & mask) ^ exor) & mask; });
}
@@ -615,7 +609,7 @@ private:
this->built();
m_delegate.resolve();
chain(
- [cb = std::move(this->m_delegate), exor = this->exor(), mask = this->mask()] (offs_t offset, input_mask_t mem_mask)
+ [cb = std::move(m_delegate), exor = this->exor(), mask = this->mask()] (offs_t offset, input_mask_t mem_mask)
{ return (devcb_read::invoke_read<Result>(cb, offset, mem_mask & mask) ^ exor) & mask; });
}
@@ -1079,7 +1073,7 @@ private:
assert(this->m_consumed);
this->built();
return m_src.build(
- [f = std::move(chain), cb = std::move(this->m_cb), exor = this->exor(), mask = this->mask()] (offs_t &offset, input_t data, std::make_unsigned_t<input_t> &mem_mask)
+ [f = std::move(chain), cb = std::move(m_cb), exor = this->exor(), mask = this->mask()] (offs_t &offset, input_t data, std::make_unsigned_t<input_t> &mem_mask)
{
auto const trans(devcb_write::invoke_transform<input_t, output_t>(cb, offset, data, mem_mask));
output_t out_mask(mem_mask & mask);
@@ -1139,7 +1133,7 @@ private:
assert(this->m_consumed);
this->built();
return
- [sink = m_sink.build(), cb = std::move(this->m_cb), in_exor = m_in_exor, in_mask = m_in_mask, exor = this->exor(), mask = this->mask()] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
+ [sink = m_sink.build(), cb = std::move(m_cb), in_exor = m_in_exor, in_mask = m_in_mask, exor = this->exor(), mask = this->mask()] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
{
data = (data ^ in_exor) & in_mask;
mem_mask &= in_mask;
@@ -1160,7 +1154,7 @@ private:
assert(this->m_consumed);
this->built();
return
- [f = std::move(chain), sink = m_sink.build(), cb = std::move(this->m_cb), in_exor = m_in_exor, in_mask = m_in_mask, exor = this->exor(), mask = this->mask()] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
+ [f = std::move(chain), sink = m_sink.build(), cb = std::move(m_cb), in_exor = m_in_exor, in_mask = m_in_mask, exor = this->exor(), mask = this->mask()] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
{
data = (data ^ in_exor) & in_mask;
mem_mask &= in_mask;
@@ -1197,7 +1191,7 @@ private:
assert(this->m_consumed);
this->built();
return
- [cb = std::move(this->m_cb)] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
+ [cb = std::move(m_cb)] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
{ devcb_write::invoke_write<Input>(cb, offset, data, mem_mask); };
}
@@ -1247,7 +1241,7 @@ private:
assert(this->m_consumed);
this->built();
return
- [cb = std::move(this->m_cb), exor = this->exor(), mask = this->mask()] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
+ [cb = std::move(m_cb), exor = this->exor(), mask = this->mask()] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
{ devcb_write::invoke_write<Input>(cb, offset, (data ^ exor) & mask, mem_mask & mask); };
}
};
@@ -1291,7 +1285,7 @@ private:
this->built();
m_delegate.resolve();
return
- [cb = std::move(this->m_delegate)] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
+ [cb = std::move(m_delegate)] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
{ devcb_write::invoke_write<Input>(cb, offset, data, mem_mask); };
}
@@ -1357,7 +1351,7 @@ private:
this->built();
m_delegate.resolve();
return
- [cb = std::move(this->m_delegate), exor = this->exor(), mask = this->mask()] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
+ [cb = std::move(m_delegate), exor = this->exor(), mask = this->mask()] (offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
{ devcb_write::invoke_write<Input>(cb, offset, (data ^ exor) & mask, mem_mask & mask); };
}
};
diff --git a/src/emu/device.cpp b/src/emu/device.cpp
index c9097a59d4f..6a4b0d4b685 100644
--- a/src/emu/device.cpp
+++ b/src/emu/device.cpp
@@ -365,7 +365,7 @@ void device_t::reset()
// unscaled clock
//-------------------------------------------------
-void device_t::set_unscaled_clock(u32 clock)
+void device_t::set_unscaled_clock(u32 clock, bool sync_on_new_clock_domain)
{
// do nothing if no actual change
if (clock == m_unscaled_clock)
@@ -381,7 +381,7 @@ void device_t::set_unscaled_clock(u32 clock)
// if the device has already started, make sure it knows about the new clock
if (m_started)
- notify_clock_changed();
+ notify_clock_changed(sync_on_new_clock_domain);
}
@@ -464,9 +464,9 @@ u64 device_t::attotime_to_clocks(const attotime &duration) const noexcept
// callback
//-------------------------------------------------
-emu_timer *device_t::timer_alloc(device_timer_id id, void *ptr)
+emu_timer *device_t::timer_alloc(device_timer_id id)
{
- return machine().scheduler().timer_alloc(*this, id, ptr);
+ return machine().scheduler().timer_alloc(*this, id);
}
@@ -475,9 +475,9 @@ emu_timer *device_t::timer_alloc(device_timer_id id, void *ptr)
// call our device callback
//-------------------------------------------------
-void device_t::timer_set(const attotime &duration, device_timer_id id, int param, void *ptr)
+void device_t::timer_set(const attotime &duration, device_timer_id id, int param)
{
- machine().scheduler().timer_set(duration, *this, id, param, ptr);
+ machine().scheduler().timer_set(duration, *this, id, param);
}
@@ -609,7 +609,6 @@ void device_t::start()
}
// register our save states
- save_item(NAME(m_clock));
save_item(NAME(m_unscaled_clock));
save_item(NAME(m_clock_scale));
@@ -688,6 +687,21 @@ void device_t::pre_save()
void device_t::post_load()
{
+ // recompute clock-related parameters if something changed
+ u32 const scaled_clock = m_unscaled_clock * m_clock_scale;
+ if (m_clock != scaled_clock)
+ {
+ m_clock = scaled_clock;
+ m_attoseconds_per_clock = (scaled_clock == 0) ? 0 : HZ_TO_ATTOSECONDS(scaled_clock);
+
+ // recalculate all derived clocks
+ for (device_t &child : subdevices())
+ child.calculate_derived_clock();
+
+ // make sure the device knows about the new clock
+ notify_clock_changed();
+ }
+
// notify the interface
for (device_interface &intf : interfaces())
intf.interface_post_load();
@@ -702,11 +716,11 @@ void device_t::post_load()
// that the clock has changed
//-------------------------------------------------
-void device_t::notify_clock_changed()
+void device_t::notify_clock_changed(bool sync_on_new_clock_domain)
{
// first notify interfaces
for (device_interface &intf : interfaces())
- intf.interface_clock_changed();
+ intf.interface_clock_changed(sync_on_new_clock_domain);
// then notify the device
device_clock_changed();
@@ -872,7 +886,7 @@ void device_t::device_debug_setup()
// fires
//-------------------------------------------------
-void device_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+void device_t::device_timer(emu_timer &timer, device_timer_id id, int param)
{
// do nothing by default
}
@@ -1188,7 +1202,7 @@ void device_interface::interface_post_load()
// implementation
//-------------------------------------------------
-void device_interface::interface_clock_changed()
+void device_interface::interface_clock_changed(bool sync_on_new_clock_domain)
{
// do nothing by default
}
diff --git a/src/emu/device.h b/src/emu/device.h
index 77c12cb2d56..4ea1a940320 100644
--- a/src/emu/device.h
+++ b/src/emu/device.h
@@ -210,7 +210,7 @@ private:
assert(!owner);
assert(!clock);
- return make_unique_clear<DriverClass>(mconfig, type, tag);
+ return std::make_unique<DriverClass>(mconfig, type, tag);
}
create_func const m_creator;
@@ -696,19 +696,20 @@ public:
// clock/timing accessors
u32 clock() const { return m_clock; }
u32 unscaled_clock() const { return m_unscaled_clock; }
- void set_unscaled_clock(u32 clock);
- void set_unscaled_clock(const XTAL &xtal) { set_unscaled_clock(xtal.value()); }
- void set_unscaled_clock_int(u32 clock) { set_unscaled_clock(clock); } // non-overloaded name because binding to overloads is ugly
+ void set_unscaled_clock(u32 clock, bool sync_on_new_clock_domain = false);
+ void set_unscaled_clock(const XTAL &xtal, bool sync_on_new_clock_domain = false) { set_unscaled_clock(xtal.value(), sync_on_new_clock_domain); }
+ void set_unscaled_clock_int(u32 clock) { set_unscaled_clock(clock, false); } // non-overloaded name because binding to overloads is ugly
+ void set_unscaled_clock_int_sync(u32 clock) { set_unscaled_clock(clock, true); } // non-overloaded name because binding to overloads is ugly
double clock_scale() const { return m_clock_scale; }
void set_clock_scale(double clockscale);
attotime clocks_to_attotime(u64 clocks) const noexcept;
u64 attotime_to_clocks(const attotime &duration) const noexcept;
// timer interfaces
- emu_timer *timer_alloc(device_timer_id id = 0, void *ptr = nullptr);
- void timer_set(const attotime &duration, device_timer_id id = 0, int param = 0, void *ptr = nullptr);
- void synchronize(device_timer_id id = 0, int param = 0, void *ptr = nullptr) { timer_set(attotime::zero, id, param, ptr); }
- void timer_expired(emu_timer &timer, device_timer_id id, int param, void *ptr) { device_timer(timer, id, param, ptr); }
+ emu_timer *timer_alloc(device_timer_id id = 0);
+ void timer_set(const attotime &duration, device_timer_id id = 0, int param = 0);
+ void synchronize(device_timer_id id = 0, int param = 0) { timer_set(attotime::zero, id, param); }
+ void timer_expired(emu_timer &timer, device_timer_id id, int param) { device_timer(timer, id, param); }
/// \brief Register data for save states
///
@@ -834,7 +835,7 @@ protected:
void debug_setup();
void pre_save();
void post_load();
- void notify_clock_changed();
+ void notify_clock_changed(bool sync_on_new_clock_domain = false);
finder_base *register_auto_finder(finder_base &autodev);
void register_callback(devcb_base &callback);
@@ -976,7 +977,7 @@ protected:
virtual void device_clock_changed();
virtual void device_debug_setup();
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param);
//------------------- end derived class overrides
@@ -1182,7 +1183,7 @@ public:
/// \sa interface_pre_save device_t::device_post_load
virtual void interface_post_load() ATTR_COLD;
- virtual void interface_clock_changed();
+ virtual void interface_clock_changed(bool sync_on_new_clock_domain);
virtual void interface_debug_setup();
private:
diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp
index 49dee5f650e..0e9074fe3b2 100644
--- a/src/emu/diexec.cpp
+++ b/src/emu/diexec.cpp
@@ -164,7 +164,7 @@ void device_execute_interface::spin_until_time(const attotime &duration)
suspend_until_trigger(TRIGGER_SUSPENDTIME + timetrig, true);
// then set a timer for it
- m_scheduler->timer_set(duration, timer_expired_delegate(FUNC(device_execute_interface::timed_trigger_callback),this), TRIGGER_SUSPENDTIME + timetrig, this);
+ m_scheduler->timer_set(duration, timer_expired_delegate(FUNC(device_execute_interface::timed_trigger_callback),this), TRIGGER_SUSPENDTIME + timetrig);
timetrig = (timetrig + 1) % 256;
}
@@ -475,7 +475,7 @@ void device_execute_interface::interface_post_reset()
// information for this device
//-------------------------------------------------
-void device_execute_interface::interface_clock_changed()
+void device_execute_interface::interface_clock_changed(bool sync_on_new_clock_domain)
{
// a clock of zero disables the device
if (device().clock() == 0)
@@ -492,6 +492,10 @@ void device_execute_interface::interface_clock_changed()
m_cycles_per_second = clocks_to_cycles(device().clock());
m_attoseconds_per_cycle = HZ_TO_ATTOSECONDS(m_cycles_per_second);
+ // resynchronize the localtime to the clock domain when asked to
+ if (sync_on_new_clock_domain)
+ m_localtime = attotime::from_ticks(m_localtime.as_ticks(device().clock())+1, device().clock());
+
// update the device's divisor
s64 attos = m_attoseconds_per_cycle;
m_divshift = 0;
@@ -682,7 +686,7 @@ if (TEMPLOG) printf("setline(%s,%d,%d,%d)\n", m_execute->device().tag(), m_linen
if (event_index >= std::size(m_queue))
{
m_qindex--;
- empty_event_queue(nullptr,0);
+ empty_event_queue(0);
event_index = m_qindex++;
m_execute->device().logerror("Exceeded pending input line event queue on device '%s'!\n", m_execute->device().tag());
}
@@ -696,7 +700,7 @@ if (TEMPLOG) printf("setline(%s,%d,%d,%d)\n", m_execute->device().tag(), m_linen
// if this is the first one, set the timer
if (event_index == 0)
- m_execute->scheduler().synchronize(timer_expired_delegate(FUNC(device_execute_interface::device_input::empty_event_queue),this), 0, this);
+ m_execute->scheduler().synchronize(timer_expired_delegate(FUNC(device_execute_interface::device_input::empty_event_queue),this));
}
}
diff --git a/src/emu/diexec.h b/src/emu/diexec.h
index 065248a9046..1490c20389d 100644
--- a/src/emu/diexec.h
+++ b/src/emu/diexec.h
@@ -216,7 +216,7 @@ protected:
virtual void interface_post_start() override;
virtual void interface_pre_reset() override;
virtual void interface_post_reset() override;
- virtual void interface_clock_changed() override;
+ virtual void interface_clock_changed(bool sync_on_new_clock_domain) override;
// for use by devcpu for now...
int current_input_state(unsigned i) const { return m_input[i].m_curstate; }
diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp
index 031ed46eb30..4e5ca05e002 100644
--- a/src/emu/diimage.cpp
+++ b/src/emu/diimage.cpp
@@ -11,6 +11,7 @@
#include "emu.h"
#include "emuopts.h"
+#include "fileio.h"
#include "romload.h"
#include "softlist.h"
#include "softlist_dev.h"
@@ -25,35 +26,7 @@
#include <cctype>
#include <cstring>
#include <regex>
-
-
-//**************************************************************************
-// DEVICE CONFIG IMAGE INTERFACE
-//**************************************************************************
-const image_device_type_info device_image_interface::m_device_info_array[] =
- {
- { IO_UNKNOWN, "unknown", "unkn" }, /* 0 */
- { IO_CARTSLOT, "cartridge", "cart" }, /* 1 */
- { IO_FLOPPY, "floppydisk", "flop" }, /* 2 */
- { IO_HARDDISK, "harddisk", "hard" }, /* 3 */
- { IO_CYLINDER, "cylinder", "cyln" }, /* 4 */
- { IO_CASSETTE, "cassette", "cass" }, /* 5 */
- { IO_PUNCHCARD, "punchcard", "pcrd" }, /* 6 */
- { IO_PUNCHTAPE, "punchtape", "ptap" }, /* 7 */
- { IO_PRINTER, "printout", "prin" }, /* 8 */
- { IO_SERIAL, "serial", "serl" }, /* 9 */
- { IO_PARALLEL, "parallel", "parl" }, /* 10 */
- { IO_SNAPSHOT, "snapshot", "dump" }, /* 11 */
- { IO_QUICKLOAD, "quickload", "quik" }, /* 12 */
- { IO_MEMCARD, "memcard", "memc" }, /* 13 */
- { IO_CDROM, "cdrom", "cdrm" }, /* 14 */
- { IO_MAGTAPE, "magtape", "magt" }, /* 15 */
- { IO_ROM, "romimage", "rom" }, /* 16 */
- { IO_MIDIIN, "midiin", "min" }, /* 17 */
- { IO_MIDIOUT, "midiout", "mout" }, /* 18 */
- { IO_PICTURE, "picture", "pic" }, /* 19 */
- { IO_VIDEO, "vidfile", "vid" } /* 20 */
- };
+#include <sstream>
//**************************************************************************
@@ -103,6 +76,7 @@ device_image_interface::device_image_interface(const machine_config &mconfig, de
, m_create_format(0)
, m_create_args(nullptr)
, m_user_loadable(true)
+ , m_must_be_loaded(false)
, m_is_loading(false)
, m_is_reset_and_loading(false)
{
@@ -132,56 +106,6 @@ void device_image_interface::interface_config_complete()
//-------------------------------------------------
-// find_device_type - search through list of
-// device types to extract data
-//-------------------------------------------------
-
-const image_device_type_info *device_image_interface::find_device_type(iodevice_t type)
-{
- for (const image_device_type_info &info : m_device_info_array)
- {
- if (info.m_type == type)
- return &info;
- }
- return nullptr;
-}
-
-//-------------------------------------------------
-// device_typename - retrieves device type name
-//-------------------------------------------------
-
-const char *device_image_interface::device_typename(iodevice_t type)
-{
- const image_device_type_info *info = find_device_type(type);
- return (info != nullptr) ? info->m_name : "unknown";
-}
-
-//-------------------------------------------------
-// device_brieftypename - retrieves device
-// brief type name
-//-------------------------------------------------
-
-const char *device_image_interface::device_brieftypename(iodevice_t type)
-{
- const image_device_type_info *info = find_device_type(type);
- return (info != nullptr) ? info->m_shortname : "unk";
-}
-
-//-------------------------------------------------
-// device_typeid - retrieves device type id
-//-------------------------------------------------
-
-iodevice_t device_image_interface::device_typeid(const char *name)
-{
- for (const image_device_type_info &info : m_device_info_array)
- {
- if (!core_stricmp(name, info.m_name) || !core_stricmp(name, info.m_shortname))
- return info.m_type;
- }
- return (iodevice_t)-1;
-}
-
-//-------------------------------------------------
// set_image_filename - specifies the filename of
// an image
//-------------------------------------------------
@@ -231,10 +155,10 @@ bool device_image_interface::is_filetype(std::string_view candidate_filetype) co
// image creation by name
//-------------------------------------------------
-const image_device_format *device_image_interface::device_get_named_creatable_format(const std::string &format_name) noexcept
+const image_device_format *device_image_interface::device_get_named_creatable_format(std::string_view format_name) const noexcept
{
- for (auto &format : m_formatlist)
- if (format->name() == format_name)
+ for (const auto &format : m_formatlist)
+ if (std::string_view(format->name()) == format_name)
return format.get();
return nullptr;
}
@@ -266,11 +190,10 @@ void device_image_interface::add_format(std::string &&name, std::string &&descri
****************************************************************************/
//-------------------------------------------------
-// image_clear_error - clear out any specified
-// error
+// clear_error - clear out any specified error
//-------------------------------------------------
-void device_image_interface::clear_error()
+void device_image_interface::clear_error() noexcept
{
m_err.clear();
m_err_message.clear();
@@ -370,7 +293,7 @@ const software_info *device_image_interface::software_entry() const noexcept
// get_software_region
//-------------------------------------------------
-u8 *device_image_interface::get_software_region(const char *tag)
+u8 *device_image_interface::get_software_region(std::string_view tag)
{
if (!loaded_through_softlist())
return nullptr;
@@ -385,7 +308,7 @@ u8 *device_image_interface::get_software_region(const char *tag)
// image_get_software_region_length
//-------------------------------------------------
-u32 device_image_interface::get_software_region_length(const char *tag)
+u32 device_image_interface::get_software_region_length(std::string_view tag)
{
std::string full_tag = util::string_format("%s:%s", device().tag(), tag);
memory_region *region = device().machine().root_device().memregion(full_tag);
@@ -397,7 +320,7 @@ u32 device_image_interface::get_software_region_length(const char *tag)
// image_get_feature
//-------------------------------------------------
-const char *device_image_interface::get_feature(const char *feature_name) const
+const char *device_image_interface::get_feature(std::string_view feature_name) const
{
return !m_software_part_ptr ? nullptr : m_software_part_ptr->feature(feature_name);
}
@@ -407,7 +330,7 @@ const char *device_image_interface::get_feature(const char *feature_name) const
// load_software_region -
//-------------------------------------------------
-bool device_image_interface::load_software_region(const char *tag, std::unique_ptr<u8[]> &ptr)
+bool device_image_interface::load_software_region(std::string_view tag, std::unique_ptr<u8[]> &ptr)
{
size_t size = get_software_region_length(tag);
@@ -428,43 +351,25 @@ bool device_image_interface::load_software_region(const char *tag, std::unique_p
// to be loaded
// ****************************************************************************
-bool device_image_interface::run_hash(util::core_file &file, u32 skip_bytes, util::hash_collection &hashes, const char *types)
+std::error_condition device_image_interface::run_hash(util::random_read &file, u32 skip_bytes, util::hash_collection &hashes, const char *types)
{
// reset the hash; we want to override existing data
hashes.reset();
// figure out the size, and "cap" the skip bytes
u64 size;
- if (file.length(size))
- return false;
+ std::error_condition filerr = file.length(size);
+ if (filerr)
+ return filerr;
skip_bytes = u32(std::min<u64>(skip_bytes, size));
- // seek to the beginning
- file.seek(skip_bytes, SEEK_SET); // TODO: check error return
- u64 position = skip_bytes;
-
- // keep on reading hashes
- hashes.begin(types);
- while (position < size)
- {
- uint8_t buffer[8192];
-
- // read bytes
- const size_t count = size_t(std::min<u64>(size - position, sizeof(buffer)));
- size_t actual_count;
- const std::error_condition filerr = file.read(buffer, count, actual_count);
- if (filerr || !actual_count)
- return false;
- position += actual_count;
-
- // and compute the hashes
- hashes.buffer(buffer, actual_count);
- }
- hashes.end();
+ // and compute the hashes
+ size_t actual_count;
+ filerr = hashes.compute(file, skip_bytes, size - skip_bytes, actual_count, types);
+ if (filerr)
+ return filerr;
- // cleanup
- file.seek(0, SEEK_SET); // TODO: check error return
- return true;
+ return std::error_condition();
}
@@ -477,7 +382,7 @@ bool device_image_interface::image_checkhash()
{
// do not cause a linear read of 600 megs please
// TODO: use SHA1 in the CHD header as the hash
- if (image_type() == IO_CDROM)
+ if (image_is_chd_type())
return true;
// Skip calculating the hash when we have an image mounted through a software list
@@ -485,18 +390,18 @@ bool device_image_interface::image_checkhash()
return true;
// run the hash
- if (!run_hash(*m_file, unhashed_header_length(), m_hash, util::hash_collection::HASH_TYPES_ALL))
+ if (run_hash(*m_file, unhashed_header_length(), m_hash, util::hash_collection::HASH_TYPES_ALL))
return false;
}
return true;
}
-util::hash_collection device_image_interface::calculate_hash_on_file(util::core_file &file) const
+util::hash_collection device_image_interface::calculate_hash_on_file(util::random_read &file) const
{
// calculate the hash
util::hash_collection hash;
- if (!run_hash(file, unhashed_header_length(), hash, util::hash_collection::HASH_TYPES_ALL))
+ if (run_hash(file, unhashed_header_length(), hash, util::hash_collection::HASH_TYPES_ALL))
hash.reset();
return hash;
}
@@ -514,33 +419,6 @@ u32 device_image_interface::crc()
}
-//-------------------------------------------------
-// support_command_line_image_creation - do we
-// want to support image creation from the front
-// end command line?
-//-------------------------------------------------
-
-bool device_image_interface::support_command_line_image_creation() const noexcept
-{
- bool result;
- switch (image_type())
- {
- case IO_PRINTER:
- case IO_SERIAL:
- case IO_PARALLEL:
- // going by the assumption that these device image types should support this
- // behavior; ideally we'd get rid of IO_* and just push this to the specific
- // devices
- result = true;
- break;
- default:
- result = false;
- break;
- }
- return result;
-}
-
-
// ****************************************************************************
// Battery functions
//
@@ -619,34 +497,6 @@ void device_image_interface::battery_save(const void *buffer, int length)
}
-//-------------------------------------------------
-// uses_file_extension - update configuration
-// based on completed device setup
-//-------------------------------------------------
-
-bool device_image_interface::uses_file_extension(const char *file_extension) const
-{
- bool result = false;
-
- if (file_extension[0] == '.')
- file_extension++;
-
- /* find the extensions */
- std::string extensions(file_extensions());
- char *ext = strtok((char*)extensions.c_str(),",");
- while (ext != nullptr)
- {
- if (!core_stricmp(ext, file_extension))
- {
- result = true;
- break;
- }
- ext = strtok (nullptr, ",");
- }
- return result;
-}
-
-
// ***************************************************************************
// IMAGE LOADING
// ***************************************************************************
@@ -816,7 +666,24 @@ bool device_image_interface::load_software(software_list_device &swlist, std::st
else
filerr = m_mame_file->open(romp->name());
if (filerr)
+ {
m_mame_file.reset();
+ std::ostringstream msg;
+ util::stream_format(msg,
+ "%s: error opening image file %s: %s (%s:%d)",
+ device().tag(), romp->name(),
+ filerr.message(),
+ filerr.category().name(),
+ filerr.value());
+ if (!searchpath.empty())
+ {
+ msg << " (tried in";
+ for (auto const &path : searchpath)
+ msg << ' ' << path;
+ msg << ')';
+ }
+ osd_printf_error("%s\n", std::move(msg).str());
+ }
warningcount += verify_length_and_hash(m_mame_file.get(), romp->name(), romp->get_length(), util::hash_collection(romp->hashdata()));
@@ -1137,12 +1004,10 @@ const util::option_guide &device_image_interface::create_option_guide() const
void device_image_interface::update_names()
{
- const char *inst_name = custom_instance_name();
- const char *brief_name = custom_brief_instance_name();
- if (inst_name == nullptr)
- inst_name = device_typename(image_type());
- if (brief_name == nullptr)
- brief_name = device_brieftypename(image_type());
+ const char *inst_name = image_type_name();
+ const char *brief_name = image_brief_type_name();
+ assert(inst_name != nullptr);
+ assert(brief_name != nullptr);
// count instances of the general image type, or device type if custom
int count = 0;
@@ -1151,19 +1016,21 @@ void device_image_interface::update_names()
{
if (this == &image)
index = count;
- const char *other_name = image.custom_instance_name();
- if (!other_name)
- other_name = device_typename(image.image_type());
+ const char *other_name = image.image_type_name();
+ const char *other_brief_name = image.image_brief_type_name();
+ assert(other_name != nullptr);
+ assert(other_brief_name != nullptr);
- if (other_name == inst_name || !strcmp(other_name, inst_name))
+ if (other_name == inst_name || !strcmp(other_name, inst_name) ||
+ other_brief_name == brief_name || !strcmp(other_brief_name, brief_name))
count++;
}
- m_canonical_instance_name = string_format("%s%d", inst_name, index + 1);
+ m_canonical_instance_name = util::string_format("%s%d", inst_name, index + 1);
if (count > 1)
{
m_instance_name = m_canonical_instance_name;
- m_brief_instance_name = string_format("%s%d", brief_name, index + 1);
+ m_brief_instance_name = util::string_format("%s%d", brief_name, index + 1);
}
else
{
diff --git a/src/emu/diimage.h b/src/emu/diimage.h
index 67d20c43402..08d48020cc3 100644
--- a/src/emu/diimage.h
+++ b/src/emu/diimage.h
@@ -29,33 +29,6 @@
// TYPE DEFINITIONS
//**************************************************************************
-enum iodevice_t
-{
- /* List of all supported devices. Refer to the device by these names only */
- IO_UNKNOWN,
- IO_CARTSLOT, /* 1 - Cartridge Port, as found on most console and on some computers */
- IO_FLOPPY, /* 2 - Floppy Disk unit */
- IO_HARDDISK, /* 3 - Hard Disk unit */
- IO_CYLINDER, /* 4 - Magnetically-Coated Cylinder */
- IO_CASSETTE, /* 5 - Cassette Recorder (common on early home computers) */
- IO_PUNCHCARD, /* 6 - Card Puncher/Reader */
- IO_PUNCHTAPE, /* 7 - Tape Puncher/Reader (reels instead of punchcards) */
- IO_PRINTER, /* 8 - Printer device */
- IO_SERIAL, /* 9 - Generic Serial Port */
- IO_PARALLEL, /* 10 - Generic Parallel Port */
- IO_SNAPSHOT, /* 11 - Complete 'snapshot' of the state of the computer */
- IO_QUICKLOAD, /* 12 - Allow to load program/data into memory, without matching any actual device */
- IO_MEMCARD, /* 13 - Memory card */
- IO_CDROM, /* 14 - optical CD-ROM disc */
- IO_MAGTAPE, /* 15 - Magnetic tape */
- IO_ROM, /* 16 - Individual ROM image - the Amstrad CPC has a few applications that were sold on 16kB ROMs */
- IO_MIDIIN, /* 17 - MIDI In port */
- IO_MIDIOUT, /* 18 - MIDI Out port */
- IO_PICTURE, /* 19 - A single-frame image */
- IO_VIDEO, /* 20 - A video file */
- IO_COUNT /* 21 - Total Number of IO_devices for searching */
-};
-
enum class image_error : int
{
INTERNAL = 1,
@@ -69,13 +42,6 @@ const std::error_category &image_category() noexcept;
inline std::error_condition make_error_condition(image_error e) noexcept { return std::error_condition(int(e), image_category()); }
namespace std { template <> struct is_error_condition_enum<image_error> : public std::true_type { }; }
-struct image_device_type_info
-{
- iodevice_t m_type;
- const char *m_name;
- const char *m_shortname;
-};
-
class image_device_format
{
public:
@@ -124,35 +90,30 @@ public:
device_image_interface(const machine_config &mconfig, device_t &device);
virtual ~device_image_interface();
- static const char *device_typename(iodevice_t type);
- static const char *device_brieftypename(iodevice_t type);
- static iodevice_t device_typeid(const char *name);
-
virtual image_init_result call_load() { return image_init_result::PASS; }
virtual image_init_result call_create(int format_type, util::option_resolution *format_options) { return image_init_result::PASS; }
virtual void call_unload() { }
virtual std::string call_display() { return std::string(); }
virtual u32 unhashed_header_length() const noexcept { return 0; }
virtual bool core_opens_image_file() const noexcept { return true; }
- virtual iodevice_t image_type() const noexcept = 0;
+ virtual bool image_is_chd_type() const noexcept { return false; }
virtual bool is_readable() const noexcept = 0;
virtual bool is_writeable() const noexcept = 0;
virtual bool is_creatable() const noexcept = 0;
- virtual bool must_be_loaded() const noexcept = 0;
virtual bool is_reset_on_load() const noexcept = 0;
- virtual bool support_command_line_image_creation() const noexcept;
+ virtual bool support_command_line_image_creation() const noexcept { return false; }
virtual const char *image_interface() const noexcept { return nullptr; }
virtual const char *file_extensions() const noexcept = 0;
virtual const util::option_guide &create_option_guide() const;
- virtual const char *custom_instance_name() const noexcept { return nullptr; }
- virtual const char *custom_brief_instance_name() const noexcept { return nullptr; }
+ virtual const char *image_type_name() const noexcept = 0;
+ virtual const char *image_brief_type_name() const noexcept = 0;
const image_device_format *device_get_indexed_creatable_format(int index) const noexcept { return (index < m_formatlist.size()) ? m_formatlist.at(index).get() : nullptr; }
- const image_device_format *device_get_named_creatable_format(const std::string &format_name) noexcept;
+ const image_device_format *device_get_named_creatable_format(std::string_view format_name) const noexcept;
const util::option_guide &device_get_creation_option_guide() const { return create_option_guide(); }
std::string_view error();
- void seterror(std::error_condition err, const char *message);
+ void seterror(std::error_condition err, const char *message = nullptr);
void message(const char *format, ...) ATTR_PRINTF(2,3);
bool exists() const noexcept { return !m_image_name.empty(); }
@@ -165,7 +126,7 @@ public:
bool is_filetype(std::string_view candidate_filetype) const;
bool is_open() const noexcept { return bool(m_file); }
- util::core_file &image_core_file() const noexcept { return *m_file; }
+ util::core_file &image_core_file() const noexcept { assert(is_open()); return *m_file; }
bool is_readonly() const noexcept { return m_readonly; }
// image file I/O wrappers
@@ -204,28 +165,11 @@ public:
m_file->tell(result);
return result;
}
- int fgetc()
- {
- char ch;
- if (fread(&ch, 1) != 1)
- ch = '\0';
- return ch;
- }
- char *fgets(char *buffer, u32 length)
- {
- check_for_file();
- return m_file->gets(buffer, length);
- }
bool image_feof()
{
check_for_file();
return m_file->eof();
}
- const void *ptr()
- {
- check_for_file();
- return m_file->buffer();
- }
// allocate and read into buffers
u32 fread(std::unique_ptr<u8 []> &ptr, u32 length) { ptr = std::make_unique<u8 []>(length); return fread(ptr.get(), length); }
@@ -243,25 +187,22 @@ public:
const std::string &working_directory() const { return m_working_directory; }
// access to software list properties and ROM data areas
- u8 *get_software_region(const char *tag);
- u32 get_software_region_length(const char *tag);
- const char *get_feature(const char *feature_name) const;
- bool load_software_region(const char *tag, std::unique_ptr<u8[]> &ptr);
+ u8 *get_software_region(std::string_view tag);
+ u32 get_software_region_length(std::string_view tag);
+ const char *get_feature(std::string_view feature_name) const;
+ bool load_software_region(std::string_view tag, std::unique_ptr<u8[]> &ptr);
u32 crc();
util::hash_collection& hash() { return m_hash; }
- util::hash_collection calculate_hash_on_file(util::core_file &file) const;
+ util::hash_collection calculate_hash_on_file(util::random_read &file) const;
void battery_load(void *buffer, int length, int fill);
void battery_load(void *buffer, int length, const void *def_buffer);
void battery_save(const void *buffer, int length);
- const char *image_type_name() const { return device_typename(image_type()); }
-
const std::string &instance_name() const { return m_instance_name; }
const std::string &brief_instance_name() const { return m_brief_instance_name; }
const std::string &canonical_instance_name() const { return m_canonical_instance_name; }
- bool uses_file_extension(const char *file_extension) const;
const formatlist_type &formatlist() const { return m_formatlist; }
// loads an image file
@@ -277,9 +218,11 @@ public:
bool load_software(software_list_device &swlist, std::string_view swname, const rom_entry *entry);
std::error_condition reopen_for_write(std::string_view path);
- void set_user_loadable(bool user_loadable) { m_user_loadable = user_loadable; }
+ void set_user_loadable(bool user_loadable) noexcept { m_user_loadable = user_loadable; }
+ void set_must_be_loaded(bool must_be_loaded) noexcept { m_must_be_loaded = must_be_loaded; }
bool user_loadable() const noexcept { return m_user_loadable; }
+ bool must_be_loaded() const noexcept { return m_must_be_loaded; }
bool is_reset_and_loading() const noexcept { return m_is_reset_and_loading; }
const std::string &full_software_name() const noexcept { return m_full_software_name; }
@@ -297,7 +240,7 @@ protected:
void set_image_filename(std::string_view filename);
- void clear_error();
+ void clear_error() noexcept;
void check_for_file() const { if (!m_file) throw emu_fatalerror("%s(%s): Illegal operation on unmounted image", device().shortname(), device().tag()); }
@@ -311,12 +254,6 @@ protected:
void add_format(std::unique_ptr<image_device_format> &&format);
void add_format(std::string &&name, std::string &&description, std::string &&extensions, std::string &&optspec);
- // derived class overrides
-
- // configuration
- static const image_device_type_info *find_device_type(iodevice_t type);
- static const image_device_type_info m_device_info_array[];
-
// error related info
std::error_condition m_err;
std::string m_err_message;
@@ -340,7 +277,7 @@ private:
bool load_software_part(std::string_view identifier);
bool init_phase() const;
- static bool run_hash(util::core_file &file, u32 skip_bytes, util::hash_collection &hashes, const char *types);
+ static std::error_condition run_hash(util::random_read &file, u32 skip_bytes, util::hash_collection &hashes, const char *types);
// loads an image or software items and resets - called internally when we
// load an is_reset_on_load() item
@@ -370,6 +307,8 @@ private:
// we want to disable command line cart loading...
bool m_user_loadable;
+ bool m_must_be_loaded;
+
bool m_is_loading;
bool m_is_reset_and_loading;
diff --git a/src/emu/dinetwork.cpp b/src/emu/dinetwork.cpp
index 69cc7e9235f..3ad9f4c925b 100644
--- a/src/emu/dinetwork.cpp
+++ b/src/emu/dinetwork.cpp
@@ -3,11 +3,13 @@
#include "emu.h"
#include "osdnet.h"
-device_network_interface::device_network_interface(const machine_config &mconfig, device_t &device, float bandwidth)
+device_network_interface::device_network_interface(const machine_config &mconfig, device_t &device, u32 bandwidth, u32 mtu)
: device_interface(device, "network")
{
m_promisc = false;
- m_bandwidth = bandwidth;
+ // Convert to Mibps to Bps
+ m_bandwidth = bandwidth << (20 - 3);
+ m_mtu = mtu;
set_mac("\0\0\0\0\0\0");
m_intf = -1;
m_loopback_control = false;
@@ -44,7 +46,7 @@ int device_network_interface::send(u8 *buf, int len, int fcs)
if (result)
{
// schedule receive complete callback
- m_recv_timer->adjust(attotime::from_ticks(len, m_bandwidth * 1'000'000 / 8), result);
+ m_recv_timer->adjust(attotime::from_ticks(len, m_bandwidth), result);
}
}
else if (m_dev)
@@ -56,7 +58,7 @@ int device_network_interface::send(u8 *buf, int len, int fcs)
}
// schedule transmit complete callback
- m_send_timer->adjust(attotime::from_ticks(len, m_bandwidth * 1'000'000 / 8), result);
+ m_send_timer->adjust(attotime::from_ticks(len, m_bandwidth), result);
return result;
}
@@ -84,7 +86,7 @@ void device_network_interface::recv_cb(u8 *buf, int len)
m_dev->stop();
// schedule receive complete callback
- m_recv_timer->adjust(attotime::from_ticks(len, m_bandwidth * 1'000'000 / 8), result);
+ m_recv_timer->adjust(attotime::from_ticks(len, m_bandwidth), result);
}
}
@@ -113,7 +115,8 @@ void device_network_interface::set_interface(int id)
{
if(m_dev)
m_dev->stop();
- m_dev.reset(open_netdev(id, this, (int)(m_bandwidth*1000000/8.0f/1500)));
+ // Set device polling time to transfer time for one mtu
+ m_dev.reset(open_netdev(id, this, (int)(m_bandwidth / m_mtu)));
if(!m_dev) {
device().logerror("Network interface %d not found\n", id);
id = -1;
diff --git a/src/emu/dinetwork.h b/src/emu/dinetwork.h
index 99909e93905..c2629f665fc 100644
--- a/src/emu/dinetwork.h
+++ b/src/emu/dinetwork.h
@@ -8,7 +8,7 @@ class osd_netdev;
class device_network_interface : public device_interface
{
public:
- device_network_interface(const machine_config &mconfig, device_t &device, float bandwidth);
+ device_network_interface(const machine_config &mconfig, device_t &device, u32 bandwidth, u32 mtu = 1500);
virtual ~device_network_interface();
void interface_pre_start() override;
@@ -39,7 +39,10 @@ protected:
bool m_promisc;
char m_mac[6];
- float m_bandwidth;
+ // bandwidth in bytes per second
+ u32 m_bandwidth;
+ // maximum transmission unit, used for device polling time
+ u32 m_mtu;
std::unique_ptr<osd_netdev> m_dev;
int m_intf;
bool m_loopback_control;
diff --git a/src/emu/dinvram.h b/src/emu/dinvram.h
index fb02a9c6e14..0549e183c6a 100644
--- a/src/emu/dinvram.h
+++ b/src/emu/dinvram.h
@@ -35,15 +35,15 @@ public:
// public accessors... for now
void nvram_reset() { nvram_default(); }
- void nvram_load(emu_file &file) { nvram_read(file); }
- void nvram_save(emu_file &file) { nvram_write(file); }
+ bool nvram_load(util::read_stream &file) { return nvram_read(file); }
+ bool nvram_save(util::write_stream &file) { return nvram_write(file); }
bool nvram_can_save() { return nvram_can_write(); }
protected:
// derived class overrides
virtual void nvram_default() = 0;
- virtual void nvram_read(emu_file &file) = 0;
- virtual void nvram_write(emu_file &file) = 0;
+ virtual bool nvram_read(util::read_stream &file) = 0;
+ virtual bool nvram_write(util::write_stream &file) = 0;
virtual bool nvram_can_write() { return true; }
};
diff --git a/src/emu/dislot.cpp b/src/emu/dislot.cpp
index e30cd41d46f..6f7bb4b592f 100644
--- a/src/emu/dislot.cpp
+++ b/src/emu/dislot.cpp
@@ -72,6 +72,42 @@ device_slot_interface::slot_option &device_slot_interface::option_add_internal(c
}
+device_slot_interface::slot_option &device_slot_interface::option_replace(const char *name, const device_type &devtype)
+{
+ if (!name || !*name)
+ throw emu_fatalerror("slot '%s' attempt to replace option without name\n", device().tag());
+
+ auto search = m_options.find(name);
+ if (search == m_options.end())
+ throw emu_fatalerror("slot '%s' attempt to replace nonexistent option '%s'\n", device().tag(), name);
+
+ return (search->second = std::make_unique<slot_option>(name, devtype, true))->clock(m_default_clock);
+}
+
+
+device_slot_interface::slot_option &device_slot_interface::option_replace_internal(const char *name, const device_type &devtype)
+{
+ if (!name || !*name)
+ throw emu_fatalerror("slot '%s' attempt to replace option without name\n", device().tag());
+
+ auto search = m_options.find(name);
+ if (search == m_options.end())
+ throw emu_fatalerror("slot '%s' attempt to replace nonexistent option '%s'\n", device().tag(), name);
+
+ return (search->second = std::make_unique<slot_option>(name, devtype, false))->clock(m_default_clock);
+}
+
+
+void device_slot_interface::option_remove(const char *name)
+{
+ if (!name || !*name)
+ throw emu_fatalerror("slot '%s' attempt to remove option without name\n", device().tag());
+
+ if (m_options.erase(name) == 0)
+ throw emu_fatalerror("slot '%s' attempt to remove nonexistent option '%s'\n", device().tag(), name);
+}
+
+
device_slot_interface::slot_option *device_slot_interface::config_option(const char *name)
{
auto const search = m_options.find(name);
diff --git a/src/emu/dislot.h b/src/emu/dislot.h
index 97d314028a2..dd2fde5fac1 100644
--- a/src/emu/dislot.h
+++ b/src/emu/dislot.h
@@ -132,6 +132,10 @@ public:
/// configuration.
slot_option &option_add_internal(const char *option, const device_type &devtype);
+ slot_option &option_replace(const char *option, const device_type &devtype);
+ slot_option &option_replace_internal(const char *option, const device_type &devtype);
+ void option_remove(const char *option);
+
void set_option_default_bios(const char *option, const char *default_bios) { config_option(option)->default_bios(default_bios); }
template <typename T> void set_option_machine_config(const char *option, T &&machine_config) { config_option(option)->machine_config(std::forward<T>(machine_config)); }
void set_option_device_input_defaults(const char *option, const input_device_default *default_input) { config_option(option)->input_device_defaults(default_input); }
diff --git a/src/emu/drivers/empty.cpp b/src/emu/drivers/empty.cpp
index 23cf5443013..6b60367403b 100644
--- a/src/emu/drivers/empty.cpp
+++ b/src/emu/drivers/empty.cpp
@@ -10,7 +10,7 @@
#include "emu.h"
#include "emuopts.h"
-#include "render.h"
+#include "screen.h"
//**************************************************************************
// DRIVER STATE
diff --git a/src/emu/drivers/testcpu.cpp b/src/emu/drivers/testcpu.cpp
index 574e6fc88b3..1cdb945db88 100644
--- a/src/emu/drivers/testcpu.cpp
+++ b/src/emu/drivers/testcpu.cpp
@@ -38,7 +38,7 @@ public:
}
// timer callback; used to wrest control of the system
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override
{
static const u32 sample_instructions[] =
{
diff --git a/src/emu/emu.h b/src/emu/emu.h
index d648ee932de..f4fa0c21888 100644
--- a/src/emu/emu.h
+++ b/src/emu/emu.h
@@ -18,6 +18,9 @@
#ifndef __EMU_H__
#define __EMU_H__
+// get forward declarations before anything else
+#include "emufwd.h"
+
#include <list>
#include <forward_list>
#include <vector>
@@ -34,17 +37,13 @@
#include "attotime.h"
#include "profiler.h"
-// http interface helpers
-#include "http.h"
-
// commonly-referenced utilities imported from lib/util
-#include "corealloc.h"
+#include "corefile.h"
+#include "delegate.h"
+#include "hash.h"
#include "palette.h"
// emulator-specific utilities
-#include "hash.h"
-#include "fileio.h"
-#include "delegate.h"
#include "devdelegate.h"
// memory and address spaces
diff --git a/src/emu/emucore.h b/src/emu/emucore.h
index 768fa8c7280..8074fb0fe73 100644
--- a/src/emu/emucore.h
+++ b/src/emu/emucore.h
@@ -13,35 +13,38 @@
#pragma once
-// standard C includes
-#include <cassert>
-#include <cmath>
-#include <cstdio>
-#include <cstring>
-#include <cstdlib>
-#include <cstdarg>
-
// some cleanups for Solaris for things defined in stdlib.h
#if defined(__sun__) && defined(__svr4__)
#undef si_status
#undef WWORD
#endif
-// standard C++ includes
-#include <exception>
-#include <string>
-#include <type_traits>
-#include <typeinfo>
+// centralised forward declarations
+#include "emufwd.h"
-// core system includes
-#include "osdcomm.h"
+// common stuff from lib/util
+#include "corealloc.h"
#include "coretmpl.h"
#include "bitmap.h"
#include "endianness.h"
#include "strformat.h"
#include "vecstream.h"
-#include "emufwd.h"
+// common stuff from osd
+#include "osdcomm.h"
+
+// standard C++ includes
+#include <exception>
+#include <string>
+#include <type_traits>
+#include <typeinfo>
+
+// standard C includes
+#include <cassert>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
//**************************************************************************
@@ -421,4 +424,11 @@ inline u64 d2u(double d)
return u.vv;
}
+
+//**************************************************************************
+// USEFUL UTILITIES
+//**************************************************************************
+
+using util::make_unique_clear;
+
#endif // MAME_EMU_EMUCORE_H
diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h
index 8b8e59b9250..6d0528015c4 100644
--- a/src/emu/emufwd.h
+++ b/src/emu/emufwd.h
@@ -152,6 +152,12 @@ class memory_view;
// declared in emuopts.h
class emu_options;
+// declared in fileio.h
+class emu_file;
+
+// declared in http.h
+class http_manager;
+
// declared in gamedrv.h
class game_driver;
diff --git a/src/emu/emumem.cpp b/src/emu/emumem.cpp
index 3982debf2cc..b08657c9087 100644
--- a/src/emu/emumem.cpp
+++ b/src/emu/emumem.cpp
@@ -865,62 +865,62 @@ void address_space_installer::populate_map_entry(const address_map_entry &entry,
-memory_passthrough_handler *address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 8-bits wide bus read tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 16-bits wide bus read tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 32-bits wide bus read tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 64-bits wide bus read tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 8-bits wide bus write tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 16-bits wide bus write tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 32-bits wide bus write tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 64-bits wide bus write tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 8-bits wide bus read/write tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 16-bits wide bus read/write tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph)
{
fatalerror("Tryingw to install a 32-bits wide bus read/write tap in a %d-bits wide bus\n", data_width());
}
-memory_passthrough_handler *address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph)
+memory_passthrough_handler address_space_installer::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph)
{
fatalerror("Trying to install a 64-bits wide bus read/write tap in a %d-bits wide bus\n", data_width());
}
diff --git a/src/emu/emumem.h b/src/emu/emumem.h
index 3d4d664469e..c805de6155c 100644
--- a/src/emu/emumem.h
+++ b/src/emu/emumem.h
@@ -17,6 +17,8 @@
#ifndef MAME_EMU_EMUMEM_H
#define MAME_EMU_EMUMEM_H
+#include "notifier.h"
+
#include <optional>
#include <set>
#include <type_traits>
@@ -50,6 +52,14 @@ enum class read_or_write
};
+//**************************************************************************
+// FORWARD DECLARATIONS
+//**************************************************************************
+
+class handler_entry;
+template<int Width, int AddrShift> class handler_entry_read_passthrough;
+template<int Width, int AddrShift> class handler_entry_write_passthrough;
+
//**************************************************************************
// TYPE DEFINITIONS
@@ -90,7 +100,7 @@ struct memory_entry_context {
struct memory_entry {
offs_t start, end;
- class handler_entry *entry;
+ handler_entry *entry;
std::vector<memory_entry_context> context;
};
@@ -465,6 +475,29 @@ constexpr int handler_entry_dispatch_lowbits(int highbits, int width, int ashift
width + ashift;
}
+
+// =====================-> Passthrough handler management structure
+
+class memory_passthrough_handler_impl
+{
+public:
+ memory_passthrough_handler_impl(address_space &space) : m_space(space) {}
+ memory_passthrough_handler_impl(memory_passthrough_handler_impl const &) = delete;
+
+ void remove();
+
+private:
+ address_space &m_space;
+ std::unordered_set<handler_entry *> m_handlers;
+
+ void add_handler(handler_entry *handler) { m_handlers.insert(handler); }
+ void remove_handler(handler_entry *handler) { m_handlers.erase(m_handlers.find(handler)); }
+
+ friend address_space;
+ template<int Width, int AddrShift> friend class ::handler_entry_read_passthrough;
+ template<int Width, int AddrShift> friend class ::handler_entry_write_passthrough;
+};
+
} // namespace emu::detail
@@ -561,8 +594,6 @@ protected:
// Provides the populate/read/get_ptr/lookup API
-template<int Width, int AddrShift> class handler_entry_read_passthrough;
-
template<int Width, int AddrShift> class handler_entry_read : public handler_entry
{
public:
@@ -596,7 +627,7 @@ public:
virtual void populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read<Width, AddrShift> *handler);
virtual void populate_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read<Width, AddrShift> *handler);
- inline void populate_mismatched(offs_t start, offs_t end, offs_t mirror, const memory_units_descriptor<Width, AddrShift> &descriptor) {
+ void populate_mismatched(offs_t start, offs_t end, offs_t mirror, const memory_units_descriptor<Width, AddrShift> &descriptor) {
start &= ~NATIVE_MASK;
end |= NATIVE_MASK;
std::vector<mapping> mappings;
@@ -609,7 +640,7 @@ public:
virtual void populate_mismatched_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, const memory_units_descriptor<Width, AddrShift> &descriptor, u8 rkey, std::vector<mapping> &mappings);
virtual void populate_mismatched_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, const memory_units_descriptor<Width, AddrShift> &descriptor, std::vector<mapping> &mappings);
- inline void populate_passthrough(offs_t start, offs_t end, offs_t mirror, handler_entry_read_passthrough<Width, AddrShift> *handler) {
+ void populate_passthrough(offs_t start, offs_t end, offs_t mirror, handler_entry_read_passthrough<Width, AddrShift> *handler) {
start &= ~NATIVE_MASK;
end |= NATIVE_MASK;
std::vector<mapping> mappings;
@@ -636,8 +667,6 @@ public:
// Provides the populate/write/get_ptr/lookup API
-template<int Width, int AddrShift> class handler_entry_write_passthrough;
-
template<int Width, int AddrShift> class handler_entry_write : public handler_entry
{
public:
@@ -711,20 +740,21 @@ public:
// =====================-> Passthrough handler management structure
class memory_passthrough_handler
{
- template<int Width, int AddrShift> friend class handler_entry_read_passthrough;
- template<int Width, int AddrShift> friend class handler_entry_write_passthrough;
-
public:
- memory_passthrough_handler(address_space &space) : m_space(space) {}
+ memory_passthrough_handler() : m_impl() {}
+ memory_passthrough_handler(std::shared_ptr<emu::detail::memory_passthrough_handler_impl> const &impl) : m_impl(impl) {}
- inline void remove();
+ void remove()
+ {
+ auto impl(m_impl.lock());
+ if (impl)
+ impl->remove();
+ }
private:
- address_space &m_space;
- std::unordered_set<handler_entry *> m_handlers;
+ std::weak_ptr<emu::detail::memory_passthrough_handler_impl> m_impl;
- void add_handler(handler_entry *handler) { m_handlers.insert(handler); }
- void remove_handler(handler_entry *handler) { m_handlers.erase(m_handlers.find(handler)); }
+ friend class address_space;
};
// =====================-> Forward declaration for address_space
@@ -1543,6 +1573,8 @@ private:
handler_entry_read <Width, AddrShift> *m_root_read; // decode tree roots
handler_entry_write<Width, AddrShift> *m_root_write;
+ util::notifier_subscription m_subscription;
+
NativeType read_native(offs_t address, NativeType mask = ~NativeType(0));
void write_native(offs_t address, NativeType data, NativeType mask = ~NativeType(0));
std::pair<NativeType, u16> read_native_flags(offs_t address, NativeType mask = ~NativeType(0));
@@ -1687,32 +1719,32 @@ public:
virtual void install_device_delegate(offs_t addrstart, offs_t addrend, device_t &device, address_map_constructor &map, u64 unitmask = 0, int cswidth = 0, u16 flags = 0) = 0;
// install taps without mirroring
- memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
- memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
- memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
- memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
- memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
- memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
- memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
- memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
- memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
- memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
- memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
- memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
+ memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
+ memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
+ memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
+ memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_read_tap(addrstart, addrend, 0, name, tap, mph); }
+ memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
+ memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
+ memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
+ memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr) { return install_write_tap(addrstart, addrend, 0, name, tap, mph); }
+ memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
+ memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
+ memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
+ memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr) { return install_readwrite_tap(addrstart, addrend, 0, name, tapr, tapw, mph); }
// install taps with mirroring
- virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
- virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tap, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapr, std::function<void (offs_t offset, u8 &data, u8 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapr, std::function<void (offs_t offset, u16 &data, u16 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapr, std::function<void (offs_t offset, u32 &data, u32 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
+ virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapr, std::function<void (offs_t offset, u64 &data, u64 mem_mask)> tapw, memory_passthrough_handler *mph = nullptr);
// install views
void install_view(offs_t addrstart, offs_t addrend, memory_view &view) { install_view(addrstart, addrend, 0, view); }
@@ -1918,11 +1950,6 @@ class address_space : public address_space_installer
template<int Width, int AddrShift> friend class handler_entry_read_unmapped;
template<int Width, int AddrShift> friend class handler_entry_write_unmapped;
- struct notifier_t {
- std::function<void (read_or_write)> m_notifier;
- int m_id;
- };
-
protected:
// construction/destruction
address_space(memory_manager &manager, device_memory_interface &memory, int spacenum);
@@ -1962,15 +1989,14 @@ public:
v.set(this, get_specific_info());
}
- int add_change_notifier(std::function<void (read_or_write)> n);
- void remove_change_notifier(int id);
+ util::notifier_subscription add_change_notifier(delegate<void (read_or_write)> &&n);
+ template <typename T> util::notifier_subscription add_change_notifier(T &&n) { return add_change_notifier(delegate<void (read_or_write)>(std::forward<T>(n))); }
void invalidate_caches(read_or_write mode) {
if(u32(mode) & ~m_in_notification) {
u32 old = m_in_notification;
m_in_notification |= u32(mode);
- for(const auto &n : m_notifiers)
- n.m_notifier(mode);
+ m_notifiers(mode);
m_in_notification = old;
}
}
@@ -1981,7 +2007,7 @@ public:
u64 unmap() const { return m_unmap; }
- memory_passthrough_handler *make_mph();
+ std::shared_ptr<emu::detail::memory_passthrough_handler_impl> make_mph(memory_passthrough_handler *mph);
// debug helpers
virtual std::string get_handler_string(read_or_write readorwrite, offs_t byteaddress) const = 0;
@@ -2088,10 +2114,9 @@ protected:
handler_entry *m_nop_r;
handler_entry *m_nop_w;
- std::vector<std::unique_ptr<memory_passthrough_handler>> m_mphs;
+ std::vector<std::shared_ptr<emu::detail::memory_passthrough_handler_impl>> m_mphs;
- std::vector<notifier_t> m_notifiers; // notifier list for address map change
- int m_notifier_id; // next notifier id
+ util::notifier<read_or_write> m_notifiers; // notifier list for address map change
u32 m_in_notification; // notification(s) currently being done
};
@@ -2397,7 +2422,7 @@ write_native(offs_t address, typename emu::detail::handler_entry_size<Width>::uX
m_cache_w->write(address, data, mask);
}
-void memory_passthrough_handler::remove()
+inline void emu::detail::memory_passthrough_handler_impl::remove()
{
m_space.remove_passthrough(m_handlers);
}
@@ -2421,18 +2446,19 @@ set(address_space *space, std::pair<void *, void *> rw)
m_space = space;
m_addrmask = space->addrmask();
- space->add_change_notifier([this](read_or_write mode) {
- if(u32(mode) & u32(read_or_write::READ)) {
- m_addrend_r = 0;
- m_addrstart_r = 1;
- m_cache_r = nullptr;
- }
- if(u32(mode) & u32(read_or_write::WRITE)) {
- m_addrend_w = 0;
- m_addrstart_w = 1;
- m_cache_w = nullptr;
- }
- });
+ m_subscription = space->add_change_notifier(
+ [this] (read_or_write mode) {
+ if(u32(mode) & u32(read_or_write::READ)) {
+ m_addrend_r = 0;
+ m_addrstart_r = 1;
+ m_cache_r = nullptr;
+ }
+ if(u32(mode) & u32(read_or_write::WRITE)) {
+ m_addrend_w = 0;
+ m_addrstart_w = 1;
+ m_cache_w = nullptr;
+ }
+ });
m_root_read = (handler_entry_read <Width, AddrShift> *)(rw.first);
m_root_write = (handler_entry_write<Width, AddrShift> *)(rw.second);
diff --git a/src/emu/emumem_aspace.cpp b/src/emu/emumem_aspace.cpp
index 5aeea17c11a..cf7302ce104 100644
--- a/src/emu/emumem_aspace.cpp
+++ b/src/emu/emumem_aspace.cpp
@@ -292,9 +292,9 @@ public:
using address_space::install_write_tap;
using address_space::install_readwrite_tap;
- virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
- virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
- virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph) override;
+ virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
+ virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
+ virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph) override;
// construction/destruction
address_space_specific(memory_manager &manager, device_memory_interface &memory, int spacenum, int address_width)
@@ -810,7 +810,6 @@ address_space::address_space(memory_manager &manager, device_memory_interface &m
m_spacenum(spacenum),
m_log_unmap(true),
m_name(memory.space_config(spacenum)->name()),
- m_notifier_id(0),
m_in_notification(0)
{
}
@@ -1084,73 +1083,78 @@ template<int Level, int Width, int AddrShift, endianness_t Endian> void address_
view.make_subdispatch(""); // Must be called after populate
}
-memory_passthrough_handler *address_space::make_mph()
+std::shared_ptr<emu::detail::memory_passthrough_handler_impl> address_space::make_mph(memory_passthrough_handler *mph)
{
- m_mphs.emplace_back(std::make_unique<memory_passthrough_handler>(*this));
- return m_mphs.back().get();
+ if (mph)
+ {
+ auto impl(mph->m_impl.lock());
+ if (impl)
+ {
+ assert(&impl->m_space == this);
+ return impl;
+ }
+ }
+ return m_mphs.emplace_back(std::make_shared<emu::detail::memory_passthrough_handler_impl>(*this));
}
//-------------------------------------------------
// install_read_tap - install a read tap on the bus
//-------------------------------------------------
-template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler *address_space_specific<Level, Width, AddrShift, Endian>::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
+template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler address_space_specific<Level, Width, AddrShift, Endian>::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
{
offs_t nstart, nend, nmask, nmirror;
check_optimize_mirror("install_read_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
- if (!mph)
- mph = make_mph();
+ auto impl = make_mph(mph);
- auto handler = new handler_entry_read_tap<Width, AddrShift>(this, *mph, name, tap);
+ auto handler = new handler_entry_read_tap<Width, AddrShift>(this, *impl, name, tap);
m_root_read->populate_passthrough(nstart, nend, nmirror, handler);
handler->unref();
invalidate_caches(read_or_write::READ);
- return mph;
+ return impl;
}
//-------------------------------------------------
// install_write_tap - install a write tap on the bus
//-------------------------------------------------
-template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler *address_space_specific<Level, Width, AddrShift, Endian>::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
+template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler address_space_specific<Level, Width, AddrShift, Endian>::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
{
offs_t nstart, nend, nmask, nmirror;
check_optimize_mirror("install_write_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
- if (!mph)
- mph = make_mph();
+ auto impl = make_mph(mph);
- auto handler = new handler_entry_write_tap<Width, AddrShift>(this, *mph, name, tap);
+ auto handler = new handler_entry_write_tap<Width, AddrShift>(this, *impl, name, tap);
m_root_write->populate_passthrough(nstart, nend, nmirror, handler);
handler->unref();
invalidate_caches(read_or_write::WRITE);
- return mph;
+ return impl;
}
//-------------------------------------------------
// install_write_tap - install a read and a write tap on the bus
//-------------------------------------------------
-template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler *address_space_specific<Level, Width, AddrShift, Endian>::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph)
+template<int Level, int Width, int AddrShift, endianness_t Endian> memory_passthrough_handler address_space_specific<Level, Width, AddrShift, Endian>::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph)
{
offs_t nstart, nend, nmask, nmirror;
check_optimize_mirror("install_readwrite_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
- if (!mph)
- mph = make_mph();
+ auto impl = make_mph(mph);
- auto rhandler = new handler_entry_read_tap <Width, AddrShift>(this, *mph, name, tapr);
+ auto rhandler = new handler_entry_read_tap <Width, AddrShift>(this, *impl, name, tapr);
m_root_read ->populate_passthrough(nstart, nend, nmirror, rhandler);
rhandler->unref();
- auto whandler = new handler_entry_write_tap<Width, AddrShift>(this, *mph, name, tapw);
+ auto whandler = new handler_entry_write_tap<Width, AddrShift>(this, *impl, name, tapw);
m_root_write->populate_passthrough(nstart, nend, nmirror, whandler);
whandler->unref();
invalidate_caches(read_or_write::READWRITE);
- return mph;
+ return impl;
}
@@ -1291,19 +1295,7 @@ template<int Level, int Width, int AddrShift, endianness_t Endian> void address_
// MEMORY MAPPING HELPERS
//**************************************************************************
-int address_space::add_change_notifier(std::function<void (read_or_write)> n)
+util::notifier_subscription address_space::add_change_notifier(delegate<void (read_or_write)> &&n)
{
- int id = m_notifier_id++;
- m_notifiers.emplace_back(notifier_t{ std::move(n), id });
- return id;
-}
-
-void address_space::remove_change_notifier(int id)
-{
- for(auto i = m_notifiers.begin(); i != m_notifiers.end(); i++)
- if (i->m_id == id) {
- m_notifiers.erase(i);
- return;
- }
- fatalerror("Unknown notifier id %d, double remove?\n", id);
+ return m_notifiers.subscribe(std::move(n));
}
diff --git a/src/emu/emumem_hep.h b/src/emu/emumem_hep.h
index 60fc422b72e..a98b44c267d 100644
--- a/src/emu/emumem_hep.h
+++ b/src/emu/emumem_hep.h
@@ -10,7 +10,7 @@ template<int Width, int AddrShift> class handler_entry_read_passthrough : public
public:
using uX = typename emu::detail::handler_entry_size<Width>::uX;
- handler_entry_read_passthrough(address_space *space, memory_passthrough_handler &mph) : handler_entry_read<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(nullptr) {}
+ handler_entry_read_passthrough(address_space *space, emu::detail::memory_passthrough_handler_impl &mph) : handler_entry_read<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(nullptr) {}
~handler_entry_read_passthrough();
virtual handler_entry_read_passthrough<Width, AddrShift> *instantiate(handler_entry_read<Width, AddrShift> *next) const = 0;
@@ -20,10 +20,10 @@ public:
void detach(const std::unordered_set<handler_entry *> &handlers) override;
protected:
- memory_passthrough_handler &m_mph;
+ emu::detail::memory_passthrough_handler_impl &m_mph;
handler_entry_read<Width, AddrShift> *m_next;
- handler_entry_read_passthrough(address_space *space, memory_passthrough_handler &mph, handler_entry_read<Width, AddrShift> *next) : handler_entry_read<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(next) { next->ref(); mph.add_handler(this); }
+ handler_entry_read_passthrough(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, handler_entry_read<Width, AddrShift> *next) : handler_entry_read<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(next) { next->ref(); mph.add_handler(this); }
};
template<int Width, int AddrShift> class handler_entry_write_passthrough : public handler_entry_write<Width, AddrShift>
@@ -31,7 +31,7 @@ template<int Width, int AddrShift> class handler_entry_write_passthrough : publi
public:
using uX = typename emu::detail::handler_entry_size<Width>::uX;
- handler_entry_write_passthrough(address_space *space, memory_passthrough_handler &mph) : handler_entry_write<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(nullptr) {}
+ handler_entry_write_passthrough(address_space *space, emu::detail::memory_passthrough_handler_impl &mph) : handler_entry_write<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(nullptr) {}
~handler_entry_write_passthrough();
virtual handler_entry_write_passthrough<Width, AddrShift> *instantiate(handler_entry_write<Width, AddrShift> *next) const = 0;
@@ -41,8 +41,8 @@ public:
void detach(const std::unordered_set<handler_entry *> &handlers) override;
protected:
- memory_passthrough_handler &m_mph;
+ emu::detail::memory_passthrough_handler_impl &m_mph;
handler_entry_write<Width, AddrShift> *m_next;
- handler_entry_write_passthrough(address_space *space, memory_passthrough_handler &mph, handler_entry_write<Width, AddrShift> *next) : handler_entry_write<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(next) { next->ref(); mph.add_handler(this); }
+ handler_entry_write_passthrough(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, handler_entry_write<Width, AddrShift> *next) : handler_entry_write<Width, AddrShift>(space, handler_entry::F_PASSTHROUGH), m_mph(mph), m_next(next) { next->ref(); mph.add_handler(this); }
};
diff --git a/src/emu/emumem_het.h b/src/emu/emumem_het.h
index 2914605772b..a148e3d3533 100644
--- a/src/emu/emumem_het.h
+++ b/src/emu/emumem_het.h
@@ -14,7 +14,7 @@ template<int Width, int AddrShift> class handler_entry_read_tap : public handler
public:
using uX = typename emu::detail::handler_entry_size<Width>::uX;
- handler_entry_read_tap(address_space *space, memory_passthrough_handler &mph, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_read_passthrough<Width, AddrShift>(space, mph), m_name(name), m_tap(std::move(tap)) {}
+ handler_entry_read_tap(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_read_passthrough<Width, AddrShift>(space, mph), m_name(name), m_tap(std::move(tap)) {}
~handler_entry_read_tap() = default;
uX read(offs_t offset, uX mem_mask) const override;
@@ -28,7 +28,7 @@ protected:
std::string m_name;
std::function<void (offs_t offset, uX &data, uX mem_mask)> m_tap;
- handler_entry_read_tap(address_space *space, memory_passthrough_handler &mph, handler_entry_read<Width, AddrShift> *next, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_read_passthrough<Width, AddrShift>(space, mph, next), m_name(name), m_tap(tap) {}
+ handler_entry_read_tap(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, handler_entry_read<Width, AddrShift> *next, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_read_passthrough<Width, AddrShift>(space, mph, next), m_name(name), m_tap(tap) {}
};
template<int Width, int AddrShift> class handler_entry_write_tap : public handler_entry_write_passthrough<Width, AddrShift>
@@ -36,7 +36,7 @@ template<int Width, int AddrShift> class handler_entry_write_tap : public handle
public:
using uX = typename emu::detail::handler_entry_size<Width>::uX;
- handler_entry_write_tap(address_space *space, memory_passthrough_handler &mph, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_write_passthrough<Width, AddrShift>(space, mph), m_name(name), m_tap(std::move(tap)) {}
+ handler_entry_write_tap(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_write_passthrough<Width, AddrShift>(space, mph), m_name(name), m_tap(std::move(tap)) {}
~handler_entry_write_tap() = default;
void write(offs_t offset, uX data, uX mem_mask) const override;
@@ -50,7 +50,7 @@ protected:
std::string m_name;
std::function<void (offs_t offset, uX &data, uX mem_mask)> m_tap;
- handler_entry_write_tap(address_space *space, memory_passthrough_handler &mph, handler_entry_write<Width, AddrShift> *next, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_write_passthrough<Width, AddrShift>(space, mph, next), m_name(name), m_tap(tap) {}
+ handler_entry_write_tap(address_space *space, emu::detail::memory_passthrough_handler_impl &mph, handler_entry_write<Width, AddrShift> *next, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap) : handler_entry_write_passthrough<Width, AddrShift>(space, mph, next), m_name(name), m_tap(tap) {}
};
#endif // MAME_EMU_EMUMEM_HET_H
diff --git a/src/emu/emumem_mview.cpp b/src/emu/emumem_mview.cpp
index 06007c7d0b5..b916e3f951f 100644
--- a/src/emu/emumem_mview.cpp
+++ b/src/emu/emumem_mview.cpp
@@ -126,9 +126,9 @@ public:
using address_space_installer::install_write_tap;
using address_space_installer::install_readwrite_tap;
- virtual memory_passthrough_handler *install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
- virtual memory_passthrough_handler *install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
- virtual memory_passthrough_handler *install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph) override;
+ virtual memory_passthrough_handler install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
+ virtual memory_passthrough_handler install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph) override;
+ virtual memory_passthrough_handler install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph) override;
virtual void unmap_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, u16 flags, read_or_write readorwrite, bool quiet) override;
virtual void install_ram_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, u16 flags, read_or_write readorwrite, void *baseptr) override;
@@ -898,65 +898,62 @@ template<int Level, int Width, int AddrShift> void memory_view_entry_specific<Le
view.make_subdispatch(key()); // Must be called after populate
}
-template<int Level, int Width, int AddrShift> memory_passthrough_handler *memory_view_entry_specific<Level, Width, AddrShift>::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
+template<int Level, int Width, int AddrShift> memory_passthrough_handler memory_view_entry_specific<Level, Width, AddrShift>::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
{
offs_t nstart, nend, nmask, nmirror;
check_range_optimize_mirror("install_read_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
- if (!mph)
- mph = m_view.m_space->make_mph();
+ auto impl = m_view.m_space->make_mph(mph);
r()->select_u(m_id);
w()->select_u(m_id);
- auto handler = new handler_entry_read_tap<Width, AddrShift>(m_view.m_space, *mph, name, tap);
+ auto handler = new handler_entry_read_tap<Width, AddrShift>(m_view.m_space, *impl, name, tap);
r()->populate_passthrough(nstart, nend, nmirror, handler);
handler->unref();
invalidate_caches(read_or_write::READ);
- return mph;
+ return impl;
}
-template<int Level, int Width, int AddrShift> memory_passthrough_handler *memory_view_entry_specific<Level, Width, AddrShift>::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
+template<int Level, int Width, int AddrShift> memory_passthrough_handler memory_view_entry_specific<Level, Width, AddrShift>::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tap, memory_passthrough_handler *mph)
{
offs_t nstart, nend, nmask, nmirror;
check_range_optimize_mirror("install_write_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
- if (!mph)
- mph = m_view.m_space->make_mph();
+ auto impl = m_view.m_space->make_mph(mph);
r()->select_u(m_id);
w()->select_u(m_id);
- auto handler = new handler_entry_write_tap<Width, AddrShift>(m_view.m_space, *mph, name, tap);
+ auto handler = new handler_entry_write_tap<Width, AddrShift>(m_view.m_space, *impl, name, tap);
w()->populate_passthrough(nstart, nend, nmirror, handler);
handler->unref();
invalidate_caches(read_or_write::WRITE);
- return mph;
+ return impl;
}
-template<int Level, int Width, int AddrShift> memory_passthrough_handler *memory_view_entry_specific<Level, Width, AddrShift>::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph)
+template<int Level, int Width, int AddrShift> memory_passthrough_handler memory_view_entry_specific<Level, Width, AddrShift>::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapr, std::function<void (offs_t offset, uX &data, uX mem_mask)> tapw, memory_passthrough_handler *mph)
{
offs_t nstart, nend, nmask, nmirror;
check_range_optimize_mirror("install_readwrite_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror);
- if (!mph)
- mph = m_view.m_space->make_mph();
+ auto impl = m_view.m_space->make_mph(mph);
r()->select_u(m_id);
w()->select_u(m_id);
- auto rhandler = new handler_entry_read_tap <Width, AddrShift>(m_view.m_space, *mph, name, tapr);
+ auto rhandler = new handler_entry_read_tap <Width, AddrShift>(m_view.m_space, *impl, name, tapr);
r() ->populate_passthrough(nstart, nend, nmirror, rhandler);
rhandler->unref();
- auto whandler = new handler_entry_write_tap<Width, AddrShift>(m_view.m_space, *mph, name, tapw);
+ auto whandler = new handler_entry_write_tap<Width, AddrShift>(m_view.m_space, *impl, name, tapw);
w()->populate_passthrough(nstart, nend, nmirror, whandler);
whandler->unref();
invalidate_caches(read_or_write::READWRITE);
- return mph;
+ return impl;
}
template<int Level, int Width, int AddrShift> void memory_view_entry_specific<Level, Width, AddrShift>::install_device_delegate(offs_t addrstart, offs_t addrend, device_t &device, address_map_constructor &delegate, u64 unitmask, int cswidth, u16 flags)
diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp
index 8959c00da03..5a1722df737 100644
--- a/src/emu/emuopts.cpp
+++ b/src/emu/emuopts.cpp
@@ -528,7 +528,7 @@ void emu_options::update_slot_and_image_options()
if (add_and_remove_slot_options())
changed = true;
- // second, we perform an analgous operation with m_image_options
+ // second, we perform an analogous operation with m_image_options
if (add_and_remove_image_options())
changed = true;
@@ -1220,8 +1220,8 @@ void slot_option::set_bios(std::string &&text)
{
if (!m_specified)
{
- m_specified = true;
m_specified_value = value();
+ m_specified = true;
}
m_specified_bios = std::move(text);
}
diff --git a/src/emu/fileio.cpp b/src/emu/fileio.cpp
index 6d5d6b8a806..a1bf4adbcb4 100644
--- a/src/emu/fileio.cpp
+++ b/src/emu/fileio.cpp
@@ -107,7 +107,7 @@ path_iterator &path_iterator::operator=(path_iterator const &that)
// multipath sequence
//-------------------------------------------------
-bool path_iterator::next(std::string &buffer, const char *name)
+bool path_iterator::next(std::string &buffer)
{
// if none left, return false to indicate we are done
if (!m_is_first && (m_searchpath.cend() == m_current))
@@ -120,10 +120,6 @@ bool path_iterator::next(std::string &buffer, const char *name)
if (m_searchpath.cend() != m_current)
++m_current;
- // append the name if we have one
- if (name)
- util::path_append(buffer, name);
-
// bump the index and return true
m_is_first = false;
return true;
@@ -160,9 +156,13 @@ const osd::directory::entry *file_enumerator::next(const char *subdir)
while (!m_curdir)
{
// if we fail to get anything more, we're done
- if (!m_iterator.next(m_pathbuffer, subdir))
+ if (!m_iterator.next(m_pathbuffer))
return nullptr;
+ // append the subdir if we have one
+ if (subdir)
+ util::path_append(m_pathbuffer, subdir);
+
// open the path
m_curdir = osd::directory::open(m_pathbuffer);
}
@@ -259,7 +259,7 @@ util::hash_collection &emu_file::hashes(std::string_view types)
// determine which hashes we need
std::string needed;
for (char scan : types)
- if (already_have.find_first_of(scan) == -1)
+ if (already_have.find_first_of(scan) == std::string::npos)
needed.push_back(scan);
// if we need nothing, skip it
@@ -279,15 +279,14 @@ util::hash_collection &emu_file::hashes(std::string_view types)
return m_hashes;
}
- // read the data if we can
- const u8 *filedata = (const u8 *)m_file->buffer();
- if (filedata == nullptr)
+ std::uint64_t length;
+ if (m_file->length(length))
return m_hashes;
- // compute the hash
- std::uint64_t length;
- if (!m_file->length(length))
- m_hashes.compute(filedata, length, needed.c_str());
+ // hash the data
+ std::size_t actual;
+ (void)m_hashes.compute(*m_file, 0U, length, actual, needed.c_str()); // FIXME: need better interface to report errors
+
return m_hashes;
}
@@ -805,7 +804,7 @@ std::error_condition emu_file::load_zipped_file()
m_zipdata.resize(m_ziplength);
// read the data into our buffer and return
- auto const ziperr = m_zipfile->decompress(&m_zipdata[0], m_zipdata.size());
+ auto const ziperr = m_zipfile->decompress(m_zipdata.data(), m_zipdata.size());
if (ziperr)
{
m_zipdata.clear();
@@ -813,7 +812,7 @@ std::error_condition emu_file::load_zipped_file()
}
// convert to RAM file
- std::error_condition const filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file);
+ std::error_condition const filerr = util::core_file::open_ram(m_zipdata.data(), m_zipdata.size(), m_openflags, m_file);
if (filerr)
{
m_zipdata.clear();
diff --git a/src/emu/fileio.h b/src/emu/fileio.h
index 91aedad173e..7398e649c6e 100644
--- a/src/emu/fileio.h
+++ b/src/emu/fileio.h
@@ -61,7 +61,7 @@ public:
path_iterator &operator=(path_iterator const &that);
// main interface
- bool next(std::string &buffer, const char *name = nullptr);
+ bool next(std::string &buffer);
void reset();
private:
diff --git a/src/emu/hashfile.cpp b/src/emu/hashfile.cpp
index a6107e5e630..8436ad339fb 100644
--- a/src/emu/hashfile.cpp
+++ b/src/emu/hashfile.cpp
@@ -13,6 +13,7 @@
#include "drivenum.h"
#include "emuopts.h"
+#include "fileio.h"
#include "hash.h"
diff --git a/src/emu/http.cpp b/src/emu/http.cpp
index f36244e31ac..8c95e731552 100644
--- a/src/emu/http.cpp
+++ b/src/emu/http.cpp
@@ -9,6 +9,9 @@
***************************************************************************/
#include "emu.h"
+#include "http.h"
+#include "server_http.hpp"
+#include "server_ws.hpp"
#ifdef __sun
#define ASIO_DISABLE_DEV_POLL
diff --git a/src/emu/http.h b/src/emu/http.h
index b0adf1e2b3d..e7c26d7980f 100644
--- a/src/emu/http.h
+++ b/src/emu/http.h
@@ -10,18 +10,12 @@
#pragma once
-#ifndef __EMU_H__
-#error Dont include this file directly; include emu.h instead.
-#endif
-
#ifndef MAME_EMU_HTTP_H
#define MAME_EMU_HTTP_H
#include <mutex>
#include <thread>
#include <ctime>
-#include "server_http.hpp"
-#include "server_ws.hpp"
//**************************************************************************
// TYPE DEFINITIONS
@@ -33,6 +27,13 @@ namespace asio
class io_context;
}
+namespace webpp
+{
+ class http_server;
+ class ws_server;
+ struct Connection;
+}
+
class http_manager
{
DISABLE_COPYING(http_manager);
diff --git a/src/emu/image.cpp b/src/emu/image.cpp
index 5e58758eb89..e7f070eb9ea 100644
--- a/src/emu/image.cpp
+++ b/src/emu/image.cpp
@@ -14,6 +14,7 @@
#include "config.h"
#include "drivenum.h"
#include "emuopts.h"
+#include "fileio.h"
#include "softlist.h"
#include "corestr.h"
diff --git a/src/emu/image.h b/src/emu/image.h
index daf48b1f21d..95dca8a92b9 100644
--- a/src/emu/image.h
+++ b/src/emu/image.h
@@ -36,7 +36,7 @@ private:
void options_extract();
int write_config(emu_options &options, const char *filename, const game_driver *gamedrv);
- bool try_change_working_directory(std::string &working_directory, const std::string &subdir);;
+ bool try_change_working_directory(std::string &working_directory, const std::string &subdir);
// internal state
running_machine & m_machine; // reference to our machine
diff --git a/src/emu/inpttype.ipp b/src/emu/inpttype.ipp
index aca3973673a..03f6e3e1dab 100644
--- a/src/emu/inpttype.ipp
+++ b/src/emu/inpttype.ipp
@@ -19,83 +19,83 @@ namespace {
#define CORE_INPUT_TYPES_P1 \
CORE_INPUT_TYPES_BEGIN(p1) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_UP, N_p("input-name", "P1 Up"), input_seq(KEYCODE_UP, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_DOWN, N_p("input-name", "P1 Down"), input_seq(KEYCODE_DOWN, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_LEFT, N_p("input-name", "P1 Left"), input_seq(KEYCODE_LEFT, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_RIGHT, N_p("input-name", "P1 Right"), input_seq(KEYCODE_RIGHT, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_UP, N_p("input-name", "P1 Right Stick/Up"), input_seq(KEYCODE_I, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_DOWN, N_p("input-name", "P1 Right Stick/Down"), input_seq(KEYCODE_K, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_LEFT, N_p("input-name", "P1 Right Stick/Left"), input_seq(KEYCODE_J, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_RIGHT, N_p("input-name", "P1 Right Stick/Right"), input_seq(KEYCODE_L, input_seq::or_code, JOYCODE_BUTTON4_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_UP, N_p("input-name", "P1 Left Stick/Up"), input_seq(KEYCODE_E, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_DOWN, N_p("input-name", "P1 Left Stick/Down"), input_seq(KEYCODE_D, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_LEFT, N_p("input-name", "P1 Left Stick/Left"), input_seq(KEYCODE_S, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_RIGHT, N_p("input-name", "P1 Left Stick/Right"), input_seq(KEYCODE_F, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON1, N_p("input-name", "P1 Button 1"), input_seq(KEYCODE_LCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0), input_seq::or_code, MOUSECODE_BUTTON1_INDEXED(0), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON2, N_p("input-name", "P1 Button 2"), input_seq(KEYCODE_LALT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(0), input_seq::or_code, MOUSECODE_BUTTON3_INDEXED(0), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON3, N_p("input-name", "P1 Button 3"), input_seq(KEYCODE_SPACE, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(0), input_seq::or_code, MOUSECODE_BUTTON2_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON4, N_p("input-name", "P1 Button 4"), input_seq(KEYCODE_LSHIFT, input_seq::or_code, JOYCODE_BUTTON4_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON5, N_p("input-name", "P1 Button 5"), input_seq(KEYCODE_Z, input_seq::or_code, JOYCODE_BUTTON5_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON6, N_p("input-name", "P1 Button 6"), input_seq(KEYCODE_X, input_seq::or_code, JOYCODE_BUTTON6_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON7, N_p("input-name", "P1 Button 7"), input_seq(KEYCODE_C, input_seq::or_code, JOYCODE_BUTTON7_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON8, N_p("input-name", "P1 Button 8"), input_seq(KEYCODE_V, input_seq::or_code, JOYCODE_BUTTON8_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON9, N_p("input-name", "P1 Button 9"), input_seq(KEYCODE_B, input_seq::or_code, JOYCODE_BUTTON9_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON10, N_p("input-name", "P1 Button 10"), input_seq(KEYCODE_N, input_seq::or_code, JOYCODE_BUTTON10_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON11, N_p("input-name", "P1 Button 11"), input_seq(KEYCODE_M, input_seq::or_code, JOYCODE_BUTTON11_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON12, N_p("input-name", "P1 Button 12"), input_seq(KEYCODE_COMMA, input_seq::or_code, JOYCODE_BUTTON12_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON13, N_p("input-name", "P1 Button 13"), input_seq(KEYCODE_STOP, input_seq::or_code, JOYCODE_BUTTON13_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON14, N_p("input-name", "P1 Button 14"), input_seq(KEYCODE_SLASH, input_seq::or_code, JOYCODE_BUTTON14_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON15, N_p("input-name", "P1 Button 15"), input_seq(KEYCODE_RSHIFT, input_seq::or_code, JOYCODE_BUTTON15_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON16, N_p("input-name", "P1 Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, START, N_p("input-name", "P1 Start"), input_seq(KEYCODE_1, input_seq::or_code, JOYCODE_START_INDEXED(0)) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, SELECT, N_p("input-name", "P1 Select"), input_seq(KEYCODE_5, input_seq::or_code, JOYCODE_SELECT_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_UP, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_DOWN, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_LEFT, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_RIGHT, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq(KEYCODE_I, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq(KEYCODE_K, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq(KEYCODE_J, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq(KEYCODE_L, input_seq::or_code, JOYCODE_BUTTON4_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq(KEYCODE_E, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq(KEYCODE_D, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq(KEYCODE_S, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq(KEYCODE_F, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_LCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0), input_seq::or_code, MOUSECODE_BUTTON1_INDEXED(0), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_LALT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(0), input_seq::or_code, MOUSECODE_BUTTON3_INDEXED(0), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_SPACE, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(0), input_seq::or_code, MOUSECODE_BUTTON2_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(KEYCODE_LSHIFT, input_seq::or_code, JOYCODE_BUTTON4_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(KEYCODE_Z, input_seq::or_code, JOYCODE_BUTTON5_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(KEYCODE_X, input_seq::or_code, JOYCODE_BUTTON6_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(KEYCODE_C, input_seq::or_code, JOYCODE_BUTTON7_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(KEYCODE_V, input_seq::or_code, JOYCODE_BUTTON8_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(KEYCODE_B, input_seq::or_code, JOYCODE_BUTTON9_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(KEYCODE_N, input_seq::or_code, JOYCODE_BUTTON10_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(KEYCODE_M, input_seq::or_code, JOYCODE_BUTTON11_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(KEYCODE_COMMA, input_seq::or_code, JOYCODE_BUTTON12_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(KEYCODE_STOP, input_seq::or_code, JOYCODE_BUTTON13_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(KEYCODE_SLASH, input_seq::or_code, JOYCODE_BUTTON14_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(KEYCODE_RSHIFT, input_seq::or_code, JOYCODE_BUTTON15_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_1, input_seq::or_code, JOYCODE_START_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_5, input_seq::or_code, JOYCODE_SELECT_INDEXED(0)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P1_MAHJONG \
CORE_INPUT_TYPES_BEGIN(p1_mahjong) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_A, N_p("input-name", "P1 Mahjong A"), input_seq(KEYCODE_A) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_B, N_p("input-name", "P1 Mahjong B"), input_seq(KEYCODE_B) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_C, N_p("input-name", "P1 Mahjong C"), input_seq(KEYCODE_C) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_D, N_p("input-name", "P1 Mahjong D"), input_seq(KEYCODE_D) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_E, N_p("input-name", "P1 Mahjong E"), input_seq(KEYCODE_E) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_F, N_p("input-name", "P1 Mahjong F"), input_seq(KEYCODE_F) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_G, N_p("input-name", "P1 Mahjong G"), input_seq(KEYCODE_G) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_H, N_p("input-name", "P1 Mahjong H"), input_seq(KEYCODE_H) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_I, N_p("input-name", "P1 Mahjong I"), input_seq(KEYCODE_I) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_J, N_p("input-name", "P1 Mahjong J"), input_seq(KEYCODE_J) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_K, N_p("input-name", "P1 Mahjong K"), input_seq(KEYCODE_K) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_L, N_p("input-name", "P1 Mahjong L"), input_seq(KEYCODE_L) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_M, N_p("input-name", "P1 Mahjong M"), input_seq(KEYCODE_M) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_N, N_p("input-name", "P1 Mahjong N"), input_seq(KEYCODE_N) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_O, N_p("input-name", "P1 Mahjong O"), input_seq(KEYCODE_O) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_P, N_p("input-name", "P1 Mahjong P"), input_seq(KEYCODE_COLON) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_Q, N_p("input-name", "P1 Mahjong Q"), input_seq(KEYCODE_Q) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_KAN, N_p("input-name", "P1 Mahjong Kan"), input_seq(KEYCODE_LCONTROL) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_PON, N_p("input-name", "P1 Mahjong Pon"), input_seq(KEYCODE_LALT) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_CHI, N_p("input-name", "P1 Mahjong Chi"), input_seq(KEYCODE_SPACE) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_REACH, N_p("input-name", "P1 Mahjong Reach"), input_seq(KEYCODE_LSHIFT) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_RON, N_p("input-name", "P1 Mahjong Ron"), input_seq(KEYCODE_Z) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_FLIP_FLOP, N_p("input-name", "P1 Mahjong Flip Flop"), input_seq(KEYCODE_Y) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_BET, N_p("input-name", "P1 Mahjong Bet"), input_seq(KEYCODE_3) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_SCORE, N_p("input-name", "P1 Mahjong Take Score"), input_seq(KEYCODE_RCONTROL) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_DOUBLE_UP, N_p("input-name", "P1 Mahjong Double Up"), input_seq(KEYCODE_RSHIFT) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_BIG, N_p("input-name", "P1 Mahjong Big"), input_seq(KEYCODE_ENTER) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_SMALL, N_p("input-name", "P1 Mahjong Small"), input_seq(KEYCODE_BACKSPACE) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_LAST_CHANCE, N_p("input-name", "P1 Mahjong Last Chance"), input_seq(KEYCODE_RALT) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_A, N_p("input-name", "%p Mahjong A"), input_seq(KEYCODE_A_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_B, N_p("input-name", "%p Mahjong B"), input_seq(KEYCODE_B_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_C, N_p("input-name", "%p Mahjong C"), input_seq(KEYCODE_C_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_D, N_p("input-name", "%p Mahjong D"), input_seq(KEYCODE_D_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_E, N_p("input-name", "%p Mahjong E"), input_seq(KEYCODE_E_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_F, N_p("input-name", "%p Mahjong F"), input_seq(KEYCODE_F_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_G, N_p("input-name", "%p Mahjong G"), input_seq(KEYCODE_G_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_H, N_p("input-name", "%p Mahjong H"), input_seq(KEYCODE_H_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_I, N_p("input-name", "%p Mahjong I"), input_seq(KEYCODE_I_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_J, N_p("input-name", "%p Mahjong J"), input_seq(KEYCODE_J_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_K, N_p("input-name", "%p Mahjong K"), input_seq(KEYCODE_K_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_L, N_p("input-name", "%p Mahjong L"), input_seq(KEYCODE_L_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_M, N_p("input-name", "%p Mahjong M"), input_seq(KEYCODE_M_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_N, N_p("input-name", "%p Mahjong N"), input_seq(KEYCODE_N_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_O, N_p("input-name", "%p Mahjong O"), input_seq(KEYCODE_O_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_P, N_p("input-name", "%p Mahjong P"), input_seq(KEYCODE_COLON_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_Q, N_p("input-name", "%p Mahjong Q"), input_seq(KEYCODE_Q_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_KAN, N_p("input-name", "%p Mahjong Kan"), input_seq(KEYCODE_LCONTROL_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_PON, N_p("input-name", "%p Mahjong Pon"), input_seq(KEYCODE_LALT_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_CHI, N_p("input-name", "%p Mahjong Chi"), input_seq(KEYCODE_SPACE_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_REACH, N_p("input-name", "%p Mahjong Reach"), input_seq(KEYCODE_LSHIFT_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_RON, N_p("input-name", "%p Mahjong Ron"), input_seq(KEYCODE_Z_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_FLIP_FLOP, N_p("input-name", "%p Mahjong Flip Flop"), input_seq(KEYCODE_Y_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_BET, N_p("input-name", "%p Mahjong Bet"), input_seq(KEYCODE_3_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_SCORE, N_p("input-name", "%p Mahjong Take Score"), input_seq(KEYCODE_RCONTROL_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_DOUBLE_UP, N_p("input-name", "%p Mahjong Double Up"), input_seq(KEYCODE_RSHIFT_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_BIG, N_p("input-name", "%p Mahjong Big"), input_seq(KEYCODE_ENTER_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_SMALL, N_p("input-name", "%p Mahjong Small"), input_seq(KEYCODE_BACKSPACE_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, MAHJONG_LAST_CHANCE, N_p("input-name", "%p Mahjong Last Chance"), input_seq(KEYCODE_RALT_INDEXED(0)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P1_HANAFUDA \
CORE_INPUT_TYPES_BEGIN(p1_hanafuda) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_A, N_p("input-name", "P1 Hanafuda A/1"), input_seq(KEYCODE_A) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_B, N_p("input-name", "P1 Hanafuda B/2"), input_seq(KEYCODE_B) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_C, N_p("input-name", "P1 Hanafuda C/3"), input_seq(KEYCODE_C) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_D, N_p("input-name", "P1 Hanafuda D/4"), input_seq(KEYCODE_D) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_E, N_p("input-name", "P1 Hanafuda E/5"), input_seq(KEYCODE_E) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_F, N_p("input-name", "P1 Hanafuda F/6"), input_seq(KEYCODE_F) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_G, N_p("input-name", "P1 Hanafuda G/7"), input_seq(KEYCODE_G) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_H, N_p("input-name", "P1 Hanafuda H/8"), input_seq(KEYCODE_H) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_YES, N_p("input-name", "P1 Hanafuda Yes"), input_seq(KEYCODE_M) ) \
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_NO, N_p("input-name", "P1 Hanafuda No"), input_seq(KEYCODE_N) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_A, N_p("input-name", "%p Hanafuda A/1"), input_seq(KEYCODE_A_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_B, N_p("input-name", "%p Hanafuda B/2"), input_seq(KEYCODE_B_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_C, N_p("input-name", "%p Hanafuda C/3"), input_seq(KEYCODE_C_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_D, N_p("input-name", "%p Hanafuda D/4"), input_seq(KEYCODE_D_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_E, N_p("input-name", "%p Hanafuda E/5"), input_seq(KEYCODE_E_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_F, N_p("input-name", "%p Hanafuda F/6"), input_seq(KEYCODE_F_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_G, N_p("input-name", "%p Hanafuda G/7"), input_seq(KEYCODE_G_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_H, N_p("input-name", "%p Hanafuda H/8"), input_seq(KEYCODE_H_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_YES, N_p("input-name", "%p Hanafuda Yes"), input_seq(KEYCODE_M_INDEXED(0)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_NO, N_p("input-name", "%p Hanafuda No"), input_seq(KEYCODE_N_INDEXED(0)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_GAMBLE \
@@ -137,355 +137,421 @@ namespace {
#define CORE_INPUT_TYPES_P2 \
CORE_INPUT_TYPES_BEGIN(p2) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_UP, N_p("input-name", "P2 Up"), input_seq(KEYCODE_R, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_DOWN, N_p("input-name", "P2 Down"), input_seq(KEYCODE_F, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_LEFT, N_p("input-name", "P2 Left"), input_seq(KEYCODE_D, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_RIGHT, N_p("input-name", "P2 Right"), input_seq(KEYCODE_G, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_UP, N_p("input-name", "P2 Right Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_DOWN, N_p("input-name", "P2 Right Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_LEFT, N_p("input-name", "P2 Right Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_RIGHT, N_p("input-name", "P2 Right Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_UP, N_p("input-name", "P2 Left Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_DOWN, N_p("input-name", "P2 Left Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_LEFT, N_p("input-name", "P2 Left Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_RIGHT, N_p("input-name", "P2 Left Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON1, N_p("input-name", "P2 Button 1"), input_seq(KEYCODE_A, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(1), input_seq::or_code, MOUSECODE_BUTTON1_INDEXED(1), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON2, N_p("input-name", "P2 Button 2"), input_seq(KEYCODE_S, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(1), input_seq::or_code, MOUSECODE_BUTTON3_INDEXED(1), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON3, N_p("input-name", "P2 Button 3"), input_seq(KEYCODE_Q, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(1), input_seq::or_code, MOUSECODE_BUTTON2_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON4, N_p("input-name", "P2 Button 4"), input_seq(KEYCODE_W, input_seq::or_code, JOYCODE_BUTTON4_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON5, N_p("input-name", "P2 Button 5"), input_seq(KEYCODE_E, input_seq::or_code, JOYCODE_BUTTON5_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON6, N_p("input-name", "P2 Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON7, N_p("input-name", "P2 Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON8, N_p("input-name", "P2 Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON9, N_p("input-name", "P2 Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON10, N_p("input-name", "P2 Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON11, N_p("input-name", "P2 Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON12, N_p("input-name", "P2 Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON13, N_p("input-name", "P2 Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON14, N_p("input-name", "P2 Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON15, N_p("input-name", "P2 Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON16, N_p("input-name", "P2 Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, START, N_p("input-name", "P2 Start"), input_seq(KEYCODE_2, input_seq::or_code, JOYCODE_START_INDEXED(1)) ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, SELECT, N_p("input-name", "P2 Select"), input_seq(KEYCODE_6, input_seq::or_code, JOYCODE_SELECT_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_R, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_F, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_D, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_G, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_A, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(1), input_seq::or_code, MOUSECODE_BUTTON1_INDEXED(1), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_S, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(1), input_seq::or_code, MOUSECODE_BUTTON3_INDEXED(1), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_Q, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(1), input_seq::or_code, MOUSECODE_BUTTON2_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(KEYCODE_W, input_seq::or_code, JOYCODE_BUTTON4_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(KEYCODE_E, input_seq::or_code, JOYCODE_BUTTON5_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_2, input_seq::or_code, JOYCODE_START_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_6, input_seq::or_code, JOYCODE_SELECT_INDEXED(1)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P2_MAHJONG \
CORE_INPUT_TYPES_BEGIN(p2_mahjong) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_A, N_p("input-name", "P2 Mahjong A"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_B, N_p("input-name", "P2 Mahjong B"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_C, N_p("input-name", "P2 Mahjong C"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_D, N_p("input-name", "P2 Mahjong D"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_E, N_p("input-name", "P2 Mahjong E"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_F, N_p("input-name", "P2 Mahjong F"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_G, N_p("input-name", "P2 Mahjong G"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_H, N_p("input-name", "P2 Mahjong H"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_I, N_p("input-name", "P2 Mahjong I"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_J, N_p("input-name", "P2 Mahjong J"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_K, N_p("input-name", "P2 Mahjong K"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_L, N_p("input-name", "P2 Mahjong L"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_M, N_p("input-name", "P2 Mahjong M"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_N, N_p("input-name", "P2 Mahjong N"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_O, N_p("input-name", "P2 Mahjong O"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_P, N_p("input-name", "P2 Mahjong P"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_Q, N_p("input-name", "P2 Mahjong Q"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_KAN, N_p("input-name", "P2 Mahjong Kan"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_PON, N_p("input-name", "P2 Mahjong Pon"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_CHI, N_p("input-name", "P2 Mahjong Chi"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_REACH, N_p("input-name", "P2 Mahjong Reach"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_RON, N_p("input-name", "P2 Mahjong Ron"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_BET, N_p("input-name", "P2 Mahjong Bet"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_LAST_CHANCE, N_p("input-name", "P2 Mahjong Last Chance"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_SCORE, N_p("input-name", "P2 Mahjong Take Score"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_DOUBLE_UP, N_p("input-name", "P2 Mahjong Double Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_FLIP_FLOP, N_p("input-name", "P2 Mahjong Flip Flop"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_BIG, N_p("input-name", "P2 Mahjong Big"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_SMALL, N_p("input-name", "P2 Mahjong Small"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_A, N_p("input-name", "%p Mahjong A"), input_seq(KEYCODE_A_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_B, N_p("input-name", "%p Mahjong B"), input_seq(KEYCODE_B_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_C, N_p("input-name", "%p Mahjong C"), input_seq(KEYCODE_C_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_D, N_p("input-name", "%p Mahjong D"), input_seq(KEYCODE_D_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_E, N_p("input-name", "%p Mahjong E"), input_seq(KEYCODE_E_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_F, N_p("input-name", "%p Mahjong F"), input_seq(KEYCODE_F_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_G, N_p("input-name", "%p Mahjong G"), input_seq(KEYCODE_G_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_H, N_p("input-name", "%p Mahjong H"), input_seq(KEYCODE_H_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_I, N_p("input-name", "%p Mahjong I"), input_seq(KEYCODE_I_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_J, N_p("input-name", "%p Mahjong J"), input_seq(KEYCODE_J_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_K, N_p("input-name", "%p Mahjong K"), input_seq(KEYCODE_K_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_L, N_p("input-name", "%p Mahjong L"), input_seq(KEYCODE_L_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_M, N_p("input-name", "%p Mahjong M"), input_seq(KEYCODE_M_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_N, N_p("input-name", "%p Mahjong N"), input_seq(KEYCODE_N_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_O, N_p("input-name", "%p Mahjong O"), input_seq(KEYCODE_O_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_P, N_p("input-name", "%p Mahjong P"), input_seq(KEYCODE_COLON_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_Q, N_p("input-name", "%p Mahjong Q"), input_seq(KEYCODE_Q_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_KAN, N_p("input-name", "%p Mahjong Kan"), input_seq(KEYCODE_LCONTROL_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_PON, N_p("input-name", "%p Mahjong Pon"), input_seq(KEYCODE_LALT_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_CHI, N_p("input-name", "%p Mahjong Chi"), input_seq(KEYCODE_SPACE_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_REACH, N_p("input-name", "%p Mahjong Reach"), input_seq(KEYCODE_LSHIFT_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_RON, N_p("input-name", "%p Mahjong Ron"), input_seq(KEYCODE_Z_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_FLIP_FLOP, N_p("input-name", "%p Mahjong Flip Flop"), input_seq(KEYCODE_Y_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_BET, N_p("input-name", "%p Mahjong Bet"), input_seq(KEYCODE_3_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_SCORE, N_p("input-name", "%p Mahjong Take Score"), input_seq(KEYCODE_RCONTROL_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_DOUBLE_UP, N_p("input-name", "%p Mahjong Double Up"), input_seq(KEYCODE_RSHIFT_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_BIG, N_p("input-name", "%p Mahjong Big"), input_seq(KEYCODE_ENTER_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_SMALL, N_p("input-name", "%p Mahjong Small"), input_seq(KEYCODE_BACKSPACE_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, MAHJONG_LAST_CHANCE, N_p("input-name", "%p Mahjong Last Chance"), input_seq(KEYCODE_RALT_INDEXED(1)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P2_HANAFUDA \
CORE_INPUT_TYPES_BEGIN(p2_hanafuda) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_A, N_p("input-name", "P2 Hanafuda A/1"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_B, N_p("input-name", "P2 Hanafuda B/2"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_C, N_p("input-name", "P2 Hanafuda C/3"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_D, N_p("input-name", "P2 Hanafuda D/4"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_E, N_p("input-name", "P2 Hanafuda E/5"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_F, N_p("input-name", "P2 Hanafuda F/6"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_G, N_p("input-name", "P2 Hanafuda G/7"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_H, N_p("input-name", "P2 Hanafuda H/8"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_YES, N_p("input-name", "P2 Hanafuda Yes"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_NO, N_p("input-name", "P2 Hanafuda No"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_A, N_p("input-name", "%p Hanafuda A/1"), input_seq(KEYCODE_A_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_B, N_p("input-name", "%p Hanafuda B/2"), input_seq(KEYCODE_B_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_C, N_p("input-name", "%p Hanafuda C/3"), input_seq(KEYCODE_C_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_D, N_p("input-name", "%p Hanafuda D/4"), input_seq(KEYCODE_D_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_E, N_p("input-name", "%p Hanafuda E/5"), input_seq(KEYCODE_E_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_F, N_p("input-name", "%p Hanafuda F/6"), input_seq(KEYCODE_F_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_G, N_p("input-name", "%p Hanafuda G/7"), input_seq(KEYCODE_G_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_H, N_p("input-name", "%p Hanafuda H/8"), input_seq(KEYCODE_H_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_YES, N_p("input-name", "%p Hanafuda Yes"), input_seq(KEYCODE_M_INDEXED(1)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_NO, N_p("input-name", "%p Hanafuda No"), input_seq(KEYCODE_N_INDEXED(1)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P3 \
CORE_INPUT_TYPES_BEGIN(p3) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_UP, N_p("input-name", "P3 Up"), input_seq(KEYCODE_I, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_DOWN, N_p("input-name", "P3 Down"), input_seq(KEYCODE_K, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_LEFT, N_p("input-name", "P3 Left"), input_seq(KEYCODE_J, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_RIGHT, N_p("input-name", "P3 Right"), input_seq(KEYCODE_L, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_UP, N_p("input-name", "P3 Right Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_DOWN, N_p("input-name", "P3 Right Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_LEFT, N_p("input-name", "P3 Right Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_RIGHT, N_p("input-name", "P3 Right Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_UP, N_p("input-name", "P3 Left Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_DOWN, N_p("input-name", "P3 Left Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_LEFT, N_p("input-name", "P3 Left Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_RIGHT, N_p("input-name", "P3 Left Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON1, N_p("input-name", "P3 Button 1"), input_seq(KEYCODE_RCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(2), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON2, N_p("input-name", "P3 Button 2"), input_seq(KEYCODE_RSHIFT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(2), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON3, N_p("input-name", "P3 Button 3"), input_seq(KEYCODE_ENTER, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON4, N_p("input-name", "P3 Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON5, N_p("input-name", "P3 Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON6, N_p("input-name", "P3 Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON7, N_p("input-name", "P3 Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON8, N_p("input-name", "P3 Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON9, N_p("input-name", "P3 Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON10, N_p("input-name", "P3 Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON11, N_p("input-name", "P3 Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON12, N_p("input-name", "P3 Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON13, N_p("input-name", "P3 Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON14, N_p("input-name", "P3 Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON15, N_p("input-name", "P3 Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON16, N_p("input-name", "P3 Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, START, N_p("input-name", "P3 Start"), input_seq(KEYCODE_3, input_seq::or_code, JOYCODE_START_INDEXED(2)) ) \
- INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, SELECT, N_p("input-name", "P3 Select"), input_seq(KEYCODE_7, input_seq::or_code, JOYCODE_SELECT_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_I, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_K, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_J, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_L, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_RCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(2), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_RSHIFT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(2), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_ENTER, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_3, input_seq::or_code, JOYCODE_START_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_7, input_seq::or_code, JOYCODE_SELECT_INDEXED(2)) ) \
+ CORE_INPUT_TYPES_END()
+
+#define CORE_INPUT_TYPES_P3_MAHJONG \
+ CORE_INPUT_TYPES_BEGIN(p3_mahjong) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_A, N_p("input-name", "%p Mahjong A"), input_seq(KEYCODE_A_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_B, N_p("input-name", "%p Mahjong B"), input_seq(KEYCODE_B_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_C, N_p("input-name", "%p Mahjong C"), input_seq(KEYCODE_C_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_D, N_p("input-name", "%p Mahjong D"), input_seq(KEYCODE_D_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_E, N_p("input-name", "%p Mahjong E"), input_seq(KEYCODE_E_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_F, N_p("input-name", "%p Mahjong F"), input_seq(KEYCODE_F_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_G, N_p("input-name", "%p Mahjong G"), input_seq(KEYCODE_G_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_H, N_p("input-name", "%p Mahjong H"), input_seq(KEYCODE_H_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_I, N_p("input-name", "%p Mahjong I"), input_seq(KEYCODE_I_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_J, N_p("input-name", "%p Mahjong J"), input_seq(KEYCODE_J_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_K, N_p("input-name", "%p Mahjong K"), input_seq(KEYCODE_K_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_L, N_p("input-name", "%p Mahjong L"), input_seq(KEYCODE_L_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_M, N_p("input-name", "%p Mahjong M"), input_seq(KEYCODE_M_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_N, N_p("input-name", "%p Mahjong N"), input_seq(KEYCODE_N_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_O, N_p("input-name", "%p Mahjong O"), input_seq(KEYCODE_O_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_P, N_p("input-name", "%p Mahjong P"), input_seq(KEYCODE_COLON_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_Q, N_p("input-name", "%p Mahjong Q"), input_seq(KEYCODE_Q_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_KAN, N_p("input-name", "%p Mahjong Kan"), input_seq(KEYCODE_LCONTROL_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_PON, N_p("input-name", "%p Mahjong Pon"), input_seq(KEYCODE_LALT_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_CHI, N_p("input-name", "%p Mahjong Chi"), input_seq(KEYCODE_SPACE_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_REACH, N_p("input-name", "%p Mahjong Reach"), input_seq(KEYCODE_LSHIFT_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_RON, N_p("input-name", "%p Mahjong Ron"), input_seq(KEYCODE_Z_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_FLIP_FLOP, N_p("input-name", "%p Mahjong Flip Flop"), input_seq(KEYCODE_Y_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_BET, N_p("input-name", "%p Mahjong Bet"), input_seq(KEYCODE_3_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_SCORE, N_p("input-name", "%p Mahjong Take Score"), input_seq(KEYCODE_RCONTROL_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_DOUBLE_UP, N_p("input-name", "%p Mahjong Double Up"), input_seq(KEYCODE_RSHIFT_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_BIG, N_p("input-name", "%p Mahjong Big"), input_seq(KEYCODE_ENTER_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_SMALL, N_p("input-name", "%p Mahjong Small"), input_seq(KEYCODE_BACKSPACE_INDEXED(2)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, MAHJONG_LAST_CHANCE, N_p("input-name", "%p Mahjong Last Chance"), input_seq(KEYCODE_RALT_INDEXED(2)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P4 \
CORE_INPUT_TYPES_BEGIN(p4) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_UP, N_p("input-name", "P4 Up"), input_seq(KEYCODE_8_PAD, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_DOWN, N_p("input-name", "P4 Down"), input_seq(KEYCODE_2_PAD, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_LEFT, N_p("input-name", "P4 Left"), input_seq(KEYCODE_4_PAD, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_RIGHT, N_p("input-name", "P4 Right"), input_seq(KEYCODE_6_PAD, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_UP, N_p("input-name", "P4 Right Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_DOWN, N_p("input-name", "P4 Right Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_LEFT, N_p("input-name", "P4 Right Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_RIGHT, N_p("input-name", "P4 Right Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_UP, N_p("input-name", "P4 Left Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_DOWN, N_p("input-name", "P4 Left Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_LEFT, N_p("input-name", "P4 Left Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_RIGHT, N_p("input-name", "P4 Left Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON1, N_p("input-name", "P4 Button 1"), input_seq(KEYCODE_0_PAD, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON2, N_p("input-name", "P4 Button 2"), input_seq(KEYCODE_DEL_PAD, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON3, N_p("input-name", "P4 Button 3"), input_seq(KEYCODE_ENTER_PAD, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON4, N_p("input-name", "P4 Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON5, N_p("input-name", "P4 Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON6, N_p("input-name", "P4 Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON7, N_p("input-name", "P4 Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON8, N_p("input-name", "P4 Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON9, N_p("input-name", "P4 Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON10, N_p("input-name", "P4 Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON11, N_p("input-name", "P4 Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON12, N_p("input-name", "P4 Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON13, N_p("input-name", "P4 Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON14, N_p("input-name", "P4 Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON15, N_p("input-name", "P4 Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON16, N_p("input-name", "P4 Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, START, N_p("input-name", "P4 Start"), input_seq(KEYCODE_4, input_seq::or_code, JOYCODE_START_INDEXED(3)) ) \
- INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, SELECT, N_p("input-name", "P4 Select"), input_seq(KEYCODE_8, input_seq::or_code, JOYCODE_SELECT_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_8_PAD, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_2_PAD, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_4_PAD, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_6_PAD, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_0_PAD, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_DEL_PAD, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_ENTER_PAD, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_4, input_seq::or_code, JOYCODE_START_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_8, input_seq::or_code, JOYCODE_SELECT_INDEXED(3)) ) \
+ CORE_INPUT_TYPES_END()
+
+#define CORE_INPUT_TYPES_P4_MAHJONG \
+ CORE_INPUT_TYPES_BEGIN(p4_mahjong) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_A, N_p("input-name", "%p Mahjong A"), input_seq(KEYCODE_A_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_B, N_p("input-name", "%p Mahjong B"), input_seq(KEYCODE_B_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_C, N_p("input-name", "%p Mahjong C"), input_seq(KEYCODE_C_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_D, N_p("input-name", "%p Mahjong D"), input_seq(KEYCODE_D_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_E, N_p("input-name", "%p Mahjong E"), input_seq(KEYCODE_E_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_F, N_p("input-name", "%p Mahjong F"), input_seq(KEYCODE_F_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_G, N_p("input-name", "%p Mahjong G"), input_seq(KEYCODE_G_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_H, N_p("input-name", "%p Mahjong H"), input_seq(KEYCODE_H_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_I, N_p("input-name", "%p Mahjong I"), input_seq(KEYCODE_I_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_J, N_p("input-name", "%p Mahjong J"), input_seq(KEYCODE_J_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_K, N_p("input-name", "%p Mahjong K"), input_seq(KEYCODE_K_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_L, N_p("input-name", "%p Mahjong L"), input_seq(KEYCODE_L_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_M, N_p("input-name", "%p Mahjong M"), input_seq(KEYCODE_M_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_N, N_p("input-name", "%p Mahjong N"), input_seq(KEYCODE_N_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_O, N_p("input-name", "%p Mahjong O"), input_seq(KEYCODE_O_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_P, N_p("input-name", "%p Mahjong P"), input_seq(KEYCODE_COLON_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_Q, N_p("input-name", "%p Mahjong Q"), input_seq(KEYCODE_Q_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_KAN, N_p("input-name", "%p Mahjong Kan"), input_seq(KEYCODE_LCONTROL_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_PON, N_p("input-name", "%p Mahjong Pon"), input_seq(KEYCODE_LALT_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_CHI, N_p("input-name", "%p Mahjong Chi"), input_seq(KEYCODE_SPACE_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_REACH, N_p("input-name", "%p Mahjong Reach"), input_seq(KEYCODE_LSHIFT_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_RON, N_p("input-name", "%p Mahjong Ron"), input_seq(KEYCODE_Z_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_FLIP_FLOP, N_p("input-name", "%p Mahjong Flip Flop"), input_seq(KEYCODE_Y_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_BET, N_p("input-name", "%p Mahjong Bet"), input_seq(KEYCODE_3_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_SCORE, N_p("input-name", "%p Mahjong Take Score"), input_seq(KEYCODE_RCONTROL_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_DOUBLE_UP, N_p("input-name", "%p Mahjong Double Up"), input_seq(KEYCODE_RSHIFT_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_BIG, N_p("input-name", "%p Mahjong Big"), input_seq(KEYCODE_ENTER_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_SMALL, N_p("input-name", "%p Mahjong Small"), input_seq(KEYCODE_BACKSPACE_INDEXED(3)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, MAHJONG_LAST_CHANCE, N_p("input-name", "%p Mahjong Last Chance"), input_seq(KEYCODE_RALT_INDEXED(3)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P5 \
CORE_INPUT_TYPES_BEGIN(p5) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_UP, N_p("input-name", "P5 Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_DOWN, N_p("input-name", "P5 Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_LEFT, N_p("input-name", "P5 Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_RIGHT, N_p("input-name", "P5 Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_UP, N_p("input-name", "P5 Right Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_DOWN, N_p("input-name", "P5 Right Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_LEFT, N_p("input-name", "P5 Right Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_RIGHT, N_p("input-name", "P5 Right Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_UP, N_p("input-name", "P5 Left Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_DOWN, N_p("input-name", "P5 Left Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_LEFT, N_p("input-name", "P5 Left Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_RIGHT, N_p("input-name", "P5 Left Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON1, N_p("input-name", "P5 Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON2, N_p("input-name", "P5 Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON3, N_p("input-name", "P5 Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON4, N_p("input-name", "P5 Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON5, N_p("input-name", "P5 Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON6, N_p("input-name", "P5 Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON7, N_p("input-name", "P5 Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON8, N_p("input-name", "P5 Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON9, N_p("input-name", "P5 Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON10, N_p("input-name", "P5 Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON11, N_p("input-name", "P5 Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON12, N_p("input-name", "P5 Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON13, N_p("input-name", "P5 Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON14, N_p("input-name", "P5 Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON15, N_p("input-name", "P5 Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON16, N_p("input-name", "P5 Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(4)) ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, START, N_p("input-name", "P5 Start"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, SELECT, N_p("input-name", "P5 Select"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(4)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, START, N_p("input-name", "%p Start"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, SELECT, N_p("input-name", "%p Select"), input_seq() ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P6 \
CORE_INPUT_TYPES_BEGIN(p6) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_UP, N_p("input-name", "P6 Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_DOWN, N_p("input-name", "P6 Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_LEFT, N_p("input-name", "P6 Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_RIGHT, N_p("input-name", "P6 Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_UP, N_p("input-name", "P6 Right Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_DOWN, N_p("input-name", "P6 Right Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_LEFT, N_p("input-name", "P6 Right Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_RIGHT, N_p("input-name", "P6 Right Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_UP, N_p("input-name", "P6 Left Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_DOWN, N_p("input-name", "P6 Left Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_LEFT, N_p("input-name", "P6 Left Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_RIGHT, N_p("input-name", "P6 Left Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON1, N_p("input-name", "P6 Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON2, N_p("input-name", "P6 Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON3, N_p("input-name", "P6 Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON4, N_p("input-name", "P6 Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON5, N_p("input-name", "P6 Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON6, N_p("input-name", "P6 Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON7, N_p("input-name", "P6 Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON8, N_p("input-name", "P6 Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON9, N_p("input-name", "P6 Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON10, N_p("input-name", "P6 Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON11, N_p("input-name", "P6 Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON12, N_p("input-name", "P6 Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON13, N_p("input-name", "P6 Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON14, N_p("input-name", "P6 Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON15, N_p("input-name", "P6 Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON16, N_p("input-name", "P6 Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(5)) ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, START, N_p("input-name", "P6 Start"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, SELECT, N_p("input-name", "P6 Select"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(5)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, START, N_p("input-name", "%p Start"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, SELECT, N_p("input-name", "%p Select"), input_seq() ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P7 \
CORE_INPUT_TYPES_BEGIN(p7) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_UP, N_p("input-name", "P7 Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_DOWN, N_p("input-name", "P7 Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_LEFT, N_p("input-name", "P7 Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_RIGHT, N_p("input-name", "P7 Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_UP, N_p("input-name", "P7 Right Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_DOWN, N_p("input-name", "P7 Right Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_LEFT, N_p("input-name", "P7 Right Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_RIGHT, N_p("input-name", "P7 Right Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_UP, N_p("input-name", "P7 Left Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_DOWN, N_p("input-name", "P7 Left Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_LEFT, N_p("input-name", "P7 Left Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_RIGHT, N_p("input-name", "P7 Left Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON1, N_p("input-name", "P7 Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON2, N_p("input-name", "P7 Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON3, N_p("input-name", "P7 Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON4, N_p("input-name", "P7 Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON5, N_p("input-name", "P7 Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON6, N_p("input-name", "P7 Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON7, N_p("input-name", "P7 Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON8, N_p("input-name", "P7 Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON9, N_p("input-name", "P7 Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON10, N_p("input-name", "P7 Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON11, N_p("input-name", "P7 Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON12, N_p("input-name", "P7 Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON13, N_p("input-name", "P7 Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON14, N_p("input-name", "P7 Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON15, N_p("input-name", "P7 Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON16, N_p("input-name", "P7 Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(6)) ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, START, N_p("input-name", "P7 Start"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, SELECT, N_p("input-name", "P7 Select"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(6)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, START, N_p("input-name", "%p Start"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, SELECT, N_p("input-name", "%p Select"), input_seq() ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P8 \
CORE_INPUT_TYPES_BEGIN(p8) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_UP, N_p("input-name", "P8 Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_DOWN, N_p("input-name", "P8 Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_LEFT, N_p("input-name", "P8 Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_RIGHT, N_p("input-name", "P8 Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_UP, N_p("input-name", "P8 Right Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_DOWN, N_p("input-name", "P8 Right Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_LEFT, N_p("input-name", "P8 Right Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_RIGHT, N_p("input-name", "P8 Right Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_UP, N_p("input-name", "P8 Left Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_DOWN, N_p("input-name", "P8 Left Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_LEFT, N_p("input-name", "P8 Left Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_RIGHT, N_p("input-name", "P8 Left Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON1, N_p("input-name", "P8 Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON2, N_p("input-name", "P8 Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON3, N_p("input-name", "P8 Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON4, N_p("input-name", "P8 Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON5, N_p("input-name", "P8 Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON6, N_p("input-name", "P8 Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON7, N_p("input-name", "P8 Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON8, N_p("input-name", "P8 Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON9, N_p("input-name", "P8 Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON10, N_p("input-name", "P8 Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON11, N_p("input-name", "P8 Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON12, N_p("input-name", "P8 Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON13, N_p("input-name", "P8 Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON14, N_p("input-name", "P8 Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON15, N_p("input-name", "P8 Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON16, N_p("input-name", "P8 Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(7)) ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, START, N_p("input-name", "P8 Start"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, SELECT, N_p("input-name", "P8 Select"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(7)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, START, N_p("input-name", "%p Start"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, SELECT, N_p("input-name", "%p Select"), input_seq() ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P9 \
CORE_INPUT_TYPES_BEGIN(p9) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_UP, N_p("input-name", "P9 Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_DOWN, N_p("input-name", "P9 Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_LEFT, N_p("input-name", "P9 Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_RIGHT, N_p("input-name", "P9 Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_UP, N_p("input-name", "P9 Right Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_DOWN, N_p("input-name", "P9 Right Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_LEFT, N_p("input-name", "P9 Right Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_RIGHT, N_p("input-name", "P9 Right Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_UP, N_p("input-name", "P9 Left Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_DOWN, N_p("input-name", "P9 Left Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_LEFT, N_p("input-name", "P9 Left Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_RIGHT, N_p("input-name", "P9 Left Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON1, N_p("input-name", "P9 Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON2, N_p("input-name", "P9 Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON3, N_p("input-name", "P9 Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON4, N_p("input-name", "P9 Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON5, N_p("input-name", "P9 Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON6, N_p("input-name", "P9 Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON7, N_p("input-name", "P9 Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON8, N_p("input-name", "P9 Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON9, N_p("input-name", "P9 Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON10, N_p("input-name", "P9 Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON11, N_p("input-name", "P9 Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON12, N_p("input-name", "P9 Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON13, N_p("input-name", "P9 Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON14, N_p("input-name", "P9 Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON15, N_p("input-name", "P9 Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON16, N_p("input-name", "P9 Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(8)) ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, START, N_p("input-name", "P9 Start"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, SELECT, N_p("input-name", "P9 Select"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(8)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, START, N_p("input-name", "%p Start"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, SELECT, N_p("input-name", "%p Select"), input_seq() ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_P10 \
CORE_INPUT_TYPES_BEGIN(p10) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_UP, N_p("input-name", "P10 Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_DOWN, N_p("input-name", "P10 Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_LEFT, N_p("input-name", "P10 Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_RIGHT, N_p("input-name", "P10 Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_UP, N_p("input-name", "P10 Right Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_DOWN, N_p("input-name", "P10 Right Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_LEFT, N_p("input-name", "P10 Right Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_RIGHT, N_p("input-name", "P10 Right Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_UP, N_p("input-name", "P10 Left Stick/Up"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_DOWN, N_p("input-name", "P10 Left Stick/Down"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_LEFT, N_p("input-name", "P10 Left Stick/Left"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_RIGHT, N_p("input-name", "P10 Left Stick/Right"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON1, N_p("input-name", "P10 Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON2, N_p("input-name", "P10 Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON3, N_p("input-name", "P10 Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON4, N_p("input-name", "P10 Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON5, N_p("input-name", "P10 Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON6, N_p("input-name", "P10 Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON7, N_p("input-name", "P10 Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON8, N_p("input-name", "P10 Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON9, N_p("input-name", "P10 Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON10, N_p("input-name", "P10 Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON11, N_p("input-name", "P10 Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON12, N_p("input-name", "P10 Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON13, N_p("input-name", "P10 Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON14, N_p("input-name", "P10 Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON15, N_p("input-name", "P10 Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON16, N_p("input-name", "P10 Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(9)) ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, START, N_p("input-name", "P10 Start"), input_seq() ) \
- INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, SELECT, N_p("input-name", "P10 Select"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(9)) ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, START, N_p("input-name", "%p Start"), input_seq() ) \
+ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, SELECT, N_p("input-name", "%p Select"), input_seq() ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_START \
@@ -547,44 +613,44 @@ namespace {
#define CORE_INPUT_TYPES_PEDAL \
CORE_INPUT_TYPES_BEGIN(pedal) \
- INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL, N_p("input-name", "P1 Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(0)), input_seq(), input_seq(KEYCODE_LCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0)) ) \
- INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL, N_p("input-name", "P2 Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(1)), input_seq(), input_seq(KEYCODE_A, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(1)) ) \
- INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL, N_p("input-name", "P3 Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(2)), input_seq(), input_seq(KEYCODE_RCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(2)) ) \
- INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL, N_p("input-name", "P4 Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(3)), input_seq(), input_seq(KEYCODE_0_PAD, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(3)) ) \
- INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL, N_p("input-name", "P5 Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(4)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(4)) ) \
- INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL, N_p("input-name", "P6 Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(5)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(5)) ) \
- INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL, N_p("input-name", "P7 Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(6)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(6)) ) \
- INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL, N_p("input-name", "P8 Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(7)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(7)) ) \
- INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL, N_p("input-name", "P9 Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(8)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(8)) ) \
- INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL, N_p("input-name", "P10 Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(9)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(9)) ) \
+ INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(0)), input_seq(), input_seq(KEYCODE_LCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0)) ) \
+ INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(1)), input_seq(), input_seq(KEYCODE_A, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(1)) ) \
+ INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(2)), input_seq(), input_seq(KEYCODE_RCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(2)) ) \
+ INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(3)), input_seq(), input_seq(KEYCODE_0_PAD, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(3)) ) \
+ INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(4)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(4)) ) \
+ INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(5)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(5)) ) \
+ INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(6)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(6)) ) \
+ INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(7)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(7)) ) \
+ INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(8)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(8)) ) \
+ INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(9)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(9)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_PEDAL2 \
CORE_INPUT_TYPES_BEGIN(pedal2) \
- INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL2, N_p("input-name", "P1 Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(0)), input_seq(), input_seq(KEYCODE_LALT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(0)) ) \
- INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL2, N_p("input-name", "P2 Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(1)), input_seq(), input_seq(KEYCODE_S, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(1)) ) \
- INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL2, N_p("input-name", "P3 Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(2)), input_seq(), input_seq(KEYCODE_RSHIFT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(2)) ) \
- INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL2, N_p("input-name", "P4 Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(3)), input_seq(), input_seq(KEYCODE_DEL_PAD, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(3)) ) \
- INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL2, N_p("input-name", "P5 Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(4)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(4)) ) \
- INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL2, N_p("input-name", "P6 Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(5)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(5)) ) \
- INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL2, N_p("input-name", "P7 Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(6)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(6)) ) \
- INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL2, N_p("input-name", "P8 Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(7)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(7)) ) \
- INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL2, N_p("input-name", "P9 Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(8)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(8)) ) \
- INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL2, N_p("input-name", "P10 Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(9)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(9)) ) \
+ INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(0)), input_seq(), input_seq(KEYCODE_LALT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(0)) ) \
+ INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(1)), input_seq(), input_seq(KEYCODE_S, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(1)) ) \
+ INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(2)), input_seq(), input_seq(KEYCODE_RSHIFT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(2)) ) \
+ INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(3)), input_seq(), input_seq(KEYCODE_DEL_PAD, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(3)) ) \
+ INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(4)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(4)) ) \
+ INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(5)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(5)) ) \
+ INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(6)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(6)) ) \
+ INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(7)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(7)) ) \
+ INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(8)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(8)) ) \
+ INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(9)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(9)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_PEDAL3 \
CORE_INPUT_TYPES_BEGIN(pedal3) \
- INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL3, N_p("input-name", "P1 Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_SPACE, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(0)) ) \
- INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL3, N_p("input-name", "P2 Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_Q, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(1)) ) \
- INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL3, N_p("input-name", "P3 Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_ENTER, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(2)) ) \
- INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL3, N_p("input-name", "P4 Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_ENTER_PAD, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(3)) ) \
- INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL3, N_p("input-name", "P5 Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(4)) ) \
- INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL3, N_p("input-name", "P6 Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(5)) ) \
- INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL3, N_p("input-name", "P7 Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(6)) ) \
- INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL3, N_p("input-name", "P8 Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(7)) ) \
- INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL3, N_p("input-name", "P9 Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(8)) ) \
- INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL3, N_p("input-name", "P10 Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(9)) ) \
+ INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_SPACE, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(0)) ) \
+ INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_Q, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(1)) ) \
+ INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_ENTER, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(2)) ) \
+ INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_ENTER_PAD, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(3)) ) \
+ INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(4)) ) \
+ INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(5)) ) \
+ INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(6)) ) \
+ INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(7)) ) \
+ INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(8)) ) \
+ INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(9)) ) \
CORE_INPUT_TYPES_END()
#define CORE_INPUT_TYPES_PADDLE \
@@ -920,7 +986,9 @@ CORE_INPUT_TYPES_P2
CORE_INPUT_TYPES_P2_MAHJONG
CORE_INPUT_TYPES_P2_HANAFUDA
CORE_INPUT_TYPES_P3
+CORE_INPUT_TYPES_P3_MAHJONG
CORE_INPUT_TYPES_P4
+CORE_INPUT_TYPES_P4_MAHJONG
CORE_INPUT_TYPES_P5
CORE_INPUT_TYPES_P6
CORE_INPUT_TYPES_P7
@@ -978,7 +1046,9 @@ constexpr size_t core_input_types_count()
CORE_INPUT_TYPES_P2_MAHJONG
CORE_INPUT_TYPES_P2_HANAFUDA
CORE_INPUT_TYPES_P3
+ CORE_INPUT_TYPES_P3_MAHJONG
CORE_INPUT_TYPES_P4
+ CORE_INPUT_TYPES_P4_MAHJONG
CORE_INPUT_TYPES_P5
CORE_INPUT_TYPES_P6
CORE_INPUT_TYPES_P7
@@ -1034,7 +1104,9 @@ ATTR_COLD inline void emplace_core_types(std::vector<input_type_entry> &typelist
emplace_core_types_p2_mahjong(typelist);
emplace_core_types_p2_hanafuda(typelist);
emplace_core_types_p3(typelist);
+ emplace_core_types_p3_mahjong(typelist);
emplace_core_types_p4(typelist);
+ emplace_core_types_p4_mahjong(typelist);
emplace_core_types_p5(typelist);
emplace_core_types_p6(typelist);
emplace_core_types_p7(typelist);
diff --git a/src/emu/input.cpp b/src/emu/input.cpp
index 5c49d1c2dab..169f76aabe3 100644
--- a/src/emu/input.cpp
+++ b/src/emu/input.cpp
@@ -860,7 +860,7 @@ std::string input_manager::code_to_token(input_code code) const
std::string str(devclass);
if (!devindex.empty())
str.append("_").append(devindex);
- if (devcode[0] != 0)
+ if (!devcode.empty())
str.append("_").append(devcode);
if (modifier != nullptr)
str.append("_").append(modifier);
@@ -1150,7 +1150,7 @@ input_seq input_manager::seq_clean(const input_seq &seq) const
{
// if this is a code item which is not valid, don't copy it and remove any preceding ORs/NOTs
input_code code = seq[codenum];
- if (!code.internal() && code_name(code).empty())
+ if (!code.internal() && (((code.device_index() > 0) && !m_class[code.device_class()]->multi()) || !item_from_code(code)))
{
while (clean_index > 0 && clean_codes[clean_index - 1].internal())
{
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp
index 0ea7974caf5..5999a75abe5 100644
--- a/src/emu/ioport.cpp
+++ b/src/emu/ioport.cpp
@@ -93,6 +93,7 @@
#include "emu.h"
#include "emuopts.h"
#include "config.h"
+#include "fileio.h"
#include "xmlfile.h"
#include "profiler.h"
#include "ui/uimain.h"
@@ -101,6 +102,7 @@
#include "util/corestr.h"
#include "util/ioprocsfilter.h"
+#include "util/language.h"
#include "util/unicode.h"
#include "osdepend.h"
@@ -307,6 +309,148 @@ inline bool input_seq_good(running_machine &machine, input_seq const &seq)
return input_seq::end_code != machine.input().seq_clean(seq)[0];
}
+
+std::string substitute_player(std::string_view name, u8 player)
+{
+ using util::lang_translate;
+
+ std::string result;
+ while (!name.empty())
+ {
+ auto const found = name.find('%');
+ if ((std::string_view::npos == found) || (name.length() == found + 1))
+ {
+ result.append(name);
+ break;
+ }
+ switch (name[found + 1])
+ {
+ case '%':
+ result.append(name.substr(0, found + 1));
+ break;
+ case 'p':
+ result.append(name.substr(0, found));
+ result.append(util::string_format(_("input-name", "P%1$u"), player + 1));
+ break;
+ default:
+ result.append(name.substr(0, found + 2));
+ }
+ name.remove_prefix(found + 2);
+ }
+ return result;
+}
+
+
+
+// ======================> inp_header
+
+// header at the front of INP files
+class inp_header
+{
+public:
+ // parameters
+ static constexpr unsigned MAJVERSION = 3;
+ static constexpr unsigned MINVERSION = 0;
+
+ bool read(emu_file &f)
+ {
+ return f.read(m_data, sizeof(m_data)) == sizeof(m_data);
+ }
+ bool write(emu_file &f) const
+ {
+ return f.write(m_data, sizeof(m_data)) == sizeof(m_data);
+ }
+
+ bool check_magic() const
+ {
+ return 0 == std::memcmp(MAGIC, m_data + OFFS_MAGIC, OFFS_BASETIME - OFFS_MAGIC);
+ }
+ u64 get_basetime() const
+ {
+ return
+ (u64(m_data[OFFS_BASETIME + 0]) << (0 * 8)) |
+ (u64(m_data[OFFS_BASETIME + 1]) << (1 * 8)) |
+ (u64(m_data[OFFS_BASETIME + 2]) << (2 * 8)) |
+ (u64(m_data[OFFS_BASETIME + 3]) << (3 * 8)) |
+ (u64(m_data[OFFS_BASETIME + 4]) << (4 * 8)) |
+ (u64(m_data[OFFS_BASETIME + 5]) << (5 * 8)) |
+ (u64(m_data[OFFS_BASETIME + 6]) << (6 * 8)) |
+ (u64(m_data[OFFS_BASETIME + 7]) << (7 * 8));
+ }
+ unsigned get_majversion() const
+ {
+ return m_data[OFFS_MAJVERSION];
+ }
+ unsigned get_minversion() const
+ {
+ return m_data[OFFS_MINVERSION];
+ }
+ std::string get_sysname() const
+ {
+ return get_string<OFFS_SYSNAME, OFFS_APPDESC>();
+ }
+ std::string get_appdesc() const
+ {
+ return get_string<OFFS_APPDESC, OFFS_END>();
+ }
+
+ void set_magic()
+ {
+ std::memcpy(m_data + OFFS_MAGIC, MAGIC, OFFS_BASETIME - OFFS_MAGIC);
+ }
+ void set_basetime(u64 time)
+ {
+ m_data[OFFS_BASETIME + 0] = u8((time >> (0 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 1] = u8((time >> (1 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 2] = u8((time >> (2 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 3] = u8((time >> (3 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 4] = u8((time >> (4 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 5] = u8((time >> (5 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 6] = u8((time >> (6 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 7] = u8((time >> (7 * 8)) & 0x00ff);
+ }
+ void set_version()
+ {
+ m_data[OFFS_MAJVERSION] = MAJVERSION;
+ m_data[OFFS_MINVERSION] = MINVERSION;
+ }
+ void set_sysname(std::string const &name)
+ {
+ set_string<OFFS_SYSNAME, OFFS_APPDESC>(name);
+ }
+ void set_appdesc(std::string const &desc)
+ {
+ set_string<OFFS_APPDESC, OFFS_END>(desc);
+ }
+
+private:
+ template <std::size_t BEGIN, std::size_t END> void set_string(std::string const &str)
+ {
+ std::size_t const used = (std::min<std::size_t>)(str.size() + 1, END - BEGIN);
+ std::memcpy(m_data + BEGIN, str.c_str(), used);
+ if ((END - BEGIN) > used)
+ std::memset(m_data + BEGIN + used, 0, (END - BEGIN) - used);
+ }
+ template <std::size_t BEGIN, std::size_t END> std::string get_string() const
+ {
+ char const *const begin = reinterpret_cast<char const *>(m_data + BEGIN);
+ return std::string(begin, std::find(begin, reinterpret_cast<char const *>(m_data + END), '\0'));
+ }
+
+ static constexpr std::size_t OFFS_MAGIC = 0x00; // 0x08 bytes
+ static constexpr std::size_t OFFS_BASETIME = 0x08; // 0x08 bytes (little-endian binary integer)
+ static constexpr std::size_t OFFS_MAJVERSION = 0x10; // 0x01 bytes (binary integer)
+ static constexpr std::size_t OFFS_MINVERSION = 0x11; // 0x01 bytes (binary integer)
+ // 0x02 bytes reserved
+ static constexpr std::size_t OFFS_SYSNAME = 0x14; // 0x0c bytes (ASCII)
+ static constexpr std::size_t OFFS_APPDESC = 0x20; // 0x20 bytes (ASCII)
+ static constexpr std::size_t OFFS_END = 0x40;
+
+ static u8 const MAGIC[OFFS_BASETIME - OFFS_MAGIC];
+
+ u8 m_data[OFFS_END];
+};
+
} // anonymous namespace
@@ -391,6 +535,24 @@ input_type_entry::input_type_entry(ioport_type type, ioport_group group, int pla
//-------------------------------------------------
+// name - gets the display name for the input
+// type
+//-------------------------------------------------
+
+std::string input_type_entry::name() const
+{
+ using util::lang_translate;
+
+ if (!m_name)
+ return std::string();
+ else if ((group() < IPG_PLAYER1) || (group() > IPG_PLAYER10))
+ return _("input-name", m_name);
+ else
+ return substitute_player(_("input-name", m_name), player());
+}
+
+
+//-------------------------------------------------
// replace_code - replace all instances of
// oldcodewith newcode in all sequences
//-------------------------------------------------
@@ -662,6 +824,20 @@ ioport_field::ioport_field(ioport_port &port, ioport_type type, ioport_value def
}
}
+
+//-------------------------------------------------
+// ~ioport_field - destructor
+//-------------------------------------------------
+
+ioport_field::~ioport_field()
+{
+}
+
+
+//-------------------------------------------------
+// set_value - programmatically set field value
+//-------------------------------------------------
+
void ioport_field::set_value(ioport_value value)
{
if (is_analog())
@@ -672,11 +848,15 @@ void ioport_field::set_value(ioport_value value)
//-------------------------------------------------
-// ~ioport_field - destructor
+// clear_value - clear programmatic override
//-------------------------------------------------
-ioport_field::~ioport_field()
+void ioport_field::clear_value()
{
+ if (is_analog())
+ live().analog->clear_value();
+ else
+ m_digital_value = false;
}
@@ -685,16 +865,25 @@ ioport_field::~ioport_field()
// field (this must never return nullptr)
//-------------------------------------------------
-const char *ioport_field::name() const
+std::string ioport_field::name() const
{
- // if we have a non-default name, use that
- if (m_live != nullptr && !m_live->name.empty())
- return m_live->name.c_str();
- if (m_name != nullptr)
+ using util::lang_translate;
+
+ // if we have an overridden name, use that
+ if (m_live && !m_live->name.empty())
+ return m_live->name;
+
+ // if no specific name, use the generic name for the type
+ if (!m_name)
+ return manager().type_name(m_type, m_player);
+
+ // return name for non-controller fields as-is
+ ioport_group const group = manager().type_group(m_type, m_player);
+ if ((group < IPG_PLAYER1) || (group > IPG_PLAYER10))
return m_name;
- // otherwise, return the name associated with the type
- return manager().type_name(m_type, m_player);
+ // substitute the player number in if necessary
+ return substitute_player(m_name, m_player);
}
@@ -750,8 +939,8 @@ void ioport_field::set_defseq(input_seq_type seqtype, const input_seq &newseq)
ioport_type_class ioport_field::type_class() const noexcept
{
// inputs associated with specific players
- ioport_group group = manager().type_group(m_type, m_player);
- if (group >= IPG_PLAYER1 && group <= IPG_PLAYER10)
+ ioport_group const group = manager().type_group(m_type, m_player);
+ if ((group >= IPG_PLAYER1) && (group <= IPG_PLAYER10))
return INPUT_CLASS_CONTROLLER;
// keys (names derived from character codes)
@@ -1657,8 +1846,6 @@ ioport_manager::ioport_manager(running_machine &machine)
, m_safe_to_read(false)
, m_last_frame_time(attotime::zero)
, m_last_delta_nsec(0)
- , m_record_file(machine.options().input_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)
- , m_playback_file(machine.options().input_directory(), OPEN_FLAG_READ)
, m_playback_accumulated_speed(0)
, m_playback_accumulated_frames(0)
, m_deselected_card_config()
@@ -1702,12 +1889,14 @@ time_t ioport_manager::initialize()
if (&port.second->device() == &device)
{
for (ioport_field &field : port.second->fields())
+ {
if (field.type_class() == INPUT_CLASS_CONTROLLER)
{
if (players < field.player() + 1)
players = field.player() + 1;
field.set_player(field.player() + player_offset);
}
+ }
}
}
player_offset += players;
@@ -1846,15 +2035,21 @@ ioport_manager::~ioport_manager()
// type/player
//-------------------------------------------------
-const char *ioport_manager::type_name(ioport_type type, u8 player) const noexcept
+std::string ioport_manager::type_name(ioport_type type, u8 player) const
{
+ using util::lang_translate;
+
// if we have a machine, use the live state and quick lookup
- input_type_entry *entry = m_type_to_entry[type][player];
- if (entry != nullptr && entry->name() != nullptr)
- return entry->name();
+ input_type_entry const *const entry = m_type_to_entry[type][player];
+ if (entry)
+ {
+ std::string name = entry->name();
+ if (!name.empty())
+ return name;
+ }
// if we find nothing, return a default string (not a null pointer)
- return "???";
+ return _("input-name", "???");
}
@@ -2313,7 +2508,10 @@ bool ioport_manager::load_controller_config(
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
{
if (input_seq_good(machine(), newseq[seqtype].first))
+ {
+ field.live().seq[seqtype] = newseq[seqtype].first;
field.set_defseq(seqtype, newseq[seqtype].first);
+ }
}
// fetch configurable attributes
@@ -2723,7 +2921,8 @@ time_t ioport_manager::playback_init()
return 0;
// open the playback file
- std::error_condition const filerr = m_playback_file.open(filename);
+ m_playback_file = std::make_unique<emu_file>(machine().options().input_directory(), OPEN_FLAG_READ);
+ std::error_condition const filerr = m_playback_file->open(filename);
// return an explicit error if file isn't found in given path
if (filerr == std::errc::no_such_file_or_directory)
@@ -2735,7 +2934,7 @@ time_t ioport_manager::playback_init()
// read the header and verify that it is a modern version; if not, print an error
inp_header header;
- if (!header.read(m_playback_file))
+ if (!header.read(*m_playback_file))
fatalerror("Input file is corrupt or invalid (missing header)\n");
if (!header.check_magic())
fatalerror("Input file invalid or in an older, unsupported format\n");
@@ -2755,7 +2954,7 @@ time_t ioport_manager::playback_init()
osd_printf_info("Input file is for machine '%s', not for current machine '%s'\n", sysname, machine().system().name);
// enable compression
- m_playback_stream = util::zlib_read(m_playback_file, 16386);
+ m_playback_stream = util::zlib_read(*m_playback_file, 16386);
return basetime;
}
@@ -2771,7 +2970,7 @@ void ioport_manager::playback_end(const char *message)
{
// close the file
m_playback_stream.reset();
- m_playback_file.close();
+ m_playback_file.reset();
// pop a message
if (message != nullptr)
@@ -2893,7 +3092,8 @@ void ioport_manager::record_init()
return;
// open the record file
- std::error_condition const filerr = m_record_file.open(filename);
+ m_record_file = std::make_unique<emu_file>(machine().options().input_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+ std::error_condition const filerr = m_record_file->open(filename);
if (filerr)
throw emu_fatalerror("ioport_manager::record_init: Failed to open file for recording (%s:%d %s)", filerr.category().name(), filerr.value(), filerr.message());
@@ -2910,10 +3110,10 @@ void ioport_manager::record_init()
header.set_appdesc(util::string_format("%s %s", emulator_info::get_appname(), emulator_info::get_build_version()));
// write it
- header.write(m_record_file);
+ header.write(*m_record_file);
// enable compression
- m_record_stream = util::zlib_write(m_record_file, 6, 16384);
+ m_record_stream = util::zlib_write(*m_record_file, 6, 16384);
}
@@ -2928,7 +3128,7 @@ void ioport_manager::record_end(const char *message)
{
// close the file
m_record_stream.reset(); // TODO: check for errors flushing the last compressed block before doing this
- m_record_file.close();
+ m_record_file.reset();
// pop a message
if (message != nullptr)
@@ -3260,6 +3460,7 @@ analog_field::analog_field(ioport_field &field)
m_adjdefvalue(field.defvalue() & field.mask()),
m_adjmin(field.minval() & field.mask()),
m_adjmax(field.maxval() & field.mask()),
+ m_adjoverride(field.defvalue() & field.mask()),
m_sensitivity(field.sensitivity()),
m_reverse(field.analog_reverse()),
m_delta(field.delta()),
@@ -3267,7 +3468,6 @@ analog_field::analog_field(ioport_field &field)
m_accum(0),
m_previous(0),
m_previousanalog(0),
- m_prog_analog_value(0),
m_minimum(INPUT_ABSOLUTE_MIN),
m_maximum(INPUT_ABSOLUTE_MAX),
m_center(0),
@@ -3283,7 +3483,7 @@ analog_field::analog_field(ioport_field &field)
m_single_scale(false),
m_interpolate(false),
m_lastdigital(false),
- m_was_written(false)
+ m_use_adjoverride(false)
{
// compute the shift amount and number of bits
for (ioport_value mask = field.mask(); !(mask & 1); mask >>= 1)
@@ -3523,16 +3723,28 @@ s32 analog_field::apply_settings(s32 value) const
//-------------------------------------------------
-// set_value - take a new value to be used
-// at next frame update
+// set_value - override the value that will be
+// read from the field
//-------------------------------------------------
void analog_field::set_value(s32 value)
{
- m_was_written = true;
- m_prog_analog_value = value;
+ m_use_adjoverride = true;
+ m_adjoverride = std::clamp(value, m_adjmin, m_adjmax);
+}
+
+
+//-------------------------------------------------
+// clear_value - clear programmatic override
+//-------------------------------------------------
+
+void analog_field::clear_value()
+{
+ m_use_adjoverride = false;
+ m_adjoverride = m_adjdefvalue;
}
+
//-------------------------------------------------
// frame_update - update the internals of a
// single analog field periodically
@@ -3551,13 +3763,6 @@ void analog_field::frame_update(running_machine &machine)
input_item_class itemclass;
s32 rawvalue = machine.input().seq_axis_value(m_field.seq(SEQ_TYPE_STANDARD), itemclass);
- // use programmatically set value if available
- if (m_was_written)
- {
- m_was_written = false;
- rawvalue = m_prog_analog_value;
- }
-
// if we got an absolute input, it overrides everything else
if (itemclass == ITEM_CLASS_ABSOLUTE)
{
@@ -3703,6 +3908,13 @@ void analog_field::read(ioport_value &result)
if (!m_field.enabled())
return;
+ // if set programmatically, only use the override value
+ if (m_use_adjoverride)
+ {
+ result = m_adjoverride;
+ return;
+ }
+
// start with the raw value
s32 value = m_accum;
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index c767d44c250..76f61debcac 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -662,116 +662,6 @@ typedef device_delegate<void (ioport_field &, u32, ioport_value, ioport_value)>
typedef device_delegate<float (float)> ioport_field_crossmap_delegate;
-// ======================> inp_header
-
-// header at the front of INP files
-class inp_header
-{
-public:
- // parameters
- static constexpr unsigned MAJVERSION = 3;
- static constexpr unsigned MINVERSION = 0;
-
- bool read(emu_file &f)
- {
- return f.read(m_data, sizeof(m_data)) == sizeof(m_data);
- }
- bool write(emu_file &f) const
- {
- return f.write(m_data, sizeof(m_data)) == sizeof(m_data);
- }
-
- bool check_magic() const
- {
- return 0 == std::memcmp(MAGIC, m_data + OFFS_MAGIC, OFFS_BASETIME - OFFS_MAGIC);
- }
- u64 get_basetime() const
- {
- return
- (u64(m_data[OFFS_BASETIME + 0]) << (0 * 8)) |
- (u64(m_data[OFFS_BASETIME + 1]) << (1 * 8)) |
- (u64(m_data[OFFS_BASETIME + 2]) << (2 * 8)) |
- (u64(m_data[OFFS_BASETIME + 3]) << (3 * 8)) |
- (u64(m_data[OFFS_BASETIME + 4]) << (4 * 8)) |
- (u64(m_data[OFFS_BASETIME + 5]) << (5 * 8)) |
- (u64(m_data[OFFS_BASETIME + 6]) << (6 * 8)) |
- (u64(m_data[OFFS_BASETIME + 7]) << (7 * 8));
- }
- unsigned get_majversion() const
- {
- return m_data[OFFS_MAJVERSION];
- }
- unsigned get_minversion() const
- {
- return m_data[OFFS_MINVERSION];
- }
- std::string get_sysname() const
- {
- return get_string<OFFS_SYSNAME, OFFS_APPDESC>();
- }
- std::string get_appdesc() const
- {
- return get_string<OFFS_APPDESC, OFFS_END>();
- }
-
- void set_magic()
- {
- std::memcpy(m_data + OFFS_MAGIC, MAGIC, OFFS_BASETIME - OFFS_MAGIC);
- }
- void set_basetime(u64 time)
- {
- m_data[OFFS_BASETIME + 0] = u8((time >> (0 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 1] = u8((time >> (1 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 2] = u8((time >> (2 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 3] = u8((time >> (3 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 4] = u8((time >> (4 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 5] = u8((time >> (5 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 6] = u8((time >> (6 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 7] = u8((time >> (7 * 8)) & 0x00ff);
- }
- void set_version()
- {
- m_data[OFFS_MAJVERSION] = MAJVERSION;
- m_data[OFFS_MINVERSION] = MINVERSION;
- }
- void set_sysname(std::string const &name)
- {
- set_string<OFFS_SYSNAME, OFFS_APPDESC>(name);
- }
- void set_appdesc(std::string const &desc)
- {
- set_string<OFFS_APPDESC, OFFS_END>(desc);
- }
-
-private:
- template <std::size_t BEGIN, std::size_t END> void set_string(std::string const &str)
- {
- std::size_t const used = (std::min<std::size_t>)(str.size() + 1, END - BEGIN);
- std::memcpy(m_data + BEGIN, str.c_str(), used);
- if ((END - BEGIN) > used)
- std::memset(m_data + BEGIN + used, 0, (END - BEGIN) - used);
- }
- template <std::size_t BEGIN, std::size_t END> std::string get_string() const
- {
- char const *const begin = reinterpret_cast<char const *>(m_data + BEGIN);
- return std::string(begin, std::find(begin, reinterpret_cast<char const *>(m_data + END), '\0'));
- }
-
- static constexpr std::size_t OFFS_MAGIC = 0x00; // 0x08 bytes
- static constexpr std::size_t OFFS_BASETIME = 0x08; // 0x08 bytes (little-endian binary integer)
- static constexpr std::size_t OFFS_MAJVERSION = 0x10; // 0x01 bytes (binary integer)
- static constexpr std::size_t OFFS_MINVERSION = 0x11; // 0x01 bytes (binary integer)
- // 0x02 bytes reserved
- static constexpr std::size_t OFFS_SYSNAME = 0x14; // 0x0c bytes (ASCII)
- static constexpr std::size_t OFFS_APPDESC = 0x20; // 0x20 bytes (ASCII)
- static constexpr std::size_t OFFS_END = 0x40;
-
- static u8 const MAGIC[OFFS_BASETIME - OFFS_MAGIC];
-
- u8 m_data[OFFS_END];
-};
-
-
// ======================> input_device_default
// device defined default input settings
@@ -798,7 +688,7 @@ public:
ioport_group group() const noexcept { return m_group; }
u8 player() const noexcept { return m_player; }
const char *token() const noexcept { return m_token; }
- const char *name() const noexcept { return m_name; }
+ std::string name() const;
input_seq &defseq(input_seq_type seqtype = SEQ_TYPE_STANDARD) noexcept { return m_defseq[seqtype]; }
const input_seq &defseq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept { return m_defseq[seqtype]; }
const input_seq &seq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept { return m_seq[seqtype]; }
@@ -1026,6 +916,7 @@ public:
u8 player() const { return m_player; }
bool digital_value() const { return m_digital_value; }
void set_value(ioport_value value);
+ void clear_value();
bool optional() const { return ((m_flags & FIELD_FLAG_OPTIONAL) != 0); }
bool cocktail() const { return ((m_flags & FIELD_FLAG_COCKTAIL) != 0); }
@@ -1037,7 +928,7 @@ public:
bool analog_invert() const { return ((m_flags & ANALOG_FLAG_INVERT) != 0); }
u8 impulse() const noexcept { return m_impulse; }
- const char *name() const;
+ std::string name() const;
const char *specific_name() const noexcept { return m_name; }
const input_seq &seq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept;
const input_seq &defseq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept;
@@ -1262,8 +1153,9 @@ public:
float crosshair_read();
void frame_update(running_machine &machine);
- // setters
+ // programmatic override (for script bindings)
void set_value(s32 value);
+ void clear_value();
private:
// helpers
@@ -1280,6 +1172,7 @@ private:
s32 m_adjdefvalue; // adjusted default value from the config
s32 m_adjmin; // adjusted minimum value from the config
s32 m_adjmax; // adjusted maximum value from the config
+ s32 m_adjoverride; // programmatically set adjusted value
// live values of configurable parameters
s32 m_sensitivity; // current live sensitivity (100=normal)
@@ -1291,7 +1184,6 @@ private:
s32 m_accum; // accumulated value (including relative adjustments)
s32 m_previous; // previous adjusted value
s32 m_previousanalog; // previous analog value
- s32 m_prog_analog_value; // programmatically set analog value
// parameters for modifying live values
s32 m_minimum; // minimum adjusted value
@@ -1313,7 +1205,7 @@ private:
bool m_single_scale; // scale joystick differently if default is between min/max
bool m_interpolate; // should we do linear interpolation for mid-frame reads?
bool m_lastdigital; // was the last modification caused by a digital form?
- bool m_was_written; // was the last modification caused programmatically?
+ bool m_use_adjoverride; // override what will be read from the field
};
@@ -1382,7 +1274,7 @@ public:
// type helpers
const std::vector<input_type_entry> &types() const noexcept { return m_typelist; }
bool type_pressed(ioport_type type, int player = 0);
- const char *type_name(ioport_type type, u8 player) const noexcept;
+ std::string type_name(ioport_type type, u8 player) const;
ioport_group type_group(ioport_type type, int player) const noexcept;
const input_seq &type_seq(ioport_type type, int player = 0, input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept;
void set_type_seq(ioport_type type, int player, input_seq_type seqtype, const input_seq &newseq) noexcept;
@@ -1449,8 +1341,8 @@ private:
attoseconds_t m_last_delta_nsec; // nanoseconds that passed since the previous callback
// playback/record information
- emu_file m_record_file; // recording file (closed if not recording)
- emu_file m_playback_file; // playback file (closed if not recording)
+ std::unique_ptr<emu_file> m_record_file; // recording file (nullptr if not recording)
+ std::unique_ptr<emu_file> m_playback_file; // playback file (nullptr if not recording)
util::write_stream::ptr m_record_stream; // recording stream (nullptr if not recording)
util::read_stream::ptr m_playback_stream; // playback stream (nullptr if not recording)
u64 m_playback_accumulated_speed; // accumulated speed during playback
diff --git a/src/emu/layout/nes_rob.lay b/src/emu/layout/nes_rob.lay
new file mode 100644
index 00000000000..2cff2a814ad
--- /dev/null
+++ b/src/emu/layout/nes_rob.lay
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!--
+license:CC0
+-->
+<mamelayout version="2">
+
+<!-- define elements -->
+
+ <element name="text_m1"><text align="1" string="motor 1:"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_m2"><text align="1" string="motor 2:"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_m3"><text align="1" string="motor 3:"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+
+ <element name="mstatus0">
+ <text state="1" align="1" string="DOWN"><color red="1.0" green="1.0" blue="0.2" /></text>
+ <text state="0" align="1" string="DOWN"><color red="0.2" green="0.2" blue="0.2" /></text>
+ </element>
+ <element name="mstatus1">
+ <text state="1" align="1" string="UP"><color red="1.0" green="1.0" blue="0.2" /></text>
+ <text state="0" align="1" string="UP"><color red="0.2" green="0.2" blue="0.2" /></text>
+ </element>
+ <element name="mstatus2">
+ <text state="1" align="1" string="CLOSE"><color red="1.0" green="1.0" blue="0.2" /></text>
+ <text state="0" align="1" string="CLOSE"><color red="0.2" green="0.2" blue="0.2" /></text>
+ </element>
+ <element name="mstatus3">
+ <text state="1" align="1" string="OPEN"><color red="1.0" green="1.0" blue="0.2" /></text>
+ <text state="0" align="1" string="OPEN"><color red="0.2" green="0.2" blue="0.2" /></text>
+ </element>
+ <element name="mstatus4">
+ <text state="1" align="1" string="RIGHT"><color red="1.0" green="1.0" blue="0.2" /></text>
+ <text state="0" align="1" string="RIGHT"><color red="0.2" green="0.2" blue="0.2" /></text>
+ </element>
+ <element name="mstatus5">
+ <text state="1" align="1" string="LEFT"><color red="1.0" green="1.0" blue="0.2" /></text>
+ <text state="0" align="1" string="LEFT"><color red="0.2" green="0.2" blue="0.2" /></text>
+ </element>
+
+ <element name="led" defstate="0">
+ <disk state="1"><color red="1.0" green="0.1" blue="0.15" /></disk>
+ <disk state="0"><color red="0.15" green="0.015" blue="0.017" /></disk>
+ </element>
+
+
+<!-- build screen -->
+
+ <view name="Internal Layout">
+ <bounds left="4.5" right="17" top="7" bottom="14.25" />
+
+ <element ref="text_m1"><bounds x="5.5" y="10" width="5" height="1" /></element>
+ <element ref="text_m2"><bounds x="5.5" y="11.25" width="5" height="1" /></element>
+ <element ref="text_m3"><bounds x="5.5" y="12.5" width="5" height="1" /></element>
+
+ <element name="rob_motor.1" ref="mstatus1"><bounds x="10" y="10" width="5" height="1" /></element>
+ <element name="rob_motor.0" ref="mstatus0"><bounds x="13.5" y="10" width="5" height="1" /></element>
+ <element name="rob_motor.5" ref="mstatus5"><bounds x="10" y="11.25" width="5" height="1" /></element>
+ <element name="rob_motor.4" ref="mstatus4"><bounds x="13.5" y="11.25" width="5" height="1" /></element>
+ <element name="rob_motor.2" ref="mstatus2"><bounds x="10" y="12.5" width="5" height="1" /></element>
+ <element name="rob_motor.3" ref="mstatus3"><bounds x="13.5" y="12.5" width="5" height="1" /></element>
+
+ <element name="rob_led" ref="led"><bounds x="10" y="8" width="1" height="1" /></element>
+
+ </view>
+</mamelayout>
diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp
index 7e9d8091359..6613c5654bf 100644
--- a/src/emu/machine.cpp
+++ b/src/emu/machine.cpp
@@ -6,91 +6,39 @@
Controls execution of the core MAME system.
-****************************************************************************
-
- Since there has been confusion in the past over the order of
- initialization and other such things, here it is, all spelled out
- as of January, 2008:
-
- main()
- - does platform-specific init
- - calls mame_execute() [mame.c]
-
- mame_execute() [mame.c]
- - calls mame_validitychecks() [validity.c] to perform validity checks on all compiled drivers
- - begins resource tracking (level 1)
- - calls create_machine [mame.c] to initialize the running_machine structure
- - calls init_machine() [mame.c]
-
- init_machine() [mame.c]
- - calls fileio_init() [fileio.c] to initialize file I/O info
- - calls config_init() [config.c] to initialize configuration system
- - calls input_init() [input.c] to initialize the input system
- - calls output_init() [output.c] to initialize the output system
- - calls state_init() [state.c] to initialize save state system
- - calls state_save_allow_registration() [state.c] to allow registrations
- - calls palette_init() [palette.c] to initialize palette system
- - calls render_init() [render.c] to initialize the rendering system
- - calls ui_init() [ui.c] to initialize the user interface
- - calls generic_machine_init() [machine/generic.c] to initialize generic machine structures
- - calls timer_init() [timer.c] to reset the timer system
- - calls osd_init() [osdepend.h] to do platform-specific initialization
- - calls input_port_init() [inptport.c] to set up the input ports
- - calls rom_init() [romload.c] to load the game's ROMs
- - calls memory_init() [memory.c] to process the game's memory maps
- - calls the driver's DRIVER_INIT callback
- - calls device_list_start() [devintrf.c] to start any devices
- - calls video_init() [video.c] to start the video system
- - calls tilemap_init() [tilemap.c] to start the tilemap system
- - calls crosshair_init() [crsshair.c] to configure the crosshairs
- - calls sound_init() [sound.c] to start the audio system
- - calls debugger_init() [debugger.c] to set up the debugger
- - calls the driver's MACHINE_START, SOUND_START, and VIDEO_START callbacks
- - calls cheat_init() [cheat.c] to initialize the cheat system
- - calls image_init() [image.c] to initialize the image system
-
- - calls config_load_settings() [config.c] to load the configuration file
- - calls nvram_load [machine/generic.c] to load NVRAM
- - calls ui_display_startup_screens() [ui.c] to display the startup screens
- - begins resource tracking (level 2)
- - calls soft_reset() [mame.c] to reset all systems
-
- -------------------( at this point, we're up and running )----------------------
-
- - calls scheduler->timeslice() [schedule.c] over and over until we exit
- - ends resource tracking (level 2), freeing all auto_mallocs and timers
- - calls the nvram_save() [machine/generic.c] to save NVRAM
- - calls config_save_settings() [config.c] to save the game's configuration
- - calls all registered exit routines [mame.c]
- - ends resource tracking (level 1), freeing all auto_mallocs and timers
-
- - exits the program
-
***************************************************************************/
#include "emu.h"
-#include "emuopts.h"
-#include "osdepend.h"
+
#include "config.h"
-#include "debugger.h"
-#include "render.h"
-#include "uiinput.h"
#include "crsshair.h"
-#include "unzip.h"
-#include "debug/debugvw.h"
#include "debug/debugcpu.h"
+#include "debug/debugvw.h"
+#include "debugger.h"
#include "dirtc.h"
+#include "emuopts.h"
+#include "fileio.h"
+#include "http.h"
#include "image.h"
+#include "natkeyboard.h"
#include "network.h"
+#include "render.h"
#include "romload.h"
#include "tilemap.h"
-#include "natkeyboard.h"
+#include "uiinput.h"
+
#include "ui/uimain.h"
+
#include "corestr.h"
-#include <ctime>
+#include "unzip.h"
+
+#include "osdepend.h"
+
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
+#include <ctime>
+
#if defined(__EMSCRIPTEN__)
#include <emscripten.h>
#endif
@@ -497,7 +445,7 @@ void running_machine::schedule_soft_reset()
//-------------------------------------------------
// get_statename - allow to specify a subfolder of
// the state directory for state loading/saving,
-// very useful for MESS and consoles or computers
+// very useful for consoles or computers
// where you can have separate folders for diff
// software
//-------------------------------------------------
@@ -645,10 +593,10 @@ void running_machine::schedule_save(std::string &&filename)
// immediate_save - save state.
//-------------------------------------------------
-void running_machine::immediate_save(const char *filename)
+void running_machine::immediate_save(std::string_view filename)
{
// specify the filename to save or load
- set_saveload_filename(filename);
+ set_saveload_filename(std::string(filename));
// set up some parameters for handle_saveload()
m_saveload_schedule = saveload_schedule::SAVE;
@@ -682,10 +630,10 @@ void running_machine::schedule_load(std::string &&filename)
// immediate_load - load state.
//-------------------------------------------------
-void running_machine::immediate_load(const char *filename)
+void running_machine::immediate_load(std::string_view filename)
{
// specify the filename to save or load
- set_saveload_filename(filename);
+ set_saveload_filename(std::string(filename));
// set up some parameters for handle_saveload()
m_saveload_schedule = saveload_schedule::LOAD;
@@ -997,7 +945,7 @@ void running_machine::handle_saveload()
// of the system
//-------------------------------------------------
-void running_machine::soft_reset(void *ptr, s32 param)
+void running_machine::soft_reset(s32 param)
{
logerror("Soft reset\n");
@@ -1028,6 +976,17 @@ void running_machine::logfile_callback(const char *buffer)
//-------------------------------------------------
+// steal_debuglogfile - relinquish ownership of
+// the debug.log file
+//-------------------------------------------------
+
+std::unique_ptr<emu_file> running_machine::steal_debuglogfile()
+{
+ return std::move(m_debuglogfile);
+}
+
+
+//-------------------------------------------------
// start_all_devices - start any unstarted devices
//-------------------------------------------------
@@ -1176,7 +1135,8 @@ void running_machine::nvram_load()
emu_file file(options().nvram_directory(), OPEN_FLAG_READ);
if (!file.open(nvram_filename(nvram.device())))
{
- nvram.nvram_load(file);
+ if (!nvram.nvram_load(file))
+ osd_printf_error("Error reading NVRAM file %s\n", file.filename());
file.close();
}
else
@@ -1198,7 +1158,8 @@ void running_machine::nvram_save()
emu_file file(options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
if (!file.open(nvram_filename(nvram.device())))
{
- nvram.nvram_save(file);
+ if (!nvram.nvram_save(file))
+ osd_printf_error("Error writing NVRAM file %s\n", file.filename());
file.close();
}
}
diff --git a/src/emu/machine.h b/src/emu/machine.h
index f3aef08d265..4bef86ce3a7 100644
--- a/src/emu/machine.h
+++ b/src/emu/machine.h
@@ -177,8 +177,8 @@ public:
void export_http_api();
// TODO: Do saves and loads still require scheduling?
- void immediate_save(const char *filename);
- void immediate_load(const char *filename);
+ void immediate_save(std::string_view filename);
+ void immediate_load(std::string_view filename);
// rewind operations
bool rewind_capture();
@@ -217,7 +217,7 @@ public:
bool debug_enabled() { return (debug_flags & DEBUG_FLAG_ENABLED) != 0; }
// used by debug_console to take ownership of the debug.log file
- std::unique_ptr<emu_file> steal_debuglogfile() { return std::move(m_debuglogfile); }
+ std::unique_ptr<emu_file> steal_debuglogfile();
private:
class side_effects_disabler {
@@ -248,7 +248,7 @@ private:
void start();
void set_saveload_filename(std::string &&filename);
void handle_saveload();
- void soft_reset(void *ptr = nullptr, s32 param = 0);
+ void soft_reset(s32 param = 0);
std::string nvram_filename(device_t &device) const;
void nvram_load();
void nvram_save();
diff --git a/src/emu/main.cpp b/src/emu/main.cpp
index e5467238238..6ce109ae1ef 100644
--- a/src/emu/main.cpp
+++ b/src/emu/main.cpp
@@ -10,6 +10,7 @@
#include "emu.h"
#include "emuopts.h"
+#include "http.h"
machine_manager::machine_manager(emu_options& options, osd_interface& osd)
: m_osd(osd),
@@ -18,8 +19,17 @@ machine_manager::machine_manager(emu_options& options, osd_interface& osd)
{
}
+machine_manager::~machine_manager()
+{
+}
+
void machine_manager::start_http_server()
{
m_http = std::make_unique<http_manager>(options().http(), options().http_port(), options().http_root());
}
+
+http_manager *machine_manager::http()
+{
+ return m_http.get();
+}
diff --git a/src/emu/main.h b/src/emu/main.h
index 3c75205de14..89399e21690 100644
--- a/src/emu/main.h
+++ b/src/emu/main.h
@@ -71,7 +71,7 @@ protected:
// construction/destruction
machine_manager(emu_options& options, osd_interface& osd);
public:
- virtual ~machine_manager() { }
+ virtual ~machine_manager();
osd_interface &osd() const { return m_osd; }
emu_options &options() const { return m_options; }
@@ -88,7 +88,7 @@ public:
virtual void update_machine() { }
- http_manager *http() { return m_http.get(); }
+ http_manager *http();
void start_http_server();
protected:
diff --git a/src/emu/mconfig.cpp b/src/emu/mconfig.cpp
index fb97c3138a3..2c8c1aa011b 100644
--- a/src/emu/mconfig.cpp
+++ b/src/emu/mconfig.cpp
@@ -257,24 +257,23 @@ std::pair<const char *, device_t *> machine_config::resolve_owner(const char *ta
device_t *owner(m_current_device);
// if the device path is absolute, start from the root
- if (tag[0] == ':')
- {
- tag++;
- owner = m_root_device.get();
- }
+ if (!*tag || (':' == *tag) || ('^' == *tag))
+ throw emu_fatalerror("Attempting to add device with tag containing parent references '%s'\n", orig_tag);
// go down the path until we're done with it
- while (strchr(tag, ':'))
+ char const *next;
+ while ((next = strchr(tag, ':')) != nullptr)
{
- const char *next = strchr(tag, ':');
assert(next != tag);
std::string_view part(tag, next - tag);
owner = owner->subdevices().find(part);
if (!owner)
- throw emu_fatalerror("Could not find %s when looking up path for device %s\n", part, orig_tag);
- tag = next+1;
+ throw emu_fatalerror("Could not find '%s' when looking up path for device '%s'\n", part, orig_tag);
+ tag = next + 1;
+ if ('^' == *tag)
+ throw emu_fatalerror("Attempting to add device with tag containing parent references '%s'\n", orig_tag);
}
- assert(tag[0] != '\0');
+ assert(*tag != '\0');
return std::make_pair(tag, owner);
}
@@ -296,7 +295,7 @@ std::tuple<const char *, device_t *, device_t *> machine_config::prepare_replace
if (old_device)
remove_references(*old_device);
else
- osd_printf_warning("Warning: attempting to replace non-existent device '%s'\n", tag);
+ throw emu_fatalerror("Attempting to replace non-existent device '%s'\n", tag);
return std::make_tuple(owner.first, owner.second, old_device);
}
diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h
index c600ca06665..c6cacde581f 100644
--- a/src/emu/mconfig.h
+++ b/src/emu/mconfig.h
@@ -133,7 +133,7 @@ public:
/// replace an existing device.
/// \return A device replacement helper to pass to a device type
/// when replacing an existing device.
- emu::detail::machine_config_replace replace() { return emu::detail::machine_config_replace(*this); };
+ emu::detail::machine_config_replace replace() { return emu::detail::machine_config_replace(*this); }
/// \brief Set internal layout for current device
///
diff --git a/src/emu/memarray.cpp b/src/emu/memarray.cpp
index 22bfa17b80a..660e07ad9a1 100644
--- a/src/emu/memarray.cpp
+++ b/src/emu/memarray.cpp
@@ -90,11 +90,6 @@ void memory_array::set(void *base, u32 bytes, int membits, endianness_t endianne
// set - additional setter variants
//-------------------------------------------------
-void memory_array::set(const address_space &space, void *base, u32 bytes, int bpe)
-{
- set(base, bytes, space.data_width(), space.endianness(), bpe);
-}
-
void memory_array::set(const memory_share &share, int bpe)
{
set(share.ptr(), share.bytes(), share.bitwidth(), share.endianness(), bpe);
diff --git a/src/emu/memarray.h b/src/emu/memarray.h
index f9a7e406a8e..fc7e47c4b3c 100644
--- a/src/emu/memarray.h
+++ b/src/emu/memarray.h
@@ -42,14 +42,12 @@ public:
memory_array();
memory_array(void *base, u32 bytes, int membits, endianness_t endianness, int bpe) { set(base, bytes, membits, endianness, bpe); }
template <typename _Type> memory_array(std::vector<_Type> &array, endianness_t endianness, int bpe) { set(array, endianness, bpe); }
- memory_array(const address_space &space, void *base, u32 bytes, int bpe) { set(space, base, bytes, bpe); }
memory_array(const memory_share &share, int bpe) { set(share, bpe); }
memory_array(const memory_array &array) { set(array); }
// configuration
void set(void *base, u32 bytes, int membits, endianness_t endianness, int bpe);
template <typename _Type> void set(std::vector<_Type> &array, endianness_t endianness, int bpe) { set(&array[0], array.size(), 8*sizeof(_Type), endianness, bpe); }
- void set(const address_space &space, void *base, u32 bytes, int bpe);
void set(const memory_share &share, int bpe);
void set(const memory_array &array);
diff --git a/src/emu/natkeyboard.cpp b/src/emu/natkeyboard.cpp
index e5dcdc93dbc..5a36e6b8e13 100644
--- a/src/emu/natkeyboard.cpp
+++ b/src/emu/natkeyboard.cpp
@@ -864,7 +864,7 @@ void natural_keyboard::internal_post(char32_t ch)
// when posting a string of characters
//-------------------------------------------------
-void natural_keyboard::timer(void *ptr, int param)
+void natural_keyboard::timer(s32 param)
{
if (!m_queue_chars.isnull())
{
diff --git a/src/emu/natkeyboard.h b/src/emu/natkeyboard.h
index c3454ee8dd4..dc89b0eb156 100644
--- a/src/emu/natkeyboard.h
+++ b/src/emu/natkeyboard.h
@@ -109,7 +109,7 @@ private:
bool can_post_alternate(char32_t ch);
attotime choose_delay(char32_t ch);
void internal_post(char32_t ch);
- void timer(void *ptr, int param);
+ void timer(s32 param);
std::string unicode_to_string(char32_t ch) const;
const keycode_map_entry *find_code(char32_t ch) const;
diff --git a/src/emu/recording.cpp b/src/emu/recording.cpp
index 9e3c1f3f4ae..611e5ae327b 100644
--- a/src/emu/recording.cpp
+++ b/src/emu/recording.cpp
@@ -9,7 +9,10 @@
***************************************************************************/
#include "emu.h"
+
+#include "fileio.h"
#include "screen.h"
+
#include "aviio.h"
#include "png.h"
diff --git a/src/emu/render.cpp b/src/emu/render.cpp
index 1f9918539d5..b9a96e81fad 100644
--- a/src/emu/render.cpp
+++ b/src/emu/render.cpp
@@ -41,6 +41,7 @@
#include "corestr.h"
#include "emuopts.h"
+#include "fileio.h"
#include "rendfont.h"
#include "rendlay.h"
#include "rendutil.h"
@@ -1197,63 +1198,103 @@ void render_target::compute_visible_area(s32 target_width, s32 target_height, fl
// apply orientation if required
if (target_orientation & ORIENTATION_SWAP_XY)
- src_aspect = 1.0 / src_aspect;
+ src_aspect = 1.0f / src_aspect;
- // get target aspect
- float target_aspect = (float)target_width / (float)target_height * target_pixel_aspect;
+ // we need the ratio of target to source aspect
+ float aspect_ratio = m_keepaspect ? (float)target_width / (float)target_height * target_pixel_aspect / src_aspect : 1.0f;
+
+ // first compute (a, b) scale factors to fit the screen
+ float a = (float)target_width / src_width;
+ float b = (float)target_height / src_height;
// apply automatic axial stretching if required
int scale_mode = m_scale_mode;
- if (m_scale_mode == SCALE_FRACTIONAL_AUTO)
- {
- bool is_rotated = (m_manager.machine().system().flags & ORIENTATION_SWAP_XY) ^ (target_orientation & ORIENTATION_SWAP_XY);
- scale_mode = is_rotated ? SCALE_FRACTIONAL_Y : SCALE_FRACTIONAL_X;
- }
+ if (scale_mode == SCALE_FRACTIONAL_AUTO)
+ scale_mode = (m_manager.machine().system().flags & ORIENTATION_SWAP_XY) ^ (target_orientation & ORIENTATION_SWAP_XY) ?
+ SCALE_FRACTIONAL_Y : SCALE_FRACTIONAL_X;
- // first compute scale factors to fit the screen
- float xscale = (float)target_width / src_width;
- float yscale = (float)target_height / src_height;
+ // determine the scaling method for each axis
+ bool a_is_fract = (scale_mode == SCALE_FRACTIONAL_X || scale_mode == SCALE_FRACTIONAL);
+ bool b_is_fract = (scale_mode == SCALE_FRACTIONAL_Y || scale_mode == SCALE_FRACTIONAL);
- // apply aspect correction
- if (m_keepaspect)
- {
- if (target_aspect > src_aspect)
- xscale *= src_aspect / target_aspect;
- else
- yscale *= target_aspect / src_aspect;
- }
+ // check if we have user defined scale factors, if so use them instead, but only on integer axes
+ int a_user = a_is_fract ? 0 : m_int_scale_x;
+ int b_user = b_is_fract ? 0 : m_int_scale_y;
- bool x_fits = render_round_nearest(xscale) * src_width <= target_width;
- bool y_fits = render_round_nearest(yscale) * src_height <= target_height;
+ // we allow overscan either explicitely or if integer scale factors are forced by user
+ bool int_overscan = m_int_overscan || (m_keepaspect && (a_user != 0 || b_user != 0));
+ float a_max = std::max(a, (float)a_user);
+ float b_max = std::max(b, (float)b_user);
- // compute integer scale factors
- float integer_x = std::max(1.0f, float(m_int_overscan || x_fits ? render_round_nearest(xscale) : floor(xscale)));
- float integer_y = std::max(1.0f, float(m_int_overscan || y_fits ? render_round_nearest(yscale) : floor(yscale)));
- // check if we have user defined scale factors, if so use them instead
- integer_x = m_int_scale_x > 0 ? m_int_scale_x : integer_x;
- integer_y = m_int_scale_y > 0 ? m_int_scale_y : integer_y;
+ // get the usable bounding box considering the type of scaling for each axis
+ float usable_aspect = (a_is_fract ? a : std::max(1.0f, floorf(a))) * src_width /
+ ((b_is_fract ? b : std::max(1.0f, floorf(b))) * src_height) * target_pixel_aspect;
- // now apply desired scale mode
- if (scale_mode == SCALE_FRACTIONAL_X)
+ // depending on the relative shape between target and source, let's define 'a' and 'b' so that:
+ // * a is the leader axis (first to hit a boundary)
+ // * b is the follower axis
+ if (usable_aspect > src_aspect)
{
- if (m_keepaspect) xscale *= integer_y / yscale;
- yscale = integer_y;
+ std::swap(a, b);
+ std::swap(a_user, b_user);
+ std::swap(a_is_fract, b_is_fract);
+ std::swap(a_max, b_max);
+ aspect_ratio = 1.0f / aspect_ratio;
}
- else if (scale_mode == SCALE_FRACTIONAL_Y)
- {
- if (m_keepaspect) yscale *= integer_x / xscale;
- xscale = integer_x;
- }
- else
+
+ // now find an (a, b) pair that best fits our boundaries and scale options
+ float a_best = 1.0f, b_best = 1.0f;
+ float diff = 1000;
+
+ // fill (a0, a1) range
+ float u = a_user == 0 ? a : (float)a_user;
+ float a_range[] = {a_is_fract ? u : std::max(1.0f, floorf(u)), a_is_fract ? u : std::max(1.0f, roundf(u))};
+
+ for (float aa : a_range)
{
- xscale = integer_x;
- yscale = integer_y;
+ // apply aspect correction to 'b' axis if needed, considering resulting 'a' borders
+ float ba = b * (m_keepaspect ? aspect_ratio * (aa / a) : 1.0f);
+
+ // fill (b0, b1) range
+ float v = b_user == 0 ? ba : (float)b_user;
+ float b_range[] = {b_is_fract ? v : std::max(1.0f, floorf(v)), b_is_fract ? v : std::max(1.0f, roundf(v))};
+
+ for (float bb : b_range)
+ {
+ // we may need to propagate proportions back to 'a' axis
+ float ab = aa;
+ if (m_keepaspect && a_user == 0)
+ {
+ if (a_is_fract) ab *= (bb / ba);
+ else if (b_user != 0) ab = std::max(1.0f, roundf(ab * (bb / ba)));
+ }
+
+ // if overscan isn't allowed, discard values that exceed the usable bounding box, except a minimum of 1.0f
+ if (!int_overscan && ((ab > a_max && bb > 1.0f) || (bb > b_max && ab > 1.0f)))
+ continue;
+
+ // score the result
+ float new_diff = fabsf(aspect_ratio * (a / b) - (ab / bb));
+
+ if (new_diff <= diff)
+ {
+ diff = new_diff;
+ a_best = ab;
+ b_best = bb;
+ }
+ }
}
+ a = a_best;
+ b = b_best;
+
+ // restore orientation
+ if (usable_aspect > src_aspect)
+ std::swap(a, b);
// set the final width/height
- visible_width = render_round_nearest(src_width * xscale);
- visible_height = render_round_nearest(src_height * yscale);
+ visible_width = render_round_nearest(src_width * a);
+ visible_height = render_round_nearest(src_height * b);
break;
}
}
@@ -1338,10 +1379,6 @@ void render_target::compute_minimum_size(s32 &minwidth, s32 &minheight)
render_primitive_list &render_target::get_primitives()
{
- // remember the base values if this is the first frame
- if (!m_base_view)
- m_base_view = &current_view();
-
// switch to the next primitive list
render_primitive_list &list = m_primlist[m_listindex];
m_listindex = (m_listindex + 1) % std::size(m_primlist);
@@ -2313,11 +2350,11 @@ void render_target::add_container_primitives(render_primitive_list &list, const
// clip the primitive
if (!m_transform_container && PRIMFLAG_GET_VECTOR(curitem.flags()))
{
- clipped = render_clip_line(&prim->bounds, &root_cliprect);
+ clipped = render_clip_line(prim->bounds, root_cliprect);
}
else
{
- clipped = render_clip_line(&prim->bounds, &cliprect);
+ clipped = render_clip_line(prim->bounds, cliprect);
}
break;
@@ -2350,7 +2387,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const
prim->texcoords = oriented_texcoords[finalorient];
// apply clipping
- clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords);
+ clipped = render_clip_quad(prim->bounds, cliprect, &prim->texcoords);
// apply the final orientation from the quad flags and then build up the final flags
prim->flags |= (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK))
@@ -2410,7 +2447,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const
prim->texcoords = oriented_texcoords[finalorient];
// apply clipping
- clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords);
+ clipped = render_clip_quad(prim->bounds, cliprect, &prim->texcoords);
// apply the final orientation from the quad flags and then build up the final flags
prim->flags |= (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK))
@@ -2426,7 +2463,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const
| PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA);
// apply clipping
- clipped = render_clip_quad(&prim->bounds, &cliprect, nullptr);
+ clipped = render_clip_quad(prim->bounds, cliprect, nullptr);
}
}
break;
@@ -2551,7 +2588,7 @@ void render_target::add_element_primitives(render_primitive_list &list, const ob
}
// add to the list or free if we're clipped out
- bool const clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords);
+ bool const clipped = render_clip_quad(prim->bounds, cliprect, &prim->texcoords);
list.append_or_return(*prim, clipped);
}
}
@@ -2613,10 +2650,18 @@ int render_target::view_index(layout_view &targetview) const
// config_load - process config information
//-------------------------------------------------
-void render_target::config_load(util::xml::data_node const &targetnode)
+void render_target::config_load(util::xml::data_node const *targetnode)
{
+ // remember the view selected via command line and INI options
+ if (!m_base_view)
+ m_base_view = &current_view();
+
+ // bail if no configuration
+ if (!targetnode)
+ return;
+
// find the view
- const char *viewname = targetnode.get_attribute_string("view", nullptr);
+ const char *viewname = targetnode->get_attribute_string("view", nullptr);
if (viewname != nullptr)
for (int viewnum = 0; viewnum < 1000; viewnum++)
{
@@ -2631,12 +2676,12 @@ void render_target::config_load(util::xml::data_node const &targetnode)
}
// modify the artwork config
- int const zoom = targetnode.get_attribute_int("zoom", -1);
+ int const zoom = targetnode->get_attribute_int("zoom", -1);
if (zoom == 0 || zoom == 1)
set_zoom_to_screen(zoom);
// apply orientation
- int rotate = targetnode.get_attribute_int("rotate", -1);
+ int rotate = targetnode->get_attribute_int("rotate", -1);
if (rotate != -1)
{
if (rotate == 90)
@@ -2660,7 +2705,7 @@ void render_target::config_load(util::xml::data_node const &targetnode)
}
// apply per-view settings
- for (util::xml::data_node const *viewnode = targetnode.get_child("view"); viewnode; viewnode = viewnode->get_next_sibling("view"))
+ for (util::xml::data_node const *viewnode = targetnode->get_child("view"); viewnode; viewnode = viewnode->get_next_sibling("view"))
{
char const *const viewname = viewnode->get_attribute_string("name", nullptr);
if (!viewname)
@@ -3297,8 +3342,20 @@ void render_manager::resolve_tags()
void render_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
// we only care about system-specific configuration with matching nodes
- if ((cfg_type != config_type::SYSTEM) || !parentnode)
+ if (cfg_type == config_type::DEFAULT)
+ {
+ // let the targets stabilise themselves
+ for (render_target &target : m_targetlist)
+ {
+ if (!target.hidden())
+ target.config_load(nullptr);
+ }
return;
+ }
+ else if ((cfg_type != config_type::SYSTEM) || !parentnode)
+ {
+ return;
+ }
// check the UI target
util::xml::data_node const *const uinode = parentnode->get_child("interface");
@@ -3314,7 +3371,7 @@ void render_manager::config_load(config_type cfg_type, config_level cfg_level, u
{
render_target *const target = target_by_index(targetnode->get_attribute_int("index", -1));
if (target && !target->hidden())
- target->config_load(*targetnode);
+ target->config_load(targetnode);
}
// iterate over screen nodes
diff --git a/src/emu/render.h b/src/emu/render.h
index d4f99377d70..27205206d1f 100644
--- a/src/emu/render.h
+++ b/src/emu/render.h
@@ -47,18 +47,11 @@
#define MAME_EMU_RENDER_H
#include "rendertypes.h"
-#include "screen.h"
-#include <array>
#include <cmath>
-#include <functional>
-#include <map>
+#include <list>
#include <memory>
#include <mutex>
-#include <string>
-#include <string_view>
-#include <tuple>
-#include <unordered_map>
#include <utility>
#include <vector>
@@ -586,7 +579,7 @@ private:
std::pair<float, float> map_point_internal(s32 target_x, s32 target_y);
// config callbacks
- void config_load(util::xml::data_node const &targetnode);
+ void config_load(util::xml::data_node const *targetnode);
bool config_save(util::xml::data_node &targetnode);
// view lookups
diff --git a/src/emu/rendertypes.h b/src/emu/rendertypes.h
index 43f2ebb85e7..b3eed6ad9bd 100644
--- a/src/emu/rendertypes.h
+++ b/src/emu/rendertypes.h
@@ -20,6 +20,16 @@
//**************************************************************************
+// texture formats
+enum texture_format
+{
+ TEXFORMAT_UNDEFINED = 0, // require a format to be specified
+ TEXFORMAT_PALETTE16, // 16bpp palettized, no alpha
+ TEXFORMAT_RGB32, // 32bpp 8-8-8 RGB
+ TEXFORMAT_ARGB32, // 32bpp 8-8-8-8 ARGB
+ TEXFORMAT_YUY16 // 16bpp 8-8 Y/Cb, Y/Cr in sequence
+};
+
// blending modes
enum
{
diff --git a/src/emu/rendfont.cpp b/src/emu/rendfont.cpp
index ae295e39e2d..3d79f0e6ac2 100644
--- a/src/emu/rendfont.cpp
+++ b/src/emu/rendfont.cpp
@@ -10,7 +10,10 @@
#include "emu.h"
#include "rendfont.h"
+
#include "emuopts.h"
+#include "fileio.h"
+
#include "corestr.h"
#include "coreutil.h"
@@ -121,13 +124,15 @@ public:
static constexpr unsigned MAJVERSION = 1;
static constexpr unsigned MINVERSION = 0;
- bool read(emu_file &f)
+ bool read(util::read_stream &f)
{
- return f.read(m_data, sizeof(m_data)) == sizeof(m_data);
+ std::size_t actual(0);
+ return !f.read(m_data, sizeof(m_data), actual) && actual == sizeof(m_data);
}
- bool write(emu_file &f)
+ bool write(util::write_stream &f)
{
- return f.write(m_data, sizeof(m_data)) == sizeof(m_data);
+ std::size_t actual(0);
+ return !f.write(m_data, sizeof(m_data), actual) && actual == sizeof(m_data);
}
bool check_magic() const
@@ -593,10 +598,9 @@ render_font::render_font(render_manager &manager, const char *filename)
}
// load the compiled in data instead
- emu_file ramfile(OPEN_FLAG_READ);
- std::error_condition const filerr(ramfile.open_ram(font_uismall, sizeof(font_uismall)));
- if (!filerr)
- load_cached(ramfile, 0, 0);
+ util::random_read::ptr ramfile = util::ram_read(font_uismall, sizeof(font_uismall));
+ if (ramfile)
+ load_cached(*ramfile, 0, 0);
render_font_command_glyph();
}
@@ -906,11 +910,11 @@ float render_font::utf8string_width(float height, float aspect, std::string_view
// and create a new cached version
//-------------------------------------------------
-bool render_font::load_cached_bdf(const char *filename)
+bool render_font::load_cached_bdf(std::string_view filename)
{
std::error_condition filerr;
u32 chunk;
- u64 bytes;
+ std::size_t bytes;
// first try to open the BDF itself
emu_file file(m_manager.machine().options().font_path(), OPEN_FLAG_READ);
@@ -943,9 +947,7 @@ bool render_font::load_cached_bdf(const char *filename)
u32 const hash(core_crc32(0, reinterpret_cast<u8 const *>(&m_rawdata[0]), bytes));
// create the cached filename, changing the 'F' to a 'C' on the extension
- std::string cachedname(filename);
- if ((4U < cachedname.length()) && !core_stricmp(&cachedname[cachedname.length() - 4], ".bdf"))
- cachedname.erase(cachedname.length() - 4);
+ std::string cachedname(filename, 0, filename.length() - ((4U < filename.length()) && core_filename_ends_with(filename, ".bdf") ? 4 : 0));
cachedname.append(".bdc");
// attempt to open the cached version of the font
@@ -978,11 +980,25 @@ bool render_font::load_cached_bdf(const char *filename)
m_rawdata[m_rawsize] = '\0';
// load the BDF
- bool const result = load_bdf();
+ bool result = load_bdf();
// if we loaded okay, create a cached one
if (result)
- save_cached(cachedname.c_str(), m_rawsize, hash);
+ {
+ osd_printf_info("Generating cached BDF font...\n");
+
+ // attempt to open the file
+ emu_file cachefile(m_manager.machine().options().font_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
+ filerr = cachefile.open(cachedname);
+ if (filerr)
+ result = false;
+ else
+ {
+ result = save_cached(cachefile, m_rawsize, hash);
+ if (!result)
+ cachefile.remove_on_close();
+ }
+ }
else
m_rawdata.clear();
@@ -1324,7 +1340,7 @@ bool render_font::load_bdf()
// some progress for big fonts
if (0 == (++charcount % 256))
- osd_printf_warning("Loading BDF font... (%d characters loaded)\n", charcount);
+ osd_printf_info("Loading BDF font... (%d characters loaded)\n", charcount);
}
}
@@ -1344,12 +1360,17 @@ bool render_font::load_bdf()
// load_cached - load a font in cached format
//-------------------------------------------------
-bool render_font::load_cached(emu_file &file, u64 length, u32 hash)
+bool render_font::load_cached(util::random_read &file, u64 length, u32 hash)
{
// get the file size, read the header, and check that it looks good
- u64 const filesize(file.size());
+ u64 filesize;
bdc_header header;
- if (!header.read(file))
+ if (file.length(filesize))
+ {
+ LOG("render_font::load_cached: error determining size of BDC file\n");
+ return false;
+ }
+ else if (!header.read(file))
{
osd_printf_warning("render_font::load_cached: error reading BDC header\n");
return false;
@@ -1371,14 +1392,20 @@ bool render_font::load_cached(emu_file &file, u64 length, u32 hash)
m_yoffs = header.get_y_offset();
m_defchar = header.get_default_character();
u32 const numchars(header.get_glyph_count());
- if ((file.tell() + (u64(numchars) * bdc_table_entry::size())) > filesize)
+ u64 filepos;
+ if (file.tell(filepos))
+ {
+ LOG("render_font::load_cached: failed to determine position in BDC file\n");
+ return false;
+ }
+ else if ((filepos + (u64(numchars) * bdc_table_entry::size())) > filesize)
{
LOG("render_font::load_cached: BDC file is too small to hold glyph table\n");
return false;
}
// now read the rest of the data
- u64 const remaining(filesize - file.tell());
+ u64 const remaining(filesize - filepos);
try
{
m_rawdata.resize(std::size_t(remaining));
@@ -1390,7 +1417,8 @@ bool render_font::load_cached(emu_file &file, u64 length, u32 hash)
for (u64 bytes_read = 0; remaining > bytes_read; )
{
u32 const chunk((std::min)(u64(std::numeric_limits<u32>::max()), remaining));
- if (file.read(&m_rawdata[bytes_read], chunk) != chunk)
+ std::size_t bytes(0);
+ if (file.read(&m_rawdata[bytes_read], chunk, bytes) || bytes != chunk)
{
osd_printf_error("render_font::load_cached: error reading BDC data\n");
m_rawdata.clear();
@@ -1450,16 +1478,8 @@ bool render_font::load_cached(emu_file &file, u64 length, u32 hash)
// save_cached - save a font in cached format
//-------------------------------------------------
-bool render_font::save_cached(const char *filename, u64 length, u32 hash)
+bool render_font::save_cached(util::random_write &file, u64 length, u32 hash)
{
- osd_printf_warning("Generating cached BDF font...\n");
-
- // attempt to open the file
- emu_file file(m_manager.machine().options().font_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- std::error_condition const filerr = file.open(filename);
- if (filerr)
- return false;
-
// count glyphs
unsigned numchars = 0;
for (glyph const *const page : m_glyphs)
@@ -1474,8 +1494,6 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
try
{
- u32 bytes_written;
-
{
LOG("render_font::save_cached: writing header\n");
bdc_header hdr;
@@ -1490,7 +1508,9 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
if (!hdr.write(file))
throw emu_fatalerror("Error writing cached file");
}
- u64 const table_offs(file.tell());
+ u64 table_offs;
+ if (file.tell(table_offs))
+ throw emu_fatalerror("Error writing cached file");
// allocate an array to hold the character data
std::vector<u8> chartable(std::size_t(numchars) * bdc_table_entry::size(), 0);
@@ -1499,8 +1519,8 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
std::vector<u8> tempbuffer(65536);
// write the empty table to the beginning of the file
- bytes_written = file.write(&chartable[0], chartable.size());
- if (bytes_written != chartable.size())
+ std::size_t bytes_written(0);
+ if (file.write(&chartable[0], chartable.size(), bytes_written) || bytes_written != chartable.size())
throw emu_fatalerror("Error writing cached file");
// loop over all characters
@@ -1543,8 +1563,7 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
*dest++ = accum;
// write the data
- bytes_written = file.write(&tempbuffer[0], dest - &tempbuffer[0]);
- if (bytes_written != dest - &tempbuffer[0])
+ if (file.write(&tempbuffer[0], dest - &tempbuffer[0], bytes_written) || bytes_written != dest - &tempbuffer[0])
throw emu_fatalerror("Error writing cached file");
// free the bitmap and texture
@@ -1568,13 +1587,13 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
if (!chartable.empty())
{
LOG("render_font::save_cached: writing character table\n");
- file.seek(table_offs, SEEK_SET);
+ if (file.seek(table_offs, SEEK_SET))
+ return false;
u8 const *bytes(&chartable[0]);
for (u64 remaining = chartable.size(); remaining; )
{
u32 const chunk((std::min<u64>)(std::numeric_limits<u32>::max(), remaining));
- bytes_written = file.write(bytes, chunk);
- if (chunk != bytes_written)
+ if (file.write(bytes, chunk, bytes_written) || chunk != bytes_written)
throw emu_fatalerror("Error writing cached file");
bytes += chunk;
remaining -= chunk;
@@ -1586,7 +1605,6 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
}
catch (...)
{
- file.remove_on_close();
return false;
}
}
@@ -1595,13 +1613,13 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash)
void render_font::render_font_command_glyph()
{
// FIXME: this is copy/pasta from the BDC loading, and it shouldn't be injected into every font
- emu_file file(OPEN_FLAG_READ);
- if (!file.open_ram(font_uicmd14, sizeof(font_uicmd14)))
+ util::random_read::ptr file = util::ram_read(font_uicmd14, sizeof(font_uicmd14));
+ if (file)
{
// get the file size, read the header, and check that it looks good
- u64 const filesize(file.size());
+ u64 const filesize = sizeof(font_uicmd14);
bdc_header header;
- if (!header.read(file))
+ if (!header.read(*file))
{
osd_printf_warning("render_font::render_font_command_glyph: error reading BDC header\n");
return;
@@ -1616,14 +1634,20 @@ void render_font::render_font_command_glyph()
m_height_cmd = header.get_height();
m_yoffs_cmd = header.get_y_offset();
u32 const numchars(header.get_glyph_count());
- if ((file.tell() + (u64(numchars) * bdc_table_entry::size())) > filesize)
+ u64 filepos;
+ if (file->tell(filepos))
+ {
+ LOG("render_font::render_font_command_glyph: failed to determine position in BDC file\n");
+ return;
+ }
+ else if ((filepos + (u64(numchars) * bdc_table_entry::size())) > filesize)
{
LOG("render_font::render_font_command_glyph: BDC file is too small to hold glyph table\n");
return;
}
// now read the rest of the data
- u64 const remaining(filesize - file.tell());
+ u64 const remaining(filesize - filepos);
try
{
m_rawdata_cmd.resize(std::size_t(remaining));
@@ -1635,7 +1659,8 @@ void render_font::render_font_command_glyph()
for (u64 bytes_read = 0; remaining > bytes_read; )
{
u32 const chunk((std::min)(u64(std::numeric_limits<u32>::max()), remaining));
- if (file.read(&m_rawdata_cmd[bytes_read], chunk) != chunk)
+ std::size_t bytes(0);
+ if (file->read(&m_rawdata_cmd[bytes_read], chunk, bytes) || bytes != chunk)
{
osd_printf_error("render_font::render_font_command_glyph: error reading BDC data\n");
m_rawdata_cmd.clear();
diff --git a/src/emu/rendfont.h b/src/emu/rendfont.h
index 15f6754657b..2d812860ae4 100644
--- a/src/emu/rendfont.h
+++ b/src/emu/rendfont.h
@@ -82,10 +82,10 @@ private:
// helpers
glyph &get_char(char32_t chnum);
void char_expand(char32_t chnum, glyph &ch);
- bool load_cached_bdf(const char *filename);
+ bool load_cached_bdf(std::string_view filename);
bool load_bdf();
- bool load_cached(emu_file &file, u64 length, u32 hash);
- bool save_cached(const char *filename, u64 length, u32 hash);
+ bool load_cached(util::random_read &file, u64 length, u32 hash);
+ bool save_cached(util::random_write &file, u64 length, u32 hash);
void render_font_command_glyph();
diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp
index 28011b8372c..ffe680fa625 100644
--- a/src/emu/rendlay.cpp
+++ b/src/emu/rendlay.cpp
@@ -13,6 +13,7 @@
#include "rendlay.h"
#include "emuopts.h"
+#include "fileio.h"
#include "rendfont.h"
#include "rendutil.h"
#include "video/rgbutil.h"
@@ -1249,7 +1250,6 @@ layout_element::make_component_map const layout_element::s_make_component{
{ "simplecounter", &make_component<simplecounter_component> },
{ "reel", &make_component<reel_component> },
{ "led7seg", &make_component<led7seg_component> },
- { "led8seg_gts1", &make_component<led8seg_gts1_component> },
{ "led14seg", &make_component<led14seg_component> },
{ "led14segsc", &make_component<led14segsc_component> },
{ "led16seg", &make_component<led16seg_component> },
@@ -2109,7 +2109,7 @@ protected:
}
else if (c.a)
{
- // compute premultiplied colors
+ // compute premultiplied color
u32 const a(c.a * 255.0F);
u32 const r(u32(c.r * (255.0F * 255.0F)) * a);
u32 const g(u32(c.g * (255.0F * 255.0F)) * a);
@@ -2145,9 +2145,9 @@ public:
render_color const c(color(state));
u32 const f(rgb_t(u8(c.r * 255), u8(c.g * 255), u8(c.b * 255)));
u32 const a(c.a * 255.0F);
- u32 const r(c.r * c.a * (255.0F * 255.0F * 255.0F));
- u32 const g(c.g * c.a * (255.0F * 255.0F * 255.0F));
- u32 const b(c.b * c.a * (255.0F * 255.0F * 255.0F));
+ u32 const r(c.r * (255.0F * 255.0F) * a);
+ u32 const g(c.g * (255.0F * 255.0F) * a);
+ u32 const b(c.b * (255.0F * 255.0F) * a);
u32 const inva(255 - a);
if (!a)
return;
@@ -2519,74 +2519,6 @@ protected:
};
-// 8-segment fluorescent (Gottlieb System 1)
-class layout_element::led8seg_gts1_component : public component
-{
-public:
- // construction/destruction
- led8seg_gts1_component(environment &env, util::xml::data_node const &compnode)
- : component(env, compnode)
- {
- }
-
-protected:
- // overrides
- virtual int maxstate() const override { return 255; }
-
- virtual void draw_aligned(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
- {
- rgb_t const onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
- rgb_t const offpen = rgb_t(0x20, 0xff, 0xff, 0xff);
- rgb_t const backpen = rgb_t(0x00, 0x00, 0x00, 0x00);
-
- // sizes for computation
- int const bmwidth = 250;
- int const bmheight = 400;
- int const segwidth = 40;
- int const skewwidth = 40;
-
- // allocate a temporary bitmap for drawing
- bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight);
- tempbitmap.fill(backpen);
-
- // top bar
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 0)) ? onpen : offpen);
-
- // top-right bar
- draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (state & (1 << 1)) ? onpen : offpen);
-
- // bottom-right bar
- draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, (state & (1 << 2)) ? onpen : offpen);
-
- // bottom bar
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, (state & (1 << 3)) ? onpen : offpen);
-
- // bottom-left bar
- draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 4)) ? onpen : offpen);
-
- // top-left bar
- draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 5)) ? onpen : offpen);
-
- // horizontal bars
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, 2*bmwidth/3 - 2*segwidth/3, bmheight/2, segwidth, (state & (1 << 6)) ? onpen : offpen);
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3 + bmwidth/2, bmwidth - 2*segwidth/3, bmheight/2, segwidth, (state & (1 << 6)) ? onpen : offpen);
-
- // vertical bars
- draw_segment_vertical(tempbitmap, 0 + segwidth/3 - 8, bmheight/2 - segwidth/3 + 2, 2*bmwidth/3 - segwidth/2 - 4, segwidth + 8, backpen);
- draw_segment_vertical(tempbitmap, 0 + segwidth/3, bmheight/2 - segwidth/3, 2*bmwidth/3 - segwidth/2 - 4, segwidth, (state & (1 << 7)) ? onpen : offpen);
-
- draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3 - 2, bmheight - segwidth/3 + 8, 2*bmwidth/3 - segwidth/2 - 4, segwidth + 8, backpen);
- draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - segwidth/3, 2*bmwidth/3 - segwidth/2 - 4, segwidth, (state & (1 << 7)) ? onpen : offpen);
-
- // apply skew
- apply_skew(tempbitmap, 40);
-
- // resample to the target size
- render_resample_argb_bitmap_hq(dest, tempbitmap, color(state));
- }
-};
-
-
// 14-segment LCD
class layout_element::led14seg_component : public component
{
@@ -3177,7 +3109,7 @@ protected:
// shift the reels a bit based on this param, allows fine tuning
int use_state = (state + m_stateoffset) % max_state_used;
- // compute premultiplied colors
+ // compute premultiplied color
render_color const c(color(state));
u32 const r = c.r * 255.0f;
u32 const g = c.g * 255.0f;
@@ -3329,7 +3261,7 @@ private:
// shift the reels a bit based on this param, allows fine tuning
int use_state = (state + m_stateoffset) % max_state_used;
- // compute premultiplied colors
+ // compute premultiplied color
render_color const c(color(state));
u32 const r = c.r * 255.0f;
u32 const g = c.g * 255.0f;
@@ -3747,7 +3679,7 @@ void layout_element::component::draw_text(
int align,
const render_color &color)
{
- // compute premultiplied colors
+ // compute premultiplied color
u32 const r(color.r * 255.0f);
u32 const g(color.g * 255.0f);
u32 const b(color.b * 255.0f);
diff --git a/src/emu/rendlay.h b/src/emu/rendlay.h
index da9edfcf752..29b38fdd5d0 100644
--- a/src/emu/rendlay.h
+++ b/src/emu/rendlay.h
@@ -16,6 +16,16 @@
#include "rendertypes.h"
#include "screen.h"
+#include <array>
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <tuple>
+#include <unordered_map>
+#include <vector>
+
//**************************************************************************
// TYPE DEFINITIONS
@@ -113,16 +123,16 @@ private:
virtual void draw_aligned(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state);
// drawing helpers
- void draw_text(render_font &font, bitmap_argb32 &dest, const rectangle &bounds, std::string_view str, int align, const render_color &color);
- void draw_segment_horizontal_caps(bitmap_argb32 &dest, int minx, int maxx, int midy, int width, int caps, rgb_t color);
- void draw_segment_horizontal(bitmap_argb32 &dest, int minx, int maxx, int midy, int width, rgb_t color);
- void draw_segment_vertical_caps(bitmap_argb32 &dest, int miny, int maxy, int midx, int width, int caps, rgb_t color);
- void draw_segment_vertical(bitmap_argb32 &dest, int miny, int maxy, int midx, int width, rgb_t color);
- void draw_segment_diagonal_1(bitmap_argb32 &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color);
- void draw_segment_diagonal_2(bitmap_argb32 &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color);
- void draw_segment_decimal(bitmap_argb32 &dest, int midx, int midy, int width, rgb_t color);
- void draw_segment_comma(bitmap_argb32 &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color);
- void apply_skew(bitmap_argb32 &dest, int skewwidth);
+ static void draw_text(render_font &font, bitmap_argb32 &dest, const rectangle &bounds, std::string_view str, int align, const render_color &color);
+ static void draw_segment_horizontal_caps(bitmap_argb32 &dest, int minx, int maxx, int midy, int width, int caps, rgb_t color);
+ static void draw_segment_horizontal(bitmap_argb32 &dest, int minx, int maxx, int midy, int width, rgb_t color);
+ static void draw_segment_vertical_caps(bitmap_argb32 &dest, int miny, int maxy, int midx, int width, int caps, rgb_t color);
+ static void draw_segment_vertical(bitmap_argb32 &dest, int miny, int maxy, int midx, int width, rgb_t color);
+ static void draw_segment_diagonal_1(bitmap_argb32 &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color);
+ static void draw_segment_diagonal_2(bitmap_argb32 &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color);
+ static void draw_segment_decimal(bitmap_argb32 &dest, int midx, int midy, int width, rgb_t color);
+ static void draw_segment_comma(bitmap_argb32 &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color);
+ static void apply_skew(bitmap_argb32 &dest, int skewwidth);
private:
using bounds_vector = emu::render::detail::bounds_vector;
@@ -141,7 +151,6 @@ private:
class disk_component;
class text_component;
class led7seg_component;
- class led8seg_gts1_component;
class led14seg_component;
class led16seg_component;
class led14segsc_component;
@@ -173,7 +182,6 @@ private:
// internal helpers
static void element_scale(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param);
template <typename T> static component::ptr make_component(environment &env, util::xml::data_node const &compnode);
- template <int D> static component::ptr make_dotmatrix_component(environment &env, util::xml::data_node const &compnode);
static make_component_map const s_make_component; // maps component XML names to creator functions
@@ -281,7 +289,7 @@ public:
// interactivity
bool has_input() const { return bool(m_input_port); }
- std::pair<ioport_port *, ioport_value> input_tag_and_mask() const { return std::make_pair(m_input_port, m_input_mask); };
+ std::pair<ioport_port *, ioport_value> input_tag_and_mask() const { return std::make_pair(m_input_port, m_input_mask); }
bool clickthrough() const { return m_clickthrough; }
// fetch state based on configured source
diff --git a/src/emu/rendutil.cpp b/src/emu/rendutil.cpp
index 2d0a823db28..cffef8263d7 100644
--- a/src/emu/rendutil.cpp
+++ b/src/emu/rendutil.cpp
@@ -19,6 +19,7 @@
#include <csetjmp>
#include <cstdlib>
+#include <tuple>
namespace {
@@ -375,118 +376,118 @@ static void resample_argb_bitmap_bilinear(u32 *dest, u32 drowpixels, u32 dwidth,
}
-/*-------------------------------------------------
- render_clip_line - clip a line to a rectangle
--------------------------------------------------*/
+//-------------------------------------------------
+// render_clip_line - clip a line to a rectangle
+//-------------------------------------------------
-bool render_clip_line(render_bounds *bounds, const render_bounds *clip)
+bool render_clip_line(render_bounds &bounds, const render_bounds &clip)
{
- /* loop until we get a final result */
- while (1)
+ // loop until we get a final result
+ while (true)
{
u8 code0 = 0, code1 = 0;
u8 thiscode;
float x, y;
- /* compute Cohen Sutherland bits for first coordinate */
- if (bounds->y0 > clip->y1)
+ // compute Cohen Sutherland bits for first coordinate
+ if (bounds.y0 > clip.y1)
code0 |= 1;
- if (bounds->y0 < clip->y0)
+ if (bounds.y0 < clip.y0)
code0 |= 2;
- if (bounds->x0 > clip->x1)
+ if (bounds.x0 > clip.x1)
code0 |= 4;
- if (bounds->x0 < clip->x0)
+ if (bounds.x0 < clip.x0)
code0 |= 8;
- /* compute Cohen Sutherland bits for second coordinate */
- if (bounds->y1 > clip->y1)
+ // compute Cohen Sutherland bits for second coordinate
+ if (bounds.y1 > clip.y1)
code1 |= 1;
- if (bounds->y1 < clip->y0)
+ if (bounds.y1 < clip.y0)
code1 |= 2;
- if (bounds->x1 > clip->x1)
+ if (bounds.x1 > clip.x1)
code1 |= 4;
- if (bounds->x1 < clip->x0)
+ if (bounds.x1 < clip.x0)
code1 |= 8;
- /* trivial accept: just return false */
+ // trivial accept: just return false
if ((code0 | code1) == 0)
return false;
- /* trivial reject: just return true */
+ // trivial reject: just return true
if ((code0 & code1) != 0)
return true;
- /* fix one of the OOB cases */
+ // fix one of the OOB cases
thiscode = code0 ? code0 : code1;
- /* off the bottom */
+ // off the bottom
if (thiscode & 1)
{
- x = bounds->x0 + (bounds->x1 - bounds->x0) * (clip->y1 - bounds->y0) / (bounds->y1 - bounds->y0);
- y = clip->y1;
+ x = bounds.x0 + (bounds.x1 - bounds.x0) * (clip.y1 - bounds.y0) / (bounds.y1 - bounds.y0);
+ y = clip.y1;
}
- /* off the top */
+ // off the top
else if (thiscode & 2)
{
- x = bounds->x0 + (bounds->x1 - bounds->x0) * (clip->y0 - bounds->y0) / (bounds->y1 - bounds->y0);
- y = clip->y0;
+ x = bounds.x0 + (bounds.x1 - bounds.x0) * (clip.y0 - bounds.y0) / (bounds.y1 - bounds.y0);
+ y = clip.y0;
}
- /* off the right */
+ // off the right
else if (thiscode & 4)
{
- y = bounds->y0 + (bounds->y1 - bounds->y0) * (clip->x1 - bounds->x0) / (bounds->x1 - bounds->x0);
- x = clip->x1;
+ y = bounds.y0 + (bounds.y1 - bounds.y0) * (clip.x1 - bounds.x0) / (bounds.x1 - bounds.x0);
+ x = clip.x1;
}
- /* off the left */
+ // off the left
else
{
- y = bounds->y0 + (bounds->y1 - bounds->y0) * (clip->x0 - bounds->x0) / (bounds->x1 - bounds->x0);
- x = clip->x0;
+ y = bounds.y0 + (bounds.y1 - bounds.y0) * (clip.x0 - bounds.x0) / (bounds.x1 - bounds.x0);
+ x = clip.x0;
}
- /* fix the appropriate coordinate */
+ // fix the appropriate coordinate
if (thiscode == code0)
{
- bounds->x0 = x;
- bounds->y0 = y;
+ bounds.x0 = x;
+ bounds.y0 = y;
}
else
{
- bounds->x1 = x;
- bounds->y1 = y;
+ bounds.x1 = x;
+ bounds.y1 = y;
}
}
}
-/*-------------------------------------------------
- render_clip_quad - clip a quad to a rectangle
--------------------------------------------------*/
+//-------------------------------------------------
+// render_clip_quad - clip a quad to a rectangle
+//-------------------------------------------------
-bool render_clip_quad(render_bounds *bounds, const render_bounds *clip, render_quad_texuv *texcoords)
+bool render_clip_quad(render_bounds &bounds, const render_bounds &clip, render_quad_texuv *texcoords)
{
- /* ensure our assumptions about the bounds are correct */
- assert(bounds->x0 <= bounds->x1);
- assert(bounds->y0 <= bounds->y1);
+ // ensure our assumptions about the bounds are correct
+ assert(bounds.x0 <= bounds.x1);
+ assert(bounds.y0 <= bounds.y1);
- /* trivial reject */
- if (bounds->y1 < clip->y0)
+ // trivial reject
+ if (bounds.y1 < clip.y0)
return true;
- if (bounds->y0 > clip->y1)
+ if (bounds.y0 > clip.y1)
return true;
- if (bounds->x1 < clip->x0)
+ if (bounds.x1 < clip.x0)
return true;
- if (bounds->x0 > clip->x1)
+ if (bounds.x0 > clip.x1)
return true;
- /* clip top (x0,y0)-(x1,y1) */
- if (bounds->y0 < clip->y0)
+ // clip top (x0,y0)-(x1,y1)
+ if (bounds.y0 < clip.y0)
{
- float frac = (clip->y0 - bounds->y0) / (bounds->y1 - bounds->y0);
- bounds->y0 = clip->y0;
+ float frac = (clip.y0 - bounds.y0) / (bounds.y1 - bounds.y0);
+ bounds.y0 = clip.y0;
if (texcoords != nullptr)
{
texcoords->tl.u += (texcoords->bl.u - texcoords->tl.u) * frac;
@@ -496,11 +497,11 @@ bool render_clip_quad(render_bounds *bounds, const render_bounds *clip, render_q
}
}
- /* clip bottom (x3,y3)-(x2,y2) */
- if (bounds->y1 > clip->y1)
+ // clip bottom (x3,y3)-(x2,y2)
+ if (bounds.y1 > clip.y1)
{
- float frac = (bounds->y1 - clip->y1) / (bounds->y1 - bounds->y0);
- bounds->y1 = clip->y1;
+ float frac = (bounds.y1 - clip.y1) / (bounds.y1 - bounds.y0);
+ bounds.y1 = clip.y1;
if (texcoords != nullptr)
{
texcoords->bl.u -= (texcoords->bl.u - texcoords->tl.u) * frac;
@@ -510,11 +511,11 @@ bool render_clip_quad(render_bounds *bounds, const render_bounds *clip, render_q
}
}
- /* clip left (x0,y0)-(x3,y3) */
- if (bounds->x0 < clip->x0)
+ // clip left (x0,y0)-(x3,y3)
+ if (bounds.x0 < clip.x0)
{
- float frac = (clip->x0 - bounds->x0) / (bounds->x1 - bounds->x0);
- bounds->x0 = clip->x0;
+ float frac = (clip.x0 - bounds.x0) / (bounds.x1 - bounds.x0);
+ bounds.x0 = clip.x0;
if (texcoords != nullptr)
{
texcoords->tl.u += (texcoords->tr.u - texcoords->tl.u) * frac;
@@ -524,11 +525,11 @@ bool render_clip_quad(render_bounds *bounds, const render_bounds *clip, render_q
}
}
- /* clip right (x1,y1)-(x2,y2) */
- if (bounds->x1 > clip->x1)
+ // clip right (x1,y1)-(x2,y2)
+ if (bounds.x1 > clip.x1)
{
- float frac = (bounds->x1 - clip->x1) / (bounds->x1 - bounds->x0);
- bounds->x1 = clip->x1;
+ float frac = (bounds.x1 - clip.x1) / (bounds.x1 - bounds.x0);
+ bounds.x1 = clip.x1;
if (texcoords != nullptr)
{
texcoords->tr.u -= (texcoords->tr.u - texcoords->tl.u) * frac;
@@ -541,14 +542,14 @@ bool render_clip_quad(render_bounds *bounds, const render_bounds *clip, render_q
}
-/*-------------------------------------------------
- render_line_to_quad - convert a line and a
- width to four points
--------------------------------------------------*/
+//-------------------------------------------------
+// render_line_to_quad - convert a line and a
+// width to four points
+//-----------------------------------------------
-void render_line_to_quad(const render_bounds *bounds, float width, float length_extension, render_bounds *bounds0, render_bounds *bounds1)
+std::pair<render_bounds, render_bounds> render_line_to_quad(const render_bounds &bounds, float width, float length_extension)
{
- render_bounds modbounds = *bounds;
+ render_bounds modbounds = bounds;
/*
High-level logic -- due to math optimizations, this info is lost below.
@@ -595,18 +596,18 @@ void render_line_to_quad(const render_bounds *bounds, float width, float length_
D.y = p1.y - 0.5 * w * u.x
*/
- /* we only care about the half-width */
+ // we only care about the half-width
float half_width = width * 0.5f;
- /* compute a vector from point 0 to point 1 */
+ // compute a vector from point 0 to point 1
float unitx = modbounds.x1 - modbounds.x0;
float unity = modbounds.y1 - modbounds.y0;
- /* points just use a +1/+1 unit vector; this gives a nice diamond pattern */
+ // points just use a +1/+1 unit vector; this gives a nice diamond pattern
if (unitx == 0 && unity == 0)
{
- /* length of a unit vector (1,1) */
- float unit_length = 0.70710678f;
+ // length of a unit vector (1,1)
+ constexpr float unit_length = 0.70710678f;
unitx = unity = unit_length * half_width;
modbounds.x0 -= unitx;
@@ -615,12 +616,12 @@ void render_line_to_quad(const render_bounds *bounds, float width, float length_
modbounds.y1 += unity;
}
- /* lines need to be divided by their length */
+ // lines need to be divided by their length
else
{
float length = sqrtf(unitx * unitx + unity * unity);
- /* extend line length */
+ // extend line length
if (length_extension > 0.0f)
{
float half_length_extension = length_extension *0.5f;
@@ -634,27 +635,16 @@ void render_line_to_quad(const render_bounds *bounds, float width, float length_
modbounds.y1 += directiony * half_length_extension;
}
- /* prescale unitx and unity by the half-width */
+ // prescale unitx and unity by the half-width
float invlength = half_width / length;
unitx *= invlength;
unity *= invlength;
}
- /* rotate the unit vector by 90 degrees and add to point 0 */
- bounds0->x0 = modbounds.x0 - unity;
- bounds0->y0 = modbounds.y0 + unitx;
-
- /* rotate the unit vector by -90 degrees and add to point 0 */
- bounds0->x1 = modbounds.x0 + unity;
- bounds0->y1 = modbounds.y0 - unitx;
-
- /* rotate the unit vector by 90 degrees and add to point 1 */
- bounds1->x0 = modbounds.x1 - unity;
- bounds1->y0 = modbounds.y1 + unitx;
-
- /* rotate the unit vector by -90 degrees and add to point 1 */
- bounds1->x1 = modbounds.x1 + unity;
- bounds1->y1 = modbounds.y1 - unitx;
+ // rotate the unit vector by 90 and -90 degrees and add to points 0 and 1
+ return std::make_pair(
+ render_bounds{ modbounds.x0 - unity, modbounds.y0 + unitx, modbounds.x0 + unity, modbounds.y0 - unitx },
+ render_bounds{ modbounds.x1 - unity, modbounds.y1 + unitx, modbounds.x1 + unity, modbounds.y1 - unitx });
}
diff --git a/src/emu/rendutil.h b/src/emu/rendutil.h
index 4d2b89567e3..1ffcdf41263 100644
--- a/src/emu/rendutil.h
+++ b/src/emu/rendutil.h
@@ -17,6 +17,7 @@
#include <algorithm>
#include <cmath>
+#include <utility>
/* ----- image formats ----- */
@@ -40,9 +41,9 @@ enum ru_imgformat
/* ----- render utilities ----- */
void render_resample_argb_bitmap_hq(bitmap_argb32 &dest, bitmap_argb32 &source, const render_color &color, bool force = false);
-bool render_clip_line(render_bounds *bounds, const render_bounds *clip);
-bool render_clip_quad(render_bounds *bounds, const render_bounds *clip, render_quad_texuv *texcoords);
-void render_line_to_quad(const render_bounds *bounds, float width, float length_extension, render_bounds *bounds0, render_bounds *bounds1);
+bool render_clip_line(render_bounds &bounds, const render_bounds &clip);
+bool render_clip_quad(render_bounds &bounds, const render_bounds &clip, render_quad_texuv *texcoords);
+std::pair<render_bounds, render_bounds> render_line_to_quad(const render_bounds &bounds, float width, float length_extension);
void render_load_msdib(bitmap_argb32 &bitmap, util::random_read &file);
void render_load_jpeg(bitmap_argb32 &bitmap, util::random_read &file);
bool render_load_png(bitmap_argb32 &bitmap, util::random_read &file, bool load_as_alpha_to_existing = false);
diff --git a/src/emu/romload.cpp b/src/emu/romload.cpp
index c4c3101bc89..4ce34832c78 100644
--- a/src/emu/romload.cpp
+++ b/src/emu/romload.cpp
@@ -11,12 +11,14 @@
#include "emu.h"
#include "romload.h"
-#include "corestr.h"
-#include "emuopts.h"
#include "drivenum.h"
+#include "emuopts.h"
+#include "fileio.h"
#include "softlist_dev.h"
#include "ui/uimain.h"
+#include "corestr.h"
+
#include <algorithm>
#include <set>
@@ -1070,7 +1072,13 @@ void rom_load_manager::process_disk_entries(std::initializer_list<std::reference
err = do_open_disk(machine().options(), searchpath, romp, chd->orig_chd(), next_parent);
if (err)
{
- handle_missing_file(romp, std::vector<std::string>(), err);
+ std::vector<std::string> tried;
+ for (auto const &paths : searchpath)
+ {
+ for (std::string const &path : paths.get())
+ tried.emplace_back(path);
+ }
+ handle_missing_file(romp, tried, err);
chd = nullptr;
continue;
}
@@ -1200,7 +1208,7 @@ void rom_load_manager::normalize_flags_for_device(std::string_view rgntag, u8 &w
/*-------------------------------------------------
load_software_part_region - load a software part
- This is used by MESS when loading a piece of
+ This is used by MAME when loading a piece of
software. The code should be merged with
process_region_list or updated to use a slight
more general process_region_list.
@@ -1220,7 +1228,7 @@ void rom_load_manager::load_software_part_region(device_t &device, software_list
const software_info *const swinfo = swlist.find(std::string(swname));
if (swinfo)
{
- // dispay a warning for unsupported software
+ // display a warning for unsupported software
// TODO: list supported clones like we do for machines?
if (swinfo->supported() == software_support::PARTIALLY_SUPPORTED)
{
diff --git a/src/emu/save.cpp b/src/emu/save.cpp
index a27a98ee23c..b8acfa24b0a 100644
--- a/src/emu/save.cpp
+++ b/src/emu/save.cpp
@@ -208,7 +208,7 @@ void save_manager::save_memory(device_t *device, const char *module, const char
// state
//-------------------------------------------------
-save_error save_manager::check_file(running_machine &machine, emu_file &file, const char *gamename, void (CLIB_DECL *errormsg)(const char *fmt, ...))
+save_error save_manager::check_file(running_machine &machine, util::core_file &file, const char *gamename, void (CLIB_DECL *errormsg)(const char *fmt, ...))
{
// if we want to validate the signature, compute it
u32 sig;
@@ -217,7 +217,8 @@ save_error save_manager::check_file(running_machine &machine, emu_file &file, co
// seek to the beginning and read the header
file.seek(0, SEEK_SET);
u8 header[HEADER_SIZE];
- if (file.read(header, sizeof(header)) != sizeof(header))
+ size_t actual(0);
+ if (file.read(header, sizeof(header), actual) || actual != sizeof(header))
{
if (errormsg != nullptr)
(*errormsg)("Could not read %s save file header",emulator_info::get_appname());
@@ -257,7 +258,7 @@ void save_manager::dispatch_presave()
// write_file - writes the data to a file
//-------------------------------------------------
-save_error save_manager::write_file(emu_file &file)
+save_error save_manager::write_file(util::core_file &file)
{
util::write_stream::ptr writer;
save_error err = do_write(
@@ -290,7 +291,7 @@ save_error save_manager::write_file(emu_file &file)
// read_file - read the data from a file
//-------------------------------------------------
-save_error save_manager::read_file(emu_file &file)
+save_error save_manager::read_file(util::core_file &file)
{
util::read_stream::ptr reader;
return do_read(
diff --git a/src/emu/save.h b/src/emu/save.h
index 2ea17ab9921..677f127853a 100644
--- a/src/emu/save.h
+++ b/src/emu/save.h
@@ -300,9 +300,9 @@ public:
{ save_pointer(nullptr, "global", nullptr, index, std::forward<ItemType>(value), element, valname, count); }
// file processing
- static save_error check_file(running_machine &machine, emu_file &file, const char *gamename, void (CLIB_DECL *errormsg)(const char *fmt, ...));
- save_error write_file(emu_file &file);
- save_error read_file(emu_file &file);
+ static save_error check_file(running_machine &machine, util::core_file &file, const char *gamename, void (CLIB_DECL *errormsg)(const char *fmt, ...));
+ save_error write_file(util::core_file &file);
+ save_error read_file(util::core_file &file);
save_error write_stream(std::ostream &str);
save_error read_stream(std::istream &str);
diff --git a/src/emu/schedule.cpp b/src/emu/schedule.cpp
index e32afb68f00..dd72dfa13b0 100644
--- a/src/emu/schedule.cpp
+++ b/src/emu/schedule.cpp
@@ -49,7 +49,6 @@ emu_timer::emu_timer() :
m_next(nullptr),
m_prev(nullptr),
m_param(0),
- m_ptr(nullptr),
m_enabled(false),
m_temporary(false),
m_period(attotime::zero),
@@ -75,7 +74,7 @@ emu_timer::~emu_timer()
// re-allocated as a non-device timer
//-------------------------------------------------
-inline emu_timer &emu_timer::init(running_machine &machine, timer_expired_delegate callback, void *ptr, bool temporary)
+inline emu_timer &emu_timer::init(running_machine &machine, timer_expired_delegate callback, bool temporary)
{
// ensure the entire timer state is clean
m_machine = &machine;
@@ -83,7 +82,6 @@ inline emu_timer &emu_timer::init(running_machine &machine, timer_expired_delega
m_prev = nullptr;
m_callback = callback;
m_param = 0;
- m_ptr = ptr;
m_enabled = false;
m_temporary = temporary;
m_period = attotime::never;
@@ -107,7 +105,7 @@ inline emu_timer &emu_timer::init(running_machine &machine, timer_expired_delega
// re-allocated as a device timer
//-------------------------------------------------
-inline emu_timer &emu_timer::init(device_t &device, device_timer_id id, void *ptr, bool temporary)
+inline emu_timer &emu_timer::init(device_t &device, device_timer_id id, bool temporary)
{
// ensure the entire timer state is clean
m_machine = &device.machine();
@@ -115,7 +113,6 @@ inline emu_timer &emu_timer::init(device_t &device, device_timer_id id, void *pt
m_prev = nullptr;
m_callback = timer_expired_delegate(FUNC(emu_timer::device_timer_expired), this);
m_param = 0;
- m_ptr = ptr;
m_enabled = false;
m_temporary = temporary;
m_period = attotime::never;
@@ -296,7 +293,7 @@ inline void emu_timer::schedule_next_period()
void emu_timer::dump() const
{
- machine().logerror("%p: en=%d temp=%d exp=%15s start=%15s per=%15s param=%d ptr=%p", this, m_enabled, m_temporary, m_expire.as_string(PRECISION), m_start.as_string(PRECISION), m_period.as_string(PRECISION), m_param, m_ptr);
+ machine().logerror("%p: en=%d temp=%d exp=%15s start=%15s per=%15s param=%d", this, m_enabled, m_temporary, m_expire.as_string(PRECISION), m_start.as_string(PRECISION), m_period.as_string(PRECISION), m_param);
if (m_device == nullptr)
if (m_callback.name() == nullptr)
machine().logerror(" cb=NULL\n");
@@ -312,9 +309,9 @@ void emu_timer::dump() const
// conditional jump on the hot path
//-------------------------------------------------
-void emu_timer::device_timer_expired(emu_timer &timer, void *ptr, s32 param)
+void emu_timer::device_timer_expired(emu_timer &timer, s32 param)
{
- timer.m_device->timer_expired(timer, timer.m_id, param, ptr);
+ timer.m_device->timer_expired(timer, timer.m_id, param);
}
@@ -340,7 +337,7 @@ device_scheduler::device_scheduler(running_machine &machine) :
m_quantum_minimum(ATTOSECONDS_IN_NSEC(1) / 1000)
{
// append a single never-expiring timer so there is always one in the list
- m_timer_list = &m_timer_allocator.alloc()->init(machine, timer_expired_delegate(), nullptr, true);
+ m_timer_list = &m_timer_allocator.alloc()->init(machine, timer_expired_delegate(), true);
m_timer_list->adjust(attotime::never);
// register global states
@@ -597,9 +594,9 @@ void device_scheduler::boost_interleave(const attotime &timeslice_time, const at
// timer and return a pointer
//-------------------------------------------------
-emu_timer *device_scheduler::timer_alloc(timer_expired_delegate callback, void *ptr)
+emu_timer *device_scheduler::timer_alloc(timer_expired_delegate callback)
{
- return &m_timer_allocator.alloc()->init(machine(), callback, ptr, false);
+ return &m_timer_allocator.alloc()->init(machine(), callback, false);
}
@@ -609,9 +606,9 @@ emu_timer *device_scheduler::timer_alloc(timer_expired_delegate callback, void *
// amount of time
//-------------------------------------------------
-void device_scheduler::timer_set(const attotime &duration, timer_expired_delegate callback, int param, void *ptr)
+void device_scheduler::timer_set(const attotime &duration, timer_expired_delegate callback, int param)
{
- m_timer_allocator.alloc()->init(machine(), callback, ptr, true).adjust(duration, param);
+ m_timer_allocator.alloc()->init(machine(), callback, true).adjust(duration, param);
}
@@ -620,9 +617,9 @@ void device_scheduler::timer_set(const attotime &duration, timer_expired_delegat
// and return a pointer
//-------------------------------------------------
-emu_timer *device_scheduler::timer_alloc(device_t &device, device_timer_id id, void *ptr)
+emu_timer *device_scheduler::timer_alloc(device_t &device, device_timer_id id)
{
- return &m_timer_allocator.alloc()->init(device, id, ptr, false);
+ return &m_timer_allocator.alloc()->init(device, id, false);
}
@@ -632,9 +629,9 @@ emu_timer *device_scheduler::timer_alloc(device_t &device, device_timer_id id, v
// time
//-------------------------------------------------
-void device_scheduler::timer_set(const attotime &duration, device_t &device, device_timer_id id, int param, void *ptr)
+void device_scheduler::timer_set(const attotime &duration, device_t &device, device_timer_id id, int param)
{
- m_timer_allocator.alloc()->init(device, id, ptr, true).adjust(duration, param);
+ m_timer_allocator.alloc()->init(device, id, true).adjust(duration, param);
}
@@ -655,7 +652,7 @@ void device_scheduler::eat_all_cycles()
// given amount of time
//-------------------------------------------------
-void device_scheduler::timed_trigger(void *ptr, s32 param)
+void device_scheduler::timed_trigger(s32 param)
{
trigger(param);
}
@@ -904,7 +901,7 @@ inline void device_scheduler::execute_timers()
LOG("execute_timers: timer device %s timer %d\n", timer.m_device->tag(), timer.m_id);
else
LOG("execute_timers: timer callback %s\n", timer.m_callback.name());
- timer.m_callback(timer.m_ptr, timer.m_param);
+ timer.m_callback(timer.m_param);
}
g_profiler.stop();
diff --git a/src/emu/schedule.h b/src/emu/schedule.h
index 9e90ed68ed5..b194c8b2d1c 100644
--- a/src/emu/schedule.h
+++ b/src/emu/schedule.h
@@ -22,7 +22,7 @@
// MACROS
//**************************************************************************
-#define TIMER_CALLBACK_MEMBER(name) void name(void *ptr, s32 param)
+#define TIMER_CALLBACK_MEMBER(name) void name(s32 param)
//**************************************************************************
@@ -30,7 +30,7 @@
//**************************************************************************
// timer callbacks look like this
-typedef named_delegate<void (void *, s32)> timer_expired_delegate;
+typedef named_delegate<void (s32)> timer_expired_delegate;
// ======================> emu_timer
@@ -45,8 +45,8 @@ class emu_timer
~emu_timer();
// allocation and re-use
- emu_timer &init(running_machine &machine, timer_expired_delegate callback, void *ptr, bool temporary);
- emu_timer &init(device_t &device, device_timer_id id, void *ptr, bool temporary);
+ emu_timer &init(running_machine &machine, timer_expired_delegate callback, bool temporary);
+ emu_timer &init(device_t &device, device_timer_id id, bool temporary);
emu_timer &release();
public:
@@ -55,12 +55,10 @@ public:
running_machine &machine() const noexcept { assert(m_machine != nullptr); return *m_machine; }
bool enabled() const { return m_enabled; }
int param() const { return m_param; }
- void *ptr() const { return m_ptr; }
// setters
bool enable(bool enable = true);
void set_param(int param) { m_param = param; }
- void set_ptr(void *ptr) { m_ptr = ptr; }
// control
void reset(const attotime &duration = attotime::never) { adjust(duration, m_param, m_period); }
@@ -78,7 +76,7 @@ private:
void register_save();
void schedule_next_period();
void dump() const;
- static void device_timer_expired(emu_timer &timer, void *ptr, s32 param);
+ static void device_timer_expired(emu_timer &timer, s32 param);
// internal state
running_machine * m_machine; // reference to the owning machine
@@ -86,7 +84,6 @@ private:
emu_timer * m_prev; // previous timer in order in the list
timer_expired_delegate m_callback; // callback function
s32 m_param; // integer parameter
- void * m_ptr; // pointer parameter
bool m_enabled; // is the timer enabled?
bool m_temporary; // is the timer temporary?
attotime m_period; // the repeat frequency of the timer
@@ -124,13 +121,13 @@ public:
void suspend_resume_changed() { m_suspend_changes_pending = true; }
// timers, specified by callback/name
- emu_timer *timer_alloc(timer_expired_delegate callback, void *ptr = nullptr);
- void timer_set(const attotime &duration, timer_expired_delegate callback, int param = 0, void *ptr = nullptr);
- void synchronize(timer_expired_delegate callback = timer_expired_delegate(), int param = 0, void *ptr = nullptr) { timer_set(attotime::zero, callback, param, ptr); }
+ emu_timer *timer_alloc(timer_expired_delegate callback);
+ void timer_set(const attotime &duration, timer_expired_delegate callback, int param = 0);
+ void synchronize(timer_expired_delegate callback = timer_expired_delegate(), int param = 0) { timer_set(attotime::zero, callback, param); }
// timers, specified by device/id; generally devices should use the device_t methods instead
- emu_timer *timer_alloc(device_t &device, device_timer_id id = 0, void *ptr = nullptr);
- void timer_set(const attotime &duration, device_t &device, device_timer_id id = 0, int param = 0, void *ptr = nullptr);
+ emu_timer *timer_alloc(device_t &device, device_timer_id id = 0);
+ void timer_set(const attotime &duration, device_t &device, device_timer_id id = 0, int param = 0);
// debugging
void dump_timers() const;
@@ -140,7 +137,7 @@ public:
private:
// callbacks
- void timed_trigger(void *ptr, s32 param);
+ void timed_trigger(s32 param);
void presave();
void postload();
diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp
index 5a9c055bbbb..77ae6fbea02 100644
--- a/src/emu/screen.cpp
+++ b/src/emu/screen.cpp
@@ -12,6 +12,7 @@
#include "screen.h"
#include "emuopts.h"
+#include "fileio.h"
#include "render.h"
#include "rendutil.h"
@@ -554,7 +555,7 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
, m_curtexture(0)
, m_changed(true)
, m_last_partial_scan(0)
- , m_partial_scan_hpos(-1)
+ , m_partial_scan_hpos(0)
, m_color(rgb_t(0xff, 0xff, 0xff, 0xff))
, m_brightness(0xff)
, m_frame_period(DEFAULT_FRAME_PERIOD.as_attoseconds())
@@ -683,9 +684,9 @@ void screen_device::device_validity_check(validity_checker &valid) const
osd_printf_error("Non-raster display cannot have a variable width\n");
}
- // check for zero frame rate
- if (m_refresh == 0)
- osd_printf_error("Invalid (zero) refresh rate\n");
+ // check for invalid frame rate
+ if (m_refresh == 0 || m_refresh > ATTOSECONDS_PER_SECOND)
+ osd_printf_error("Invalid (under 1Hz) refresh rate\n");
texture_format texformat = !m_screen_update_ind16.isnull() ? TEXFORMAT_PALETTE16 : TEXFORMAT_RGB32;
if (m_palette.finder_tag() != finder_base::DUMMY_TAG)
@@ -934,7 +935,7 @@ void screen_device::device_post_load()
// fires
//-------------------------------------------------
-void screen_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+void screen_device::device_timer(emu_timer &timer, device_timer_id id, int param)
{
switch (id)
{
@@ -1244,7 +1245,7 @@ bool screen_device::update_partial(int scanline)
// remember where we left off
m_last_partial_scan = scanline + 1;
- m_partial_scan_hpos = -1;
+ m_partial_scan_hpos = 0;
return true;
}
@@ -1298,10 +1299,10 @@ void screen_device::update_now()
if (current_vpos > m_last_partial_scan)
{
// if the line before us was incomplete, we must do it in two pieces
- if (m_partial_scan_hpos >= 0)
+ if (m_partial_scan_hpos > 0)
{
// now finish the previous partial scanline
- clip.set((std::max)(clip.left(), m_partial_scan_hpos + 1),
+ clip.set((std::max)(clip.left(), m_partial_scan_hpos),
clip.right(),
(std::max)(clip.top(), m_last_partial_scan),
(std::min)(clip.bottom(), m_last_partial_scan));
@@ -1340,7 +1341,7 @@ void screen_device::update_now()
m_changed |= ~flags & UPDATE_HAS_NOT_CHANGED;
}
- m_partial_scan_hpos = -1;
+ m_partial_scan_hpos = 0;
m_last_partial_scan++;
}
if (current_vpos > m_last_partial_scan)
@@ -1350,47 +1351,50 @@ void screen_device::update_now()
}
// now draw this partial scanline
- clip = m_visarea;
-
- clip.set((std::max)(clip.left(), m_partial_scan_hpos + 1),
- (std::min)(clip.right(), current_hpos),
- (std::max)(clip.top(), current_vpos),
- (std::min)(clip.bottom(), current_vpos));
-
- // and if there's something to draw, do it
- if (!clip.empty())
+ if (current_hpos > 0)
{
- g_profiler.start(PROFILER_VIDEO);
+ clip = m_visarea;
- LOG_PARTIAL_UPDATES(("doing scanline partial draw: Y %d X %d-%d\n", clip.bottom(), clip.left(), clip.right()));
+ clip.set((std::max)(clip.left(), m_partial_scan_hpos),
+ (std::min)(clip.right(), current_hpos - 1),
+ (std::max)(clip.top(), current_vpos),
+ (std::min)(clip.bottom(), current_vpos));
- u32 flags = 0;
- screen_bitmap &curbitmap = m_bitmap[m_curbitmap];
- if (m_video_attributes & VIDEO_VARIABLE_WIDTH)
+ // and if there's something to draw, do it
+ if (!clip.empty())
{
- pre_update_scanline(current_vpos);
- switch (curbitmap.format())
+ g_profiler.start(PROFILER_VIDEO);
+
+ LOG_PARTIAL_UPDATES(("doing scanline partial draw: Y %d X %d-%d\n", clip.bottom(), clip.left(), clip.right()));
+
+ u32 flags = 0;
+ screen_bitmap &curbitmap = m_bitmap[m_curbitmap];
+ if (m_video_attributes & VIDEO_VARIABLE_WIDTH)
{
- default:
- case BITMAP_FORMAT_IND16: flags = m_screen_update_ind16(*this, *(bitmap_ind16 *)m_scan_bitmaps[m_curbitmap][current_vpos], clip); break;
- case BITMAP_FORMAT_RGB32: flags = m_screen_update_rgb32(*this, *(bitmap_rgb32 *)m_scan_bitmaps[m_curbitmap][current_vpos], clip); break;
+ pre_update_scanline(current_vpos);
+ switch (curbitmap.format())
+ {
+ default:
+ case BITMAP_FORMAT_IND16: flags = m_screen_update_ind16(*this, *(bitmap_ind16 *)m_scan_bitmaps[m_curbitmap][current_vpos], clip); break;
+ case BITMAP_FORMAT_RGB32: flags = m_screen_update_rgb32(*this, *(bitmap_rgb32 *)m_scan_bitmaps[m_curbitmap][current_vpos], clip); break;
+ }
}
- }
- else
- {
- switch (curbitmap.format())
+ else
{
- default:
- case BITMAP_FORMAT_IND16: flags = m_screen_update_ind16(*this, curbitmap.as_ind16(), clip); break;
- case BITMAP_FORMAT_RGB32: flags = m_screen_update_rgb32(*this, curbitmap.as_rgb32(), clip); break;
+ switch (curbitmap.format())
+ {
+ default:
+ case BITMAP_FORMAT_IND16: flags = m_screen_update_ind16(*this, curbitmap.as_ind16(), clip); break;
+ case BITMAP_FORMAT_RGB32: flags = m_screen_update_rgb32(*this, curbitmap.as_rgb32(), clip); break;
+ }
}
- }
- m_partial_updates_this_frame++;
- g_profiler.stop();
+ m_partial_updates_this_frame++;
+ g_profiler.stop();
- // if we modified the bitmap, we have to commit
- m_changed |= ~flags & UPDATE_HAS_NOT_CHANGED;
+ // if we modified the bitmap, we have to commit
+ m_changed |= ~flags & UPDATE_HAS_NOT_CHANGED;
+ }
}
// remember where we left off
@@ -1407,7 +1411,7 @@ void screen_device::update_now()
void screen_device::reset_partial_updates()
{
m_last_partial_scan = 0;
- m_partial_scan_hpos = -1;
+ m_partial_scan_hpos = 0;
m_partial_updates_this_frame = 0;
m_scanline0_timer->adjust(time_until_pos(0));
}
diff --git a/src/emu/screen.h b/src/emu/screen.h
index b909c25cecc..f5fa859a8c2 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -13,6 +13,8 @@
#pragma once
+#include "rendertypes.h"
+
#include <type_traits>
#include <utility>
@@ -31,16 +33,6 @@ enum screen_type_enum
SCREEN_TYPE_SVG
};
-// texture formats
-enum texture_format
-{
- TEXFORMAT_UNDEFINED = 0, // require a format to be specified
- TEXFORMAT_PALETTE16, // 16bpp palettized, no alpha
- TEXFORMAT_RGB32, // 32bpp 8-8-8 RGB
- TEXFORMAT_ARGB32, // 32bpp 8-8-8-8 ARGB
- TEXFORMAT_YUY16 // 16bpp 8-8 Y/Cb, Y/Cr in sequence
-};
-
// screen_update callback flags
constexpr u32 UPDATE_HAS_NOT_CHANGED = 0x0001; // the video has not changed
@@ -233,7 +225,7 @@ public:
screen_device &set_raw(u32 pixclock, u16 htotal, u16 hbend, u16 hbstart, u16 vtotal, u16 vbend, u16 vbstart)
{
assert(pixclock != 0);
- m_clock = pixclock;
+ set_clock(pixclock);
m_refresh = HZ_TO_ATTOSECONDS(pixclock) * htotal * vtotal;
m_vblank = m_refresh / vtotal * (vtotal - (vbstart - vbend));
m_width = htotal;
@@ -246,6 +238,10 @@ public:
xtal.validate(std::string("Configuring screen ") + tag());
return set_raw(xtal.value(), htotal, hbend, hbstart, vtotal, vbend, vbstart);
}
+ screen_device &set_raw(const XTAL &xtal, u16 htotal, u16 vtotal, rectangle visarea)
+ {
+ return set_raw(xtal, htotal, visarea.left(), visarea.right() + 1, vtotal, visarea.top(), visarea.bottom() + 1);
+ }
void set_refresh(attoseconds_t rate) { m_refresh = rate; }
/// \brief Set refresh rate in Hertz
@@ -445,7 +441,7 @@ private:
virtual void device_reset() override;
virtual void device_stop() override;
virtual void device_post_load() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
// internal helpers
void set_container(render_container &container) { m_container = &container; }
diff --git a/src/emu/softlist_dev.cpp b/src/emu/softlist_dev.cpp
index 7d25dd17013..c6a32f0b30f 100644
--- a/src/emu/softlist_dev.cpp
+++ b/src/emu/softlist_dev.cpp
@@ -13,6 +13,7 @@
#include "diimage.h"
#include "emuopts.h"
+#include "fileio.h"
#include "romload.h"
#include "validity.h"
diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp
index 56b7d7ef071..a4cb5041d8f 100644
--- a/src/emu/sound.cpp
+++ b/src/emu/sound.cpp
@@ -885,7 +885,7 @@ void sound_stream::reprime_sync_timer()
// synchronous stream
//-------------------------------------------------
-void sound_stream::sync_update(void *, s32)
+void sound_stream::sync_update(s32)
{
update();
reprime_sync_timer();
@@ -1457,7 +1457,7 @@ stream_buffer::sample_t sound_manager::adjust_toward_compressor_scale(stream_buf
// and send it to the OSD layer
//-------------------------------------------------
-void sound_manager::update(void *ptr, int param)
+void sound_manager::update(int param)
{
VPRINTF(("sound_update\n"));
diff --git a/src/emu/sound.h b/src/emu/sound.h
index c1e66808ae6..658c956e5d4 100644
--- a/src/emu/sound.h
+++ b/src/emu/sound.h
@@ -373,6 +373,7 @@ public:
// safely write a sample to the buffer
void put(s32 start, sample_t sample)
{
+ sound_assert(u32(start) < samples());
m_buffer->put(index_to_buffer_index(start), sample);
}
@@ -399,6 +400,7 @@ public:
// safely add a sample to the buffer
void add(s32 start, sample_t sample)
{
+ sound_assert(u32(start) < samples());
u32 index = index_to_buffer_index(start);
m_buffer->put(index, m_buffer->get(index) + sample);
}
@@ -458,7 +460,6 @@ private:
// given a stream starting offset, return the buffer index
u32 index_to_buffer_index(s32 start) const
{
- sound_assert(u32(start) < samples());
u32 index = start + m_start;
if (index >= m_buffer->size())
index -= m_buffer->size();
@@ -673,7 +674,7 @@ private:
void reprime_sync_timer();
// timer callback for synchronous streams
- void sync_update(void *, s32);
+ void sync_update(s32);
// return a view of 0 data covering the given time period
read_stream_view empty_view(attotime start, attotime end);
@@ -816,7 +817,7 @@ private:
stream_buffer::sample_t adjust_toward_compressor_scale(stream_buffer::sample_t curscale, stream_buffer::sample_t prevsample, stream_buffer::sample_t rawsample);
// periodic sound update, called STREAMS_UPDATE_FREQUENCY per second
- void update(void *ptr = nullptr, s32 param = 0);
+ void update(s32 param = 0);
// internal state
running_machine &m_machine; // reference to the running machine
diff --git a/src/emu/validity.cpp b/src/emu/validity.cpp
index 18ba2c6fc6b..e4cf0860064 100644
--- a/src/emu/validity.cpp
+++ b/src/emu/validity.cpp
@@ -2292,8 +2292,9 @@ void validity_checker::validate_analog_input_field(const ioport_field &field)
void validity_checker::validate_dip_settings(const ioport_field &field)
{
- const char *demo_sounds = ioport_string_from_index(INPUT_STRING_Demo_Sounds);
- const char *flipscreen = ioport_string_from_index(INPUT_STRING_Flip_Screen);
+ char const *const demo_sounds = ioport_string_from_index(INPUT_STRING_Demo_Sounds);
+ char const *const flipscreen = ioport_string_from_index(INPUT_STRING_Flip_Screen);
+ char const *const name = field.specific_name();
u8 coin_list[__input_string_coinage_end + 1 - __input_string_coinage_start] = { 0 };
bool coin_error = false;
@@ -2306,15 +2307,15 @@ void validity_checker::validate_dip_settings(const ioport_field &field)
coin_list[strindex - __input_string_coinage_start] = 1;
// make sure demo sounds default to on
- if (field.name() == demo_sounds && strindex == INPUT_STRING_On && field.defvalue() != setting->value())
+ if (name == demo_sounds && strindex == INPUT_STRING_On && field.defvalue() != setting->value())
osd_printf_error("Demo Sounds must default to On\n");
// check for bad demo sounds options
- if (field.name() == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
+ if (name == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
osd_printf_error("Demo Sounds option must be Off/On, not %s\n", setting->name());
// check for bad flip screen options
- if (field.name() == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
+ if (name == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
osd_printf_error("Flip Screen option must be Off/On, not %s\n", setting->name());
// if we have a neighbor, compare ourselves to him
@@ -2324,21 +2325,21 @@ void validity_checker::validate_dip_settings(const ioport_field &field)
// check for inverted off/on DIP switch order
int next_strindex = get_defstr_index(nextsetting->name(), true);
if (strindex == INPUT_STRING_On && next_strindex == INPUT_STRING_Off)
- osd_printf_error("%s option must have Off/On options in the order: Off, On\n", field.name());
+ osd_printf_error("%s option must have Off/On options in the order: Off, On\n", name);
// check for inverted yes/no DIP switch order
else if (strindex == INPUT_STRING_Yes && next_strindex == INPUT_STRING_No)
- osd_printf_error("%s option must have Yes/No options in the order: No, Yes\n", field.name());
+ osd_printf_error("%s option must have Yes/No options in the order: No, Yes\n", name);
// check for inverted upright/cocktail DIP switch order
else if (strindex == INPUT_STRING_Cocktail && next_strindex == INPUT_STRING_Upright)
- osd_printf_error("%s option must have Upright/Cocktail options in the order: Upright, Cocktail\n", field.name());
+ osd_printf_error("%s option must have Upright/Cocktail options in the order: Upright, Cocktail\n", name);
// check for proper coin ordering
else if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end && next_strindex >= __input_string_coinage_start && next_strindex <= __input_string_coinage_end &&
strindex >= next_strindex && setting->condition() == nextsetting->condition())
{
- osd_printf_error("%s option has unsorted coinage %s > %s\n", field.name(), setting->name(), nextsetting->name());
+ osd_printf_error("%s option has unsorted coinage %s > %s\n", name, setting->name(), nextsetting->name());
coin_error = true;
}
}
@@ -2467,9 +2468,6 @@ void validity_checker::validate_inputs(device_t &root)
// check for invalid UTF-8
if (!utf8_is_valid_string(name))
osd_printf_error("Field '%s' has invalid characters\n", name);
-
- // look up the string and print an error if default strings are not used
- /*strindex =get_defstr_index(defstr_map, name, driver, &error);*/
}
// verify conditions on the field
diff --git a/src/emu/video.cpp b/src/emu/video.cpp
index 652272f680b..f50d33d224a 100644
--- a/src/emu/video.cpp
+++ b/src/emu/video.cpp
@@ -11,10 +11,12 @@
#include "emu.h"
#include "emuopts.h"
#include "debugger.h"
+#include "fileio.h"
#include "ui/uimain.h"
#include "crsshair.h"
#include "rendersw.hxx"
#include "output.h"
+#include "screen.h"
#include "corestr.h"
#include "png.h"
@@ -317,7 +319,7 @@ std::string video_manager::speed_text()
// file handle
//-------------------------------------------------
-void video_manager::save_snapshot(screen_device *screen, emu_file &file)
+void video_manager::save_snapshot(screen_device *screen, util::core_file &file)
{
// validate
assert(!m_snap_native || screen != nullptr);
@@ -492,7 +494,7 @@ void video_manager::exit()
// when there are no screens to drive it
//-------------------------------------------------
-void video_manager::screenless_update_callback(void *ptr, int param)
+void video_manager::screenless_update_callback(int param)
{
// force an update
frame_update(false);
@@ -506,8 +508,13 @@ void video_manager::screenless_update_callback(void *ptr, int param)
void video_manager::postload()
{
+ attotime const emutime = machine().time();
for (const auto &x : m_movie_recordings)
- x->set_next_frame_time(machine().time());
+ x->set_next_frame_time(emutime);
+
+ // reset speed measurements
+ m_speed_last_realtime = osd_ticks();
+ m_speed_last_emutime = emutime;
}
@@ -590,7 +597,7 @@ bool video_manager::finish_screen_updates()
bool has_live_screen = false;
for (screen_device &screen : iter)
{
- if (screen.partial_scan_hpos() >= 0) // previous update ended mid-scanline
+ if (screen.partial_scan_hpos() > 0) // previous update ended mid-scanline
screen.update_now();
screen.update_partial(screen.visible_area().max_y);
@@ -1129,7 +1136,7 @@ std::error_condition video_manager::open_next(emu_file &file, const char *extens
if (pos_time != -1)
{
- char t_str[15];
+ char t_str[16];
const std::time_t cur_time = std::time(nullptr);
strftime(t_str, sizeof(t_str), "%Y%m%d_%H%M%S", std::localtime(&cur_time));
strreplace(snapstr, "%t", t_str);
diff --git a/src/emu/video.h b/src/emu/video.h
index c6d69194ba1..da57d6b8a98 100644
--- a/src/emu/video.h
+++ b/src/emu/video.h
@@ -78,7 +78,7 @@ public:
// snapshots
bool snap_native() const { return m_snap_native; }
render_target &snapshot_target() { return *m_snap_target; }
- void save_snapshot(screen_device *screen, emu_file &file);
+ void save_snapshot(screen_device *screen, util::core_file &file);
void save_active_screen_snapshots();
// movies
@@ -90,7 +90,7 @@ public:
private:
// internal helpers
void exit();
- void screenless_update_callback(void *ptr, int param);
+ void screenless_update_callback(int param);
void postload();
// effective value helpers
diff --git a/src/emu/xtal.cpp b/src/emu/xtal.cpp
index 16178a2bfc7..403993ab2d7 100644
--- a/src/emu/xtal.cpp
+++ b/src/emu/xtal.cpp
@@ -80,10 +80,12 @@ const double XTAL::known_xtals[] = {
2'000'000, /* 2_MHz_XTAL - */
2'012'160, /* 2.01216_MHz_XTAL Cidelsa Draco sound board */
2'097'152, /* 2.097152_MHz_XTAL Icatel 1995 - Brazilian public payphone */
+ 2'250'000, /* 2.25_MHz_XTAL Resonator - YM2154 on Yamaha PSR-60 & PSR-70 */
2'376'000, /* 2.376_MHz_XTAL CIT-101 keyboard */
2'457'600, /* 2.4576_MHz_XTAL Atari ST MFP */
2'500'000, /* 2.5_MHz_XTAL Janken Man units */
2'600'000, /* 2.6_MHz_XTAL Sharp PC-1500 */
+ 2'700'000, /* 2.7_MHz_XTAL Resonator - YM2154 on Yamaha RX15 */
2'950'000, /* 2.95_MHz_XTAL Playmatic MPU-C, MPU-III & Sound-3 */
3'000'000, /* 3_MHz_XTAL Probably only used to drive 68705 or similar MCUs on 80's Taito PCBs */
3'072'000, /* 3.072_MHz_XTAL INS 8520 input clock rate */
@@ -122,6 +124,7 @@ const double XTAL::known_xtals[] = {
5'460'000, /* 5.46_MHz_XTAL ec1840 and ec1841 keyboard */
5'529'600, /* 5.5296_MHz_XTAL Kontron PSI98 keyboard */
5'626'000, /* 5.626_MHz_XTAL RCA CDP1869 PAL dot clock */
+ 5'659'200, /* 5.6592_MHz_XTAL Digilog 320 dot clock */
5'670'000, /* 5.67_MHz_XTAL RCA CDP1869 NTSC dot clock */
5'714'300, /* 5.7143_MHz_XTAL Cidelsa Destroyer, TeleVideo serial keyboards */
5'856'000, /* 5.856_MHz_XTAL HP 3478A Multimeter */
@@ -261,6 +264,7 @@ const double XTAL::known_xtals[] = {
16'364'000, /* 16.364_MHz_XTAL Corvus Concept */
16'384'000, /* 16.384_MHz_XTAL - */
16'400'000, /* 16.4_MHz_XTAL MS 6102 */
+ 16'537'000, /* 16.537_MHz_XTAL Falco terminals 80-column clock */
16'572'000, /* 16.572_MHz_XTAL Micro-Term ACT-5A */
16'588'800, /* 16.5888_MHz_XTAL SM 7238 */
16'666'600, /* 16.6666_MHz_XTAL Firebeat GCU */
@@ -327,6 +331,7 @@ const double XTAL::known_xtals[] = {
22'464'000, /* 22.464_MHz_XTAL CIT-101 132-column display clock */
22'579'000, /* 22.579_MHz_XTAL Sega System H1 SCSP clock */
22'656'000, /* 22.656_MHz_XTAL Super Pinball Action (~1440x NTSC line rate) */
+ 22'680'000, /* 22.680_MHz_XTAL HDS200 80-columns display clock */
22'896'000, /* 22.896_MHz_XTAL DEC VT220 132-column display clock */
23'200'000, /* 23.2_MHz_XTAL Roland JV-80 & JV-880 PCM clock */
23'814'000, /* 23.814_MHz_XTAL TeleVideo TVI-912, 920 & 950 */
@@ -371,7 +376,7 @@ const double XTAL::known_xtals[] = {
28'475'000, /* 28.475_MHz_XTAL CoCo 3 PAL */
28'480'000, /* 28.48_MHz_XTAL Chromatics CGC-7900 */
28'636'000, /* 28.636_MHz_XTAL Super Kaneko Nova System */
- 28'636'363, /* 28.636363_MHz_XTAL Later Leland games and Atari GT, Amiga NTSC, Raiden2 h/w (8x NTSC subcarrier)*/
+ 28'636'363, /* 28.636363_MHz_XTAL Later Leland games and Atari GT, Amiga NTSC, Raiden2 h/w (8x NTSC subcarrier), NEC PC-88xx */
28'640'000, /* 28.64_MHz_XTAL Fuuki FG-1c AI AM-2 PCB */
28'700'000, /* 28.7_MHz_XTAL - */
29'376'000, /* 29.376_MHz_XTAL Qume QVT-103 */
@@ -402,6 +407,8 @@ const double XTAL::known_xtals[] = {
34'000'000, /* 34_MHz_XTAL Gaelco PCBs */
34'291'712, /* 34.291712_MHz_XTAL Fairlight CMI master card */
34'846'000, /* 34.846_MHz_XTAL Visual 550 */
+ 35'469'000, /* 35.469_MHz_XTAL ZX Spectrum +2/+3 (~8x PAL subcarrier) */
+ 35'640'000, /* 35.640_MHz_XTAL HDS200 132-column display clock */
35'834'400, /* 35.8344_MHz_XTAL Tab Products E-22 132-column display clock */
35'840'000, /* 35.84_MHz_XTAL Akai MPC 60 voice PCB */
35'904'000, /* 35.904_MHz_XTAL Used on HP98543 graphics board */
@@ -450,6 +457,7 @@ const double XTAL::known_xtals[] = {
57'272'727, /* 57.272727_MHz_XTAL Psikyo SH2 with /2 divider (16x NTSC subcarrier)*/
57'283'200, /* 57.2832_MHz_XTAL Macintosh IIci RBV, 15-inch portrait display */
58'000'000, /* 58_MHz_XTAL Magic Reel (Play System) */
+ 58'982'400, /* 58.9824_MHz_XTAL Wyse WY-65 */
59'292'000, /* 59.292_MHz_XTAL Data General D461 */
60'000'000, /* 60_MHz_XTAL ARM610 */
61'440'000, /* 61.44_MHz_XTAL Donkey Kong */