mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
osd/modules/input: Detect joystick reconnection with SDL. (#9605)
Also improved display name scheme for joystick axes and buttons.
This commit is contained in:
parent
25c64006b7
commit
8614b890d3
@ -447,7 +447,7 @@ protected:
|
||||
public:
|
||||
|
||||
const osd_options * options() const { return m_options; }
|
||||
input_device_list * devicelist() { return &m_devicelist; }
|
||||
input_device_list & devicelist() { return m_devicelist; }
|
||||
bool input_enabled() const { return m_input_enabled; }
|
||||
bool input_paused() const { return m_input_paused; }
|
||||
bool mouse_enabled() const { return m_mouse_enabled; }
|
||||
@ -504,7 +504,7 @@ public:
|
||||
|
||||
virtual void exit() override
|
||||
{
|
||||
devicelist()->free_all_devices();
|
||||
devicelist().free_all_devices();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -238,7 +238,7 @@ public:
|
||||
result = dinput_set_dword_property(devinfo->dinput.device, DIPROP_AXISMODE, 0, DIPH_DEVICE, DIPROPAXISMODE_REL);
|
||||
if (result != DI_OK && result != DI_PROPNOEFFECT)
|
||||
{
|
||||
osd_printf_error("DirectInput: Unable to set relative mode for mouse %u (%s)\n", static_cast<unsigned int>(devicelist()->size()), devinfo->name());
|
||||
osd_printf_error("DirectInput: Unable to set relative mode for mouse %u (%s)\n", static_cast<unsigned int>(devicelist().size()), devinfo->name());
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -277,7 +277,7 @@ public:
|
||||
|
||||
error:
|
||||
if (devinfo)
|
||||
devicelist()->free_device(*devinfo);
|
||||
devicelist().free_device(*devinfo);
|
||||
goto exit;
|
||||
}
|
||||
};
|
||||
@ -449,10 +449,10 @@ void dinput_joystick_device::poll()
|
||||
int dinput_joystick_device::configure()
|
||||
{
|
||||
HRESULT result;
|
||||
auto devicelist = static_cast<input_module_base&>(module()).devicelist();
|
||||
auto &devicelist = static_cast<input_module_base&>(module()).devicelist();
|
||||
|
||||
// temporary approximation of index
|
||||
int devindex = devicelist->size();
|
||||
int devindex = devicelist.size();
|
||||
|
||||
// set absolute mode
|
||||
result = dinput_set_dword_property(dinput.device, DIPROP_AXISMODE, 0, DIPH_DEVICE, DIPROPAXISMODE_ABS);
|
||||
|
@ -72,7 +72,7 @@ public:
|
||||
std::string utf8_instance_id = utf8_instance_name + " product_" + guid_to_string(instance->guidProduct) + " instance_" + guid_to_string(instance->guidInstance);
|
||||
|
||||
// allocate memory for the device object
|
||||
TDevice &devinfo = module.devicelist()->create_device<TDevice>(machine, std::move(utf8_instance_name), std::move(utf8_instance_id), module);
|
||||
TDevice &devinfo = module.devicelist().create_device<TDevice>(machine, std::move(utf8_instance_name), std::move(utf8_instance_id), module);
|
||||
|
||||
// attempt to create a device
|
||||
result = m_dinput->CreateDevice(instance->guidInstance, devinfo.dinput.device.GetAddressOf(), nullptr);
|
||||
@ -133,7 +133,7 @@ public:
|
||||
return &devinfo;
|
||||
|
||||
error:
|
||||
module.devicelist()->free_device(devinfo);
|
||||
module.devicelist().free_device(devinfo);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,7 @@ public:
|
||||
m_global_inputs_enabled = downcast<windows_options &>(machine.options()).global_inputs();
|
||||
|
||||
// If we added no devices, no need to register for notifications
|
||||
if (devicelist()->empty())
|
||||
if (devicelist().empty())
|
||||
return;
|
||||
|
||||
// finally, register to receive raw input WM_INPUT messages if we found devices
|
||||
@ -539,7 +539,7 @@ protected:
|
||||
|
||||
tname.reset();
|
||||
|
||||
TDevice &devinfo = devicelist()->create_device<TDevice>(machine, std::move(utf8_name), std::move(utf8_id), *this);
|
||||
TDevice &devinfo = devicelist().create_device<TDevice>(machine, std::move(utf8_name), std::move(utf8_id), *this);
|
||||
|
||||
// Add the handle
|
||||
devinfo.set_handle(rawinputdevice.hDevice);
|
||||
@ -594,14 +594,14 @@ protected:
|
||||
|
||||
// find the device in the list and update
|
||||
auto target_device = std::find_if(
|
||||
devicelist()->begin(),
|
||||
devicelist()->end(),
|
||||
devicelist().begin(),
|
||||
devicelist().end(),
|
||||
[input] (auto const &device)
|
||||
{
|
||||
auto devinfo = dynamic_cast<rawinput_device *>(device.get());
|
||||
return devinfo && (input->header.hDevice == devinfo->device_handle());
|
||||
});
|
||||
if (devicelist()->end() == target_device)
|
||||
if (devicelist().end() == target_device)
|
||||
return false;
|
||||
|
||||
static_cast<rawinput_device *>(target_device->get())->queue_events(input, 1);
|
||||
@ -629,14 +629,14 @@ protected:
|
||||
|
||||
// find the device in the list and update
|
||||
auto target_device = std::find_if(
|
||||
devicelist()->begin(),
|
||||
devicelist()->end(),
|
||||
devicelist().begin(),
|
||||
devicelist().end(),
|
||||
[&utf8_id] (auto const &device)
|
||||
{
|
||||
auto devinfo = dynamic_cast<rawinput_device *>(device.get());
|
||||
return devinfo && !devinfo->device_handle() && (devinfo->id() == utf8_id);
|
||||
});
|
||||
if (devicelist()->end() == target_device)
|
||||
if (devicelist().end() == target_device)
|
||||
return false;
|
||||
|
||||
static_cast<rawinput_device *>(target_device->get())->set_handle(rawinputdevice);
|
||||
@ -652,15 +652,15 @@ protected:
|
||||
|
||||
// find the device in the list and update
|
||||
auto target_device = std::find_if(
|
||||
devicelist()->begin(),
|
||||
devicelist()->end(),
|
||||
devicelist().begin(),
|
||||
devicelist().end(),
|
||||
[rawinputdevice] (auto const &device)
|
||||
{
|
||||
auto devinfo = dynamic_cast<rawinput_device *>(device.get());
|
||||
return devinfo && (rawinputdevice == devinfo->device_handle());
|
||||
});
|
||||
|
||||
if (devicelist()->end() == target_device)
|
||||
if (devicelist().end() == target_device)
|
||||
return false;
|
||||
|
||||
(*target_device)->reset();
|
||||
|
@ -20,12 +20,13 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <cctype>
|
||||
// ReSharper disable once CppUnusedIncludeDirective
|
||||
#include <cstddef>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <queue>
|
||||
|
||||
// MAME headers
|
||||
#include "emu.h"
|
||||
@ -373,6 +374,14 @@ protected:
|
||||
class sdl_keyboard_device : public sdl_device
|
||||
{
|
||||
public:
|
||||
// state information for a keyboard
|
||||
struct keyboard_state
|
||||
{
|
||||
int32_t state[0x3ff]; // must be int32_t!
|
||||
int8_t oldkey[MAX_KEYS];
|
||||
int8_t currkey[MAX_KEYS];
|
||||
};
|
||||
|
||||
keyboard_state keyboard;
|
||||
|
||||
sdl_keyboard_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
|
||||
@ -483,6 +492,13 @@ private:
|
||||
int last_y;
|
||||
|
||||
public:
|
||||
// state information for a mouse
|
||||
struct mouse_state
|
||||
{
|
||||
int32_t lX, lY;
|
||||
int32_t buttons[MAX_BUTTONS];
|
||||
};
|
||||
|
||||
mouse_state mouse;
|
||||
|
||||
sdl_mouse_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
|
||||
@ -602,40 +618,40 @@ public:
|
||||
// sdl_joystick_device
|
||||
//============================================================
|
||||
|
||||
// state information for a joystick
|
||||
struct sdl_joystick_state
|
||||
{
|
||||
int32_t axes[MAX_AXES];
|
||||
int32_t buttons[MAX_BUTTONS];
|
||||
int32_t hatsU[MAX_HATS], hatsD[MAX_HATS], hatsL[MAX_HATS], hatsR[MAX_HATS];
|
||||
int32_t balls[MAX_AXES];
|
||||
};
|
||||
|
||||
struct sdl_api_state
|
||||
{
|
||||
SDL_Joystick *device;
|
||||
SDL_Haptic *hapdevice;
|
||||
SDL_JoystickID joystick_id;
|
||||
};
|
||||
|
||||
class sdl_joystick_device : public sdl_device
|
||||
{
|
||||
public:
|
||||
// state information for a joystick
|
||||
struct sdl_joystick_state
|
||||
{
|
||||
int32_t axes[MAX_AXES];
|
||||
int32_t buttons[MAX_BUTTONS];
|
||||
int32_t hatsU[MAX_HATS], hatsD[MAX_HATS], hatsL[MAX_HATS], hatsR[MAX_HATS];
|
||||
int32_t balls[MAX_AXES];
|
||||
};
|
||||
|
||||
struct sdl_api_state
|
||||
{
|
||||
SDL_Joystick *device = nullptr;
|
||||
SDL_Haptic *hapdevice = nullptr;
|
||||
SDL_JoystickID joystick_id;
|
||||
std::optional<std::string> serial;
|
||||
};
|
||||
|
||||
sdl_joystick_state joystick;
|
||||
sdl_api_state sdl_state;
|
||||
|
||||
sdl_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
|
||||
sdl_device(machine, std::move(name), std::move(id), DEVICE_CLASS_JOYSTICK, module),
|
||||
joystick({{0}}),
|
||||
sdl_state({ nullptr })
|
||||
joystick({{0}})
|
||||
{
|
||||
}
|
||||
|
||||
~sdl_joystick_device()
|
||||
{
|
||||
if (sdl_state.device != nullptr)
|
||||
if (sdl_state.device)
|
||||
{
|
||||
if (sdl_state.hapdevice != nullptr)
|
||||
if (sdl_state.hapdevice)
|
||||
{
|
||||
SDL_HapticClose(sdl_state.hapdevice);
|
||||
sdl_state.hapdevice = nullptr;
|
||||
@ -665,38 +681,10 @@ public:
|
||||
break;
|
||||
|
||||
case SDL_JOYHATMOTION:
|
||||
if (sdlevent.jhat.value & SDL_HAT_UP)
|
||||
{
|
||||
joystick.hatsU[sdlevent.jhat.hat] = 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
joystick.hatsU[sdlevent.jhat.hat] = 0;
|
||||
}
|
||||
if (sdlevent.jhat.value & SDL_HAT_DOWN)
|
||||
{
|
||||
joystick.hatsD[sdlevent.jhat.hat] = 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
joystick.hatsD[sdlevent.jhat.hat] = 0;
|
||||
}
|
||||
if (sdlevent.jhat.value & SDL_HAT_LEFT)
|
||||
{
|
||||
joystick.hatsL[sdlevent.jhat.hat] = 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
joystick.hatsL[sdlevent.jhat.hat] = 0;
|
||||
}
|
||||
if (sdlevent.jhat.value & SDL_HAT_RIGHT)
|
||||
{
|
||||
joystick.hatsR[sdlevent.jhat.hat] = 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
joystick.hatsR[sdlevent.jhat.hat] = 0;
|
||||
}
|
||||
joystick.hatsU[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_UP) ? 0x80 : 0;
|
||||
joystick.hatsD[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_DOWN) ? 0x80 : 0;
|
||||
joystick.hatsL[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_LEFT) ? 0x80 : 0;
|
||||
joystick.hatsR[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_RIGHT) ? 0x80 : 0;
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
@ -704,6 +692,21 @@ public:
|
||||
if (sdlevent.jbutton.button < MAX_BUTTONS)
|
||||
joystick.buttons[sdlevent.jbutton.button] = (sdlevent.jbutton.state == SDL_PRESSED) ? 0x80 : 0;
|
||||
break;
|
||||
|
||||
case SDL_JOYDEVICEREMOVED:
|
||||
osd_printf_verbose("Joystick: %s [GUID %s] disconnected\n", name(), id());
|
||||
reset();
|
||||
if (sdl_state.device)
|
||||
{
|
||||
if (sdl_state.hapdevice)
|
||||
{
|
||||
SDL_HapticClose(sdl_state.hapdevice);
|
||||
sdl_state.hapdevice = nullptr;
|
||||
}
|
||||
SDL_JoystickClose(sdl_state.device);
|
||||
sdl_state.device = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -786,9 +789,10 @@ public:
|
||||
void handle_event(SDL_Event &sdlevent) override
|
||||
{
|
||||
// By default dispatch event to every device
|
||||
devicelist()->for_each_device([&sdlevent](auto device) {
|
||||
downcast<sdl_device*>(device)->queue_events(&sdlevent, 1);
|
||||
});
|
||||
devicelist().for_each_device(
|
||||
[&sdlevent](auto device) {
|
||||
downcast<sdl_device*>(device)->queue_events(&sdlevent, 1);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -810,13 +814,12 @@ public:
|
||||
{
|
||||
sdl_input_module::input_init(machine);
|
||||
|
||||
static int event_types[] = {
|
||||
static_cast<int>(SDL_KEYDOWN),
|
||||
static_cast<int>(SDL_KEYUP),
|
||||
static_cast<int>(SDL_TEXTINPUT)
|
||||
};
|
||||
static int const event_types[] = {
|
||||
int(SDL_KEYDOWN),
|
||||
int(SDL_KEYUP),
|
||||
int(SDL_TEXTINPUT) };
|
||||
|
||||
sdl_event_manager::instance().subscribe(event_types, std::size(event_types), this);
|
||||
sdl_event_manager::instance().subscribe(event_types, this);
|
||||
|
||||
// Read our keymap and store a pointer to our table
|
||||
m_key_trans_table = sdlinput_read_keymap(machine);
|
||||
@ -826,7 +829,7 @@ public:
|
||||
osd_printf_verbose("Keyboard: Start initialization\n");
|
||||
|
||||
// SDL only has 1 keyboard add it now
|
||||
auto &devinfo = devicelist()->create_device<sdl_keyboard_device>(machine, "System keyboard", "System keyboard", *this);
|
||||
auto &devinfo = devicelist().create_device<sdl_keyboard_device>(machine, "System keyboard", "System keyboard", *this);
|
||||
|
||||
// populate it
|
||||
for (int keynum = 0; local_table[keynum].mame_key != ITEM_ID_INVALID; keynum++)
|
||||
@ -942,19 +945,18 @@ public:
|
||||
{
|
||||
sdl_input_module::input_init(machine);
|
||||
|
||||
static int event_types[] = {
|
||||
static_cast<int>(SDL_MOUSEMOTION),
|
||||
static_cast<int>(SDL_MOUSEBUTTONDOWN),
|
||||
static_cast<int>(SDL_MOUSEBUTTONUP),
|
||||
static_cast<int>(SDL_MOUSEWHEEL)
|
||||
};
|
||||
static int const event_types[] = {
|
||||
int(SDL_MOUSEMOTION),
|
||||
int(SDL_MOUSEBUTTONDOWN),
|
||||
int(SDL_MOUSEBUTTONUP),
|
||||
int(SDL_MOUSEWHEEL) };
|
||||
|
||||
sdl_event_manager::instance().subscribe(event_types, std::size(event_types), this);
|
||||
sdl_event_manager::instance().subscribe(event_types, this);
|
||||
|
||||
osd_printf_verbose("Mouse: Start initialization\n");
|
||||
|
||||
// SDL currently only supports one mouse
|
||||
auto &devinfo = devicelist()->create_device<sdl_mouse_device>(machine, "System mouse", "System mouse", *this);
|
||||
auto &devinfo = devicelist().create_device<sdl_mouse_device>(machine, "System mouse", "System mouse", *this);
|
||||
|
||||
// add the axes
|
||||
devinfo.device()->add_item("X", ITEM_ID_XAXIS, generic_axis_get_state<std::int32_t>, &devinfo.mouse.lX);
|
||||
@ -981,12 +983,15 @@ void devmap_register(device_map_t &devmap, int physical_idx, const std::string &
|
||||
auto entry = std::find_if(
|
||||
std::begin(devmap.map),
|
||||
std::end(devmap.map),
|
||||
[&name] (auto &item) { return (item.name == name) && (item.physical < 0); });
|
||||
[&name] (auto const &item) { return (item.name == name) && (item.physical < 0); });
|
||||
|
||||
// If we didn't find it by name, find the first free slot
|
||||
if (entry == std::end(devmap.map))
|
||||
{
|
||||
entry = std::find_if(std::begin(devmap.map), std::end(devmap.map), [] (auto &item) { return item.name.empty(); });
|
||||
entry = std::find_if(
|
||||
std::begin(devmap.map),
|
||||
std::end(devmap.map),
|
||||
[] (auto const &item) { return item.name.empty(); });
|
||||
}
|
||||
|
||||
if (entry != std::end(devmap.map))
|
||||
@ -1054,13 +1059,12 @@ public:
|
||||
|
||||
char tempname[512];
|
||||
|
||||
m_sixaxis_mode = downcast<const sdl_options*>(options())->sixaxis();
|
||||
m_sixaxis_mode = downcast<const sdl_options *>(options())->sixaxis();
|
||||
|
||||
devmap_init(machine, &m_joy_map, SDLOPTION_JOYINDEX, 8, "Joystick mapping");
|
||||
|
||||
osd_printf_verbose("Joystick: Start initialization\n");
|
||||
int physical_stick;
|
||||
for (physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++)
|
||||
for (int physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++)
|
||||
{
|
||||
std::string joy_name = remove_spaces(SDL_JoystickNameForIndex(physical_stick));
|
||||
devmap_register(m_joy_map, physical_stick, joy_name);
|
||||
@ -1073,28 +1077,40 @@ public:
|
||||
if (!devinfo)
|
||||
continue;
|
||||
|
||||
physical_stick = m_joy_map.map[stick].physical;
|
||||
SDL_Joystick *joy = SDL_JoystickOpen(physical_stick);
|
||||
int const physical_stick = m_joy_map.map[stick].physical;
|
||||
SDL_Joystick *const joy = SDL_JoystickOpen(physical_stick);
|
||||
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joy);
|
||||
char guid_str[256];
|
||||
guid_str[0] = '\0';
|
||||
SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)-1);
|
||||
SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str) - 1);
|
||||
|
||||
devinfo->sdl_state.device = joy;
|
||||
devinfo->sdl_state.joystick_id = SDL_JoystickInstanceID(joy);
|
||||
devinfo->sdl_state.hapdevice = SDL_HapticOpenFromJoystick(joy);
|
||||
|
||||
osd_printf_verbose("Joystick: %s [GUID %s]\n", SDL_JoystickNameForIndex(physical_stick), guid_str);
|
||||
osd_printf_verbose("Joystick: ... %d axes, %d buttons %d hats %d balls\n", SDL_JoystickNumAxes(joy), SDL_JoystickNumButtons(joy), SDL_JoystickNumHats(joy), SDL_JoystickNumBalls(joy));
|
||||
osd_printf_verbose("Joystick: ... Physical id %d mapped to logical id %d\n", physical_stick, stick + 1);
|
||||
if (devinfo->sdl_state.hapdevice != nullptr)
|
||||
{
|
||||
osd_printf_verbose("Joystick: ... Has haptic capability\n");
|
||||
}
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
char const *const serial = SDL_JoystickGetSerial(joy);
|
||||
if (serial)
|
||||
devinfo->sdl_state.serial = serial;
|
||||
else
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
devinfo->sdl_state.serial = std::nullopt;
|
||||
|
||||
osd_printf_verbose("Joystick: %s [GUID %s] Vendor ID %04X, Product ID %04X, Revision %04X\n",
|
||||
SDL_JoystickNameForIndex(physical_stick),
|
||||
guid_str,
|
||||
SDL_JoystickGetVendor(joy),
|
||||
SDL_JoystickGetProduct(joy),
|
||||
SDL_JoystickGetProductVersion(joy));
|
||||
osd_printf_verbose("Joystick: ... %d axes, %d buttons %d hats %d balls\n",
|
||||
SDL_JoystickNumAxes(joy),
|
||||
SDL_JoystickNumButtons(joy),
|
||||
SDL_JoystickNumHats(joy),
|
||||
SDL_JoystickNumBalls(joy));
|
||||
osd_printf_verbose("Joystick: ... Physical id %d mapped to logical id %d\n", physical_stick, stick + 1);
|
||||
if (devinfo->sdl_state.hapdevice)
|
||||
osd_printf_verbose("Joystick: ... Has haptic capability\n");
|
||||
else
|
||||
{
|
||||
osd_printf_verbose("Joystick: ... Does not have haptic capability\n");
|
||||
}
|
||||
|
||||
// loop over all axes
|
||||
for (int axis = 0; axis < SDL_JoystickNumAxes(joy); axis++)
|
||||
@ -1108,7 +1124,7 @@ public:
|
||||
else
|
||||
itemid = ITEM_ID_OTHER_AXIS_ABSOLUTE;
|
||||
|
||||
snprintf(tempname, sizeof(tempname), "A%d %s", axis, devinfo->name().c_str());
|
||||
snprintf(tempname, sizeof(tempname), "A%d", axis + 1);
|
||||
devinfo->device()->add_item(tempname, itemid, generic_axis_get_state<std::int32_t>, &devinfo->joystick.axes[axis]);
|
||||
}
|
||||
|
||||
@ -1128,7 +1144,7 @@ public:
|
||||
else
|
||||
itemid = ITEM_ID_OTHER_SWITCH;
|
||||
|
||||
snprintf(tempname, sizeof(tempname), "button %d", button);
|
||||
snprintf(tempname, sizeof(tempname), "Button %d", button + 1);
|
||||
devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.buttons[button]);
|
||||
}
|
||||
|
||||
@ -1137,16 +1153,16 @@ public:
|
||||
{
|
||||
input_item_id itemid;
|
||||
|
||||
snprintf(tempname, sizeof(tempname), "hat %d Up", hat);
|
||||
snprintf(tempname, sizeof(tempname), "Hat %d Up", hat + 1);
|
||||
itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1UP + 4 * hat : ITEM_ID_OTHER_SWITCH);
|
||||
devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsU[hat]);
|
||||
snprintf(tempname, sizeof(tempname), "hat %d Down", hat);
|
||||
snprintf(tempname, sizeof(tempname), "Hat %d Down", hat + 1);
|
||||
itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1DOWN + 4 * hat : ITEM_ID_OTHER_SWITCH);
|
||||
devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsD[hat]);
|
||||
snprintf(tempname, sizeof(tempname), "hat %d Left", hat);
|
||||
snprintf(tempname, sizeof(tempname), "Hat %d Left", hat + 1);
|
||||
itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1LEFT + 4 * hat : ITEM_ID_OTHER_SWITCH);
|
||||
devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsL[hat]);
|
||||
snprintf(tempname, sizeof(tempname), "hat %d Right", hat);
|
||||
snprintf(tempname, sizeof(tempname), "Hat %d Right", hat + 1);
|
||||
itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1RIGHT + 4 * hat : ITEM_ID_OTHER_SWITCH);
|
||||
devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsR[hat]);
|
||||
}
|
||||
@ -1161,46 +1177,90 @@ public:
|
||||
else
|
||||
itemid = ITEM_ID_OTHER_AXIS_RELATIVE;
|
||||
|
||||
snprintf(tempname, sizeof(tempname), "R%d %s", ball * 2, devinfo->name().c_str());
|
||||
snprintf(tempname, sizeof(tempname), "R%d X", ball + 1);
|
||||
devinfo->device()->add_item(tempname, (input_item_id)itemid, generic_axis_get_state<std::int32_t>, &devinfo->joystick.balls[ball * 2]);
|
||||
snprintf(tempname, sizeof(tempname), "R%d %s", ball * 2 + 1, devinfo->name().c_str());
|
||||
snprintf(tempname, sizeof(tempname), "R%d Y", ball + 1);
|
||||
devinfo->device()->add_item(tempname, (input_item_id)(itemid + 1), generic_axis_get_state<std::int32_t>, &devinfo->joystick.balls[ball * 2 + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
static int event_types[] = {
|
||||
static_cast<int>(SDL_JOYAXISMOTION),
|
||||
static_cast<int>(SDL_JOYBALLMOTION),
|
||||
static_cast<int>(SDL_JOYHATMOTION),
|
||||
static_cast<int>(SDL_JOYBUTTONDOWN),
|
||||
static_cast<int>(SDL_JOYBUTTONUP)
|
||||
};
|
||||
static int const event_types[] = {
|
||||
int(SDL_JOYAXISMOTION),
|
||||
int(SDL_JOYBALLMOTION),
|
||||
int(SDL_JOYHATMOTION),
|
||||
int(SDL_JOYBUTTONDOWN),
|
||||
int(SDL_JOYBUTTONUP),
|
||||
int(SDL_JOYDEVICEADDED),
|
||||
int(SDL_JOYDEVICEREMOVED) };
|
||||
|
||||
sdl_event_manager::instance().subscribe(event_types, std::size(event_types), this);
|
||||
sdl_event_manager::instance().subscribe(event_types, this);
|
||||
|
||||
osd_printf_verbose("Joystick: End initialization\n");
|
||||
}
|
||||
|
||||
virtual void handle_event(SDL_Event &sdlevent) override
|
||||
{
|
||||
// Figure out which joystick this event id destined for
|
||||
auto target_device = std::find_if(
|
||||
devicelist()->begin(),
|
||||
devicelist()->end(),
|
||||
[&sdlevent] (auto &device)
|
||||
{
|
||||
std::unique_ptr<device_info> &ptr = device;
|
||||
return downcast<sdl_joystick_device*>(ptr.get())->sdl_state.joystick_id == sdlevent.jdevice.which;
|
||||
});
|
||||
|
||||
// If we find a matching joystick, dispatch the event to the joystick
|
||||
if (target_device != devicelist()->end())
|
||||
if (SDL_JOYDEVICEADDED == sdlevent.type)
|
||||
{
|
||||
downcast<sdl_joystick_device*>((*target_device).get())->queue_events(&sdlevent, 1);
|
||||
SDL_Joystick *const joy = SDL_JoystickOpen(sdlevent.jdevice.which);
|
||||
if (joy)
|
||||
{
|
||||
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joy);
|
||||
char guid_str[256];
|
||||
guid_str[0] = '\0';
|
||||
SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str) - 1);
|
||||
char const *serial = nullptr;
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
serial = SDL_JoystickGetSerial(joy);
|
||||
#endif
|
||||
auto target_device = std::find_if(
|
||||
devicelist().begin(),
|
||||
devicelist().end(),
|
||||
[&guid_str, &serial] (auto const &device)
|
||||
{
|
||||
auto &devinfo = downcast<sdl_joystick_device &>(*device);
|
||||
return
|
||||
!devinfo.sdl_state.device &&
|
||||
(devinfo.id() == guid_str) &&
|
||||
((serial && devinfo.sdl_state.serial && (*devinfo.sdl_state.serial == serial)) || (!serial && !devinfo.sdl_state.serial));
|
||||
});
|
||||
if (devicelist().end() != target_device)
|
||||
{
|
||||
auto &devinfo = downcast<sdl_joystick_device &>(**target_device);
|
||||
devinfo.sdl_state.device = joy;
|
||||
devinfo.sdl_state.joystick_id = SDL_JoystickInstanceID(joy);
|
||||
devinfo.sdl_state.hapdevice = SDL_HapticOpenFromJoystick(joy);
|
||||
osd_printf_verbose("Joystick: %s [GUID %s] reconnected\n", devinfo.name(), guid_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_JoystickClose(joy);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Figure out which joystick this event id destined for
|
||||
sdl_joystick_device *const target_device = find_joystick(sdlevent.jdevice.which); // FIXME: this depends on SDL_JoystickID being the same size as Sint32
|
||||
|
||||
// If we find a matching joystick, dispatch the event to the joystick
|
||||
if (target_device)
|
||||
target_device->queue_events(&sdlevent, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
sdl_joystick_device *find_joystick(SDL_JoystickID instance)
|
||||
{
|
||||
for (auto &ptr : devicelist())
|
||||
{
|
||||
sdl_joystick_device *const device = downcast<sdl_joystick_device *>(ptr.get());
|
||||
if (device->sdl_state.device && (device->sdl_state.joystick_id == instance))
|
||||
return device;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sdl_joystick_device *create_joystick_device(running_machine &machine, device_map_t *devmap, int index, input_device_class devclass)
|
||||
{
|
||||
char tempname[20];
|
||||
@ -1215,16 +1275,16 @@ private:
|
||||
{
|
||||
snprintf(tempname, std::size(tempname), "NC%d", index);
|
||||
m_sixaxis_mode
|
||||
? devicelist()->create_device<sdl_sixaxis_joystick_device>(machine, tempname, guid_str, *this)
|
||||
: devicelist()->create_device<sdl_joystick_device>(machine, tempname, guid_str, *this);
|
||||
? devicelist().create_device<sdl_sixaxis_joystick_device>(machine, tempname, guid_str, *this)
|
||||
: devicelist().create_device<sdl_joystick_device>(machine, tempname, guid_str, *this);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_sixaxis_mode
|
||||
? &devicelist()->create_device<sdl_sixaxis_joystick_device>(machine, std::string(devmap->map[index].name), guid_str, *this)
|
||||
: &devicelist()->create_device<sdl_joystick_device>(machine, std::string(devmap->map[index].name), guid_str, *this);
|
||||
? &devicelist().create_device<sdl_sixaxis_joystick_device>(machine, std::string(devmap->map[index].name), guid_str, *this)
|
||||
: &devicelist().create_device<sdl_joystick_device>(machine, std::string(devmap->map[index].name), guid_str, *this);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -267,7 +267,7 @@ void sdl_osd_interface::release_keys()
|
||||
{
|
||||
auto keybd = dynamic_cast<input_module_base*>(m_keyboard_input);
|
||||
if (keybd != nullptr)
|
||||
keybd->devicelist()->reset_devices();
|
||||
keybd->devicelist().reset_devices();
|
||||
}
|
||||
|
||||
bool sdl_osd_interface::should_hide_mouse()
|
||||
|
@ -8,40 +8,17 @@
|
||||
//
|
||||
//============================================================
|
||||
|
||||
#ifndef INPUT_SDLCOMMON_H_
|
||||
#define INPUT_SDLCOMMON_H_
|
||||
#ifndef MAME_OSD_INPUT_INPUT_SDLCOMMON_H
|
||||
#define MAME_OSD_INPUT_INPUT_SDLCOMMON_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
|
||||
#define MAX_DEVMAP_ENTRIES 16
|
||||
#define SDL_MODULE_EVENT_BUFFER_SIZE 5
|
||||
|
||||
// state information for a keyboard
|
||||
struct keyboard_state
|
||||
{
|
||||
int32_t state[0x3ff]; // must be int32_t!
|
||||
int8_t oldkey[MAX_KEYS];
|
||||
int8_t currkey[MAX_KEYS];
|
||||
};
|
||||
|
||||
// state information for a mouse
|
||||
struct mouse_state
|
||||
{
|
||||
int32_t lX, lY;
|
||||
int32_t buttons[MAX_BUTTONS];
|
||||
};
|
||||
|
||||
|
||||
// state information for a joystick; DirectInput state must be first element
|
||||
struct joystick_state
|
||||
{
|
||||
SDL_Joystick *device;
|
||||
int32_t axes[MAX_AXES];
|
||||
int32_t buttons[MAX_BUTTONS];
|
||||
int32_t hatsU[MAX_HATS], hatsD[MAX_HATS], hatsL[MAX_HATS], hatsR[MAX_HATS];
|
||||
int32_t balls[MAX_AXES];
|
||||
};
|
||||
|
||||
struct device_map_t
|
||||
{
|
||||
@ -79,15 +56,14 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void subscribe(int* event_types, int num_event_types, TSubscriber *subscriber)
|
||||
template <size_t N>
|
||||
void subscribe(int const (&event_types)[N], TSubscriber *subscriber)
|
||||
{
|
||||
std::lock_guard<std::mutex> scope_lock(m_lock);
|
||||
|
||||
// Add the subscription
|
||||
for (int i = 0; i < num_event_types; i++)
|
||||
{
|
||||
m_subscription_index.emplace(event_types[i], subscriber);
|
||||
}
|
||||
for (int i : event_types)
|
||||
m_subscription_index.emplace(i, subscriber);
|
||||
}
|
||||
|
||||
void unsubscribe(TSubscriber *subscriber)
|
||||
@ -199,4 +175,4 @@ static inline void devmap_init(running_machine &machine, device_map_t *devmap, c
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // MAME_OSD_INPUT_INPUT_SDLCOMMON_H
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
virtual void input_init(running_machine &machine) override
|
||||
{
|
||||
// Add a single win32 keyboard device that we'll monitor using Win32
|
||||
auto &devinfo = devicelist()->create_device<win32_keyboard_device>(machine, "Win32 Keyboard 1", "Win32 Keyboard 1", *this);
|
||||
auto &devinfo = devicelist().create_device<win32_keyboard_device>(machine, "Win32 Keyboard 1", "Win32 Keyboard 1", *this);
|
||||
|
||||
keyboard_trans_table &table = keyboard_trans_table::instance();
|
||||
|
||||
@ -106,7 +106,7 @@ public:
|
||||
case INPUT_EVENT_KEYDOWN:
|
||||
case INPUT_EVENT_KEYUP:
|
||||
args = static_cast<KeyPressEventArgs*>(eventdata);
|
||||
devicelist()->for_each_device([args](auto device)
|
||||
devicelist().for_each_device([args](auto device)
|
||||
{
|
||||
auto keyboard = dynamic_cast<win32_keyboard_device*>(device);
|
||||
if (keyboard != nullptr)
|
||||
@ -206,7 +206,7 @@ public:
|
||||
return;
|
||||
|
||||
// allocate a device
|
||||
auto &devinfo = devicelist()->create_device<win32_mouse_device>(machine, "Win32 Mouse 1", "Win32 Mouse 1", *this);
|
||||
auto &devinfo = devicelist().create_device<win32_mouse_device>(machine, "Win32 Mouse 1", "Win32 Mouse 1", *this);
|
||||
|
||||
// populate the axes
|
||||
for (int axisnum = 0; axisnum < 2; axisnum++)
|
||||
@ -235,7 +235,7 @@ public:
|
||||
return false;
|
||||
|
||||
auto args = static_cast<MouseButtonEventArgs*>(eventdata);
|
||||
devicelist()->for_each_device([args](auto device)
|
||||
devicelist().for_each_device([args](auto device)
|
||||
{
|
||||
auto mouse = dynamic_cast<win32_mouse_device*>(device);
|
||||
if (mouse != nullptr)
|
||||
@ -268,7 +268,7 @@ public:
|
||||
m_lightgun_shared_axis_mode = downcast<windows_options &>(machine.options()).dual_lightgun();
|
||||
|
||||
// Since we are about to be added to the list, the current size is the zero-based index of where we will be
|
||||
m_gun_index = downcast<wininput_module&>(module).devicelist()->size();
|
||||
m_gun_index = downcast<wininput_module&>(module).devicelist().size();
|
||||
}
|
||||
|
||||
void poll() override
|
||||
@ -391,7 +391,7 @@ public:
|
||||
static const char *const gun_names[] = { "Win32 Gun 1", "Win32 Gun 2" };
|
||||
|
||||
// allocate a device
|
||||
auto &devinfo = devicelist()->create_device<win32_lightgun_device>(machine, gun_names[gunnum], gun_names[gunnum], *this);
|
||||
auto &devinfo = devicelist().create_device<win32_lightgun_device>(machine, gun_names[gunnum], gun_names[gunnum], *this);
|
||||
|
||||
// populate the axes
|
||||
for (int axisnum = 0; axisnum < 2; axisnum++)
|
||||
@ -421,7 +421,7 @@ public:
|
||||
return false;
|
||||
|
||||
auto args = static_cast<MouseButtonEventArgs*>(eventdata);
|
||||
devicelist()->for_each_device([args](auto device)
|
||||
devicelist().for_each_device([args](auto device)
|
||||
{
|
||||
auto lightgun = dynamic_cast<win32_lightgun_device*>(device);
|
||||
if (lightgun != nullptr)
|
||||
|
@ -538,9 +538,9 @@ public:
|
||||
osd_printf_verbose("Device %i: Registered %i events.\n", static_cast<int>(info->id), events_registered);
|
||||
|
||||
// register ourself to handle events from event manager
|
||||
int event_types[] = { motion_type, button_press_type, button_release_type };
|
||||
int const event_types[] = { motion_type, button_press_type, button_release_type };
|
||||
osd_printf_verbose("Events types to register: motion:%d, press:%d, release:%d\n", motion_type, button_press_type, button_release_type);
|
||||
x11_event_manager::instance().subscribe(event_types, std::size(event_types), this);
|
||||
x11_event_manager::instance().subscribe(event_types, this);
|
||||
}
|
||||
|
||||
osd_printf_verbose("Lightgun: End initialization\n");
|
||||
@ -582,14 +582,14 @@ public:
|
||||
}
|
||||
|
||||
// Figure out which lightgun this event id destined for
|
||||
auto target_device = std::find_if(devicelist()->begin(), devicelist()->end(), [deviceid](auto &device)
|
||||
auto target_device = std::find_if(devicelist().begin(), devicelist().end(), [deviceid](auto &device)
|
||||
{
|
||||
std::unique_ptr<device_info> &ptr = device;
|
||||
return downcast<x11_input_device*>(ptr.get())->x11_state.deviceid == deviceid;
|
||||
});
|
||||
|
||||
// If we find a matching lightgun, dispatch the event to the lightgun
|
||||
if (target_device != devicelist()->end())
|
||||
if (target_device != devicelist().end())
|
||||
{
|
||||
downcast<x11_input_device*>((*target_device).get())->queue_events(&xevent, 1);
|
||||
}
|
||||
@ -604,7 +604,7 @@ private:
|
||||
{
|
||||
char tempname[20];
|
||||
snprintf(tempname, std::size(tempname), "NC%d", index);
|
||||
return &devicelist()->create_device<x11_lightgun_device>(machine, tempname, tempname, *this);
|
||||
return &devicelist().create_device<x11_lightgun_device>(machine, tempname, tempname, *this);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -612,7 +612,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
return &devicelist()->create_device<x11_lightgun_device>(machine, std::string(m_lightgun_map.map[index].name), std::string(m_lightgun_map.map[index].name), *this);
|
||||
return &devicelist().create_device<x11_lightgun_device>(machine, std::string(m_lightgun_map.map[index].name), std::string(m_lightgun_map.map[index].name), *this);
|
||||
}
|
||||
|
||||
void add_lightgun_buttons(XAnyClassPtr first_info_class, int num_classes, x11_lightgun_device &devinfo) const
|
||||
|
@ -186,7 +186,7 @@ xinput_joystick_device * xinput_api_helper::create_xinput_device(running_machine
|
||||
snprintf(device_name, sizeof(device_name), "XInput Player %u", index + 1);
|
||||
|
||||
// allocate the device object
|
||||
auto &devinfo = module.devicelist()->create_device<xinput_joystick_device>(machine, device_name, device_name, module, shared_from_this());
|
||||
auto &devinfo = module.devicelist().create_device<xinput_joystick_device>(machine, device_name, device_name, module, shared_from_this());
|
||||
|
||||
// Set the player ID
|
||||
devinfo.xinput_state.player_index = index;
|
||||
|
Loading…
Reference in New Issue
Block a user