From bb1aacbd0b5cf2b4afd51da772c2ecf7a864e6d1 Mon Sep 17 00:00:00 2001 From: fig02 Date: Sat, 5 Sep 2020 09:45:10 -0400 Subject: z_lights.c OK (#343) * rename some structs * changes * rename stuff and start a func * progress * progress * progress * remove unwanted file * progress * match last few funcs * done, i think * small changes * match Lights_Draw (thanks krim) * comments * cleanup * most pr suggestions * name changes * rename --- src/code/z_actor.c | 47 +++-- src/code/z_collision_check.c | 12 +- src/code/z_eff_shield_particle.c | 17 +- src/code/z_effect_soft_sprite.c | 8 +- src/code/z_lights.c | 418 +++++++++++++++++++++++++++++---------- src/code/z_play.c | 10 +- src/code/z_scene.c | 2 +- 7 files changed, 360 insertions(+), 154 deletions(-) (limited to 'src/code') diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 4f51d9485..019c3c239 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -12,7 +12,7 @@ void ActorShape_Init(ActorShape* shape, f32 arg1, void* shadowDrawFunc, f32 arg3 shape->unk_14 = -1; } -void func_8002B200(Actor* actor, LightMapper* lightMapper, GlobalContext* globalCtx, Gfx* dlist, Color_RGBA8* color) { +void func_8002B200(Actor* actor, Lights* lights, GlobalContext* globalCtx, Gfx* dlist, Color_RGBA8* color) { f32 temp1; f32 temp2; MtxF sp60; @@ -57,18 +57,18 @@ void func_8002B200(Actor* actor, LightMapper* lightMapper, GlobalContext* global } } -void ActorShadow_DrawFunc_Circle(Actor* actor, LightMapper* lightMapper, GlobalContext* globalCtx) { - func_8002B200(actor, lightMapper, globalCtx, &D_04049210, NULL); +void ActorShadow_DrawFunc_Circle(Actor* actor, Lights* lights, GlobalContext* globalCtx) { + func_8002B200(actor, lights, globalCtx, &D_04049210, NULL); } Color_RGBA8 D_80115F80 = { 255, 255, 255, 255 }; -void ActorShadow_DrawFunc_WhiteCircle(Actor* actor, LightMapper* lightMapper, GlobalContext* globalCtx) { - func_8002B200(actor, lightMapper, globalCtx, &D_04049210, &D_80115F80); +void ActorShadow_DrawFunc_WhiteCircle(Actor* actor, Lights* lights, GlobalContext* globalCtx) { + func_8002B200(actor, lights, globalCtx, &D_04049210, &D_80115F80); } -void ActorShadow_DrawFunc_Squiggly(Actor* actor, LightMapper* lightMapper, GlobalContext* globalCtx) { - func_8002B200(actor, lightMapper, globalCtx, &D_04049AD0, NULL); +void ActorShadow_DrawFunc_Squiggly(Actor* actor, Lights* lights, GlobalContext* globalCtx) { + func_8002B200(actor, lights, globalCtx, &D_04049AD0, NULL); } void func_8002B66C(GlobalContext* globalCtx, Light* light, MtxF* arg2, s32 arg3, f32 arg4, f32 arg5, f32 arg6) { @@ -97,7 +97,7 @@ void func_8002B66C(GlobalContext* globalCtx, Light* light, MtxF* arg2, s32 arg3, #ifdef NON_MATCHING // saved register, stack usage and minor ordering differences -void ActorShadow_DrawFunc_Teardrop(Actor* actor, LightMapper* lightMapper, GlobalContext* globalCtx) { +void ActorShadow_DrawFunc_Teardrop(Actor* actor, Lights* lights, GlobalContext* globalCtx) { MtxF spE8; f32 spE0[2]; s32 i; @@ -125,7 +125,7 @@ void ActorShadow_DrawFunc_Teardrop(Actor* actor, LightMapper* lightMapper, Globa temp_14 = actor->shape.unk_14; actor->shape.unk_10 *= 0.3f; actor->shape.unk_14 *= ((temp_f20 - 20.0f) * 0.02f) > 1.0f ? 1.0f : ((temp_f20 - 20.0f) * 0.02f); - ActorShadow_DrawFunc_Circle(actor, lightMapper, globalCtx); + ActorShadow_DrawFunc_Circle(actor, lights, globalCtx); actor->shape.unk_10 = temp_10; actor->shape.unk_14 = temp_14; } @@ -133,7 +133,7 @@ void ActorShadow_DrawFunc_Teardrop(Actor* actor, LightMapper* lightMapper, Globa if (temp_f20 < 200.0f) { phi_s7 = &actor->unk_CC[0]; spAC = &spE0[0]; - temp_s6 = lightMapper->numLights; + temp_s6 = lights->numLights; temp_s6 -= 2; OPEN_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 1741); @@ -151,7 +151,7 @@ void ActorShadow_DrawFunc_Teardrop(Actor* actor, LightMapper* lightMapper, Globa phi_f2 = phi_s7->y - *spAC; if ((phi_f2 >= -1.0f) && (phi_f2 < 500.0f)) { - phi_s0 = lightMapper->lights; + phi_s0 = &lights->l.l[0]; if (phi_f2 <= 0.0f) { actor->shape.unk_15++; @@ -1724,8 +1724,8 @@ s32 func_8002F9EC(GlobalContext* globalCtx, Actor* actor, UNK_TYPE arg2, UNK_TYP } // Local data used for Farore's Wind light (stored in BSS, possibly a struct?) -LightInfoPositional D_8015BC00; -z_Light* D_8015BC10; +LightInfo D_8015BC00; +LightNode* D_8015BC10; s32 D_8015BC14; f32 D_8015BC18; @@ -1754,9 +1754,9 @@ void func_8002FA60(GlobalContext* globalCtx) { lightPos.y = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y + 80.0f; lightPos.z = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z; - Lights_InitType0PositionalLight(&D_8015BC00, lightPos.x, lightPos.y, lightPos.z, 0xFF, 0xFF, 0xFF, -1); + Lights_PointNoGlowSetInfo(&D_8015BC00, lightPos.x, lightPos.y, lightPos.z, 0xFF, 0xFF, 0xFF, -1); - D_8015BC10 = Lights_Insert(globalCtx, &globalCtx->lightCtx, &D_8015BC00); + D_8015BC10 = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &D_8015BC00); D_8015BC14 = 0; D_8015BC18 = 0.0f; } @@ -1919,8 +1919,7 @@ void func_8002FBAC(GlobalContext* globalCtx) { lightPos.y = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y + spD8; lightPos.z = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z; - Lights_InitType0PositionalLight(&D_8015BC00, lightPos.x, lightPos.y, lightPos.z, 0xFF, 0xFF, 0xFF, - 500.0f * spD4); + Lights_PointNoGlowSetInfo(&D_8015BC00, lightPos.x, lightPos.y, lightPos.z, 0xFF, 0xFF, 0xFF, 500.0f * spD4); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 5474); } @@ -1930,7 +1929,7 @@ void func_8002FBAC(GlobalContext* globalCtx) { #endif void func_80030488(GlobalContext* globalCtx) { - Lights_Remove(globalCtx, &globalCtx->lightCtx, D_8015BC10); + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, D_8015BC10); } void func_800304B0(GlobalContext* globalCtx) { @@ -2150,16 +2149,16 @@ void Actor_FaultPrint(Actor* actor, char* command) { void Actor_Draw(GlobalContext* globalCtx, Actor* actor) { FaultClient faultClient; - LightMapper* lightMapper; + Lights* lights; Fault_AddClient(&faultClient, Actor_FaultPrint, actor, "Actor_draw"); OPEN_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 6035); - lightMapper = Lights_CreateMapper(&globalCtx->lightCtx, globalCtx->state.gfxCtx); + lights = LightContext_NewLights(&globalCtx->lightCtx, globalCtx->state.gfxCtx); - func_8007A474(lightMapper, globalCtx->lightCtx.lightsHead, (actor->flags & 0x400000) ? NULL : &actor->posRot.pos); - func_80079EFC(lightMapper, globalCtx->state.gfxCtx); + Lights_BindAll(lights, globalCtx->lightCtx.listHead, (actor->flags & 0x400000) ? NULL : &actor->posRot.pos); + Lights_Draw(lights, globalCtx->state.gfxCtx); if (actor->flags & 0x1000) { func_800D1694(actor->posRot.pos.x + globalCtx->mainCamera.unk_80.x, @@ -2206,7 +2205,7 @@ void Actor_Draw(GlobalContext* globalCtx, Actor* actor) { } if (actor->shape.shadowDrawFunc != NULL) { - actor->shape.shadowDrawFunc(actor, lightMapper, globalCtx); + actor->shape.shadowDrawFunc(actor, lights, globalCtx); } CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 6119); @@ -2425,7 +2424,7 @@ void func_800315AC(GlobalContext* globalCtx, ActorContext* actorCtx) { func_8002FBAC(globalCtx); if (IREG(32) == 0) { - func_8007ABBC(globalCtx); + Lights_DrawGlow(globalCtx); } if ((HREG(64) != 1) || (HREG(75) != 0)) { diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c index fca60ed13..105db862a 100644 --- a/src/code/z_collision_check.c +++ b/src/code/z_collision_check.c @@ -3068,9 +3068,9 @@ void func_80062CD4(GlobalContext* globalCtx, Vec3f* v) { init.position.x = (s32)v->x; init.position.y = (s32)v->y; init.position.z = (s32)v->z; - init.lightParams.posX = init.position.x; - init.lightParams.posY = init.position.y; - init.lightParams.posZ = init.position.z; + init.lightPoint.x = init.position.x; + init.lightPoint.y = init.position.y; + init.lightPoint.z = init.position.z; Effect_Add(globalCtx, &sp24, EFFECT_SHIELD_PARTICLE, 0, 1, &init); } @@ -3111,9 +3111,9 @@ void func_80062E14(GlobalContext* globalCtx, Vec3f* v, Vec3f* arg2) { init.position.x = (s32)v->x; init.position.y = (s32)v->y; init.position.z = (s32)v->z; - init.lightParams.posX = init.position.x; - init.lightParams.posY = init.position.y; - init.lightParams.posZ = init.position.z; + init.lightPoint.x = init.position.x; + init.lightPoint.y = init.position.y; + init.lightPoint.z = init.position.z; Effect_Add(globalCtx, &sp24, EFFECT_SHIELD_PARTICLE, 0, 1, &init); Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, arg2, 4, &D_801333E0, &D_801333E0, &D_801333E8); diff --git a/src/code/z_eff_shield_particle.c b/src/code/z_eff_shield_particle.c index 46a0b9502..42e3cde6c 100644 --- a/src/code/z_eff_shield_particle.c +++ b/src/code/z_eff_shield_particle.c @@ -50,11 +50,12 @@ void EffectShieldParticle_Init(void* thisx, void* initParamsx) { this->lightDecay = initParams->lightDecay; if (this->lightDecay == true) { - this->lightInfo.type = 0; - this->lightInfo.params = initParams->lightParams; - this->light = Lights_Insert(Effect_GetGlobalCtx(), &Effect_GetGlobalCtx()->lightCtx, &this->lightInfo); + this->lightInfo.type = LIGHT_POINT_NOGLOW; + this->lightInfo.params.point = initParams->lightPoint; + this->lightNode = + LightContext_InsertLight(Effect_GetGlobalCtx(), &Effect_GetGlobalCtx()->lightCtx, &this->lightInfo); } else { - this->light = NULL; + this->lightNode = NULL; } } } @@ -63,10 +64,10 @@ void EffectShieldParticle_Destroy(void* thisx) { EffectShieldParticle* this = (EffectShieldParticle*)thisx; if ((this != NULL) && (this->lightDecay == true)) { - if (this->light == Effect_GetGlobalCtx()->lightCtx.lightsHead) { - Effect_GetGlobalCtx()->lightCtx.lightsHead = this->light->next; + if (this->lightNode == Effect_GetGlobalCtx()->lightCtx.listHead) { + Effect_GetGlobalCtx()->lightCtx.listHead = this->lightNode->next; } - Lights_Remove(Effect_GetGlobalCtx(), &Effect_GetGlobalCtx()->lightCtx, this->light); + LightContext_RemoveLight(Effect_GetGlobalCtx(), &Effect_GetGlobalCtx()->lightCtx, this->lightNode); } } @@ -100,7 +101,7 @@ s32 EffectShieldParticle_Update(void* thisx) { } if (this->lightDecay == true) { - this->lightInfo.params.radius /= 2; + this->lightInfo.params.point.radius /= 2; } this->timer++; diff --git a/src/code/z_effect_soft_sprite.c b/src/code/z_effect_soft_sprite.c index 8af41a464..6f9a16f89 100644 --- a/src/code/z_effect_soft_sprite.c +++ b/src/code/z_effect_soft_sprite.c @@ -295,12 +295,12 @@ void EffectSs_Draw(GlobalContext* globalCtx, s32 index) { // original name: "EffectSoftSprite2_disp" void EffectSs_DrawAll(GlobalContext* globalCtx) { - LightMapper* lightMapper; + Lights* lights; s32 i; - lightMapper = Lights_CreateMapper(&globalCtx->lightCtx, globalCtx->state.gfxCtx); - func_8007A474(lightMapper, globalCtx->lightCtx.lightsHead, 0); - func_80079EFC(lightMapper, globalCtx->state.gfxCtx); + lights = LightContext_NewLights(&globalCtx->lightCtx, globalCtx->state.gfxCtx); + Lights_BindAll(lights, globalCtx->lightCtx.listHead, NULL); + Lights_Draw(lights, globalCtx->state.gfxCtx); for (i = 0; i < sEffectSsInfo.tableSize; i++) { if (sEffectSsInfo.table[i].life > -1) { diff --git a/src/code/z_lights.c b/src/code/z_lights.c index 83f0a7032..50e351aa4 100644 --- a/src/code/z_lights.c +++ b/src/code/z_lights.c @@ -1,190 +1,396 @@ #include #include -LightsList sLightsList; +#define LIGHTS_BUFFER_SIZE 32 -void Lights_InitPositionalLight(LightInfoPositional* info, s16 posX, s16 posY, s16 posZ, u8 red, u8 green, u8 blue, - s16 radius, u32 type) { +typedef struct { + /* 0x000 */ s32 numOccupied; + /* 0x004 */ s32 searchIndex; + /* 0x008 */ LightNode buf[LIGHTS_BUFFER_SIZE]; +} LightsBuffer; // size = 0x188 + +LightsBuffer sLightsBuffer; + +void Lights_PointSetInfo(LightInfo* info, s16 x, s16 y, s16 z, u8 r, u8 g, u8 b, s16 radius, s32 type) { info->type = type; - info->params.posX = posX; - info->params.posY = posY; - info->params.posZ = posZ; - Lights_SetPositionalLightColorAndRadius(info, red, green, blue, radius); + info->params.point.x = x; + info->params.point.y = y; + info->params.point.z = z; + Lights_PointSetColorAndRadius(info, r, g, b, radius); } -void Lights_InitType0PositionalLight(LightInfoPositional* info, s16 posX, s16 posY, s16 posZ, u8 red, u8 green, u8 blue, - s16 radius) { - Lights_InitPositionalLight(info, posX, posY, posZ, red, green, blue, radius, 0); +void Lights_PointNoGlowSetInfo(LightInfo* info, s16 x, s16 y, s16 z, u8 r, u8 g, u8 b, s16 radius) { + Lights_PointSetInfo(info, x, y, z, r, g, b, radius, LIGHT_POINT_NOGLOW); } -void Lights_InitType2PositionalLight(LightInfoPositional* info, s16 posX, s16 posY, s16 posZ, u8 red, u8 green, u8 blue, - s16 radius) { - Lights_InitPositionalLight(info, posX, posY, posZ, red, green, blue, radius, 2); +void Lights_PointGlowSetInfo(LightInfo* info, s16 x, s16 y, s16 z, u8 r, u8 g, u8 b, s16 radius) { + Lights_PointSetInfo(info, x, y, z, r, g, b, radius, LIGHT_POINT_GLOW); } -void Lights_SetPositionalLightColorAndRadius(LightInfoPositional* info, u8 red, u8 green, u8 blue, s16 radius) { - info->params.red = red; - info->params.green = green; - info->params.blue = blue; - info->params.radius = radius; +void Lights_PointSetColorAndRadius(LightInfo* info, u8 r, u8 g, u8 b, s16 radius) { + info->params.point.color[0] = r; + info->params.point.color[1] = g; + info->params.point.color[2] = b; + info->params.point.radius = radius; } -void Lights_InitDirectional(LightInfoDirectional* info, s8 dirX, s8 dirY, s8 dirZ, u8 red, u8 green, u8 blue) { - info->type = 1; - info->params.dirX = dirX; - info->params.dirY = dirY; - info->params.dirZ = dirZ; - info->params.red = red; - info->params.green = green; - info->params.blue = blue; +void Lights_DirectionalSetInfo(LightInfo* info, s8 x, s8 y, s8 z, u8 r, u8 g, u8 b) { + info->type = LIGHT_DIRECTIONAL; + info->params.dir.x = x; + info->params.dir.y = y; + info->params.dir.z = z; + info->params.dir.color[0] = r; + info->params.dir.color[1] = g; + info->params.dir.color[2] = b; } -void Lights_MapperInit(LightMapper* mapper, u8 red, u8 green, u8 blue) { - mapper->ambient.l.col[0] = red; - mapper->ambient.l.colc[0] = red; - mapper->ambient.l.col[1] = green; - mapper->ambient.l.colc[1] = green; - mapper->ambient.l.col[2] = blue; - mapper->ambient.l.colc[2] = blue; - mapper->numLights = 0; +// unused +void Lights_Reset(Lights* lights, u8 ambentR, u8 ambentG, u8 ambentB) { + lights->l.a.l.col[0] = lights->l.a.l.colc[0] = ambentR; + lights->l.a.l.col[1] = lights->l.a.l.colc[1] = ambentG; + lights->l.a.l.col[2] = lights->l.a.l.colc[2] = ambentB; + lights->numLights = 0; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_lights/func_80079EFC.s") +/* + * Draws every light in the provided Lights group + */ +void Lights_Draw(Lights* lights, GraphicsContext* gfxCtx) { + Light* light; + s32 i; -Light* Lights_MapperGetNextFreeSlot(LightMapper* mapper) { - if (6 < mapper->numLights) { - return NULL; + OPEN_DISPS(gfxCtx, "../z_lights.c", 339); + + gSPNumLights(oGfxCtx->polyOpa.p++, lights->numLights); + gSPNumLights(oGfxCtx->polyXlu.p++, lights->numLights); + + i = 0; + light = &lights->l.l[0]; + + while (i < lights->numLights) { + i++; + gSPLight(oGfxCtx->polyOpa.p++, light, i); + gSPLight(oGfxCtx->polyXlu.p++, light, i); + light++; } - return &mapper->lights[mapper->numLights++]; + if (0) {} + + i++; // abmient light is total number of lights + 1 + gSPLight(oGfxCtx->polyOpa.p++, &lights->l.a, i); + gSPLight(oGfxCtx->polyXlu.p++, &lights->l.a, i); + + CLOSE_DISPS(gfxCtx, "../z_lights.c", 352); +} + +Light* Lights_FindSlot(Lights* lights) { + if (lights->numLights >= 7) { + return NULL; + } else { + return &lights->l.l[lights->numLights++]; + } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_lights/func_8007A0B4.s") +void Lights_BindPoint(Lights* lights, LightParams* params, Vec3f* vec) { + f32 xDiff; + f32 yDiff; + f32 zDiff; + f32 posDiff; + f32 scale; + Light* light; + + if (vec != NULL) { + xDiff = params->point.x - vec->x; + yDiff = params->point.y - vec->y; + zDiff = params->point.z - vec->z; + scale = params->point.radius; + posDiff = SQ(xDiff) + SQ(yDiff) + SQ(zDiff); + + if (posDiff < SQ(scale)) { + light = Lights_FindSlot(lights); + + if (light != NULL) { + posDiff = sqrtf(posDiff); + if (1) {} + scale = posDiff / scale; + scale = 1 - SQ(scale); + + light->l.col[0] = light->l.colc[0] = params->point.color[0] * scale; + light->l.col[1] = light->l.colc[1] = params->point.color[1] * scale; + light->l.col[2] = light->l.colc[2] = params->point.color[2] * scale; + + scale = (posDiff < 1.0f) ? 120.0f : 120.0f / posDiff; + + light->l.dir[0] = xDiff * scale; + light->l.dir[1] = yDiff * scale; + light->l.dir[2] = zDiff * scale; + } + } + } +} -void func_8007A40C(LightMapper* mapper, LightInfoDirectionalParams* params, GlobalContext* globalCtx) { - Light* light = Lights_MapperGetNextFreeSlot(mapper); +void Lights_BindDirectional(Lights* lights, LightParams* params, Vec3f* vec) { + Light* light = Lights_FindSlot(lights); if (light != NULL) { - light->l.col[0] = light->l.colc[0] = params->red; - light->l.col[1] = light->l.colc[1] = params->green; - light->l.col[2] = light->l.colc[2] = params->blue; - light->l.dir[0] = params->dirX; - light->l.dir[1] = params->dirY; - light->l.dir[2] = params->dirZ; + light->l.col[0] = light->l.colc[0] = params->dir.color[0]; + light->l.col[1] = light->l.colc[1] = params->dir.color[1]; + light->l.col[2] = light->l.colc[2] = params->dir.color[2]; + light->l.dir[0] = params->dir.x; + light->l.dir[1] = params->dir.y; + light->l.dir[2] = params->dir.z; } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_lights/func_8007A474.s") +/* + * For every light in a provided list, try to find a free slot in the provided Lights group and bind + * a light to it. Then apply color and positional/directional info for each light + * based on the parameters supplied by the node. + * + * Note: Lights in a given list can only be binded to however many free slots are + * available in the Lights group. This is at most 7 slots for a new group, but could be less. + */ +void Lights_BindAll(Lights* lights, LightNode* listHead, Vec3f* vec) { + LightsBindFunc bindFuncs[] = { Lights_BindPoint, Lights_BindDirectional, Lights_BindPoint }; + LightInfo* info; + + while (listHead != NULL) { + info = listHead->info; + bindFuncs[info->type](lights, &info->params, vec); + listHead = listHead->next; + } +} -z_Light* Lights_FindFreeSlot() { - z_Light* ret; +LightNode* Lights_FindBufSlot() { + LightNode* node; - if (0x1F < sLightsList.numOccupied) { + if (sLightsBuffer.numOccupied >= LIGHTS_BUFFER_SIZE) { return NULL; } - ret = &sLightsList.lights[sLightsList.nextFree]; + node = &sLightsBuffer.buf[sLightsBuffer.searchIndex]; - while (ret->info != NULL) { - sLightsList.nextFree++; + while (node->info != NULL) { + sLightsBuffer.searchIndex++; - if (sLightsList.nextFree < 0x20) { - ret++; + if (sLightsBuffer.searchIndex < LIGHTS_BUFFER_SIZE) { + node++; } else { - sLightsList.nextFree = 0; - ret = &sLightsList.lights[0]; + sLightsBuffer.searchIndex = 0; + node = &sLightsBuffer.buf[0]; } } - sLightsList.numOccupied++; + sLightsBuffer.numOccupied++; - return ret; + return node; } // return type must not be void to match -s32 Lights_Free(z_Light* light) { +s32 Lights_FreeNode(LightNode* light) { if (light != NULL) { - sLightsList.numOccupied--; + sLightsBuffer.numOccupied--; light->info = NULL; - sLightsList.nextFree = (light - sLightsList.lights) / sizeof(z_Light); + sLightsBuffer.searchIndex = (light - sLightsBuffer.buf) / sizeof(LightNode); } } -void func_8007A614(GlobalContext* globalCtx, LightingContext* lightCtx) { - Lights_ClearHead(globalCtx, lightCtx); - Lights_SetAmbientColor(lightCtx, 80, 80, 80); - func_8007A698(lightCtx, 0, 0, 0, 0x3e4, 0x3200); - bzero(&sLightsList, sizeof(sLightsList)); +void LightContext_Init(GlobalContext* globalCtx, LightContext* lightCtx) { + LightContext_InitList(globalCtx, lightCtx); + LightContext_SetAmbientColor(lightCtx, 80, 80, 80); + func_8007A698(lightCtx, 0, 0, 0, 0x3E4, 0x3200); + bzero(&sLightsBuffer, sizeof(sLightsBuffer)); } -void Lights_SetAmbientColor(LightingContext* lightCtx, u8 red, u8 green, u8 blue) { - lightCtx->ambientRed = red; - lightCtx->ambientGreen = green; - lightCtx->ambientBlue = blue; +void LightContext_SetAmbientColor(LightContext* lightCtx, u8 r, u8 g, u8 b) { + lightCtx->ambient.r = r; + lightCtx->ambient.g = g; + lightCtx->ambient.b = b; } -void func_8007A698(LightingContext* lightCtx, u8 arg1, u8 arg2, u8 arg3, s16 arg4, s16 arg5) { +void func_8007A698(LightContext* lightCtx, u8 arg1, u8 arg2, u8 arg3, s16 numLights, s16 arg5) { lightCtx->unk_07 = arg1; lightCtx->unk_08 = arg2; lightCtx->unk_09 = arg3; - lightCtx->unk_0A = arg4; + lightCtx->unk_0A = numLights; lightCtx->unk_0C = arg5; } -LightMapper* Lights_CreateMapper(LightingContext* lightCtx, GraphicsContext* gfxCtx) { - return func_8007A960(gfxCtx, lightCtx->ambientRed, lightCtx->ambientGreen, lightCtx->ambientBlue); +/* + * Allocate a new Lights group and initilize the ambient color with that provided by LightContext + */ +Lights* LightContext_NewLights(LightContext* lightCtx, GraphicsContext* gfxCtx) { + return Lights_New(gfxCtx, lightCtx->ambient.r, lightCtx->ambient.g, lightCtx->ambient.b); } -void Lights_ClearHead(GlobalContext* globalCtx, LightingContext* lightCtx) { - lightCtx->lightsHead = NULL; +void LightContext_InitList(GlobalContext* globalCtx, LightContext* lightCtx) { + lightCtx->listHead = NULL; } -void Lights_RemoveAll(GlobalContext* globalCtx, LightingContext* lightCtx) { - while (lightCtx->lightsHead != NULL) { - Lights_Remove(globalCtx, lightCtx, lightCtx->lightsHead); - lightCtx->lightsHead = lightCtx->lightsHead->next; +void LightContext_DestroyList(GlobalContext* globalCtx, LightContext* lightCtx) { + while (lightCtx->listHead != NULL) { + LightContext_RemoveLight(globalCtx, lightCtx, lightCtx->listHead); + lightCtx->listHead = lightCtx->listHead->next; } } -z_Light* Lights_Insert(GlobalContext* globalCtx, LightingContext* lightCtx, void* info) { - z_Light* light; +/* + * Insert a new light into the list pointed to by LightContext + * + * Note: Due to the limited number of slots in a Lights group, inserting too many lights in the + * list may result in older entries not being bound to a Light when calling Lights_BindAll + */ +LightNode* LightContext_InsertLight(GlobalContext* globalCtx, LightContext* lightCtx, LightInfo* info) { + LightNode* node; - light = Lights_FindFreeSlot(); - if (light != NULL) { - light->info = info; - light->prev = NULL; - light->next = lightCtx->lightsHead; + node = Lights_FindBufSlot(); + + if (node != NULL) { + node->info = info; + node->prev = NULL; + node->next = lightCtx->listHead; - if (lightCtx->lightsHead != NULL) { - lightCtx->lightsHead->prev = light; + if (lightCtx->listHead != NULL) { + lightCtx->listHead->prev = node; } - lightCtx->lightsHead = light; + lightCtx->listHead = node; } - return light; + return node; } -void Lights_Remove(GlobalContext* globalCtx, LightingContext* lightCtx, z_Light* light) { - if (light != NULL) { - if (light->prev != NULL) { - light->prev->next = light->next; +void LightContext_RemoveLight(GlobalContext* globalCtx, LightContext* lightCtx, LightNode* node) { + if (node != NULL) { + if (node->prev != NULL) { + node->prev->next = node->next; } else { - lightCtx->lightsHead = light->next; + lightCtx->listHead = node->next; } - if (light->next != NULL) { - light->next->prev = light->prev; + if (node->next != NULL) { + node->next->prev = node->prev; } - Lights_Free(light); + Lights_FreeNode(node); } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_lights/func_8007A824.s") +// unused +Lights* Lights_NewAndDraw(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 ambientB, u8 numLights, u8 r, u8 g, + u8 b, s8 x, s8 y, s8 z) { + Lights* lights; + s32 i; + + lights = Graph_Alloc(gfxCtx, sizeof(Lights)); + + lights->l.a.l.col[0] = lights->l.a.l.colc[0] = ambientR; + lights->l.a.l.col[1] = lights->l.a.l.colc[1] = ambientG; + lights->l.a.l.col[2] = lights->l.a.l.colc[2] = ambientB; + lights->numLights = numLights; + + for (i = 0; i < numLights; i++) { + lights->l.l[i].l.col[0] = lights->l.l[i].l.colc[0] = r; + lights->l.l[i].l.col[1] = lights->l.l[i].l.colc[1] = g; + lights->l.l[i].l.col[2] = lights->l.l[i].l.colc[2] = b; + lights->l.l[i].l.dir[0] = x; + lights->l.l[i].l.dir[1] = y; + lights->l.l[i].l.dir[2] = z; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_lights/func_8007A960.s") + Lights_Draw(lights, gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_lights/func_8007A9B4.s") + return lights; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_lights/func_8007ABBC.s") +Lights* Lights_New(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 ambientB) { + Lights* lights; + + lights = Graph_Alloc(gfxCtx, sizeof(Lights)); + + lights->l.a.l.col[0] = lights->l.a.l.colc[0] = ambientR; + lights->l.a.l.col[1] = lights->l.a.l.colc[1] = ambientG; + lights->l.a.l.col[2] = lights->l.a.l.colc[2] = ambientB; + lights->numLights = 0; + + return lights; +} + +void Lights_GlowCheck(GlobalContext* globalCtx) { + LightNode* node; + LightPoint* params; + Vec3f pos; + Vec3f multDest; + f32 wDest; + f32 wX; + f32 wY; + s32 wZ; + s32 zBuf; + + node = globalCtx->lightCtx.listHead; + + while (node != NULL) { + params = &node->info->params.point; + + if (node->info->type == LIGHT_POINT_GLOW) { + pos.x = params->x; + pos.y = params->y; + pos.z = params->z; + func_8002BE04(globalCtx, &pos, &multDest, &wDest); + params->drawGlow = false; + wX = multDest.x * wDest; + wY = multDest.y * wDest; + + if ((multDest.z > 1.0f) && (fabsf(wX) < 1.0f) && (fabsf(wY) < 1.0f)) { + wZ = (s32)((multDest.z * wDest) * 16352.0f) + 16352; + zBuf = gZBuffer[(s32)((wY * -120.0f) + 120.0f)][(s32)((wX * 160.0f) + 160.0f)] * 4; + if (1) {} + if (1) {} + + if (wZ < (func_8006F0A0(zBuf) >> 3)) { + params->drawGlow = true; + } + } + } + node = node->next; + } +} + +void Lights_DrawGlow(GlobalContext* globalCtx) { + s32 pad; + LightNode* node; + + node = globalCtx->lightCtx.listHead; + + OPEN_DISPS(globalCtx->state.gfxCtx, "../z_lights.c", 887); + + oGfxCtx->polyXlu.p = func_800947AC(oGfxCtx->polyXlu.p++); + gDPSetAlphaDither(oGfxCtx->polyXlu.p++, G_AD_NOISE); + gDPSetColorDither(oGfxCtx->polyXlu.p++, G_CD_MAGICSQ); + gSPDisplayList(oGfxCtx->polyXlu.p++, D_04015720); + + while (node != NULL) { + LightInfo* info; + LightPoint* params; + f32 scale; + s32 pad[4]; + + info = node->info; + params = &info->params.point; + + if ((info->type == LIGHT_POINT_GLOW) && (params->drawGlow)) { + scale = SQ(params->radius) * 0.0000026f; + + gDPSetPrimColor(oGfxCtx->polyXlu.p++, 0, 0, params->color[0], params->color[1], params->color[2], 50); + Matrix_Translate(params->x, params->y, params->z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_lights.c", 918), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(oGfxCtx->polyXlu.p++, D_04015760); + } + + node = node->next; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_lights.c", 927); +} diff --git a/src/code/z_play.c b/src/code/z_play.c index 1a1b8431a..a3ab3930f 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -1071,7 +1071,7 @@ void Gameplay_DrawOverlayElements(GlobalContext* globalCtx) { // regalloc, stack usage and minor ordering differences void Gameplay_Draw(GlobalContext* globalCtx) { GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; - LightMapper* sp228; + Lights* sp228; Vec3f sp21C; OPEN_DISPS(gfxCtx, "../z_play.c", 3907); @@ -1208,9 +1208,9 @@ void Gameplay_Draw(GlobalContext* globalCtx) { } if ((HREG(80) != 10) || (HREG(90) & 8)) { - sp228 = Lights_CreateMapper(&globalCtx->lightCtx, gfxCtx); - func_8007A474(sp228, globalCtx->lightCtx.lightsHead, 0); - func_80079EFC(sp228, gfxCtx); + sp228 = LightContext_NewLights(&globalCtx->lightCtx, gfxCtx); + Lights_BindAll(sp228, globalCtx->lightCtx.listHead, NULL); + Lights_Draw(sp228, gfxCtx); } if ((HREG(80) != 10) || (HREG(84) != 0)) { @@ -1467,7 +1467,7 @@ void Gameplay_InitScene(GlobalContext* globalCtx, s32 spawn) { globalCtx->setupPathList = NULL; globalCtx->nbSetupActors = 0; Object_InitBank(globalCtx, &globalCtx->objectCtx); - func_8007A614(globalCtx, &globalCtx->lightCtx); + LightContext_Init(globalCtx, &globalCtx->lightCtx); func_80098CBC(globalCtx, &globalCtx->nbTransitionActors); func_80096FD4(globalCtx, &globalCtx->roomCtx.curRoom); YREG(15) = 0; diff --git a/src/code/z_scene.c b/src/code/z_scene.c index 436fc72c6..733d08fa4 100644 --- a/src/code/z_scene.c +++ b/src/code/z_scene.c @@ -336,7 +336,7 @@ void func_80098B74(GlobalContext* globalCtx, SceneCmd* cmd) { lightInfo = SEGMENTED_TO_VIRTUAL(cmd->lightList.segment); for (i = 0; i < cmd->lightList.num; i++) { - Lights_Insert(globalCtx, &globalCtx->lightCtx, lightInfo); + LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, lightInfo); lightInfo++; } } -- cgit v1.2.3