mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-23 15:23:44 +02:00
Implement config loading in libretro builds
This commit is contained in:
parent
c5af94c25a
commit
8c16bc0092
24 changed files with 224 additions and 252 deletions
|
@ -1,8 +1,8 @@
|
|||
global_sources += files([
|
||||
global_sources += files(
|
||||
'binding-base.cpp',
|
||||
'binding-util.cpp',
|
||||
'module_rpg.cpp',
|
||||
'sandbox.cpp',
|
||||
'wasi.cpp',
|
||||
'wasm-rt.cpp',
|
||||
])
|
||||
)
|
||||
|
|
|
@ -242,11 +242,7 @@ struct ALStreamOpenHandler : FileSystem::OpenHandler
|
|||
|
||||
if (!strcmp(sig, "MThd"))
|
||||
{
|
||||
#ifdef MKXPZ_RETRO
|
||||
shState->midiState().initIfNeeded();
|
||||
#else
|
||||
shState->midiState().initIfNeeded(shState->config());
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
if (HAVE_FLUID)
|
||||
{
|
||||
|
|
|
@ -31,7 +31,9 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifndef MKXPZ_RETRO
|
||||
#ifdef MKXPZ_RETRO
|
||||
# include "graphics.h"
|
||||
#else
|
||||
# include "sdl-util.h"
|
||||
# include <SDL_thread.h>
|
||||
# include <SDL_timer.h>
|
||||
|
@ -74,24 +76,16 @@ struct AudioPrivate
|
|||
MeWatchState state;
|
||||
} meWatch;
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
AudioPrivate()
|
||||
#else
|
||||
AudioPrivate(RGSSThreadData &rtData)
|
||||
#endif // MKXPZ_RETRO
|
||||
: bgs(ALStream::Looped, "bgs"),
|
||||
me(ALStream::NotLooped, "me"),
|
||||
#ifndef MKXPZ_RETRO
|
||||
se(rtData.config),
|
||||
#ifndef MKXPZ_RETRO
|
||||
syncPoint(rtData.syncPoint),
|
||||
#endif // MKXPZ_RETRO
|
||||
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++) {
|
||||
#endif // MKXPZ_RETRO
|
||||
std::string id = std::string("bgm" + std::to_string(i));
|
||||
bgmTracks.push_back(new AudioStream(ALStream::Looped, id.c_str()));
|
||||
}
|
||||
|
@ -123,9 +117,10 @@ struct AudioPrivate
|
|||
|
||||
void meWatchProc()
|
||||
{
|
||||
#ifdef MKXPZ_RETRO // TODO: use FPS
|
||||
const float fadeOutStep = 1.f / (200 / 17);
|
||||
const float fadeInStep = 1.f / (1000 / 17);
|
||||
#ifdef MKXPZ_RETRO
|
||||
const int fps = shState->graphics().getFrameRate();
|
||||
const float fadeOutStep = 5.f / fps;
|
||||
const float fadeInStep = 1.f / fps;
|
||||
#else
|
||||
const float fadeOutStep = 1.f / (200 / AUDIO_SLEEP);
|
||||
const float fadeInStep = 1.f / (1000 / AUDIO_SLEEP);
|
||||
|
@ -316,15 +311,9 @@ struct AudioPrivate
|
|||
#endif // MKXPZ_RETRO
|
||||
};
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
Audio::Audio()
|
||||
: p(new AudioPrivate())
|
||||
{}
|
||||
#else
|
||||
Audio::Audio(RGSSThreadData &rtData)
|
||||
: p(new AudioPrivate(rtData))
|
||||
{}
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
void Audio::render() {
|
||||
|
|
|
@ -77,15 +77,13 @@ public:
|
|||
|
||||
void reset();
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
Audio();
|
||||
~Audio();
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
private:
|
||||
#ifndef MKXPZ_RETRO
|
||||
private:
|
||||
#endif // MKXPZ_RETRO
|
||||
Audio(RGSSThreadData &rtData);
|
||||
~Audio();
|
||||
#ifdef MKXPZ_RETRO
|
||||
private:
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
friend struct SharedStatePrivate;
|
||||
|
|
|
@ -78,7 +78,7 @@ struct SharedMidiState
|
|||
}
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
void initIfNeeded()
|
||||
void initIfNeeded(const Config &conf)
|
||||
{
|
||||
if (inited)
|
||||
return;
|
||||
|
@ -93,8 +93,8 @@ struct SharedMidiState
|
|||
flSettings = fluid.new_settings();
|
||||
fluid.settings_setnum(flSettings, "synth.gain", 1.0f);
|
||||
fluid.settings_setnum(flSettings, "synth.sample-rate", SYNTH_SAMPLERATE);
|
||||
fluid.settings_setint(flSettings, "synth.chorus.active", 0);
|
||||
fluid.settings_setint(flSettings, "synth.reverb.active", 0);
|
||||
fluid.settings_setint(flSettings, "synth.chorus.active", conf.midi.chorus);
|
||||
fluid.settings_setint(flSettings, "synth.reverb.active", conf.midi.reverb);
|
||||
|
||||
extern const uint8_t mkxp_gmgsx_sf2[];
|
||||
extern const size_t mkxp_gmgsx_sf2_len;
|
||||
|
|
|
@ -94,17 +94,9 @@ arrayPushBack(std::vector<size_t> &array, size_t size, size_t index)
|
|||
array[size-1] = v;
|
||||
}
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
SoundEmitter::SoundEmitter()
|
||||
#else
|
||||
SoundEmitter::SoundEmitter(const Config &conf)
|
||||
#endif // MKXPZ_RETRO
|
||||
: bufferBytes(0),
|
||||
#ifdef MKXPZ_RETRO
|
||||
srcCount(6), // TODO: get from config
|
||||
#else
|
||||
srcCount(conf.SE.sourceCount),
|
||||
#endif // MKXPZ_RETRO
|
||||
alSrcs(srcCount),
|
||||
atchBufs(srcCount),
|
||||
srcPrio(srcCount)
|
||||
|
|
|
@ -49,11 +49,7 @@ struct SoundEmitter
|
|||
/* Indices of sources, sorted by priority (lowest first) */
|
||||
std::vector<size_t> srcPrio;
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
SoundEmitter();
|
||||
#else
|
||||
SoundEmitter(const Config &conf);
|
||||
#endif // MKXPZ_RETRO
|
||||
~SoundEmitter();
|
||||
|
||||
void play(const std::string &filename,
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
//
|
||||
|
||||
#include "config.h"
|
||||
#ifdef MKXPZ_RETRO
|
||||
# include "core.h"
|
||||
#else
|
||||
# include <SDL_filesystem.h>
|
||||
#endif // MKXPZ_RETRO
|
||||
#include <assert.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -28,7 +32,8 @@
|
|||
|
||||
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);
|
||||
if (!path)
|
||||
return std::string("");
|
||||
|
@ -36,8 +41,9 @@ std::string prefPath(const char *org, const char *app) {
|
|||
SDL_free(path);
|
||||
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_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());
|
||||
if (src.is_null())
|
||||
return false;
|
||||
|
@ -84,7 +90,8 @@ bool copyObject(json::value &dest, json::value &src, const char *objectName = ""
|
|||
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);
|
||||
if (!e)
|
||||
return defaultValue;
|
||||
|
@ -96,16 +103,40 @@ bool getEnvironmentBool(const char *env, bool defaultValue) {
|
|||
|
||||
return defaultValue;
|
||||
}
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
json::value readConfFile(const char *path) {
|
||||
static json::value readConfFile(const char *path) {
|
||||
|
||||
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({});
|
||||
}
|
||||
|
||||
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);
|
||||
#endif // MKXPZ_RETRO
|
||||
ret = json::parse5(Encoding::convertString(cfg));
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
|
@ -121,7 +152,12 @@ json::value readConfFile(const char *path) {
|
|||
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() {}
|
||||
|
||||
|
@ -254,17 +290,21 @@ try { exp } catch (...) {}
|
|||
SET_OPT(defScreenW, 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
|
||||
if (!gameFolder.empty() && !mkxp_fs::setCurrentDirectory(gameFolder.c_str())) {
|
||||
throw Exception(Exception::MKXPError, "Unable to switch into gameFolder %s", gameFolder.c_str());
|
||||
}
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
readGameINI();
|
||||
|
||||
#ifndef MKXPZ_RETRO
|
||||
// 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);
|
||||
json::value userConf = readConfFile(userConfPath.c_str());
|
||||
copyObject(optsJ, userConf);
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
// now RESUME
|
||||
|
||||
|
@ -342,8 +382,10 @@ try { exp } catch (...) {}
|
|||
SE.sourceCount = clamp(SE.sourceCount, 1, 64);
|
||||
BGM.trackCount = clamp(BGM.trackCount, 1, 16);
|
||||
|
||||
#ifndef MKXPZ_RETRO
|
||||
// Determine whether to open a console window on... Windows
|
||||
winConsole = getEnvironmentBool("MKXPZ_WINDOWS_CONSOLE", editor.debug);
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Determine whether to use the Metal renderer on macOS
|
||||
|
@ -351,11 +393,13 @@ try { exp } catch (...) {}
|
|||
preferMetalRenderer = isMetalSupported() && getEnvironmentBool("MKXPZ_MACOS_METAL", preferMetalRenderer);
|
||||
#endif
|
||||
|
||||
#ifndef MKXPZ_RETRO
|
||||
// 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.
|
||||
// The config is re-read after the window is already created, so some entries
|
||||
// may not take effect
|
||||
manualFolderSelect = getEnvironmentBool("MKXPZ_FOLDER_SELECT", false);
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
raw = optsJ;
|
||||
}
|
||||
|
@ -387,14 +431,29 @@ void Config::readGameINI() {
|
|||
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");
|
||||
SDLRWStream iniFile(iniFileName.c_str(), "r");
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
bool convSuccess = false;
|
||||
#ifdef MKXPZ_RETRO
|
||||
if (iniFile->is_open())
|
||||
#else
|
||||
if (iniFile)
|
||||
#endif // MKXPZ_RETRO
|
||||
{
|
||||
INIConfiguration ic;
|
||||
#ifdef MKXPZ_RETRO
|
||||
PHYSFSRWBuf buf(iniFile);
|
||||
std::istream stream(&buf);
|
||||
if (ic.load(stream))
|
||||
#else
|
||||
if (ic.load(iniFile.stream()))
|
||||
#endif // MKXPZ_RETRO
|
||||
{
|
||||
GUARD(game.title = ic.getStringProperty("Game", "Title"););
|
||||
GUARD(game.scripts = ic.getStringProperty("Game", "Scripts"););
|
||||
|
@ -429,7 +488,9 @@ void Config::readGameINI() {
|
|||
if (dataPathApp.empty())
|
||||
dataPathApp = game.title;
|
||||
|
||||
#ifndef MKXPZ_RETRO
|
||||
customDataPath = mkxp_fs::normalizePath(prefPath(dataPathOrg.c_str(), dataPathApp.c_str()).c_str(), 0, 1);
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
if (rgssVersion == 0) {
|
||||
/* Try to guess RGSS version based on Data/Scripts extension */
|
||||
|
|
|
@ -35,7 +35,9 @@ struct Config {
|
|||
int rgssVersion;
|
||||
|
||||
bool debugMode;
|
||||
#ifndef MKXPZ_RETRO
|
||||
bool winConsole;
|
||||
#endif // MKXPZ_RETRO
|
||||
bool preferMetalRenderer;
|
||||
bool displayFPS;
|
||||
bool printFPS;
|
||||
|
@ -78,7 +80,9 @@ struct Config {
|
|||
} integerScaling;
|
||||
|
||||
std::string gameFolder;
|
||||
#ifndef MKXPZ_RETRO
|
||||
bool manualFolderSelect;
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
bool anyAltToggleFS;
|
||||
bool enableReset;
|
||||
|
@ -165,7 +169,9 @@ struct Config {
|
|||
std::string userConfPath;
|
||||
|
||||
/* Internal */
|
||||
#ifndef MKXPZ_RETRO
|
||||
std::string customDataPath;
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
Config();
|
||||
|
||||
|
|
75
src/core.cpp
75
src/core.cpp
|
@ -37,6 +37,7 @@
|
|||
#include "gl-fun.h"
|
||||
#include "glstate.h"
|
||||
#include "sharedmidistate.h"
|
||||
#include "eventthread.h"
|
||||
|
||||
using namespace mkxp_retro;
|
||||
using namespace mkxp_sandbox;
|
||||
|
@ -59,6 +60,7 @@ static int16_t *sound_buf = NULL;
|
|||
static bool retro_framebuffer_supported;
|
||||
static bool shared_state_initialized;
|
||||
static PHYSFS_File *rgssad = NULL;
|
||||
static retro_system_av_info av_info;
|
||||
|
||||
namespace mkxp_retro {
|
||||
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<Input> mkxp_retro::input;
|
||||
boost::optional<FileSystem> mkxp_retro::fs;
|
||||
static boost::optional<Config> conf;
|
||||
static boost::optional<RGSSThreadData> thread_data;
|
||||
static std::string game_path;
|
||||
|
||||
static VALUE func(VALUE arg) {
|
||||
|
@ -165,6 +169,8 @@ static void deinit_sandbox() {
|
|||
PHYSFS_close(rgssad);
|
||||
rgssad = NULL;
|
||||
}
|
||||
thread_data.reset();
|
||||
conf.reset();
|
||||
fs.reset();
|
||||
input.reset();
|
||||
}
|
||||
|
@ -201,13 +207,16 @@ static bool init_sandbox() {
|
|||
|
||||
fs->addPath(parsed_game_path.c_str(), "/mkxp-retro-game");
|
||||
|
||||
// TODO: use execName from config instead of hardcoding "Game" as the filename
|
||||
if ((rgssad = PHYSFS_openRead("/mkxp-retro-game/Game.rgssad")) != NULL) {
|
||||
PHYSFS_mountHandle(rgssad, "Game.rgssad", "/mkxp-retro-game", 1);
|
||||
} else if ((rgssad = PHYSFS_openRead("/mkxp-retro-game/Game.rgss2a")) != NULL) {
|
||||
PHYSFS_mountHandle(rgssad, "Game.rgss2a", "/mkxp-retro-game", 1);
|
||||
} else if ((rgssad = PHYSFS_openRead("/mkxp-retro-game/Game.rgss3a")) != NULL) {
|
||||
PHYSFS_mountHandle(rgssad, "Game.rgss3a", "/mkxp-retro-game", 1);
|
||||
conf.emplace();
|
||||
conf->read(0, NULL);
|
||||
thread_data.emplace((EventThread *)NULL, (const char *)NULL, (SDL_Window *)NULL, (ALCdevice *)NULL, 60, 1, *conf);
|
||||
|
||||
if ((rgssad = PHYSFS_openRead(("/mkxp-retro-game/" + conf->execName + ".rgssad").c_str())) != NULL) {
|
||||
PHYSFS_mountHandle(rgssad, (conf->execName + ".rgssad").c_str(), "/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);
|
||||
|
@ -254,7 +263,7 @@ static bool init_sandbox() {
|
|||
fluid_set_log_function(FLUID_INFO, fluid_log, NULL);
|
||||
fluid_set_log_function(FLUID_DBG, fluid_log, NULL);
|
||||
|
||||
audio.emplace();
|
||||
audio.emplace(*thread_data);
|
||||
|
||||
try {
|
||||
mkxp_retro::sandbox.emplace();
|
||||
|
@ -264,6 +273,16 @@ static bool init_sandbox() {
|
|||
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;
|
||||
frame_rate = 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) {
|
||||
std::memset(info, 0, sizeof *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,
|
||||
};
|
||||
*info = av_info;
|
||||
}
|
||||
|
||||
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()`
|
||||
if (!shared_state_initialized) {
|
||||
SharedState::initInstance(NULL);
|
||||
SharedState::initInstance(&thread_data.get());
|
||||
shared_state_initialized = true;
|
||||
} else if (hw_render.context_type != RETRO_HW_CONTEXT_NONE) {
|
||||
glState.reset();
|
||||
|
@ -391,9 +399,7 @@ extern "C" RETRO_API void retro_run() {
|
|||
}
|
||||
}
|
||||
|
||||
if (mkxp_retro::sandbox.has_value()) {
|
||||
// Update frame rate if needed
|
||||
if (frame_rate != shState->graphics().getFrameRate()) {
|
||||
if (mkxp_retro::sandbox.has_value() && frame_rate != shState->graphics().getFrameRate()) {
|
||||
frame_rate = shState->graphics().getFrameRate();
|
||||
frame_rate_remainder %= frame_rate;
|
||||
samples_per_frame = SYNTH_SAMPLERATE / frame_rate;
|
||||
|
@ -407,21 +413,8 @@ extern "C" RETRO_API void retro_run() {
|
|||
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);
|
||||
}
|
||||
av_info.timing.fps = frame_rate;
|
||||
environment(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &av_info);
|
||||
}
|
||||
|
||||
void *fb;
|
||||
|
@ -447,7 +440,9 @@ extern "C" RETRO_API void retro_run() {
|
|||
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()) {
|
||||
audio->render();
|
||||
|
|
|
@ -1237,11 +1237,7 @@ void Bitmap::stretchBlt(IntRect destRect,
|
|||
if (srcSurf)
|
||||
{
|
||||
SDL_Rect srcRect = sourceRect;
|
||||
#ifdef MKXPZ_RETRO
|
||||
bool subImageFix = false; // TODO: get from config
|
||||
#else
|
||||
bool subImageFix = shState->config().subImageFix;
|
||||
#endif // MKXPZ_RETRO
|
||||
bool srcRectTooBig = srcRect.w > glState.caps.maxTexSize ||
|
||||
srcRect.h > glState.caps.maxTexSize;
|
||||
bool srcSurfTooBig = !unpack_subimage && (
|
||||
|
@ -1843,7 +1839,10 @@ Color Bitmap::getPixel(int x, int y) const
|
|||
}
|
||||
|
||||
#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
|
||||
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;
|
||||
|
||||
if (p->animation.fps <= 0)
|
||||
#ifdef MKXPZ_RETRO // TODO: use actual FPS
|
||||
p->animation.fps = 60.0;
|
||||
#else
|
||||
p->animation.fps = shState->graphics().getFrameRate();
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
p->animation.frames.push_back(p->gl);
|
||||
|
||||
|
|
|
@ -624,11 +624,7 @@ void Font::initDefaults(const SharedFontState &sfs)
|
|||
std::vector<std::string> &names = FontPrivate::initialDefaultNames;
|
||||
names.clear();
|
||||
|
||||
#ifdef MKXPZ_RETRO // TODO: get from config
|
||||
switch (1)
|
||||
#else
|
||||
switch (rgssVer)
|
||||
#endif // MKXPZ_RETRO
|
||||
{
|
||||
case 1 :
|
||||
// FIXME: Japanese version has "MS PGothic" instead
|
||||
|
@ -648,13 +644,8 @@ void Font::initDefaults(const SharedFontState &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::defaultShadow = (rgssVer == 2 ? true : false);
|
||||
#endif // MKXPZ_RETRO
|
||||
}
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
|
|
|
@ -195,18 +195,10 @@ int smoothScalingMethod(int scaleIsSpecial)
|
|||
case SameScale:
|
||||
return NearestNeighbor;
|
||||
case DownScale:
|
||||
#ifdef MKXPZ_RETRO
|
||||
return 0; // TODO: get from config
|
||||
#else
|
||||
return shState->config().smoothScalingDown;
|
||||
#endif // MKXPZ_RETRO
|
||||
}
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
return 0; // TODO: get from config
|
||||
#else
|
||||
return shState->config().smoothScaling;
|
||||
#endif // MKXPZ_RETRO
|
||||
}
|
||||
|
||||
static void _blitBegin(FBO::ID fbo, const Vec2i &size, int scaleIsSpecial)
|
||||
|
|
|
@ -104,16 +104,12 @@ namespace TEX
|
|||
|
||||
static inline void setSmooth(bool mode)
|
||||
{
|
||||
#ifndef MKXPZ_RETRO // TODO: get from config
|
||||
if (mode && shState->config().smoothScalingMipmaps) {
|
||||
gl.GenerateMipmap(GL_TEXTURE_2D);
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
} else {
|
||||
#endif // MKXPZ_RETRO
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -127,19 +127,12 @@ void GLState::reset() {
|
|||
blendMode.init(BlendNormal);
|
||||
blend.init(true);
|
||||
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));
|
||||
viewport.init(IntRect(0, 0, conf.defScreenW, conf.defScreenH));
|
||||
#endif // MKXPZ_RETRO
|
||||
program.init(0);
|
||||
|
||||
gl.ActiveTexture(GL_TEXTURE0);
|
||||
|
||||
#ifndef MKXPZ_RETRO // TODO
|
||||
if (conf.maxTextureSize > 0)
|
||||
caps.maxTexSize = conf.maxTextureSize;
|
||||
#endif // MKXPZ_RETRO
|
||||
}
|
||||
|
|
|
@ -70,17 +70,10 @@
|
|||
#include <climits>
|
||||
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
# define DEF_SCREEN_W 640
|
||||
# define DEF_SCREEN_H 480
|
||||
|
||||
# define DEF_FRAMERATE 40
|
||||
#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 VIDEO_DELAY 10
|
||||
|
@ -859,18 +852,10 @@ struct GraphicsPrivate {
|
|||
|
||||
GraphicsPrivate(RGSSThreadData *rtData)
|
||||
: 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,
|
||||
rtData->config.enableHires ? (int)lround(rtData->config.framebufferScalingFactor * DEF_SCREEN_H) : DEF_SCREEN_H),
|
||||
#endif // MKXPZ_RETRO
|
||||
scSize(scRes),
|
||||
#ifdef MKXPZ_RETRO
|
||||
winSize(640, 480), // TODO: use actual screen size
|
||||
#else
|
||||
winSize(rtData->config.defScreenW, rtData->config.defScreenH),
|
||||
#endif // MKXPZ_RETRO
|
||||
screen(scRes.x, scRes.y), threadData(rtData),
|
||||
#ifndef MKXPZ_RETRO
|
||||
glCtx(SDL_GL_GetCurrentContext()),
|
||||
|
@ -880,11 +865,7 @@ struct GraphicsPrivate {
|
|||
#ifndef MKXPZ_RETRO
|
||||
fpsLimiter(frameRate),
|
||||
#endif // MKXPZ_RETRO
|
||||
#ifdef MKXPZ_RETRO
|
||||
useFrameSkip(false), // TODO: get from config
|
||||
#else
|
||||
useFrameSkip(rtData->config.frameSkip),
|
||||
#endif // MKXPZ_RETRO
|
||||
frozen(false),
|
||||
last_update(0), last_avg_update(0), backingScaleFactor(1), integerScaleFactor(0, 0),
|
||||
#ifdef MKXPZ_RETRO
|
||||
|
@ -906,11 +887,7 @@ struct GraphicsPrivate {
|
|||
rebuildIntegerScaleBuffer();
|
||||
}
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
recalculateScreenSize(true); // TODO: get from config
|
||||
#else
|
||||
recalculateScreenSize(rtData->config.fixedAspectRatio);
|
||||
#endif // MKXPZ_RETRO
|
||||
updateScreenResoRatio(rtData);
|
||||
|
||||
TEXFBO::init(frozenScene);
|
||||
|
@ -1575,7 +1552,7 @@ int Graphics::displayContentHeight() const {
|
|||
|
||||
int Graphics::displayWidth() const {
|
||||
#ifdef MKXPZ_RETRO
|
||||
return 640; // TODO: use actual width
|
||||
return Graphics::displayContentWidth();
|
||||
#else
|
||||
SDL_DisplayMode dm{};
|
||||
SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(shState->sdlWindow()), &dm);
|
||||
|
@ -1585,7 +1562,7 @@ int Graphics::displayWidth() const {
|
|||
|
||||
int Graphics::displayHeight() const {
|
||||
#ifdef MKXPZ_RETRO
|
||||
return 480; // TODO: use actual height
|
||||
return Graphics::displayContentHeight();
|
||||
#else
|
||||
SDL_DisplayMode 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
|
||||
// attribute, but there's really no point in state duplication
|
||||
#ifdef MKXPZ_RETRO
|
||||
return true; // TODO: get from config
|
||||
#else
|
||||
return shState->config().fixedAspectRatio;
|
||||
#endif // MKXPZ_RETRO
|
||||
}
|
||||
|
||||
void Graphics::setFixedAspectRatio(bool value)
|
||||
|
@ -1815,11 +1788,7 @@ void Graphics::setFixedAspectRatio(bool value)
|
|||
int Graphics::getSmoothScaling() const
|
||||
{
|
||||
// Same deal as with fixed aspect ratio
|
||||
#ifdef MKXPZ_RETRO
|
||||
return 0; // TODO: get from config
|
||||
#else
|
||||
return shState->config().smoothScaling;
|
||||
#endif // MKXPZ_RETRO
|
||||
}
|
||||
|
||||
void Graphics::setSmoothScaling(int value)
|
||||
|
|
|
@ -632,11 +632,7 @@ void Sprite::draw()
|
|||
int sourceWidthHires = p->bitmap->hasHires() ? p->bitmap->getHires()->width() : p->bitmap->width();
|
||||
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;
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
int targetWidthHires = (int)lround(framebufferScalingFactor * p->bitmap->width() * p->trans.getScale().x);
|
||||
int targetHeightHires = (int)lround(framebufferScalingFactor * p->bitmap->height() * p->trans.getScale().y);
|
||||
|
@ -747,11 +743,7 @@ void Sprite::draw()
|
|||
shader.bind();
|
||||
|
||||
shader.setTexSize(Vec2i(sourceWidthHires, sourceHeightHires));
|
||||
#ifdef MKXPZ_RETRO
|
||||
shader.setSharpness(100); // TODO: get from config
|
||||
#else
|
||||
shader.setSharpness(shState->config().bicubicSharpness);
|
||||
#endif // MKXPZ_RETRO
|
||||
shader.setSpriteMat(p->trans.getMatrix());
|
||||
shader.applyViewportProj();
|
||||
base = &shader;
|
||||
|
@ -775,11 +767,7 @@ void Sprite::draw()
|
|||
shader.bind();
|
||||
|
||||
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)));
|
||||
#endif // MKXPZ_RETRO
|
||||
shader.setSpriteMat(p->trans.getMatrix());
|
||||
shader.applyViewportProj();
|
||||
base = &shader;
|
||||
|
|
|
@ -605,11 +605,7 @@ struct TilemapPrivate
|
|||
/* Mega surface tileset */
|
||||
SDL_Surface *tsSurf = tileset->megaSurface();
|
||||
|
||||
#ifdef MKXPZ_RETRO
|
||||
if (false) // TODO: get from config
|
||||
#else
|
||||
if (shState->config().subImageFix)
|
||||
#endif // MKXPZ_RETRO
|
||||
{
|
||||
/* Implementation for broken GL drivers */
|
||||
FBO::bind(atlas.gl.fbo);
|
||||
|
|
|
@ -111,12 +111,8 @@ Viewport::Viewport()
|
|||
: SceneElement(*shState->screen()),
|
||||
sceneLink(this)
|
||||
{
|
||||
#ifdef MKXPZ_RETRO
|
||||
initViewport(0, 0, 640, 480); // TODO: use the actual viewport size
|
||||
#else
|
||||
const Graphics &graphics = shState->graphics();
|
||||
initViewport(0, 0, graphics.width(), graphics.height());
|
||||
#endif // MKXPZ_RETRO
|
||||
}
|
||||
|
||||
void Viewport::initViewport(int x, int y, int width, int height)
|
||||
|
|
|
@ -88,6 +88,9 @@ public:
|
|||
inline PHYSFS_File &operator*() {
|
||||
return *get();
|
||||
}
|
||||
inline bool is_open() {
|
||||
return inner != NULL;
|
||||
}
|
||||
};
|
||||
|
||||
FileSystem(const char *argv0,
|
||||
|
|
|
@ -21,12 +21,13 @@
|
|||
|
||||
#include "input.h"
|
||||
#include "core.h"
|
||||
#include "sharedstate.h"
|
||||
#include "graphics.h"
|
||||
|
||||
#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_START (rgssVer >= 2 ? 0.375 : 0.400)
|
||||
#define REPEAT_DELAY 0.1
|
||||
#define FPS 60.0 // TODO: use the actual FPS
|
||||
|
||||
static std::unordered_map<int, uint8_t> codeToJoypadId = {
|
||||
{Input::Down, RETRO_DEVICE_ID_JOYPAD_DOWN},
|
||||
|
@ -233,7 +234,8 @@ bool Input::isReleased(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)
|
||||
|
@ -243,7 +245,7 @@ unsigned int Input::count(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)
|
||||
|
|
|
@ -8,9 +8,7 @@ if is_libretro
|
|||
global_args += '-DMPG123_NO_LARGENAME'
|
||||
global_args += '-DGL_GLES_PROTOTYPES=0'
|
||||
|
||||
if host_system == 'darwin'
|
||||
global_dependencies += compilers['cpp'].find_library('iconv')
|
||||
endif
|
||||
global_dependencies += dependency('iconv', static: core_is_static or host_system == 'windows')
|
||||
|
||||
global_dependencies += subproject('libretro-common').get_variable('libretro_common')
|
||||
|
||||
|
@ -381,7 +379,7 @@ global_include_dirs += include_directories('.',
|
|||
|
||||
main_source = files(
|
||||
is_libretro ? 'core.cpp' : 'main.cpp',
|
||||
is_libretro ? [] : 'config.cpp',
|
||||
'config.cpp',
|
||||
is_libretro ? [] : 'eventthread.cpp',
|
||||
is_libretro ? [] : 'settingsmenu.cpp',
|
||||
'sharedstate.cpp',
|
||||
|
@ -427,7 +425,7 @@ main_source = files(
|
|||
'display/gl/tilequad.cpp',
|
||||
'display/gl/vertex.cpp',
|
||||
|
||||
is_libretro ? [] : 'util/iniconfig.cpp',
|
||||
'util/iniconfig.cpp',
|
||||
is_libretro ? [] : 'util/win-consoleutils.cpp',
|
||||
|
||||
'etc/etc.cpp',
|
||||
|
|
|
@ -77,9 +77,9 @@ struct SharedStatePrivate
|
|||
FileSystem fileSystem;
|
||||
|
||||
EventThread &eThread;
|
||||
#endif // MKXPZ_RETRO
|
||||
RGSSThreadData &rtData;
|
||||
Config &config;
|
||||
#endif // MKXPZ_RETRO
|
||||
SharedMidiState midiState;
|
||||
|
||||
Graphics graphics;
|
||||
|
@ -117,9 +117,9 @@ struct SharedStatePrivate
|
|||
sdlWindow(threadData->window),
|
||||
fileSystem(threadData->argv0, threadData->config.allowSymlinks),
|
||||
eThread(*threadData->ethread),
|
||||
#endif // MKXPZ_RETRO
|
||||
rtData(*threadData),
|
||||
config(threadData->config),
|
||||
#endif // MKXPZ_RETRO
|
||||
#ifdef MKXPZ_RETRO
|
||||
midiState(),
|
||||
#else
|
||||
|
@ -184,12 +184,10 @@ struct SharedStatePrivate
|
|||
TEXFBO::allocEmpty(gpTexFBO, globalTexW, globalTexH);
|
||||
TEXFBO::linkFBO(gpTexFBO);
|
||||
|
||||
#ifndef MKXPZ_RETRO
|
||||
/* RGSS3 games will call setup_midi, so there's
|
||||
* no need to do it on startup */
|
||||
if (rgssVer <= 2)
|
||||
midiState.initIfNeeded(threadData->config);
|
||||
#endif // MKXPZ_RETRO
|
||||
}
|
||||
|
||||
~SharedStatePrivate()
|
||||
|
@ -206,9 +204,7 @@ void SharedState::initInstance(RGSSThreadData *threadData)
|
|||
* SharedState depends on GlobalIBO existing,
|
||||
* Font depends on SharedState existing */
|
||||
|
||||
#ifndef MKXPZ_RETRO
|
||||
rgssVersion = threadData->config.rgssVersion;
|
||||
#endif // MKXPZ_RETRO
|
||||
|
||||
_globalIBO = new GlobalIBO();
|
||||
_globalIBO->ensureSize(1);
|
||||
|
@ -262,9 +258,9 @@ GSATT(Scene*, screen)
|
|||
#ifndef MKXPZ_RETRO
|
||||
GSATT(FileSystem&, fileSystem)
|
||||
GSATT(EventThread&, eThread)
|
||||
#endif // MKXPZ_RETRO
|
||||
GSATT(RGSSThreadData&, rtData)
|
||||
GSATT(Config&, config)
|
||||
#endif // MKXPZ_RETRO
|
||||
GSATT(Graphics&, graphics)
|
||||
#ifndef MKXPZ_RETRO
|
||||
GSATT(Input&, input)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef SDLUTIL_H
|
||||
#define SDLUTIL_H
|
||||
|
||||
#ifndef MKXPZ_RETRO
|
||||
#ifdef MKXPZ_RETRO
|
||||
# include "filesystem.h"
|
||||
#else
|
||||
# include <SDL_atomic.h>
|
||||
# include <SDL_thread.h>
|
||||
# include <SDL_rwops.h>
|
||||
|
@ -11,6 +13,48 @@
|
|||
#include <iostream>
|
||||
#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
|
||||
struct AtomicFlag
|
||||
{
|
||||
|
@ -41,6 +85,17 @@ struct AtomicFlag
|
|||
private:
|
||||
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
|
||||
struct AtomicFlag
|
||||
{
|
||||
|
@ -129,48 +184,17 @@ inline bool readFileSDL(const char *path,
|
|||
return true;
|
||||
}
|
||||
|
||||
template<size_t bufSize = 248, size_t pbSize = 8>
|
||||
class SDLRWBuf : public std::streambuf
|
||||
class SDLRead
|
||||
{
|
||||
public:
|
||||
SDLRWBuf(SDL_RWops *ops)
|
||||
: ops(ops)
|
||||
static size_t read(SDL_RWops *ops, void *buf, size_t size)
|
||||
{
|
||||
char *end = buf + bufSize + pbSize;
|
||||
setg(end, end, end);
|
||||
return SDL_RWread(ops, buf, 1, size);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -199,7 +223,7 @@ public:
|
|||
|
||||
private:
|
||||
SDL_RWops *ops;
|
||||
SDLRWBuf<> buf;
|
||||
SDLRWBuf buf;
|
||||
std::istream s;
|
||||
};
|
||||
#endif // MKXPZ_RETRO
|
||||
|
|
Loading…
Add table
Reference in a new issue