Basic Return to Dinosaur land support

This commit is contained in:
Snesrev 2023-08-15 22:37:55 +02:00
parent 7d9528dbb1
commit c96e0c98d7
11 changed files with 88 additions and 39 deletions

View File

@ -235,6 +235,10 @@ kLmFeature_MusicRegTweak = 1 << 17
kLmFeature_TideWaterTweak = 1 << 18
kLmFeature_EnemyCollTweak = 1 << 19
kLmFeature_Ow4bppGfx = 1 << 20
kLmFeature_DontResetOwPlayersMap = 1 << 21
kLmFeature_NonStdGfxAA8D = 1 << 22
kLmFeature_TimerTweaks = 1 << 23
kLmFeature_NoDefaultSavePrompts = 1 << 24
kHack_Walljump = 1 << 0
@ -734,10 +738,15 @@ def print_all(args):
lm_feat.flags |= kLmFeature_TideWaterTweak if get_byte(0xa045) == 0x22 else 0
lm_feat.flags |= kLmFeature_EnemyCollTweak if get_byte(0x194B6) == 0x5c else 0
lm_feat.flags |= kLmFeature_Ow4bppGfx if get_bytes(0xA149, 4) != b'\x22\x28\xBA\x00' else 0
lm_feat.flags |= kLmFeature_DontResetOwPlayersMap if get_byte(0xa0a0) == 0xea else 0
lm_feat.flags |= kLmFeature_NonStdGfxAA8D if get_byte(0xAA8D) != 0x08 else 0
lm_feat.flags |= kLmFeature_TimerTweaks if get_byte(0x58E24) == 0x8f else 0
lm_feat.flags |= kLmFeature_NoDefaultSavePrompts if get_byte(0x3BA26) == 0 else 0
# Allows Mario to perform a wall kick by sliding along a wall and pressing the
# B button.
lm_feat.hacks |= kHack_Walljump if get_24(0xA2A2) != 0x586F1 else 0
lm_feat.hacks |= kHack_Walljump if get_24(0xA2A1) != 0x86F122 else 0
def add_custom_ow_palette():
r = b''

View File

@ -52,6 +52,7 @@ kHackInfo = {
'enhanced' : ('Super Mario World Enhanced.ips', '2882a39ac64b597e9260e92aaba610d0b6f03adb', 'Super Mario World Enhanced.bsdiff', '5a53369916fd728033d16db3abceb487900f903a', 'ebe23d8a26759ba1b5c2f4d6d8f8db3ab88e902f'),
'redrawn' : ('smw_redrawn.ips', '7168df51ba025a12177ce00e88540c1341ef3efc', 'smw_redrawn.bsdiff', '13b658e626020aa35dca4e1c3648c6a6d8afa901', '50702ffc8c2e7115c9ba0c80c8ec40da5a487651'),
'nsmb' : ('SMW with Levels from NSMB.bps', '4277edf003340021ce4e68fe2278d1d73f4d798c', 'SMW with Levels from NSMB.bsdiff', 'e2d2487324374aea1d67a6aa6b3b47f8b3e6727c', '877e9c6fce29e80e4c52892120af06748550487a'),
'return_dino_land' : ('Return to Dinosaur Land.bps', 'e9a891ecd0f6f43a4592487ca2590311be00396d', 'Return to Dinosaur Land.bsdiff', 'ad2ebd7b416cbfd3cd7cac833b0ca7f690b9144b', '1d03777086f3c86b1693f9ce2411f560813732a8')
}
kModsPath = os.path.join(DEFAULT_ROM_DIRECTORY, '../smw_hacks/mods')

View File

@ -279,6 +279,7 @@ Snes *SnesInit(const uint8 *data, int data_size) {
}
}
g_rtl_game_info->initialize();
snes_reset(g_snes, true); // reset after loading
PatchBugs(1, 0);
} else {
g_runmode = RM_MINE;

View File

@ -1534,7 +1534,7 @@ void SubmapSwitchProcess01_UpdateLayer1(void);
void SubmapSwitchProcess05_UpdatePalette(void);
void SubmapSwitchProcess06_EndWindowHDMA(void);
void SubmapSwitchProcess07_EndSubmapSwitch(void);
void UnlockOverworldPathBasedOnExit(void);
uint16 UnlockOverworldPathBasedOnExit(void);
uint16 UpdateLevelName_049D7F(uint16 j, uint16 k, uint16 r2w);
void UpdateLevelName(uint16 r0w);
void UpdateOverworldSpritePosition(uint8 k);
@ -2114,6 +2114,10 @@ enum {
kLmFeature_TideWaterTweak = 1 << 18,
kLmFeature_EnemyCollTweak = 1 << 19,
kLmFeature_Ow4bppGfx = 1 << 20,
kLmFeature_DontResetOwPlayersMap = 1 << 21,
kLmFeature_NonStdGfxAA8D = 1 << 22,
kLmFeature_TimerTweaks = 1 << 23,
kLmFeature_NoDefaultSavePrompts = 1 << 24,
};
// Non lunar magic hacks

View File

@ -2135,6 +2135,7 @@ void GameMode0C_LoadOverworld() { // 00a087
ClearOverworldAndCutsceneRAM();
if (misc_intro_level_flag) {
timer_title_screen_input_timer = -80;
if (!HAS_LM_FEATURE(kLmFeature_DontResetOwPlayersMap))
ow_players_map[0] = 0;
mirror_mosaic_size_and_bgenable = -16;
misc_game_mode = 16;
@ -2710,8 +2711,9 @@ void UploadGraphicsFiles_UploadGFXFile(uint16 dst_addr, uint8 j, uint8 index) {
}
bool lm_flag = HAS_LM_FEATURE(kLmFeature_4bppgfx);
bool lm_flag2 = HAS_LM_FEATURE(kLmFeature_NonStdGfxAA8D);
if (misc_level_tileset_setting >= 0x11 && j == (lm_flag ? 0x32 : 8) || j == (lm_flag ? 0x32 : 30)) {
if (misc_level_tileset_setting >= 0x11 && j == (lm_flag2 ? 0x32 : 8) || j == (lm_flag2 ? 0x32 : 30)) {
uint16 r10w = -256;
for (int8 i = 127; i >= 0; --i) {
for (int8 k = 7; k >= 0; --k) {
@ -2720,11 +2722,12 @@ void UploadGraphicsFiles_UploadGFXFile(uint16 dst_addr, uint8 j, uint8 index) {
*(uint16 *)&graphics_3_bppto4_bppbuffer[(uint8)k] = WORD(p0[0]) | swap16(v11);
p0 += 2;
}
int step = lm_flag ? 2 : 1;
for (int8 m = 7; m >= 0; --m) {
const uint8 *v14 = p0;
uint16 r12w = *v14;
*dst++ = r12w | r10w & (*(uint16 *)&graphics_3_bppto4_bppbuffer[(uint8)m] | swap16(*(uint16 *)v14));
p0 += 1;
p0 += step;
}
}
} else {
@ -4267,7 +4270,8 @@ void PlayerState09_Death() { // 00d0b6
if (!flag_prevent_yoshi_carry_over)
yoshi_carry_over_levels_flag = 0;
if ((--player_current_life_count & 0x80) == 0) {
if (counter_timer_ones | counter_timer_tens | counter_timer_hundreds) {
if (HAS_LM_FEATURE(kLmFeature_TimerTweaks) && lm_timer_var != 0 ||
counter_timer_ones | counter_timer_tens | counter_timer_hundreds) {
misc_game_mode = 11;
return;
}

View File

@ -741,9 +741,20 @@ LABEL_11:
}
void OwProcess02_HandleLevelBeaten() { // 048f87
UnlockOverworldPathBasedOnExit();
uint16 r4 = UnlockOverworldPathBasedOnExit();
uint8 v0 = 7;
while ((uint8)ow_tile_player_is_standing_on != kOwTriggerSaveTiles_048F7F[v0]) {
uint8 a = (uint8)ow_tile_player_is_standing_on;
if (g_lunar_magic) {
if (ow_level_tile_settings[ow_level_number_of_each_tiletbl[r4]] & 0x10) {
a = 0x80;
} else {
if (HAS_LM_FEATURE(kLmFeature_NoDefaultSavePrompts))
a = 0xff;
}
}
while (a != kOwTriggerSaveTiles_048F7F[v0]) {
if ((--v0 & 0x80) != 0)
goto LABEL_10;
}
@ -1279,8 +1290,10 @@ void OwProcess0C_IntroMarch() { // 0498c6
}
}
void UnlockOverworldPathBasedOnExit() { // 049903
if ((int8)misc_exit_level_action > 0) {
uint16 UnlockOverworldPathBasedOnExit() { // 049903
if ((int8)misc_exit_level_action <= 0)
return 0;
uint16 r8 = kSharedOverworldPathTables_DATA_049060[(uint8)(misc_exit_level_action - 1)];
uint8 v0 = player_current_characterx4;
PointU16 *pt = get_PointU16(ow_players_pos, player_current_characterx4);
@ -1299,7 +1312,7 @@ void UnlockOverworldPathBasedOnExit() { // 049903
} while (v4 >= 0);
}
*(uint16 *)&ow_level_tile_settings[ow_level_number_of_each_tiletbl[r4w]] |= kBitTable_Bank04[(uint16)(2 * (v3 & 3)) >> 1];
}
return r4w;
}
void HandleOverworldPathExits() { // 049a24
@ -2043,7 +2056,7 @@ void OwEventProcess07_SilentEventsAndEndOfEvent_Entry2(uint8 a, bool from_where)
if (HAS_LM_FEATURE(kLmFeature_EventStuff)) {
LmHook_EventStuff(a, from_where);
} else {
for (uint8 i = 43; (i & 0x80) == 0; --i) {
for (uint8 i = kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_SIZE - 1; (i & 0x80) == 0; --i) {
if (a == kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles[i]) {
uint8 v4 = i;
uint8 r2 = kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileLayer[i];

View File

@ -594,6 +594,8 @@ void LoadLevelHeader() { // 0584e3
r0 = hdr[3];
if (!counter_sublevels_entered) {
counter_timer_hundreds = kLoadLevelHeader_TimerTable[r0 >> 6];
if (HAS_LM_FEATURE(kLmFeature_TimerTweaks))
lm_timer_var = counter_timer_hundreds;
counter_timer_tens = 0;
counter_timer_ones = 0;
}

View File

@ -245,6 +245,17 @@ void SmwCpuInitialize(void) {
static const uint8 kRevert_0x2e6ec[] = { 0xa9, 0x38, 0x9d, 0xea, 0x15 };
memcpy(SnesRomPtr(0x2e6ec), kRevert_0x2e6ec, sizeof(kRevert_0x2e6ec));
}
// fast rom
static const uint8 kRevert_0xfffc[] = { 0x00, 0x80 };
memcpy(SnesRomPtr(0xfffc), kRevert_0xfffc, sizeof(kRevert_0xfffc));
static const uint8 kRevert_0xffea[] = { 0x6a, 0x81 };
memcpy(SnesRomPtr(0xffea), kRevert_0xffea, sizeof(kRevert_0xffea));
static const uint8 kRevert_0x801c[] = { 0xfb };
memcpy(SnesRomPtr(0x801c), kRevert_0x801c, sizeof(kRevert_0x801c));
static const uint8 kRevert_0x8713[] = { 0xb7, 0x02, 0x85, 0x01 };
memcpy(SnesRomPtr(0x8713), kRevert_0x8713, sizeof(kRevert_0x8713));
}
}

View File

@ -751,14 +751,16 @@ static void cpu_doOpcode(Cpu* cpu, uint8_t opcode) {
pc_hist[pc_hist_ctr] = cur_pc;
pc_hist_ctr = (pc_hist_ctr + 1) & 15;
if (0 && cur_pc == 0x5D83B) {
if (cur_pc == 0x3FDE0) {
DumpCpuHistory();
g_snes->debug_cycles = 0;
}
if (cur_pc == pc_bp) {
printf("Reached BP 0x%x. A=0x%.2x, X=0x%.2x, Y=0x%.2x. C=%d. lm_var13CD=%x\n",
cur_pc, cpu->a, cpu->x, cpu->y, cpu->c,
*(uint16*)&g_ram[14]);
printf("Reached BP 0x%x. A=0x%.2x, X=0x%.2x, Y=0x%.2x. C=0x%.2x,0x%.2x\n",
cur_pc, cpu->a, cpu->x, cpu->y,
g_ram[0xbcee],
g_ram[0xad10]);
// printf("T: 16 j=%d, %d\n", g_cpu->y, g_cpu->a);
bp_cnt += 1;
//g_snes->debug_cycles = 1;
@ -776,7 +778,7 @@ restart:
break;
case 2: // rtl
cpu->pc = cpu_pullWord(cpu) + 1;
cpu->k = cpu_pullByte(cpu);
cpu->k = cpu_pullByte(cpu) & 0x7f;
break;
case 0xe5:
case 0xe9:
@ -1002,7 +1004,7 @@ restart:
cpu_pushByte(cpu, cpu->k);
cpu_pushWord(cpu, cpu->pc - 1);
cpu->pc = value;
cpu->k = newK;
cpu->k = newK & 0x7f;
break;
}
case 0x23: { // and sr
@ -1378,7 +1380,7 @@ restart:
DumpCpuHistory();
Die("The game has crashed!\n");
}
cpu->k = new_k;
cpu->k = new_k & 0x7f;
cpu->pc = value;
break;
}
@ -1488,7 +1490,7 @@ restart:
}
cpu->pc = cpu_pullWord(cpu) + 1;
cpu->k = cpu_pullByte(cpu);
cpu->k = cpu_pullByte(cpu) & 0x7f;
break;
}
case 0x6c: { // jmp ind
@ -2175,7 +2177,7 @@ restart:
case 0xdc: { // jml ial
uint16_t adr = cpu_readOpcodeWord(cpu);
cpu->pc = cpu_readWord(cpu, adr, (adr + 1) & 0xffff);
cpu->k = cpu_read(cpu, (adr + 2) & 0xffff);
cpu->k = cpu_read(cpu, (adr + 2) & 0xffff) & 0x7f;
break;
}
case 0xdd: { // cmp abx(r)

View File

@ -98,7 +98,7 @@ bool snes_loadRom(Snes* snes, const uint8_t* data, int length) {
snes->cart, headers[used].cartType,
newData, newLength, headers[used].chips > 0 ? headers[used].ramSize : 0
);
snes_reset(snes, true); // reset after loading
free(newData);
return true;
}

View File

@ -1048,4 +1048,6 @@ typedef struct ExAnimationInfo {
#define lm_title_screen_var (*(uint16 *)(g_ram + 0x1fffe))
#define lm_timer_var (*(uint8 *)(g_ram + 0x1ffe0))
extern bool g_lunar_magic;