#include "z64eff_footmark.h" #include "z64.h" #include "macros.h" #include "assets/code/eff_footmark/eff_footmark.c" void EffFootmark_Init(PlayState* play) { EffFootmark* footmark; s32 i; for (footmark = play->footprintInfo, i = 0; i < ARRAY_COUNT(play->footprintInfo); i++, footmark++) { footmark->actor = NULL; footmark->pos.x = 0; footmark->pos.y = 0; footmark->pos.z = 0; footmark->flags = 0; footmark->id = 0; footmark->alpha = 0; footmark->alphaChange = 0; } } void EffFootmark_Add(PlayState* play, MtxF* mf, Actor* actor, u8 id, Vec3f* pos, u16 size, u8 red, u8 green, u8 blue, u16 alpha, u16 alphaChange, u16 fadeOutDelay) { s32 i; EffFootmark* footmark; EffFootmark* destination = NULL; EffFootmark* oldest = NULL; s32 isNew = true; for (footmark = play->footprintInfo, i = 0; i < ARRAY_COUNT(play->footprintInfo); i++, footmark++) { if (((actor == footmark->actor) && (footmark->id == id)) && !(footmark->flags & FOOTMARK_FLAG_1)) { if (fabsf(footmark->pos.x - pos->x) <= 1) { if (fabsf(footmark->pos.z - pos->z) <= 1) { isNew = false; break; } } // This footmark is being re-added at a new pos. Let's mark this one to start fading out. footmark->flags = FOOTMARK_FLAG_1; } if (footmark->actor == NULL) { destination = footmark; } else if (destination == NULL) { if (((oldest != NULL) && (footmark->age > oldest->age)) || (oldest == NULL)) { oldest = footmark; } } } if (isNew && ((destination != NULL) || (oldest != NULL))) { if (destination == NULL) { destination = oldest; } Matrix_MtxFCopy(&destination->mf, mf); destination->actor = actor; destination->pos.x = pos->x; destination->pos.y = pos->y; destination->pos.z = pos->z; destination->flags = 0; destination->id = id; destination->red = red; destination->green = green; destination->blue = blue; destination->alpha = alpha; destination->alphaChange = alphaChange; destination->size = size; destination->fadeOutDelay = fadeOutDelay; destination->age = 0; } } void EffFootmark_Update(PlayState* play) { EffFootmark* footmark; s32 i; for (footmark = play->footprintInfo, i = 0; i < ARRAY_COUNT(play->footprintInfo); i++, footmark++) { if (footmark->actor == NULL) { continue; } if (CHECK_FLAG_ALL(footmark->flags, FOOTMARK_FLAG_1)) { if ((u32)footmark->age < UINT16_MAX) { footmark->age++; } if (footmark->fadeOutDelay == 0) { if (footmark->alpha >= footmark->alphaChange + 0x1000) { footmark->alpha -= footmark->alphaChange; } else { footmark->actor = NULL; } } else if (footmark->fadeOutDelay > 0) { footmark->fadeOutDelay--; } } } } void EffFootmark_Draw(PlayState* play) { EffFootmark* footmark; s32 i; GraphicsContext* gfxCtx = play->state.gfxCtx; Gfx_SetupDL44_Xlu(play->state.gfxCtx); gSPDisplayList(gfxCtx->polyXlu.p++, gEffFootprintMaterialDL); for (footmark = play->footprintInfo, i = 0; i < ARRAY_COUNT(play->footprintInfo); i++, footmark++) { if (footmark->actor != NULL) { Matrix_Put(&footmark->mf); Matrix_Scale(footmark->size * (1.0f / 0x100) * 0.7f, 1, footmark->size * (1.0f / 0x100), MTXMODE_APPLY); gSPMatrix(gfxCtx->polyXlu.p++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD); gDPSetPrimColor(gfxCtx->polyXlu.p++, 0, 0, footmark->red, footmark->green, footmark->blue, footmark->alpha >> 8); gSPDisplayList(gfxCtx->polyXlu.p++, gEffFootprintModelDL); } } }