win32: use new input system

This commit is contained in:
flyinghead 2019-02-21 17:57:51 +01:00
parent 4ae11053ce
commit 94f346a1e0
6 changed files with 155 additions and 50 deletions

View File

@ -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;

View File

@ -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)
{ {

View File

@ -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
{ {

View File

@ -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();

View File

@ -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)

View File

@ -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);