input/input_sdl.cpp: Added an SDL lightgun provider.

This does essentially the same thing as the Win32 lightgun provider,
mapping the absolute pointer position over the window to gun axes.

Also added a bunch of const in the windows input handling code.

docs: Bumped version, as features that are not in a releaesd version of
MAME are now documented.
This commit is contained in:
Vas Crabb 2024-04-26 06:26:22 +10:00
parent 3b618bd7f0
commit f91b896cda
14 changed files with 428 additions and 128 deletions

View File

@ -775,24 +775,24 @@ OSD-related Options
* - **Microsoft Windows**
- win
- dwrite
- none
- auto
-
- sdl [#UIFPSDLWindows]_.
- sdl [#UIFPSDLWindows]_
- none
* - **macOS**
-
-
- none
- auto
- osx
- sdl
- none
* - **Linux**
-
-
- none
- auto
-
- sdl
- none
.. rubric:: Footnotes
@ -816,26 +816,19 @@ Example:
:stub-columns: 0
* - **Microsoft Windows**
- auto [#KBIPAutoWindows]_.
- auto [#KBIPAutoWindows]_
- rawinput
- dinput
- win32
- sdl [#KBIPSDLWindows]_
- none
- sdl [#KBIPSDLWindows]_.
* - **SDL (macOS and Linux)**
- auto [#KBIPAutoSDL]_.
- auto [#KBIPAutoSDL]_
-
-
-
- none
- sdl
* - **Linux**
- auto [#KBIPAutoSDL]_.
-
-
-
- none
- sdl
.. rubric:: Footnotes
@ -868,26 +861,19 @@ Example:
:stub-columns: 0
* - **Microsoft Windows**
- auto [#MIPAutoWindows]_.
- auto [#MIPAutoWindows]_
- rawinput
- dinput
- win32
- sdl [#MIPSDLWindows]_
- none
- sdl [#MIPSDLWindows]_.
* - **SDL (macOS and Linux)**
- auto [#MIPAutoSDL]_.
- auto [#MIPAutoSDL]_
-
-
-
- none
- sdl
* - **Linux**
- auto [#MIPAutoSDL]_.
-
-
-
- none
- sdl
.. rubric:: Footnotes
@ -916,36 +902,37 @@ Example:
:stub-columns: 0
* - **Microsoft Windows**
- auto [#LGIPAutoWindows]_.
- auto [#LGIPAutoWindows]_
- rawinput
- win32
- sdl [#LGIPSDLWindows]_
-
- none
-
-
* - **macOS**
- auto [#LGIPAutoSDL]_.
- auto [#LGIPAutoSDL]_
-
-
- sdl
-
- none
-
-
* - **Linux**
- auto [#LGIPAutoLinux]_.
- auto [#LGIPAutoSDL]_
-
-
- none
-
- sdl
- x11
- none
.. rubric:: Footnotes
.. [#LGIPAutoWindows] On Windows, auto will try ``rawinput`` with fallback to
``win32``, or ``none`` if it doesn't find any.
.. [#LGIPAutoSDL] On non-Linux SDL, ``auto`` will default to ``none``.
.. [#LGIPSDLWindows] SDL support on Windows requires that you compile MAME with
the support in. By default SDL is not included in Windows
builds of MAME.
.. [#LGIPAutoLinux] On SDL/Linux, ``auto`` will default to ``x11``, or ``none``
if it doesn't find any.
.. [#LGIPAutoSDL] On SDL, ``auto`` will default to ``sdl``.
Example:
.. code-block:: bash
@ -964,15 +951,15 @@ Example:
:stub-columns: 0
* - **Microsoft Windows**
- auto [#JIPAutoWindows]_.
- auto [#JIPAutoWindows]_
- winhybrid
- dinput
- xinput
- sdlgame
- sdljoy
- sdlgame [#JIPSDLWindows]_
- sdljoy [#JIPSDLWindows]_
- none
* - **SDL**
- auto [#JIPAutoSDL]_.
- auto [#JIPAutoSDL]_
-
-
-
@ -984,6 +971,10 @@ Example:
.. [#JIPAutoWindows] On Windows native, auto will default to ``winhybrid``.
.. [#JIPSDLWindows] SDL support on Windows requires that you compile MAME with
the support in. By default SDL is not included in Windows
builds of MAME.
.. [#JIPAutoSDL] On SDL, auto will default to ``sdlgame``.
winhybrid

View File

@ -423,10 +423,12 @@ SDL Keyboard Mapping
| :ref:`keymap_file <mame-scommandline-keymapfile>`
SDL Joystick Mapping
SDL Input Options
~~~~~~~~~~~~~~~~~~~~
| :ref:`sixaxis <mame-scommandline-sixaxis>`
| :ref:`[no]enable_touch <mame-scommandline-enabletouch>`
| :ref:`[no]sixaxis <mame-scommandline-sixaxis>`
| :ref:`[no]dual_lightgun <mame-scommandline-duallightgun>`
SDL Lightgun Mapping

View File

@ -80,6 +80,23 @@ SDL Input Options
undesirable behaviour with other controllers. Only affects the ``sdljoy``
joystick provider. Default is OFF (**-nosixaxis**)
.. _mame-scommandline-duallightgun:
**-[no]dual_lightgun** / **-[no]dual**
Controls whether or not MAME attempts to track two lightguns that appear as
a single mouse. This option requires the :ref:`lightgun option
<mame-commandline-nolightgun>` to be on and the :ref:`lightgunprovider
option <mame-commandline-lightgunprovider>` to be set to *sdl*.
This option supports dual lightgun setups that work by setting the mouse
pointer location at the moment a lightgun trigger is activated. The primary
and secondary triggers on the first lightgun correspond to the first and
second mouse buttons, and the primary and secondary triggers on the second
lightgun correspond to the third and fourth mouse buttons.
The default is OFF (**-nodual_lightgun**).
SDL Lightgun Mapping
--------------------

View File

@ -63,9 +63,9 @@ copyright = u'1997-2024, MAMEdev and contributors'
# built documents.
#
# The short X.Y version.
version = '0.265'
version = '0.266'
# The full version, including alpha/beta/rc tags.
release = '0.265'
release = '0.266'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -749,14 +749,14 @@ protected:
rawinputdevice.hDevice);
}
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)
{
// handle raw input data
case INPUT_EVENT_RAWINPUT:
{
HRAWINPUT const rawinputdevice = *static_cast<HRAWINPUT *>(eventdata);
HRAWINPUT const rawinputdevice = *reinterpret_cast<HRAWINPUT const *>(eventdata);
union { RAWINPUT r; BYTE b[4096]; } small_buffer;
std::unique_ptr<BYTE []> larger_buffer;
@ -786,7 +786,7 @@ protected:
{
std::lock_guard<std::mutex> scope_lock(m_module_lock);
auto *input = reinterpret_cast<RAWINPUT *>(data);
auto *const input = reinterpret_cast<RAWINPUT const *>(data);
if (!input->header.hDevice)
return false;
@ -809,7 +809,7 @@ protected:
case INPUT_EVENT_ARRIVAL:
{
HRAWINPUT const rawinputdevice = *static_cast<HRAWINPUT *>(eventdata);
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;
@ -842,7 +842,7 @@ protected:
case INPUT_EVENT_REMOVAL:
{
HRAWINPUT const rawinputdevice = *static_cast<HRAWINPUT *>(eventdata);
HRAWINPUT const rawinputdevice = *reinterpret_cast<HRAWINPUT const *>(eventdata);
std::lock_guard<std::mutex> scope_lock(m_module_lock);

View File

@ -642,29 +642,18 @@ private:
//============================================================
// sdl_mouse_device
// sdl_mouse_device_base
//============================================================
class sdl_mouse_device : public sdl_device
class sdl_mouse_device_base : public sdl_device
{
public:
sdl_mouse_device(std::string &&name, std::string &&id, input_module &module) :
sdl_device(std::move(name), std::move(id), module),
m_mouse({0}),
m_x(0),
m_y(0),
m_v(0),
m_h(0)
{
}
virtual void poll(bool relative_reset) override
{
sdl_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);
}
@ -673,12 +662,28 @@ public:
virtual void reset() override
{
memset(&m_mouse, 0, sizeof(m_mouse));
m_x = m_y = m_v = m_h = 0;
m_v = m_h = 0;
}
virtual void configure(input_device &device) override
protected:
// state information for a mouse
struct mouse_state
{
// add the axes
s32 lX, lY, lV, lH;
s32 buttons[MAX_BUTTONS];
};
sdl_mouse_device_base(std::string &&name, std::string &&id, input_module &module) :
sdl_device(std::move(name), std::move(id), module),
m_mouse({0}),
m_v(0),
m_h(0)
{
}
void add_common_items(input_device &device, unsigned buttons)
{
// add horizontal and vertical axes - relative for a mouse or absolute for a gun
device.add_item(
"X",
std::string_view(),
@ -691,6 +696,62 @@ public:
ITEM_ID_YAXIS,
generic_axis_get_state<s32>,
&m_mouse.lY);
// add buttons
for (int button = 0; button < buttons; button++)
{
input_item_id itemid = (input_item_id)(ITEM_ID_BUTTON1 + button);
int const offset = button ^ (((1 == button) || (2 == button)) ? 3 : 0);
device.add_item(
default_button_name(button),
std::string_view(),
itemid,
generic_button_get_state<s32>,
&m_mouse.buttons[offset]);
}
}
mouse_state m_mouse;
s32 m_v, m_h;
};
//============================================================
// sdl_mouse_device
//============================================================
class sdl_mouse_device : public sdl_mouse_device_base
{
public:
sdl_mouse_device(std::string &&name, std::string &&id, input_module &module) :
sdl_mouse_device_base(std::move(name), std::move(id), module),
m_x(0),
m_y(0)
{
}
virtual void poll(bool relative_reset) override
{
sdl_mouse_device_base::poll(relative_reset);
if (relative_reset)
{
m_mouse.lX = std::exchange(m_x, 0);
m_mouse.lY = std::exchange(m_y, 0);
}
}
virtual void reset() override
{
sdl_mouse_device_base::reset();
m_x = m_y = 0;
}
virtual void configure(input_device &device) override
{
add_common_items(device, 5);
// add scroll axes
device.add_item(
"Scroll V",
std::string_view(),
@ -703,19 +764,6 @@ public:
ITEM_ID_RZAXIS,
generic_axis_get_state<s32>,
&m_mouse.lH);
// add the buttons
for (int button = 0; button < 4; button++)
{
input_item_id itemid = (input_item_id)(ITEM_ID_BUTTON1 + button);
int const offset = button ^ (((1 == button) || (2 == button)) ? 3 : 0);
device.add_item(
default_button_name(button),
std::string_view(),
itemid,
generic_button_get_state<s32>,
&m_mouse.buttons[offset]);
}
}
virtual void process_event(SDL_Event const &event) override
@ -749,15 +797,173 @@ public:
}
private:
// state information for a mouse
struct mouse_state
{
s32 lX, lY, lV, lH;
s32 buttons[MAX_BUTTONS];
};
s32 m_x, m_y;
};
mouse_state m_mouse;
s32 m_x, m_y, m_v, m_h;
//============================================================
// sdl_lightgun_device
//============================================================
class sdl_lightgun_device : public sdl_mouse_device_base
{
public:
sdl_lightgun_device(std::string &&name, std::string &&id, input_module &module) :
sdl_mouse_device_base(std::move(name), std::move(id), module),
m_x(0),
m_y(0),
m_window(0)
{
}
virtual void poll(bool relative_reset) override
{
sdl_mouse_device_base::poll(relative_reset);
SDL_Window *const win(m_window ? SDL_GetWindowFromID(m_window) : nullptr);
if (win)
{
int w, h;
SDL_GetWindowSize(win, &w, &h);
m_mouse.lX = normalize_absolute_axis(m_x, 0, w - 1);
m_mouse.lY = normalize_absolute_axis(m_y, 0, h - 1);
}
else
{
m_mouse.lX = 0;
m_mouse.lY = 0;
}
}
virtual void reset() override
{
sdl_mouse_device_base::reset();
m_x = m_y = 0;
m_window = 0;
}
virtual void configure(input_device &device) override
{
add_common_items(device, 5);
// add scroll axes
device.add_item(
"Scroll V",
std::string_view(),
ITEM_ID_ADD_RELATIVE1,
generic_axis_get_state<s32>,
&m_mouse.lV);
device.add_item(
"Scroll H",
std::string_view(),
ITEM_ID_ADD_RELATIVE2,
generic_axis_get_state<s32>,
&m_mouse.lH);
}
virtual void process_event(SDL_Event const &event) override
{
switch (event.type)
{
case SDL_MOUSEMOTION:
m_x = event.motion.x;
m_y = event.motion.y;
m_window = event.motion.windowID;
break;
case SDL_MOUSEBUTTONDOWN:
m_mouse.buttons[event.button.button - 1] = 0x80;
m_x = event.button.x;
m_y = event.button.y;
m_window = event.button.windowID;
break;
case SDL_MOUSEBUTTONUP:
m_mouse.buttons[event.button.button - 1] = 0;
m_x = event.button.x;
m_y = event.button.y;
m_window = event.button.windowID;
break;
case SDL_MOUSEWHEEL:
// adjust SDL 1-per-click to match Win32 120-per-click
#if SDL_VERSION_ATLEAST(2, 0, 18)
m_v += std::lround(event.wheel.preciseY * 120 * input_device::RELATIVE_PER_PIXEL);
m_h += std::lround(event.wheel.preciseX * 120 * input_device::RELATIVE_PER_PIXEL);
#else
m_v += event.wheel.y * 120 * input_device::RELATIVE_PER_PIXEL;
m_h += event.wheel.x * 120 * input_device::RELATIVE_PER_PIXEL;
#endif
break;
case SDL_WINDOWEVENT:
if ((event.window.windowID == m_window) && (SDL_WINDOWEVENT_LEAVE == event.window.event))
m_window = 0;
break;
}
}
private:
s32 m_x, m_y;
u32 m_window;
};
//============================================================
// sdl_dual_lightgun_device
//============================================================
class sdl_dual_lightgun_device : public sdl_mouse_device_base
{
public:
sdl_dual_lightgun_device(std::string &&name, std::string &&id, input_module &module, u8 index) :
sdl_mouse_device_base(std::move(name), std::move(id), module),
m_index(index)
{
}
virtual void configure(input_device &device) override
{
add_common_items(device, 2);
}
virtual void process_event(SDL_Event const &event) override
{
switch (event.type)
{
case SDL_MOUSEBUTTONDOWN:
{
SDL_Window *const win(SDL_GetWindowFromID(event.button.windowID));
u8 const button = translate_button(event);
if (win && ((button / 2) == m_index))
{
int w, h;
SDL_GetWindowSize(win, &w, &h);
m_mouse.buttons[(button & 1) << 1] = 0x80;
m_mouse.lX = normalize_absolute_axis(event.button.x, 0, w - 1);
m_mouse.lY = normalize_absolute_axis(event.button.y, 0, h - 1);
}
}
break;
case SDL_MOUSEBUTTONUP:
{
u8 const button = translate_button(event);
if ((button / 2) == m_index)
m_mouse.buttons[(button & 1) << 1] = 0;
}
break;
}
}
private:
static u8 translate_button(SDL_Event const &event)
{
u8 const index(event.button.button - 1);
return index ^ (((1 == index) || (2 == index)) ? 3 : 0);
}
u8 const m_index;
};
@ -1955,7 +2161,7 @@ public:
{
sdl_input_module<sdl_keyboard_device>::input_init(machine);
static int const event_types[] = {
constexpr int event_types[] = {
int(SDL_KEYDOWN),
int(SDL_KEYUP) };
@ -2079,7 +2285,7 @@ public:
{
sdl_input_module::input_init(machine);
static int const event_types[] = {
constexpr int event_types[] = {
int(SDL_MOUSEMOTION),
int(SDL_MOUSEBUTTONDOWN),
int(SDL_MOUSEBUTTONUP),
@ -2101,6 +2307,73 @@ public:
};
//============================================================
// sdl_lightgun_module
//============================================================
class sdl_lightgun_module : public sdl_input_module<sdl_mouse_device_base>
{
public:
sdl_lightgun_module() : sdl_input_module<sdl_mouse_device_base>(OSD_LIGHTGUNINPUT_PROVIDER, "sdl")
{
}
virtual void input_init(running_machine &machine) override
{
auto &sdlopts = dynamic_cast<sdl_options const &>(*options());
sdl_input_module::input_init(machine);
bool const dual(sdlopts.dual_lightgun());
if (!dual)
{
constexpr int event_types[] = {
int(SDL_MOUSEMOTION),
int(SDL_MOUSEBUTTONDOWN),
int(SDL_MOUSEBUTTONUP),
int(SDL_MOUSEWHEEL),
int(SDL_WINDOWEVENT) };
subscribe(osd(), event_types);
}
else
{
constexpr int event_types[] = {
int(SDL_MOUSEBUTTONDOWN),
int(SDL_MOUSEBUTTONUP) };
subscribe(osd(), event_types);
}
osd_printf_verbose("Lightgun: Start initialization\n");
if (!dual)
{
auto &devinfo = create_device<sdl_lightgun_device>(
DEVICE_CLASS_LIGHTGUN,
"System pointer gun 1",
"System pointer gun 1");
osd_printf_verbose("Lightgun: Registered %s\n", devinfo.name());
}
else
{
auto &dev1info = create_device<sdl_dual_lightgun_device>(
DEVICE_CLASS_LIGHTGUN,
"System pointer gun 1",
"System pointer gun 1",
0);
osd_printf_verbose("Lightgun: Registered %s\n", dev1info.name());
auto &dev2info = create_device<sdl_dual_lightgun_device>(
DEVICE_CLASS_LIGHTGUN,
"System pointer gun 2",
"System pointer gun 2",
1);
osd_printf_verbose("Lightgun: Registered %s\n", dev2info.name());
}
osd_printf_verbose("Lightgun: End initialization\n");
}
};
//============================================================
// sdl_joystick_module_base
//============================================================
@ -2284,7 +2557,7 @@ public:
for (int physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++)
create_joystick_device(physical_stick, sixaxis_mode);
static int const event_types[] = {
constexpr int event_types[] = {
int(SDL_JOYAXISMOTION),
int(SDL_JOYBALLMOTION),
int(SDL_JOYHATMOTION),
@ -2405,7 +2678,7 @@ public:
create_game_controller_device(physical_stick, ctrl);
}
static int const joy_event_types[] = {
constexpr int joy_event_types[] = {
int(SDL_JOYAXISMOTION),
int(SDL_JOYBALLMOTION),
int(SDL_JOYHATMOTION),
@ -2413,7 +2686,7 @@ public:
int(SDL_JOYBUTTONUP),
int(SDL_JOYDEVICEADDED),
int(SDL_JOYDEVICEREMOVED) };
static int const event_types[] = {
constexpr int event_types[] = {
int(SDL_JOYAXISMOTION),
int(SDL_JOYBALLMOTION),
int(SDL_JOYHATMOTION),
@ -2571,6 +2844,7 @@ namespace {
MODULE_NOT_SUPPORTED(sdl_keyboard_module, OSD_KEYBOARDINPUT_PROVIDER, "sdl")
MODULE_NOT_SUPPORTED(sdl_mouse_module, OSD_MOUSEINPUT_PROVIDER, "sdl")
MODULE_NOT_SUPPORTED(sdl_lightgun_module, OSD_LIGHTGUNINPUT_PROVIDER, "sdl")
MODULE_NOT_SUPPORTED(sdl_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "sdljoy")
MODULE_NOT_SUPPORTED(sdl_game_controller_module, OSD_JOYSTICKINPUT_PROVIDER, "sdlgame")
@ -2583,5 +2857,6 @@ MODULE_NOT_SUPPORTED(sdl_game_controller_module, OSD_JOYSTICKINPUT_PROVIDER, "sd
MODULE_DEFINITION(KEYBOARDINPUT_SDL, osd::sdl_keyboard_module)
MODULE_DEFINITION(MOUSEINPUT_SDL, osd::sdl_mouse_module)
MODULE_DEFINITION(LIGHTGUNINPUT_SDL, osd::sdl_lightgun_module)
MODULE_DEFINITION(JOYSTICKINPUT_SDLJOY, osd::sdl_joystick_module)
MODULE_DEFINITION(JOYSTICKINPUT_SDLGAME, osd::sdl_game_controller_module)

View File

@ -105,14 +105,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);
});
@ -276,13 +276,13 @@ 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))
{
if ((eventid == INPUT_EVENT_MOUSE_BUTTON) || (eventid == INPUT_EVENT_MOUSE_WHEEL))
{
auto const *const args = reinterpret_cast<MouseUpdateEventArgs *>(eventdata);
auto const *const args = reinterpret_cast<MouseUpdateEventArgs const *>(eventdata);
devicelist().for_each_device(
[args] (auto &device) { device.queue_events(args, 1); });
return true;
@ -537,13 +537,13 @@ 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))
{
if ((eventid == INPUT_EVENT_MOUSE_BUTTON) || (eventid == INPUT_EVENT_MOUSE_WHEEL))
{
auto const *const args = reinterpret_cast<MouseUpdateEventArgs *>(eventdata);
auto const *const args = reinterpret_cast<MouseUpdateEventArgs const *>(eventdata);
devicelist().for_each_device(
[args] (auto &device) { device.queue_events(args, 1); });
return true;

View File

@ -40,7 +40,7 @@ bool windows_osd_interface::should_hide_mouse() const
return true;
}
bool windows_osd_interface::handle_input_event(input_event eventid, void *eventdata) const
bool windows_osd_interface::handle_input_event(input_event eventid, void const *eventdata) const
{
bool handled = false;

View File

@ -31,7 +31,7 @@ protected:
virtual ~wininput_event_handler() = default;
public:
virtual bool handle_input_event(input_event eventid, void *data)
virtual bool handle_input_event(input_event eventid, void const *data)
{
return false;
}

View File

@ -308,6 +308,7 @@ void osd_common_t::register_options()
REGISTER_MODULE(m_mod_man, MOUSEINPUT_WIN32);
REGISTER_MODULE(m_mod_man, MOUSE_NONE);
REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_SDL);
REGISTER_MODULE(m_mod_man, LIGHTGUN_X11);
REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_RAWINPUT);
REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_WIN32);

View File

@ -69,6 +69,7 @@ const options_entry f_sdl_option_entries[] =
{ nullptr, nullptr, core_options::option_type::HEADER, "SDL INPUT OPTIONS" },
{ SDLOPTION_ENABLE_TOUCH, "0", core_options::option_type::BOOLEAN, "enable touch input support" },
{ SDLOPTION_SIXAXIS, "0", core_options::option_type::BOOLEAN, "use special handling for PS3 Sixaxis controllers" },
{ SDLOPTION_DUAL_LIGHTGUN ";dual", "0", core_options::option_type::BOOLEAN, "enable dual lightgun input" },
#if (USE_XINPUT)
// lightgun mapping

View File

@ -28,6 +28,7 @@
#define SDLOPTION_ENABLE_TOUCH "enable_touch"
#define SDLOPTION_SIXAXIS "sixaxis"
#define SDLOPTION_DUAL_LIGHTGUN "dual_lightgun"
#if defined(USE_XINPUT) && USE_XINPUT
#define SDLOPTION_LIGHTGUNINDEX "lightgun_index"
#endif
@ -86,6 +87,7 @@ public:
// input options
bool enable_touch() const { return bool_value(SDLOPTION_ENABLE_TOUCH); }
bool sixaxis() const { return bool_value(SDLOPTION_SIXAXIS); }
bool dual_lightgun() const { return bool_value(SDLOPTION_DUAL_LIGHTGUN); }
const char *video_driver() const { return value(SDLOPTION_VIDEODRIVER); }
const char *render_driver() const { return value(SDLOPTION_RENDERDRIVER); }

View File

@ -297,7 +297,7 @@ void win_window_info::show_pointer()
s_saved_cursor_pos.x = s_saved_cursor_pos.y = -1;
}
while (ShowCursor(TRUE) < 1) {};
while (ShowCursor(TRUE) < 1) { }
ShowCursor(FALSE);
}
@ -342,7 +342,7 @@ static LRESULT CALLBACK winwindow_video_window_proc_ui(HWND wnd, UINT message, W
// is_mame_window
//============================================================
static bool is_mame_window(HWND hwnd)
inline bool is_mame_window(HWND hwnd)
{
for (const auto &window : osd_common_t::window_list())
if (dynamic_cast<win_window_info &>(*window).platform_window() == hwnd)
@ -351,50 +351,50 @@ static bool is_mame_window(HWND hwnd)
return false;
}
inline static BOOL handle_mouse_button(windows_osd_interface *osd, int button, int down, int x, int y)
inline BOOL handle_mouse_button(windows_osd_interface &osd, int button, int down, LPARAM lparam)
{
MouseUpdateEventArgs args;
args.pressed = (down ? 1 : 0) << button;
args.released = (down ? 0 : 1) << button;
args.vdelta = 0;
args.hdelta = 0;
args.xpos = x;
args.ypos = y;
args.xpos = GET_X_LPARAM(lparam);
args.ypos = GET_Y_LPARAM(lparam);
bool handled = osd->handle_input_event(INPUT_EVENT_MOUSE_BUTTON, &args);
bool const handled = osd.handle_input_event(INPUT_EVENT_MOUSE_BUTTON, &args);
// When in lightgun mode or mouse mode, the mouse click may be routed to the input system
// because the mouse interactions in the UI are routed from the video_window_proc below
// we need to make sure they aren't suppressed in these cases.
return handled && !osd->options().lightgun() && !osd->options().mouse();
return handled && !osd.options().lightgun() && !osd.options().mouse();
}
inline static BOOL handle_mouse_wheel(windows_osd_interface *osd, int v, int h, int x, int y)
inline BOOL handle_mouse_wheel(windows_osd_interface &osd, int v, int h, LPARAM lparam)
{
MouseUpdateEventArgs args;
args.pressed = 0;
args.released = 0;
args.vdelta = v;
args.hdelta = h;
args.xpos = x;
args.ypos = y;
args.xpos = GET_X_LPARAM(lparam);
args.ypos = GET_Y_LPARAM(lparam);
bool handled = osd->handle_input_event(INPUT_EVENT_MOUSE_WHEEL, &args);
bool const handled = osd.handle_input_event(INPUT_EVENT_MOUSE_WHEEL, &args);
// When in lightgun mode or mouse mode, the mouse wheel may be routed to the input system
// because the mouse interactions in the UI are routed from the video_window_proc below
// we need to make sure they aren't suppressed in these cases.
return handled && !osd->options().lightgun() && !osd->options().mouse();
return handled && !osd.options().lightgun() && !osd.options().mouse();
}
inline static BOOL handle_keypress(windows_osd_interface *osd, int vkey, int down, int scancode, BOOL extended_key)
inline BOOL handle_keypress(windows_osd_interface &osd, int vkey, int down, LPARAM lparam)
{
KeyPressEventArgs args;
args.event_id = down ? INPUT_EVENT_KEYDOWN : INPUT_EVENT_KEYUP;
args.scancode = MAKE_DI_SCAN(scancode, extended_key);
args.scancode = MAKE_DI_SCAN(SCAN_CODE(lparam), IS_EXTENDED(lparam));
args.vkey = vkey;
return osd->handle_input_event(args.event_id, &args);
return osd.handle_input_event(args.event_id, &args);
}
//============================================================
@ -435,54 +435,55 @@ void windows_osd_interface::process_events(bool ingame, bool nodispatch)
// forward mouse button downs to the input system
case WM_LBUTTONDOWN:
dispatch = !handle_mouse_button(this, 0, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam));
dispatch = !handle_mouse_button(*this, 0, TRUE, message.lParam);
break;
case WM_RBUTTONDOWN:
dispatch = !handle_mouse_button(this, 1, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam));
dispatch = !handle_mouse_button(*this, 1, TRUE, message.lParam);
break;
case WM_MBUTTONDOWN:
dispatch = !handle_mouse_button(this, 2, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam));
dispatch = !handle_mouse_button(*this, 2, TRUE, message.lParam);
break;
case WM_XBUTTONDOWN:
dispatch = !handle_mouse_button(this, 3, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam));
dispatch = !handle_mouse_button(*this, (GET_XBUTTON_WPARAM(message.wParam) == XBUTTON1) ? 3 : 4, TRUE, message.lParam);
break;
// forward mouse button ups to the input system
case WM_LBUTTONUP:
dispatch = !handle_mouse_button(this, 0, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam));
dispatch = !handle_mouse_button(*this, 0, FALSE, message.lParam);
break;
case WM_RBUTTONUP:
dispatch = !handle_mouse_button(this, 1, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam));
dispatch = !handle_mouse_button(*this, 1, FALSE, message.lParam);
break;
case WM_MBUTTONUP:
dispatch = !handle_mouse_button(this, 2, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam));
dispatch = !handle_mouse_button(*this, 2, FALSE, message.lParam);
break;
case WM_XBUTTONUP:
dispatch = !handle_mouse_button(this, 3, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam));
dispatch = !handle_mouse_button(*this, (GET_XBUTTON_WPARAM(message.wParam) == XBUTTON1) ? 3 : 4, FALSE, message.lParam);
break;
// forward mouse wheel movement to the input system
case WM_MOUSEWHEEL:
dispatch = !handle_mouse_wheel(this, GET_WHEEL_DELTA_WPARAM(message.wParam), 0, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam));
dispatch = !handle_mouse_wheel(*this, GET_WHEEL_DELTA_WPARAM(message.wParam), 0, message.lParam);
break;
case WM_MOUSEHWHEEL:
dispatch = !handle_mouse_wheel(this, 0, GET_WHEEL_DELTA_WPARAM(message.wParam), GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam));
dispatch = !handle_mouse_wheel(*this, 0, GET_WHEEL_DELTA_WPARAM(message.wParam), message.lParam);
break;
// forward keystrokes to the input system
case WM_KEYDOWN:
if (NOT_ALREADY_DOWN(message.lParam))
dispatch = !handle_keypress(this, message.wParam, TRUE, SCAN_CODE(message.lParam), IS_EXTENDED(message.lParam));
dispatch = !handle_keypress(*this, message.wParam, TRUE, message.lParam);
break;
case WM_KEYUP:
dispatch = !handle_keypress(this, message.wParam, FALSE, SCAN_CODE(message.lParam), IS_EXTENDED(message.lParam));
dispatch = !handle_keypress(*this, message.wParam, FALSE, message.lParam);
break;
}
}
@ -1220,6 +1221,16 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
case WM_POINTERCAPTURECHANGED:
window->pointer_capture_changed(wparam, lparam);
break;
// TODO: other pointer events?
//case WM_POINTERACTIVATE:
//case WM_POINTERDEVICECHANGE:
//case WM_POINTERDEVICECINRANGE:
//case WM_POINTERDEVICECOUTOFRANGE:
//case WM_POINTERROUTEDAWAY:
//case WM_POINTERROUTEDRELEASED:
//case WM_POINTERROUTEDTO:
//case WM_POINTERWHEEL:
//case WM_POINTERHWHEEL:
// pause the system when we start a menu or resize
case WM_ENTERSIZEMOVE:

View File

@ -80,7 +80,7 @@ public:
void extract_video_config();
// windows OSD specific
bool handle_input_event(input_event eventid, void *eventdata) const;
bool handle_input_event(input_event eventid, const void *eventdata) const;
bool should_hide_mouse() const;
virtual bool has_focus() const override;