Spit MAD at TestCollisions (#458)

This splits MAD at the same point as the other files so that it's ready
when I figure out how to rename functions for this overlay.
This commit is contained in:
sozud 2023-08-08 19:23:47 -07:00 committed by GitHub
parent 967db3e206
commit b66ab4572d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 927 additions and 926 deletions

View File

@ -63,6 +63,7 @@ segments:
- [0xD884, rodata]
- [0xD8C8, c]
- [0xE964, c]
- [0xEDB8, c]
- [0x139E0, c]
- [0x197D8, data]
- [0x19E94]

View File

@ -4,929 +4,3 @@
#include "../update.h"
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", func_8018EC90);
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", func_8018EDB8);
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", EntityNumericDamage);
void CreateEntityFromLayout(Entity* entity, LayoutEntity* initDesc) {
DestroyEntity(entity);
entity->entityId = initDesc->entityId & 0x3FF;
entity->pfnUpdate = PfnEntityUpdates[entity->entityId - 1];
entity->posX.i.hi = initDesc->posX - g_Camera.posX.i.hi;
entity->posY.i.hi = initDesc->posY - g_Camera.posY.i.hi;
entity->params = initDesc->params;
entity->entityRoomIndex = initDesc->entityRoomIndex >> 8;
entity->unk68 = initDesc->entityId >> 0xA & 7;
}
void CreateEntityWhenInVerticalRange(LayoutEntity* layoutObj) {
s16 yClose;
s16 yFar;
s16 posY;
Entity* entity;
posY = g_Camera.posY.i.hi;
yClose = posY - 0x40;
yFar = posY + 0x120;
if (yClose < 0) {
yClose = 0;
}
posY = layoutObj->posY;
if (posY < yClose) {
return;
}
if (yFar < posY) {
return;
}
switch (layoutObj->entityId & 0xE000) {
case 0x0:
entity =
&g_Entities[STAGE_ENTITY_START + (u8)layoutObj->entityRoomIndex];
if (entity->entityId == E_NONE) {
CreateEntityFromLayout(entity, layoutObj);
}
break;
case 0x8000:
break;
case 0xA000:
entity =
&g_Entities[STAGE_ENTITY_START + (u8)layoutObj->entityRoomIndex];
CreateEntityFromLayout(entity, layoutObj);
break;
}
}
void CreateEntityWhenInHorizontalRange(LayoutEntity* layoutObj) {
s16 xClose;
s16 xFar;
s16 posX;
Entity* entity;
posX = g_Camera.posX.i.hi;
xClose = posX - 0x40;
xFar = posX + 0x140;
if (xClose < 0) {
xClose = 0;
}
posX = layoutObj->posX;
if (posX < xClose) {
return;
}
if (xFar < posX) {
return;
}
switch (layoutObj->entityId & 0xE000) {
case 0x0:
entity =
&g_Entities[STAGE_ENTITY_START + (u8)layoutObj->entityRoomIndex];
if (entity->entityId == E_NONE) {
CreateEntityFromLayout(entity, layoutObj);
}
break;
case 0x8000:
break;
case 0xA000:
entity =
&g_Entities[STAGE_ENTITY_START + (u8)layoutObj->entityRoomIndex];
CreateEntityFromLayout(entity, layoutObj);
break;
}
}
void func_80190838(s32 arg0) {
s32 a1 = 0xFFFE;
arg0 = (s16)arg0;
loop_1:
if (D_801997D8->posX == a1 || D_801997D8->posX < arg0) {
D_801997D8++;
goto loop_1;
}
}
void func_80190884(s16 arg0) {
while (true) {
if ((D_801997D8->posX != 0xFFFF) &&
((arg0 >= (s32)D_801997D8->posX) || (D_801997D8->posX == 0xFFFE))) {
break;
}
D_801997D8--;
}
}
#ifndef NON_MATCHING
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", func_801908DC);
#else
void func_801908DC(s16 arg0) {
u32 temp_a0, temp_v1_2;
if (D_801997E0 != 0) {
func_80190838((s16)(arg0 - D_80097908));
D_801997E0 = 0;
}
while (true) {
if (D_801997D8->posX == 0xFFFF || arg0 < D_801997D8->posX)
break;
temp_a0 = ((u32)D_801997D8->unk6 >> 8) + 0xFF;
temp_v1_2 = temp_a0 & 0xFF;
if (temp_v1_2 == 0xFF || (((1 << (temp_a0 & 0x1F)) &
g_entityDestroyed[temp_v1_2 >> 5]) == 0)) {
func_80190608(D_801997D8);
}
D_801997D8++;
}
}
#endif
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", func_801909D8);
void func_80190AD8(s16 arg0) {
while (true) {
if ((D_801997DC[1] != 0xFFFE) && ((s32)D_801997DC[1] >= arg0)) {
break;
}
D_801997DC += 5;
}
}
void func_80190B24(s16 arg0) {
while (true) {
if ((D_801997DC[1] != 0xFFFF) &&
((arg0 >= D_801997DC[1] || D_801997DC[1] == 0xFFFE))) {
break;
}
D_801997DC -= 5;
}
}
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", func_80190B7C);
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", func_80190C78);
void InitRoomEntities(s32 objLayoutId) {
u16* pObjLayoutStart = g_pStObjLayout[objLayoutId];
Unkstruct8* currentRoomTileLayout = &g_CurrentRoomTileLayout;
s16 temp_s0;
s16 arg0;
s16 i;
u16* temp_v1;
D_801997D8 = pObjLayoutStart;
D_801997DC = D_801803C8[objLayoutId];
if (*pObjLayoutStart != 0xFFFE) {
D_801997D8 = pObjLayoutStart + 1;
arg0 = Random() & 0xFF;
for (i = 0; true; i++) {
temp_v1 = D_801997D8;
D_801997D8 = temp_v1 + 1;
arg0 -= temp_v1[0];
if (arg0 < 0) {
break;
}
D_801997D8 = temp_v1 + 3;
}
D_801997D8 = (temp_v1[2] << 0x10) + temp_v1[1];
D_801997DC += i * 2 + 2;
D_801997DC = (D_801997DC[1] << 0x10) + D_801997DC[0];
}
arg0 = currentRoomTileLayout->unkA;
temp_s0 = arg0 + 0x140;
i = arg0 - 0x40;
if (i < 0) {
i = 0;
}
D_801997E0 = 0;
D_801997E4 = 0;
func_80190838(i);
func_801908DC(temp_s0);
func_80190AD8(currentRoomTileLayout->unkE + 0x120);
}
void func_80190F04(void) {
Unkstruct8* currentRoomTileLayout = &g_CurrentRoomTileLayout;
if (D_80097908 != 0) {
s16 tmp = g_Camera.posX.i.hi;
if (D_80097908 > 0)
func_801908DC(tmp + 0x140);
else
func_801909D8(tmp - 0x40);
}
if (D_8009790C != 0) {
s16 tmp = currentRoomTileLayout->unkE;
if (D_8009790C > 0)
func_80190B7C(tmp + 0x120);
else
func_80190C78(tmp - 0x40);
}
}
void CreateEntityFromCurrentEntity(u16 entityId, Entity* entity) {
DestroyEntity(entity);
entity->entityId = entityId;
entity->pfnUpdate = PfnEntityUpdates[entityId - 1];
entity->posX.i.hi = g_CurrentEntity->posX.i.hi;
entity->posY.i.hi = g_CurrentEntity->posY.i.hi;
}
void CreateEntityFromEntity(u16 entityId, Entity* ent1, Entity* ent2) {
DestroyEntity(ent2);
ent2->entityId = entityId;
ent2->pfnUpdate = PfnEntityUpdates[entityId - 1];
ent2->posX.i.hi = (s16)ent1->posX.i.hi;
ent2->posY.i.hi = (s16)ent1->posY.i.hi;
}
s32 func_801910A8(Entity* e) {
s16 diff;
diff = PLAYER.posX.i.hi - e->posX.i.hi;
diff = ABS(diff);
if (diff >= 17) {
diff = 0;
} else {
diff = PLAYER.posY.i.hi - e->posY.i.hi;
diff = ABS(diff);
diff = diff < 33;
}
return diff;
}
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", EntityRedDoor);
void DestroyEntity(Entity* item) {
s32 i;
s32 length;
u32* ptr;
if (item->flags & FLAG_HAS_PRIMS) {
g_api.FreePrimitives(item->primIndex);
}
ptr = (u32*)item;
length = sizeof(Entity) / sizeof(s32);
for (i = 0; i < length; i++)
*ptr++ = 0;
}
void DestroyEntityFromIndex(s16 index) {
Entity* entity = &g_Entities[index];
while (entity < &D_8007EF1C) {
DestroyEntity(entity);
entity++;
}
}
void PreventEntityFromRespawning(Entity* entity) {
if (entity->entityRoomIndex != 0) {
u32 value = (entity->entityRoomIndex - 1);
u16 index = value / 32;
u16 bit = value % 32;
g_entityDestroyed[index] |= 1 << bit;
}
}
#include "st/AnimateEntity.h"
u8 func_80191F24(u8 frames[], Entity* self, u8 arg2) {
u16 animFrameStart = self->animFrameIdx * 2;
u8* var_s1 = &frames[animFrameStart];
s16 var_a1 = 0;
if (self->animFrameDuration == 0) {
if (*var_s1 != 0) {
if (*var_s1 == 0xFF) {
return 0;
}
self->animFrameDuration = *var_s1++ + (u8)self->ext.stub[0x3F];
self->animCurFrame = *var_s1++;
self->animFrameIdx++;
var_a1 = 128;
} else {
var_s1 = frames;
self->animFrameIdx = 0;
self->animFrameDuration = 0;
self->ext.stub[0x3F] = (arg2 * Random()) >> 8;
self->animFrameDuration = *var_s1++ + (u8)self->ext.stub[0x3F];
self->animCurFrame = *var_s1;
self->animFrameIdx++;
return 0;
}
}
self->animFrameDuration--;
self->animCurFrame = var_s1[-1];
var_a1 |= 1;
return var_a1;
}
s32 GetDistanceToPlayerX(void) {
s16 value = g_CurrentEntity->posX.i.hi - PLAYER.posX.i.hi;
if (value < 0) {
value = -value;
}
return value;
}
s32 GetDistanceToPlayerY(void) {
s32 value = g_CurrentEntity->posY.i.hi - PLAYER.posY.i.hi;
if (value < 0) {
value = -value;
}
return value;
}
s16 GetSideToPlayer(void) {
s16 var_a0 = g_CurrentEntity->posX.i.hi > PLAYER.posX.i.hi;
if (g_CurrentEntity->posY.i.hi > PLAYER.posY.i.hi) {
var_a0 |= 2;
}
return var_a0;
}
void MoveEntity(void) {
g_CurrentEntity->posX.val += g_CurrentEntity->velocityX;
g_CurrentEntity->posY.val += g_CurrentEntity->velocityY;
}
void FallEntity(void) {
if (g_CurrentEntity->velocityY < FALL_TERMINAL_VELOCITY) {
g_CurrentEntity->velocityY += FALL_GRAVITY;
}
}
u8 func_8019214C(void) {
u8 unkState;
Entity* entity;
MoveEntity();
FallEntity();
entity = g_CurrentEntity;
if (unkState & 1) {
entity->velocityY = 0;
}
return unkState;
}
s32 func_80192190(u16* sensors) {
Collider col;
Collider colBack;
s16 x;
s16 y;
s16 i;
MoveEntity();
FallEntity();
if (g_CurrentEntity->velocityY >= 0) {
x = g_CurrentEntity->posX.i.hi;
y = g_CurrentEntity->posY.i.hi;
for (i = 0; i < 4; i++) {
x += *sensors++;
y += *sensors++;
g_api.CheckCollision(x, y, &col, 0);
if (col.effects & EFFECT_UNK_8000) {
if (i == 1) {
if (col.effects & EFFECT_SOLID) {
g_api.CheckCollision(x, y - 8, &colBack, 0);
if (!(colBack.effects & EFFECT_SOLID)) {
g_CurrentEntity->posY.i.hi =
(u16)g_CurrentEntity->posY.i.hi + 4 + col.unk18;
g_CurrentEntity->velocityX = 0;
g_CurrentEntity->velocityY = 0;
g_CurrentEntity->flags &= ~FLAG_UNK_10000000;
return 1;
}
}
continue;
}
}
if (col.effects & EFFECT_NOTHROUGH && i != 1) {
if (col.effects & EFFECT_QUICKSAND) {
g_CurrentEntity->flags &= ~FLAG_UNK_10000000;
return 4;
}
g_api.CheckCollision(x, y - 8, &colBack, 0);
if (!(colBack.effects & EFFECT_SOLID)) {
g_CurrentEntity->posY.i.hi =
g_CurrentEntity->posY.i.hi + col.unk18;
g_CurrentEntity->velocityX = 0;
g_CurrentEntity->velocityY = 0;
g_CurrentEntity->flags &= ~FLAG_UNK_10000000;
return 1;
}
}
}
}
g_CurrentEntity->flags |= FLAG_UNK_10000000;
return 0;
}
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", func_80192408);
s32 func_80192618(s16* posX) {
Collider collider;
s16 temp2;
s16 temp4;
s16 x, y;
g_CurrentEntity->posX.val += g_CurrentEntity->velocityX;
temp2 = g_CurrentEntity->posY.i.hi + 3;
g_CurrentEntity->posY.i.hi = temp2;
x = g_CurrentEntity->posX.i.hi + *posX;
posX++;
y = temp2 + *posX;
g_api.CheckCollision(x, y, &collider, 0);
if (!(collider.effects & EFFECT_SOLID)) {
return 0;
}
posX++;
g_CurrentEntity->posY.i.hi = g_CurrentEntity->posY.i.hi + collider.unk18;
if (g_CurrentEntity->velocityX != 0) {
if (g_CurrentEntity->velocityX < 0) {
temp4 = x - *posX;
posX++;
} else {
temp4 = x + *posX;
posX++;
}
y = y + *posX - 7;
g_api.CheckCollision(temp4, y, &collider, 0);
if (collider.effects & EFFECT_SOLID) {
if ((collider.effects & (EFFECT_UNK_8000 | EFFECT_UNK_0002)) ==
EFFECT_UNK_0002) {
g_CurrentEntity->posX.val =
g_CurrentEntity->posX.val - g_CurrentEntity->velocityX;
g_CurrentEntity->velocityX = 0;
return 0xFF;
}
return 0x61;
}
y += 15;
g_api.CheckCollision(temp4, y, &collider, 0);
if (collider.effects & EFFECT_SOLID) {
if (collider.effects & EFFECT_UNK_8000) {
return 0x61;
}
return 1;
}
g_CurrentEntity->posX.val -= g_CurrentEntity->velocityX;
g_CurrentEntity->velocityX = 0;
return 0x80;
}
return 1;
}
Entity* AllocEntity(Entity* start, Entity* end) {
Entity* current = start;
while (current < end) {
if (current->entityId == E_NONE) {
DestroyEntity(current);
return current;
}
current++;
}
return NULL;
}
s32 func_80192860(u8 arg0, s16 arg1) { return D_801809EC[arg0 & 0xFF] * arg1; }
s16 func_8019288C(u8 arg0) { return D_801809EC[arg0]; }
void func_801928A8(s32 arg0, s16 arg1) {
g_CurrentEntity->velocityX = func_80192860(arg0, arg1);
g_CurrentEntity->velocityY = func_80192860(arg0 - 0x40, arg1);
}
u8 func_80192914(s16 x, s16 y) { return ((ratan2(y, x) >> 4) + 0x40); }
u8 func_8019294C(Entity* a, Entity* b) {
s32 diffX = (u16)b->posX.i.hi - (u16)a->posX.i.hi;
s32 diffY = (u16)b->posY.i.hi - (u16)a->posY.i.hi;
return func_80192914(diffX, diffY);
}
u8 func_80192994(s32 x, s32 y) {
s32 diffX = x - (u16)g_CurrentEntity->posX.i.hi;
s32 diffY = y - (u16)g_CurrentEntity->posY.i.hi;
return func_80192914(diffX, diffY);
}
u8 func_801929DC(u8 arg0, u8 arg1, u8 arg2) {
u8 var_v0;
s8 temp_a2 = arg2 - arg1;
if (temp_a2 < 0) {
var_v0 = -temp_a2;
} else {
var_v0 = temp_a2;
}
if (var_v0 > arg0) {
if (temp_a2 < 0) {
var_v0 = arg1 - arg0;
} else {
var_v0 = arg1 + arg0;
}
return var_v0;
}
return arg2;
}
void func_80192A34(u16 slope, s16 speed) {
Entity* entity;
s32 moveX;
s32 moveY;
moveX = rcos(slope) * speed;
entity = g_CurrentEntity;
if (moveX < 0) {
moveX += 15;
}
entity->velocityX = moveX >> 4;
moveY = rsin(slope) * speed;
entity = g_CurrentEntity;
if (moveY < 0) {
moveY += 15;
}
entity->velocityY = moveY >> 4;
}
u16 func_80192AC0(s16 x, s16 y) { return ratan2(y, x); }
u16 func_80192AF0(Entity* a, Entity* b) {
s32 diffX = b->posX.i.hi - a->posX.i.hi;
s32 diffY = b->posY.i.hi - a->posY.i.hi;
return ratan2(diffY, diffX);
}
u16 func_80192B28(s32 x, s32 y) {
s16 diffX = x - (u16)g_CurrentEntity->posX.i.hi;
s16 diffY = y - (u16)g_CurrentEntity->posY.i.hi;
return ratan2(diffY, diffX);
}
u16 func_80192B70(u16 arg0, u16 arg1, u16 arg2) {
u16 var_v0 = arg1;
u16 temp_a2 = arg2 - arg1;
u16 var_v0_2;
if (temp_a2 & 0x800) {
var_v0_2 = (0x800 - temp_a2) & 0x7FF;
} else {
var_v0_2 = temp_a2;
}
if (var_v0_2 > arg0) {
if (temp_a2 & 0x800) {
var_v0 = arg1 - arg0;
} else {
var_v0 = arg1 + arg0;
}
return var_v0;
}
return arg2;
}
void func_80192BD0(s32 arg0) {
g_CurrentEntity->step = (s16)(arg0 & 0xFF);
g_CurrentEntity->step_s = 0;
g_CurrentEntity->animFrameIdx = 0;
g_CurrentEntity->animFrameDuration = 0;
}
void func_80192BF0(s32 arg0) {
g_CurrentEntity->step_s = (s16)(arg0 & 0xFF);
g_CurrentEntity->animFrameIdx = 0;
g_CurrentEntity->animFrameDuration = 0;
}
void func_80192C0C(u16 arg0, u16 arg1) {
Entity* entity;
if (arg1 != 0) {
g_api.PlaySfx(arg1);
}
if (arg0 == 0xFF) {
DestroyEntity(g_CurrentEntity);
return;
}
entity = g_CurrentEntity;
entity->unk19 = 0;
entity->entityId = E_EXPLOSION;
entity->pfnUpdate = (PfnEntityUpdate)EntityExplosion;
entity->params = arg0;
entity->animCurFrame = 0;
g_CurrentEntity->step = 0;
g_CurrentEntity->step_s = 0;
}
void InitializeEntity(u16 arg0[]) {
u16 enemyId;
EnemyDef* enemyDef;
g_CurrentEntity->animSet = *arg0++;
g_CurrentEntity->animCurFrame = *arg0++;
g_CurrentEntity->unk5A = *arg0++;
g_CurrentEntity->palette = *arg0++;
enemyId = *arg0++;
g_CurrentEntity->enemyId = enemyId;
enemyDef = &g_api.enemyDefs[enemyId];
g_CurrentEntity->hitPoints = enemyDef->hitPoints;
g_CurrentEntity->attack = enemyDef->attack;
g_CurrentEntity->attackElement = enemyDef->attackElement;
g_CurrentEntity->hitboxState = enemyDef->unkC;
g_CurrentEntity->hitboxWidth = enemyDef->hitboxWidth;
g_CurrentEntity->hitboxHeight = enemyDef->hitboxHeight;
g_CurrentEntity->flags = enemyDef->unk24;
g_CurrentEntity->hitboxOffX = 0;
g_CurrentEntity->hitboxOffY = 0;
g_CurrentEntity->step_s = 0;
g_CurrentEntity->step++;
if (g_CurrentEntity->zPriority == 0) {
g_CurrentEntity->zPriority = g_zEntityCenter.S16.unk0 - 0xC;
}
}
void EntityDummy(Entity* arg0) {
if (arg0->step == 0) {
arg0->step++;
}
}
s32 func_80192DD0(u16* hitSensors, s16 sensorCount) {
Collider collider;
s16 i;
s32 velocityX;
u16 temp_a1;
s16 x;
s16 y;
velocityX = g_CurrentEntity->velocityX;
if (velocityX != 0) {
x = g_CurrentEntity->posX.i.hi;
y = g_CurrentEntity->posY.i.hi;
for (i = 0; i < sensorCount; i++) {
if (velocityX < 0) {
s16 newX = x + *hitSensors++;
x = newX;
} else {
s16 newX = x - *hitSensors++;
x = newX;
}
y += *hitSensors++;
g_api.CheckCollision(x, y, &collider, 0);
if (collider.effects & EFFECT_UNK_0002 &&
((!(collider.effects & EFFECT_UNK_8000)) || (i != 0))) {
return 2;
}
}
return 0;
}
}
void func_80192EF8(u16* hitSensors, s16 sensorCount) {
Collider collider;
s16 i;
s32 velocityX;
s16 x;
s16 y;
velocityX = g_CurrentEntity->velocityX;
if (velocityX == 0)
return;
x = g_CurrentEntity->posX.i.hi;
y = g_CurrentEntity->posY.i.hi;
for (i = 0; i < sensorCount; i++) {
if (velocityX < 0) {
x = x + *hitSensors++;
} else {
x = x - *hitSensors++;
}
y += *hitSensors++;
g_api.CheckCollision(x, y, &collider, 0);
if (collider.effects & EFFECT_UNK_0002 &&
(!(collider.effects & EFFECT_UNK_8000) || i != 0)) {
if (velocityX < 0) {
g_CurrentEntity->posX.i.hi += collider.unk1C;
} else {
g_CurrentEntity->posX.i.hi += collider.unk14;
}
return;
}
}
}
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", func_80193050);
void ReplaceBreakableWithItemDrop(Entity* self) {
u16 params;
PreventEntityFromRespawning(self);
#if STAGE != STAGE_ST0
if (!(g_Status.relics[RELIC_CUBE_OF_ZOE] & 2)) {
DestroyEntity(self);
return;
}
#endif
params = self->params &= 0xFFF;
if (params < 0x80) {
self->entityId = E_PRIZE_DROP;
self->pfnUpdate = (PfnEntityUpdate)EntityPrizeDrop;
self->animFrameDuration = 0;
self->animFrameIdx = 0;
} else {
params -= 0x80;
self->entityId = E_EQUIP_ITEM_DROP;
self->pfnUpdate = (PfnEntityUpdate)EntityEquipItemDrop;
}
self->params = params;
self->unk6D = 0x10;
self->step = 0;
}
void func_8019344C(void) {
s32 temp_v1;
Entity* entity;
entity = g_CurrentEntity;
if (entity->velocityY >= 0) {
temp_v1 =
entity->ext.generic.unk88.S16.unk0 + entity->ext.generic.unk84.unk;
entity->ext.generic.unk84.unk = temp_v1;
entity->velocityX = temp_v1;
if (temp_v1 == 0x10000 || temp_v1 == -0x10000) {
entity->ext.generic.unk88.S16.unk0 =
-entity->ext.generic.unk88.S16.unk0;
}
entity = g_CurrentEntity;
}
if (entity->velocityY < FIX(0.25)) {
entity->velocityY += FIX(0.125);
}
}
void func_801934D0(u16 arg0) {
Collider collider;
if (g_CurrentEntity->velocityX < 0) {
g_api.CheckCollision(g_CurrentEntity->posX.i.hi,
g_CurrentEntity->posY.i.hi - 7, &collider, 0);
if (collider.effects & EFFECT_NOTHROUGH) {
g_CurrentEntity->velocityY = 0;
}
}
g_api.CheckCollision(g_CurrentEntity->posX.i.hi,
g_CurrentEntity->posY.i.hi + 7, &collider, 0);
if (arg0) {
if (!(collider.effects & EFFECT_NOTHROUGH)) {
MoveEntity();
FallEntity();
return;
}
g_CurrentEntity->velocityX = 0;
g_CurrentEntity->velocityY = 0;
if (collider.effects & EFFECT_QUICKSAND) {
g_CurrentEntity->posY.val += FIX(0.125);
return;
}
g_CurrentEntity->posY.i.hi =
(u16)g_CurrentEntity->posY.i.hi + collider.unk18;
return;
}
if (!(collider.effects & EFFECT_NOTHROUGH)) {
MoveEntity();
func_8019344C();
}
}
INCLUDE_ASM("asm/us/st/mad/nonmatchings/E964", CollectHeart);
void* const D_80180D60[];
const s32 D_80180D88[]; // c_GoldPrizes
void CollectGold(u16 goldSize) { // CollectGold
s32 *gold, *unk;
u16 goldSizeIndex;
g_api.PlaySfx(0x69D);
gold = &g_Status.gold;
goldSizeIndex = goldSize - 2;
*gold += D_80180D88[goldSizeIndex];
if (*gold > MAX_GOLD) {
*gold = MAX_GOLD;
}
unk = &D_80097410;
if (*unk) {
g_api.FreePrimitives(D_80097414); // g_api.FreePrimitives
*unk = 0;
}
func_80198BC8(D_80180D60[goldSizeIndex], 1);
DestroyEntity(g_CurrentEntity);
}
void func_801937BC(void) {}
void func_801937C4(void) { DestroyEntity(g_CurrentEntity); }
void CollectSubweapon(u16 subWeaponIdx) {
Entity* player = &PLAYER;
u16 subWeapon;
g_api.PlaySfx(0x672);
subWeapon = g_Status.subWeapon;
g_Status.subWeapon = D_80180D1C[subWeaponIdx];
if (subWeapon == g_Status.subWeapon) {
subWeapon = 1;
g_CurrentEntity->unk6D = 0x10;
} else {
subWeapon = D_80180D4C[subWeapon];
g_CurrentEntity->unk6D = 0x60;
}
if (subWeapon != 0) {
g_CurrentEntity->params = subWeapon;
g_CurrentEntity->posY.i.hi = player->posY.i.hi + 12;
g_CurrentEntity->step = 7;
g_CurrentEntity->step_s = 0;
g_CurrentEntity->velocityY = FIX(-2.5);
g_CurrentEntity->animCurFrame = 0;
g_CurrentEntity->ext.generic.unk88.S16.unk2 = 5;
if (player->facing != 1) {
g_CurrentEntity->velocityX = FIX(-2);
return;
}
g_CurrentEntity->velocityX = FIX(2);
return;
}
DestroyEntity(g_CurrentEntity);
}
void CollectHeartVessel(void) {
g_api.PlaySfx(0x670);
g_api.func_800FE044(HEART_VESSEL_INCREASE, 0x4000);
DestroyEntity(g_CurrentEntity);
}
void CollectLifeVessel(void) {
g_api.PlaySfx(0x670);
g_api.func_800FE044(LIFE_VESSEL_INCREASE, 0x8000);
DestroyEntity(g_CurrentEntity);
}
void DestroyCurrentEntity(void) { DestroyEntity(g_CurrentEntity); }
Entity* func_801939C4(void) {
g_CurrentEntity->step = 3;
g_CurrentEntity->params = 4;
return g_CurrentEntity;
}

926
src/st/mad/EDB8.c Normal file
View File

@ -0,0 +1,926 @@
#include "mad.h"
INCLUDE_ASM("asm/us/st/mad/nonmatchings/EDB8", func_8018EDB8);
INCLUDE_ASM("asm/us/st/mad/nonmatchings/EDB8", EntityNumericDamage);
void CreateEntityFromLayout(Entity* entity, LayoutEntity* initDesc) {
DestroyEntity(entity);
entity->entityId = initDesc->entityId & 0x3FF;
entity->pfnUpdate = PfnEntityUpdates[entity->entityId - 1];
entity->posX.i.hi = initDesc->posX - g_Camera.posX.i.hi;
entity->posY.i.hi = initDesc->posY - g_Camera.posY.i.hi;
entity->params = initDesc->params;
entity->entityRoomIndex = initDesc->entityRoomIndex >> 8;
entity->unk68 = initDesc->entityId >> 0xA & 7;
}
void CreateEntityWhenInVerticalRange(LayoutEntity* layoutObj) {
s16 yClose;
s16 yFar;
s16 posY;
Entity* entity;
posY = g_Camera.posY.i.hi;
yClose = posY - 0x40;
yFar = posY + 0x120;
if (yClose < 0) {
yClose = 0;
}
posY = layoutObj->posY;
if (posY < yClose) {
return;
}
if (yFar < posY) {
return;
}
switch (layoutObj->entityId & 0xE000) {
case 0x0:
entity =
&g_Entities[STAGE_ENTITY_START + (u8)layoutObj->entityRoomIndex];
if (entity->entityId == E_NONE) {
CreateEntityFromLayout(entity, layoutObj);
}
break;
case 0x8000:
break;
case 0xA000:
entity =
&g_Entities[STAGE_ENTITY_START + (u8)layoutObj->entityRoomIndex];
CreateEntityFromLayout(entity, layoutObj);
break;
}
}
void CreateEntityWhenInHorizontalRange(LayoutEntity* layoutObj) {
s16 xClose;
s16 xFar;
s16 posX;
Entity* entity;
posX = g_Camera.posX.i.hi;
xClose = posX - 0x40;
xFar = posX + 0x140;
if (xClose < 0) {
xClose = 0;
}
posX = layoutObj->posX;
if (posX < xClose) {
return;
}
if (xFar < posX) {
return;
}
switch (layoutObj->entityId & 0xE000) {
case 0x0:
entity =
&g_Entities[STAGE_ENTITY_START + (u8)layoutObj->entityRoomIndex];
if (entity->entityId == E_NONE) {
CreateEntityFromLayout(entity, layoutObj);
}
break;
case 0x8000:
break;
case 0xA000:
entity =
&g_Entities[STAGE_ENTITY_START + (u8)layoutObj->entityRoomIndex];
CreateEntityFromLayout(entity, layoutObj);
break;
}
}
void func_80190838(s32 arg0) {
s32 a1 = 0xFFFE;
arg0 = (s16)arg0;
loop_1:
if (D_801997D8->posX == a1 || D_801997D8->posX < arg0) {
D_801997D8++;
goto loop_1;
}
}
void func_80190884(s16 arg0) {
while (true) {
if ((D_801997D8->posX != 0xFFFF) &&
((arg0 >= (s32)D_801997D8->posX) || (D_801997D8->posX == 0xFFFE))) {
break;
}
D_801997D8--;
}
}
#ifndef NON_MATCHING
INCLUDE_ASM("asm/us/st/mad/nonmatchings/EDB8", func_801908DC);
#else
void func_801908DC(s16 arg0) {
u32 temp_a0, temp_v1_2;
if (D_801997E0 != 0) {
func_80190838((s16)(arg0 - D_80097908));
D_801997E0 = 0;
}
while (true) {
if (D_801997D8->posX == 0xFFFF || arg0 < D_801997D8->posX)
break;
temp_a0 = ((u32)D_801997D8->unk6 >> 8) + 0xFF;
temp_v1_2 = temp_a0 & 0xFF;
if (temp_v1_2 == 0xFF || (((1 << (temp_a0 & 0x1F)) &
g_entityDestroyed[temp_v1_2 >> 5]) == 0)) {
func_80190608(D_801997D8);
}
D_801997D8++;
}
}
#endif
INCLUDE_ASM("asm/us/st/mad/nonmatchings/EDB8", func_801909D8);
void func_80190AD8(s16 arg0) {
while (true) {
if ((D_801997DC[1] != 0xFFFE) && ((s32)D_801997DC[1] >= arg0)) {
break;
}
D_801997DC += 5;
}
}
void func_80190B24(s16 arg0) {
while (true) {
if ((D_801997DC[1] != 0xFFFF) &&
((arg0 >= D_801997DC[1] || D_801997DC[1] == 0xFFFE))) {
break;
}
D_801997DC -= 5;
}
}
INCLUDE_ASM("asm/us/st/mad/nonmatchings/EDB8", func_80190B7C);
INCLUDE_ASM("asm/us/st/mad/nonmatchings/EDB8", func_80190C78);
void InitRoomEntities(s32 objLayoutId) {
u16* pObjLayoutStart = g_pStObjLayout[objLayoutId];
Unkstruct8* currentRoomTileLayout = &g_CurrentRoomTileLayout;
s16 temp_s0;
s16 arg0;
s16 i;
u16* temp_v1;
D_801997D8 = pObjLayoutStart;
D_801997DC = D_801803C8[objLayoutId];
if (*pObjLayoutStart != 0xFFFE) {
D_801997D8 = pObjLayoutStart + 1;
arg0 = Random() & 0xFF;
for (i = 0; true; i++) {
temp_v1 = D_801997D8;
D_801997D8 = temp_v1 + 1;
arg0 -= temp_v1[0];
if (arg0 < 0) {
break;
}
D_801997D8 = temp_v1 + 3;
}
D_801997D8 = (temp_v1[2] << 0x10) + temp_v1[1];
D_801997DC += i * 2 + 2;
D_801997DC = (D_801997DC[1] << 0x10) + D_801997DC[0];
}
arg0 = currentRoomTileLayout->unkA;
temp_s0 = arg0 + 0x140;
i = arg0 - 0x40;
if (i < 0) {
i = 0;
}
D_801997E0 = 0;
D_801997E4 = 0;
func_80190838(i);
func_801908DC(temp_s0);
func_80190AD8(currentRoomTileLayout->unkE + 0x120);
}
void func_80190F04(void) {
Unkstruct8* currentRoomTileLayout = &g_CurrentRoomTileLayout;
if (D_80097908 != 0) {
s16 tmp = g_Camera.posX.i.hi;
if (D_80097908 > 0)
func_801908DC(tmp + 0x140);
else
func_801909D8(tmp - 0x40);
}
if (D_8009790C != 0) {
s16 tmp = currentRoomTileLayout->unkE;
if (D_8009790C > 0)
func_80190B7C(tmp + 0x120);
else
func_80190C78(tmp - 0x40);
}
}
void CreateEntityFromCurrentEntity(u16 entityId, Entity* entity) {
DestroyEntity(entity);
entity->entityId = entityId;
entity->pfnUpdate = PfnEntityUpdates[entityId - 1];
entity->posX.i.hi = g_CurrentEntity->posX.i.hi;
entity->posY.i.hi = g_CurrentEntity->posY.i.hi;
}
void CreateEntityFromEntity(u16 entityId, Entity* ent1, Entity* ent2) {
DestroyEntity(ent2);
ent2->entityId = entityId;
ent2->pfnUpdate = PfnEntityUpdates[entityId - 1];
ent2->posX.i.hi = (s16)ent1->posX.i.hi;
ent2->posY.i.hi = (s16)ent1->posY.i.hi;
}
s32 func_801910A8(Entity* e) {
s16 diff;
diff = PLAYER.posX.i.hi - e->posX.i.hi;
diff = ABS(diff);
if (diff >= 17) {
diff = 0;
} else {
diff = PLAYER.posY.i.hi - e->posY.i.hi;
diff = ABS(diff);
diff = diff < 33;
}
return diff;
}
INCLUDE_ASM("asm/us/st/mad/nonmatchings/EDB8", EntityRedDoor);
void DestroyEntity(Entity* item) {
s32 i;
s32 length;
u32* ptr;
if (item->flags & FLAG_HAS_PRIMS) {
g_api.FreePrimitives(item->primIndex);
}
ptr = (u32*)item;
length = sizeof(Entity) / sizeof(s32);
for (i = 0; i < length; i++)
*ptr++ = 0;
}
void DestroyEntityFromIndex(s16 index) {
Entity* entity = &g_Entities[index];
while (entity < &D_8007EF1C) {
DestroyEntity(entity);
entity++;
}
}
void PreventEntityFromRespawning(Entity* entity) {
if (entity->entityRoomIndex != 0) {
u32 value = (entity->entityRoomIndex - 1);
u16 index = value / 32;
u16 bit = value % 32;
g_entityDestroyed[index] |= 1 << bit;
}
}
#include "st/AnimateEntity.h"
u8 func_80191F24(u8 frames[], Entity* self, u8 arg2) {
u16 animFrameStart = self->animFrameIdx * 2;
u8* var_s1 = &frames[animFrameStart];
s16 var_a1 = 0;
if (self->animFrameDuration == 0) {
if (*var_s1 != 0) {
if (*var_s1 == 0xFF) {
return 0;
}
self->animFrameDuration = *var_s1++ + (u8)self->ext.stub[0x3F];
self->animCurFrame = *var_s1++;
self->animFrameIdx++;
var_a1 = 128;
} else {
var_s1 = frames;
self->animFrameIdx = 0;
self->animFrameDuration = 0;
self->ext.stub[0x3F] = (arg2 * Random()) >> 8;
self->animFrameDuration = *var_s1++ + (u8)self->ext.stub[0x3F];
self->animCurFrame = *var_s1;
self->animFrameIdx++;
return 0;
}
}
self->animFrameDuration--;
self->animCurFrame = var_s1[-1];
var_a1 |= 1;
return var_a1;
}
s32 GetDistanceToPlayerX(void) {
s16 value = g_CurrentEntity->posX.i.hi - PLAYER.posX.i.hi;
if (value < 0) {
value = -value;
}
return value;
}
s32 GetDistanceToPlayerY(void) {
s32 value = g_CurrentEntity->posY.i.hi - PLAYER.posY.i.hi;
if (value < 0) {
value = -value;
}
return value;
}
s16 GetSideToPlayer(void) {
s16 var_a0 = g_CurrentEntity->posX.i.hi > PLAYER.posX.i.hi;
if (g_CurrentEntity->posY.i.hi > PLAYER.posY.i.hi) {
var_a0 |= 2;
}
return var_a0;
}
void MoveEntity(void) {
g_CurrentEntity->posX.val += g_CurrentEntity->velocityX;
g_CurrentEntity->posY.val += g_CurrentEntity->velocityY;
}
void FallEntity(void) {
if (g_CurrentEntity->velocityY < FALL_TERMINAL_VELOCITY) {
g_CurrentEntity->velocityY += FALL_GRAVITY;
}
}
u8 func_8019214C(void) {
u8 unkState;
Entity* entity;
MoveEntity();
FallEntity();
entity = g_CurrentEntity;
if (unkState & 1) {
entity->velocityY = 0;
}
return unkState;
}
s32 func_80192190(u16* sensors) {
Collider col;
Collider colBack;
s16 x;
s16 y;
s16 i;
MoveEntity();
FallEntity();
if (g_CurrentEntity->velocityY >= 0) {
x = g_CurrentEntity->posX.i.hi;
y = g_CurrentEntity->posY.i.hi;
for (i = 0; i < 4; i++) {
x += *sensors++;
y += *sensors++;
g_api.CheckCollision(x, y, &col, 0);
if (col.effects & EFFECT_UNK_8000) {
if (i == 1) {
if (col.effects & EFFECT_SOLID) {
g_api.CheckCollision(x, y - 8, &colBack, 0);
if (!(colBack.effects & EFFECT_SOLID)) {
g_CurrentEntity->posY.i.hi =
(u16)g_CurrentEntity->posY.i.hi + 4 + col.unk18;
g_CurrentEntity->velocityX = 0;
g_CurrentEntity->velocityY = 0;
g_CurrentEntity->flags &= ~FLAG_UNK_10000000;
return 1;
}
}
continue;
}
}
if (col.effects & EFFECT_NOTHROUGH && i != 1) {
if (col.effects & EFFECT_QUICKSAND) {
g_CurrentEntity->flags &= ~FLAG_UNK_10000000;
return 4;
}
g_api.CheckCollision(x, y - 8, &colBack, 0);
if (!(colBack.effects & EFFECT_SOLID)) {
g_CurrentEntity->posY.i.hi =
g_CurrentEntity->posY.i.hi + col.unk18;
g_CurrentEntity->velocityX = 0;
g_CurrentEntity->velocityY = 0;
g_CurrentEntity->flags &= ~FLAG_UNK_10000000;
return 1;
}
}
}
}
g_CurrentEntity->flags |= FLAG_UNK_10000000;
return 0;
}
INCLUDE_ASM("asm/us/st/mad/nonmatchings/EDB8", func_80192408);
s32 func_80192618(s16* posX) {
Collider collider;
s16 temp2;
s16 temp4;
s16 x, y;
g_CurrentEntity->posX.val += g_CurrentEntity->velocityX;
temp2 = g_CurrentEntity->posY.i.hi + 3;
g_CurrentEntity->posY.i.hi = temp2;
x = g_CurrentEntity->posX.i.hi + *posX;
posX++;
y = temp2 + *posX;
g_api.CheckCollision(x, y, &collider, 0);
if (!(collider.effects & EFFECT_SOLID)) {
return 0;
}
posX++;
g_CurrentEntity->posY.i.hi = g_CurrentEntity->posY.i.hi + collider.unk18;
if (g_CurrentEntity->velocityX != 0) {
if (g_CurrentEntity->velocityX < 0) {
temp4 = x - *posX;
posX++;
} else {
temp4 = x + *posX;
posX++;
}
y = y + *posX - 7;
g_api.CheckCollision(temp4, y, &collider, 0);
if (collider.effects & EFFECT_SOLID) {
if ((collider.effects & (EFFECT_UNK_8000 | EFFECT_UNK_0002)) ==
EFFECT_UNK_0002) {
g_CurrentEntity->posX.val =
g_CurrentEntity->posX.val - g_CurrentEntity->velocityX;
g_CurrentEntity->velocityX = 0;
return 0xFF;
}
return 0x61;
}
y += 15;
g_api.CheckCollision(temp4, y, &collider, 0);
if (collider.effects & EFFECT_SOLID) {
if (collider.effects & EFFECT_UNK_8000) {
return 0x61;
}
return 1;
}
g_CurrentEntity->posX.val -= g_CurrentEntity->velocityX;
g_CurrentEntity->velocityX = 0;
return 0x80;
}
return 1;
}
Entity* AllocEntity(Entity* start, Entity* end) {
Entity* current = start;
while (current < end) {
if (current->entityId == E_NONE) {
DestroyEntity(current);
return current;
}
current++;
}
return NULL;
}
s32 func_80192860(u8 arg0, s16 arg1) { return D_801809EC[arg0 & 0xFF] * arg1; }
s16 func_8019288C(u8 arg0) { return D_801809EC[arg0]; }
void func_801928A8(s32 arg0, s16 arg1) {
g_CurrentEntity->velocityX = func_80192860(arg0, arg1);
g_CurrentEntity->velocityY = func_80192860(arg0 - 0x40, arg1);
}
u8 func_80192914(s16 x, s16 y) { return ((ratan2(y, x) >> 4) + 0x40); }
u8 func_8019294C(Entity* a, Entity* b) {
s32 diffX = (u16)b->posX.i.hi - (u16)a->posX.i.hi;
s32 diffY = (u16)b->posY.i.hi - (u16)a->posY.i.hi;
return func_80192914(diffX, diffY);
}
u8 func_80192994(s32 x, s32 y) {
s32 diffX = x - (u16)g_CurrentEntity->posX.i.hi;
s32 diffY = y - (u16)g_CurrentEntity->posY.i.hi;
return func_80192914(diffX, diffY);
}
u8 func_801929DC(u8 arg0, u8 arg1, u8 arg2) {
u8 var_v0;
s8 temp_a2 = arg2 - arg1;
if (temp_a2 < 0) {
var_v0 = -temp_a2;
} else {
var_v0 = temp_a2;
}
if (var_v0 > arg0) {
if (temp_a2 < 0) {
var_v0 = arg1 - arg0;
} else {
var_v0 = arg1 + arg0;
}
return var_v0;
}
return arg2;
}
void func_80192A34(u16 slope, s16 speed) {
Entity* entity;
s32 moveX;
s32 moveY;
moveX = rcos(slope) * speed;
entity = g_CurrentEntity;
if (moveX < 0) {
moveX += 15;
}
entity->velocityX = moveX >> 4;
moveY = rsin(slope) * speed;
entity = g_CurrentEntity;
if (moveY < 0) {
moveY += 15;
}
entity->velocityY = moveY >> 4;
}
u16 func_80192AC0(s16 x, s16 y) { return ratan2(y, x); }
u16 func_80192AF0(Entity* a, Entity* b) {
s32 diffX = b->posX.i.hi - a->posX.i.hi;
s32 diffY = b->posY.i.hi - a->posY.i.hi;
return ratan2(diffY, diffX);
}
u16 func_80192B28(s32 x, s32 y) {
s16 diffX = x - (u16)g_CurrentEntity->posX.i.hi;
s16 diffY = y - (u16)g_CurrentEntity->posY.i.hi;
return ratan2(diffY, diffX);
}
u16 func_80192B70(u16 arg0, u16 arg1, u16 arg2) {
u16 var_v0 = arg1;
u16 temp_a2 = arg2 - arg1;
u16 var_v0_2;
if (temp_a2 & 0x800) {
var_v0_2 = (0x800 - temp_a2) & 0x7FF;
} else {
var_v0_2 = temp_a2;
}
if (var_v0_2 > arg0) {
if (temp_a2 & 0x800) {
var_v0 = arg1 - arg0;
} else {
var_v0 = arg1 + arg0;
}
return var_v0;
}
return arg2;
}
void func_80192BD0(s32 arg0) {
g_CurrentEntity->step = (s16)(arg0 & 0xFF);
g_CurrentEntity->step_s = 0;
g_CurrentEntity->animFrameIdx = 0;
g_CurrentEntity->animFrameDuration = 0;
}
void func_80192BF0(s32 arg0) {
g_CurrentEntity->step_s = (s16)(arg0 & 0xFF);
g_CurrentEntity->animFrameIdx = 0;
g_CurrentEntity->animFrameDuration = 0;
}
void func_80192C0C(u16 arg0, u16 arg1) {
Entity* entity;
if (arg1 != 0) {
g_api.PlaySfx(arg1);
}
if (arg0 == 0xFF) {
DestroyEntity(g_CurrentEntity);
return;
}
entity = g_CurrentEntity;
entity->unk19 = 0;
entity->entityId = E_EXPLOSION;
entity->pfnUpdate = (PfnEntityUpdate)EntityExplosion;
entity->params = arg0;
entity->animCurFrame = 0;
g_CurrentEntity->step = 0;
g_CurrentEntity->step_s = 0;
}
void InitializeEntity(u16 arg0[]) {
u16 enemyId;
EnemyDef* enemyDef;
g_CurrentEntity->animSet = *arg0++;
g_CurrentEntity->animCurFrame = *arg0++;
g_CurrentEntity->unk5A = *arg0++;
g_CurrentEntity->palette = *arg0++;
enemyId = *arg0++;
g_CurrentEntity->enemyId = enemyId;
enemyDef = &g_api.enemyDefs[enemyId];
g_CurrentEntity->hitPoints = enemyDef->hitPoints;
g_CurrentEntity->attack = enemyDef->attack;
g_CurrentEntity->attackElement = enemyDef->attackElement;
g_CurrentEntity->hitboxState = enemyDef->unkC;
g_CurrentEntity->hitboxWidth = enemyDef->hitboxWidth;
g_CurrentEntity->hitboxHeight = enemyDef->hitboxHeight;
g_CurrentEntity->flags = enemyDef->unk24;
g_CurrentEntity->hitboxOffX = 0;
g_CurrentEntity->hitboxOffY = 0;
g_CurrentEntity->step_s = 0;
g_CurrentEntity->step++;
if (g_CurrentEntity->zPriority == 0) {
g_CurrentEntity->zPriority = g_zEntityCenter.S16.unk0 - 0xC;
}
}
void EntityDummy(Entity* arg0) {
if (arg0->step == 0) {
arg0->step++;
}
}
s32 func_80192DD0(u16* hitSensors, s16 sensorCount) {
Collider collider;
s16 i;
s32 velocityX;
u16 temp_a1;
s16 x;
s16 y;
velocityX = g_CurrentEntity->velocityX;
if (velocityX != 0) {
x = g_CurrentEntity->posX.i.hi;
y = g_CurrentEntity->posY.i.hi;
for (i = 0; i < sensorCount; i++) {
if (velocityX < 0) {
s16 newX = x + *hitSensors++;
x = newX;
} else {
s16 newX = x - *hitSensors++;
x = newX;
}
y += *hitSensors++;
g_api.CheckCollision(x, y, &collider, 0);
if (collider.effects & EFFECT_UNK_0002 &&
((!(collider.effects & EFFECT_UNK_8000)) || (i != 0))) {
return 2;
}
}
return 0;
}
}
void func_80192EF8(u16* hitSensors, s16 sensorCount) {
Collider collider;
s16 i;
s32 velocityX;
s16 x;
s16 y;
velocityX = g_CurrentEntity->velocityX;
if (velocityX == 0)
return;
x = g_CurrentEntity->posX.i.hi;
y = g_CurrentEntity->posY.i.hi;
for (i = 0; i < sensorCount; i++) {
if (velocityX < 0) {
x = x + *hitSensors++;
} else {
x = x - *hitSensors++;
}
y += *hitSensors++;
g_api.CheckCollision(x, y, &collider, 0);
if (collider.effects & EFFECT_UNK_0002 &&
(!(collider.effects & EFFECT_UNK_8000) || i != 0)) {
if (velocityX < 0) {
g_CurrentEntity->posX.i.hi += collider.unk1C;
} else {
g_CurrentEntity->posX.i.hi += collider.unk14;
}
return;
}
}
}
INCLUDE_ASM("asm/us/st/mad/nonmatchings/EDB8", func_80193050);
void ReplaceBreakableWithItemDrop(Entity* self) {
u16 params;
PreventEntityFromRespawning(self);
#if STAGE != STAGE_ST0
if (!(g_Status.relics[RELIC_CUBE_OF_ZOE] & 2)) {
DestroyEntity(self);
return;
}
#endif
params = self->params &= 0xFFF;
if (params < 0x80) {
self->entityId = E_PRIZE_DROP;
self->pfnUpdate = (PfnEntityUpdate)EntityPrizeDrop;
self->animFrameDuration = 0;
self->animFrameIdx = 0;
} else {
params -= 0x80;
self->entityId = E_EQUIP_ITEM_DROP;
self->pfnUpdate = (PfnEntityUpdate)EntityEquipItemDrop;
}
self->params = params;
self->unk6D = 0x10;
self->step = 0;
}
void func_8019344C(void) {
s32 temp_v1;
Entity* entity;
entity = g_CurrentEntity;
if (entity->velocityY >= 0) {
temp_v1 =
entity->ext.generic.unk88.S16.unk0 + entity->ext.generic.unk84.unk;
entity->ext.generic.unk84.unk = temp_v1;
entity->velocityX = temp_v1;
if (temp_v1 == 0x10000 || temp_v1 == -0x10000) {
entity->ext.generic.unk88.S16.unk0 =
-entity->ext.generic.unk88.S16.unk0;
}
entity = g_CurrentEntity;
}
if (entity->velocityY < FIX(0.25)) {
entity->velocityY += FIX(0.125);
}
}
void func_801934D0(u16 arg0) {
Collider collider;
if (g_CurrentEntity->velocityX < 0) {
g_api.CheckCollision(g_CurrentEntity->posX.i.hi,
g_CurrentEntity->posY.i.hi - 7, &collider, 0);
if (collider.effects & EFFECT_NOTHROUGH) {
g_CurrentEntity->velocityY = 0;
}
}
g_api.CheckCollision(g_CurrentEntity->posX.i.hi,
g_CurrentEntity->posY.i.hi + 7, &collider, 0);
if (arg0) {
if (!(collider.effects & EFFECT_NOTHROUGH)) {
MoveEntity();
FallEntity();
return;
}
g_CurrentEntity->velocityX = 0;
g_CurrentEntity->velocityY = 0;
if (collider.effects & EFFECT_QUICKSAND) {
g_CurrentEntity->posY.val += FIX(0.125);
return;
}
g_CurrentEntity->posY.i.hi =
(u16)g_CurrentEntity->posY.i.hi + collider.unk18;
return;
}
if (!(collider.effects & EFFECT_NOTHROUGH)) {
MoveEntity();
func_8019344C();
}
}
INCLUDE_ASM("asm/us/st/mad/nonmatchings/EDB8", CollectHeart);
void* const D_80180D60[];
const s32 D_80180D88[]; // c_GoldPrizes
void CollectGold(u16 goldSize) { // CollectGold
s32 *gold, *unk;
u16 goldSizeIndex;
g_api.PlaySfx(0x69D);
gold = &g_Status.gold;
goldSizeIndex = goldSize - 2;
*gold += D_80180D88[goldSizeIndex];
if (*gold > MAX_GOLD) {
*gold = MAX_GOLD;
}
unk = &D_80097410;
if (*unk) {
g_api.FreePrimitives(D_80097414); // g_api.FreePrimitives
*unk = 0;
}
func_80198BC8(D_80180D60[goldSizeIndex], 1);
DestroyEntity(g_CurrentEntity);
}
void func_801937BC(void) {}
void func_801937C4(void) { DestroyEntity(g_CurrentEntity); }
void CollectSubweapon(u16 subWeaponIdx) {
Entity* player = &PLAYER;
u16 subWeapon;
g_api.PlaySfx(0x672);
subWeapon = g_Status.subWeapon;
g_Status.subWeapon = D_80180D1C[subWeaponIdx];
if (subWeapon == g_Status.subWeapon) {
subWeapon = 1;
g_CurrentEntity->unk6D = 0x10;
} else {
subWeapon = D_80180D4C[subWeapon];
g_CurrentEntity->unk6D = 0x60;
}
if (subWeapon != 0) {
g_CurrentEntity->params = subWeapon;
g_CurrentEntity->posY.i.hi = player->posY.i.hi + 12;
g_CurrentEntity->step = 7;
g_CurrentEntity->step_s = 0;
g_CurrentEntity->velocityY = FIX(-2.5);
g_CurrentEntity->animCurFrame = 0;
g_CurrentEntity->ext.generic.unk88.S16.unk2 = 5;
if (player->facing != 1) {
g_CurrentEntity->velocityX = FIX(-2);
return;
}
g_CurrentEntity->velocityX = FIX(2);
return;
}
DestroyEntity(g_CurrentEntity);
}
void CollectHeartVessel(void) {
g_api.PlaySfx(0x670);
g_api.func_800FE044(HEART_VESSEL_INCREASE, 0x4000);
DestroyEntity(g_CurrentEntity);
}
void CollectLifeVessel(void) {
g_api.PlaySfx(0x670);
g_api.func_800FE044(LIFE_VESSEL_INCREASE, 0x8000);
DestroyEntity(g_CurrentEntity);
}
void DestroyCurrentEntity(void) { DestroyEntity(g_CurrentEntity); }
Entity* func_801939C4(void) {
g_CurrentEntity->step = 3;
g_CurrentEntity->params = 4;
return g_CurrentEntity;
}