Widescreen: keep original size, extend view horizontally; fix player/camera
- Default render size is 768 high and as wide as the monitor aspect
(1835x768 on 3440x1440), scaled up: everything keeps the size players
know and the view only grows sideways. Height=0 keeps native 1:1.
- Ground: 818/888 clip limits, screen centre floats and integer
immediates, ground quad list (capped at 1749) moved with the tile list.
- 3D: cGranny ortho (+-512 x +-384, incl. HUD items) scaled; inverse
projection 0x623a20 (1/1024, 1/768) follows the render size, which fixes
the camera following the player ("outside world") and the missing
player / ESC menu.
- tools: game-input.ps1 + autotest-load.ps1 drive the game (load the first
save game, screenshots in-game and with the ESC menu).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
795fe8f087
commit
df31c9c105
6 files changed
+324
-45
No files matched your search
+58
-1
@@ -43,6 +43,42 @@ constexpr uint32_t kViewHeightUsers[] = {
|
||||
0x0062ea5e, 0x0062f345, 0x0063068a, 0x00630f77,
|
||||
};
|
||||
|
||||
// More screen constants the world view reads (float, `f... dword ptr [addr]`).
|
||||
constexpr uint32_t kScreenHalfWidthF = 0x0088e6fc; // float 512.0 (screen centre x)
|
||||
constexpr uint32_t kScreenHalfHeightF = 0x0088e9f0; // float 384.0 (screen centre y)
|
||||
constexpr uint32_t kGroundClipBottomF = 0x0089011c; // float 818.0 (768 + 50)
|
||||
constexpr uint32_t kClipBottom888F = 0x00890124; // float 888.0 (768 + 120)
|
||||
constexpr uint32_t kViewHalfWidthUsers[] = {
|
||||
0x0062b485, 0x0062dc83, 0x0062e37c, 0x0062e960, 0x0062e989, 0x0062efd8, 0x0062eff2,
|
||||
0x0063058a, 0x006305b5, 0x00630c08, 0x00630c22, 0x00632032, 0x0063205c,
|
||||
};
|
||||
constexpr uint32_t kViewHalfHeightUsers[] = {
|
||||
0x006252fe, 0x00625341, 0x0062b4be, 0x0062dcbe, 0x0062e390, 0x0062e996, 0x0062e9a2, 0x0062f002,
|
||||
0x0062f00e, 0x006305c2, 0x006305ce, 0x00630c2f, 0x00630c3b, 0x0063206a, 0x0063207a,
|
||||
};
|
||||
// Outside the world view object, but drawing into the world: the zoom
|
||||
// transform around the screen centre in FUN_0041eaf0. (The 512/1024 in
|
||||
// cGranny::renderComplex case 9 are an effect animation, not the screen.)
|
||||
constexpr uint32_t kCreatureHalfWidthUsers[] = {0x0041ed2b, 0x0041ed35};
|
||||
constexpr uint32_t kCreatureHalfHeightUsers[] = {0x0041ed41, 0x0041ed4b};
|
||||
// Precomputed reciprocals of the screen size. 0x623a20 (screen -> view,
|
||||
// inverse of 0x623c40) uses 1/1024 and 1/768. Other users of these constants
|
||||
// are texel/time maths.
|
||||
constexpr uint32_t kScreenInvWidthF = 0x0088e710; // float 1/1024
|
||||
constexpr uint32_t kScreenInvHeightF = 0x0089005c; // float 1/768
|
||||
constexpr uint32_t kViewInvWidthUsers[] = {0x00623a49};
|
||||
constexpr uint32_t kViewInvHeightUsers[] = {0x00623a5f};
|
||||
constexpr uint32_t kGroundClipBottomUsers[] = {0x0062b464};
|
||||
constexpr uint32_t kClipBottom888Users[] = {0x0062dc62};
|
||||
|
||||
// Screen centre as integer immediates (`add reg, 200h` / `mov reg, 200h` and
|
||||
// the matching 180h), in pairs x, y.
|
||||
constexpr uint32_t kCenterImmediates[][2] = {
|
||||
{0x0062b4c6, 0x0062b4e9}, {0x0062cc40, 0x0062cc50}, {0x0062dcc6, 0x0062dce1},
|
||||
{0x0062e398, 0x0062e3a9}, {0x0062f967, 0x0062f96d}, {0x0062fe60, 0x0062fe7d},
|
||||
{0x006315aa, 0x006315b0}, {0x00631aca, 0x00631ae7}, {0x00631c53, 0x00631c70},
|
||||
};
|
||||
|
||||
// cWorldView0 is allocated with `push 970F4h; call operator new` here.
|
||||
constexpr uint32_t kWorldViewAllocSizePush = 0x006101aa;
|
||||
constexpr uint32_t kWorldViewSize = 0x970f4;
|
||||
@@ -53,11 +89,22 @@ constexpr uint32_t kWorldViewSize = 0x970f4;
|
||||
constexpr uint32_t kTileListOffset = 0x3ff2c;
|
||||
constexpr uint32_t kTileListEntrySize = 0x98;
|
||||
constexpr uint32_t kTileListUsers[] = {
|
||||
0x0062b6d9, 0x0062b6ec, 0x0062b709, 0x0062b730, 0x0062b74b, 0x0062b763, // writer, row renderer 0x62b000
|
||||
0x0062b6d9, 0x0062b6ec, 0x0062b709, 0x0062b730, 0x0062b74b, 0x0062b763, // writer, row renderer FUN_0062b000
|
||||
0x0062b777, 0x0062b797, 0x0062b7b7, 0x0062b7d7,
|
||||
0x0062df47, 0x0062e252, // readers (lea base pointer)
|
||||
};
|
||||
|
||||
// cWorldView0's ground quad list: 0x90-byte entries at +0xb64 plus a parallel
|
||||
// int array at +0x3e3c4, count at +0x3ff1c, capped at 0x6d5 (1749): beyond
|
||||
// that the last quad is overwritten, so the ground stops drawing.
|
||||
constexpr uint32_t kGroundQuadOffset = 0xb64;
|
||||
constexpr uint32_t kGroundQuadEntrySize = 0x90;
|
||||
constexpr uint32_t kGroundQuadIndexOffset = 0x3e3c4;
|
||||
constexpr uint32_t kGroundQuadCap = 0x6d5;
|
||||
constexpr uint32_t kGroundQuadCapCompare = 0x0062b603; // cmp eax, 6D5h
|
||||
constexpr uint32_t kGroundQuadUsers[] = {0x0062b5e2, 0x0062d58e}; // lea [..+0B64h] / [..+0B7Ch]
|
||||
constexpr uint32_t kGroundQuadIndexUsers[] = {0x0062b5f6, 0x0062d588}; // [..+3E3C4h]
|
||||
|
||||
// Ortho projection of the 3D models: x -267..267, y -200..200 world units
|
||||
// span the 1024x768 screen (times zoom). Doubles, read with `fmul qword ptr`.
|
||||
constexpr uint32_t kOrthoLeftD = 0x0088ee40; // double -267.0
|
||||
@@ -68,6 +115,7 @@ constexpr uint32_t kOrthoTopD = 0x0088ee58; // double 200.0
|
||||
// World view instructions `fmul st, qword ptr [kOrtho*D]` (zoomed projection),
|
||||
// four per site, in the order top, bottom, right, left.
|
||||
constexpr uint32_t kOrthoZoomedUsers[][4] = {
|
||||
{0x004b19c1, 0x004b19dc, 0x004b19ed, 0x004b19fe}, // FUN_004b1740, outside the view class
|
||||
{0x00624fdb, 0x00624ff3, 0x00625001, 0x0062500f},
|
||||
{0x00628355, 0x0062836d, 0x0062837b, 0x00628389},
|
||||
{0x0062852f, 0x00628547, 0x00628555, 0x00628563},
|
||||
@@ -80,4 +128,13 @@ constexpr uint32_t kOrthoPushSequences[] = {
|
||||
0x0060c1f7, 0x0060da54, 0x00625039, 0x006283b3, 0x0062858d, 0x00628d3b,
|
||||
};
|
||||
|
||||
// cGranny::render variants (3D creatures) project in screen pixels with an
|
||||
// ortho camera of x -512..512, y -384..384: 4 consecutive `push imm32` in the
|
||||
// order top (384), bottom (-384), right (512), left (-512).
|
||||
// The last one is cUI_NetGranny (3D items in the HUD, e.g. the belt). It must
|
||||
// be scaled too: game logic (0x44d9f0, camera target) converts world to screen
|
||||
// with whatever projection the device has, which is usually the HUD's, and
|
||||
// uses the (redirected) view width with it.
|
||||
constexpr uint32_t kGrannyOrthoPushSequences[] = {0x0040ebc9, 0x0040f5cf, 0x0040feff, 0x006f1ecb};
|
||||
|
||||
} // namespace game::addr
|
||||
Reference in new issue
Block a user