This matches RGSS's behavior should an Audio method be called for a non-existent file, and prevents a segfault if an attempt raises an error and then play is called again for the previously playing file.
As part of this fix, we're now storing the SDL_RWops for audio streams directly in the source structs.
This commit removes the multiplication of all OpenAL output by 0.8 added
by 4560589e25 because I feel like the 0.8
factor served no purpose other than to fix perceived problems with the
volume scale, which the commit that this pull request is part of is
supposed to address. Feel free to revert this commit if it turns out the
0.8 factor served some other purpose.
In RGSS, uninitialized disposable objects (and Fonts, sort of) are technically disposed, and other objects (Tone, Color, Rect, and Table) are created with all values set to 0. It's also possible to reinitialize them, although reinitializing disposables leaks memory.
This commit causes MiniFFI and FileInt objects to improperly raise disposed errors if used while uninitialized, but that feels acceptable to me.
While this does close small memory leaks, this is mostly for threading reasons. We're not supposed to call rb_raise with the gvl released, and calling rb_raise prevents GFX_UNLOCK from being called, which would cause problems for any games that want to call graphical operations in multiple threads should the user reset.
We're also now calling Graphics.__reset__ and Audio.__reset__ via eval instead of directly calling the functions, in case a game wants to hook them.
Without these blocks the strings aren't released until the thread that created them is closed, which means file accesses especially leak memory.
Also refocus the game when closing the keybindings window on macOS.
rb_raise calls longjmp, which bypasses C++ destructors, and also keeps the error for catch blocks from being unallocated if passed by reference, which we do for exceptions.
Some of the calls I left can still jump out of try blocks, which you're not supposed to do, but there shouldn't be any objects with destructors initialized at those points so it's probably fine.
If game devs want to use framerates outside of Enterbrain's arbitrary
restrictions, there's no reason for us to prevent it. Same reason we
don't restrict the resolution.
Fixes https://github.com/mkxp-z/mkxp-z/issues/64
PhysicsFS supports disabling symlinks, but this is intended for
environments where scripts are sandboxed. Since mkxp-z runs Ruby code
unsandboxed, this doesn't yield any practical security benefit for us.
It's currently not (much of) a problem because few or no games use multiple threads, but I believe that ruby can run its garbage collector while the GVL is released, which means that Graphics.update and Graphics.wait are currently not thread safe.
Moving the call to GFX_LOCK into dispose() should fix this.
Path caching and atlas dumping incur a nontrivial performance hit, so it's
useful to log that they're happening so that users are reminded to disable
them if they were enabled accidentally.