summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/input/input_win32.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/input/input_win32.cpp')
-rw-r--r--src/osd/modules/input/input_win32.cpp255
1 files changed, 177 insertions, 78 deletions
diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp
index 6919c8d5c42..921c902ad31 100644
--- a/src/osd/modules/input/input_win32.cpp
+++ b/src/osd/modules/input/input_win32.cpp
@@ -46,6 +46,7 @@ public:
virtual void reset() override
{
+ event_based_device::reset();
memset(&m_keyboard, 0, sizeof(m_keyboard));
}
@@ -59,6 +60,8 @@ public:
TCHAR 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
if (GetKeyNameText(((keynum & 0x7f) << 16) | ((keynum & 0x80) << 17), keyname, std::size(keyname)) == 0)
_sntprintf(keyname, std::size(keyname), TEXT("Scan%03d"), keynum);
std::string name = text::from_tstring(keyname);
@@ -103,14 +106,14 @@ public:
create_device<win32_keyboard_device>(DEVICE_CLASS_KEYBOARD, "Win32 Keyboard 1", "Win32 Keyboard 1");
}
- virtual bool handle_input_event(input_event eventid, void *eventdata) override
+ virtual bool handle_input_event(input_event eventid, void const *eventdata) override
{
switch (eventid)
{
case INPUT_EVENT_KEYDOWN:
case INPUT_EVENT_KEYUP:
devicelist().for_each_device(
- [args = static_cast<KeyPressEventArgs const *>(eventdata)] (auto &device)
+ [args = reinterpret_cast<KeyPressEventArgs const *>(eventdata)] (auto &device)
{
device.queue_events(args, 1);
});
@@ -127,13 +130,15 @@ public:
// win32_mouse_device
//============================================================
-class win32_mouse_device : public event_based_device<MouseButtonEventArgs>
+class win32_mouse_device : public event_based_device<MouseUpdateEventArgs>
{
public:
win32_mouse_device(std::string &&name, std::string &&id, input_module &module) :
event_based_device(std::move(name), std::move(id), module),
m_mouse({0}),
- m_win32_mouse({{0}})
+ m_win32_mouse({{0}}),
+ m_vscroll(0),
+ m_hscroll(0)
{
}
@@ -144,7 +149,7 @@ public:
if (!relative_reset)
return;
- CURSORINFO cursor_info = {0};
+ CURSORINFO cursor_info = { 0 };
cursor_info.cbSize = sizeof(CURSORINFO);
GetCursorInfo(&cursor_info);
@@ -167,23 +172,42 @@ public:
SetCursorPos(m_win32_mouse.last_point.x, m_win32_mouse.last_point.y);
}
+
+ // update scroll axes
+ m_mouse.lV = std::exchange(m_vscroll, 0) * input_device::RELATIVE_PER_PIXEL;
+ m_mouse.lH = std::exchange(m_hscroll, 0) * input_device::RELATIVE_PER_PIXEL;
}
virtual void configure(input_device &device) override
{
// 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_mouse.lX + axisnum);
- }
+ 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 < 2; butnum++)
+ for (int butnum = 0; butnum < 5; butnum++)
{
device.add_item(
default_button_name(butnum),
@@ -196,15 +220,28 @@ public:
virtual void reset() override
{
+ event_based_device::reset();
memset(&m_mouse, 0, sizeof(m_mouse));
memset(&m_win32_mouse, 0, sizeof(m_win32_mouse));
+ m_vscroll = m_hscroll = 0;
}
protected:
- virtual void process_event(MouseButtonEventArgs const &args) override
+ virtual void process_event(MouseUpdateEventArgs const &args) override
{
// set the button state
- m_mouse.rgbButtons[args.button] = args.keydown ? 0x80 : 0x00;
+ assert(!(args.pressed & args.released));
+ for (unsigned i = 0; 5 > i; ++i)
+ {
+ if (BIT(args.pressed, i))
+ m_mouse.rgbButtons[i] = 0x80;
+ else if (BIT(args.released, i))
+ m_mouse.rgbButtons[i] = 0x00;
+ }
+
+ // accumulate scroll delta
+ m_vscroll += args.vdelta;
+ m_hscroll += args.hdelta;
}
private:
@@ -215,6 +252,7 @@ private:
mouse_state m_mouse;
win32_mouse_state m_win32_mouse;
+ long m_vscroll, m_hscroll;
};
@@ -240,16 +278,20 @@ public:
create_device<win32_mouse_device>(DEVICE_CLASS_MOUSE, "Win32 Mouse 1", "Win32 Mouse 1");
}
- virtual bool handle_input_event(input_event eventid, void *eventdata) override
+ virtual bool handle_input_event(input_event eventid, void const *eventdata) override
{
- if (!manager().class_enabled(DEVICE_CLASS_MOUSE) || eventid != INPUT_EVENT_MOUSE_BUTTON)
- return false;
-
- auto const *const args = static_cast<MouseButtonEventArgs *>(eventdata);
- devicelist().for_each_device(
- [args] (auto &device) { device.queue_events(args, 1); });
+ if (manager().class_enabled(DEVICE_CLASS_MOUSE))
+ {
+ if ((eventid == INPUT_EVENT_MOUSE_BUTTON) || (eventid == INPUT_EVENT_MOUSE_WHEEL))
+ {
+ auto const *const args = reinterpret_cast<MouseUpdateEventArgs const *>(eventdata);
+ devicelist().for_each_device(
+ [args] (auto &device) { device.queue_events(args, 1); });
+ return true;
+ }
+ }
- return true;
+ return false;
}
};
@@ -258,15 +300,26 @@ public:
// win32_lightgun_device_base
//============================================================
-class win32_lightgun_device_base : public event_based_device<MouseButtonEventArgs>
+class win32_lightgun_device_base : public event_based_device<MouseUpdateEventArgs>
{
public:
virtual void reset() override
{
+ event_based_device::reset();
memset(&m_mouse, 0, sizeof(m_mouse));
}
- virtual void configure(input_device &device) override
+protected:
+ win32_lightgun_device_base(
+ std::string &&name,
+ std::string &&id,
+ input_module &module) :
+ event_based_device(std::move(name), std::move(id), module),
+ m_mouse({ 0 })
+ {
+ }
+
+ void do_configure(input_device &device, unsigned buttons)
{
// populate the axes
for (int axisnum = 0; axisnum < 2; axisnum++)
@@ -280,7 +333,7 @@ public:
}
// populate the buttons
- for (int butnum = 0; butnum < 2; butnum++)
+ for (int butnum = 0; butnum < buttons; butnum++)
{
device.add_item(
default_button_name(butnum),
@@ -291,16 +344,6 @@ public:
}
}
-protected:
- win32_lightgun_device_base(
- std::string &&name,
- std::string &&id,
- input_module &module) :
- event_based_device(std::move(name), std::move(id), module),
- m_mouse({ 0 })
- {
- }
-
mouse_state m_mouse;
};
@@ -317,7 +360,9 @@ public:
std::string &&name,
std::string &&id,
input_module &module) :
- win32_lightgun_device_base(std::move(name), std::move(id), module)
+ win32_lightgun_device_base(std::move(name), std::move(id), module),
+ m_vscroll(0),
+ m_hscroll(0)
{
}
@@ -346,14 +391,60 @@ public:
// update the X/Y positions
m_mouse.lX = xpos;
m_mouse.lY = ypos;
+
+ // update the scroll axes if appropriate
+ if (relative_reset)
+ {
+ m_mouse.lV = std::exchange(m_vscroll, 0) * input_device::RELATIVE_PER_PIXEL;
+ m_mouse.lH = std::exchange(m_hscroll, 0) * input_device::RELATIVE_PER_PIXEL;
+ }
+ }
+
+ virtual void configure(input_device &device) override
+ {
+ do_configure(device, 5);
+
+ // add scroll axes
+ device.add_item(
+ "Scroll V",
+ std::string_view(),
+ ITEM_ID_ADD_RELATIVE1,
+ generic_axis_get_state<LONG>,
+ &m_mouse.lV);
+ device.add_item(
+ "Scroll H",
+ std::string_view(),
+ ITEM_ID_ADD_RELATIVE2,
+ generic_axis_get_state<LONG>,
+ &m_mouse.lH);
+ }
+
+ virtual void reset() override
+ {
+ win32_lightgun_device_base::reset();
+ m_vscroll = m_hscroll = 0;
}
protected:
- virtual void process_event(MouseButtonEventArgs const &args) override
+ virtual void process_event(MouseUpdateEventArgs const &args) override
{
// In non-shared axis mode, just update the button state
- m_mouse.rgbButtons[args.button] = args.keydown ? 0x80 : 0x00;
+ assert(!(args.pressed & args.released));
+ for (unsigned i = 0; 5 > i; ++i)
+ {
+ if (BIT(args.pressed, i))
+ m_mouse.rgbButtons[i] = 0x80;
+ else if (BIT(args.released, i))
+ m_mouse.rgbButtons[i] = 0x00;
+ }
+
+ // accumulate scroll delta
+ m_vscroll += args.vdelta;
+ m_hscroll += args.hdelta;
}
+
+private:
+ long m_vscroll, m_hscroll;
};
@@ -374,38 +465,42 @@ public:
{
}
-protected:
- virtual void process_event(MouseButtonEventArgs const &args) override
+ virtual void configure(input_device &device) override
{
- int const button = args.button;
-
- if (button > 3)
- return; // We only handle the first four buttons in shared axis mode
- else if (button >= 2 && m_gun_index == 0)
- return; // First gun doesn't handle buttons 2 and 3
- else if (button < 2 && m_gun_index == 1)
- return; // Second gun doesn't handle buttons 0 and 1
-
- // Adjust the button if we're the second lightgun
- int const logical_button = (m_gun_index == 1) ? (button - 2) : button;
+ do_configure(device, 2);
+ }
- // set the button state
- m_mouse.rgbButtons[logical_button] = args.keydown ? 0x80 : 0x00;
- if (args.keydown)
+protected:
+ virtual void process_event(MouseUpdateEventArgs const &args) override
+ {
+ // We only handle the first four buttons in shared axis mode
+ assert(!(args.pressed & args.released));
+ for (unsigned i = 0; 2 > i; ++i)
{
- // get the position relative to the window
- HWND const hwnd = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
- RECT client_rect;
- GetClientRect(hwnd, &client_rect);
-
- POINT mousepos;
- mousepos.x = args.xpos;
- mousepos.y = args.ypos;
- ScreenToClient(hwnd, &mousepos);
-
- // convert to absolute coordinates
- m_mouse.lX = normalize_absolute_axis(mousepos.x, client_rect.left, client_rect.right);
- m_mouse.lY = normalize_absolute_axis(mousepos.y, client_rect.top, client_rect.bottom);
+ // Adjust the button if we're the second lightgun
+ unsigned const bit = i + ((1 == m_gun_index) ? 2 : 0);
+ if (BIT(args.pressed, bit))
+ {
+ m_mouse.rgbButtons[i] = 0x80;
+
+ // get the position relative to the window
+ HWND const hwnd = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
+ RECT client_rect;
+ GetClientRect(hwnd, &client_rect);
+
+ POINT mousepos;
+ mousepos.x = args.xpos;
+ mousepos.y = args.ypos;
+ ScreenToClient(hwnd, &mousepos);
+
+ // convert to absolute coordinates
+ m_mouse.lX = normalize_absolute_axis(mousepos.x, client_rect.left, client_rect.right);
+ m_mouse.lY = normalize_absolute_axis(mousepos.y, client_rect.top, client_rect.bottom);
+ }
+ else if (BIT(args.released, bit))
+ {
+ m_mouse.rgbButtons[i] = 0x00;
+ }
}
}
@@ -445,16 +540,20 @@ public:
}
}
- virtual bool handle_input_event(input_event eventid, void *eventdata) override
+ virtual bool handle_input_event(input_event eventid, void const *eventdata) override
{
- if (!manager().class_enabled(DEVICE_CLASS_LIGHTGUN) || eventid != INPUT_EVENT_MOUSE_BUTTON)
- return false;
-
- auto const *const args = static_cast<MouseButtonEventArgs *>(eventdata);
- devicelist().for_each_device(
- [args] (auto &device) { device.queue_events(args, 1); });
+ if (manager().class_enabled(DEVICE_CLASS_LIGHTGUN))
+ {
+ if ((eventid == INPUT_EVENT_MOUSE_BUTTON) || (eventid == INPUT_EVENT_MOUSE_WHEEL))
+ {
+ auto const *const args = reinterpret_cast<MouseUpdateEventArgs const *>(eventdata);
+ devicelist().for_each_device(
+ [args] (auto &device) { device.queue_events(args, 1); });
+ return true;
+ }
+ }
- return true;
+ return false;
}
};