From de74fc1bc3bfc1b63bedf3f9c5dc0f2872cf09d1 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Wed, 24 Feb 2016 17:44:42 +0100 Subject: [PATCH 01/34] EventThread: Fix mouse cursor not being hidden --- src/eventthread.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/eventthread.cpp b/src/eventthread.cpp index e3bf194..9217a4a 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -127,7 +127,9 @@ void EventThread::process(RGSSThreadData &rtData) bool displayingFPS = false; bool cursorInWindow = false; - bool windowFocused = false; + + /* SDL doesn't send an initial FOCUS_GAINED event */ + bool windowFocused = true; bool terminate = false; From 47ef36ca190a8be7449aae4717af9e70a74cbf19 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Wed, 24 Feb 2016 17:55:28 +0100 Subject: [PATCH 02/34] EventThread: ifdef out broken SDL function on OSX --- src/eventthread.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/eventthread.cpp b/src/eventthread.cpp index 9217a4a..00c1b3e 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -111,7 +111,11 @@ void EventThread::process(RGSSThreadData &rtData) UnidirMessage &windowSizeMsg = rtData.windowSizeMsg; initALCFunctions(rtData.alcDev); + + // XXX this function breaks input focus on OSX +#ifndef __MACOSX__ SDL_SetEventFilter(eventFilter, &rtData); +#endif fullscreen = rtData.config.fullscreen; int toggleFSMod = rtData.config.anyAltToggleFS ? KMOD_ALT : KMOD_LALT; From fdaf6c3611566a9e818baed2357e02bf93e1a0e8 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Wed, 27 Jul 2016 11:56:43 +0200 Subject: [PATCH 03/34] Bitmap: Split surface pixel address calculation into helper --- src/bitmap.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/bitmap.cpp b/src/bitmap.cpp index 24fb70f..b2d1f3d 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -768,6 +768,14 @@ void Bitmap::clear() p->onModified(); } +static uint32_t &getPixelAt(SDL_Surface *surf, SDL_PixelFormat *form, int x, int y) +{ + size_t offset = x*form->BytesPerPixel + y*surf->pitch; + uint8_t *bytes = (uint8_t*) surf->pixels + offset; + + return *((uint32_t*) bytes); +} + Color Bitmap::getPixel(int x, int y) const { guardDisposed(); @@ -790,9 +798,7 @@ Color Bitmap::getPixel(int x, int y) const glState.viewport.pop(); } - size_t offset = x*p->format->BytesPerPixel + y*p->surface->pitch; - uint8_t *bytes = (uint8_t*) p->surface->pixels + offset; - uint32_t pixel = *((uint32_t*) bytes); + uint32_t pixel = getPixelAt(p->surface, p->format, x, y); return Color((pixel >> p->format->Rshift) & 0xFF, (pixel >> p->format->Gshift) & 0xFF, From e98c2e0535b6baf1691cff53996ecfd02121899f Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Wed, 27 Jul 2016 11:59:08 +0200 Subject: [PATCH 04/34] Bitmap: Don't throw away cached surface in setPixel() Instead, update the surface with the same change. For many consecutive getPixel() -> setPixel() calls on the same bitmap, this avoids calling glReadPixels at every iteration. --- src/bitmap.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/bitmap.cpp b/src/bitmap.cpp index b2d1f3d..a677207 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -221,9 +221,9 @@ struct BitmapPrivate surf = surfConv; } - void onModified() + void onModified(bool freeSurface = true) { - if (surface) + if (surface && freeSurface) { SDL_FreeSurface(surface); surface = 0; @@ -825,7 +825,16 @@ void Bitmap::setPixel(int x, int y, const Color &color) p->addTaintedArea(IntRect(x, y, 1, 1)); - p->onModified(); + /* Setting just a single pixel is no reason to throw away the + * whole cached surface; we can just apply the same change */ + + if (p->surface) + { + uint32_t &surfPixel = getPixelAt(p->surface, p->format, x, y); + surfPixel = SDL_MapRGBA(p->format, pixel[0], pixel[1], pixel[2], pixel[3]); + } + + p->onModified(false); } void Bitmap::hueChange(int hue) From d4e09f55bd67a3165a9c1a8fd49d7c8a1e71cf1f Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Wed, 27 Jul 2016 12:03:45 +0200 Subject: [PATCH 05/34] WindowVX: Fix move() not setting the correct dirty flags --- src/windowvx.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/windowvx.cpp b/src/windowvx.cpp index 02a70d9..fe2aaef 100644 --- a/src/windowvx.cpp +++ b/src/windowvx.cpp @@ -852,10 +852,15 @@ void WindowVX::move(int x, int y, int width, int height) const Vec2i size(std::max(0, width), std::max(0, height)); - if (p->geo.w != size.x || p->geo.h != size.y) + if (p->geo.size() != size) + { + p->base.vertDirty = true; p->base.texSizeDirty = true; + p->clipRectDirty = true; + p->ctrlVertDirty = true; + } - p->geo = IntRect(x, y, size.x, size.y); + p->geo = IntRect(Vec2i(x, y), size); p->updateBaseQuad(); } From 0ec1fce4acc0e5cb942ae4fad7d730ee23b30488 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Mon, 12 Sep 2016 20:16:39 +0200 Subject: [PATCH 06/34] MRI: Bind Audio.setup_midi --- binding-mri/audio-binding.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/binding-mri/audio-binding.cpp b/binding-mri/audio-binding.cpp index 262f5c7..59919ad 100644 --- a/binding-mri/audio-binding.cpp +++ b/binding-mri/audio-binding.cpp @@ -97,6 +97,15 @@ DEF_FADE( me ) DEF_PLAY_STOP( se ) +RB_METHOD(audioSetupMidi) +{ + RB_UNUSED_PARAM; + + shState->audio().setupMidi(); + + return Qnil; +} + RB_METHOD(audioReset) { RB_UNUSED_PARAM; @@ -135,6 +144,8 @@ audioBindingInit() { BIND_POS( bgm ); BIND_POS( bgs ); + + _rb_define_module_function(module, "setup_midi", audioSetupMidi); } BIND_PLAY_STOP( se ) From 541e24f67822c20f54b3ab36c1d3a7e6fa0caa76 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Tue, 4 Oct 2016 15:16:57 +0200 Subject: [PATCH 07/34] Bitmap: Use more accurate HSV-based hue shift algorithm The previously YIQ-based algorithm turned out to be both slow, and horribly inaccurate. Another algorithm based on rotating the color value in the RGB cube along the diagonal axis was also considered, which was acceptable in terms of accuracy, and very fast. In the end, I decided on a HSV-based one, because it is by far the most accurate one, while still being a tad faster than the YIQ solution. Algorithm source: gamedev.stackexchange.com/a/59808/24839 A very simple GPU time benchmark when shifting a 2048^2 bitmap: YIQ rot RGB rot HSV shift radeon 13.4 ms 2.8 ms 11.4 ms intel 13.0 ms 6.0 ms 10.5 ms radeon: HD 3650 mobility intel: N3540 integrated (Baytrail) However hue shifting has never shown up as a bottleneck before, so these are more academic. --- shader/hue.frag | 70 ++++++++++++++++++++++--------------------------- src/bitmap.cpp | 7 ++--- src/shader.cpp | 6 ----- src/shader.h | 3 +-- 4 files changed, 34 insertions(+), 52 deletions(-) diff --git a/shader/hue.frag b/shader/hue.frag index 405c91b..61143ac 100644 --- a/shader/hue.frag +++ b/shader/hue.frag @@ -1,48 +1,40 @@ -uniform sampler2D inputTexture; -uniform float hueAdjust; +uniform sampler2D texture; +uniform mediump float hueAdjust; varying vec2 v_texCoord; +/* Source: gamedev.stackexchange.com/a/59808/24839 */ +vec3 rgb2hsv(vec3 c) +{ + const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + + /* Avoid divide-by-zero situations by adding a very tiny delta. + * Since we always deal with underlying 8-Bit color values, this + * should never mask a real value */ + const float eps = 1.0e-10; + + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + eps)), d / (q.x + eps), q.x); +} + +vec3 hsv2rgb(vec3 c) +{ + const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + void main () { - const vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0); - const vec4 kRGBToI = vec4 (0.596, -0.275, -0.321, 0.0); - const vec4 kRGBToQ = vec4 (0.212, -0.523, 0.311, 0.0); + vec4 color = texture2D (texture, v_texCoord.xy); + vec3 hsv = rgb2hsv(color.rgb); - const vec4 kYIQToR = vec4 (1.0, 0.956, 0.621, 0.0); - const vec4 kYIQToG = vec4 (1.0, -0.272, -0.647, 0.0); - const vec4 kYIQToB = vec4 (1.0, -1.107, 1.704, 0.0); + hsv.x += hueAdjust; + color.rgb = hsv2rgb(hsv); - /* Sample the input pixel */ - vec4 color = texture2D (inputTexture, v_texCoord.xy); - - /* Convert to YIQ */ - float YPrime = dot (color, kRGBToYPrime); - float I = dot (color, kRGBToI); - float Q = dot (color, kRGBToQ); - - /* Calculate the hue and chroma */ - float hue = atan (Q, I); - float chroma = sqrt (I * I + Q * Q); - - /* Make the user's adjustments */ - hue += hueAdjust; - - /* Remember old I and color */ - float IOriginal = I; - vec4 coOriginal = color; - - /* Convert back to YIQ */ - Q = chroma * sin (hue); - I = chroma * cos (hue); - - /* Convert back to RGB */ - vec4 yIQ = vec4 (YPrime, I, Q, 0.0); - color.r = dot (yIQ, kYIQToR); - color.g = dot (yIQ, kYIQToG); - color.b = dot (yIQ, kYIQToB); - - /* Save the result */ - gl_FragColor = (IOriginal == 0.0) ? coOriginal : color; + gl_FragColor = color; } diff --git a/src/bitmap.cpp b/src/bitmap.cpp index a677207..96cd968 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -854,13 +854,10 @@ void Bitmap::hueChange(int hue) quad.setTexPosRect(texRect, texRect); quad.setColor(Vec4(1, 1, 1, 1)); - /* Calculate hue parameter */ - hue = wrapRange(hue, 0, 359); - float hueAdj = -((M_PI * 2) / 360) * hue; - HueShader &shader = shState->shaders().hue; shader.bind(); - shader.setHueAdjust(hueAdj); + /* Shader expects normalized value */ + shader.setHueAdjust(wrapRange(hue, 0, 359) / 360.0f); FBO::bind(newTex.fbo); p->pushSetViewport(shader); diff --git a/src/shader.cpp b/src/shader.cpp index 3b22483..824454d 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -551,7 +551,6 @@ HueShader::HueShader() ShaderBase::init(); GET_U(hueAdjust); - GET_U(inputTexture); } void HueShader::setHueAdjust(float value) @@ -559,11 +558,6 @@ void HueShader::setHueAdjust(float value) gl.Uniform1f(u_hueAdjust, value); } -void HueShader::setInputTexture(TEX::ID tex) -{ - setTexUniform(u_inputTexture, 0, tex); -} - SimpleMatrixShader::SimpleMatrixShader() { diff --git a/src/shader.h b/src/shader.h index 323b10a..7b4eb02 100644 --- a/src/shader.h +++ b/src/shader.h @@ -241,10 +241,9 @@ public: HueShader(); void setHueAdjust(float value); - void setInputTexture(TEX::ID tex); private: - GLint u_hueAdjust, u_inputTexture; + GLint u_hueAdjust; }; class SimpleMatrixShader : public ShaderBase From 55cec53911f6706f6ad7ae58095644235e2259ba Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Fri, 17 Feb 2017 19:29:38 +0100 Subject: [PATCH 08/34] Sprite: Clamp src_rect to bitmap bounds --- src/sprite.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/sprite.cpp b/src/sprite.cpp index 760bb0b..7999546 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -134,12 +134,23 @@ struct SpritePrivate void onSrcRectChange() { - if (mirrored) - quad.setTexRect(srcRect->toFloatRect().hFlipped()); - else - quad.setTexRect(srcRect->toFloatRect()); + FloatRect rect = srcRect->toFloatRect(); + Vec2i bmSize; - quad.setPosRect(IntRect(0, 0, srcRect->width, srcRect->height)); + if (bitmap) + bmSize = Vec2i(bitmap->width(), bitmap->height()); + + if (mirrored) + rect = rect.hFlipped(); + + /* Clamp the rectangle so it doesn't reach outside + * the bitmap bounds */ + rect.w = clamp(rect.w, 0, bmSize.x-rect.x); + rect.h = clamp(rect.h, 0, bmSize.y-rect.y); + + quad.setTexRect(rect); + + quad.setPosRect(FloatRect(0, 0, rect.w, rect.h)); recomputeBushDepth(); wave.dirty = true; From c4dd3ffaf63bcd2a751b69db9e51df845232ac43 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Fri, 3 Mar 2017 19:37:19 +0100 Subject: [PATCH 09/34] Config: Use set for preloadScripts Would probably make sense for all other string vectors too. --- binding-mri/binding-mri.cpp | 5 +++-- src/config.cpp | 8 +++++++- src/config.h | 3 ++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index 5cb518e..c28cdaa 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -452,8 +452,9 @@ static void runRMXPScripts(BacktraceData &btData) } /* Execute preloaded scripts */ - for (size_t i = 0; i < conf.preloadScripts.size(); ++i) - runCustomScript(conf.preloadScripts[i]); + for (std::set::iterator i = conf.preloadScripts.begin(); + i != conf.preloadScripts.end(); ++i) + runCustomScript(*i); VALUE exc = rb_gv_get("$!"); if (exc != Qnil) diff --git a/src/config.cpp b/src/config.cpp index 9173acc..a58ddab 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -134,6 +134,12 @@ static std::string prefPath(const char *org, const char *app) return str; } +template +std::set setFromVec(const std::vector &vec) +{ + return std::set(vec.begin(), vec.end()); +} + typedef std::vector StringVec; namespace po = boost::program_options; @@ -226,7 +232,7 @@ void Config::read(int argc, char *argv[]) PO_DESC_ALL; - GUARD_ALL( preloadScripts = vm["preloadScript"].as(); ); + GUARD_ALL( preloadScripts = setFromVec(vm["preloadScript"].as()); ); GUARD_ALL( rtps = vm["RTP"].as(); ); diff --git a/src/config.h b/src/config.h index fc9bbda..d82698d 100644 --- a/src/config.h +++ b/src/config.h @@ -24,6 +24,7 @@ #include #include +#include struct Config { @@ -77,7 +78,7 @@ struct Config bool useScriptNames; std::string customScript; - std::vector preloadScripts; + std::set preloadScripts; std::vector rtps; std::vector fontSubs; From 6349146e0198c995cadb923a7991576064df7e90 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sat, 4 Mar 2017 11:04:02 +0100 Subject: [PATCH 10/34] main: Only set window icon on Linux OSX carries high-resolution icons in its bundles, and windows uses windres to embed .ico files, so don't interfere with those. --- src/main.cpp | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index eb07970..4b5e234 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -166,6 +166,24 @@ static void showInitError(const std::string &msg) SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "mkxp", msg.c_str(), 0); } +static void setupWindowIcon(const Config &conf, SDL_Window *win) +{ + SDL_RWops *iconSrc; + + if (conf.iconPath.empty()) + iconSrc = SDL_RWFromConstMem(assets_icon_png, assets_icon_png_len); + else + iconSrc = SDL_RWFromFile(conf.iconPath.c_str(), "rb"); + + SDL_Surface *iconImg = IMG_Load_RW(iconSrc, SDL_TRUE); + + if (iconImg) + { + SDL_SetWindowIcon(win, iconImg); + SDL_FreeSurface(iconImg); + } +} + int main(int argc, char *argv[]) { SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); @@ -239,16 +257,6 @@ int main(int argc, char *argv[]) return 0; } - /* Setup application icon */ - SDL_RWops *iconSrc; - - if (conf.iconPath.empty()) - iconSrc = SDL_RWFromConstMem(assets_icon_png, assets_icon_png_len); - else - iconSrc = SDL_RWFromFile(conf.iconPath.c_str(), "rb"); - - SDL_Surface *iconImg = IMG_Load_RW(iconSrc, SDL_TRUE); - SDL_Window *win; Uint32 winFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_FOCUS; @@ -267,11 +275,13 @@ int main(int argc, char *argv[]) return 0; } - if (iconImg) - { - SDL_SetWindowIcon(win, iconImg); - SDL_FreeSurface(iconImg); - } + /* OSX and Windows have their own native ways of + * dealing with icons; don't interfere with them */ +#ifdef __LINUX__ + setupWindowIcon(conf, win); +#else + (void) setupWindowIcon; +#endif ALCdevice *alcDev = alcOpenDevice(0); From 0f9b5f274a9a2d9decff69c963b40ce37365d2a9 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Wed, 8 Mar 2017 16:30:07 +0100 Subject: [PATCH 11/34] Filesystem: Search for "Fonts/" with case-insensitivity --- src/filesystem.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/filesystem.cpp b/src/filesystem.cpp index fe5d403..d7fd36b 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -458,7 +458,7 @@ struct FontSetsCBData SharedFontState *sfs; }; -static void fontSetEnumCB(void *data, const char *, +static void fontSetEnumCB(void *data, const char *dir, const char *fname) { FontSetsCBData *d = static_cast(data); @@ -480,7 +480,7 @@ static void fontSetEnumCB(void *data, const char *, return; char filename[512]; - snprintf(filename, sizeof(filename), "Fonts/%s", fname); + snprintf(filename, sizeof(filename), "%s/%s", dir, fname); PHYSFS_File *handle = PHYSFS_openRead(filename); @@ -495,11 +495,29 @@ static void fontSetEnumCB(void *data, const char *, SDL_RWclose(&ops); } +/* Basically just a case-insensitive search + * for the folder "Fonts"... */ +static void findFontsFolderCB(void *data, const char *, + const char *fname) +{ + size_t i = 0; + char buffer[512]; + const char *s = fname; + + while (s && i < sizeof(buffer)) + buffer[i++] = tolower(*s++); + + buffer[i] = '\0'; + + if (strcmp(buffer, "fonts") == 0) + PHYSFS_enumerateFilesCallback(fname, fontSetEnumCB, data); +} + void FileSystem::initFontSets(SharedFontState &sfs) { FontSetsCBData d = { p, &sfs }; - PHYSFS_enumerateFilesCallback("Fonts", fontSetEnumCB, &d); + PHYSFS_enumerateFilesCallback(".", findFontsFolderCB, &d); } struct OpenReadEnumData From 60e967e3b781ce170b30ffd744e132145ef37bd7 Mon Sep 17 00:00:00 2001 From: Marty Plummer Date: Fri, 3 Mar 2017 22:45:31 -0600 Subject: [PATCH 12/34] Add icon and resource files for windows Signed-off-by: Marty Plummer --- assets/icon.ico | Bin 0 -> 16958 bytes assets/resource.h | 1 + assets/resource.rc | 4 ++++ src/main.cpp | 4 ++++ 4 files changed, 9 insertions(+) create mode 100644 assets/icon.ico create mode 100644 assets/resource.h create mode 100644 assets/resource.rc diff --git a/assets/icon.ico b/assets/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2a10780dd1c609077bcc4a2cbd42ddfe422d5aac GIT binary patch literal 16958 zcmd^{ONbps6ozXaVaUc1L_sBw8zhY4!hj?y!W~2iJ_AwQh>Ju>LUx}W{;KYJ zoT`a2bNaWkV)VP)EI(_^{l=JOv69THm~=-gyJ~*VD#6_G*ublSbY!GWxpEiSCW0m!^WP`l%XtjI$dMu7t*r(I?;^{)25CTUKS7F-m}o&?8kqVW36fn z@;|y^>}%f``{<$4_XAt7X&Tg(k{jX-_PKdupEzplhrf@Gxu{(}_|4eI-!OJ=E~~q5 z3pQcfBKBD=?(e&Q!%AAT;`2H1v;w z?TyFo+xF}&WB0w8Yy)f`h4_|2zcZg5`l>y+J$@fP|Cz={jl;3ciZ>k(x~iKQ>)MRn zx4|pt2k?UdEOm&vG&9HX&U+ng5BDD%Xalg+Ss$>T2=7rxV_loR_p0{CR&0(jC=RA! zi1lQs%N*B+alQ(3J|CO0J;tJV)moYTL}op|k@I^VQ{885&*2AK*`A3#Rj9+duCC6q z@~8hW_VCxn@_jD9XzYXgdQ6-&@|e%dWYowi;&pg6DtggOP`QulO z-T7qUx;wWf`tosX zrYoKE8{%Zk;%NmGIf%=RGN&7grHwC`+AS6Ea7655N@5Qyk2m@Ugml*7!~RHhimz zcm7Aoe#9%P5mJY`!ER(X9S^_+wn!eBA$;s%oxf+LdEYZ$Nmk6*zeU`XsGDg6bkunt zkJ!bzRJxryuVHQUDYy#jPNa>qv_m;PgSyF_UAGot?8W4 z{GOA|H#{yvR*;XbVf!U62ew#_;{Hr3qz~hxj%5;OU6=DoGKLQ`)~VP~gsdFUs|ACz~ zKp4Lot$*aRn)>=jI#c6YSz5vR=TwZp@%mRjt5}ZWlUx5vR~gQtyu|t!?Cb%8?d%bX z>X)T&;{8u%|J%{IK^e}nyteOu!4~zk-~TGf-7#}{_*t5sceL660j8W^%KJaSpYeZj z-=?ge%ktXl{{oY6#vJ>R@bBS!@SG#9#ws8D;K2aKCQcXVTMXBi^;d-N35*558S4D-zm``*qwgn}*%v(80L7 zWB(od`&hspyY8Zr{&eck&{v{P3c&czhB+^?I4{iEnOcy6HI!2p&f zbWD}Pcfg#?{kl=?n`B+E=jJ+W2g4|IUX?=|5Xbl4ru%Sw?}>LFo3VXVT9knH-hb9O zpBU@FKCb)Ev>$CS@E**_{de$t;#|ejWIw^4D(syV4{eZ-m! z=`Q*EN5Kn({{X)NzLjv7Q1QaHsF{aMWTOLJZ6^GQ_!sf94$K!y8@5fTiwtDN_Z9WH zX~^F(^LLH>ofCiefb)0a{w#8;fB$Z+U0>3VwR*kI5XvpNjc`q0HX-e-;9tV7wYLa& zxni#18qX@YN;uamP6Zwn^3saVxatz%s!M5o y$LT}g4nFkl +#include "resource.h" + +IDI_APPICON ICON "icon.ico" diff --git a/src/main.cpp b/src/main.cpp index 4b5e234..1ad3ee2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,7 +40,11 @@ #include "binding.h" +#ifdef __WINDOWS__ +#include "resource.h" +#elif __LINUX__ #include "icon.png.xxd" +#endif static void rgssThreadError(RGSSThreadData *rtData, const std::string &msg) From 3ea24bd7578ccefbef6d50397d9fd80fba6de253 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sat, 8 Apr 2017 16:16:36 +0200 Subject: [PATCH 13/34] EventThread: Make system cursor visible over black aspect ratio bars Should be less confusing for the player. --- src/eventthread.cpp | 48 ++++++++++++++++++++++++++++++++++++--------- src/eventthread.h | 6 +++++- src/graphics.cpp | 3 +++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/eventthread.cpp b/src/eventthread.cpp index 00c1b3e..42dab49 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -83,6 +83,7 @@ enum REQUEST_SETCURSORVISIBLE, UPDATE_FPS, + UPDATE_SCREEN_RECT, EVENT_COUNT }; @@ -131,6 +132,8 @@ void EventThread::process(RGSSThreadData &rtData) bool displayingFPS = false; bool cursorInWindow = false; + /* Will be updated eventually */ + SDL_Rect gameScreen = { 0, 0, 0, 0 }; /* SDL doesn't send an initial FOCUS_GAINED event */ bool windowFocused = true; @@ -170,7 +173,7 @@ void EventThread::process(RGSSThreadData &rtData) delete sMenu; sMenu = 0; - updateCursorState(cursorInWindow && windowFocused); + updateCursorState(cursorInWindow && windowFocused, gameScreen); } continue; @@ -211,14 +214,14 @@ void EventThread::process(RGSSThreadData &rtData) case SDL_WINDOWEVENT_ENTER : cursorInWindow = true; mouseState.inWindow = true; - updateCursorState(cursorInWindow && windowFocused && !sMenu); + updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen); break; case SDL_WINDOWEVENT_LEAVE : cursorInWindow = false; mouseState.inWindow = false; - updateCursorState(cursorInWindow && windowFocused && !sMenu); + updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen); break; @@ -229,13 +232,13 @@ void EventThread::process(RGSSThreadData &rtData) case SDL_WINDOWEVENT_FOCUS_GAINED : windowFocused = true; - updateCursorState(cursorInWindow && windowFocused && !sMenu); + updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen); break; case SDL_WINDOWEVENT_FOCUS_LOST : windowFocused = false; - updateCursorState(cursorInWindow && windowFocused && !sMenu); + updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen); resetInputStates(); break; @@ -268,7 +271,7 @@ void EventThread::process(RGSSThreadData &rtData) if (!sMenu) { sMenu = new SettingsMenu(rtData); - updateCursorState(false); + updateCursorState(false, gameScreen); } sMenu->raise(); @@ -374,6 +377,7 @@ void EventThread::process(RGSSThreadData &rtData) case SDL_MOUSEMOTION : mouseState.x = event.motion.x; mouseState.y = event.motion.y; + updateCursorState(cursorInWindow, gameScreen); break; case SDL_FINGERDOWN : @@ -413,7 +417,7 @@ void EventThread::process(RGSSThreadData &rtData) case REQUEST_SETCURSORVISIBLE : showCursor = event.user.code; - updateCursorState(cursorInWindow); + updateCursorState(cursorInWindow, gameScreen); break; case UPDATE_FPS : @@ -438,6 +442,15 @@ void EventThread::process(RGSSThreadData &rtData) SDL_SetWindowTitle(win, buffer); break; + + case UPDATE_SCREEN_RECT : + gameScreen.x = event.user.windowID; + gameScreen.y = event.user.code; + gameScreen.w = reinterpret_cast(event.user.data1); + gameScreen.h = reinterpret_cast(event.user.data2); + updateCursorState(cursorInWindow, gameScreen); + + break; } } @@ -532,9 +545,13 @@ void EventThread::setFullscreen(SDL_Window *win, bool mode) fullscreen = mode; } -void EventThread::updateCursorState(bool inWindow) +void EventThread::updateCursorState(bool inWindow, + const SDL_Rect &screen) { - if (inWindow) + SDL_Point pos = { mouseState.x, mouseState.y }; + bool inScreen = inWindow && SDL_PointInRect(&pos, &screen); + + if (inScreen) SDL_ShowCursor(showCursor ? SDL_TRUE : SDL_FALSE); else SDL_ShowCursor(SDL_TRUE); @@ -640,6 +657,19 @@ void EventThread::notifyFrame() SDL_PushEvent(&event); } +void EventThread::notifyGameScreenChange(const SDL_Rect &screen) +{ + /* We have to get a bit hacky here to fit the rectangle + * data into the user event struct */ + SDL_Event event; + event.type = usrIdStart + UPDATE_SCREEN_RECT; + event.user.windowID = screen.x; + event.user.code = screen.y; + event.user.data1 = reinterpret_cast(screen.w); + event.user.data2 = reinterpret_cast(screen.h); + SDL_PushEvent(&event); +} + void SyncPoint::haltThreads() { if (mainSync.locked) diff --git a/src/eventthread.h b/src/eventthread.h index 46051f1..02a9ea1 100644 --- a/src/eventthread.h +++ b/src/eventthread.h @@ -98,12 +98,16 @@ public: /* RGSS thread calls this once per frame */ void notifyFrame(); + /* Called on game screen (size / offset) changes */ + void notifyGameScreenChange(const SDL_Rect &screen); + private: static int eventFilter(void *, SDL_Event*); void resetInputStates(); void setFullscreen(SDL_Window *, bool mode); - void updateCursorState(bool inWindow); + void updateCursorState(bool inWindow, + const SDL_Rect &screen); bool fullscreen; bool showCursor; diff --git a/src/graphics.cpp b/src/graphics.cpp index fe51f74..d205697 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -566,6 +566,9 @@ struct GraphicsPrivate glState.viewport.refresh(); recalculateScreenSize(threadData); updateScreenResoRatio(threadData); + + SDL_Rect screen = { scOffset.x, scOffset.y, scSize.x, scSize.y }; + threadData->ethread->notifyGameScreenChange(screen); } } From 0481f920b08fae7d5002842166b5e84341a1000d Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sat, 8 Apr 2017 18:41:56 +0200 Subject: [PATCH 14/34] Input: Remove ugly [-20,-20] mouse position hack This was supposed to disappear shortly after To the Moon's release, but it unfortunately survived a bit longer :) The status of the mouse cursor being inside / outside the game window is now properly exposed (in MRI) via MKXP.mouse_in_window. --- binding-mri/binding-mri.cpp | 9 +++++++++ src/input.cpp | 6 ------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index c28cdaa..f0a4bb4 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -80,6 +80,7 @@ RB_METHOD(mriP); RB_METHOD(mkxpDataDirectory); RB_METHOD(mkxpPuts); RB_METHOD(mkxpRawKeyStates); +RB_METHOD(mkxpMouseInWindow); RB_METHOD(mriRgssMain); RB_METHOD(mriRgssStop); @@ -144,6 +145,7 @@ static void mriBindingInit() _rb_define_module_function(mod, "data_directory", mkxpDataDirectory); _rb_define_module_function(mod, "puts", mkxpPuts); _rb_define_module_function(mod, "raw_key_states", mkxpRawKeyStates); + _rb_define_module_function(mod, "mouse_in_window", mkxpMouseInWindow); rb_gv_set("MKXP", Qtrue); } @@ -222,6 +224,13 @@ RB_METHOD(mkxpRawKeyStates) return str; } +RB_METHOD(mkxpMouseInWindow) +{ + RB_UNUSED_PARAM; + + return rb_bool_new(EventThread::mouseState.inWindow); +} + static VALUE rgssMainCb(VALUE block) { rb_funcall2(block, rb_intern("call"), 0, 0); diff --git a/src/input.cpp b/src/input.cpp index d7978bd..22dab5d 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -665,9 +665,6 @@ int Input::mouseX() { RGSSThreadData &rtData = shState->rtData(); - if (!EventThread::mouseState.inWindow) - return -20; - return (EventThread::mouseState.x - rtData.screenOffset.x) * rtData.sizeResoRatio.x; } @@ -675,9 +672,6 @@ int Input::mouseY() { RGSSThreadData &rtData = shState->rtData(); - if (!EventThread::mouseState.inWindow) - return -20; - return (EventThread::mouseState.y - rtData.screenOffset.y) * rtData.sizeResoRatio.y; } From e4079d5738d9a7b7676c7febd7a2ef596878941a Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sat, 8 Apr 2017 19:13:31 +0200 Subject: [PATCH 15/34] Fix build on OSX after 60e967e3b781ce170b30ffd744e132145ef37bd7 --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1ad3ee2..a87ae48 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,10 +42,10 @@ #ifdef __WINDOWS__ #include "resource.h" -#elif __LINUX__ -#include "icon.png.xxd" #endif +#include "icon.png.xxd" + static void rgssThreadError(RGSSThreadData *rtData, const std::string &msg) { From 06feafe9efcdc7a90c5c670e897cccb15c753879 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sat, 8 Apr 2017 20:06:12 +0200 Subject: [PATCH 16/34] Add missing include --- src/eventthread.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/eventthread.cpp b/src/eventthread.cpp index 42dab49..08b6c29 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include From 1478e1e0f9154eb82b708ed1e68f269fa422857a Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sun, 23 Apr 2017 12:28:34 +0200 Subject: [PATCH 17/34] Config: Add "maxTextureSize" entry to artificially limit texture sizes --- mkxp.conf.sample | 11 +++++++++++ src/config.cpp | 1 + src/config.h | 1 + src/glstate.cpp | 6 +++++- src/glstate.h | 4 +++- src/sharedstate.cpp | 1 + 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/mkxp.conf.sample b/mkxp.conf.sample index b88f216..0062451 100644 --- a/mkxp.conf.sample +++ b/mkxp.conf.sample @@ -124,6 +124,17 @@ # subImageFix=false +# Limit the maximum size (width, height) of +# most textures mkxp will create (exceptions are +# rendering backbuffers and similar). +# If set to 0, the hardware maximum is used. +# This is useful for recording traces that can +# be played back on machines with lower specs. +# (default: 0) +# +# maxTextureSize=0 + + # Set the base path of the game to '/path/to/game' # (default: executable directory) # diff --git a/src/config.cpp b/src/config.cpp index a58ddab..0fab180 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -166,6 +166,7 @@ void Config::read(int argc, char *argv[]) PO_DESC(syncToRefreshrate, bool, false) \ PO_DESC(solidFonts, bool, false) \ PO_DESC(subImageFix, bool, false) \ + PO_DESC(maxTextureSize, int, 0) \ PO_DESC(gameFolder, std::string, ".") \ PO_DESC(anyAltToggleFS, bool, false) \ PO_DESC(enableReset, bool, true) \ diff --git a/src/config.h b/src/config.h index d82698d..f6dc2c4 100644 --- a/src/config.h +++ b/src/config.h @@ -49,6 +49,7 @@ struct Config bool solidFonts; bool subImageFix; + int maxTextureSize; std::string gameFolder; bool anyAltToggleFS; diff --git a/src/glstate.cpp b/src/glstate.cpp index 73aec31..ff88de7 100644 --- a/src/glstate.cpp +++ b/src/glstate.cpp @@ -23,6 +23,7 @@ #include "shader.h" #include "etc.h" #include "gl-fun.h" +#include "config.h" #include @@ -111,7 +112,7 @@ GLState::Caps::Caps() gl.GetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); } -GLState::GLState() +GLState::GLState(const Config &conf) { gl.Disable(GL_DEPTH_TEST); @@ -121,4 +122,7 @@ GLState::GLState() scissorTest.init(false); scissorBox.init(IntRect(0, 0, 640, 480)); program.init(0); + + if (conf.maxTextureSize > 0) + caps.maxTexSize = conf.maxTextureSize; } diff --git a/src/glstate.h b/src/glstate.h index 63b0bcb..02830e6 100644 --- a/src/glstate.h +++ b/src/glstate.h @@ -27,6 +27,8 @@ #include #include +struct Config; + template struct GLProperty { @@ -130,7 +132,7 @@ public: } caps; - GLState(); + GLState(const Config &conf); }; #endif // GLSTATE_H diff --git a/src/sharedstate.cpp b/src/sharedstate.cpp index 9872af7..0778da9 100644 --- a/src/sharedstate.cpp +++ b/src/sharedstate.cpp @@ -109,6 +109,7 @@ struct SharedStatePrivate graphics(threadData), input(*threadData), audio(*threadData), + _glState(threadData->config), fontState(threadData->config), stampCounter(0) { From 006f701fecf405f8d0b0743c346c047a4c74be4e Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sun, 23 Apr 2017 14:32:11 +0200 Subject: [PATCH 18/34] Config: Add "enableBlitting" entry to toggle GL_EXT_framebuffer_blit --- mkxp.conf.sample | 9 +++++++++ src/config.cpp | 1 + src/config.h | 1 + src/main.cpp | 3 +++ 4 files changed, 14 insertions(+) diff --git a/mkxp.conf.sample b/mkxp.conf.sample index 0062451..500dcc6 100644 --- a/mkxp.conf.sample +++ b/mkxp.conf.sample @@ -124,6 +124,15 @@ # subImageFix=false +# Enable framebuffer blitting if the driver is +# capable of it. Some drivers carry buggy +# implementations of this functionality, so +# disabling it can be used as a workaround +# (default: enabled) +# +# enableBlitting=true + + # Limit the maximum size (width, height) of # most textures mkxp will create (exceptions are # rendering backbuffers and similar). diff --git a/src/config.cpp b/src/config.cpp index 0fab180..33d8160 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -166,6 +166,7 @@ void Config::read(int argc, char *argv[]) PO_DESC(syncToRefreshrate, bool, false) \ PO_DESC(solidFonts, bool, false) \ PO_DESC(subImageFix, bool, false) \ + PO_DESC(enableBlitting, bool, true) \ PO_DESC(maxTextureSize, int, 0) \ PO_DESC(gameFolder, std::string, ".") \ PO_DESC(anyAltToggleFS, bool, false) \ diff --git a/src/config.h b/src/config.h index f6dc2c4..d2d4650 100644 --- a/src/config.h +++ b/src/config.h @@ -49,6 +49,7 @@ struct Config bool solidFonts; bool subImageFix; + bool enableBlitting; int maxTextureSize; std::string gameFolder; diff --git a/src/main.cpp b/src/main.cpp index a87ae48..1a3fc4e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -102,6 +102,9 @@ int rgssThreadFun(void *userdata) return 0; } + if (!conf.enableBlitting) + gl.BlitFramebuffer = 0; + gl.ClearColor(0, 0, 0, 1); gl.Clear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapWindow(win); From cab453ac3a230c1bb06488540f4706f6dad5b39a Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 11 May 2017 12:20:08 +0200 Subject: [PATCH 19/34] Graphics: Use proper resizing function for TEXFBOs Manually resizing the contained TEX objects skips updating the width/height TEXFBO properties, which GLMeta::blit relies on. --- src/graphics.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/graphics.cpp b/src/graphics.cpp index d205697..8a6301a 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -92,11 +92,9 @@ struct PingPong { screenW = width; screenH = height; + for (int i = 0; i < 2; ++i) - { - TEX::bind(rt[i].tex); - TEX::allocEmpty(width, height); - } + TEXFBO::allocEmpty(rt[i], width, height); } void startRender() @@ -946,16 +944,13 @@ void Graphics::resizeScreen(int width, int height) p->screen.setResolution(width, height); - TEX::bind(p->frozenScene.tex); - TEX::allocEmpty(width, height); - TEX::bind(p->currentScene.tex); - TEX::allocEmpty(width, height); + TEXFBO::allocEmpty(p->frozenScene, width, height); + TEXFBO::allocEmpty(p->currentScene, width, height); FloatRect screenRect(0, 0, width, height); p->screenQuad.setTexPosRect(screenRect, screenRect); - TEX::bind(p->transBuffer.tex); - TEX::allocEmpty(width, height); + TEXFBO::allocEmpty(p->transBuffer, width, height); shState->eThread().requestWindowResize(width, height); } From bd694f9f99566de6de98be48d75bee826f5103bb Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 11 May 2017 12:37:15 +0200 Subject: [PATCH 20/34] Graphics: Remove superfluous TEXFBOs while reusing existing ones While the PingPong buffers were always texture-backed, currentScene and transBuffer used to be backed by renderbuffers, which might have been more optimized as render targets on older hardware; but since all buffers in Graphics got switched to being texture backed to allow blitting via rendering (when hardware blitting isn't available or broken, eg. on mobile platforms), their reason to exist vanished. For transBuffer, we can reuse the backbuffer of the PingPong structure, while currentScene might have been useless from the start. --- src/graphics.cpp | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/graphics.cpp b/src/graphics.cpp index 8a6301a..6a12cb3 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -474,9 +474,7 @@ struct GraphicsPrivate bool frozen; TEXFBO frozenScene; - TEXFBO currentScene; Quad screenQuad; - TEXFBO transBuffer; /* Global list of all live Disposables * (disposed on reset) */ @@ -502,26 +500,15 @@ struct GraphicsPrivate TEXFBO::allocEmpty(frozenScene, scRes.x, scRes.y); TEXFBO::linkFBO(frozenScene); - TEXFBO::init(currentScene); - TEXFBO::allocEmpty(currentScene, scRes.x, scRes.y); - TEXFBO::linkFBO(currentScene); - FloatRect screenRect(0, 0, scRes.x, scRes.y); screenQuad.setTexPosRect(screenRect, screenRect); - TEXFBO::init(transBuffer); - TEXFBO::allocEmpty(transBuffer, scRes.x, scRes.y); - TEXFBO::linkFBO(transBuffer); - fpsLimiter.resetFrameAdjust(); } ~GraphicsPrivate() { TEXFBO::fini(frozenScene); - TEXFBO::fini(currentScene); - - TEXFBO::fini(transBuffer); } void updateScreenResoRatio(RGSSThreadData *rtData) @@ -721,8 +708,15 @@ void Graphics::transition(int duration, setBrightness(255); + /* The PP frontbuffer will hold the current scene after the + * composition step. Since the backbuffer is unused during + * the transition, we can reuse it as the target buffer for + * the final rendered image. */ + TEXFBO ¤tScene = p->screen.getPP().frontBuffer(); + TEXFBO &transBuffer = p->screen.getPP().backBuffer(); + /* Capture new scene */ - p->compositeToBuffer(p->currentScene); + p->screen.composite(); /* If no transition bitmap is provided, * we can use a simplified shader */ @@ -735,7 +729,7 @@ void Graphics::transition(int duration, shader.bind(); shader.applyViewportProj(); shader.setFrozenScene(p->frozenScene.tex); - shader.setCurrentScene(p->currentScene.tex); + shader.setCurrentScene(currentScene.tex); shader.setTransMap(transMap->getGLTypes().tex); shader.setVague(vague / 256.0f); shader.setTexSize(p->scRes); @@ -746,7 +740,7 @@ void Graphics::transition(int duration, shader.bind(); shader.applyViewportProj(); shader.setFrozenScene(p->frozenScene.tex); - shader.setCurrentScene(p->currentScene.tex); + shader.setCurrentScene(currentScene.tex); shader.setTexSize(p->scRes); } @@ -790,7 +784,7 @@ void Graphics::transition(int duration, /* Draw the composed frame to a buffer first * (we need this because we're skipping PingPong) */ - FBO::bind(p->transBuffer.fbo); + FBO::bind(transBuffer.fbo); FBO::clear(); p->screenQuad.draw(); @@ -801,7 +795,7 @@ void Graphics::transition(int duration, FBO::clear(); GLMeta::blitBeginScreen(Vec2i(p->winSize)); - GLMeta::blitSource(p->transBuffer); + GLMeta::blitSource(transBuffer); p->metaBlitBufferFlippedScaled(); GLMeta::blitEnd(); @@ -945,13 +939,10 @@ void Graphics::resizeScreen(int width, int height) p->screen.setResolution(width, height); TEXFBO::allocEmpty(p->frozenScene, width, height); - TEXFBO::allocEmpty(p->currentScene, width, height); FloatRect screenRect(0, 0, width, height); p->screenQuad.setTexPosRect(screenRect, screenRect); - TEXFBO::allocEmpty(p->transBuffer, width, height); - shState->eThread().requestWindowResize(width, height); } From f5c30affaaa8f09187ebffebde44033d564b8e2e Mon Sep 17 00:00:00 2001 From: Marty Plummer Date: Thu, 25 May 2017 04:39:45 -0500 Subject: [PATCH 21/34] mingw-w64: allow cmake cross-compile Tested on gentoo with x86_64-w64-mingw32 toolchain and libraries. Signed-off-by: Marty Plummer --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d875826..7029f79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,7 @@ find_package(ZLIB REQUIRED) ## Setup main source ## set(MAIN_HEADERS + assets/resource.h src/quadarray.h src/audio.h src/binding.h @@ -205,6 +206,10 @@ set(MAIN_SOURCE src/fluid-fun.cpp ) +if(WIN32) + list(APPEND MAIN_SOURCE assets/resource.rc) +endif() + source_group("MKXP Source" FILES ${MAIN_SOURCE} ${MAIN_HEADERS}) ## Setup embedded source ## @@ -404,6 +409,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE ${DEFINES} ) target_include_directories(${PROJECT_NAME} PRIVATE + assets src ${SIGCXX_INCLUDE_DIRS} ${PIXMAN_INCLUDE_DIRS} From fba20e62944671c4b18d5ade5b61ccb534a03375 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sun, 30 Jul 2017 23:00:18 +0200 Subject: [PATCH 22/34] Sprite: Check for disposed state before accessing bitmap --- src/sprite.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sprite.cpp b/src/sprite.cpp index 7999546..2cfe13a 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -121,7 +121,7 @@ struct SpritePrivate void recomputeBushDepth() { - if (!bitmap) + if (nullOrDisposed(bitmap)) return; /* Calculate effective (normalized) bush depth */ @@ -137,7 +137,7 @@ struct SpritePrivate FloatRect rect = srcRect->toFloatRect(); Vec2i bmSize; - if (bitmap) + if (!nullOrDisposed(bitmap)) bmSize = Vec2i(bitmap->width(), bitmap->height()); if (mirrored) From f172f58c747240599e212f2ede57f37bd393a170 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 10 Aug 2017 21:39:17 +0200 Subject: [PATCH 23/34] Sprite: Fix regression with "mirror" attribute FloatRect::hFlipped() returns a rectangle with negative width, which was clobbered by the clamping further down. Regression introduced in 55cec53911f6706f6ad7ae58095644235e2259ba. --- src/sprite.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sprite.cpp b/src/sprite.cpp index 2cfe13a..26eb297 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -140,15 +140,12 @@ struct SpritePrivate if (!nullOrDisposed(bitmap)) bmSize = Vec2i(bitmap->width(), bitmap->height()); - if (mirrored) - rect = rect.hFlipped(); - /* Clamp the rectangle so it doesn't reach outside * the bitmap bounds */ rect.w = clamp(rect.w, 0, bmSize.x-rect.x); rect.h = clamp(rect.h, 0, bmSize.y-rect.y); - quad.setTexRect(rect); + quad.setTexRect(mirrored ? rect.hFlipped() : rect); quad.setPosRect(FloatRect(0, 0, rect.w, rect.h)); recomputeBushDepth(); From 01e17ed5c64553a08ba3eb04df0b4c29a377c026 Mon Sep 17 00:00:00 2001 From: Marty Plummer Date: Sat, 22 Jul 2017 16:50:50 -0500 Subject: [PATCH 24/34] windows: move windows specific files Moved the windows-specific files into their own subdir for cleanliness's sake and mesonbuild organization. Signed-off-by: Marty Plummer --- CMakeLists.txt | 4 ++-- {assets => windows}/icon.ico | Bin {assets => windows}/resource.h | 0 {assets => windows}/resource.rc | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename {assets => windows}/icon.ico (100%) rename {assets => windows}/resource.h (100%) rename {assets => windows}/resource.rc (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7029f79..7c29f7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,7 +207,7 @@ set(MAIN_SOURCE ) if(WIN32) - list(APPEND MAIN_SOURCE assets/resource.rc) + list(APPEND MAIN_SOURCE windows/resource.rc) endif() source_group("MKXP Source" FILES ${MAIN_SOURCE} ${MAIN_HEADERS}) @@ -409,8 +409,8 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE ${DEFINES} ) target_include_directories(${PROJECT_NAME} PRIVATE - assets src + windows ${SIGCXX_INCLUDE_DIRS} ${PIXMAN_INCLUDE_DIRS} ${PHYSFS_INCLUDE_DIRS} diff --git a/assets/icon.ico b/windows/icon.ico similarity index 100% rename from assets/icon.ico rename to windows/icon.ico diff --git a/assets/resource.h b/windows/resource.h similarity index 100% rename from assets/resource.h rename to windows/resource.h diff --git a/assets/resource.rc b/windows/resource.rc similarity index 100% rename from assets/resource.rc rename to windows/resource.rc From fde6a92197d3c0b646f19e443d4618ac47044fff Mon Sep 17 00:00:00 2001 From: Carsten Teibes Date: Fri, 18 Aug 2017 19:45:57 +0200 Subject: [PATCH 25/34] Fix deprecation warning on build with MRI>2.3 Fixes #158. The old alias is deprecated since: ruby/ruby@fdb957925f2f. --- binding-mri/binding-util.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/binding-mri/binding-util.h b/binding-mri/binding-util.h index 83589f7..1b758be 100644 --- a/binding-mri/binding-util.h +++ b/binding-mri/binding-util.h @@ -67,7 +67,7 @@ raiseRbExc(const Exception &exc); /* 2.1 has added a new field (flags) to rb_data_type_t */ #include -#if RUBY_API_VERSION_MINOR > 0 +#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 1 /* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */ #define DEF_TYPE_FLAGS 0 #else @@ -90,7 +90,12 @@ raiseRbExc(const Exception &exc); template static VALUE classAllocate(VALUE klass) { +/* 2.3 has changed the name of this function */ +#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 3 + return rb_data_typed_object_wrap(klass, 0, rbType); +#else return rb_data_typed_object_alloc(klass, 0, rbType); +#endif } template From b1bdf1e44509765758fdfba03aae8d0b83841e57 Mon Sep 17 00:00:00 2001 From: Carsten Teibes Date: Fri, 18 Aug 2017 19:06:11 +0200 Subject: [PATCH 26/34] Fix CMake build, only use `resource.h` on Windows This was broken in commit 01e17ed5c645 (move windows specific files). --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c29f7d..cdfcd32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,6 @@ find_package(ZLIB REQUIRED) ## Setup main source ## set(MAIN_HEADERS - assets/resource.h src/quadarray.h src/audio.h src/binding.h @@ -207,6 +206,7 @@ set(MAIN_SOURCE ) if(WIN32) + list(APPEND MAIN_HEADERS windows/resource.h) list(APPEND MAIN_SOURCE windows/resource.rc) endif() From d427df0c2bc7775d61da7e6bcbbe92b3e0c074ae Mon Sep 17 00:00:00 2001 From: Carsten Teibes Date: Sun, 8 Oct 2017 23:11:18 +0200 Subject: [PATCH 27/34] Adapt RGSS archivers and filesystem to physfs 3.0 API --- src/filesystem.cpp | 49 ++++++++++++++++++++++++++-------------------- src/rgssad.cpp | 28 +++++++++++++++----------- 2 files changed, 45 insertions(+), 32 deletions(-) diff --git a/src/filesystem.cpp b/src/filesystem.cpp index d7fd36b..f27b3bd 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -398,8 +398,8 @@ struct CacheEnumData } }; -static void cacheEnumCB(void *d, const char *origdir, - const char *fname) +static PHYSFS_EnumerateCallbackResult +cacheEnumCB(void *d, const char *origdir, const char *fname) { CacheEnumData &data = *static_cast(d); char fullPath[512]; @@ -426,7 +426,7 @@ static void cacheEnumCB(void *d, const char *origdir, /* Iterate over its contents */ data.fileLists.push(&list); - PHYSFS_enumerateFilesCallback(fullPath, cacheEnumCB, d); + PHYSFS_enumerate(fullPath, cacheEnumCB, d); data.fileLists.pop(); } else @@ -441,13 +441,15 @@ static void cacheEnumCB(void *d, const char *origdir, /* Add the lower -> mixed mapping of the file's full path */ data.p->pathCache.insert(lowerCase, mixedCase); } + + return PHYSFS_ENUM_OK; } void FileSystem::createPathCache() { CacheEnumData data(p); data.fileLists.push(&p->fileLists[""]); - PHYSFS_enumerateFilesCallback("", cacheEnumCB, &data); + PHYSFS_enumerate("", cacheEnumCB, &data); p->havePathCache = true; } @@ -458,8 +460,8 @@ struct FontSetsCBData SharedFontState *sfs; }; -static void fontSetEnumCB(void *data, const char *dir, - const char *fname) +static PHYSFS_EnumerateCallbackResult +fontSetEnumCB (void *data, const char *dir, const char *fname) { FontSetsCBData *d = static_cast(data); @@ -467,7 +469,7 @@ static void fontSetEnumCB(void *data, const char *dir, const char *ext = findExt(fname); if (!ext) - return; + return PHYSFS_ENUM_STOP; char lowExt[8]; size_t i; @@ -477,7 +479,7 @@ static void fontSetEnumCB(void *data, const char *dir, lowExt[i] = '\0'; if (strcmp(lowExt, "ttf") && strcmp(lowExt, "otf")) - return; + return PHYSFS_ENUM_STOP; char filename[512]; snprintf(filename, sizeof(filename), "%s/%s", dir, fname); @@ -485,7 +487,7 @@ static void fontSetEnumCB(void *data, const char *dir, PHYSFS_File *handle = PHYSFS_openRead(filename); if (!handle) - return; + return PHYSFS_ENUM_ERROR; SDL_RWops ops; initReadOps(handle, ops, false); @@ -493,12 +495,14 @@ static void fontSetEnumCB(void *data, const char *dir, d->sfs->initFontSetCB(ops, filename); SDL_RWclose(&ops); + + return PHYSFS_ENUM_OK; } /* Basically just a case-insensitive search * for the folder "Fonts"... */ -static void findFontsFolderCB(void *data, const char *, - const char *fname) +static PHYSFS_EnumerateCallbackResult +findFontsFolderCB(void *data, const char *, const char *fname) { size_t i = 0; char buffer[512]; @@ -510,14 +514,16 @@ static void findFontsFolderCB(void *data, const char *, buffer[i] = '\0'; if (strcmp(buffer, "fonts") == 0) - PHYSFS_enumerateFilesCallback(fname, fontSetEnumCB, data); + PHYSFS_enumerate(fname, fontSetEnumCB, data); + + return PHYSFS_ENUM_OK; } void FileSystem::initFontSets(SharedFontState &sfs) { FontSetsCBData d = { p, &sfs }; - PHYSFS_enumerateFilesCallback(".", findFontsFolderCB, &d); + PHYSFS_enumerate(".", findFontsFolderCB, &d); } struct OpenReadEnumData @@ -550,19 +556,19 @@ struct OpenReadEnumData {} }; -static void openReadEnumCB(void *d, const char *dirpath, - const char *filename) +static PHYSFS_EnumerateCallbackResult +openReadEnumCB(void *d, const char *dirpath, const char *filename) { OpenReadEnumData &data = *static_cast(d); char buffer[512]; const char *fullPath; if (data.stopSearching) - return; + return PHYSFS_ENUM_STOP; /* If there's not even a partial match, continue searching */ if (strncmp(filename, data.filename, data.filenameN) != 0) - return; + return PHYSFS_ENUM_OK; if (!*dirpath) { @@ -580,7 +586,7 @@ static void openReadEnumCB(void *d, const char *dirpath, * of the extension), or up to a following '\0' (full match), we've * found our file */ if (last != '.' && last != '\0') - return; + return PHYSFS_ENUM_STOP; /* If the path cache is active, translate from lower case * to mixed case path */ @@ -595,9 +601,9 @@ static void openReadEnumCB(void *d, const char *dirpath, * be a deeper rooted problem somewhere within PhysFS. * Just abort alltogether. */ data.stopSearching = true; - data.physfsError = PHYSFS_getLastError(); + data.physfsError = PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()); - return; + return PHYSFS_ENUM_ERROR; } initReadOps(phys, data.ops, false); @@ -608,6 +614,7 @@ static void openReadEnumCB(void *d, const char *dirpath, data.stopSearching = true; ++data.matchCount; + return PHYSFS_ENUM_OK; } void FileSystem::openRead(OpenHandler &handler, const char *filename) @@ -653,7 +660,7 @@ void FileSystem::openRead(OpenHandler &handler, const char *filename) } else { - PHYSFS_enumerateFilesCallback(dir, openReadEnumCB, &data); + PHYSFS_enumerate(dir, openReadEnumCB, &data); } if (data.physfsError) diff --git a/src/rgssad.cpp b/src/rgssad.cpp index 17e8417..4b51472 100644 --- a/src/rgssad.cpp +++ b/src/rgssad.cpp @@ -331,14 +331,16 @@ verifyHeader(PHYSFS_Io *io, char version) } static void* -RGSS_openArchive(PHYSFS_Io *io, const char *, int forWrite) +RGSS_openArchive(PHYSFS_Io *io, const char *, int forWrite, int *claimed) { if (forWrite) - return 0; + return NULL; /* Version 1 */ if (!verifyHeader(io, 1)) - return 0; + return NULL; + else + *claimed = 1; RGSS_archiveData *data = new RGSS_archiveData; data->archiveIo = io; @@ -389,9 +391,9 @@ RGSS_openArchive(PHYSFS_Io *io, const char *, int forWrite) return data; } -static void +static PHYSFS_EnumerateCallbackResult RGSS_enumerateFiles(void *opaque, const char *dirname, - PHYSFS_EnumFilesCallback cb, + PHYSFS_EnumerateCallback cb, const char *origdir, void *callbackdata) { RGSS_archiveData *data = static_cast(opaque); @@ -399,13 +401,15 @@ RGSS_enumerateFiles(void *opaque, const char *dirname, std::string _dirname(dirname); if (!data->dirHash.contains(_dirname)) - return; + return PHYSFS_ENUM_STOP; const BoostSet &entries = data->dirHash[_dirname]; BoostSet::const_iterator iter; for (iter = entries.cbegin(); iter != entries.cend(); ++iter) cb(callbackdata, origdir, iter->c_str()); + + return PHYSFS_ENUM_OK; } static PHYSFS_Io* @@ -536,19 +540,21 @@ readUint32AndXor(PHYSFS_Io *io, uint32_t &result, uint32_t key) } static void* -RGSS3_openArchive(PHYSFS_Io *io, const char *, int forWrite) +RGSS3_openArchive(PHYSFS_Io *io, const char *, int forWrite, int *claimed) { if (forWrite) - return 0; + return NULL; /* Version 3 */ if (!verifyHeader(io, 3)) - return 0; + return NULL; + else + *claimed = 1; uint32_t baseMagic; if (!readUint32(io, baseMagic)) - return 0; + return NULL; baseMagic = (baseMagic * 9) + 3; @@ -605,7 +611,7 @@ RGSS3_openArchive(PHYSFS_Io *io, const char *, int forWrite) error: delete data; - return 0; + return NULL; } return data; From 7d9a85dbbd43f7dd26ef5ce07b2772bbd1e59a3a Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Mon, 11 Dec 2017 00:48:35 +0100 Subject: [PATCH 28/34] Config: Add entry to override the game window title --- mkxp.conf.sample | 6 ++++++ src/config.cpp | 1 + src/config.h | 1 + src/main.cpp | 5 ++++- 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/mkxp.conf.sample b/mkxp.conf.sample index 500dcc6..2d9ad45 100644 --- a/mkxp.conf.sample +++ b/mkxp.conf.sample @@ -77,6 +77,12 @@ # defScreenW=640 +# Override the game window title +# (default: none) +# +# windowTitle=Custom Title + + # Specify the window height on startup. If set to 0, # it will default to the default resolution height # specific to the RGSS version (480 in RGSS1, 416 diff --git a/src/config.cpp b/src/config.cpp index 33d8160..4d47152 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -161,6 +161,7 @@ void Config::read(int argc, char *argv[]) PO_DESC(vsync, bool, false) \ PO_DESC(defScreenW, int, 0) \ PO_DESC(defScreenH, int, 0) \ + PO_DESC(windowTitle, std::string, "") \ PO_DESC(fixedFramerate, int, 0) \ PO_DESC(frameSkip, bool, true) \ PO_DESC(syncToRefreshrate, bool, false) \ diff --git a/src/config.h b/src/config.h index d2d4650..5cc8bb7 100644 --- a/src/config.h +++ b/src/config.h @@ -41,6 +41,7 @@ struct Config int defScreenW; int defScreenH; + std::string windowTitle; int fixedFramerate; bool frameSkip; diff --git a/src/main.cpp b/src/main.cpp index 1a3fc4e..40ae391 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -233,6 +233,9 @@ int main(int argc, char *argv[]) conf.readGameINI(); + if (conf.windowTitle.empty()) + conf.windowTitle = conf.game.title; + assert(conf.rgssVersion >= 1 && conf.rgssVersion <= 3); printRgssVersion(conf.rgssVersion); @@ -272,7 +275,7 @@ int main(int argc, char *argv[]) if (conf.fullscreen) winFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - win = SDL_CreateWindow(conf.game.title.c_str(), + win = SDL_CreateWindow(conf.windowTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, conf.defScreenW, conf.defScreenH, winFlags); From 2f81fbbf4b9871d8443477262f475ee52fed14a2 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Mon, 11 Dec 2017 00:51:21 +0100 Subject: [PATCH 29/34] Fix ordering --- mkxp.conf.sample | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mkxp.conf.sample b/mkxp.conf.sample index 2d9ad45..9863eaf 100644 --- a/mkxp.conf.sample +++ b/mkxp.conf.sample @@ -77,12 +77,6 @@ # defScreenW=640 -# Override the game window title -# (default: none) -# -# windowTitle=Custom Title - - # Specify the window height on startup. If set to 0, # it will default to the default resolution height # specific to the RGSS version (480 in RGSS1, 416 @@ -92,6 +86,12 @@ # defScreenH=480 +# Override the game window title +# (default: none) +# +# windowTitle=Custom Title + + # Enforce a static frame rate # (0 = disabled) # From 947974cac649769a9c569162e5f16022896a2652 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Tue, 12 Dec 2017 17:57:02 +0100 Subject: [PATCH 30/34] Config: Properly use windowTitle everywhere instead of game.title --- src/eventthread.cpp | 8 ++++---- src/main.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/eventthread.cpp b/src/eventthread.cpp index 08b6c29..6ffdb29 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -296,14 +296,14 @@ void EventThread::process(RGSSThreadData &rtData) if (fullscreen) { /* Prevent fullscreen flicker */ - strncpy(pendingTitle, rtData.config.game.title.c_str(), + strncpy(pendingTitle, rtData.config.windowTitle.c_str(), sizeof(pendingTitle)); havePendingTitle = true; break; } - SDL_SetWindowTitle(win, rtData.config.game.title.c_str()); + SDL_SetWindowTitle(win, rtData.config.windowTitle.c_str()); } break; @@ -410,7 +410,7 @@ void EventThread::process(RGSSThreadData &rtData) case REQUEST_MESSAGEBOX : SDL_ShowSimpleMessageBox(event.user.code, - rtData.config.game.title.c_str(), + rtData.config.windowTitle.c_str(), (const char*) event.user.data1, win); free(event.user.data1); msgBoxDone.set(); @@ -429,7 +429,7 @@ void EventThread::process(RGSSThreadData &rtData) break; snprintf(buffer, sizeof(buffer), "%s - %d FPS", - rtData.config.game.title.c_str(), event.user.code); + rtData.config.windowTitle.c_str(), event.user.code); /* Updating the window title in fullscreen * mode seems to cause flickering */ diff --git a/src/main.cpp b/src/main.cpp index 40ae391..e457639 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -353,13 +353,13 @@ int main(int argc, char *argv[]) if (rtData.rqTermAck) SDL_WaitThread(rgssThread, 0); else - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.game.title.c_str(), + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.windowTitle.c_str(), "The RGSS script seems to be stuck and mkxp will now force quit", win); if (!rtData.rgssErrorMsg.empty()) { Debug() << rtData.rgssErrorMsg; - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.game.title.c_str(), + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.windowTitle.c_str(), rtData.rgssErrorMsg.c_str(), win); } From 7902d0942d17627e2ada58bfa3ce1898003c951d Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Tue, 12 Dec 2017 22:45:01 +0100 Subject: [PATCH 31/34] Filesystem: Properly iterate top level dir entries "." seemed to have worked in earlier PhysFS versions, but it was never the correct way. --- src/filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filesystem.cpp b/src/filesystem.cpp index f27b3bd..8e50ee8 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -523,7 +523,7 @@ void FileSystem::initFontSets(SharedFontState &sfs) { FontSetsCBData d = { p, &sfs }; - PHYSFS_enumerate(".", findFontsFolderCB, &d); + PHYSFS_enumerate("", findFontsFolderCB, &d); } struct OpenReadEnumData From 183ebbed65687c4074b8431765b7d6ac4d8d2d35 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Tue, 12 Dec 2017 22:46:25 +0100 Subject: [PATCH 32/34] RGSSAD: Fix parsing of top level directory entries We were spamming every path into the hash (including the top level ones) without noticing... oh well. --- src/rgssad.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rgssad.cpp b/src/rgssad.cpp index 4b51472..ac8772a 100644 --- a/src/rgssad.cpp +++ b/src/rgssad.cpp @@ -297,6 +297,8 @@ processDirectories(RGSS_archiveData *data, BoostSet &topLevel, if (slash) nameBuf[i] = '/'; + + break; } /* Check for more entries */ From 9f44ee50688fe1fda3a3a17226d351da8da98405 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Mon, 22 Jan 2018 10:54:21 +0100 Subject: [PATCH 33/34] FileSystem: Fix while termination condition --- src/filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 8e50ee8..33d383d 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -508,7 +508,7 @@ findFontsFolderCB(void *data, const char *, const char *fname) char buffer[512]; const char *s = fname; - while (s && i < sizeof(buffer)) + while (*s && i < sizeof(buffer)) buffer[i++] = tolower(*s++); buffer[i] = '\0'; From b5e5a26d8b0b1a8ea1b502cba3b432e7fac088a4 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 22 Feb 2018 04:37:47 -0300 Subject: [PATCH 34/34] Config: Set debug editor's debug variables into ruby --- binding-mri/binding-mri.cpp | 9 +++++++++ binding-mruby/binding-mruby.cpp | 9 +++++++++ src/config.cpp | 21 +++++++++++++++++++++ src/config.h | 6 ++++++ 4 files changed, 45 insertions(+) diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index f0a4bb4..1c0057b 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -147,7 +147,16 @@ static void mriBindingInit() _rb_define_module_function(mod, "raw_key_states", mkxpRawKeyStates); _rb_define_module_function(mod, "mouse_in_window", mkxpMouseInWindow); + /* Load global constants */ rb_gv_set("MKXP", Qtrue); + + VALUE debug = rb_bool_new(shState->config().editor.debug); + if (rgssVer == 1) + rb_gv_set("DEBUG", debug); + else if (rgssVer >= 2) + rb_gv_set("TEST", debug); + + rb_gv_set("BTEST", rb_bool_new(shState->config().editor.battleTest)); } static void diff --git a/binding-mruby/binding-mruby.cpp b/binding-mruby/binding-mruby.cpp index 867d2d6..a713d73 100644 --- a/binding-mruby/binding-mruby.cpp +++ b/binding-mruby/binding-mruby.cpp @@ -114,8 +114,17 @@ static void mrbBindingInit(mrb_state *mrb) /* Load RPG module */ mrb_load_irep(mrb, mrbModuleRPG); + /* Load global constants */ mrb_define_global_const(mrb, "MKXP", mrb_true_value()); + mrb_value debug = rb_bool_new(shState->config().editor.debug); + if (rgssVer == 1) + mrb_define_global_const(mrb, "DEBUG", debug); + else if (rgssVer >= 2) + mrb_define_global_const(mrb, "TEST", debug); + + mrb_define_global_const(mrb, "BTEST", mrb_bool_value(shState->config().editor.battleTest)); + mrb_gc_arena_restore(mrb, arena); } diff --git a/src/config.cpp b/src/config.cpp index 4d47152..fee3b5a 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -189,6 +189,27 @@ void Config::read(int argc, char *argv[]) // Not gonna take your shit boost #define GUARD_ALL( exp ) try { exp } catch(...) {} + editor.debug = false; + editor.battleTest = false; + + /* Read arguments sent from the editor */ + if (argc > 1) + { + std::string argv1 = argv[1]; + /* RGSS1 uses "debug", 2 and 3 use "test" */ + if (argv1 == "debug" || argv1 == "test") + editor.debug = true; + else if (argv1 == "btest") + editor.battleTest = true; + + /* Fix offset */ + if (editor.debug || editor.battleTest) + { + argc--; + argv++; + } + } + #define PO_DESC(key, type, def) (#key, po::value< type >()->default_value(def)) po::options_description podesc; diff --git a/src/config.h b/src/config.h index 5cc8bb7..e380250 100644 --- a/src/config.h +++ b/src/config.h @@ -88,6 +88,12 @@ struct Config std::vector rubyLoadpaths; + /* Editor flags */ + struct { + bool debug; + bool battleTest; + } editor; + /* Game INI contents */ struct { std::string scripts;