Add support for retropads, with and without analog extension.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2020-12-23 16:38:22 +00:00
parent eae49b3f41
commit a1f67585d9
10 changed files with 114 additions and 39 deletions

View file

@ -12,7 +12,9 @@ if (IS_DIRECTORY ${LIBRETRO_PATH})
rdirectsound.cpp
interface.cpp
game.cpp
joypadbase.cpp
joypad.cpp
analog.cpp
)
target_include_directories(ra2 PRIVATE

View file

@ -0,0 +1,22 @@
#include "frontends/retro/analog.h"
#include "frontends/retro/environment.h"
#include "libretro.h"
#define AXIS_MIN -32768
#define AXIS_MAX 32767
Analog::Analog()
: myAxisCodes(2)
{
myAxisCodes[0] = std::make_pair(RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
myAxisCodes[1] = std::make_pair(RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y);
}
double Analog::getAxis(int i) const
{
const auto & code = myAxisCodes[i];
const int value = input_state_cb(0, RETRO_DEVICE_ANALOG, code.first, code.second);
const double axis = 2.0 * double(value - AXIS_MIN) / double(AXIS_MAX - AXIS_MIN) - 1.0;
return axis;
}

View file

@ -0,0 +1,17 @@
#pragma once
#include "frontends/retro/joypadbase.h"
#include <vector>
class Analog : public JoypadBase
{
public:
Analog();
virtual double getAxis(int i) const;
private:
std::vector<std::pair<unsigned, unsigned> > myAxisCodes;
};

View file

@ -24,5 +24,3 @@ retro_audio_sample_t audio_cb;
retro_audio_sample_batch_t audio_batch_cb;
std::string retro_base_directory;
unsigned int retro_devices[RETRO_DEVICES] = {};

View file

@ -13,7 +13,3 @@ extern retro_audio_sample_t audio_cb;
extern retro_audio_sample_batch_t audio_batch_cb;
extern std::string retro_base_directory;
#define RETRO_DEVICES 1
extern unsigned int retro_devices[RETRO_DEVICES];

View file

@ -5,24 +5,14 @@
Joypad::Joypad()
: myButtonCodes(2), myAxisCodes(2)
: myAxisCodes(2)
{
myButtonCodes[0] = RETRO_DEVICE_ID_JOYPAD_A;
myButtonCodes[1] = RETRO_DEVICE_ID_JOYPAD_B;
myAxisCodes[0][RETRO_DEVICE_ID_JOYPAD_LEFT] = -1.0;
myAxisCodes[0][RETRO_DEVICE_ID_JOYPAD_RIGHT] = 1.0;
myAxisCodes[1][RETRO_DEVICE_ID_JOYPAD_UP] = -1.0;
myAxisCodes[1][RETRO_DEVICE_ID_JOYPAD_DOWN] = 1.0;
}
bool Joypad::getButton(int i) const
{
const int value = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, myButtonCodes[i]);
// if (value)
// log_cb(RETRO_LOG_INFO, "Joypad button: %d.\n", value);
return value != 0;
}
double Joypad::getAxis(int i) const
{
for (const auto & axis : myAxisCodes[i])
@ -30,7 +20,6 @@ double Joypad::getAxis(int i) const
const int value = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, axis.first);
if (value)
{
// log_cb(RETRO_LOG_INFO, "Joypad axis: %d.\n", value);
return axis.second;
}
}

View file

@ -1,20 +1,18 @@
#pragma once
#include "linux/paddle.h"
#include "frontends/retro/joypadbase.h"
#include <vector>
#include <map>
class Joypad : public Paddle
class Joypad : public JoypadBase
{
public:
Joypad();
virtual bool getButton(int i) const;
virtual double getAxis(int i) const;
private:
std::vector<unsigned> myButtonCodes;
std::vector<std::map<unsigned, double> > myAxisCodes;
};

View file

@ -0,0 +1,18 @@
#include "frontends/retro/joypadbase.h"
#include "frontends/retro/environment.h"
#include "libretro.h"
JoypadBase::JoypadBase()
: myButtonCodes(2)
{
myButtonCodes[0] = RETRO_DEVICE_ID_JOYPAD_A;
myButtonCodes[1] = RETRO_DEVICE_ID_JOYPAD_B;
}
bool JoypadBase::getButton(int i) const
{
const int value = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, myButtonCodes[i]);
return value != 0;
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "linux/paddle.h"
#include <vector>
#include <map>
class JoypadBase : public Paddle
{
public:
JoypadBase();
virtual bool getButton(int i) const;
private:
std::vector<unsigned> myButtonCodes;
};

View file

@ -11,6 +11,7 @@
#include "frontends/retro/game.h"
#include "frontends/retro/environment.h"
#include "frontends/retro/joypad.h"
#include "frontends/retro/analog.h"
namespace
{
@ -40,11 +41,27 @@ unsigned retro_api_version(void)
void retro_set_controller_port_device(unsigned port, unsigned device)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
log_cb(RETRO_LOG_INFO, "Plugging device %u into port %u.\n", device, port);
log_cb(RETRO_LOG_INFO, "RA2: %s, Plugging device %u into port %u.\n", __FUNCTION__, device, port);
if (port < RETRO_DEVICES)
retro_devices[port] = device;
if (port == 0)
{
switch (device)
{
case RETRO_DEVICE_NONE:
Paddle::instance().reset();
break;
case RETRO_DEVICE_JOYPAD:
Paddle::instance().reset(new Joypad);
Paddle::setSquaring(false);
break;
case RETRO_DEVICE_ANALOG:
Paddle::instance().reset(new Analog);
Paddle::setSquaring(true);
break;
default:
break;
}
}
}
void retro_get_system_info(retro_system_info *info)
@ -84,19 +101,22 @@ void retro_set_environment(retro_environment_t cb)
else
log_cb = fallback_log;
static const struct retro_controller_description controllers[] = {
{ "Nintendo DS", RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0) },
};
static const struct retro_controller_description controllers[] =
{
{ "Standard Joypad", RETRO_DEVICE_JOYPAD },
{ "Analog Joypad", RETRO_DEVICE_ANALOG }
};
static const struct retro_controller_info ports[] = {
{ controllers, 1 },
{ NULL, 0 },
};
static const struct retro_controller_info ports[] =
{
{ controllers, sizeof(controllers) / sizeof(controllers[0]) },
{ nullptr, 0 }
};
cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
// retro_keyboard_callback callback = {&Game::keyboardCallback};
// cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &callback);
// retro_keyboard_callback callback = {&Game::keyboardCallback};
// cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &callback);
}
void retro_set_audio_sample(retro_audio_sample_t cb)
@ -154,9 +174,6 @@ bool retro_load_game(const retro_game_info *info)
log_cb(RETRO_LOG_INFO, "Game path: %s:%d\n", info->path, ok);
Paddle::instance().reset(new Joypad);
Paddle::setSquaring(false);
return ok;
}
catch (const std::exception & e)