summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/ioport.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/ioport.h')
-rw-r--r--src/emu/ioport.h164
1 files changed, 107 insertions, 57 deletions
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index bc8dab543be..8d16f7e4fa8 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -17,6 +17,8 @@
#ifndef __INPTPORT_H__
#define __INPTPORT_H__
+#include <cstdint>
+#include <cstring>
#include <time.h>
@@ -34,11 +36,6 @@ const ioport_value IP_ACTIVE_LOW = 0xffffffff;
// maximum number of players supported
const int MAX_PLAYERS = 8;
-// INP file parameters
-const UINT32 INP_HEADER_SIZE = 64;
-const UINT32 INP_HEADER_MAJVERSION = 3;
-const UINT32 INP_HEADER_MINVERSION = 0;
-
// unicode constants
const unicode_char UCHAR_PRIVATE = 0x100000;
const unicode_char UCHAR_SHIFT_1 = UCHAR_PRIVATE + 0;
@@ -697,15 +694,110 @@ typedef delegate<bool ()> ioport_charqueue_empty_delegate;
// ======================> inp_header
// header at the front of INP files
-struct inp_header
+class inp_header
{
- char header[8]; // +00: 8 byte header - must be "MAMEINP\0"
- UINT64 basetime; // +08: base time of recording
- UINT8 majversion; // +10: major INP version
- UINT8 minversion; // +11: minor INP version
- UINT8 reserved[2]; // +12: must be zero
- char gamename[12]; // +14: game name string, NULL-terminated
- char version[32]; // +20: system version string, NULL-terminated
+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);
+ }
+ std::uint64_t get_basetime() const
+ {
+ return
+ (std::uint64_t(m_data[OFFS_BASETIME + 0]) << (0 * 8)) |
+ (std::uint64_t(m_data[OFFS_BASETIME + 1]) << (1 * 8)) |
+ (std::uint64_t(m_data[OFFS_BASETIME + 2]) << (2 * 8)) |
+ (std::uint64_t(m_data[OFFS_BASETIME + 3]) << (3 * 8)) |
+ (std::uint64_t(m_data[OFFS_BASETIME + 4]) << (4 * 8)) |
+ (std::uint64_t(m_data[OFFS_BASETIME + 5]) << (5 * 8)) |
+ (std::uint64_t(m_data[OFFS_BASETIME + 6]) << (6 * 8)) |
+ (std::uint64_t(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(std::uint64_t time)
+ {
+ m_data[OFFS_BASETIME + 0] = std::uint8_t((time >> (0 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 1] = std::uint8_t((time >> (1 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 2] = std::uint8_t((time >> (2 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 3] = std::uint8_t((time >> (3 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 4] = std::uint8_t((time >> (4 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 5] = std::uint8_t((time >> (5 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 6] = std::uint8_t((time >> (6 * 8)) & 0x00ff);
+ m_data[OFFS_BASETIME + 7] = std::uint8_t((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 std::uint8_t const MAGIC[OFFS_BASETIME - OFFS_MAGIC];
+
+ std::uint8_t m_data[OFFS_END];
};
@@ -1580,7 +1672,6 @@ private:
#define DECLARE_INPUT_CHANGED_MEMBER(name) void name(ioport_field &field, void *param, ioport_value oldval, ioport_value newval)
// macro for port changed callback functions (PORT_CROSSHAIR_MAPPER)
-#define CROSSHAIR_MAPPER(name) float name(device_t &device, ioport_field &field, float linear_value)
#define CROSSHAIR_MAPPER_MEMBER(name) float name(ioport_field &field, float linear_value)
#define DECLARE_CROSSHAIR_MAPPER_MEMBER(name) float name(ioport_field &field, float linear_value)
@@ -1727,9 +1818,6 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
configurer.field_set_analog_invert();
// read callbacks
-#define PORT_CUSTOM(_callback, _param) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate(_callback, #_callback, DEVICE_SELF, (device_t *)NULL), (void *)(_param));
-
#define PORT_CUSTOM_MEMBER(_device, _class, _member, _param) \
configurer.field_set_dynamic_read(ioport_field_read_delegate(&_class::_member, #_class "::" #_member, _device, (_class *)NULL), (void *)(_param));
@@ -1738,18 +1826,12 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
configurer.field_set_dynamic_write(ioport_field_write_delegate(&_class::_member, #_class "::" #_member, _device, (_class *)NULL), (void *)(_param));
// input device handler
-#define PORT_READ_LINE_DEVICE(_device, _read_line_device) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate(&ioport_read_line_wrapper<_read_line_device>, #_read_line_device, _device, (device_t *)NULL));
-
#define PORT_READ_LINE_DEVICE_MEMBER(_device, _class, _member) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate(&ioport_read_line_wrapper<_class, &_class::_member>, #_class "::" #_member, _device, (_class *)NULL));
+ configurer.field_set_dynamic_read(ioport_field_read_delegate([](_class &device, ioport_field &field, void *param)->ioport_value { return (device._member() & 1) ? ~ioport_value(0) : 0; } , #_class "::" #_member, _device, (_class *)NULL));
// output device handler
-#define PORT_WRITE_LINE_DEVICE(_device, _write_line_device) \
- configurer.field_set_dynamic_write(ioport_field_write_delegate(&ioport_write_line_wrapper<_write_line_device>, #_write_line_device, _device, (device_t *)NULL));
-
#define PORT_WRITE_LINE_DEVICE_MEMBER(_device, _class, _member) \
- configurer.field_set_dynamic_write(ioport_field_write_delegate(&ioport_write_line_wrapper<_class, &_class::_member>, #_class "::" #_member, _device, (_class *)NULL));
+ configurer.field_set_dynamic_write(ioport_field_write_delegate([](_class &device, ioport_field &field, void *param, ioport_value oldval, ioport_value newval) { device._member(newval); }, #_class "::" #_member, _device, (_class *)NULL));
// dip switch definition
#define PORT_DIPNAME(_mask, _default, _name) \
@@ -1829,38 +1911,6 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
#define PORT_HBLANK(_screen) \
PORT_READ_LINE_DEVICE_MEMBER(_screen, screen_device, hblank)
-
-
-//**************************************************************************
-// INLINE TEMPLATES
-//**************************************************************************
-
-template<int (*_FunctionPointer)(device_t *)>
-ioport_value ioport_read_line_wrapper(device_t &device, ioport_field &field, void *param)
-{
- return ((*_FunctionPointer)(&device) & 1) ? ~ioport_value(0) : 0;
-}
-
-template<class _FunctionClass, int (_FunctionClass::*_FunctionPointer)()>
-ioport_value ioport_read_line_wrapper(_FunctionClass &device, ioport_field &field, void *param)
-{
- return ((device.*_FunctionPointer)() & 1) ? ~ioport_value(0) : 0;
-}
-
-template<void (*_FunctionPointer)(device_t *, int)>
-void ioport_write_line_wrapper(device_t &device, ioport_field &field, void *param, ioport_value oldval, ioport_value newval)
-{
- return (*_FunctionPointer)(&device, newval);
-}
-
-template<class _FunctionClass, void (_FunctionClass::*_FunctionPointer)(int)>
-void ioport_write_line_wrapper(_FunctionClass &device, ioport_field &field, void *param, ioport_value oldval, ioport_value newval)
-{
- return (device.*_FunctionPointer)(newval);
-}
-
-
-
//**************************************************************************
// INLINE FUNCTIONS
//**************************************************************************