re: document SYS4INI logical resolution settings

This commit is contained in:
gamer147
2026-07-24 14:07:57 -04:00
parent e46d64ecc6
commit 4ebe861b79
5 changed files with 39 additions and 5 deletions

View File

@@ -99,8 +99,8 @@ Struct `EngineCtx`, size `0xa1000`. Applied to the Ghidra `/v2` image (dispatch-
| `0x9c660` | `sys4ini_records` | `void*` | SYS4INI 80-byte record base at embedded FileDB+0x414; record = base + id*0x50 |
| `0x9f274` | `mounted_aai_catalogs` | `void*` | base of 256-entry selector-keyed AAI catalog-pointer table inside the embedded FileDB; op 0x143 scans slots 1..255 from +0x9f278 |
| `0x9f278` | `mounted_aai_catalog_selector_1` | `void*` | selector-one cell and op 0x143 scan start; subsequent dwords are selector 2..255 |
| `0xa0cc0` | `screen_w` | `int` | screen width (640) |
| `0xa0cc4` | `screen_h` | `int` | screen height (480) |
| `0xa0cc0` | `screen_w` | `int` | logical screen width; constructor/default registry uses 640, then the SYS4INI SCREENX setting overrides it (Himegari 800) |
| `0xa0cc4` | `screen_h` | `int` | logical screen height; constructor/default registry uses 480, then the SYS4INI SCREENY setting overrides it (Himegari 600) |
| `0xa0cc8` | `screen_bpp` | `int` | screen bpp (8) |
| `0xa0ce4` | `run_state_flags` | `uint` | interpreter run-state flags (bit1 sleeping; 0x8000000 skip/fast-forward) |
| `0xa0ce8` | `timed_callback_abort_signal` | `int` | scheduler-polled abort/input signal cleared when op 0xd5 starts; redirects to abort PC when configured |

View File

@@ -146,6 +146,24 @@ decompile `ctx->cur_ctx_index` / `ctx->frame_instruction_word_count` / `ctx->run
## Findings
### Logical screen dimensions come from the SYS4INI settings trailer (resolved 2026-07-24)
AGE has a compiled fallback, but the shipped game's logical resolution is data-driven. Engine construction
at `0x413860` initializes `EngineCtx.screen_w/screen_h` to `640x480`, and
`engine_settings_register_defaults@0x46be30` independently registers `set:WinX=640` and
`set:WinY=480`. During `engine_load_sys4ini_and_mount_append_catalogs@0x4099f0`, the loader advances past
the archive/file directory and VM-bank metadata into the remaining SYS4INI data, then calls
`engine_apply_sys4ini_settings@0x4056d0`. That routine loads the serialized settings through the engine
settings service and copies `set:WinX`/`set:WinY` into the two context fields before surfaces and the main
window are created.
The decompressed Himegari SYS4INI trailer explicitly contains `SCREENX=800` and `SCREENY=600`. As an
independent cross-game check, Kamidori's trailer contains `1024x576`. Thus the answer for the logical game
canvas is **SYS4INI per-game data overriding a generic EXE fallback**, not a separately compiled AGE
binary for every resolution. `display:ScreenMode`, `display:FullScreenWidth/Height`, aspect mode, and
related registered settings govern presentation/fullscreen selection separately; they do not redefine the
authored logical canvas. The serialized trailer location is recorded in `sys4-format-notes.md`.
### ops `0x1a2`/`0x1a3` store and restore shared `SAVE.DAT` integer cells (resolved 2026-07-20)
The SCJUMP slice assumed `u00428010` resolved a decision value to a scene. **That premise is wrong**,

View File

@@ -14,6 +14,18 @@ live in `tools/probe_*.py`.
> `vm-map/opcodes.toml`. The tag values below (0x71/0x03/0x8F etc.) are the
> *opcodes at table targets*: 0x8F=`call`, 0x03=`call-script`, 0x71=`u0041A7B0`.
## SYS4INI directory and per-game settings trailer — CONFIRMED
`SYS4INI.BIN` is not only the asset catalog. Its `S4IC` LZSS stream begins with the archive names and
80-byte file records documented in `asset-resolution-re.md`, then continues with VM-bank metadata and a
NUL-delimited per-game engine-settings trailer. `tools/parse_sys4ini.py` currently consumes only the
directory prefix.
The Himegari trailer contains `SCREENX=800` and `SCREENY=600`; Kamidori's independent SYS4INI contains
`SCREENX=1024` and `SCREENY=576`. This establishes the authored logical canvas as per-game data. Native
initialization and the executable's `640x480` fallback are documented in `engine-re.md`;
fullscreen/display-mode settings are a separate concern from these logical dimensions.
## Header — CONFIRMED
Fixed 60-byte (0x3C) header: 8-byte magic + thirteen little-endian u32 fields.

View File

@@ -17,7 +17,7 @@ Container format (little-endian x86), signature "S4IC422 " at offset 0:
The LZSS stream (GARbro-style: 0x1000 ring buffer, zero-filled, init pos 0xFEE,
control bits LSB->MSB, 1=literal, 0=two-byte back-reference: offset=(hi&0xf0)<<4
| lo, length=3+(hi&0xf)) decompresses to a plain directory:
| lo, length=3+(hi&0xf)) begins with a plain directory:
uint32 arc_count
{ char name[256] } x arc_count archive filenames (DATA1.ALF ..)
@@ -26,6 +26,10 @@ control bits LSB->MSB, 1=literal, 0=two-byte back-reference: offset=(hi&0xf0)<<4
uint32 file_number; uint32 offset;
uint32 size } x file_count (80 bytes each)
The directory is followed by VM-bank metadata and a per-game engine-settings
trailer. This tool currently emits only the asset directory; see
docs/sys4-format-notes.md for the trailer finding.
Entries whose name is "@" are placeholders and skipped (matches GARbro/exs4alf).
Usage: py -3.11 -X utf8 tools/parse_sys4ini.py [--check]

View File

@@ -476,12 +476,12 @@ note = "selector-one cell and op 0x143 scan start; subsequent dwords are selecto
offset = 0xa0cc0
name = "screen_w"
type = "int"
note = "screen width (640)"
note = "logical screen width; constructor/default registry uses 640, then the SYS4INI SCREENX setting overrides it (Himegari 800)"
[[field]]
offset = 0xa0cc4
name = "screen_h"
type = "int"
note = "screen height (480)"
note = "logical screen height; constructor/default registry uses 480, then the SYS4INI SCREENY setting overrides it (Himegari 600)"
[[field]]
offset = 0xa0cc8
name = "screen_bpp"