From a819cb54a6a7c15bc42ab8334e32b78754f33f12 Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Fri, 3 Mar 2017 19:37:19 +0100 Subject: [PATCH 01/13] 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<std::string>::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<typename T> +std::set<T> setFromVec(const std::vector<T> &vec) +{ + return std::set<T>(vec.begin(), vec.end()); +} + typedef std::vector<std::string> 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<StringVec>(); ); + GUARD_ALL( preloadScripts = setFromVec(vm["preloadScript"].as<StringVec>()); ); GUARD_ALL( rtps = vm["RTP"].as<StringVec>(); ); 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 <string> #include <vector> +#include <set> struct Config { @@ -77,7 +78,7 @@ struct Config bool useScriptNames; std::string customScript; - std::vector<std::string> preloadScripts; + std::set<std::string> preloadScripts; std::vector<std::string> rtps; std::vector<std::string> fontSubs; From 3b5f2608ec28f4faaca183d73197504037d82e52 Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Sat, 4 Mar 2017 11:04:02 +0100 Subject: [PATCH 02/13] 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 a5a648ac861e3c8cac8576749e64262c31c04e60 Mon Sep 17 00:00:00 2001 From: Marty Plummer <ntzrmtthihu777@gmail.com> Date: Fri, 3 Mar 2017 22:45:31 -0600 Subject: [PATCH 03/13] Add icon and resource files for windows Signed-off-by: Marty Plummer <ntzrmtthihu777@gmail.com> --- 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 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 literal 0 HcmV?d00001 diff --git a/assets/resource.h b/assets/resource.h new file mode 100644 index 0000000..32015bd --- /dev/null +++ b/assets/resource.h @@ -0,0 +1 @@ +#define IDI_APPICON 101 diff --git a/assets/resource.rc b/assets/resource.rc new file mode 100644 index 0000000..293e38d --- /dev/null +++ b/assets/resource.rc @@ -0,0 +1,4 @@ +#include <windows.h> +#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 fbfee3ed9b6a9486ebdbaee1598ece88ae6eef68 Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Wed, 8 Mar 2017 16:30:07 +0100 Subject: [PATCH 04/13] 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<FontSetsCBData*>(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 2f273bade8d943d699ff69ed3fbd87d5837b087f Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Sat, 8 Apr 2017 16:16:36 +0200 Subject: [PATCH 05/13] 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<intptr_t>(event.user.data1); + gameScreen.h = reinterpret_cast<intptr_t>(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<void*>(screen.w); + event.user.data2 = reinterpret_cast<void*>(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 d25551e2666397dfb9321bef064d5c0f96198622 Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Sat, 8 Apr 2017 18:41:56 +0200 Subject: [PATCH 06/13] 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 2e240d9fbec83cc431202de905201bdfbda4a0f9 Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Sat, 8 Apr 2017 19:13:31 +0200 Subject: [PATCH 07/13] 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 1bc27177443776dfb835f7f7ff980d369f34f7ac Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Sat, 8 Apr 2017 20:06:12 +0200 Subject: [PATCH 08/13] 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 <SDL_timer.h> #include <SDL_thread.h> #include <SDL_touch.h> +#include <SDL_rect.h> #include <al.h> #include <alc.h> From 9fec876e3240ac3503db748e0f7d9094e86a5602 Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Sun, 23 Apr 2017 12:28:34 +0200 Subject: [PATCH 09/13] 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 <SDL_rect.h> @@ -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 <stack> #include <assert.h> +struct Config; + template<typename T> 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 04634ed8fe3670c4366d74fe46c414006ff9568f Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Sun, 23 Apr 2017 14:32:11 +0200 Subject: [PATCH 10/13] 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 4063e7aa9d052c973658cd78f7db549a224bd155 Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Thu, 11 May 2017 12:20:08 +0200 Subject: [PATCH 11/13] 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 128cc08e89bc39df931dae827693b7503092c530 Mon Sep 17 00:00:00 2001 From: Jonas Kulla <Nyocurio@gmail.com> Date: Thu, 11 May 2017 12:37:15 +0200 Subject: [PATCH 12/13] 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 c09d24ff0a0678f46c595c396afc204bd9f19942 Mon Sep 17 00:00:00 2001 From: Marty Plummer <ntzrmtthihu777@gmail.com> Date: Thu, 25 May 2017 04:17:02 -0500 Subject: [PATCH 13/13] Allows cross-compilation to windows targets. Tested on gentoo with x86_64-w64-mingw32 toolchain and libraries. Signed-off-by: Marty Plummer <ntzrmtthihu777@gmail.com> --- 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}