mirror of
https://github.com/zeldaret/mm.git
synced 2026-05-24 07:10:44 -04:00
6069a1585f
* Match Player_GetHeight * Another bunch * Fix merge conflict * rename Gfx_DrawDListXlu * add WEEROR * Actor_Spawn * almost Actor_SpawnTransitionActors and Actor_Delete * A bunch of small actors * More renames * format * Some Player renames * a few more * import data * run formatter * func_800B7170 * whoops * Fix merge issues * Whoops 2 * func_800B83BC and func_800B83F8 * Actor_IsActorFacingPlayerAndWithinRange * add some prototypes * match Actor_UpdateBgCheckInfo * func_800B7678 * mark Actor_SpawnAsChildAndCutscene as non_matching * Actor_Draw * Update is chaotic * 2 new matches * func_800BC8B8 * Another bunch * function renames * run formatter * cleanup * remove unnecesary casts * add missing sfx * Fix renames * fix merge * func_800BF7CC * small bunch * another bunch * func_800BE184 non_matching * two more * split z_cheap_proc * Another bunch * another bunch * a few and a non matching * yeee * a * Actor_DrawAll non_equivalent * Actor_RecordUndrawnActor * i don't know what to put in this commit message * func_800B4B50 non matching * func_800B42F8 non matching * func_800B5040 * func_800B5814 non_equiv * func_800B6584 * func_800B6608 * func_800B6680 * func_800B7E04 * func_800B8118 * func_800b9170 * , * func_800BC4EC * func_800BA6FC * func_800BA798 * func_800BA8B8 * Actor_LoadOverlay * small cleanup * func_800BB2D0 * meh * func_800BBAC0 * func_800BC270 * func_800B5208 non matching * Fix warnings * meh * rename some ActorShadow_ functions * fairy * Flags_ * fix warnings * format * Actor_PickUp and family * func_800B8E58 * match Actor_RemoveFromCategory * another bit of docs * Match func_800B86C8 * And another bit * rename Player_GetRunSpeedLimit * func_800B9E84 * func_800BE63C * func_800BB8EC * match func_800B5814 * match func_800B9334 * cleanup * fix conflicts: first pass * another fix * actorfixer fix * fix conflicts * func_800BE680 non_equivalent * Improve func_800BE680 a bit * func_800BE680 equivalent (?) * func_800BE680 equivalent * Actor_UpdateActor equivalent * format * use some ExchangeItemID enum values * Some more cleaning * more cleanup * More name stealing from OoT * match func_800B82EC * match func_800B9D1C and a bit of cleanup * Add ACTOR_FLAGS placeholders * Renames and match func_800BE184 * last pass of name stealing * format * fix conflicts * more cleanup * more cleanup * cleanup and OVERLAY_RELOCATION_OFFSET macro * Remove prototypes of obviously internal-only functions, update variable names, forward declare where necessary, remove all `param_\d`s * remove newlines * minor rename * Use ACTOR_FLAGS in z_actor * Match func_800BE3D0 * Rename movement functions * Document Actor_CalcOffsetOrientedToDrawRotation * velX -> horizontalSpeed * A bit of documentation for actor movement functions * format * Fix merge issues * format * Format * Fix renames * fix warnings * fix conflicts * review :D * Update src/overlays/actors/ovl_En_Ma4/z_en_ma4.c Co-authored-by: Derek Hensley <hensley.derek58@gmail.com> * Fix * format * Actor_SpawnSetupActors * engineer review * Update src/code/z_actor.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * A bunch of Engineer's reviews * more Engineer's review * a * whoops * run actorfixer * c'mon * 😮💨 * whoops * warning * More engineer's review * run format * I'm dumb * a * match func_800BE680 * Match Actor_DrawZTarget * Match Actor_SpawnAsChildAndCutscene, fix non-equivalent in Actor_UpdateActor * Fix merge issue * format * update actor * Steal a bit of @Thar0 documentation from OoT's z_message * Run actorfixer * Fix renames * Match func_800B4B50 thanks to @hensldm * Improve ActorShadow_DrawFeet thanks to @hensldm * whoops * Actor_PlaySfxAtProjectedPos * Actor_UpdateActor matched by @hensldm * Match func_800BA2FC by @hensldm * Match Actor_SpawnTransitionActors by @hensldm * Match func_800BB604 by @hensldm * Match Actor_DrawAll by @hensldm * ActorShadow_DrawFeet by @hensldm * Actor_UpdateAll by @hensldm * Match func_800BCCDC by @engineer124 * Small Actor_PlaySfxAtPos by @engineer124 * ACTOR_FLAGS_ALL and a bit of cleanup * Add invisible comment * Small docs pass * Fix merge * Engineer's review * format lol * Actor_DrawDoorLock docs * Actor_SpawnShieldParticlesMetal * fix merge issues * sActorFaultClient * fix * commit message * Run actorfixer.py && format.sh * Fix warnings * fixes * format * bss * Update include/functions.h Co-authored-by: Derek Hensley <hensley.derek58@gmail.com> * Address review * Fix merge issues, format and such * fix merge issues * Add ACTORCAT_MAX * actorList -> actorLists * Fix merge issues * format * Enable WERROR on jenkinsfile * Fix merge * Use object symbols * address review * format * review * fix merge issues * fix * VRAM_PTR_SIZE, small cleanup and format * review Co-authored-by: Elliptic Ellipsis <elliptic.ellipsis@gmail.com> Co-authored-by: Derek Hensley <hensley.derek58@gmail.com> Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> Co-authored-by: engineer124 <engineer124engineer124@gmail.com>
437 lines
18 KiB
C
437 lines
18 KiB
C
#include "global.h"
|
|
|
|
static s16 sHeartsPrimColors[3][3] = { { 255, 70, 50 }, { 255, 190, 0 }, { 100, 100, 255 } };
|
|
static s16 sHeartsEnvColors[3][3] = { { 50, 40, 60 }, { 255, 0, 0 }, { 0, 0, 255 } };
|
|
static s16 sHeartsPrimFactors[3][3] = { { 0, 0, 0 }, { 0, 120, -50 }, { -155, 30, 205 } };
|
|
static s16 sHeartsEnvFactors[3][3] = { { 0, 0, 0 }, { 205, -40, -60 }, { -50, -40, 195 } };
|
|
static s16 sHeartsDDPrimColors[3][3] = { { 255, 255, 255 }, { 255, 190, 0 }, { 100, 100, 255 } };
|
|
static s16 sHeartsDDEnvColors[3][3] = { { 200, 0, 0 }, { 255, 0, 0 }, { 0, 0, 255 } };
|
|
static s16 sHeartsDDPrimFactors[3][3] = { { 0, 0, 0 }, { 0, -65, -255 }, { -155, -155, 0 } };
|
|
static s16 sHeartsDDEnvFactors[3][3] = { { 0, 0, 0 }, { 55, 0, 0 }, { -200, 0, 255 } };
|
|
|
|
s16 sBeatingHeartsDDPrim[3];
|
|
s16 sBeatingHeartsDDEnv[3];
|
|
s16 sHeartsDDPrim[2][3];
|
|
s16 sHeartsDDEnv[2][3];
|
|
|
|
extern TexturePtr D_02000000; // Empty heart texture
|
|
extern TexturePtr D_02000100; // Quarter Heart Texture
|
|
extern TexturePtr D_02000200; // Half Heart Texture
|
|
extern TexturePtr D_02000300; // Three Quarter Heart Texture
|
|
extern TexturePtr D_02000400; // Full heart texture
|
|
extern TexturePtr D_02000500; // Empty Double Defense Heart texture
|
|
extern TexturePtr D_02000600; // Quarter Double Defense Heart Texture
|
|
extern TexturePtr D_02000700; // Half Double Defense Heart Texture
|
|
extern TexturePtr D_02000800; // Three Quarter Double Defense Heart Texture
|
|
extern TexturePtr D_02000900; // Full Double Defense Heart texture
|
|
|
|
TexturePtr HeartTextures[] = { &D_02000400, &D_02000100, &D_02000100, &D_02000100, &D_02000100, &D_02000100,
|
|
&D_02000200, &D_02000200, &D_02000200, &D_02000200, &D_02000200, &D_02000300,
|
|
&D_02000300, &D_02000300, &D_02000300, &D_02000300 };
|
|
|
|
TexturePtr HeartDDTextures[] = { &D_02000900, &D_02000600, &D_02000600, &D_02000600, &D_02000600, &D_02000600,
|
|
&D_02000700, &D_02000700, &D_02000700, &D_02000700, &D_02000700, &D_02000800,
|
|
&D_02000800, &D_02000800, &D_02000800, &D_02000800 };
|
|
|
|
void LifeMeter_Init(GlobalContext* globalCtx) {
|
|
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
|
|
|
|
interfaceCtx->unkTimer = 320;
|
|
|
|
interfaceCtx->health = gSaveContext.health;
|
|
|
|
interfaceCtx->lifeColorChange = 0;
|
|
interfaceCtx->lifeColorChangeDirection = 0;
|
|
|
|
interfaceCtx->lifeSizeChange = interfaceCtx->lifeColorChange;
|
|
interfaceCtx->lifeSizeChangeDirection = interfaceCtx->lifeColorChangeDirection;
|
|
|
|
interfaceCtx->heartsPrimR[0] = 255;
|
|
interfaceCtx->heartsPrimG[0] = 70;
|
|
interfaceCtx->heartsPrimB[0] = 50;
|
|
|
|
interfaceCtx->heartsEnvR[0] = 50;
|
|
interfaceCtx->heartsEnvG[0] = 40;
|
|
interfaceCtx->heartsEnvB[0] = 60;
|
|
|
|
interfaceCtx->heartsPrimR[1] = 255;
|
|
interfaceCtx->heartsPrimG[1] = 70;
|
|
interfaceCtx->heartsPrimB[1] = 50;
|
|
|
|
interfaceCtx->heartsEnvR[1] = 50;
|
|
interfaceCtx->heartsEnvG[1] = 40;
|
|
interfaceCtx->heartsEnvB[1] = 60;
|
|
|
|
sHeartsDDPrim[0][0] = sHeartsDDPrim[1][0] = 255;
|
|
sHeartsDDPrim[0][1] = sHeartsDDPrim[1][1] = 255;
|
|
sHeartsDDPrim[0][2] = sHeartsDDPrim[1][2] = 255;
|
|
|
|
sHeartsDDEnv[0][0] = sHeartsDDEnv[1][0] = 200;
|
|
sHeartsDDEnv[0][1] = sHeartsDDEnv[1][1] = 0;
|
|
sHeartsDDEnv[0][2] = sHeartsDDEnv[1][2] = 0;
|
|
}
|
|
|
|
void LifeMeter_UpdateColors(GlobalContext* globalCtx) {
|
|
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
|
|
f32 factorBeating = interfaceCtx->lifeColorChange * 0.1f;
|
|
f32 ddFactor;
|
|
s32 type = 0;
|
|
s32 ddType;
|
|
s16 rFactor;
|
|
s16 gFactor;
|
|
s16 bFactor;
|
|
|
|
if (interfaceCtx) {}
|
|
|
|
if (interfaceCtx->lifeColorChangeDirection != 0) {
|
|
interfaceCtx->lifeColorChange--;
|
|
if (interfaceCtx->lifeColorChange <= 0) {
|
|
interfaceCtx->lifeColorChange = 0;
|
|
interfaceCtx->lifeColorChangeDirection = 0;
|
|
}
|
|
} else {
|
|
interfaceCtx->lifeColorChange++;
|
|
if (interfaceCtx->lifeColorChange >= 10) {
|
|
interfaceCtx->lifeColorChange = 10;
|
|
interfaceCtx->lifeColorChangeDirection = 1;
|
|
}
|
|
}
|
|
|
|
ddFactor = factorBeating;
|
|
|
|
interfaceCtx->heartsPrimR[0] = 255;
|
|
interfaceCtx->heartsPrimG[0] = 70;
|
|
interfaceCtx->heartsPrimB[0] = 50;
|
|
|
|
interfaceCtx->heartsEnvR[0] = 50;
|
|
interfaceCtx->heartsEnvG[0] = 40;
|
|
interfaceCtx->heartsEnvB[0] = 60;
|
|
|
|
interfaceCtx->heartsPrimR[1] = sHeartsPrimColors[type][0];
|
|
interfaceCtx->heartsPrimG[1] = sHeartsPrimColors[type][1];
|
|
interfaceCtx->heartsPrimB[1] = sHeartsPrimColors[type][2];
|
|
|
|
interfaceCtx->heartsEnvR[1] = sHeartsEnvColors[type][0];
|
|
interfaceCtx->heartsEnvG[1] = sHeartsEnvColors[type][1];
|
|
interfaceCtx->heartsEnvB[1] = sHeartsEnvColors[type][2];
|
|
|
|
rFactor = sHeartsPrimFactors[0][0] * factorBeating;
|
|
gFactor = sHeartsPrimFactors[0][1] * factorBeating;
|
|
bFactor = sHeartsPrimFactors[0][2] * factorBeating;
|
|
|
|
interfaceCtx->beatingHeartPrim[0] = (u8)(rFactor + 255) & 0xFF;
|
|
interfaceCtx->beatingHeartPrim[1] = (u8)(gFactor + 70) & 0xFF;
|
|
interfaceCtx->beatingHeartPrim[2] = (u8)(bFactor + 50) & 0xFF;
|
|
|
|
rFactor = sHeartsEnvFactors[0][0] * factorBeating;
|
|
gFactor = sHeartsEnvFactors[0][1] * factorBeating;
|
|
bFactor = sHeartsEnvFactors[0][2] * factorBeating;
|
|
|
|
if (1) {}
|
|
ddType = type;
|
|
|
|
interfaceCtx->beatingHeartEnv[0] = (u8)(rFactor + 50) & 0xFF;
|
|
interfaceCtx->beatingHeartEnv[1] = (u8)(gFactor + 40) & 0xFF;
|
|
interfaceCtx->beatingHeartEnv[2] = (u8)(bFactor + 60) & 0xFF;
|
|
|
|
sHeartsDDPrim[0][0] = 255;
|
|
sHeartsDDPrim[0][1] = 255;
|
|
sHeartsDDPrim[0][2] = 255;
|
|
|
|
sHeartsDDEnv[0][0] = 200;
|
|
sHeartsDDEnv[0][1] = 0;
|
|
sHeartsDDEnv[0][2] = 0;
|
|
|
|
sHeartsDDPrim[1][0] = sHeartsDDPrimColors[ddType][0];
|
|
sHeartsDDPrim[1][1] = sHeartsDDPrimColors[ddType][1];
|
|
sHeartsDDPrim[1][2] = sHeartsDDPrimColors[ddType][2];
|
|
|
|
sHeartsDDEnv[1][0] = sHeartsDDEnvColors[ddType][0];
|
|
sHeartsDDEnv[1][1] = sHeartsDDEnvColors[ddType][1];
|
|
sHeartsDDEnv[1][2] = sHeartsDDEnvColors[ddType][2];
|
|
|
|
rFactor = sHeartsDDPrimFactors[ddType][0] * ddFactor;
|
|
gFactor = sHeartsDDPrimFactors[ddType][1] * ddFactor;
|
|
bFactor = sHeartsDDPrimFactors[ddType][2] * ddFactor;
|
|
|
|
sBeatingHeartsDDPrim[0] = (u8)(rFactor + 255) & 0xFF;
|
|
sBeatingHeartsDDPrim[1] = (u8)(gFactor + 255) & 0xFF;
|
|
sBeatingHeartsDDPrim[2] = (u8)(bFactor + 255) & 0xFF;
|
|
|
|
rFactor = sHeartsDDEnvFactors[ddType][0] * ddFactor;
|
|
gFactor = sHeartsDDEnvFactors[ddType][1] * ddFactor;
|
|
bFactor = sHeartsDDEnvFactors[ddType][2] * ddFactor;
|
|
|
|
sBeatingHeartsDDEnv[0] = (u8)(rFactor + 200) & 0xFF;
|
|
sBeatingHeartsDDEnv[1] = (u8)(gFactor + 0) & 0xFF;
|
|
sBeatingHeartsDDEnv[2] = (u8)(bFactor + 0) & 0xFF;
|
|
}
|
|
|
|
s32 LifeMeter_SaveInterfaceHealth(GlobalContext* globalCtx) {
|
|
gSaveContext.health = globalCtx->interfaceCtx.health;
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 LifeMeter_IncreaseInterfaceHealth(GlobalContext* globalCtx) {
|
|
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
|
|
|
|
interfaceCtx->unkTimer = 320;
|
|
interfaceCtx->health += 0x10;
|
|
if (globalCtx->interfaceCtx.health >= gSaveContext.health) {
|
|
globalCtx->interfaceCtx.health = gSaveContext.health;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
s32 LifeMeter_DecreaseInterfaceHealth(GlobalContext* globalCtx) {
|
|
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
|
|
|
|
if (interfaceCtx->unkTimer != 0) {
|
|
interfaceCtx->unkTimer--;
|
|
} else {
|
|
interfaceCtx->unkTimer = 320;
|
|
interfaceCtx->health -= 0x10;
|
|
if (interfaceCtx->health <= 0) {
|
|
interfaceCtx->health = 0;
|
|
globalCtx->damagePlayer(globalCtx, -(((void)0, gSaveContext.health) + 1));
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void LifeMeter_Draw(GlobalContext* globalCtx) {
|
|
s32 pad[5];
|
|
TexturePtr heartTex;
|
|
s32 curColorSet;
|
|
f32 offsetX;
|
|
f32 offsetY;
|
|
s32 i;
|
|
f32 posY;
|
|
f32 posX;
|
|
f32 halfTexSize;
|
|
f32 temp_f4;
|
|
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
|
|
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
|
|
Vtx* beatingHeartVtx = interfaceCtx->beatingHeartVtx;
|
|
s32 fractionHeartCount = gSaveContext.health % 0x10;
|
|
s16 healthCapacity = gSaveContext.healthCapacity / 0x10;
|
|
s16 fullHeartCount = gSaveContext.health / 0x10;
|
|
s32 pad2;
|
|
f32 lifesize = interfaceCtx->lifeSizeChange * 0.1f;
|
|
u32 curCombineModeSet = 0;
|
|
TexturePtr temp = NULL;
|
|
s32 ddCount = gSaveContext.inventory.dungeonKeys[9] - 1;
|
|
|
|
OPEN_DISPS(gfxCtx);
|
|
|
|
if ((gSaveContext.health % 0x10) == 0) {
|
|
fullHeartCount--;
|
|
}
|
|
offsetY = 0.0f;
|
|
offsetX = 0.0f;
|
|
curColorSet = -1;
|
|
|
|
for (i = 0; i < healthCapacity; i++) {
|
|
if ((ddCount < 0) || (ddCount < i)) {
|
|
if (i < fullHeartCount) {
|
|
if (curColorSet != 0) {
|
|
curColorSet = 0;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, interfaceCtx->heartsPrimR[0], interfaceCtx->heartsPrimG[0],
|
|
interfaceCtx->heartsPrimB[0], interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, interfaceCtx->heartsEnvR[0], interfaceCtx->heartsEnvG[0],
|
|
interfaceCtx->heartsEnvB[0], 255);
|
|
}
|
|
} else if (i == fullHeartCount) {
|
|
if (curColorSet != 1) {
|
|
curColorSet = 1;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, interfaceCtx->beatingHeartPrim[0],
|
|
interfaceCtx->beatingHeartPrim[1], interfaceCtx->beatingHeartPrim[2],
|
|
interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, interfaceCtx->beatingHeartEnv[0], interfaceCtx->beatingHeartEnv[1],
|
|
interfaceCtx->beatingHeartEnv[2], 255);
|
|
}
|
|
} else if (fullHeartCount < i) {
|
|
if (curColorSet != 2) {
|
|
curColorSet = 2;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, interfaceCtx->heartsPrimR[0], interfaceCtx->heartsPrimG[0],
|
|
interfaceCtx->heartsPrimB[0], interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, interfaceCtx->heartsEnvR[0], interfaceCtx->heartsEnvG[0],
|
|
interfaceCtx->heartsEnvB[0], 255);
|
|
}
|
|
} else {
|
|
if (curColorSet != 3) {
|
|
curColorSet = 3;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, interfaceCtx->heartsPrimR[1], interfaceCtx->heartsPrimG[1],
|
|
interfaceCtx->heartsPrimB[1], interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, interfaceCtx->heartsEnvR[1], interfaceCtx->heartsEnvG[1],
|
|
interfaceCtx->heartsEnvB[1], 255);
|
|
}
|
|
}
|
|
|
|
if (i < fullHeartCount) {
|
|
heartTex = &D_02000400;
|
|
} else if (i == fullHeartCount) {
|
|
heartTex = HeartTextures[fractionHeartCount];
|
|
} else {
|
|
heartTex = &D_02000000;
|
|
}
|
|
} else {
|
|
if (i < fullHeartCount) {
|
|
if (curColorSet != 4) {
|
|
curColorSet = 4;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sHeartsDDPrim[0][0], sHeartsDDPrim[0][1], sHeartsDDPrim[0][2],
|
|
interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, sHeartsDDEnv[0][0], sHeartsDDEnv[0][1], sHeartsDDEnv[0][2], 255);
|
|
}
|
|
} else if (i == fullHeartCount) {
|
|
if (curColorSet != 5) {
|
|
curColorSet = 5;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sBeatingHeartsDDPrim[0], sBeatingHeartsDDPrim[1],
|
|
sBeatingHeartsDDPrim[2], interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, sBeatingHeartsDDEnv[0], sBeatingHeartsDDEnv[1],
|
|
sBeatingHeartsDDEnv[2], 255);
|
|
}
|
|
} else if (i > fullHeartCount) {
|
|
if (curColorSet != 6) {
|
|
curColorSet = 6;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sHeartsDDPrim[0][0], sHeartsDDPrim[0][1], sHeartsDDPrim[0][2],
|
|
interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, sHeartsDDEnv[0][0], sHeartsDDEnv[0][1], sHeartsDDEnv[0][2], 255);
|
|
}
|
|
} else if (curColorSet != 7) {
|
|
curColorSet = 7;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sHeartsDDPrim[1][0], sHeartsDDPrim[1][1], sHeartsDDPrim[1][2],
|
|
interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, sHeartsDDEnv[1][0], sHeartsDDEnv[1][1], sHeartsDDEnv[1][2], 255);
|
|
}
|
|
if (i < fullHeartCount) {
|
|
heartTex = &D_02000900;
|
|
} else if (i == fullHeartCount) {
|
|
heartTex = HeartDDTextures[fractionHeartCount];
|
|
} else {
|
|
heartTex = &D_02000500;
|
|
}
|
|
}
|
|
|
|
if (temp != heartTex) {
|
|
temp = heartTex;
|
|
gDPLoadTextureBlock(OVERLAY_DISP++, heartTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
|
G_TX_NOLOD, G_TX_NOLOD);
|
|
}
|
|
|
|
if (i != fullHeartCount) {
|
|
if ((ddCount < 0) || (i > ddCount)) {
|
|
if (curCombineModeSet != 1) {
|
|
curCombineModeSet = 1;
|
|
func_8012C654(gfxCtx);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE,
|
|
0, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
|
|
}
|
|
} else if (curCombineModeSet != 3) {
|
|
curCombineModeSet = 3;
|
|
func_8012C654(gfxCtx);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0,
|
|
ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0);
|
|
}
|
|
posY = 26.0f + offsetY;
|
|
posX = 30.0f + offsetX;
|
|
temp_f4 = 1.0f;
|
|
temp_f4 /= 0.68f;
|
|
temp_f4 *= 1 << 10;
|
|
halfTexSize = 8.0f;
|
|
halfTexSize *= 0.68f;
|
|
gSPTextureRectangle(OVERLAY_DISP++, (s32)((posX - halfTexSize) * 4), (s32)((posY - halfTexSize) * 4),
|
|
(s32)((posX + halfTexSize) * 4), (s32)((posY + halfTexSize) * 4), G_TX_RENDERTILE, 0, 0,
|
|
(s32)temp_f4, (s32)temp_f4);
|
|
} else {
|
|
Mtx* mtx;
|
|
|
|
if ((ddCount < 0) || (ddCount < i)) {
|
|
if (curCombineModeSet != 2) {
|
|
curCombineModeSet = 2;
|
|
func_8012C8D4(gfxCtx);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE,
|
|
0, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
|
|
gDPSetAlphaCompare(OVERLAY_DISP++, G_AC_THRESHOLD);
|
|
}
|
|
} else {
|
|
if (curCombineModeSet != 4) {
|
|
curCombineModeSet = 4;
|
|
func_8012C8D4(gfxCtx);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, PRIMITIVE,
|
|
0, ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0);
|
|
gDPSetAlphaCompare(OVERLAY_DISP++, G_AC_THRESHOLD);
|
|
}
|
|
}
|
|
mtx = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
|
func_801780F0(mtx, 1.0f - (0.32f * lifesize), 1.0f - (0.32f * lifesize), 1.0f - (0.32f * lifesize),
|
|
-130.0f + offsetX, 94.5f - offsetY, 0.0f);
|
|
gSPMatrix(OVERLAY_DISP++, mtx, G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPVertex(OVERLAY_DISP++, beatingHeartVtx, 4, 0);
|
|
gSP1Quadrangle(OVERLAY_DISP++, 0, 2, 3, 1, 0);
|
|
}
|
|
offsetX += 10.0f;
|
|
if (i == 9) {
|
|
offsetY += 10.0f;
|
|
offsetX = 0.0f;
|
|
}
|
|
}
|
|
CLOSE_DISPS(gfxCtx);
|
|
}
|
|
|
|
void LifeMeter_UpdateSizeAndBeep(GlobalContext* globalCtx) {
|
|
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
|
|
|
|
if (interfaceCtx->lifeSizeChangeDirection != 0) {
|
|
interfaceCtx->lifeSizeChange--;
|
|
if (interfaceCtx->lifeSizeChange <= 0) {
|
|
interfaceCtx->lifeSizeChange = 0;
|
|
interfaceCtx->lifeSizeChangeDirection = 0;
|
|
if (Player_InCsMode(&globalCtx->state) == 0 && (globalCtx->pauseCtx.state == 0) &&
|
|
(globalCtx->pauseCtx.debugState == 0) && LifeMeter_IsCritical() && func_801690CC(globalCtx) == 0) {
|
|
// Player_InCsMode and func_801690CC : Check if in Cutscene
|
|
play_sound(NA_SE_SY_HITPOINT_ALARM);
|
|
}
|
|
}
|
|
} else {
|
|
interfaceCtx->lifeSizeChange++;
|
|
if ((s32)interfaceCtx->lifeSizeChange >= 10) {
|
|
interfaceCtx->lifeSizeChange = 10;
|
|
interfaceCtx->lifeSizeChangeDirection = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
u32 LifeMeter_IsCritical(void) {
|
|
s16 criticalThreshold;
|
|
|
|
if (gSaveContext.healthCapacity <= 80) { // healthCapacity <= 5 hearts?
|
|
criticalThreshold = 16;
|
|
|
|
} else if (gSaveContext.healthCapacity <= 160) { // healthCapacity <= 10 hearts?
|
|
criticalThreshold = 24;
|
|
|
|
} else if (gSaveContext.healthCapacity <= 240) { // healthCapacity <= 15 hearts?
|
|
criticalThreshold = 32;
|
|
} else {
|
|
criticalThreshold = 44;
|
|
}
|
|
|
|
if ((criticalThreshold >= gSaveContext.health) && (gSaveContext.health > 0)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|