Files
z80/gamepad.cpp

186 lines
6.9 KiB
C++

#include "gamepad.h"
#include <SDL2/SDL.h>
#include "zx_ula.h"
#include <vector>
#define GAMEPAD_BUTTON_LEFT 0
#define GAMEPAD_BUTTON_RIGHT 1
#define GAMEPAD_BUTTON_UP 2
#define GAMEPAD_BUTTON_DOWN 3
#define GAMEPAD_BUTTON_FIRE 4
namespace gamepad
{
struct gamepad_t
{
SDL_GameController *gamepad;
int32_t index;
uint8_t type;
bool buttons[5] { false, false, false, false, false };
};
std::vector<gamepad_t> gamepads;
uint8_t getNextType()
{
uint8_t next_type = GAMEPAD_TYPE_SINCLAIR_1;
bool found = false;
while (!found)
{
found = true;
for (auto gamepad : gamepads)
{
if (gamepad.type == next_type)
{
found = false;
next_type++;
if (next_type == GAMEPAD_TYPE_CUSTOM) return next_type;
break;
}
}
}
return next_type;
}
uint8_t add(int32_t index, uint8_t type)
{
if (SDL_IsGameController(index)) {
gamepad_t gamepad;
gamepad.gamepad = SDL_GameControllerOpen(index);
if (SDL_GameControllerGetAttached(gamepad.gamepad) == SDL_TRUE) SDL_GameControllerEventState(SDL_ENABLE);
gamepad.index = index;
gamepad.type = ( (type == GAMEPAD_TYPE_ANY) ? getNextType() : type );
gamepads.push_back(gamepad);
}
return gamepads.size()-1;
}
void modify(int32_t index, uint8_t type)
{
for (auto& gamepad : gamepads)
{
if (gamepad.index == index)
{
gamepad.type = type;
return;
}
}
}
void remove(int32_t index)
{
SDL_GameController *game_controller = SDL_GameControllerFromInstanceID(index);
for (int i=0; i<gamepads.size(); ++i)
{
if (gamepads[i].gamepad == game_controller) gamepads.erase(gamepads.begin()+i);
}
SDL_GameControllerClose(game_controller);
}
void buttonDown(int32_t index, uint8_t button)
{
SDL_GameController *game_controller = SDL_GameControllerFromInstanceID(index);
for (auto& gamepad : gamepads)
{
if (gamepad.gamepad == game_controller)
{
switch(button)
{
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: gamepad.buttons[GAMEPAD_BUTTON_LEFT]=true; break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: gamepad.buttons[GAMEPAD_BUTTON_RIGHT]=true; break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: gamepad.buttons[GAMEPAD_BUTTON_DOWN]=true; break;
case SDL_CONTROLLER_BUTTON_DPAD_UP: gamepad.buttons[GAMEPAD_BUTTON_UP]=true; break;
case SDL_CONTROLLER_BUTTON_A: gamepad.buttons[GAMEPAD_BUTTON_FIRE]=true; break;
}
switch(gamepad.type)
{
case GAMEPAD_TYPE_SINCLAIR_1:
switch(button)
{
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: zx_ula::keydown('1'); break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: zx_ula::keydown('2'); break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: zx_ula::keydown('3'); break;
case SDL_CONTROLLER_BUTTON_DPAD_UP: zx_ula::keydown('4'); break;
case SDL_CONTROLLER_BUTTON_A: zx_ula::keydown('5'); break;
}
break;
case GAMEPAD_TYPE_SINCLAIR_2:
switch(button)
{
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: zx_ula::keydown('6'); break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: zx_ula::keydown('7'); break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: zx_ula::keydown('8'); break;
case SDL_CONTROLLER_BUTTON_DPAD_UP: zx_ula::keydown('9'); break;
case SDL_CONTROLLER_BUTTON_A: zx_ula::keydown('0'); break;
}
break;
}
return;
}
}
}
void buttonUp(int32_t index, uint8_t button)
{
SDL_GameController *game_controller = SDL_GameControllerFromInstanceID(index);
for (auto& gamepad : gamepads)
{
if (gamepad.gamepad == game_controller)
{
switch(button)
{
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: gamepad.buttons[GAMEPAD_BUTTON_LEFT]=false; break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: gamepad.buttons[GAMEPAD_BUTTON_RIGHT]=false; break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: gamepad.buttons[GAMEPAD_BUTTON_DOWN]=false; break;
case SDL_CONTROLLER_BUTTON_DPAD_UP: gamepad.buttons[GAMEPAD_BUTTON_UP]=false; break;
case SDL_CONTROLLER_BUTTON_A: gamepad.buttons[GAMEPAD_BUTTON_FIRE]=false; break;
}
switch(gamepad.type)
{
case GAMEPAD_TYPE_SINCLAIR_1:
switch(button)
{
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: zx_ula::keyup('1'); break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: zx_ula::keyup('2'); break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: zx_ula::keyup('3'); break;
case SDL_CONTROLLER_BUTTON_DPAD_UP: zx_ula::keyup('4'); break;
case SDL_CONTROLLER_BUTTON_A: zx_ula::keyup('5'); break;
}
break;
case GAMEPAD_TYPE_SINCLAIR_2:
switch(button)
{
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: zx_ula::keyup('6'); break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: zx_ula::keyup('7'); break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: zx_ula::keyup('8'); break;
case SDL_CONTROLLER_BUTTON_DPAD_UP: zx_ula::keyup('9'); break;
case SDL_CONTROLLER_BUTTON_A: zx_ula::keyup('0'); break;
}
break;
}
return;
}
}
}
uint8_t getNumGamepads()
{
return gamepads.size();
}
uint8_t getGamepadType(uint8_t index)
{
if (gamepads.size()>index) return gamepads[index].type;
return 0;
}
void setGamepadType(uint8_t index, uint8_t type)
{
if (gamepads.size()>index) gamepads[index].type = type;
}
}