From 2adf8ab2651d5dc06cc3cc039b590757bf59d5eb Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Wed, 11 Dec 2013 20:46:54 +0100 Subject: [PATCH] Transition from QtCore to stdc++ / STL / boost This looks like a pretty major change, but in reality, 80% of it is just renames of types and corresponding methods. The config parsing code has been completely replaced with a boost::program_options based version. This means that the config file format slightly changed (checkout the updated README). I still expect there to be bugs / unforseen events. Those should be fixed in follow up commits. Also, finally reverted back to using pkg-config to locate and link libruby. Yay for less hacks! --- README.md | 81 +++++++++--------- binding-mri/binding-mri.cpp | 79 +++++++++--------- binding-mri/binding-util.cpp | 9 +- binding-mri/binding-util.h | 4 +- binding-mri/bitmap-binding.cpp | 2 - binding-mri/etc-binding.cpp | 2 - binding-mri/filesystem-binding.cpp | 2 - binding-mruby/binding-mruby.cpp | 48 ++++++----- binding-mruby/bitmap-binding.cpp | 2 - binding-mruby/disposable-binding.h | 2 + binding-mruby/etc-binding.cpp | 2 - binding-mruby/mrb-ext/file.cpp | 10 +-- binding-mruby/mrb-ext/kernel.cpp | 2 - binding-mruby/mrb-ext/marshal.cpp | 18 ++-- binding-mruby/table-binding.cpp | 2 - binding-null/binding-null.cpp | 5 +- mkxp.pro | 40 ++++++--- src/audio.cpp | 51 +++++------ src/bitmap.cpp | 57 +++++++++++-- src/boost-hash.h | 130 +++++++++++++++++++++++++++++ src/config.cpp | 126 ++++++++++++++++------------ src/config.h | 19 ++--- src/debuglogger.cpp | 30 ++----- src/debugwriter.h | 56 +++++++++++++ src/eventthread.cpp | 15 ++-- src/eventthread.h | 4 +- src/exception.h | 16 ++-- src/filesystem.cpp | 48 +++++------ src/flashable.h | 2 - src/font.cpp | 82 +++++++++--------- src/main.cpp | 43 +++++----- src/perftimer.cpp | 8 +- src/scene.cpp | 2 - src/shader.cpp | 31 +++---- src/sharedstate.cpp | 23 ++--- src/sprite.cpp | 2 - src/texpool.cpp | 82 ++++++++++-------- src/util.h | 37 ++++++++ src/viewport.cpp | 2 - src/window.cpp | 2 - 40 files changed, 722 insertions(+), 456 deletions(-) create mode 100644 src/boost-hash.h create mode 100644 src/debugwriter.h diff --git a/README.md b/README.md index 27e71ed..cc7a006 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ mkxp is a project that seeks to provide a fully open source implementation of th It is licensed under the GNU General Public License v2+. ## Bindings -Bindings provide the glue code for an interpreted language environment to run game scripts in. As of right now, they are compiled directly into the executable (however, the scripting language itself might not be). Currently there are three bindings: +Bindings provide the glue code for an interpreted language environment to run game scripts in. Currently there are three bindings: ### MRI Website: https://www.ruby-lang.org/en/ @@ -15,8 +15,6 @@ Matz's Ruby Interpreter, also called CRuby, is the most widely deployed version For a list of differences, see: http://stackoverflow.com/questions/21574/what-is-the-difference-between-ruby-1-8-and-ruby-1-9 -To select this binding, run `qmake BINDING=BINDING_MRI` - ### mruby (Lightweight Ruby) Website: https://github.com/mruby/mruby @@ -24,23 +22,20 @@ mruby is a new endeavor by Matz and others to create a more lightweight, spec-ad Due to heavy differences between mruby and MRI as well as lacking modules, running RPG Maker games with this binding will most likely not work correctly. It is provided as experimental code. You can eg. write your own ruby scripts and run them. -Some extensions to the standard classes/modules are provided taking the RPG Maker XP helpfile as a quasi "standard". These include Marshal, File, FileTest and Time. +Some extensions to the standard classes/modules are provided, taking the RPG Maker XP helpfile as a quasi "reference". These include Marshal, File, FileTest and Time. **Important:** If you decide to use [mattn's oniguruma regexp gem](https://github.com/mattn/mruby-onig-regexp), don't forget to add `-lonig` to the linker flags to avoid ugly symbol overlaps with libc. -To select this binding, run `qmake BINDING=BINDING_MRUBY` - ### null This binding only exists for testing purposes and does nothing (the engine quits immediately). It can be used to eg. run a minimal RGSS game loop directly in C++. -To select this binding, run `qmake BINDING=BINDING_NULL` +## Dependencies / Building -## Dependencies - -* QtCore 4.8 -* libsigc++ -* PhysFS -* glew +* Boost.Unordered (headers only) +* Boost.Program_options +* libsigc++ 2.0 +* PhysFS (latest hg) +* GLEW >= 1.7 * OpenAL * SDL2 * SDL2_image @@ -49,44 +44,44 @@ To select this binding, run `qmake BINDING=BINDING_NULL` * pixman * zlib (only ruby bindings) -(If no version specified, assume latest *development version*, ie. freshest one from git/hg/svn) +mkxp employs Qt's qmake build system, so you'll need to install that beforehand. + +qmake will use pkg-config to locate the respective include/library paths. If you installed any dependencies into non-standard prefixes, make sure to adjust your `PKG_CONFIG_PATH` variable accordingly. + +The exception is boost, which is weird in that it still hasn't managed to pull off pkg-config support (seriously?). *If you installed boost in a non-standard prefix*, you will need to pass its include path via `BOOST_I` and library path via `BOOST_L`, either as direct arguments to qmake (`qmake BOOST_I="/usr/include" ...`) or via environment variables. + +**MRI-Binding**: pkg-config will look for `ruby-2.1.pc`, but you can modify mkxp.pro to use 2.0 instead. This is the default binding, so no arguments to qmake needed (`BINDING=BINDING_MRI` to be explicit). + +**MRuby-Binding**: place the "mruby" folder into the project folder and build it first. Add `BINDING=BINDING_MRUBY` to qmake's arguments. + +**Null-Binding**: Add `BINDING=BINDING_NULL` to qmake's arguments. ### Supported image/audio formats -These depend on the auxiliary libraries. For maximum RGSS compliance, build SDL2_image with png/jpg support, and SDL_sound with oggvorbis/wav/mp3 support. - -### MRI binding: -Place a recent version of ruby in the project folder, apply all patches from "patches/ruby" and build it. - -### mruby binding: -Place a recent version of mruby in the project folder and build it. +These depend on the SDL auxiliary libraries. For maximum RGSS compliance, build SDL2_image with png/jpg support, and SDL_sound with oggvorbis/wav/mp3 support. To run mkxp, you should have a graphics card capable of at least **OpenGL 2.0** with an up-to-date driver installed. -## Building - -mkxp employs Qt's qmake build system, so you'll need to install that beforehand. After cloning mkxp, run one of the above qmake calls, or simply `qmake` to select the default binding (currently MRI), then `make`. - ## Configuration -mkxp reads configuration data from the file "mkxp.conf" contained in the current directory. The format is ini-style. The "[General]" group may contain following entries: +mkxp reads configuration data from the file "mkxp.conf" contained in the current directory. The format is ini-style. Do *not* use quotes around file paths (spaces won't break). Following entries are interpreted: -| Key | Type | Default | Description | -| ---------------- | ----------- | ------- | ------------------------------------------------------------------------------- | -| debugMode | bool | false | Log OpenGL debug information to the console | -| winResizable | bool | false | Game window is resizable | -| fullscreen | bool | false | Start game in fullscreen (this can always be toggled with Alt-Enter at runtime) | -| fixedAspectRatio | bool | true | Don't stretch the game screen to fit the window size | -| smoothScaling | bool | false | Apply linear interpolation when game screen is stretched | -| vsync | bool | false | Sync screen redraws to the monitor refresh rate | -| defScreenW | int | 640 | Width the game window starts in (this is **not** the game resolution) | -| defScreenH | int | 480 | Height the game window starts in | -| fixedFramerate | int | 0 | FPS will be fixed to this amount. Ignored if 0. | -| frameSkip | bool | true | Skip frames to catch up (useful to disable eg. with Valgrind) | -| solidFonts | bool | false | Don't use alpha blending for fonts | -| gameFolder | string | "." | mkxp will look for all game related files here | -| allowSymlinks | bool | false | Allow symlinks to be followed in the game folder. | -| customScript | string | "" | Execute a raw ruby script file instead of an RPG Maker game. | -| RTPs | string list | "" | A list of space separated paths to RTPs to be used (See next section) | +| Key | Type | Default | Description | +| ---------------- | ------ | ------- | ------------------------------------------------------------------------------- | +| debugMode | bool | false | Log OpenGL debug information to the console | +| winResizable | bool | false | Game window is resizable | +| fullscreen | bool | false | Start game in fullscreen (this can always be toggled with Alt-Enter at runtime) | +| fixedAspectRatio | bool | true | Don't stretch the game screen to fit the window size | +| smoothScaling | bool | false | Apply linear interpolation when game screen is stretched | +| vsync | bool | false | Sync screen redraws to the monitor refresh rate | +| defScreenW | int | 640 | Width the game window starts in (this is **not** the game resolution) | +| defScreenH | int | 480 | Height the game window starts in | +| fixedFramerate | int | 0 | FPS will be fixed to this amount. Ignored if 0. | +| frameSkip | bool | true | Skip frames to catch up (useful to disable eg. with Valgrind) | +| solidFonts | bool | false | Don't use alpha blending for fonts | +| gameFolder | string | "." | mkxp will look for all game related files here | +| allowSymlinks | bool | false | Allow symlinks to be followed in the game folder. | +| customScript | string | "" | Execute a raw ruby script file instead of an RPG Maker game. | +| RTP | string | "" | Path to a Run Time Package to be used. Can be specified multiple times. | ## RTPs diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index d44b168..a89fe83 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -24,19 +24,18 @@ #include "sharedstate.h" #include "eventthread.h" #include "filesystem.h" +#include "util.h" +#include "debugwriter.h" -#include "./ruby/include/ruby.h" -#include "./ruby/include/ruby/encoding.h" +#include +#include + +#include #include #include -#include -#include - -#include - extern const char module_rpg[]; static void mriBindingExecute(); @@ -102,9 +101,9 @@ static void mriBindingInit() } static void -showMsg(const QByteArray &msg) +showMsg(const std::string &msg) { - shState->eThread().showMessageBox(msg.constData()); + shState->eThread().showMessageBox(msg.c_str()); } RB_METHOD(mkxpPuts) @@ -114,7 +113,7 @@ RB_METHOD(mkxpPuts) const char *str; rb_get_args(argc, argv, "z", &str RB_ARG_END); - qDebug() << str; + Debug() << str; return Qnil; } @@ -174,49 +173,45 @@ RB_METHOD(mriDataDirectory) static void runCustomScript(const char *filename) { - QFile scriptFile(filename); - if (!scriptFile.open(QFile::ReadOnly)) + std::string scriptData("#encoding:utf-8\n"); + + if (!readFile(filename, scriptData)) { - showMsg(QByteArray("Unable to open '") + filename + "'"); + showMsg(std::string("Unable to open '") + filename + "'"); return; } - QByteArray scriptData = scriptFile.readAll(); - scriptFile.close(); - - scriptData.prepend("#encoding:utf-8\n"); - - rb_eval_string_protect(scriptData.constData(), 0); + rb_eval_string_protect(scriptData.c_str(), 0); } VALUE kernelLoadDataInt(const char *filename); struct Script { - QByteArray name; - QByteArray encData; + std::string name; + std::string encData; uint32_t unknown; - QByteArray decData; + std::string decData; }; static void runRMXPScripts() { - const QByteArray &scriptPack = shState->rtData().config.game.scripts; + const std::string &scriptPack = shState->rtData().config.game.scripts; - if (scriptPack.isEmpty()) + if (scriptPack.empty()) { showMsg("No game scripts specified (missing Game.ini?)"); return; } - if (!shState->fileSystem().exists(scriptPack.constData())) + if (!shState->fileSystem().exists(scriptPack.c_str())) { showMsg("Unable to open '" + scriptPack + "'"); return; } - VALUE scriptArray = kernelLoadDataInt(scriptPack.constData()); + VALUE scriptArray = kernelLoadDataInt(scriptPack.c_str()); if (rb_type(scriptArray) != RUBY_T_ARRAY) { @@ -226,7 +221,7 @@ static void runRMXPScripts() size_t scriptCount = RARRAY_LEN(scriptArray); - QByteArray decodeBuffer; + std::string decodeBuffer; decodeBuffer.resize(0x1000); std::vector