Add support for gamepads (hardcoded to be the first).

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2020-10-15 12:55:27 +01:00
parent 4866867d06
commit e8972aa824
4 changed files with 73 additions and 1 deletions

View file

@ -4,6 +4,7 @@ add_executable(sa2
main.cpp
bitmaps.cpp
emulator.cpp
gamepad.cpp
)
find_package(Boost REQUIRED

View file

@ -0,0 +1,42 @@
#include "StdAfx.h"
#include "frontends/sa2/gamepad.h"
#include "Log.h"
#define AXIS_MIN -32768
#define AXIS_MAX 32767
Gamepad::Gamepad(const int index)
: myButtonCodes(2), myAxisCodes(2)
{
myController.reset(SDL_GameControllerOpen(index), SDL_GameControllerClose);
myButtonCodes[0] = SDL_CONTROLLER_BUTTON_A;
myButtonCodes[1] = SDL_CONTROLLER_BUTTON_B;
myAxisCodes[0] = SDL_CONTROLLER_AXIS_LEFTX;
myAxisCodes[1] = SDL_CONTROLLER_AXIS_LEFTY;
}
bool Gamepad::getButton(int i) const
{
int value = 0;
if (myController)
{
value = SDL_GameControllerGetButton(myController.get(), myButtonCodes[i]);
}
return value != 0;
}
int Gamepad::getAxis(int i) const
{
if (myController)
{
const int value = SDL_GameControllerGetAxis(myController.get(), myAxisCodes[i]);
int pdl = 255 * (value - AXIS_MIN) / (AXIS_MAX - AXIS_MIN);
return pdl;
}
else
{
return 0;
}
}

View file

@ -0,0 +1,23 @@
#pragma once
#include "linux/paddle.h"
#include <SDL.h>
#include <vector>
#include <memory>
class Gamepad : public Paddle
{
public:
Gamepad(const int index);
virtual bool getButton(int i) const;
virtual int getAxis(int i) const;
private:
std::shared_ptr<SDL_GameController> myController;
std::vector<SDL_GameControllerButton> myButtonCodes;
std::vector<SDL_GameControllerAxis> myAxisCodes;
};

View file

@ -11,6 +11,7 @@
#include "frontends/common2/utils.h"
#include "frontends/common2/programoptions.h"
#include "frontends/sa2/emulator.h"
#include "frontends/sa2/gamepad.h"
#include "StdAfx.h"
#include "Common.h"
@ -159,6 +160,8 @@ void run_sdl(int argc, const char * argv [])
InitializeRegistry(options);
Paddle::instance().reset(new Gamepad(0));
g_nMemoryClearType = options.memclear;
initialiseEmulator();
@ -206,7 +209,7 @@ void run_sdl(int argc, const char * argv [])
int main(int argc, const char * argv [])
{
//First we need to start up SDL, and make sure it went ok
if (SDL_Init(SDL_INIT_VIDEO) != 0)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) != 0)
{
std::cerr << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
@ -224,6 +227,9 @@ int main(int argc, const char * argv [])
std::cerr << e.what() << std::endl;
}
// this must happen BEFORE the SDL_Quit() as otherwise we have a double free (of the game controller).
Paddle::instance().reset();
SDL_Quit();
return exit;