win32: use new input system
This commit is contained in:
parent
4ae11053ce
commit
94f346a1e0
|
@ -55,10 +55,12 @@ bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed)
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case EMU_BTN_ESCAPE:
|
case EMU_BTN_ESCAPE:
|
||||||
dc_stop();
|
if (pressed)
|
||||||
|
dc_stop();
|
||||||
break;
|
break;
|
||||||
case EMU_BTN_MENU:
|
case EMU_BTN_MENU:
|
||||||
gui_open_settings();
|
if (pressed)
|
||||||
|
gui_open_settings();
|
||||||
break;
|
break;
|
||||||
case EMU_BTN_TRIGGER_LEFT:
|
case EMU_BTN_TRIGGER_LEFT:
|
||||||
lt[_maple_port] = pressed ? 255 : 0;
|
lt[_maple_port] = pressed ? 255 : 0;
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
}
|
}
|
||||||
InputMapping *get_input_mapping() { return input_mapper; }
|
InputMapping *get_input_mapping() { return input_mapper; }
|
||||||
void save_mapping();
|
void save_mapping();
|
||||||
bool remappable() { return _remappable; }
|
bool remappable() { return _remappable && input_mapper != NULL; }
|
||||||
|
|
||||||
static void Register(std::shared_ptr<GamepadDevice> gamepad)
|
static void Register(std::shared_ptr<GamepadDevice> gamepad)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "../input/gamepad_device.h"
|
#include "../input/gamepad_device.h"
|
||||||
#include "evdev.h"
|
#include "evdev.h"
|
||||||
#include "rend/gui.h"
|
|
||||||
|
|
||||||
class EvdevGamepadDevice : public GamepadDevice
|
class EvdevGamepadDevice : public GamepadDevice
|
||||||
{
|
{
|
||||||
|
|
|
@ -418,17 +418,21 @@ static void detect_input_popup(int index, bool analog)
|
||||||
ImGui::Text("Time out in %d s", (int)(5 - (now - map_start_time)));
|
ImGui::Text("Time out in %d s", (int)(5 - (now - map_start_time)));
|
||||||
if (mapped_code != -1)
|
if (mapped_code != -1)
|
||||||
{
|
{
|
||||||
if (analog)
|
InputMapping *input_mapping = mapped_device->get_input_mapping();
|
||||||
|
if (input_mapping != NULL)
|
||||||
{
|
{
|
||||||
u32 previous_mapping = mapped_device->get_input_mapping()->get_axis_code(axis_keys[index]);
|
if (analog)
|
||||||
bool inverted = false;
|
{
|
||||||
if (previous_mapping != -1)
|
u32 previous_mapping = input_mapping->get_axis_code(axis_keys[index]);
|
||||||
inverted = mapped_device->get_input_mapping()->get_axis_inverted(previous_mapping);
|
bool inverted = false;
|
||||||
// FIXME Allow inverted to be set
|
if (previous_mapping != -1)
|
||||||
mapped_device->get_input_mapping()->set_axis(axis_keys[index], mapped_code, inverted);
|
inverted = input_mapping->get_axis_inverted(previous_mapping);
|
||||||
|
// FIXME Allow inverted to be set
|
||||||
|
input_mapping->set_axis(axis_keys[index], mapped_code, inverted);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
input_mapping->set_button(button_keys[index], mapped_code);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mapped_device->get_input_mapping()->set_button(button_keys[index], mapped_code);
|
|
||||||
mapped_device = NULL;
|
mapped_device = NULL;
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
|
@ -456,7 +460,8 @@ static void controller_mapping_popup(std::shared_ptr<GamepadDevice> gamepad)
|
||||||
- (col0_width + ImGui::GetStyle().ItemSpacing.x)
|
- (col0_width + ImGui::GetStyle().ItemSpacing.x)
|
||||||
- (ImGui::CalcTextSize("Map").x + ImGui::GetStyle().FramePadding.x * 2.0f + ImGui::GetStyle().ItemSpacing.x);
|
- (ImGui::CalcTextSize("Map").x + ImGui::GetStyle().FramePadding.x * 2.0f + ImGui::GetStyle().ItemSpacing.x);
|
||||||
|
|
||||||
if (ImGui::Button("Done", ImVec2(100 * scaling, 30 * scaling)))
|
InputMapping *input_mapping = gamepad->get_input_mapping();
|
||||||
|
if (input_mapping == NULL || ImGui::Button("Done", ImVec2(100 * scaling, 30 * scaling)))
|
||||||
{
|
{
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
gamepad->save_mapping();
|
gamepad->save_mapping();
|
||||||
|
@ -477,7 +482,7 @@ static void controller_mapping_popup(std::shared_ptr<GamepadDevice> gamepad)
|
||||||
ImGui::PushID(key_id);
|
ImGui::PushID(key_id);
|
||||||
ImGui::Text("%s", button_names[j]);
|
ImGui::Text("%s", button_names[j]);
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
u32 code = gamepad->get_input_mapping()->get_button_code(button_keys[j]);
|
u32 code = input_mapping->get_button_code(button_keys[j]);
|
||||||
if (code != -1)
|
if (code != -1)
|
||||||
ImGui::Text("%d", code);
|
ImGui::Text("%d", code);
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
|
@ -511,7 +516,7 @@ static void controller_mapping_popup(std::shared_ptr<GamepadDevice> gamepad)
|
||||||
ImGui::PushID(key_id);
|
ImGui::PushID(key_id);
|
||||||
ImGui::Text("%s", axis_names[j]);
|
ImGui::Text("%s", axis_names[j]);
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
u32 code = gamepad->get_input_mapping()->get_axis_code(axis_keys[j]);
|
u32 code = input_mapping->get_axis_code(axis_keys[j]);
|
||||||
if (code != -1)
|
if (code != -1)
|
||||||
ImGui::Text("%d", code);
|
ImGui::Text("%d", code);
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "oslib\audiostream.h"
|
#include "oslib\audiostream.h"
|
||||||
#include "imgread\common.h"
|
#include "imgread\common.h"
|
||||||
#include "rend\gui.h"
|
#include "rend\gui.h"
|
||||||
|
#include "xinput_gamepad.h"
|
||||||
|
|
||||||
#define _WIN32_WINNT 0x0500
|
#define _WIN32_WINNT 0x0500
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -122,6 +123,7 @@ void os_SetupInput()
|
||||||
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
|
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
|
||||||
mcfg_CreateDevices();
|
mcfg_CreateDevices();
|
||||||
#endif
|
#endif
|
||||||
|
XInputGamepadDevice::CreateDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo)
|
LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
|
@ -293,40 +295,10 @@ void UpdateInputState(u32 port)
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateController(u32 port)
|
void UpdateController(u32 port)
|
||||||
{
|
{
|
||||||
XINPUT_STATE state;
|
std::shared_ptr<XInputGamepadDevice> gamepad = XInputGamepadDevice::GetXInputDevice(port);
|
||||||
|
if (gamepad != NULL)
|
||||||
if (XInputGetState(port, &state) == 0)
|
gamepad->ReadInput();
|
||||||
{
|
|
||||||
WORD xbutton = state.Gamepad.wButtons;
|
|
||||||
|
|
||||||
if (xbutton & XINPUT_GAMEPAD_A)
|
|
||||||
kcode[port] &= ~key_CONT_A;
|
|
||||||
if (xbutton & XINPUT_GAMEPAD_B)
|
|
||||||
kcode[port] &= ~key_CONT_B;
|
|
||||||
if (xbutton & XINPUT_GAMEPAD_Y)
|
|
||||||
kcode[port] &= ~key_CONT_Y;
|
|
||||||
if (xbutton & XINPUT_GAMEPAD_X)
|
|
||||||
kcode[port] &= ~key_CONT_X;
|
|
||||||
|
|
||||||
if (xbutton & XINPUT_GAMEPAD_START)
|
|
||||||
kcode[port] &= ~key_CONT_START;
|
|
||||||
|
|
||||||
if (xbutton & XINPUT_GAMEPAD_DPAD_UP)
|
|
||||||
kcode[port] &= ~key_CONT_DPAD_UP;
|
|
||||||
if (xbutton & XINPUT_GAMEPAD_DPAD_DOWN)
|
|
||||||
kcode[port] &= ~key_CONT_DPAD_DOWN;
|
|
||||||
if (xbutton & XINPUT_GAMEPAD_DPAD_LEFT)
|
|
||||||
kcode[port] &= ~key_CONT_DPAD_LEFT;
|
|
||||||
if (xbutton & XINPUT_GAMEPAD_DPAD_RIGHT)
|
|
||||||
kcode[port] &= ~key_CONT_DPAD_RIGHT;
|
|
||||||
|
|
||||||
lt[port] |= state.Gamepad.bLeftTrigger;
|
|
||||||
rt[port] |= state.Gamepad.bRightTrigger;
|
|
||||||
|
|
||||||
joyx[port] |= state.Gamepad.sThumbLX / 257;
|
|
||||||
joyy[port] |= -state.Gamepad.sThumbLY / 257;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateVibration(u32 port, u32 value)
|
void UpdateVibration(u32 port, u32 value)
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
#include "../input/gamepad_device.h"
|
||||||
|
#include <Xinput.h>
|
||||||
|
|
||||||
|
class XInputMapping : public InputMapping
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XInputMapping()
|
||||||
|
{
|
||||||
|
name = "XInput";
|
||||||
|
set_button(DC_BTN_A, XINPUT_GAMEPAD_A);
|
||||||
|
set_button(DC_BTN_B, XINPUT_GAMEPAD_B);
|
||||||
|
set_button(DC_BTN_X, XINPUT_GAMEPAD_X);
|
||||||
|
set_button(DC_BTN_Y, XINPUT_GAMEPAD_Y);
|
||||||
|
set_button(DC_DPAD_UP, XINPUT_GAMEPAD_DPAD_UP);
|
||||||
|
set_button(DC_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_DOWN);
|
||||||
|
set_button(DC_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_LEFT);
|
||||||
|
set_button(DC_DPAD_RIGHT, XINPUT_GAMEPAD_DPAD_RIGHT);
|
||||||
|
set_button(DC_BTN_START, XINPUT_GAMEPAD_START);
|
||||||
|
set_button(EMU_BTN_TRIGGER_LEFT, XINPUT_GAMEPAD_LEFT_SHOULDER);
|
||||||
|
set_button(EMU_BTN_TRIGGER_RIGHT, XINPUT_GAMEPAD_RIGHT_SHOULDER);
|
||||||
|
set_button(EMU_BTN_MENU, XINPUT_GAMEPAD_BACK);
|
||||||
|
set_axis(DC_AXIS_LT, 0, false);
|
||||||
|
set_axis(DC_AXIS_RT, 1, false);
|
||||||
|
set_axis(DC_AXIS_X, 2, false);
|
||||||
|
set_axis(DC_AXIS_Y, 3, false);
|
||||||
|
set_axis(DC_AXIS_X2, 4, false);
|
||||||
|
set_axis(DC_AXIS_Y2, 5, false);
|
||||||
|
dirty = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class XInputGamepadDevice : public GamepadDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XInputGamepadDevice(int maple_port, int xinput_port)
|
||||||
|
: GamepadDevice(maple_port, "xinput"), _xinput_port(xinput_port)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadInput()
|
||||||
|
{
|
||||||
|
XINPUT_STATE state;
|
||||||
|
|
||||||
|
if (XInputGetState(_xinput_port, &state) == 0)
|
||||||
|
{
|
||||||
|
if (input_mapper == NULL)
|
||||||
|
Open();
|
||||||
|
u32 xbutton = state.Gamepad.wButtons;
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
gamepad_btn_input(1 << i, (xbutton & (1 << i)) != 0);
|
||||||
|
}
|
||||||
|
gamepad_axis_input(0, state.Gamepad.bLeftTrigger);
|
||||||
|
gamepad_axis_input(1, state.Gamepad.bRightTrigger);
|
||||||
|
gamepad_axis_input(2, state.Gamepad.sThumbLX);
|
||||||
|
gamepad_axis_input(3, state.Gamepad.sThumbLY);
|
||||||
|
gamepad_axis_input(4, state.Gamepad.sThumbRX);
|
||||||
|
gamepad_axis_input(5, state.Gamepad.sThumbRY);
|
||||||
|
}
|
||||||
|
else if (input_mapper != NULL)
|
||||||
|
{
|
||||||
|
printf("xinput: Controller '%s' on port %d disconnected\n", _name.c_str(), _xinput_port);
|
||||||
|
GamepadDevice::Unregister(xinput_gamepads[_xinput_port]);
|
||||||
|
input_mapper = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Open()
|
||||||
|
{
|
||||||
|
JOYCAPS joycaps;
|
||||||
|
int rc = joyGetDevCaps(_xinput_port, &joycaps, sizeof(joycaps));
|
||||||
|
if (rc != 0)
|
||||||
|
_name = "xinput" + std::to_string(_xinput_port);
|
||||||
|
else
|
||||||
|
_name = joycaps.szPname;
|
||||||
|
printf("xinput: Opened controller '%s' on port %d ", _name.c_str(), _xinput_port);
|
||||||
|
if (!find_mapping())
|
||||||
|
{
|
||||||
|
input_mapper = new XInputMapping();
|
||||||
|
input_mapper->name = _name + " mapping";
|
||||||
|
save_mapping();
|
||||||
|
printf("using default mapping\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("using custom mapping '%s'\n", input_mapper->name.c_str());
|
||||||
|
GamepadDevice::Register(xinput_gamepads[_xinput_port]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateDevices()
|
||||||
|
{
|
||||||
|
for (int port = 0; port < XUSER_MAX_COUNT; port++)
|
||||||
|
xinput_gamepads[port] = std::make_shared<XInputGamepadDevice>(port, port);
|
||||||
|
}
|
||||||
|
static void CloseDevices()
|
||||||
|
{
|
||||||
|
for (int port = 0; port < XUSER_MAX_COUNT; port++)
|
||||||
|
GamepadDevice::Unregister(xinput_gamepads[port]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<XInputGamepadDevice> GetXInputDevice(int port)
|
||||||
|
{
|
||||||
|
return xinput_gamepads[port];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void load_axis_min_max(u32 axis) override
|
||||||
|
{
|
||||||
|
if (axis == 0 || axis == 1)
|
||||||
|
{
|
||||||
|
axis_ranges[axis] = 255;
|
||||||
|
axis_min_values[axis] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
axis_ranges[axis] = 65535;
|
||||||
|
axis_min_values[axis] = -32768;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const int _xinput_port;
|
||||||
|
static std::vector<std::shared_ptr<XInputGamepadDevice>> xinput_gamepads;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<XInputGamepadDevice>> XInputGamepadDevice::xinput_gamepads(XUSER_MAX_COUNT);
|
Loading…
Reference in New Issue