diff --git a/docs/progress.svg b/docs/progress.svg index 95bc079..22f5e33 100644 --- a/docs/progress.svg +++ b/docs/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -20.25% (243) · 77.25% (927) · 0.67% (8) · 1.83% (22) +20.33% (244) · 77.17% (926) · 0.67% (8) · 1.83% (22) - - + + @@ -111,7 +111,7 @@ void __cdecl Output_DrawPolyGTMap(const int16_t *obj_ptr); void __cdecl Output_DrawPolyWGTMap(const int16_t *obj_ptr); int32_t __cdecl Output_XGenX(const int16_t *obj_ptr); -int32_t __cdecl Output_XGenXG(const int16_t *obj_ptr); +int32_t __cdecl Output_XGenXG(const int16_t *obj_ptr); int32_t __cdecl Output_XGenXGUV(const int16_t *obj_ptr); int32_t __cdecl Output_XGen_XGUVPerspFP(const int16_t *obj_ptr); void __cdecl Output_GTMap_Persp32FP(int32_t y0, int32_t y1, uint8_t *tex_page); @@ -1281,10 +1281,10 @@ Tomb2.exe progress according to the function sizes: -12.16% · 87.51% · 0.02% · 0.31% +12.26% · 87.41% · 0.02% · 0.31% - - + + @@ -1571,7 +1571,7 @@ void __cdecl Lara_State_Stop(struct ITEM_INFO *item, struct COLL_INFO *coll); void __cdecl MovableBlock(int16_t item_num); void __cdecl Effect_Draw(int16_t fx_num); -int32_t __cdecl Output_XGenXG(const int16_t *obj_ptr); +int32_t __cdecl Output_XGenXG(const int16_t *obj_ptr); void __cdecl DrawAssaultTimer(void); int16_t __cdecl StartGame(int32_t levelID, GF_LEVEL_TYPE levelType); void __cdecl Lara_State_Run(struct ITEM_INFO *item, struct COLL_INFO *coll); diff --git a/docs/progress.txt b/docs/progress.txt index 3dea370..220946f 100644 --- a/docs/progress.txt +++ b/docs/progress.txt @@ -1177,7 +1177,7 @@ typedef enum LARA_MESH { 00402BD0 0000003C + void __cdecl Output_DrawPolyGTMap(const int16_t *obj_ptr); 00402C10 0000003C + void __cdecl Output_DrawPolyWGTMap(const int16_t *obj_ptr); 00402C50 000000D2 + int32_t __cdecl Output_XGenX(const int16_t *obj_ptr); -00402D30 00000146 - int32_t __cdecl Output_XGenXG(const int16_t *obj_ptr); +00402D30 00000146 + int32_t __cdecl Output_XGenXG(const int16_t *obj_ptr); 00402E80 00000219 - int32_t __cdecl Output_XGenXGUV(const int16_t *obj_ptr); 004030A0 00000284 - int32_t __cdecl Output_XGen_XGUVPerspFP(const int16_t *obj_ptr); 00403330 00000FC6 - void __cdecl Output_GTMap_Persp32FP(int32_t y0, int32_t y1, uint8_t *tex_page); diff --git a/src/game/output.c b/src/game/output.c index 9ced3ec..8941084 100644 --- a/src/game/output.c +++ b/src/game/output.c @@ -859,7 +859,7 @@ int32_t __cdecl Output_XGenX(const int16_t *obj_ptr) if (y1 < y2) { CLAMPG(y_min, y1); - int32_t x_size = x2 - x1; + const int32_t x_size = x2 - x1; int32_t y_size = y2 - y1; struct XBUF_X *x_ptr = (struct XBUF_X *)g_XBuffer + y1; @@ -873,7 +873,7 @@ int32_t __cdecl Output_XGenX(const int16_t *obj_ptr) } } else if (y2 < y1) { CLAMPL(y_max, y1); - int32_t x_size = x1 - x2; + const int32_t x_size = x1 - x2; int32_t y_size = y1 - y2; struct XBUF_X *x_ptr = (struct XBUF_X *)g_XBuffer + y2; @@ -896,3 +896,71 @@ int32_t __cdecl Output_XGenX(const int16_t *obj_ptr) g_XGenY2 = y_max; return 1; } + +int32_t __cdecl Output_XGenXG(const int16_t *obj_ptr) +{ + int32_t pt_count = *obj_ptr++; + const struct XGEN_XG *pt2 = (const struct XGEN_XG *)obj_ptr; + const struct XGEN_XG *pt1 = pt2 + (pt_count - 1); + + int32_t y_min = pt1->y; + int32_t y_max = pt1->y; + + while (pt_count--) { + const int32_t x1 = pt1->x; + const int32_t y1 = pt1->y; + const int32_t g1 = pt1->g; + const int32_t x2 = pt2->x; + const int32_t y2 = pt2->y; + const int32_t g2 = pt2->g; + pt1 = pt2++; + + if (y1 < y2) { + CLAMPG(y_min, y1); + const int32_t g_size = g2 - g1; + const int32_t x_size = x2 - x1; + int32_t y_size = y2 - y1; + + struct XBUF_XG *xg_ptr = (struct XBUF_XG *)g_XBuffer + y1; + const int32_t x_add = PHD_ONE * x_size / y_size; + const int32_t g_add = PHD_HALF * g_size / y_size; + int32_t x = x1 * PHD_ONE + (PHD_ONE - 1); + int32_t g = g1 * PHD_HALF; + + while (y_size--) { + x += x_add; + g += g_add; + xg_ptr->x2 = x; + xg_ptr->g2 = g; + xg_ptr++; + } + } else if (y2 < y1) { + CLAMPL(y_max, y1); + const int32_t g_size = g1 - g2; + const int32_t x_size = x1 - x2; + int32_t y_size = y1 - y2; + + struct XBUF_XG *xg_ptr = (struct XBUF_XG *)g_XBuffer + y2; + const int32_t x_add = PHD_ONE * x_size / y_size; + const int32_t g_add = PHD_HALF * g_size / y_size; + int32_t x = x2 * PHD_ONE + 1; + int32_t g = g2 * PHD_HALF; + + while (y_size--) { + x += x_add; + g += g_add; + xg_ptr->x1 = x; + xg_ptr->g1 = g; + xg_ptr++; + } + } + } + + if (y_min == y_max) { + return 0; + } + + g_XGenY1 = y_min; + g_XGenY2 = y_max; + return 1; +} diff --git a/src/game/output.h b/src/game/output.h index 0d3614b..8820ed1 100644 --- a/src/game/output.h +++ b/src/game/output.h @@ -30,3 +30,4 @@ void __cdecl Output_DrawPolyGouraud(const int16_t *obj_ptr); void __cdecl Output_DrawPolyGTMap(const int16_t *obj_ptr); void __cdecl Output_DrawPolyWGTMap(const int16_t *obj_ptr); int32_t __cdecl Output_XGenX(const int16_t *obj_ptr); +int32_t __cdecl Output_XGenXG(const int16_t *obj_ptr); diff --git a/src/global/const.h b/src/global/const.h index 9696718..e1f3c4e 100644 --- a/src/global/const.h +++ b/src/global/const.h @@ -1,4 +1,5 @@ #define PHD_ONE 0x10000 +#define PHD_HALF 0x100 #define PHD_DEGREE (PHD_ONE / 360) // = 182 #define PHD_360 (PHD_ONE) // = 65536 = 0x10000 #define PHD_180 (PHD_ONE / 2) // = 32768 = 0x8000 diff --git a/src/global/funcs.h b/src/global/funcs.h index 2a5ee47..20fffed 100644 --- a/src/global/funcs.h +++ b/src/global/funcs.h @@ -6,7 +6,6 @@ // clang-format off #define Output_InsertInventoryBackground ((void __cdecl (*)(const int16_t *obj_ptr))0x00401D50) -#define Output_XGenXG ((int32_t __cdecl (*)(const int16_t *obj_ptr))0x00402D30) #define Output_XGenXGUV ((int32_t __cdecl (*)(const int16_t *obj_ptr))0x00402E80) #define Output_XGen_XGUVPerspFP ((int32_t __cdecl (*)(const int16_t *obj_ptr))0x004030A0) #define Output_GTMap_Persp32FP ((void __cdecl (*)(int32_t y0, int32_t y1, uint8_t *tex_page))0x00403330) diff --git a/src/global/types.h b/src/global/types.h index 4446124..3d519a6 100644 --- a/src/global/types.h +++ b/src/global/types.h @@ -1530,6 +1530,12 @@ typedef struct XBUF_X { int32_t x2; } XBUF_X; +typedef struct XGEN_XG { + int16_t x; + int16_t y; + int16_t g; +} XGEN_XG; + typedef struct XBUF_XG { int32_t x1; int32_t g1; diff --git a/src/inject_exec.c b/src/inject_exec.c index cc7d28b..dd9e150 100644 --- a/src/inject_exec.c +++ b/src/inject_exec.c @@ -111,6 +111,7 @@ static void Inject_Output(void) INJECT(1, 0x00402BD0, Output_DrawPolyGTMap); INJECT(1, 0x00402C10, Output_DrawPolyWGTMap); INJECT(1, 0x00402C50, Output_XGenX); + INJECT(1, 0x00402D30, Output_XGenXG); } static void Inject_Music(void)