From 01ef6c5785177d558cc861b0a1c94908aa344323 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski <dash@wind.garden> Date: Mon, 22 Jul 2024 10:41:46 +0200 Subject: [PATCH] port Room_SetBounds --- docs/progress.svg | 16 ++--- docs/progress.txt | 9 ++- src/game/room_draw.c | 148 ++++++++++++++++++++++++++++++++++++++++++- src/game/room_draw.h | 4 ++ src/global/funcs.h | 1 - src/global/types.h | 6 ++ src/global/vars.h | 1 + src/inject_exec.c | 1 + 8 files changed, 175 insertions(+), 11 deletions(-) diff --git a/docs/progress.svg b/docs/progress.svg index 7a62a2d2..cc9f2412 100644 --- a/docs/progress.svg +++ b/docs/progress.svg @@ -69,10 +69,10 @@ </g> <g transform="translate(0 116)"> <text x="0" y="7.50">Tomb2.exe progress according to the physical function order:</text> -<text class="todo" style="font-size: 12px; " x="747" y="9"><tspan text-anchor="end"><tspan class="decompiled">47.87% (583)</tspan> · <tspan class="known">49.67% (605)</tspan> · <tspan class="todo">0% (0)</tspan> · <tspan class="unused">2.46% (30)</tspan></tspan></text> +<text class="todo" style="font-size: 12px; " x="747" y="9"><tspan text-anchor="end"><tspan class="decompiled">47.95% (584)</tspan> · <tspan class="known">49.59% (604)</tspan> · <tspan class="todo">0% (0)</tspan> · <tspan class="unused">2.46% (30)</tspan></tspan></text> <g transform="translate(0 20)"> -<rect width="357.55" height="6" x="0" y="0" class="decompiled"/> -<rect width="371.05" height="6" x="357.55" y="0" class="known"/> +<rect width="358.17" height="6" x="0" y="0" class="decompiled"/> +<rect width="370.43" height="6" x="358.17" y="0" class="known"/> <rect width="18.40" height="6" x="728.60" y="0" class="unused"/> </g> <g transform="translate(0 31)"> @@ -286,7 +286,7 @@ <rect width="12" height="12" x="105" y="60" class="known"><title>int32_t __cdecl Game_Draw(void);</title></rect> <rect width="12" height="12" x="120" y="60" class="known"><title>void __cdecl Room_DrawAllRooms(int16_t current_room);</title></rect> <rect width="12" height="12" x="135" y="60" class="decompiled"><title>void __cdecl Room_GetBounds(void);</title></rect> -<rect width="12" height="12" x="150" y="60" class="known"><title>void __cdecl Room_SetBounds(const int16_t *objptr, int32_t room_num, ROOM_INFO *parent);</title></rect> +<rect width="12" height="12" x="150" y="60" class="decompiled"><title>void __cdecl Room_SetBounds(const int16_t *objptr, int32_t room_num, ROOM_INFO *parent);</title></rect> <rect width="12" height="12" x="165" y="60" class="known"><title>void __cdecl Room_Clip(ROOM_INFO *r);</title></rect> <rect width="12" height="12" x="180" y="60" class="known"><title>void __cdecl Room_DrawSingleRoomGeometry(int16_t room_num);</title></rect> <rect width="12" height="12" x="195" y="60" class="known"><title>void __cdecl Room_DrawSingleRoomObjects(int16_t room_num);</title></rect> @@ -1298,10 +1298,10 @@ </g> <g transform="translate(0 546)"> <text x="0" y="7.50">Tomb2.exe progress according to the function sizes:</text> -<text class="todo" style="font-size: 12px; " x="747" y="9"><tspan text-anchor="end"><tspan class="decompiled">45.34%</tspan> · <tspan class="known">54.34%</tspan> · <tspan class="todo">0%</tspan> · <tspan class="unused">0.33%</tspan></tspan></text> +<text class="todo" style="font-size: 12px; " x="747" y="9"><tspan text-anchor="end"><tspan class="decompiled">45.60%</tspan> · <tspan class="known">54.08%</tspan> · <tspan class="todo">0%</tspan> · <tspan class="unused">0.33%</tspan></tspan></text> <g transform="translate(0 20)"> -<rect width="338.66" height="6" x="0" y="0" class="decompiled"/> -<rect width="405.90" height="6" x="338.66" y="0" class="known"/> +<rect width="340.62" height="6" x="0" y="0" class="decompiled"/> +<rect width="403.94" height="6" x="340.62" y="0" class="known"/> <rect width="2.44" height="6" x="744.56" y="0" class="unused"/> </g> <g transform="translate(0 31)"> @@ -1385,7 +1385,7 @@ <rect width="24.49" height="24.32" x="267.09" y="83.15" class="known"><title>void __cdecl Diver_Control(int16_t item_num);</title></rect> <rect width="24.49" height="24.26" x="267.09" y="110.47" class="known"><title>void __cdecl Dog_Control(int16_t item_num);</title></rect> <rect width="24.49" height="24.23" x="267.09" y="137.73" class="known"><title>int32_t __cdecl Effect_ExplodingDeath(int16_t item_num, int32_t mesh_bits, int16_t damage);</title></rect> -<rect width="24.49" height="24.02" x="267.09" y="164.97" class="known"><title>void __cdecl Room_SetBounds(const int16_t *objptr, int32_t room_num, ROOM_INFO *parent);</title></rect> +<rect width="24.49" height="24.02" x="267.09" y="164.97" class="decompiled"><title>void __cdecl Room_SetBounds(const int16_t *objptr, int32_t room_num, ROOM_INFO *parent);</title></rect> <rect width="24.49" height="23.99" x="267.09" y="191.99" class="known"><title>void __cdecl AnimateShotgun(int32_t weapon_type);</title></rect> <rect width="24.49" height="23.81" x="267.09" y="218.98" class="known"><title>void __cdecl Object_DrawAnimatingItem(ITEM_INFO *item);</title></rect> <rect width="24.49" height="23.69" x="267.09" y="245.79" class="decompiled"><title>void __cdecl WinVidStart(void);</title></rect> diff --git a/docs/progress.txt b/docs/progress.txt index eb5d6567..11fde05e 100644 --- a/docs/progress.txt +++ b/docs/progress.txt @@ -2606,6 +2606,12 @@ typedef struct __unaligned { } shift, rot; } OBJECT_BOUNDS; +typedef struct __unaligned { + int32_t xv; + int32_t yv; + int32_t zv; +} DOOR_VBUF; + typedef enum { TO_OBJECT = 0, TO_CAMERA = 1, @@ -2883,7 +2889,7 @@ typedef enum { 0x00418990 0x0037 - int32_t __cdecl Game_Draw(void); 0x004189D0 0x02B0 - void __cdecl Room_DrawAllRooms(int16_t current_room); 0x00418C80 0x01C6 + void __cdecl Room_GetBounds(void); -0x00418E50 0x037F - void __cdecl Room_SetBounds(const int16_t *objptr, int32_t room_num, ROOM_INFO *parent); +0x00418E50 0x037F + void __cdecl Room_SetBounds(const int16_t *objptr, int32_t room_num, ROOM_INFO *parent); 0x004191D0 0x03D2 - void __cdecl Room_Clip(ROOM_INFO *r); 0x004195B0 0x00B4 - void __cdecl Room_DrawSingleRoomGeometry(int16_t room_num); 0x00419670 0x0218 - void __cdecl Room_DrawSingleRoomObjects(int16_t room_num); @@ -4338,3 +4344,4 @@ typedef enum { 0x005261AC - int32_t g_OutsideTop; 0x00525B00 - int32_t g_OutsideBottom; 0x00525900 - int32_t g_BoundRooms[MAX_BOUND_ROOMS]; +0x005258C0 - DOOR_VBUF g_DoorVBuf[4]; diff --git a/src/game/room_draw.c b/src/game/room_draw.c index b8cdbe0c..6404be2f 100644 --- a/src/game/room_draw.c +++ b/src/game/room_draw.c @@ -2,7 +2,6 @@ #include "game/matrix.h" #include "global/funcs.h" -#include "global/types.h" #include "global/vars.h" void __cdecl Room_GetBounds(void) @@ -76,3 +75,150 @@ void __cdecl Room_GetBounds(void) Matrix_Pop(); } } + +void __cdecl Room_SetBounds( + const int16_t *obj_ptr, int32_t room_num, const ROOM_INFO *parent) +{ + ROOM_INFO *const r = &g_Rooms[room_num]; + const DOOR_INFO *const door = (const DOOR_INFO *)(obj_ptr - 1); + + // clang-format off + if (r->bound_left <= parent->test_left && + r->bound_right >= parent->test_right && + r->bound_top <= parent->test_top && + r->bound_bottom >= parent->test_bottom + ) { + return; + } + // clang-format on + + const MATRIX *const m = g_MatrixPtr; + int32_t left = parent->test_right; + int32_t right = parent->test_left; + int32_t bottom = parent->test_top; + int32_t top = parent->test_bottom; + + DOOR_VBUF door_vbuf[4]; + int32_t z_behind = 0; + int32_t z_too_far = 0; + + for (int32_t i = 0; i < 4; i++) { + DOOR_VBUF *const dvbuf = &door_vbuf[i]; + const XYZ_16 *const dvtx = &door->vertex[i]; + const int32_t xv = + m->_03 + dvtx->x * m->_00 + m->_01 * dvtx->y + m->_02 * dvtx->z; + const int32_t yv = + m->_13 + m->_12 * dvtx->z + m->_11 * dvtx->y + m->_10 * dvtx->x; + const int32_t zv = + m->_23 + m->_21 * dvtx->y + m->_22 * dvtx->z + m->_20 * dvtx->x; + dvbuf->xv = xv; + dvbuf->yv = yv; + dvbuf->zv = zv; + + if (zv <= 0) { + z_behind++; + continue; + } + + if (zv > g_PhdFarZ) { + z_too_far++; + } + + int32_t xs; + int32_t ys; + const int32_t zp = zv / g_PhdPersp; + if (zp) { + xs = xv / zp + g_PhdWinCenterX; + ys = yv / zp + g_PhdWinCenterY; + } else { + xs = xv < 0 ? g_PhdWinLeft : g_PhdWinRight; + ys = yv < 0 ? g_PhdWinTop : g_PhdWinBottom; + } + + if (xs - 1 < left) { + left = xs - 1; + } + if (xs + 1 > right) { + right = xs + 1; + } + if (ys - 1 < top) { + top = ys - 1; + } + if (ys + 1 > bottom) { + bottom = ys + 1; + } + } + + if (z_behind == 4 || z_too_far == 4) { + return; + } + + if (z_behind > 0) { + const DOOR_VBUF *dest = &door_vbuf[0]; + const DOOR_VBUF *last = &door_vbuf[3]; + + for (int32_t i = 0; i < 4; i++, last = dest++) { + if ((dest->zv < 0) == (last->zv < 0)) { + continue; + } + + if (dest->xv < 0 && last->xv < 0) { + left = 0; + } else if (dest->xv > 0 && last->xv > 0) { + right = g_PhdWinMaxX; + } else { + left = 0; + right = g_PhdWinMaxX; + } + + if (dest->yv < 0 && last->yv < 0) { + top = 0; + } else if (dest->yv > 0 && last->yv > 0) { + bottom = g_PhdWinMaxY; + } else { + top = 0; + bottom = g_PhdWinMaxY; + } + } + } + + if (left < parent->test_left) { + left = parent->test_left; + } + if (right > parent->test_right) { + right = parent->test_right; + } + if (top < parent->test_top) { + top = parent->test_top; + } + if (bottom > parent->test_bottom) { + bottom = parent->test_bottom; + } + + if (left >= right || top >= bottom) { + return; + } + + if (r->bound_active & 2) { + if (left < r->test_left) { + r->test_left = left; + } + if (top < r->test_top) { + r->test_top = top; + } + if (right > r->test_right) { + r->test_right = right; + } + if (bottom > r->test_bottom) { + r->test_bottom = bottom; + } + } else { + g_BoundRooms[g_BoundEnd++ % MAX_BOUND_ROOMS] = room_num; + r->bound_active |= 2; + r->bound_active += (int16_t)(g_MidSort << 8); + r->test_left = left; + r->test_right = right; + r->test_top = top; + r->test_bottom = bottom; + } +} diff --git a/src/game/room_draw.h b/src/game/room_draw.h index 42977df2..b69c8ffe 100644 --- a/src/game/room_draw.h +++ b/src/game/room_draw.h @@ -1,3 +1,7 @@ #pragma once +#include "global/types.h" + void __cdecl Room_GetBounds(void); +void __cdecl Room_SetBounds( + const int16_t *obj_ptr, int32_t room_num, const ROOM_INFO *parent); diff --git a/src/global/funcs.h b/src/global/funcs.h index 3bf40a5a..cf295419 100644 --- a/src/global/funcs.h +++ b/src/global/funcs.h @@ -31,7 +31,6 @@ #define Game_DrawCinematic ((int32_t __cdecl (*)(void))0x00418950) #define Game_Draw ((int32_t __cdecl (*)(void))0x00418990) #define Room_DrawAllRooms ((void __cdecl (*)(int16_t current_room))0x004189D0) -#define Room_SetBounds ((void __cdecl (*)(const int16_t *objptr, int32_t room_num, ROOM_INFO *parent))0x00418E50) #define Room_Clip ((void __cdecl (*)(ROOM_INFO *r))0x004191D0) #define Room_DrawSingleRoomGeometry ((void __cdecl (*)(int16_t room_num))0x004195B0) #define Room_DrawSingleRoomObjects ((void __cdecl (*)(int16_t room_num))0x00419670) diff --git a/src/global/types.h b/src/global/types.h index 11ddb7d9..b099f152 100644 --- a/src/global/types.h +++ b/src/global/types.h @@ -2622,6 +2622,12 @@ typedef struct __unaligned { } shift, rot; } OBJECT_BOUNDS; +typedef struct __unaligned { + int32_t xv; + int32_t yv; + int32_t zv; +} DOOR_VBUF; + typedef enum { TO_OBJECT = 0, TO_CAMERA = 1, diff --git a/src/global/vars.h b/src/global/vars.h index 04911d9e..c56e60aa 100644 --- a/src/global/vars.h +++ b/src/global/vars.h @@ -321,6 +321,7 @@ extern const char *g_TR2XVersion; #define g_Outside (*(int32_t*)0x005252B4) #define g_DrawRoomsCount (*(int32_t*)0x005252B8) #define g_IMMatrixStack (*(MATRIX(*)[256])0x005252C0) +#define g_DoorVBuf (*(DOOR_VBUF(*)[4])0x005258C0) #define g_IMFrac (*(int32_t*)0x005258F0) #define g_Anims (*(ANIM_STRUCT **)0x005258F4) #define g_BoundRooms (*(int32_t(*)[MAX_BOUND_ROOMS])0x00525900) diff --git a/src/inject_exec.c b/src/inject_exec.c index 6eaf0236..849f151b 100644 --- a/src/inject_exec.c +++ b/src/inject_exec.c @@ -252,6 +252,7 @@ static void Inject_Room(const bool enable) INJECT(enable, 0x00416700, Room_RemoveFlipItems); INJECT(enable, 0x004167A0, Room_AddFlipItems); INJECT(enable, 0x00418C80, Room_GetBounds); + INJECT(enable, 0x00418E50, Room_SetBounds); } static void Inject_Matrix(const bool enable)