Used for the treasure chest opening effect in Rance Quest.
Implemented using draw_plugin. The render() method of draw_plugin is no
longer dedicated to custom sprites, but can be used for any sprites to
override the default sprite rendering function.
It is called when the plugin is unbound from a sprite, or when the
sprite to which the plugin is bound is released.
This prevents memory leaks when sprites are destroyed without the plugin
being released, and simplifies lifetime management of the DrawDungeon
plugin.
It draws a quadrilateral with arbitrary vertex and texture coordinates.
This is used to properly implement DrawGraph.DrawDeformedSpriteBilinear,
and will be used to implement ChipmunkSpriteEngine.
SP_SetSpriteTransformPos in a subsequent patch.
- Add support for setBreakpoints request
- Add source locations to stackTrace response
- Source-level stepIn/stepOut/next executions
All of these only work if debug information is available. Otherwise they
work at the instruction level as before.
In SACT2, if two sprites have the same Z value, they are rendered in
increasing order of their sprite numbers. This behavior is documented in
the SDK manual.
However, in later versions of the sprite engine (SACTDX,
StoatSpriteEngine, ChipmunkSpriteEngine), sprites are drawn in the order
they were created.
This fixes an issue in Rance Quest Magnum which relies on this behavior.
This setting has a significant impact on system load, so users may want
xsystem4 to remember their preference.
This implementation uses a JSON format, while the AliceSoft's
implementation saves it to a binary file (WindowSetting.sav).
This only records the wait_vsync setting, since the other fields in
window_settings are currently no-op.
Before this, the resume save format defaulted to JSON, which could not
be loaded by System40.exe and save/load was sometimes too slow even on
desktop environments.
In xsystem4-android the RSM format has been the default for 9 months and
no problems have been reported. Let's make this the default on all
platforms.
This adds source-level debugging capabilities to the command-line
debugger, utilizing debug information generated by sys4dc. The debug
information format is documented at:
https://github.com/kichikuou/sys4dc/blob/master/docs/debug_info.md
The location of the debug information file can be specified with the
`--debug-info` command-line flag. If not specified, xsystem4 will
attempt to load it from `gamedir_path("src/debug_info.json")`.
When debug information is available, a breakpoint can be set at a
specific line in a file using `breakpoint <file> <line>`. Also, `step`
and `next` commands advance execution to the next source line (this is
naively implemented by repeating instruction-level stepping).
Used in Tsuma Shibori, and some indie System 4 games.
This HLL is a draw plugin that uses SACT2's "custom sprite" mechanism.
Custom sprites do not have a texture. Instead, the plugin's render()
callback draws them directly to the main surface.
Before this, the BoneTransforms uniform block consumed
(4 * 4 * sizeof(float) * MAX_BONES) = 19712 bytes, which exceeds 16384,
the minimum possible value of GL_MAX_UNIFORM_BLOCK_SIZE in OpenGL ES
3.2.
Since the bone matrices are affine, we can drop the 4th rows and pack
them into a mat4x3 array. Now the BoneTransforms block is 14784 bytes
and it should work with all OpenGL ES 3.2 implementations.
In TapirEngine, the following lighting features are not used:
- global ambient
- directional lights
- specular lights
- rim lights
- fog
(The setters / getters for these parameters are still there, but they
don't affect rendering.)
This implementation disables those features in GLSL using #ifdefs. The C
code that sets up the lighting remains almost unchanged --
glGetUniformLocation() will return -1 if the specified uniform variable
name is not found, and glUniform*(-1, ...) will be no-op.
It is exposed through StoatSpriteEngine functions, and is normally only
visible when the game's debug mode is enabled. It's very useful for
checking graphics performance.
This is the maximum number of bones in a model for Rance Quest
(pasuteru_full.POL).
Now bone transform matrices are stored in a uniform buffer object,
because its size exceeds GL_MAX_VERTEX_UNIFORM_COMPONENTS in iOS Safari.
Collision detection is based on a mesh named "collision" in the map's 3D
model. The "collision" mesh specifies the area in which the character
can move in the xz plane, and the y coordinate represents the height of
the map at that point.
Now cglm 0.9.2 is required, for 2D AABB operations.
This is used for collision detection between a map object and the player
character. The current implementation is very simple, only performing
AABB intersection tests, but it is enough to allow the player to walk
around the first dungeon in Rance Quest.
V5 is used until Daiteikoku, and v7 since Rance Quest. Since both are
Ain v6, the save version is determined by the presence of the "MainVM"
field in AliceStart.ini.
Notable changes:
* The numerator / denominator parameters of AddMotion[HV]GaugeRate are
int in GoatGUIEngine but float in GUIEngine and PartsEngine.
* AnteaterADVEngine.ADVLogList_AddText has second parameter
(int WindowNo) since Oyako Rankan.
This also avoids using non-void functions where a void function is
expected. It is fine in most ABIs, but raises a runtime error in wasm32.
It is currently only used to populate a field in RSM v9 save file.
As far as I can tell from examining Rance 01's resume save, this
reference does not seem to increment the target's refcount.
Use the normal effect system for fullscreen effects. This allows effects
that are implemented via shaders to be used, such as the blind effects
which are used frequently in Daibanchou.
Delegates "weakly" reference objects, meaning that referenced objects
can be deleted. Delegate invocations must not invoke on deleted objects.
This is achieved as follows:
* Each heap object has a sequential number.
* Each delegate object is backed by a page storing (object, function,
seq) triples.
* Deleted objects can be detected by comparing the sequential number
stored in the delegate with the sequential number of the object
currently on the heap.
This is consistent with the AliceSoft's implementation (presumed from
the contents of resume save).
This implementation removes dead objects from the delegate in DG_CALL
and DG_NUMOF instructions. (We could do that more often, e.g. when an
object is added to a delegate.)
This breaks existing resume saves that contain delegates. For games that
predate delegate support, this does not affect the save format.
This reverts the following commits:
* 4b1257f "Fix delegate memory management"
* 9bb4665 "Add changes to vm.h" (partial revert)
* 75d6386 "Fix ResumeSave/ResumeLoad bugs with delegates" (partial
revert)
We are going to take a different approach to implementing weak
references in delegates.
Add an option to insert a delay when skipping messages with CTRL.
This is accomplished by overriding the 'A' function. Since the function
to check the state of a key (CTRL in this case) varies by game, an
xsystem4-specific system call is added for this purpose.
Fixes#119
gfx_render_text uses floats for layout, so the parts_text layout should
use floats to match.
This fixes an issue with off-center text in the English version of Rance
01.
This adds a new parameter `blend` to `gfx_draw_glyph()`. When `blend` is
true, the function performs normal alpha blending (same as
`gfx_draw_glyph_to_pmap()`).
If `blend` is false, the resulting pixel color will be the text color
and the alpha value will be copied from the glyph texture. However, if
the alpha value is less than 0.01, the pixel will not be written.
If you are drawing on a transparent texture (which will later be blended
into another texture), `blend` should be false. If you are drawing on top
of an image, `blend` should be true.
`gfx_draw_glyph()` used to fill transparent pixels with text color, but
this step is no longer needed and has been removed.
== Handles
As a general pattern, these libraries have an interface based on integer
handles allocated by Open() and released by Close(); in the AliceSoft's
implementation, handles are pointers to internal objects. Note that:
* 0 is used to represent an invalid handle, and
* Small numbers cannot be handles. For example, Mamanyonyo has code that
treats an integer as a CG number if it is less than 10000, and as a
surface handle otherwise.
In this patch, handles are generated using id_pool.h functions. In order
to achieve the above, the interface is extended so that the minimum ID
value can be specified (the `base` parameter of id_pool_init()).
== Graphics System
Surface objects (implemented in vmSurface.[ch]) plays a central role in
Mamanyonyo's graphics system, and the sprite system (vmSprite.c) is
implemented on top of it. vmSprite.c uses scene.h functions.
== vmChrLoader and vmMapLoader
Since Mamanyonyo's character data format is the same as Widenyo's,
the ChrLoader code has been refactored and used from vmChrLoader.c.
On the other hand, MapLoader and vmMapLoader do not share code because
the map file format is different from Widenyo.