From 9762bf52e0c175b3e3376eff95db44a2067ec043 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Sat, 11 Jul 2026 12:58:49 -0400 Subject: [PATCH] Track platform portability dependencies --- docs/PROJECT-STRUCTURE.md | 1 + docs/platform-portability.md | 90 +++++++++++++++++++++++++ docs/remake-architecture-and-roadmap.md | 3 +- 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 docs/platform-portability.md diff --git a/docs/PROJECT-STRUCTURE.md b/docs/PROJECT-STRUCTURE.md index 34ae5c8..4b670f1 100644 --- a/docs/PROJECT-STRUCTURE.md +++ b/docs/PROJECT-STRUCTURE.md @@ -67,6 +67,7 @@ S:\Game Hacking\Eushully\Himegari\ ← workspace root (three siblings) │ ├── global-memory-re.md runtime global observation RE (SHELVED; future starting point) │ ├── remake-architecture-and-roadmap.md THE direction doc (phases A–E) │ ├── phase-a-slice-plan.md the current slice (A0/A1/A2) + │ ├── platform-portability.md OS dependencies + future cross-platform readiness │ ├── vm-mapping-plan.md the phased decode plan │ ├── himegari-port-reference.md master reference + engine background │ ├── name-resolution.md call-script + global-var name recovery (+ globals.toml registry) diff --git a/docs/platform-portability.md b/docs/platform-portability.md new file mode 100644 index 0000000..b897777 --- /dev/null +++ b/docs/platform-portability.md @@ -0,0 +1,90 @@ +# Platform Portability + +Living inventory of operating-system dependencies in the reimplementation and the work needed for future +non-Windows builds. This is a tracking reference, not a commitment to expand the current Phase A slice. +Native-engine reverse engineering remains Windows-oriented because the original game is a Windows program; +that does not by itself make the authored runtime Windows-only. + +## Current portability boundary + +The VM and content pipeline are already mostly platform-neutral: + +- `Age.Engine` uses managed .NET for script loading, bytecode execution, SYS4 catalog parsing, bounded + ALF/AAI reads, LZSS, AGF-to-RGBA8 decode, and retained graphics state. +- Godot owns ordinary graphics presentation, input, BGM, voice, and SFX playback. +- Effectful bytecode operations cross `Hosting/IHost.cs`; the VM does not call native OS APIs. +- Movie payloads arrive from `IAssetStore` as owned bytes and decoded frames enter the compositor as the + platform-neutral `RgbaImage` type. + +The current runtime's only direct native Windows API use is the movie decoder described below. There are +also softer Windows assumptions that should be tested or replaced before claiming portable exports. + +## Dependency inventory + +| Area | Current dependency | Runtime impact | Portability status / future action | +|---|---|---|---| +| SC0000 movie decode | `godot/DirectShowMovieDecoder.cs`: DirectShow COM objects plus `ole32.dll` `CoInitializeEx` / `CoUninitialize` | Movie startup cannot run outside Windows | Introduce a decoder interface and backend factory; retain DirectShow on Windows while adding a portable MPEG backend | +| Movie integration | `godot/Main.cs` directly constructs and stores `DirectShowMovieDecoder`; `Main` is marked `SupportedOSPlatform("windows")` | The frontend has no runtime fallback or OS-specific source selection | Type `MovieRuntime` against the decoder interface, select by platform/build, and move the Windows annotation to the DirectShow backend | +| Movie audio | DirectShow connects only the video pin to the sample grabber/null renderer | The MPEG audio stream is intentionally silent on every platform | Design a PCM/audio-clock contract or let a future backend own synchronized A/V; separate feature slice | +| ADV font discovery | `godot/Main.cs` probes `C:/Windows/Fonts` for Japanese fonts | Harmless fallback today, but appearance depends on host fonts | Bundle/configure a redistributable font or add platform-specific discovery | +| Filesystem semantics | Several filename and containment comparisons use `OrdinalIgnoreCase`; installed assets are conventionally uppercase | Needs validation on case-sensitive filesystems; may hide casing or containment mistakes | Add Linux/macOS tests with mixed-case synthetic roots and use filesystem-appropriate containment rules | +| Install/repository discovery | `engine/Age.Engine/Sys4/Paths.cs` finds `age-reimpl` above `AppContext.BaseDirectory` and assumes the current workspace sibling layout | Suitable for development, not packaged exports on any OS | Replace runtime discovery with a user-selected game root/profile; retain repository paths only for developer tools/tests | +| Archive parity oracle | One integration test launches `bin/BinExtractALF.exe` | Windows-only test helper, not a shipped runtime dependency | Skip/replace on non-Windows CI; runtime ALF/AAI readers do not depend on it | +| Native RE tools | Frida/Ghidra helpers target the original `AGE.EXE`; supporting utilities include Windows executables and Windows command conventions | Development/research only | Keep separate from export requirements; document platform prerequisites per tool | +| Python workflow | Operating guide uses Windows `py -3.11` invocation | Developer workflow only | Add equivalent `python3` instructions if non-Windows development becomes active | + +No authored runtime code currently calls native DirectSound or Direct3D. Mentions of those APIs in +`docs/engine-re.md` describe the original AGE implementation. The port's ordinary audio and rendering use +Godot abstractions. + +## Movie backend replacement seam + +The existing connection is localized but one abstraction short of being replaceable without edits: + +``` +VM op 0x236 + -> IHost.PlayMovieToSurface + -> VFS-owned MoviePayload bytes + -> DirectShowMovieDecoder + -> newest RGBA frame + -> retained movie surface + -> Godot compositor +``` + +Everything before and after `DirectShowMovieDecoder` is portable. The backend currently exposes the right +conceptual operations (`TryTakeFrame`, `IsCompleted`, and `Dispose`) but they are not formalized as an +interface. A future cleanup should: + +1. Add an `IMovieDecoder` contract for frame delivery, completion, failure, and disposal. +2. Add an injected factory that accepts `MoviePayload` and selects an available backend. +3. Keep DirectShow in a Windows-specific source set or assembly, with its platform annotation local to it. +4. Implement a portable MPEG program-stream backend that produces the same top-down RGBA8 frames. +5. Preserve newest-frame-wins delivery, asynchronous playback, synchronous open failure, EOF notification, + and the retained-surface lifecycle already validated for opcode `0x236`. +6. Treat synchronized movie audio as a separate extension of the contract rather than coupling it to the + compositor. + +An OS-specific build is also viable: include DirectShow only in Windows exports and a different decoder in +other exports. The current plain `net8.0` project has no conditional backend selection. COM declarations may +compile on another OS, but `[SupportedOSPlatform]` is analyzer metadata rather than a runtime guard, and +loading `ole32.dll` or DirectShow CLSIDs will fail there. + +## Cross-platform validation gates + +Before advertising a platform as supported: + +1. Build and export the Godot C# project for that target without compiling an unusable native backend. +2. Run the platform-neutral engine tests, with Windows-only parity oracles explicitly classified. +3. Exercise SYS4/AAI/ALF loose override precedence on a case-sensitive filesystem. +4. Decode representative raw/compressed AGF variants and compare RGBA output with established fixtures. +5. Play SC0000 through texture, BGM, voice, SFX, and movie publication using only the original archives. +6. Verify Japanese font discovery/rendering and user-selected game-root handling outside the repository. +7. If movie audio is implemented, validate A/V synchronization, interruption, EOF, and teardown separately + from video visibility. + +## Update rule + +Add an entry whenever authored runtime code gains an OS API, native library, platform-specific path, +filesystem assumption, conditional build rule, or platform-specific test oracle. Record whether it affects +the shipped runtime, only development tooling, or only native-engine research. Cross-link detailed subsystem +semantics to their canonical document instead of duplicating them here. diff --git a/docs/remake-architecture-and-roadmap.md b/docs/remake-architecture-and-roadmap.md index 3916dea..83d1cfd 100644 --- a/docs/remake-architecture-and-roadmap.md +++ b/docs/remake-architecture-and-roadmap.md @@ -64,7 +64,8 @@ Three layers, cleanly separated: loop is too hot for GDScript. Presentation, UI, mod tooling, and export targets use Godot. This is why **Godot now fits**: under the earlier "faithful port" framing it was overkill (you'd use ~10% of it); under *remake/enhance/mod* its editor, UI toolkit, asset pipeline, GDScript modding, - and multi-platform export all earn their keep. + and multi-platform export all earn their keep. Current OS dependencies and the gates for future exports + are tracked in `docs/platform-portability.md`; they do not expand the active Phase A scope. - **Toolchain vs runtime.** The runtime owns the canonical parser+VM (C#). The Python tools remain the offline analysis/authoring chain; they were the reference implementation and stay useful for modders. They share the *format spec* (documented), not code — acceptable for a small, stable