diff --git a/src/funcs.h b/src/funcs.h index 044ff70..8a17b42 100644 --- a/src/funcs.h +++ b/src/funcs.h @@ -1341,8 +1341,8 @@ void Eproj_Pickup_Missiles(void); void Eproj_Pickup_PowerBombs(void); void Eproj_Pickup_SmallHealth(void); void Eproj_Pickup_SuperMissiles(void); -void Eproj_SetVelTowardsSamus1(uint16 k); -void Eproj_SetVelTowardsSamus2(uint16 k); +uint16 EprojInstr_SetVelTowardsSamus1(uint16 k, uint16 j); +uint16 EprojInstr_SetVelTowardsSamus2(uint16 k, uint16 j); void Eproj_SetXvelRandom(uint16 k); void Eproj_SetYvelRandom(uint16 k); void GetValuesForScreenShaking(void); @@ -6125,6 +6125,7 @@ void DecompressToMem_IpArg(const void* p); #define fnPlmInstr_GotoIfDoorBitSet 0x848A72 #define fnPlmInstr_IncrementDoorHitCounterAndJGE 0x848A91 #define fnPlmInstr_IncrementArgumentAndJGE 0x848ACD +#define fnlocret_848AE0 0x848AE0 #define fnPlmInstr_SetBTS 0x848AF1 #define fnPlmInstr_DrawPlmBlock 0x848B05 #define fnPlmInstr_DrawPlmBlock_ 0x848B17 @@ -6219,6 +6220,7 @@ void DecompressToMem_IpArg(const void* p); #define fnPlmPreInstr_EscapeRoomBeforeOldTourianEscapeShaft 0x84B948 #define fnPlmSetup_B974 0x84B96C #define fnPlmSetup_B9C1_CrittersEscapeBlock 0x84B978 +#define fnPlmInstr_SetCrittersEscapedEvent 0x84B9B9 #define fnPlmSetup_B9ED_CrittersEscapeBlock 0x84B9C5 #define fnsub_84B9F1 0x84B9F1 #define fnPlmInstr_JumpIfSamusHasNoBombs 0x84BA6F @@ -6531,6 +6533,8 @@ void DecompressToMem_IpArg(const void* p); #define fnEprojInit_TourianStatueDustClouds 0x86AF43 #define fnEprojInit_TourianLandingDustCloudsRightFoot 0x86AF50 #define fnEprojInstr_MoveY_Minus4 0x86AF92 +#define fnEprojInstr_SetVelTowardsSamus1 0x86B269 +#define fnEprojInstr_SetVelTowardsSamus2 0x86B272 #define fnEprojInit_TorizoLandingDustCloudLeftFoot 0x86AFCD #define fnEprojInit_GoldenTorizoEgg 0x86B001 #define fnEprojPreInstr_GoldenTorizoEgg 0x86B043 @@ -9496,6 +9500,8 @@ void DecompressToMem_IpArg(const void* p); #define fnEscapeEtecoon_Instr_2 0xB3E610 #define fnEscapeEtecoon_Main 0xB3E655 #define fnEscapeEtecoon_E65C 0xB3E65C +#define fnEscapeEtecoon_E670 0xB3E670 +#define fnEscapeEtecoon_E680 0xB3E680 #define fnEscapeEtecoon_Init 0xB3E6CB #define fnEscapeDachora_Instr_2 0xB3EAA8 #define fnEscapeDachora_Instr_3 0xB3EAB8 diff --git a/src/ida_types.h b/src/ida_types.h index 37ad0f5..1f94d75 100644 --- a/src/ida_types.h +++ b/src/ida_types.h @@ -1438,6 +1438,7 @@ typedef struct Ram7800_FireFlea { /* 145 */ typedef union ExtraEnemyRam7800 { Ram7800_Kraid kraid; + uint8 pad[64]; }ExtraEnemyRam7800; /* 146 */ diff --git a/src/sm_84.c b/src/sm_84.c index d084fe7..7a19b54 100644 --- a/src/sm_84.c +++ b/src/sm_84.c @@ -457,7 +457,8 @@ void CallPlmPreInstr(uint32 ea, uint16 k) { case fnnullsub_78: case fnnullsub_79: case fnnullsub_80: - case fnnullsub_81: return; + case fnnullsub_81: + case fnlocret_848AE0: return; case fnPlmPreInstr_SetMetroidsClearState_Ev0x10: PlmPreInstr_SetMetroidsClearState_Ev0x10(k); return; case fnPlmPreInstr_SetMetroidsClearState_Ev0x11: PlmPreInstr_SetMetroidsClearState_Ev0x11(k); return; case fnPlmPreInstr_SetMetroidsClearState_Ev0x12: PlmPreInstr_SetMetroidsClearState_Ev0x12(k); return; @@ -539,6 +540,7 @@ uint16 CallPlmInstr(uint32 ea, uint16 j, uint16 k) { case fnPlmInstr_PlaceSamusOnSaveStation: return PlmInstr_PlaceSamusOnSaveStation(j, k); case fnPlmInstr_DisplayGameSavedMessageBox: return PlmInstr_DisplayGameSavedMessageBox(j, k); case fnPlmInstr_EnableMovementAndSetSaveStationUsed: return PlmInstr_EnableMovementAndSetSaveStationUsed(j, k); + case fnPlmInstr_SetCrittersEscapedEvent: return PlmInstr_SetCrittersEscapedEvent(j, k); case fnPlmInstr_JumpIfSamusHasNoBombs: return PlmInstr_JumpIfSamusHasNoBombs(j, k); case fnPlmInstr_MovePlmRight4Blocks: return PlmInstr_MovePlmRight4Blocks(j, k); case fnPlmInstr_ClearTrigger: return PlmInstr_ClearTrigger(j, k); @@ -3051,7 +3053,6 @@ uint8 PlmSetup_D6F2_WreckedShipChozoHandTrigger(uint16 j) { // 0x84D620 CallSomeSamusCode(0); static const SpawnHardcodedPlmArgs unk_84D673 = { 0x17, 0x1d, 0xd6f8 }; SpawnHardcodedPlm(&unk_84D673); - return 0; } plm_header_ptr[j >> 1] = 0; return 1; diff --git a/src/sm_86.c b/src/sm_86.c index 9d9c172..8807287 100644 --- a/src/sm_86.c +++ b/src/sm_86.c @@ -425,6 +425,8 @@ uint16 CallEprojInstr(uint32 ea, uint16 k, uint16 j) { case fnEprojInstr_GotoDependingOnXDirection: return EprojInstr_GotoDependingOnXDirection(k, j); case fnEprojInstr_ResetXYpos1: return EprojInstr_ResetXYpos1(k, j); case fnEprojInstr_MoveY_Minus4: return EprojInstr_MoveY_Minus4(k, j); + case fnEprojInstr_SetVelTowardsSamus1: return EprojInstr_SetVelTowardsSamus1(k, j); + case fnEprojInstr_SetVelTowardsSamus2: return EprojInstr_SetVelTowardsSamus2(k, j); case fnEprojInstr_GotoIfFunc1: return EprojInstr_GotoIfFunc1(k, j); case fnEprojInstr_ResetXYpos2: return EprojInstr_ResetXYpos2(k, j); case fnEprojInstr_SpawnTourianStatueUnlockingParticle: return EprojInstr_SpawnTourianStatueUnlockingParticle(k, j); @@ -3062,16 +3064,14 @@ void EprojPreInstr_B237(uint16 k) { // 0x86B237 } } -void Eproj_SetVelTowardsSamus1(uint16 k) { // 0x86B269 - char v1; - - v1 = CalculateAngleOfSamusFromEproj(k); - sub_86B279(k, v1 & 0x7F); +uint16 EprojInstr_SetVelTowardsSamus1(uint16 k, uint16 j) { // 0x86B269 + sub_86B279(k, CalculateAngleOfSamusFromEproj(k) & 0x7F); + return j; } -void Eproj_SetVelTowardsSamus2(uint16 k) { // 0x86B272 - uint16 v1 = CalculateAngleOfSamusFromEproj(k); - sub_86B279(k, v1 | 0x80); +uint16 EprojInstr_SetVelTowardsSamus2(uint16 k, uint16 j) { // 0x86B272 + sub_86B279(k, CalculateAngleOfSamusFromEproj(k) | 0x80); + return j; } void sub_86B279(uint16 k, uint16 a) { // 0x86B279 @@ -5608,7 +5608,7 @@ uint16 EprojInstr_QueueSfx2_B(uint16 k, uint16 j) { // 0x86EEA3 uint16 EprojInstr_EEAF(uint16 k, uint16 j) { // 0x86EEAF uint16 v2 = RandomDropRoutine(k); - if (sign16(v2 - 6)) { + if (k != 0 && sign16(v2 - 6)) { uint16 v3 = 2 * v2; int v4 = k >> 1; enemy_projectile_E[v4] = v3; diff --git a/src/sm_94.c b/src/sm_94.c index ff38dab..e44ed04 100644 --- a/src/sm_94.c +++ b/src/sm_94.c @@ -886,8 +886,8 @@ uint8 BlockColl_Vert_SpecialBlock(void) { // 0x949102 v0 = BTS[cur_block_index]; if ((v0 & 0x80) != 0) { R34 = off_9492E9[area_index]; - uint8 *v3 = RomPtr_94(R34); - uint8 v4 = SpawnPLM(*(uint16 *)&v3[(uint16)(2 * (v0 & 0x7F))]) & 1; + uint16 *v3 = (uint16*)RomPtr_94(R34); + uint8 v4 = SpawnPLM(v3[v0 & 0x7F]) & 1; if (v4) return BlockColl_Vert_SolidShootGrappleBlock(); return v4; diff --git a/src/sm_a0.c b/src/sm_a0.c index ac07077..339b9e0 100644 --- a/src/sm_a0.c +++ b/src/sm_a0.c @@ -1341,6 +1341,8 @@ void CallEnemyPreInstr(uint32 ea) { case fnShaktool_PreInstr_0: Shaktool_PreInstr_0(k); return; case fnnullsub_277: return; case fnEscapeEtecoon_E65C: EscapeEtecoon_E65C(k); return; + case fnEscapeEtecoon_E670: EscapeEtecoon_E670(k); return; + case fnEscapeEtecoon_E680: EscapeEtecoon_E680(k); return; case fnsub_A3E168: sub_A3E168(k); return; case fnMaridiaSnail_Func_7: MaridiaSnail_Func_7(k); return; case fnMaridiaSnail_Func_9: MaridiaSnail_Func_9(k); return; diff --git a/src/sm_a7.c b/src/sm_a7.c index 4992fb4..d544334 100644 --- a/src/sm_a7.c +++ b/src/sm_a7.c @@ -2213,9 +2213,7 @@ void Phantoon_Main(void) { // 0xA7CEA6 Phantoon_Func_2(cur_enemy_index); Enemy_Phantoon *EK = Get_Phantoon(cur_enemy_index); CallEnemyPreInstr(EK->phant_var_F | 0xA70000); - printf("What is X?\n"); - uint16 tt = cur_enemy_index; // wtf bug - if (!tt) { + if (cur_enemy_index == 0) { // code bug: X is overwritten Enemy_Phantoon *E0 = Get_Phantoon(0); Enemy_Phantoon *E1 = Get_Phantoon(0x40u); Enemy_Phantoon *E2 = Get_Phantoon(0x80); diff --git a/src/sm_aa.c b/src/sm_aa.c index 4023ff5..2ee27aa 100644 --- a/src/sm_aa.c +++ b/src/sm_aa.c @@ -1506,9 +1506,10 @@ void Shaktool_DD25(uint16 k) { // 0xAADD25 Shaktool_DB27(k, v8); for (int i = 12; i >= 0; i -= 2) { Shaktool_DC07(k); - E->shakt_var_F = FUNC16(nullsub_274); - E->base.current_instruction = g_off_AADF13[i >> 1]; - E->base.instruction_timer = 1; + Enemy_Shaktool *EK = Get_Shaktool(k); + EK->shakt_var_F = FUNC16(nullsub_274); + EK->base.current_instruction = g_off_AADF13[i >> 1]; + EK->base.instruction_timer = 1; k -= 64; } } else { diff --git a/src/sm_cpu_infra.c b/src/sm_cpu_infra.c index 00902f0..b2496a4 100644 --- a/src/sm_cpu_infra.c +++ b/src/sm_cpu_infra.c @@ -276,6 +276,12 @@ void PatchBugs(uint32 mode, uint32 addr) { } else if (FixBugHook(0x829325)) { // forgot to change bank g_cpu->db = 0x82; + } else if (FixBugHook(0x848ACD)) { + // PlmInstr_IncrementArgumentAndJGE A is not zeroed + g_cpu->a = 0; + } else if (FixBugHook(0xA7CEB2)) { + // Phantoon_Main forgots to reload x + g_cpu->x = cur_enemy_index; } } diff --git a/src/sm_rtl.c b/src/sm_rtl.c index c27f021..1907554 100644 --- a/src/sm_rtl.c +++ b/src/sm_rtl.c @@ -423,12 +423,24 @@ void RtlSaveSnapshot(const char *filename, bool saving_with_bug) { fclose(f); } +static const char *const kBugSaves[] = { + "shaktool", "shinespark", "bombtorizo", "chozo", "draygon", "draygon2", "golden-torizo", "motherbomb", "phantoon" +}; + void RtlSaveLoad(int cmd, int slot) { char name[128]; - sprintf(name, "saves/save%d.sav", slot); + if (slot >= 256) { + int i = slot - 256; + if (cmd == kSaveLoad_Save || i >= sizeof(kBugSaves) / sizeof(kBugSaves[0])) + return; + sprintf(name, "saves/bug-%s.sav", kBugSaves[i]); + } else { + sprintf(name, "saves/save%d.sav", slot); + } printf("*** %s slot %d\n", cmd == kSaveLoad_Save ? "Saving" : cmd == kSaveLoad_Load ? "Loading" : "Replaying", slot); if (cmd != kSaveLoad_Save) { + FILE *f = fopen(name, "rb"); if (f == NULL) { printf("Failed fopen: %s\n", name);