Compare commits

...

252 Commits

Author SHA1 Message Date
Amaryllis Kulla 6a875b30d2 README: Update matrix space link 2023-10-12 20:53:19 +02:00
Amaryllis Kulla 998aa9f846 README: Update soundfont link 2023-10-05 21:18:55 +02:00
Amaryllis Kulla b4c439c6eb README: Update links 2023-09-08 20:54:46 +02:00
Amaryllis Kulla 380b676777
README: Point binary links at mapleshrine.eu 2021-11-06 00:04:25 +01:00
Amaryllis Kulla a962c158db Update copyright notice again
Keep information on first file creation year,
and update my email address yet again.
2021-10-16 22:57:08 +02:00
Jaiden cf6403ae65 Update glstate.cpp
Fixes the GL blend formula for Subtractive blending
2021-09-19 15:24:12 +02:00
Ancurio f138731f7c Update copyright notice 2021-09-06 20:50:44 +02:00
mara ac8f4b1594 build: Support SDL_sound in different prefix as SDL2
As the required SDL_sound is a custom fork which is not packaged as
system package, it could plausibly be installed in a different path.
2021-09-03 07:43:11 +02:00
Jari Vetoniemi 990843a50b Compile with newer openal-soft 2021-08-28 07:40:15 +02:00
Jari Vetoniemi 66dc9309db Add .editorconfig to the project
Saves time and hassle
2020-08-12 22:17:37 +02:00
Jonas Kulla 5c117a55bf
README: Remember that markdown is a thing 2020-08-10 09:42:00 +02:00
Jonas Kulla cb09036c55
README: Add project discord link 2020-08-10 09:41:19 +02:00
Jonas Kulla 6903f2ab43 README: Add link to gist document 2020-05-06 07:38:25 +02:00
Jonas Kulla 9dc42914de README: Clarify target group of project 2019-06-20 06:01:20 +02:00
Jonas Kulla 86194118a3 FileSystem: Check PHYSFS_registerArchiver() for success 2019-05-18 16:48:17 +02:00
Jonas Kulla 98bdfcf758 FileSystem: Check PHYSFS_init() for success
Move it above the allocations so exceptions don't leak memory.
2019-05-18 16:42:56 +02:00
Jonas Kulla 6fa5b8c856 Sprite: Define M_PI manually
Apparently (older?) mingw-w64 with C++11 enabled doesn't have it.
2019-05-18 16:21:21 +02:00
Jonas Kulla d6b477b887 qmake.pro: Add explicit C++11 flags 2019-05-18 16:17:09 +02:00
Jonas Kulla 9dcfb66e86 fluid-fun: Define destructor signature based on fluidsynth version
As per @carstene1ns 's suggestion.
2019-03-22 21:16:57 +01:00
Jonas Kulla d4b9adc1d1 fluid-fun: Adjust function signature to fluidsynth 2.0
This breaks compilation with FLUID_SHARED against <2.0 versions,
which should be reasonable given that the default mode can still
dynamically load both variants.

Fixes #219.
2019-03-21 08:07:02 +01:00
Luis Caceres 43cb318862 Config: Add case-insensitive ini file parser 2019-03-19 19:26:50 +01:00
Eliza Velasquez bab22d87be Fix font enumeration
Currently, the font enumeration callback erroneously stops searching if
it finds any files that aren't fonts. In the case that you have, say, a
desktop.ini or a .DS_Store or a license file, it may prevent all of the
fonts from being loaded. This commit resolves this.
2018-10-13 20:28:36 +02:00
Jonas Kulla ae59fcd112 Graphics: Fix transition when new scene has gray tone effect
Rendering the scene may cause PingPong swaps of front / backbuffer,
so don't take references to those buffers until after rendering.

Fixes #199
2018-05-21 12:22:23 +02:00
ReinUsesLisp b5e5a26d8b Config: Set debug editor's debug variables into ruby 2018-02-22 09:08:45 +01:00
Jonas Kulla 9f44ee5068 FileSystem: Fix while termination condition 2018-01-22 10:54:21 +01:00
Jonas Kulla 183ebbed65 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.
2017-12-12 22:46:25 +01:00
Jonas Kulla 7902d0942d Filesystem: Properly iterate top level dir entries
"." seemed to have worked in earlier PhysFS versions,
but it was never the correct way.
2017-12-12 22:45:01 +01:00
Jonas Kulla 947974cac6 Config: Properly use windowTitle everywhere instead of game.title 2017-12-12 17:57:02 +01:00
Jonas Kulla 2f81fbbf4b Fix ordering 2017-12-11 00:51:21 +01:00
Jonas Kulla 7d9a85dbbd Config: Add entry to override the game window title 2017-12-11 00:48:35 +01:00
Carsten Teibes d427df0c2b Adapt RGSS archivers and filesystem to physfs 3.0 API 2017-10-12 14:27:19 +02:00
Carsten Teibes b1bdf1e445 Fix CMake build, only use `resource.h` on Windows
This was broken in commit 01e17ed5c6 (move windows specific files).
2017-08-18 22:42:27 +02:00
Carsten Teibes fde6a92197 Fix deprecation warning on build with MRI>2.3
Fixes #158.

The old alias is deprecated since: ruby/ruby@fdb957925f.
2017-08-18 22:41:16 +02:00
Marty Plummer 01e17ed5c6 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 <ntzrmtthihu777@gmail.com>
2017-08-10 21:58:31 +02:00
Jonas Kulla f172f58c74 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 55cec53911.
2017-08-10 21:39:17 +02:00
Jonas Kulla fba20e6294 Sprite: Check for disposed state before accessing bitmap 2017-07-30 23:00:18 +02:00
Marty Plummer f5c30affaa mingw-w64: allow cmake cross-compile
Tested on gentoo with x86_64-w64-mingw32 toolchain and libraries.

Signed-off-by: Marty Plummer <ntzrmtthihu777@gmail.com>
2017-05-25 13:01:11 +02:00
Jonas Kulla bd694f9f99 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.
2017-05-11 12:37:15 +02:00
Jonas Kulla cab453ac3a 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.
2017-05-11 12:32:56 +02:00
Jonas Kulla 006f701fec Config: Add "enableBlitting" entry to toggle GL_EXT_framebuffer_blit 2017-04-23 14:32:11 +02:00
Jonas Kulla 1478e1e0f9 Config: Add "maxTextureSize" entry to artificially limit texture sizes 2017-04-23 14:10:54 +02:00
Jonas Kulla 06feafe9ef Add missing include 2017-04-08 20:06:12 +02:00
Jonas Kulla e4079d5738 Fix build on OSX after 60e967e3b7 2017-04-08 19:13:31 +02:00
Jonas Kulla 0481f920b0 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.
2017-04-08 18:45:24 +02:00
Jonas Kulla 3ea24bd757 EventThread: Make system cursor visible over black aspect ratio bars
Should be less confusing for the player.
2017-04-08 18:45:24 +02:00
Marty Plummer 60e967e3b7 Add icon and resource files for windows
Signed-off-by: Marty Plummer <ntzrmtthihu777@gmail.com>
2017-03-09 08:24:13 +01:00
Jonas Kulla 0f9b5f274a Filesystem: Search for "Fonts/" with case-insensitivity 2017-03-08 16:30:07 +01:00
Jonas Kulla 6349146e01 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.
2017-03-04 11:04:02 +01:00
Jonas Kulla c4dd3ffaf6 Config: Use set for preloadScripts
Would probably make sense for all other string vectors too.
2017-03-03 19:37:19 +01:00
Jonas Kulla 55cec53911 Sprite: Clamp src_rect to bitmap bounds 2017-02-17 19:29:38 +01:00
Jonas Kulla 541e24f678 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.
2016-10-30 08:50:45 +01:00
Jonas Kulla 0ec1fce4ac MRI: Bind Audio.setup_midi 2016-09-12 20:20:56 +02:00
Jonas Kulla d4e09f55bd WindowVX: Fix move() not setting the correct dirty flags 2016-07-27 12:03:45 +02:00
Jonas Kulla e98c2e0535 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.
2016-07-27 11:59:08 +02:00
Jonas Kulla fdaf6c3611 Bitmap: Split surface pixel address calculation into helper 2016-07-27 11:56:43 +02:00
Jonas Kulla 47ef36ca19 EventThread: ifdef out broken SDL function on OSX 2016-02-24 17:55:28 +01:00
Jonas Kulla de74fc1bc3 EventThread: Fix mouse cursor not being hidden 2016-02-24 17:45:55 +01:00
Jonas Kulla 5d776319b5 Font/MRI: Improve handling of (default_)name attributes
More accurate behavior, such as Font objects properly inheriting
their name attributes, and centralization of code for picking
the first existing name from a passed string array.

Also centralizes initial default_name population in core.

Note: This currently breaks the mruby binding build.
2016-01-05 08:47:52 +01:00
Jonas Kulla 53b5b923d4 Merge pull request #138 from mook/graphics-playmovie-stub
MRI: Stub out Graphics.play_movie
2015-10-30 16:20:47 +01:00
Mook 8e411cbcfe Graphics: Stub out play_movie
Some people are using it to detect the RGSS version.
2015-10-30 08:01:36 -07:00
Jonas Kulla 7bf6eca362 EventThread: Comment out unneeded SDL2 constants 2015-07-26 23:56:50 +02:00
Jonas Kulla 4d97a17c44 TilemapVX: Ensure legs of out-of-view table tiles are drawn 2015-07-21 12:13:25 +02:00
Jonas Kulla 7017ca1c53 Use static lifetime for constant array 2015-07-21 12:13:25 +02:00
Jonas Kulla 30465691ae Tilemap: Fix map viewport calculation
Calculation was completely off as it didn't take into
account the imposed viewport origin.

All in all, similar fixes as the previous ones to TilemapVX.
2015-07-21 12:13:25 +02:00
Jonas Kulla dd7545fcf2 TilemapVX: Clean up the horrible map viewport calculation code
Also rename "offset" to "origin" which makes a lot more sense
for ox/oy attributes.
2015-07-21 12:13:24 +02:00
Jonas Kulla 5aaeb0206c Remove some stuff that was accidentally committed 2015-07-21 12:13:24 +02:00
Jonas Kulla 9a3dd2d554 Config: Enable smoothScaling by default
There's really no reason not to.
2015-07-21 12:13:24 +02:00
Jonas Kulla 384249c31a Unify float literals to use f suffix and avoid double promotions
I might have missed some.
2015-07-21 12:13:24 +02:00
Jonas Kulla d1ee507ec4 Vec2i, IntRect: Add unequal operator 2015-07-21 12:13:24 +02:00
Jonas Kulla 21247b18b5 Merge pull request #127 from cremno/add-sprite-bush_opacity
MRI: add Sprite#{bush_opacity,bush_opacity=} bindings
2015-07-21 12:12:24 +02:00
cremno 861d261af2 add Sprite#{bush_opacity,bush_opacity=} 2015-07-21 07:27:53 +02:00
Jonas Kulla fe6799d00b TilemapVX: Fix map viewport calculation 2015-07-10 04:58:28 +02:00
Jonas Kulla fe709b6010 Use vector math 2015-07-10 04:51:29 +02:00
Jonas Kulla 54c1107f19 FileSystem: Fix file lookup if unrelated files with same name exist
Before, even though we did match all possible extensions,
we only took the first match and tried opening it.
If we were looking for a .png image, but there was an unrelated
.txt file with the same name (as it actually happens in RTPs),
we would potentially see the .txt first, try opening it,
and fail alltogether, even though the image file existed.

Now we try opening all matching files until we find one that
we can parse.

This fixes #101.
2015-07-09 15:38:50 +02:00
Jonas Kulla 533e69275a Constify 2015-07-09 14:53:59 +02:00
Jonas Kulla e4558c9dfb Use FS::openReadRaw() where ext supplementing makes no sense
Specifically, in places where the full filename is always supplied,
eg. when reading .rxdata type files.
2015-07-09 12:58:01 +02:00
Jonas Kulla 5382cc11a3 MidiSource: Close source SDL_RWops before throwing error 2015-07-09 12:38:04 +02:00
Jonas Kulla 1e9e24e45c README: Add note about RGSS version support 2015-07-09 12:33:55 +02:00
Jonas Kulla 9acdd206f6 Vec4: Rename 'xyzHasEffect()' to something that makes sense 2015-07-07 16:07:04 +02:00
Jonas Kulla 6e176a454c Constify 2015-07-07 16:06:45 +02:00
Jonas Kulla afab51279e Graphics: Fix viewport color/flash effectiveness calculation
Fixes #121.
2015-07-07 16:06:11 +02:00
Jonas Kulla 61849a9158 GLMeta: Eliminate redundant parameter 2015-07-07 15:25:48 +02:00
Jonas Kulla 2d31d08fa6 Add some general fixes from #111 found by @chosenofbear 2015-06-18 07:21:55 +02:00
Jonas Kulla e778dc17c5 Relocate SDL_sound patches into forked repo 2015-06-18 07:11:38 +02:00
Jonas Kulla 6380a93cec Graphics: Fix ::transition() "filename" default value
The default value is an empty string, which triggers the simple
transition. Passing null is not legal (and wasn't possible in
mkxp from Ruby side anyway).

Fixes #108.
2015-06-10 13:30:26 +02:00
Jonas Kulla 064b7ac80d README: Add link to dependency kit 2015-06-03 16:01:29 +02:00
Jonas Kulla d5bacf50f5 TileAtlasVX: Fix table extents being covered by below tiles
Fixes the appearance of tables in VX, which place table
tiles on the same layer as ground tiles.
2015-05-31 20:58:05 +02:00
Jonas Kulla e4bc08e972 Fix for old, broken OpenAL-Soft headers
See 4219b91bbb
2015-05-26 01:40:53 +02:00
Jonas Kulla 88eca58268 Revert "check Ruby strings for embedded null bytes"
This reverts commit 29dfda0011.
It turned out to be a bad idea after all.
2015-05-11 23:13:02 +02:00
Jonas Kulla e72bced0f7 'snprintf()' guarantees null termination of buffer
Thanks @cremno.
2015-03-27 08:21:47 +01:00
Jonas Kulla 794e86d0ab AudioStream: Prevent MeWatch from restarting fully faded out stream 2015-03-22 09:06:29 +01:00
Jonas Kulla 7260c467b8 AudioStream: Clarify thread-safe usage of stream flags 2015-03-22 08:42:43 +01:00
Jonas Kulla 8d7166f3d2 MRI: Fix Font.name returning nil
I wish I had tests..
2015-03-16 08:36:29 +01:00
Jonas Kulla 5379511d95 Bitmap: Fix vertical alignment for some letters with outline 2015-03-04 23:34:56 +01:00
Jonas Kulla 91c9bfd0f4 Fix compilation failure inside OSX ifdef block 2015-02-26 19:44:05 +01:00
Jonas Kulla 7393f7e951 Config: Add "execName" to specify ini and rgssad filenames 2015-02-19 02:23:23 +01:00
Jonas Kulla 531441d4e3 Make audio asset decoding failures non-fatal
Matches RMXP behavior. This is also useful in case midi files
are to be played, but fluidsynth isn't available.
2015-02-17 02:09:55 +01:00
Jonas Kulla 0f91bdefea Fix indentation 2015-02-17 01:48:05 +01:00
Jonas Kulla 44eaaf5985 FileSystem: Change file lookup to match all extensions
Previously, file lookup (ie. extension supplementing) would only
try out a few predetermined extensions based on the asset type.
This was not accurate in regard to RMXP's behavior, which will
happily match "some_asset" against "some_asset.abcef" and try
to open it.

Some games make use of this quirk and rename their ogg audio files
to "*.dat" or similar to thwart users from copying them.

This change also makes it easier to read arbitrary formats
supported by SDL_image without modifying mkxp.
2015-02-17 01:42:11 +01:00
Jonas Kulla 87462fd7b0 Use more explicit vector math via method overloads 2015-02-10 17:04:00 +01:00
Jonas Kulla a4b1be1da5 Remove superfluous lines 2015-02-10 15:53:58 +01:00
Jonas Kulla c328ebee04 Typo 2015-02-10 15:53:12 +01:00
Jonas Kulla 713ea07558 SDL hints need to be set before initialization 2015-02-10 15:51:33 +01:00
Jonas Kulla b2631d4c23 Bitmap: Fix scaled blit from mega surface to texture
SDL's default blend mode for surfaces (SDL_BLENDMODE_BLEND)
renders the source surface unusable for further use.
2015-02-10 15:34:42 +01:00
Jonas Kulla 4864f63c6c Sprite: Fix visibility calculation
The previous code assumed the scene origin to always be 0,0.
2015-02-04 15:17:45 +01:00
Jonas Kulla e339964076 MidiSource: Fix some channels being mute after looping 2015-01-22 13:13:57 +01:00
Jonas Kulla 64a3ac3769 README: Add soundfont link and mark font outlines as done 2015-01-21 14:58:54 +01:00
Jonas Kulla fa0459ad93 Fix code formatting 2015-01-15 11:09:12 +01:00
Jonas Kulla 74f8c91bf4 Oops 2015-01-15 09:05:51 +01:00
Jonas Kulla 7cbe1eef94 Graphics: Improve transition "vague" parameter accuracy 2015-01-15 08:26:33 +01:00
Jonas Kulla f6604a88b8 sdl-util.h: Consider physical filesystem when opening raw files
This is necessary so games stored on external SD cards can be
run under Android.
2015-01-15 08:11:01 +01:00
Jonas Kulla c92df0ce3a EventThread: Pause OpenAL device when entering background
This requires ALC_SOFT_pause_device to be present. It stops the
alc thread from needlessly consuming CPU resources.
2015-01-15 08:07:22 +01:00
Jonas Kulla 7c6a2b2c62 Pause RGSS execution when moving into background on Android
Assuming that there is enough memory for mkxp to stay in the
background and that the OS doesn't kill the process, this should
allow smooth resuming after moving back into the foreground.

For now, EGL context loss is not handled.
2015-01-15 08:02:21 +01:00
Jonas Kulla 012d87d05a Disable accelerometer joystick emulation on Android 2015-01-15 07:21:07 +01:00
Jonas Kulla f1da585f33 Be explicit about how relative paths are resolved in mkxp.conf 2015-01-15 07:18:02 +01:00
Jonas Kulla a05a3deff6 EventThread: Factor out event discarding code 2015-01-03 20:48:31 +01:00
Jonas Kulla 6f88ddc51c Config: Move default entry values into PO_DESC macro list 2015-01-03 19:28:23 +01:00
Jonas Kulla 7003039e56 EventThread: Track touch state (maximum 4 fingers) 2015-01-03 19:18:52 +01:00
Jonas Kulla 146e0294b4 Add option to fix the framerate to the native screen refresh rate
Useful on mobile devices where using non-standard framerates
looks absolutely horrible and screen refresh rates vary highly.
2015-01-03 18:58:13 +01:00
Jonas Kulla 4fb94aaf10 FileSystem: Add fallback to wrapped SDL_RWops if normal mounting fails
Makes it easy to mount archives on Android residing in "assets/".
2015-01-02 14:50:14 +01:00
Jonas Kulla 3411435138 Factor out some thread communication code (window size, bindings) 2015-01-02 01:41:23 +01:00
Jonas Kulla c63a8947ce Tilemap: Don't emit draw with zero quads
This is illegal on some mobile drivers.
2015-01-02 00:09:53 +01:00
Jonas Kulla b42725ea20 Add config option working around buggy graphics drivers
"subImageFix=true" should fix missing text on radeonsi fglrx
as well as most mobile drivers. Also fixes tileset atlas on
mobile.
2015-01-01 23:38:11 +01:00
Jonas Kulla 9122446b23 EventThread: Discard fake mouse events on mobile 2014-12-31 18:52:21 +01:00
Jonas Kulla 7cbf81c83a Add 'printFPS' config entry to continuously print FPS to console
Useful on platforms that don't have window decorations.
2014-12-31 18:52:21 +01:00
Jonas Kulla b4bca7ea3b GLState: Constify 2014-12-31 18:52:21 +01:00
Jonas Kulla 725af97e7b gl-util.h: Unify function qualifier use 2014-12-31 18:52:21 +01:00
Jonas Kulla 35077793a0 Add std::streambuf wrapper around SDL_RWops for boost
Also add SDL_RWops version of the readFile utility function.
2014-12-31 18:52:21 +01:00
Jonas Kulla 5974d05380 Create OpenAL device in main() and store in RGSSThreadData 2014-12-31 18:52:21 +01:00
Jonas Kulla 3596fc568d main.cpp: Immediately query the actual window size after creation 2014-12-31 18:52:21 +01:00
Jonas Kulla 69795be30b Android uses the Linux shared object naming convention 2014-12-31 18:52:21 +01:00
Jonas Kulla 0a484c8a31 std::string constructor doesn't like null pointers 2014-12-31 18:52:20 +01:00
Jonas Kulla 4560589e25 Audio: Set overall volume of OpenAL output to 0.8 2014-12-31 18:52:20 +01:00
Jonas Kulla 4b08d82ea4 MRI: dataDirectory: Return "." if customDataPath is not defined 2014-12-31 18:52:20 +01:00
Jonas Kulla 88c41bcc62 Debug: Use native logging on Android 2014-12-31 18:52:20 +01:00
Jonas Kulla a112529f53 Use compile time strlen 2014-12-31 18:52:20 +01:00
Jonas Kulla b963c67339 SharedState: Don't reallocate global tex on every bind 2014-12-31 18:52:20 +01:00
Jonas Kulla ee17bb2137 Call glReleaseShaderCompiler on GLES 2014-12-31 18:52:20 +01:00
Jonas Kulla 3fb4108306 gl-fun.h: Add some enums missing in gl2.h 2014-12-31 18:52:20 +01:00
Jonas Kulla fcfa079e7b Perform chdir(gameFolder) early in main() 2014-12-31 18:52:20 +01:00
Jonas Kulla 03a6c657c4 main.cpp: Always display errors in a message box 2014-12-31 18:52:20 +01:00
Jonas Kulla b39964a49a MRI: Make error handling during script load more robust 2014-12-31 18:52:20 +01:00
Jonas Kulla 2f95c0613a Shaders: Prefer arithmetic conditionals to branching 2014-12-31 18:52:20 +01:00
Jonas Kulla 373b90af00 Graphics: Optimize Viewport effect rendering
Using the kitchen sink plane shader for viewport effects, even
if only a small part of them are active, incurs great performance
loss on mobile, so split the rendering into multiple optional
passes which additionally use the blending hardware for faster
mixing (lerping).
Also, don't mirror the PingPong textures if the viewport effect
covers the entire screen area anyway.
2014-12-31 18:52:19 +01:00
Jonas Kulla 3c0a530eba Sprite: Add special case shader for translucent effect
Translucent sprites (opacity < 255) are very common,
so using a custom shader instead of the full blown effect one
helps a lot, especially on mobile.
2014-12-31 18:52:19 +01:00
Jonas Kulla a53163660f Shader: Refine preprocessing on GLES platform
Don't globally set float precision to mediump, only fragment
shaders need that and defining it for vertex shaders causes
tilemap cracks.

Also manually define low precision for variables that hold
color / alpha values.
2014-12-31 18:52:19 +01:00
Jonas Kulla a501e4f22f Add ruby patch for statically linking zlib extension 2014-12-31 18:52:19 +01:00
Jonas Kulla 02f19c03c9 Merge pull request #86 from Daverball/controller-fix
Xbox controllers require JoyHat events to be tracked on windows
2014-12-31 18:50:57 +01:00
David Salvisberg 90e1c09711 Added support for JHat events. 2014-12-31 16:39:28 +01:00
Jonas Kulla d18e3e6a53 Merge pull request #84 from Daverball/hue-shader-fix
hue shader turns pure white pixels black on some GPUs.
2014-12-31 16:12:08 +01:00
David Salvisberg 8240f3333f Fixed hue shader turning pure white pixel to pure black on some GPUs. 2014-12-31 16:02:10 +01:00
Jonas Kulla 150abff1c0 Merge pull request #85 from Daverball/save-button-config
Button config menu should save config to disk whenever changes are accepted.
2014-12-31 14:13:53 +01:00
Jonas Kulla 78e246c11d Merge pull request #83 from Daverball/master
Added rudimentary support for font outlines.
2014-12-31 13:51:44 +01:00
David Salvisberg b1e1d28879 Added rudimentary support for font outlines. 2014-12-31 13:49:18 +01:00
David Salvisberg 6829ddc09f Removed store keybindings from main, since it now already gets stored onAccept. 2014-12-28 06:06:28 +01:00
David Salvisberg 7413c3d994 Make button config menu save changes to disk whenever the changes are accepted. 2014-12-27 14:40:08 +01:00
Jonas Kulla 11cfe887c2 Fix several classes not accepting disposed bitmaps
Fixes an error in Alpha Kimori.
2014-12-22 08:22:45 +01:00
Jonas Kulla 685f8b63b3 Input: Integer button codes are still allowed in RGSS3 2014-12-09 04:21:48 +01:00
Jonas Kulla 6c92101e05 icon.svg: Resize page to drawing for easier rasterization 2014-11-30 21:46:18 +01:00
Jonas Kulla 3faaed89d0 icon.svg: Use 'inkscape -l' to strip inkscape specific tags 2014-11-30 21:09:11 +01:00
Jonas Kulla 98b0b71359 Don't use relative paths when #including xxd output 2014-11-30 17:50:24 +01:00
Jonas Kulla 60f101f2e6 Tilemap(VX): Factor out common code into tilemap-common.h
Renamed flashmap.h to tilemap-common.h as it already contained
shared functions.
2014-11-30 17:46:28 +01:00
Jonas Kulla faef0e8503 README: Add prebuilt windows binaries link 2014-11-30 17:41:34 +01:00
Jonas Kulla f00cb60707 debugwriter.h: Use unbuffered cerr instead of clog 2014-11-29 17:55:18 +01:00
Jonas Kulla c1aab96454 Rename src/debuglogger -> src/gl-debug 2014-11-29 17:51:37 +01:00
Jonas Kulla bc31922c33 Allow inserting GL string markers (GREMEDY_string_marker) 2014-11-29 17:33:39 +01:00
Jonas Kulla 5979c5f778 Add placeholder application icon 2014-11-29 17:30:53 +01:00
Jonas Kulla cfd9345e87 MRuby: Update module_rpg.c to newest bytecode format 2014-11-29 14:55:43 +01:00
Jonas Kulla c2f8b6b749 SettingsMenu: Fix help label sometimes not appearing 2014-11-28 06:04:34 +01:00
Jonas Kulla 276160f0d5 gl-fun.h: Fix compilation with outdated SDL headers 2014-11-22 17:03:16 +01:00
Jonas Kulla f236e34e2d Serializable, Table: Some general cleanups 2014-11-20 14:45:54 +01:00
Jonas Kulla 33c571e691 MRI: Fix mingw build crash when linking with -mwindows 2014-11-20 13:51:35 +01:00
Jonas Kulla 9ac14800da Keybindings: SDL_GetPrefPath result always ends with separator 2014-11-17 07:24:22 +01:00
Jonas Kulla 5c3f4b905a Use fopen with binary mode everywhere (for Windows compat) 2014-11-17 07:18:39 +01:00
Jonas Kulla f7a3e3c5d2 Table: General clean up and code reduction
- Use STL vector instead of doing manual mallocs
- Throw away the resize optimizations; hardly useful
- Marshal.dump data layout is the same as ours (in LE),
  so we can just memcpy everything instead of copying
  one by one

Throwing away part of the very first code I wrote for mkxp
felt very refreshing I must say.
2014-11-02 23:37:35 +01:00
Jonas Kulla a98ad3134b TilemapVX: Implement flash tiles 2014-10-27 15:52:41 +01:00
Jonas Kulla 577f606dac Tilemap: Factor out flash tile code
This will be reused later in TilemapVX.
2014-10-26 20:00:56 +01:00
Jonas Kulla 05b32d76ca Minor cleanup 2014-10-25 23:38:19 +02:00
Jonas Kulla c9d5059238 Pass value object attributes by reference (instead of pointer)
This underlines that no reference inside the setter is taken,
and that these attributes are non-nullable.

Also removes a couple of superfluous attribute macros.
2014-10-25 23:33:41 +02:00
Jonas Kulla 5549ff78f0 Bindings: Viewport: Don't dispose children in RGSS2/3 2014-10-24 18:55:03 +02:00
Jonas Kulla 1a489aafaf Bindings: Fix inconsistency in Viewport dispose (RGSS1)
As noted, on Viewport dispose, RMXP always calls the core
dispose method for child objects regardless of whether
user scripts override it in sub classes.

Implement this behavior in mkxp to prevent infinite recursion.
2014-10-24 18:35:05 +02:00
Jonas Kulla 8b31f97bb4 MRuby: Fix compilation 2014-10-24 18:26:10 +02:00
Jonas Kulla ecf9b065c8 MRI: Revise 'MKXP.data_directory' behavior
This function which was formerly a simple wrapper around
SLD_GetPrefPath() is changed to instead return the directory
assembled from org/app name specified in mkxp.conf, so one
can be sure that both mkxp and user scripts will always write
into the same directory when a custom path is preferred.
2014-10-22 04:16:15 +02:00
Jonas Kulla af8f3a36d2 MRI: Move former 'System' module into 'MKXP' module
This breaks script compatibility.

'System' is way too generic of a name to reserve for mkxp use,
and I have already seen at least one occurance in the wild of
it being used by user scripts.

Ideally, all mkxp RGSS extensions would be moved under this
module, but I feel like the core modules (Input, Graphics etc)
are more safe as users are hesitant to directly extend these.
2014-10-22 04:15:40 +02:00
Jonas Kulla 8e1852a281 Remove left-over dead code 2014-10-21 19:51:08 +02:00
Jonas Kulla 4a8b0f30c8 MRI: Add 'System.raw_key_states' to query full keyboard state
Returns a byte array with all key states (0 = released,
1 = pressed) indexed via SDL_SCANCODE_* enums.
2014-10-20 10:27:01 +02:00
Jonas Kulla e44a1e32fa Reorder some lines 2014-10-20 10:20:08 +02:00
Jonas Kulla 6145c59305 fluid-fun: Don't dlclose libfluidsynth, ever
Some versions of the library do nasty things with thread
local storage without cleaning up after themselves.
2014-10-20 10:17:48 +02:00
Jonas Kulla 1c1d72b03e README: VX / VX Ace support is no longer experimental 2014-10-18 02:21:19 +02:00
Jonas Kulla e1a45c29e2 README: Add OSX build by Ali and clarify SDL2 patch note 2014-10-18 02:15:00 +02:00
Jonas Kulla 5094f5c7c1 Add minor assert 2014-10-16 09:10:27 +02:00
Jonas Kulla 47851718eb MRI: Handle exceptions raised in preloaded scripts 2014-10-15 06:27:43 +02:00
Jonas Kulla 2cd70b9edd Window: Don't update anything if width*height == 0
Fixes GL errors.
2014-10-15 06:26:46 +02:00
Jonas Kulla 19b1c3d7c2 README: Mention SDL patch needed for F1 menu 2014-10-12 14:54:30 +02:00
Jonas Kulla 64a26b4911 README: Add link to prebuilt binaries 2014-10-12 02:38:28 +02:00
Jonas Kulla dd73db2e9d Introduce F1 menu to reconfigure key bindings at runtime 2014-10-11 20:48:44 +02:00
Jonas Kulla af145c3a01 mkxp.pro: Make MRI version a qmake config option
Example: qmake MRIVERSION=2.2
2014-10-11 15:36:21 +02:00
Jonas Kulla 520162f36a Use safe way to get at a vector's data pointer
&std::vector<C>[0] is not guaranteed to not throw if the
vector is empty. Better safe than sorry.
2014-10-09 19:02:29 +02:00
Jonas Kulla 1b7ed5ed78 Font: Fix default 'shadow' value for RGSS1 2014-10-09 18:53:24 +02:00
Jonas Kulla 0c08fc2d16 gl-fun.h: Fix function type signature 2014-10-06 21:10:19 +02:00
Jonas Kulla 18076c9ae4 Merge branch 'master' of github.com:Ancurio/mkxp
Conflicts:
	src/tileatlasvx.cpp

I fucked up somehow.
2014-10-03 20:21:07 +02:00
Jonas Kulla c1d89e4f8d CMakeLists.txt: Bump default MRI version to 2.1 2014-10-03 20:15:52 +02:00
Jonas Kulla 55a2cf562e TileAtlasVX: Followup fix
Use rectangle intersection to correctly clip source
rectangles with origin != (0,0).
2014-10-03 06:58:54 +02:00
Jonas Kulla df73045d81 TileAtlasVX: Followup fix
Use rectangle intersection to correctly clip source
rectangles with origin != (0,0).
2014-10-03 06:51:39 +02:00
Jonas Kulla db78e55371 TileAtlasVX: Clamp blit src rect to tileset bitmap size 2014-10-02 16:41:53 +02:00
Jonas Kulla 95cda4035e fluid-fun: Fix fluidsynth soname on OSX 2014-10-01 19:19:25 +02:00
Jonas Kulla 7b65977eb9 Silence "uninitialized" warnings 2014-10-01 06:29:47 +02:00
Jonas Kulla fa911b8018 gl-fun: Don't rely on SDL_opengl.h for function type definitions 2014-10-01 04:48:23 +02:00
Jonas Kulla 5ea964eee8 CMakeLists.txt: Link against libiconv on OSX 2014-09-30 14:17:33 +02:00
Jonas Kulla 51a0f3903c Audio: Clean up threading and add AudioStream fadein (RGSS3) 2014-09-30 09:13:12 +02:00
Jonas Kulla 46497eae01 CMakeLists.txt: Add missing shader source 2014-09-30 01:34:10 +02:00
Jonas Kulla 3dd703f732 MRI: Use ruby 2.0 compatible function name 2014-09-30 00:48:22 +02:00
Jonas Kulla 4a015c6397 Bitmap: Add font shadow rendering 2014-09-29 10:30:41 +02:00
Jonas Kulla 9e64dff01c Bitmap: Fix mem leak 2014-09-29 10:30:16 +02:00
Jonas Kulla 9758e660c4 Tilemap/VX: Ensure proxy objects don't outlive their parents
Either of these would previously crash (same for VX):

tm = Tilemap.new
at = tm.autotiles
tm = nil
GC.start
at[0] = Bitmap.new(1, 1)

tm = Tilemap.new
at = tm.autotiles
tm.dispose
at[0] = Bitmap.new(1, 1)

Funnily, this makes RMXP itself crash too, but crashing is
never acceptable except for possibly resource exhaustion.
2014-09-26 18:21:50 +02:00
Jonas Kulla e9d0d0566b RGSSError is a subclass of StandardError 2014-09-26 18:20:27 +02:00
Jonas Kulla d223d83cbf Implement F12 game reset (MRI only)
Can be disabled with "enableReset=false".

While at it, also replace the flakey volatile bool flags
with proper atomics.
2014-09-26 06:25:47 +02:00
Jonas Kulla 3a2e560139 Input: Fix default keybinds 2014-09-26 06:25:47 +02:00
Jonas Kulla 2550fd8ccc WindowVX: Initialize all dirty flags and connect tmp tone 2014-09-26 06:24:43 +02:00
Jonas Kulla 81ac0780f8 Revert Disposable concept back into core
Pretty much a revert of
e858bbdcf5.

We need this in core to properly implement F12 reset.
2014-09-23 21:12:58 +02:00
Jonas Kulla 3983fe66e9 Config: Print parsing errors instead of ignoring them 2014-09-23 19:23:11 +02:00
Jonas Kulla 17efcbbbbd tl;dr: I fucking suck at coding (fix double free)
MRI: Filesystem: A garbage collected SDL_RWops file handle
will call close on itself even if 'close' was explicitly
called on it on the script side before.
2014-09-23 17:26:30 +02:00
Jonas Kulla 8d67b7c91d MRI: Init default font names to correct value (RGSS2) 2014-09-23 12:05:28 +02:00
Jonas Kulla 5c3c73ee94 README: Remove erroneous line about cmake 2014-09-15 09:42:09 +02:00
Jonas Kulla 3a29385df0 MRI: load_data: Catch exceptions and pass onto ruby 2014-09-13 07:26:42 +02:00
Jonas Kulla 05041fdb03 Couple fixes to last SDL_sound patch 2014-09-13 07:26:42 +02:00
Jonas Kulla 61b77c2027 Merge pull request #69 from cremno/check-ruby-string-for-embedded-null-bytes
MRI: check Ruby strings for embedded null bytes
2014-09-12 23:30:07 +02:00
Jonas Kulla f49cd4391a Merge pull request #68 from cremno/vxtilemap-has-9-bitmaps
VX tilemap has 9 bitmaps
2014-09-12 23:13:08 +02:00
cremno 6abc207f1e VX tilemap has 9 bitmaps 2014-09-12 15:21:20 +02:00
cremno 29dfda0011 check Ruby strings for embedded null bytes
The RGSS doesn't do it. But doing it shouldn't be a problem, as it's the
correct way. If a game is broken by this commit (unlikely), then the game
needs to be fixed as silent truncation is highly unlikely to be wanted.
2014-09-12 15:20:12 +02:00
Jonas Kulla a365a7a754 Spacing 2014-09-12 06:42:18 +02:00
Jonas Kulla 0c318ee0b2 SDL_sound: Add wave IMA ADPCM (4bit) support patch 2014-09-12 06:39:49 +02:00
Jonas Kulla 757a1d5e39 Load fluidsynth entrypoints dynamically (and make them optional)
This removes the static dependency on fluidsynth being present
at buildtime (even headers aren't needed anymore).

Even though midi is a default format for the RPG XP/VX series,
it has fallen more and more out of use, with VX Ace completely
abandoning it from the RTP and making ogg vorbis the de facto
standard. Midi support is kept for legacy reasons, but isn't
encouraged. On top of all this, fluidsynth together with glib
is a heavy dependency that often times won't even be used.
Making it optional at build time is an attempt to unify and
keep build config fragmentation low.

In RGSS3, fluidsynth / midi is not initialized at all by
default, but rather on demand when either a midi track is
played back or Audio.setup_midi is called.
2014-09-09 00:08:32 +02:00
Jonas Kulla 673a25f811 Bitmap: Don't use 'pixman_region_clear'
It's not included in older pixman versions.
2014-09-07 19:11:20 +02:00
Jonas Kulla ac9b98157e TilemapVX: Use SimpleShader for unanimated ground layers
Also remove some useless member variables.
2014-09-06 22:02:00 +02:00
Jonas Kulla 6bc3460294 Core, MRI: Don't expose RGSS3 functionality in 2 2014-09-06 02:01:20 +02:00
Jonas Kulla bca95adc0e MRI: WindowVX dummy contents object is always created
The check was against rgssVer >= 2, but since that's always
true if WindowVX is used, it was pointless.
2014-09-05 22:54:57 +02:00
Jonas Kulla 9461449cc9 MRuby: Fix handling of Etc/Font properties
Port of f8c26fc515.
2014-09-05 22:53:19 +02:00
Jonas Kulla 7f41b9cc45 Config: Correctly setup rgssVer / screen size with customScript 2014-09-05 21:54:16 +02:00
Jonas Kulla 4d54fce8ee Small compilation fix (mruby is still broken though) 2014-09-05 01:59:01 +02:00
Jonas Kulla 0131ed09f0 Bindings: Remove 'wrapNilProperty'
It's completely useless lol.
2014-09-05 01:59:01 +02:00
Jonas Kulla f8c26fc515 Core/MRI: Fix handling of Etc/Font properties
The gist of it is that for Etc and Font props, the assignment
operator (eg. 'sprite.color=') does not take a reference of the
right hand parameter and replaces its previous one with it (this
was the old behavior). Rather, it keeps its internal property
object and copies the parameter object into it by value.
The getter is unchanged; it still returns a reference to the
internal property object.

s = Sprite.new
c = Color.new
s.color = c
p s.color == c # => true
p s.color.object_id == c.object_id # => false (true before)
c = s.color
p s.color.object_id == c.object_id # => true
2014-09-05 01:58:41 +02:00
Jonas Kulla f665d8b41c BoostSet: Add 'remove' and rename BoostHash::erase to remove
This is more consistent with Qt's method naming.
2014-09-05 01:06:08 +02:00
Jonas Kulla 10186e8dcc Input: Fix isRepeated off-by-one error and do small optim. 2014-09-03 02:35:57 +02:00
Jonas Kulla d2d86e7002 Merge pull request #66 from cremno/add-rgss2-3-input.repeat
Input: add RGSS2/3 Input.repeat?
2014-09-02 23:42:14 +02:00
Jonas Kulla 8c1cf27b7c Merge pull request #67 from cremno/add-rgss-3-0-1-etc-classes-equality-comparison
add RGSS 3.0.1 etc classes equality comparison
2014-09-02 20:09:10 +02:00
Jonas Kulla 8975255ecf Merge pull request #65 from cremno/define-case-and-hash-equality-for-etc-classes
define case and hash equality for etc classes
2014-09-02 20:02:47 +02:00
cremno fd4f7c66d1 bump RGSS_VERSION to 3.0.1 2014-09-02 19:53:09 +02:00
cremno 7acbb06fbd add RGSS 3.0.1 etc classes equality comparison
RGSS 3.0.1 finally fixed #==, #===, #eql? for Color, Tone, and Rect.
Now instances of them can be compared to other kinds of objects.
2014-09-02 19:53:05 +02:00
Jonas Kulla 48b1af1e43 Merge pull request #64 from Ancurio/show_exc_fixes
MRI: Fix exception message box script name and display script index
2014-09-02 19:48:10 +02:00
cremno a366862076 define case and hash equality for etc classes
RGSS also defines #=== and #eql? for Color, Tone, and Rect:

  Color.instance_method(:==) == Color.instance_method(:===)   # => true
  Color.instance_method(:==) == Color.instance_method(:eql?)  # => true
2014-09-02 19:18:51 +02:00
cremno 4b08eee81f add RGSS2/3 Input.repeat? 2014-09-02 19:14:05 +02:00
186 changed files with 10310 additions and 5520 deletions

5
.editorconfig Normal file
View File

@ -0,0 +1,5 @@
root=true
[*]
end_of_line = lf
indent_style = tab
indent_size = 4

View File

@ -3,7 +3,7 @@ Project(mkxp)
## Setup options ##
option(MIDI "Enable midi support" ON)
option(SHARED_FLUID "Dynamically link fluidsynth at build time" OFF)
option(WORKDIR_CURRENT "Keep current directory on startup" OFF)
option(FORCE32 "Force 32bit compile on 64bit OS" OFF)
set(BINDING "MRI" CACHE STRING "The Binding Type (MRI, MRUBY, NULL)")
@ -110,6 +110,7 @@ set(MAIN_HEADERS
src/flashable.h
src/font.h
src/input.h
src/iniconfig.h
src/plane.h
src/scene.h
src/sprite.h
@ -124,8 +125,9 @@ set(MAIN_HEADERS
src/glstate.h
src/quad.h
src/tilemap.h
src/tilemap-common.h
src/graphics.h
src/debuglogger.h
src/gl-debug.h
src/global-ibo.h
src/exception.h
src/filesystem.h
@ -135,6 +137,8 @@ set(MAIN_HEADERS
src/gl-util.h
src/util.h
src/config.h
src/settingsmenu.h
src/keybindings.h
src/tileatlas.h
src/sharedstate.h
src/al-util.h
@ -151,6 +155,9 @@ set(MAIN_HEADERS
src/windowvx.h
src/tilemapvx.h
src/tileatlasvx.h
src/sharedmidistate.h
src/fluid-fun.h
src/sdl-util.h
)
set(MAIN_SOURCE
@ -161,6 +168,7 @@ set(MAIN_SOURCE
src/filesystem.cpp
src/font.cpp
src/input.cpp
src/iniconfig.cpp
src/plane.cpp
src/scene.cpp
src/sprite.cpp
@ -174,9 +182,11 @@ set(MAIN_SOURCE
src/tilemap.cpp
src/autotiles.cpp
src/graphics.cpp
src/debuglogger.cpp
src/gl-debug.cpp
src/etc.cpp
src/config.cpp
src/settingsmenu.cpp
src/keybindings.cpp
src/tileatlas.cpp
src/sharedstate.cpp
src/gl-fun.cpp
@ -193,32 +203,46 @@ set(MAIN_SOURCE
src/tilemapvx.cpp
src/tileatlasvx.cpp
src/autotilesvx.cpp
src/midisource.cpp
src/fluid-fun.cpp
)
if(WIN32)
list(APPEND MAIN_HEADERS windows/resource.h)
list(APPEND MAIN_SOURCE windows/resource.rc)
endif()
source_group("MKXP Source" FILES ${MAIN_SOURCE} ${MAIN_HEADERS})
## Setup embedded source ##
set(EMBEDDED_INPUT
shader/common.h
shader/transSimple.frag
shader/trans.frag
shader/hue.frag
shader/sprite.frag
shader/plane.frag
shader/gray.frag
shader/bitmapBlit.frag
shader/flatColor.frag
shader/simple.frag
shader/simpleColor.frag
shader/simpleAlpha.frag
shader/simpleAlphaUni.frag
shader/flashMap.frag
shader/minimal.vert
shader/simple.vert
shader/simpleColor.vert
shader/sprite.vert
shader/tilemap.vert
shader/tilemapvx.vert
shader/blur.frag
shader/blurH.vert
shader/blurV.vert
shader/simpleMatrix.vert
assets/liberation.ttf
assets/icon.png
)
if (RGSS2)
@ -227,16 +251,10 @@ if (RGSS2)
)
endif()
if (MIDI)
pkg_check_modules(MIDI REQUIRED fluidsynth)
if (SHARED_FLUID)
pkg_check_modules(FLUID REQUIRED fluidsynth)
list(APPEND DEFINES
MIDI
)
list(APPEND MAIN_HEADERS
src/sharedmidistate.h
)
list(APPEND MAIN_SOURCE
src/midisource.cpp
SHARED_FLUID
)
endif()
@ -276,7 +294,7 @@ source_group("Embedded Source" FILES ${EMBEDDED_INPUT} ${EMBEDDED_SOURCE})
## Setup binding source ##
if (BINDING STREQUAL "MRI")
set(MRIVERSION "2.0" CACHE STRING "Version of MRI to link with")
set(MRIVERSION "2.1" CACHE STRING "Version of MRI to link with")
pkg_check_modules(MRI REQUIRED ruby-${MRIVERSION})
list(APPEND DEFINES
BINDING_MRI
@ -368,6 +386,7 @@ if(APPLE)
list(APPEND PLATFORM_LIBRARIES
${CARBON_LIBRARY}
${IOKIT_LIBRARY}
"-liconv"
)
endif()
@ -393,14 +412,16 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE
)
target_include_directories(${PROJECT_NAME} PRIVATE
src
windows
${SIGCXX_INCLUDE_DIRS}
${PIXMAN_INCLUDE_DIRS}
${PHYSFS_INCLUDE_DIRS}
${SDL2_INCLUDE_DIRS} # Blindly assume other SDL bits are in same directory
${SDL_SOUND_INCLUDE_DIRS}
${Boost_INCLUDE_DIR}
${MRI_INCLUDE_DIRS}
${VORBISFILE_INCLUDE_DIRS}
${MIDI_INCLUDE_DIRS}
${FLUID_INCLUDE_DIRS}
${OPENAL_INCLUDE_DIR}
)
@ -415,7 +436,7 @@ target_link_libraries(${PROJECT_NAME}
${Boost_LIBRARIES}
${MRI_LIBRARIES}
${VORBISFILE_LIBRARIES}
${MIDI_LIBRARIES}
${FLUID_LIBRARIES}
${OPENAL_LIBRARY}
${ZLIB_LIBRARY}

View File

@ -1,26 +1,19 @@
# mkxp
mkxp is a project that seeks to provide a fully open source implementation of the Ruby Game Scripting System (RGSS) interface used in the popular game creation software "RPG Maker XP" (trademark by Enterbrain, Inc.), with focus on Linux. The goal is to be able to run games created with the above software natively without changing a single file. Experimental support for RPG Maker VX / VX Ace games is present.
Discord community: https://discord.gg/A8xHE8P
Matrix space: https://matrix.to/#/#rpgmaker:mapleshrine.eu
Further links: https://mapleshrine.eu
mkxp is a project that seeks to provide a fully open source implementation of the Ruby Game Scripting System (RGSS) interface used in the popular game creation software "RPG Maker XP", "RPG Maker VX" and "RPG Maker VX Ace" (trademark by Enterbrain, Inc.), with focus on Linux. The goal is to be able to run games created with the above software natively without changing a single file.
It is licensed under the GNU General Public License v2+.
## RGSS2 / RGSS3
Support for these RGSS versions is experimental. A lot is implemented (to the point that you can play the VX Ace sample game, with caveats), but not everything is in place yet. Note that there is no cmake support for building these at the moment.
## Prebuilt binaries
[**Linux / Windows**](https://www.mapleshrine.eu/releases/)
[**OSX**](https://app.box.com/mkxpmacbuilds) by Ali
Missing RGSS2 functionality:
* Text shadow
Missing RGSS3 functionality:
* Text outline
* Movie playback
* F12 reset
* Audio fade-in
Some other things might be implemented, but simply not bound yet.
RGSS2 might work a little bit less than 3 because I don't have a VX license and as such am unable to experiment thoroughly on it.
## Should I use mkxp
mkxp primarily targets technically versed users that are comfortable with Ruby / RGSS, and ideally know how to compile the project themselves. The reason for this is that for most games, due to Win32-API usage, mkxp is simply not a plug-and-play solution, but a building block with which a fully cross-platform version can be created in time.
## Bindings
Bindings provide the glue code for an interpreted language environment to run game scripts in. Currently there are three bindings:
@ -33,6 +26,8 @@ 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
This binding supports RGSS1, RGSS2 and RGSS3.
### mruby (Lightweight Ruby)
Website: https://github.com/mruby/mruby
@ -42,6 +37,8 @@ Due to heavy differences between mruby and MRI as well as lacking modules, runni
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.
This binding only supports RGSS1.
**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.
### null
@ -54,31 +51,32 @@ This binding only exists for testing purposes and does nothing (the engine quits
* libsigc++ 2.0
* PhysFS (latest hg)
* OpenAL
* SDL2
* SDL2*
* SDL2_image
* SDL2_ttf
* SDL_sound (latest hg, apply provided patches!)
* [my SDL_sound fork](https://github.com/Ancurio/SDL_sound)
* vorbisfile
* pixman
* fluidsynth (if midi enabled)
* zlib (only ruby bindings)
* OpenGL header (alternatively GLES2 with `DEFINES+=GLES2_HEADER`)
* libiconv (on Windows, optional with INI_ENCODING)
* libguess (optional with INI_ENCODING)
(* For the F1 menu to work correctly under Linux/X11, you need latest hg + [this patch](https://bugzilla.libsdl.org/show_bug.cgi?id=2745))
mkxp employs Qt's qmake build system, so you'll need to install that beforehand. Alternatively, you can build with cmake (FIXME: add cmake instructions).
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. You can specify a library suffix (eg. "-mt") via `BOOST_LIB_SUFFIX` if needed.
Midi support is enabled by default; you can disable it via `qmake CONFIG+=DISABLE_MIDI`, in which case the fluidsynth dependency is dropped. When building fluidsynth yourself, you can disable almost all options (audio drivers etc.) as they are not used. Note that upstream fluidsynth has support for sharing soundfont data between synthesizers (mkxp uses multiple synths), so if your memory usage is very high, you might want to try compiling fluidsynth from git master.
Midi support is enabled by default and requires fluidsynth to be present at runtime (not needed for building); if mkxp can't find it at runtime, midi playback is disabled. It looks for `libfluidsynth.so.1` on Linux, `libfluidsynth.dylib.1` on OSX and `fluidsynth.dll` on Windows, so make sure to have one of these in your link path. If you still need fluidsynth to be hard linked at buildtime, use `CONFIG+=SHARED_FLUID`. When building fluidsynth yourself, you can disable almost all options (audio drivers etc.) as they are not used. Note that upstream fluidsynth has support for sharing soundfont data between synthesizers (mkxp uses multiple synths), so if your memory usage is very high, you might want to try compiling fluidsynth from git master.
By default, mkxp switches into the directory where its binary is contained and then starts reading the configuration and resolving relative paths. In case this is undesired (eg. when the binary is to be installed to a system global, read-only location), it can be turned off by adding `DEFINES+=WORKDIR_CURRENT` to qmake's arguments.
To auto detect the encoding of the game title in `Game.ini` and auto convert it to UTF-8, build with `CONFIG+=INI_ENCODING`. Requires iconv implementation and libguess. If the encoding is wrongly detected, you can set the "titleLanguage" hint in mkxp.conf.
**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=MRI` to be explicit).
**MRI-Binding**: pkg-config will look for `ruby-2.1.pc`, but you can override the version with `MRIVERSION=2.2` ('2.2' being an example). This is the default binding, so no arguments to qmake needed (`BINDING=MRI` to be explicit).
**MRuby-Binding**: place the "mruby" folder into the project folder and build it first. Add `BINDING=MRUBY` to qmake's arguments.
@ -89,6 +87,10 @@ These depend on the SDL auxiliary libraries. For maximum RGSS compliance, build
To run mkxp, you should have a graphics card capable of at least **OpenGL (ES) 2.0** with an up-to-date driver installed.
## Dependency kit
To facilitate hacking, I have assembled a package containing all dependencies to compile mkxp on a bare-bones Ubuntu 12.04 64bit installation. Compatibility with other distributions has not been tested. You can download it [here](https://mapleshrine.eu/depkits/linux64.tar.xz). Read the "README" for instructions.
## Configuration
mkxp reads configuration data from the file "mkxp.conf". The format is ini-style. Do *not* use quotes around file paths (spaces won't break). Lines starting with '#' are comments. See 'mkxp.conf.sample' for a list of accepted entries.
@ -99,13 +101,11 @@ The syntax is: `--<option>=<value>`
Example: `./mkxp --gameFolder="my game" --vsync=true --fixedFramerate=60`
## Midi music (*ALPHA STATUS*)
## Midi music
mkxp doesn't come with a soundfont by default, so you will have to supply it yourself (set its path in the config). Playback has been tested and should work reasonably well with all RTP assets.
Known issues with midi playback:
* Some songs' instruments become mute after looping
You can use this public domain soundfont: [GMGSx.sf2](https://mapleshrine.eu/unsorted/GMGSx.sf2)
## Fonts
@ -115,9 +115,9 @@ If a requested font is not found, no error is generated. Instead, a built-in fon
## What doesn't work (yet)
* Movie playback
* wma audio files
* The Win32API ruby class (for obvious reasons)
* Restarting the game with F12
* Creating Bitmaps with sizes greater than the OpenGL texture size limit (around 8192 on modern cards)*
\* There is an exception to this, called *mega surface*. When a Bitmap bigger than the texture limit is created from a file, it is not stored in VRAM, but regular RAM. Its sole purpose is to be used as a tileset bitmap. Any other operation to it (besides blitting to a regular Bitmap) will result in an error.

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

50
assets/icon.svg Normal file
View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="100"
height="100"
id="svg2">
<defs
id="defs4">
<linearGradient
id="linearGradient3821">
<stop
id="stop3823"
style="stop-color:#00ff88;stop-opacity:1"
offset="0" />
<stop
id="stop3825"
style="stop-color:#00ff86;stop-opacity:1"
offset="1" />
</linearGradient>
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-323.76562,-436.67187)"
id="layer1">
<path
d="m 373.76195,439.49229 c -26.05643,0 -47.17591,21.12683 -47.17591,47.18326 0,26.05643 21.11948,47.17591 47.17591,47.17591 26.05643,0 47.18326,-21.11948 47.18326,-47.17591 0,-26.05643 -21.12683,-47.18326 -47.18326,-47.18326 z m 0,26.80867 c 11.25095,0 20.37459,9.12364 20.37459,20.37459 0,11.25094 -9.12364,20.36724 -20.37459,20.36724 -11.25094,0 -20.36724,-9.1163 -20.36724,-20.36724 0,-11.25095 9.1163,-20.37459 20.36724,-20.37459 z"
inkscape:connector-curvature="0"
id="path2985"
style="fill:#00ff87;fill-opacity:1;stroke:#000000;stroke-width:5.64083672;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -97,6 +97,24 @@ DEF_FADE( me )
DEF_PLAY_STOP( se )
RB_METHOD(audioSetupMidi)
{
RB_UNUSED_PARAM;
shState->audio().setupMidi();
return Qnil;
}
RB_METHOD(audioReset)
{
RB_UNUSED_PARAM;
shState->audio().reset();
return Qnil;
}
#define BIND_PLAY_STOP(entity) \
_rb_define_module_function(module, #entity "_play", audio_##entity##Play); \
@ -126,7 +144,11 @@ audioBindingInit()
{
BIND_POS( bgm );
BIND_POS( bgs );
_rb_define_module_function(module, "setup_midi", audioSetupMidi);
}
BIND_PLAY_STOP( se )
_rb_define_module_function(module, "__reset__", audioReset);
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -25,8 +25,10 @@
#include "eventthread.h"
#include "filesystem.h"
#include "util.h"
#include "sdl-util.h"
#include "debugwriter.h"
#include "graphics.h"
#include "audio.h"
#include "boost-hash.h"
#include <ruby.h>
@ -44,11 +46,13 @@ extern const char module_rpg3[];
static void mriBindingExecute();
static void mriBindingTerminate();
static void mriBindingReset();
ScriptBinding scriptBindingImpl =
{
mriBindingExecute,
mriBindingTerminate
mriBindingTerminate,
mriBindingReset
};
ScriptBinding *scriptBinding = &scriptBindingImpl;
@ -73,8 +77,10 @@ void fileIntBindingInit();
RB_METHOD(mriPrint);
RB_METHOD(mriP);
RB_METHOD(mriDataDirectory);
RB_METHOD(mkxpDataDirectory);
RB_METHOD(mkxpPuts);
RB_METHOD(mkxpRawKeyStates);
RB_METHOD(mkxpMouseInWindow);
RB_METHOD(mriRgssMain);
RB_METHOD(mriRgssStop);
@ -115,7 +121,7 @@ static void mriBindingInit()
_rb_define_module_function(rb_mKernel, "msgbox", mriPrint);
_rb_define_module_function(rb_mKernel, "msgbox_p", mriP);
rb_define_global_const("RGSS_VERSION", rb_str_new_cstr("3.0.0"));
rb_define_global_const("RGSS_VERSION", rb_str_new_cstr("3.0.1"));
}
else
{
@ -135,11 +141,22 @@ static void mriBindingInit()
else
assert(!"unreachable");
VALUE mod = rb_define_module("System");
_rb_define_module_function(mod, "data_directory", mriDataDirectory);
VALUE mod = rb_define_module("MKXP");
_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);
/* 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
@ -148,18 +165,6 @@ showMsg(const std::string &msg)
shState->eThread().showMessageBox(msg.c_str());
}
RB_METHOD(mkxpPuts)
{
RB_UNUSED_PARAM;
const char *str;
rb_get_args(argc, argv, "z", &str RB_ARG_END);
Debug() << str;
return Qnil;
}
static void printP(int argc, VALUE *argv,
const char *convMethod, const char *sep)
{
@ -196,29 +201,90 @@ RB_METHOD(mriP)
return Qnil;
}
RB_METHOD(mriDataDirectory)
RB_METHOD(mkxpDataDirectory)
{
RB_UNUSED_PARAM;
const std::string &path = shState->config().customDataPath;
const char *s = path.empty() ? "." : path.c_str();
return rb_str_new_cstr(s);
}
RB_METHOD(mkxpPuts)
{
RB_UNUSED_PARAM;
const char *org, *app;
const char *str;
rb_get_args(argc, argv, "z", &str RB_ARG_END);
rb_get_args(argc, argv, "zz", &org, &app RB_ARG_END);
Debug() << str;
char *path = SDL_GetPrefPath(org, app);
return Qnil;
}
VALUE pathStr = rb_str_new_cstr(path);
RB_METHOD(mkxpRawKeyStates)
{
RB_UNUSED_PARAM;
SDL_free(path);
VALUE str = rb_str_new(0, sizeof(EventThread::keyStates));
memcpy(RSTRING_PTR(str), EventThread::keyStates, sizeof(EventThread::keyStates));
return pathStr;
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);
return Qnil;
}
static VALUE rgssMainRescue(VALUE arg, VALUE exc)
{
VALUE *excRet = (VALUE*) arg;
*excRet = exc;
return Qnil;
}
static void processReset()
{
shState->graphics().reset();
shState->audio().reset();
shState->rtData().rqReset.clear();
shState->graphics().repaintWait(shState->rtData().rqResetFinish,
false);
}
RB_METHOD(mriRgssMain)
{
RB_UNUSED_PARAM;
// TODO: Implement F12 reset
rb_yield(Qnil);
while (true)
{
VALUE exc = Qnil;
rb_rescue2((VALUE(*)(ANYARGS)) rgssMainCb, rb_block_proc(),
(VALUE(*)(ANYARGS)) rgssMainRescue, (VALUE) &exc,
rb_eException, (VALUE) 0);
if (NIL_P(exc))
break;
if (rb_obj_class(exc) == getRbData()->exc[Reset])
processReset();
else
rb_exc_raise(exc);
}
return Qnil;
}
@ -292,7 +358,7 @@ static void runCustomScript(const std::string &filename)
{
std::string scriptData;
if (!readFile(filename.c_str(), scriptData))
if (!readFileSDL(filename.c_str(), scriptData))
{
showMsg(std::string("Unable to open '") + filename + "'");
return;
@ -302,7 +368,7 @@ static void runCustomScript(const std::string &filename)
newStringUTF8(filename.c_str(), filename.size()), NULL);
}
VALUE kernelLoadDataInt(const char *filename);
VALUE kernelLoadDataInt(const char *filename, bool rubyExc);
struct BacktraceData
{
@ -329,7 +395,19 @@ static void runRMXPScripts(BacktraceData &btData)
return;
}
VALUE scriptArray = kernelLoadDataInt(scriptPack.c_str());
VALUE scriptArray;
/* We checked if Scripts.rxdata exists, but something might
* still go wrong */
try
{
scriptArray = kernelLoadDataInt(scriptPack.c_str(), false);
}
catch (const Exception &e)
{
showMsg(std::string("Failed to read script data: ") + e.msg);
return;
}
if (!RB_TYPE_P(scriptArray, RUBY_T_ARRAY))
{
@ -392,33 +470,47 @@ 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);
for (long i = 0; i < scriptCount; ++i)
VALUE exc = rb_gv_get("$!");
if (exc != Qnil)
return;
while (true)
{
VALUE script = rb_ary_entry(scriptArray, i);
VALUE scriptDecoded = rb_ary_entry(script, 3);
VALUE string = newStringUTF8(RSTRING_PTR(scriptDecoded),
RSTRING_LEN(scriptDecoded));
for (long i = 0; i < scriptCount; ++i)
{
VALUE script = rb_ary_entry(scriptArray, i);
VALUE scriptDecoded = rb_ary_entry(script, 3);
VALUE string = newStringUTF8(RSTRING_PTR(scriptDecoded),
RSTRING_LEN(scriptDecoded));
VALUE fname;
const char *scriptName = RSTRING_PTR(rb_ary_entry(script, 1));
char buf[512];
int len;
VALUE fname;
const char *scriptName = RSTRING_PTR(rb_ary_entry(script, 1));
char buf[512];
int len;
if (conf.useScriptNames)
len = snprintf(buf, sizeof(buf), "%03ld:%s", i, scriptName);
else
len = snprintf(buf, sizeof(buf), SCRIPT_SECTION_FMT, i);
if (conf.useScriptNames)
len = snprintf(buf, sizeof(buf), "%03ld:%s", i, scriptName);
else
len = snprintf(buf, sizeof(buf), SCRIPT_SECTION_FMT, i);
fname = newStringUTF8(buf, len);
btData.scriptNames.insert(buf, scriptName);
fname = newStringUTF8(buf, len);
btData.scriptNames.insert(buf, scriptName);
int state;
evalString(string, fname, &state);
if (state)
int state;
evalString(string, fname, &state);
if (state)
break;
}
VALUE exc = rb_gv_get("$!");
if (rb_obj_class(exc) != getRbData()->exc[Reset])
break;
processReset();
}
}
@ -483,6 +575,13 @@ static void showExc(VALUE exc, const BacktraceData &btData)
static void mriBindingExecute()
{
/* Normally only a ruby executable would do a sysinit,
* but not doing it will lead to crashes due to closed
* stdio streams on some platforms (eg. Windows) */
int argc = 0;
char **argv = 0;
ruby_sysinit(&argc, &argv);
ruby_setup();
rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding()));
@ -520,10 +619,15 @@ static void mriBindingExecute()
ruby_cleanup(0);
shState->rtData().rqTermAck = true;
shState->rtData().rqTermAck.set();
}
static void mriBindingTerminate()
{
rb_raise(rb_eSystemExit, " ");
}
static void mriBindingReset()
{
rb_raise(getRbData()->exc[Reset], " ");
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -41,7 +41,6 @@ struct
} static customExc[] =
{
{ MKXP, "MKXPError" },
{ RGSS, "RGSSError" },
{ PHYSFS, "PHYSFSError" },
{ SDL, "SDLError" }
};
@ -51,6 +50,9 @@ RbData::RbData()
for (size_t i = 0; i < ARRAY_SIZE(customExc); ++i)
exc[customExc[i].id] = rb_define_class(customExc[i].name, rb_eException);
exc[RGSS] = rb_define_class("RGSSError", rb_eStandardError);
exc[Reset] = rb_define_class(rgssVer >= 3 ? "RGSSReset" : "Reset", rb_eException);
exc[ErrnoENOENT] = rb_const_get(rb_const_get(rb_cObject, rb_intern("Errno")), rb_intern("ENOENT"));
exc[IOError] = rb_eIOError;
exc[TypeError] = rb_eTypeError;

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -29,6 +29,7 @@
enum RbException
{
RGSS = 0,
Reset,
PHYSFS,
SDL,
MKXP,
@ -66,7 +67,7 @@ raiseRbExc(const Exception &exc);
/* 2.1 has added a new field (flags) to rb_data_type_t */
#include <ruby/version.h>
#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
@ -89,7 +90,12 @@ raiseRbExc(const Exception &exc);
template<rb_data_type_t *rbType>
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<class C>
@ -101,22 +107,12 @@ static void freeInstance(void *inst)
void
raiseDisposedAccess(VALUE self);
inline void
checkDisposed(VALUE self)
{
if (!RTYPEDDATA_DATA(self))
raiseDisposedAccess(self);
}
template<class C>
inline C *
getPrivateData(VALUE self)
{
C *c = static_cast<C*>(RTYPEDDATA_DATA(self));
if (!c)
raiseDisposedAccess(self);
return c;
}
@ -124,8 +120,6 @@ template<class C>
static inline C *
getPrivateDataCheck(VALUE self, const rb_data_type_t &type)
{
/* We don't check for disposed here because any disposable
* property is always also nullable */
void *obj = Check_TypedStruct(self, &type);
return static_cast<C*>(obj);
}
@ -160,12 +154,6 @@ wrapProperty(VALUE self, void *prop, const char *iv,
return propObj;
}
inline void
wrapNilProperty(VALUE self, const char *iv)
{
rb_iv_set(self, iv, Qnil);
}
/* Implemented: oSszfibn| */
int
rb_get_args(int argc, VALUE *argv, const char *format, ...);
@ -316,30 +304,11 @@ rb_check_argc(int actual, int expected)
return self; \
}
#define DEF_PROP_OBJ(Klass, PropKlass, PropName, prop_iv) \
RB_METHOD(Klass##Get##PropName) \
{ \
RB_UNUSED_PARAM; \
checkDisposed(self); \
return rb_iv_get(self, prop_iv); \
} \
RB_METHOD(Klass##Set##PropName) \
{ \
rb_check_argc(argc, 1); \
Klass *k = getPrivateData<Klass>(self); \
VALUE propObj = *argv; \
PropKlass *prop; \
prop = getPrivateDataCheck<PropKlass>(propObj, PropKlass##Type); \
GUARD_EXC( k->set##PropName(prop); ) \
rb_iv_set(self, prop_iv, propObj); \
return propObj; \
}
/* Object property with allowed NIL
/* Object property which is copied by reference, with allowed NIL
* FIXME: Getter assumes prop is disposable,
* because self.disposed? is not checked in this case.
* Should make this more clear */
#define DEF_PROP_OBJ_NIL(Klass, PropKlass, PropName, prop_iv) \
#define DEF_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv) \
RB_METHOD(Klass##Get##PropName) \
{ \
RB_UNUSED_PARAM; \
@ -361,12 +330,33 @@ rb_check_argc(int actual, int expected)
return propObj; \
}
/* Object property which is copied by value, not reference */
#define DEF_PROP_OBJ_VAL(Klass, PropKlass, PropName, prop_iv) \
RB_METHOD(Klass##Get##PropName) \
{ \
RB_UNUSED_PARAM; \
checkDisposed<Klass>(self); \
return rb_iv_get(self, prop_iv); \
} \
RB_METHOD(Klass##Set##PropName) \
{ \
rb_check_argc(argc, 1); \
Klass *k = getPrivateData<Klass>(self); \
VALUE propObj = *argv; \
PropKlass *prop; \
prop = getPrivateDataCheck<PropKlass>(propObj, PropKlass##Type); \
GUARD_EXC( k->set##PropName(*prop); ) \
return propObj; \
}
#define DEF_PROP(Klass, type, PropName, arg_fun, value_fun) \
RB_METHOD(Klass##Get##PropName) \
{ \
RB_UNUSED_PARAM; \
Klass *k = getPrivateData<Klass>(self); \
return value_fun(k->get##PropName()); \
type value = 0; \
GUARD_EXC( value = k->get##PropName(); ) \
return value_fun(value); \
} \
RB_METHOD(Klass##Set##PropName) \
{ \

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -43,7 +43,7 @@ void bitmapInitProps(Bitmap *b, VALUE self)
rb_obj_call_init(fontObj, 0, 0);
Font *font = getPrivateData<Font>(fontObj);
b->setFont(font);
b->setInitFont(font);
rb_iv_set(self, "font", fontObj);
}
@ -128,7 +128,7 @@ RB_METHOD(bitmapBlt)
src = getPrivateDataCheck<Bitmap>(srcObj, BitmapType);
srcRect = getPrivateDataCheck<Rect>(srcRectObj, RectType);
GUARD_EXC( b->blt(x, y, src, srcRect->toIntRect(), opacity); );
GUARD_EXC( b->blt(x, y, *src, srcRect->toIntRect(), opacity); );
return self;
}
@ -151,7 +151,7 @@ RB_METHOD(bitmapStretchBlt)
destRect = getPrivateDataCheck<Rect>(destRectObj, RectType);
srcRect = getPrivateDataCheck<Rect>(srcRectObj, RectType);
GUARD_EXC( b->stretchBlt(destRect->toIntRect(), src, srcRect->toIntRect(), opacity); );
GUARD_EXC( b->stretchBlt(destRect->toIntRect(), *src, srcRect->toIntRect(), opacity); );
return self;
}
@ -323,7 +323,7 @@ RB_METHOD(bitmapTextSize)
return wrapObject(rect, RectType);
}
DEF_PROP_OBJ(Bitmap, Font, Font, "font")
DEF_PROP_OBJ_VAL(Bitmap, Font, Font, "font")
RB_METHOD(bitmapGradientFillRect)
{
@ -413,12 +413,25 @@ RB_METHOD(bitmapRadialBlur)
return Qnil;
}
// FIXME: This isn't entire correct as the cloned bitmap
// does not get a cloned version of the original bitmap's 'font'
// attribute (the internal font attrb is the default one, whereas
// the stored iv visible to ruby would still be the same as the original)
// Not sure if this needs fixing though
INITCOPY_FUN(Bitmap)
RB_METHOD(bitmapInitializeCopy)
{
rb_check_argc(argc, 1);
VALUE origObj = argv[0];
if (!OBJ_INIT_COPY(self, origObj))
return self;
Bitmap *orig = getPrivateData<Bitmap>(origObj);
Bitmap *b = 0;
GUARD_EXC( b = new Bitmap(*orig); );
bitmapInitProps(b, self);
b->setFont(orig->getFont());
setPrivateData(self, b);
return self;
}
void
@ -430,7 +443,7 @@ bitmapBindingInit()
disposableBindingInit<Bitmap>(klass);
_rb_define_method(klass, "initialize", bitmapInitialize);
_rb_define_method(klass, "initialize_copy", BitmapInitializeCopy);
_rb_define_method(klass, "initialize_copy", bitmapInitializeCopy);
_rb_define_method(klass, "width", bitmapWidth);
_rb_define_method(klass, "height", bitmapHeight);

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -27,8 +27,7 @@
/* 'Children' are disposables that are disposed together
* with their parent. Currently this is only used by Viewport
* in RGSS1.
* FIXME: Disable this behavior when RGSS2 or 3 */
* in RGSS1. */
inline void
disposableAddChild(VALUE disp, VALUE child)
{
@ -52,9 +51,8 @@ disposableDisposeChildren(VALUE disp)
if (NIL_P(children))
return;
ID dispFun = rb_intern("dispose");
ID dispFun = rb_intern("_mkxp_dispose_alias");
/* Note: RMXP doesn't call overridden 'dispose' methods here */
for (long i = 0; i < RARRAY_LEN(children); ++i)
rb_funcall2(rb_ary_entry(children, i), dispFun, 0, 0);
}
@ -64,32 +62,54 @@ RB_METHOD(disposableDispose)
{
RB_UNUSED_PARAM;
C *c = static_cast<C*>(RTYPEDDATA_DATA(self));
C *d = getPrivateData<C>(self);
/* Nothing to do if already disposed */
if (!c)
if (!d)
return Qnil;
disposableDisposeChildren(self);
/* Nothing to do if already disposed */
if (d->isDisposed())
return Qnil;
delete c;
setPrivateData(self, 0);
if (rgssVer == 1)
disposableDisposeChildren(self);
d->dispose();
return Qnil;
}
template<class C>
RB_METHOD(disposableIsDisposed)
{
RB_UNUSED_PARAM;
return rb_bool_new(RTYPEDDATA_DATA(self) == 0);
C *d = getPrivateData<C>(self);
if (!d)
return Qtrue;
return rb_bool_new(d->isDisposed());
}
template<class C>
static void disposableBindingInit(VALUE klass)
{
_rb_define_method(klass, "dispose", disposableDispose<C>);
_rb_define_method(klass, "disposed?", disposableIsDisposed);
_rb_define_method(klass, "disposed?", disposableIsDisposed<C>);
/* Make sure we always have access to the original method, even
* if it is overridden by user scripts */
if (rgssVer == 1)
rb_define_alias(klass, "_mkxp_dispose_alias", "dispose");
}
template<class C>
inline void
checkDisposed(VALUE self)
{
if (disposableIsDisposed<C>(0, 0, self) == Qtrue)
raiseDisposedAccess(self);
}
#endif // DISPOSABLEBINDING_H

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -22,6 +22,7 @@
#include "etc.h"
#include "binding-util.h"
#include "serializable-binding.h"
#include "sharedstate.h"
DEF_TYPE(Color);
DEF_TYPE(Tone);
@ -68,6 +69,9 @@ ATTR_INT_RW(Rect, Height)
VALUE otherObj; \
Klass *other; \
rb_get_args(argc, argv, "o", &otherObj RB_ARG_END); \
if (rgssVer >= 3) \
if (!rb_typeddata_is_kind_of(otherObj, &Klass##Type)) \
return Qfalse; \
other = getPrivateDataCheck<Klass>(otherObj, Klass##Type); \
return rb_bool_new(*p == *other); \
}
@ -106,7 +110,7 @@ INIT_FUN(Rect, int, "iiii", 0)
{ \
VALUE otherObj = argv[0]; \
Klass *other = getPrivateDataCheck<Klass>(otherObj, Klass##Type); \
k->set(*other); \
*k = *other; \
} \
else \
{ \
@ -177,6 +181,8 @@ INITCOPY_FUN(Rect)
_rb_define_method(klass, "initialize_copy", Klass##InitializeCopy); \
_rb_define_method(klass, "set", Klass##Set); \
_rb_define_method(klass, "==", Klass##Equal); \
_rb_define_method(klass, "===", Klass##Equal); \
_rb_define_method(klass, "eql?", Klass##Equal); \
_rb_define_method(klass, "to_s", Klass##Stringify); \
_rb_define_method(klass, "inspect", Klass##Stringify); \
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -40,10 +40,23 @@ fileIntFreeInstance(void *inst)
DEF_TYPE_CUSTOMFREE(FileInt, fileIntFreeInstance);
static VALUE
fileIntForPath(const char *path)
fileIntForPath(const char *path, bool rubyExc)
{
SDL_RWops *ops = SDL_AllocRW();
shState->fileSystem().openRead(*ops, path);
try
{
shState->fileSystem().openReadRaw(*ops, path);
}
catch (const Exception &e)
{
SDL_FreeRW(ops);
if (rubyExc)
raiseRbExc(e);
else
throw e;
}
VALUE klass = rb_const_get(rb_cObject, rb_intern("FileInt"));
@ -110,11 +123,11 @@ RB_METHOD(fileIntBinmode)
}
VALUE
kernelLoadDataInt(const char *filename)
kernelLoadDataInt(const char *filename, bool rubyExc)
{
rb_gc_start();
VALUE port = fileIntForPath(filename);
VALUE port = fileIntForPath(filename, rubyExc);
VALUE marsh = rb_const_get(rb_cObject, rb_intern("Marshal"));
@ -133,7 +146,7 @@ RB_METHOD(kernelLoadData)
const char *filename;
rb_get_args(argc, argv, "z", &filename RB_ARG_END);
return kernelLoadDataInt(filename);
return kernelLoadDataInt(filename, true);
}
RB_METHOD(kernelSaveData)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -27,6 +27,29 @@
#include <string.h>
static void
collectStrings(VALUE obj, std::vector<std::string> &out)
{
if (RB_TYPE_P(obj, RUBY_T_STRING))
{
out.push_back(RSTRING_PTR(obj));
}
else if (RB_TYPE_P(obj, RUBY_T_ARRAY))
{
for (long i = 0; i < RARRAY_LEN(obj); ++i)
{
VALUE str = rb_ary_entry(obj, i);
/* Non-string objects are tolerated (ignored) */
if (!RB_TYPE_P(str, RUBY_T_STRING))
continue;
out.push_back(RSTRING_PTR(str));
}
}
}
DEF_TYPE(Font);
RB_METHOD(fontDoesExist)
@ -48,31 +71,40 @@ RB_METHOD(FontSetName);
RB_METHOD(fontInitialize)
{
VALUE name = Qnil;
VALUE namesObj = Qnil;
int size = 0;
rb_get_args(argc, argv, "|oi", &name, &size RB_ARG_END);
rb_get_args(argc, argv, "|oi", &namesObj, &size RB_ARG_END);
Font *f = new Font(0, size);
Font *f;
if (NIL_P(namesObj))
{
namesObj = rb_iv_get(rb_obj_class(self), "default_name");
f = new Font(0, size);
}
else
{
std::vector<std::string> names;
collectStrings(namesObj, names);
f = new Font(&names, size);
}
/* This is semantically wrong; the new Font object should take
* a dup'ed object here in case of an array. Ditto for the setters.
* However the same bug/behavior exists in all RM versions. */
rb_iv_set(self, "name", namesObj);
setPrivateData(self, f);
/* Wrap property objects */
f->setColor(new Color(*f->getColor()));
wrapProperty(self, f->getColor(), "color", ColorType);
f->initDynAttribs();
wrapProperty(self, &f->getColor(), "color", ColorType);
if (rgssVer >= 3)
{
f->setOutColor(new Color(*f->getOutColor()));
wrapProperty(self, f->getOutColor(), "out_color", ColorType);
}
if (NIL_P(name))
name = rb_iv_get(rb_obj_class(self), "default_name");
/* Going over the 'name=' function automatically causes
* a possbile name array to be re-verified for existing fonts */
FontSetName(1, &name, self);
wrapProperty(self, &f->getOutColor(), "out_color", ColorType);
return self;
}
@ -90,14 +122,12 @@ RB_METHOD(fontInitializeCopy)
setPrivateData(self, f);
/* Wrap property objects */
f->setColor(new Color(*f->getColor()));
wrapProperty(self, f->getColor(), "color", ColorType);
f->initDynAttribs();
wrapProperty(self, &f->getColor(), "color", ColorType);
if (rgssVer >= 3)
{
f->setOutColor(new Color(*f->getOutColor()));
wrapProperty(self, f->getOutColor(), "out_color", ColorType);
}
wrapProperty(self, &f->getOutColor(), "out_color", ColorType);
return self;
}
@ -109,68 +139,33 @@ RB_METHOD(FontGetName)
return rb_iv_get(self, "name");
}
static void
fontSetNameHelper(VALUE self, int argc, VALUE *argv,
const char *nameIv, char *outBuf, size_t outLen)
{
rb_check_argc(argc, 1);
VALUE arg = argv[0];
// Fixme: in RGSS3, specifying "" (and only that) as font name results in
// no text being drawn (everything else is substituted with Arial I think)
strncpy(outBuf, "", outLen);
if (RB_TYPE_P(arg, RUBY_T_STRING))
{
strncpy(outBuf, RSTRING_PTR(arg), outLen);
}
else if (RB_TYPE_P(arg, RUBY_T_ARRAY))
{
for (long i = 0; i < RARRAY_LEN(arg); ++i)
{
VALUE str = rb_ary_entry(arg, i);
/* Non-string objects are tolerated (ignored) */
if (!RB_TYPE_P(str, RUBY_T_STRING))
continue;
const char *family = RSTRING_PTR(str);
/* We only set the core Font object's name attribute
* to the actually existing font name */
if (!shState->fontState().fontPresent(family))
continue;
strncpy(outBuf, family, outLen);
}
}
/* RMXP doesn't even care if the argument type is
* something other than string/array. Whatever... */
rb_iv_set(self, nameIv, arg);
}
RB_METHOD(FontSetName)
{
Font *f = getPrivateData<Font>(self);
char result[256];
fontSetNameHelper(self, argc, argv, "default_name",
result, sizeof(result));
rb_check_argc(argc, 1);
f->setName(result);
std::vector<std::string> namesObj;
collectStrings(argv[0], namesObj);
f->setName(namesObj);
rb_iv_set(self, "name", argv[0]);
return argv[0];
}
template<class C>
static void checkDisposed(VALUE) {}
DEF_PROP_OBJ_VAL(Font, Color, Color, "color")
DEF_PROP_OBJ_VAL(Font, Color, OutColor, "out_color")
DEF_PROP_I(Font, Size)
DEF_PROP_B(Font, Bold)
DEF_PROP_B(Font, Italic)
DEF_PROP_B(Font, Shadow)
DEF_PROP_B(Font, Outline)
DEF_PROP_OBJ(Font, Color, Color, "color")
DEF_PROP_OBJ(Font, Color, OutColor, "out_color")
#define DEF_KLASS_PROP(Klass, type, PropName, param_t_s, value_fun) \
RB_METHOD(Klass##Get##PropName) \
@ -187,10 +182,10 @@ DEF_PROP_OBJ(Font, Color, OutColor, "out_color")
return value_fun(value); \
}
DEF_KLASS_PROP(Font, int, DefaultSize, "i", rb_fix_new)
DEF_KLASS_PROP(Font, bool, DefaultBold, "b", rb_bool_new)
DEF_KLASS_PROP(Font, bool, DefaultItalic, "b", rb_bool_new)
DEF_KLASS_PROP(Font, bool, DefaultShadow, "b", rb_bool_new)
DEF_KLASS_PROP(Font, int, DefaultSize, "i", rb_fix_new)
DEF_KLASS_PROP(Font, bool, DefaultBold, "b", rb_bool_new)
DEF_KLASS_PROP(Font, bool, DefaultItalic, "b", rb_bool_new)
DEF_KLASS_PROP(Font, bool, DefaultShadow, "b", rb_bool_new)
DEF_KLASS_PROP(Font, bool, DefaultOutline, "b", rb_bool_new)
RB_METHOD(FontGetDefaultOutColor)
@ -201,13 +196,14 @@ RB_METHOD(FontGetDefaultOutColor)
RB_METHOD(FontSetDefaultOutColor)
{
RB_UNUSED_PARAM;
VALUE colorObj;
rb_get_args(argc, argv, "o", &colorObj RB_ARG_END);
Color *c = getPrivateDataCheck<Color>(colorObj, ColorType);
Font::setDefaultOutColor(c);
rb_iv_set(self, "default_out_color", colorObj);
Font::setDefaultOutColor(*c);
return colorObj;
}
@ -221,11 +217,15 @@ RB_METHOD(FontGetDefaultName)
RB_METHOD(FontSetDefaultName)
{
char result[256];
fontSetNameHelper(self, argc, argv, "default_name",
result, sizeof(result));
RB_UNUSED_PARAM;
Font::setDefaultName(result);
rb_check_argc(argc, 1);
std::vector<std::string> namesObj;
collectStrings(argv[0], namesObj);
Font::setDefaultName(namesObj, shState->fontState());
rb_iv_set(self, "default_name", argv[0]);
return argv[0];
}
@ -239,13 +239,14 @@ RB_METHOD(FontGetDefaultColor)
RB_METHOD(FontSetDefaultColor)
{
RB_UNUSED_PARAM;
VALUE colorObj;
rb_get_args(argc, argv, "o", &colorObj RB_ARG_END);
Color *c = getPrivateDataCheck<Color>(colorObj, ColorType);
Font::setDefaultColor(c);
rb_iv_set(self, "default_color", colorObj);
Font::setDefaultColor(*c);
return colorObj;
}
@ -262,9 +263,29 @@ fontBindingInit()
VALUE klass = rb_define_class("Font", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&FontType>);
Font::setDefaultColor(new Color(*Font::getDefaultColor()));
wrapProperty(klass, Font::getDefaultColor(), "default_color", ColorType);
rb_iv_set(klass, "default_name", rb_str_new_cstr(Font::getDefaultName()));
Font::initDefaultDynAttribs();
wrapProperty(klass, &Font::getDefaultColor(), "default_color", ColorType);
/* Initialize default names */
const std::vector<std::string> &defNames = Font::getInitialDefaultNames();
VALUE defNamesObj;
if (defNames.size() == 1)
{
defNamesObj = rb_str_new_cstr(defNames[0].c_str());
}
else
{
defNamesObj = rb_ary_new2(defNames.size());
for (size_t i = 0; i < defNames.size(); ++i)
rb_ary_push(defNamesObj, rb_str_new_cstr(defNames[i].c_str()));
}
rb_iv_set(klass, "default_name", defNamesObj);
if (rgssVer >= 3)
wrapProperty(klass, &Font::getDefaultOutColor(), "default_out_color", ColorType);
INIT_KLASS_PROP_BIND(Font, DefaultName, "default_name");
INIT_KLASS_PROP_BIND(Font, DefaultSize, "default_size");

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -48,7 +48,7 @@ RB_METHOD(graphicsTransition)
RB_UNUSED_PARAM;
int duration = 8;
const char *filename = 0;
const char *filename = "";
int vague = 40;
rb_get_args(argc, argv, "|izi", &duration, &filename, &vague RB_ARG_END);
@ -174,6 +174,27 @@ RB_METHOD(graphicsResizeScreen)
return Qnil;
}
RB_METHOD(graphicsReset)
{
RB_UNUSED_PARAM;
shState->graphics().reset();
return Qnil;
}
RB_METHOD(graphicsPlayMovie)
{
RB_UNUSED_PARAM;
const char *filename;
rb_get_args(argc, argv, "z", &filename RB_ARG_END);
shState->graphics().playMovie(filename);
return Qnil;
}
DEF_GRA_PROP_I(FrameRate)
DEF_GRA_PROP_I(FrameCount)
DEF_GRA_PROP_I(Brightness)
@ -196,6 +217,8 @@ void graphicsBindingInit()
_rb_define_module_function(module, "transition", graphicsTransition);
_rb_define_module_function(module, "frame_reset", graphicsFrameReset);
_rb_define_module_function(module, "__reset__", graphicsReset);
INIT_GRA_PROP_BIND( FrameRate, "frame_rate" );
INIT_GRA_PROP_BIND( FrameCount, "frame_count" );
@ -212,6 +235,11 @@ void graphicsBindingInit()
INIT_GRA_PROP_BIND( Brightness, "brightness" );
}
if (rgssVer >= 3)
{
_rb_define_module_function(module, "play_movie", graphicsPlayMovie);
}
INIT_GRA_PROP_BIND( Fullscreen, "fullscreen" );
INIT_GRA_PROP_BIND( ShowCursor, "show_cursor" );
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -38,17 +38,22 @@ static int getButtonArg(int argc, VALUE *argv)
{
int num;
if (rgssVer >= 3)
{
ID sym;
rb_get_args(argc, argv, "n", &sym RB_ARG_END);
rb_check_argc(argc, 1);
if (FIXNUM_P(argv[0]))
{
num = FIX2INT(argv[0]);
}
else if (SYMBOL_P(argv[0]) && rgssVer >= 3)
{
VALUE symHash = getRbData()->buttoncodeHash;
num = FIX2INT(rb_hash_lookup2(symHash, ID2SYM(sym), INT2FIX(Input::None)));
num = FIX2INT(rb_hash_lookup2(symHash, argv[0], INT2FIX(Input::None)));
}
else
{
rb_get_args(argc, argv, "i", &num RB_ARG_END);
// FIXME: RMXP allows only few more types that
// don't make sense (symbols in pre 3, floats)
num = 0;
}
return num;

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -33,19 +33,17 @@ RB_METHOD(planeInitialize)
setPrivateData(self, p);
p->setColor(new Color);
p->setTone(new Tone);
p->initDynAttribs();
wrapNilProperty(self, "bitmap");
wrapProperty(self, p->getColor(), "color", ColorType);
wrapProperty(self, p->getTone(), "tone", ToneType);
wrapProperty(self, &p->getColor(), "color", ColorType);
wrapProperty(self, &p->getTone(), "tone", ToneType);
return self;
}
DEF_PROP_OBJ_NIL(Plane, Bitmap, Bitmap, "bitmap")
DEF_PROP_OBJ(Plane, Color, Color, "color")
DEF_PROP_OBJ(Plane, Tone, Tone, "tone")
DEF_PROP_OBJ_REF(Plane, Bitmap, Bitmap, "bitmap")
DEF_PROP_OBJ_VAL(Plane, Color, Color, "color")
DEF_PROP_OBJ_VAL(Plane, Tone, Tone, "tone")
DEF_PROP_I(Plane, OX)
DEF_PROP_I(Plane, OY)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -37,28 +37,26 @@ RB_METHOD(spriteInitialize)
setPrivateData(self, s);
/* Wrap property objects */
s->setSrcRect(new Rect);
s->setColor(new Color);
s->setTone(new Tone);
s->initDynAttribs();
wrapNilProperty(self, "bitmap");
wrapProperty(self, s->getSrcRect(), "src_rect", RectType);
wrapProperty(self, s->getColor(), "color", ColorType);
wrapProperty(self, s->getTone(), "tone", ToneType);
wrapProperty(self, &s->getSrcRect(), "src_rect", RectType);
wrapProperty(self, &s->getColor(), "color", ColorType);
wrapProperty(self, &s->getTone(), "tone", ToneType);
return self;
}
DEF_PROP_OBJ_NIL(Sprite, Bitmap, Bitmap, "bitmap")
DEF_PROP_OBJ(Sprite, Rect, SrcRect, "src_rect")
DEF_PROP_OBJ(Sprite, Color, Color, "color")
DEF_PROP_OBJ(Sprite, Tone, Tone, "tone")
DEF_PROP_OBJ_REF(Sprite, Bitmap, Bitmap, "bitmap")
DEF_PROP_OBJ_VAL(Sprite, Rect, SrcRect, "src_rect")
DEF_PROP_OBJ_VAL(Sprite, Color, Color, "color")
DEF_PROP_OBJ_VAL(Sprite, Tone, Tone, "tone")
DEF_PROP_I(Sprite, X)
DEF_PROP_I(Sprite, Y)
DEF_PROP_I(Sprite, OX)
DEF_PROP_I(Sprite, OY)
DEF_PROP_I(Sprite, BushDepth)
DEF_PROP_I(Sprite, BushOpacity)
DEF_PROP_I(Sprite, Opacity)
DEF_PROP_I(Sprite, BlendType)
DEF_PROP_I(Sprite, WaveAmp)
@ -129,6 +127,8 @@ spriteBindingInit()
_rb_define_method(klass, "width", spriteWidth);
_rb_define_method(klass, "height", spriteHeight);
INIT_PROP_BIND( Sprite, BushOpacity, "bush_opacity" );
INIT_PROP_BIND( Sprite, WaveAmp, "wave_amp" );
INIT_PROP_BIND( Sprite, WaveLength, "wave_length" );
INIT_PROP_BIND( Sprite, WaveSpeed, "wave_speed" );

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -94,6 +94,10 @@ RB_METHOD(tilemapInitialize)
rb_iv_set(autotilesObj, "array", ary);
/* Circular reference so both objects are always
* alive at the same time */
rb_iv_set(autotilesObj, "tilemap", self);
return self;
}
@ -101,6 +105,8 @@ RB_METHOD(tilemapGetAutotiles)
{
RB_UNUSED_PARAM;
checkDisposed<Tilemap>(self);
return rb_iv_get(self, "autotiles");
}
@ -119,15 +125,15 @@ RB_METHOD(tilemapGetViewport)
{
RB_UNUSED_PARAM;
checkDisposed(self);
checkDisposed<Tilemap>(self);
return rb_iv_get(self, "viewport");
}
DEF_PROP_OBJ(Tilemap, Bitmap, Tileset, "tileset")
DEF_PROP_OBJ(Tilemap, Table, MapData, "map_data")
DEF_PROP_OBJ(Tilemap, Table, FlashData, "flash_data")
DEF_PROP_OBJ(Tilemap, Table, Priorities, "priorities")
DEF_PROP_OBJ_REF(Tilemap, Bitmap, Tileset, "tileset")
DEF_PROP_OBJ_REF(Tilemap, Table, MapData, "map_data")
DEF_PROP_OBJ_REF(Tilemap, Table, FlashData, "flash_data")
DEF_PROP_OBJ_REF(Tilemap, Table, Priorities, "priorities")
DEF_PROP_B(Tilemap, Visible)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2014 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -58,12 +58,16 @@ RB_METHOD(tilemapVXInitialize)
VALUE autotilesObj = rb_iv_get(self, "bitmap_array");
VALUE ary = rb_ary_new2(7);
for (int i = 0; i < 7; ++i)
VALUE ary = rb_ary_new2(9);
for (int i = 0; i < 9; ++i)
rb_ary_push(ary, Qnil);
rb_iv_set(autotilesObj, "array", ary);
/* Circular reference so both objects are always
* alive at the same time */
rb_iv_set(autotilesObj, "tilemap", self);
return self;
}
@ -71,6 +75,8 @@ RB_METHOD(tilemapVXGetBitmapArray)
{
RB_UNUSED_PARAM;
checkDisposed<TilemapVX>(self);
return rb_iv_get(self, "bitmap_array");
}
@ -85,11 +91,10 @@ RB_METHOD(tilemapVXUpdate)
return Qnil;
}
DEF_PROP_OBJ_NIL(TilemapVX, Viewport, Viewport, "viewport")
DEF_PROP_OBJ(TilemapVX, Table, MapData, "map_data")
DEF_PROP_OBJ(TilemapVX, Table, FlashData, "flash_data")
DEF_PROP_OBJ(TilemapVX, Table, Flags, "flags")
DEF_PROP_OBJ_REF(TilemapVX, Viewport, Viewport, "viewport")
DEF_PROP_OBJ_REF(TilemapVX, Table, MapData, "map_data")
DEF_PROP_OBJ_REF(TilemapVX, Table, FlashData, "flash_data")
DEF_PROP_OBJ_REF(TilemapVX, Table, Flags, "flags")
DEF_PROP_B(TilemapVX, Visible)
@ -120,7 +125,7 @@ RB_METHOD(tilemapVXBitmapsGet)
int i;
rb_get_args (argc, argv, "i", &i RB_ARG_END);
if (i < 0 || i > 6)
if (i < 0 || i > 8)
return Qnil;
VALUE ary = rb_iv_get(self, "array");

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -62,13 +62,11 @@ RB_METHOD(viewportInitialize)
setPrivateData(self, v);
/* Wrap property objects */
v->setRect(new Rect(*v->getRect()));
v->setColor(new Color);
v->setTone(new Tone);
v->initDynAttribs();
wrapProperty(self, v->getRect(), "rect", RectType);
wrapProperty(self, v->getColor(), "color", ColorType);
wrapProperty(self, v->getTone(), "tone", ToneType);
wrapProperty(self, &v->getRect(), "rect", RectType);
wrapProperty(self, &v->getColor(), "color", ColorType);
wrapProperty(self, &v->getTone(), "tone", ToneType);
/* 'elements' holds all SceneElements that become children
* of this viewport, so we can dispose them when the viewport
@ -78,9 +76,9 @@ RB_METHOD(viewportInitialize)
return self;
}
DEF_PROP_OBJ(Viewport, Rect, Rect, "rect")
DEF_PROP_OBJ(Viewport, Color, Color, "color")
DEF_PROP_OBJ(Viewport, Tone, Tone, "tone")
DEF_PROP_OBJ_VAL(Viewport, Rect, Rect, "rect")
DEF_PROP_OBJ_VAL(Viewport, Color, Color, "color")
DEF_PROP_OBJ_VAL(Viewport, Tone, Tone, "tone")
DEF_PROP_I(Viewport, OX)
DEF_PROP_I(Viewport, OY)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -35,7 +35,7 @@ RB_METHOD(viewportElementGetViewport)
{
RB_UNUSED_PARAM;
checkDisposed(self);
checkDisposed<C>(self);
return rb_iv_get(self, "viewport");
}
@ -75,7 +75,9 @@ viewportElementInitialize(int argc, VALUE *argv, VALUE self)
if (!NIL_P(viewportObj))
{
viewport = getPrivateDataCheck<Viewport>(viewportObj, ViewportType);
disposableAddChild(viewportObj, self);
if (rgssVer == 1)
disposableAddChild(viewportObj, self);
}
/* Construct object */

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -32,10 +32,9 @@ RB_METHOD(windowInitialize)
setPrivateData(self, w);
w->setCursorRect(new Rect);
wrapNilProperty(self, "windowskin");
wrapNilProperty(self, "contents");
wrapProperty(self, w->getCursorRect(), "cursor_rect", RectType);
w->initDynAttribs();
wrapProperty(self, &w->getCursorRect(), "cursor_rect", RectType);
return self;
}
@ -51,9 +50,9 @@ RB_METHOD(windowUpdate)
return Qnil;
}
DEF_PROP_OBJ_NIL(Window, Bitmap, Windowskin, "windowskin")
DEF_PROP_OBJ_NIL(Window, Bitmap, Contents, "contents")
DEF_PROP_OBJ(Window, Rect, CursorRect, "cursor_rect")
DEF_PROP_OBJ_REF(Window, Bitmap, Windowskin, "windowskin")
DEF_PROP_OBJ_REF(Window, Bitmap, Contents, "contents")
DEF_PROP_OBJ_VAL(Window, Rect, CursorRect, "cursor_rect")
DEF_PROP_B(Window, Stretch)
DEF_PROP_B(Window, Active)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -51,19 +51,17 @@ RB_METHOD(windowVXInitialize)
setPrivateData(self, w);
w->setCursorRect(new Rect);
w->setTone(new Tone);
wrapNilProperty(self, "windowskin");
wrapProperty(self, w->getTone(), "tone", ToneType);
wrapProperty(self, w->getCursorRect(), "cursor_rect", RectType);
w->initDynAttribs();
if (rgssVer >= 2)
{
Bitmap *contents = new Bitmap(1, 1);
VALUE contentsObj = wrapObject(contents, BitmapType);
bitmapInitProps(contents, contentsObj);
rb_iv_set(self, "contents", contentsObj);
}
wrapProperty(self, &w->getCursorRect(), "cursor_rect", RectType);
if (rgssVer >= 3)
wrapProperty(self, &w->getTone(), "tone", ToneType);
Bitmap *contents = new Bitmap(1, 1);
VALUE contentsObj = wrapObject(contents, BitmapType);
bitmapInitProps(contents, contentsObj);
rb_iv_set(self, "contents", contentsObj);
return self;
}
@ -109,11 +107,11 @@ RB_METHOD(windowVXIsClosed)
return rb_bool_new(w->isClosed());
}
DEF_PROP_OBJ_NIL(WindowVX, Bitmap, Windowskin, "windowskin")
DEF_PROP_OBJ_NIL(WindowVX, Bitmap, Contents, "contents")
DEF_PROP_OBJ_REF(WindowVX, Bitmap, Windowskin, "windowskin")
DEF_PROP_OBJ_REF(WindowVX, Bitmap, Contents, "contents")
DEF_PROP_OBJ(WindowVX, Rect, CursorRect, "cursor_rect")
DEF_PROP_OBJ(WindowVX, Tone, Tone, "tone")
DEF_PROP_OBJ_VAL(WindowVX, Rect, CursorRect, "cursor_rect")
DEF_PROP_OBJ_VAL(WindowVX, Tone, Tone, "tone")
DEF_PROP_I(WindowVX, X)
DEF_PROP_I(WindowVX, Y)
@ -142,17 +140,12 @@ windowVXBindingInit()
viewportElementBindingInit<WindowVX>(klass);
_rb_define_method(klass, "initialize", windowVXInitialize);
_rb_define_method(klass, "update", windowVXUpdate);
_rb_define_method(klass, "move", windowVXMove);
_rb_define_method(klass, "open?", windowVXIsOpen);
_rb_define_method(klass, "close?", windowVXIsClosed);
INIT_PROP_BIND( WindowVX, Windowskin, "windowskin" );
INIT_PROP_BIND( WindowVX, Contents, "contents" );
INIT_PROP_BIND( WindowVX, CursorRect, "cursor_rect" );
INIT_PROP_BIND( WindowVX, Active, "active" );
INIT_PROP_BIND( WindowVX, ArrowsVisible, "arrows_visible" );
INIT_PROP_BIND( WindowVX, Pause, "pause" );
INIT_PROP_BIND( WindowVX, X, "x" );
INIT_PROP_BIND( WindowVX, Y, "y" );
@ -160,11 +153,20 @@ windowVXBindingInit()
INIT_PROP_BIND( WindowVX, Height, "height" );
INIT_PROP_BIND( WindowVX, OX, "ox" );
INIT_PROP_BIND( WindowVX, OY, "oy" );
INIT_PROP_BIND( WindowVX, Padding, "padding" );
INIT_PROP_BIND( WindowVX, PaddingBottom, "padding_bottom" );
INIT_PROP_BIND( WindowVX, Opacity, "opacity" );
INIT_PROP_BIND( WindowVX, BackOpacity, "back_opacity" );
INIT_PROP_BIND( WindowVX, ContentsOpacity, "contents_opacity" );
INIT_PROP_BIND( WindowVX, Openness, "openness" );
if (rgssVer >= 3)
{
_rb_define_method(klass, "move", windowVXMove);
_rb_define_method(klass, "open?", windowVXIsOpen);
_rb_define_method(klass, "close?", windowVXIsClosed);
INIT_PROP_BIND( WindowVX, ArrowsVisible, "arrows_visible" );
INIT_PROP_BIND( WindowVX, Padding, "padding" );
INIT_PROP_BIND( WindowVX, PaddingBottom, "padding_bottom" );
INIT_PROP_BIND( WindowVX, Tone, "tone" );
}
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -51,11 +51,13 @@
static void mrbBindingExecute();
static void mrbBindingTerminate();
static void mrbBindingReset();
ScriptBinding scriptBindingImpl =
{
mrbBindingExecute,
mrbBindingTerminate
mrbBindingTerminate,
mrbBindingReset
};
ScriptBinding *scriptBinding = &scriptBindingImpl;
@ -112,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);
}
@ -190,7 +201,7 @@ static void
runCustomScript(mrb_state *mrb, mrbc_context *ctx, const char *filename)
{
/* Execute custom script */
FILE *f = fopen(filename, "r");
FILE *f = fopen(filename, "rb");
if (!f)
{
@ -215,7 +226,7 @@ static void
runMrbFile(mrb_state *mrb, const char *filename)
{
/* Execute compiled script */
FILE *f = fopen(filename, "r");
FILE *f = fopen(filename, "rb");
if (!f)
{
@ -264,7 +275,7 @@ runRMXPScripts(mrb_state *mrb, mrbc_context *ctx)
mrb_state *scriptMrb = mrb_open();
SDL_RWops ops;
shState->fileSystem().openRead(ops, scriptPack.c_str());
shState->fileSystem().openReadRaw(ops, scriptPack.c_str());
mrb_value scriptArray = mrb_nil_value();
std::string readError;
@ -384,7 +395,7 @@ static void mrbBindingExecute()
checkException(mrb);
shState->rtData().rqTermAck = true;
shState->rtData().rqTermAck.set();
shState->texPool().disable();
mrbc_context_free(mrb, ctx);
@ -398,3 +409,8 @@ static void mrbBindingTerminate()
mrb_raise(mrb, data->exc[Shutdown], "");
}
static void mrbBindingReset()
{
// No idea how to do this with mruby yet
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -37,9 +37,11 @@ struct
SYMD(viewport),
SYMD(bitmap),
SYMD(color),
SYMD(out_color),
SYMD(tone),
SYMD(rect),
SYMD(src_rect),
SYMD(tilemap),
SYMD(tileset),
SYMD(autotiles),
SYMD(map_data),
@ -51,8 +53,9 @@ struct
SYMD(path),
SYMD(array),
SYMD(default_color),
SYMD(default_out_color),
SYMD(children),
SYMD(dispose)
SYMD(_mkxp_dispose_alias)
};
static elementsN(symData);
@ -66,7 +69,6 @@ struct MrbExcData
static const MrbExcData excData[] =
{
{ Shutdown, "SystemExit" },
{ RGSS, "RGSSError" },
{ PHYSFS, "PHYSFSError" },
{ SDL, "SDLError" },
{ MKXP, "MKXPError" },
@ -106,6 +108,8 @@ MrbData::MrbData(mrb_state *mrb)
for (size_t i = 0; i < excDataN; ++i)
exc[excData[i].ind] = mrb_define_class(mrb, excData[i].str, mrb->eException_class);
exc[RGSS] = mrb_define_class(mrb, "RGSSError", mrb->eStandardError_class);
RClass *errnoMod = mrb_define_module(mrb, "Errno");
for (size_t i = 0; i < enoExcDataN; ++i)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -38,9 +38,11 @@ enum CommonSymbol
CSviewport,
CSbitmap,
CScolor,
CSout_color,
CStone,
CSrect,
CSsrc_rect,
CStilemap,
CStileset,
CSautotiles,
CSmap_data,
@ -52,8 +54,9 @@ enum CommonSymbol
CSpath,
CSarray,
CSdefault_color,
CSdefault_out_color,
CSchildren,
CSdispose,
CS_mkxp_dispose_alias,
CommonSymbolsMax
};
@ -149,10 +152,11 @@ defineClass(mrb_state *mrb, const char *name)
#define MRB_FUN_UNUSED_PARAM { (void) mrb; }
#define DEF_PROP_OBJ(Klass, PropKlass, PropName, prop_iv) \
/* Object property which is copied by value, not reference */
#define DEF_PROP_OBJ_VAL(Klass, PropKlass, PropName, prop_iv) \
MRB_METHOD(Klass##Get##PropName) \
{ \
checkDisposed(mrb, self); \
checkDisposed<Klass>(mrb, self); \
return getProperty(mrb, self, prop_iv); \
} \
MRB_METHOD(Klass##Set##PropName) \
@ -162,13 +166,12 @@ defineClass(mrb_state *mrb, const char *name)
PropKlass *prop; \
mrb_get_args(mrb, "o", &propObj); \
prop = getPrivateDataCheck<PropKlass>(mrb, propObj, PropKlass##Type); \
GUARD_EXC( k->set##PropName(prop); ) \
setProperty(mrb, self, prop_iv, propObj); \
GUARD_EXC( k->set##PropName(*prop); ) \
return propObj; \
}
/* Object property with allowed NIL */
#define DEF_PROP_OBJ_NIL(Klass, PropKlass, PropName, prop_iv) \
/* Object property which is copied by reference, with allowed NIL */
#define DEF_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv) \
MRB_METHOD(Klass##Get##PropName) \
{ \
return getProperty(mrb, self, prop_iv); \
@ -192,7 +195,9 @@ defineClass(mrb_state *mrb, const char *name)
MRB_METHOD(Klass##Get##PropName) \
{ \
Klass *k = getPrivateData<Klass>(mrb, self); \
return mrb_##conv_t##_value(k->get##PropName()); \
mrb_type value = 0; \
GUARD_EXC( value = k->get##PropName(); ) \
return mrb_##conv_t##_value(value); \
} \
MRB_METHOD(Klass##Set##PropName) \
{ \
@ -254,21 +259,12 @@ getSym(mrb_state *mrb, CommonSymbol sym)
void
raiseDisposedAccess(mrb_state *mrb, mrb_value self);
inline void checkDisposed(mrb_state *mrb, mrb_value self)
{
if (!DATA_PTR(self))
raiseDisposedAccess(mrb, self);
}
template<class C>
inline C *
getPrivateData(mrb_state *mrb, mrb_value self)
getPrivateData(mrb_state *, mrb_value self)
{
C *c = static_cast<C*>(DATA_PTR(self));
if (!c)
raiseDisposedAccess(mrb, self);
return c;
}
@ -300,7 +296,7 @@ wrapObject(mrb_state *mrb, void *p, const mrb_data_type &type)
return obj;
}
inline void
inline mrb_value
wrapProperty(mrb_state *mrb, mrb_value self,
void *prop, CommonSymbol iv, const mrb_data_type &type)
{
@ -310,15 +306,8 @@ wrapProperty(mrb_state *mrb, mrb_value self,
mrb_obj_ptr(self),
getSym(mrb, iv),
propObj);
}
inline void
wrapNilProperty(mrb_state *mrb, mrb_value self, CommonSymbol iv)
{
mrb_obj_iv_set(mrb,
mrb_obj_ptr(self),
getSym(mrb, iv),
mrb_nil_value());
return propObj;
}
inline mrb_value

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -22,6 +22,7 @@
#include "bitmap.h"
#include "font.h"
#include "exception.h"
#include "sharedstate.h"
#include "disposable-binding.h"
#include "binding-util.h"
#include "binding-types.h"
@ -51,11 +52,15 @@ MRB_METHOD(bitmapInitialize)
/* Wrap properties */
Font *font = new Font();
b->setFont(font);
font->setColor(new Color(*font->getColor()));
b->setInitFont(font);
font->initDynAttribs();
wrapProperty(mrb, self, font, CSfont, FontType);
wrapProperty(mrb, getProperty(mrb, self, CSfont), font->getColor(), CScolor, ColorType);
mrb_value fontProp = wrapProperty(mrb, self, font, CSfont, FontType);
wrapProperty(mrb, fontProp, &font->getColor(), CScolor, ColorType);
if (rgssVer >= 3)
wrapProperty(mrb, fontProp, &font->getOutColor(), CSout_color, ColorType);
return self;
}
@ -109,7 +114,7 @@ MRB_METHOD(bitmapBlt)
src = getPrivateDataCheck<Bitmap>(mrb, srcObj, BitmapType);
srcRect = getPrivateDataCheck<Rect>(mrb, srcRectObj, RectType);
GUARD_EXC( b->blt(x, y, src, srcRect->toIntRect(), opacity); )
GUARD_EXC( b->blt(x, y, *src, srcRect->toIntRect(), opacity); )
return mrb_nil_value();
}
@ -132,7 +137,7 @@ MRB_METHOD(bitmapStretchBlt)
destRect = getPrivateDataCheck<Rect>(mrb, destRectObj, RectType);
srcRect = getPrivateDataCheck<Rect>(mrb, srcRectObj, RectType);
GUARD_EXC( b->stretchBlt(destRect->toIntRect(), src, srcRect->toIntRect(), opacity); )
GUARD_EXC( b->stretchBlt(destRect->toIntRect(), *src, srcRect->toIntRect(), opacity); )
return mrb_nil_value();
}
@ -275,7 +280,7 @@ MRB_METHOD(bitmapTextSize)
MRB_METHOD(bitmapGetFont)
{
checkDisposed(mrb, self);
checkDisposed<Bitmap>(mrb, self);
return getProperty(mrb, self, CSfont);
}
@ -291,8 +296,7 @@ MRB_METHOD(bitmapSetFont)
font = getPrivateDataCheck<Font>(mrb, fontObj, FontType);
GUARD_EXC( b->setFont(font); )
setProperty(mrb, self, CSfont, fontObj);
GUARD_EXC( b->setFont(*font); )
return mrb_nil_value();
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -60,39 +60,58 @@ disposableDisposeChildren(mrb_state *mrb, mrb_value disp)
for (mrb_int i = 0; i < RARRAY_LEN(children); ++i)
mrb_funcall_argv(mrb, mrb_ary_entry(children, i),
mrbData->symbols[CSdispose], 0, 0);
mrbData->symbols[CS_mkxp_dispose_alias], 0, 0);
}
template<class C>
MRB_METHOD(disposableDispose)
{
C *c = static_cast<C*>(DATA_PTR(self));
C *d = static_cast<C*>(DATA_PTR(self));
/* Nothing to do if already disposed */
if (!c)
if (!d)
return mrb_nil_value();
disposableDisposeChildren(mrb, self);
if (d->isDisposed())
return mrb_nil_value();
delete c;
DATA_PTR(self) = 0;
if (rgssVer == 1)
disposableDisposeChildren(mrb, self);
d->dispose();
return mrb_nil_value();
}
template<class C>
MRB_METHOD(disposableDisposed)
MRB_METHOD(disposableIsDisposed)
{
MRB_UNUSED_PARAM;
return mrb_bool_value(DATA_PTR(self) == 0);
C *d = static_cast<C*>(DATA_PTR(self));
if (!d)
return mrb_true_value();
return mrb_bool_value(d->isDisposed());
}
template<class C>
static void disposableBindingInit(mrb_state *mrb, RClass *klass)
{
mrb_define_method(mrb, klass, "dispose", disposableDispose<C>, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "disposed?", disposableDisposed<C>, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "disposed?", disposableIsDisposed<C>, MRB_ARGS_NONE());
if (rgssVer == 1)
mrb_alias_method(mrb, klass, getMrbData(mrb)->symbols[CS_mkxp_dispose_alias],
mrb_intern_lit(mrb, "dispose"));
}
template<class C>
inline void
checkDisposed(mrb_state *mrb, mrb_value self)
{
if (mrb_test(disposableIsDisposed<C>(0, self)))
raiseDisposedAccess(mrb, self);
}
#endif // DISPOSABLEBINDING_H

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -20,6 +20,7 @@
*/
#include "font.h"
#include "sharedstate.h"
#include "binding-util.h"
#include "binding-types.h"
#include "exception.h"
@ -53,8 +54,12 @@ MRB_METHOD(fontInitialize)
setPrivateData(self, f, FontType);
/* Wrap property objects */
f->setColor(new Color(*f->getColor()));
wrapProperty(mrb, self, f->getColor(), CScolor, ColorType);
f->initDynAttribs();
wrapProperty(mrb, self, &f->getColor(), CScolor, ColorType);
if (rgssVer >= 3)
wrapProperty(mrb, self, &f->getOutColor(), CSout_color, ColorType);
return self;
}
@ -69,8 +74,12 @@ MRB_METHOD(fontInitializeCopy)
setPrivateData(self, f, FontType);
/* Wrap property objects */
f->setColor(new Color(*f->getColor()));
wrapProperty(mrb, self, f->getColor(), CScolor, ColorType);
f->initDynAttribs();
wrapProperty(mrb, self, &f->getColor(), CScolor, ColorType);
if (rgssVer >= 3)
wrapProperty(mrb, self, &f->getOutColor(), CSout_color, ColorType);
return self;
}
@ -94,10 +103,16 @@ MRB_METHOD(FontSetName)
return name;
}
template<class C>
static void checkDisposed(mrb_state *, mrb_value) {}
DEF_PROP_I(Font, Size)
DEF_PROP_B(Font, Bold)
DEF_PROP_B(Font, Italic)
DEF_PROP_OBJ(Font, Color, Color, CScolor)
DEF_PROP_B(Font, Outline)
DEF_PROP_B(Font, Shadow)
DEF_PROP_OBJ_VAL(Font, Color, Color, CScolor)
DEF_PROP_OBJ_VAL(Font, Color, OutColor, CSout_color)
#define DEF_KLASS_PROP(Klass, mrb_type, PropName, arg_type, conv_t) \
static mrb_value \
@ -114,9 +129,11 @@ DEF_PROP_OBJ(Font, Color, Color, CScolor)
return mrb_##conv_t##_value(value); \
}
DEF_KLASS_PROP(Font, mrb_int, DefaultSize, "i", fixnum)
DEF_KLASS_PROP(Font, mrb_bool, DefaultBold, "b", bool)
DEF_KLASS_PROP(Font, mrb_bool, DefaultItalic, "b", bool)
DEF_KLASS_PROP(Font, mrb_int, DefaultSize, "i", fixnum)
DEF_KLASS_PROP(Font, mrb_bool, DefaultBold, "b", bool)
DEF_KLASS_PROP(Font, mrb_bool, DefaultItalic, "b", bool)
DEF_KLASS_PROP(Font, mrb_bool, DefaultOutline, "b", bool)
DEF_KLASS_PROP(Font, mrb_bool, DefaultShadow, "b", bool)
MRB_FUNCTION(FontGetDefaultName)
{
@ -140,13 +157,33 @@ MRB_METHOD(FontGetDefaultColor)
MRB_METHOD(FontSetDefaultColor)
{
MRB_UNUSED_PARAM;
mrb_value colorObj;
mrb_get_args(mrb, "o", &colorObj);
Color *c = getPrivateDataCheck<Color>(mrb, colorObj, ColorType);
Font::setDefaultColor(c);
setProperty(mrb, self, CSdefault_color, colorObj);
Font::setDefaultColor(*c);
return colorObj;
}
MRB_METHOD(FontGetDefaultOutColor)
{
return getProperty(mrb, self, CSdefault_out_color);
}
MRB_METHOD(FontSetDefaultOutColor)
{
MRB_UNUSED_PARAM;
mrb_value colorObj;
mrb_get_args(mrb, "o", &colorObj);
Color *c = getPrivateDataCheck<Color>(mrb, colorObj, ColorType);
Font::setDefaultOutColor(*c);
return colorObj;
}
@ -162,25 +199,48 @@ fontBindingInit(mrb_state *mrb)
{
RClass *klass = defineClass(mrb, "Font");
Font::setDefaultColor(new Color(*Font::getDefaultColor()));
wrapProperty(mrb, mrb_obj_value(klass), Font::getDefaultColor(), CSdefault_color, ColorType);
Font::initDefaultDynAttribs();
wrapProperty(mrb, mrb_obj_value(klass), &Font::getDefaultColor(), CSdefault_color, ColorType);
mrb_define_class_method(mrb, klass, "exist?", fontDoesExist, MRB_ARGS_REQ(1));
INIT_KLASS_PROP_BIND(Font, DefaultName, "default_name");
INIT_KLASS_PROP_BIND(Font, DefaultSize, "default_size");
INIT_KLASS_PROP_BIND(Font, DefaultBold, "default_bold");
INIT_KLASS_PROP_BIND(Font, DefaultItalic, "default_italic");
INIT_KLASS_PROP_BIND(Font, DefaultColor, "default_color");
INIT_KLASS_PROP_BIND(Font, DefaultName, "default_name");
INIT_KLASS_PROP_BIND(Font, DefaultSize, "default_size");
INIT_KLASS_PROP_BIND(Font, DefaultBold, "default_bold");
INIT_KLASS_PROP_BIND(Font, DefaultItalic, "default_italic");
INIT_KLASS_PROP_BIND(Font, DefaultColor, "default_color");
if (rgssVer >= 2)
{
INIT_KLASS_PROP_BIND(Font, DefaultShadow, "default_shadow");
}
if (rgssVer >= 3)
{
INIT_KLASS_PROP_BIND(Font, DefaultOutline, "default_outline");
INIT_KLASS_PROP_BIND(Font, DefaultOutColor, "default_out_color");
wrapProperty(mrb, mrb_obj_value(klass), &Font::getDefaultOutColor(), CSdefault_out_color, ColorType);
}
mrb_define_method(mrb, klass, "initialize", fontInitialize, MRB_ARGS_OPT(2));
mrb_define_method(mrb, klass, "initialize_copy", fontInitializeCopy, MRB_ARGS_REQ(1));
INIT_PROP_BIND(Font, Name, "name");
INIT_PROP_BIND(Font, Size, "size");
INIT_PROP_BIND(Font, Bold, "bold");
INIT_PROP_BIND(Font, Italic, "italic");
INIT_PROP_BIND(Font, Color, "color");
INIT_PROP_BIND(Font, Name, "name");
INIT_PROP_BIND(Font, Size, "size");
INIT_PROP_BIND(Font, Bold, "bold");
INIT_PROP_BIND(Font, Italic, "italic");
INIT_PROP_BIND(Font, Color, "color");
if (rgssVer >= 2)
{
INIT_PROP_BIND(Font, Shadow, "shadow");
}
if (rgssVer >= 3)
{
INIT_PROP_BIND(Font, Outline, "outline");
INIT_PROP_BIND(Font, OutColor, "out_color");
}
mrb_define_method(mrb, klass, "inspect", inspectObject, MRB_ARGS_NONE());
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -45,7 +45,7 @@ MRB_FUNCTION(graphicsFreeze)
MRB_FUNCTION(graphicsTransition)
{
mrb_int duration = 8;
const char *filename = 0;
const char *filename = "";
mrb_int vague = 40;
mrb_get_args(mrb, "|izi", &duration, &filename, &vague);

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -40,20 +40,26 @@ MRB_FUNCTION(inputUpdate)
static mrb_int getButtonArg(mrb_state *mrb)
{
mrb_int num;
mrb_value arg;
if (rgssVer >= 3)
mrb_get_args(mrb, "o", &arg);
if (mrb_fixnum_p(arg))
{
num = mrb_fixnum(arg);
}
else if (mrb_symbol_p(arg) && rgssVer >= 3)
{
mrb_sym sym;
mrb_get_args(mrb, "n", &sym);
mrb_value symHash = getMrbData(mrb)->buttoncodeHash;
mrb_value numVal = mrb_hash_fetch(mrb, symHash, mrb_symbol_value(sym),
mrb_value numVal = mrb_hash_fetch(mrb, symHash, arg,
mrb_fixnum_value(Input::None));
num = mrb_fixnum(numVal);
}
else
{
mrb_get_args(mrb, "i", &num);
// FIXME: RMXP allows only few more types that
// don't make sense (symbols in pre 3, floats)
num = 0;
}
return num;

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -20,6 +20,7 @@
*/
#include "rwmem.h"
#include "util.h"
#include <SDL_rwops.h>
@ -101,7 +102,7 @@ int RWMemGetData(SDL_RWops *ops, void *buffer)
ByteVec *v = getRWPrivate(ops);
if (buffer)
memcpy(buffer, &(*v)[0], v->size());
memcpy(buffer, dataPtr(*v), v->size());
return v->size();
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -33,19 +33,17 @@ MRB_METHOD(planeInitialize)
setPrivateData(self, p, PlaneType);
p->setColor(new Color);
p->setTone(new Tone);
p->initDynAttribs();
wrapNilProperty(mrb, self, CSbitmap);
wrapProperty(mrb, self, p->getColor(), CScolor, ColorType);
wrapProperty(mrb, self, p->getTone(), CStone, ToneType);
wrapProperty(mrb, self, &p->getColor(), CScolor, ColorType);
wrapProperty(mrb, self, &p->getTone(), CStone, ToneType);
return self;
}
DEF_PROP_OBJ(Plane, Bitmap, Bitmap, CSbitmap)
DEF_PROP_OBJ(Plane, Color, Color, CScolor)
DEF_PROP_OBJ(Plane, Tone, Tone, CStone)
DEF_PROP_OBJ_REF(Plane, Bitmap, Bitmap, CSbitmap)
DEF_PROP_OBJ_VAL(Plane, Color, Color, CScolor)
DEF_PROP_OBJ_VAL(Plane, Tone, Tone, CStone)
DEF_PROP_I(Plane, OX)
DEF_PROP_I(Plane, OY)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -20,6 +20,7 @@
*/
#include "sprite.h"
#include "sharedstate.h"
#include "disposable-binding.h"
#include "flashable-binding.h"
#include "sceneelement-binding.h"
@ -35,22 +36,19 @@ MRB_METHOD(spriteInitialize)
setPrivateData(self, s, SpriteType);
/* Wrap property objects */
s->setSrcRect(new Rect);
s->setColor(new Color);
s->setTone(new Tone);
s->initDynAttribs();
wrapNilProperty(mrb, self, CSbitmap);
wrapProperty(mrb, self, s->getSrcRect(), CSsrc_rect, RectType);
wrapProperty(mrb, self, s->getColor(), CScolor, ColorType);
wrapProperty(mrb, self, s->getTone(), CStone, ToneType);
wrapProperty(mrb, self, &s->getSrcRect(), CSsrc_rect, RectType);
wrapProperty(mrb, self, &s->getColor(), CScolor, ColorType);
wrapProperty(mrb, self, &s->getTone(), CStone, ToneType);
return self;
}
DEF_PROP_OBJ_NIL(Sprite, Bitmap, Bitmap, CSbitmap)
DEF_PROP_OBJ(Sprite, Rect, SrcRect, CSsrc_rect)
DEF_PROP_OBJ(Sprite, Color, Color, CScolor)
DEF_PROP_OBJ(Sprite, Tone, Tone, CStone)
DEF_PROP_OBJ_REF(Sprite, Bitmap, Bitmap, CSbitmap)
DEF_PROP_OBJ_VAL(Sprite, Rect, SrcRect, CSsrc_rect)
DEF_PROP_OBJ_VAL(Sprite, Color, Color, CScolor)
DEF_PROP_OBJ_VAL(Sprite, Tone, Tone, CStone)
DEF_PROP_I(Sprite, X)
DEF_PROP_I(Sprite, Y)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -93,19 +93,26 @@ MRB_METHOD(tilemapInitialize)
wrapProperty(mrb, self, &t->getAutotiles(), CSautotiles, TilemapAutotilesType);
mrb_value autotilesObj = mrb_iv_get(mrb, self, getMrbData(mrb)->symbols[CSautotiles]);
MrbData &mrbData = *getMrbData(mrb);
mrb_value autotilesObj = mrb_iv_get(mrb, self, mrbData.symbols[CSautotiles]);
mrb_value ary = mrb_ary_new_capa(mrb, 7);
for (int i = 0; i < 7; ++i)
mrb_ary_push(mrb, ary, mrb_nil_value());
mrb_iv_set(mrb, autotilesObj, getMrbData(mrb)->symbols[CSarray], ary);
mrb_iv_set(mrb, autotilesObj, mrbData.symbols[CSarray], ary);
/* Circular reference so both objects are always
* alive at the same time */
mrb_iv_set(mrb, autotilesObj, mrbData.symbols[CStilemap], self);
return self;
}
MRB_METHOD(tilemapGetAutotiles)
{
checkDisposed<Tilemap>(mrb, self);
return getProperty(mrb, self, CSautotiles);
}
@ -120,15 +127,15 @@ MRB_METHOD(tilemapUpdate)
MRB_METHOD(tilemapGetViewport)
{
checkDisposed(mrb, self);
checkDisposed<Tilemap>(mrb, self);
return getProperty(mrb, self, CSviewport);
}
DEF_PROP_OBJ(Tilemap, Bitmap, Tileset, CStileset)
DEF_PROP_OBJ(Tilemap, Table, MapData, CSmap_data)
DEF_PROP_OBJ(Tilemap, Table, FlashData, CSflash_data)
DEF_PROP_OBJ(Tilemap, Table, Priorities, CSpriorities)
DEF_PROP_OBJ_REF(Tilemap, Bitmap, Tileset, CStileset)
DEF_PROP_OBJ_REF(Tilemap, Table, MapData, CSmap_data)
DEF_PROP_OBJ_REF(Tilemap, Table, FlashData, CSflash_data)
DEF_PROP_OBJ_REF(Tilemap, Table, Priorities, CSpriorities)
DEF_PROP_B(Tilemap, Visible)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -57,20 +57,18 @@ MRB_METHOD(viewportInitialize)
setPrivateData(self, v, ViewportType);
/* Wrap property objects */
v->setRect(new Rect(*v->getRect()));
v->setColor(new Color);
v->setTone(new Tone);
v->initDynAttribs();
wrapProperty(mrb, self, v->getRect(), CSrect, RectType);
wrapProperty(mrb, self, v->getColor(), CScolor, ColorType);
wrapProperty(mrb, self, v->getTone(), CStone, ToneType);
wrapProperty(mrb, self, &v->getRect(), CSrect, RectType);
wrapProperty(mrb, self, &v->getColor(), CScolor, ColorType);
wrapProperty(mrb, self, &v->getTone(), CStone, ToneType);
return self;
}
DEF_PROP_OBJ(Viewport, Rect, Rect, CSrect)
DEF_PROP_OBJ(Viewport, Color, Color, CScolor)
DEF_PROP_OBJ(Viewport, Tone, Tone, CStone)
DEF_PROP_OBJ_VAL(Viewport, Rect, Rect, CSrect)
DEF_PROP_OBJ_VAL(Viewport, Color, Color, CScolor)
DEF_PROP_OBJ_VAL(Viewport, Tone, Tone, CStone)
DEF_PROP_I(Viewport, OX)
DEF_PROP_I(Viewport, OY)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -32,7 +32,7 @@
template<class C>
MRB_METHOD(viewportElementGetViewport)
{
checkDisposed(mrb, self);
checkDisposed<C>(mrb, self);
return getProperty(mrb, self, CSviewport);
}
@ -50,7 +50,9 @@ viewportElementInitialize(mrb_state *mrb, mrb_value self)
if (!mrb_nil_p(viewportObj))
{
viewport = getPrivateDataCheck<Viewport>(mrb, viewportObj, ViewportType);
disposableAddChild(mrb, viewportObj, self);
if (rgssVer == 1)
disposableAddChild(mrb, viewportObj, self);
}
/* Construct object */

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -32,10 +32,8 @@ MRB_METHOD(windowInitialize)
setPrivateData(self, w, WindowType);
w->setCursorRect(new Rect);
wrapNilProperty(mrb, self, CSwindowskin);
wrapNilProperty(mrb, self, CScontents);
wrapProperty(mrb, self, w->getCursorRect(), CScursor_rect, RectType);
w->initDynAttribs();
wrapProperty(mrb, self, &w->getCursorRect(), CScursor_rect, RectType);
return self;
}
@ -49,9 +47,9 @@ MRB_METHOD(windowUpdate)
return mrb_nil_value();
}
DEF_PROP_OBJ_NIL(Window, Bitmap, Windowskin, CSwindowskin)
DEF_PROP_OBJ_NIL(Window, Bitmap, Contents, CScontents)
DEF_PROP_OBJ(Window, Rect, CursorRect, CScursor_rect)
DEF_PROP_OBJ_REF(Window, Bitmap, Windowskin, CSwindowskin)
DEF_PROP_OBJ_REF(Window, Bitmap, Contents, CScontents)
DEF_PROP_OBJ_VAL(Window, Rect, CursorRect, CScursor_rect)
DEF_PROP_B(Window, Stretch)
DEF_PROP_B(Window, Active)

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -27,7 +27,7 @@
static void nullBindingExecute()
{
Debug() << "The null binding doesn't do anything, so we're done!";
shState->rtData().rqTermAck = true;
shState->rtData().rqTermAck.set();
}
static void nullBindingTerminate()
@ -35,10 +35,16 @@ static void nullBindingTerminate()
}
static void nullBindingReset()
{
}
ScriptBinding scriptBindingImpl =
{
nullBindingExecute,
nullBindingTerminate
nullBindingTerminate,
nullBindingReset
};
ScriptBinding *scriptBinding = &scriptBindingImpl;

View File

@ -1,4 +1,14 @@
# Lines starting with '#' are comments
# Lines starting with '#' are comments.
#
# About filesystem paths specified in this config:
# The "gameFolder" path is resolved either relative
# to the directory containing the mkxp executable
# (the default behavior), or relative to the current
# working directory (when compiled with
# -DWORKDIR_CURRENT). All other paths are resolved
# relative to gameFolder and ignoring both RTPs and
# encrypted archives.
# Specify the RGSS version to run under.
# Possible values are 0, 1, 2, 3. If set to 0,
@ -17,6 +27,14 @@
# debugMode=false
# Continuously print average FPS to console.
# This setting does not affect the window title
# FPS display toggled via F2
# (default: disabled)
#
# printFPS=false
# Game window is resizable
# (default: disabled)
#
@ -39,9 +57,9 @@
# Apply linear interpolation when game screen
# is upscaled
# (default: disabled)
# (default: enabled)
#
# smoothScaling=false
# smoothScaling=true
# Sync screen redraws to the monitor refresh rate
@ -68,6 +86,12 @@
# defScreenH=480
# Override the game window title
# (default: none)
#
# windowTitle=Custom Title
# Enforce a static frame rate
# (0 = disabled)
#
@ -80,12 +104,52 @@
# frameSkip=true
# Use a fixed framerate that is approx. equal to the
# native screen refresh rate. This is different from
# "fixedFramerate" because the actual frame rate is
# reported back to the game, ensuring correct timers.
# If the screen refresh rate cannot be determined,
# this option is force-disabled
# (default: disabled)
#
# syncToRefreshrate=false
# Don't use alpha blending when rendering text
# (default: disabled)
#
# solidFonts=false
# Work around buggy graphics drivers which don't
# properly synchronize texture access, most
# apparent when text doesn't show up or the map
# tileset doesn't render at all
# (default: disabled)
#
# 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).
# 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)
#
@ -99,12 +163,31 @@
# anyAltToggleFS=false
# Enable F12 game reset
# (default: enabled)
#
# enableReset=true
# Allow symlinks for game assets to be followed
# (default: disabled)
#
# allowSymlinks=false
# Organisation / company and application / game
# name to build the directory path where mkxp
# will store game specific data (eg. key bindings).
# If not specified, mkxp will save to a common
# directory shared by all games. Note that these
# are TWO individual config entries, and both need
# to be defined for this to take effect.
# (default: none)
#
# dataPathOrg=mycompany
# dataPathApp=mygame
# Set the game window icon to 'path/to/icon.png'
# (default: none)
#
@ -199,6 +282,19 @@
# SE.sourceCount=6
# The Windows game executable name minus ".exe". By default
# this is "Game", but some developers manually rename it.
# mkxp needs this name because both the .ini (game
# configuration) and .rgssad (encrypted data archive) must
# carry the same name minus their extension, and we cannot
# guess the executable's name.
# You could just as well rename them both to "Game.ini" and
# "Game.rgssad", but specifying the executable name here
# is a tiny bit less intrusive.
#
# execName=Game
# Give a hint on which language the game title as
# specified in the Game.ini is, useful if the encoding
# is being falsely detected. Relevant only if mkxp was

View File

@ -8,11 +8,9 @@ INCLUDEPATH += . src
CONFIG(release, debug|release): DEFINES += NDEBUG
CONFIG += MIDI
DISABLE_MIDI {
CONFIG -= MIDI
}
CONFIG += c++11
# And for older qmake versions..
QMAKE_CXXFLAGS += -std=c++11
isEmpty(BINDING) {
BINDING = MRI
@ -50,7 +48,7 @@ unix {
PKGCONFIG += sigc++-2.0 pixman-1 zlib physfs vorbisfile \
sdl2 SDL2_image SDL2_ttf SDL_sound openal
MIDI {
SHARED_FLUID {
PKGCONFIG += fluidsynth
}
@ -95,6 +93,7 @@ HEADERS += \
src/flashable.h \
src/font.h \
src/input.h \
src/iniconfig.h \
src/plane.h \
src/scene.h \
src/sprite.h \
@ -109,8 +108,9 @@ HEADERS += \
src/glstate.h \
src/quad.h \
src/tilemap.h \
src/tilemap-common.h \
src/graphics.h \
src/debuglogger.h \
src/gl-debug.h \
src/global-ibo.h \
src/exception.h \
src/filesystem.h \
@ -120,6 +120,8 @@ HEADERS += \
src/gl-util.h \
src/util.h \
src/config.h \
src/settingsmenu.h \
src/keybindings.h \
src/tileatlas.h \
src/sharedstate.h \
src/al-util.h \
@ -135,7 +137,10 @@ HEADERS += \
src/rgssad.h \
src/windowvx.h \
src/tilemapvx.h \
src/tileatlasvx.h
src/tileatlasvx.h \
src/sharedmidistate.h \
src/fluid-fun.h \
src/sdl-util.h
SOURCES += \
src/main.cpp \
@ -145,6 +150,7 @@ SOURCES += \
src/filesystem.cpp \
src/font.cpp \
src/input.cpp \
src/iniconfig.cpp \
src/plane.cpp \
src/scene.cpp \
src/sprite.cpp \
@ -158,9 +164,11 @@ SOURCES += \
src/tilemap.cpp \
src/autotiles.cpp \
src/graphics.cpp \
src/debuglogger.cpp \
src/gl-debug.cpp \
src/etc.cpp \
src/config.cpp \
src/settingsmenu.cpp \
src/keybindings.cpp \
src/tileatlas.cpp \
src/sharedstate.cpp \
src/gl-fun.cpp \
@ -176,19 +184,26 @@ SOURCES += \
src/windowvx.cpp \
src/tilemapvx.cpp \
src/tileatlasvx.cpp \
src/autotilesvx.cpp
src/autotilesvx.cpp \
src/midisource.cpp \
src/fluid-fun.cpp
EMBED = \
shader/common.h \
shader/transSimple.frag \
shader/trans.frag \
shader/hue.frag \
shader/sprite.frag \
shader/plane.frag \
shader/gray.frag \
shader/bitmapBlit.frag \
shader/flatColor.frag \
shader/simple.frag \
shader/simpleColor.frag \
shader/simpleAlpha.frag \
shader/simpleAlphaUni.frag \
shader/flashMap.frag \
shader/minimal.vert \
shader/simple.vert \
shader/simpleColor.vert \
shader/sprite.vert \
@ -198,16 +213,11 @@ EMBED = \
shader/blurV.vert \
shader/simpleMatrix.vert \
shader/tilemapvx.vert \
assets/liberation.ttf
assets/liberation.ttf \
assets/icon.png
MIDI {
HEADERS += \
src/sharedmidistate.h
SOURCES += \
src/midisource.cpp
DEFINES += MIDI
SHARED_FLUID {
DEFINES += SHARED_FLUID
}
INI_ENCODING {
@ -274,7 +284,11 @@ BINDING_MRUBY {
}
BINDING_MRI {
PKGCONFIG += ruby-2.1
isEmpty(MRIVERSION) {
MRIVERSION = 2.1
}
PKGCONFIG += ruby-$$MRIVERSION
DEFINES += BINDING_MRI
# EMBED2 = binding-mri/module_rpg.rb

View File

@ -1,54 +0,0 @@
diff -r 719dade41745 Makefile.am
--- a/Makefile.am Wed Aug 15 23:52:18 2012 -0400
+++ b/Makefile.am Thu Nov 28 18:42:40 2013 +0100
@@ -1,8 +1,8 @@
lib_LTLIBRARIES = libSDL_sound.la
-SUBDIRS = decoders . playsound
+SUBDIRS = decoders .
-libSDL_soundincludedir = $(includedir)/SDL
+libSDL_soundincludedir = $(includedir)/SDL2
libSDL_soundinclude_HEADERS = \
SDL_sound.h
@@ -49,3 +49,5 @@
echo >> $(distdir)/docs/README
rm -rf `find $(distdir) -type d -name ".svn"`
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = SDL_sound.pc
diff -r 719dade41745 SDL_sound.pc.in
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SDL_sound.pc.in Thu Nov 28 18:42:40 2013 +0100
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: SDL_sound
+Description: audio decoding library for Simple DirectMedia Layer
+Version: @VERSION@
+Requires: sdl2 >= @SDL_VERSION@
+Libs: -L${libdir} -lSDL_sound
+Cflags: -I${includedir}/SDL2
diff -r 719dade41745 configure.in
--- a/configure.in Wed Aug 15 23:52:18 2012 -0400
+++ b/configure.in Thu Nov 28 18:42:40 2013 +0100
@@ -107,7 +107,8 @@
dnl ---------------------------------------------------------------------
dnl Check for SDL
-SDL_VERSION=1.2.0
+SDL_VERSION=2.0.0
+AC_SUBST(SDL_VERSION)
AM_PATH_SDL($SDL_VERSION,
:,
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
@@ -339,4 +340,5 @@
decoders/timidity/Makefile
decoders/libmpg123/Makefile
playsound/Makefile
+SDL_sound.pc
])

View File

@ -0,0 +1,43 @@
--- a/common.mk
+++ b/common.mk
@@ -95,6 +95,7 @@ COMMONOBJS = array.$(OBJEXT) \
vm_trace.$(OBJEXT) \
thread.$(OBJEXT) \
cont.$(OBJEXT) \
+ ext/zlib/zlib.$(OBJEXT) \
$(BUILTIN_ENCOBJS) \
$(BUILTIN_TRANSOBJS) \
$(MISSING)
diff --git a/ruby-2.1.5.orig/configure b/ruby-2.1.5/configure
index d0f1f68..45ab642 100755
--- a/configure
+++ b/configure
@@ -2838,6 +2838,8 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+LIBS="$LIBS -lz"
+
{ # environment section
--- a/configure.in
+++ b/configure.in
@@ -31,6 +31,8 @@ rm() {
}
])])])
+LIBS="$LIBS -lz"
+
{ # environment section
AC_ARG_WITH(baseruby,
--- a/inits.c
+++ b/inits.c
@@ -61,5 +61,6 @@ rb_call_inits(void)
CALL(Complex);
CALL(version);
CALL(vm_trace);
+ CALL(zlib);
}
#undef CALL

View File

@ -6,7 +6,7 @@ uniform sampler2D destination;
uniform vec4 subRect;
uniform float opacity;
uniform lowp float opacity;
varying vec2 v_texCoord;

View File

@ -6,7 +6,7 @@ varying vec2 v_blurCoord[2];
void main()
{
vec4 frag = vec4(0, 0, 0, 0);
lowp vec4 frag = vec4(0, 0, 0, 0);
frag += texture2D(texture, v_texCoord);
frag += texture2D(texture, v_blurCoord[0]);

15
shader/common.h Normal file
View File

@ -0,0 +1,15 @@
#ifdef GLSLES
#ifdef FRAGMENT_SHADER
/* Only the fragment shader has no default float precision */
precision mediump float;
#endif
#else
/* Desktop GLSL doesn't know about these */
#define highp
#define mediump
#define lowp
#endif

View File

@ -1,7 +1,7 @@
uniform float alpha;
uniform lowp float alpha;
varying vec4 v_color;
varying lowp vec4 v_color;
void main()
{

7
shader/flatColor.frag Normal file
View File

@ -0,0 +1,7 @@
uniform lowp vec4 color;
void main()
{
gl_FragColor = color;
}

19
shader/gray.frag Normal file
View File

@ -0,0 +1,19 @@
uniform sampler2D texture;
uniform lowp float gray;
varying vec2 v_texCoord;
const vec3 lumaF = vec3(.299, .587, .114);
void main()
{
/* Sample source color */
vec4 frag = texture2D(texture, v_texCoord);
/* Apply gray */
float luma = dot(frag.rgb, lumaF);
frag.rgb = mix(frag.rgb, vec3(luma), gray);
gl_FragColor = frag;
}

View File

@ -1,44 +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;
// 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 = color;
}

8
shader/minimal.vert Normal file
View File

@ -0,0 +1,8 @@
uniform mat4 projMat;
attribute vec2 position;
void main()
{
gl_Position = projMat * vec4(position, 0, 1);
}

View File

@ -1,11 +1,11 @@
uniform sampler2D texture;
uniform vec4 tone;
uniform lowp vec4 tone;
uniform float opacity;
uniform vec4 color;
uniform vec4 flash;
uniform lowp float opacity;
uniform lowp vec4 color;
uniform lowp vec4 flash;
varying vec2 v_texCoord;

View File

@ -2,7 +2,7 @@
uniform sampler2D texture;
varying vec2 v_texCoord;
varying vec4 v_color;
varying lowp vec4 v_color;
void main()
{

View File

@ -0,0 +1,11 @@
uniform sampler2D texture;
uniform lowp float alpha;
varying vec2 v_texCoord;
void main()
{
gl_FragColor = texture2D(texture, v_texCoord);
gl_FragColor.a *= alpha;
}

View File

@ -1,5 +1,5 @@
varying vec4 v_color;
varying lowp vec4 v_color;
void main()
{

View File

@ -6,10 +6,10 @@ uniform vec2 translation;
attribute vec2 position;
attribute vec2 texCoord;
attribute vec4 color;
attribute lowp vec4 color;
varying vec2 v_texCoord;
varying vec4 v_color;
varying lowp vec4 v_color;
void main()
{

View File

@ -6,10 +6,10 @@ uniform vec2 texSizeInv;
attribute vec2 position;
attribute vec2 texCoord;
attribute vec4 color;
attribute lowp vec4 color;
varying vec2 v_texCoord;
varying vec4 v_color;
varying lowp vec4 v_color;
void main()
{

View File

@ -1,13 +1,13 @@
uniform sampler2D texture;
uniform vec4 tone;
uniform lowp vec4 tone;
uniform float opacity;
uniform vec4 color;
uniform lowp float opacity;
uniform lowp vec4 color;
uniform float bushDepth;
uniform float bushOpacity;
uniform lowp float bushOpacity;
varying vec2 v_texCoord;
@ -32,7 +32,7 @@ void main()
frag.rgb = mix(frag.rgb, color.rgb, color.a);
/* Apply bush alpha by mathematical if */
float underBush = float(v_texCoord.y < bushDepth);
lowp float underBush = float(v_texCoord.y < bushDepth);
frag.a *= clamp(bushOpacity + underBush, 0.0, 1.0);
gl_FragColor = frag;

View File

@ -18,8 +18,9 @@ const float atAniOffset = 32.0*3.0;
void main()
{
vec2 tex = texCoord;
if (tex.x <= atAreaW && tex.y <= atAreaH)
tex.x += aniIndex * atAniOffset;
lowp float pred = float(tex.x <= atAreaW && tex.y <= atAreaH);
tex.x += aniIndex * atAniOffset * pred;
gl_Position = projMat * vec4(position + translation, 0, 1);

View File

@ -18,14 +18,15 @@ const float atAreaCW = 4.0*32.0;
void main()
{
vec2 tex = texCoord;
lowp float pred;
/* Type A autotiles shift horizontally */
if (tex.x <= atAreaA.x && tex.y <= atAreaA.y)
tex.x += aniOffset.x;
pred = float(tex.x <= atAreaA.x && tex.y <= atAreaA.y);
tex.x += aniOffset.x * pred;
/* Type C autotiles shift vertically */
if (tex.x >= atAreaCX && tex.x <= (atAreaCX+atAreaCW) && tex.y <= atAreaA.y)
tex.y += aniOffset.y;
pred = float(tex.x >= atAreaCX && tex.x <= (atAreaCX+atAreaCW) && tex.y <= atAreaA.y);
tex.y += aniOffset.y * pred;
gl_Position = projMat * vec4(position + translation, 0, 1);

View File

@ -14,7 +14,7 @@ void main()
{
float transV = texture2D(transMap, v_texCoord).r;
float cTransV = clamp(transV, prog, prog+vague);
float alpha = (cTransV - prog) / vague;
lowp float alpha = (cTransV - prog) / vague;
vec4 newFrag = texture2D(currentScene, v_texCoord);
vec4 oldFrag = texture2D(frozenScene, v_texCoord);

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -238,5 +238,6 @@ inline ALenum chooseALFormat(int sampleSize, int channelCount)
#define AUDIO_SLEEP 10
#define STREAM_BUF_SIZE 32768
#define GLOBAL_VOLUME 0.8f
#endif // ALUTIL_H

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2014 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -61,9 +61,7 @@ ALDataSource *createSDLSource(SDL_RWops &ops,
ALDataSource *createVorbisSource(SDL_RWops &ops,
bool looped);
#ifdef MIDI
ALDataSource *createMidiSource(SDL_RWops &ops,
bool looped);
#endif
#endif // ALDATASOURCE_H

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2014 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -22,8 +22,14 @@
#include "alstream.h"
#include "sharedstate.h"
#include "sharedmidistate.h"
#include "eventthread.h"
#include "filesystem.h"
#include "exception.h"
#include "aldatasource.h"
#include "fluid-fun.h"
#include "sdl-util.h"
#include "debugwriter.h"
#include <SDL_mutex.h>
#include <SDL_thread.h>
@ -36,14 +42,12 @@ ALStream::ALStream(LoopMode loopMode,
source(0),
thread(0),
preemptPause(false),
streamInited(false),
needsRewind(false),
pitch(1.0)
pitch(1.0f)
{
alSrc = AL::Source::gen();
AL::Source::setVolume(alSrc, 1.0);
AL::Source::setPitch(alSrc, 1.0);
AL::Source::setVolume(alSrc, 1.0f);
AL::Source::setPitch(alSrc, 1.0f);
AL::Source::detachBuffer(alSrc);
for (int i = 0; i < STREAM_BUFS; ++i)
@ -121,6 +125,9 @@ void ALStream::stop()
void ALStream::play(float offset)
{
if (!source)
return;
checkStopped();
switch (state)
@ -165,7 +172,7 @@ void ALStream::setPitch(float value)
/* If the source supports setting pitch natively,
* we don't have to do it via OpenAL */
if (source && source->setPitch(value))
AL::Source::setPitch(alSrc, 1.0);
AL::Source::setPitch(alSrc, 1.0f);
else
AL::Source::setPitch(alSrc, value);
}
@ -192,52 +199,87 @@ void ALStream::closeSource()
delete source;
}
void ALStream::openSource(const std::string &filename)
struct ALStreamOpenHandler : FileSystem::OpenHandler
{
const char *ext;
shState->fileSystem().openRead(srcOps, filename.c_str(), FileSystem::Audio, false, &ext);
needsRewind = false;
SDL_RWops *srcOps;
bool looped;
ALDataSource *source;
std::string errorMsg;
bool readSig = rgssVer >= 2;
ALStreamOpenHandler(SDL_RWops &srcOps, bool looped)
: srcOps(&srcOps), looped(looped), source(0)
{}
#ifdef MIDI
readSig = true;
#endif
if (readSig)
bool tryRead(SDL_RWops &ops, const char *ext)
{
/* Copy this because we need to keep it around,
* as we will continue reading data from it later */
*srcOps = ops;
/* Try to read ogg file signature */
char sig[5] = { 0 };
SDL_RWread(&srcOps, sig, 1, 4);
SDL_RWseek(&srcOps, 0, RW_SEEK_SET);
SDL_RWread(srcOps, sig, 1, 4);
SDL_RWseek(srcOps, 0, RW_SEEK_SET);
if (!strcmp(sig, "OggS"))
try
{
source = createVorbisSource(srcOps, looped);
return;
if (!strcmp(sig, "OggS"))
{
source = createVorbisSource(*srcOps, looped);
return true;
}
if (!strcmp(sig, "MThd"))
{
shState->midiState().initIfNeeded(shState->config());
if (HAVE_FLUID)
{
source = createMidiSource(*srcOps, looped);
return true;
}
}
source = createSDLSource(*srcOps, ext, STREAM_BUF_SIZE, looped);
}
catch (const Exception &e)
{
/* All source constructors will close the passed ops
* before throwing errors */
errorMsg = e.msg;
return false;
}
#ifdef MIDI
if (!strcmp(sig, "MThd"))
{
source = createMidiSource(srcOps, looped);
return;
}
#endif
return true;
}
};
source = createSDLSource(srcOps, ext, STREAM_BUF_SIZE, looped);
void ALStream::openSource(const std::string &filename)
{
ALStreamOpenHandler handler(srcOps, looped);
shState->fileSystem().openRead(handler, filename.c_str());
source = handler.source;
needsRewind.clear();
if (!source)
{
char buf[512];
snprintf(buf, sizeof(buf), "Unable to decode audio stream: %s: %s",
filename.c_str(), handler.errorMsg.c_str());
Debug() << buf;
}
}
void ALStream::stopStream()
{
threadTermReq = true;
threadTermReq.set();
if (thread)
{
SDL_WaitThread(thread, 0);
thread = 0;
needsRewind = true;
needsRewind.set();
}
/* Need to stop the source _after_ the thread has terminated,
@ -253,14 +295,15 @@ void ALStream::startStream(float offset)
AL::Source::clearQueue(alSrc);
preemptPause = false;
streamInited = false;
sourceExhausted = false;
threadTermReq = false;
streamInited.clear();
sourceExhausted.clear();
threadTermReq.clear();
startOffset = offset;
procFrames = offset * source->sampleRate();
thread = SDL_CreateThread(streamDataFun, threadName.c_str(), this);
thread = createSDLThread
<ALStream, &ALStream::streamData>(this, threadName);
}
void ALStream::pauseStream()
@ -348,7 +391,7 @@ void ALStream::streamData()
resumeStream();
firstBuffer = false;
streamInited = true;
streamInited.set();
}
if (threadTermReq)
@ -356,7 +399,7 @@ void ALStream::streamData()
if (status == ALDataSource::EndOfStream)
{
sourceExhausted = true;
sourceExhausted.set();
break;
}
}
@ -365,6 +408,8 @@ void ALStream::streamData()
* refill and queue them up again */
while (true)
{
shState->rtData().syncPoint.passSecondarySync();
ALint procBufs = AL::Source::getProcBufferCount(alSrc);
while (procBufs--)
@ -404,7 +449,7 @@ void ALStream::streamData()
if (status == ALDataSource::Error)
{
sourceExhausted = true;
sourceExhausted.set();
return;
}
@ -423,7 +468,7 @@ void ALStream::streamData()
lastBuf = buf;
if (status == ALDataSource::EndOfStream)
sourceExhausted = true;
sourceExhausted.set();
}
if (threadTermReq)
@ -432,10 +477,3 @@ void ALStream::streamData()
SDL_Delay(AUDIO_SLEEP);
}
}
int ALStream::streamDataFun(void *_self)
{
ALStream &self = *static_cast<ALStream*>(_self);
self.streamData();
return 0;
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2014 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -23,12 +23,11 @@
#define ALSTREAM_H
#include "al-util.h"
#include "sdl-util.h"
#include <string>
#include <SDL_rwops.h>
struct SDL_mutex;
struct SDL_thread;
struct ALDataSource;
#define STREAM_BUFS 3
@ -59,12 +58,12 @@ struct ALStream
/* When this flag isn't set and alSrc is
* in 'STOPPED' state, stream isn't over
* (it just hasn't started yet) */
bool streamInited;
bool sourceExhausted;
AtomicFlag streamInited;
AtomicFlag sourceExhausted;
bool threadTermReq;
AtomicFlag threadTermReq;
bool needsRewind;
AtomicFlag needsRewind;
float startOffset;
float pitch;
@ -118,7 +117,6 @@ private:
/* thread func */
void streamData();
static int streamDataFun(void *);
};
#endif // ALSTREAM_H

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -24,10 +24,9 @@
#include "audiostream.h"
#include "soundemitter.h"
#include "sharedstate.h"
#ifdef MIDI
#include "sharedmidistate.h"
#endif
#include "eventthread.h"
#include "sdl-util.h"
#include <string>
@ -42,6 +41,8 @@ struct AudioPrivate
SoundEmitter se;
SyncPoint &syncPoint;
/* The 'MeWatch' is responsible for detecting
* a playing ME, quickly fading out the BGM and
* keeping it paused/stopped while the ME plays,
@ -58,36 +59,37 @@ struct AudioPrivate
struct
{
SDL_Thread *thread;
bool active;
bool termReq;
AtomicFlag termReq;
MeWatchState state;
} meWatch;
AudioPrivate(const Config &conf)
AudioPrivate(RGSSThreadData &rtData)
: bgm(ALStream::Looped, "bgm"),
bgs(ALStream::Looped, "bgs"),
me(ALStream::NotLooped, "me"),
se(conf)
se(rtData.config),
syncPoint(rtData.syncPoint)
{
meWatch.active = false;
meWatch.termReq = false;
meWatch.state = MeNotPlaying;
meWatch.thread = SDL_CreateThread(meWatchFun, "audio_mewatch", this);
meWatch.thread = createSDLThread
<AudioPrivate, &AudioPrivate::meWatchFun>(this, "audio_mewatch");
}
~AudioPrivate()
{
meWatch.termReq = true;
meWatch.termReq.set();
SDL_WaitThread(meWatch.thread, 0);
}
void meWatchFunInt()
void meWatchFun()
{
const float fadeOutStep = 1.f / (200 / AUDIO_SLEEP);
const float fadeInStep = 1.f / (1000 / AUDIO_SLEEP);
while (true)
{
syncPoint.passSecondarySync();
if (meWatch.termReq)
return;
@ -124,13 +126,13 @@ struct AudioPrivate
bgm.lockStream();
float vol = bgm.extVolume;
float vol = bgm.getVolume(AudioStream::External);
vol -= fadeOutStep;
if (vol < 0 || bgm.stream.queryState() != ALStream::Playing)
{
/* Either BGM has fully faded out, or stopped midway. -> MePlaying */
bgm.setExtVolume1(0);
bgm.setVolume(AudioStream::External, 0);
bgm.stream.pause();
meWatch.state = MePlaying;
bgm.unlockStream();
@ -139,7 +141,7 @@ struct AudioPrivate
break;
}
bgm.setExtVolume1(vol);
bgm.setVolume(AudioStream::External, vol);
bgm.unlockStream();
me.unlockStream();
@ -168,7 +170,7 @@ struct AudioPrivate
else
{
/* BGM is stopped. -> MeNotPlaying */
bgm.setExtVolume1(1.0);
bgm.setVolume(AudioStream::External, 1.0f);
if (!bgm.noResumeStop)
bgm.stream.play();
@ -191,7 +193,7 @@ struct AudioPrivate
if (bgm.stream.queryState() == ALStream::Stopped)
{
/* BGM stopped midway fade in. -> MeNotPlaying */
bgm.setExtVolume1(1.0);
bgm.setVolume(AudioStream::External, 1.0f);
meWatch.state = MeNotPlaying;
bgm.unlockStream();
@ -211,17 +213,17 @@ struct AudioPrivate
break;
}
float vol = bgm.extVolume;
float vol = bgm.getVolume(AudioStream::External);
vol += fadeInStep;
if (vol >= 1)
{
/* BGM fully faded in. -> MeNotPlaying */
vol = 1.0;
vol = 1.0f;
meWatch.state = MeNotPlaying;
}
bgm.setExtVolume1(vol);
bgm.setVolume(AudioStream::External, vol);
me.unlockStream();
bgm.unlockStream();
@ -233,17 +235,10 @@ struct AudioPrivate
SDL_Delay(AUDIO_SLEEP);
}
}
static int meWatchFun(void *self)
{
static_cast<AudioPrivate*>(self)->meWatchFunInt();
return 0;
}
};
Audio::Audio(const Config &conf)
: p(new AudioPrivate(conf))
Audio::Audio(RGSSThreadData &rtData)
: p(new AudioPrivate(rtData))
{}
@ -317,9 +312,7 @@ void Audio::seStop()
void Audio::setupMidi()
{
#ifdef MIDI
shState->midiState().initDefaultSynths();
#endif
shState->midiState().initIfNeeded(shState->config());
}
float Audio::bgmPos()
@ -332,4 +325,12 @@ float Audio::bgsPos()
return p->bgs.playingOffset();
}
void Audio::reset()
{
p->bgm.stop();
p->bgs.stop();
p->me.stop();
p->se.stop();
}
Audio::~Audio() { delete p; }

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -33,7 +33,7 @@
* quite make out their meaning yet) */
struct AudioPrivate;
struct Config;
struct RGSSThreadData;
class Audio
{
@ -67,8 +67,10 @@ public:
float bgmPos();
float bgsPos();
void reset();
private:
Audio(const Config &conf);
Audio(RGSSThreadData &rtData);
~Audio();
friend struct SharedStatePrivate;

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2014 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -30,19 +30,21 @@
AudioStream::AudioStream(ALStream::LoopMode loopMode,
const std::string &threadId)
: baseVolume(1.0),
fadeVolume(1.0),
extVolume(1.0),
extPaused(false),
: extPaused(false),
noResumeStop(false),
stream(loopMode, threadId)
{
current.volume = 1.0;
current.pitch = 1.0;
current.volume = 1.0f;
current.pitch = 1.0f;
for (size_t i = 0; i < VolumeTypeCount; ++i)
volumes[i] = 1.0f;
fade.active = false;
fade.thread = 0;
fade.threadName = std::string("audio_fade (") + threadId + ")";
fade.threadName = std::string("audio_fadeout (") + threadId + ")";
fadeIn.thread = 0;
fadeIn.threadName = std::string("audio_fadein (") + threadId + ")";
streamMut = SDL_CreateMutex();
}
@ -51,10 +53,16 @@ AudioStream::~AudioStream()
{
if (fade.thread)
{
fade.reqTerm = true;
fade.reqTerm.set();
SDL_WaitThread(fade.thread, 0);
}
if (fadeIn.thread)
{
fadeIn.rqTerm.set();
SDL_WaitThread(fadeIn.thread, 0);
}
lockStream();
stream.stop();
@ -70,12 +78,12 @@ void AudioStream::play(const std::string &filename,
int pitch,
float offset)
{
finiFadeInt();
finiFadeOutInt();
lockStream();
float _volume = clamp<int>(volume, 0, 100) / 100.f;
float _pitch = clamp<int>(pitch, 50, 150) / 100.f;
float _volume = clamp<int>(volume, 0, 100) / 100.0f;
float _pitch = clamp<int>(pitch, 50, 150) / 100.0f;
ALStream::State sState = stream.queryState();
@ -96,7 +104,7 @@ void AudioStream::play(const std::string &filename,
&& _pitch == current.pitch
&& (sState == ALStream::Playing || sState == ALStream::Paused))
{
setBaseVolume(_volume);
setVolume(Base, _volume);
current.volume = _volume;
unlockStream();
return;
@ -132,9 +140,15 @@ void AudioStream::play(const std::string &filename,
break;
}
setBaseVolume(_volume);
setVolume(Base, _volume);
stream.setPitch(_pitch);
if (offset > 0)
{
setVolume(FadeIn, 0);
startFadeIn();
}
current.filename = filename;
current.volume = _volume;
current.pitch = _pitch;
@ -149,7 +163,7 @@ void AudioStream::play(const std::string &filename,
void AudioStream::stop()
{
finiFadeInt();
finiFadeOutInt();
lockStream();
@ -165,6 +179,7 @@ void AudioStream::fadeOut(int duration)
lockStream();
ALStream::State sState = stream.queryState();
noResumeStop = true;
if (fade.active)
{
@ -190,18 +205,19 @@ void AudioStream::fadeOut(int duration)
if (fade.thread)
{
fade.reqFini = true;
fade.reqFini.set();
SDL_WaitThread(fade.thread, 0);
fade.thread = 0;
}
fade.active = true;
fade.msStep = (1.0) / duration;
fade.reqFini = false;
fade.reqTerm = false;
fade.active.set();
fade.msStep = 1.0f / duration;
fade.reqFini.clear();
fade.reqTerm.clear();
fade.startTicks = SDL_GetTicks();
fade.thread = SDL_CreateThread(fadeThreadFun, fade.threadName.c_str(), this);
fade.thread = createSDLThread
<AudioStream, &AudioStream::fadeOutThread>(this, fade.threadName);
unlockStream();
}
@ -219,16 +235,15 @@ void AudioStream::unlockStream()
SDL_UnlockMutex(streamMut);
}
void AudioStream::setFadeVolume(float value)
void AudioStream::setVolume(VolumeType type, float value)
{
fadeVolume = value;
volumes[type] = value;
updateVolume();
}
void AudioStream::setExtVolume1(float value)
float AudioStream::getVolume(VolumeType type)
{
extVolume = value;
updateVolume();
return volumes[type];
}
float AudioStream::playingOffset()
@ -236,28 +251,47 @@ float AudioStream::playingOffset()
return stream.queryOffset();
}
void AudioStream::finiFadeInt()
{
if (!fade.thread)
return;
fade.reqFini = true;
SDL_WaitThread(fade.thread, 0);
fade.thread = 0;
}
void AudioStream::updateVolume()
{
stream.setVolume(baseVolume * fadeVolume * extVolume);
float vol = GLOBAL_VOLUME;
for (size_t i = 0; i < VolumeTypeCount; ++i)
vol *= volumes[i];
stream.setVolume(vol);
}
void AudioStream::setBaseVolume(float value)
void AudioStream::finiFadeOutInt()
{
baseVolume = value;
updateVolume();
if (fade.thread)
{
fade.reqFini.set();
SDL_WaitThread(fade.thread, 0);
fade.thread = 0;
}
if (fadeIn.thread)
{
fadeIn.rqFini.set();
SDL_WaitThread(fadeIn.thread, 0);
fadeIn.thread = 0;
}
}
void AudioStream::fadeThread()
void AudioStream::startFadeIn()
{
/* Previous fadein should always be terminated in play() */
assert(!fadeIn.thread);
fadeIn.rqFini.clear();
fadeIn.rqTerm.clear();
fadeIn.startTicks = SDL_GetTicks();
fadeIn.thread = createSDLThread
<AudioStream, &AudioStream::fadeInThread>(this, fadeIn.threadName);
}
void AudioStream::fadeOutThread()
{
while (true)
{
@ -268,36 +302,64 @@ void AudioStream::fadeThread()
lockStream();
uint32_t curDur = SDL_GetTicks() - fade.startTicks;
float resVol = 1.0 - (curDur*fade.msStep);
float resVol = 1.0f - (curDur*fade.msStep);
ALStream::State state = stream.queryState();
if (state != ALStream::Playing
|| resVol < 0
|| fade.reqFini)
|| resVol < 0
|| fade.reqFini)
{
if (state != ALStream::Paused)
stream.stop();
setFadeVolume(1.0);
setVolume(FadeOut, 1.0f);
unlockStream();
break;
}
setFadeVolume(resVol);
setVolume(FadeOut, resVol);
unlockStream();
SDL_Delay(AUDIO_SLEEP);
}
fade.active = false;
fade.active.clear();
}
int AudioStream::fadeThreadFun(void *self)
void AudioStream::fadeInThread()
{
static_cast<AudioStream*>(self)->fadeThread();
while (true)
{
if (fadeIn.rqTerm)
break;
return 0;
lockStream();
/* Fade in duration is always 1 second */
uint32_t cur = SDL_GetTicks() - fadeIn.startTicks;
float prog = cur / 1000.0f;
ALStream::State state = stream.queryState();
if (state != ALStream::Playing
|| prog >= 1.0f
|| fadeIn.rqFini)
{
setVolume(FadeIn, 1.0f);
unlockStream();
break;
}
/* Quadratic increase (not really the same as
* in RMVXA, but close enough) */
setVolume(FadeIn, prog*prog);
unlockStream();
SDL_Delay(AUDIO_SLEEP);
}
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2014 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -24,12 +24,10 @@
#include "al-util.h"
#include "alstream.h"
#include "sdl-util.h"
#include <string>
struct SDL_mutex;
struct SDL_Thread;
struct AudioStream
{
struct
@ -39,21 +37,28 @@ struct AudioStream
float pitch;
} current;
/* Volume set with 'play()' */
float baseVolume;
/* Volume set by external threads,
/* Volumes set by external threads,
* such as for fade-in/out.
* Multiplied with intVolume for final
* playback volume.
* fadeVolume: used by fade-out thread.
* extVolume: used by MeWatch. */
float fadeVolume;
float extVolume;
* Multiplied together for final
* playback volume. Used with setVolume().
* Base is set by play().
* External is used by MeWatch */
enum VolumeType
{
Base = 0,
FadeOut,
FadeIn,
External,
VolumeTypeCount
};
/* Note that 'extPaused' and 'noResumeStop' are
* effectively only used with the AudioStream
* instance representing the BGM */
* instance representing the BGM.
* They are not AtomicFlags because they're regarded
* as part of the underlying stream state, and
* always accessed with the stream lock held */
/* Flag indicating that the MeWatch paused this
* (BGM) stream because a ME started playing.
@ -76,18 +81,19 @@ struct AudioStream
ALStream stream;
SDL_mutex *streamMut;
/* Fade out */
struct
{
/* Fade is in progress */
bool active;
/* Fade out is in progress */
AtomicFlag active;
/* Request fade thread to finish and
* cleanup (like it normally would) */
bool reqFini;
AtomicFlag reqFini;
/* Request fade thread to terminate
* immediately */
bool reqTerm;
AtomicFlag reqTerm;
SDL_Thread *thread;
std::string threadName;
@ -100,6 +106,18 @@ struct AudioStream
uint32_t startTicks;
} fade;
/* Fade in */
struct
{
AtomicFlag rqFini;
AtomicFlag rqTerm;
SDL_Thread *thread;
std::string threadName;
uint32_t startTicks;
} fadeIn;
AudioStream(ALStream::LoopMode loopMode,
const std::string &threadId);
~AudioStream();
@ -117,19 +135,20 @@ struct AudioStream
void lockStream();
void unlockStream();
void setFadeVolume(float value);
void setExtVolume1(float value);
void setVolume(VolumeType type, float value);
float getVolume(VolumeType type);
float playingOffset();
private:
void finiFadeInt();
float volumes[VolumeTypeCount];
void updateVolume();
void setBaseVolume(float value);
void fadeThread();
static int fadeThreadFun(void *);
void finiFadeOutInt();
void startFadeIn();
void fadeOutThread();
void fadeInThread();
};
#endif // AUDIOSTREAM_H

View File

@ -4,196 +4,196 @@ extern const StaticRect autotileRects[] =
{
{ 32.5, 64.5, 15, 15 },
{ 48.5, 64.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 32.5, 80.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 48.5, 64.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 32.5, 80.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 32.5, 64.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 32.5, 80.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 32.5, 80.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 32.5, 64.5, 15, 15 },
{ 48.5, 64.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 32.5, 80.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 48.5, 64.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 32.5, 80.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 32.5, 64.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 32.5, 80.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 32.5, 80.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 32.5, 64.5, 15, 15 },
{ 48.5, 64.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 48.5, 64.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 32.5, 64.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 48.5, 80.5, 15, 15 },
{ 32.5, 64.5, 15, 15 },
{ 48.5, 64.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 48.5, 64.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 32.5, 64.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 0.5, 64.5, 15, 15 },
{ 16.5, 64.5, 15, 15 },
{ 16.5, 80.5, 15, 15 },
{ 0.5, 80.5, 15, 15 },
{ 16.5, 80.5, 15, 15 },
{ 0.5, 64.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 16.5, 80.5, 15, 15 },
{ 0.5, 80.5, 15, 15 },
{ 16.5, 80.5, 15, 15 },
{ 0.5, 64.5, 15, 15 },
{ 16.5, 64.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 0.5, 80.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 0.5, 64.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 0.5, 80.5, 15, 15 },
{ 32.5, 32.5, 15, 15 },
{ 48.5, 32.5, 15, 15 },
{ 48.5, 48.5, 15, 15 },
{ 32.5, 48.5, 15, 15 },
{ 32.5, 32.5, 15, 15 },
{ 48.5, 32.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 32.5, 32.5, 15, 15 },
{ 48.5, 32.5, 15, 15 },
{ 32.5, 48.5, 15, 15 },
{ 32.5, 32.5, 15, 15 },
{ 48.5, 32.5, 15, 15 },
{ 48.5, 48.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 32.5, 32.5, 15, 15 },
{ 48.5, 32.5, 15, 15 },
{ 32.5, 48.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 32.5, 32.5, 15, 15 },
{ 48.5, 32.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 48.5, 48.5, 15, 15 },
{ 32.5, 32.5, 15, 15 },
{ 48.5, 32.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 64.5, 64.5, 15, 15 },
{ 80.5, 64.5, 15, 15 },
{ 80.5, 80.5, 15, 15 },
{ 64.5, 80.5, 15, 15 },
{ 80.5, 80.5, 15, 15 },
{ 64.5, 64.5, 15, 15 },
{ 80.5, 64.5, 15, 15 },
{ 80.5, 80.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 80.5, 80.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 80.5, 64.5, 15, 15 },
{ 80.5, 80.5, 15, 15 },
{ 64.5, 80.5, 15, 15 },
{ 80.5, 80.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 80.5, 64.5, 15, 15 },
{ 80.5, 80.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 80.5, 80.5, 15, 15 },
{ 32.5, 96.5, 15, 15 },
{ 48.5, 96.5, 15, 15 },
{ 48.5, 112.5, 15, 15 },
{ 32.5, 112.5, 15, 15 },
{ 48.5, 112.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 48.5, 96.5, 15, 15 },
{ 48.5, 112.5, 15, 15 },
{ 32.5, 112.5, 15, 15 },
{ 48.5, 112.5, 15, 15 },
{ 32.5, 96.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 48.5, 112.5, 15, 15 },
{ 32.5, 112.5, 15, 15 },
{ 48.5, 112.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 48.5, 112.5, 15, 15 },
{ 32.5, 112.5, 15, 15 },
{ 48.5, 112.5, 15, 15 },
{ 0.5, 64.5, 15, 15 },
{ 80.5, 64.5, 15, 15 },
{ 80.5, 80.5, 15, 15 },
{ 0.5, 80.5, 15, 15 },
{ 80.5, 80.5, 15, 15 },
{ 32.5, 32.5, 15, 15 },
{ 48.5, 32.5, 15, 15 },
{ 48.5, 112.5, 15, 15 },
{ 32.5, 112.5, 15, 15 },
{ 48.5, 112.5, 15, 15 },
{ 0.5, 32.5, 15, 15 },
{ 16.5, 32.5, 15, 15 },
{ 0.5, 48.5, 15, 15 },
{ 16.5, 48.5, 15, 15 },
{ 0.5, 48.5, 15, 15 },
{ 0.5, 32.5, 15, 15 },
{ 16.5, 32.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 0.5, 48.5, 15, 15 },
{ 80.5, 16.5, 15, 15 },
{ 64.5, 32.5, 15, 15 },
{ 80.5, 32.5, 15, 15 },
{ 80.5, 48.5, 15, 15 },
{ 64.5, 48.5, 15, 15 },
{ 80.5, 48.5, 15, 15 },
{ 64.5, 32.5, 15, 15 },
{ 80.5, 32.5, 15, 15 },
{ 80.5, 48.5, 15, 15 },
{ 64.5, 16.5, 15, 15 },
{ 80.5, 48.5, 15, 15 },
{ 64.5, 96.5, 15, 15 },
{ 80.5, 96.5, 15, 15 },
{ 80.5, 112.5, 15, 15 },
{ 64.5, 112.5, 15, 15 },
{ 80.5, 112.5, 15, 15 },
{ 64.5, 0.5, 15, 15 },
{ 80.5, 96.5, 15, 15 },
{ 80.5, 112.5, 15, 15 },
{ 64.5, 112.5, 15, 15 },
{ 80.5, 112.5, 15, 15 },
{ 0.5, 96.5, 15, 15 },
{ 16.5, 96.5, 15, 15 },
{ 16.5, 112.5, 15, 15 },
{ 0.5, 112.5, 15, 15 },
{ 16.5, 112.5, 15, 15 },
{ 0.5, 96.5, 15, 15 },
{ 80.5, 0.5, 15, 15 },
{ 16.5, 112.5, 15, 15 },
{ 0.5, 112.5, 15, 15 },
{ 16.5, 112.5, 15, 15 },
{ 0.5, 32.5, 15, 15 },
{ 80.5, 32.5, 15, 15 },
{ 80.5, 48.5, 15, 15 },
{ 0.5, 48.5, 15, 15 },
{ 80.5, 48.5, 15, 15 },
{ 0.5, 32.5, 15, 15 },
{ 16.5, 32.5, 15, 15 },
{ 16.5, 112.5, 15, 15 },
{ 0.5, 112.5, 15, 15 },
{ 16.5, 112.5, 15, 15 },
{ 0.5, 96.5, 15, 15 },
{ 80.5, 96.5, 15, 15 },
{ 80.5, 112.5, 15, 15 },
{ 0.5, 112.5, 15, 15 },
{ 80.5, 112.5, 15, 15 },
{ 64.5, 32.5, 15, 15 },
{ 80.5, 32.5, 15, 15 },
{ 80.5, 112.5, 15, 15 },
{ 64.5, 112.5, 15, 15 },
{ 80.5, 112.5, 15, 15 },
{ 0.5, 32.5, 15, 15 },
{ 80.5, 32.5, 15, 15 },
{ 80.5, 112.5, 15, 15 },
{ 0.5, 112.5, 15, 15 },
{ 80.5, 112.5, 15, 15 },
{ 0.5, 0.5, 15, 15 },
{ 16.5, 0.5, 15, 15 },
{ 16.5, 16.5, 15, 15 },
{ 0.5, 16.5, 15, 15 }
{ 0.5, 16.5, 15, 15 },
{ 16.5, 16.5, 15, 15 }
};
extern const int autotileRectsN = sizeof(autotileRects) / sizeof(autotileRects[0]);

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -35,6 +35,10 @@ struct ScriptBinding
* function will perform a longjmp instead of returning,
* so be careful about any variables with local storage */
void (*terminate) (void);
/* Instructs the binding to issue a game reset.
* Same conditions as for terminate apply */
void (*reset) (void);
};
/* VTable defined in the binding source */

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -51,6 +51,8 @@
"Operation not supported for mega surfaces"); \
}
#define OUTLINE_SIZE 1
/* Normalize (= ensure width and
* height are positive) */
static IntRect normalizedRect(const IntRect &rect)
@ -113,6 +115,7 @@ struct BitmapPrivate
~BitmapPrivate()
{
SDL_FreeFormat(format);
pixman_region_fini(&tainted);
}
@ -125,7 +128,8 @@ struct BitmapPrivate
void clearTaintedArea()
{
pixman_region_clear(&tainted);
pixman_region_fini(&tainted);
pixman_region_init(&tainted);
}
void addTaintedArea(const IntRect &rect)
@ -217,9 +221,9 @@ struct BitmapPrivate
surf = surfConv;
}
void onModified()
void onModified(bool freeSurface = true)
{
if (surface)
if (surface && freeSurface)
{
SDL_FreeSurface(surface);
surface = 0;
@ -229,12 +233,26 @@ struct BitmapPrivate
}
};
struct BitmapOpenHandler : FileSystem::OpenHandler
{
SDL_Surface *surf;
BitmapOpenHandler()
: surf(0)
{}
bool tryRead(SDL_RWops &ops, const char *ext)
{
surf = IMG_LoadTyped_RW(&ops, 1, ext);
return surf != 0;
}
};
Bitmap::Bitmap(const char *filename)
{
SDL_RWops ops;
const char *extension;
shState->fileSystem().openRead(ops, filename, FileSystem::Image, false, &extension);
SDL_Surface *imgSurf = IMG_LoadTyped_RW(&ops, 1, extension);
BitmapOpenHandler handler;
shState->fileSystem().openRead(handler, filename);
SDL_Surface *imgSurf = handler.surf;
if (!imgSurf)
throw Exception(Exception::SDLError, "Error loading image '%s': %s",
@ -247,6 +265,7 @@ Bitmap::Bitmap(const char *filename)
/* Mega surface */
p = new BitmapPrivate(this);
p->megaSurface = imgSurf;
SDL_SetSurfaceBlendMode(p->megaSurface, SDL_BLENDMODE_NONE);
}
else
{
@ -296,21 +315,18 @@ Bitmap::Bitmap(const Bitmap &other)
p->gl = shState->texPool().request(other.width(), other.height());
blt(0, 0, &other, rect());
blt(0, 0, other, rect());
}
Bitmap::~Bitmap()
{
if (p->megaSurface)
SDL_FreeSurface(p->megaSurface);
else
shState->texPool().release(p->gl);
delete p;
dispose();
}
int Bitmap::width() const
{
guardDisposed();
if (p->megaSurface)
return p->megaSurface->w;
@ -319,6 +335,8 @@ int Bitmap::width() const
int Bitmap::height() const
{
guardDisposed();
if (p->megaSurface)
return p->megaSurface->h;
@ -327,14 +345,16 @@ int Bitmap::height() const
IntRect Bitmap::rect() const
{
guardDisposed();
return IntRect(0, 0, width(), height());
}
void Bitmap::blt(int x, int y,
const Bitmap *source, IntRect rect,
const Bitmap &source, IntRect rect,
int opacity)
{
if (!source)
if (source.isDisposed())
return;
// FIXME: RGSS allows the source rect to both lie outside
@ -343,23 +363,25 @@ void Bitmap::blt(int x, int y,
// doesn't fix anything for a direct stretch_blt call).
/* Clamp rect to source bitmap size */
if (rect.x + rect.w > source->width())
rect.w = source->width() - rect.x;
if (rect.x + rect.w > source.width())
rect.w = source.width() - rect.x;
if (rect.y + rect.h > source->height())
rect.h = source->height() - rect.y;
if (rect.y + rect.h > source.height())
rect.h = source.height() - rect.y;
stretchBlt(IntRect(x, y, rect.w, rect.h),
source, rect, opacity);
}
void Bitmap::stretchBlt(const IntRect &destRect,
const Bitmap *source, const IntRect &sourceRect,
const Bitmap &source, const IntRect &sourceRect,
int opacity)
{
guardDisposed();
GUARD_MEGA;
if (!source)
if (source.isDisposed())
return;
opacity = clamp(opacity, 0, 255);
@ -367,13 +389,45 @@ void Bitmap::stretchBlt(const IntRect &destRect,
if (opacity == 0)
return;
if (source->megaSurface())
SDL_Surface *srcSurf = source.megaSurface();
if (srcSurf && shState->config().subImageFix)
{
/* Blit from software surface, for broken GL drivers */
Vec2i gpTexSize;
shState->ensureTexSize(sourceRect.w, sourceRect.h, gpTexSize);
shState->bindTex();
GLMeta::subRectImageUpload(srcSurf->w, sourceRect.x, sourceRect.y, 0, 0,
sourceRect.w, sourceRect.h, srcSurf, GL_RGBA);
GLMeta::subRectImageEnd();
SimpleShader &shader = shState->shaders().simple;
shader.bind();
shader.setTranslation(Vec2i());
shader.setTexSize(gpTexSize);
p->pushSetViewport(shader);
p->bindFBO();
Quad &quad = shState->gpQuad();
quad.setTexRect(FloatRect(0, 0, sourceRect.w, sourceRect.h));
quad.setPosRect(destRect);
p->blitQuad(quad);
p->popViewport();
p->addTaintedArea(destRect);
p->onModified();
return;
}
else if (srcSurf)
{
/* Blit from software surface */
/* Don't do transparent blits for now */
if (opacity < 255)
source->ensureNonMega();
SDL_Surface *srcSurf = source->megaSurface();
source.ensureNonMega();
SDL_Rect srcRect = sourceRect;
SDL_Rect dstRect = destRect;
@ -390,26 +444,25 @@ void Bitmap::stretchBlt(const IntRect &destRect,
SDL_Surface *blitTemp =
SDL_CreateRGBSurface(0, destRect.w, destRect.h, bpp, rMask, gMask, bMask, aMask);
// FXIME: This is supposed to be a scaled blit, put SDL2 for some reason
// makes the source surface unusable after BlitScaled() is called. Investigate!
SDL_BlitSurface(srcSurf, &srcRect, blitTemp, 0);
SDL_BlitScaled(srcSurf, &srcRect, blitTemp, 0);
TEX::bind(p->gl.tex);
if (bltRect.w == dstRect.w && bltRect.h == dstRect.h)
{
/* Dest rectangle lies within bounding box */
TEX::uploadSubImage(destRect.x, destRect.y,
destRect.w, destRect.h,
blitTemp->pixels, GL_RGBA);
}
else
{
/* Clipped blit */
GLMeta::subRectImageUpload(blitTemp->w, bltRect.x - dstRect.x, bltRect.y - dstRect.y,
bltRect.x, bltRect.y, bltRect.w, bltRect.h, blitTemp, GL_RGBA);
GLMeta::subRectImageEnd();
}
SDL_FreeSurface(blitTemp);
p->onModified();
@ -420,7 +473,7 @@ void Bitmap::stretchBlt(const IntRect &destRect,
{
/* Fast blit */
GLMeta::blitBegin(p->gl);
GLMeta::blitSource(source->p->gl);
GLMeta::blitSource(source.p->gl);
GLMeta::blitRectangle(sourceRect, destRect);
GLMeta::blitEnd();
}
@ -436,10 +489,10 @@ void Bitmap::stretchBlt(const IntRect &destRect,
GLMeta::blitRectangle(destRect, Vec2i());
GLMeta::blitEnd();
FloatRect bltSubRect((float) sourceRect.x / source->width(),
(float) sourceRect.y / source->height(),
((float) source->width() / sourceRect.w) * ((float) destRect.w / gpTex.width),
((float) source->height() / sourceRect.h) * ((float) destRect.h / gpTex.height));
FloatRect bltSubRect((float) sourceRect.x / source.width(),
(float) sourceRect.y / source.height(),
((float) source.width() / sourceRect.w) * ((float) destRect.w / gpTex.width),
((float) source.height() / sourceRect.h) * ((float) destRect.h / gpTex.height));
BltShader &shader = shState->shaders().blt;
shader.bind();
@ -451,7 +504,7 @@ void Bitmap::stretchBlt(const IntRect &destRect,
quad.setTexPosRect(sourceRect, destRect);
quad.setColor(Vec4(1, 1, 1, normOpacity));
source->p->bindTexture(shader);
source.p->bindTexture(shader);
p->bindFBO();
p->pushSetViewport(shader);
@ -461,7 +514,6 @@ void Bitmap::stretchBlt(const IntRect &destRect,
}
p->addTaintedArea(destRect);
p->onModified();
}
@ -474,6 +526,8 @@ void Bitmap::fillRect(int x, int y,
void Bitmap::fillRect(const IntRect &rect, const Vec4 &color)
{
guardDisposed();
GUARD_MEGA;
p->fillRect(rect, color);
@ -500,6 +554,8 @@ void Bitmap::gradientFillRect(const IntRect &rect,
const Vec4 &color1, const Vec4 &color2,
bool vertical)
{
guardDisposed();
GUARD_MEGA;
SimpleColorShader &shader = shState->shaders().simpleColor;
@ -544,6 +600,8 @@ void Bitmap::clearRect(int x, int y, int width, int height)
void Bitmap::clearRect(const IntRect &rect)
{
guardDisposed();
GUARD_MEGA;
p->fillRect(rect, Vec4());
@ -553,6 +611,8 @@ void Bitmap::clearRect(const IntRect &rect)
void Bitmap::blur()
{
guardDisposed();
GUARD_MEGA;
Quad &quad = shState->gpQuad();
@ -596,6 +656,8 @@ void Bitmap::blur()
void Bitmap::radialBlur(int angle, int divisions)
{
guardDisposed();
GUARD_MEGA;
angle = clamp<int>(angle, 0, 359);
@ -689,6 +751,8 @@ void Bitmap::radialBlur(int angle, int divisions)
void Bitmap::clear()
{
guardDisposed();
GUARD_MEGA;
p->bindFBO();
@ -704,8 +768,18 @@ 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();
GUARD_MEGA;
if (x < 0 || y < 0 || x >= width() || y >= height())
@ -724,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,
@ -736,6 +808,8 @@ Color Bitmap::getPixel(int x, int y) const
void Bitmap::setPixel(int x, int y, const Color &color)
{
guardDisposed();
GUARD_MEGA;
uint8_t pixel[] =
@ -751,11 +825,22 @@ 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)
{
guardDisposed();
GUARD_MEGA;
if ((hue % 360) == 0)
@ -769,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);
@ -815,8 +897,97 @@ static std::string fixupString(const char *str)
return s;
}
static void applyShadow(SDL_Surface *&in, const SDL_PixelFormat &fm, const SDL_Color &c)
{
SDL_Surface *out = SDL_CreateRGBSurface
(0, in->w+1, in->h+1, fm.BitsPerPixel, fm.Rmask, fm.Gmask, fm.Bmask, fm.Amask);
float fr = c.r / 255.0f;
float fg = c.g / 255.0f;
float fb = c.b / 255.0f;
/* We allocate an output surface one pixel wider and higher than the input,
* (implicitly) blit a copy of the input with RGB values set to black into
* it with x/y offset by 1, then blend the input surface over it at origin
* (0,0) using the bitmap blit equation (see shader/bitmapBlit.frag) */
for (int y = 0; y < in->h+1; ++y)
for (int x = 0; x < in->w+1; ++x)
{
/* src: input pixel, shd: shadow pixel */
uint32_t src = 0, shd = 0;
/* Output pixel location */
uint32_t *outP = ((uint32_t*) ((uint8_t*) out->pixels + y*out->pitch)) + x;
if (y < in->h && x < in->w)
src = ((uint32_t*) ((uint8_t*) in->pixels + y*in->pitch))[x];
if (y > 0 && x > 0)
shd = ((uint32_t*) ((uint8_t*) in->pixels + (y-1)*in->pitch))[x-1];
/* Set shadow pixel RGB values to 0 (black) */
shd &= fm.Amask;
if (x == 0 || y == 0)
{
*outP = src;
continue;
}
if (x == in->w || y == in->h)
{
*outP = shd;
continue;
}
/* Input and shadow alpha values */
uint8_t srcA, shdA;
srcA = (src & fm.Amask) >> fm.Ashift;
shdA = (shd & fm.Amask) >> fm.Ashift;
if (srcA == 255 || shdA == 0)
{
*outP = src;
continue;
}
if (srcA == 0 && shdA == 0)
{
*outP = 0;
continue;
}
float fSrcA = srcA / 255.0f;
float fShdA = shdA / 255.0f;
/* Because opacity == 1, co1 == fSrcA */
float co2 = fShdA * (1.0f - fSrcA);
/* Result alpha */
float fa = fSrcA + co2;
/* Temp value to simplify arithmetic below */
float co3 = fSrcA / fa;
/* Result colors */
uint8_t r, g, b, a;
r = clamp<float>(fr * co3, 0, 1) * 255.0f;
g = clamp<float>(fg * co3, 0, 1) * 255.0f;
b = clamp<float>(fb * co3, 0, 1) * 255.0f;
a = clamp<float>(fa, 0, 1) * 255.0f;
*outP = SDL_MapRGBA(&fm, r, g, b, a);
}
/* Store new surface in the input pointer */
SDL_FreeSurface(in);
in = out;
}
void Bitmap::drawText(const IntRect &rect, const char *str, int align)
{
guardDisposed();
GUARD_MEGA;
std::string fixed = fixupString(str);
@ -829,12 +1000,13 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
return;
TTF_Font *font = p->font->getSdlFont();
Color *fontColor = p->font->getColor();
const Color &fontColor = p->font->getColor();
const Color &outColor = p->font->getOutColor();
SDL_Color c;
fontColor->toSDLColor(c);
SDL_Color c = fontColor.toSDLColor();
c.a = 255;
float txtAlpha = fontColor->norm.w;
float txtAlpha = fontColor.norm.w;
SDL_Surface *txtSurf;
@ -845,6 +1017,36 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
p->ensureFormat(txtSurf, SDL_PIXELFORMAT_ABGR8888);
int rawTxtSurfH = txtSurf->h;
if (p->font->getShadow())
applyShadow(txtSurf, *p->format, c);
/* outline using TTF_Outline and blending it together with SDL_BlitSurface
* FIXME: outline is forced to have the same opacity as the font color */
if (p->font->getOutline())
{
SDL_Color co = outColor.toSDLColor();
co.a = 255;
SDL_Surface *outline;
/* set the next font render to render the outline */
TTF_SetFontOutline(font, OUTLINE_SIZE);
if (shState->rtData().config.solidFonts)
outline = TTF_RenderUTF8_Solid(font, str, co);
else
outline = TTF_RenderUTF8_Blended(font, str, co);
p->ensureFormat(outline, SDL_PIXELFORMAT_ABGR8888);
SDL_Rect outRect = {OUTLINE_SIZE, OUTLINE_SIZE, txtSurf->w, txtSurf->h};
SDL_SetSurfaceBlendMode(txtSurf, SDL_BLENDMODE_BLEND);
SDL_BlitSurface(txtSurf, NULL, outline, &outRect);
SDL_FreeSurface(txtSurf);
txtSurf = outline;
/* reset outline to 0 */
TTF_SetFontOutline(font, 0);
}
int alignX = rect.x;
switch (align)
@ -865,7 +1067,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
if (alignX < rect.x)
alignX = rect.x;
int alignY = rect.y + (rect.h - txtSurf->h) / 2;
int alignY = rect.y + (rect.h - rawTxtSurfH) / 2;
float squeeze = (float) rect.w / txtSurf->w;
@ -877,11 +1079,11 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
Vec2i gpTexSize;
shState->ensureTexSize(txtSurf->w, txtSurf->h, gpTexSize);
bool fastBlit = !p->touchesTaintedArea(posRect) && txtAlpha == 1.0;
bool fastBlit = !p->touchesTaintedArea(posRect) && txtAlpha == 1.0f;
if (fastBlit)
{
if (squeeze == 1.0)
if (squeeze == 1.0f && !shState->config().subImageFix)
{
/* Even faster: upload directly to bitmap texture.
* We have to make sure the posRect lies within the texture
@ -1045,6 +1247,8 @@ static uint16_t utf8_to_ucs2(const char *_input,
IntRect Bitmap::textSize(const char *str)
{
guardDisposed();
GUARD_MEGA;
TTF_Font *font = p->font->getSdlFont();
@ -1067,7 +1271,17 @@ IntRect Bitmap::textSize(const char *str)
return IntRect(0, 0, w, h);
}
DEF_ATTR_SIMPLE(Bitmap, Font, Font*, p->font)
DEF_ATTR_RD_SIMPLE(Bitmap, Font, Font&, *p->font)
void Bitmap::setFont(Font &value)
{
*p->font = value;
}
void Bitmap::setInitFont(Font *value)
{
p->font = value;
}
TEXFBO &Bitmap::getGLTypes()
{
@ -1081,6 +1295,9 @@ SDL_Surface *Bitmap::megaSurface() const
void Bitmap::ensureNonMega() const
{
if (isDisposed())
return;
GUARD_MEGA;
}
@ -1093,3 +1310,13 @@ void Bitmap::taintArea(const IntRect &rect)
{
p->addTaintedArea(rect);
}
void Bitmap::releaseResources()
{
if (p->megaSurface)
SDL_FreeSurface(p->megaSurface);
else
shState->texPool().release(p->gl);
delete p;
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -49,11 +49,11 @@ public:
IntRect rect() const;
void blt(int x, int y,
const Bitmap *source, IntRect rect,
const Bitmap &source, IntRect rect,
int opacity = 255);
void stretchBlt(const IntRect &destRect,
const Bitmap *source, const IntRect &sourceRect,
const Bitmap &source, const IntRect &sourceRect,
int opacity = 255);
void fillRect(int x, int y,
@ -99,7 +99,11 @@ public:
IntRect textSize(const char *str);
DECL_ATTR(Font, Font*)
DECL_ATTR(Font, Font&)
/* Sets initial reference without copying by value,
* use at construction */
void setInitFont(Font *value);
/* <internal> */
TEXFBO &getGLTypes();
@ -116,6 +120,9 @@ public:
sigc::signal<void> modified;
private:
void releaseResources();
const char *klassName() const { return "bitmap"; }
BitmapPrivate *p;
};

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -53,7 +53,7 @@ public:
p.insert(PairType(key, value));
}
inline void erase(const K &key)
inline void remove(const K &key)
{
p.erase(key);
}
@ -116,6 +116,11 @@ public:
p.insert(key);
}
inline void remove(const K &key)
{
p.erase(key);
}
inline const_iterator cbegin() const
{
return p.cbegin();

View File

@ -1 +1 @@
#include "../liberation.ttf.xxd"
#include "liberation.ttf.xxd"

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -25,11 +25,15 @@
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
#include <SDL_filesystem.h>
#include <fstream>
#include <stdint.h>
#include "debugwriter.h"
#include "util.h"
#include "sdl-util.h"
#include "iniconfig.h"
#ifdef INI_ENCODING
extern "C" {
@ -118,65 +122,96 @@ static bool validUtf8(const char *string)
return true;
}
static std::string prefPath(const char *org, const char *app)
{
char *path = SDL_GetPrefPath(org, app);
if (!path)
return std::string();
std::string str(path);
SDL_free(path);
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;
#define CONF_FILE "mkxp.conf"
Config::Config()
: rgssVersion(0),
debugMode(false),
winResizable(false),
fullscreen(false),
fixedAspectRatio(true),
smoothScaling(false),
vsync(false),
defScreenW(0),
defScreenH(0),
fixedFramerate(0),
frameSkip(true),
solidFonts(false),
gameFolder("."),
anyAltToggleFS(false),
allowSymlinks(false),
pathCache(true),
useScriptNames(false)
{
midi.chorus = false;
midi.reverb = false;
SE.sourceCount = 6;
}
{}
void Config::read(int argc, char *argv[])
{
#define PO_DESC_ALL \
PO_DESC(rgssVersion, int) \
PO_DESC(debugMode, bool) \
PO_DESC(winResizable, bool) \
PO_DESC(fullscreen, bool) \
PO_DESC(fixedAspectRatio, bool) \
PO_DESC(smoothScaling, bool) \
PO_DESC(vsync, bool) \
PO_DESC(defScreenW, int) \
PO_DESC(defScreenH, int) \
PO_DESC(fixedFramerate, int) \
PO_DESC(frameSkip, bool) \
PO_DESC(solidFonts, bool) \
PO_DESC(gameFolder, std::string) \
PO_DESC(anyAltToggleFS, bool) \
PO_DESC(allowSymlinks, bool) \
PO_DESC(iconPath, std::string) \
PO_DESC(titleLanguage, std::string) \
PO_DESC(midi.soundFont, std::string) \
PO_DESC(midi.chorus, bool) \
PO_DESC(midi.reverb, bool) \
PO_DESC(SE.sourceCount, int) \
PO_DESC(customScript, std::string) \
PO_DESC(pathCache, bool) \
PO_DESC(useScriptNames, bool)
PO_DESC(rgssVersion, int, 0) \
PO_DESC(debugMode, bool, false) \
PO_DESC(printFPS, bool, false) \
PO_DESC(winResizable, bool, false) \
PO_DESC(fullscreen, bool, false) \
PO_DESC(fixedAspectRatio, bool, true) \
PO_DESC(smoothScaling, bool, true) \
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) \
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) \
PO_DESC(enableReset, bool, true) \
PO_DESC(allowSymlinks, bool, false) \
PO_DESC(dataPathOrg, std::string, "") \
PO_DESC(dataPathApp, std::string, "") \
PO_DESC(iconPath, std::string, "") \
PO_DESC(execName, std::string, "Game") \
PO_DESC(titleLanguage, std::string, "") \
PO_DESC(midi.soundFont, std::string, "") \
PO_DESC(midi.chorus, bool, false) \
PO_DESC(midi.reverb, bool, false) \
PO_DESC(SE.sourceCount, int, 6) \
PO_DESC(customScript, std::string, "") \
PO_DESC(pathCache, bool, true) \
PO_DESC(useScriptNames, bool, false)
// Not gonna take your shit boost
#define GUARD_ALL( exp ) try { exp } catch(...) {}
#define PO_DESC(key, type) (#key, po::value< type >()->default_value(key))
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;
podesc.add_options()
@ -190,32 +225,39 @@ void Config::read(int argc, char *argv[])
po::variables_map vm;
/* Parse command line options */
po::parsed_options cmdPo =
po::command_line_parser(argc, argv).options(podesc)
.allow_unregistered()
.run();
try
{
po::parsed_options cmdPo =
po::command_line_parser(argc, argv).options(podesc).run();
po::store(cmdPo, vm);
}
catch (po::error &error)
{
Debug() << "Command line:" << error.what();
}
GUARD_ALL( po::store(cmdPo, vm); )
/* Parse configuration file (mkxp.conf) */
std::ifstream confFile;
confFile.open("mkxp.conf");
/* Parse configuration file */
SDLRWStream confFile(CONF_FILE, "r");
if (confFile)
{
GUARD_ALL( po::store(po::parse_config_file(confFile, podesc, true), vm); )
try
{
po::store(po::parse_config_file(confFile.stream(), podesc, true), vm);
po::notify(vm);
}
catch (po::error &error)
{
Debug() << CONF_FILE":" << error.what();
}
}
confFile.close();
po::notify(vm);
#undef PO_DESC
#define PO_DESC(key, type) GUARD_ALL( key = vm[#key].as< type >(); )
#define PO_DESC(key, type, def) GUARD_ALL( key = vm[#key].as< type >(); )
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>(); );
@ -229,6 +271,11 @@ void Config::read(int argc, char *argv[])
rgssVersion = clamp(rgssVersion, 0, 3);
SE.sourceCount = clamp(SE.sourceCount, 1, 64);
if (!dataPathOrg.empty() && !dataPathApp.empty())
customDataPath = prefPath(dataPathOrg.c_str(), dataPathApp.c_str());
commonDataPath = prefPath(".", "mkxp");
}
static std::string baseName(const std::string &path)
@ -241,35 +288,61 @@ static std::string baseName(const std::string &path)
return path.substr(pos + 1);
}
static void setupScreenSize(Config &conf)
{
if (conf.defScreenW <= 0)
conf.defScreenW = (conf.rgssVersion == 1 ? 640 : 544);
if (conf.defScreenH <= 0)
conf.defScreenH = (conf.rgssVersion == 1 ? 480 : 416);
}
void Config::readGameINI()
{
if (!customScript.empty())
{
game.title = baseName(customScript);
if (rgssVersion == 0)
rgssVersion = 1;
setupScreenSize(*this);
return;
}
po::options_description podesc;
podesc.add_options()
("Game.Title", po::value<std::string>())
("Game.Scripts", po::value<std::string>())
;
std::string iniFilename = execName + ".ini";
SDLRWStream iniFile(iniFilename.c_str(), "r");
std::string iniPath = gameFolder + "/Game.ini";
if (iniFile)
{
INIConfiguration ic;
if(ic.load(iniFile.stream()))
{
GUARD_ALL( game.title = ic.getStringProperty("Game", "Title"); );
GUARD_ALL( game.scripts = ic.getStringProperty("Game", "Scripts"); );
std::ifstream iniFile;
iniFile.open((iniPath).c_str());
strReplace(game.scripts, '\\', '/');
po::variables_map vm;
GUARD_ALL( po::store(po::parse_config_file(iniFile, podesc, true), vm); )
po::notify(vm);
if (game.title.empty())
{
Debug() << iniFilename + ": Could not find Game.Title property";
}
iniFile.close();
GUARD_ALL( game.title = vm["Game.Title"].as<std::string>(); );
GUARD_ALL( game.scripts = vm["Game.Scripts"].as<std::string>(); );
strReplace(game.scripts, '\\', '/');
if (game.scripts.empty())
{
Debug() << iniFilename + ": Could not find Game.Scripts property";
}
}
else
{
Debug() << iniFilename + ": Failed to parse ini file";
}
}
else
{
Debug() << "FAILED to open" << iniFilename;
}
#ifdef INI_ENCODING
/* Can add more later */
@ -355,9 +428,5 @@ void Config::readGameINI()
}
}
if (defScreenW <= 0)
defScreenW = (rgssVersion == 1 ? 640 : 544);
if (defScreenH <= 0)
defScreenH = (rgssVersion == 1 ? 480 : 416);
setupScreenSize(*this);
}

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -24,12 +24,14 @@
#include <string>
#include <vector>
#include <set>
struct Config
{
int rgssVersion;
bool debugMode;
bool printFPS;
bool winResizable;
bool fullscreen;
@ -39,18 +41,29 @@ struct Config
int defScreenW;
int defScreenH;
std::string windowTitle;
int fixedFramerate;
bool frameSkip;
bool syncToRefreshrate;
bool solidFonts;
bool subImageFix;
bool enableBlitting;
int maxTextureSize;
std::string gameFolder;
bool anyAltToggleFS;
bool enableReset;
bool allowSymlinks;
bool pathCache;
std::string dataPathOrg;
std::string dataPathApp;
std::string iconPath;
std::string execName;
std::string titleLanguage;
struct
@ -68,19 +81,29 @@ 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;
std::vector<std::string> rubyLoadpaths;
/* Editor flags */
struct {
bool debug;
bool battleTest;
} editor;
/* Game INI contents */
struct {
std::string scripts;
std::string title;
} game;
/* Internal */
std::string customDataPath;
std::string commonDataPath;
Config();
void read(int argc, char *argv[]);

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -26,6 +26,11 @@
#include <sstream>
#include <vector>
#ifdef __ANDROID__
#include <android/log.h>
#endif
/* A cheap replacement for qDebug() */
class Debug
@ -56,7 +61,11 @@ public:
~Debug()
{
std::clog << buf.str() << std::endl;
#ifdef __ANDROID__
__android_log_write(ANDROID_LOG_DEBUG, "mkxp", buf.str().c_str());
#else
std::cerr << buf.str() << std::endl;
#endif
}
private:

View File

@ -3,7 +3,7 @@
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -22,71 +22,76 @@
#ifndef DISPOSABLE_H
#define DISPOSABLE_H
#include "intrulist.h"
#include "exception.h"
#include "sharedstate.h"
#include "graphics.h"
#include <assert.h>
#include <sigc++/signal.h>
#include <sigc++/connection.h>
class Disposable
{
public:
~Disposable()
Disposable()
: disposed(false),
link(this)
{
shState->graphics().addDisposable(this);
}
virtual ~Disposable()
{
shState->graphics().remDisposable(this);
}
void dispose()
{
if (disposed)
return;
releaseResources();
disposed = true;
wasDisposed();
}
sigc::signal<void> wasDisposed;
};
/* A helper struct which monitors the dispose signal of
* properties, and automatically sets the prop pointer to
* null. Can call an optional notify method when prop is
* nulled */
template<class C, typename P>
struct DisposeWatch
{
typedef void (C::*NotifyFun)();
DisposeWatch(C &owner, P *&propLocation, NotifyFun notify = 0)
: owner(owner),
notify(notify),
propLocation(propLocation)
{}
~DisposeWatch()
bool isDisposed() const
{
dispCon.disconnect();
return disposed;
}
/* Call this when a new object was set for the prop */
void update(Disposable *prop)
sigc::signal<void> wasDisposed;
protected:
void guardDisposed() const
{
dispCon.disconnect();
if (!prop)
return;
dispCon = prop->wasDisposed.connect
(sigc::mem_fun(this, &DisposeWatch::onDisposed));
if (isDisposed())
throw Exception(Exception::RGSSError,
"disposed %s", klassName());
}
private:
/* The object owning the prop (and this helper) */
C &owner;
/* Optional notify method */
const NotifyFun notify;
/* Location of the prop pointer inside the owner */
P * &propLocation;
sigc::connection dispCon;
virtual void releaseResources() = 0;
virtual const char *klassName() const = 0;
void onDisposed()
{
dispCon.disconnect();
propLocation = 0;
friend class Graphics;
if (notify)
(owner.*notify)();
}
bool disposed;
IntruListLink<Disposable> link;
};
template<class C>
inline bool
nullOrDisposed(const C *d)
{
if (!d)
return true;
if (d->isDisposed())
return true;
return false;
}
#endif // DISPOSABLE_H

Some files were not shown because too many files have changed in this diff Show More