diff --git a/README.md b/README.md index 148b8890..c2fa94da 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ This repo contains a work-in-progress decompilation of Diddy Kong Racing for the All versions are supported, and the US 1.0 version (SHA1 = 0cb115d8716dbbc2922fda38e533b9fe63bb9670) of the game is the default if not specified. -As of June 1, 2025, this is our current score: +As of June 5, 2025, this is our current score:     Decomp progress: 89.17% -    Documentation progress: 58.97% +    Documentation progress: 59.17% --- @@ -117,30 +117,30 @@ s32 is_drumstick_unlocked(void) { ``` -As of June 1, 2025, this is our current score: +As of June 5, 2025, this is our current score: ``` - =================================================================== - ADVENTURE ONE (ASM -> C Decompilation) - -------------- 89.17% Complete (90.50% NON_MATCHING) -------------- - # Decompiled functions: 1907 - # GLOBAL_ASM remaining: 44 + ==================================================================== + ADVENTURE ONE (ASM -> C Decompilation) + -------------- 89.17% Complete (90.50% NON_MATCHING) --------------- + # Decompiled functions: 1907 + # GLOBAL_ASM remaining: 44 # NON_MATCHING functions: 6 - # NON_EQUIVALENT WIP functions: 15 - --------------------------- Game Status --------------------------- + # NON_EQUIVALENT WIP functions: 23 + --------------------------- Game Status ---------------------------- Balloons: 41/47, Keys: 4/4, Trophies: 4/5 - T.T. Amulets: 4/4, Wizpig Amulets: 4/4 - ------------------------------------------------------------------- + T.T. Amulets: 4/4, Wizpig Amulets: 4/4 + -------------------------------------------------------------------- We are racing in Spaceport Alpha. (Lap 3/3) - =================================================================== + ==================================================================== ADVENTURE TWO (Cleanup & Documentation) - ------------------------- 58.97% Complete ------------------------- - # Documented functions: 1204 - # Undocumented remaining: 450 - --------------------------- Game Status --------------------------- - Balloons: 28/47, Keys: 3/4, Trophies: 2/5 - T.T. Amulets: 3/4, Wizpig Amulets: 2/4 - ------------------------------------------------------------------- - We are collecting silver coins in Pirate Lagoon. (8/8 silver coins) - =================================================================== + ------------------------- 59.17% Complete -------------------------- + # Documented functions: 1206 + # Undocumented remaining: 448 + --------------------------- Game Status ---------------------------- + Balloons: 29/47, Keys: 3/4, Trophies: 2/5 + T.T. Amulets: 3/4, Wizpig Amulets: 2/4 + -------------------------------------------------------------------- + We are collecting silver coins in Treasure Caves. (0/8 silver coins) + ==================================================================== ``` diff --git a/include/f3ddkr.h b/include/f3ddkr.h index a46dfc7c..7527dbba 100644 --- a/include/f3ddkr.h +++ b/include/f3ddkr.h @@ -6,29 +6,63 @@ // This file is an extension of PR/gbi.h -// Color combiner values. These need better names! -#define DKR_CC_UNK0 0, 0, 0, COMBINED, COMBINED, 0, PRIMITIVE, 0 -#define DKR_CC_UNK1 ENVIRONMENT, COMBINED, ENV_ALPHA, COMBINED, COMBINED, 0, PRIMITIVE, 0 -#define DKR_CC_UNK2 ENVIRONMENT, COMBINED, ENV_ALPHA, COMBINED, 0, 0, 0, COMBINED -#define DKR_CC_UNK3 ENVIRONMENT, SHADE, ENV_ALPHA, SHADE, 0, 0, 0, SHADE -#define DKR_CC_UNK4 ENVIRONMENT, SHADE, ENV_ALPHA, SHADE, 0, 0, 0, PRIMITIVE -#define DKR_CC_UNK5 TEXEL0, PRIMITIVE, SHADE_ALPHA, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0 -#define DKR_CC_UNK6 ENVIRONMENT, COMBINED, SHADE, COMBINED, 0, 0, 0, COMBINED -#define DKR_CC_UNK7 TEXEL1, TEXEL0, PRIMITIVE, TEXEL0, TEXEL1, TEXEL0, PRIMITIVE, TEXEL0 -#define DKR_CC_UNK8 COMBINED, 0, SHADE, 0, 0, 0, 0, COMBINED -#define DKR_CC_UNK9 PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0 -#define DKR_CC_UNK10 TEXEL0, 0, SCALE, 0, 0, 0, 0, TEXEL0 -#define DKR_CC_UNK11 ENVIRONMENT, TEXEL0, ENV_ALPHA, TEXEL0, TEXEL0, 0, PRIMITIVE, 0 -#define DKR_CC_UNK12 0, 0, 0, ENVIRONMENT, 0, 0, 0, TEXEL0 -#define DKR_CC_UNK13 ENVIRONMENT, TEXEL0, ENV_ALPHA, TEXEL0, TEXEL1, 0, PRIMITIVE, 0 -#define DKR_CC_UNK14 TEXEL1, TEXEL0, SHADE, TEXEL0, 1, TEXEL0, PRIMITIVE, TEXEL0 -#define DKR_CC_UNK15 ENVIRONMENT, COMBINED, ENV_ALPHA, COMBINED, COMBINED, 0, SHADE, 0 -#define DKR_CC_UNK16 ENVIRONMENT, TEXEL0, ENV_ALPHA, TEXEL0, 0, 0, 0, PRIMITIVE +// Color combiner values. -#define DKR_CC_ENVIRONMENT 0, 0, 0, ENVIRONMENT, 0, 0, 0, ENVIRONMENT -#define DKR_CC_DECALFADEPRIM 0, 0, 0, TEXEL0, TEXEL0, 0, PRIMITIVE, 0 +// cycle 1 modes -// For some reason DKR has a value for G_MDSFT_BLENDMASK, despite the fact that it is unsupported. +#define G_CC_ENVIRONMENT 0, 0, 0, ENVIRONMENT, 0, 0, 0, ENVIRONMENT +// blend two textures, modulated by SHADE, alpha modulated between texture and 1 by PRIMITITIVE +#define G_CC_BLENDTEX_MODULATEA_1_PRIM TEXEL1, TEXEL0, SHADE, TEXEL0, 1, TEXEL0, PRIMITIVE, TEXEL0 + +// The following several modes, where blending with ENVIRONMENT is modulated by ENV_ALPHA, +// are likely used to create ambient lighting defined by EnvColor (color and intensity) + +// Blend with ENVIRONMENT modulated by ENV_ALPHA, alpha unchanged +#define G_CC_BLENDI_ENV_ALPHA ENVIRONMENT, SHADE, ENV_ALPHA, SHADE, 0, 0, 0, SHADE +// Blend SHADE and ENVIRONMENT with ENV_ALPHA, alpha from PRIMITIVE +#define G_CC_BLENDI_ENV_ALPHA_A_PRIM ENVIRONMENT, SHADE, ENV_ALPHA, SHADE, 0, 0, 0, PRIMITIVE + +// The following modes do not use vertex colors at all + +// Blend TEXEL0 and ENVIRONMENT with ENV_ALPHA, alpha from PRIMITIVE +#define G_CC_BLENDT_ENV_ALPHA_A_PRIM ENVIRONMENT, TEXEL0, ENV_ALPHA, TEXEL0, 0, 0, 0, PRIMITIVE +// Blend TEXEL0 and ENVIRONMENT with ENV_ALPHA, alpha = TEXEL0 * PRIMITIVE +#define G_CC_BLENDT_ENV_ALPHA_A_TxP ENVIRONMENT, TEXEL0, ENV_ALPHA, TEXEL0, TEXEL0, 0, PRIMITIVE, 0 +// Like above, but alpha = TEXEL1 * PRIMITIVE +#define G_CC_BLENDT_ENV_ALPHA_A_T1xP ENVIRONMENT, TEXEL0, ENV_ALPHA, TEXEL0, TEXEL1, 0, PRIMITIVE, 0 + +// Decal with alpha modulated by PRIMITIVE +#define G_CC_DECAL_A_PRIM 0, 0, 0, TEXEL0, TEXEL0, 0, PRIMITIVE, 0 +// PRIMITIVE and TEXEL0 blend using SHADE_ALPHA, alpha = TEXEL0 * PRIMITIVE +#define G_CC_BLEND_SHADEALPHA TEXEL0, PRIMITIVE, SHADE_ALPHA, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0 +// PRIM and ENV blend, alpha = TEXEL0 * PRIM +#define G_CC_BLENDPE_A_PRIM PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0 +// TEXEL0 * SCALE, used in G_CYC_COPY, unclear purpose +#define G_CC_DECAL_SCALE TEXEL0, 0, SCALE, 0, 0, 0, 0, TEXEL0 +// ENVIRONMENT color, alpha from TEXEL0, used for text +#define G_CC_ENV_DECALA 0, 0, 0, ENVIRONMENT, 0, 0, 0, TEXEL0 +// blend two textures, modulated by PRIMITIVE +// used for blinking lights +#define G_CC_BLENDTEX_PRIM TEXEL1, TEXEL0, PRIMITIVE, TEXEL0, TEXEL1, TEXEL0, PRIMITIVE, TEXEL0 + +// cycle 2 modes + +// Alpha = COMBINED * PRIM +#define G_CC_MODULATEA_PRIM2 0, 0, 0, COMBINED, COMBINED, 0, PRIMITIVE, 0 +// Blend with ENV using ENV_ALPHA, alpha = COMBINED * PRIM +#define G_CC_BLENDI_ENV_ALPHA_PRIM2 ENVIRONMENT, COMBINED, ENV_ALPHA, COMBINED, COMBINED, 0, PRIMITIVE, 0 +// Blend with ENV using ENV_ALPHA, alpha unchanged +#define G_CC_BLEND_ENV_ALPHA2 ENVIRONMENT, COMBINED, ENV_ALPHA, COMBINED, 0, 0, 0, COMBINED +// Blend with ENV using SHADE, alpha unchanged; used after G_CC_BLEND_SHADEALPHA +#define G_CC_BLENDI_SHADE ENVIRONMENT, COMBINED, SHADE, COMBINED, 0, 0, 0, COMBINED +// Blend with ENV using ENV_ALPHA, alpha = COMBINED * SHADE; used for water +#define G_CC_BLENDI_ENV_ALPHA_MODULATEA2 ENVIRONMENT, COMBINED, ENV_ALPHA, COMBINED, COMBINED, 0, SHADE, 0 +#define G_CC_MODULATEIDECALA2 COMBINED, 0, SHADE, 0, 0, 0, 0, COMBINED + +// Inside the RSP, when we change otherMode, it sends the new mode to the RDP with the lower 4 bits set to 1. +// If we use the standard g*SPSetOtherMode macros, this doesn't matter to us. +// But in DKR, direct command transmission to the RDP is often used, bypassing processing in the RSP, +// so in custom code we also need to set those 4 bits to 1. #define G_DKR_BLENDMASK 15 // OtherMode_H values. @@ -52,18 +86,14 @@ // OtherMode_L values. #define DKR_OML_COMMON G_AC_NONE | G_ZS_PIXEL -// Render mode values. These need better names! -#define DKR_RM_UNKNOWN0 Z_UPD | GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_IN, G_BL_1MA) -#define DKR_RM_UNKNOWN1 GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_IN, G_BL_1MA) -#define DKR_RM_UNKNOWN2 AA_EN | IM_RD | CLR_ON_CVG | FORCE_BL | CVG_DST_WRAP | ZMODE_OPA -#define DKR_RM_UNKNOWN2_1 DKR_RM_UNKNOWN2 | GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) -#define DKR_RM_UNKNOWN2_2 DKR_RM_UNKNOWN2 | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) -#define DKR_RM_UNKNOWN3 AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_X_ALPHA | ALPHA_CVG_SEL | CVG_DST_CLAMP | ZMODE_OPA -#define DKR_RM_UNKNOWN3_1 DKR_RM_UNKNOWN3 | GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) -#define DKR_RM_UNKNOWN3_2 DKR_RM_UNKNOWN3 | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) -#define DKR_RM_UNKNOWN4 AA_EN | Z_CMP | IM_RD | CVG_X_ALPHA | FORCE_BL | CVG_DST_CLAMP | ZMODE_XLU -#define DKR_RM_UNKNOWN4_1 DKR_RM_UNKNOWN4 | GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) -#define DKR_RM_UNKNOWN4_2 DKR_RM_UNKNOWN4 | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) +// modified version of RM_AA_ZB_XLU_LINE, with ALPHA_CVG_SEL disabled +#define RM_AA_ZB_XLU_LINE_MOD(clk) \ + AA_EN | Z_CMP | IM_RD | CVG_X_ALPHA | \ + FORCE_BL | CVG_DST_CLAMP | ZMODE_XLU | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define G_RM_AA_ZB_XLU_LINE_MOD RM_AA_ZB_XLU_LINE_MOD(1) +#define G_RM_AA_ZB_XLU_LINE_MOD2 RM_AA_ZB_XLU_LINE_MOD(2) // Temporary until all commands are properly defined. #define fast3d_cmd(pkt, word0, word1) \ diff --git a/include/structs.h b/include/structs.h index 20a05b76..d0410e9e 100644 --- a/include/structs.h +++ b/include/structs.h @@ -799,8 +799,8 @@ typedef struct ObjectHeader { /* 0x1C */ ObjHeaderParticleEntry *objectParticles; s32 pad20; /* 0x24 */ ObjectHeader24 *unk24; - /* 0x28 */ f32 shadeBrightness; - /* 0x2C */ f32 shadeAmbient; + /* 0x28 */ f32 shadeAmbient; + /* 0x2C */ f32 shadeDiffuse; /* 0x30 */ u16 flags; /* 0x32 */ s16 shadowGroup; /* 0x34 */ s16 unk34; @@ -835,7 +835,7 @@ typedef struct ObjectHeader { /* 0x5E */ u8 pad5E[0x2]; /* 0x60 */ char internalName[16]; /* 0x70 */ u8 unk70; - /* 0x71 */ u8 unk71; + /* 0x71 */ u8 directionalPointLighting; // If enabled, the model is lit from the direction of the light source; if disabled, lighting is applied evenly from all sides /* 0x72 */ u8 unk72; u8 pad73[0x5]; } ObjectHeader; @@ -876,33 +876,33 @@ typedef struct WaterEffect { } WaterEffect; typedef struct ShadeProperties { - f32 unk0; - u8 unk4; - u8 unk5; - u8 unk6; - u8 unk7; - s16 unk8; - s16 unkA; - s16 unkC; - u8 unkE; - u8 unkF; - u8 unk10; - u8 unk11; - s16 unk12; - s16 unk14; - s16 unk16; - u8 unk18; - u8 unk19; - u8 unk1A; - u8 unk1B; - s16 unk1C; - s16 unk1E; - s16 unk20; - s16 unk22; - s16 unk24; - s16 unk26; - f32 brightness; - f32 ambient; + /* 0x00 */ f32 unk0; + /* 0x04 */ u8 lightR; + /* 0x05 */ u8 lightG; + /* 0x06 */ u8 lightB; + /* 0x07 */ u8 lightIntensity; + /* 0x08 */ s16 lightDirX; + /* 0x0A */ s16 lightDirY; + /* 0x0C */ s16 lightDirZ; + /* 0x0E */ u8 secondaryLightR; + /* 0x0F */ u8 secondaryLightG; + /* 0x10 */ u8 secondaryLightB; + /* 0x11 */ u8 secondaryLightIntensity; + /* 0x12 */ s16 secondaryLightDirX; + /* 0x14 */ s16 secondaryLightDirY; + /* 0x16 */ s16 secondaryLightDirZ; + /* 0x18 */ u8 shadowR; + /* 0x19 */ u8 shadowG; + /* 0x1A */ u8 shadowB; + /* 0x1B */ u8 unk1B; + /* 0x1C */ s16 shadowDirX; + /* 0x1E */ s16 shadowDirY; + /* 0x20 */ s16 shadowDirZ; + /* 0x22 */ s16 unk22; + /* 0x24 */ s16 unk24; + /* 0x26 */ s16 unk26; + /* 0x28 */ f32 ambient; + /* 0x2C */ f32 diffuse; } ShadeProperties; typedef f32 FakeHalfMatrix[2][4]; diff --git a/src/font.c b/src/font.c index 5e996df9..e672dc88 100644 --- a/src/font.c +++ b/src/font.c @@ -18,16 +18,16 @@ Gfx dDialogueBoxBegin[] = { Gfx dDialogueBoxDrawModes[][2] = { { - gsDPSetCombineMode(DKR_CC_UNK11, DKR_CC_UNK11), + gsDPSetCombineMode(G_CC_BLENDT_ENV_ALPHA_A_TxP, G_CC_BLENDT_ENV_ALPHA_A_TxP), gsDPSetOtherMode(DKR_OMH_1CYC_POINT_NOPERSP, DKR_OML_COMMON | G_RM_XLU_SURF | G_RM_XLU_SURF2), }, { - gsDPSetCombineMode(DKR_CC_ENVIRONMENT, DKR_CC_ENVIRONMENT), + gsDPSetCombineMode(G_CC_ENVIRONMENT, G_CC_ENVIRONMENT), gsDPSetOtherMode(DKR_OMH_1CYC_POINT_NOPERSP, DKR_OML_COMMON | G_RM_XLU_SURF | G_RM_XLU_SURF2), }, #if REGION == REGION_JP { - gsDPSetCombineMode(DKR_CC_UNK13, G_CC_PASS2), + gsDPSetCombineMode(G_CC_BLENDT_ENV_ALPHA_A_T1xP, G_CC_PASS2), gsDPSetOtherMode(DKR_OMH_2CYC_POINT_NOPERSP, DKR_OML_COMMON | G_RM_NOOP | G_RM_XLU_SURF2), }, #endif diff --git a/src/lights.c b/src/lights.c index f0959a34..ab4b8339 100644 --- a/src/lights.c +++ b/src/lights.c @@ -14,8 +14,8 @@ ObjectLight *D_800DC954 = NULL; s32 gMaxLights = 0; s32 gNumActiveLights = 0; unk800DC960 *D_800DC960 = NULL; -Vec3f *D_800DC964 = NULL; -s32 D_800DC968 = 0; // Currently unknown, might be a different type. +Vec3f *gLightDirs = NULL; +s32 numLights = 0; // Currently unknown, might be a different type. /*******************************/ @@ -38,7 +38,7 @@ void free_lights(void) { gActiveLights = NULL; D_800DC954 = NULL; D_800DC960 = NULL; - D_800DC964 = NULL; + gLightDirs = NULL; } gNumActiveLights = 0; gMaxLights = 0; @@ -62,7 +62,7 @@ void setup_lights(s32 count) { buffer += temp * sizeof(ObjectLight *); D_800DC954 = (ObjectLight *) buffer; D_800DC960 = (unk800DC960 *) ((u32) D_800DC954 + temp * sizeof(ObjectLight)); - D_800DC964 = (Vec3f *) ((u32) D_800DC960 + temp * sizeof(unk800DC960)); + gLightDirs = (Vec3f *) ((u32) D_800DC960 + temp * sizeof(unk800DC960)); for (i = 0; i < gMaxLights; i++) { gActiveLights[i] = &D_800DC954[i]; } @@ -95,16 +95,16 @@ ObjectLight *func_80031CAC(Object *obj, LevelObjectEntry_RgbaLight *lightEntry) light->pos.y = lightEntry->common.y; light->pos.z = lightEntry->common.z; } - light->unk1C = lightEntry->unkA << 16; + light->colourR = lightEntry->unkA << 16; light->unk2C = 0; light->unk3C = 0; - light->unk20 = lightEntry->unkB << 16; + light->colourG = lightEntry->unkB << 16; light->unk30 = 0; light->unk3E = 0; - light->unk24 = lightEntry->unkC << 16; + light->colourB = lightEntry->unkC << 16; light->unk34 = 0; light->unk40 = 0; - light->unk28 = lightEntry->unkD << 16; + light->intensity = lightEntry->unkD << 16; light->unk38 = 0; light->unk42 = 0; light->unk44 = NULL; @@ -162,16 +162,16 @@ ObjectLight *add_object_light(Object *obj, ObjectHeader24 *arg1) { light->pos.x = light->homeX; light->pos.y = light->homeY; light->pos.z = light->homeZ; - light->unk1C = arg1->unk2 << 16; + light->colourR = arg1->unk2 << 16; light->unk2C = 0; light->unk3C = 0; - light->unk20 = arg1->unk3 << 16; + light->colourG = arg1->unk3 << 16; light->unk30 = 0; light->unk3E = 0; - light->unk24 = arg1->unk4 << 16; + light->colourB = arg1->unk4 << 16; light->unk34 = 0; light->unk40 = 0; - light->unk28 = arg1->unk5 << 16; + light->intensity = arg1->unk5 << 16; light->unk38 = 0; light->unk42 = 0; if (arg1->unk6 != 0xFFFF) { @@ -234,14 +234,14 @@ UNUSED void toggle_object_light(ObjectLight *light) { UNUSED void func_80032248(ObjectLight *light, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6) { if (arg2 > 0) { light->unk3C = arg2; - light->unk2C = ((arg1 << 0x10) - light->unk1C) / arg2; + light->unk2C = ((arg1 << 0x10) - light->colourR) / arg2; } if (arg4 > 0) { light->unk3E = arg4; - light->unk30 = ((arg3 << 0x10) - light->unk20) / arg4; + light->unk30 = ((arg3 << 0x10) - light->colourG) / arg4; } if (arg6 > 0) { - light->unk34 = ((arg5 << 0x10) - light->unk24) / arg6; + light->unk34 = ((arg5 << 0x10) - light->colourB) / arg6; light->unk40 = arg6; } } @@ -249,7 +249,7 @@ UNUSED void func_80032248(ObjectLight *light, s32 arg1, s32 arg2, s32 arg3, s32 UNUSED void func_80032344(ObjectLight *light, s32 arg1, s32 arg2) { if (arg2 > 0) { light->unk42 = arg2; - light->unk38 = ((arg1 << 0x10) - light->unk28) / arg2; + light->unk38 = ((arg1 << 0x10) - light->intensity) / arg2; } } @@ -295,49 +295,49 @@ void func_80032424(ObjectLight *light, s32 updateRate) { var_a3 = light->unk44; } temp_v0 = (0x10000 / temp_v1->unk4); - light->unk1C = ((var_a3->unk0 - temp_v1->unk0) * light->unk4C * temp_v0) + (temp_v1->unk0 << 0x10); - light->unk20 = ((var_a3->unk1 - temp_v1->unk1) * light->unk4C * temp_v0) + (temp_v1->unk1 << 0x10); - light->unk24 = ((var_a3->unk2 - temp_v1->unk2) * light->unk4C * temp_v0) + (temp_v1->unk2 << 0x10); - light->unk28 = ((var_a3->unk3 - temp_v1->unk3) * light->unk4C * temp_v0) + (temp_v1->unk3 << 0x10); + light->colourR = ((var_a3->unk0 - temp_v1->unk0) * light->unk4C * temp_v0) + (temp_v1->unk0 << 0x10); + light->colourG = ((var_a3->unk1 - temp_v1->unk1) * light->unk4C * temp_v0) + (temp_v1->unk1 << 0x10); + light->colourB = ((var_a3->unk2 - temp_v1->unk2) * light->unk4C * temp_v0) + (temp_v1->unk2 << 0x10); + light->intensity = ((var_a3->unk3 - temp_v1->unk3) * light->unk4C * temp_v0) + (temp_v1->unk3 << 0x10); } else { if (light->unk3C != 0) { temp_v0 = light->unk3C; if (updateRate < light->unk3C) { - light->unk1C += light->unk2C * updateRate; + light->colourR += light->unk2C * updateRate; light->unk3C -= updateRate; } else { light->unk3C = 0; - light->unk1C += light->unk2C * temp_v0; + light->colourR += light->unk2C * temp_v0; } } if (light->unk3E != 0) { temp_v0 = light->unk3E; if (updateRate < light->unk3E) { - light->unk20 += light->unk30 * updateRate; + light->colourG += light->unk30 * updateRate; light->unk3E -= updateRate; } else { light->unk3E = 0; - light->unk20 += light->unk30 * temp_v0; + light->colourG += light->unk30 * temp_v0; } } if (light->unk40 != 0) { temp_v0 = light->unk40; if (updateRate < light->unk40) { - light->unk24 += light->unk34 * updateRate; + light->colourB += light->unk34 * updateRate; light->unk40 -= updateRate; } else { light->unk40 = 0; - light->unk24 += light->unk34 * temp_v0; + light->colourB += light->unk34 * temp_v0; } } if (light->unk42 != 0) { temp_v0 = light->unk42; if (updateRate < light->unk42) { - light->unk28 += light->unk38 * updateRate; + light->intensity += light->unk38 * updateRate; light->unk42 -= updateRate; } else { light->unk42 = 0; - light->unk28 += light->unk38 * temp_v0; + light->intensity += light->unk38 * temp_v0; } } } @@ -367,7 +367,7 @@ void func_80032424(ObjectLight *light, s32 updateRate) { } light->unk5 = 1; } - if (light->unk5 != 0) { + if (light->unk5) { light->unk50 = light->pos.x - light->radius; light->unk56 = light->pos.x + light->radius; if (light->unk0 == 1) { @@ -385,17 +385,17 @@ void func_80032424(ObjectLight *light, s32 updateRate) { light->unk5A = light->pos.z + light->radius; } if (light->unk1 == 2) { - light->unk7C.z = -1.0f; + light->direction.z = -1.0f; rotation.y_rotation = light->unk70; rotation.x_rotation = light->unk72; rotation.z_rotation = 0; - vec3f_rotate_py(&rotation, &light->unk7C); + vec3f_rotate_py(&rotation, &light->direction); if (light->owner != NULL) { - vec3f_rotate(&light->owner->segment.trans.rotation, &light->unk7C); + vec3f_rotate(&light->owner->segment.trans.rotation, &light->direction); } - light->unk7C.x = -light->unk7C.x; - light->unk7C.y = -light->unk7C.y; - light->unk7C.z = -light->unk7C.z; + light->direction.x = -light->direction.x; + light->direction.y = -light->direction.y; + light->direction.z = -light->direction.z; } light->unk5 = 0; } @@ -431,11 +431,11 @@ s32 get_light_count(void) { void func_80032C7C(Object *object) { ObjectLight *light; - s16 phi_a0, phi_a1; - f32 f20; - s16 sp82; - s16 sp80; - s16 sp7E; + s16 primIndex, secIndex; + f32 intensity; + s16 objX; + s16 objY; + s16 objZ; u8 sp64; s32 i; @@ -458,22 +458,24 @@ void func_80032C7C(Object *object) { break; } - sp82 = object->segment.trans.x_position; - sp80 = object->segment.trans.y_position; - sp7E = object->segment.trans.z_position; - D_800DC968 = 0; + objX = object->segment.trans.x_position; + objY = object->segment.trans.y_position; + objZ = object->segment.trans.z_position; + + numLights = 0; + for (i = 0; i < gNumActiveLights; i++) { light = gActiveLights[i]; - if ((light->unk2 & sp64) && (light->enabled == 1) && (sp82 >= light->unk50) && (light->unk56 >= sp82) && - (sp80 >= light->unk52) && (light->unk58 >= sp80) && (sp7E >= light->unk54) && (light->unk5A >= sp7E)) { + if ((light->unk2 & sp64) && (light->enabled == TRUE) && (objX >= light->unk50) && (light->unk56 >= objX) && + (objY >= light->unk52) && (light->unk58 >= objY) && (objZ >= light->unk54) && (light->unk5A >= objZ)) { if (light->unk0 == 0) { - if (light->unk28 >= 0x10000) { - D_800DC960[D_800DC968].unk0 = light; - D_800DC960[D_800DC968].unk4 = light->unk1C >> 0x10; - D_800DC960[D_800DC968].unk8 = light->unk20 >> 0x10; - D_800DC960[D_800DC968].unkC = light->unk24 >> 0x10; - D_800DC960[D_800DC968].unk10 = light->unk28 >> 0x10; - D_800DC968++; + if (light->intensity >= 0x10000) { + D_800DC960[numLights].lightObj = light; + D_800DC960[numLights].colourR = light->colourR >> 0x10; + D_800DC960[numLights].colourG = light->colourG >> 0x10; + D_800DC960[numLights].colourB = light->colourB >> 0x10; + D_800DC960[numLights].intensity = light->intensity >> 0x10; + numLights++; } } else { gLightDiffX = light->pos.x - object->segment.trans.x_position; @@ -486,14 +488,14 @@ void func_80032C7C(Object *object) { (gLightDiffX * gLightDiffX) + (gLightDiffY * gLightDiffY) + (gLightDiffZ * gLightDiffZ); if (gLightDistance < light->radiusSquare) { if (light->unk1 == 2) { - f20 = light_direction_calc(light); + intensity = light_direction_calc(light); } else { - f20 = 1.0f; + intensity = 1.0f; } - if (f20 > 0.0f) { - f20 *= light_distance_calc(light); - if (f20 > 0.0f) { - if (object->segment.header->unk71 != 0) { + if (intensity > 0.0f) { + intensity *= light_distance_calc(light); + if (intensity > 0.0f) { + if (object->segment.header->directionalPointLighting) { if (gLightDistance > 0.0f) { f32 temp = 1.0f / sqrtf(gLightDistance); gLightDiffX *= temp; @@ -504,16 +506,16 @@ void func_80032C7C(Object *object) { gLightDiffY = 0; gLightDiffZ = -1.0f; } - D_800DC964[D_800DC968].x = gLightDiffX; - D_800DC964[D_800DC968].y = gLightDiffY; - D_800DC964[D_800DC968].z = gLightDiffZ; + gLightDirs[numLights].x = gLightDiffX; + gLightDirs[numLights].y = gLightDiffY; + gLightDirs[numLights].z = gLightDiffZ; } - D_800DC960[D_800DC968].unk0 = light; - D_800DC960[D_800DC968].unk4 = light->unk1C >> 0x10; - D_800DC960[D_800DC968].unk8 = light->unk20 >> 0x10; - D_800DC960[D_800DC968].unkC = light->unk24 >> 0x10; - D_800DC960[D_800DC968].unk10 = (u8) f20; - D_800DC968++; + D_800DC960[numLights].lightObj = light; + D_800DC960[numLights].colourR = light->colourR >> 0x10; + D_800DC960[numLights].colourG = light->colourG >> 0x10; + D_800DC960[numLights].colourB = light->colourB >> 0x10; + D_800DC960[numLights].intensity = (u8) intensity; + numLights++; } } } @@ -521,66 +523,68 @@ void func_80032C7C(Object *object) { } } - if (object->segment.header->unk71 != 0) { - if (D_800DC968 == 0) { - object->shading->unk7 = 0; - object->shading->unk11 = 0; - } else if (D_800DC968 == 1) { - object->shading->unk4 = D_800DC960[0].unk4; - object->shading->unk5 = D_800DC960[0].unk8; - object->shading->unk6 = D_800DC960[0].unkC; - object->shading->unk7 = D_800DC960[0].unk10; - object->shading->unk11 = 0; - object->shading->unk8 = D_800DC964[0].x * 8192.0f; - object->shading->unkA = D_800DC964[0].y * 8192.0f; - object->shading->unkC = D_800DC964[0].z * 8192.0f; + if (object->segment.header->directionalPointLighting) { + // find two brightest light sources + if (numLights == 0) { + object->shading->lightIntensity = 0; + object->shading->secondaryLightIntensity = 0; + } else if (numLights == 1) { + object->shading->lightR = D_800DC960[0].colourR; + object->shading->lightG = D_800DC960[0].colourG; + object->shading->lightB = D_800DC960[0].colourB; + object->shading->lightIntensity = D_800DC960[0].intensity; + object->shading->secondaryLightIntensity = 0; + object->shading->lightDirX = gLightDirs[0].x * 8192.0f; + object->shading->lightDirY = gLightDirs[0].y * 8192.0f; + object->shading->lightDirZ = gLightDirs[0].z * 8192.0f; } else { - if (D_800DC960[1].unk10 < D_800DC960[0].unk10) { - phi_a0 = 0; - phi_a1 = 1; + if (D_800DC960[1].intensity < D_800DC960[0].intensity) { + primIndex = 0; + secIndex = 1; } else { - phi_a0 = 1; - phi_a1 = 0; + primIndex = 1; + secIndex = 0; } - for (i = 2; i < D_800DC968; i++) { - if (D_800DC960[phi_a1].unk10 < D_800DC960[i].unk10) { - if (D_800DC960[phi_a0].unk10 < D_800DC960[i].unk10) { - phi_a1 = phi_a0; - phi_a0 = i; + for (i = 2; i < numLights; i++) { + if (D_800DC960[secIndex].intensity < D_800DC960[i].intensity) { + if (D_800DC960[primIndex].intensity < D_800DC960[i].intensity) { + secIndex = primIndex; + primIndex = i; } else { - phi_a1 = i; + secIndex = i; } } } - object->shading->unk4 = D_800DC960[phi_a0].unk4; - object->shading->unk5 = D_800DC960[phi_a0].unk8; - object->shading->unk6 = D_800DC960[phi_a0].unkC; - object->shading->unk7 = D_800DC960[phi_a0].unk10; - object->shading->unk8 = D_800DC964[phi_a0].x * 8192.0f; - object->shading->unkA = D_800DC964[phi_a0].y * 8192.0f; - object->shading->unkC = D_800DC964[phi_a0].z * 8192.0f; - object->shading->unkE = D_800DC960[phi_a1].unk4; - object->shading->unkF = D_800DC960[phi_a1].unk8; - object->shading->unk10 = D_800DC960[phi_a1].unkC; - object->shading->unk11 = D_800DC960[phi_a1].unk10; - object->shading->unk12 = D_800DC964[phi_a1].x * 8192.0f; - object->shading->unk14 = D_800DC964[phi_a1].y * 8192.0f; - object->shading->unk16 = D_800DC964[phi_a1].z * 8192.0f; + object->shading->lightR = D_800DC960[primIndex].colourR; + object->shading->lightG = D_800DC960[primIndex].colourG; + object->shading->lightB = D_800DC960[primIndex].colourB; + object->shading->lightIntensity = D_800DC960[primIndex].intensity; + object->shading->lightDirX = gLightDirs[primIndex].x * 8192.0f; + object->shading->lightDirY = gLightDirs[primIndex].y * 8192.0f; + object->shading->lightDirZ = gLightDirs[primIndex].z * 8192.0f; + + object->shading->secondaryLightR = D_800DC960[secIndex].colourR; + object->shading->secondaryLightG = D_800DC960[secIndex].colourG; + object->shading->secondaryLightB = D_800DC960[secIndex].colourB; + object->shading->secondaryLightIntensity = D_800DC960[secIndex].intensity; + object->shading->secondaryLightDirX = gLightDirs[secIndex].x * 8192.0f; + object->shading->secondaryLightDirY = gLightDirs[secIndex].y * 8192.0f; + object->shading->secondaryLightDirZ = gLightDirs[secIndex].z * 8192.0f; } } else { - if (D_800DC968 > 0) { - if (D_800DC968 >= 2) { + if (numLights > 0) { + if (numLights >= 2) { func_800337E4(); } - object->shading->unk4 = D_800DC960[0].unk4; - object->shading->unk5 = D_800DC960[0].unk8; - object->shading->unk6 = D_800DC960[0].unkC; - object->shading->unk7 = D_800DC960[0].unk10; + object->shading->lightR = D_800DC960[0].colourR; + object->shading->lightG = D_800DC960[0].colourG; + object->shading->lightB = D_800DC960[0].colourB; + object->shading->lightIntensity = D_800DC960[0].intensity; } else { - object->shading->unk4 = 0xFF; - object->shading->unk5 = 0xFF; - object->shading->unk6 = 0xFF; - object->shading->unk7 = 0; + object->shading->lightR = 255; + object->shading->lightG = 255; + object->shading->lightB = 255; + object->shading->lightIntensity = 0; } } } @@ -590,28 +594,28 @@ void func_800337E4(void) { s32 temp_lo; s32 i; - for (i = 1; i < D_800DC968; i++) { - if (D_800DC960[i].unk10 >= 2) { - if (D_800DC960[0].unk10 >= D_800DC960[i].unk10) { - temp_lo = (D_800DC960[i].unk10 << 16) / D_800DC960[0].unk10; - D_800DC960[0].unk4 += (D_800DC960[i].unk4 * temp_lo) >> 16; - D_800DC960[0].unk8 += (D_800DC960[i].unk8 * temp_lo) >> 16; - D_800DC960[0].unkC += (D_800DC960[i].unkC * temp_lo) >> 16; + for (i = 1; i < numLights; i++) { + if (D_800DC960[i].intensity >= 2) { + if (D_800DC960[0].intensity >= D_800DC960[i].intensity) { + temp_lo = (D_800DC960[i].intensity << 16) / D_800DC960[0].intensity; + D_800DC960[0].colourR += (D_800DC960[i].colourR * temp_lo) >> 16; + D_800DC960[0].colourG += (D_800DC960[i].colourG * temp_lo) >> 16; + D_800DC960[0].colourB += (D_800DC960[i].colourB * temp_lo) >> 16; } else { - temp_lo = (D_800DC960[0].unk10 << 16) / D_800DC960[i].unk10; - D_800DC960[0].unk4 = ((D_800DC960[0].unk4 * temp_lo) >> 16) + D_800DC960[i].unk4; - D_800DC960[0].unk8 = ((D_800DC960[0].unk8 * temp_lo) >> 16) + D_800DC960[i].unk8; - D_800DC960[0].unkC = ((D_800DC960[0].unkC * temp_lo) >> 16) + D_800DC960[i].unkC; - D_800DC960[0].unk10 = D_800DC960[i].unk10; + temp_lo = (D_800DC960[0].intensity << 16) / D_800DC960[i].intensity; + D_800DC960[0].colourR = ((D_800DC960[0].colourR * temp_lo) >> 16) + D_800DC960[i].colourR; + D_800DC960[0].colourG = ((D_800DC960[0].colourG * temp_lo) >> 16) + D_800DC960[i].colourG; + D_800DC960[0].colourB = ((D_800DC960[0].colourB * temp_lo) >> 16) + D_800DC960[i].colourB; + D_800DC960[0].intensity = D_800DC960[i].intensity; } - if (D_800DC960[0].unk4 >= 256) { - D_800DC960[0].unk4 = 255; + if (D_800DC960[0].colourR >= 256) { + D_800DC960[0].colourR = 255; } - if (D_800DC960[0].unk8 >= 256) { - D_800DC960[0].unk8 = 255; + if (D_800DC960[0].colourG >= 256) { + D_800DC960[0].colourG = 255; } - if (D_800DC960[0].unkC >= 256) { - D_800DC960[0].unkC = 255; + if (D_800DC960[0].colourB >= 256) { + D_800DC960[0].colourB = 255; } } } @@ -624,7 +628,7 @@ f32 light_distance_calc(ObjectLight *light) { f32 dist; f32 mag; - dist = light->unk28 / 65536.0f; + dist = light->intensity / 65536.0f; switch (light->type) { case LIGHT_UNK1: mag = 1.0f - (sqrtf(gLightDistance) * light->radiusMag); @@ -656,14 +660,14 @@ f32 light_distance_calc(ObjectLight *light) { * Official Name: lightDirectionCalc */ f32 light_direction_calc(ObjectLight *light) { - f32 mag; + f32 invDist; f32 distance; distance = gLightDistance; if (distance > 0.0f) { - mag = 1.0f / sqrtf(distance); - distance = (gLightDiffX * mag * light->unk7C.x) + (gLightDiffY * mag * light->unk7C.y) + - (gLightDiffZ * mag * light->unk7C.z); + invDist = 1.0f / sqrtf(distance); + distance = (gLightDiffX * invDist * light->direction.x) + (gLightDiffY * invDist * light->direction.y) + + (gLightDiffZ * invDist * light->direction.z); if (distance < 0.0f) { distance = 0.0f; } diff --git a/src/lights.h b/src/lights.h index 54460b6b..adc5e683 100644 --- a/src/lights.h +++ b/src/lights.h @@ -41,10 +41,10 @@ typedef struct ObjectLight { s16 homeZ; Object *owner; Vec3f pos; - s32 unk1C; - s32 unk20; - s32 unk24; - s32 unk28; + s32 colourR; + s32 colourG; + s32 colourB; + s32 intensity; s32 unk2C; s32 unk30; s32 unk34; @@ -78,16 +78,16 @@ typedef struct ObjectLight { s16 unk76; u16 unk78; u16 unk7A; - Vec3f unk7C; // Think this might be scale. + Vec3f direction; // Think this might be scale. } ObjectLight; /* Size: 0x14 bytes */ typedef struct unk800DC960 { - ObjectLight* unk0; - s32 unk4; - s32 unk8; - s32 unkC; - s32 unk10; + ObjectLight* lightObj; + s32 colourR; + s32 colourG; + s32 colourB; + s32 intensity; } unk800DC960; void free_lights(void); diff --git a/src/object_functions.c b/src/object_functions.c index 90ec4e2f..f4ae83cb 100644 --- a/src/object_functions.c +++ b/src/object_functions.c @@ -622,8 +622,8 @@ void obj_loop_trophycab(Object *obj, s32 updateRate) { } } } - obj->shading->ambient = 0.612f; - obj->shading->brightness = 0.0f; + obj->shading->diffuse = 0.612f; + obj->shading->ambient = 0.0f; tempObj = get_racer_object(PLAYER_ONE); if (tempObj != NULL) { diffX = obj->segment.trans.x_position - tempObj->segment.trans.x_position; @@ -690,7 +690,7 @@ void obj_loop_trophycab(Object *obj, s32 updateRate) { } obj->unk5C->unk100 = NULL; if (worldBalloons) { - obj->shading->brightness = 0.552f; + obj->shading->ambient = 0.552f; } } } @@ -6173,7 +6173,7 @@ void obj_init_midifade(Object *obj, LevelObjectEntry_MidiFade *entry) { midiFade->unkC = oy; midiFade->unk10 = oz; midiFade->unk14 = -((obj->segment.trans.x_position * ox) + (obj->segment.trans.y_position * oy) + - (obj->segment.trans.z_position * oz)); + (obj->segment.trans.z_position * oz)); midiFade->unk2 = entry->unk1A; midiFade->unk40 = entry->unk1B; diff --git a/src/object_models.c b/src/object_models.c index 28d95040..2431f3c2 100644 --- a/src/object_models.c +++ b/src/object_models.c @@ -773,7 +773,7 @@ s32 func_80060EA8(ObjectModel *arg0) { for (var_s1 = 0; var_s1 < temp_v1; var_s1++) { if (temp_ra[var_s1].miscData != BATCH_VTX_COL || (temp_ra[var_s1].flags & RENDER_ENVMAP)) { var_a3 = (var_a3 + (temp_ra[var_s1 + 1]).verticesOffset) - temp_ra[var_s1].verticesOffset; - } + } } if (var_a3 > 0) { temp_s3 = arg0->vertices; @@ -791,10 +791,10 @@ s32 func_80060EA8(ObjectModel *arg0) { mempool_free(spAC); return 1; } - + var_v1 = arg0->numberOfBatches; for (var_s1_2 = 0; var_s1_2 < var_v1; var_s1_2++) { - temp_v0_4 = &var_ra[var_s1_2]; + temp_v0_4 = &var_ra[var_s1_2]; temp_s4 = temp_v0_4->verticesOffset; for (var_s5 = temp_v0_4->facesOffset; var_s5 < (temp_v0_4 + 1)->facesOffset; var_s5 += 1) { for (var_a3_2 = 0; var_a3_2 < 3; var_a3_2++) { @@ -835,17 +835,23 @@ s32 func_80060EA8(ObjectModel *arg0) { var_a1 = 0; temp_v1_3 = &temp_s3[var_t3]; if (batchNum >= 0) { -loop_30: + loop_30: temp_a3 = &var_ra[var_a1]; - if ((sp50->miscData == temp_a3->miscData) && (((var_a0 = temp_a3->verticesOffset, (var_a1 == batchNum)) && (var_a0 < var_t3)) || ((var_a1 != batchNum) && (var_a0 < (temp_a3 + 1)->verticesOffset))) && (var_a2 < 0)) { -loop_36: + if ((sp50->miscData == temp_a3->miscData) && + (((var_a0 = temp_a3->verticesOffset, (var_a1 == batchNum)) && (var_a0 < var_t3)) || + ((var_a1 != batchNum) && (var_a0 < (temp_a3 + 1)->verticesOffset))) && + (var_a2 < 0)) { + loop_36: temp_v1_4 = &temp_s3[var_a0]; - if ((temp_v1_3->x == temp_v1_4->x) && (temp_v1_3->y == temp_v1_4->y) && (temp_v1_3->z == temp_v1_4->z)) { + if ((temp_v1_3->x == temp_v1_4->x) && (temp_v1_3->y == temp_v1_4->y) && + (temp_v1_3->z == temp_v1_4->z)) { var_a2 = *(temp_v0_5 + (var_a0 * 2)); } temp_t8_3 = var_a0 + 1; var_a0 = temp_t8_3; - if ((((var_a1 == batchNum) && (temp_t8_3 < var_t3)) || ((var_a1 != batchNum) && (var_a0 < (temp_a3 + 1)->verticesOffset))) && (var_a2 < 0)) { + if ((((var_a1 == batchNum) && (temp_t8_3 < var_t3)) || + ((var_a1 != batchNum) && (var_a0 < (temp_a3 + 1)->verticesOffset))) && + (var_a2 < 0)) { goto loop_36; } } @@ -868,16 +874,23 @@ loop_36: var_a1_2 = 0; temp_v1_5 = &temp_s3[var_t3]; if (batchNum >= 0) { -loop_54: + loop_54: temp_a3_2 = &var_ra[var_a1_2]; - if ((temp_a3_2->flags & RENDER_ENVMAP) && (((var_a0_2 = temp_a3_2->verticesOffset, (var_a1_2 == batchNum)) && (var_a0_2 < var_t3)) || ((var_a1_2 != batchNum) && (var_a0_2 < (temp_a3_2 + 1)->facesOffset))) && (var_a2_2 < 0)) { -loop_60: + if ((temp_a3_2->flags & RENDER_ENVMAP) && + (((var_a0_2 = temp_a3_2->verticesOffset, (var_a1_2 == batchNum)) && + (var_a0_2 < var_t3)) || + ((var_a1_2 != batchNum) && (var_a0_2 < (temp_a3_2 + 1)->facesOffset))) && + (var_a2_2 < 0)) { + loop_60: temp_v1_6 = &temp_s3[var_a0_2]; - if ((temp_v1_5->x == temp_v1_6->x) && (temp_v1_5->y == temp_v1_6->y) && (temp_v1_5->z == temp_v1_6->z)) { + if ((temp_v1_5->x == temp_v1_6->x) && (temp_v1_5->y == temp_v1_6->y) && + (temp_v1_5->z == temp_v1_6->z)) { var_a2_2 = *(temp_v0_5 + (var_a0_2 * 2)); } var_a0_2++; - if ((((var_a1_2 == batchNum) && (var_a0_2 < var_t3)) || ((var_a1_2 != batchNum) && (var_a0_2 < (temp_a3_2 + 1)->facesOffset))) && (var_a2_2 < 0)) { + if ((((var_a1_2 == batchNum) && (var_a0_2 < var_t3)) || + ((var_a1_2 != batchNum) && (var_a0_2 < (temp_a3_2 + 1)->facesOffset))) && + (var_a2_2 < 0)) { goto loop_60; } } @@ -920,7 +933,8 @@ loop_60: while (var_s1_4 < var_v1_3) { temp_s1_2 = var_s1_4 + 1; temp_t0 = &var_ra[var_s1_4]; - if ((temp_t0->miscData != BATCH_VTX_COL) || (var_t8_2 = temp_s1_2 << 0x10, ((temp_t0->flags & RENDER_ENVMAP) != 0))) { + if ((temp_t0->miscData != BATCH_VTX_COL) || + (var_t8_2 = temp_s1_2 << 0x10, ((temp_t0->flags & RENDER_ENVMAP) != 0))) { var_s5_2 = temp_t0->facesOffset; var_t8_2 = temp_s1_2 << 0x10; if (var_s5_2 < (temp_t0 + 1)->facesOffset) { @@ -929,7 +943,7 @@ loop_60: temp_a0 = &spB0->verticesArray[var_t7]; var_a3_4 = 0; var_t6 = temp_a0; -loop_89: + loop_89: temp_a2 = *(temp_v0_5 + ((s16) (var_t6[1] + temp_t0->verticesOffset) * 2)); var_a3_4 += 1; if (temp_a2 >= 0) { @@ -975,7 +989,7 @@ loop_89: var_t9_2 = temp_a3_3 << 0x10; if (temp_a2_2 >= 0) { spA0[var_a0_3].x = temp_v0_6[temp_a2_2].x; - spA0[var_a0_3].y= temp_v0_6[temp_a2_2].y; + spA0[var_a0_3].y = temp_v0_6[temp_a2_2].y; spA0[var_a0_3].z = temp_v0_6[temp_a2_2].z; var_t9_2 = temp_a3_3 << 0x10; var_a0_3++; diff --git a/src/objects.c b/src/objects.c index c0a3c1e8..56c5d9ec 100644 --- a/src/objects.c +++ b/src/objects.c @@ -2164,26 +2164,25 @@ s32 init_object_shading(Object *obj, ShadeProperties *shadeData) { if (obj->segment.header->modelType == OBJECT_MODEL_TYPE_3D_MODEL) { for (i = 0; obj->unk68[i] == NULL; i++) {} if (obj->unk68[i] != NULL && obj->unk68[i]->objModel->unk40 != NULL) { - set_shading_properties(obj->shading, obj->segment.header->shadeBrightness, - obj->segment.header->shadeAmbient, 0, obj->segment.header->shadeAngleY, - obj->segment.header->shadeAngleZ); + set_shading_properties(obj->shading, obj->segment.header->shadeAmbient, obj->segment.header->shadeDiffuse, + 0, obj->segment.header->shadeAngleY, obj->segment.header->shadeAngleZ); if (obj->segment.header->unk3D != 0) { - obj->shading->unk4 = obj->segment.header->unk3A; - obj->shading->unk5 = obj->segment.header->unk3B; - obj->shading->unk6 = obj->segment.header->unk3C; - obj->shading->unk7 = obj->segment.header->unk3D; - obj->shading->unk8 = -(obj->shading->unk1C >> 1); - obj->shading->unkA = -(obj->shading->unk1E >> 1); - obj->shading->unkC = -(obj->shading->unk20 >> 1); + obj->shading->lightR = obj->segment.header->unk3A; + obj->shading->lightG = obj->segment.header->unk3B; + obj->shading->lightB = obj->segment.header->unk3C; + obj->shading->lightIntensity = obj->segment.header->unk3D; + obj->shading->lightDirX = -(obj->shading->shadowDirX >> 1); + obj->shading->lightDirY = -(obj->shading->shadowDirY >> 1); + obj->shading->lightDirZ = -(obj->shading->shadowDirZ >> 1); } returnSize = sizeof(ShadeProperties); } } else if (obj->segment.header->modelType == OBJECT_MODEL_TYPE_SPRITE_BILLBOARD) { obj->shading->unk0 = 1.0f; - shadeData->unk4 = 0xFF; - shadeData->unk5 = 0xFF; - shadeData->unk6 = 0xFF; - shadeData->unk7 = 0; + shadeData->lightR = 255; + shadeData->lightG = 255; + shadeData->lightB = 255; + shadeData->lightIntensity = 0; returnSize = 8; } if (returnSize == 0) { @@ -3181,8 +3180,8 @@ void render_3d_billboard(Object *obj) { gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, 255, 255, 255, 255); } if (hasEnvCol) { - gDPSetEnvColor(gObjectCurrDisplayList++, obj->shading->unk4, obj->shading->unk5, obj->shading->unk6, - obj->shading->unk7); + gDPSetEnvColor(gObjectCurrDisplayList++, obj->shading->lightR, obj->shading->lightG, obj->shading->lightB, + obj->shading->lightIntensity); } else if (obj->behaviorId == BHV_LAVA_SPURT) { hasEnvCol = TRUE; gDPSetEnvColor(gObjectCurrDisplayList++, 255, 255, 0, 255); @@ -3238,11 +3237,11 @@ void render_3d_billboard(Object *obj) { void render_3d_model(Object *obj) { s32 i; s32 intensity; - s32 alpha; + s32 opacity; s32 vertOffset; s32 obj60_unk0; s32 hasOpacity; - s32 hasEnvCol; + s32 hasLighting; s32 flags; s32 meshBatch; s32 cicFailed; @@ -3261,12 +3260,12 @@ void render_3d_model(Object *obj) { if (obj68 != NULL) { objModel = obj68->objModel; hasOpacity = FALSE; - hasEnvCol = FALSE; + hasLighting = FALSE; intensity = 255; if (obj->shading != NULL) { intensity = (s32) (obj->shading->unk0 * 255.0f * gCurrentLightIntensity); hasOpacity = TRUE; - hasEnvCol = TRUE; + hasLighting = TRUE; } if (obj->behaviorId == BHV_RACER) { racerObj = &obj->unk64->racer; @@ -3324,44 +3323,44 @@ void render_3d_model(Object *obj) { racerObj->headAngle = 0; } } - alpha = obj->segment.object.opacity; - if (alpha > 255) { - alpha = 255; + opacity = obj->segment.object.opacity; + if (opacity > 255) { + opacity = 255; } // If the behavior is a water zipper, then halve it's transparency. if (obj->behaviorId == BHV_ZIPPER_WATER) { - alpha >>= 1; + opacity >>= 1; } - if (alpha < 255) { + if (opacity < 255) { hasOpacity = TRUE; } - if (hasEnvCol) { - gDPSetEnvColor(gObjectCurrDisplayList++, obj->shading->unk4, obj->shading->unk5, obj->shading->unk6, - obj->shading->unk7); + if (hasLighting) { + gDPSetEnvColor(gObjectCurrDisplayList++, obj->shading->lightR, obj->shading->lightG, obj->shading->lightB, + obj->shading->lightIntensity); } else { gDPSetEnvColor(gObjectCurrDisplayList++, 255, 255, 255, 0); } - if (obj->segment.header->unk71) { - gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, obj->shading->unk18, obj->shading->unk19, - obj->shading->unk1A, alpha); - tex_primcolour_on(); + if (obj->segment.header->directionalPointLighting) { + gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, obj->shading->shadowR, obj->shading->shadowG, + obj->shading->shadowB, opacity); + directional_lighting_on(); } else if (hasOpacity) { - gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, intensity, intensity, intensity, alpha); + gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, intensity, intensity, intensity, opacity); } else { gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, 255, 255, 255, 255); } - if (alpha < 255) { + if (opacity < 255) { meshBatch = render_mesh(objModel, obj, 0, RENDER_SEMI_TRANSPARENT, vertOffset); } else { meshBatch = render_mesh(objModel, obj, 0, RENDER_NONE, vertOffset); } - if (obj->segment.header->unk71) { + if (obj->segment.header->directionalPointLighting) { if (hasOpacity) { - gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, intensity, intensity, intensity, alpha); + gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, intensity, intensity, intensity, opacity); } else { gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, 255, 255, 255, 255); } - tex_primcolour_off(); + directional_lighting_off(); } if (obj->unk60 != NULL) { obj60_unk0 = obj->unk60->unk0; @@ -3385,7 +3384,7 @@ void render_3d_model(Object *obj) { } else { flags = (RENDER_Z_COMPARE | RENDER_FOG_ACTIVE | RENDER_Z_UPDATE | RENDER_ANTI_ALIASING); } - if (alpha < 255) { + if (opacity < 255) { flags |= RENDER_SEMI_TRANSPARENT; } #ifdef ANTI_TAMPER @@ -3405,7 +3404,8 @@ void render_3d_model(Object *obj) { if (var_v0_2) { func_80012C98(&gObjectCurrDisplayList); gDPSetEnvColor(gObjectCurrDisplayList++, 255, 255, 255, 0); - gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, intensity, intensity, intensity, alpha); + gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, intensity, intensity, intensity, + opacity); } loopObj->properties.common.unk0 = render_sprite_billboard(&gObjectCurrDisplayList, &gObjectCurrMatrix, @@ -3444,20 +3444,20 @@ void render_3d_model(Object *obj) { } } if (meshBatch != -1) { - if (obj->segment.header->unk71) { - gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, obj->shading->unk18, obj->shading->unk19, - obj->shading->unk1A, alpha); - tex_primcolour_on(); + if (obj->segment.header->directionalPointLighting) { + gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, obj->shading->shadowR, obj->shading->shadowG, + obj->shading->shadowB, opacity); + directional_lighting_on(); } render_mesh(objModel, obj, meshBatch, RENDER_SEMI_TRANSPARENT, vertOffset); - if (obj->segment.header->unk71) { - tex_primcolour_off(); + if (obj->segment.header->directionalPointLighting) { + directional_lighting_off(); } } - if (hasOpacity || obj->segment.header->unk71) { + if (hasOpacity || obj->segment.header->directionalPointLighting) { gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, 255, 255, 255, 255); } - if (hasEnvCol) { + if (hasLighting) { gDPSetEnvColor(gObjectCurrDisplayList++, 255, 255, 255, 0); } mtx_pop(&gObjectCurrDisplayList); @@ -6704,52 +6704,52 @@ UNUSED void func_8001D248(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED s32 arg2) { * Applies shading properties to a global variable. * Presumably intended for level geometry, which supports shading, but never uses it. */ -void set_world_shading(f32 brightness, f32 ambient, s16 angleX, s16 angleY, s16 angleZ) { - set_shading_properties((ShadeProperties *) &gWorldShading, brightness, ambient, angleX, angleY, angleZ); +void set_world_shading(f32 ambient, f32 diffuse, s16 angleX, s16 angleY, s16 angleZ) { + set_shading_properties((ShadeProperties *) &gWorldShading, ambient, diffuse, angleX, angleY, angleZ); } /** * Add values onto the existing properties of an objects shading. * Resets the shading based off the new values. */ -UNUSED void add_shading_properties(Object *obj, f32 brightnessChange, f32 ambientChange, s16 angleX, s16 angleY, +UNUSED void add_shading_properties(Object *obj, f32 ambientChange, f32 diffuseChange, s16 angleX, s16 angleY, s16 angleZ) { if (obj->shading != NULL) { - obj->shading->brightness += brightnessChange; - if (obj->shading->brightness < 0.0f) { - obj->shading->brightness = 0.0f; - } else if (obj->shading->brightness > 1.0f) { - obj->shading->brightness = 1.0f; - } obj->shading->ambient += ambientChange; if (obj->shading->ambient < 0.0f) { obj->shading->ambient = 0.0f; + } else if (obj->shading->ambient > 1.0f) { + obj->shading->ambient = 1.0f; } - if (obj->shading->ambient >= 2.0f) { - obj->shading->ambient = 1.99f; + obj->shading->diffuse += diffuseChange; + if (obj->shading->diffuse < 0.0f) { + obj->shading->diffuse = 0.0f; } - set_shading_properties(obj->shading, obj->shading->brightness, obj->shading->ambient, + if (obj->shading->diffuse >= 2.0f) { + obj->shading->diffuse = 1.99f; + } + set_shading_properties(obj->shading, obj->shading->ambient, obj->shading->diffuse, (obj->shading->unk22 + angleX), (obj->shading->unk24 + angleY), (obj->shading->unk26 + angleZ)); if (obj->segment.header->unk3D != 0) { - obj->shading->unk4 = obj->segment.header->unk3A; - obj->shading->unk5 = obj->segment.header->unk3B; - obj->shading->unk6 = obj->segment.header->unk3C; - obj->shading->unk7 = obj->segment.header->unk3D; - obj->shading->unk8 = -(obj->shading->unk1C >> 1); - obj->shading->unkA = -(obj->shading->unk1E >> 1); - obj->shading->unkC = -(obj->shading->unk20 >> 1); + obj->shading->lightR = obj->segment.header->unk3A; + obj->shading->lightG = obj->segment.header->unk3B; + obj->shading->lightB = obj->segment.header->unk3C; + obj->shading->lightIntensity = obj->segment.header->unk3D; + obj->shading->lightDirX = -(obj->shading->shadowDirX >> 1); + obj->shading->lightDirY = -(obj->shading->shadowDirY >> 1); + obj->shading->lightDirZ = -(obj->shading->shadowDirZ >> 1); } } } -void set_shading_properties(ShadeProperties *arg0, f32 brightness, f32 ambient, s16 angleX, s16 angleY, s16 angleZ) { +void set_shading_properties(ShadeProperties *arg0, f32 ambient, f32 diffuse, s16 angleX, s16 angleY, s16 angleZ) { Vec3s angle; Vec3f velocityPos; arg0->unk22 = angleX; - arg0->brightness = brightness; arg0->ambient = ambient; + arg0->diffuse = diffuse; arg0->unk0 = 1.0f; arg0->unk24 = angleY; arg0->unk26 = angleZ; @@ -6760,12 +6760,12 @@ void set_shading_properties(ShadeProperties *arg0, f32 brightness, f32 ambient, velocityPos.x = 0.0f; velocityPos.y = 0.0f; vec3f_rotate(&angle, &velocityPos); - arg0->unk1C = -velocityPos.x; - arg0->unk1E = -velocityPos.y; - arg0->unk20 = -velocityPos.z; - arg0->unk18 = 0; - arg0->unk19 = 0; - arg0->unk1A = 0; + arg0->shadowDirX = -velocityPos.x; + arg0->shadowDirY = -velocityPos.y; + arg0->shadowDirZ = -velocityPos.z; + arg0->shadowR = 0; + arg0->shadowG = 0; + arg0->shadowB = 0; } /** @@ -6809,11 +6809,11 @@ void obj_shade_fancy(ObjectModel *model, Object *object, s32 arg2, f32 intensity if (dynamicLightingEnabled) { // Calculates dynamic lighting for the object - if (object->segment.header->unk71) { - // Dynamic lighting for some objects? (Intro diddy, Taj, T.T., Bosses) + if (object->segment.header->directionalPointLighting) { + // Dynamic directional lighting for some objects (Intro diddy, Taj, T.T., Bosses) calc_dynamic_lighting_for_object_1(object, model, arg2, object, intensity, 1.0f); } else { - // Dynamic lighting for other objects? (Racers, Rare logo, Wizpig face, etc.) + // Dynamic ambient lighting for other objects (Racers, Rare logo, Wizpig face, etc.) calc_dynamic_lighting_for_object_2(object, model, arg2, intensity); } } @@ -6828,93 +6828,100 @@ void obj_shade_fancy(ObjectModel *model, Object *object, s32 arg2, f32 intensity void calc_dynamic_lighting_for_object_1(Object *object, ObjectModel *model, s16 arg2, Object *anotherObject, f32 intensity, f32 arg5) { - s16 sp9E; + s16 normIdx; s16 j; s16 i; - Vec3s sp94; + Vec3s objRot; s32 s6; - s32 x1, y1, z1; - s32 x2, y2, z2; - s32 ambientTemp; - s32 brightnessTemp; - s32 t8; - s32 v1; - Vec3f sp5C; + s32 lightDirX, lightDirY, lightDirZ; // 16.16 fixed point, normalized + s32 shadowDirX, shadowDirY, shadowDirZ; // 16.16 fixed point, normalized + s32 diffuseFactor; + s32 ambientFactor; + s32 lightIntensity; + s32 shadeStrength; + Vec3f direction; Vertex *vertices; - Vec3s *model40Entries; + Vec3s *normals; if (object->shading == NULL) { return; } vertices = object->curVertData; - model40Entries = model->unk40; - sp9E = 0; + normals = model->unk40; + normIdx = 0; - sp5C.x = -(object->shading->unk8 << 3); - sp5C.y = -(object->shading->unkA << 3); - sp5C.z = -(object->shading->unkC << 3); - sp94.y_rotation = -object->segment.trans.rotation.y_rotation; - sp94.x_rotation = -object->segment.trans.rotation.x_rotation; - sp94.z_rotation = -object->segment.trans.rotation.z_rotation; - vec3f_rotate_ypr(&sp94, &sp5C); + direction.x = -(object->shading->lightDirX << 3); + direction.y = -(object->shading->lightDirY << 3); + direction.z = -(object->shading->lightDirZ << 3); + objRot.y_rotation = -object->segment.trans.rotation.y_rotation; + objRot.x_rotation = -object->segment.trans.rotation.x_rotation; + objRot.z_rotation = -object->segment.trans.rotation.z_rotation; + vec3f_rotate_ypr(&objRot, &direction); if (object->segment.header->unk3D != 0 && arg2) { - mtxf_transform_dir(get_projection_matrix_f32(), &sp5C, &sp5C); + mtxf_transform_dir(get_projection_matrix_f32(), &direction, &direction); } - x1 = -sp5C.x; - y1 = -sp5C.y; - z1 = -sp5C.z; - s6 = object->shading->unk7; - sp5C.x = object->shading->unk1C << 2; - sp5C.y = object->shading->unk1E << 2; - sp5C.z = object->shading->unk20 << 2; + lightDirX = -direction.x; + lightDirY = -direction.y; + lightDirZ = -direction.z; + s6 = object->shading->lightIntensity; + + direction.x = object->shading->shadowDirX << 2; + direction.y = object->shading->shadowDirY << 2; + direction.z = object->shading->shadowDirZ << 2; if (arg2) { - mtxf_transform_dir(get_projection_matrix_f32(), &sp5C, &sp5C); + mtxf_transform_dir(get_projection_matrix_f32(), &direction, &direction); } - vec3f_rotate_ypr(&sp94, &sp5C); + vec3f_rotate_ypr(&objRot, &direction); - x2 = sp5C.x; - y2 = sp5C.y; - z2 = sp5C.z; + shadowDirX = direction.x; + shadowDirY = direction.y; + shadowDirZ = direction.z; - brightnessTemp = object->shading->brightness * object->shading->unk0 * 255.0f * intensity; - ambientTemp = object->shading->ambient * object->shading->unk0 * 255.0f * intensity; + ambientFactor = object->shading->ambient * object->shading->unk0 * 255.0f * intensity; + diffuseFactor = object->shading->diffuse * object->shading->unk0 * 255.0f * intensity; for (i = 0; i < model->numberOfBatches; i++) { if (model->batches[i].miscData != BATCH_VTX_COL) { // 0xFF means use vertex colors for (j = model->batches[i].verticesOffset; j < model->batches[i + 1].verticesOffset; j++) { - t8 = (model40Entries[sp9E].x * x1 + model40Entries[sp9E].y * y1 + model40Entries[sp9E].z * z1) >> 13; - if (t8 > 0) { - t8 = (t8 * s6) >> 16; - if (t8 > 255) { - t8 = 255; + // calculate lighting + lightIntensity = (normals[normIdx].x * lightDirX + normals[normIdx].y * lightDirY + + normals[normIdx].z * lightDirZ) >> + 13; + if (lightIntensity > 0) { + lightIntensity = (lightIntensity * s6) >> 16; + if (lightIntensity > 255) { + lightIntensity = 255; } } else { - t8 = 0; + lightIntensity = 0; } - v1 = (model40Entries[sp9E].x * x2 + model40Entries[sp9E].y * y2 + model40Entries[sp9E].z * z2) >> 13; - if (v1 > 0) { - v1 = (v1 * ambientTemp) >> 16; - v1 += brightnessTemp; - if (v1 > 255) { - v1 = 255; + // calculate shading + shadeStrength = (normals[normIdx].x * shadowDirX + normals[normIdx].y * shadowDirY + + normals[normIdx].z * shadowDirZ) >> + 13; + if (shadeStrength > 0) { + shadeStrength = (shadeStrength * diffuseFactor) >> 16; + shadeStrength += ambientFactor; + if (shadeStrength > 255) { + shadeStrength = 255; } } else { - v1 = brightnessTemp; + shadeStrength = ambientFactor; } - vertices[j].r = t8; - vertices[j].g = t8; - vertices[j].b = t8; - vertices[j].a = v1; - sp9E++; + vertices[j].r = lightIntensity; + vertices[j].g = lightIntensity; + vertices[j].b = lightIntensity; + vertices[j].a = shadeStrength; + normIdx++; } } else if (model->batches[i].flags & RENDER_ENVMAP) { - sp9E += model->batches[i + 1].verticesOffset - model->batches[i].verticesOffset; + normIdx += model->batches[i + 1].verticesOffset - model->batches[i].verticesOffset; } } } diff --git a/src/objects.h b/src/objects.h index b265f515..b94dd62f 100644 --- a/src/objects.h +++ b/src/objects.h @@ -406,8 +406,8 @@ void ainode_enable(void); void ainode_tail_set(s32 nodeID); Object *ainode_tail(s32 *nodeID); Object *ainode_get(s32 nodeID); -void set_world_shading(f32 brightness, f32 ambient, s16 angleX, s16 angleY, s16 angleZ); -void set_shading_properties(ShadeProperties *arg0, f32 brightness, f32 ambient, s16 angleX, s16 angleY, s16 angleZ); +void set_world_shading(f32 ambient, f32 diffuse, s16 angleX, s16 angleY, s16 angleZ); +void set_shading_properties(ShadeProperties *arg0, f32 ambient, f32 diffuse, s16 angleX, s16 angleY, s16 angleZ); void obj_shade_fancy(ObjectModel *model, Object *object, s32 arg2, f32 intensity); s32 *get_misc_asset(s32 index); s32 func_8001E2EC(s32 arg0); diff --git a/src/printf.c b/src/printf.c index c96906d9..249d5caa 100644 --- a/src/printf.c +++ b/src/printf.c @@ -515,7 +515,7 @@ s32 debug_text_character(Gfx **dList, s32 asciiVal) { fontCharU = gDebugFontCoords[gDebugFontTexture][asciiVal].u; fontCharWidth = (gDebugFontCoords[gDebugFontTexture][asciiVal].v - fontCharU) + 1; if (gDebugTextOn) { - gDPSetCombineMode((*dList)++, DKR_CC_UNK12, DKR_CC_UNK12); + gDPSetCombineMode((*dList)++, G_CC_ENV_DECALA, G_CC_ENV_DECALA); gSPTextureRectangle((*dList)++, (gDebugTextX << 2), (gDebugTextY << 2), ((gDebugTextX + fontCharWidth) << 2), ((gDebugTextY + 10) << 2), 0, (fontCharU << 5), 0, 1024, 1024); } diff --git a/src/screen_asset.c b/src/screen_asset.c index de2e14ab..d4695e12 100644 --- a/src/screen_asset.c +++ b/src/screen_asset.c @@ -2,7 +2,7 @@ // Render settings for the screens Gfx gRdpSetModeScreenAsset[] = { - gsDPSetCombineMode(DKR_CC_UNK10, DKR_CC_UNK10), + gsDPSetCombineMode(G_CC_DECAL_SCALE, G_CC_DECAL_SCALE), gsDPSetOtherMode(DKR_OMH_COPY_POINT_NOPERSP, DKR_OML_COMMON | G_RM_NOOP | G_RM_NOOP2), }; diff --git a/src/textures_sprites.c b/src/textures_sprites.c index 634a868d..321c1e11 100644 --- a/src/textures_sprites.c +++ b/src/textures_sprites.c @@ -6,10 +6,12 @@ #include "tracks.h" #include "game_ui.h" -#define TEX_HEADER_COUNT 175 +#define MAX_NUM_TEXTURES 700 #define TEX_SPRITE_COUNT 50 #define TEX_PALLETE_COUNT 20 -#define TEX_PALLETE_COLOURS 640 +#define MAX_TEX_PALETTE_SIZE 640 +#define TEXTURE_GFX_SIZE (12 * sizeof(Gfx)) +#define PALETTE_GFX_SIZE (6 * sizeof(Gfx)) /************ .data ************/ @@ -18,15 +20,31 @@ s32 gSpriteOpaque = TRUE; // See "include/f3ddkr.h" for the defines +/** + * Description of how these rendering modes work. + * + * First, the color combiner: + * Color – the texture color is modulated by vertex shading. In the second cycle, the result is blended with the + * environmental lighting color. Alpha – the texture alpha is multiplied by the vertex alpha (!) and then by the alpha + * of PrimColor, which controls the overall transparency of the model. + * + * Now regarding the rendering modes: the base mode is XLU_SURF. However, in the first group, every mode has Z buffer + * updates enabled. Presumably, this speeds up rendering of overlapping translucent primitives by allowing Z-based + * rejection, but the visual result depends on draw order. For example: if you draw the far primitive first, then the + * near one, both will be visible. But if drawn in the reverse order, only the near one will appear — the far one won't + * render at all, even though the background behind the near primitive will remain visible. + * + * It’s also unclear why G_RM_NOOP is used in the first cycle instead of G_RM_PASS, but the effect should be the same: + * the pixel color is passed unchanged to the second cycle. + */ Gfx dRenderSettingsVtxAlpha[][2] = { // Semitransparent Vertex Alpha'd surface (Zsorted) - DRAW_TABLE_GROUP(G_CC_MODULATEIA, DKR_CC_UNK0, DKR_OMH_2CYC_BILERP, DKR_RM_UNKNOWN0, G_RM_XLU_SURF2, - DKR_RM_UNKNOWN0, G_RM_AA_XLU_SURF2, DKR_RM_UNKNOWN0, G_RM_ZB_XLU_SURF2, DKR_RM_UNKNOWN0, - G_RM_AA_ZB_XLU_SURF2), + DRAW_TABLE_GROUP(G_CC_MODULATERGBA, G_CC_MODULATEA_PRIM2, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_XLU_SURF2 | Z_UPD, + G_RM_NOOP, G_RM_AA_XLU_SURF2 | Z_UPD, G_RM_NOOP, G_RM_ZB_XLU_SURF2 | Z_UPD, G_RM_NOOP, + G_RM_AA_ZB_XLU_SURF2 | Z_UPD), // Semitransparent Vertex Alpha'd surface (No Zsort) - DRAW_TABLE_GROUP(G_CC_MODULATEIA, DKR_CC_UNK1, DKR_OMH_2CYC_BILERP, DKR_RM_UNKNOWN1, G_RM_XLU_SURF2, - DKR_RM_UNKNOWN1, G_RM_AA_XLU_SURF2, DKR_RM_UNKNOWN1, G_RM_ZB_XLU_SURF2, DKR_RM_UNKNOWN1, - G_RM_AA_ZB_XLU_SURF2), + DRAW_TABLE_GROUP(G_CC_MODULATERGBA, G_CC_BLENDI_ENV_ALPHA_PRIM2, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, + G_RM_NOOP, G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_ZB_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_XLU_SURF2), }; Gfx dRenderSettingsSpriteCld[][2] = { @@ -39,21 +57,13 @@ Gfx dRenderSettingsSpriteCld[][2] = { // Should probably be merged with dRenderSettingsSpriteCld Gfx dRenderSettingsSpriteXlu[][2] = { // Semitransparent Sprite (Overwrite coverage) - DRAW_TABLE_ENTRY(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_POINT, G_RM_XLU_SURF, G_RM_XLU_SURF2), - DRAW_TABLE_ENTRY(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_POINT, DKR_RM_UNKNOWN2_1, - DKR_RM_UNKNOWN2_2), - DRAW_TABLE_ENTRY(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_POINT, DKR_RM_UNKNOWN3_1, - DKR_RM_UNKNOWN3_2), - DRAW_TABLE_ENTRY(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_POINT, G_RM_AA_ZB_XLU_INTER, - G_RM_AA_ZB_XLU_INTER2), + DRAW_TABLE_GROUP(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_POINT, G_RM_XLU_SURF, G_RM_XLU_SURF2, + G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2, + G_RM_AA_ZB_XLU_INTER, G_RM_AA_ZB_XLU_INTER2), // Semitransparent Sprite (Overwrite coverage) (Copy) - DRAW_TABLE_ENTRY(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_POINT, G_RM_XLU_SURF, G_RM_XLU_SURF2), - DRAW_TABLE_ENTRY(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_POINT, DKR_RM_UNKNOWN2_1, - DKR_RM_UNKNOWN2_2), - DRAW_TABLE_ENTRY(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_POINT, DKR_RM_UNKNOWN3_1, - DKR_RM_UNKNOWN3_2), - DRAW_TABLE_ENTRY(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_POINT, G_RM_AA_ZB_XLU_INTER, - G_RM_AA_ZB_XLU_INTER2) + DRAW_TABLE_GROUP(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_POINT, G_RM_XLU_SURF, G_RM_XLU_SURF2, + G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2, + G_RM_AA_ZB_XLU_INTER, G_RM_AA_ZB_XLU_INTER2) }; Gfx dRenderSettingsCommon[][2] = { @@ -66,13 +76,13 @@ Gfx dRenderSettingsCommon[][2] = { G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_ZB_XLU_SURF, G_RM_ZB_XLU_SURF2, G_RM_AA_ZB_XLU_SURF, G_RM_AA_ZB_XLU_SURF2), // Opaque Surface with fog - DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, DKR_CC_UNK1, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_OPA_SURF2, - G_RM_FOG_SHADE_A, G_RM_AA_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_OPA_SURF2, G_RM_FOG_SHADE_A, - G_RM_AA_ZB_OPA_SURF2), + DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, G_CC_BLENDI_ENV_ALPHA_PRIM2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, + G_RM_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_OPA_SURF2, + G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2), // Semitransparent Surface with fog - DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, DKR_CC_UNK1, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, - G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_SURF2, G_RM_FOG_SHADE_A, - G_RM_AA_ZB_XLU_SURF2), + DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, G_CC_BLENDI_ENV_ALPHA_PRIM2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, + G_RM_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_SURF2, + G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2), // Cutout Surface with primitive colour DRAW_TABLE_GROUP(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_BILERP, G_RM_XLU_SURF, G_RM_XLU_SURF2, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2, @@ -82,11 +92,11 @@ Gfx dRenderSettingsCommon[][2] = { G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2, G_RM_AA_ZB_XLU_INTER, G_RM_AA_ZB_XLU_INTER2), // Cutout Surface with primitive colour and fog - DRAW_TABLE_GROUP(G_CC_MODULATEIA_PRIM, DKR_CC_UNK2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, + DRAW_TABLE_GROUP(G_CC_MODULATEIA_PRIM, G_CC_BLEND_ENV_ALPHA2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_INTER2), // Cutout Surface with primitive colour and fog (Zsorted interpenetrating) - DRAW_TABLE_GROUP(G_CC_MODULATEIA_PRIM, DKR_CC_UNK2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, + DRAW_TABLE_GROUP(G_CC_MODULATEIA_PRIM, G_CC_BLEND_ENV_ALPHA2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_INTER2 | Z_UPD, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_INTER2), // Opaque Surface with indexed texture @@ -113,7 +123,7 @@ Gfx dRenderSettingsCommon[][2] = { DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA, DKR_OMH_1CYC_CI_BILERP, G_RM_XLU_SURF, G_RM_XLU_SURF2, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2, G_RM_AA_ZB_XLU_INTER, G_RM_AA_ZB_XLU_INTER2), - // Opqaue Surface with indexed texture and fog (Cutout) + // Opaque Surface with indexed texture and fog (Cutout) DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, G_CC_PASS2, DKR_OMH_2CYC_CI_BILERP, G_RM_FOG_SHADE_A, G_RM_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2), @@ -126,20 +136,20 @@ Gfx dRenderSettingsCommon[][2] = { Gfx dRenderSettingsCutout[][2] = { // Semitransparent Surface DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_BILERP, G_RM_XLU_SURF, G_RM_XLU_SURF2, - G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2, DKR_RM_UNKNOWN4_1, - DKR_RM_UNKNOWN4_2), + G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2, + G_RM_AA_ZB_XLU_LINE_MOD, G_RM_AA_ZB_XLU_LINE_MOD2), // Semitransparent Surface (Copy) DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, G_CC_MODULATEIA_PRIM, DKR_OMH_1CYC_BILERP, G_RM_XLU_SURF, G_RM_XLU_SURF2, - G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2, DKR_RM_UNKNOWN4_1, - DKR_RM_UNKNOWN4_2), + G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2, + G_RM_AA_ZB_XLU_LINE_MOD, G_RM_AA_ZB_XLU_LINE_MOD2), // Semitransparent Surface with fog - DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, DKR_CC_UNK1, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, - G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2, G_RM_FOG_SHADE_A, - DKR_RM_UNKNOWN4_2), + DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, G_CC_BLENDI_ENV_ALPHA_PRIM2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, + G_RM_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2, + G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_LINE_MOD2), // Semitransparent Surface with fog (Copy) - DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, DKR_CC_UNK1, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, - G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2, G_RM_FOG_SHADE_A, - DKR_RM_UNKNOWN4_2), + DRAW_TABLE_GROUP(G_CC_MODULATEIDECALA, G_CC_BLENDI_ENV_ALPHA_PRIM2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, + G_RM_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2, + G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_LINE_MOD2), }; Gfx dRenderSettingsDecal[][2] = { @@ -154,11 +164,15 @@ Gfx dRenderSettingsDecal[][2] = { DRAW_TABLE_ENTRY(G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA, DKR_OMH_1CYC_BILERP, G_RM_AA_ZB_XLU_DECAL, G_RM_AA_ZB_XLU_DECAL2), // Opaque Decal with fog. - DRAW_TABLE_ENTRY(G_CC_MODULATEIDECALA, DKR_CC_UNK1, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_ZB_OPA_DECAL2), - DRAW_TABLE_ENTRY(G_CC_MODULATEIDECALA, DKR_CC_UNK1, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_DECAL2), + DRAW_TABLE_ENTRY(G_CC_MODULATEIDECALA, G_CC_BLENDI_ENV_ALPHA_PRIM2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, + G_RM_ZB_OPA_DECAL2), + DRAW_TABLE_ENTRY(G_CC_MODULATEIDECALA, G_CC_BLENDI_ENV_ALPHA_PRIM2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, + G_RM_AA_ZB_OPA_DECAL2), // Semitransparent Decal with fog. - DRAW_TABLE_ENTRY(G_CC_MODULATEIDECALA, DKR_CC_UNK1, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_DECAL2), - DRAW_TABLE_ENTRY(G_CC_MODULATEIDECALA, DKR_CC_UNK1, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_DECAL2), + DRAW_TABLE_ENTRY(G_CC_MODULATEIDECALA, G_CC_BLENDI_ENV_ALPHA_PRIM2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, + G_RM_ZB_XLU_DECAL2), + DRAW_TABLE_ENTRY(G_CC_MODULATEIDECALA, G_CC_BLENDI_ENV_ALPHA_PRIM2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, + G_RM_AA_ZB_XLU_DECAL2), // Opaque Decal with indexed texture. DRAW_TABLE_ENTRY(G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA, DKR_OMH_1CYC_CI_BILERP, G_RM_ZB_OPA_DECAL, G_RM_ZB_OPA_DECAL2), @@ -178,94 +192,120 @@ Gfx dRenderSettingsDecal[][2] = { }; Gfx dRenderSettingsSolidColourVtxAlpha[][2] = { - DRAW_TABLE_GROUP(DKR_CC_UNK3, G_CC_MODULATEIA_PRIM2, DKR_OMH_2CYC_POINT, G_RM_NOOP, G_RM_XLU_SURF2, G_RM_NOOP, - G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_ZB_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_XLU_SURF2), + DRAW_TABLE_GROUP(G_CC_BLENDI_ENV_ALPHA, G_CC_MODULATEIA_PRIM2, DKR_OMH_2CYC_POINT, G_RM_NOOP, G_RM_XLU_SURF2, + G_RM_NOOP, G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_ZB_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_XLU_SURF2), }; Gfx dRenderSettingsSolidColour[][2] = { // Opaque Surface - DRAW_TABLE_GROUP(DKR_CC_UNK4, DKR_CC_UNK4, DKR_OMH_1CYC_POINT, G_RM_OPA_SURF, G_RM_OPA_SURF2, G_RM_AA_OPA_SURF, - G_RM_AA_OPA_SURF2, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2, G_RM_AA_ZB_OPA_INTER, - G_RM_AA_ZB_OPA_INTER2), + DRAW_TABLE_GROUP(G_CC_BLENDI_ENV_ALPHA_A_PRIM, G_CC_BLENDI_ENV_ALPHA_A_PRIM, DKR_OMH_1CYC_POINT, G_RM_OPA_SURF, + G_RM_OPA_SURF2, G_RM_AA_OPA_SURF, G_RM_AA_OPA_SURF2, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2, + G_RM_AA_ZB_OPA_INTER, G_RM_AA_ZB_OPA_INTER2), // Semitransparent Surface - DRAW_TABLE_GROUP(DKR_CC_UNK4, DKR_CC_UNK4, DKR_OMH_1CYC_POINT, G_RM_XLU_SURF, G_RM_XLU_SURF2, G_RM_AA_XLU_SURF, - G_RM_AA_XLU_SURF2, G_RM_ZB_XLU_SURF, G_RM_ZB_XLU_SURF2, G_RM_AA_ZB_XLU_SURF, G_RM_AA_ZB_XLU_SURF2), + DRAW_TABLE_GROUP(G_CC_BLENDI_ENV_ALPHA_A_PRIM, G_CC_BLENDI_ENV_ALPHA_A_PRIM, DKR_OMH_1CYC_POINT, G_RM_XLU_SURF, + G_RM_XLU_SURF2, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2, G_RM_ZB_XLU_SURF, G_RM_ZB_XLU_SURF2, + G_RM_AA_ZB_XLU_SURF, G_RM_AA_ZB_XLU_SURF2), // Opaque Surface with fog - DRAW_TABLE_GROUP(DKR_CC_UNK4, G_CC_MODULATEIA_PRIM2, DKR_OMH_2CYC_POINT, G_RM_FOG_SHADE_A, G_RM_OPA_SURF2, - G_RM_FOG_SHADE_A, G_RM_AA_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_OPA_SURF2, G_RM_FOG_SHADE_A, - G_RM_AA_ZB_OPA_SURF2), - // Semitransparent Surface - DRAW_TABLE_GROUP(DKR_CC_UNK4, G_CC_MODULATEIA_PRIM2, DKR_OMH_2CYC_POINT, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, - G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_SURF2, G_RM_FOG_SHADE_A, - G_RM_AA_ZB_XLU_SURF2), + DRAW_TABLE_GROUP(G_CC_BLENDI_ENV_ALPHA_A_PRIM, G_CC_MODULATEIA_PRIM2, DKR_OMH_2CYC_POINT, G_RM_FOG_SHADE_A, + G_RM_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_OPA_SURF2, + G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2), + // Semitransparent Surface with fog + DRAW_TABLE_GROUP(G_CC_BLENDI_ENV_ALPHA_A_PRIM, G_CC_MODULATEIA_PRIM2, DKR_OMH_2CYC_POINT, G_RM_FOG_SHADE_A, + G_RM_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_SURF2, + G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2), }; // Some kind of texture on top of a solid colour Gfx dRenderSettingsPrimOverlay[][2] = { // Opaque Surface - DRAW_TABLE_ENTRY(DKR_CC_DECALFADEPRIM, DKR_CC_DECALFADEPRIM, DKR_OMH_1CYC_BILERP, G_RM_ZB_OPA_DECAL, - G_RM_ZB_OPA_DECAL2), - DRAW_TABLE_ENTRY(DKR_CC_DECALFADEPRIM, DKR_CC_DECALFADEPRIM, DKR_OMH_1CYC_BILERP, G_RM_AA_ZB_OPA_DECAL, + DRAW_TABLE_ENTRY(G_CC_DECAL_A_PRIM, G_CC_DECAL_A_PRIM, DKR_OMH_1CYC_BILERP, G_RM_ZB_OPA_DECAL, G_RM_ZB_OPA_DECAL2), + DRAW_TABLE_ENTRY(G_CC_DECAL_A_PRIM, G_CC_DECAL_A_PRIM, DKR_OMH_1CYC_BILERP, G_RM_AA_ZB_OPA_DECAL, G_RM_AA_ZB_OPA_DECAL2), // Semitransparent Surface - DRAW_TABLE_ENTRY(DKR_CC_DECALFADEPRIM, DKR_CC_DECALFADEPRIM, DKR_OMH_1CYC_BILERP, G_RM_ZB_XLU_DECAL, - G_RM_ZB_XLU_DECAL2), - DRAW_TABLE_ENTRY(DKR_CC_DECALFADEPRIM, DKR_CC_DECALFADEPRIM, DKR_OMH_1CYC_BILERP, G_RM_AA_ZB_XLU_DECAL, + DRAW_TABLE_ENTRY(G_CC_DECAL_A_PRIM, G_CC_DECAL_A_PRIM, DKR_OMH_1CYC_BILERP, G_RM_ZB_XLU_DECAL, G_RM_ZB_XLU_DECAL2), + DRAW_TABLE_ENTRY(G_CC_DECAL_A_PRIM, G_CC_DECAL_A_PRIM, DKR_OMH_1CYC_BILERP, G_RM_AA_ZB_XLU_DECAL, G_RM_AA_ZB_XLU_DECAL2), // Opaque Surface with indexed texture - DRAW_TABLE_ENTRY(DKR_CC_DECALFADEPRIM, DKR_CC_DECALFADEPRIM, DKR_OMH_1CYC_CI_BILERP, G_RM_ZB_OPA_DECAL, + DRAW_TABLE_ENTRY(G_CC_DECAL_A_PRIM, G_CC_DECAL_A_PRIM, DKR_OMH_1CYC_CI_BILERP, G_RM_ZB_OPA_DECAL, G_RM_ZB_OPA_DECAL2), - DRAW_TABLE_ENTRY(DKR_CC_DECALFADEPRIM, DKR_CC_DECALFADEPRIM, DKR_OMH_1CYC_CI_BILERP, G_RM_AA_ZB_OPA_DECAL, + DRAW_TABLE_ENTRY(G_CC_DECAL_A_PRIM, G_CC_DECAL_A_PRIM, DKR_OMH_1CYC_CI_BILERP, G_RM_AA_ZB_OPA_DECAL, G_RM_AA_ZB_OPA_DECAL2), // Semitransparent Surface with indexed texture - DRAW_TABLE_ENTRY(DKR_CC_DECALFADEPRIM, DKR_CC_DECALFADEPRIM, DKR_OMH_1CYC_CI_BILERP, G_RM_ZB_XLU_DECAL, + DRAW_TABLE_ENTRY(G_CC_DECAL_A_PRIM, G_CC_DECAL_A_PRIM, DKR_OMH_1CYC_CI_BILERP, G_RM_ZB_XLU_DECAL, G_RM_ZB_XLU_DECAL2), - DRAW_TABLE_ENTRY(DKR_CC_DECALFADEPRIM, DKR_CC_DECALFADEPRIM, DKR_OMH_1CYC_CI_BILERP, G_RM_AA_ZB_XLU_DECAL, + DRAW_TABLE_ENTRY(G_CC_DECAL_A_PRIM, G_CC_DECAL_A_PRIM, DKR_OMH_1CYC_CI_BILERP, G_RM_AA_ZB_XLU_DECAL, G_RM_AA_ZB_XLU_DECAL2) }; -// Not sure what it is specifically, but some onscreen actors like TT and Taj use it. -Gfx dRenderSettingsPrimCol[][2] = { +/** + * Color combiner behavior: + * + * RGB: First, `PrimColor` and the texture color are blended using the vertex alpha as the blend factor + * (0 = fully shaded color, 1 = pure texture). + * The result is then blended with `EnvColor`, modulated by the vertex RGB color + * (all RGB components are expected to be equal, representing lighting intensity). + * + * Alpha: The texture's alpha is multiplied by the alpha value of `PrimColor`. + * + * This setup enables more advanced lighting by combining directional shadowing (e.g. from the sky) + * with directional lighting (e.g. from a colored point light). + * + * This differs from simpler lighting models where illumination is uniform and non-directional. + * + * - `EnvColor` represents the light color. + * - `PrimColor` represents the shadow (shaded) color. + * - The vertex alpha is the **inverted shadow strength**: + * - alpha = 1 → fully lit (pure texture), + * - alpha = 0 → fully shaded (flat `PrimColor`). + * - The vertex RGB intensity acts as the **lighting intensity**. + */ +Gfx dRenderSettingsDirectionalLighting[][2] = { // Opaque Surface - DRAW_TABLE_GROUP(DKR_CC_UNK5, DKR_CC_UNK6, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_OPA_SURF2, G_RM_NOOP, - G_RM_AA_OPA_SURF2, G_RM_NOOP, G_RM_ZB_OPA_SURF2, G_RM_NOOP, G_RM_AA_ZB_OPA_SURF2), + DRAW_TABLE_GROUP(G_CC_BLEND_SHADEALPHA, G_CC_BLENDI_SHADE, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_OPA_SURF2, + G_RM_NOOP, G_RM_AA_OPA_SURF2, G_RM_NOOP, G_RM_ZB_OPA_SURF2, G_RM_NOOP, G_RM_AA_ZB_OPA_SURF2), // Semitransparent Surface - DRAW_TABLE_GROUP(DKR_CC_UNK5, DKR_CC_UNK6, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, G_RM_NOOP, - G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_ZB_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_XLU_SURF2), + DRAW_TABLE_GROUP(G_CC_BLEND_SHADEALPHA, G_CC_BLENDI_SHADE, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, + G_RM_NOOP, G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_ZB_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_XLU_SURF2), // Opaque Surface with indexed texture - DRAW_TABLE_GROUP(DKR_CC_UNK5, DKR_CC_UNK6, DKR_OMH_2CYC_CI_BILERP, G_RM_NOOP, G_RM_OPA_SURF2, G_RM_NOOP, - G_RM_AA_OPA_SURF2, G_RM_NOOP, G_RM_ZB_OPA_SURF2, G_RM_NOOP, G_RM_AA_ZB_OPA_SURF2), + DRAW_TABLE_GROUP(G_CC_BLEND_SHADEALPHA, G_CC_BLENDI_SHADE, DKR_OMH_2CYC_CI_BILERP, G_RM_NOOP, G_RM_OPA_SURF2, + G_RM_NOOP, G_RM_AA_OPA_SURF2, G_RM_NOOP, G_RM_ZB_OPA_SURF2, G_RM_NOOP, G_RM_AA_ZB_OPA_SURF2), // Semitransparent Surface with indexed texture - DRAW_TABLE_GROUP(DKR_CC_UNK5, DKR_CC_UNK6, DKR_OMH_2CYC_CI_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, G_RM_NOOP, - G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_TEX_EDGE2, G_RM_NOOP, G_RM_AA_ZB_XLU_INTER2), + DRAW_TABLE_GROUP(G_CC_BLEND_SHADEALPHA, G_CC_BLENDI_SHADE, DKR_OMH_2CYC_CI_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, + G_RM_NOOP, G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_TEX_EDGE2, G_RM_NOOP, G_RM_AA_ZB_XLU_INTER2), }; // Only opaque surface is actually used here. Gfx dRenderSettingsBlinkingLights[][2] = { // Opaque Surface - DRAW_TABLE_GROUP(DKR_CC_UNK7, DKR_CC_UNK8, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_OPA_SURF2, G_RM_NOOP, - G_RM_AA_OPA_SURF2, G_RM_NOOP, G_RM_ZB_OPA_SURF2, G_RM_NOOP, G_RM_AA_ZB_OPA_SURF2), + DRAW_TABLE_GROUP(G_CC_BLENDTEX_PRIM, G_CC_MODULATEIDECALA2, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_OPA_SURF2, + G_RM_NOOP, G_RM_AA_OPA_SURF2, G_RM_NOOP, G_RM_ZB_OPA_SURF2, G_RM_NOOP, G_RM_AA_ZB_OPA_SURF2), // Semitransparent Surface - DRAW_TABLE_GROUP(DKR_CC_UNK7, DKR_CC_UNK8, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, G_RM_NOOP, - G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_ZB_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_XLU_SURF2), + DRAW_TABLE_GROUP(G_CC_BLENDTEX_PRIM, G_CC_MODULATEIDECALA2, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, + G_RM_NOOP, G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_ZB_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_XLU_SURF2), // Opaque Surface with fog - DRAW_TABLE_GROUP(DKR_CC_UNK7, DKR_CC_UNK8, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_OPA_SURF2, G_RM_FOG_SHADE_A, - G_RM_AA_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2), + DRAW_TABLE_GROUP(G_CC_BLENDTEX_PRIM, G_CC_MODULATEIDECALA2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_OPA_SURF2, + G_RM_FOG_SHADE_A, G_RM_AA_OPA_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_OPA_SURF2, G_RM_FOG_SHADE_A, + G_RM_AA_ZB_OPA_SURF2), // Semitransparent Surface with fog - DRAW_TABLE_GROUP(DKR_CC_UNK7, DKR_CC_UNK8, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, G_RM_FOG_SHADE_A, - G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2), + DRAW_TABLE_GROUP(G_CC_BLENDTEX_PRIM, G_CC_MODULATEIDECALA2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, + G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_SURF2, G_RM_FOG_SHADE_A, + G_RM_AA_ZB_XLU_SURF2), // Cutout Surface - DRAW_TABLE_GROUP(DKR_CC_UNK7, DKR_CC_UNK8, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, G_RM_NOOP, - G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_TEX_EDGE2, G_RM_NOOP, DKR_RM_UNKNOWN4_2), + DRAW_TABLE_GROUP(G_CC_BLENDTEX_PRIM, G_CC_MODULATEIDECALA2, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, + G_RM_NOOP, G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_TEX_EDGE2, G_RM_NOOP, + G_RM_AA_ZB_XLU_LINE_MOD2), // Cutout Surface (Copy) - DRAW_TABLE_GROUP(DKR_CC_UNK7, DKR_CC_UNK8, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, G_RM_NOOP, - G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_TEX_EDGE2, G_RM_NOOP, DKR_RM_UNKNOWN4_2), + DRAW_TABLE_GROUP(G_CC_BLENDTEX_PRIM, G_CC_MODULATEIDECALA2, DKR_OMH_2CYC_BILERP, G_RM_NOOP, G_RM_XLU_SURF2, + G_RM_NOOP, G_RM_AA_XLU_SURF2, G_RM_NOOP, G_RM_AA_ZB_TEX_EDGE2, G_RM_NOOP, + G_RM_AA_ZB_XLU_LINE_MOD2), // Cutout Surface with fog - DRAW_TABLE_GROUP(DKR_CC_UNK7, DKR_CC_UNK8, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, G_RM_FOG_SHADE_A, - G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2, G_RM_FOG_SHADE_A, DKR_RM_UNKNOWN4_2), + DRAW_TABLE_GROUP(G_CC_BLENDTEX_PRIM, G_CC_MODULATEIDECALA2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, + G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2, G_RM_FOG_SHADE_A, + G_RM_AA_ZB_XLU_LINE_MOD2), // Cutout Surface with fog (Copy) - DRAW_TABLE_GROUP(DKR_CC_UNK7, DKR_CC_UNK8, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, G_RM_FOG_SHADE_A, - G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2, G_RM_FOG_SHADE_A, DKR_RM_UNKNOWN4_2), + DRAW_TABLE_GROUP(G_CC_BLENDTEX_PRIM, G_CC_MODULATEIDECALA2, DKR_OMH_2CYC_BILERP, G_RM_FOG_SHADE_A, G_RM_XLU_SURF2, + G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2, G_RM_FOG_SHADE_A, + G_RM_AA_ZB_XLU_LINE_MOD2), }; Gfx dBasicRenderSettingsZBOff[] = { @@ -288,9 +328,10 @@ Gfx dBasicRenderSettingsZBOn[] = { }; Gfx dBasicRenderModes[][2] = { - DRAW_TABLE_ENTRY(DKR_CC_UNK9, DKR_CC_UNK9, DKR_OMH_1CYC_BILERP_NOPERSP, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2), + DRAW_TABLE_ENTRY(G_CC_BLENDPE_A_PRIM, G_CC_BLENDPE_A_PRIM, DKR_OMH_1CYC_BILERP_NOPERSP, G_RM_ZB_CLD_SURF, + G_RM_ZB_CLD_SURF2), DRAW_TABLE_ENTRY(G_CC_BLENDPE, G_CC_BLENDPE, DKR_OMH_1CYC_BILERP, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2), - DRAW_TABLE_ENTRY(DKR_CC_UNK9, G_CC_PASS2, DKR_OMH_2CYC_BILERP, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2) + DRAW_TABLE_ENTRY(G_CC_BLENDPE_A_PRIM, G_CC_PASS2, DKR_OMH_2CYC_BILERP, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2) }; /*******************************/ @@ -318,9 +359,9 @@ s32 *gTextureCache; u8 *gCiPalettes; s32 gNumberOfLoadedTextures; s32 D_80126334; -s32 gTextureAssetID[2]; +s32 gTextureTableSize[2]; s32 gCiPalettesSize; -s32 D_80126344; +s32 gFirstTexIsLoaded; s32 *gSpriteOffsetTable; s32 *gSpriteCache; @@ -340,7 +381,7 @@ s32 gBlockedRenderFlags; TextureHeader *gCurrentTextureHeader; s16 gUsingTexture; s16 gForceFlags; -s16 gUsePrimColour; +s16 gUseDirectionalLighting; /******************************/ @@ -350,18 +391,18 @@ s16 gUsePrimColour; void tex_init_textures(void) { s32 i; - gTextureCache = mempool_alloc_safe(sizeof(TextureHeader) * TEX_HEADER_COUNT, COLOUR_TAG_MAGENTA); - gCiPalettes = mempool_alloc_safe(TEX_PALLETE_COLOURS, COLOUR_TAG_MAGENTA); + gTextureCache = mempool_alloc_safe(8 * MAX_NUM_TEXTURES, COLOUR_TAG_MAGENTA); + gCiPalettes = mempool_alloc_safe(MAX_TEX_PALETTE_SIZE, COLOUR_TAG_MAGENTA); gNumberOfLoadedTextures = 0; gCiPalettesSize = 0; gTextureAssetTable[TEX_TABLE_2D] = (s32 *) load_asset_section_from_rom(ASSET_TEXTURES_2D_TABLE); gTextureAssetTable[TEX_TABLE_3D] = (s32 *) load_asset_section_from_rom(ASSET_TEXTURES_3D_TABLE); for (i = 0; gTextureAssetTable[TEX_TABLE_2D][i] != -1; i++) {} - gTextureAssetID[TEX_TABLE_2D] = --i; + gTextureTableSize[TEX_TABLE_2D] = --i; for (i = 0; gTextureAssetTable[TEX_TABLE_3D][i] != -1; i++) {} - gTextureAssetID[TEX_TABLE_3D] = --i; + gTextureTableSize[TEX_TABLE_3D] = --i; gSpriteCache = mempool_alloc_safe(sizeof(Sprite) * TEX_SPRITE_COUNT, COLOUR_TAG_MAGENTA); gCurrentSprite = mempool_alloc_safe(sizeof(Sprite) * 32, COLOUR_TAG_MAGENTA); @@ -374,7 +415,7 @@ void tex_init_textures(void) { gSpriteTableSize--; gTempTextureHeader = mempool_alloc_safe(sizeof(TempTexHeader), COLOUR_TAG_MAGENTA); - D_80126344 = 0; + gFirstTexIsLoaded = FALSE; } /** @@ -398,7 +439,7 @@ void tex_enable_modes(s32 flags) { * Goes unused. */ UNUSED s32 tex_get_table_2D(void) { - return gTextureAssetID[TEX_TABLE_2D]; + return gTextureTableSize[TEX_TABLE_2D]; } /** @@ -406,7 +447,7 @@ UNUSED s32 tex_get_table_2D(void) { * Goes unused. */ UNUSED s32 tex_get_table_3D(void) { - return gTextureAssetID[TEX_TABLE_3D]; + return gTextureTableSize[TEX_TABLE_3D]; } /** @@ -416,110 +457,135 @@ UNUSED s32 sprite_table_size(void) { return gSpriteTableSize; } -// Official Name: texLoadTexture -TextureHeader *load_texture(s32 arg0) { +/** + * Loads a texture into memory and initializes display lists for texture loading. + * First checks if the texture is already in the cache. + * Also loads color palettes if the texture uses them (though this game doesn't use such textures). + * + * Official Name: texLoadTexture + */ +TextureHeader *load_texture(s32 id) { TextureHeader *tex; TextureHeader *texTemp; - u32 temp_a1; + u32 compressedStart; s32 assetIndex; s32 assetOffset; s32 assetSize; s32 paletteOffset; s32 assetSection; - s32 texIndex; - s32 assetTable; + s32 slotIndex; + s32 tableType; s32 i; u16 numberOfTextures; - s32 sp3C; + s32 uncompressedSize; - arg0 &= 0xFFFF; - assetIndex = arg0; + // 'id' is a 16-bit value; the highest bit determines whether it's a 2D or 3D texture + id &= 0xFFFF; + assetIndex = id; assetSection = ASSET_TEXTURES_2D; - assetTable = 0; - if (arg0 & 0x8000) { - assetTable = 1; - assetIndex = arg0 & 0x7FFF; + tableType = TEX_TABLE_2D; + if (id & ASSET_MASK_TEX3D) { + tableType = TEX_TABLE_3D; + assetIndex = id & 0x7FFF; assetSection = ASSET_TEXTURES_3D; } - if ((assetIndex >= gTextureAssetID[assetTable]) || (assetIndex < 0)) { - arg0 = 0; + + // If the index is out of bounds, fall back to texture 0. Returning NULL would be better. + if (assetIndex >= gTextureTableSize[tableType] || assetIndex < 0) { + id = 0; } + + // Check if texture is already loaded; if so, increment the reference count and return it. for (i = 0; i < gNumberOfLoadedTextures; i++) { - if (arg0 == gTextureCache[ASSETCACHE_ID(i)]) { + if (id == gTextureCache[ASSETCACHE_ID(i)]) { tex = (TextureHeader *) gTextureCache[ASSETCACHE_PTR(i)]; tex->numberOfInstances++; return tex; } } - assetOffset = gTextureAssetTable[assetTable][assetIndex]; - assetSize = gTextureAssetTable[assetTable][assetIndex + 1] - assetOffset; - load_asset_to_address(assetSection, (u32) gTempTextureHeader, assetOffset, 0x28); + assetOffset = gTextureAssetTable[tableType][assetIndex]; + assetSize = gTextureAssetTable[tableType][assetIndex + 1] - assetOffset; + load_asset_to_address(assetSection, (u32) gTempTextureHeader, assetOffset, sizeof(TempTexHeader)); numberOfTextures = gTempTextureHeader->header.numOfTextures >> 8; + // Allocate memory for the texture and its display lists. + // If compressed, decompress it. if (!gTempTextureHeader->header.isCompressed) { - tex = (TextureHeader *) mempool_alloc(numberOfTextures * 0x60 + assetSize, gTexColourTag); + tex = (TextureHeader *) mempool_alloc(numberOfTextures * TEXTURE_GFX_SIZE + assetSize, gTexColourTag); if (tex == NULL) { return NULL; } load_asset_to_address(assetSection, (u32) tex, assetOffset, assetSize); } else { - sp3C = byteswap32((u8 *) &gTempTextureHeader->uncompressedSize) + sizeof(TextureHeader); - tex = (TextureHeader *) mempool_alloc(numberOfTextures * 0x60 + sp3C, gTexColourTag); + // Allocate enough memory for the decompressed texture + uncompressedSize = byteswap32((u8 *) &gTempTextureHeader->uncompressedSize) + sizeof(TextureHeader); + tex = (TextureHeader *) mempool_alloc(numberOfTextures * TEXTURE_GFX_SIZE + uncompressedSize, gTexColourTag); if (tex == NULL) { return NULL; } - temp_a1 = (((s32) tex + sp3C) - assetSize); - temp_a1 = (s32) temp_a1 - (s32) temp_a1 % 16; - load_asset_to_address(assetSection, temp_a1, assetOffset, assetSize); - gzip_inflate((u8 *) (temp_a1 + sizeof(TextureHeader)), (u8 *) tex); - assetSize = sp3C - sizeof(TextureHeader); + + // Load the compressed texture at the end of the allocated block, + // so it can be decompressed into the entire block + compressedStart = (((s32) tex + uncompressedSize) - assetSize); + compressedStart = (s32) compressedStart - (s32) compressedStart % 16; + load_asset_to_address(assetSection, compressedStart, assetOffset, assetSize); + gzip_inflate((u8 *) (compressedStart + sizeof(TextureHeader)), (u8 *) tex); + assetSize = uncompressedSize - sizeof(TextureHeader); } - texIndex = -1; + + // Find an available slot in the texture cache and store the newly loaded texture + slotIndex = -1; for (i = 0; i < gNumberOfLoadedTextures; i++) { if (gTextureCache[ASSETCACHE_ID(i)] == -1) { - texIndex = i; + slotIndex = i; } } - if (texIndex == -1) { - texIndex = gNumberOfLoadedTextures; + if (slotIndex == -1) { + slotIndex = gNumberOfLoadedTextures; gNumberOfLoadedTextures++; } - gTextureCache[ASSETCACHE_ID(texIndex)] = arg0; - gTextureCache[ASSETCACHE_PTR(texIndex)] = (s32) tex; + gTextureCache[ASSETCACHE_ID(slotIndex)] = id; + gTextureCache[ASSETCACHE_PTR(slotIndex)] = (s32) tex; + + // Load palettes if needed. If the texture has multiple frames, the palette is shared, so we only load it once. paletteOffset = -1; - if ((tex->format & 0xF) == TEX_FORMAT_CI4) { - if (D_80126344 == 0) { + if (TEX_FORMAT(tex->format) == TEX_FORMAT_CI4) { + if (!gFirstTexIsLoaded) { load_asset_to_address(ASSET_EMPTY_14, (u32) &gCiPalettes[gCiPalettesSize], tex->ciPaletteOffset, 32); tex->ciPaletteOffset = gCiPalettesSize; gCiPalettesSize += 32; // (32 bytes / 2 bytes per color) = 16 colors. } paletteOffset = gCiPalettesSize - 32; } - if ((tex->format & 0xF) == TEX_FORMAT_CI8) { - if (D_80126344 == 0) { - load_asset_to_address(ASSET_EMPTY_14, (u32) &gCiPalettesSize[gCiPalettes], tex->ciPaletteOffset, 128); + if (TEX_FORMAT(tex->format) == TEX_FORMAT_CI8) { + if (!gFirstTexIsLoaded) { + // Normally, TEX_FORMAT_CI8 requires 256 colors (512 bytes), + // but maybe only 64 colors (128 bytes) are actually used in this game + load_asset_to_address(ASSET_EMPTY_14, (u32) &gCiPalettes[gCiPalettesSize], tex->ciPaletteOffset, 128); tex->ciPaletteOffset = gCiPalettesSize; gCiPalettesSize += 128; // (128 bytes / 2 bytes per color) = 64 colors. } paletteOffset = gCiPalettesSize - 128; } - D_80126344 = 0; + gFirstTexIsLoaded = FALSE; + // Initialize display lists for each frame of the texture assetOffset = (s32) align16((u8 *) ((s32) tex + assetSize)); texTemp = tex; for (i = 0; i < numberOfTextures; i++) { material_init(texTemp, (Gfx *) assetOffset); if (paletteOffset >= 0) { texTemp->ciPaletteOffset = paletteOffset; - assetOffset += 0x30; // I'm guessing it takes 6 f3d commands to load the palette + assetOffset += PALETTE_GFX_SIZE; // I'm guessing it takes 6 f3d commands to load the palette + //!@bug — no memory was allocated for this! } - assetOffset += 0x60; // I'm guessing it takes 12 f3d commands to load the texture + assetOffset += TEXTURE_GFX_SIZE; // I'm guessing it takes 12 f3d commands to load the texture texTemp = (TextureHeader *) ((s32) texTemp + texTemp->textureSize); } - if (gCiPalettesSize >= 0x280) { + if (gCiPalettesSize >= MAX_TEX_PALETTE_SIZE) { return NULL; } - if (gNumberOfLoadedTextures > 700) { + if (gNumberOfLoadedTextures > MAX_NUM_TEXTURES) { return NULL; } return tex; @@ -533,7 +599,7 @@ TextureHeader *load_texture(s32 arg0) { void tex_free(TextureHeader *tex) { s32 i; - if (tex != 0) { + if (tex != NULL) { if ((--tex->numberOfInstances) <= 0) { for (i = 0; i < gNumberOfLoadedTextures; i++) { if ((s32) tex == gTextureCache[ASSETCACHE_PTR(i)]) { @@ -558,17 +624,16 @@ void set_texture_colour_tag(s32 tagID) { } /** - * Gets the texture cache index from the argument. - * Returns NULL if the entry is invalid. + * Returns the texture stored in the specified cache slot, if any. */ -UNUSED s32 tex_cache_index(s32 texID) { - if (texID < 0 || texID >= gNumberOfLoadedTextures) { +UNUSED TextureHeader *get_cached_texture_by_slot(s32 slotId) { + if (slotId < 0 || slotId >= gNumberOfLoadedTextures) { return NULL; } - if (gTextureCache[ASSETCACHE_PTR(texID)] == -1) { + if (gTextureCache[ASSETCACHE_PTR(slotId)] == -1) { return NULL; } - return gTextureCache[ASSETCACHE_PTR(texID)]; + return (TextureHeader *) gTextureCache[ASSETCACHE_PTR(slotId)]; } /** @@ -582,24 +647,24 @@ void rendermode_reset(Gfx **dList) { gUsingTexture = FALSE; gForceFlags = TRUE; gBlockedRenderFlags = RENDER_NONE; - gUsePrimColour = FALSE; + gUseDirectionalLighting = FALSE; gDPPipeSync((*dList)++); gSPSetGeometryMode((*dList)++, G_SHADING_SMOOTH | G_SHADE | G_ZBUFFER); } /** - * Enables usage of combiners utilising the indidual primitive colours. + * Enables usage of combiners utilising the individual primitive colours. */ -void tex_primcolour_on(void) { - gUsePrimColour = TRUE; +void directional_lighting_on(void) { + gUseDirectionalLighting = TRUE; gForceFlags = TRUE; } /** - * Disables usage of combiners utilising the indidual primitive colours. + * Disables usage of combiners utilising the individual primitive colours. */ -void tex_primcolour_off(void) { - gUsePrimColour = FALSE; +void directional_lighting_off(void) { + gUseDirectionalLighting = FALSE; gForceFlags = TRUE; } @@ -660,7 +725,7 @@ void material_set(Gfx **dList, TextureHeader *texhead, s32 flags, s32 texOffset) gUsingTexture = FALSE; } - flags = (gUsePrimColour) + flags = (gUseDirectionalLighting) ? (flags & (RENDER_DECAL | RENDER_COLOUR_INDEX | RENDER_ANTI_ALIASING | RENDER_Z_COMPARE | RENDER_SEMI_TRANSPARENT)) : (flags & (RENDER_VTX_ALPHA | RENDER_DECAL | RENDER_Z_UPDATE | RENDER_COLOUR_INDEX | RENDER_CUTOUT | @@ -674,7 +739,7 @@ void material_set(Gfx **dList, TextureHeader *texhead, s32 flags, s32 texOffset) } if ((flags & RENDER_VTX_ALPHA) != (gCurrentRenderFlags & RENDER_VTX_ALPHA) || gForceFlags) { - if (flags & RENDER_VTX_ALPHA || gUsePrimColour) { + if (flags & RENDER_VTX_ALPHA || gUseDirectionalLighting) { gSPClearGeometryMode((*dList)++, G_FOG); } else { gSPSetGeometryMode((*dList)++, G_FOG); @@ -708,37 +773,40 @@ void material_set(Gfx **dList, TextureHeader *texhead, s32 flags, s32 texOffset) return; } - if (gUsePrimColour) { - if (flags & RENDER_DECAL && flags & RENDER_Z_COMPARE) { + if (gUseDirectionalLighting) { + if ((flags & RENDER_DECAL) && (flags & RENDER_Z_COMPARE)) { dlIndex = 0; if (flags & RENDER_ANTI_ALIASING) { dlIndex |= 1; // Anti Aliasing } if (flags & RENDER_SEMI_TRANSPARENT) { - dlIndex |= 2; // Z Compare + dlIndex |= 2; // Semi-transparent } if (flags & RENDER_COLOUR_INDEX) { dlIndex |= 4; // Colour Index } + // In this mode, the decal is rendered without any shading or lighting whatsoever. + // It's unclear what this mode has in common with the complex lighting mode set below. gDkrDmaDisplayList((*dList)++, OS_K0_TO_PHYSICAL(dRenderSettingsPrimOverlay[dlIndex]), numberOfGfxCommands(dRenderSettingsPrimOverlay[0])); return; } if (flags & RENDER_COLOUR_INDEX) { - flags = (flags ^ RENDER_COLOUR_INDEX) | RENDER_FOG_ACTIVE; + // set flag 8 if color indexed + flags = (flags ^ RENDER_COLOUR_INDEX) | 8; } - gDkrDmaDisplayList((*dList)++, OS_K0_TO_PHYSICAL(dRenderSettingsPrimCol[flags]), - numberOfGfxCommands(dRenderSettingsPrimCol[0])); + gDkrDmaDisplayList((*dList)++, OS_K0_TO_PHYSICAL(dRenderSettingsDirectionalLighting[flags]), + numberOfGfxCommands(dRenderSettingsDirectionalLighting[0])); return; } - if (flags & RENDER_DECAL && flags & RENDER_Z_COMPARE) { + if ((flags & RENDER_DECAL) && (flags & RENDER_Z_COMPARE)) { dlIndex = 0; if (flags & RENDER_ANTI_ALIASING) { dlIndex |= 1; // Anti Aliasing } if (flags & RENDER_SEMI_TRANSPARENT) { - dlIndex |= 2; // Z Compare + dlIndex |= 2; // Semi-transparent } if (flags & RENDER_FOG_ACTIVE) { dlIndex |= 4; // Fog @@ -805,7 +873,7 @@ void material_set_blinking_lights(Gfx **dList, TextureHeader *texture_list, u32 } gDPPipeSync((*dList)++); - gCurrentTextureHeader = 0; + gCurrentTextureHeader = NULL; flags &= (RENDER_ANTI_ALIASING | RENDER_Z_COMPARE | RENDER_SEMI_TRANSPARENT | RENDER_FOG_ACTIVE | RENDER_CUTOUT); gSPSetGeometryMode((*dList)++, G_FOG); @@ -856,7 +924,7 @@ void material_load_simple(Gfx **dList, s32 flags) { numberOfGfxCommands(dRenderSettingsSpriteCld[0])); } else { // fake ^ 0 required for some reason - gDkrDmaDisplayList((*dList)++, OS_K0_TO_PHYSICAL(dRenderSettingsSpriteXlu[(flags - 16) ^ 0]), + gDkrDmaDisplayList((*dList)++, OS_K0_TO_PHYSICAL(dRenderSettingsSpriteXlu[(flags - RENDER_CUTOUT) ^ 0]), numberOfGfxCommands(dRenderSettingsSpriteXlu[0])); } } else { @@ -947,10 +1015,10 @@ Sprite *tex_load_sprite(s32 spriteID, s32 arg1) { } gTexColourTag = COLOUR_TAG_MAGENTA; - D_80126344 = 1; + gFirstTexIsLoaded = TRUE; } - D_80126344 = 0; + gFirstTexIsLoaded = FALSE; if (allocFailed) { for (i = 0; i < frameCount; i++) { tex = (TextureHeader *) newSprite->frames[i]; @@ -986,7 +1054,7 @@ Sprite *tex_load_sprite(s32 spriteID, s32 arg1) { * Gets the sprite cache index from the argument. * Returns NULL if the entry is invalid. */ -s32 sprite_cache_index(s32 cacheID) { +UNUSED s32 sprite_cache_index(s32 cacheID) { if (cacheID < 0 || cacheID >= gSpriteCacheCount) { return NULL; } @@ -1015,7 +1083,7 @@ s32 tex_asset_size(s32 id) { textureTableType = TEX_TABLE_3D; id &= (ASSET_MASK_TEX3D - 1); } - if (id >= gTextureAssetID[textureTableType] || id < 0) { + if (id >= gTextureTableSize[textureTableType] || id < 0) { return 0; } textureRomOffset = gTextureAssetTable[textureTableType][id]; @@ -1042,8 +1110,8 @@ UNUSED u8 func_8007C660(s32 texID) { return 0; } if (D_80126370 == 0) { - D_80126370 = (u8 *) mempool_alloc_safe(gTextureAssetID[TEX_TABLE_2D], COLOUR_TAG_MAGENTA); - for (i = 0; i < gTextureAssetID[TEX_TABLE_2D]; i++) { + D_80126370 = (u8 *) mempool_alloc_safe(gTextureTableSize[TEX_TABLE_2D], COLOUR_TAG_MAGENTA); + for (i = 0; i < gTextureTableSize[TEX_TABLE_2D]; i++) { D_80126370[i] = 0; } for (i = 0; i < gSpriteTableSize; i++) { diff --git a/src/textures_sprites.h b/src/textures_sprites.h index 6ccec09c..79116d2b 100644 --- a/src/textures_sprites.h +++ b/src/textures_sprites.h @@ -151,8 +151,8 @@ s32 tex_get_table_3D(void); s32 sprite_table_size(void); void set_texture_colour_tag(s32 tagID); void rendermode_reset(Gfx **dList); -void tex_primcolour_on(void); -void tex_primcolour_off(void); +void directional_lighting_on(void); +void directional_lighting_off(void); void material_set_no_tex_offset(Gfx **dList, TextureHeader *texhead, u32 flags); void sprite_opaque(s32 setting); s32 tex_palette_id(s16 paletteID); diff --git a/src/tracks.c b/src/tracks.c index 11fa605e..c3d25027 100644 --- a/src/tracks.c +++ b/src/tracks.c @@ -1558,7 +1558,7 @@ void draw_gradient_background(void) { headerGreen1 = gCurrentLevelHeader2->BGColourBottomG; headerBlue1 = gCurrentLevelHeader2->BGColourBottomB; rendermode_reset(&gTrackDL); - material_set_no_tex_offset(&gTrackDL, 0, RENDER_FOG_ACTIVE); + material_set_no_tex_offset(&gTrackDL, NULL, RENDER_FOG_ACTIVE); gSPVertexDKR(gTrackDL++, OS_K0_TO_PHYSICAL(verts), 4, 0); gSPPolygon(gTrackDL++, OS_K0_TO_PHYSICAL(tris), 2, 0); @@ -1829,7 +1829,7 @@ void render_level_geometry_and_objects(void) { } rendermode_reset(&gTrackDL); - material_set_no_tex_offset(&gTrackDL, 0, RENDER_FOG_ACTIVE | RENDER_Z_COMPARE); + material_set_no_tex_offset(&gTrackDL, NULL, RENDER_FOG_ACTIVE | RENDER_Z_COMPARE); func_80012C3C(&gTrackDL); // Particles and FX diff --git a/src/waves.c b/src/waves.c index cae46cbd..be3e603f 100644 --- a/src/waves.c +++ b/src/waves.c @@ -988,7 +988,7 @@ void waves_render(Gfx **dList, Mtx **mtx, s32 viewportID) { tex2 = set_animated_texture_header(gWaveTexture, gWaveBatch->texOffset * (128 * 128)); wave_load_material(tex1, 1); wave_load_material(tex2, 0); - gDPSetCombineMode(gWaveDL++, DKR_CC_UNK14, DKR_CC_UNK15); + gDPSetCombineMode(gWaveDL++, G_CC_BLENDTEX_MODULATEA_1_PRIM, G_CC_BLENDI_ENV_ALPHA_MODULATEA2); if (TEX_FORMAT(tex1->format) == TEX_FORMAT_RGBA32 && cam_get_viewport_layout() <= VIEWPORT_LAYOUT_1_PLAYER) { gDPSetOtherMode(gWaveDL++, DKR_OMH_2CYC_BILERP, DKR_OML_COMMON | G_RM_AA_ZB_XLU_INTER2); @@ -1006,7 +1006,7 @@ void waves_render(Gfx **dList, Mtx **mtx, s32 viewportID) { gSPSetGeometryMode(gWaveDL++, G_FOG); tex1 = set_animated_texture_header(gWaveTexture, gWaveBatch->texOffset * (128 * 128)); gDkrDmaDisplayList(gWaveDL++, OS_K0_TO_PHYSICAL(tex1->cmd), tex1->numberOfCommands); - gDPSetCombineMode(gWaveDL++, DKR_CC_UNK16, DKR_CC_UNK8); + gDPSetCombineMode(gWaveDL++, G_CC_BLENDT_ENV_ALPHA_A_PRIM, G_CC_MODULATEIDECALA2); gDPSetOtherMode(gWaveDL++, DKR_OMH_2CYC_BILERP, DKR_OML_COMMON | G_RM_FOG_SHADE_A | G_RM_AA_ZB_OPA_SURF2); gDPSetPrimColor(gWaveDL++, 0, 0, 255, 255, 255, 255); if (D_800E3180 != NULL) { diff --git a/ver/symbols/symbol_addrs.jpn.v79.txt b/ver/symbols/symbol_addrs.jpn.v79.txt index 7adb37f7..6c264c73 100644 --- a/ver/symbols/symbol_addrs.jpn.v79.txt +++ b/ver/symbols/symbol_addrs.jpn.v79.txt @@ -1275,8 +1275,8 @@ tex_free = 0x8007B5CC; set_texture_colour_tag = 0x8007B684; tex_cache_index = 0x8007B690; rendermode_reset = 0x8007B6E0; -tex_primcolour_on = 0x8007B74C; -tex_primcolour_off = 0x8007B764; +directional_lighting_on = 0x8007B74C; +directional_lighting_off = 0x8007B764; set_animated_texture_header = 0x8007B77C; material_set_no_tex_offset = 0x8007B7D8; material_set = 0x8007B7F8; @@ -2257,7 +2257,7 @@ D_800DC954 = 0x800DE2F4; gMaxLights = 0x800DE2F8; gNumActiveLights = 0x800DE2FC; D_800DC960 = 0x800DE300; -D_800DC964 = 0x800DE304; +gLightDirs = 0x800DE304; D_800DC968 = 0x800DE308; // object_functions.c .data @@ -2450,7 +2450,7 @@ dRenderSettingsDecal = 0x800E0798; dRenderSettingsSolidColourVtxAlpha = 0x800E0898; dRenderSettingsSolidColour = 0x800E08D8; dRenderSettingsPrimOverlay = 0x800E09D8; -dRenderSettingsPrimCol = 0x800E0A58; +dRenderSettingsDirectionalLighting = 0x800E0A58; dRenderSettingsBlinkingLights = 0x800E0B58; dBasicRenderSettingsZBOff = 0x800E0D58; dBasicRenderSettingsZBOn = 0x800E0D88; @@ -4135,9 +4135,9 @@ gTextureCache = 0x80127DB8; gCiPalettes = 0x80127DBC; gNumberOfLoadedTextures = 0x80127DC0; D_80126334 = 0x80127DC4; -gTextureAssetID = 0x80127DC8; +gTextureTableSize = 0x80127DC8; gCiPalettesSize = 0x80127DD0; -D_80126344 = 0x80127DD4; +gFirstTexIsLoaded = 0x80127DD4; gSpriteOffsetTable = 0x80127DD8; gSpriteCache = 0x80127DDC; gCurrentSprite = 0x80127DE0; @@ -4154,7 +4154,7 @@ gBlockedRenderFlags = 0x80127E08; gCurrentTextureHeader = 0x80127E0C; gUsingTexture = 0x80127E10; gForceFlags = 0x80127E12; -gUsePrimColour = 0x80127E14; +gUseDirectionalLighting = 0x80127E14; // menu .bss gCourseInitials = 0x80127E20; diff --git a/ver/symbols/symbol_addrs.pal.v77.txt b/ver/symbols/symbol_addrs.pal.v77.txt index 10010dde..fa52c02c 100644 --- a/ver/symbols/symbol_addrs.pal.v77.txt +++ b/ver/symbols/symbol_addrs.pal.v77.txt @@ -1271,8 +1271,8 @@ tex_free = 0x8007B2BC; set_texture_colour_tag = 0x8007B374; tex_cache_index = 0x8007B380; rendermode_reset = 0x8007B3D0; -tex_primcolour_on = 0x8007B43C; -tex_primcolour_off = 0x8007B454; +directional_lighting_on = 0x8007B43C; +directional_lighting_off = 0x8007B454; set_animated_texture_header = 0x8007B46C; material_set_no_tex_offset = 0x8007B4C8; material_set = 0x8007B4E8; @@ -2153,7 +2153,7 @@ D_800DC954 = 0x800DC9E4; gMaxLights = 0x800DC9E8; gNumActiveLights = 0x800DC9EC; D_800DC960 = 0x800DC9F0; -D_800DC964 = 0x800DC9F4; +gLightDirs = 0x800DC9F4; D_800DC968 = 0x800DC9F8; gTajTransformTransitionEnd = 0x800DCA00; gTajTransition = 0x800DCA08; @@ -2303,7 +2303,7 @@ dRenderSettingsDecal = 0x800DEE78; dRenderSettingsSolidColourVtxAlpha = 0x800DEF78; dRenderSettingsSolidColour = 0x800DEFB8; dRenderSettingsPrimOverlay = 0x800DF0B8; -dRenderSettingsPrimCol = 0x800DF138; +dRenderSettingsDirectionalLighting = 0x800DF138; dRenderSettingsBlinkingLights = 0x800DF238; dBasicRenderSettingsZBOff = 0x800DF438; dBasicRenderSettingsZBOn = 0x800DF468; @@ -3821,9 +3821,9 @@ gTextureCache = 0x801263B8; gCiPalettes = 0x801263BC; gNumberOfLoadedTextures = 0x801263C0; D_80126334 = 0x801263C4; -gTextureAssetID = 0x801263C8; +gTextureTableSize = 0x801263C8; gCiPalettesSize = 0x801263D0; -D_80126344 = 0x801263D4; +gFirstTexIsLoaded = 0x801263D4; gSpriteOffsetTable = 0x801263D8; gSpriteCache = 0x801263DC; gCurrentSprite = 0x801263E0; @@ -3840,7 +3840,7 @@ gBlockedRenderFlags = 0x80126408; gCurrentTextureHeader = 0x8012640C; gUsingTexture = 0x80126410; gForceFlags = 0x80126412; -gUsePrimColour = 0x80126414; +gUseDirectionalLighting = 0x80126414; gCourseInitials = 0x80126420; gFLapInitials = 0x80126424; gAdventureSaveGhost = 0x80126428; diff --git a/ver/symbols/symbol_addrs.pal.v80.txt b/ver/symbols/symbol_addrs.pal.v80.txt index b810f0ae..ee606224 100644 --- a/ver/symbols/symbol_addrs.pal.v80.txt +++ b/ver/symbols/symbol_addrs.pal.v80.txt @@ -1194,8 +1194,8 @@ tex_free = 0x8007B70C; set_texture_colour_tag = 0x8007B7C4; tex_cache_index = 0x8007B7D0; rendermode_reset = 0x8007B820; -tex_primcolour_on = 0x8007B88C; -tex_primcolour_off = 0x8007B8A4; +directional_lighting_on = 0x8007B88C; +directional_lighting_off = 0x8007B8A4; set_animated_texture_header = 0x8007B8BC; material_set_no_tex_offset = 0x8007B918; material_set = 0x8007B938; @@ -2080,7 +2080,7 @@ D_800DC954 = 0x800DCF54; gMaxLights = 0x800DCF58; gNumActiveLights = 0x800DCF5C; D_800DC960 = 0x800DCF60; -D_800DC964 = 0x800DCF64; +gLightDirs = 0x800DCF64; D_800DC968 = 0x800DCF68; gTajTransformTransitionEnd = 0x800DCF70; gTajTransition = 0x800DCF78; @@ -2231,7 +2231,7 @@ dRenderSettingsDecal = 0x800DF3F8; dRenderSettingsSolidColourVtxAlpha = 0x800DF4F8; dRenderSettingsSolidColour = 0x800DF538; dRenderSettingsPrimOverlay = 0x800DF638; -dRenderSettingsPrimCol = 0x800DF6B8; +dRenderSettingsDirectionalLighting = 0x800DF6B8; dRenderSettingsBlinkingLights = 0x800DF7B8; dBasicRenderSettingsZBOff = 0x800DF9B8; dBasicRenderSettingsZBOn = 0x800DF9E8; @@ -3753,9 +3753,9 @@ gTextureCache = 0x80126958; gCiPalettes = 0x8012695C; gNumberOfLoadedTextures = 0x80126960; D_80126334 = 0x80126964; -gTextureAssetID = 0x80126968; +gTextureTableSize = 0x80126968; gCiPalettesSize = 0x80126970; -D_80126344 = 0x80126974; +gFirstTexIsLoaded = 0x80126974; gSpriteOffsetTable = 0x80126978; gSpriteCache = 0x8012697C; gCurrentSprite = 0x80126980; @@ -3772,7 +3772,7 @@ gBlockedRenderFlags = 0x801269A8; gCurrentTextureHeader = 0x801269AC; gUsingTexture = 0x801269B0; gForceFlags = 0x801269B2; -gUsePrimColour = 0x801269B4; +gUseDirectionalLighting = 0x801269B4; gCourseInitials = 0x801269C0; gFLapInitials = 0x801269C4; gAdventureSaveGhost = 0x801269C8; diff --git a/ver/symbols/symbol_addrs.us.v77.txt b/ver/symbols/symbol_addrs.us.v77.txt index 5bbe0c77..24cc1fca 100644 --- a/ver/symbols/symbol_addrs.us.v77.txt +++ b/ver/symbols/symbol_addrs.us.v77.txt @@ -1271,8 +1271,8 @@ tex_free = 0x8007B2BC; set_texture_colour_tag = 0x8007B374; tex_cache_index = 0x8007B380; rendermode_reset = 0x8007B3D0; -tex_primcolour_on = 0x8007B43C; -tex_primcolour_off = 0x8007B454; +directional_lighting_on = 0x8007B43C; +directional_lighting_off = 0x8007B454; set_animated_texture_header = 0x8007B46C; material_set_no_tex_offset = 0x8007B4C8; material_set = 0x8007B4E8; @@ -2252,7 +2252,7 @@ D_800DC954 = 0x800DC954; gMaxLights = 0x800DC958; gNumActiveLights = 0x800DC95C; D_800DC960 = 0x800DC960; -D_800DC964 = 0x800DC964; +gLightDirs = 0x800DC964; D_800DC968 = 0x800DC968; // object_functions.c .data @@ -2444,7 +2444,7 @@ dRenderSettingsDecal = 0x800DEDE8; dRenderSettingsSolidColourVtxAlpha = 0x800DEEE8; dRenderSettingsSolidColour = 0x800DEF28; dRenderSettingsPrimOverlay = 0x800DF028; -dRenderSettingsPrimCol = 0x800DF0A8; +dRenderSettingsDirectionalLighting = 0x800DF0A8; dRenderSettingsBlinkingLights = 0x800DF1A8; dBasicRenderSettingsZBOff = 0x800DF3A8; dBasicRenderSettingsZBOn = 0x800DF3D8; @@ -4248,9 +4248,9 @@ gTextureCache = 0x80126328; gCiPalettes = 0x8012632C; gNumberOfLoadedTextures = 0x80126330; D_80126334 = 0x80126334; -gTextureAssetID = 0x80126338; +gTextureTableSize = 0x80126338; gCiPalettesSize = 0x80126340; -D_80126344 = 0x80126344; +gFirstTexIsLoaded = 0x80126344; gSpriteOffsetTable = 0x80126348; gSpriteCache = 0x8012634C; gCurrentSprite = 0x80126350; @@ -4267,7 +4267,7 @@ gBlockedRenderFlags = 0x80126378; gCurrentTextureHeader = 0x8012637C; gUsingTexture = 0x80126380; gForceFlags = 0x80126382; -gUsePrimColour = 0x80126384; +gUseDirectionalLighting = 0x80126384; // menu .bss gCourseInitials = 0x80126390; diff --git a/ver/symbols/symbol_addrs.us.v80.txt b/ver/symbols/symbol_addrs.us.v80.txt index f0475cc5..afb6812e 100644 --- a/ver/symbols/symbol_addrs.us.v80.txt +++ b/ver/symbols/symbol_addrs.us.v80.txt @@ -1194,8 +1194,8 @@ tex_free = 0x8007B70C; set_texture_colour_tag = 0x8007B7C4; tex_cache_index = 0x8007B7D0; rendermode_reset = 0x8007B820; -tex_primcolour_on = 0x8007B88C; -tex_primcolour_off = 0x8007B8A4; +directional_lighting_on = 0x8007B88C; +directional_lighting_off = 0x8007B8A4; set_animated_texture_header = 0x8007B8BC; material_set_no_tex_offset = 0x8007B918; material_set = 0x8007B938; @@ -2077,7 +2077,7 @@ D_800DC954 = 0x800DCEC4; gMaxLights = 0x800DCEC8; gNumActiveLights = 0x800DCECC; D_800DC960 = 0x800DCED0; -D_800DC964 = 0x800DCED4; +gLightDirs = 0x800DCED4; D_800DC968 = 0x800DCED8; gTajTransformTransitionEnd = 0x800DCEE0; gTajTransition = 0x800DCEE8; @@ -2228,7 +2228,7 @@ dRenderSettingsDecal = 0x800DF368; dRenderSettingsSolidColourVtxAlpha = 0x800DF468; dRenderSettingsSolidColour = 0x800DF4A8; dRenderSettingsPrimOverlay = 0x800DF5A8; -dRenderSettingsPrimCol = 0x800DF628; +dRenderSettingsDirectionalLighting = 0x800DF628; dRenderSettingsBlinkingLights = 0x800DF728; dBasicRenderSettingsZBOff = 0x800DF928; dBasicRenderSettingsZBOn = 0x800DF958; @@ -3749,9 +3749,9 @@ gTextureCache = 0x801268C8; gCiPalettes = 0x801268CC; gNumberOfLoadedTextures = 0x801268D0; D_80126334 = 0x801268D4; -gTextureAssetID = 0x801268D8; +gTextureTableSize = 0x801268D8; gCiPalettesSize = 0x801268E0; -D_80126344 = 0x801268E4; +gFirstTexIsLoaded = 0x801268E4; gSpriteOffsetTable = 0x801268E8; gSpriteCache = 0x801268EC; gCurrentSprite = 0x801268F0; @@ -3768,7 +3768,7 @@ gBlockedRenderFlags = 0x80126918; gCurrentTextureHeader = 0x8012691C; gUsingTexture = 0x80126920; gForceFlags = 0x80126922; -gUsePrimColour = 0x80126924; +gUseDirectionalLighting = 0x80126924; gCourseInitials = 0x80126930; gFLapInitials = 0x80126934; gAdventureSaveGhost = 0x80126938;