summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/input/input_rawinput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/input/input_rawinput.cpp')
-rw-r--r--src/osd/modules/input/input_rawinput.cpp1028
1 files changed, 607 insertions, 421 deletions
diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp
index 9243ec4a0f4..5b6813dcd59 100644
--- a/src/osd/modules/input/input_rawinput.cpp
+++ b/src/osd/modules/input/input_rawinput.cpp
@@ -6,41 +6,39 @@
//
//============================================================
-#include "input_module.h"
#include "modules/osdmodule.h"
#if defined(OSD_WINDOWS)
-// standard windows headers
-#include <windows.h>
-#include <tchar.h>
-#undef interface
+#include "input_windows.h"
-#include <mutex>
-#include <functional>
-#include <algorithm>
+#include "input_wincommon.h"
-// MAME headers
-#include "emu.h"
-#include "strconv.h"
-
-// MAMEOS headers
-#include "modules/lib/osdlib.h"
#include "winmain.h"
#include "window.h"
-#include "input_common.h"
-#include "input_windows.h"
+#include "modules/lib/osdlib.h"
+#include "strconv.h"
-//============================================================
-// MACROS
-//============================================================
+// MAME headers
+#include "inpttype.h"
+
+#include <algorithm>
+#include <cassert>
+#include <chrono>
+#include <functional>
+#include <mutex>
+#include <new>
+#include <utility>
+
+// standard windows headers
+#include <windows.h>
+#include <tchar.h>
-// Typedefs for dynamically loaded functions
-typedef UINT (WINAPI *get_rawinput_device_list_ptr)(PRAWINPUTDEVICELIST, PUINT, UINT);
-typedef UINT (WINAPI *get_rawinput_data_ptr)( HRAWINPUT, UINT, LPVOID, PUINT, UINT);
-typedef UINT (WINAPI *get_rawinput_device_info_ptr)(HANDLE, UINT, LPVOID, PUINT);
-typedef BOOL (WINAPI *register_rawinput_devices_ptr)(PCRAWINPUTDEVICE, UINT, UINT);
+
+namespace osd {
+
+namespace {
class safe_regkey
{
@@ -48,17 +46,24 @@ private:
HKEY m_key;
public:
- safe_regkey()
- : m_key(nullptr)
- {
- }
+ safe_regkey() : m_key(nullptr) { }
+ safe_regkey(safe_regkey const &) = delete;
+ safe_regkey(safe_regkey &&key) : m_key(key.m_key) { key.m_key = nullptr; }
+ explicit safe_regkey(HKEY key) : m_key(key) { }
- explicit safe_regkey(HKEY key)
- : m_key(key)
+ ~safe_regkey() { close(); }
+
+ safe_regkey &operator=(safe_regkey const &) = delete;
+
+ safe_regkey &operator=(safe_regkey &&key)
{
+ close();
+ m_key = key.m_key;
+ key.m_key = nullptr;
+ return *this;
}
- bool valid() const { return m_key != nullptr; }
+ explicit operator bool() const { return m_key != nullptr; }
void close()
{
@@ -69,70 +74,68 @@ public:
}
}
- ~safe_regkey()
- {
- close();
- }
-
operator HKEY() const { return m_key; }
-};
-//============================================================
-// reg_open_key
-//============================================================
-
-static safe_regkey reg_open_key(HKEY basekey, const std::wstring &subkey)
-{
- HKEY key;
- if (RegOpenKeyEx(basekey, subkey.c_str(), 0, KEY_READ, &key) == ERROR_SUCCESS)
- return safe_regkey(key);
+ safe_regkey open(std::wstring const &subkey) const { return open(m_key, subkey); }
- return safe_regkey();
+ std::wstring enum_key(int index) const
+ {
+ WCHAR keyname[256];
+ DWORD namelen = std::size(keyname);
+ if (RegEnumKeyEx(m_key, index, keyname, &namelen, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS)
+ return std::wstring(keyname, namelen);
+ else
+ return std::wstring();
+ }
-}
+ std::wstring query_string(WCHAR const *path) const
+ {
+ // first query to get the length
+ DWORD datalen;
+ if (RegQueryValueExW(m_key, path, nullptr, nullptr, nullptr, &datalen) != ERROR_SUCCESS)
+ return std::wstring();
-//============================================================
-// reg_enum_key
-//============================================================
+ // allocate a buffer
+ auto buffer = std::make_unique<WCHAR []>((datalen + (sizeof(WCHAR) * 2) - 1) / sizeof(WCHAR));
-static std::wstring reg_enum_key(HKEY key, int index)
-{
- WCHAR keyname[MAX_PATH];
- DWORD namelen;
- if (RegEnumKeyEx(key, index, keyname, &namelen, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS)
- return std::wstring(keyname, namelen);
+ // now get the actual data
+ if (RegQueryValueExW(m_key, path, nullptr, nullptr, reinterpret_cast<LPBYTE>(buffer.get()), &datalen) != ERROR_SUCCESS)
+ return std::wstring();
- return std::wstring();
-}
-
-//============================================================
-// reg_query_string
-//============================================================
-
-static std::wstring reg_query_string(HKEY key, const TCHAR *path)
-{
- DWORD datalen;
- LONG result;
+ buffer[datalen / sizeof(WCHAR)] = 0;
+ return std::wstring(buffer.get());
+ }
- // first query to get the length
- result = RegQueryValueEx(key, path, nullptr, nullptr, nullptr, &datalen);
- if (result != ERROR_SUCCESS)
- return std::wstring();
+ template <typename T> void foreach_subkey(T &&action) const
+ {
+ std::wstring name;
+ for (int i = 0; ; i++)
+ {
+ name = enum_key(i);
+ if (name.empty())
+ break;
- // allocate a buffer
- auto buffer = std::make_unique<TCHAR[]>(datalen + sizeof(TCHAR));
- buffer[datalen / sizeof(TCHAR)] = 0;
+ safe_regkey const subkey = open(name);
+ if (!subkey)
+ break;
- // now get the actual data
- result = RegQueryValueEx(key, path, nullptr, nullptr, reinterpret_cast<LPBYTE>(buffer.get()), &datalen);
- if (result == ERROR_SUCCESS)
- return std::wstring(buffer.get());
+ bool const shouldcontinue = action(subkey);
+ if (!shouldcontinue)
+ break;
+ }
+ }
- // otherwise return an empty string
- return std::wstring();
-}
+ static safe_regkey open(HKEY basekey, std::wstring const &subkey)
+ {
+ HKEY key(nullptr);
+ if (RegOpenKeyEx(basekey, subkey.c_str(), 0, KEY_READ, &key) == ERROR_SUCCESS)
+ return safe_regkey(key);
+ else
+ return safe_regkey();
+ }
+};
-static std::wstring trim_prefix(const std::wstring &devicename)
+std::wstring trim_prefix(const std::wstring &devicename)
{
// remove anything prior to the final semicolon
auto semicolon_index = devicename.find_last_of(';');
@@ -142,22 +145,22 @@ static std::wstring trim_prefix(const std::wstring &devicename)
return devicename;
}
-static std::wstring compute_device_regpath(const std::wstring &name)
+std::wstring compute_device_regpath(const std::wstring &name)
{
static const std::wstring basepath(L"SYSTEM\\CurrentControlSet\\Enum\\");
// allocate a temporary string and concatenate the base path plus the name
- auto regpath_buffer = std::make_unique<TCHAR[]>(basepath.length() + 1 + name.length());
+ auto regpath_buffer = std::make_unique<WCHAR []>(basepath.length() + 1 + name.length());
wcscpy(regpath_buffer.get(), basepath.c_str());
- WCHAR * chdst = regpath_buffer.get() + basepath.length();
+ WCHAR *chdst = regpath_buffer.get() + basepath.length();
// convert all # to \ in the name
for (int i = 4; i < name.length(); i++)
- *chdst++ = (name[i] == '#') ? '\\' : name[i];
+ *chdst++ = (name[i] == '#') ? L'\\' : name[i];
*chdst = 0;
// remove the final chunk
- chdst = wcsrchr(regpath_buffer.get(), '\\');
+ chdst = wcsrchr(regpath_buffer.get(), L'\\');
if (chdst == nullptr)
return std::wstring();
@@ -166,15 +169,15 @@ static std::wstring compute_device_regpath(const std::wstring &name)
return std::wstring(regpath_buffer.get());
}
-static std::wstring improve_name_from_base_path(const std::wstring &regpath, bool *hid)
+std::wstring improve_name_from_base_path(const std::wstring &regpath, bool *hid)
{
// now try to open the registry key
- auto device_key = reg_open_key(HKEY_LOCAL_MACHINE, regpath);
- if (!device_key.valid())
+ auto device_key = safe_regkey::open(HKEY_LOCAL_MACHINE, regpath);
+ if (!device_key)
return std::wstring();
// fetch the device description; if it exists, we are finished
- auto regstring = reg_query_string(device_key, L"DeviceDesc");
+ auto regstring = device_key.query_string(L"DeviceDesc");
if (!regstring.empty())
return trim_prefix(regstring);
@@ -183,25 +186,7 @@ static std::wstring improve_name_from_base_path(const std::wstring &regpath, boo
return std::wstring();
}
-static void foreach_subkey(HKEY key, std::function<bool(HKEY)> action)
-{
- for (int i = 0; ; i++)
- {
- std::wstring name = reg_enum_key(key, i);
- if (name.empty())
- break;
-
- safe_regkey subkey = reg_open_key(key, name);
- if (!subkey.valid())
- break;
-
- bool shouldcontinue = action(subkey);
- if (!shouldcontinue)
- break;
- }
-}
-
-static std::wstring improve_name_from_usb_path(const std::wstring &regpath)
+std::wstring improve_name_from_usb_path(const std::wstring &regpath)
{
static const std::wstring usbbasepath(L"SYSTEM\\CurrentControlSet\\Enum\\USB");
@@ -213,40 +198,43 @@ static std::wstring improve_name_from_usb_path(const std::wstring &regpath)
std::wstring parentid = regpath.substr(last_slash_index + 1);
// open the USB key
- auto usb_key = reg_open_key(HKEY_LOCAL_MACHINE, usbbasepath);
- if (!usb_key.valid())
+ auto usb_key = safe_regkey::open(HKEY_LOCAL_MACHINE, usbbasepath);
+ if (!usb_key)
return std::wstring();
std::wstring regstring;
- foreach_subkey(usb_key, [&regstring, &parentid](HKEY subkey)
- {
- foreach_subkey(subkey, [&regstring, &parentid](HKEY endkey)
- {
- std::wstring endparentid = reg_query_string(endkey, L"ParentIdPrefix");
+ usb_key.foreach_subkey(
+ [&regstring, &parentid] (safe_regkey const &subkey)
+ {
+ subkey.foreach_subkey(
+ [&regstring, &parentid] (safe_regkey const &endkey)
+ {
+ std::wstring endparentid = endkey.query_string(L"ParentIdPrefix");
- // This key doesn't have a ParentIdPrefix
- if (endparentid.empty())
- return true;
+ // This key doesn't have a ParentIdPrefix
+ if (endparentid.empty())
+ return true;
- // do we have a match?
- if (parentid.find(endparentid) == 0)
- regstring = reg_query_string(endkey, L"DeviceDesc");
+ // do we have a match?
+ if (parentid.find(endparentid) == 0)
+ regstring = endkey.query_string(L"DeviceDesc");
- return regstring.empty();
- });
+ return regstring.empty();
+ });
- return regstring.empty();
- });
+ return regstring.empty();
+ });
return trim_prefix(regstring);
}
+
//============================================================
// rawinput_device_improve_name
//============================================================
-static std::wstring rawinput_device_improve_name(const std::wstring &name)
+std::wstring rawinput_device_improve_name(const std::wstring &name)
{
// The RAW name received is formatted as:
// \??\type-id#hardware-id#instance-id#{DeviceClasses-id}
@@ -282,20 +270,36 @@ static std::wstring rawinput_device_improve_name(const std::wstring &name)
class rawinput_device : public event_based_device<RAWINPUT>
{
-private:
- HANDLE m_handle;
-
public:
- rawinput_device(running_machine& machine, const char *name, const char *id, input_device_class deviceclass, input_module& module)
- : event_based_device(machine, name, id, deviceclass, module),
- m_handle(nullptr)
+ rawinput_device(std::string &&name, std::string &&id, input_module &module, HANDLE handle) :
+ event_based_device(std::move(name), std::move(id), module),
+ m_handle(handle)
{
}
HANDLE device_handle() const { return m_handle; }
- void set_handle(HANDLE handle) { m_handle = handle; }
+
+ bool reconnect_candidate(std::string_view i) const { return !m_handle && (id() == i); }
+
+ void detach_device()
+ {
+ assert(m_handle);
+ m_handle = nullptr;
+ osd_printf_verbose("RawInput: %s [ID %s] disconnected\n", name(), id());
+ }
+
+ void attach_device(HANDLE handle)
+ {
+ assert(!m_handle);
+ m_handle = handle;
+ osd_printf_verbose("RawInput: %s [ID %s] reconnected\n", name(), id());
+ }
+
+private:
+ HANDLE m_handle;
};
+
//============================================================
// rawinput_keyboard_device
//============================================================
@@ -303,490 +307,672 @@ public:
class rawinput_keyboard_device : public rawinput_device
{
public:
- keyboard_state keyboard;
+ rawinput_keyboard_device(std::string &&name, std::string &&id, input_module &module, HANDLE handle) :
+ rawinput_device(std::move(name), std::move(id), module, handle),
+ m_pause_pressed(std::chrono::steady_clock::time_point::min()),
+ m_e1(0xffff),
+ m_keyboard({ { 0 } })
+ {
+ }
- rawinput_keyboard_device(running_machine& machine, const char *name, const char *id, input_module& module)
- : rawinput_device(machine, name, id, DEVICE_CLASS_KEYBOARD, module),
- keyboard({{0}})
+ virtual void reset() override
{
+ rawinput_device::reset();
+ m_pause_pressed = std::chrono::steady_clock::time_point::min();
+ memset(&m_keyboard, 0, sizeof(m_keyboard));
+ m_e1 = 0xffff;
}
- void reset() override
+ virtual void poll(bool relative_reset) override
{
- memset(&keyboard, 0, sizeof(keyboard));
+ rawinput_device::poll(relative_reset);
+ if (m_keyboard.state[0x80 | 0x45] && (std::chrono::steady_clock::now() > (m_pause_pressed + std::chrono::milliseconds(30))))
+ m_keyboard.state[0x80 | 0x45] = 0x00;
}
- void process_event(RAWINPUT &rawinput) override
+ virtual void process_event(RAWINPUT const &rawinput) override
{
// determine the full DIK-compatible scancode
- uint8_t scancode = (rawinput.data.keyboard.MakeCode & 0x7f) | ((rawinput.data.keyboard.Flags & RI_KEY_E0) ? 0x80 : 0x00);
+ uint8_t scancode;
- // scancode 0xaa is a special shift code we need to ignore
- if (scancode == 0xaa)
+ // the only thing that uses this is Pause
+ if (rawinput.data.keyboard.Flags & RI_KEY_E1)
+ {
+ m_e1 = rawinput.data.keyboard.MakeCode;
return;
+ }
+ else if (0xffff != m_e1)
+ {
+ auto const e1 = std::exchange(m_e1, 0xffff);
+ if (!(rawinput.data.keyboard.Flags & RI_KEY_E0))
+ {
+ if (((e1 & ~USHORT(0x80)) == 0x1d) && ((rawinput.data.keyboard.MakeCode & ~USHORT(0x80)) == 0x45))
+ {
+ if (rawinput.data.keyboard.Flags & RI_KEY_BREAK)
+ return; // RawInput generates a fake break immediately after the make - ignore it
+
+ m_pause_pressed = std::chrono::steady_clock::now();
+ scancode = 0x80 | 0x45;
+ }
+ else
+ {
+ return; // no idea
+ }
+ }
+ else
+ {
+ return; // shouldn't happen, ignore it
+ }
+ }
+ else
+ {
+ // strip bit 7 of the make code to work around dodgy drivers that set it for key up events
+ if (rawinput.data.keyboard.MakeCode & ~USHORT(0xff))
+ {
+ // won't fit in a byte along with the E0 flag
+ return;
+ }
+ scancode = (rawinput.data.keyboard.MakeCode & 0x7f) | ((rawinput.data.keyboard.Flags & RI_KEY_E0) ? 0x80 : 0x00);
+
+ // fake shift generated with cursor control and Ins/Del for compatibility with very old DOS software
+ if (scancode == 0xaa)
+ return;
+ }
// set or clear the key
- keyboard.state[scancode] = (rawinput.data.keyboard.Flags & RI_KEY_BREAK) ? 0x00 : 0x80;
+ m_keyboard.state[scancode] = (rawinput.data.keyboard.Flags & RI_KEY_BREAK) ? 0x00 : 0x80;
}
+
+ virtual void configure(input_device &device) override
+ {
+ keyboard_trans_table const &table = keyboard_trans_table::instance();
+
+ // FIXME: GetKeyNameTextW is for scan codes from WM_KEYDOWN, which aren't quite the same as DIK_* keycodes
+ // in particular, NumLock and Pause are reversed for US-style keyboard systems
+ for (unsigned keynum = 0; keynum < MAX_KEYS; keynum++)
+ {
+ input_item_id itemid = table.map_di_scancode_to_itemid(keynum);
+ WCHAR keyname[100];
+
+ // generate the name
+ // FIXME: GetKeyNameText gives bogus names for media keys and various other things
+ // in many cases it ignores the "extended" bit and returns the key name corresponding to the scan code alone
+ LONG lparam = ((keynum & 0x7f) << 16) | ((keynum & 0x80) << 17);
+ if ((keynum & 0x7f) == 0x45)
+ lparam ^= 0x0100'0000; // horrid hack
+ if (GetKeyNameTextW(lparam, keyname, std::size(keyname)) == 0)
+ _snwprintf(keyname, std::size(keyname), L"Scan%03d", keynum);
+ std::string name = text::from_wstring(keyname);
+
+ // add the item to the device
+ device.add_item(
+ name,
+ util::string_format("SCAN%03d", keynum),
+ itemid,
+ generic_button_get_state<std::uint8_t>,
+ &m_keyboard.state[keynum]);
+ }
+ }
+
+private:
+ std::chrono::steady_clock::time_point m_pause_pressed;
+ uint16_t m_e1;
+ keyboard_state m_keyboard;
};
+
//============================================================
// rawinput_mouse_device
//============================================================
class rawinput_mouse_device : public rawinput_device
{
-private:
- std::mutex m_device_lock;
public:
- mouse_state mouse;
-
- rawinput_mouse_device(running_machine& machine, const char *name, const char *id, input_module& module)
- : rawinput_device(machine, name, id, DEVICE_CLASS_MOUSE, module),
- mouse({0})
+ rawinput_mouse_device(std::string &&name, std::string &&id, input_module &module, HANDLE handle) :
+ rawinput_device(std::move(name), std::move(id), module, handle),
+ m_mouse({0}),
+ m_x(0),
+ m_y(0),
+ m_v(0),
+ m_h(0)
{
}
- void poll() override
+ virtual void poll(bool relative_reset) override
{
- mouse.lX = 0;
- mouse.lY = 0;
- mouse.lZ = 0;
-
- rawinput_device::poll();
+ rawinput_device::poll(relative_reset);
+ if (relative_reset)
+ {
+ m_mouse.lX = std::exchange(m_x, 0);
+ m_mouse.lY = std::exchange(m_y, 0);
+ m_mouse.lV = std::exchange(m_v, 0);
+ m_mouse.lH = std::exchange(m_h, 0);
+ }
}
- void reset() override
+ virtual void reset() override
{
- memset(&mouse, 0, sizeof(mouse));
+ rawinput_device::reset();
+ memset(&m_mouse, 0, sizeof(m_mouse));
+ m_x = m_y = m_v = m_h = 0;
}
- void process_event(RAWINPUT &rawinput) override
+ virtual void configure(input_device &device) override
{
+ // populate the axes
+ device.add_item(
+ "X",
+ std::string_view(),
+ ITEM_ID_XAXIS,
+ generic_axis_get_state<LONG>,
+ &m_mouse.lX);
+ device.add_item(
+ "Y",
+ std::string_view(),
+ ITEM_ID_YAXIS,
+ generic_axis_get_state<LONG>,
+ &m_mouse.lY);
+ device.add_item(
+ "Scroll V",
+ std::string_view(),
+ ITEM_ID_ZAXIS,
+ generic_axis_get_state<LONG>,
+ &m_mouse.lV);
+ device.add_item(
+ "Scroll H",
+ std::string_view(),
+ ITEM_ID_RZAXIS,
+ generic_axis_get_state<LONG>,
+ &m_mouse.lH);
+
+ // populate the buttons
+ for (int butnum = 0; butnum < 5; butnum++)
+ {
+ device.add_item(
+ default_button_name(butnum),
+ std::string_view(),
+ input_item_id(ITEM_ID_BUTTON1 + butnum),
+ generic_button_get_state<BYTE>,
+ &m_mouse.rgbButtons[butnum]);
+ }
+ }
+ virtual void process_event(RAWINPUT const &rawinput) override
+ {
// If this data was intended for a rawinput mouse
if (rawinput.data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
{
+ m_x += rawinput.data.mouse.lLastX * input_device::RELATIVE_PER_PIXEL;
+ m_y += rawinput.data.mouse.lLastY * input_device::RELATIVE_PER_PIXEL;
- mouse.lX += rawinput.data.mouse.lLastX * INPUT_RELATIVE_PER_PIXEL;
- mouse.lY += rawinput.data.mouse.lLastY * INPUT_RELATIVE_PER_PIXEL;
-
- // update zaxis
+ // update Z/Rz axes (vertical/horizontal scroll)
if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
- mouse.lZ += static_cast<int16_t>(rawinput.data.mouse.usButtonData) * INPUT_RELATIVE_PER_PIXEL;
+ m_v += int16_t(rawinput.data.mouse.usButtonData) * input_device::RELATIVE_PER_PIXEL;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_HWHEEL)
+ m_h += int16_t(rawinput.data.mouse.usButtonData) * input_device::RELATIVE_PER_PIXEL;
// update the button states; always update the corresponding mouse buttons
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) mouse.rgbButtons[0] = 0x80;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) mouse.rgbButtons[0] = 0x00;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) mouse.rgbButtons[1] = 0x80;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) mouse.rgbButtons[1] = 0x00;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) mouse.rgbButtons[2] = 0x80;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) mouse.rgbButtons[2] = 0x00;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) mouse.rgbButtons[3] = 0x80;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) mouse.rgbButtons[3] = 0x00;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) mouse.rgbButtons[4] = 0x80;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) mouse.rgbButtons[4] = 0x00;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) m_mouse.rgbButtons[0] = 0x80;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) m_mouse.rgbButtons[0] = 0x00;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) m_mouse.rgbButtons[1] = 0x80;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) m_mouse.rgbButtons[1] = 0x00;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) m_mouse.rgbButtons[2] = 0x80;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) m_mouse.rgbButtons[2] = 0x00;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) m_mouse.rgbButtons[3] = 0x80;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) m_mouse.rgbButtons[3] = 0x00;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) m_mouse.rgbButtons[4] = 0x80;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) m_mouse.rgbButtons[4] = 0x00;
}
}
+
+private:
+ mouse_state m_mouse;
+ LONG m_x, m_y, m_v, m_h;
};
+
//============================================================
// rawinput_lightgun_device
//============================================================
class rawinput_lightgun_device : public rawinput_device
{
-private:
- std::mutex m_device_lock;
public:
- mouse_state lightgun;
-
- rawinput_lightgun_device(running_machine& machine, const char *name, const char *id, input_module& module)
- : rawinput_device(machine, name, id, DEVICE_CLASS_LIGHTGUN, module),
- lightgun({0})
+ rawinput_lightgun_device(std::string &&name, std::string &&id, input_module &module, HANDLE handle) :
+ rawinput_device(std::move(name), std::move(id), module, handle),
+ m_lightgun({0}),
+ m_v(0),
+ m_h(0)
{
}
- void poll() override
+ virtual void poll(bool relative_reset) override
{
- lightgun.lZ = 0;
+ rawinput_device::poll(relative_reset);
+ if (relative_reset)
+ {
+ m_lightgun.lV = std::exchange(m_v, 0);
+ m_lightgun.lH = std::exchange(m_h, 0);
+ }
+ }
- rawinput_device::poll();
+ virtual void reset() override
+ {
+ rawinput_device::reset();
+ memset(&m_lightgun, 0, sizeof(m_lightgun));
+ m_v = 0;
+ m_h = 0;
}
- void reset() override
+ virtual void configure(input_device &device) override
{
- memset(&lightgun, 0, sizeof(lightgun));
+ // populate the axes
+ for (int axisnum = 0; axisnum < 2; axisnum++)
+ {
+ device.add_item(
+ default_axis_name[axisnum],
+ std::string_view(),
+ input_item_id(ITEM_ID_XAXIS + axisnum),
+ generic_axis_get_state<LONG>,
+ &m_lightgun.lX + axisnum);
+ }
+
+ // scroll wheels are always relative if present
+ device.add_item(
+ "Scroll V",
+ std::string_view(),
+ ITEM_ID_ADD_RELATIVE1,
+ generic_axis_get_state<LONG>,
+ &m_lightgun.lV);
+ device.add_item(
+ "Scroll H",
+ std::string_view(),
+ ITEM_ID_ADD_RELATIVE2,
+ generic_axis_get_state<LONG>,
+ &m_lightgun.lH);
+
+ // populate the buttons
+ for (int butnum = 0; butnum < 5; butnum++)
+ {
+ device.add_item(
+ default_button_name(butnum),
+ std::string_view(),
+ input_item_id(ITEM_ID_BUTTON1 + butnum),
+ generic_button_get_state<BYTE>,
+ &m_lightgun.rgbButtons[butnum]);
+ }
}
- void process_event(RAWINPUT &rawinput) override
+ virtual void process_event(RAWINPUT const &rawinput) override
{
// If this data was intended for a rawinput lightgun
if (rawinput.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
{
-
// update the X/Y positions
- lightgun.lX = normalize_absolute_axis(rawinput.data.mouse.lLastX, 0, INPUT_ABSOLUTE_MAX);
- lightgun.lY = normalize_absolute_axis(rawinput.data.mouse.lLastY, 0, INPUT_ABSOLUTE_MAX);
+ m_lightgun.lX = normalize_absolute_axis(rawinput.data.mouse.lLastX, 0, input_device::ABSOLUTE_MAX);
+ m_lightgun.lY = normalize_absolute_axis(rawinput.data.mouse.lLastY, 0, input_device::ABSOLUTE_MAX);
- // update zaxis
+ // update Z/Rz axes
if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
- lightgun.lZ += static_cast<int16_t>(rawinput.data.mouse.usButtonData) * INPUT_RELATIVE_PER_PIXEL;
+ m_v += int16_t(rawinput.data.mouse.usButtonData) * input_device::RELATIVE_PER_PIXEL;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_HWHEEL)
+ m_h += int16_t(rawinput.data.mouse.usButtonData) * input_device::RELATIVE_PER_PIXEL;
// update the button states; always update the corresponding mouse buttons
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) lightgun.rgbButtons[0] = 0x80;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) lightgun.rgbButtons[0] = 0x00;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) lightgun.rgbButtons[1] = 0x80;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) lightgun.rgbButtons[1] = 0x00;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) lightgun.rgbButtons[2] = 0x80;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) lightgun.rgbButtons[2] = 0x00;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) lightgun.rgbButtons[3] = 0x80;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) lightgun.rgbButtons[3] = 0x00;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) lightgun.rgbButtons[4] = 0x80;
- if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) lightgun.rgbButtons[4] = 0x00;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) m_lightgun.rgbButtons[0] = 0x80;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) m_lightgun.rgbButtons[0] = 0x00;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) m_lightgun.rgbButtons[1] = 0x80;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) m_lightgun.rgbButtons[1] = 0x00;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) m_lightgun.rgbButtons[2] = 0x80;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) m_lightgun.rgbButtons[2] = 0x00;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) m_lightgun.rgbButtons[3] = 0x80;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) m_lightgun.rgbButtons[3] = 0x00;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) m_lightgun.rgbButtons[4] = 0x80;
+ if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) m_lightgun.rgbButtons[4] = 0x00;
}
}
+
+private:
+ mouse_state m_lightgun;
+ LONG m_v, m_h;
};
+
//============================================================
-// rawinput_module - base class for rawinput modules
+// rawinput_module - base class for RawInput modules
//============================================================
-class rawinput_module : public wininput_module
+class rawinput_module : public wininput_module<rawinput_device>
{
private:
- osd::dynamic_module::ptr m_user32_dll;
- get_rawinput_device_list_ptr get_rawinput_device_list;
- get_rawinput_data_ptr get_rawinput_data;
- get_rawinput_device_info_ptr get_rawinput_device_info;
- register_rawinput_devices_ptr register_rawinput_devices;
- std::mutex m_module_lock;
+ std::mutex m_module_lock;
public:
- rawinput_module(const char *type, const char* name)
- : wininput_module(type, name),
- get_rawinput_device_list(nullptr),
- get_rawinput_data(nullptr),
- get_rawinput_device_info(nullptr),
- register_rawinput_devices(nullptr)
+ rawinput_module(const char *type, const char *name) : wininput_module<rawinput_device>(type, name)
{
}
- bool probe() override
+ virtual bool probe() override
{
- m_user32_dll = osd::dynamic_module::open({ "user32.dll" });
-
- get_rawinput_device_list = m_user32_dll->bind<get_rawinput_device_list_ptr>("GetRawInputDeviceList");
- get_rawinput_data = m_user32_dll->bind<get_rawinput_data_ptr>("GetRawInputData");
- get_rawinput_device_info = m_user32_dll->bind<get_rawinput_device_info_ptr>("GetRawInputDeviceInfoW");
- register_rawinput_devices = m_user32_dll->bind<register_rawinput_devices_ptr>("RegisterRawInputDevices");
-
- if (!get_rawinput_device_list || !get_rawinput_data ||
- !get_rawinput_device_info || !register_rawinput_devices )
- {
- return false;
- }
-
return true;
}
- void input_init(running_machine &machine) override
+ virtual void input_init(running_machine &machine) override
{
- // get the number of devices, allocate a device list, and fetch it
- UINT device_count = 0;
- if ((*get_rawinput_device_list)(nullptr, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0)
- return;
+ wininput_module<rawinput_device>::input_init(machine);
- if (device_count == 0)
+ // get initial number of devices
+ UINT device_count = 0;
+ if (GetRawInputDeviceList(nullptr, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0)
+ {
+ osd_printf_error("Error getting initial number of RawInput devices.\n");
return;
-
- auto rawinput_devices = std::make_unique<RAWINPUTDEVICELIST[]>(device_count);
- if ((*get_rawinput_device_list)(rawinput_devices.get(), &device_count, sizeof(RAWINPUTDEVICELIST)) == -1)
+ }
+ if (!device_count)
return;
- // iterate backwards through devices; new devices are added at the head
- for (int devnum = device_count - 1; devnum >= 0; devnum--)
+ std::unique_ptr<RAWINPUTDEVICELIST []> rawinput_devices;
+ UINT retrieved;
+ do
{
- RAWINPUTDEVICELIST *device = &rawinput_devices[devnum];
- add_rawinput_device(machine, device);
+ rawinput_devices.reset(new (std::nothrow) RAWINPUTDEVICELIST [device_count]);
+ if (!rawinput_devices)
+ {
+ osd_printf_error("Error allocating buffer for RawInput device list.\n");
+ return;
+ }
+ retrieved = GetRawInputDeviceList(rawinput_devices.get(), &device_count, sizeof(RAWINPUTDEVICELIST));
}
-
- // don't enable global inputs when debugging
- if (!machine.options().debug())
+ while ((UINT(-1) == retrieved) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER));
+ if (UINT(-1) == retrieved)
{
- m_global_inputs_enabled = downcast<windows_options &>(machine.options()).global_inputs();
+ osd_printf_error("Error listing RawInput devices.\n");
+ return;
}
+ // iterate backwards through devices; new devices are added at the head
+ for (int devnum = retrieved - 1; devnum >= 0; devnum--)
+ add_rawinput_device(rawinput_devices[devnum]);
+
// If we added no devices, no need to register for notifications
- if (devicelist()->size() == 0)
+ if (devicelist().empty())
return;
// finally, register to receive raw input WM_INPUT messages if we found devices
RAWINPUTDEVICE registration;
registration.usUsagePage = usagepage();
registration.usUsage = usage();
- registration.dwFlags = m_global_inputs_enabled ? 0x00000100 : 0;
- registration.hwndTarget = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window();
+ registration.dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
+ registration.hwndTarget = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
// register the device
- (*register_rawinput_devices)(&registration, 1, sizeof(registration));
+ RegisterRawInputDevices(&registration, 1, sizeof(registration));
}
protected:
- virtual void add_rawinput_device(running_machine& machine, RAWINPUTDEVICELIST * device) = 0;
+ virtual void add_rawinput_device(RAWINPUTDEVICELIST const &device) = 0;
virtual USHORT usagepage() = 0;
virtual USHORT usage() = 0;
- int init_internal() override
- {
- if (!get_rawinput_device_list || !get_rawinput_data ||
- !get_rawinput_device_info || !register_rawinput_devices )
- {
- return 1;
- }
-
- osd_printf_verbose("RawInput: APIs detected\n");
- return 0;
- }
-
template<class TDevice>
- TDevice* create_rawinput_device(running_machine &machine, PRAWINPUTDEVICELIST rawinputdevice)
+ TDevice *create_rawinput_device(input_device_class deviceclass, RAWINPUTDEVICELIST const &rawinputdevice)
{
- TDevice* devinfo;
- UINT name_length = 0;
// determine the length of the device name, allocate it, and fetch it if not nameless
- if ((*get_rawinput_device_info)(rawinputdevice->hDevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
+ UINT name_length = 0;
+ if (GetRawInputDeviceInfoW(rawinputdevice.hDevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
return nullptr;
- std::unique_ptr<TCHAR[]> tname = std::make_unique<TCHAR[]>(name_length + 1);
- if (name_length > 1 && (*get_rawinput_device_info)(rawinputdevice->hDevice, RIDI_DEVICENAME, tname.get(), &name_length) == -1)
+ std::unique_ptr<WCHAR []> tname = std::make_unique<WCHAR []>(name_length + 1);
+ if (name_length > 1 && GetRawInputDeviceInfoW(rawinputdevice.hDevice, RIDI_DEVICENAME, tname.get(), &name_length) == UINT(-1))
return nullptr;
// if this is an RDP name, skip it
- if (_tcsstr(tname.get(), TEXT("Root#RDP_")) != nullptr)
+ if (wcsstr(tname.get(), L"Root#RDP_") != nullptr)
return nullptr;
- // improve the name and then allocate a device
- std::wstring name = rawinput_device_improve_name(tname.get());
-
- // convert name to utf8
- std::string utf8_name = osd::text::from_wstring(name.c_str());
-
- // set device id to raw input name
- std::string utf8_id = osd::text::from_wstring(tname.get());
+ // improve the name
+ std::string utf8_name = text::from_wstring(rawinput_device_improve_name(tname.get()));
- devinfo = devicelist()->create_device<TDevice>(machine, utf8_name.c_str(), utf8_id.c_str(), *this);
+ // set device ID to raw input name
+ std::string utf8_id = text::from_wstring(tname.get());
- // Add the handle
- devinfo->set_handle(rawinputdevice->hDevice);
+ tname.reset();
- return devinfo;
+ // allocate a device
+ return &create_device<TDevice>(
+ deviceclass,
+ std::move(utf8_name),
+ std::move(utf8_id),
+ rawinputdevice.hDevice);
}
- bool handle_input_event(input_event eventid, void* eventdata) override
+ virtual bool handle_input_event(input_event eventid, void const *eventdata) override
{
- // Only handle raw input data
- if (!input_enabled() || eventid != INPUT_EVENT_RAWINPUT)
- return false;
-
- HRAWINPUT rawinputdevice = *static_cast<HRAWINPUT*>(eventdata);
-
- BYTE small_buffer[4096];
- std::unique_ptr<BYTE[]> larger_buffer;
- LPBYTE data = small_buffer;
- UINT size;
-
- // ignore if not enabled
- if (!input_enabled())
- return false;
+ switch (eventid)
+ {
+ // handle raw input data
+ case INPUT_EVENT_RAWINPUT:
+ {
+ HRAWINPUT const rawinputdevice = *reinterpret_cast<HRAWINPUT const *>(eventdata);
+
+ union { RAWINPUT r; BYTE b[4096]; } small_buffer;
+ std::unique_ptr<BYTE []> larger_buffer;
+ LPVOID data = &small_buffer;
+ UINT size;
+
+ // determine the size of data buffer we need
+ if (GetRawInputData(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0)
+ return false;
+
+ // if necessary, allocate a temporary buffer and fetch the data
+ if (size > sizeof(small_buffer))
+ {
+ larger_buffer.reset(new (std::align_val_t(alignof(RAWINPUT)), std::nothrow) BYTE [size]);
+ data = larger_buffer.get();
+ if (!data)
+ return false;
+ }
+
+ // fetch the data and process the appropriate message types
+ UINT result = GetRawInputData(rawinputdevice, RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
+ if (UINT(-1) == result)
+ {
+ return false;
+ }
+ else if (result)
+ {
+ std::lock_guard<std::mutex> scope_lock(m_module_lock);
+
+ auto *const input = reinterpret_cast<RAWINPUT const *>(data);
+ if (!input->header.hDevice)
+ return false;
+
+ // find the device in the list and update
+ auto target_device = std::find_if(
+ devicelist().begin(),
+ devicelist().end(),
+ [input] (auto const &device)
+ {
+ return input->header.hDevice == device->device_handle();
+ });
+ if (devicelist().end() == target_device)
+ return false;
+
+ (*target_device)->queue_events(input, 1);
+ return true;
+ }
+ }
+ break;
- // determine the size of databuffer we need
- if ((*get_rawinput_data)(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0)
- return false;
+ case INPUT_EVENT_ARRIVAL:
+ {
+ HRAWINPUT const rawinputdevice = *reinterpret_cast<HRAWINPUT const *>(eventdata);
+
+ // determine the length of the device name, allocate it, and fetch it if not nameless
+ UINT name_length = 0;
+ if (GetRawInputDeviceInfoW(rawinputdevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
+ return false;
+
+ std::unique_ptr<WCHAR []> tname = std::make_unique<WCHAR []>(name_length + 1);
+ if (name_length > 1 && GetRawInputDeviceInfoW(rawinputdevice, RIDI_DEVICENAME, tname.get(), &name_length) == UINT(-1))
+ return false;
+ std::string utf8_id = text::from_wstring(tname.get());
+ tname.reset();
+
+ std::lock_guard<std::mutex> scope_lock(m_module_lock);
+
+ // find the device in the list and update
+ auto target_device = std::find_if(
+ devicelist().begin(),
+ devicelist().end(),
+ [&utf8_id] (auto const &device)
+ {
+ return device->reconnect_candidate(utf8_id);
+ });
+ if (devicelist().end() == target_device)
+ return false;
+
+ (*target_device)->attach_device(rawinputdevice);
+ return true;
+ }
+ break;
- // if necessary, allocate a temporary buffer and fetch the data
- if (size > sizeof(small_buffer))
- {
- larger_buffer = std::make_unique<BYTE[]>(size);
- data = larger_buffer.get();
- if (data == nullptr)
- return false;
- }
+ case INPUT_EVENT_REMOVAL:
+ {
+ HRAWINPUT const rawinputdevice = *reinterpret_cast<HRAWINPUT const *>(eventdata);
- // fetch the data and process the appropriate message types
- bool result = (*get_rawinput_data)(static_cast<HRAWINPUT>(rawinputdevice), RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
- if (result)
- {
- std::lock_guard<std::mutex> scope_lock(m_module_lock);
+ std::lock_guard<std::mutex> scope_lock(m_module_lock);
- RAWINPUT *input = reinterpret_cast<RAWINPUT*>(data);
+ // find the device in the list and update
+ auto target_device = std::find_if(
+ devicelist().begin(),
+ devicelist().end(),
+ [rawinputdevice] (auto const &device)
+ {
+ return rawinputdevice == device->device_handle();
+ });
- // find the device in the list and update
- auto target_device = std::find_if(devicelist()->begin(), devicelist()->end(), [input](auto &device)
- {
- auto devinfo = dynamic_cast<rawinput_device*>(device.get());
- return devinfo != nullptr && input->header.hDevice == devinfo->device_handle();
- });
+ if (devicelist().end() == target_device)
+ return false;
- if (target_device != devicelist()->end())
- {
- static_cast<rawinput_device*>((*target_device).get())->queue_events(input, 1);
+ (*target_device)->reset();
+ (*target_device)->detach_device();
return true;
}
+ break;
+
+ default:
+ break;
}
+ // must have been unhandled
return false;
}
};
+
//============================================================
-// keyboard_input_rawinput - rawinput keyboard module
+// keyboard_input_rawinput - RawInput keyboard module
//============================================================
class keyboard_input_rawinput : public rawinput_module
{
public:
- keyboard_input_rawinput()
- : rawinput_module(OSD_KEYBOARDINPUT_PROVIDER, "rawinput")
+ keyboard_input_rawinput() : rawinput_module(OSD_KEYBOARDINPUT_PROVIDER, "rawinput")
{
}
protected:
- USHORT usagepage() override { return 1; }
- USHORT usage() override { return 6; }
- void add_rawinput_device(running_machine& machine, RAWINPUTDEVICELIST * device) override
+ virtual USHORT usagepage() override { return 1; }
+ virtual USHORT usage() override { return 6; }
+
+ virtual void add_rawinput_device(RAWINPUTDEVICELIST const &device) override
{
// make sure this is a keyboard
- if (device->dwType != RIM_TYPEKEYBOARD)
+ if (device.dwType != RIM_TYPEKEYBOARD)
return;
// allocate and link in a new device
- rawinput_keyboard_device *devinfo = create_rawinput_device<rawinput_keyboard_device>(machine, device);
- if (devinfo == nullptr)
- return;
-
- keyboard_trans_table &table = keyboard_trans_table::instance();
-
- // populate it
- for (int keynum = 0; keynum < MAX_KEYS; keynum++)
- {
- input_item_id itemid = table.map_di_scancode_to_itemid(keynum);
- TCHAR keyname[100];
-
- // generate the name
- if (GetKeyNameText(((keynum & 0x7f) << 16) | ((keynum & 0x80) << 17), keyname, ARRAY_LENGTH(keyname)) == 0)
- _sntprintf(keyname, ARRAY_LENGTH(keyname), TEXT("Scan%03d"), keynum);
- std::string name = osd::text::from_tstring(keyname);
-
- // add the item to the device
- devinfo->device()->add_item(name.c_str(), itemid, generic_button_get_state<std::uint8_t>, &devinfo->keyboard.state[keynum]);
- }
+ create_rawinput_device<rawinput_keyboard_device>(DEVICE_CLASS_KEYBOARD, device);
}
};
+
//============================================================
-// mouse_input_rawinput - rawinput mouse module
+// mouse_input_rawinput - RawInput mouse module
//============================================================
class mouse_input_rawinput : public rawinput_module
{
public:
- mouse_input_rawinput()
- : rawinput_module(OSD_MOUSEINPUT_PROVIDER, "rawinput")
+ mouse_input_rawinput() : rawinput_module(OSD_MOUSEINPUT_PROVIDER, "rawinput")
{
}
protected:
- USHORT usagepage() override { return 1; }
- USHORT usage() override { return 2; }
- void add_rawinput_device(running_machine& machine, RAWINPUTDEVICELIST * device) override
+ virtual USHORT usagepage() override { return 1; }
+ virtual USHORT usage() override { return 2; }
+
+ virtual void add_rawinput_device(RAWINPUTDEVICELIST const &device) override
{
// make sure this is a mouse
- if (device->dwType != RIM_TYPEMOUSE)
+ if (device.dwType != RIM_TYPEMOUSE)
return;
// allocate and link in a new device
- rawinput_mouse_device *devinfo = create_rawinput_device<rawinput_mouse_device>(machine, device);
- if (devinfo == nullptr)
- return;
-
- // populate the axes
- for (int axisnum = 0; axisnum < 3; axisnum++)
- {
- devinfo->device()->add_item(
- default_axis_name[axisnum],
- static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum),
- generic_axis_get_state<LONG>,
- &devinfo->mouse.lX + axisnum);
- }
-
- // populate the buttons
- for (int butnum = 0; butnum < 5; butnum++)
- {
- devinfo->device()->add_item(
- default_button_name(butnum),
- static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum),
- generic_button_get_state<BYTE>,
- &devinfo->mouse.rgbButtons[butnum]);
- }
+ create_rawinput_device<rawinput_mouse_device>(DEVICE_CLASS_MOUSE, device);
}
};
+
//============================================================
-// lightgun_input_rawinput - rawinput lightgun module
+// lightgun_input_rawinput - RawInput lightgun module
//============================================================
class lightgun_input_rawinput : public rawinput_module
{
public:
- lightgun_input_rawinput()
- : rawinput_module(OSD_LIGHTGUNINPUT_PROVIDER, "rawinput")
+ lightgun_input_rawinput() : rawinput_module(OSD_LIGHTGUNINPUT_PROVIDER, "rawinput")
{
}
protected:
- USHORT usagepage() override { return 1; }
- USHORT usage() override { return 2; }
- void add_rawinput_device(running_machine& machine, RAWINPUTDEVICELIST * device) override
- {
+ virtual USHORT usagepage() override { return 1; }
+ virtual USHORT usage() override { return 2; }
+ virtual void add_rawinput_device(RAWINPUTDEVICELIST const &device) override
+ {
// make sure this is a mouse
- if (device->dwType != RIM_TYPEMOUSE)
+ if (device.dwType != RIM_TYPEMOUSE)
return;
// allocate and link in a new device
- rawinput_lightgun_device *devinfo = create_rawinput_device<rawinput_lightgun_device>(machine, device);
- if (devinfo == nullptr)
- return;
-
- // populate the axes
- for (int axisnum = 0; axisnum < 3; axisnum++)
- {
- devinfo->device()->add_item(
- default_axis_name[axisnum],
- static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum),
- generic_axis_get_state<LONG>,
- &devinfo->lightgun.lX + axisnum);
- }
-
- // populate the buttons
- for (int butnum = 0; butnum < 5; butnum++)
- {
- devinfo->device()->add_item(
- default_button_name(butnum),
- static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum),
- generic_button_get_state<BYTE>,
- &devinfo->lightgun.rgbButtons[butnum]);
- }
+ create_rawinput_device<rawinput_lightgun_device>(DEVICE_CLASS_LIGHTGUN, device);
}
};
-#else
+} // anonymous namespace
+
+} // namespace osd
+
+#else // defined(OSD_WINDOWS)
+
+#include "input_module.h"
+
+namespace osd {
+
+namespace {
+
MODULE_NOT_SUPPORTED(keyboard_input_rawinput, OSD_KEYBOARDINPUT_PROVIDER, "rawinput")
MODULE_NOT_SUPPORTED(mouse_input_rawinput, OSD_MOUSEINPUT_PROVIDER, "rawinput")
MODULE_NOT_SUPPORTED(lightgun_input_rawinput, OSD_LIGHTGUNINPUT_PROVIDER, "rawinput")
-#endif
-MODULE_DEFINITION(KEYBOARDINPUT_RAWINPUT, keyboard_input_rawinput)
-MODULE_DEFINITION(MOUSEINPUT_RAWINPUT, mouse_input_rawinput)
-MODULE_DEFINITION(LIGHTGUNINPUT_RAWINPUT, lightgun_input_rawinput)
+} // anonymous namespace
+
+} // namespace osd
+
+#endif // defined(OSD_WINDOWS)
+
+MODULE_DEFINITION(KEYBOARDINPUT_RAWINPUT, osd::keyboard_input_rawinput)
+MODULE_DEFINITION(MOUSEINPUT_RAWINPUT, osd::mouse_input_rawinput)
+MODULE_DEFINITION(LIGHTGUNINPUT_RAWINPUT, osd::lightgun_input_rawinput)