- [EMU] analog controller support in LIBPAD

This commit is contained in:
Ilya Shurumov 2020-10-21 00:47:52 +06:00
parent 728bbfc95a
commit 139aa1bc3e

View File

@ -16,7 +16,7 @@ void PadInitDirect(unsigned char* pad1, unsigned char* pad2)
padData[0] = pad1;
PADRAW* pad = (PADRAW*)pad1;
pad->status = 0xFF;
pad->id = 0x41; // always init first controller
pad->id = 0;
pad->analog[0] = 128;
pad->analog[1] = 128;
@ -157,91 +157,103 @@ void PadSetAct(int unk00, unsigned char* unk01, int unk02)
UNIMPLEMENTED();
}
unsigned short UpdateGameControllerInput(SDL_GameController* pad)
void UpdateGameControllerInput(SDL_GameController* cont, PADRAW* pad)
{
unsigned short ret = 0xFFFF;
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_X))//Square
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_X))//Square
{
ret &= ~0x8000;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_B))//Circle
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_B))//Circle
{
ret &= ~0x2000;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_Y))//Triangle
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_Y))//Triangle
{
ret &= ~0x1000;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_A))//Cross
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_A))//Cross
{
ret &= ~0x4000;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_LEFTSHOULDER))//L1
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_LEFTSHOULDER))//L1
{
ret &= ~0x400;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER))//R1
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER))//R1
{
ret &= ~0x800;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_DPAD_UP))//UP
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_DPAD_UP))//UP
{
ret &= ~0x10;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_DPAD_DOWN))//DOWN
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_DPAD_DOWN))//DOWN
{
ret &= ~0x40;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_DPAD_LEFT))//LEFT
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_DPAD_LEFT))//LEFT
{
ret &= ~0x80;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))//RIGHT
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))//RIGHT
{
ret &= ~0x20;
}
if (SDL_GameControllerGetAxis(pad, SDL_CONTROLLER_AXIS_TRIGGERLEFT))//L2
if (SDL_GameControllerGetAxis(cont, SDL_CONTROLLER_AXIS_TRIGGERLEFT))//L2
{
ret &= ~0x100;
}
if (SDL_GameControllerGetAxis(pad, SDL_CONTROLLER_AXIS_TRIGGERRIGHT))//R2
if (SDL_GameControllerGetAxis(cont, SDL_CONTROLLER_AXIS_TRIGGERRIGHT))//R2
{
ret &= ~0x200;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_LEFTSTICK))//L3
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_LEFTSTICK))//L3
{
ret &= ~0x2;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_RIGHTSTICK))//R3
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_RIGHTSTICK))//R3
{
ret &= ~0x4;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_BACK))//SELECT
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_BACK))//SELECT
{
ret &= ~0x1;
}
if (SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_START))//START
if (SDL_GameControllerGetButton(cont, SDL_CONTROLLER_BUTTON_START))//START
{
ret &= ~0x8;
}
short leftX = SDL_GameControllerGetAxis(cont, SDL_CONTROLLER_AXIS_LEFTX);
short leftY = SDL_GameControllerGetAxis(cont, SDL_CONTROLLER_AXIS_LEFTY);
short rightX = SDL_GameControllerGetAxis(cont, SDL_CONTROLLER_AXIS_RIGHTX);
short rightY = SDL_GameControllerGetAxis(cont, SDL_CONTROLLER_AXIS_RIGHTY);
return ret;
*(unsigned short*)pad->buttons = ret;
// map to range
pad->analog[0] = (rightX / 256) + 128;
pad->analog[1] = (rightY / 256) + 128;
pad->analog[2] = (leftX / 256) + 128;
pad->analog[3] = (leftY / 256) + 128;
}
unsigned short UpdateKeyboardInput()
@ -342,19 +354,32 @@ void InternalPadUpdates()
{
if (padHandle[i] != NULL)
{
unsigned short controllerInputs = UpdateGameControllerInput(padHandle[i]);
PADRAW* pad = (PADRAW*)padData[i];
UpdateGameControllerInput(padHandle[i], pad);
pad->status = 0; // PadStateStable?
pad->id = 0x41;
*(unsigned short*)pad->buttons = controllerInputs;
pad->analog[0] = 128;
pad->analog[1] = 128;
pad->analog[2] = 128;
pad->analog[3] = 128;
// switch to analog state
if(pad->analog[0] != 127 ||
pad->analog[1] != 127 ||
pad->analog[2] != 127 ||
pad->analog[3] != 127 ||
pad->id == 0x41)
{
eprintf("Switched controller type to ANALOG\n");
pad->id = 0x73;
}
if (activeControllers & 0x1)
{
// switch state
if(kbInputs != 0xFFFF && pad->id == 0x73)
{
eprintf("Switched controller type to SIMPLE\n");
pad->id = 0x41;
}
*(unsigned short*)pad->buttons &= kbInputs;
}
}
@ -370,10 +395,10 @@ void InternalPadUpdates()
pad->status = 0; // PadStateStable?
pad->id = 0x41;
*(unsigned short*)pad->buttons = kbInputs;
pad->analog[0] = 128;
pad->analog[1] = 128;
pad->analog[2] = 128;
pad->analog[3] = 128;
pad->analog[0] = 127; // TODO: mouse?
pad->analog[1] = 127;
pad->analog[2] = 127;
pad->analog[3] = 127;
}
}