Fix crocomire menu hang (Fixes #1)

Renamed some variables
Also fixed so Replay works again
This commit is contained in:
Snesrev
2023-03-11 00:16:17 +01:00
parent 622c15ca7b
commit 5a0a84c649
6 changed files with 95 additions and 71 deletions

View File

@@ -344,7 +344,7 @@ CoroutineRet HandleMessageBoxInteraction_Async(void) { // 0x85846D
do { do {
COROUTINE_AWAIT(3, WaitForNMI_NoUpdate_Async()); COROUTINE_AWAIT(3, WaitForNMI_NoUpdate_Async());
ReadJoypadInputs(); ReadJoypadInputs();
} while (!joypad1_lastkeys); } while ((bug_fix_counter < 1 ? joypad1_newkeys : joypad1_lastkeys) == 0);
} }
GETOUT:; GETOUT:;
COROUTINE_END(0); COROUTINE_END(0);

View File

@@ -27,7 +27,7 @@ static const uint16 g_word_A486A4 = 0x640;
#define g_word_A49BC7 (*(uint16*)RomPtr(0xa49bc7)) #define g_word_A49BC7 (*(uint16*)RomPtr(0xa49bc7))
#define g_word_A49BC9 (*(uint16*)RomPtr(0xa49bc9)) #define g_word_A49BC9 (*(uint16*)RomPtr(0xa49bc9))
#define g_word_A49BCB (*(uint16*)RomPtr(0xa49bcb)) #define g_word_A49BCB (*(uint16*)RomPtr(0xa49bcb))
#define g_byte_A49697 ((uint8*)RomPtr(0xa49697)) #define kCrocoVlineRandomPos ((uint8*)RomPtr(0xa49697))
#define g_word_A49BBD ((uint16*)RomPtr(0xa49bbd)) #define g_word_A49BBD ((uint16*)RomPtr(0xa49bbd))
#define g_word_A498CA ((uint16*)RomPtr(0xa498ca)) #define g_word_A498CA ((uint16*)RomPtr(0xa498ca))
#define g_word_A499CB ((uint16*)RomPtr(0xa499cb)) #define g_word_A499CB ((uint16*)RomPtr(0xa499cb))
@@ -394,7 +394,7 @@ void Crocomire_Init(void) { // 0xA48A5A
if ((*(uint16 *)&boss_bits_for_area[area_index] & 2) != 0) { if ((*(uint16 *)&boss_bits_for_area[area_index] & 2) != 0) {
*(uint16 *)scrolls = 257; *(uint16 *)scrolls = 257;
*(uint16 *)&scrolls[2] = 257; *(uint16 *)&scrolls[2] = 257;
*(uint16 *)&g_byte_7E0688 = 0; croco_target_0688 = 0;
Enemy_Crocomire *E = Get_Crocomire(0); Enemy_Crocomire *E = Get_Crocomire(0);
E->base.properties = E->base.properties & 0x7BFF | 0x400; E->base.properties = E->base.properties & 0x7BFF | 0x400;
static const SpawnHardcodedPlmArgs unk_A48AFA = { 0x20, 0x03, 0xb753 }; static const SpawnHardcodedPlmArgs unk_A48AFA = { 0x20, 0x03, 0xb753 };
@@ -419,7 +419,7 @@ void Crocomire_Init(void) { // 0xA48A5A
vram_write_queue_tail = v6 + 7; vram_write_queue_tail = v6 + 7;
} else { } else {
DisableMinimapAndMarkBossRoomAsExplored(); DisableMinimapAndMarkBossRoomAsExplored();
g_word_7E069A = 0; croco_word_7E069A = 0;
Enemy_Crocomire *E = Get_Crocomire(cur_enemy_index); Enemy_Crocomire *E = Get_Crocomire(cur_enemy_index);
E->crocom_var_A = 0; E->crocom_var_A = 0;
E->crocom_var_E = 0; E->crocom_var_E = 0;
@@ -815,7 +815,7 @@ void Crocomire_Func_49(void) { // 0xA49099
Get_Crocomire(0x40u)->base.properties |= 0x200u; Get_Crocomire(0x40u)->base.properties |= 0x200u;
SpawnHardcodedPlm(&unk_A490D4); SpawnHardcodedPlm(&unk_A490D4);
camera_distance_index = 0; camera_distance_index = 0;
*(uint16 *)&g_byte_7E0688 = 0; croco_target_0688 = 0;
} }
} }
@@ -1018,8 +1018,8 @@ void Crocomire_92D8(void) { // 0xA492D8
void Crocomire_Func_57(void) { // 0xA49341 void Crocomire_Func_57(void) { // 0xA49341
int i; int i;
*(uint16 *)&g_byte_7E068C = 48; croco_word_068C = 48;
*(uint16 *)&g_byte_7E0688 = 48; croco_target_0688 = 48;
Enemy_Crocomire *E = Get_Crocomire(cur_enemy_index); Enemy_Crocomire *E = Get_Crocomire(cur_enemy_index);
++E->crocom_var_A; ++E->crocom_var_A;
++E->crocom_var_A; ++E->crocom_var_A;
@@ -1074,8 +1074,8 @@ void Crocomire_Func_59(void) { // 0xA493ED
++E->crocom_var_A; ++E->crocom_var_A;
++E->crocom_var_A; ++E->crocom_var_A;
E->base.instruction_timer = 1; E->base.instruction_timer = 1;
*(uint16 *)&g_byte_7E068C = 48; croco_word_068C = 48;
*(uint16 *)&g_byte_7E0688 = 48; croco_target_0688 = 48;
E->base.current_instruction = addr_kCrocomire_Ilist_BF7E; E->base.current_instruction = addr_kCrocomire_Ilist_BF7E;
uint16 v1 = 0; uint16 v1 = 0;
do { do {
@@ -1100,15 +1100,15 @@ void Crocomire_Func_60(void) { // 0xA4943D
++E->crocom_var_A; ++E->crocom_var_A;
++E->crocom_var_A; ++E->crocom_var_A;
g_word_7E0692 = 256; g_word_7E0692 = 256;
g_word_7E0690 = 0; croco_cur_vline_idx = 0;
g_word_7E0698 = *(uint16 *)((char *)&g_word_A49BC5 + g_word_7E069A); g_word_7E0698 = *(uint16 *)((char *)&g_word_A49BC5 + croco_word_7E069A);
g_word_7E0694 = g_word_7E0698; g_word_7E0694 = g_word_7E0698;
g_word_7E0696 = *(uint16 *)((char *)&g_word_A49BC7 + g_word_7E069A); g_word_7E0696 = *(uint16 *)((char *)&g_word_A49BC7 + croco_word_7E069A);
g_word_7E068E = *(uint16 *)((char *)&g_word_A49BC9 + g_word_7E069A); g_word_7E068E = *(uint16 *)((char *)&g_word_A49BC9 + croco_word_7E069A);
R0_.addr = 0; R0_.addr = 0;
*(uint16 *)&R0_.bank = *(uint16 *)((char *)&g_word_A49BCB + g_word_7E069A); *(uint16 *)&R0_.bank = *(uint16 *)((char *)&g_word_A49BCB + croco_word_7E069A);
uint16 v6; uint16 v6;
for (i = g_word_7E069A + 8; ; i = v6 + 4) { for (i = croco_word_7E069A + 8; ; i = v6 + 4) {
uint16 v2 = *(uint16 *)((char *)&g_word_A49BC5 + i); uint16 v2 = *(uint16 *)((char *)&g_word_A49BC5 + i);
if (v2 == 0xFFFF) if (v2 == 0xFFFF)
break; break;
@@ -1123,10 +1123,10 @@ void Crocomire_Func_60(void) { // 0xA4943D
--R18_; --R18_;
} while ((R18_ & 0x8000u) == 0); } while ((R18_ & 0x8000u) == 0);
} }
g_word_7E069A = i + 2; croco_word_7E069A = i + 2;
g_word_7E068A = i + 2; g_word_7E068A = i + 2;
for (j = 128; j >= 0; j -= 2) for (j = 128; j >= 0; j -= 2)
*(uint16 *)&g_byte_7E069C[(uint16)j] = 0; *(uint16 *)&croco_vline_height[(uint16)j] = 0;
} }
void Crocomire_Func_61(void) { // 0xA494B2 void Crocomire_Func_61(void) { // 0xA494B2
@@ -1215,11 +1215,10 @@ void Crocomire_Func_65(void) { // 0xA49580
if ((int16)(g_word_7E0692 - 20480) >= 0) { if ((int16)(g_word_7E0692 - 20480) >= 0) {
LABEL_4:; LABEL_4:;
Enemy_Crocomire *EK = Get_Crocomire(cur_enemy_index); Enemy_Crocomire *EK = Get_Crocomire(cur_enemy_index);
++EK->crocom_var_A; EK->crocom_var_A += 2;
++EK->crocom_var_A; for (i = croco_word_7E069A; *(uint16 *)((char *)&g_word_A49BC5 + i) != 0xFFFF; i += 8)
for (i = g_word_7E069A; *(uint16 *)((char *)&g_word_A49BC5 + i) != 0xFFFF; i += 8)
; ;
g_word_7E069A = i + 2; croco_word_7E069A = i + 2;
hdma_object_channels_bitmask[E0->crocom_var_1F >> 1] = 0; hdma_object_channels_bitmask[E0->crocom_var_1F >> 1] = 0;
return; return;
} }
@@ -1272,63 +1271,58 @@ void Crocomire_Func_66(void) { // 0xA49653
} }
static const uint8 g_byte_A49BBD[8] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe }; static const uint8 kCrocoEraseLineMasks[8] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
// Used when dissolving the crocomire thing
uint16 Crocomire_Func_67(void) { // 0xA496C8 uint16 Crocomire_Func_67(void) { // 0xA496C8
VramWriteEntry *v9; VramWriteEntry *v9;
uint16 result = 0; int n = croco_word_068C;
R18_ = g_byte_7E068C;
R20_ = 0; R20_ = 0;
R22_ = 0; R22_ = 0;
uint16 v2 = g_word_7E0690;
while (1) { while (1) {
LOBYTE(result) = g_byte_A49697[v2]; if (croco_cur_vline_idx > 48) // bugfix
if ((int8)(g_byte_7E069C[result] - g_byte_7E0688) < 0) return 1;
int rr = kCrocoVlineRandomPos[croco_cur_vline_idx];
if ((int8)(croco_vline_height[rr] - croco_target_0688) < 0)
break; break;
if ((int16)(++v2 - 128) >= 0) { if (++croco_cur_vline_idx >= 128) {
LOBYTE(g_word_7E0690) = 0; croco_cur_vline_idx = 0;
return 0; return 0;
} }
} }
g_word_7E0690 = v2; assert(croco_cur_vline_idx <= 48);
result = v2 & 7; int vline_idx = kCrocoVlineRandomPos[croco_cur_vline_idx];
uint16 v3 = result; uint8 mask = kCrocoEraseLineMasks[vline_idx & 7];
do { do {
uint16 v4 = g_byte_A49697[g_word_7E0690]; int q = croco_vline_height[vline_idx];
R20_ = 4 * (v4 & 0xFFF8); int j = 2 * (q & 7) + ((q & ~7) << 6) + 4 * (vline_idx & ~7);
R20_ += 2 * (g_byte_7E069C[v4] & 7); ram4000.backups.field_0[j + 0] &= mask;
uint16 v5 = R20_ + ((*(uint16 *)&g_byte_7E069C[v4] & 0xFFF8) << 6); ram4000.backups.field_0[j + 1] &= mask;
ram4000.backups.field_0[v5] &= g_byte_A49BBD[v3]; ram4000.backups.field_0[j + 16] &= mask;
ram4000.backups.field_0[v5 + 1] &= g_byte_A49BBD[v3]; ram4000.backups.field_0[j + 17] &= mask;
ram4000.backups.field_0[v5 + 16] &= g_byte_A49BBD[v3];
ram4000.backups.field_0[v5 + 17] &= g_byte_A49BBD[v3]; if (croco_vline_height[vline_idx] == 48)
uint8 v6 = g_byte_A49697[g_word_7E0690];
if (g_byte_7E069C[v6] == 48)
break; break;
++ *(uint16 *)&g_byte_7E069C[v6]; croco_vline_height[vline_idx]++;
R22_ = g_byte_7E069C[v6];
--R18_; --R18_;
} while (R18_); } while (--n);
uint16 v7, v8; uint16 v7, v8;
while (1) { while (1) {
v7 = g_word_7E068A + g_word_7E069A; v7 = g_word_7E068A + croco_word_7E069A;
v8 = vram_write_queue_tail; v8 = vram_write_queue_tail;
if (*(uint16 *)((char *)&g_word_A49BC5 + (uint16)(g_word_7E068A + g_word_7E069A)) != 0xFFFF) if (*(uint16 *)((char *)&g_word_A49BC5 + v7) != 0xFFFF)
break; break;
g_word_7E068A = 0; g_word_7E068A = 0;
} }
v9 = gVramWriteEntry(vram_write_queue_tail); v9 = gVramWriteEntry(vram_write_queue_tail);
v9->size = *(uint16 *)((char *)&g_word_A49BC5 + (uint16)(g_word_7E068A + g_word_7E069A)); v9->size = *(uint16 *)((char *)&g_word_A49BC5 + v7);
v9->src.addr = *(uint16 *)((char *)&g_word_A49BCB + v7); v9->src.addr = *(uint16 *)((char *)&g_word_A49BCB + v7);
*(uint16 *)&v9->src.bank = *(uint16 *)((char *)&g_word_A49BC9 + v7); *(uint16 *)&v9->src.bank = *(uint16 *)((char *)&g_word_A49BC9 + v7);
v9->vram_dst = *(uint16 *)((char *)&g_word_A49BC7 + v7); v9->vram_dst = *(uint16 *)((char *)&g_word_A49BC7 + v7);
vram_write_queue_tail = v8 + 7; vram_write_queue_tail = v8 + 7;
g_word_7E068A += 8; g_word_7E068A += 8;
uint16 v10 = g_word_7E0690;
if (!sign16(g_word_7E0690 - 128))
g_word_7E0690 = 0;
g_word_7E0690 = v10;
return 1; return 1;
} }
@@ -1419,8 +1413,8 @@ void Crocomire_Func_71(void) { // 0xA4990A
uint16 crocom_var_D = E->crocom_var_D; uint16 crocom_var_D = E->crocom_var_D;
if (crocom_var_D) { if (crocom_var_D) {
E->crocom_var_D = crocom_var_D - 1; E->crocom_var_D = crocom_var_D - 1;
v3 = *(uint16 *)&g_byte_7E0688; v3 = croco_target_0688;
int v4 = *(uint16 *)&g_byte_7E0688 >> 1; int v4 = croco_target_0688 >> 1;
if (g_word_A499CB[v4] != 0xFFFF) { if (g_word_A499CB[v4] != 0xFFFF) {
uint16 v5 = vram_write_queue_tail; uint16 v5 = vram_write_queue_tail;
v6 = gVramWriteEntry(vram_write_queue_tail); v6 = gVramWriteEntry(vram_write_queue_tail);
@@ -1430,7 +1424,7 @@ void Crocomire_Func_71(void) { // 0xA4990A
R18_ = (reg_OBSEL & 7) << 13; R18_ = (reg_OBSEL & 7) << 13;
v6->vram_dst = g_word_A499CB[v4] + R18_; v6->vram_dst = g_word_A499CB[v4] + R18_;
vram_write_queue_tail = v5 + 7; vram_write_queue_tail = v5 + 7;
*(uint16 *)&g_byte_7E0688 = v3 + 2; croco_target_0688 = v3 + 2;
} }
} else { } else {
E->base.x_pos = 480; E->base.x_pos = 480;

View File

@@ -304,6 +304,16 @@ uint32 PatchBugs(uint32 mode, uint32 addr) {
} else if (FixBugHook(0xA2D38C)) { } else if (FixBugHook(0xA2D38C)) {
// MaridiaLargeSnail_Touch uses uninitialized X // MaridiaLargeSnail_Touch uses uninitialized X
g_cpu->x = cur_enemy_index; g_cpu->x = cur_enemy_index;
} else if (FixBugHook(0xA4970F)) {
// Crocomire_Func_67 does weird things
g_cpu->a &= 0xff;
g_cpu->y = g_cpu->x & 0x7;
} else if (FixBugHook(0xA496E0)) {
if (g_cpu->x > 48) {
croco_cur_vline_idx = g_cpu->x;
g_cpu->mf = 0;
return 0xA497CE;
}
} }
return 0; return 0;
@@ -351,7 +361,7 @@ static void VerifySnapshotsEq(Snapshot *b, Snapshot *a, Snapshot *prev) {
memcpy(&b->ram[0x1f5b], &a->ram[0x1f5b], 0x100 - 0x5b); // stacck memcpy(&b->ram[0x1f5b], &a->ram[0x1f5b], 0x100 - 0x5b); // stacck
memcpy(&b->ram[0x44], &a->ram[0x44], 3); // decompress_dst_tmp memcpy(&b->ram[0x44], &a->ram[0x44], 3); // decompress_dst_tmp
memcpy(&b->ram[0x19b3], &a->ram[0x19b3], 1); // mode7_spawn_param memcpy(&b->ram[0x19b3], &a->ram[0x19b3], 1); // mode7_spawn_param
memcpy(&b->ram[0x12], &a->ram[0x12], 2); // R18 memcpy(&b->ram[0x12], &a->ram[0x12], 6); // R18, R20, R22
memcpy(&b->ram[0x1993], &a->ram[0x1993], 2); // enemy_projectile_init_param memcpy(&b->ram[0x1993], &a->ram[0x1993], 2); // enemy_projectile_init_param
memcpy(&b->ram[0x49], &a->ram[0x49], 1); // decompress_src.bank memcpy(&b->ram[0x49], &a->ram[0x49], 1); // decompress_src.bank
memcpy(&b->ram[0x1B9D], &a->ram[0x1B9D], 2); // cinematic_spawn_param memcpy(&b->ram[0x1B9D], &a->ram[0x1B9D], 2); // cinematic_spawn_param
@@ -539,6 +549,14 @@ void FixupCarry(uint32 addr) {
*RomPtr(addr) = 0; *RomPtr(addr) = 0;
} }
void RtlUpdateSnesPatchForBugfix() {
// Patch HandleMessageBoxInteraction logic
{ uint8 t[] = { 0x20, 0x50, 0x96, 0x60 }; PatchBytes(0x8584A3, t, sizeof(t)); }
// while ((bug_fix_counter < 1 ? joypad1_newkeys : joypad1_lastkeys) == 0);
{ uint8 t[] = { 0x20, 0x36, 0x81, 0x22, 0x59, 0x94, 0x80, 0xc2, 0x30, 0xa5, (bug_fix_counter < 1) ? 0x8f : 0x85, 0xf0, 0xf3, 0x60 }; PatchBytes(0x859650, t, sizeof(t)); }
{ uint8 t[] = { 0x18, 0x18 }; PatchBytes(0x8584CC, t, sizeof(t)); } // Don't wait 2 loops
}
Snes *SnesInit(const char *filename) { Snes *SnesInit(const char *filename) {
g_snes = snes_init(g_ram); g_snes = snes_init(g_ram);
@@ -668,11 +686,6 @@ Snes *SnesInit(const char *filename) {
{ uint8 t[] = { 0x18, 0x18, 0x18 }; PatchBytes(0x8580DC, t, sizeof(t)); } // Remove MsgBoxDelayFrames_2 { uint8 t[] = { 0x18, 0x18, 0x18 }; PatchBytes(0x8580DC, t, sizeof(t)); } // Remove MsgBoxDelayFrames_2
{ uint8 t[] = { 0x18, 0x18, 0x18 }; PatchBytes(0x8580F2, t, sizeof(t)); } // Remove MsgBoxDelayFrames_2 { uint8 t[] = { 0x18, 0x18, 0x18 }; PatchBytes(0x8580F2, t, sizeof(t)); } // Remove MsgBoxDelayFrames_2
// Patch HandleMessageBoxInteraction logic
{ uint8 t[] = { 0x20, 0x50, 0x96, 0x60 }; PatchBytes(0x8584A3, t, sizeof(t)); }
{ uint8 t[] = { 0x20, 0x36, 0x81, 0x22, 0x59, 0x94, 0x80, 0xc2, 0x30, 0xa5, 0x8b, 0xf0, 0xf3, 0x60 }; PatchBytes(0x859650, t, sizeof(t)); }
{ uint8 t[] = { 0x18, 0x18 }; PatchBytes(0x8584CC, t, sizeof(t)); } // Don't wait 2 loops
// Patch RestorePpuForMessageBox // Patch RestorePpuForMessageBox
{ uint8 t[] = { 0x18, 0x18, 0x18 }; PatchBytes(0x85861C, t, sizeof(t)); } // WaitForNMI_NoUpdate { uint8 t[] = { 0x18, 0x18, 0x18 }; PatchBytes(0x85861C, t, sizeof(t)); } // WaitForNMI_NoUpdate
{ uint8 t[] = { 0x18, 0x18, 0x18 }; PatchBytes(0x858651, t, sizeof(t)); } // WaitForNMI_NoUpdate { uint8 t[] = { 0x18, 0x18, 0x18 }; PatchBytes(0x858651, t, sizeof(t)); } // WaitForNMI_NoUpdate
@@ -727,6 +740,8 @@ Snes *SnesInit(const char *filename) {
{ uint8 t[] = { 0x18, 0x18, 0x18, 0x80 }; PatchBytes(0x828A80, t, sizeof(t)); } // SfxHandlers_3_WaitForAck { uint8 t[] = { 0x18, 0x18, 0x18, 0x80 }; PatchBytes(0x828A80, t, sizeof(t)); } // SfxHandlers_3_WaitForAck
{ uint8 t[] = { 0x06 }; PatchBytes(0x828A67, t, sizeof(t)); } // sfx_clear_delay { uint8 t[] = { 0x06 }; PatchBytes(0x828A67, t, sizeof(t)); } // sfx_clear_delay
RtlUpdateSnesPatchForBugfix();
for (size_t i = 0; i != arraysize(kPatchedCarrys); i++) { for (size_t i = 0; i != arraysize(kPatchedCarrys); i++) {
uint8 t = *RomPtr(kPatchedCarrys[i]); uint8 t = *RomPtr(kPatchedCarrys[i]);
if (t) { if (t) {

View File

@@ -245,10 +245,6 @@ void StateRecorder_Load(StateRecorder *sr, FILE *f, bool replay_mode) {
if (!is_reset) if (!is_reset)
RtlRestoreMusicAfterLoad_Locked(false); RtlRestoreMusicAfterLoad_Locked(false);
// For some reason couroutine_state is not 1...
if (g_snes->cpu->k == 0x00 && g_snes->cpu->pc == 0x841c)
coroutine_state_0 = 1;
// Temporarily fix reset state // Temporarily fix reset state
// if (g_snes->cpu->k == 0x82 && g_snes->cpu->pc == 0xf716) // if (g_snes->cpu->k == 0x82 && g_snes->cpu->pc == 0xf716)
// g_snes->cpu->pc = 0xf71c; // g_snes->cpu->pc = 0xf71c;
@@ -387,6 +383,11 @@ void RtlStopReplay(void) {
StateRecorder_StopReplay(&state_recorder); StateRecorder_StopReplay(&state_recorder);
} }
enum {
// Version was bumped to 1 after I fixed bug #1
kCurrentBugFixCounter = 1,
};
bool RtlRunFrame(int inputs) { bool RtlRunFrame(int inputs) {
// Avoid up/down and left/right from being pressed at the same time // Avoid up/down and left/right from being pressed at the same time
if ((inputs & 0x30) == 0x30) inputs ^= 0x30; if ((inputs & 0x30) == 0x30) inputs ^= 0x30;
@@ -402,6 +403,15 @@ bool RtlRunFrame(int inputs) {
if (state_recorder.snapshot_flags & 1) { if (state_recorder.snapshot_flags & 1) {
state_recorder.snapshot_flags &= ~1; state_recorder.snapshot_flags &= ~1;
inputs = state_recorder.last_inputs; inputs = state_recorder.last_inputs;
} else {
if (bug_fix_counter != kCurrentBugFixCounter) {
printf("bug_fix_counter %d => %d\n", bug_fix_counter, kCurrentBugFixCounter);
if (bug_fix_counter < kCurrentBugFixCounter) {
bug_fix_counter = kCurrentBugFixCounter;
StateRecorder_RecordPatchByte(&state_recorder, (uint8 *)&bug_fix_counter - g_ram, (uint8 *)&bug_fix_counter, 2);
RtlUpdateSnesPatchForBugfix();
}
}
} }
StateRecorder_Record(&state_recorder, inputs); StateRecorder_Record(&state_recorder, inputs);

View File

@@ -176,6 +176,7 @@ bool RtlRunFrame(int inputs);
void RtlReadSram(); void RtlReadSram();
void RtlWriteSram(); void RtlWriteSram();
void RtlSaveSnapshot(const char *filename, bool saving_with_bug); void RtlSaveSnapshot(const char *filename, bool saving_with_bug);
void RtlUpdateSnesPatchForBugfix();
uint16 Mult8x8(uint8 a, uint8 b); uint16 Mult8x8(uint8 a, uint8 b);
uint16 SnesDivide(uint16 a, uint8 b); uint16 SnesDivide(uint16 a, uint8 b);

View File

@@ -127,6 +127,10 @@
#define coroutine_completion_flags (*(uint8*)(g_ram+0x782)) #define coroutine_completion_flags (*(uint8*)(g_ram+0x782))
#define my_counter (*(uint16*)(g_ram+0x77E)) #define my_counter (*(uint16*)(g_ram+0x77E))
// Keep track of which bug fixes have been made to prevent
// replays from desyncing.
#define bug_fix_counter (*(uint16*)(g_ram+0x1FF00))
#define g_word_7E0596 (*(uint16*)(g_ram+0x596)) #define g_word_7E0596 (*(uint16*)(g_ram+0x596))
#define g_word_7E0598 (*(uint16*)(g_ram+0x598)) #define g_word_7E0598 (*(uint16*)(g_ram+0x598))
#define set_to_e0_by_scrolling_sky (*(uint16*)(g_ram+0x59A)) #define set_to_e0_by_scrolling_sky (*(uint16*)(g_ram+0x59A))
@@ -205,17 +209,17 @@
#define sfx2_queue ((uint8*)(g_ram+0x666)) #define sfx2_queue ((uint8*)(g_ram+0x666))
#define sfx3_queue ((uint8*)(g_ram+0x676)) #define sfx3_queue ((uint8*)(g_ram+0x676))
#define sound_handler_downtime (*(uint16*)(g_ram+0x686)) #define sound_handler_downtime (*(uint16*)(g_ram+0x686))
#define g_byte_7E0688 (*(uint8*)(g_ram+0x688)) #define croco_target_0688 (*(uint16*)(g_ram+0x688))
#define g_word_7E068A (*(uint16*)(g_ram+0x68A)) #define g_word_7E068A (*(uint16*)(g_ram+0x68A))
#define g_byte_7E068C (*(uint8*)(g_ram+0x68C)) #define croco_word_068C (*(uint8*)(g_ram+0x68C))
#define g_word_7E068E (*(uint16*)(g_ram+0x68E)) #define g_word_7E068E (*(uint16*)(g_ram+0x68E))
#define g_word_7E0690 (*(uint16*)(g_ram+0x690)) #define croco_cur_vline_idx (*(uint16*)(g_ram+0x690))
#define g_word_7E0692 (*(uint16*)(g_ram+0x692)) #define g_word_7E0692 (*(uint16*)(g_ram+0x692))
#define g_word_7E0694 (*(uint16*)(g_ram+0x694)) #define g_word_7E0694 (*(uint16*)(g_ram+0x694))
#define g_word_7E0696 (*(uint16*)(g_ram+0x696)) #define g_word_7E0696 (*(uint16*)(g_ram+0x696))
#define g_word_7E0698 (*(uint16*)(g_ram+0x698)) #define g_word_7E0698 (*(uint16*)(g_ram+0x698))
#define g_word_7E069A (*(uint16*)(g_ram+0x69A)) #define croco_word_7E069A (*(uint16*)(g_ram+0x69A))
#define g_byte_7E069C ((uint8*)(g_ram+0x69C)) #define croco_vline_height ((uint8*)(g_ram+0x69C))
#define UNUSED_byte_7E071C (*(uint8*)(g_ram+0x71C)) #define UNUSED_byte_7E071C (*(uint8*)(g_ram+0x71C))
#define nmi_copy_samus_halves (*(uint16*)(g_ram+0x71D)) #define nmi_copy_samus_halves (*(uint16*)(g_ram+0x71D))
#define nmi_copy_samus_top_half_src (*(uint16*)(g_ram+0x71F)) #define nmi_copy_samus_top_half_src (*(uint16*)(g_ram+0x71F))