Implement config loading in libretro builds

This commit is contained in:
刘皓 2025-04-11 23:12:05 -04:00
parent c5af94c25a
commit 8c16bc0092
No known key found for this signature in database
GPG key ID: 7901753DB465B711
24 changed files with 224 additions and 252 deletions

View file

@ -1,8 +1,8 @@
global_sources += files([ global_sources += files(
'binding-base.cpp', 'binding-base.cpp',
'binding-util.cpp', 'binding-util.cpp',
'module_rpg.cpp', 'module_rpg.cpp',
'sandbox.cpp', 'sandbox.cpp',
'wasi.cpp', 'wasi.cpp',
'wasm-rt.cpp', 'wasm-rt.cpp',
]) )

View file

@ -242,11 +242,7 @@ struct ALStreamOpenHandler : FileSystem::OpenHandler
if (!strcmp(sig, "MThd")) if (!strcmp(sig, "MThd"))
{ {
#ifdef MKXPZ_RETRO
shState->midiState().initIfNeeded();
#else
shState->midiState().initIfNeeded(shState->config()); shState->midiState().initIfNeeded(shState->config());
#endif // MKXPZ_RETRO
if (HAVE_FLUID) if (HAVE_FLUID)
{ {

View file

@ -31,7 +31,9 @@
#include <string> #include <string>
#include <vector> #include <vector>
#ifndef MKXPZ_RETRO #ifdef MKXPZ_RETRO
# include "graphics.h"
#else
# include "sdl-util.h" # include "sdl-util.h"
# include <SDL_thread.h> # include <SDL_thread.h>
# include <SDL_timer.h> # include <SDL_timer.h>
@ -74,24 +76,16 @@ struct AudioPrivate
MeWatchState state; MeWatchState state;
} meWatch; } meWatch;
#ifdef MKXPZ_RETRO
AudioPrivate()
#else
AudioPrivate(RGSSThreadData &rtData) AudioPrivate(RGSSThreadData &rtData)
#endif // MKXPZ_RETRO
: bgs(ALStream::Looped, "bgs"), : bgs(ALStream::Looped, "bgs"),
me(ALStream::NotLooped, "me"), me(ALStream::NotLooped, "me"),
#ifndef MKXPZ_RETRO
se(rtData.config), se(rtData.config),
#ifndef MKXPZ_RETRO
syncPoint(rtData.syncPoint), syncPoint(rtData.syncPoint),
#endif // MKXPZ_RETRO #endif // MKXPZ_RETRO
volumeRatio(1) volumeRatio(1)
{ {
#ifdef MKXPZ_RETRO
for (int i = 0; i < 16; i++) { // TODO: read BGM track count from config
#else
for (int i = 0; i < rtData.config.BGM.trackCount; i++) { for (int i = 0; i < rtData.config.BGM.trackCount; i++) {
#endif // MKXPZ_RETRO
std::string id = std::string("bgm" + std::to_string(i)); std::string id = std::string("bgm" + std::to_string(i));
bgmTracks.push_back(new AudioStream(ALStream::Looped, id.c_str())); bgmTracks.push_back(new AudioStream(ALStream::Looped, id.c_str()));
} }
@ -123,9 +117,10 @@ struct AudioPrivate
void meWatchProc() void meWatchProc()
{ {
#ifdef MKXPZ_RETRO // TODO: use FPS #ifdef MKXPZ_RETRO
const float fadeOutStep = 1.f / (200 / 17); const int fps = shState->graphics().getFrameRate();
const float fadeInStep = 1.f / (1000 / 17); const float fadeOutStep = 5.f / fps;
const float fadeInStep = 1.f / fps;
#else #else
const float fadeOutStep = 1.f / (200 / AUDIO_SLEEP); const float fadeOutStep = 1.f / (200 / AUDIO_SLEEP);
const float fadeInStep = 1.f / (1000 / AUDIO_SLEEP); const float fadeInStep = 1.f / (1000 / AUDIO_SLEEP);
@ -316,15 +311,9 @@ struct AudioPrivate
#endif // MKXPZ_RETRO #endif // MKXPZ_RETRO
}; };
#ifdef MKXPZ_RETRO
Audio::Audio()
: p(new AudioPrivate())
{}
#else
Audio::Audio(RGSSThreadData &rtData) Audio::Audio(RGSSThreadData &rtData)
: p(new AudioPrivate(rtData)) : p(new AudioPrivate(rtData))
{} {}
#endif // MKXPZ_RETRO
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
void Audio::render() { void Audio::render() {

View file

@ -77,15 +77,13 @@ public:
void reset(); void reset();
#ifdef MKXPZ_RETRO
Audio();
~Audio();
#endif // MKXPZ_RETRO
private:
#ifndef MKXPZ_RETRO #ifndef MKXPZ_RETRO
private:
#endif // MKXPZ_RETRO
Audio(RGSSThreadData &rtData); Audio(RGSSThreadData &rtData);
~Audio(); ~Audio();
#ifdef MKXPZ_RETRO
private:
#endif // MKXPZ_RETRO #endif // MKXPZ_RETRO
friend struct SharedStatePrivate; friend struct SharedStatePrivate;

View file

@ -78,7 +78,7 @@ struct SharedMidiState
} }
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
void initIfNeeded() void initIfNeeded(const Config &conf)
{ {
if (inited) if (inited)
return; return;
@ -93,8 +93,8 @@ struct SharedMidiState
flSettings = fluid.new_settings(); flSettings = fluid.new_settings();
fluid.settings_setnum(flSettings, "synth.gain", 1.0f); fluid.settings_setnum(flSettings, "synth.gain", 1.0f);
fluid.settings_setnum(flSettings, "synth.sample-rate", SYNTH_SAMPLERATE); fluid.settings_setnum(flSettings, "synth.sample-rate", SYNTH_SAMPLERATE);
fluid.settings_setint(flSettings, "synth.chorus.active", 0); fluid.settings_setint(flSettings, "synth.chorus.active", conf.midi.chorus);
fluid.settings_setint(flSettings, "synth.reverb.active", 0); fluid.settings_setint(flSettings, "synth.reverb.active", conf.midi.reverb);
extern const uint8_t mkxp_gmgsx_sf2[]; extern const uint8_t mkxp_gmgsx_sf2[];
extern const size_t mkxp_gmgsx_sf2_len; extern const size_t mkxp_gmgsx_sf2_len;

View file

@ -94,17 +94,9 @@ arrayPushBack(std::vector<size_t> &array, size_t size, size_t index)
array[size-1] = v; array[size-1] = v;
} }
#ifdef MKXPZ_RETRO
SoundEmitter::SoundEmitter()
#else
SoundEmitter::SoundEmitter(const Config &conf) SoundEmitter::SoundEmitter(const Config &conf)
#endif // MKXPZ_RETRO
: bufferBytes(0), : bufferBytes(0),
#ifdef MKXPZ_RETRO
srcCount(6), // TODO: get from config
#else
srcCount(conf.SE.sourceCount), srcCount(conf.SE.sourceCount),
#endif // MKXPZ_RETRO
alSrcs(srcCount), alSrcs(srcCount),
atchBufs(srcCount), atchBufs(srcCount),
srcPrio(srcCount) srcPrio(srcCount)

View file

@ -49,11 +49,7 @@ struct SoundEmitter
/* Indices of sources, sorted by priority (lowest first) */ /* Indices of sources, sorted by priority (lowest first) */
std::vector<size_t> srcPrio; std::vector<size_t> srcPrio;
#ifdef MKXPZ_RETRO
SoundEmitter();
#else
SoundEmitter(const Config &conf); SoundEmitter(const Config &conf);
#endif // MKXPZ_RETRO
~SoundEmitter(); ~SoundEmitter();
void play(const std::string &filename, void play(const std::string &filename,

View file

@ -6,7 +6,11 @@
// //
#include "config.h" #include "config.h"
#include <SDL_filesystem.h> #ifdef MKXPZ_RETRO
# include "core.h"
#else
# include <SDL_filesystem.h>
#endif // MKXPZ_RETRO
#include <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>
@ -28,7 +32,8 @@
namespace json = json5pp; namespace json = json5pp;
std::string prefPath(const char *org, const char *app) { #ifndef MKXPZ_RETRO
static std::string prefPath(const char *org, const char *app) {
char *path = SDL_GetPrefPath(org, app); char *path = SDL_GetPrefPath(org, app);
if (!path) if (!path)
return std::string(""); return std::string("");
@ -36,8 +41,9 @@ std::string prefPath(const char *org, const char *app) {
SDL_free(path); SDL_free(path);
return ret; return ret;
} }
#endif // MKXPZ_RETRO
void fillStringVec(json::value &item, std::vector<std::string> &vector) { static void fillStringVec(json::value &item, std::vector<std::string> &vector) {
if (!item.is_array()) { if (!item.is_array()) {
if (item.is_string()) { if (item.is_string()) {
vector.push_back(item.as_string()); vector.push_back(item.as_string());
@ -53,7 +59,7 @@ void fillStringVec(json::value &item, std::vector<std::string> &vector) {
} }
} }
bool copyObject(json::value &dest, json::value &src, const char *objectName = "") { static bool copyObject(json::value &dest, json::value &src, const char *objectName = "") {
assert(dest.is_object()); assert(dest.is_object());
if (src.is_null()) if (src.is_null())
return false; return false;
@ -84,7 +90,8 @@ bool copyObject(json::value &dest, json::value &src, const char *objectName = ""
return true; return true;
} }
bool getEnvironmentBool(const char *env, bool defaultValue) { #ifndef MKXPZ_RETRO
static bool getEnvironmentBool(const char *env, bool defaultValue) {
const char *e = SDL_getenv(env); const char *e = SDL_getenv(env);
if (!e) if (!e)
return defaultValue; return defaultValue;
@ -96,16 +103,40 @@ bool getEnvironmentBool(const char *env, bool defaultValue) {
return defaultValue; return defaultValue;
} }
#endif // MKXPZ_RETRO
json::value readConfFile(const char *path) { static json::value readConfFile(const char *path) {
json::value ret(0); json::value ret(0);
if (!mkxp_fs::fileExists(path)) {
#ifdef MKXPZ_RETRO
FileSystem::File file(*mkxp_retro::fs, path, FileSystem::OpenMode::Read);
if (!file.is_open())
#else
if (!mkxp_fs::fileExists(path))
#endif // MKXPZ_RETRO
{
return json::object({}); return json::object({});
} }
try { try {
#ifdef MKXPZ_RETRO
std::vector<uint8_t> buf(16);
size_t size = 0;
for (;;) {
PHYSFS_sint64 n = PHYSFS_readBytes(file.get(), buf.data() + size, buf.size() - size);
if (n <= 0) {
break;
}
size += n;
if (size >= buf.size()) {
buf.resize(buf.size() * 2);
}
}
std::string cfg(buf.begin(), buf.begin() + size);
#else
std::string cfg = mkxp_fs::contentsOfFileAsString(path); std::string cfg = mkxp_fs::contentsOfFileAsString(path);
#endif // MKXPZ_RETRO
ret = json::parse5(Encoding::convertString(cfg)); ret = json::parse5(Encoding::convertString(cfg));
} }
catch (const std::exception &e) { catch (const std::exception &e) {
@ -121,7 +152,12 @@ json::value readConfFile(const char *path) {
return ret; return ret;
} }
#define CONF_FILE "mkxp.json" #define _CONF_FILE "mkxp.json"
#ifdef MKXPZ_RETRO
# define CONF_FILE "/mkxp-retro-game/" _CONF_FILE
#else
# define CONF_FILE _CONF_FILE
#endif // MKXPZ_RETRO
Config::Config() {} Config::Config() {}
@ -254,17 +290,21 @@ try { exp } catch (...) {}
SET_OPT(defScreenW, integer); SET_OPT(defScreenW, integer);
SET_OPT(defScreenH, integer); SET_OPT(defScreenH, integer);
#ifndef MKXPZ_RETRO
// Take a break real quick and witch to set game folder and read the game's ini // Take a break real quick and witch to set game folder and read the game's ini
if (!gameFolder.empty() && !mkxp_fs::setCurrentDirectory(gameFolder.c_str())) { if (!gameFolder.empty() && !mkxp_fs::setCurrentDirectory(gameFolder.c_str())) {
throw Exception(Exception::MKXPError, "Unable to switch into gameFolder %s", gameFolder.c_str()); throw Exception(Exception::MKXPError, "Unable to switch into gameFolder %s", gameFolder.c_str());
} }
#endif // MKXPZ_RETRO
readGameINI(); readGameINI();
#ifndef MKXPZ_RETRO
// Now check for an extra mkxp.conf in the user's save directory and merge anything else from that // Now check for an extra mkxp.conf in the user's save directory and merge anything else from that
userConfPath = mkxp_fs::normalizePath(std::string(customDataPath + "/" CONF_FILE).c_str(), 0, 1); userConfPath = mkxp_fs::normalizePath(std::string(customDataPath + "/" CONF_FILE).c_str(), 0, 1);
json::value userConf = readConfFile(userConfPath.c_str()); json::value userConf = readConfFile(userConfPath.c_str());
copyObject(optsJ, userConf); copyObject(optsJ, userConf);
#endif // MKXPZ_RETRO
// now RESUME // now RESUME
@ -342,8 +382,10 @@ try { exp } catch (...) {}
SE.sourceCount = clamp(SE.sourceCount, 1, 64); SE.sourceCount = clamp(SE.sourceCount, 1, 64);
BGM.trackCount = clamp(BGM.trackCount, 1, 16); BGM.trackCount = clamp(BGM.trackCount, 1, 16);
#ifndef MKXPZ_RETRO
// Determine whether to open a console window on... Windows // Determine whether to open a console window on... Windows
winConsole = getEnvironmentBool("MKXPZ_WINDOWS_CONSOLE", editor.debug); winConsole = getEnvironmentBool("MKXPZ_WINDOWS_CONSOLE", editor.debug);
#endif // MKXPZ_RETRO
#ifdef __APPLE__ #ifdef __APPLE__
// Determine whether to use the Metal renderer on macOS // Determine whether to use the Metal renderer on macOS
@ -351,11 +393,13 @@ try { exp } catch (...) {}
preferMetalRenderer = isMetalSupported() && getEnvironmentBool("MKXPZ_MACOS_METAL", preferMetalRenderer); preferMetalRenderer = isMetalSupported() && getEnvironmentBool("MKXPZ_MACOS_METAL", preferMetalRenderer);
#endif #endif
#ifndef MKXPZ_RETRO
// Determine whether to allow manual selection of a game folder on startup // Determine whether to allow manual selection of a game folder on startup
// Only works on macOS atm, mainly used to test games located outside of the bundle. // Only works on macOS atm, mainly used to test games located outside of the bundle.
// The config is re-read after the window is already created, so some entries // The config is re-read after the window is already created, so some entries
// may not take effect // may not take effect
manualFolderSelect = getEnvironmentBool("MKXPZ_FOLDER_SELECT", false); manualFolderSelect = getEnvironmentBool("MKXPZ_FOLDER_SELECT", false);
#endif // MKXPZ_RETRO
raw = optsJ; raw = optsJ;
} }
@ -387,14 +431,29 @@ void Config::readGameINI() {
return; return;
} }
#ifdef MKXPZ_RETRO
std::string iniFileName("/mkxp-retro-game/" + execName + ".ini");
std::shared_ptr<FileSystem::File> iniFile(new FileSystem::File(*mkxp_retro::fs, iniFileName.c_str(), FileSystem::OpenMode::Read));
#else
std::string iniFileName(execName + ".ini"); std::string iniFileName(execName + ".ini");
SDLRWStream iniFile(iniFileName.c_str(), "r"); SDLRWStream iniFile(iniFileName.c_str(), "r");
#endif // MKXPZ_RETRO
bool convSuccess = false; bool convSuccess = false;
#ifdef MKXPZ_RETRO
if (iniFile->is_open())
#else
if (iniFile) if (iniFile)
#endif // MKXPZ_RETRO
{ {
INIConfiguration ic; INIConfiguration ic;
#ifdef MKXPZ_RETRO
PHYSFSRWBuf buf(iniFile);
std::istream stream(&buf);
if (ic.load(stream))
#else
if (ic.load(iniFile.stream())) if (ic.load(iniFile.stream()))
#endif // MKXPZ_RETRO
{ {
GUARD(game.title = ic.getStringProperty("Game", "Title");); GUARD(game.title = ic.getStringProperty("Game", "Title"););
GUARD(game.scripts = ic.getStringProperty("Game", "Scripts");); GUARD(game.scripts = ic.getStringProperty("Game", "Scripts"););
@ -429,7 +488,9 @@ void Config::readGameINI() {
if (dataPathApp.empty()) if (dataPathApp.empty())
dataPathApp = game.title; dataPathApp = game.title;
#ifndef MKXPZ_RETRO
customDataPath = mkxp_fs::normalizePath(prefPath(dataPathOrg.c_str(), dataPathApp.c_str()).c_str(), 0, 1); customDataPath = mkxp_fs::normalizePath(prefPath(dataPathOrg.c_str(), dataPathApp.c_str()).c_str(), 0, 1);
#endif // MKXPZ_RETRO
if (rgssVersion == 0) { if (rgssVersion == 0) {
/* Try to guess RGSS version based on Data/Scripts extension */ /* Try to guess RGSS version based on Data/Scripts extension */

View file

@ -35,7 +35,9 @@ struct Config {
int rgssVersion; int rgssVersion;
bool debugMode; bool debugMode;
#ifndef MKXPZ_RETRO
bool winConsole; bool winConsole;
#endif // MKXPZ_RETRO
bool preferMetalRenderer; bool preferMetalRenderer;
bool displayFPS; bool displayFPS;
bool printFPS; bool printFPS;
@ -78,7 +80,9 @@ struct Config {
} integerScaling; } integerScaling;
std::string gameFolder; std::string gameFolder;
#ifndef MKXPZ_RETRO
bool manualFolderSelect; bool manualFolderSelect;
#endif // MKXPZ_RETRO
bool anyAltToggleFS; bool anyAltToggleFS;
bool enableReset; bool enableReset;
@ -165,7 +169,9 @@ struct Config {
std::string userConfPath; std::string userConfPath;
/* Internal */ /* Internal */
#ifndef MKXPZ_RETRO
std::string customDataPath; std::string customDataPath;
#endif // MKXPZ_RETRO
Config(); Config();

View file

@ -37,6 +37,7 @@
#include "gl-fun.h" #include "gl-fun.h"
#include "glstate.h" #include "glstate.h"
#include "sharedmidistate.h" #include "sharedmidistate.h"
#include "eventthread.h"
using namespace mkxp_retro; using namespace mkxp_retro;
using namespace mkxp_sandbox; using namespace mkxp_sandbox;
@ -59,6 +60,7 @@ static int16_t *sound_buf = NULL;
static bool retro_framebuffer_supported; static bool retro_framebuffer_supported;
static bool shared_state_initialized; static bool shared_state_initialized;
static PHYSFS_File *rgssad = NULL; static PHYSFS_File *rgssad = NULL;
static retro_system_av_info av_info;
namespace mkxp_retro { namespace mkxp_retro {
retro_log_printf_t log_printf; retro_log_printf_t log_printf;
@ -107,6 +109,8 @@ boost::optional<struct sandbox> mkxp_retro::sandbox;
boost::optional<Audio> mkxp_retro::audio; boost::optional<Audio> mkxp_retro::audio;
boost::optional<Input> mkxp_retro::input; boost::optional<Input> mkxp_retro::input;
boost::optional<FileSystem> mkxp_retro::fs; boost::optional<FileSystem> mkxp_retro::fs;
static boost::optional<Config> conf;
static boost::optional<RGSSThreadData> thread_data;
static std::string game_path; static std::string game_path;
static VALUE func(VALUE arg) { static VALUE func(VALUE arg) {
@ -165,6 +169,8 @@ static void deinit_sandbox() {
PHYSFS_close(rgssad); PHYSFS_close(rgssad);
rgssad = NULL; rgssad = NULL;
} }
thread_data.reset();
conf.reset();
fs.reset(); fs.reset();
input.reset(); input.reset();
} }
@ -201,13 +207,16 @@ static bool init_sandbox() {
fs->addPath(parsed_game_path.c_str(), "/mkxp-retro-game"); fs->addPath(parsed_game_path.c_str(), "/mkxp-retro-game");
// TODO: use execName from config instead of hardcoding "Game" as the filename conf.emplace();
if ((rgssad = PHYSFS_openRead("/mkxp-retro-game/Game.rgssad")) != NULL) { conf->read(0, NULL);
PHYSFS_mountHandle(rgssad, "Game.rgssad", "/mkxp-retro-game", 1); thread_data.emplace((EventThread *)NULL, (const char *)NULL, (SDL_Window *)NULL, (ALCdevice *)NULL, 60, 1, *conf);
} else if ((rgssad = PHYSFS_openRead("/mkxp-retro-game/Game.rgss2a")) != NULL) {
PHYSFS_mountHandle(rgssad, "Game.rgss2a", "/mkxp-retro-game", 1); if ((rgssad = PHYSFS_openRead(("/mkxp-retro-game/" + conf->execName + ".rgssad").c_str())) != NULL) {
} else if ((rgssad = PHYSFS_openRead("/mkxp-retro-game/Game.rgss3a")) != NULL) { PHYSFS_mountHandle(rgssad, (conf->execName + ".rgssad").c_str(), "/mkxp-retro-game", 1);
PHYSFS_mountHandle(rgssad, "Game.rgss3a", "/mkxp-retro-game", 1); } else if ((rgssad = PHYSFS_openRead(("/mkxp-retro-game/" + conf->execName + ".rgss2a").c_str())) != NULL) {
PHYSFS_mountHandle(rgssad, (conf->execName + ".rgss2a").c_str(), "/mkxp-retro-game", 1);
} else if ((rgssad = PHYSFS_openRead(("/mkxp-retro-game/" + conf->execName + ".rgss3a").c_str())) != NULL) {
PHYSFS_mountHandle(rgssad, (conf->execName + ".rgss3a").c_str(), "/mkxp-retro-game", 1);
} }
PHYSFS_mountMemory(mkxp_retro_dist_zip, mkxp_retro_dist_zip_len, NULL, "mkxp-retro-dist.zip", "/mkxp-retro-dist", 1); PHYSFS_mountMemory(mkxp_retro_dist_zip, mkxp_retro_dist_zip_len, NULL, "mkxp-retro-dist.zip", "/mkxp-retro-dist", 1);
@ -254,7 +263,7 @@ static bool init_sandbox() {
fluid_set_log_function(FLUID_INFO, fluid_log, NULL); fluid_set_log_function(FLUID_INFO, fluid_log, NULL);
fluid_set_log_function(FLUID_DBG, fluid_log, NULL); fluid_set_log_function(FLUID_DBG, fluid_log, NULL);
audio.emplace(); audio.emplace(*thread_data);
try { try {
mkxp_retro::sandbox.emplace(); mkxp_retro::sandbox.emplace();
@ -264,6 +273,16 @@ static bool init_sandbox() {
return false; return false;
} }
int default_width = conf->rgssVersion == 1 ? 640 : 544;
int default_height = conf->rgssVersion == 1 ? 480 : 544;
av_info.geometry.base_width = conf->enableHires ? (int)lround(conf->framebufferScalingFactor * default_width) : default_width;
av_info.geometry.base_height = conf->enableHires ? (int)lround(conf->framebufferScalingFactor * default_height) : default_height;
av_info.geometry.max_width = av_info.geometry.base_width;
av_info.geometry.max_height = av_info.geometry.base_height;
av_info.geometry.aspect_ratio = (float)av_info.geometry.base_width / (float)av_info.geometry.base_height;
av_info.timing.fps = conf->rgssVersion == 1 ? 40.0 : 60.0;
av_info.timing.sample_rate = (double)SYNTH_SAMPLERATE;
sound_buf = NULL; sound_buf = NULL;
frame_rate = 0; frame_rate = 0;
frame_rate_remainder = 0; frame_rate_remainder = 0;
@ -346,18 +365,7 @@ extern "C" RETRO_API void retro_get_system_info(struct retro_system_info *info)
} }
extern "C" RETRO_API void retro_get_system_av_info(struct retro_system_av_info *info) { extern "C" RETRO_API void retro_get_system_av_info(struct retro_system_av_info *info) {
std::memset(info, 0, sizeof *info); *info = av_info;
info->timing = {
.fps = 40.0,
.sample_rate = (double)SYNTH_SAMPLERATE,
};
info->geometry = {
.base_width = 640,
.base_height = 480,
.max_width = 640,
.max_height = 480,
.aspect_ratio = 640.0f / 480.0f,
};
} }
extern "C" RETRO_API void retro_set_controller_port_device(unsigned int port, unsigned int device) { extern "C" RETRO_API void retro_set_controller_port_device(unsigned int port, unsigned int device) {
@ -373,7 +381,7 @@ extern "C" RETRO_API void retro_run() {
// We deferred initializing the shared state since the OpenGL symbols aren't available until the first call to `retro_run()` // We deferred initializing the shared state since the OpenGL symbols aren't available until the first call to `retro_run()`
if (!shared_state_initialized) { if (!shared_state_initialized) {
SharedState::initInstance(NULL); SharedState::initInstance(&thread_data.get());
shared_state_initialized = true; shared_state_initialized = true;
} else if (hw_render.context_type != RETRO_HW_CONTEXT_NONE) { } else if (hw_render.context_type != RETRO_HW_CONTEXT_NONE) {
glState.reset(); glState.reset();
@ -391,37 +399,22 @@ extern "C" RETRO_API void retro_run() {
} }
} }
if (mkxp_retro::sandbox.has_value()) { if (mkxp_retro::sandbox.has_value() && frame_rate != shState->graphics().getFrameRate()) {
// Update frame rate if needed frame_rate = shState->graphics().getFrameRate();
if (frame_rate != shState->graphics().getFrameRate()) { frame_rate_remainder %= frame_rate;
frame_rate = shState->graphics().getFrameRate(); samples_per_frame = SYNTH_SAMPLERATE / frame_rate;
frame_rate_remainder %= frame_rate; samples_per_frame_remainder = SYNTH_SAMPLERATE % frame_rate;
samples_per_frame = SYNTH_SAMPLERATE / frame_rate;
samples_per_frame_remainder = SYNTH_SAMPLERATE % frame_rate;
if (sound_buf != NULL) { if (sound_buf != NULL) {
mkxp_aligned_free(sound_buf); mkxp_aligned_free(sound_buf);
}
sound_buf = (int16_t *)mkxp_aligned_malloc(16, (samples_per_frame + !!samples_per_frame_remainder) * 2 * sizeof(int16_t));
if (sound_buf == NULL) {
throw std::bad_alloc();
}
struct retro_system_av_info info;
std::memset(&info, 0, sizeof info);
info.timing = {
.fps = (double)frame_rate,
.sample_rate = (double)SYNTH_SAMPLERATE,
};
info.geometry = {
.base_width = 640,
.base_height = 480,
.max_width = 640,
.max_height = 480,
.aspect_ratio = 640.0f / 480.0f,
};
environment(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info);
} }
sound_buf = (int16_t *)mkxp_aligned_malloc(16, (samples_per_frame + !!samples_per_frame_remainder) * 2 * sizeof(int16_t));
if (sound_buf == NULL) {
throw std::bad_alloc();
}
av_info.timing.fps = frame_rate;
environment(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &av_info);
} }
void *fb; void *fb;
@ -447,7 +440,9 @@ extern "C" RETRO_API void retro_run() {
fb = frame_buf; fb = frame_buf;
} }
} }
video_refresh(fb, 640, 480, 640 * 4); unsigned int width = shState->graphics().width();
unsigned int height = shState->graphics().height();
video_refresh(fb, width, height, width * 4);
if (mkxp_retro::sandbox.has_value()) { if (mkxp_retro::sandbox.has_value()) {
audio->render(); audio->render();

View file

@ -1237,11 +1237,7 @@ void Bitmap::stretchBlt(IntRect destRect,
if (srcSurf) if (srcSurf)
{ {
SDL_Rect srcRect = sourceRect; SDL_Rect srcRect = sourceRect;
#ifdef MKXPZ_RETRO
bool subImageFix = false; // TODO: get from config
#else
bool subImageFix = shState->config().subImageFix; bool subImageFix = shState->config().subImageFix;
#endif // MKXPZ_RETRO
bool srcRectTooBig = srcRect.w > glState.caps.maxTexSize || bool srcRectTooBig = srcRect.w > glState.caps.maxTexSize ||
srcRect.h > glState.caps.maxTexSize; srcRect.h > glState.caps.maxTexSize;
bool srcSurfTooBig = !unpack_subimage && ( bool srcSurfTooBig = !unpack_subimage && (
@ -1843,7 +1839,10 @@ Color Bitmap::getPixel(int x, int y) const
} }
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
return Color(); // TODO: implement return Color(((uint8_t *)p->surface->pixels)[4 * (p->surface->w * y + x)],
((uint8_t *)p->surface->pixels)[4 * (p->surface->w * y + x) + 1],
((uint8_t *)p->surface->pixels)[4 * (p->surface->w * y + x) + 2],
((uint8_t *)p->surface->pixels)[4 * (p->surface->w * y + x) + 3]);
#else #else
uint32_t pixel = getPixelAt(p->surface, p->format, x, y); uint32_t pixel = getPixelAt(p->surface, p->format, x, y);
@ -2686,11 +2685,7 @@ int Bitmap::addFrame(Bitmap &source, int position)
p->animation.startTime = 0; p->animation.startTime = 0;
if (p->animation.fps <= 0) if (p->animation.fps <= 0)
#ifdef MKXPZ_RETRO // TODO: use actual FPS
p->animation.fps = 60.0;
#else
p->animation.fps = shState->graphics().getFrameRate(); p->animation.fps = shState->graphics().getFrameRate();
#endif // MKXPZ_RETRO
p->animation.frames.push_back(p->gl); p->animation.frames.push_back(p->gl);

View file

@ -624,11 +624,7 @@ void Font::initDefaults(const SharedFontState &sfs)
std::vector<std::string> &names = FontPrivate::initialDefaultNames; std::vector<std::string> &names = FontPrivate::initialDefaultNames;
names.clear(); names.clear();
#ifdef MKXPZ_RETRO // TODO: get from config
switch (1)
#else
switch (rgssVer) switch (rgssVer)
#endif // MKXPZ_RETRO
{ {
case 1 : case 1 :
// FIXME: Japanese version has "MS PGothic" instead // FIXME: Japanese version has "MS PGothic" instead
@ -648,13 +644,8 @@ void Font::initDefaults(const SharedFontState &sfs)
setDefaultName(names, sfs); setDefaultName(names, sfs);
#ifdef MKXPZ_RETRO // TODO: get from config
FontPrivate::defaultOutline = false;
FontPrivate::defaultShadow = false;
#else
FontPrivate::defaultOutline = (rgssVer >= 3 ? true : false); FontPrivate::defaultOutline = (rgssVer >= 3 ? true : false);
FontPrivate::defaultShadow = (rgssVer == 2 ? true : false); FontPrivate::defaultShadow = (rgssVer == 2 ? true : false);
#endif // MKXPZ_RETRO
} }
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO

View file

@ -195,18 +195,10 @@ int smoothScalingMethod(int scaleIsSpecial)
case SameScale: case SameScale:
return NearestNeighbor; return NearestNeighbor;
case DownScale: case DownScale:
#ifdef MKXPZ_RETRO
return 0; // TODO: get from config
#else
return shState->config().smoothScalingDown; return shState->config().smoothScalingDown;
#endif // MKXPZ_RETRO
} }
#ifdef MKXPZ_RETRO
return 0; // TODO: get from config
#else
return shState->config().smoothScaling; return shState->config().smoothScaling;
#endif // MKXPZ_RETRO
} }
static void _blitBegin(FBO::ID fbo, const Vec2i &size, int scaleIsSpecial) static void _blitBegin(FBO::ID fbo, const Vec2i &size, int scaleIsSpecial)

View file

@ -104,16 +104,12 @@ namespace TEX
static inline void setSmooth(bool mode) static inline void setSmooth(bool mode)
{ {
#ifndef MKXPZ_RETRO // TODO: get from config
if (mode && shState->config().smoothScalingMipmaps) { if (mode && shState->config().smoothScalingMipmaps) {
gl.GenerateMipmap(GL_TEXTURE_2D); gl.GenerateMipmap(GL_TEXTURE_2D);
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} else { } else {
#endif // MKXPZ_RETRO
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mode ? GL_LINEAR : GL_NEAREST); gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mode ? GL_LINEAR : GL_NEAREST);
#ifndef MKXPZ_RETRO
} }
#endif // MKXPZ_RETRO
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mode ? GL_LINEAR : GL_NEAREST); gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mode ? GL_LINEAR : GL_NEAREST);
} }

View file

@ -127,19 +127,12 @@ void GLState::reset() {
blendMode.init(BlendNormal); blendMode.init(BlendNormal);
blend.init(true); blend.init(true);
scissorTest.init(false); scissorTest.init(false);
#ifdef MKXPZ_RETRO
scissorBox.init(IntRect(0, 0, 640, 480)); // TODO: get from config
viewport.init(IntRect(0, 0, 640, 480));
#else
scissorBox.init(IntRect(0, 0, conf.defScreenW, conf.defScreenH)); scissorBox.init(IntRect(0, 0, conf.defScreenW, conf.defScreenH));
viewport.init(IntRect(0, 0, conf.defScreenW, conf.defScreenH)); viewport.init(IntRect(0, 0, conf.defScreenW, conf.defScreenH));
#endif // MKXPZ_RETRO
program.init(0); program.init(0);
gl.ActiveTexture(GL_TEXTURE0); gl.ActiveTexture(GL_TEXTURE0);
#ifndef MKXPZ_RETRO // TODO
if (conf.maxTextureSize > 0) if (conf.maxTextureSize > 0)
caps.maxTexSize = conf.maxTextureSize; caps.maxTexSize = conf.maxTextureSize;
#endif // MKXPZ_RETRO
} }

View file

@ -70,17 +70,10 @@
#include <climits> #include <climits>
#ifdef MKXPZ_RETRO #define DEF_SCREEN_W (rgssVer == 1 ? 640 : 544)
# define DEF_SCREEN_W 640 #define DEF_SCREEN_H (rgssVer == 1 ? 480 : 416)
# define DEF_SCREEN_H 480
# define DEF_FRAMERATE 40 #define DEF_FRAMERATE (rgssVer == 1 ? 40 : 60)
#else
# define DEF_SCREEN_W (rgssVer == 1 ? 640 : 544)
# define DEF_SCREEN_H (rgssVer == 1 ? 480 : 416)
# define DEF_FRAMERATE (rgssVer == 1 ? 40 : 60)
#endif // MKXPZ_RETRO
#define DEF_MAX_VIDEO_FRAMES 30 #define DEF_MAX_VIDEO_FRAMES 30
#define VIDEO_DELAY 10 #define VIDEO_DELAY 10
@ -859,18 +852,10 @@ struct GraphicsPrivate {
GraphicsPrivate(RGSSThreadData *rtData) GraphicsPrivate(RGSSThreadData *rtData)
: scResLores(DEF_SCREEN_W, DEF_SCREEN_H), : scResLores(DEF_SCREEN_W, DEF_SCREEN_H),
#ifdef MKXPZ_RETRO
scRes(DEF_SCREEN_W, DEF_SCREEN_H), // TODO: get from config
#else
scRes(rtData->config.enableHires ? (int)lround(rtData->config.framebufferScalingFactor * DEF_SCREEN_W) : DEF_SCREEN_W, scRes(rtData->config.enableHires ? (int)lround(rtData->config.framebufferScalingFactor * DEF_SCREEN_W) : DEF_SCREEN_W,
rtData->config.enableHires ? (int)lround(rtData->config.framebufferScalingFactor * DEF_SCREEN_H) : DEF_SCREEN_H), rtData->config.enableHires ? (int)lround(rtData->config.framebufferScalingFactor * DEF_SCREEN_H) : DEF_SCREEN_H),
#endif // MKXPZ_RETRO
scSize(scRes), scSize(scRes),
#ifdef MKXPZ_RETRO
winSize(640, 480), // TODO: use actual screen size
#else
winSize(rtData->config.defScreenW, rtData->config.defScreenH), winSize(rtData->config.defScreenW, rtData->config.defScreenH),
#endif // MKXPZ_RETRO
screen(scRes.x, scRes.y), threadData(rtData), screen(scRes.x, scRes.y), threadData(rtData),
#ifndef MKXPZ_RETRO #ifndef MKXPZ_RETRO
glCtx(SDL_GL_GetCurrentContext()), glCtx(SDL_GL_GetCurrentContext()),
@ -880,11 +865,7 @@ struct GraphicsPrivate {
#ifndef MKXPZ_RETRO #ifndef MKXPZ_RETRO
fpsLimiter(frameRate), fpsLimiter(frameRate),
#endif // MKXPZ_RETRO #endif // MKXPZ_RETRO
#ifdef MKXPZ_RETRO
useFrameSkip(false), // TODO: get from config
#else
useFrameSkip(rtData->config.frameSkip), useFrameSkip(rtData->config.frameSkip),
#endif // MKXPZ_RETRO
frozen(false), frozen(false),
last_update(0), last_avg_update(0), backingScaleFactor(1), integerScaleFactor(0, 0), last_update(0), last_avg_update(0), backingScaleFactor(1), integerScaleFactor(0, 0),
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
@ -906,11 +887,7 @@ struct GraphicsPrivate {
rebuildIntegerScaleBuffer(); rebuildIntegerScaleBuffer();
} }
#ifdef MKXPZ_RETRO
recalculateScreenSize(true); // TODO: get from config
#else
recalculateScreenSize(rtData->config.fixedAspectRatio); recalculateScreenSize(rtData->config.fixedAspectRatio);
#endif // MKXPZ_RETRO
updateScreenResoRatio(rtData); updateScreenResoRatio(rtData);
TEXFBO::init(frozenScene); TEXFBO::init(frozenScene);
@ -1575,7 +1552,7 @@ int Graphics::displayContentHeight() const {
int Graphics::displayWidth() const { int Graphics::displayWidth() const {
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
return 640; // TODO: use actual width return Graphics::displayContentWidth();
#else #else
SDL_DisplayMode dm{}; SDL_DisplayMode dm{};
SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(shState->sdlWindow()), &dm); SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(shState->sdlWindow()), &dm);
@ -1585,7 +1562,7 @@ int Graphics::displayWidth() const {
int Graphics::displayHeight() const { int Graphics::displayHeight() const {
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
return 480; // TODO: use actual height return Graphics::displayContentHeight();
#else #else
SDL_DisplayMode dm{}; SDL_DisplayMode dm{};
SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(shState->sdlWindow()), &dm); SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(shState->sdlWindow()), &dm);
@ -1794,11 +1771,7 @@ bool Graphics::getFixedAspectRatio() const
{ {
// It's a bit hacky to expose config values as a Graphics // It's a bit hacky to expose config values as a Graphics
// attribute, but there's really no point in state duplication // attribute, but there's really no point in state duplication
#ifdef MKXPZ_RETRO
return true; // TODO: get from config
#else
return shState->config().fixedAspectRatio; return shState->config().fixedAspectRatio;
#endif // MKXPZ_RETRO
} }
void Graphics::setFixedAspectRatio(bool value) void Graphics::setFixedAspectRatio(bool value)
@ -1815,11 +1788,7 @@ void Graphics::setFixedAspectRatio(bool value)
int Graphics::getSmoothScaling() const int Graphics::getSmoothScaling() const
{ {
// Same deal as with fixed aspect ratio // Same deal as with fixed aspect ratio
#ifdef MKXPZ_RETRO
return 0; // TODO: get from config
#else
return shState->config().smoothScaling; return shState->config().smoothScaling;
#endif // MKXPZ_RETRO
} }
void Graphics::setSmoothScaling(int value) void Graphics::setSmoothScaling(int value)

View file

@ -632,11 +632,7 @@ void Sprite::draw()
int sourceWidthHires = p->bitmap->hasHires() ? p->bitmap->getHires()->width() : p->bitmap->width(); int sourceWidthHires = p->bitmap->hasHires() ? p->bitmap->getHires()->width() : p->bitmap->width();
int sourceHeightHires = p->bitmap->hasHires() ? p->bitmap->getHires()->height() : p->bitmap->height(); int sourceHeightHires = p->bitmap->hasHires() ? p->bitmap->getHires()->height() : p->bitmap->height();
#ifdef MKXPZ_RETRO
double framebufferScalingFactor = 1.0; // TODO: get from config
#else
double framebufferScalingFactor = shState->config().enableHires ? shState->config().framebufferScalingFactor : 1.0; double framebufferScalingFactor = shState->config().enableHires ? shState->config().framebufferScalingFactor : 1.0;
#endif // MKXPZ_RETRO
int targetWidthHires = (int)lround(framebufferScalingFactor * p->bitmap->width() * p->trans.getScale().x); int targetWidthHires = (int)lround(framebufferScalingFactor * p->bitmap->width() * p->trans.getScale().x);
int targetHeightHires = (int)lround(framebufferScalingFactor * p->bitmap->height() * p->trans.getScale().y); int targetHeightHires = (int)lround(framebufferScalingFactor * p->bitmap->height() * p->trans.getScale().y);
@ -747,11 +743,7 @@ void Sprite::draw()
shader.bind(); shader.bind();
shader.setTexSize(Vec2i(sourceWidthHires, sourceHeightHires)); shader.setTexSize(Vec2i(sourceWidthHires, sourceHeightHires));
#ifdef MKXPZ_RETRO
shader.setSharpness(100); // TODO: get from config
#else
shader.setSharpness(shState->config().bicubicSharpness); shader.setSharpness(shState->config().bicubicSharpness);
#endif // MKXPZ_RETRO
shader.setSpriteMat(p->trans.getMatrix()); shader.setSpriteMat(p->trans.getMatrix());
shader.applyViewportProj(); shader.applyViewportProj();
base = &shader; base = &shader;
@ -775,11 +767,7 @@ void Sprite::draw()
shader.bind(); shader.bind();
shader.setTexSize(Vec2i(sourceWidthHires, sourceHeightHires)); shader.setTexSize(Vec2i(sourceWidthHires, sourceHeightHires));
#ifdef MKXPZ_RETRO
shader.setTargetScale(Vec2(1.0f, 1.0f)); // TODO: get from config
#else
shader.setTargetScale(Vec2((float)(shState->config().xbrzScalingFactor), (float)(shState->config().xbrzScalingFactor))); shader.setTargetScale(Vec2((float)(shState->config().xbrzScalingFactor), (float)(shState->config().xbrzScalingFactor)));
#endif // MKXPZ_RETRO
shader.setSpriteMat(p->trans.getMatrix()); shader.setSpriteMat(p->trans.getMatrix());
shader.applyViewportProj(); shader.applyViewportProj();
base = &shader; base = &shader;

View file

@ -605,11 +605,7 @@ struct TilemapPrivate
/* Mega surface tileset */ /* Mega surface tileset */
SDL_Surface *tsSurf = tileset->megaSurface(); SDL_Surface *tsSurf = tileset->megaSurface();
#ifdef MKXPZ_RETRO
if (false) // TODO: get from config
#else
if (shState->config().subImageFix) if (shState->config().subImageFix)
#endif // MKXPZ_RETRO
{ {
/* Implementation for broken GL drivers */ /* Implementation for broken GL drivers */
FBO::bind(atlas.gl.fbo); FBO::bind(atlas.gl.fbo);

View file

@ -111,12 +111,8 @@ Viewport::Viewport()
: SceneElement(*shState->screen()), : SceneElement(*shState->screen()),
sceneLink(this) sceneLink(this)
{ {
#ifdef MKXPZ_RETRO
initViewport(0, 0, 640, 480); // TODO: use the actual viewport size
#else
const Graphics &graphics = shState->graphics(); const Graphics &graphics = shState->graphics();
initViewport(0, 0, graphics.width(), graphics.height()); initViewport(0, 0, graphics.width(), graphics.height());
#endif // MKXPZ_RETRO
} }
void Viewport::initViewport(int x, int y, int width, int height) void Viewport::initViewport(int x, int y, int width, int height)

View file

@ -88,6 +88,9 @@ public:
inline PHYSFS_File &operator*() { inline PHYSFS_File &operator*() {
return *get(); return *get();
} }
inline bool is_open() {
return inner != NULL;
}
}; };
FileSystem(const char *argv0, FileSystem(const char *argv0,

View file

@ -21,12 +21,13 @@
#include "input.h" #include "input.h"
#include "core.h" #include "core.h"
#include "sharedstate.h"
#include "graphics.h"
#define JOYPAD_BUTTON_MAX 16 #define JOYPAD_BUTTON_MAX 16
#define REPEAT_NONE 255 #define REPEAT_NONE 255
#define REPEAT_START 0.4 // TODO: should be 0.375 when RGSS version >= 2 #define REPEAT_START (rgssVer >= 2 ? 0.375 : 0.400)
#define REPEAT_DELAY 0.1 #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},
@ -233,7 +234,8 @@ bool Input::isReleased(int button)
bool Input::isRepeated(int button) bool Input::isRepeated(int button)
{ {
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)); int frame_rate = shState->graphics().getFrameRate();
return p->isRepeat(button) && (p->repeatCount == 0 || (p->repeatCount >= (size_t)std::ceil(REPEAT_START * frame_rate) && (p->repeatCount + 1) % (size_t)std::ceil(REPEAT_DELAY * frame_rate) == 0));
} }
unsigned int Input::count(int button) unsigned int Input::count(int button)
@ -243,7 +245,7 @@ unsigned int Input::count(int button)
double Input::repeatTime(int button) double Input::repeatTime(int button)
{ {
return p->isRepeat(button) ? (double)p->repeatCount / FPS : 0; return p->isRepeat(button) ? (double)p->repeatCount / shState->graphics().getFrameRate() : 0;
} }
bool Input::isPressedEx(int button, bool isVKey) bool Input::isPressedEx(int button, bool isVKey)

View file

@ -8,9 +8,7 @@ if is_libretro
global_args += '-DMPG123_NO_LARGENAME' global_args += '-DMPG123_NO_LARGENAME'
global_args += '-DGL_GLES_PROTOTYPES=0' global_args += '-DGL_GLES_PROTOTYPES=0'
if host_system == 'darwin' global_dependencies += dependency('iconv', static: core_is_static or host_system == 'windows')
global_dependencies += compilers['cpp'].find_library('iconv')
endif
global_dependencies += subproject('libretro-common').get_variable('libretro_common') global_dependencies += subproject('libretro-common').get_variable('libretro_common')
@ -381,7 +379,7 @@ global_include_dirs += include_directories('.',
main_source = files( main_source = files(
is_libretro ? 'core.cpp' : 'main.cpp', is_libretro ? 'core.cpp' : 'main.cpp',
is_libretro ? [] : 'config.cpp', 'config.cpp',
is_libretro ? [] : 'eventthread.cpp', is_libretro ? [] : 'eventthread.cpp',
is_libretro ? [] : 'settingsmenu.cpp', is_libretro ? [] : 'settingsmenu.cpp',
'sharedstate.cpp', 'sharedstate.cpp',
@ -427,7 +425,7 @@ main_source = files(
'display/gl/tilequad.cpp', 'display/gl/tilequad.cpp',
'display/gl/vertex.cpp', 'display/gl/vertex.cpp',
is_libretro ? [] : 'util/iniconfig.cpp', 'util/iniconfig.cpp',
is_libretro ? [] : 'util/win-consoleutils.cpp', is_libretro ? [] : 'util/win-consoleutils.cpp',
'etc/etc.cpp', 'etc/etc.cpp',

View file

@ -77,9 +77,9 @@ struct SharedStatePrivate
FileSystem fileSystem; FileSystem fileSystem;
EventThread &eThread; EventThread &eThread;
#endif // MKXPZ_RETRO
RGSSThreadData &rtData; RGSSThreadData &rtData;
Config &config; Config &config;
#endif // MKXPZ_RETRO
SharedMidiState midiState; SharedMidiState midiState;
Graphics graphics; Graphics graphics;
@ -117,9 +117,9 @@ struct SharedStatePrivate
sdlWindow(threadData->window), sdlWindow(threadData->window),
fileSystem(threadData->argv0, threadData->config.allowSymlinks), fileSystem(threadData->argv0, threadData->config.allowSymlinks),
eThread(*threadData->ethread), eThread(*threadData->ethread),
#endif // MKXPZ_RETRO
rtData(*threadData), rtData(*threadData),
config(threadData->config), config(threadData->config),
#endif // MKXPZ_RETRO
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
midiState(), midiState(),
#else #else
@ -184,12 +184,10 @@ struct SharedStatePrivate
TEXFBO::allocEmpty(gpTexFBO, globalTexW, globalTexH); TEXFBO::allocEmpty(gpTexFBO, globalTexW, globalTexH);
TEXFBO::linkFBO(gpTexFBO); TEXFBO::linkFBO(gpTexFBO);
#ifndef MKXPZ_RETRO
/* RGSS3 games will call setup_midi, so there's /* RGSS3 games will call setup_midi, so there's
* no need to do it on startup */ * no need to do it on startup */
if (rgssVer <= 2) if (rgssVer <= 2)
midiState.initIfNeeded(threadData->config); midiState.initIfNeeded(threadData->config);
#endif // MKXPZ_RETRO
} }
~SharedStatePrivate() ~SharedStatePrivate()
@ -206,9 +204,7 @@ void SharedState::initInstance(RGSSThreadData *threadData)
* SharedState depends on GlobalIBO existing, * SharedState depends on GlobalIBO existing,
* Font depends on SharedState existing */ * Font depends on SharedState existing */
#ifndef MKXPZ_RETRO
rgssVersion = threadData->config.rgssVersion; rgssVersion = threadData->config.rgssVersion;
#endif // MKXPZ_RETRO
_globalIBO = new GlobalIBO(); _globalIBO = new GlobalIBO();
_globalIBO->ensureSize(1); _globalIBO->ensureSize(1);
@ -262,9 +258,9 @@ GSATT(Scene*, screen)
#ifndef MKXPZ_RETRO #ifndef MKXPZ_RETRO
GSATT(FileSystem&, fileSystem) GSATT(FileSystem&, fileSystem)
GSATT(EventThread&, eThread) GSATT(EventThread&, eThread)
#endif // MKXPZ_RETRO
GSATT(RGSSThreadData&, rtData) GSATT(RGSSThreadData&, rtData)
GSATT(Config&, config) GSATT(Config&, config)
#endif // MKXPZ_RETRO
GSATT(Graphics&, graphics) GSATT(Graphics&, graphics)
#ifndef MKXPZ_RETRO #ifndef MKXPZ_RETRO
GSATT(Input&, input) GSATT(Input&, input)

View file

@ -1,7 +1,9 @@
#ifndef SDLUTIL_H #ifndef SDLUTIL_H
#define SDLUTIL_H #define SDLUTIL_H
#ifndef MKXPZ_RETRO #ifdef MKXPZ_RETRO
# include "filesystem.h"
#else
# include <SDL_atomic.h> # include <SDL_atomic.h>
# include <SDL_thread.h> # include <SDL_thread.h>
# include <SDL_rwops.h> # include <SDL_rwops.h>
@ -11,6 +13,48 @@
#include <iostream> #include <iostream>
#include <unistd.h> #include <unistd.h>
template<typename O, typename R, size_t bufSize = 248, size_t pbSize = 8>
class RWBuf : public std::streambuf
{
public:
RWBuf(O ops)
: ops(ops)
{
char *end = buf + bufSize + pbSize;
setg(end, end, end);
}
private:
int_type underflow()
{
if (!ops)
return traits_type::eof();
if (gptr() < egptr())
return traits_type::to_int_type(*gptr());
char *base = buf;
char *start = base;
if (eback() == base)
{
std::memmove(base, egptr() - pbSize, pbSize);
start += pbSize;
}
size_t n = R::read(ops, start, bufSize - (start - base));
if (n == 0)
return traits_type::eof();
setg(base, start, start + n);
return underflow();
}
O ops;
char buf[bufSize+pbSize];
};
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
struct AtomicFlag struct AtomicFlag
{ {
@ -41,6 +85,17 @@ struct AtomicFlag
private: private:
mutable bool atom; mutable bool atom;
}; };
class PHYSFSRead
{
public:
static size_t read(std::shared_ptr<struct FileSystem::File> ops, void *buf, size_t size)
{
return std::max((PHYSFS_sint64)0, PHYSFS_readBytes(ops->get(), buf, size));
}
};
typedef RWBuf<std::shared_ptr<struct FileSystem::File>, PHYSFSRead> PHYSFSRWBuf;
#else #else
struct AtomicFlag struct AtomicFlag
{ {
@ -129,48 +184,17 @@ inline bool readFileSDL(const char *path,
return true; return true;
} }
template<size_t bufSize = 248, size_t pbSize = 8> class SDLRead
class SDLRWBuf : public std::streambuf
{ {
public: public:
SDLRWBuf(SDL_RWops *ops) static size_t read(SDL_RWops *ops, void *buf, size_t size)
: ops(ops)
{ {
char *end = buf + bufSize + pbSize; return SDL_RWread(ops, buf, 1, size);
setg(end, end, end);
} }
private:
int_type underflow()
{
if (!ops)
return traits_type::eof();
if (gptr() < egptr())
return traits_type::to_int_type(*gptr());
char *base = buf;
char *start = base;
if (eback() == base)
{
std::memmove(base, egptr() - pbSize, pbSize);
start += pbSize;
}
size_t n = SDL_RWread(ops, start, 1, bufSize - (start - base));
if (n == 0)
return traits_type::eof();
setg(base, start, start + n);
return underflow();
}
SDL_RWops *ops;
char buf[bufSize+pbSize];
}; };
typedef RWBuf<SDL_RWops *, SDLRead> SDLRWBuf;
class SDLRWStream class SDLRWStream
{ {
public: public:
@ -199,7 +223,7 @@ public:
private: private:
SDL_RWops *ops; SDL_RWops *ops;
SDLRWBuf<> buf; SDLRWBuf buf;
std::istream s; std::istream s;
}; };
#endif // MKXPZ_RETRO #endif // MKXPZ_RETRO