z_lights fully matched (#80)

* z_lights OK

* Documentation

* Fixup for z_collision_check

* Improve function types of bind functions

* Fixup for types
This commit is contained in:
Rozelette
2021-03-27 14:29:30 -05:00
committed by GitHub
parent 012e3c21ae
commit fee7a49abc
20 changed files with 557 additions and 530 deletions
+26 -26
View File
@@ -27,34 +27,34 @@ void GameState_SetFBFilter(Gfx** gfx, u32 arg1) {
if ((R_FB_FILTER_TYPE > 0) && (R_FB_FILTER_TYPE < 5)) {
D_801F8010.type = R_FB_FILTER_TYPE;
D_801F8010.color.red = R_FB_FILTER_PRIM_COLOR(0);
D_801F8010.color.green = R_FB_FILTER_PRIM_COLOR(1);
D_801F8010.color.blue = R_FB_FILTER_PRIM_COLOR(2);
D_801F8010.color.alpha = R_FB_FILTER_A;
D_801F8010.color.r = R_FB_FILTER_PRIM_COLOR(0);
D_801F8010.color.g = R_FB_FILTER_PRIM_COLOR(1);
D_801F8010.color.b = R_FB_FILTER_PRIM_COLOR(2);
D_801F8010.color.a = R_FB_FILTER_A;
func_80140D10(&D_801F8010, &_gfx, arg1);
} else {
if ((R_FB_FILTER_TYPE == 5) || (R_FB_FILTER_TYPE == 6)) {
D_801F8020.useRgba = (R_FB_FILTER_TYPE == 6);
D_801F8020.primColor.red = R_FB_FILTER_PRIM_COLOR(0);
D_801F8020.primColor.green = R_FB_FILTER_PRIM_COLOR(1);
D_801F8020.primColor.blue = R_FB_FILTER_PRIM_COLOR(2);
D_801F8020.primColor.alpha = R_FB_FILTER_A;
D_801F8020.envColor.red = R_FB_FILTER_ENV_COLOR(0);
D_801F8020.envColor.green = R_FB_FILTER_ENV_COLOR(1);
D_801F8020.envColor.blue = R_FB_FILTER_ENV_COLOR(2);
D_801F8020.envColor.alpha = R_FB_FILTER_A;
D_801F8020.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
D_801F8020.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
D_801F8020.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
D_801F8020.primColor.a = R_FB_FILTER_A;
D_801F8020.envColor.r = R_FB_FILTER_ENV_COLOR(0);
D_801F8020.envColor.g = R_FB_FILTER_ENV_COLOR(1);
D_801F8020.envColor.b = R_FB_FILTER_ENV_COLOR(2);
D_801F8020.envColor.a = R_FB_FILTER_A;
func_80142100(&D_801F8020, &_gfx, arg1);
} else {
if (R_FB_FILTER_TYPE == 7) {
sMonoColors.unk_00 = 0;
sMonoColors.primColor.red = R_FB_FILTER_PRIM_COLOR(0);
sMonoColors.primColor.green = R_FB_FILTER_PRIM_COLOR(1);
sMonoColors.primColor.blue = R_FB_FILTER_PRIM_COLOR(2);
sMonoColors.primColor.alpha = R_FB_FILTER_A;
sMonoColors.envColor.red = R_FB_FILTER_ENV_COLOR(0);
sMonoColors.envColor.green = R_FB_FILTER_ENV_COLOR(1);
sMonoColors.envColor.blue = R_FB_FILTER_ENV_COLOR(2);
sMonoColors.envColor.alpha = R_FB_FILTER_A;
sMonoColors.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
sMonoColors.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
sMonoColors.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
sMonoColors.primColor.a = R_FB_FILTER_A;
sMonoColors.envColor.r = R_FB_FILTER_ENV_COLOR(0);
sMonoColors.envColor.g = R_FB_FILTER_ENV_COLOR(1);
sMonoColors.envColor.b = R_FB_FILTER_ENV_COLOR(2);
sMonoColors.envColor.a = R_FB_FILTER_A;
VisMono_Draw(&sMonoColors, &_gfx, arg1);
}
}
@@ -81,11 +81,11 @@ void GameState_Draw(GameState *ctxt, GraphicsContext *gCtxt) {
if (R_FB_FILTER_TYPE && R_FB_FILTER_ENV_COLOR(3) == 0) {
GameState_SetFBFilter(&nextDisplayList, (u32) gCtxt->zbuffer);
}
if (R_ENABLE_ARENA_DBG < 0) {
R_ENABLE_ARENA_DBG = 0;
}
gSPEndDisplayList(nextDisplayList++);
Graph_BranchDlist(_polyOpa, nextDisplayList);
gCtxt->polyOpa.p = nextDisplayList;
@@ -111,12 +111,12 @@ void Game_ResetSegments(GraphicsContext *gCtxt) {
void func_801736DC(GraphicsContext *gCtxt) {
Gfx* nextDisplayList;
Gfx* _polyOpa;
nextDisplayList = Graph_GfxPlusOne(_polyOpa = gCtxt->polyOpa.p);
gSPDisplayList(gCtxt->overlay.p++, nextDisplayList);
gSPEndDisplayList(nextDisplayList++);
Graph_BranchDlist(_polyOpa, nextDisplayList);
gCtxt->polyOpa.p = nextDisplayList;
}
@@ -207,7 +207,7 @@ lblUnk:;
Gamealloc_Init(&ctxt->alloc);
Game_InitHeap(ctxt, 0x100000);
Game_SetFramerateDivisor(ctxt, 3);
gameStateInit(ctxt);
func_80140CE0(&D_801F8010);
@@ -216,7 +216,7 @@ lblUnk:;
func_80140898(&D_801F8048);
func_801773A0(&D_801F7FF0);
func_8013ED9C();
osSendMesg(&ctxt->gfxCtx->unk5C, NULL, 1);
}
+6 -6
View File
@@ -3828,9 +3828,9 @@ void CollisionCheck_SpawnShieldParticles(GlobalContext* ctxt, Vec3f* v) {
shieldParticleInitMetal.position.x = v->x;
shieldParticleInitMetal.position.y = v->y;
shieldParticleInitMetal.position.z = v->z;
shieldParticleInitMetal.lightParams.posX = shieldParticleInitMetal.position.x;
shieldParticleInitMetal.lightParams.posY = shieldParticleInitMetal.position.y;
shieldParticleInitMetal.lightParams.posZ = shieldParticleInitMetal.position.z;
shieldParticleInitMetal.lightPoint.x = shieldParticleInitMetal.position.x;
shieldParticleInitMetal.lightPoint.y = shieldParticleInitMetal.position.y;
shieldParticleInitMetal.lightPoint.z = shieldParticleInitMetal.position.z;
Effect_Add(ctxt, &effectIndex, 3, 0, 1, &shieldParticleInitMetal);
}
@@ -3883,9 +3883,9 @@ void CollisionCheck_SpawnShieldParticlesWood(GlobalContext* ctxt, Vec3f* v, Vec3
shieldParticleInitWood.position.x = v->x;
shieldParticleInitWood.position.y = v->y;
shieldParticleInitWood.position.z = v->z;
shieldParticleInitWood.lightParams.posX = shieldParticleInitWood.position.x;
shieldParticleInitWood.lightParams.posY = shieldParticleInitWood.position.y;
shieldParticleInitWood.lightParams.posZ = shieldParticleInitWood.position.z;
shieldParticleInitWood.lightPoint.x = shieldParticleInitWood.position.x;
shieldParticleInitWood.lightPoint.y = shieldParticleInitWood.position.y;
shieldParticleInitWood.lightPoint.z = shieldParticleInitWood.position.z;
Effect_Add(ctxt, &effectIndex, 3, 0, 1, &shieldParticleInitWood);
func_8019F1C0(pos, 0x1837);
+4 -4
View File
@@ -253,12 +253,12 @@ void EffectSS_DrawParticle(GlobalContext* ctxt, s32 index) {
}
void EffectSS_DrawAllParticles(GlobalContext* ctxt) {
LightMapper* s0;
Lights* s0;
s32 i;
s0 = Lights_CreateMapper(&ctxt->lightCtx, ctxt->state.gfxCtx);
Lights_MapLights(s0, ctxt->lightCtx.lightsHead, 0, ctxt);
Lights_UploadLights(s0, ctxt->state.gfxCtx);
s0 = LightContext_NewLights(&ctxt->lightCtx, ctxt->state.gfxCtx);
Lights_BindAll(s0, ctxt->lightCtx.listHead, 0, ctxt);
Lights_Draw(s0, ctxt->state.gfxCtx);
for (i = 0; i < EffectSS2Info.size; i++) {
if (EffectSS2Info.data_table[i].life > -1) {
+9 -9
View File
@@ -538,11 +538,11 @@ void Math_SmoothScaleMaxS(s16* start, s16 target, s16 scale, s16 maxStep) {
*start += v0;
}
void Color_RGBA8_Copy(ColorRGBA8* dst, ColorRGBA8* src) {
dst->red = src->red;
dst->green = src->green;
dst->blue = src->blue;
dst->alpha = src->alpha;
void Color_RGBA8_Copy(Color_RGBA8* dst, Color_RGBA8* src) {
dst->r = src->r;
dst->g = src->g;
dst->b = src->b;
dst->a = src->a;
}
void func_801000A4(u16 a0) {
@@ -569,11 +569,11 @@ void Lib_TranslateAndRotateYVec3f(Vec3f* translation, s16 rotation, Vec3f* src,
}
#ifdef NON_MATCHING
void Lib_LerpRGB(RGB* a, RGB* b, f32 t, RGB* dst) {
void Lib_LerpRGB(Color_RGB8* a, Color_RGB8* b, f32 t, Color_RGB8* dst) {
// XXX regalloc is slightly off
dst->red = (f32)a->red + ((f32)b->red - (f32)a->red) * t;
dst->green = (f32)a->green + ((f32)b->green - (f32)a->green) * t;
dst->blue = (f32)a->blue + ((f32)b->blue - (f32)a->blue) * t;
dst->r = (f32)a->r + ((f32)b->r - (f32)a->r) * t;
dst->g = (f32)a->g + ((f32)b->g - (f32)a->g) * t;
dst->b = (f32)a->b + ((f32)b->b - (f32)a->b) * t;
}
#else
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_lib/Lib_LerpRGB.asm")
+250 -252
View File
@@ -1,152 +1,143 @@
#include <ultra64.h>
#include <global.h>
void Lights_InitPositionalLight(LightInfoPositional* info, s16 posX, s16 posY, s16 posZ, u8 red, u8 green, u8 blue, s16 radius, u32 type) {
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_SetPositionalLightPosition(LightInfoPositional* info, s16 posX, s16 posY, s16 posZ) {
info->params.posX = posX;
info->params.posY = posY;
info->params.posZ = posZ;
void Lights_PointSetPosition(LightInfo* info, s16 x, s16 y, s16 z) {
info->params.point.x = x;
info->params.point.y = y;
info->params.point.z = z;
}
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->lights.a.l.colc[0] = red;
mapper->lights.a.l.col[0] = red;
mapper->lights.a.l.colc[1] = green;
mapper->lights.a.l.col[1] = green;
mapper->lights.a.l.colc[2] = blue;
mapper->lights.a.l.col[2] = blue;
mapper->numLights = 0;
void Lights_Reset(Lights* lights, u8 r, u8 g, u8 b) {
lights->l.a.l.colc[0] = r;
lights->l.a.l.col[0] = r;
lights->l.a.l.colc[1] = g;
lights->l.a.l.col[1] = g;
lights->l.a.l.colc[2] = b;
lights->l.a.l.col[2] = b;
lights->numLights = 0;
}
// XXX regalloc
#ifdef NON_MATCHING
void Lights_UploadLights(LightMapper* mapper, GraphicsContext* gCtxt) {
/*
* Draws every light in the provided Lights group
*/
void Lights_Draw(Lights* lights, GraphicsContext* gfxCtx) {
Light* l;
s32 i;
gSPNumLights(gCtxt->polyOpa.p++, mapper->numLights);
gSPNumLights(gCtxt->polyXlu.p++, mapper->numLights);
OPEN_DISPS(gfxCtx);
l = &mapper->lights.l[0];
gSPNumLights(POLY_OPA_DISP++, lights->numLights);
gSPNumLights(POLY_XLU_DISP++, lights->numLights);
for (i = 0; i < mapper->numLights;) {
gSPLight(gCtxt->polyOpa.p++, l, ++i);
gSPLight(gCtxt->polyXlu.p++, l++, i);
l = lights->l.l;
for (i = 0; i < lights->numLights;) {
gSPLight(POLY_OPA_DISP++, l, ++i);
gSPLight(POLY_XLU_DISP++, l++, i);
}
gSPLight(gCtxt->polyOpa.p++, &mapper->lights.a, ++i);
gSPLight(gCtxt->polyXlu.p++, &mapper->lights.a, i);
}
#else
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_lights/Lights_UploadLights.asm")
#endif
gSPLight(POLY_OPA_DISP++, &lights->l.a, ++i);
gSPLight(POLY_XLU_DISP++, &lights->l.a, i);
Light* Lights_MapperGetNextFreeSlot(LightMapper* mapper) {
if (6 < mapper->numLights) {
CLOSE_DISPS(gfxCtx);
}
Light* Lights_FindSlot(Lights* lights) {
if (lights->numLights >= 7) {
return NULL;
}
return &mapper->lights.l[mapper->numLights++];
return &lights->l.l[lights->numLights++];
}
// XXX regalloc, some reorderings
#ifdef NON_MATCHING
void Lights_MapPositionalWithReference(LightMapper* mapper, LightInfoPositionalParams* params, Vec3f* pos) {
void Lights_BindPointWithReference(Lights* lights, LightParams* params, Vec3f* pos) {
f32 xDiff;
f32 yDiff;
f32 zDiff;
f32 dist;
f32 radiusF;
f32 posDiff;
f32 scale;
Light* light;
if (pos == NULL) return;
if ((pos != NULL) && (params->point.radius >= 1)) {
xDiff = params->point.x - pos->x;
yDiff = params->point.y - pos->y;
zDiff = params->point.z - pos->z;
scale = params->point.radius;
posDiff = SQ(xDiff) + SQ(yDiff) + SQ(zDiff);
if (params->radius < 1) return;
if (SQ(scale) > posDiff) {
light = Lights_FindSlot(lights);
xDiff = params->posX - pos->x;
yDiff = params->posY - pos->y;
zDiff = params->posZ - pos->z;
radiusF = params->radius;
dist = xDiff * xDiff + yDiff * yDiff + zDiff * zDiff;
if (light != NULL) {
posDiff = sqrtf(posDiff);
scale = posDiff / scale;
scale = 1 - SQ(scale);
if (radiusF * radiusF > dist) {
light = Lights_MapperGetNextFreeSlot(mapper);
if (light == NULL) return;
light->l.col[0] = params->point.color[0] * scale;
light->l.colc[0] = light->l.col[0];
light->l.col[1] = params->point.color[1] * scale;
light->l.colc[1] = light->l.col[1];
light->l.col[2] = params->point.color[2] * scale;
light->l.colc[2] = light->l.col[2];
dist = sqrtf(dist);
scale = (posDiff < 1) ? 120 : 120 / posDiff;
light->l.colc[0] = light->l.col[0] = params->red * (1 - (dist / radiusF) * (dist / radiusF));
light->l.colc[1] = light->l.col[1] = params->green * (1 - (dist / radiusF) * (dist / radiusF));
light->l.colc[2] = light->l.col[2] = params->blue * (1 - (dist / radiusF) * (dist / radiusF));
if (dist < 1) {
dist = 120;
} else {
dist = 120 / dist;
light->l.dir[0] = xDiff * scale;
light->l.dir[1] = yDiff * scale;
light->l.dir[2] = zDiff * scale;
}
}
xDiff *= dist;
yDiff *= dist;
zDiff *= dist;
light->l.dir[0] = xDiff;
light->l.dir[1] = yDiff;
light->l.dir[2] = zDiff;
}
}
#else
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_lights/Lights_MapPositionalWithReference.asm")
#endif
// This function matches, but uses .rodata. We don't have a good way to match partial .rodata for a file yet.
#ifdef NON_MATCHING
void Lights_MapPositional(LightMapper* mapper, LightInfoPositionalParams* params, GlobalContext* ctxt) {
void Lights_BindPoint(Lights* lights, LightParams* params, GlobalContext* globalCtx) {
Light* light;
f32 radiusF = params->radius;
f32 radiusF = params->point.radius;
Vec3f posF;
Vec3f adjustedPos;
u32 pad;
if (radiusF > 0) {
posF.x = params->posX;
posF.y = params->posY;
posF.z = params->posZ;
Matrix_MultiplyByVectorXYZ(&ctxt->unk187B0,&posF,&adjustedPos);
posF.x = params->point.x;
posF.y = params->point.y;
posF.z = params->point.z;
Matrix_MultiplyByVectorXYZ(&globalCtx->unk187B0,&posF,&adjustedPos);
if ((adjustedPos.z > -radiusF) &&
(600 + radiusF > adjustedPos.z) &&
(400 > fabsf(adjustedPos.x) - radiusF) &&
(400 > fabsf(adjustedPos.y) - radiusF)) {
light = Lights_MapperGetNextFreeSlot(mapper);
light = Lights_FindSlot(lights);
if (light != NULL) {
radiusF = 4500000.0f / (radiusF * radiusF);
if (radiusF > 255) {
@@ -155,236 +146,250 @@ void Lights_MapPositional(LightMapper* mapper, LightInfoPositionalParams* params
radiusF = 20;
}
light->lPos.col[0] = params->red;
light->lPos.colc[0] = light->lPos.col[0];
light->lPos.col[1] = params->green;
light->lPos.colc[1] = light->lPos.col[1];
light->lPos.col[2] = params->blue;
light->lPos.colc[2] = light->lPos.col[2];
light->lPos.pos[0] = params->posX;
light->lPos.pos[1] = params->posY;
light->lPos.pos[2] = params->posZ;
light->lPos.pad1 = 0x8;
light->lPos.pad2 = 0xFF;
light->lPos.unkE = (s8)radiusF;
light->p.col[0] = params->point.color[0];
light->p.colc[0] = light->p.col[0];
light->p.col[1] = params->point.color[1];
light->p.colc[1] = light->p.col[1];
light->p.col[2] = params->point.color[2];
light->p.colc[2] = light->p.col[2];
light->p.pos[0] = params->point.x;
light->p.pos[1] = params->point.y;
light->p.pos[2] = params->point.z;
light->p.unk3 = 0x8;
light->p.unk7 = 0xFF;
light->p.unkE = (s32)radiusF;
}
}
}
}
#else
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_lights/Lights_MapPositional.asm")
#endif
void Lights_MapDirectional(LightMapper* mapper, LightInfoDirectionalParams* params, GlobalContext* ctxt) {
Light* light = Lights_MapperGetNextFreeSlot(mapper);
void Lights_BindDirectional(Lights* lights, LightParams* params, void* unused) {
Light* light = Lights_FindSlot(lights);
if (light != NULL) {
light->l.col[0] = params->red;
light->l.col[0] = params->dir.color[0];
light->l.colc[0] = light->l.col[0];
light->l.col[1] = params->green;
light->l.col[1] = params->dir.color[1];
light->l.colc[1] = light->l.col[1];
light->l.col[2] = params->blue;
light->l.col[2] = params->dir.color[2];
light->l.colc[2] = light->l.col[2];
light->l.dir[0] = params->dirX;
light->l.dir[1] = params->dirY;
light->l.dir[2] = params->dirZ;
light->l.pad1 = 0;
light->l.dir[0] = params->dir.x;
light->l.dir[1] = params->dir.y;
light->l.dir[2] = params->dir.z;
light->l.pad1 = 0; // TODO the fact that pad1 is set here means that it now does something in MM's microcode
}
}
void Lights_MapLights(LightMapper* mapper, z_Light* lights, Vec3f* refPos, GlobalContext* ctxt) {
if (lights != NULL) {
if ((refPos == NULL) && (mapper->enablePosLights == 1)) {
/**
* 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* refPos, GlobalContext* globalCtx) {
static LightsPosBindFunc posBindFuncs[] = { Lights_BindPoint, Lights_BindDirectional, Lights_BindPoint };
static LightsBindFunc dirBindFuncs[] = { Lights_BindPointWithReference, Lights_BindDirectional, Lights_BindPointWithReference };
if (listHead != NULL) {
if ((refPos == NULL) && (lights->enablePosLights == 1)) {
do {
lightPositionalMapFuncs[lights->info->type](mapper, &lights->info->params, ctxt);
lights = lights->next;
} while (lights != NULL);
posBindFuncs[listHead->info->type](lights, &listHead->info->params, globalCtx);
listHead = listHead->next;
} while (listHead != NULL);
} else {
do {
lightDirectionalMapFuncs[lights->info->type](mapper, &lights->info->params, refPos);
lights = lights->next;
} while (lights != NULL);
dirBindFuncs[listHead->info->type](lights, &listHead->info->params, refPos);
listHead = listHead->next;
} while (listHead != NULL);
}
}
}
z_Light* Lights_FindFreeSlot(void) {
z_Light* ret;
LightNode* Lights_FindBufSlot() {
LightNode* ret;
if (0x1f < lightsList.numOccupied) {
if (sLightsBuffer.numOccupied >= LIGHTS_BUFFER_SIZE) {
return NULL;
}
ret = &lightsList.lights[lightsList.nextFree];
ret = &sLightsBuffer.lights[sLightsBuffer.searchIndex];
while (ret->info != NULL) {
lightsList.nextFree++;
if (lightsList.nextFree < 0x20) {
sLightsBuffer.searchIndex++;
if (sLightsBuffer.searchIndex < LIGHTS_BUFFER_SIZE) {
ret++;
} else {
lightsList.nextFree = 0;
ret = &lightsList.lights[0];
sLightsBuffer.searchIndex = 0;
ret = &sLightsBuffer.lights[0];
}
}
lightsList.numOccupied++;
sLightsBuffer.numOccupied++;
return ret;
}
void Lights_Free(z_Light* light) {
void Lights_FreeNode(LightNode* light) {
if (light != NULL) {
lightsList.numOccupied--;
sLightsBuffer.numOccupied--;
light->info = NULL;
lightsList.nextFree = (light - lightsList.lights) / (s32)sizeof(z_Light); //! @bug Due to pointer arithmetic, the division is unnecessary
sLightsBuffer.searchIndex = (light - sLightsBuffer.lights) / (s32)sizeof(LightNode); //! @bug Due to pointer arithmetic, the division is unnecessary
}
}
void Lights_Init(GlobalContext* ctxt, LightingContext* lCtxt) {
Lights_ClearHead(ctxt, lCtxt);
Lights_SetAmbientColor(lCtxt, 80, 80, 80);
func_80102544(lCtxt, 0, 0, 0, 0x3e4, 0x3200);
bzero(&lightsList, sizeof(LightsList));
void LightContext_Init(GlobalContext* globalCtx, LightContext* lightCtx) {
LightContext_InitList(globalCtx, lightCtx);
LightContext_SetAmbientColor(lightCtx, 80, 80, 80);
func_80102544(lightCtx, 0, 0, 0, 0x3E4, 0x3200);
bzero(&sLightsBuffer, sizeof(LightsBuffer));
}
void Lights_SetAmbientColor(LightingContext* lCtxt, u8 red, u8 green, u8 blue) {
lCtxt->ambientRed = red;
lCtxt->ambientGreen = green;
lCtxt->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_80102544(LightingContext* lCtxt, u8 a1, u8 a2, u8 a3, s16 sp12, s16 sp16) {
lCtxt->unk7 = a1;
lCtxt->unk8 = a2;
lCtxt->unk9 = a3;
lCtxt->unkA = sp12;
lCtxt->unkC = sp16;
void func_80102544(LightContext* lightCtx, u8 a1, u8 a2, u8 a3, s16 numLights, s16 sp16) {
lightCtx->unk7 = a1;
lightCtx->unk8 = a2;
lightCtx->unk9 = a3;
lightCtx->unkA = numLights;
lightCtx->unkC = sp16;
}
LightMapper* Lights_CreateMapper(LightingContext* lCtxt, GraphicsContext* gCtxt) {
return Lights_MapperAllocateAndInit(gCtxt, lCtxt->ambientRed, lCtxt->ambientGreen, lCtxt->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* ctxt, LightingContext* lCtxt) {
lCtxt->lightsHead = NULL;
void LightContext_InitList(GlobalContext* globalCtx, LightContext* lightCtx) {
lightCtx->listHead = NULL;
}
void Lights_RemoveAll(GlobalContext* ctxt, LightingContext* lCtxt) {
while (lCtxt->lightsHead != NULL) {
Lights_Remove(ctxt, lCtxt, lCtxt->lightsHead);
lCtxt->lightsHead = lCtxt->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* ctxt, LightingContext* lCtxt, LightInfo* 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* light;
light = Lights_FindFreeSlot();
light = Lights_FindBufSlot();
if (light != NULL) {
light->info = info;
light->prev = NULL;
light->next = lCtxt->lightsHead;
light->next = lightCtx->listHead;
if (lCtxt->lightsHead != NULL) {
lCtxt->lightsHead->prev = light;
if (lightCtx->listHead != NULL) {
lightCtx->listHead->prev = light;
}
lCtxt->lightsHead = light;
lightCtx->listHead = light;
}
return light;
}
void Lights_Remove(GlobalContext* ctxt, LightingContext* lCtxt, z_Light* light) {
void LightContext_RemoveLight(GlobalContext* globalCtx, LightContext* lightCtx, LightNode* light) {
if (light != NULL) {
if (light->prev != NULL) {
light->prev->next = light->next;
} else {
lCtxt->lightsHead = light->next;
lightCtx->listHead = light->next;
}
if (light->next != NULL) {
light->next->prev = light->prev;
}
Lights_Free(light);
Lights_FreeNode(light);
}
}
LightMapper* func_801026E8(GraphicsContext* gCtxt, u8 ambientRed, u8 ambientGreen, u8 ambientBlue, u8 numLights, u8 red, u8 green, u8 blue, s8 dirX, s8 dirY, s8 dirZ) {
LightMapper* mapper;
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;
// TODO allocation should be a macro
mapper = (LightMapper *)((int)gCtxt->polyOpa.d - sizeof(LightMapper));
gCtxt->polyOpa.d = (void*)mapper;
lights = (Lights *)((int)gfxCtx->polyOpa.d - sizeof(Lights));
gfxCtx->polyOpa.d = (void*)lights;
mapper->lights.a.l.col[0] = mapper->lights.a.l.colc[0] = ambientRed;
mapper->lights.a.l.col[1] = mapper->lights.a.l.colc[1] = ambientGreen;
mapper->lights.a.l.col[2] = mapper->lights.a.l.colc[2] = ambientBlue;
mapper->enablePosLights = 0;
mapper->numLights = numLights;
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->enablePosLights = 0;
lights->numLights = numLights;
for (i = 0; i < numLights; i++) {
mapper->lights.l[i].l.col[0] = mapper->lights.l[i].l.colc[0] = red;
mapper->lights.l[i].l.col[1] = mapper->lights.l[i].l.colc[1] = green;
mapper->lights.l[i].l.col[2] = mapper->lights.l[i].l.colc[2] = blue;
mapper->lights.l[i].l.dir[0] = dirX;
mapper->lights.l[i].l.dir[1] = dirY;
mapper->lights.l[i].l.dir[2] = dirZ;
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;
}
Lights_UploadLights(mapper,gCtxt);
Lights_Draw(lights,gfxCtx);
return mapper;
return lights;
}
LightMapper* Lights_MapperAllocateAndInit(GraphicsContext* gCtxt, u8 red, u8 green, u8 blue) {
LightMapper* mapper;
Lights* Lights_New(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 ambientB) {
Lights* lights;
// TODO allocation should be a macro
mapper = (LightMapper *)((int)gCtxt->polyOpa.d - sizeof(LightMapper));
gCtxt->polyOpa.d = (void*)mapper;
lights = (Lights *)((int)gfxCtx->polyOpa.d - sizeof(Lights));
gfxCtx->polyOpa.d = (void*)lights;
mapper->lights.a.l.col[0] = red;
mapper->lights.a.l.colc[0] = red;
mapper->lights.a.l.col[1] = green;
mapper->lights.a.l.colc[1] = green;
mapper->lights.a.l.col[2] = blue;
mapper->lights.a.l.colc[2] = blue;
mapper->enablePosLights = 0;
mapper->numLights = 0;
lights->l.a.l.col[0] = ambientR;
lights->l.a.l.colc[0] = ambientR;
lights->l.a.l.col[1] = ambientG;
lights->l.a.l.colc[1] = ambientG;
lights->l.a.l.col[2] = ambientB;
lights->l.a.l.colc[2] = ambientB;
lights->enablePosLights = 0;
lights->numLights = 0;
return mapper;
return lights;
}
// XXX regalloc
#ifdef NON_MATCHING
void func_80102880(GlobalContext* ctxt) {
z_Light* light = ctxt->lightsContext.lightsHead;
LightInfoPositionalParams* params;
Vec3f local_14;
Vec3f local_20;
f32 local_24;
f32 fVar4;
s32 s2;
u32 pad[2];
void Lights_GlowCheck(GlobalContext* globalCtx) {
LightNode* light = globalCtx->lightCtx.listHead;
while (light != NULL) {
if (light->info->type == 2) {
params = (LightInfoPositionalParams*)&light->info->params;
local_14.x = params->posX;
local_14.y = params->posY;
local_14.z = params->posZ;
func_800B4EDC(ctxt, &local_14, &local_20, &local_24);
LightPoint* params = (LightPoint*)&light->info->params;
params->unk9 = 0;
if (light->info->type == LIGHT_POINT_GLOW) {
Vec3f pos;
Vec3f multDest;
f32 wDest;
if ((local_20.z > 1) &&
(fabsf(local_20.x * local_24) < 1) &&
(fabsf(local_20.y * local_24) < 1)) {
fVar4 = local_20.z * local_24;
s2 = (s32)(fVar4 * 16352) + 16352;
if (s2 < func_80178A94(local_20.x * local_24 * 160 + 160, local_20.y * local_24 * -120 + 120)) {
params->unk9 = 1;
pos.x = params->x;
pos.y = params->y;
pos.z = params->z;
func_800B4EDC(globalCtx, &pos, &multDest, &wDest);
params->drawGlow = 0;
if ((multDest.z > 1) && (fabsf(multDest.x * wDest) < 1) && (fabsf(multDest.y * wDest) < 1)) {
s32 wX = multDest.x * wDest * 160 + 160;
s32 wY = multDest.y * wDest * -120 + 120;
s32 wZ = (s32)((multDest.z * wDest) * 16352) + 16352;
s32 zBuf = func_80178A94(wX, wY);
if (wZ < zBuf) {
params->drawGlow = 1;
}
}
}
@@ -392,22 +397,16 @@ void func_80102880(GlobalContext* ctxt) {
light = light->next;
}
}
#else
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_lights/func_80102880.asm")
#endif
// XXX regalloc
#ifdef NON_MATCHING
void func_80102A64(GlobalContext* ctxt) {
void Lights_DrawGlow(GlobalContext* globalCtx) {
Gfx* dl;
LightInfoPositionalParams* params;
f32 scale;
GraphicsContext* gCtxt;
z_Light* light = ctxt->lightsContext.lightsHead;
LightPoint* params;
LightNode* light = globalCtx->lightCtx.listHead;
if (light != NULL) {
gCtxt = ctxt->common.gCtxt;
dl = func_8012C7FC(gCtxt->polyXlu.p);
OPEN_DISPS(globalCtx->state.gfxCtx);
dl = func_8012C7FC(POLY_XLU_DISP);
gSPSetOtherMode(dl++, G_SETOTHERMODE_H, 4, 4, 0x00000080); //! This doesn't resolve to any of the macros in gdi.h
@@ -417,17 +416,17 @@ void func_80102A64(GlobalContext* ctxt) {
gSPDisplayList(dl++, &D_04029CB0);
do {
if (light->info->type == 2) {
params = (LightInfoPositionalParams*)&light->info->params;
if (params->unk9 != 0) {
scale = (f32)params->radius * (f32)params->radius * 2e-6f;
if (light->info->type == LIGHT_POINT_GLOW) {
params = (LightPoint*)&light->info->params;
if (params->drawGlow) {
f32 scale = SQ((f32)params->radius) * 2e-6f;
gDPSetPrimColor(dl++, 0, 0, params->red, params->green, params->blue, 50);
gDPSetPrimColor(dl++, 0, 0, params->color[0], params->color[1], params->color[2], 50);
SysMatrix_InsertTranslation(params->posX, params->posY, params->posZ, 0);
SysMatrix_InsertTranslation(params->x, params->y, params->z, 0);
SysMatrix_InsertScale(scale,scale,scale,1);
gSPMatrix(dl++, SysMatrix_AppendStateToPolyOpaDisp((ctxt->common).gCtxt), G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPMatrix(dl++, SysMatrix_AppendStateToPolyOpaDisp(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(dl++, &D_04029CF0);
}
@@ -436,9 +435,8 @@ void func_80102A64(GlobalContext* ctxt) {
light = light->next;
} while (light != NULL);
gCtxt->polyXlu.p = dl;
POLY_XLU_DISP = dl;
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
}
#else
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_lights/func_80102A64.asm")
#endif
+1 -1
View File
@@ -310,7 +310,7 @@ void Scene_HeaderCommand0C(GlobalContext* ctxt, SceneCmd* entry) {
lightInfo = (LightInfo*)Lib_PtrSegToVirt(entry->lightList.segment);
for (i = 0; i < entry->lightList.num; i++)
{
Lights_Insert(ctxt, &ctxt->lightCtx, lightInfo);
LightContext_InsertLight(ctxt, &ctxt->lightCtx, lightInfo);
lightInfo++;
}
}
+8 -8
View File
@@ -66,7 +66,7 @@ void SceneProc_DrawType1Texture(GlobalContext* ctxt, u32 segment, ScrollingTextu
#ifdef NON_MATCHING
// Slight ordering differences at the beginning
void SceneProc_DrawFlashingTexture(GlobalContext* ctxt, u32 segment, FlashingTexturePrimColor* primColor, RGBA8* envColor) {
void SceneProc_DrawFlashingTexture(GlobalContext* ctxt, u32 segment, FlashingTexturePrimColor* primColor, Color_RGBA8* envColor) {
GraphicsContext* gfxCtx;
Gfx* dl;
@@ -108,7 +108,7 @@ void SceneProc_DrawFlashingTexture(GlobalContext* ctxt, u32 segment, FlashingTex
#endif
void SceneProc_DrawType2Texture(GlobalContext* ctxt, u32 segment, FlashingTextureParams* params) {
RGBA8* envColor;
Color_RGBA8* envColor;
FlashingTexturePrimColor* primColor = (FlashingTexturePrimColor *)Lib_PtrSegToVirt(params->primColors);
u32 pad;
u32 index = gSceneProcStep % params->cycleLength;
@@ -116,7 +116,7 @@ void SceneProc_DrawType2Texture(GlobalContext* ctxt, u32 segment, FlashingTextur
primColor += index;
if (params->envColors) {
envColor = (RGBA8*)Lib_PtrSegToVirt(params->envColors) + index;
envColor = (Color_RGBA8*)Lib_PtrSegToVirt(params->envColors) + index;
} else {
envColor = NULL;
}
@@ -132,18 +132,18 @@ s32 SceneProc_Lerp(s32 a, s32 b, f32 t) {
// Slight ordering and regalloc differences around t = ...
void SceneProc_DrawType3Texture(GlobalContext* ctxt, u32 segment, FlashingTextureParams* params) {
FlashingTextureParams* params2 = params;
RGBA8* envColorTo;
Color_RGBA8* envColorTo;
FlashingTexturePrimColor* primColorTo = (FlashingTexturePrimColor *)Lib_PtrSegToVirt(params2->primColors);
u16* keyFrames = (u16*)Lib_PtrSegToVirt(params2->keyFrames);
s32 index = gSceneProcStep % params2->cycleLength;
s32 pad1;
s32 keyFrameIndex;
RGBA8* envColorPtrIn;
Color_RGBA8* envColorPtrIn;
f32 t;
s32 pad2;
FlashingTexturePrimColor primColorIn;
RGBA8* envColorFrom;
RGBA8 envColorIn;
Color_RGBA8* envColorFrom;
Color_RGBA8 envColorIn;
s32 pad3;
FlashingTexturePrimColor* primColorFrom;
@@ -169,7 +169,7 @@ void SceneProc_DrawType3Texture(GlobalContext* ctxt, u32 segment, FlashingTextur
primColorIn.lodFrac = SceneProc_Lerp(primColorFrom->lodFrac, primColorTo->lodFrac, t);
if (params2->envColors) {
envColorTo = (RGBA8*)Lib_PtrSegToVirt(params2->envColors) + keyFrameIndex;
envColorTo = (Color_RGBA8*)Lib_PtrSegToVirt(params2->envColors) + keyFrameIndex;
envColorFrom = envColorTo - 1;
envColorIn.red = SceneProc_Lerp(envColorFrom->red, envColorTo->red, t);
envColorIn.green = SceneProc_Lerp(envColorFrom->green, envColorTo->green, t);