Last active
November 7, 2020 21:35
-
-
Save charasyn/86eea71e55dfbda8de607aa4f56ec4d4 to your computer and use it in GitHub Desktop.
bsnes-as code for ALTTP USA 1.2 to enable warping in the overworld
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The main concept here is that we will create a backup of all of these addresses | |
// when the "Save Position" button is pressed. | |
// When the user hits the "Warp to Position" button, then we will switch to | |
// the flute gamemode, and restore this data in the middle of the flute routine. | |
// This will cause the user to warp to the position we saved, instead of a | |
// predetermined flute point. | |
// This list was built by examining the flute routines. All of these values | |
// are read from tables in the ROM when fluting normally. | |
array<uint32> position_addr = { | |
0x7E00E6, | |
0x7E00E8, | |
0x7E0122, | |
0x7E0124, | |
0x7E00E0, | |
0x7E00E2, | |
0x7E011E, | |
0x7E0120, | |
0x7E0020, | |
0x7E0022, | |
0x7E0624, | |
0x7E0626, | |
0x7E0628, | |
0x7E062A, | |
0x7E008A, | |
0x7E040A, | |
0x7E0084, | |
0x7E0088, | |
0x7E0086, | |
0x7E0618, | |
0x7E061A, | |
0x7E061C, | |
0x7E061E, | |
0x7E0696, | |
0x7E0698 | |
}; | |
bool position_ready; | |
array<uint16> position_data; | |
// Some global flags used to coordinate different parts of the code | |
bool save_pos; // Set from GUI | |
bool warp_to_pos; // Set from GUI | |
bool overwrite_flute_with_saved_data; // Set from code below | |
bool skip_bird; // Set from code below | |
void post_power(bool _reset) { | |
// This should be the same interceptor as used in ALTTPO normally | |
cpu::register_pc_interceptor(0x008053, @on_main_alttp); | |
// This additional interceptor is required to overwrite the position data | |
// in the middle of the flute routine | |
cpu::register_pc_interceptor(0x02eccc, @on_flute); | |
// This interceptor is just to avoid having the bird show up when restoring position. | |
// $53982 | |
cpu::register_pc_interceptor(0x0ab982, @on_bird); | |
// Set up global flags used to enable/disable parts of the code. | |
// This was hacked together and may be greatly improvable | |
save_pos = false; | |
warp_to_pos = false; | |
overwrite_flute_with_saved_data = false; | |
skip_bird = false; | |
// Initialize position_data to blank array. | |
position_ready = false; | |
position_data = array<uint16>(position_addr.length()); | |
@mainwindow = MainWindow(); | |
} | |
void on_main_alttp(uint32 pc) { | |
if (save_pos) { | |
save_pos = false; | |
// Save position data into array. | |
for (int i = 0; i < position_addr.length(); i += 1) { | |
uint32 addr = position_addr[i]; | |
uint16 data = bus::read_u16(addr); | |
position_data[i] = data; | |
} | |
position_ready = true; | |
} | |
if (warp_to_pos) { | |
warp_to_pos = false; | |
if (position_ready) { | |
// Set flag so we will overwrite the position in the flute interceptor. | |
overwrite_flute_with_saved_data = true; | |
// Also skip the bird animation. | |
skip_bird = true; | |
/////////////////////////////////////////////////////////////////////// | |
// Set us to be returning from flute | |
// Return to gamemode 09 (overworld) | |
bus::write_u8(0x7e010c, 0x09); | |
// Set current mode:submode to 0e:0a (flute mode) | |
bus::write_u8(0x7e0010, 0x0e); | |
bus::write_u8(0x7e0011, 0x0a); | |
// Set flute sub-submode to 6, meaning "OverworldMap_PrepExit". | |
// This will do a nice fadeout and load the correct graphics, then | |
// it will go to sub-submode 7, which is "BirdTravel_LoadTargetArea". | |
// This is read in the "Messaging_BirdTravel" subroutine. | |
bus::write_u16(0x7e0200, 6); | |
} else { | |
message("Unable to warp - no previous position data!"); | |
} | |
} | |
} | |
void on_flute(uint32 pc) { | |
if (overwrite_flute_with_saved_data) { | |
overwrite_flute_with_saved_data = false; | |
// If we have saved position data, restore it. | |
if (position_ready) { | |
for (int i = 0; i < position_addr.length(); i += 1) { | |
uint32 addr = position_addr[i]; | |
uint16 data = position_data[i]; | |
bus::write_u16(addr, data); | |
} | |
// A few patches after looking at: | |
// https://github.com/spannerisms/lttphack/blob/master/src/presets.asm | |
// "Set link to be in the Overworld" | |
bus::write_u8(0x7e001b, 0); | |
// Set light / dark world properly | |
bus::write_u8(0x7ef3ca, bus::read_u8(0x7e008a) & 0x40); | |
// "Reset which BG to interact with" | |
bus::write_u8(0x7e00ee, 0); | |
} else { | |
message("Unable to overwrite in flute routine - no previous position data!"); | |
} | |
} | |
} | |
void on_bird(uint32 pc) { | |
if (skip_bird) { | |
// We just skip over the JSL that spawns the bird | |
cpu::r.pc = pc + 4; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MainWindow @mainwindow; | |
class MainWindow { | |
private GUI::Window @window; | |
private GUI::Button @btnSavePos; | |
private GUI::Button @btnWarpToPos; | |
MainWindow() { | |
@window = GUI::Window(140,32,true); | |
window.title = "Control Window"; | |
window.size = GUI::Size(300, 300); | |
auto vl = GUI::VerticalLayout(); | |
vl.setSpacing(); | |
vl.setPadding(5,5); | |
window.append(vl); | |
@btnSavePos = GUI::Button(); | |
btnSavePos.text = "Save Position"; | |
btnSavePos.onActivate(@GUI::Callback(btnSavePosCallback)); | |
vl.append(btnSavePos, GUI::Size(-1,-1)); | |
@btnWarpToPos = GUI::Button(); | |
btnWarpToPos.text = "Warp to Position"; | |
btnWarpToPos.onActivate(@GUI::Callback(btnWarpToPosCallback)); | |
vl.append(btnWarpToPos, GUI::Size(-1,-1)); | |
window.visible = true; | |
window.setFocused(); | |
} | |
private void btnSavePosCallback() { | |
save_pos = true; | |
} | |
private void btnWarpToPosCallback() { | |
warp_to_pos = true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment