Commit Graph
929 Commits
Author SHA1 Message Date
kichikuou f0a54b337d DrawDungeon14: Fix LoadWalkData and SaveWalkData
They were broken by commit 5ed05ba.
2025-08-09 14:28:41 +09:00
kichikuou 80f4246095 DrawDungeon.LoadWalkData should return true when data is not found
Returning false causes system.Error() in Rance 6.
2025-08-09 14:28:41 +09:00
Nunuhara Cabbage b71b61c1d6 Improve detection of MG version of Sengoku Rance
Fixes #241
2025-07-30 17:47:01 -07:00
Nunuhara Cabbage 8c791db5d4 Fix text overlap bug in Haruka
Fixes #252
2025-07-30 17:41:32 -07:00
Nunuhara Cabbage aeb5dbb08c Merge pull request #259 from kichikuou/global-dtors
Dungeons & Dolls: Call global variable destructors on exit
2025-07-21 21:39:38 -07:00
Nunuhara Cabbage 9db75ab870 Merge pull request #258 from kichikuou/circular-scene-buffer
AnteaterADVEngine: Change `scenes` to a circular buffer
2025-07-21 21:38:15 -07:00
kichikuou d57c8cc9f4 Dungeons & Dolls: Call global variable destructors on exit
Early versions of System4 (Sys42VM.dll < 3.0) execute destructors for
global variables on exit.

Dungeons & Dolls saves its game state in the destructors of global
variables (~CDataDoll(), ~CDataItem(), ~CDataMain()), so the game was
not saved in xsystem4 before this.

This behavior has some quirks:
 * Destructors for variables on the call stack are not called on exit.
 * Destructors are called in the reverse order of the global variable
   declarations.
 * Inside a destructor, it is possible to access another global variable
   whose destructor has already been called (!).

Since this is a problematic behavior that was removed in later versions
of Sys42VM, let's add minimal support for it as a game-specific hack.
2025-07-21 13:32:54 +09:00
kichikuou e68c41a0b9 AnteaterADVEngine: Change scenes to a circular buffer
Following the implementation of `logs` (#220), `scenes` is now also
implemented as a circular buffer. This ensures that when the number of
saved scenes reaches a certain limit (500), the oldest scenes are
automatically discarded.
2025-07-21 12:35:47 +09:00
kichikuou fbd105b697 DrawDungeon2: Implement pathfinding functions 2025-07-14 20:51:44 +09:00
kichikuou 3c7634522a DrawDungeon2: Use special event marker for boss floors 2025-07-14 16:51:59 +09:00
kichikuou 5ed05ba685 DrawDungeon2: Fix 2D map 2025-07-14 16:51:59 +09:00
kichikuou 11fe6f6dda DrawDungeon2: Do not use skybox 2025-07-14 16:51:59 +09:00
kichikuou 3057c2a96b DrawDungeon2: Load textures from Texture.dtl file
Texture.dtl contains multiple sets of wall, floor, and ceiling texture
images. dtx_load_from_dtl() randomly selects a texture set using the
floor number as the random seed and returns it as a dtx structure.
2025-07-14 16:51:59 +09:00
kichikuou 5041d817d1 Dungeons & Dolls: Implement DrawDungeon2 HLL
In DrawDungeon2, dungeons are generated randomly using a dedicated
random number generator (mtrand43.c), which is a Mersenne Twister with
N=4, M=3.

The entry point for map generation is dgn_generate_drawdungeon2(),
which deterministically generates a floor map using the floor number as
the random seed.

I verified that generated floor layout, player starting position,
exit, and treasure chest locations match the original DrawDungeon2.dll
up to the 1000th floor.
2025-07-14 16:51:32 +09:00
Nunuhara Cabbage cb4e44a551 Merge pull request #256 from kichikuou/dtor
Do not call destructors for structs passed by value to HLL functions
2025-07-13 08:27:33 -07:00
kichikuou 7dc6760928 Do not call destructors for structs passed by value to HLL functions
Some classes in Dungeons & Dolls serialize themselves using
`File.Write(this)` in their destructors. Because `File.Write` takes the
argument by value, a copy of `this` is created. If the destructor is
called on the copied `this`, it falls into an an infinite loop.
2025-07-13 13:48:30 +09:00
kichikuou e1ca00a27b Implement Array HLL
This HLL defines numerous functions, but only two are used in
Dungeons & Dolls: NV_eneq and NV_sceq.
2025-07-13 12:54:56 +09:00
kichikuou 7989ffc542 Implement CalcTable HLL
It provides 64-bit calculation functions with virtual registers.

While the original CalcTable.dll accumulates instructions and executes
them with CalcTable.Run(), this implementation performs calculations on
the fly. This simplification is possible because Run() is only called
with loop=1.
2025-07-13 12:49:34 +09:00
kichikuou 55a214553a Add message box for system.Error()
`system.Error()` is used for critical errors, so its message should be
presented to the user.

This makes system.Error() show a message box, allowing users to choose
between stopping execution or continuing.
2025-07-11 11:39:12 +09:00
kichikuou c86977ad1b 3d: Ensure shader fragment ends with a newline
The `defines` string in load_shader() is prepended to the glsl file, but
it was not terminated with a newline, so the resulting shader source
looked like this:

    #define REIGN_ENGINE 0
    #define TAPIR_ENGINE 1
    #define ENGINE 1/* Copyright (C) ...
     *
     * This program is free software; ...
    ...

This confused some OpenGL ES implementations, causing a syntax error.
https://github.com/kichikuou/xsystem4-android/issues/15
2025-06-24 18:34:46 +09:00
Nunuhara Cabbage ffb9fbae31 Silence spurious warnings
None of these are actual bugs as far as I can tell.
2025-06-23 19:04:52 -07:00
Nunuhara Cabbage 3ef7ce926b Merge pull request #249 from brombrom-hani/master
SystemService: Implement playing manual
2025-06-23 18:27:18 -07:00
Brombrom Hani 152af8685f Remove percent_encode from the compilation on windows 2025-06-23 13:09:20 +02:00
Brombrom Hani c5d6afdd08 Fix manual opening on Windows by conditionally applying percent encoding
- Only apply percent encoding on non-Windows platforms in OpenPlayingManual
- Windows uses ShellExecuteW which doesn't work with percent-encoded paths
- Unix platforms still use percent encoding for proper URL handling
- Fixes manual opening functionality on Windows systems
2025-06-23 13:03:50 +02:00
Brombrom Hani 9d6861b10b Add percent encoding for manual file paths in OpenPlayingManual
- Add percent_encode() function to properly encode URLs for SDL_OpenURL
- Removed not needed null check on filename
- Update SystemService_OpenPlayingManual to use percent encoding on file paths
2025-06-23 11:54:31 +02:00
Brombrom Hani c7ba379173 Fix file:// URL formatting for cross-platform compatibility
Use file:/// prefix on Windows and file:// on Unix-like systems.
Windows paths need the extra slash since they don't start with /.
2025-06-23 00:13:37 +02:00
Brombrom Hani f4d4e8f90a Implement open playing manual 2025-06-22 16:37:35 +02:00
kichikuou 117c72cf09 3d: Implement texture animation
Skinned models can have multiple texture images for animation. When a
material colormap in the .pol file is `image.png`, additional images are
stored with names like `image[1].png`, `image[2].png`, etc.

Animation frame information is stored in `<motion_name>.txa` file. This
is a text file containing newline-separated integers, specifying the
texture index for each motion frame.
2025-06-21 16:55:24 +09:00
kichikuou 3577079a04 3d: Do not draw shadow on transparent or sprite objects
This fixes mapT_0a.POL in Rance Quest.
2025-06-21 06:40:15 +09:00
kichikuou 8d120b8a4d 3d: Avoid zero division in update_motion() 2025-06-16 11:43:26 +09:00
kichikuou e2440a5a44 Implement TapirEngine.SetInstanceMeshShow 2025-06-16 11:43:26 +09:00
kichikuou bba3f96a1b opr: All meshes are selected by default 2025-06-16 11:43:26 +09:00
Nunuhara Cabbage 8730475f1c Merge pull request #246 from kichikuou/parts
PE_SetPartsCG_by_string_index: Accept `<save>` path
2025-06-15 18:43:49 -07:00
kichikuou 92322c27f0 PE_SetPartsCG_by_string_index: Accept <save> path
The custom characters feature in Rance Quest calls GoatGUIEngine.
SetPartsCG() with a name like "<save>SaveData\\顔CG\\filename.png",
which must be resolved with the save directory.
2025-06-15 09:37:28 +09:00
kichikuou 50cb0f8063 Fix bool return value of HLL functions
Since bool functions return a 1-byte value, the value of the upper 24
bits of r.i after ffi_call is undefined.

This actually led to a bug where PassRegister.ExistText returned
incorrect values on Windows x64.
2025-06-15 08:30:40 +09:00
Nunuhara Cabbage 13e76f67b3 Merge pull request #244 from kichikuou/parts
Implement GoatGUIEngine.AddDrawRectToPartsConstructionProcess
2025-06-14 13:04:14 -07:00
Nunuhara Cabbage 37f1bc2723 Merge pull request #243 from kichikuou/InputString
Implement InputString.Inputs and InputString.Converts
2025-06-14 13:03:34 -07:00
kichikuou c70e5e028e Implement GoatGUIEngine.AddDrawRectToPartsConstructionProcess
Used in Rance Quest.
2025-06-14 15:37:35 +09:00
kichikuou a4b4e7f5bb Implement InputString.Inputs and InputString.Converts
Used in Rance Quest.

Presumably, Inputs() returns true when there is unconverted text in IME,
and Converts() returns whether the user is in the conversion phase of
IME input.

SDL text input API cannot distinguish them, so in this implementation
both return true when there is uncommitted text.
2025-06-14 08:41:24 +09:00
kichikuou 9ccc4ab0c7 parts: Implement PE_AddWholeMotionVibrationSize
It vibrates the whole screen. To implement this, this introduces a
global motion list and parts_set_global_pos(), which sets the position
of the root of the parts tree.
2025-06-10 09:35:11 +09:00
kichikuou 929a2dd3e7 3d: Draw transparent objects before outlines
Otherwise, the background of transparent objects with outlines (e.g.
hitotsurei01.POL) are filled with the outline color.
2025-06-04 10:23:03 +09:00
kichikuou b5b92bc367 3d: Add ALPHA_MAP_TEST mode
It does alpha testing using alpha map texture.
2025-06-02 07:25:38 +09:00
kichikuou e5fadf2b73 TapirEngine: Correctly implement MeshPart in .opr parser
`MeshPart = "str"` sets the attribute to all meshes whose name contains
`str`.
2025-06-02 07:25:38 +09:00
kichikuou 2713290ac9 TapirEngine: Add support for BlendMode = Add opr attribute 2025-06-02 07:25:37 +09:00
kichikuou 378450c625 Implement TapirEngine.OptimizeInstancePathLine
It simplifies the path calculated by TapirEngine.FindInstancePath() by
removing unnecessary points.
2025-05-30 07:43:15 +09:00
kichikuou 919b86916c TapirEngine: Implement pathfinding functions
TapirEngine.FindInstancePath() takes a starting point and an end point
and executes the A* algorithm on the collision mesh. The resulting path
can be obtained with TapirEngine.GetInstancePathLine().
2025-05-30 07:43:11 +09:00
kichikuou 6fbd147c54 Implement TapirEngine.CalcPathFinderIntersectEyeVec
It returns the position on the collision mesh corresponding to the mouse
coordinates.
2025-05-26 10:06:13 +09:00
kichikuou 7e584c5fd2 Fix overlapping text issue in MangaGamer Sengoku Rance
This fixes https://github.com/kichikuou/xsystem4-android/issues/12.

This game uses DrawGraph.FillAMap() to erase text drawn on the sprite,
but our SengokuRanceFont implementation draws text on sp->text.texture.

For a detailed analysis of this issue and other possible solutions, see
https://github.com/nunuhara/xsystem4/issues/237.
2025-05-24 09:10:25 +09:00
Nunuhara Cabbage b0c7aad6c3 Merge pull request #236 from kichikuou/world_transform
gfx: Remove world_transform from struct texture
2025-05-21 06:07:34 -07:00
kichikuou 724bbcdfdd 3d: Disable light mapping for meshes without light_uv 2025-05-21 07:44:15 +09:00