From 8dbb75fb78b892d0cff497412c5e2f34e0820d31 Mon Sep 17 00:00:00 2001 From: Josh Schreuder <681706+JoshSchreuder@users.noreply.github.com> Date: Sat, 2 Nov 2024 06:38:44 +1100 Subject: [PATCH] Decompile `no0` main Ouija Table function (#1859) Match on both PSX: https://decomp.me/scratch/A79x5 PSP: https://decomp.me/scratch/HJrWp The functions directly after this are related to the sub-entities such as vase and beaker I believe, so I'll decompile those next. Possible this might lead to changes in the extensions I've added here. Think this was my first time adding new extension(s) so let me know if something's wrong there Once all that's done I'll split into a separate Ouija Table file with all the related code. --- config/symbols.us.stno0.txt | 1 + include/entity.h | 21 ++++++ src/st/no0/5BDCC.c | 130 +++++++++++++++++++++++++++++++++++- src/st/no0/no0.h | 1 + 4 files changed, 151 insertions(+), 2 deletions(-) diff --git a/config/symbols.us.stno0.txt b/config/symbols.us.stno0.txt index 2b8e6403b..a7b291003 100644 --- a/config/symbols.us.stno0.txt +++ b/config/symbols.us.stno0.txt @@ -189,6 +189,7 @@ func_801C4550 = 0x801DB470; EntityAxeKnight = 0x801DB4DC; EntityAxeKnightRotateAxe = 0x801DBBE0; EntityAxeKnightThrowingAxe = 0x801DBC38; +EntityOuijaTable = 0x801DBDCC; SkeletonAttackCheck = 0x801DCAB0; EntitySkeleton = 0x801DCB48; EntitySkeletonPieces = 0x801DD018; diff --git a/include/entity.h b/include/entity.h index 790ee49a5..912ecf898 100644 --- a/include/entity.h +++ b/include/entity.h @@ -1986,6 +1986,25 @@ typedef struct { /* 0xAE */ s16 unkAE; } ET_BackgroundVortex; +typedef struct { + /* 0x7C */ s32 : 32; + /* 0x80 */ s16 attackTimer; + /* 0x82 */ s16 : 16; + /* 0x84 */ s32 : 32; + /* 0x88 */ s32 : 32; + /* 0x8C */ s32 : 32; + /* 0x90 */ s32 unk90; +} ET_OuijaTable; + +typedef struct { + /* 0x7C */ s32 : 32; + /* 0x80 */ s32 : 32; + /* 0x84 */ s32 spawned; + /* 0x88 */ struct Entity* parent; + /* 0x8C */ s32 : 32; + /* 0x90 */ s32 isThrown; +} ET_OuijaTableContents; + // ====== RIC ENTITIES ====== // ========================== @@ -2166,6 +2185,8 @@ typedef union { // offset=0x7C ET_ClockTower clockTower; ET_BackgroundVortex bgVortex; ET_MedusaUnk1A medusaUnk1A; + ET_OuijaTable ouijaTable; + ET_OuijaTableContents ouijaTableContents; } Ext; #define SYNC_FIELD(struct1, struct2, field) \ diff --git a/src/st/no0/5BDCC.c b/src/st/no0/5BDCC.c index d4e9268f8..0dfcbc022 100644 --- a/src/st/no0/5BDCC.c +++ b/src/st/no0/5BDCC.c @@ -1,8 +1,134 @@ // SPDX-License-Identifier: AGPL-3.0-or-later #include "common.h" -#include "game.h" +#include "no0.h" -INCLUDE_ASM("st/no0/nonmatchings/5BDCC", func_us_801DBDCC); +#define VASE self + 1 +#define BEAKER self + 2 +#define WALKING_TABLE self + 3 + +extern u16 D_us_80180C14[]; +extern s16 D_us_801825CC[]; +extern u16 D_us_801825D4[]; +extern u8 D_us_801825F4[]; + +typedef enum { + /* 0 */ OUIJA_TABLE_INIT, + /* 1 */ OUIJA_TABLE_INIT_SUBENTITIES, + /* 2 */ OUIJA_TABLE_COME_ALIVE, + /* 3 */ OUIJA_TABLE_ATTACK, + /* 4 */ OUIJA_TABLE_UNUSED, + /* 255 */ OUIJA_TABLE_DEBUG = 255, +} OuijaTableSteps; + +// Main Ouija Table entity +void EntityOuijaTable(Entity* self) { + Entity* otherEntity; + + if (self->flags & FLAG_DEAD) { + otherEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (otherEntity != NULL) { + CreateEntityFromEntity(E_EXPLOSION, self, otherEntity); + otherEntity->params = 1; + } + PlaySfxPositional(SFX_STUTTER_FIREBALL); + // Destroy the spinning objects on the table + otherEntity = VASE; + otherEntity->flags |= FLAG_UNK_2000; + + otherEntity = BEAKER; + otherEntity->flags |= FLAG_UNK_2000; + DestroyEntity(self); + return; + } + + switch (self->step) { + case OUIJA_TABLE_INIT: + InitializeEntity(D_us_80180C14); + self->animCurFrame = 5; + self->hitboxOffY = 2; + return; + case OUIJA_TABLE_INIT_SUBENTITIES: + if (UnkCollisionFunc3(D_us_801825D4) & 1) { + // Spawn objects on the table + otherEntity = VASE; + CreateEntityFromEntity(E_OUIJA_TABLE_COMPONENT, self, otherEntity); + otherEntity->params = 0; + otherEntity->ext.ouijaTableContents.parent = self; + otherEntity->posX.i.hi -= 4; + otherEntity->posY.i.hi -= 16; + + otherEntity = BEAKER; + CreateEntityFromEntity(E_OUIJA_TABLE_COMPONENT, self, otherEntity); + otherEntity->params = 1; + otherEntity->ext.ouijaTableContents.parent = self; + otherEntity->posX.i.hi += 2; + otherEntity->posY.i.hi -= 20; + + otherEntity = WALKING_TABLE; + CreateEntityFromEntity(E_OUIJA_TABLE_COMPONENT, self, otherEntity); + otherEntity->params = 2; + otherEntity->ext.ouijaTableContents.parent = self; + + if (self->params) { + otherEntity->posX.i.hi += 24; + otherEntity->facingLeft = 1; + } else { + otherEntity->posX.i.hi -= 24; + } +#ifndef VERSION_PSP + // Looks like a coding error + otherEntity->posY.i.hi = otherEntity->posY.i.hi; +#endif + self->step++; + } + break; + case OUIJA_TABLE_COME_ALIVE: + // When player approaches, spring to life + if ((GetDistanceToPlayerX() < 80) && (GetDistanceToPlayerY() < 64)) { + self->facingLeft = (GetSideToPlayer() & 1) ^ 1; + otherEntity = BEAKER; + otherEntity->ext.ouijaTableContents.spawned = true; + + otherEntity = VASE; + otherEntity->ext.ouijaTableContents.spawned = true; + SetStep(3); + } + break; + case OUIJA_TABLE_ATTACK: + if (!self->step_s) { + self->ext.ouijaTable.attackTimer = 128; + self->step_s += 1; + } + if (AnimateEntity(D_us_801825F4, self) == 0) { + self->facingLeft = (GetSideToPlayer() & 1) ^ 1; + } + UnkCollisionFunc2(D_us_801825CC); + + if (self->facingLeft) { + self->velocityX = FIX(0.5); + } else { + self->velocityX = FIX(-0.5); + } + + if (!(--self->ext.ouijaTable.attackTimer)) { + self->ext.ouijaTable.attackTimer = 192; + // Throw out one of the objects on the table + if (self->ext.ouijaTable.unk90 != 0) { + otherEntity = VASE; + } else { + otherEntity = BEAKER; + } + otherEntity->ext.ouijaTableContents.isThrown = true; + // Alternate between throwing vase and beaker + self->ext.ouijaTable.unk90 ^= 1; + } + break; + case OUIJA_TABLE_UNUSED: + break; + case OUIJA_TABLE_DEBUG: +#include "../pad2_anim_debug.h" + } +} INCLUDE_ASM("st/no0/nonmatchings/5BDCC", func_us_801DC194); diff --git a/src/st/no0/no0.h b/src/st/no0/no0.h index 5f1e1015e..38fbe69e4 100644 --- a/src/st/no0/no0.h +++ b/src/st/no0/no0.h @@ -34,6 +34,7 @@ typedef enum EntityIDs { /* 0x3C */ E_SLINGER_PIECES, /* 0x48 */ E_AXE_KNIGHT_AXE = 0x48, /* 0x49 */ E_WARG_EXP_OPAQUE, + /* 0x4B */ E_OUIJA_TABLE_COMPONENT = 0x4B, /* 0x4D */ E_SKELETON = 0x4D, /* 0x4E */ E_SKELETON_THROWN_BONE, /* 0x4F */ E_SKELETON_PIECES,