File size: 3,556 Bytes
ed63829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# Engine Initialization Chain

## Overview

WA.exe initializes the engine through a chain of constructor calls that build
the DDGame monolith and its subsystems. The top-level entry is
`ConstructDDGameWrapper` which allocates DDGame and wires up all subsystems.

## Call Chain

```
WinMain / CRT startup (0x5D8B6C)
  └─ ConstructDDGameWrapper (0x56DEF0)
       β”œβ”€ Allocates DDGameWrapper (vtable 0x66A30C)
       β”œβ”€ DDGame__Constructor (0x56E220)
       β”‚    β”œβ”€ Allocates 0x98B8 bytes for DDGame
       β”‚    β”œβ”€ DDDisplay__Init (0x569D00)
       β”‚    β”‚    └─ Sets display mode, dimensions, palette, HWND
       β”‚    β”œβ”€ GfxHandler x2 (vtable 0x66B280, 0x19C bytes each)
       β”‚    β”œβ”€ Task state machines x5 (vtable 0x664118)
       β”‚    └─ Game state pointer at DDGame+0x24
       β”œβ”€ PCLandscape__Constructor (0x57ACB0)
       β”‚    β”œβ”€ vtable 0x66B208, parent = DDGame
       β”‚    β”œβ”€ Allocates terrain buffer (0x60000 bytes) at +0x8E8
       β”‚    β”œβ”€ Creates WaterEffect object (vtable 0x66B268) at +0xC8
       β”‚    β”œβ”€ Creates LandscapeShader (vtable 0x66B1DC) at +0x93C
       β”‚    └─ Loads Water.dir, Level.dir from data\Gfx\
       β”œβ”€ DSSound__Constructor (0x573D50)
       β”‚    β”œβ”€ vtable 0x66AF20
       β”‚    β”œβ”€ Master volume = Fixed(0x10000) = 1.0 at +0x8A4
       β”‚    └─ 500 sound channel slots
       └─ OpenGLCPU__Constructor (0x5A0850) [conditional]
            β”œβ”€ vtable 0x6774C0, 0x48 bytes
            β”œβ”€ Width at +0x10, Height at +0x24
            └─ OpenGL__Init (0x59F000) stores HDC/HGLRC in DDDisplay
```

## DDGameWrapper Layout

DDGameWrapper is a thin wrapper (~0x500 bytes) around DDGame:

| Offset | Field              | Notes                              |
|--------|--------------------|------------------------------------|
| 0x000  | vtable             | 0x66A30C                           |
| 0x488  | DDGame ptr         | Allocated 0x98B8-byte object       |
| 0x48C  | DDGame secondary   | Optional 0x2C-byte struct          |
| 0x4C0  | GfxHandler 0       | 0x19C bytes, vtable 0x66B280       |
| 0x4C4  | GfxHandler 1       | Optional                           |
| 0x4C8  | GfxMode            | Graphics mode flag                 |
| 0x4CC  | PCLandscape        | Pointer to landscape subsystem     |

## DDGame Key Offsets

DDGame is a ~39KB (0x98B8 bytes) monolithic object. Known landmark fields:

| Offset | Field              | Notes                              |
|--------|--------------------|------------------------------------|
| 0x0024 | game_state         | Global game state pointer          |
| 0x0028 | param              | Constructor parameter              |
| 0x11B0 | task_ptrs[5]       | 5 task state machine pointers      |
| 0x3548 | display_mode       | Display mode pointer               |
| 0x354C | display_width      | Screen width                       |
| 0x3560 | display_center_x   | Screen center X                    |
| 0x3564 | display_center_y   | Screen center Y                    |
| 0x3578 | hwnd               | Window handle                      |
| 0x358D | palette            | 256-color palette (0x400 bytes)    |
| 0x3D98 | gfx_objects[4]     | Graphics object pointers           |

## Ghidra Offset Convention

Ghidra's decompiler shows DWORD-indexed offsets for struct access:
- `param_1[0x122]` β†’ byte offset 0x122 * 4 = **0x488**
- `param_1[0x133]` β†’ byte offset 0x133 * 4 = **0x4CC**
- Always multiply DWORD index by 4 to get the true byte offset.