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-util.cpp',
'module_rpg.cpp',
'sandbox.cpp',
'wasi.cpp',
'wasm-rt.cpp',
])
)

View file

@ -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)
{

View file

@ -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() {

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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,

View file

@ -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 */

View file

@ -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();

View file

@ -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();

View file

@ -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);

View file

@ -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

View file

@ -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)

View file

@ -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);
}

View file

@ -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
}

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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)

View file

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

View file

@ -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)

View file

@ -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',

View file

@ -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)

View file

@ -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