libretro: add namespace ra2 and remove tabs.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2021-02-25 16:24:52 +00:00
parent 3b917e93be
commit 56511affa2
17 changed files with 582 additions and 519 deletions

View file

@ -6,17 +6,22 @@
#define AXIS_MIN -32768
#define AXIS_MAX 32767
Analog::Analog()
: myAxisCodes(2)
namespace ra2
{
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;
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

@ -4,14 +4,18 @@
#include <vector>
class Analog : public JoypadBase
namespace ra2
{
public:
Analog();
double getAxis(int i) const override;
class Analog : public JoypadBase
{
public:
Analog();
private:
std::vector<std::pair<unsigned, unsigned> > myAxisCodes;
};
double getAxis(int i) const override;
private:
std::vector<std::pair<unsigned, unsigned> > myAxisCodes;
};
}

View file

@ -3,32 +3,36 @@
#include <cstdarg>
#include <iostream>
void fallback_log(enum retro_log_level level, const char *fmt, ...)
namespace ra2
{
(void)level;
va_list va;
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
}
retro_log_callback logging;
retro_log_printf_t log_cb = fallback_log;
retro_input_poll_t input_poll_cb;
retro_input_state_t input_state_cb;
retro_environment_t environ_cb;
retro_video_refresh_t video_cb;
retro_audio_sample_t audio_cb;
retro_audio_sample_batch_t audio_batch_cb;
std::string retro_base_directory;
void display_message(const std::string & message)
{
retro_message rmsg;
rmsg.frames = 180;
rmsg.msg = message.c_str();
environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &rmsg);
void fallback_log(enum retro_log_level level, const char *fmt, ...)
{
(void)level;
va_list va;
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
}
retro_log_callback logging;
retro_log_printf_t log_cb = fallback_log;
retro_input_poll_t input_poll_cb;
retro_input_state_t input_state_cb;
retro_environment_t environ_cb;
retro_video_refresh_t video_cb;
retro_audio_sample_t audio_cb;
retro_audio_sample_batch_t audio_batch_cb;
std::string retro_base_directory;
void display_message(const std::string & message)
{
retro_message rmsg;
rmsg.frames = 180;
rmsg.msg = message.c_str();
environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &rmsg);
}
}

View file

@ -2,18 +2,23 @@
#include <string>
void fallback_log(enum retro_log_level level, const char *fmt, ...);
extern retro_log_callback logging;
extern retro_log_printf_t log_cb;
extern retro_input_poll_t input_poll_cb;
extern retro_input_state_t input_state_cb;
extern retro_environment_t environ_cb;
extern retro_video_refresh_t video_cb;
extern retro_audio_sample_t audio_cb;
extern retro_audio_sample_batch_t audio_batch_cb;
namespace ra2
{
extern std::string retro_base_directory;
void fallback_log(enum retro_log_level level, const char *fmt, ...);
extern retro_log_callback logging;
extern retro_log_printf_t log_cb;
extern retro_input_poll_t input_poll_cb;
extern retro_input_state_t input_state_cb;
extern retro_environment_t environ_cb;
extern retro_video_refresh_t video_cb;
extern retro_audio_sample_t audio_cb;
extern retro_audio_sample_batch_t audio_batch_cb;
extern std::string retro_base_directory;
#define MAX_PADS 1
void display_message(const std::string & message);
void display_message(const std::string & message);
}

View file

@ -49,243 +49,248 @@ namespace
}
unsigned Game::ourInputDevices[MAX_PADS] = {RETRO_DEVICE_NONE};
Game::Game(const std::shared_ptr<RetroFrame> & frame)
: myFrame(frame), mySpeed(true), myButtonStates(RETRO_DEVICE_ID_JOYPAD_R3 + 1)
namespace ra2
{
SetFrame(myFrame);
LogInit();
InitialiseRetroRegistry();
myInit.reset(new common2::Initialisation);
unsigned Game::ourInputDevices[MAX_PADS] = {RETRO_DEVICE_NONE};
switch (ourInputDevices[0])
Game::Game(const std::shared_ptr<RetroFrame> & frame)
: myFrame(frame), mySpeed(true), myButtonStates(RETRO_DEVICE_ID_JOYPAD_R3 + 1)
{
case RETRO_DEVICE_NONE:
SetFrame(myFrame);
LogInit();
InitialiseRetroRegistry();
myInit.reset(new common2::Initialisation);
switch (ourInputDevices[0])
{
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;
}
}
Game::~Game()
{
myInit.reset();
SetFrame(std::shared_ptr<FrameBase>());
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;
Registry::instance.reset();
}
}
Game::~Game()
{
myInit.reset();
SetFrame(std::shared_ptr<FrameBase>());
Paddle::instance.reset();
Registry::instance.reset();
}
retro_usec_t Game::ourFrameTime = 0;
retro_usec_t Game::ourFrameTime = 0;
void Game::executeOneFrame()
{
const size_t cyclesToExecute = mySpeed.getCyclesTillNext(ourFrameTime);
if (g_nAppMode == MODE_RUNNING)
void Game::executeOneFrame()
{
const bool bVideoUpdate = true;
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame();
const size_t cyclesToExecute = mySpeed.getCyclesTillNext(ourFrameTime);
if (g_nAppMode == MODE_RUNNING)
{
const bool bVideoUpdate = true;
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame();
const DWORD executedCycles = CpuExecute(cyclesToExecute, bVideoUpdate);
const DWORD executedCycles = CpuExecute(cyclesToExecute, bVideoUpdate);
g_dwCyclesThisFrame = (g_dwCyclesThisFrame + executedCycles) % dwClksPerFrame;
GetCardMgr().GetDisk2CardMgr().UpdateDriveState(executedCycles);
MB_PeriodicUpdate(executedCycles);
SpkrUpdate(executedCycles);
g_dwCyclesThisFrame = (g_dwCyclesThisFrame + executedCycles) % dwClksPerFrame;
GetCardMgr().GetDisk2CardMgr().UpdateDriveState(executedCycles);
MB_PeriodicUpdate(executedCycles);
SpkrUpdate(executedCycles);
}
}
}
void Game::processInputEvents()
{
input_poll_cb();
keyboardEmulation();
}
void Game::keyboardCallback(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers)
{
if (down)
void Game::processInputEvents()
{
processKeyDown(keycode, character, key_modifiers);
input_poll_cb();
keyboardEmulation();
}
else
void Game::keyboardCallback(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers)
{
processKeyUp(keycode, character, key_modifiers);
if (down)
{
processKeyDown(keycode, character, key_modifiers);
}
else
{
processKeyUp(keycode, character, key_modifiers);
}
}
}
void Game::frameTimeCallback(retro_usec_t usec)
{
ourFrameTime = usec;
}
void Game::processKeyDown(unsigned keycode, uint32_t character, uint16_t key_modifiers)
{
BYTE ch = 0;
switch (keycode)
void Game::frameTimeCallback(retro_usec_t usec)
{
case RETROK_RETURN:
ourFrameTime = usec;
}
void Game::processKeyDown(unsigned keycode, uint32_t character, uint16_t key_modifiers)
{
BYTE ch = 0;
switch (keycode)
{
ch = 0x0d;
break;
}
case RETROK_BACKSPACE: // same as AppleWin
case RETROK_LEFT:
{
ch = 0x08;
break;
}
case RETROK_RIGHT:
{
ch = 0x15;
break;
}
case RETROK_UP:
{
ch = 0x0b;
break;
}
case RETROK_DOWN:
{
ch = 0x0a;
break;
}
case RETROK_DELETE:
{
ch = 0x7f;
break;
}
case RETROK_ESCAPE:
{
ch = 0x1b;
break;
}
case RETROK_TAB:
{
ch = 0x09;
break;
}
case RETROK_LALT:
{
Paddle::setButtonPressed(Paddle::ourOpenApple);
break;
}
case RETROK_RALT:
{
Paddle::setButtonPressed(Paddle::ourSolidApple);
break;
}
case RETROK_a ... RETROK_z:
{
ch = (keycode - RETROK_a) + 0x01;
if (key_modifiers & RETROKMOD_CTRL)
case RETROK_RETURN:
{
// ok
ch = 0x0d;
break;
}
else if (key_modifiers & RETROKMOD_SHIFT)
case RETROK_BACKSPACE: // same as AppleWin
case RETROK_LEFT:
{
ch += 0x60;
ch = 0x08;
break;
}
else
case RETROK_RIGHT:
{
ch += 0x40;
ch = 0x15;
break;
}
break;
case RETROK_UP:
{
ch = 0x0b;
break;
}
case RETROK_DOWN:
{
ch = 0x0a;
break;
}
case RETROK_DELETE:
{
ch = 0x7f;
break;
}
case RETROK_ESCAPE:
{
ch = 0x1b;
break;
}
case RETROK_TAB:
{
ch = 0x09;
break;
}
case RETROK_LALT:
{
Paddle::setButtonPressed(Paddle::ourOpenApple);
break;
}
case RETROK_RALT:
{
Paddle::setButtonPressed(Paddle::ourSolidApple);
break;
}
case RETROK_a ... RETROK_z:
{
ch = (keycode - RETROK_a) + 0x01;
if (key_modifiers & RETROKMOD_CTRL)
{
// ok
}
else if (key_modifiers & RETROKMOD_SHIFT)
{
ch += 0x60;
}
else
{
ch += 0x40;
}
break;
}
}
if (!ch)
{
switch (character) {
case 0x20 ... 0x40:
case 0x5b ... 0x60:
case 0x7b ... 0x7e:
{
// not the letters
// this is very simple, but one cannot handle CRTL-key combination.
ch = character;
break;
}
}
}
if (ch)
{
addKeyToBuffer(ch);
log_cb(RETRO_LOG_INFO, "RA2: %s - %02x\n", __FUNCTION__, ch);
}
}
if (!ch)
void Game::processKeyUp(unsigned keycode, uint32_t character, uint16_t key_modifiers)
{
switch (character) {
case 0x20 ... 0x40:
case 0x5b ... 0x60:
case 0x7b ... 0x7e:
switch (keycode)
{
case RETROK_LALT:
{
// not the letters
// this is very simple, but one cannot handle CRTL-key combination.
ch = character;
break;
Paddle::setButtonReleased(Paddle::ourOpenApple);
break;
}
case RETROK_RALT:
{
Paddle::setButtonReleased(Paddle::ourSolidApple);
break;
}
}
}
if (ch)
bool Game::checkButtonPressed(unsigned id)
{
addKeyToBuffer(ch);
log_cb(RETRO_LOG_INFO, "RA2: %s - %02x\n", __FUNCTION__, ch);
}
}
// pressed if it is down now, but was up before
const int value = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, id);
const bool pressed = (value != 0) && myButtonStates[id] == 0;
void Game::processKeyUp(unsigned keycode, uint32_t character, uint16_t key_modifiers)
{
switch (keycode)
// update to avoid multiple fires
myButtonStates[id] = value;
return pressed;
}
void Game::keyboardEmulation()
{
case RETROK_LALT:
if (ourInputDevices[0] != RETRO_DEVICE_NONE)
{
Paddle::setButtonReleased(Paddle::ourOpenApple);
break;
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_R))
{
myFrame->CycleVideoType();
}
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_L))
{
myFrame->Cycle50ScanLines();
}
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_START))
{
ResetMachineState();
}
}
case RETROK_RALT:
else
{
Paddle::setButtonReleased(Paddle::ourSolidApple);
break;
std::fill(myButtonStates.begin(), myButtonStates.end(), 0);
}
}
}
bool Game::checkButtonPressed(unsigned id)
{
// pressed if it is down now, but was up before
const int value = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, id);
const bool pressed = (value != 0) && myButtonStates[id] == 0;
// update to avoid multiple fires
myButtonStates[id] = value;
return pressed;
}
void Game::keyboardEmulation()
{
if (ourInputDevices[0] != RETRO_DEVICE_NONE)
bool Game::loadGame(const std::string & path)
{
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_R))
{
myFrame->CycleVideoType();
}
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_L))
{
myFrame->Cycle50ScanLines();
}
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_START))
{
ResetMachineState();
}
const bool ok = insertDisk(path);
return ok;
}
else
bool Game::loadSnapshot(const std::string & path)
{
std::fill(myButtonStates.begin(), myButtonStates.end(), 0);
common2::setSnapshotFilename(path, true);
return true;
}
}
bool Game::loadGame(const std::string & path)
{
const bool ok = insertDisk(path);
return ok;
}
bool Game::loadSnapshot(const std::string & path)
{
common2::setSnapshotFilename(path, true);
return true;
}

View file

@ -11,41 +11,46 @@ namespace common2
class Initialisation;
}
class RetroFrame;
class Game
namespace ra2
{
public:
Game(const std::shared_ptr<RetroFrame> & frame);
~Game();
bool loadGame(const std::string & path);
bool loadSnapshot(const std::string & path);
class RetroFrame;
void executeOneFrame();
void processInputEvents();
class Game
{
public:
Game(const std::shared_ptr<RetroFrame> & frame);
~Game();
void drawVideoBuffer();
bool loadGame(const std::string & path);
bool loadSnapshot(const std::string & path);
static void keyboardCallback(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers);
void executeOneFrame();
void processInputEvents();
static void frameTimeCallback(retro_usec_t usec);
static constexpr size_t FPS = 60;
static unsigned ourInputDevices[MAX_PADS];
static retro_usec_t ourFrameTime;
void drawVideoBuffer();
private:
const std::shared_ptr<RetroFrame> myFrame;
static void keyboardCallback(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers);
common2::Speed mySpeed; // fixed speed
static void frameTimeCallback(retro_usec_t usec);
static constexpr size_t FPS = 60;
static unsigned ourInputDevices[MAX_PADS];
static retro_usec_t ourFrameTime;
std::vector<int> myButtonStates;
private:
const std::shared_ptr<RetroFrame> myFrame;
std::shared_ptr<common2::Initialisation> myInit;
common2::Speed mySpeed; // fixed speed
bool checkButtonPressed(unsigned id);
void keyboardEmulation();
std::vector<int> myButtonStates;
static void processKeyDown(unsigned keycode, uint32_t character, uint16_t key_modifiers);
static void processKeyUp(unsigned keycode, uint32_t character, uint16_t key_modifiers);
};
std::shared_ptr<common2::Initialisation> myInit;
bool checkButtonPressed(unsigned id);
void keyboardEmulation();
static void processKeyDown(unsigned keycode, uint32_t character, uint16_t key_modifiers);
static void processKeyUp(unsigned keycode, uint32_t character, uint16_t key_modifiers);
};
}

View file

@ -3,26 +3,30 @@
#include "libretro.h"
Joypad::Joypad()
: myAxisCodes(2)
namespace ra2
{
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;
}
double Joypad::getAxis(int i) const
{
for (const auto & axis : myAxisCodes[i])
Joypad::Joypad()
: myAxisCodes(2)
{
const int value = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, axis.first);
if (value)
{
return axis.second;
}
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;
}
double Joypad::getAxis(int i) const
{
for (const auto & axis : myAxisCodes[i])
{
const int value = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, axis.first);
if (value)
{
return axis.second;
}
}
return 0.0;
}
return 0.0;
}

View file

@ -5,14 +5,18 @@
#include <vector>
#include <map>
class Joypad : public JoypadBase
namespace ra2
{
public:
Joypad();
double getAxis(int i) const override;
class Joypad : public JoypadBase
{
public:
Joypad();
private:
std::vector<std::map<unsigned, double> > myAxisCodes;
};
double getAxis(int i) const override;
private:
std::vector<std::map<unsigned, double> > myAxisCodes;
};
}

View file

@ -3,16 +3,20 @@
#include "libretro.h"
JoypadBase::JoypadBase()
: myButtonCodes(2)
namespace ra2
{
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;
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

@ -5,14 +5,18 @@
#include <vector>
#include <map>
class JoypadBase : public Paddle
namespace ra2
{
public:
JoypadBase();
bool getButton(int i) const override;
class JoypadBase : public Paddle
{
public:
JoypadBase();
private:
std::vector<unsigned> myButtonCodes;
};
bool getButton(int i) const override;
private:
std::vector<unsigned> myButtonCodes;
};
}

View file

@ -19,7 +19,7 @@
namespace
{
std::unique_ptr<Game> ourGame;
std::unique_ptr<ra2::Game> ourGame;
bool endsWith(const std::string & value, const std::string & ending)
{
@ -34,37 +34,37 @@ namespace
void retro_init(void)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
const char *dir = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
if (ra2::environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
{
retro_base_directory = dir;
ra2::retro_base_directory = dir;
}
}
void retro_deinit(void)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
}
unsigned retro_api_version(void)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
return RETRO_API_VERSION;
}
void retro_set_controller_port_device(unsigned port, unsigned device)
{
log_cb(RETRO_LOG_INFO, "RA2: %s, Plugging device %u into port %u.\n", __FUNCTION__, device, port);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s, Plugging device %u into port %u.\n", __FUNCTION__, device, port);
if (port == 0)
{
Game::ourInputDevices[port] = device;
ra2::Game::ourInputDevices[port] = device;
}
}
void retro_get_system_info(retro_system_info *info)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
static std::string version = getVersion();
memset(info, 0, sizeof(*info));
@ -77,7 +77,7 @@ void retro_get_system_info(retro_system_info *info)
void retro_get_system_av_info(retro_system_av_info *info)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
Video & video = GetVideo();
@ -87,19 +87,19 @@ void retro_get_system_av_info(retro_system_av_info *info)
info->geometry.max_height = video.GetFrameBufferBorderlessHeight();
info->geometry.aspect_ratio = 0;
info->timing.fps = Game::FPS;
info->timing.fps = ra2::Game::FPS;
info->timing.sample_rate = SPKR_SAMPLE_RATE;
}
void retro_set_environment(retro_environment_t cb)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
environ_cb = cb;
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::environ_cb = cb;
if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging))
log_cb = logging.log;
if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &ra2::logging))
ra2::log_cb = ra2::logging.log;
else
log_cb = fallback_log;
ra2::log_cb = ra2::fallback_log;
static const struct retro_controller_description controllers[] =
{
@ -115,46 +115,46 @@ void retro_set_environment(retro_environment_t cb)
cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
retro_keyboard_callback keyboardCallback = {&Game::keyboardCallback};
retro_keyboard_callback keyboardCallback = {&ra2::Game::keyboardCallback};
cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &keyboardCallback);
retro_audio_buffer_status_callback audioCallback = {&RDirectSound::bufferStatusCallback};
retro_audio_buffer_status_callback audioCallback = {&ra2::bufferStatusCallback};
cb(RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK, &audioCallback);
retro_frame_time_callback timeCallback = {&Game::frameTimeCallback, 1000000 / Game::FPS};
retro_frame_time_callback timeCallback = {&ra2::Game::frameTimeCallback, 1000000 / ra2::Game::FPS};
cb(RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK, &timeCallback);
SetupRetroVariables();
ra2::SetupRetroVariables();
}
void retro_set_audio_sample(retro_audio_sample_t cb)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
audio_cb = cb;
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::audio_cb = cb;
}
void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
audio_batch_cb = cb;
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::audio_batch_cb = cb;
}
void retro_set_input_poll(retro_input_poll_t cb)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
input_poll_cb = cb;
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::input_poll_cb = cb;
}
void retro_set_input_state(retro_input_state_t cb)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
input_state_cb = cb;
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::input_state_cb = cb;
}
void retro_set_video_refresh(retro_video_refresh_t cb)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
video_cb = cb;
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::video_cb = cb;
}
void retro_run(void)
@ -163,25 +163,25 @@ void retro_run(void)
ourGame->executeOneFrame();
GetFrame().VideoPresentScreen();
const size_t ms = (1000 + 60 - 1) / 60; // round up
RDirectSound::writeAudio(ms);
ra2::writeAudio(ms);
}
bool retro_load_game(const retro_game_info *info)
{
ourGame.reset();
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
if (!ra2::environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
{
log_cb(RETRO_LOG_INFO, "XRGB8888 is not supported.\n");
ra2::log_cb(RETRO_LOG_INFO, "XRGB8888 is not supported.\n");
return false;
}
try
{
std::shared_ptr<RetroFrame> frame(new RetroFrame());
std::unique_ptr<Game> game(new Game(frame));
std::shared_ptr<ra2::RetroFrame> frame(new ra2::RetroFrame());
std::unique_ptr<ra2::Game> game(new ra2::Game(frame));
const std::string snapshotEnding = ".aws.yaml";
const std::string gamePath = info->path;
@ -196,11 +196,11 @@ bool retro_load_game(const retro_game_info *info)
ok = game->loadGame(gamePath);
}
log_cb(RETRO_LOG_INFO, "Game path: %s:%d\n", info->path, ok);
ra2::log_cb(RETRO_LOG_INFO, "Game path: %s:%d\n", info->path, ok);
if (ok)
{
display_message("Enable Game Focus Mode for better keyboard handling");
ra2::display_message("Enable Game Focus Mode for better keyboard handling");
}
std::swap(ourGame, game);
@ -208,11 +208,11 @@ bool retro_load_game(const retro_game_info *info)
}
catch (const std::exception & e)
{
log_cb(RETRO_LOG_INFO, "Exception: %s\n", e.what());
ra2::log_cb(RETRO_LOG_INFO, "Exception: %s\n", e.what());
}
catch (const std::string & s)
{
log_cb(RETRO_LOG_INFO, "Exception: %s\n", s.c_str());
ra2::log_cb(RETRO_LOG_INFO, "Exception: %s\n", s.c_str());
}
return false;
@ -221,62 +221,62 @@ bool retro_load_game(const retro_game_info *info)
void retro_unload_game(void)
{
ourGame.reset();
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
}
unsigned retro_get_region(void)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
return RETRO_REGION_NTSC;
}
void retro_reset(void)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
}
bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
return false;
}
size_t retro_serialize_size(void)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
return 0;
}
bool retro_serialize(void *data, size_t size)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
return false;
}
bool retro_unserialize(const void *data, size_t size)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
return false;
}
void retro_cheat_reset(void)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
}
void retro_cheat_set(unsigned index, bool enabled, const char *code)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
}
void *retro_get_memory_data(unsigned id)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
return nullptr;
}
size_t retro_get_memory_size(unsigned id)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
return 0;
}

View file

@ -106,7 +106,7 @@ namespace
sample = (sample * rvolume) / 128;
}
audio_batch_cb(myMixerBuffer.data(), frames);
ra2::audio_batch_cb(myMixerBuffer.data(), frames);
}
void DirectSoundGenerator::playSilence(const size_t ms)
@ -119,7 +119,7 @@ namespace
const size_t frames = ms * myBuffer->sampleRate / 1000;
myMixerBuffer.resize(2 * frames);
std::fill(myMixerBuffer.begin(), myMixerBuffer.end(), 0);
audio_batch_cb(myMixerBuffer.data(), frames);
ra2::audio_batch_cb(myMixerBuffer.data(), frames);
}
void DirectSoundGenerator::writeAudio(const size_t ms)
@ -165,7 +165,7 @@ void unregisterSoundBuffer(IDirectSoundBuffer * buffer)
}
}
namespace RDirectSound
namespace ra2
{
void writeAudio(const size_t ms)

View file

@ -2,7 +2,7 @@
#include <cstdlib>
namespace RDirectSound
namespace ra2
{
void writeAudio(const size_t ms);
void bufferStatusCallback(bool active, unsigned occupancy, bool underrun_likely);

View file

@ -74,105 +74,109 @@ namespace
}
RetroFrame::RetroFrame()
namespace ra2
{
}
void RetroFrame::FrameRefreshStatus(int drawflags)
{
if (drawflags & DRAW_TITLE)
RetroFrame::RetroFrame()
{
GetAppleWindowTitle();
display_message(g_pAppTitle.c_str());
}
}
void RetroFrame::VideoPresentScreen()
{
// this should not be necessary
// either libretro handles it
// or we should change AW
// but for now, there is no alternative
for (size_t row = 0; row < myHeight; ++row)
{
const uint8_t * src = myFrameBuffer + row * myPitch;
uint8_t * dst = myVideoBuffer.data() + (myHeight - row - 1) * myPitch;
memcpy(dst, src, myPitch);
}
video_cb(myVideoBuffer.data() + myOffset, myBorderlessWidth, myBorderlessHeight, myPitch);
}
void RetroFrame::Initialize()
{
LinuxFrame::Initialize();
FrameRefreshStatus(DRAW_TITLE);
Video & video = GetVideo();
myBorderlessWidth = video.GetFrameBufferBorderlessWidth();
myBorderlessHeight = video.GetFrameBufferBorderlessHeight();
const size_t borderWidth = video.GetFrameBufferBorderWidth();
const size_t borderHeight = video.GetFrameBufferBorderHeight();
const size_t width = video.GetFrameBufferWidth();
myHeight = video.GetFrameBufferHeight();
myFrameBuffer = video.GetFrameBuffer();
myPitch = width * sizeof(bgra_t);
myOffset = (width * borderHeight + borderWidth) * sizeof(bgra_t);
const size_t size = myHeight * myPitch;
myVideoBuffer.resize(size);
}
void RetroFrame::Destroy()
{
LinuxFrame::Destroy();
myFrameBuffer = nullptr;
myVideoBuffer.clear();
}
void RetroFrame::GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits)
{
const std::string filename = getBitmapFilename(lpBitmapName);
const std::string path = myResourcePath + filename;
std::vector<char> buffer;
readFileToBuffer(path, buffer);
if (!buffer.empty())
void RetroFrame::FrameRefreshStatus(int drawflags)
{
int32_t width, height;
uint16_t bpp;
const char * data;
uint32_t size;
const bool res = getBitmapData(buffer, width, height, bpp, data, size);
log_cb(RETRO_LOG_INFO, "RA2: %s. %s = %dx%d, %dbpp\n", __FUNCTION__, path.c_str(),
width, height, bpp);
if (res && height > 0 && size <= cb)
if (drawflags & DRAW_TITLE)
{
const size_t length = size / height;
// rows are stored upside down
char * out = static_cast<char *>(lpvBits);
for (size_t row = 0; row < height; ++row)
{
const char * src = data + row * length;
char * dst = out + (height - row - 1) * length;
memcpy(dst, src, length);
}
return;
GetAppleWindowTitle();
display_message(g_pAppTitle.c_str());
}
}
CommonFrame::GetBitmap(lpBitmapName, cb, lpvBits);
}
void RetroFrame::VideoPresentScreen()
{
// this should not be necessary
// either libretro handles it
// or we should change AW
// but for now, there is no alternative
for (size_t row = 0; row < myHeight; ++row)
{
const uint8_t * src = myFrameBuffer + row * myPitch;
uint8_t * dst = myVideoBuffer.data() + (myHeight - row - 1) * myPitch;
memcpy(dst, src, myPitch);
}
video_cb(myVideoBuffer.data() + myOffset, myBorderlessWidth, myBorderlessHeight, myPitch);
}
void RetroFrame::Initialize()
{
LinuxFrame::Initialize();
FrameRefreshStatus(DRAW_TITLE);
Video & video = GetVideo();
myBorderlessWidth = video.GetFrameBufferBorderlessWidth();
myBorderlessHeight = video.GetFrameBufferBorderlessHeight();
const size_t borderWidth = video.GetFrameBufferBorderWidth();
const size_t borderHeight = video.GetFrameBufferBorderHeight();
const size_t width = video.GetFrameBufferWidth();
myHeight = video.GetFrameBufferHeight();
myFrameBuffer = video.GetFrameBuffer();
myPitch = width * sizeof(bgra_t);
myOffset = (width * borderHeight + borderWidth) * sizeof(bgra_t);
const size_t size = myHeight * myPitch;
myVideoBuffer.resize(size);
}
void RetroFrame::Destroy()
{
LinuxFrame::Destroy();
myFrameBuffer = nullptr;
myVideoBuffer.clear();
}
void RetroFrame::GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits)
{
const std::string filename = getBitmapFilename(lpBitmapName);
const std::string path = myResourcePath + filename;
std::vector<char> buffer;
readFileToBuffer(path, buffer);
if (!buffer.empty())
{
int32_t width, height;
uint16_t bpp;
const char * data;
uint32_t size;
const bool res = getBitmapData(buffer, width, height, bpp, data, size);
log_cb(RETRO_LOG_INFO, "RA2: %s. %s = %dx%d, %dbpp\n", __FUNCTION__, path.c_str(),
width, height, bpp);
if (res && height > 0 && size <= cb)
{
const size_t length = size / height;
// rows are stored upside down
char * out = static_cast<char *>(lpvBits);
for (size_t row = 0; row < height; ++row)
{
const char * src = data + row * length;
char * dst = out + (height - row - 1) * length;
memcpy(dst, src, length);
}
return;
}
}
CommonFrame::GetBitmap(lpBitmapName, cb, lpvBits);
}
int RetroFrame::FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
log_cb(RETRO_LOG_INFO, "RA2: %s: %s - %s\n", __FUNCTION__, lpCaption, lpText);
return IDOK;
}
int RetroFrame::FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
log_cb(RETRO_LOG_INFO, "RA2: %s: %s - %s\n", __FUNCTION__, lpCaption, lpText);
return IDOK;
}

View file

@ -5,25 +5,30 @@
#include <memory>
#include <vector>
class RetroFrame : public common2::CommonFrame
namespace ra2
{
public:
RetroFrame();
void VideoPresentScreen() override;
void FrameRefreshStatus(int drawflags) override;
void Initialize() override;
void Destroy() override;
int FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType) override;
void GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits) override;
class RetroFrame : public common2::CommonFrame
{
public:
RetroFrame();
private:
std::vector<uint8_t> myVideoBuffer;
void VideoPresentScreen() override;
void FrameRefreshStatus(int drawflags) override;
void Initialize() override;
void Destroy() override;
int FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType) override;
void GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits) override;
size_t myPitch;
size_t myOffset;
size_t myHeight;
size_t myBorderlessWidth;
size_t myBorderlessHeight;
uint8_t* myFrameBuffer;
};
private:
std::vector<uint8_t> myVideoBuffer;
size_t myPitch;
size_t myOffset;
size_t myHeight;
size_t myBorderlessWidth;
size_t myBorderlessHeight;
uint8_t* myFrameBuffer;
};
}

View file

@ -105,55 +105,60 @@ namespace
}
void SetupRetroVariables()
namespace ra2
{
const size_t numberOfVariables = ourVariables.size();
std::vector<retro_variable> retroVariables(numberOfVariables + 1);
std::list<std::string> workspace; // so objects do not move when it resized
// we need to keep the char * alive till after the call to RETRO_ENVIRONMENT_SET_VARIABLES
const auto c_str = [&workspace] (const auto & s)
{
workspace.push_back(s);
return workspace.back().c_str();
};
for (size_t i = 0; i < numberOfVariables; ++i)
void SetupRetroVariables()
{
const Variable & variable = ourVariables[i];
retro_variable & retroVariable = retroVariables[i];
const size_t numberOfVariables = ourVariables.size();
std::vector<retro_variable> retroVariables(numberOfVariables + 1);
std::list<std::string> workspace; // so objects do not move when it resized
retroVariable.key = c_str(ourScope + variable.name);
retroVariable.value = c_str(getKey(variable));
// we need to keep the char * alive till after the call to RETRO_ENVIRONMENT_SET_VARIABLES
const auto c_str = [&workspace] (const auto & s)
{
workspace.push_back(s);
return workspace.back().c_str();
};
for (size_t i = 0; i < numberOfVariables; ++i)
{
const Variable & variable = ourVariables[i];
retro_variable & retroVariable = retroVariables[i];
retroVariable.key = c_str(ourScope + variable.name);
retroVariable.value = c_str(getKey(variable));
}
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, retroVariables.data());
}
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, retroVariables.data());
}
void InitialiseRetroRegistry()
{
const auto registry = std::make_shared<common2::PTreeRegistry>();
for (const Variable & variable : ourVariables)
void InitialiseRetroRegistry()
{
const std::string retroKey = ourScope + variable.name;
retro_variable retroVariable;
retroVariable.key = retroKey.c_str();
retroVariable.value = nullptr;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &retroVariable) && retroVariable.value)
const auto registry = std::make_shared<common2::PTreeRegistry>();
for (const Variable & variable : ourVariables)
{
const std::string value(retroVariable.value);
const auto check = [&value] (const auto & x)
{
return x.first == value;
};
const auto it = std::find_if(variable.values.begin(), variable.values.end(), check);
if (it != variable.values.end())
const std::string retroKey = ourScope + variable.name;
retro_variable retroVariable;
retroVariable.key = retroKey.c_str();
retroVariable.value = nullptr;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &retroVariable) && retroVariable.value)
{
registry->putDWord(variable.section, variable.key, it->second);
const std::string value(retroVariable.value);
const auto check = [&value] (const auto & x)
{
return x.first == value;
};
const auto it = std::find_if(variable.values.begin(), variable.values.end(), check);
if (it != variable.values.end())
{
registry->putDWord(variable.section, variable.key, it->second);
}
}
}
Registry::instance = registry;
}
Registry::instance = registry;
}

View file

@ -1,4 +1,9 @@
#pragma once
void SetupRetroVariables();
void InitialiseRetroRegistry();
namespace ra2
{
void SetupRetroVariables();
void InitialiseRetroRegistry();
}