From 3e73b0965ea6e36ba5015f32c84bebe5aedce39a Mon Sep 17 00:00:00 2001 From: ProjectOblivion <31639802+ProjectOblivion@users.noreply.github.com> Date: Sat, 22 Feb 2025 11:59:51 -0500 Subject: [PATCH] Decompiled LIB func_us_801AFE0C/func_psp_0925D8D8 (#2243) func_us_801AFE0C/func_psp_0925D8D8 PSX: https://decomp.me/scratch/L5A5D PSP: https://decomp.me/scratch/ydeqP Code is shared but not merged. Added PAD_NONE (value of 0) in game.h macros to make this function a little more self documenting. Also fixed a tiny error with where I put castle flag offset 0x29 previously. --- config/symbols.pspeu.stlib.txt | 5 +- config/symbols.pspeu.txt | 4 + include/castle_flags.h | 2 +- include/game.h | 85 +++++++------ include/sfx.h | 1 + src/st/lib/unk_2FA80.c | 222 +++++++++++++++++++++++++++++++- src/st/lib_psp/unk_25CD0.c | 224 ++++++++++++++++++++++++++++++++- 7 files changed, 497 insertions(+), 46 deletions(-) diff --git a/config/symbols.pspeu.stlib.txt b/config/symbols.pspeu.stlib.txt index 046bc2d2d5..4f581d1f05 100644 --- a/config/symbols.pspeu.stlib.txt +++ b/config/symbols.pspeu.stlib.txt @@ -1,6 +1,3 @@ -D_80097910 = 0x091CE5A0; -D_80097928 = 0x091CE5B0; -D_80076E98 = 0x091E5140; CreateEntityFromLayout = 0x09237700; CreateEntityWhenInVerticalRange = 0x09237820; CreateEntityWhenInHorizontalRange = 0x092379B8; @@ -120,6 +117,7 @@ CutsceneRun = 0x0925AFE8; CutsceneSkip = 0x0925B380; LIB_EntityCutscene = 0x0925B470; LIB_EntityBackgroundBlock = 0x0925D350; +func_us_801AFE0C = 0x0925D8D8; EntityLibrarianChair = 0x0925E018; PlayerIsWithinHitbox = 0x0926CE18; EntityLockCamera = 0x0926CF18; @@ -143,6 +141,7 @@ LIB_RedDoorTiles = 0x09275F08; LIB_EntityUpdates = 0x09275F18; g_EInitObtainable = 0x09276058; g_EInitParticle = 0x09276068; +D_us_80180824 = 0x09276078; g_EInitInteractable = 0x09276088; g_EInitUnkId13 = 0x09276098; g_EInitLockCamera = 0x092760A8; diff --git a/config/symbols.pspeu.txt b/config/symbols.pspeu.txt index 9a920f2c47..f6cf236f45 100644 --- a/config/symbols.pspeu.txt +++ b/config/symbols.pspeu.txt @@ -63,6 +63,8 @@ D_8017A000 = 0x08D27C40; D_8017D000 = 0x08D2AC40; DestroyEntitiesFromIndex = 0x0913E838; g_CutsceneHasControl = 0x091CE598; +D_80097910 = 0x091CE5A0; +D_80097928 = 0x091CE5B0; g_StageId = 0x091CE5B8; g_IsUsingCd = 0x091CE5C8; g_LoadFile = 0x091CE5D8; @@ -104,6 +106,8 @@ PLAYER_facingLeft = 0x091E1694; PLAYER_zPriority = 0x091E16A4; PLAYER_step = 0x91E16AC; PLAYER_step_s = 0x91E16AE; +D_80073510 = 0x091E17B8; +D_80076E98 = 0x091E5140; g_Pix = 0x091ED5F8; g_Clut = 0x091F5DF8; g_Clut_2800 = 0x091F85F8; diff --git a/include/castle_flags.h b/include/castle_flags.h index fc7c6481bd..abd0176184 100644 --- a/include/castle_flags.h +++ b/include/castle_flags.h @@ -33,10 +33,10 @@ typedef enum { /* 0x21 */ NO2_SECRET_CEILING_OPEN = 33, /* 0x22 */ NO2_STAGE_FLAG = 34, /* 0x28 */ RNO2_SECRET_WALL_OPEN = 40, // See 0x20 note + /* 0x29 */ RNO2_SECRET_FLOOR_OPEN = 41, /* 0x30 */ NO4_TO_NP3_SHORTCUT = 48, /* 0x31 */ NO0_TO_NP3_SHORTCUT = 49, /* 0x32 */ WRP_TO_NP3_SHORTCUT = 50, - /* 0x29 */ RNO2_SECRET_FLOOR_OPEN = 41, // Used for tracking the steps to unlock the jewel sword room // Bit 1 is set when the left side rocks are destroyed diff --git a/include/game.h b/include/game.h index 17da7bae6a..10b9df3886 100644 --- a/include/game.h +++ b/include/game.h @@ -143,47 +143,54 @@ typedef enum { #define DISP_STAGE_NEXT_X DISP_STAGE_W #endif -#define BUTTON_COUNT 8 -#define PAD_COUNT 2 - -#if !defined(VERSION_PSP) -#define PAD_L2 0x0001 -#define PAD_R2 0x0002 -#define PAD_L1 0x0004 -#define PAD_R1 0x0008 -#define PAD_TRIANGLE 0x0010 -#define PAD_CIRCLE 0x0020 -#define PAD_CROSS 0x0040 -#define PAD_SQUARE 0x0080 -#define PAD_SELECT 0x0100 -#define PAD_L3 0x0200 -#define PAD_R3 0x0400 -#define PAD_START 0x0800 -#define PAD_UP 0x1000 -#define PAD_RIGHT 0x2000 -#define PAD_DOWN 0x4000 -#define PAD_LEFT 0x8000 - +// PSP buttons use same order as PSX, rather than by +// value for logical conistency between the two +typedef enum { + BUTTON_COUNT = 8, + PAD_COUNT = 2, + PAD_NONE = 0x0000, +// R3 button on a DS3 controller attached to PSP +// for debug mode may not be captured in these +#ifdef VERSION_PSP + PAD_L2 = 0x0002, + PAD_R2 = 0x0400, + PAD_L1 = 0x0100, + PAD_R1 = 0x0200, + PAD_TRIANGLE = 0x1000, + PAD_CIRCLE = 0x2000, + PAD_CROSS = 0x4000, + PAD_SQUARE = 0x8000, + PAD_SELECT = 0x0001, + PAD_L3 = 0x0000, // No L3 on PSP + PAD_R3 = 0x0000, // No R3 on PSP + PAD_START = 0x0008, + PAD_UP = 0x0010, + PAD_RIGHT = 0x0020, + PAD_DOWN = 0x0040, + PAD_LEFT = 0x0080, #else -#define PAD_L2 0x0002 -#define PAD_R2 0x0400 -#define PAD_L1 0x0100 -#define PAD_R1 0x0200 -#define PAD_TRIANGLE 0x1000 -#define PAD_CIRCLE 0x2000 -#define PAD_CROSS 0x4000 -#define PAD_SQUARE 0x8000 -#define PAD_SELECT 0x0001 -#define PAD_START 0x0008 -#define PAD_UP 0x0010 -#define PAD_RIGHT 0x0020 -#define PAD_DOWN 0x0040 -#define PAD_LEFT 0x0080 + PAD_L2 = 0x0001, + PAD_R2 = 0x0002, + PAD_L1 = 0x0004, + PAD_R1 = 0x0008, + PAD_TRIANGLE = 0x0010, + PAD_CIRCLE = 0x0020, + PAD_CROSS = 0x0040, + PAD_SQUARE = 0x0080, + PAD_SELECT = 0x0100, + PAD_L3 = 0x0200, + PAD_R3 = 0x0400, + PAD_START = 0x0800, + PAD_UP = 0x1000, + PAD_RIGHT = 0x2000, + PAD_DOWN = 0x4000, + PAD_LEFT = 0x8000, #endif - -// Game Buttons unofficially refers to buttons used in playing the game. -// Direction, action and shoulder buttons. Any button except start or select. -#define GAMEBUTTONS (~(PAD_START | PAD_SELECT)) + PAD_SIM_UNK20000 = 0x20000, + // Game Buttons unofficially refers to buttons used in playing the game. + // Any button except start or select. + GAMEBUTTONS = (~(PAD_START | PAD_SELECT)), +} PlayerPad; #define MAX_PRIM_COUNT 0x500 #define MAX_PRIM_ALLOC_COUNT 0x400 diff --git a/include/sfx.h b/include/sfx.h index e0acaf1298..49e9540ffb 100644 --- a/include/sfx.h +++ b/include/sfx.h @@ -66,6 +66,7 @@ enum SfxModes { #define CD_SOUND_COMMAND_FADE_OUT_1 3 #define CD_SOUND_COMMAND_START_XA 4 #define CD_SOUND_COMMAND_6 6 +#define CD_SOUND_COMMAND_7 7 #define CD_SOUND_COMMAND_8 8 #define CD_SOUND_COMMAND_10 10 #define CD_SOUND_COMMAND_12 12 diff --git a/src/st/lib/unk_2FA80.c b/src/st/lib/unk_2FA80.c index aa2065f033..e02909ebb6 100644 --- a/src/st/lib/unk_2FA80.c +++ b/src/st/lib/unk_2FA80.c @@ -287,7 +287,227 @@ INCLUDE_RODATA("st/lib/nonmatchings/unk_2FA80", D_us_801ACD3C); INCLUDE_RODATA("st/lib/nonmatchings/unk_2FA80", D_us_801ACD60); -INCLUDE_ASM("st/lib/nonmatchings/unk_2FA80", func_us_801AFE0C); +extern s8 D_80073510; +extern u16 D_us_80180824; + +// This is probably EntityLibrarian, but I don't know for sure +void func_us_801AFE0C(Entity* self) { + Tilemap* tilemap = &g_Tilemap; + Entity* entity = g_Entities; + + switch (self->step) { + case 0: +#ifdef VERSION_PSP + func_psp_0925D4D0(); +#endif + InitializeEntity(&D_us_80180824); + if (entity->posX.i.hi < 0x100) { +// I expect these two sounds to be the same, but 0x202 has not yet been defined. +// This leads me to think that the macro that has been defined for sfx 0x302 +// is only accurate for PSX and does not align with the sfx for PSP here. +#ifdef VERSION_PSP + g_api.PlaySfx(0x302); +#else + g_api.PlaySfx(0x202); +#endif + } + if (g_CastleFlags[MET_LIBRARIAN]) { + self->step = 8; + break; + } +#ifdef VERSION_PSP + g_Player.padSim = PAD_LEFT | PAD_SIM_UNK20000; + g_Player.D_80072EFC = 1; +#endif + break; + case 1: + D_80073510 = 1; + g_PauseAllowed = false; + g_unkGraphicsStruct.pauseEnemies = true; + g_Player.padSim = PAD_LEFT; + g_Player.D_80072EFC = 1; + if (g_Player.status & PLAYER_STATUS_BAT_FORM) { + g_Player.padSim = PAD_R1; + } else if (g_Player.status & PLAYER_STATUS_MIST_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_NONE; +#else + g_Player.padSim = PAD_L1; +#endif + } else if (g_Player.status & PLAYER_STATUS_WOLF_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_L1; +#else + g_Player.padSim = PAD_R2; +#endif + } + g_Player.D_80072EFC = 1; + SetStep(2); + break; + case 2: + if (entity->posX.i.hi > 0xE8) { + if (g_Player.status & PLAYER_STATUS_TRANSFORM) { + g_Player.padSim = PAD_NONE; + if (g_Timer & 1) { + if (g_Player.status & PLAYER_STATUS_BAT_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_R1 | PAD_SIM_UNK20000; +#else + g_Player.padSim = PAD_R1; +#endif + } else if (g_Player.status & PLAYER_STATUS_MIST_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_NONE | PAD_SIM_UNK20000; +#else + g_Player.padSim = PAD_L1; +#endif + } else if (g_Player.status & PLAYER_STATUS_WOLF_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_L1 | PAD_SIM_UNK20000; +#else + g_Player.padSim = PAD_R2; +#endif + } + } + } else { + g_Player.padSim = PAD_LEFT; + } + } else { + g_CutsceneFlags |= 1; + g_Player.padSim = PAD_NONE; + entity->posX.i.hi = 0xE8; + self->step++; + } + g_Player.D_80072EFC = 1; + break; + case 3: + if (g_CutsceneFlags & 0x40) { + if (entity->posX.i.hi > 0x74) { + D_80073510 = 1; + g_Player.padSim = PAD_LEFT; + } else { + entity->posX.i.hi = 0x74; + g_Player.padSim = PAD_NONE; + self->step++; + } + } else { + entity->posX.i.hi = 0xE8; + } + g_Player.D_80072EFC = 1; + break; + case 4: + g_Player.padSim = PAD_NONE | PAD_SIM_UNK20000; + g_Player.D_80072EFC = 1; + self->step++; + break; + case 5: + g_CastleFlags[MET_LIBRARIAN] = 1; + g_api.TimeAttackController( + TIMEATTACK_EVENT_MEET_MASTER_LIBRARIAN, TIMEATTACK_SET_RECORD); + g_Player.D_80072EFC = 1; + self->step++; + /* fallthrough */ + case 6: + if (g_CutsceneFlags & 0x100) { + g_CutsceneFlags |= 0x2000; + self->step = 0x10; + break; + } + entity->posX.i.hi = 0x74; + break; + case 8: + self->step++; + /* fallthrough */ + case 9: + if (entity->posX.i.hi > 0xFF) { + g_api.PlaySfx(CD_SOUND_COMMAND_7); + DestroyEntity(self); + break; + } + if (entity->posX.i.hi < 0x75) { + switch (self->step_s) { + case 0: + D_80073510 = 1; + g_PauseAllowed = false; + g_unkGraphicsStruct.pauseEnemies = true; + g_Player.padSim = PAD_NONE; + g_Player.D_80072EFC = 0x10; + self->step_s++; + g_CutsceneFlags |= 1; + break; + case 1: + if (g_Player.status & PLAYER_STATUS_TRANSFORM) { + g_Player.padSim = PAD_NONE; + if (g_Timer & 1) { + if (g_Player.status & PLAYER_STATUS_BAT_FORM) { + g_Player.padSim = PAD_R1; + } else if (g_Player.status & PLAYER_STATUS_MIST_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_NONE; +#else + g_Player.padSim = PAD_L1; +#endif + } else if (g_Player.status & PLAYER_STATUS_WOLF_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_L1; +#else + g_Player.padSim = PAD_R2; +#endif + } + } + } else { + g_Player.padSim = PAD_LEFT; + self->step_s++; + } + g_Player.D_80072EFC = 1; + break; + case 2: + g_Player.padSim = PAD_NONE; + g_Player.D_80072EFC = 0x80; + SetStep(10); + break; + } + entity->posX.i.hi = 0x74; + } + break; + case 10: + if (!g_Player.D_80072EFC && (g_Player.pl_vram_flag & 1)) { + g_Player.padSim = PAD_NONE | PAD_SIM_UNK20000; + g_Player.D_80072EFC = 1; + self->step++; + } + entity->posX.i.hi = 0x74; + break; + case 11: + g_Player.padSim = PAD_NONE | PAD_SIM_UNK20000; + g_Player.D_80072EFC = 1; + if (g_CutsceneFlags & 0x100) { + g_CutsceneFlags |= 0x2000; + self->step = 0x10; + } + break; + case 16: +#ifdef VERSION_PSP + g_PauseAllowed = false; +#endif + g_Player.D_80072EFC = 0x20; + g_Player.padSim = PAD_RIGHT; + D_80097928 = 1; + self->step++; + break; + case 17: +#ifdef VERSION_PSP + g_PauseAllowed = false; +#endif + if (!g_Player.D_80072EFC) { +#ifdef VERSION_PSP + g_PauseAllowed = true; +#endif + SetStep(9); + } + break; + } +} extern u8 D_us_801811FC[]; extern u8 D_us_80181204[]; diff --git a/src/st/lib_psp/unk_25CD0.c b/src/st/lib_psp/unk_25CD0.c index 8ad05a03f0..5887ce4d24 100644 --- a/src/st/lib_psp/unk_25CD0.c +++ b/src/st/lib_psp/unk_25CD0.c @@ -1,11 +1,231 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -#include "../../st/lib/lib.h" +#include "../lib/lib.h" INCLUDE_ASM("st/lib_psp/psp/lib_psp/unk_25CD0", func_psp_0925D430); INCLUDE_ASM("st/lib_psp/psp/lib_psp/unk_25CD0", func_psp_0925D4D0); -INCLUDE_ASM("st/lib_psp/psp/lib_psp/unk_25CD0", func_psp_0925D8D8); +extern s8 D_80073510; +extern u16 D_us_80180824; + +// This is probably EntityLibrarian, but I don't know for sure +void func_us_801AFE0C(Entity* self) { + Tilemap* tilemap = &g_Tilemap; + Entity* entity = g_Entities; + + switch (self->step) { + case 0: +#ifdef VERSION_PSP + func_psp_0925D4D0(); +#endif + InitializeEntity(&D_us_80180824); + if (entity->posX.i.hi < 0x100) { +// I expect these two sounds to be the same, but 0x202 has not yet been defined. +// This leads me to think that the macro that has been defined for sfx 0x302 +// is only accurate for PSX and does not align with the sfx for PSP here. +#ifdef VERSION_PSP + g_api.PlaySfx(0x302); +#else + g_api.PlaySfx(0x202); +#endif + } + if (g_CastleFlags[MET_LIBRARIAN]) { + self->step = 8; + break; + } +#ifdef VERSION_PSP + g_Player.padSim = PAD_LEFT | PAD_SIM_UNK20000; + g_Player.D_80072EFC = 1; +#endif + break; + case 1: + D_80073510 = 1; + g_PauseAllowed = false; + g_unkGraphicsStruct.pauseEnemies = true; + g_Player.padSim = PAD_LEFT; + g_Player.D_80072EFC = 1; + if (g_Player.status & PLAYER_STATUS_BAT_FORM) { + g_Player.padSim = PAD_R1; + } else if (g_Player.status & PLAYER_STATUS_MIST_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_NONE; +#else + g_Player.padSim = PAD_L1; +#endif + } else if (g_Player.status & PLAYER_STATUS_WOLF_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_L1; +#else + g_Player.padSim = PAD_R2; +#endif + } + g_Player.D_80072EFC = 1; + SetStep(2); + break; + case 2: + if (entity->posX.i.hi > 0xE8) { + if (g_Player.status & PLAYER_STATUS_TRANSFORM) { + g_Player.padSim = PAD_NONE; + if (g_Timer & 1) { + if (g_Player.status & PLAYER_STATUS_BAT_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_R1 | PAD_SIM_UNK20000; +#else + g_Player.padSim = PAD_R1; +#endif + } else if (g_Player.status & PLAYER_STATUS_MIST_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_NONE | PAD_SIM_UNK20000; +#else + g_Player.padSim = PAD_L1; +#endif + } else if (g_Player.status & PLAYER_STATUS_WOLF_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_L1 | PAD_SIM_UNK20000; +#else + g_Player.padSim = PAD_R2; +#endif + } + } + } else { + g_Player.padSim = PAD_LEFT; + } + } else { + g_CutsceneFlags |= 1; + g_Player.padSim = PAD_NONE; + entity->posX.i.hi = 0xE8; + self->step++; + } + g_Player.D_80072EFC = 1; + break; + case 3: + if (g_CutsceneFlags & 0x40) { + if (entity->posX.i.hi > 0x74) { + D_80073510 = 1; + g_Player.padSim = PAD_LEFT; + } else { + entity->posX.i.hi = 0x74; + g_Player.padSim = PAD_NONE; + self->step++; + } + } else { + entity->posX.i.hi = 0xE8; + } + g_Player.D_80072EFC = 1; + break; + case 4: + g_Player.padSim = PAD_NONE | PAD_SIM_UNK20000; + g_Player.D_80072EFC = 1; + self->step++; + break; + case 5: + g_CastleFlags[MET_LIBRARIAN] = 1; + g_api.TimeAttackController( + TIMEATTACK_EVENT_MEET_MASTER_LIBRARIAN, TIMEATTACK_SET_RECORD); + g_Player.D_80072EFC = 1; + self->step++; + /* fallthrough */ + case 6: + if (g_CutsceneFlags & 0x100) { + g_CutsceneFlags |= 0x2000; + self->step = 0x10; + break; + } + entity->posX.i.hi = 0x74; + break; + case 8: + self->step++; + /* fallthrough */ + case 9: + if (entity->posX.i.hi > 0xFF) { + g_api.PlaySfx(CD_SOUND_COMMAND_7); + DestroyEntity(self); + break; + } + if (entity->posX.i.hi < 0x75) { + switch (self->step_s) { + case 0: + D_80073510 = 1; + g_PauseAllowed = false; + g_unkGraphicsStruct.pauseEnemies = true; + g_Player.padSim = PAD_NONE; + g_Player.D_80072EFC = 0x10; + self->step_s++; + g_CutsceneFlags |= 1; + break; + case 1: + if (g_Player.status & PLAYER_STATUS_TRANSFORM) { + g_Player.padSim = PAD_NONE; + if (g_Timer & 1) { + if (g_Player.status & PLAYER_STATUS_BAT_FORM) { + g_Player.padSim = PAD_R1; + } else if (g_Player.status & PLAYER_STATUS_MIST_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_NONE; +#else + g_Player.padSim = PAD_L1; +#endif + } else if (g_Player.status & PLAYER_STATUS_WOLF_FORM) { +#ifdef VERSION_PSP + g_Player.padSim = PAD_L1; +#else + g_Player.padSim = PAD_R2; +#endif + } + } + } else { + g_Player.padSim = PAD_LEFT; + self->step_s++; + } + g_Player.D_80072EFC = 1; + break; + case 2: + g_Player.padSim = PAD_NONE; + g_Player.D_80072EFC = 0x80; + SetStep(10); + break; + } + entity->posX.i.hi = 0x74; + } + break; + case 10: + if (!g_Player.D_80072EFC && (g_Player.pl_vram_flag & 1)) { + g_Player.padSim = PAD_NONE | PAD_SIM_UNK20000; + g_Player.D_80072EFC = 1; + self->step++; + } + entity->posX.i.hi = 0x74; + break; + case 11: + g_Player.padSim = PAD_NONE | PAD_SIM_UNK20000; + g_Player.D_80072EFC = 1; + if (g_CutsceneFlags & 0x100) { + g_CutsceneFlags |= 0x2000; + self->step = 0x10; + } + break; + case 16: +#ifdef VERSION_PSP + g_PauseAllowed = false; +#endif + g_Player.D_80072EFC = 0x20; + g_Player.padSim = PAD_RIGHT; + D_80097928 = 1; + self->step++; + break; + case 17: +#ifdef VERSION_PSP + g_PauseAllowed = false; +#endif + if (!g_Player.D_80072EFC) { +#ifdef VERSION_PSP + g_PauseAllowed = true; +#endif + SetStep(9); + } + break; + } +} extern u8 D_us_801811FC[]; extern u8 D_us_80181204[];