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.
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.
- 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.
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.
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.
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.
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.
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
Fixes Window_NameBox visual appearance in Skyborn.
Also nuke the second SceneElement constructor that has been
obsolete since the Tilemap mapViewport rewrite.
Setup active RGSS version at runtime. Desired version can be
specified via config, or as default, auto detected from the game
files. This removes the need to build specifically for each
version, which should help packaging a lot.
This also greatly reduces the danger of introducing code that
wouldn't compile on all RGSS version paths (as certain code paths
were completely ifdef'd out).
This can be optimized more, eg. not compiling shaders that aren't
needed in the active version.
If no source is free, instead of seizing the lowest priority one,
first try to find the lowest priority source with the same buffer
that is about to be played and use it. Otherwise, take lowest priority
one as before.
Removes the need to manually convert the Game.ini to UTF-8 every
time with eg. Japanese games. Also, setting the window title on
OSX with invalid UTF-8 crashes.
This functionality and the dependency on libiconv and libguess
are optional and can be enabled with `CONFIG+=INI_ENCODING`.
If turned off and invalid UTF-8 is encountered, the game title
is treated as being empty (ie. the folder name is used instead).
Replacement: ZLayer
I'd really have loved to have used something alluding to physical
roof tiles (as that's the closest image I have to them), but without
reusing the word "tiles".. yeah, impossible.
Instead of replicating the RGSS Disposable interface in C++
and merely binding it, redefine the 'disposed' state as the
entire core object being deleted (and the binding object's
private pointer being null).
This makes the behavior more accurate in regard to RMXP.
It is now for example possible to subclass disposable classes
and access their 'dispose'/'disposed?' methods without
initializing the base class first (because the internal pointer
is simply null before initialization). Accessing any other
base methods will still raise an exception.
There are some quirks and irregular behavior in RMXP; eg.
most nullable bitmap attributes of disposable classes
(Sprite, Plane etc.) can still be queried afterwards, but
some cannot (Tilemap#tileset), and disposing certain
attributes crashes RMXP entirely (Tilemap#autotiles[n]).
mkxp tries to behave as close possible, but will be more
lenient some circumstances.
To the core, disposed bitmap attributes will look
identically to null, which slightly diverges from RMXP
(where they're treated as still existing, but aren't drawn).
The Disposable interface has been retained containing a
single signal, for the binding to inform core when
objects are disposed (so active attributes can be set to null).
This adds a new dependency with libfuildsynth. MIDI support
is built by default, but can be disabled if not desired.
All RTP songs should work well, but there are known problems
with other files (see README). Also, the pitch shift implementation
is somewhat poor and doesn't match RMXP (at least subjectively).
A soundfont is not included and must be provided by
the user themself.
This bug occured when starting playback of a stream, then immediately
stopping it, loading a different source, and starting playback again.
The real issue was that in stopStream(), the streaming thread had
not even queued anything yet, so it first decoded some data, then
started playing the source (which had already been stopped in the main
thread), and then finally saw the term request and stopped.
Instead stopping the source after the thread has definitely
terminated fixed the problem.
Very rarely rogue buffers would remain and play on loop on song
switch because we only ever cleared processed, not queued, buffers
from the source.
The correct way to completely clear a source's queue is to
simply attach a null buffer to it.