diff --git a/include/game/shared/stage/collision.h b/include/game/shared/stage/collision.h index 5361be571..a6857c20c 100644 --- a/include/game/shared/stage/collision.h +++ b/include/game/shared/stage/collision.h @@ -78,7 +78,6 @@ u32 Coll_Player_Platform(Sprite *, CamCoord x, CamCoord y, Player *); bool32 Coll_AmyHammer_Spring(Sprite *s, CamCoord worldX, CamCoord worldY, Player *p); #endif -u32 sub_800CE94(Sprite *s, s32 sx, s32 sy, Rect8 *param3, Player *p); bool32 SA2_LABEL(sub_800DD54)(Player *p); bool32 SA2_LABEL(sub_800DE44)(Player *p); u32 SA2_LABEL(sub_800D0A0)(Sprite *s, s16 worldX, s16 worldY, s16 qSpeedX, s16 qSpeedY, u8 layer, u32 arg6); diff --git a/sa1/Makefile b/sa1/Makefile index f7dc71aee..36685193d 100644 --- a/sa1/Makefile +++ b/sa1/Makefile @@ -270,6 +270,7 @@ SA2_C_FILES := \ src/game/shared/collect_rings/results.c \ src/game/shared/menus/unused_level_select.c \ src/game/shared/stage/collision_1.c \ + src/game/shared/stage/collision_2.c \ src/game/sa1/ui/game_2_0.c \ src/game/sa1/ui/game_2_1.c \ src/game/sa1/ui/stage_results.c \ diff --git a/sa1/ldscript.txt b/sa1/ldscript.txt index 6c8f072c9..35e7eef01 100644 --- a/sa1/ldscript.txt +++ b/sa1/ldscript.txt @@ -30,7 +30,7 @@ SECTIONS { src/game/shared/stage/entities_manager.o(.text); sa2/src/game/shared/stage/collision_1.o(.text); src/game/shared/stage/collision_3.o(.text); - src/game/shared/stage/collision_2.o(.text); + sa2/src/game/shared/stage/collision_2.o(.text); sa2/src/game/shared/stage/palette_loader.o(.text); /* Menus */ diff --git a/sa1/src/game/shared/stage/collision_2.c b/sa1/src/game/shared/stage/collision_2.c deleted file mode 100644 index 24a16c163..000000000 --- a/sa1/src/game/shared/stage/collision_2.c +++ /dev/null @@ -1,349 +0,0 @@ -#include "global.h" -#include "rect.h" -#include "sprite.h" -#include "lib/m4a/m4a.h" -#include "game/shared/stage/mp_player.h" -#include "game/globals.h" -#include "game/shared/stage/collision.h" -#include "game/shared/stage/dust_cloud.h" -#include "game/shared/stage/entities_manager.h" -#include "game/shared/stage/player.h" - -#if (GAME == GAME_SA2) -#include "game/cheese.h" -#endif - -#include "game/shared/stage/entity.h" -#include "game/shared/stage/mp_event_mgr.h" -#include "game/shared/parameters/characters.h" -#include "game/shared/stage/player.h" -#include "game/shared/stage/rings_scatter.h" -#include "game/sa1/stage/trapped_animals.h" - -#include "constants/sa1/animations.h" -#include "constants/sa1/char_states.h" -#include "constants/sa1/player_transitions.h" -#include "constants/sa1/songs.h" -#include "constants/sa1/zones.h" - -// COLLISION 2 - -bool32 SA2_LABEL(sub_800DD54)(Player *p) -{ - if (p->timerInvincibility > 0 || p->timerInvulnerability > 0) { - return FALSE; - } - - p->timerInvulnerability = PLAYER_INVULNERABLE_DURATION; - - if (p->moveState & MOVESTATE_FACING_LEFT) { - p->qSpeedAirX = +Q(1.5); - } else { - p->qSpeedAirX = -Q(1.5); - } - - p->qSpeedAirY = -Q(3.0); - - if (p->moveState & MOVESTATE_IN_WATER) { - HALVE(p->qSpeedAirY); - HALVE(p->qSpeedAirX); - } - - p->moveState &= ~MOVESTATE_STOOD_ON_OBJ; - p->moveState &= ~MOVESTATE_20; - p->moveState &= ~MOVESTATE_SPIN_ATTACK; - p->moveState &= ~MOVESTATE_FLIP_WITH_MOVE_DIR; - p->moveState |= MOVESTATE_IN_AIR; - p->moveState &= ~MOVESTATE_SPINDASH; - p->moveState &= ~MOVESTATE_100; - -#if (GAME == GAME_SA1) - p->charState = 15; -#else - p->charState = SA2_CHAR_ANIM_20; -#endif - PLAYERFN_CHANGE_SHIFT_OFFSETS(p, 6, 14); - - { -#if !NON_MATCHING && (GAME == GAME_SA1) - u8 *ptr = &p->SA2_LABEL(unk61); - u32 zero = 0; - asm("strb %0, [%1]" ::"r"(zero), "r"(ptr)); - asm("add %0, #1" : "=r"(ptr)); - asm("strb %0, [%1]" ::"r"(zero), "r"(ptr)); -#else - p->SA2_LABEL(unk61) = 0; - p->SA2_LABEL(unk62) = 0; -#endif - } - - if (gGameMode == GAME_MODE_MULTI_PLAYER_COLLECT_RINGS) { -#ifndef NON_MATCHING - register u32 rings asm("r4") = gRingCount; -#else - u32 rings = gRingCount; -#endif - - if (rings > 10) { - rings = 10; - } - - InitScatteringRings(I(p->qWorldX), I(p->qWorldY), rings); - gRingCount -= rings; - - { - RoomEvent_RingLoss *roomEvent = CreateRoomEvent(); - roomEvent->type = ROOMEVENT_TYPE_PLAYER_RING_LOSS; - roomEvent->ringCount = rings; - } - } - - m4aSongNumStart(SE_LIFE_LOST); - - return TRUE; -} - -// TODO: This is close to SA2_LABEL(sub_800DD54). -bool32 SA2_LABEL(sub_800DE44)(Player *p) -{ - if (p->timerInvincibility > 0 || p->timerInvulnerability > 0) { - return FALSE; - } - - p->timerInvulnerability = PLAYER_INVULNERABLE_DURATION; - - if (p->moveState & MOVESTATE_FACING_LEFT) { - p->qSpeedAirX = -Q(1.5); - } else { - p->qSpeedAirX = +Q(1.5); - } - - p->qSpeedAirY = -Q(3.0); - - if (p->moveState & MOVESTATE_IN_WATER) { - HALVE(p->qSpeedAirY); - HALVE(p->qSpeedAirX); - } - - p->moveState &= ~MOVESTATE_STOOD_ON_OBJ; - p->moveState &= ~MOVESTATE_20; - p->moveState &= ~MOVESTATE_SPIN_ATTACK; - p->moveState &= ~MOVESTATE_FLIP_WITH_MOVE_DIR; - p->moveState |= MOVESTATE_IN_AIR; - p->moveState &= ~MOVESTATE_SPINDASH; - p->moveState &= ~MOVESTATE_100; - -#if (GAME == GAME_SA1) - p->charState = 41; -#else - p->charState = SA2_CHAR_ANIM_20; -#endif - PLAYERFN_CHANGE_SHIFT_OFFSETS(p, 6, 14); - - { -#if !NON_MATCHING && (GAME == GAME_SA1) - u8 *ptr = &p->SA2_LABEL(unk61); - u32 zero = 0; - asm("strb %0, [%1]" ::"r"(zero), "r"(ptr)); - asm("add %0, #1" : "=r"(ptr)); - asm("strb %0, [%1]" ::"r"(zero), "r"(ptr)); -#else - p->SA2_LABEL(unk61) = 0; - p->SA2_LABEL(unk62) = 0; -#endif - } - -#if (GAME == GAME_SA2) - p->transition = 9; -#endif - - if (gGameMode == GAME_MODE_MULTI_PLAYER_COLLECT_RINGS) { -#ifndef NON_MATCHING - register u32 rings asm("r4") = gRingCount; -#else - u32 rings = gRingCount; -#endif - - if (rings > 5) { - rings = 5; - } - - InitScatteringRings(I(p->qWorldX), I(p->qWorldY), rings); - gRingCount -= rings; - - { - RoomEvent_RingLoss *roomEvent = CreateRoomEvent(); - roomEvent->type = ROOMEVENT_TYPE_PLAYER_RING_LOSS; - roomEvent->ringCount = rings; - } - } - - m4aSongNumStart(SE_LIFE_LOST); - - return TRUE; -} - -#if (GAME == GAME_SA1) - -// INCOMPLETE! -// (92.41%) https://decomp.me/scratch/9c6nz -NONMATCH("asm/non_matching/game/shared/stage/collision__sub_800C934.inc", - bool32 sub_800C934(Sprite *s, s32 x, s32 y, Rect8 *rectPlayer, u32 param4, Player *p, u32 *moveState)) -{ - bool16 gravityInverted = GRAVITY_IS_INVERTED; - // bottom = sl -#ifndef NON_MATCHING - register s32 middleY asm("sl") = y + ((s->hitboxes[0].b.top + s->hitboxes[0].b.bottom) >> 1); -#else - s32 middleY = y + ((s->hitboxes[0].b.top + s->hitboxes[0].b.bottom) >> 1); -#endif - - if (!HB_COLLISION(x, y, s->hitboxes[0].b, I(p->qWorldX), I(p->qWorldY), (*rectPlayer))) { - return FALSE; - } - - if (!gravityInverted) { - if (I(p->qWorldY) > middleY) { - s32 whole = Q(s->hitboxes[0].b.bottom + y - rectPlayer->top); - p->qWorldY = *(u8 *)&p->qWorldY + whole; - asm(""); - } else { - goto test; - } - } else { - if (I(p->qWorldY) >= middleY) { - test: - if (!gravityInverted) { - p->qWorldY = Q_24_8_FRAC(p->qWorldY) + Q(s->hitboxes[0].b.top + y - rectPlayer->bottom); - } else { - p->qWorldY = Q_24_8_FRAC(p->qWorldY) + Q(s->hitboxes[0].b.bottom + y + rectPlayer->bottom); - } - - if (p->qWorldY < Q(gCamera.minY)) { - p->qWorldY = Q(gCamera.minY); - return FALSE; - } - - if (p->qWorldY >= Q(gCamera.maxY)) { - p->qWorldY = Q(gCamera.maxY); - return FALSE; - } - - if (p->qSpeedAirY < 0) { - return FALSE; - } - - rectPlayer->top = -p->spriteOffsetY; - rectPlayer->bottom = +p->spriteOffsetY; - p->qSpeedAirY = Q(0); - - if (!(p->moveState & MOVESTATE_IN_AIR) && (((p->rotation + 0x20) & 0x40) != 0)) { - p->qSpeedGround = Q(0); - } - - p->moveState |= MOVESTATE_STOOD_ON_OBJ; - *moveState |= MOVESTATE_STOOD_ON_OBJ; - - if (p->character == CHARACTER_KNUCKLES) { - if (p->SA2_LABEL(unk61) == 1 || p->SA2_LABEL(unk61) == 3) { - goto lbl; - } - } - if ((p->character != CHARACTER_AMY) || !(p->moveState & 0x04000000) || (p->SA2_LABEL(unk62) == 0)) { - p->moveState &= ~MOVESTATE_IN_AIR; - } - lbl: - p->stoodObj = s; - - if (param4 == 0) { - if (p->character != CHARACTER_KNUCKLES || (p->SA2_LABEL(unk61) != 1 && p->SA2_LABEL(unk61) != 3)) { - SA2_LABEL(sub_8021BE0)(p); - p->qSpeedGround = p->qSpeedAirX; - } - - p->rotation = 0; - } - return 1; - } else { - // 204 - p->qWorldY = Q_24_8_FRAC(p->qWorldY) + Q(s->hitboxes[0].b.top + y + rectPlayer->top); - } - } - - if (p->qWorldY < Q(gCamera.minY)) { - p->qWorldY = Q(gCamera.minY); - return FALSE; - } - - if (p->qWorldY >= Q(gCamera.maxY)) { - p->qWorldY = Q(gCamera.maxY); - return FALSE; - } - - *moveState |= MOVESTATE_10000; - - if (p->qSpeedAirY <= 0) { - p->qSpeedAirY = 0; - - if (!(p->moveState & MOVESTATE_IN_AIR)) { - if ((p->rotation + 0x20) & 0x40) { - p->qSpeedGround = 0; - } - } - - return TRUE; - } - - return FALSE; -} -END_NONMATCH - -// TODO: Check type of x/y! -// INCOMPLETE! -NONMATCH("asm/non_matching/game/shared/stage/collision__sub_800CBBC.inc", - bool32 sub_800CBBC(Sprite *s, s32 x, s32 y, Rect8 *rectPlayer, u32 UNUSED param4, Player *p, u32 *param6)) -{ - s32 shbLeft = s->hitboxes[0].b.left; - s32 shbRight = s->hitboxes[0].b.right; - s32 shbMiddleH = (shbLeft + shbRight) >> 1; - - if ((((s32)(p->rotation + 0x20) & 0xC0) >> 6) & 0x1) { - return FALSE; - } - // _0800CC04 - - if (((x + shbLeft) > (I(p->qWorldX) + rectPlayer->left)) && (RECT_RIGHT(I(p->qWorldX), rectPlayer) < shbLeft)) { - return FALSE; - } - - PLAYERFN_CHANGE_SHIFT_OFFSETS(p, 6, 14); - - return FALSE; -} -END_NONMATCH - -#endif // (GAME == GAME_SA1) - -// TODO: This might be an inline. -// Code identical to beginning of sub_800C060 -#if (GAME == GAME_SA1) -u32 Coll_Player_Entity_Intersection(Sprite *s, s16 x, s16 y, Player *p) -#elif (GAME == GAME_SA2) -u32 sub_800DF38(Sprite *s, s32 x, s32 y, Player *p) -#endif -{ - // TODO: Could this match with a 'Rect8' instead of s8[4]? - s8 rectPlayer[4] = { -p->spriteOffsetX, -p->spriteOffsetY, +p->spriteOffsetX, +p->spriteOffsetY }; - - return Coll_Player_Entity_RectIntersection(s, x, y, p, (Rect8 *)&rectPlayer); -} - -#if (GAME == GAME_SA1) -u32 sub_800CE98(Sprite *s, s16 x, s16 y, Player *p) -{ - // TODO: Could this match with a 'Rect8' instead of s8[4]? - s8 rectPlayer[4] = { -(p->spriteOffsetX + 5), (1 - p->spriteOffsetY), +(p->spriteOffsetX + 5), +(p->spriteOffsetY - 1) }; - - return Coll_Player_Entity_RectIntersection(s, x, y, p, (Rect8 *)&rectPlayer); -} -#endif diff --git a/src/game/shared/stage/collision_1.c b/src/game/shared/stage/collision_1.c index a8b3e8fa8..bf54057b1 100644 --- a/src/game/shared/stage/collision_1.c +++ b/src/game/shared/stage/collision_1.c @@ -15,6 +15,10 @@ #include "constants/sa2/char_states.h" #endif +#if (GAME == GAME_SA2) +static u32 sub_800CE94(Sprite *s, s32 sx, s32 sy, Rect8 *inRect, Player *p); +#endif + // COLLISION 1 u32 Coll_Player_Platform(Sprite *s, CamCoord x, CamCoord y, Player *p) @@ -125,7 +129,7 @@ u32 Coll_Player_Interactable(Sprite *s, s32 sx, s32 sy, Player *p) // Looks like each byte in the result is one value // TODO: Remove gotos -u32 sub_800CE94(Sprite *s, s32 sx, s32 sy, Rect8 *inRect, Player *p) +static u32 sub_800CE94(Sprite *s, s32 sx, s32 sy, Rect8 *inRect, Player *p) { s32 px = I(p->qWorldX); s32 py = I(p->qWorldY); diff --git a/src/game/shared/stage/collision_2.c b/src/game/shared/stage/collision_2.c index a322248e8..4f1fcf2c7 100644 --- a/src/game/shared/stage/collision_2.c +++ b/src/game/shared/stage/collision_2.c @@ -3,24 +3,24 @@ #include "sprite.h" #include "lib/m4a/m4a.h" #include "game/globals.h" -#include "game/shared/stage/collision.h" -#include "game/shared/stage/dust_cloud.h" -#include "game/shared/stage/entities_manager.h" -#include "game/shared/stage/player.h" -#include "game/sa2/stage/cheese.h" -#include "game/shared/stage/entity.h" +#include "game/shared/stage/collision.h" +#include "game/shared/stage/player.h" #include "game/shared/stage/mp_event_mgr.h" #include "game/shared/stage/rings_scatter.h" -#include "game/sa2/stage/trapped_animals.h" +#if (GAME == GAME_SA1) +#include "constants/sa1/animations.h" +#include "constants/sa1/songs.h" +#elif (GAME == GAME_SA2) #include "constants/sa2/animations.h" #include "constants/sa2/player_transitions.h" #include "constants/sa2/songs.h" +#endif // COLLISION 2 -bool32 sub_800DD54(Player *p) +bool32 SA2_LABEL(sub_800DD54)(Player *p) { if (p->timerInvincibility > 0 || p->timerInvulnerability > 0) { return FALSE; @@ -51,13 +51,29 @@ bool32 sub_800DD54(Player *p) p->moveState &= ~MOVESTATE_SPINDASH; p->moveState &= ~MOVESTATE_100; +#if (GAME == GAME_SA1) + p->charState = 15; +#else p->charState = SA2_CHAR_ANIM_20; +#endif PLAYERFN_CHANGE_SHIFT_OFFSETS(p, 6, 14); - p->SA2_LABEL(unk61) = 0; - p->SA2_LABEL(unk62) = 0; + { +#if (GAME == GAME_SA1) && !defined(NON_MATCHING) + u8 *ptr = &p->SA2_LABEL(unk61); + u32 zero = 0; + asm("strb %0, [%1]" ::"r"(zero), "r"(ptr)); + asm("add %0, #1" : "=r"(ptr)); + asm("strb %0, [%1]" ::"r"(zero), "r"(ptr)); +#else + p->SA2_LABEL(unk61) = 0; + p->SA2_LABEL(unk62) = 0; +#endif + } +#if (GAME == GAME_SA2) p->transition = 9; +#endif if (gGameMode == GAME_MODE_MULTI_PLAYER_COLLECT_RINGS) { RoomEvent_RingLoss *roomEvent; @@ -85,7 +101,8 @@ bool32 sub_800DD54(Player *p) } #ifndef COLLECT_RINGS_ROM -bool32 sub_800DE44(Player *p) +// TODO: is this sharing macros with SA2_LABEL(sub_800DD54) +bool32 SA2_LABEL(sub_800DE44)(Player *p) { if (p->timerInvincibility > 0 || p->timerInvulnerability > 0) { return FALSE; @@ -114,13 +131,29 @@ bool32 sub_800DE44(Player *p) p->moveState &= ~MOVESTATE_SPINDASH; p->moveState &= ~MOVESTATE_100; +#if (GAME == GAME_SA1) + p->charState = 41; +#else p->charState = SA2_CHAR_ANIM_20; +#endif PLAYERFN_CHANGE_SHIFT_OFFSETS(p, 6, 14); - p->SA2_LABEL(unk61) = 0; - p->SA2_LABEL(unk62) = 0; + { +#if !NON_MATCHING && (GAME == GAME_SA1) + u8 *ptr = &p->SA2_LABEL(unk61); + u32 zero = 0; + asm("strb %0, [%1]" ::"r"(zero), "r"(ptr)); + asm("add %0, #1" : "=r"(ptr)); + asm("strb %0, [%1]" ::"r"(zero), "r"(ptr)); +#else + p->SA2_LABEL(unk61) = 0; + p->SA2_LABEL(unk62) = 0; +#endif + } +#if (GAME == GAME_SA2) p->transition = 9; +#endif if (gGameMode == GAME_MODE_MULTI_PLAYER_COLLECT_RINGS) { RoomEvent_RingLoss *roomEvent; @@ -147,10 +180,159 @@ bool32 sub_800DE44(Player *p) return TRUE; } -u32 Coll_Player_Entity_Intersection(Sprite *s, s32 x, s32 y, Player *p) +#if (GAME == GAME_SA1) +// INCOMPLETE! +// (92.41%) https://decomp.me/scratch/9c6nz +NONMATCH("asm/non_matching/game/shared/stage/collision__sub_800C934.inc", + bool32 sub_800C934(Sprite *s, s32 x, s32 y, Rect8 *rectPlayer, u32 param4, Player *p, u32 *moveState)) +{ + bool16 gravityInverted = GRAVITY_IS_INVERTED; + // bottom = sl +#ifndef NON_MATCHING + register s32 middleY asm("sl") = y + ((s->hitboxes[0].b.top + s->hitboxes[0].b.bottom) >> 1); +#else + s32 middleY = y + ((s->hitboxes[0].b.top + s->hitboxes[0].b.bottom) >> 1); +#endif + + if (!HB_COLLISION(x, y, s->hitboxes[0].b, I(p->qWorldX), I(p->qWorldY), (*rectPlayer))) { + return FALSE; + } + + if (!gravityInverted) { + if (I(p->qWorldY) > middleY) { + s32 whole = Q(s->hitboxes[0].b.bottom + y - rectPlayer->top); + p->qWorldY = *(u8 *)&p->qWorldY + whole; + asm(""); + } else { + goto test; + } + } else { + if (I(p->qWorldY) >= middleY) { + test: + if (!gravityInverted) { + p->qWorldY = Q_24_8_FRAC(p->qWorldY) + Q(s->hitboxes[0].b.top + y - rectPlayer->bottom); + } else { + p->qWorldY = Q_24_8_FRAC(p->qWorldY) + Q(s->hitboxes[0].b.bottom + y + rectPlayer->bottom); + } + + if (p->qWorldY < Q(gCamera.minY)) { + p->qWorldY = Q(gCamera.minY); + return FALSE; + } + + if (p->qWorldY >= Q(gCamera.maxY)) { + p->qWorldY = Q(gCamera.maxY); + return FALSE; + } + + if (p->qSpeedAirY < 0) { + return FALSE; + } + + rectPlayer->top = -p->spriteOffsetY; + rectPlayer->bottom = +p->spriteOffsetY; + p->qSpeedAirY = Q(0); + + if (!(p->moveState & MOVESTATE_IN_AIR) && (((p->rotation + 0x20) & 0x40) != 0)) { + p->qSpeedGround = Q(0); + } + + p->moveState |= MOVESTATE_STOOD_ON_OBJ; + *moveState |= MOVESTATE_STOOD_ON_OBJ; + + if (p->character == CHARACTER_KNUCKLES) { + if (p->SA2_LABEL(unk61) == 1 || p->SA2_LABEL(unk61) == 3) { + goto lbl; + } + } + if ((p->character != CHARACTER_AMY) || !(p->moveState & 0x04000000) || (p->SA2_LABEL(unk62) == 0)) { + p->moveState &= ~MOVESTATE_IN_AIR; + } + lbl: + p->stoodObj = s; + + if (param4 == 0) { + if (p->character != CHARACTER_KNUCKLES || (p->SA2_LABEL(unk61) != 1 && p->SA2_LABEL(unk61) != 3)) { + SA2_LABEL(sub_8021BE0)(p); + p->qSpeedGround = p->qSpeedAirX; + } + + p->rotation = 0; + } + return 1; + } else { + // 204 + p->qWorldY = Q_24_8_FRAC(p->qWorldY) + Q(s->hitboxes[0].b.top + y + rectPlayer->top); + } + } + + if (p->qWorldY < Q(gCamera.minY)) { + p->qWorldY = Q(gCamera.minY); + return FALSE; + } + + if (p->qWorldY >= Q(gCamera.maxY)) { + p->qWorldY = Q(gCamera.maxY); + return FALSE; + } + + *moveState |= MOVESTATE_10000; + + if (p->qSpeedAirY <= 0) { + p->qSpeedAirY = 0; + + if (!(p->moveState & MOVESTATE_IN_AIR)) { + if ((p->rotation + 0x20) & 0x40) { + p->qSpeedGround = 0; + } + } + + return TRUE; + } + + return FALSE; +} +END_NONMATCH + +// TODO: Check type of x/y! +// INCOMPLETE! +NONMATCH("asm/non_matching/game/shared/stage/collision__sub_800CBBC.inc", + bool32 sub_800CBBC(Sprite *s, s32 x, s32 y, Rect8 *rectPlayer, u32 UNUSED param4, Player *p, u32 *param6)) +{ + s32 shbLeft = s->hitboxes[0].b.left; + s32 shbRight = s->hitboxes[0].b.right; + s32 shbMiddleH = (shbLeft + shbRight) >> 1; + + if ((((s32)(p->rotation + 0x20) & 0xC0) >> 6) & 0x1) { + return FALSE; + } + // _0800CC04 + + if (((x + shbLeft) > (I(p->qWorldX) + rectPlayer->left)) && (RECT_RIGHT(I(p->qWorldX), rectPlayer) < shbLeft)) { + return FALSE; + } + + PLAYERFN_CHANGE_SHIFT_OFFSETS(p, 6, 14); + + return FALSE; +} +END_NONMATCH +#endif // (GAME == GAME_SA1) + +u32 Coll_Player_Entity_Intersection(Sprite *s, CamCoord x, CamCoord y, Player *p) { s8 rectPlayer[4] = { -p->spriteOffsetX, -p->spriteOffsetY, +p->spriteOffsetX, +p->spriteOffsetY }; return Coll_Player_Entity_RectIntersection(s, x, y, p, (Rect8 *)&rectPlayer); } #endif + +#if (GAME == GAME_SA1) +u32 sub_800CE98(Sprite *s, CamCoord x, CamCoord y, Player *p) +{ + // TODO: Could this match with a 'Rect8' instead of s8[4]? + s8 rectPlayer[4] = { -(p->spriteOffsetX + 5), (1 - p->spriteOffsetY), +(p->spriteOffsetX + 5), +(p->spriteOffsetY - 1) }; + + return Coll_Player_Entity_RectIntersection(s, x, y, p, (Rect8 *)&rectPlayer); +} +#endif