Drop the names taken from an external offset header (functions and globals), keeping only names the binary itself proves: _WinMain@16 from the CRT entry call, and Class::Method names from the client's own log strings. The six functions Ghidra missed stay in the map under neutral FUN_ names, justified by vtable/pointer references. NAMES.md, README and ROADMAP no longer point at third-party offset lists. Co-Authored-By: Claude Opus 5.5 <[email protected]>
50 lines
2.7 KiB
Markdown
50 lines
2.7 KiB
Markdown
# Roadmap: from scaffold to an identical eqgame.exe
|
|
|
|
End state: `python3 tools/eq.py link` produces an `eqgame.exe` with SHA1
|
|
`e8fdc68b46df69dde0094d57fd7ba2cb33aef1c5`, where every byte of game code and
|
|
game data comes from the C++ in this repository.
|
|
|
|
## What can never live in this repo
|
|
|
|
These are copyrighted by Microsoft, Daybreak or RAD/Miles. The build takes them
|
|
from the contributor's own `orig/eqgame.exe` at build time, never from git:
|
|
|
|
| Part | Size | Plan |
|
|
|---|---|---|
|
|
| MSVC 7.1 static CRT + Dinkumware STL non-inline code (`LIBCMT`, `LIBCPMT`) | ~6.9k small functions | carved from the original (`kind lib`), or linked from a contributor's own VS.NET 2003 `Lib/` |
|
|
| VC6-built third-party libs found in the Rich header | tbd | identify, then carve or build from source if it's open (zlib 1.1.2 is) |
|
|
| `.rsrc` (icons, dialogs, version info) | 190 KB | carved; optionally an `.rc` script later |
|
|
| PE headers / Rich header | 4 KB | generated from config once the link is done with `link.exe` |
|
|
|
|
## Phases
|
|
|
|
1. **Function matching.** Done for 3 functions. ~8.4k game functions (1.94 MB) remain.
|
|
Each needs C++ that compiles byte-identically (`eq.py check` = `MATCH`).
|
|
Ghidra pseudo-C for every function lands in `build/decomp/<addr>.c`.
|
|
2. **Types and names.** Recover classes, vtables and struct layouts into `include/`.
|
|
EQEmu's Titanium packet structs help here.
|
|
3. **Translation units.** Group functions into the original `.cpp` files. Function
|
|
order in `.text` follows link order, so consecutive address ranges are files.
|
|
String literal and `.data` order inside each range confirm the boundaries.
|
|
4. **Data.** Move `.rdata` and `.data` (strings, vtables, tables, float constants)
|
|
into source via `// GLOBAL:` definitions. `eq.py link` already places annotated
|
|
initialised globals.
|
|
5. **Real link.** Replace the placing linker in `eq.py link` with MSVC 7.1 `link.exe`,
|
|
using the recovered object order, carved library objects and generated import
|
|
libs. Then rebuild the headers and verify the hash.
|
|
|
|
## How `link` works today
|
|
|
|
It starts from the original image and overwrites every matched function and every
|
|
annotated initialised global with the compiled bytes. Relocations are resolved from
|
|
the symbol map, not copied. The hash must stay equal to the original's, so any
|
|
wrong relocation or misplaced object fails the build. The coverage line it prints
|
|
is the real progress number for the "same hash from source" goal.
|
|
|
|
## Parallel work
|
|
|
|
Contributors (or agent sessions) take disjoint address ranges and put their code in
|
|
`src/eqgame/` files named for that range or the recovered class. Names and globals
|
|
come from `// FUNCTION:` / `// GLOBAL:` annotations in the source, so nobody needs
|
|
to edit `config/eqgame/symbols.txt` while decompiling.
|