Update PB explosion function and constants (#20)

- Added constants for power bomb state
- Cleaned up PowerBombExplosionProcess and added comments
This commit is contained in:
biosp4rk 2024-07-12 08:33:15 -07:00 committed by GitHub
parent 273c7b352d
commit 66b64fc593
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 71 additions and 39 deletions

View File

@ -0,0 +1,13 @@
#ifndef POWER_BOMB_EXPLOSION_CONSTANTS_H
#define POWER_BOMB_EXPLOSION_CONSTANTS_H
enum PowerBombState {
PB_STATE_NONE,
PB_STATE_UNK_1,
PB_STATE_UNK_2,
PB_STATE_EXPLODING,
PB_STATE_IMPLODING,
PB_STATE_ENDING
};
#endif /* POWER_BOMB_EXPLOSION_CONSTANTS_H */

View File

@ -15,6 +15,7 @@
#include "constants/event.h"
#include "constants/game_state.h"
#include "constants/room.h"
#include "constants/power_bomb_explosion.h"
#include "structs/animated_graphics.h"
#include "structs/color_effects.h"
@ -341,7 +342,7 @@ void AnimatedPaletteUpdate(void)
return;
// Don't update if a power bomb explosion is occuring
if (gCurrentPowerBomb.animationState != 0)
if (gCurrentPowerBomb.animationState != PB_STATE_NONE)
return;
// Don't update if disabled

View File

@ -3,6 +3,7 @@
#include "constants/block.h"
#include "constants/connection.h"
#include "constants/power_bomb_explosion.h"
// 345868
@ -63,7 +64,7 @@ const struct BombChain sBombChain_Empty = {
};
const struct PowerBomb sPowerBomb_Empty = {
.animationState = 0,
.animationState = PB_STATE_NONE,
.stage = 0,
.semiMinorAxis = 0,
.unk_3 = 0,

View File

@ -10,6 +10,7 @@
#include "constants/haze.h"
#include "constants/game_state.h"
#include "constants/room.h"
#include "constants/power_bomb_explosion.h"
#include "structs/bg_clip.h"
#include "structs/clipdata.h"
@ -344,7 +345,7 @@ u32 HazeProcess(void)
// Expanding ended, setup retracting
gCurrentHazeValue = HAZE_VALUE_POWER_BOMB_RETRACTING;
HazeSetupCode(HAZE_VALUE_POWER_BOMB_RETRACTING);
gCurrentPowerBomb.animationState = 4;
gCurrentPowerBomb.animationState = PB_STATE_IMPLODING;
if (gAnimatedGraphicsEntry.palette == 0)
{
@ -366,7 +367,7 @@ u32 HazeProcess(void)
if (gHazeProcessCodePointer())
{
gIoRegistersBackup.unk_12 = gIoRegistersBackup.BG0CNT;
gCurrentPowerBomb.animationState = 5;
gCurrentPowerBomb.animationState = PB_STATE_ENDING;
gCurrentPowerBomb.stage = 0;
HazeSetupCode(HAZE_VALUE_AFTER_POWER_BOMB);

View File

@ -12,6 +12,7 @@
#include "constants/menus/pause_screen.h"
#include "constants/samus.h"
#include "constants/in_game_cutscene.h"
#include "constants/power_bomb_explosion.h"
#include "structs/display.h"
#include "structs/hud.h"
@ -727,7 +728,7 @@ void InGameCutsceneInit(void)
case IGC_GETTING_VARIA:
case IGC_GETTING_FULLY_POWERED:
if (gCurrentPowerBomb.animationState == 0 && !gCurrentPowerBomb.powerBombPlaced)
if (gCurrentPowerBomb.animationState == PB_STATE_NONE && !gCurrentPowerBomb.powerBombPlaced)
exists = TRUE;
break;
}

View File

@ -7,6 +7,7 @@
#include "constants/haze.h"
#include "constants/game_state.h"
#include "constants/room.h"
#include "constants/power_bomb_explosion.h"
#include "structs/bg_clip.h"
#include "structs/clipdata.h"
@ -22,14 +23,14 @@
*/
void PowerBombExplosionProcess(void)
{
if (gCurrentPowerBomb.animationState > 1)
if (gCurrentPowerBomb.animationState > PB_STATE_UNK_1)
{
PowerBombExplosionSet0x12To0();
if (gCurrentPowerBomb.unk_12 == 0) // Most likely a cancelled feature
{
if (gCurrentPowerBomb.animationState == 2)
if (gCurrentPowerBomb.animationState == PB_STATE_UNK_2)
PowerBombExplosionBegin();
else if (gCurrentPowerBomb.animationState == 5)
else if (gCurrentPowerBomb.animationState == PB_STATE_ENDING)
PowerBombExplosionEnd();
else if (gGameModeSub1 == SUB_GAME_MODE_PLAYING)
PowerBombExplosion();
@ -49,8 +50,8 @@ void PowerBombExplosion(void)
s32 hitboxBottom;
s32 hitboxLeft;
s32 hitboxRight;
s32 xLoop;
s32 yLoop;
s32 outerLoop;
s32 innerLoop;
s32 xPositionLeft;
s32 xPositionRight;
s32 yPositionTop;
@ -67,20 +68,26 @@ void PowerBombExplosion(void)
hitboxTop = (s16)-verticalAxis;
hitboxBottom = (s16)verticalAxis;
// Check if left edge of explosion is past left side of room. Can only be true while in-bounds
horizontalAxis = hitboxLeft;
if (gCurrentPowerBomb.xPosition + horizontalAxis < 0)
hitboxLeft = (s16)-gCurrentPowerBomb.xPosition;
// Check if top edge of explosion is past top side of room. Can only be true while in-bounds
verticalAxis = hitboxTop;
if (gCurrentPowerBomb.yPosition + verticalAxis < 0)
hitboxTop = (s16)-gCurrentPowerBomb.yPosition;
// Check if right edge of explosion is past right side of room
// BUG: If far enough out-of-bounds, integer underflow will occur from the subtraction
horizontalAxis = hitboxRight;
if (gBgPointersAndDimensions.clipdataWidth * BLOCK_SIZE < (gCurrentPowerBomb.xPosition + horizontalAxis))
if ((gBgPointersAndDimensions.clipdataWidth * BLOCK_SIZE) < (gCurrentPowerBomb.xPosition + horizontalAxis))
hitboxRight = (s16)(gBgPointersAndDimensions.clipdataWidth * BLOCK_SIZE - gCurrentPowerBomb.xPosition);
// Check if bottom edge of explosion is past bottom side of room
// BUG: If far enough out-of-bounds, integer underflow will occur from the subtraction
verticalAxis = hitboxBottom;
if (gBgPointersAndDimensions.clipdataHeight * BLOCK_SIZE < (gCurrentPowerBomb.yPosition + verticalAxis))
if ((gBgPointersAndDimensions.clipdataHeight * BLOCK_SIZE) < (gCurrentPowerBomb.yPosition + verticalAxis))
hitboxBottom = (s16)(gBgPointersAndDimensions.clipdataHeight * BLOCK_SIZE - gCurrentPowerBomb.yPosition);
gCurrentPowerBomb.hitboxLeftOffset = hitboxLeft;
@ -88,7 +95,7 @@ void PowerBombExplosion(void)
gCurrentPowerBomb.hitboxTopOffset = hitboxTop;
gCurrentPowerBomb.hitboxBottomOffset = hitboxBottom;
if (gCurrentPowerBomb.animationState < 4)
if (gCurrentPowerBomb.animationState < PB_STATE_IMPLODING)
{
hitboxLeft = DIV_SHIFT(hitboxLeft + gCurrentPowerBomb.xPosition, BLOCK_SIZE);
hitboxRight = DIV_SHIFT(hitboxRight + gCurrentPowerBomb.xPosition, BLOCK_SIZE);
@ -99,19 +106,21 @@ void PowerBombExplosion(void)
{
gCurrentClipdataAffectingAction = CAA_POWER_BOMB;
for (xLoop = 0; xLoop < 2; xLoop++)
// Do 2 loops, one for left side and one for right side
for (outerLoop = 0; outerLoop < 2; outerLoop++)
{
if (xLoop == 0)
if (outerLoop == 0)
horizontalAxis = hitboxLeft;
else
horizontalAxis = hitboxRight;
// BUG: yPosition is not checked if out-of-bounds, which can lead to memory corruption
yPositionTop = gCurrentPowerBomb.yPosition / BLOCK_SIZE;
yPositionBottom = yPositionTop;
for (yLoop = 0; yLoop != 2;)
for (innerLoop = 0; innerLoop != 2;)
{
yLoop = 0;
innerLoop = 0;
if (yPositionTop >= hitboxTop)
{
clipdata = gBgPointersAndDimensions.pClipDecomp[yPositionTop * gBgPointersAndDimensions.clipdataWidth + horizontalAxis];
@ -121,7 +130,7 @@ void PowerBombExplosion(void)
yPositionTop = (s16)(yPositionTop - 1);
}
else
yLoop = 0x1;
innerLoop++;
if ((s32)yPositionBottom <= hitboxBottom)
{
@ -132,7 +141,7 @@ void PowerBombExplosion(void)
yPositionBottom = (s16)(yPositionBottom + 1);
}
else
yLoop++;
innerLoop++;
}
}
}
@ -140,19 +149,21 @@ void PowerBombExplosion(void)
{
gCurrentClipdataAffectingAction = CAA_POWER_BOMB;
for (xLoop = 0; xLoop < 2; xLoop++)
// Do 2 loops, one for top side and one for bottom side
for (outerLoop = 0; outerLoop < 2; outerLoop++)
{
if (xLoop == 0)
if (outerLoop == 0)
verticalAxis = hitboxTop;
else
verticalAxis = hitboxBottom;
// BUG: xPosition is not checked if out-of-bounds, which can lead to memory corruption
xPositionRight = gCurrentPowerBomb.xPosition / BLOCK_SIZE;
xPositionLeft = xPositionRight;
for (yLoop = 0; yLoop != 2; )
for (innerLoop = 0; innerLoop != 2;)
{
yLoop = 0;
innerLoop = 0;
if (xPositionLeft >= hitboxLeft)
{
clipdata = gBgPointersAndDimensions.pClipDecomp[verticalAxis * gBgPointersAndDimensions.clipdataWidth + xPositionLeft];
@ -162,7 +173,7 @@ void PowerBombExplosion(void)
xPositionLeft = (s16)(xPositionLeft - 1);
}
else
yLoop++;
innerLoop++;
if (xPositionRight <= hitboxRight)
{
@ -173,7 +184,7 @@ void PowerBombExplosion(void)
xPositionRight = (s16)(xPositionRight + 1);
}
else
yLoop++;
innerLoop++;
}
}
}
@ -194,14 +205,14 @@ void PowerBombExplosionStart(u16 xPosition, u16 yPosition, u8 owner)
return;
PowerBombExplosionSet0x12To0();
if (gCurrentPowerBomb.animationState == 0) // Check if there isn't already an explosion
if (gCurrentPowerBomb.animationState == PB_STATE_NONE) // Check if there isn't already an explosion
{
gCurrentPowerBomb.xPosition = xPosition;
gCurrentPowerBomb.yPosition = yPosition;
gCurrentPowerBomb.owner = owner;
if (gCurrentPowerBomb.unk_12 != 0)
gCurrentPowerBomb.animationState = 2;
gCurrentPowerBomb.animationState = PB_STATE_UNK_2;
else
PowerBombExplosionBegin();
}
@ -225,7 +236,7 @@ void PowerBombExplosionBegin(void)
if (gGameModeSub1 != SUB_GAME_MODE_PLAYING)
return;
gCurrentPowerBomb.animationState = 3;
gCurrentPowerBomb.animationState = PB_STATE_EXPLODING;
gCurrentPowerBomb.powerBombPlaced = FALSE;
DMA_SET(3, PALRAM_BASE, EWRAM_BASE + 0x9000, C_32_2_16(DMA_ENABLE, PALRAM_SIZE / 4));
@ -324,7 +335,7 @@ void PowerBombExplosionEnd(void)
else if (gCurrentPowerBomb.stage == 2)
{
// Kill the power bomb
gCurrentPowerBomb.animationState = 0;
gCurrentPowerBomb.animationState = PB_STATE_NONE;
gCurrentPowerBomb.owner = 0;
gCurrentPowerBomb.stage = 0;
}

View File

@ -12,6 +12,7 @@
#include "constants/sprite.h"
#include "constants/particle.h"
#include "constants/projectile.h"
#include "constants/power_bomb_explosion.h"
#include "structs/bg_clip.h"
#include "structs/clipdata.h"
@ -437,7 +438,7 @@ void ProjectileUpdate(void)
break;
case PROJECTILE_CATEGORY_POWER_BOMB:
if (ProjectileCheckNumberOfProjectiles(PROJ_TYPE_POWER_BOMB, 0x1) && gCurrentPowerBomb.animationState == 0x0
if (ProjectileCheckNumberOfProjectiles(PROJ_TYPE_POWER_BOMB, 0x1) && gCurrentPowerBomb.animationState == PB_STATE_NONE
&& ProjectileInit(PROJ_TYPE_POWER_BOMB, gSamusData.yPosition, gSamusData.xPosition))
gSamusWeaponInfo.cooldown = 0x5;
gSamusWeaponInfo.newProjectile = PROJECTILE_CATEGORY_NONE;
@ -1143,7 +1144,7 @@ void ProjectileCheckHittingSprite(void)
pEquipment = &gEquipment;
if (gCurrentPowerBomb.animationState != 0 && pEquipment->maxPowerBombs != 0)
if (gCurrentPowerBomb.animationState != PB_STATE_NONE && pEquipment->maxPowerBombs != 0)
{
o1y = gCurrentPowerBomb.yPosition;
o1x = gCurrentPowerBomb.xPosition;

View File

@ -17,6 +17,7 @@
#include "constants/samus.h"
#include "constants/room.h"
#include "constants/in_game_cutscene.h"
#include "constants/power_bomb_explosion.h"
#include "constants/menus/pause_screen.h"
#include "structs/audio.h"
@ -391,7 +392,7 @@ void RoomReset(void)
gColorFading.stage = 0;
gColorFading.unk_6 = 0;
if (gCurrentPowerBomb.animationState != 0)
if (gCurrentPowerBomb.animationState != PB_STATE_NONE)
gScreenShakeX = sScreenShake_Empty;
gCurrentPowerBomb = sPowerBomb_Empty;
@ -886,7 +887,7 @@ void RoomUpdateAnimatedGraphicsAndPalettes(void)
dontUpdateGraphics = TRUE;
}
if (!dontUpdateBgEffect && gBackgroundEffect.type != 0 && gCurrentPowerBomb.animationState == 0)
if (!dontUpdateBgEffect && gBackgroundEffect.type != 0 && gCurrentPowerBomb.animationState == PB_STATE_NONE)
BackgroundEffectUpdate();
if (!dontUpdateGraphics)

View File

@ -6,6 +6,7 @@
#include "constants/sprite.h"
#include "constants/clipdata.h"
#include "constants/event.h"
#include "constants/power_bomb_explosion.h"
#include "structs/sprite.h"
#include "structs/samus.h"
@ -138,7 +139,7 @@ void GlassTubeCheckPowerBombCollision(void)
u16 spriteRight;
if (EventFunction(EVENT_ACTION_CHECKING, EVENT_FULLY_POWERED_SUIT_OBTAINED)
&& gCurrentPowerBomb.animationState != 0x0 && gEquipment.maxPowerBombs != 0x0)
&& gCurrentPowerBomb.animationState != PB_STATE_NONE && gEquipment.maxPowerBombs != 0x0)
{
bombY = gCurrentPowerBomb.yPosition;
bombX = gCurrentPowerBomb.xPosition;

View File

@ -5,6 +5,7 @@
#include "constants/room.h"
#include "constants/game_state.h"
#include "constants/power_bomb_explosion.h"
#include "structs/power_bomb_explosion.h"
#include "structs/game_state.h"
@ -601,7 +602,7 @@ void TransparencyApplyNewBLDALPHA(struct BldalphaData* pBldalpha)
newValue = FALSE;
if (gWrittenToBLDALPHA != 0)
newValue = TRUE;
else if (gCurrentPowerBomb.animationState != 0)
else if (gCurrentPowerBomb.animationState != PB_STATE_NONE)
newValue = TRUE;
else if (pBldalpha->activeFlag & 0x80)
newValue = TRUE;
@ -684,7 +685,7 @@ void TransparencyApplyNewBLDY(struct BldyData* pBldy)
newValue = FALSE;
if (gWrittenToBLDY >= 0)
newValue = TRUE;
else if (gCurrentPowerBomb.animationState != 0)
else if (gCurrentPowerBomb.animationState != PB_STATE_NONE)
newValue = TRUE;
else if (pBldy->activeFlag & 0x80)
newValue = TRUE;
@ -747,7 +748,7 @@ void unk_55e60(void)
switch (gCurrentPowerBomb.animationState)
{
case 1:
case PB_STATE_UNK_1:
gTransparencyRelated.unk_2 = 0;
gTransparencyRelated.unk_1 = 2;
@ -755,7 +756,7 @@ void unk_55e60(void)
gWrittenToBLDALPHA = C_16_2_8(coef, 16 - coef);
break;
case 0:
case PB_STATE_NONE:
gTransparencyRelated.unk_2++;
if (gTransparencyRelated.unk_0 != 2)
{