mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-25 16:23:46 +02:00
Implement the rest of the vanilla RGSS input API for libretro builds
This commit is contained in:
parent
8ed8c5c984
commit
44da7c5f9c
2 changed files with 53 additions and 24 deletions
28
src/core.cpp
28
src/core.cpp
|
@ -52,7 +52,6 @@ static inline void *malloc_align(size_t alignment, size_t size) {
|
||||||
extern unsigned char GMGSx_sf2[];
|
extern unsigned char GMGSx_sf2[];
|
||||||
extern unsigned int GMGSx_sf2_len;
|
extern unsigned int GMGSx_sf2_len;
|
||||||
|
|
||||||
static size_t frame_number = 0;
|
|
||||||
static ALCdevice *al_device = NULL;
|
static ALCdevice *al_device = NULL;
|
||||||
static ALCcontext *al_context = NULL;
|
static ALCcontext *al_context = NULL;
|
||||||
static LPALCRENDERSAMPLESSOFT alcRenderSamplesSOFT = NULL;
|
static LPALCRENDERSAMPLESSOFT alcRenderSamplesSOFT = NULL;
|
||||||
|
@ -259,12 +258,10 @@ static bool init_sandbox() {
|
||||||
mkxp_retro::sandbox.emplace();
|
mkxp_retro::sandbox.emplace();
|
||||||
} catch (SandboxException) {
|
} catch (SandboxException) {
|
||||||
log_printf(RETRO_LOG_ERROR, "Failed to initialize Ruby\n");
|
log_printf(RETRO_LOG_ERROR, "Failed to initialize Ruby\n");
|
||||||
mkxp_retro::sandbox.reset();
|
deinit_sandbox();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_number = 0;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,17 +359,20 @@ extern "C" RETRO_API void retro_reset() {
|
||||||
extern "C" RETRO_API void retro_run() {
|
extern "C" RETRO_API void retro_run() {
|
||||||
input_poll();
|
input_poll();
|
||||||
|
|
||||||
if (mkxp_retro::sandbox.has_value()) {
|
if (!mkxp_retro::sandbox.has_value()) {
|
||||||
log_printf(RETRO_LOG_INFO, "[Sandbox] Executing frame %zu\n", ++frame_number);
|
return;
|
||||||
try {
|
}
|
||||||
if (sb().run<struct main>()) {
|
|
||||||
log_printf(RETRO_LOG_INFO, "[Sandbox] Ruby terminated normally\n");
|
try {
|
||||||
mkxp_retro::sandbox.reset();
|
if (sb().run<struct main>()) {
|
||||||
}
|
log_printf(RETRO_LOG_INFO, "[Sandbox] Ruby terminated normally\n");
|
||||||
} catch (SandboxException) {
|
deinit_sandbox();
|
||||||
log_printf(RETRO_LOG_ERROR, "[Sandbox] Ruby threw an exception\n");
|
return;
|
||||||
mkxp_retro::sandbox.reset();
|
|
||||||
}
|
}
|
||||||
|
} catch (SandboxException) {
|
||||||
|
log_printf(RETRO_LOG_ERROR, "[Sandbox] Ruby threw an exception\n");
|
||||||
|
deinit_sandbox();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
video_refresh(frame_buf, 640, 480, 640 * 4);
|
video_refresh(frame_buf, 640, 480, 640 * 4);
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
#include "binding-sandbox/core.h"
|
#include "binding-sandbox/core.h"
|
||||||
|
|
||||||
#define JOYPAD_BUTTON_MAX 16
|
#define JOYPAD_BUTTON_MAX 16
|
||||||
|
#define REPEAT_NONE 255
|
||||||
|
#define REPEAT_START 0.4 // TODO: should be 0.375 when RGSS version >= 2
|
||||||
|
#define REPEAT_DELAY 0.1
|
||||||
|
#define FPS 60.0 // TODO: use the actual FPS
|
||||||
|
|
||||||
static std::unordered_map<int, uint8_t> codeToJoypadId = {
|
static std::unordered_map<int, uint8_t> codeToJoypadId = {
|
||||||
{Input::Down, RETRO_DEVICE_ID_JOYPAD_DOWN},
|
{Input::Down, RETRO_DEVICE_ID_JOYPAD_DOWN},
|
||||||
|
@ -51,20 +55,20 @@ static const uint8_t otherDirs[4][3] = {
|
||||||
|
|
||||||
struct InputPrivate
|
struct InputPrivate
|
||||||
{
|
{
|
||||||
int buttonRepeating;
|
uint32_t repeatCount;
|
||||||
size_t buttonRepeatingCount;
|
uint16_t currJoypadState;
|
||||||
uint8_t currJoypadState;
|
uint16_t prevJoypadState;
|
||||||
uint8_t prevJoypadState;
|
uint8_t repeat;
|
||||||
uint8_t currDir4;
|
uint8_t currDir4;
|
||||||
uint8_t prevDir4;
|
uint8_t prevDir4;
|
||||||
uint8_t dir8;
|
uint8_t dir8;
|
||||||
bool joypadMaskSupported;
|
bool joypadMaskSupported;
|
||||||
|
|
||||||
InputPrivate() :
|
InputPrivate() :
|
||||||
buttonRepeating(-1),
|
repeatCount(0),
|
||||||
buttonRepeatingCount(0),
|
|
||||||
currJoypadState(0),
|
currJoypadState(0),
|
||||||
prevJoypadState(0),
|
prevJoypadState(0),
|
||||||
|
repeat(-1),
|
||||||
currDir4(0),
|
currDir4(0),
|
||||||
prevDir4(0),
|
prevDir4(0),
|
||||||
dir8(0),
|
dir8(0),
|
||||||
|
@ -74,8 +78,9 @@ struct InputPrivate
|
||||||
void updateJoypad()
|
void updateJoypad()
|
||||||
{
|
{
|
||||||
prevJoypadState = currJoypadState;
|
prevJoypadState = currJoypadState;
|
||||||
|
|
||||||
if (joypadMaskSupported) {
|
if (joypadMaskSupported) {
|
||||||
currJoypadState = (uint8_t)mkxp_retro::input_state(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
|
currJoypadState = (uint16_t)mkxp_retro::input_state(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
|
||||||
} else {
|
} else {
|
||||||
currJoypadState = 0;
|
currJoypadState = 0;
|
||||||
for (uint8_t i = 0; i < JOYPAD_BUTTON_MAX; ++i) {
|
for (uint8_t i = 0; i < JOYPAD_BUTTON_MAX; ++i) {
|
||||||
|
@ -84,6 +89,23 @@ struct InputPrivate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (repeat == REPEAT_NONE) {
|
||||||
|
if (currJoypadState != 0) {
|
||||||
|
for (uint8_t i = 0; i < JOYPAD_BUTTON_MAX; ++i) {
|
||||||
|
if (currJoypadState & (1 << i)) {
|
||||||
|
repeat = i;
|
||||||
|
repeatCount = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (currJoypadState & (1 << repeat)) {
|
||||||
|
__builtin_add_overflow(repeatCount, 1, &repeatCount);
|
||||||
|
} else {
|
||||||
|
repeat = REPEAT_NONE;
|
||||||
|
repeatCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateDir4()
|
void updateDir4()
|
||||||
|
@ -169,6 +191,12 @@ struct InputPrivate
|
||||||
auto it = codeToJoypadId.find(button);
|
auto it = codeToJoypadId.find(button);
|
||||||
return it != codeToJoypadId.end() && (prevJoypadState & (1 << it->second));
|
return it != codeToJoypadId.end() && (prevJoypadState & (1 << it->second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isRepeat(int button)
|
||||||
|
{
|
||||||
|
auto it = codeToJoypadId.find(button);
|
||||||
|
return it != codeToJoypadId.end() && repeat == it->second;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Input::Input()
|
Input::Input()
|
||||||
|
@ -185,6 +213,7 @@ void Input::update()
|
||||||
{
|
{
|
||||||
p->updateJoypad();
|
p->updateJoypad();
|
||||||
p->updateDir4();
|
p->updateDir4();
|
||||||
|
p->updateDir8();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Input::isPressed(int button)
|
bool Input::isPressed(int button)
|
||||||
|
@ -204,17 +233,17 @@ bool Input::isReleased(int button)
|
||||||
|
|
||||||
bool Input::isRepeated(int button)
|
bool Input::isRepeated(int button)
|
||||||
{
|
{
|
||||||
return isPressed(button); // TODO
|
return p->isRepeat(button) && (p->repeatCount == 0 || (p->repeatCount >= (size_t)std::ceil(REPEAT_START * FPS) && (p->repeatCount + 1) % (size_t)std::ceil(REPEAT_DELAY * FPS) == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Input::count(int button)
|
unsigned int Input::count(int button)
|
||||||
{
|
{
|
||||||
return 0; // TODO
|
return p->isRepeat(button) ? p->repeatCount : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Input::repeatTime(int button)
|
double Input::repeatTime(int button)
|
||||||
{
|
{
|
||||||
return 0.0; // TODO
|
return p->isRepeat(button) ? (double)p->repeatCount / FPS : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Input::isPressedEx(int button, bool isVKey)
|
bool Input::isPressedEx(int button, bool isVKey)
|
||||||
|
|
Loading…
Add table
Reference in a new issue