---
title: "TH04 source reconstruction"
url: "https://reamcp.dev/zh-tw/cases/th04-source-reconstruction-ee07c3"
source: "https://github.com/N0zoM1z0/th04"
source_type: "github"
repo: "https://github.com/N0zoM1z0/th04"
author: "N0zoM1z0"
author_handle: "N0zoM1z0"
stars: 32
category: "遺失原始碼還原"
categories: ["source-recovery"]
tags: []
added: "2026-10-13T03:57:25.390Z"
updated: "2026-10-12T15:30:53Z"
locale: "zh-tw"
content_locale: "zh-tw"
---

# TH04 source reconstruction

重建 PC-98 DOS 射擊遊戲 TH04 的程式碼，把 16 位元常式對應到可讀的 C++ 與當年編譯器的輸出。

## Original README

# 東方幻想郷 ～ Lotus Land Story

<p align="center">
  <img
    src="resources/title-screen.png"
    width="640"
    alt="Original Japanese TH04 title screen">
</p>

<p align="center">
  <img src="resources/progress.svg" alt="TH04 four-artifact boundary and function acceptance progress">
</p>

This repository reconstructs the original Japanese PC-98 **Touhou 4:
Lotus Land Story**. The active goal is to build `MAIN.EXE`, `OP.EXE`,
`MAINE.EXE` and `ZUN.COM` from maintained TH04 source and run the full game.
Native builds need not reproduce the original executable bytes. MAIN's two
remaining historical exactness cases are deferred.

[Current state and remaining work](docs/RE_HANDOFF.md) is the working entrypoint.
Historical function acceptance is reported by `python3 scripts/status.py` and
[PROGRESS.md](docs/PROGRESS.md); it is separate from gameplay completion.

## Current products and navigation

Development is active. All four DOS products build from maintained local source.
Retained original/reconstructed DOS comparisons agree across all four bundled
demos on consumed input, score and RNG, nine complete actor/effect pools, and 22
Boss/Midboss/player state blocks. These demos exercise Midboss fights; Boss
combat and complete process transitions still need paired validation. Complete
Demo video captures cover both graphics pages, all four
planes, text, palettes and selected GDC display fields. Text, palettes and the
compared display fields agree. Cold builds and complete replays verify repairs
to the Stage 4 carpet columns, packed bullet invalidation dimensions and
point-number multiplier glyphs. Restoring a missing Stage 4 lighting-animation
cell now also resolves Demo 1's remaining graphics differences. All four demos
agree on every compared video region across all 3,996 updates each. Full
scanout timing remains open; see the handoff for the current evidence.

Two repeated ordinary Stage 1 pairs agree through 3,996 updates on consumed
input, 36 state fields and 1,369 ordered RNG calls, including two natural deaths
and respawns. Keyboard device events begin at the original OP's observed menu
counter; no RNG or gameplay state is assigned. New after-update captures also
agree on nine whole object/effect pools and 22 state blocks; three pools stay
empty. The latest companion aggregate retains 155 differing end-of-update
keyboard samples despite equal consumed inputs and independent scalar/RNG
controls. Complete video captures now agree on both pages of all four VRAM
planes, the text plane, palettes and configured GDC display fields across this
ordinary fragment. Raw GDC timing differs on every frame and is retained.
A longer 7,500-update fragment now also pairs ordinary Boss combat: input,
RNG, nine complete pools and 22 state blocks agree through battle phases 0/1/2.
Its aggregate retains 258 end-of-update keyboard differences. Original Game
Over is independently located at frame 7,547; complete Boss defeat, process
transitions and physical scanout remain open.

Native x64 source lives on `port/modern-64`. Scoped Linux Reimu A runs cover
Normal, Lunatic and Extra clears with registration, physical saves and fresh
OP/restart checks. Four complete demos agree with the original on compared
input, score, player and RNG state, draw counts, nine complete actor/effect
pools and all 15,984 complete item-splash states. The actual idle OP→four
demos→OP route also passes selected state checks, all 15,984 shake states
and movement requests, and 40 complete canonical text-plane samples.

Restoring Midboss shake, the full physical background ring, Marisa laser color
timing, whole-pool pellet color passes and item-spawn white light dots removes
the diagnosed late-frame pixel differences. Preserving Stage4 background draw
order and tail copies also restores the initial background. Retained GNU and optimized
UBSan producers agree with the original in all 40 sampled game areas; ten separate
GNU lighting samples also agree. These game-area diagnostics do not establish
complete-picture acceptance. Whole graphics/RGB, physical scanout, broader routes and Windows
input/audio acceptance remain open; see the handoff for scoped evidence.

Native development is active. Current frozen554/31e6b3d7 GNU and optimized
UBSan now pass four strict natural headless routes: Easy ReimuA, Normal ReimuA,
Normal MarisaA and Extra ReimuA earned by the same-run Normal save. All four
complete captures/saves agree across compilers, with real clear mask1 and no
Continue. The new554/a79f199f reader rejects sentinel/high masks, wrong
partitions, Bad Ending, incomplete stages and full-checksum failures. Previous
failed window Normal acceptance stays revoked. Original full-game parity,
complete pictures, physical timing and Windows remain open; see the
[handoff](docs/RE_HANDOFF.md) for scope and recovery.

Native branch head: `c0a1060`.

Current shared DOS restores upward SMEM and descending HMEM ownership and
the graph page-copy workspace (producer 1,426/e60c079f). All 1,242 allocator and
160 page-copy controls agree with original instructions at loads1000/3333;
ABI/link/MZ/IRQ checks also pass. Analog/LCD palette, text and installed-owner
VSync recovery remain accepted with their own frozen producers. Prior complete
Demo/pool/video acceptance retains its source identity. These comparisons do
not establish byte exactness or physical CPU/IRQ timing.

CI passes 451 DOS tests; retained native CI passes 345.

Physical CPU/loading/ISR costs, other scene wait adapters, complete pictures,
broader Boss/death/process routes and Windows input/audio remain open. Native scene wait adapters and hardware owners are the next bounded work.
See the [current handoff](docs/RE_HANDOFF.md) for frozen producers and recovery.

Historical exact acceptance has its own contract; runtime agreement does not
promote it.

- [Current DOS/native evidence and remaining work](docs/PORTING_STATUS.md).
- [DOS build and normal/invincible Windows testing](docs/DOS_BUILD.md).
- [Reusable PC-98 hardware fixes and measured optimizations](docs/PC98_HARDWARE_REUSE.md).
- [Script purposes and categorized indexes](scripts/README.md).
- [Private tools, caches and cleanup recovery](docs/ANALYSIS_RETENTION.md).

## Build and run

With local inputs and the toolchain installed:

```sh
python3 scripts/preflight.py
python3 scripts/build.py
# Outputs: .analysis/build/th04/{MAIN.EXE,OP.EXE,MAINE.EXE,ZUN.COM}
python3 scripts/prepare_product_hdi.py \
  --output-dir .analysis/runtime/candidates/NEW-game
xvfb-run -a python3 scripts/probes/run_th04_maine_diagnostic_hdi.py \
  --prepared-dir .analysis/runtime/candidates/NEW-game \
  --output-dir .analysis/runtime/candidates/NEW-game/run \
  --frame-second 60 --time-limit 75
```

Run one Borland/Wine build at a time. `--only main` selects one product;
`--main-cpp-cache PATH` reuses objects only when their inputs match a prior MAIN
build. A fresh build is the final source-migration check. The build rejects
compiler/linker failures and publishes outputs after all requested products
succeed. Runtime validation remains separate.

Image preparation modifies a disposable copy of your supplied original-data
image. Original executables and game assets are never committed.

## Setup

The build uses pinned Turbo C++ 4.0J, TASM and TLINK under Wine. ReC98 supplies
the pinned MS-DOS Player and local sprite conversion inputs; product source
and headers live in this repository and do not use `masters.lib`.

```sh
mkdir -p _reference
git clone https://github.com/nmlgc/ReC98.git _reference/ReC98
git -C _reference/ReC98 checkout --detach b6ba5b0a529edbb31efdf8c0e939263804f8ee47
python3 scripts/import_targets.py /path/to/your/legal-copy.rar \
  --retain-runtime-image
bash scripts/bootstrap_toolchain.sh
python3 scripts/preflight.py
```

Host tools include Python 3, Wine, archive utilities and, for runtime checks,
the pinned DOSBox-X build plus Xvfb, xdotool and ImageMagick. See
[RUNTIME.md](docs/RUNTIME.md) for emulator setup. Analysis/database work also
uses `bootstrap_analysis_toolchain.sh` and `scripts/ghidra.py`.

## Local inputs

Supply your own legal copy.  The importer selects the Japanese `zun.hdi` and
requires these artifacts:

| Artifact | Size | SHA-256 |
| --- | ---: | --- |
| `OP.EXE` | 42,290 | `8fc3b67fa8470de15b4f2844d5623d0a93d7922fac16d82a25a90a378b516b0f` |
| `MAIN.EXE` | 156,258 | `077440a3c4e9ab52e72e9bae411276c47edc11995b5c2b83dfc83fbc039dc58b` |
| `MAINE.EXE` | 38,035 | `670de6ba907a2edbc1592de810acd92e5b89541d3dc35b70210171166d1713f8` |
| `ZUN.COM` | 7,754 | `0a12e9a489d3b704a77cf04ca3062ee48f298a9df6d237dc7dad46986e2d116e` |

These hashes currently have `candidate-local-attested` provenance: they
identify the supplied Japanese image exactly, while independent pristine-dump
confirmation remains open.  That qualification is kept separate from whether
a candidate build exactly matches the pinned bytes.

## Source and validation

Source belongs under `src/main/`, `src/op/`, `src/maine/`, `src/zun/` and
`src/shared/`, organized by subsystem. See [SOURCE_LAYOUT.md](docs/SOURCE_LAYOUT.md)
and [ARCHITECTURE.md](docs/ARCHITECTURE.md). ReC98 implementations are migration
inputs; their progress and exactness claims do not transfer automatically.

Use [RE_WORKFLOW.md](docs/RE_WORKFLOW.md) for implementation work. Install public
validation dependencies with `python3 -m pip install -r requirements-ci.txt`;
CI also checks out the pinned ReC98 source-routing reference used by the manifest
audit; this is a validation input, not a product include dependency. Private
CPU/runtime Oracles additionally require their documented local tools. Finish with:

```sh
python3 scripts/ci.py
git diff --check
```

Historical evidence is routed through [the reconstruction index](docs/reconstruction/README.md),
`config/units.csv` and `config/evidence.csv`. [ORACLES.md](docs/ORACLES.md)
defines the separate byte-exact acceptance contract. Local tools, targets,
images, builds and reports remain in ignored directories.

## License

Repository-authored code and documentation are provided under the MIT License.
This does not grant rights to the original game, its assets, or referenced
third-party work.
