Skip to content

Commit c96e0c9

Browse files
committed
Basic Return to Dinosaur land support
1 parent 7d9528d commit c96e0c9

File tree

11 files changed

+88
-39
lines changed

11 files changed

+88
-39
lines changed

assets/compile_resources.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ def decomp_data(ea):
235235
kLmFeature_TideWaterTweak = 1 << 18
236236
kLmFeature_EnemyCollTweak = 1 << 19
237237
kLmFeature_Ow4bppGfx = 1 << 20
238+
kLmFeature_DontResetOwPlayersMap = 1 << 21
239+
kLmFeature_NonStdGfxAA8D = 1 << 22
240+
kLmFeature_TimerTweaks = 1 << 23
241+
kLmFeature_NoDefaultSavePrompts = 1 << 24
238242

239243
kHack_Walljump = 1 << 0
240244

@@ -734,10 +738,15 @@ def calc_exanim_size(p):
734738
lm_feat.flags |= kLmFeature_TideWaterTweak if get_byte(0xa045) == 0x22 else 0
735739
lm_feat.flags |= kLmFeature_EnemyCollTweak if get_byte(0x194B6) == 0x5c else 0
736740
lm_feat.flags |= kLmFeature_Ow4bppGfx if get_bytes(0xA149, 4) != b'\x22\x28\xBA\x00' else 0
741+
lm_feat.flags |= kLmFeature_DontResetOwPlayersMap if get_byte(0xa0a0) == 0xea else 0
742+
lm_feat.flags |= kLmFeature_NonStdGfxAA8D if get_byte(0xAA8D) != 0x08 else 0
743+
lm_feat.flags |= kLmFeature_TimerTweaks if get_byte(0x58E24) == 0x8f else 0
744+
lm_feat.flags |= kLmFeature_NoDefaultSavePrompts if get_byte(0x3BA26) == 0 else 0
745+
737746

738747
# Allows Mario to perform a wall kick by sliding along a wall and pressing the
739748
# B button.
740-
lm_feat.hacks |= kHack_Walljump if get_24(0xA2A2) != 0x586F1 else 0
749+
lm_feat.hacks |= kHack_Walljump if get_24(0xA2A1) != 0x86F122 else 0
741750

742751
def add_custom_ow_palette():
743752
r = b''

assets/util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def get_word(addr):
5252
'enhanced' : ('Super Mario World Enhanced.ips', '2882a39ac64b597e9260e92aaba610d0b6f03adb', 'Super Mario World Enhanced.bsdiff', '5a53369916fd728033d16db3abceb487900f903a', 'ebe23d8a26759ba1b5c2f4d6d8f8db3ab88e902f'),
5353
'redrawn' : ('smw_redrawn.ips', '7168df51ba025a12177ce00e88540c1341ef3efc', 'smw_redrawn.bsdiff', '13b658e626020aa35dca4e1c3648c6a6d8afa901', '50702ffc8c2e7115c9ba0c80c8ec40da5a487651'),
5454
'nsmb' : ('SMW with Levels from NSMB.bps', '4277edf003340021ce4e68fe2278d1d73f4d798c', 'SMW with Levels from NSMB.bsdiff', 'e2d2487324374aea1d67a6aa6b3b47f8b3e6727c', '877e9c6fce29e80e4c52892120af06748550487a'),
55+
'return_dino_land' : ('Return to Dinosaur Land.bps', 'e9a891ecd0f6f43a4592487ca2590311be00396d', 'Return to Dinosaur Land.bsdiff', 'ad2ebd7b416cbfd3cd7cac833b0ca7f690b9144b', '1d03777086f3c86b1693f9ce2411f560813732a8')
5556
}
5657
kModsPath = os.path.join(DEFAULT_ROM_DIRECTORY, '../smw_hacks/mods')
5758

src/common_cpu_infra.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ Snes *SnesInit(const uint8 *data, int data_size) {
279279
}
280280
}
281281
g_rtl_game_info->initialize();
282+
snes_reset(g_snes, true); // reset after loading
282283
PatchBugs(1, 0);
283284
} else {
284285
g_runmode = RM_MINE;

src/funcs.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1534,7 +1534,7 @@ void SubmapSwitchProcess01_UpdateLayer1(void);
15341534
void SubmapSwitchProcess05_UpdatePalette(void);
15351535
void SubmapSwitchProcess06_EndWindowHDMA(void);
15361536
void SubmapSwitchProcess07_EndSubmapSwitch(void);
1537-
void UnlockOverworldPathBasedOnExit(void);
1537+
uint16 UnlockOverworldPathBasedOnExit(void);
15381538
uint16 UpdateLevelName_049D7F(uint16 j, uint16 k, uint16 r2w);
15391539
void UpdateLevelName(uint16 r0w);
15401540
void UpdateOverworldSpritePosition(uint8 k);
@@ -2114,6 +2114,10 @@ enum {
21142114
kLmFeature_TideWaterTweak = 1 << 18,
21152115
kLmFeature_EnemyCollTweak = 1 << 19,
21162116
kLmFeature_Ow4bppGfx = 1 << 20,
2117+
kLmFeature_DontResetOwPlayersMap = 1 << 21,
2118+
kLmFeature_NonStdGfxAA8D = 1 << 22,
2119+
kLmFeature_TimerTweaks = 1 << 23,
2120+
kLmFeature_NoDefaultSavePrompts = 1 << 24,
21172121
};
21182122

21192123
// Non lunar magic hacks

src/smw_00.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2135,7 +2135,8 @@ void GameMode0C_LoadOverworld() { // 00a087
21352135
ClearOverworldAndCutsceneRAM();
21362136
if (misc_intro_level_flag) {
21372137
timer_title_screen_input_timer = -80;
2138-
ow_players_map[0] = 0;
2138+
if (!HAS_LM_FEATURE(kLmFeature_DontResetOwPlayersMap))
2139+
ow_players_map[0] = 0;
21392140
mirror_mosaic_size_and_bgenable = -16;
21402141
misc_game_mode = 16;
21412142
return;
@@ -2710,8 +2711,9 @@ void UploadGraphicsFiles_UploadGFXFile(uint16 dst_addr, uint8 j, uint8 index) {
27102711
}
27112712

27122713
bool lm_flag = HAS_LM_FEATURE(kLmFeature_4bppgfx);
2714+
bool lm_flag2 = HAS_LM_FEATURE(kLmFeature_NonStdGfxAA8D);
27132715

2714-
if (misc_level_tileset_setting >= 0x11 && j == (lm_flag ? 0x32 : 8) || j == (lm_flag ? 0x32 : 30)) {
2716+
if (misc_level_tileset_setting >= 0x11 && j == (lm_flag2 ? 0x32 : 8) || j == (lm_flag2 ? 0x32 : 30)) {
27152717
uint16 r10w = -256;
27162718
for (int8 i = 127; i >= 0; --i) {
27172719
for (int8 k = 7; k >= 0; --k) {
@@ -2720,11 +2722,12 @@ void UploadGraphicsFiles_UploadGFXFile(uint16 dst_addr, uint8 j, uint8 index) {
27202722
*(uint16 *)&graphics_3_bppto4_bppbuffer[(uint8)k] = WORD(p0[0]) | swap16(v11);
27212723
p0 += 2;
27222724
}
2725+
int step = lm_flag ? 2 : 1;
27232726
for (int8 m = 7; m >= 0; --m) {
27242727
const uint8 *v14 = p0;
27252728
uint16 r12w = *v14;
27262729
*dst++ = r12w | r10w & (*(uint16 *)&graphics_3_bppto4_bppbuffer[(uint8)m] | swap16(*(uint16 *)v14));
2727-
p0 += 1;
2730+
p0 += step;
27282731
}
27292732
}
27302733
} else {
@@ -4267,7 +4270,8 @@ void PlayerState09_Death() { // 00d0b6
42674270
if (!flag_prevent_yoshi_carry_over)
42684271
yoshi_carry_over_levels_flag = 0;
42694272
if ((--player_current_life_count & 0x80) == 0) {
4270-
if (counter_timer_ones | counter_timer_tens | counter_timer_hundreds) {
4273+
if (HAS_LM_FEATURE(kLmFeature_TimerTweaks) && lm_timer_var != 0 ||
4274+
counter_timer_ones | counter_timer_tens | counter_timer_hundreds) {
42714275
misc_game_mode = 11;
42724276
return;
42734277
}

src/smw_04.c

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -741,9 +741,20 @@ void OwProcess00_OverworldEntryInitialization() { // 048ef1
741741
}
742742

743743
void OwProcess02_HandleLevelBeaten() { // 048f87
744-
UnlockOverworldPathBasedOnExit();
744+
uint16 r4 = UnlockOverworldPathBasedOnExit();
745745
uint8 v0 = 7;
746-
while ((uint8)ow_tile_player_is_standing_on != kOwTriggerSaveTiles_048F7F[v0]) {
746+
uint8 a = (uint8)ow_tile_player_is_standing_on;
747+
748+
if (g_lunar_magic) {
749+
if (ow_level_tile_settings[ow_level_number_of_each_tiletbl[r4]] & 0x10) {
750+
a = 0x80;
751+
} else {
752+
if (HAS_LM_FEATURE(kLmFeature_NoDefaultSavePrompts))
753+
a = 0xff;
754+
}
755+
}
756+
757+
while (a != kOwTriggerSaveTiles_048F7F[v0]) {
747758
if ((--v0 & 0x80) != 0)
748759
goto LABEL_10;
749760
}
@@ -1279,27 +1290,29 @@ void OwProcess0C_IntroMarch() { // 0498c6
12791290
}
12801291
}
12811292

1282-
void UnlockOverworldPathBasedOnExit() { // 049903
1283-
if ((int8)misc_exit_level_action > 0) {
1284-
uint16 r8 = kSharedOverworldPathTables_DATA_049060[(uint8)(misc_exit_level_action - 1)];
1285-
uint8 v0 = player_current_characterx4;
1286-
PointU16 *pt = get_PointU16(ow_players_pos, player_current_characterx4);
1287-
uint16 r0w = pt->x >> 4;
1288-
PointU16 *v2 = get_PointU16(ow_players_grid_aligned_pos, player_current_characterx4);
1289-
v2->x = r0w;
1290-
uint16 r2w = pt->y >> 4;
1291-
v2->y = r2w;
1292-
uint16 r4w = CalculateOverworldPlayerPosition(v0 >> 2, r0w, r2w);
1293-
uint16 v3 = ow_level_direction_flags[r4w];
1294-
int16 v4 = r8;
1295-
if (r8) {
1296-
do {
1297-
v3 >>= 1;
1298-
--v4;
1299-
} while (v4 >= 0);
1300-
}
1301-
*(uint16 *)&ow_level_tile_settings[ow_level_number_of_each_tiletbl[r4w]] |= kBitTable_Bank04[(uint16)(2 * (v3 & 3)) >> 1];
1293+
uint16 UnlockOverworldPathBasedOnExit() { // 049903
1294+
if ((int8)misc_exit_level_action <= 0)
1295+
return 0;
1296+
1297+
uint16 r8 = kSharedOverworldPathTables_DATA_049060[(uint8)(misc_exit_level_action - 1)];
1298+
uint8 v0 = player_current_characterx4;
1299+
PointU16 *pt = get_PointU16(ow_players_pos, player_current_characterx4);
1300+
uint16 r0w = pt->x >> 4;
1301+
PointU16 *v2 = get_PointU16(ow_players_grid_aligned_pos, player_current_characterx4);
1302+
v2->x = r0w;
1303+
uint16 r2w = pt->y >> 4;
1304+
v2->y = r2w;
1305+
uint16 r4w = CalculateOverworldPlayerPosition(v0 >> 2, r0w, r2w);
1306+
uint16 v3 = ow_level_direction_flags[r4w];
1307+
int16 v4 = r8;
1308+
if (r8) {
1309+
do {
1310+
v3 >>= 1;
1311+
--v4;
1312+
} while (v4 >= 0);
13021313
}
1314+
*(uint16 *)&ow_level_tile_settings[ow_level_number_of_each_tiletbl[r4w]] |= kBitTable_Bank04[(uint16)(2 * (v3 & 3)) >> 1];
1315+
return r4w;
13031316
}
13041317

13051318
void HandleOverworldPathExits() { // 049a24
@@ -2043,7 +2056,7 @@ void OwEventProcess07_SilentEventsAndEndOfEvent_Entry2(uint8 a, bool from_where)
20432056
if (HAS_LM_FEATURE(kLmFeature_EventStuff)) {
20442057
LmHook_EventStuff(a, from_where);
20452058
} else {
2046-
for (uint8 i = 43; (i & 0x80) == 0; --i) {
2059+
for (uint8 i = kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_SIZE - 1; (i & 0x80) == 0; --i) {
20472060
if (a == kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles[i]) {
20482061
uint8 v4 = i;
20492062
uint8 r2 = kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileLayer[i];

src/smw_05.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,8 @@ void LoadLevelHeader() { // 0584e3
594594
r0 = hdr[3];
595595
if (!counter_sublevels_entered) {
596596
counter_timer_hundreds = kLoadLevelHeader_TimerTable[r0 >> 6];
597+
if (HAS_LM_FEATURE(kLmFeature_TimerTweaks))
598+
lm_timer_var = counter_timer_hundreds;
597599
counter_timer_tens = 0;
598600
counter_timer_ones = 0;
599601
}

src/smw_cpu_infra.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,17 @@ void SmwCpuInitialize(void) {
245245
static const uint8 kRevert_0x2e6ec[] = { 0xa9, 0x38, 0x9d, 0xea, 0x15 };
246246
memcpy(SnesRomPtr(0x2e6ec), kRevert_0x2e6ec, sizeof(kRevert_0x2e6ec));
247247
}
248+
249+
// fast rom
250+
static const uint8 kRevert_0xfffc[] = { 0x00, 0x80 };
251+
memcpy(SnesRomPtr(0xfffc), kRevert_0xfffc, sizeof(kRevert_0xfffc));
252+
static const uint8 kRevert_0xffea[] = { 0x6a, 0x81 };
253+
memcpy(SnesRomPtr(0xffea), kRevert_0xffea, sizeof(kRevert_0xffea));
254+
static const uint8 kRevert_0x801c[] = { 0xfb };
255+
memcpy(SnesRomPtr(0x801c), kRevert_0x801c, sizeof(kRevert_0x801c));
256+
static const uint8 kRevert_0x8713[] = { 0xb7, 0x02, 0x85, 0x01 };
257+
memcpy(SnesRomPtr(0x8713), kRevert_0x8713, sizeof(kRevert_0x8713));
258+
248259
}
249260
}
250261

src/snes/cpu.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -751,14 +751,16 @@ static void cpu_doOpcode(Cpu* cpu, uint8_t opcode) {
751751
pc_hist[pc_hist_ctr] = cur_pc;
752752
pc_hist_ctr = (pc_hist_ctr + 1) & 15;
753753

754-
if (0 && cur_pc == 0x5D83B) {
754+
if (cur_pc == 0x3FDE0) {
755+
DumpCpuHistory();
755756
g_snes->debug_cycles = 0;
756757
}
757758

758759
if (cur_pc == pc_bp) {
759-
printf("Reached BP 0x%x. A=0x%.2x, X=0x%.2x, Y=0x%.2x. C=%d. lm_var13CD=%x\n",
760-
cur_pc, cpu->a, cpu->x, cpu->y, cpu->c,
761-
*(uint16*)&g_ram[14]);
760+
printf("Reached BP 0x%x. A=0x%.2x, X=0x%.2x, Y=0x%.2x. C=0x%.2x,0x%.2x\n",
761+
cur_pc, cpu->a, cpu->x, cpu->y,
762+
g_ram[0xbcee],
763+
g_ram[0xad10]);
762764
// printf("T: 16 j=%d, %d\n", g_cpu->y, g_cpu->a);
763765
bp_cnt += 1;
764766
//g_snes->debug_cycles = 1;
@@ -776,7 +778,7 @@ static void cpu_doOpcode(Cpu* cpu, uint8_t opcode) {
776778
break;
777779
case 2: // rtl
778780
cpu->pc = cpu_pullWord(cpu) + 1;
779-
cpu->k = cpu_pullByte(cpu);
781+
cpu->k = cpu_pullByte(cpu) & 0x7f;
780782
break;
781783
case 0xe5:
782784
case 0xe9:
@@ -1002,7 +1004,7 @@ static void cpu_doOpcode(Cpu* cpu, uint8_t opcode) {
10021004
cpu_pushByte(cpu, cpu->k);
10031005
cpu_pushWord(cpu, cpu->pc - 1);
10041006
cpu->pc = value;
1005-
cpu->k = newK;
1007+
cpu->k = newK & 0x7f;
10061008
break;
10071009
}
10081010
case 0x23: { // and sr
@@ -1378,7 +1380,7 @@ static void cpu_doOpcode(Cpu* cpu, uint8_t opcode) {
13781380
DumpCpuHistory();
13791381
Die("The game has crashed!\n");
13801382
}
1381-
cpu->k = new_k;
1383+
cpu->k = new_k & 0x7f;
13821384
cpu->pc = value;
13831385
break;
13841386
}
@@ -1488,7 +1490,7 @@ static void cpu_doOpcode(Cpu* cpu, uint8_t opcode) {
14881490
}
14891491

14901492
cpu->pc = cpu_pullWord(cpu) + 1;
1491-
cpu->k = cpu_pullByte(cpu);
1493+
cpu->k = cpu_pullByte(cpu) & 0x7f;
14921494
break;
14931495
}
14941496
case 0x6c: { // jmp ind
@@ -2175,7 +2177,7 @@ static void cpu_doOpcode(Cpu* cpu, uint8_t opcode) {
21752177
case 0xdc: { // jml ial
21762178
uint16_t adr = cpu_readOpcodeWord(cpu);
21772179
cpu->pc = cpu_readWord(cpu, adr, (adr + 1) & 0xffff);
2178-
cpu->k = cpu_read(cpu, (adr + 2) & 0xffff);
2180+
cpu->k = cpu_read(cpu, (adr + 2) & 0xffff) & 0x7f;
21792181
break;
21802182
}
21812183
case 0xdd: { // cmp abx(r)

src/snes/snes_other.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ bool snes_loadRom(Snes* snes, const uint8_t* data, int length) {
9898
snes->cart, headers[used].cartType,
9999
newData, newLength, headers[used].chips > 0 ? headers[used].ramSize : 0
100100
);
101-
snes_reset(snes, true); // reset after loading
101+
102102
free(newData);
103103
return true;
104104
}

0 commit comments

Comments
 (0)