diff --git a/docs/progress.svg b/docs/progress.svg
index 87f90676..3bb85632 100644
--- a/docs/progress.svg
+++ b/docs/progress.svg
@@ -69,10 +69,10 @@
Tomb2.exe progress according to the physical function order:
-27.75% (338) · 69.79% (850) · 0.66% (8) · 1.81% (22)
+27.83% (339) · 69.70% (849) · 0.66% (8) · 1.81% (22)
-
-
+
+
@@ -147,7 +147,7 @@
const int16_t *__cdecl Output_InsertObjectGT4_Sorted(const int16_t *obj_ptr, int32_t num, enum SORT_TYPE sort_type);
const int16_t *__cdecl Output_InsertObjectGT3_Sorted(const int16_t *obj_ptr, int32_t num, enum SORT_TYPE sort_type);
const int16_t *__cdecl Output_InsertObjectG4_Sorted(const int16_t *obj_ptr, int32_t num, enum SORT_TYPE sort_type);
-void __cdecl Output_InsertPoly_Gouraud(int32_t vtx_count, float z, int32_t red, int32_t green, int32_t blue, int16_t poly_type);
+void __cdecl Output_InsertPoly_Gouraud(int32_t vtx_count, float z, int32_t red, int32_t green, int32_t blue, int16_t poly_type);
const int16_t *__cdecl Output_InsertObjectG3_Sorted(const int16_t *obj_ptr, int32_t num, enum SORT_TYPE sort_type);
void __cdecl Output_InsertSprite_Sorted(int32_t z, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t sprite_idx, int16_t shade);
void __cdecl Output_InsertFlatRect_Sorted(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx);
@@ -1299,10 +1299,10 @@
Tomb2.exe progress according to the function sizes:
-25.84% · 73.84% · 0.02% · 0.31%
+25.95% · 73.73% · 0.02% · 0.31%
-
-
+
+
@@ -1556,7 +1556,7 @@
void __cdecl SpinningBlade(int16_t item_num);
void __cdecl LiftFloorCeiling(struct ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int32_t *floor, int32_t *ceiling);
void __cdecl Lara_Col_Run(struct ITEM_INFO *item, struct COLL_INFO *coll);
-void __cdecl Output_InsertPoly_Gouraud(int32_t vtx_count, float z, int32_t red, int32_t green, int32_t blue, int16_t poly_type);
+void __cdecl Output_InsertPoly_Gouraud(int32_t vtx_count, float z, int32_t red, int32_t green, int32_t blue, int16_t poly_type);
void __cdecl Boat_DoWakeEffect(struct ITEM_INFO *boat);
bool __cdecl TexturePageInit(TEXPAGE_DESC *page);
void __cdecl WinstonControl(int16_t item_num);
diff --git a/docs/progress.txt b/docs/progress.txt
index 98e035ae..d125a812 100644
--- a/docs/progress.txt
+++ b/docs/progress.txt
@@ -1339,7 +1339,7 @@ typedef enum LARA_MESH {
0040AC80 0000008C + const int16_t *__cdecl Output_InsertObjectGT4_Sorted(const int16_t *obj_ptr, int32_t num, enum SORT_TYPE sort_type);
0040AD10 0000009F + const int16_t *__cdecl Output_InsertObjectGT3_Sorted(const int16_t *obj_ptr, int32_t num, enum SORT_TYPE sort_type);
0040ADB0 0000043B + const int16_t *__cdecl Output_InsertObjectG4_Sorted(const int16_t *obj_ptr, int32_t num, enum SORT_TYPE sort_type);
-0040B1F0 00000175 - void __cdecl Output_InsertPoly_Gouraud(int32_t vtx_count, float z, int32_t red, int32_t green, int32_t blue, int16_t poly_type);
+0040B1F0 00000175 + void __cdecl Output_InsertPoly_Gouraud(int32_t vtx_count, float z, int32_t red, int32_t green, int32_t blue, int16_t poly_type);
0040B370 00000343 + const int16_t *__cdecl Output_InsertObjectG3_Sorted(const int16_t *obj_ptr, int32_t num, enum SORT_TYPE sort_type);
0040B6C0 00000347 + void __cdecl Output_InsertSprite_Sorted(int32_t z, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t sprite_idx, int16_t shade);
0040BA10 0000017F + void __cdecl Output_InsertFlatRect_Sorted(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx);
diff --git a/src/game/output.c b/src/game/output.c
index 196c0f99..9e87196a 100644
--- a/src/game/output.c
+++ b/src/game/output.c
@@ -16,6 +16,24 @@
static D3DCOLOR Output_ShadeLight(uint32_t shade);
static D3DCOLOR Output_ShadeColor(
uint32_t red, uint32_t green, uint32_t blue, uint8_t alpha);
+static D3DCOLOR Output_ShadeLightColor(
+ uint32_t shade, uint32_t red, uint32_t green, uint32_t blue, uint8_t alpha);
+static double Output_CalculatePolyZ(
+ enum SORT_TYPE sort_type, double z0, double z1, double z2, double z3);
+
+static void __fastcall Output_FlatA(int32_t y1, int32_t y2, uint8_t color_idx);
+static void __fastcall Output_TransA(int32_t y1, int32_t y2, uint8_t depth_q);
+static void __fastcall Output_GourA(int32_t y1, int32_t y2, uint8_t color_idx);
+static void __fastcall Output_GTMapA(
+ int32_t y1, int32_t y2, const uint8_t *tex_page);
+static void __fastcall Output_WGTMapA(
+ int32_t y1, int32_t y2, const uint8_t *tex_page);
+static inline void Output_ClipG(
+ struct VERTEX_INFO *const buf, const struct VERTEX_INFO *const vtx1,
+ const struct VERTEX_INFO *const vtx2, const float clip);
+static inline void Output_ClipGUV(
+ struct VERTEX_INFO *const buf, const struct VERTEX_INFO *const vtx1,
+ const struct VERTEX_INFO *const vtx2, const float clip);
static D3DCOLOR Output_ShadeColor(
uint32_t red, uint32_t green, uint32_t blue, uint8_t alpha)
@@ -34,6 +52,16 @@ static D3DCOLOR Output_ShadeLight(uint32_t shade)
return Output_ShadeColor(value, value, value, 0xFF);
}
+static D3DCOLOR Output_ShadeLightColor(
+ uint32_t shade, uint32_t red, uint32_t green, uint32_t blue, uint8_t alpha)
+{
+ shade = 0x1FFF - shade;
+ red = (red * shade) >> 12;
+ green = (green * shade) >> 12;
+ blue = (blue * shade) >> 12;
+ return Output_ShadeColor(red, green, blue, alpha);
+}
+
static double Output_CalculatePolyZ(
enum SORT_TYPE sort_type, double z0, double z1, double z2, double z3)
{
@@ -4106,3 +4134,33 @@ void __cdecl Output_InsertClippedPoly_Textured(
g_HWR_VertexPtr += vtx_count;
g_SurfaceCount++;
}
+
+void __cdecl Output_InsertPoly_Gouraud(
+ const int32_t vtx_count, const float z, const int32_t red,
+ const int32_t green, const int32_t blue, const int16_t poly_type)
+{
+ g_Sort3DPtr->_0 = (int32_t)g_Info3DPtr;
+ g_Sort3DPtr->_1 = MAKE_ZSORT(z);
+ g_Sort3DPtr++;
+
+ *g_Info3DPtr++ = poly_type;
+ *g_Info3DPtr++ = vtx_count;
+ *(D3DTLVERTEX **)g_Info3DPtr = g_HWR_VertexPtr;
+ g_Info3DPtr += sizeof(D3DTLVERTEX *) / sizeof(int16_t);
+
+ for (int i = 0; i < vtx_count; i++) {
+ g_HWR_VertexPtr[i].sx = g_VBuffer[i].x;
+ g_HWR_VertexPtr[i].sy = g_VBuffer[i].y;
+ if (g_SavedAppSettings.zbuffer) {
+ g_HWR_VertexPtr[i].sz =
+ g_FltResZBuf - g_FltResZORhw * g_VBuffer[0].rhw;
+ }
+ g_HWR_VertexPtr[i].rhw = g_VBuffer[0].rhw;
+ g_HWR_VertexPtr[i].color = Output_ShadeLightColor(
+ g_VBuffer[i].g, red, green, blue,
+ poly_type == POLY_HWR_TRANS ? 0x80 : 0xFF);
+ }
+
+ g_HWR_VertexPtr += vtx_count;
+ g_SurfaceCount++;
+}
diff --git a/src/game/output.h b/src/game/output.h
index d9aa26b3..ca71e354 100644
--- a/src/game/output.h
+++ b/src/game/output.h
@@ -151,3 +151,7 @@ const int16_t *__cdecl Output_InsertRoomSprite(
void __cdecl Output_InsertClippedPoly_Textured(
int32_t vtx_count, float z, int16_t poly_type, int16_t tex_page);
+
+void __cdecl Output_InsertPoly_Gouraud(
+ int32_t vtx_count, float z, int32_t red, int32_t green, int32_t blue,
+ int16_t poly_type);
diff --git a/src/global/funcs.h b/src/global/funcs.h
index 11a703ce..5aef23b3 100644
--- a/src/global/funcs.h
+++ b/src/global/funcs.h
@@ -8,7 +8,6 @@
#define Output_InsertInventoryBackground ((void __cdecl (*)(const int16_t *obj_ptr))0x00401D50)
#define Output_DrawClippedPoly_Textured ((void __cdecl (*)(int32_t vtx_count))0x00408D70)
#define Output_DrawPoly_Gouraud ((void __cdecl (*)(int32_t vtx_count, int32_t red, int32_t green, int32_t blue))0x004097F0)
-#define Output_InsertPoly_Gouraud ((void __cdecl (*)(int32_t vtx_count, float z, int32_t red, int32_t green, int32_t blue, int16_t poly_type))0x0040B1F0)
#define Output_DrawSprite ((void __cdecl (*)(uint32_t flags, int32_t x, int32_t y, int32_t z, int16_t sprite_idx, int16_t shade, int16_t scale))0x0040C050)
#define Output_DrawPickup ((void __cdecl (*)(int32_t sx, int32_t sy, int32_t scale, int16_t sprite_idx, int16_t shade))0x0040C320)
#define Output_DrawScreenSprite2D ((void __cdecl (*)(int32_t sx, int32_t sy, int32_t sz, int32_t scale_h, int32_t scale_v, int16_t sprite_idx, int16_t shade, uint16_t flags))0x0040C510)
diff --git a/src/inject_exec.c b/src/inject_exec.c
index 8092a8fa..13417654 100644
--- a/src/inject_exec.c
+++ b/src/inject_exec.c
@@ -183,6 +183,7 @@ static void Inject_Output(void)
INJECT(1, 0x0040AC80, Output_InsertObjectGT4_Sorted);
INJECT(1, 0x0040AD10, Output_InsertObjectGT3_Sorted);
INJECT(1, 0x0040ADB0, Output_InsertObjectG4_Sorted);
+ INJECT(1, 0x0040B1F0, Output_InsertPoly_Gouraud);
INJECT(1, 0x0040B370, Output_InsertObjectG3_Sorted);
INJECT(1, 0x0040B6C0, Output_InsertSprite_Sorted);
INJECT(1, 0x0040BA10, Output_InsertFlatRect_Sorted);