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)
{
case EMU_BTN_ESCAPE:
dc_stop();
if (pressed)
dc_stop();
break;
case EMU_BTN_MENU:
gui_open_settings();
if (pressed)
gui_open_settings();
break;
case EMU_BTN_TRIGGER_LEFT:
lt[_maple_port] = pressed ? 255 : 0;

View File

@ -51,7 +51,7 @@ public:
}
InputMapping *get_input_mapping() { return input_mapper; }
void save_mapping();
bool remappable() { return _remappable; }
bool remappable() { return _remappable && input_mapper != NULL; }
static void Register(std::shared_ptr<GamepadDevice> gamepad)
{

View File

@ -1,6 +1,5 @@
#include "../input/gamepad_device.h"
#include "evdev.h"
#include "rend/gui.h"
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)));
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]);
bool inverted = false;
if (previous_mapping != -1)
inverted = mapped_device->get_input_mapping()->get_axis_inverted(previous_mapping);
// FIXME Allow inverted to be set
mapped_device->get_input_mapping()->set_axis(axis_keys[index], mapped_code, inverted);
if (analog)
{
u32 previous_mapping = input_mapping->get_axis_code(axis_keys[index]);
bool inverted = false;
if (previous_mapping != -1)
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;
ImGui::CloseCurrentPopup();
}
@ -456,7 +460,8 @@ static void controller_mapping_popup(std::shared_ptr<GamepadDevice> gamepad)
- (col0_width + 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();
gamepad->save_mapping();
@ -477,7 +482,7 @@ static void controller_mapping_popup(std::shared_ptr<GamepadDevice> gamepad)
ImGui::PushID(key_id);
ImGui::Text("%s", button_names[j]);
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)
ImGui::Text("%d", code);
ImGui::NextColumn();
@ -511,7 +516,7 @@ static void controller_mapping_popup(std::shared_ptr<GamepadDevice> gamepad)
ImGui::PushID(key_id);
ImGui::Text("%s", axis_names[j]);
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)
ImGui::Text("%d", code);
ImGui::NextColumn();

View File

@ -2,6 +2,7 @@
#include "oslib\audiostream.h"
#include "imgread\common.h"
#include "rend\gui.h"
#include "xinput_gamepad.h"
#define _WIN32_WINNT 0x0500
#include <windows.h>
@ -122,6 +123,7 @@ void os_SetupInput()
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
mcfg_CreateDevices();
#endif
XInputGamepadDevice::CreateDevices();
}
LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo)
@ -293,40 +295,10 @@ void UpdateInputState(u32 port)
}
void UpdateController(u32 port)
{
XINPUT_STATE state;
if (XInputGetState(port, &state) == 0)
{
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;
}
{
std::shared_ptr<XInputGamepadDevice> gamepad = XInputGamepadDevice::GetXInputDevice(port);
if (gamepad != NULL)
gamepad->ReadInput();
}
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);