From 176cb8b8830c885478ab361259c1347d01e9f48b Mon Sep 17 00:00:00 2001 From: InsaneFirebat Date: Mon, 24 Mar 2025 21:42:42 -0400 Subject: [PATCH 01/43] Improve Pseudo G-Mode Toggle palette FX and enemy projectiles with pseudo g-mode Fix misplaced infidoppler define Shift temp menu RAM +$10 bytes to give us more space for permanent menu RAM --- src/defines.asm | 161 ++++++++++++++++++++++++----------------------- src/gamemenu.asm | 18 +++++- src/symbols.asm | 157 ++++++++++++++++++++++----------------------- 3 files changed, 178 insertions(+), 158 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index a78c2285..32173a16 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -78,6 +78,7 @@ !ram_activated_shine_duration = !WRAM_START+$5E !ram_watch_left_hud = !WRAM_START+$60 !ram_watch_right_hud = !WRAM_START+$62 +!ram_infidoppler_active = !WRAM_START+$64 ; ^ FREE SPACE ^ up to +$6C @@ -261,11 +262,11 @@ !ram_cm_palette_numseloutline = !WRAM_MENU_START+$70 !ram_cm_palette_numsel = !WRAM_MENU_START+$72 -!ram_infidoppler_active = !WRAM_START+$74 +!ram_cm_gmode = !WRAM_MENU_START+$74 -; ^ FREE SPACE ^ up to +$76 +; ^ FREE SPACE ^ up to +$86 -!ram_cm_preserved_timers = !WRAM_MENU_START+$78 ; 8 bytes +!ram_cm_preserved_timers = !WRAM_MENU_START+$88 ; 8 bytes ; ------------------ ; Reusable RAM Menu @@ -274,81 +275,81 @@ ; The following RAM may be used multiple times, ; as long as it isn't used multiple times on the same menu page -!ram_cm_watch_enemy_property = !WRAM_MENU_START+$80 -!ram_cm_watch_enemy_index = !WRAM_MENU_START+$82 -!ram_cm_watch_enemy_side = !WRAM_MENU_START+$84 -!ram_cm_watch_common_address = !WRAM_MENU_START+$86 - -!ram_cm_preset_elevator = !WRAM_MENU_START+$80 - -!ram_cm_door_dynamic = !WRAM_MENU_START+$80 -!ram_cm_door_menu_value = !WRAM_MENU_START+$82 -!ram_cm_door_menu_bank = !WRAM_MENU_START+$84 -!ram_cm_door_direction_index = !WRAM_MENU_START+$86 -!ram_cm_itempickups_visible = !WRAM_MENU_START+$88 -!ram_cm_itempickups_chozo = !WRAM_MENU_START+$8A -!ram_cm_itempickups_hidden = !WRAM_MENU_START+$8C - -!ram_cm_phan_first_phase = !WRAM_MENU_START+$80 -!ram_cm_phan_second_phase = !WRAM_MENU_START+$82 -!ram_cm_turret_rng = !WRAM_MENU_START+$84 - -!ram_cm_varia = !WRAM_MENU_START+$80 -!ram_cm_gravity = !WRAM_MENU_START+$82 -!ram_cm_morph = !WRAM_MENU_START+$84 -!ram_cm_bombs = !WRAM_MENU_START+$86 -!ram_cm_spring = !WRAM_MENU_START+$88 -!ram_cm_screw = !WRAM_MENU_START+$8A -!ram_cm_hijump = !WRAM_MENU_START+$8C -!ram_cm_space = !WRAM_MENU_START+$8E -!ram_cm_speed = !WRAM_MENU_START+$90 -!ram_cm_charge = !WRAM_MENU_START+$92 -!ram_cm_ice = !WRAM_MENU_START+$94 -!ram_cm_wave = !WRAM_MENU_START+$96 -!ram_cm_spazer = !WRAM_MENU_START+$98 -!ram_cm_plasma = !WRAM_MENU_START+$9A - -!ram_cm_zeb1 = !WRAM_MENU_START+$80 -!ram_cm_zeb2 = !WRAM_MENU_START+$82 -!ram_cm_zeb3 = !WRAM_MENU_START+$84 -!ram_cm_zeb4 = !WRAM_MENU_START+$86 -!ram_cm_zebmask = !WRAM_MENU_START+$88 - -!ram_cm_custompalette_blue = !WRAM_MENU_START+$80 -!ram_cm_custompalette_green = !WRAM_MENU_START+$82 -!ram_cm_custompalette_red = !WRAM_MENU_START+$84 -!ram_cm_custompalette = !WRAM_MENU_START+$86 -!ram_cm_dummy_on = !WRAM_MENU_START+$8A -!ram_cm_dummy_off = !WRAM_MENU_START+$8C -!ram_cm_dummy_num = !WRAM_MENU_START+$8E - -!ram_cm_ceres_seconds = !WRAM_MENU_START+$80 -!ram_cm_zebes_seconds = !WRAM_MENU_START+$82 - -!ram_cm_crop_mode = !WRAM_MENU_START+$80 -!ram_cm_crop_tile = !WRAM_MENU_START+$82 - -!ram_cm_brb = !WRAM_MENU_START+$80 -!ram_cm_brb_timer = !WRAM_MENU_START+$82 -!ram_cm_brb_frames = !WRAM_MENU_START+$84 -!ram_cm_brb_secs = !WRAM_MENU_START+$86 -!ram_cm_brb_mins = !WRAM_MENU_START+$88 -!ram_cm_brb_screen = !WRAM_MENU_START+$8A -!ram_cm_brb_timer_mode = !WRAM_MENU_START+$8C -!ram_cm_brb_scroll = !WRAM_MENU_START+$8E -!ram_cm_brb_scroll_X = !WRAM_MENU_START+$90 -!ram_cm_brb_scroll_Y = !WRAM_MENU_START+$92 -!ram_cm_brb_scroll_H = !WRAM_MENU_START+$94 -!ram_cm_brb_scroll_V = !WRAM_MENU_START+$96 -!ram_cm_brb_scroll_timer = !WRAM_MENU_START+$98 -!ram_cm_brb_palette = !WRAM_MENU_START+$9A -!ram_cm_brb_set_cycle = !WRAM_MENU_START+$9C -!ram_cm_brb_cycle_time = !WRAM_MENU_START+$9E - -!ram_cm_keyboard_buffer = !WRAM_MENU_START+$80 ; $18 bytes - -!ram_cm_manage_slots = !WRAM_MENU_START+$80 -!ram_cm_selected_slot = !WRAM_MENU_START+$82 +!ram_cm_watch_enemy_property = !WRAM_MENU_START+$90 +!ram_cm_watch_enemy_index = !WRAM_MENU_START+$92 +!ram_cm_watch_enemy_side = !WRAM_MENU_START+$94 +!ram_cm_watch_common_address = !WRAM_MENU_START+$96 + +!ram_cm_preset_elevator = !WRAM_MENU_START+$90 + +!ram_cm_door_dynamic = !WRAM_MENU_START+$90 +!ram_cm_door_menu_value = !WRAM_MENU_START+$92 +!ram_cm_door_menu_bank = !WRAM_MENU_START+$94 +!ram_cm_door_direction_index = !WRAM_MENU_START+$96 +!ram_cm_itempickups_visible = !WRAM_MENU_START+$98 +!ram_cm_itempickups_chozo = !WRAM_MENU_START+$9A +!ram_cm_itempickups_hidden = !WRAM_MENU_START+$9C + +!ram_cm_phan_first_phase = !WRAM_MENU_START+$90 +!ram_cm_phan_second_phase = !WRAM_MENU_START+$92 +!ram_cm_turret_rng = !WRAM_MENU_START+$94 + +!ram_cm_varia = !WRAM_MENU_START+$90 +!ram_cm_gravity = !WRAM_MENU_START+$92 +!ram_cm_morph = !WRAM_MENU_START+$94 +!ram_cm_bombs = !WRAM_MENU_START+$96 +!ram_cm_spring = !WRAM_MENU_START+$98 +!ram_cm_screw = !WRAM_MENU_START+$9A +!ram_cm_hijump = !WRAM_MENU_START+$9C +!ram_cm_space = !WRAM_MENU_START+$9E +!ram_cm_speed = !WRAM_MENU_START+$A0 +!ram_cm_charge = !WRAM_MENU_START+$A2 +!ram_cm_ice = !WRAM_MENU_START+$A4 +!ram_cm_wave = !WRAM_MENU_START+$A6 +!ram_cm_spazer = !WRAM_MENU_START+$A8 +!ram_cm_plasma = !WRAM_MENU_START+$AA + +!ram_cm_zeb1 = !WRAM_MENU_START+$90 +!ram_cm_zeb2 = !WRAM_MENU_START+$92 +!ram_cm_zeb3 = !WRAM_MENU_START+$94 +!ram_cm_zeb4 = !WRAM_MENU_START+$96 +!ram_cm_zebmask = !WRAM_MENU_START+$98 + +!ram_cm_custompalette_blue = !WRAM_MENU_START+$90 +!ram_cm_custompalette_green = !WRAM_MENU_START+$92 +!ram_cm_custompalette_red = !WRAM_MENU_START+$94 +!ram_cm_custompalette = !WRAM_MENU_START+$96 +!ram_cm_dummy_on = !WRAM_MENU_START+$9A +!ram_cm_dummy_off = !WRAM_MENU_START+$9C +!ram_cm_dummy_num = !WRAM_MENU_START+$9E + +!ram_cm_ceres_seconds = !WRAM_MENU_START+$90 +!ram_cm_zebes_seconds = !WRAM_MENU_START+$92 + +!ram_cm_crop_mode = !WRAM_MENU_START+$90 +!ram_cm_crop_tile = !WRAM_MENU_START+$92 + +!ram_cm_brb = !WRAM_MENU_START+$90 +!ram_cm_brb_timer = !WRAM_MENU_START+$92 +!ram_cm_brb_frames = !WRAM_MENU_START+$94 +!ram_cm_brb_secs = !WRAM_MENU_START+$96 +!ram_cm_brb_mins = !WRAM_MENU_START+$98 +!ram_cm_brb_screen = !WRAM_MENU_START+$9A +!ram_cm_brb_timer_mode = !WRAM_MENU_START+$9C +!ram_cm_brb_scroll = !WRAM_MENU_START+$9E +!ram_cm_brb_scroll_X = !WRAM_MENU_START+$A0 +!ram_cm_brb_scroll_Y = !WRAM_MENU_START+$A2 +!ram_cm_brb_scroll_H = !WRAM_MENU_START+$A4 +!ram_cm_brb_scroll_V = !WRAM_MENU_START+$A6 +!ram_cm_brb_scroll_timer = !WRAM_MENU_START+$A8 +!ram_cm_brb_palette = !WRAM_MENU_START+$AA +!ram_cm_brb_set_cycle = !WRAM_MENU_START+$AC +!ram_cm_brb_cycle_time = !WRAM_MENU_START+$AE + +!ram_cm_keyboard_buffer = !WRAM_MENU_START+$90 ; $18 bytes + +!ram_cm_manage_slots = !WRAM_MENU_START+$90 +!ram_cm_selected_slot = !WRAM_MENU_START+$92 ; ^ FREE SPACE ^ up to +$CE ; Note: +$B8 to +$CE range also used as frames held counters @@ -835,6 +836,7 @@ !SAMUS_CONTACT_DAMAGE_INDEX = $0A6E !SAMUS_WATER_PHYSICS = $0A70 ; Not used in vanilla !SAMUS_HYPER_BEAM = $0A76 +!TIME_IS_FROZEN = $0A78 !DEMO_PREINSTRUCTION_POINTER = $0A7A !DEMO_INSTRUCTION_TIMER = $0A7C !DEMO_INSTRUCTION_POINTER = $0A7E @@ -926,6 +928,7 @@ !SAMUS_KNOCKBACK_TIMER = $18AA !LAVA_ACID_Y = $1962 !FX_BASE_Y = $1978 +!ENEMY_PROJ_ENABLE = $198D !ENEMY_PROJ_ID = $1997 !ENEMY_PROJ_X_SUBPX = $1A27 !ENEMY_PROJ_X = $1A4B @@ -936,6 +939,7 @@ !ENEMY_PROJ_RADIUS = $1BB3 !ENEMY_PROJ_PROPERTIES = $1BD7 !MESSAGE_BOX_INDEX = $1C1F +!PLM_ENABLE = $1C23 !PLM_GFX_INDEX = $1C2D !PLM_ID = $1C37 !PLM_BLOCK_INDEX = $1C87 @@ -945,6 +949,7 @@ !PLM_ROOM_ARGUMENT = $1DC7 !PLM_VARIABLE = $1E17 !SAVE_STATION_LOCKOUT = $1E75 +!PALETTE_FX_ENABLE = $1E79 !PALETTE_FX_ID = $1E7D !PALETTE_FX_COLOR_INDICES = $1E8D !PALETTE_FX_VARIABLE = $1E9D diff --git a/src/gamemenu.asm b/src/gamemenu.asm index ba5ac8a7..0a580685 100644 --- a/src/gamemenu.asm +++ b/src/gamemenu.asm @@ -219,10 +219,24 @@ game_pacifist: %cm_toggle("Deal Zero Damage", !ram_pacifist, #$01, #0) game_debugplms: - %cm_toggle_bit_inverted("Pseudo G-Mode", $7E1C23, #$8000, #0) + %cm_toggle_bit("Pseudo G-Mode", !ram_cm_gmode, #$0001, #.routine) + .routine + CMP #$0000 : BNE .enable + ; disable + LDA #$8000 + STA !PALETTE_FX_ENABLE + STA !PLM_ENABLE + STA !ENEMY_PROJ_ENABLE + RTL + + .enable + STZ !PALETTE_FX_ENABLE + STZ !PLM_ENABLE + STZ !ENEMY_PROJ_ENABLE + RTL game_debugprojectiles: - %cm_toggle_bit("Enable Projectiles", $7E198D, #$8000, #0) + %cm_toggle_bit("Enable Projectiles", !ENEMY_PROJ_ENABLE, #$8000, #0) game_debugfixscrolloffsets: %cm_toggle_bit("Fix Scroll Offsets", !ram_fix_scroll_offsets, #$0001, #0) diff --git a/src/symbols.asm b/src/symbols.asm index 3d602a3d..ce18adc3 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -76,6 +76,7 @@ ram_print_segment_timer = !ram_print_segment_timer ; !WRAM_START+$5C ram_activated_shine_duration = !ram_activated_shine_duration ; !WRAM_START+$5E ram_watch_left_hud = !ram_watch_left_hud ; !WRAM_START+$60 ram_watch_right_hud = !ram_watch_right_hud ; !WRAM_START+$62 +ram_infidoppler_active = !ram_infidoppler_active ; !WRAM_START+$64 ; ^ FREE SPACE ^ up to +$6C @@ -259,11 +260,11 @@ ram_cm_palette_seltextbg = !ram_cm_palette_seltextbg ; !WRAM_MENU_START+$6E ram_cm_palette_numseloutline = !ram_cm_palette_numseloutline ; !WRAM_MENU_START+$70 ram_cm_palette_numsel = !ram_cm_palette_numsel ; !WRAM_MENU_START+$72 -ram_infidoppler_active = !ram_infidoppler_active ; !WRAM_START+$74 +ram_cm_gmode = !ram_cm_gmode ; !WRAM_MENU_START+$74 -; ^ FREE SPACE ^ up to +$76 +; ^ FREE SPACE ^ up to +$86 -ram_cm_preserved_timers = !ram_cm_preserved_timers ; !WRAM_MENU_START+$78 ; 8 bytes +ram_cm_preserved_timers = !ram_cm_preserved_timers ; !WRAM_MENU_START+$88 ; 8 bytes ; ------------------ ; Reusable RAM Menu @@ -272,81 +273,81 @@ ram_cm_preserved_timers = !ram_cm_preserved_timers ; !WRAM_MENU_START+$78 ; 8 by ; The following RAM may be used multiple times, ; as long as it isn't used multiple times on the same menu page -ram_cm_watch_enemy_property = !ram_cm_watch_enemy_property ; !WRAM_MENU_START+$80 -ram_cm_watch_enemy_index = !ram_cm_watch_enemy_index ; !WRAM_MENU_START+$82 -ram_cm_watch_enemy_side = !ram_cm_watch_enemy_side ; !WRAM_MENU_START+$84 -ram_cm_watch_common_address = !ram_cm_watch_common_address ; !WRAM_MENU_START+$86 - -ram_cm_preset_elevator = !ram_cm_preset_elevator ; !WRAM_MENU_START+$80 - -ram_cm_door_dynamic = !ram_cm_door_dynamic ; !WRAM_MENU_START+$80 -ram_cm_door_menu_value = !ram_cm_door_menu_value ; !WRAM_MENU_START+$82 -ram_cm_door_menu_bank = !ram_cm_door_menu_bank ; !WRAM_MENU_START+$84 -ram_cm_door_direction_index = !ram_cm_door_direction_index ; !WRAM_MENU_START+$86 -ram_cm_itempickups_visible = !ram_cm_itempickups_visible ; !WRAM_MENU_START+$88 -ram_cm_itempickups_chozo = !ram_cm_itempickups_chozo ; !WRAM_MENU_START+$8A -ram_cm_itempickups_hidden = !ram_cm_itempickups_hidden ; !WRAM_MENU_START+$8C - -ram_cm_phan_first_phase = !ram_cm_phan_first_phase ; !WRAM_MENU_START+$80 -ram_cm_phan_second_phase = !ram_cm_phan_second_phase ; !WRAM_MENU_START+$82 -ram_cm_turret_rng = !ram_cm_turret_rng ; !WRAM_MENU_START+$84 - -ram_cm_varia = !ram_cm_varia ; !WRAM_MENU_START+$80 -ram_cm_gravity = !ram_cm_gravity ; !WRAM_MENU_START+$82 -ram_cm_morph = !ram_cm_morph ; !WRAM_MENU_START+$84 -ram_cm_bombs = !ram_cm_bombs ; !WRAM_MENU_START+$86 -ram_cm_spring = !ram_cm_spring ; !WRAM_MENU_START+$88 -ram_cm_screw = !ram_cm_screw ; !WRAM_MENU_START+$8A -ram_cm_hijump = !ram_cm_hijump ; !WRAM_MENU_START+$8C -ram_cm_space = !ram_cm_space ; !WRAM_MENU_START+$8E -ram_cm_speed = !ram_cm_speed ; !WRAM_MENU_START+$90 -ram_cm_charge = !ram_cm_charge ; !WRAM_MENU_START+$92 -ram_cm_ice = !ram_cm_ice ; !WRAM_MENU_START+$94 -ram_cm_wave = !ram_cm_wave ; !WRAM_MENU_START+$96 -ram_cm_spazer = !ram_cm_spazer ; !WRAM_MENU_START+$98 -ram_cm_plasma = !ram_cm_plasma ; !WRAM_MENU_START+$9A - -ram_cm_zeb1 = !ram_cm_zeb1 ; !WRAM_MENU_START+$80 -ram_cm_zeb2 = !ram_cm_zeb2 ; !WRAM_MENU_START+$82 -ram_cm_zeb3 = !ram_cm_zeb3 ; !WRAM_MENU_START+$84 -ram_cm_zeb4 = !ram_cm_zeb4 ; !WRAM_MENU_START+$86 -ram_cm_zebmask = !ram_cm_zebmask ; !WRAM_MENU_START+$88 - -ram_cm_custompalette_blue = !ram_cm_custompalette_blue ; !WRAM_MENU_START+$80 -ram_cm_custompalette_green = !ram_cm_custompalette_green ; !WRAM_MENU_START+$82 -ram_cm_custompalette_red = !ram_cm_custompalette_red ; !WRAM_MENU_START+$84 -ram_cm_custompalette = !ram_cm_custompalette ; !WRAM_MENU_START+$86 -ram_cm_dummy_on = !ram_cm_dummy_on ; !WRAM_MENU_START+$8A -ram_cm_dummy_off = !ram_cm_dummy_off ; !WRAM_MENU_START+$8C -ram_cm_dummy_num = !ram_cm_dummy_num ; !WRAM_MENU_START+$8E - -ram_cm_ceres_seconds = !ram_cm_ceres_seconds ; !WRAM_MENU_START+$80 -ram_cm_zebes_seconds = !ram_cm_zebes_seconds ; !WRAM_MENU_START+$82 - -ram_cm_crop_mode = !ram_cm_crop_mode ; !WRAM_MENU_START+$80 -ram_cm_crop_tile = !ram_cm_crop_tile ; !WRAM_MENU_START+$82 - -ram_cm_brb = !ram_cm_brb ; !WRAM_MENU_START+$80 -ram_cm_brb_timer = !ram_cm_brb_timer ; !WRAM_MENU_START+$82 -ram_cm_brb_frames = !ram_cm_brb_frames ; !WRAM_MENU_START+$84 -ram_cm_brb_secs = !ram_cm_brb_secs ; !WRAM_MENU_START+$86 -ram_cm_brb_mins = !ram_cm_brb_mins ; !WRAM_MENU_START+$88 -ram_cm_brb_screen = !ram_cm_brb_screen ; !WRAM_MENU_START+$8A -ram_cm_brb_timer_mode = !ram_cm_brb_timer_mode ; !WRAM_MENU_START+$8C -ram_cm_brb_scroll = !ram_cm_brb_scroll ; !WRAM_MENU_START+$8E -ram_cm_brb_scroll_X = !ram_cm_brb_scroll_X ; !WRAM_MENU_START+$90 -ram_cm_brb_scroll_Y = !ram_cm_brb_scroll_Y ; !WRAM_MENU_START+$92 -ram_cm_brb_scroll_H = !ram_cm_brb_scroll_H ; !WRAM_MENU_START+$94 -ram_cm_brb_scroll_V = !ram_cm_brb_scroll_V ; !WRAM_MENU_START+$96 -ram_cm_brb_scroll_timer = !ram_cm_brb_scroll_timer ; !WRAM_MENU_START+$98 -ram_cm_brb_palette = !ram_cm_brb_palette ; !WRAM_MENU_START+$9A -ram_cm_brb_set_cycle = !ram_cm_brb_set_cycle ; !WRAM_MENU_START+$9C -ram_cm_brb_cycle_time = !ram_cm_brb_cycle_time ; !WRAM_MENU_START+$9E - -ram_cm_keyboard_buffer = !ram_cm_keyboard_buffer ; !WRAM_MENU_START+$80 ; $18 bytes - -ram_cm_manage_slots = !ram_cm_manage_slots ; !WRAM_MENU_START+$80 -ram_cm_selected_slot = !ram_cm_selected_slot ; !WRAM_MENU_START+$82 +ram_cm_watch_enemy_property = !ram_cm_watch_enemy_property ; !WRAM_MENU_START+$90 +ram_cm_watch_enemy_index = !ram_cm_watch_enemy_index ; !WRAM_MENU_START+$92 +ram_cm_watch_enemy_side = !ram_cm_watch_enemy_side ; !WRAM_MENU_START+$94 +ram_cm_watch_common_address = !ram_cm_watch_common_address ; !WRAM_MENU_START+$96 + +ram_cm_preset_elevator = !ram_cm_preset_elevator ; !WRAM_MENU_START+$90 + +ram_cm_door_dynamic = !ram_cm_door_dynamic ; !WRAM_MENU_START+$90 +ram_cm_door_menu_value = !ram_cm_door_menu_value ; !WRAM_MENU_START+$92 +ram_cm_door_menu_bank = !ram_cm_door_menu_bank ; !WRAM_MENU_START+$94 +ram_cm_door_direction_index = !ram_cm_door_direction_index ; !WRAM_MENU_START+$96 +ram_cm_itempickups_visible = !ram_cm_itempickups_visible ; !WRAM_MENU_START+$98 +ram_cm_itempickups_chozo = !ram_cm_itempickups_chozo ; !WRAM_MENU_START+$9A +ram_cm_itempickups_hidden = !ram_cm_itempickups_hidden ; !WRAM_MENU_START+$9C + +ram_cm_phan_first_phase = !ram_cm_phan_first_phase ; !WRAM_MENU_START+$90 +ram_cm_phan_second_phase = !ram_cm_phan_second_phase ; !WRAM_MENU_START+$92 +ram_cm_turret_rng = !ram_cm_turret_rng ; !WRAM_MENU_START+$94 + +ram_cm_varia = !ram_cm_varia ; !WRAM_MENU_START+$90 +ram_cm_gravity = !ram_cm_gravity ; !WRAM_MENU_START+$92 +ram_cm_morph = !ram_cm_morph ; !WRAM_MENU_START+$94 +ram_cm_bombs = !ram_cm_bombs ; !WRAM_MENU_START+$96 +ram_cm_spring = !ram_cm_spring ; !WRAM_MENU_START+$98 +ram_cm_screw = !ram_cm_screw ; !WRAM_MENU_START+$9A +ram_cm_hijump = !ram_cm_hijump ; !WRAM_MENU_START+$9C +ram_cm_space = !ram_cm_space ; !WRAM_MENU_START+$9E +ram_cm_speed = !ram_cm_speed ; !WRAM_MENU_START+$A0 +ram_cm_charge = !ram_cm_charge ; !WRAM_MENU_START+$A2 +ram_cm_ice = !ram_cm_ice ; !WRAM_MENU_START+$A4 +ram_cm_wave = !ram_cm_wave ; !WRAM_MENU_START+$A6 +ram_cm_spazer = !ram_cm_spazer ; !WRAM_MENU_START+$A8 +ram_cm_plasma = !ram_cm_plasma ; !WRAM_MENU_START+$AA + +ram_cm_zeb1 = !ram_cm_zeb1 ; !WRAM_MENU_START+$90 +ram_cm_zeb2 = !ram_cm_zeb2 ; !WRAM_MENU_START+$92 +ram_cm_zeb3 = !ram_cm_zeb3 ; !WRAM_MENU_START+$94 +ram_cm_zeb4 = !ram_cm_zeb4 ; !WRAM_MENU_START+$96 +ram_cm_zebmask = !ram_cm_zebmask ; !WRAM_MENU_START+$98 + +ram_cm_custompalette_blue = !ram_cm_custompalette_blue ; !WRAM_MENU_START+$90 +ram_cm_custompalette_green = !ram_cm_custompalette_green ; !WRAM_MENU_START+$92 +ram_cm_custompalette_red = !ram_cm_custompalette_red ; !WRAM_MENU_START+$94 +ram_cm_custompalette = !ram_cm_custompalette ; !WRAM_MENU_START+$96 +ram_cm_dummy_on = !ram_cm_dummy_on ; !WRAM_MENU_START+$9A +ram_cm_dummy_off = !ram_cm_dummy_off ; !WRAM_MENU_START+$9C +ram_cm_dummy_num = !ram_cm_dummy_num ; !WRAM_MENU_START+$9E + +ram_cm_ceres_seconds = !ram_cm_ceres_seconds ; !WRAM_MENU_START+$90 +ram_cm_zebes_seconds = !ram_cm_zebes_seconds ; !WRAM_MENU_START+$92 + +ram_cm_crop_mode = !ram_cm_crop_mode ; !WRAM_MENU_START+$90 +ram_cm_crop_tile = !ram_cm_crop_tile ; !WRAM_MENU_START+$92 + +ram_cm_brb = !ram_cm_brb ; !WRAM_MENU_START+$90 +ram_cm_brb_timer = !ram_cm_brb_timer ; !WRAM_MENU_START+$92 +ram_cm_brb_frames = !ram_cm_brb_frames ; !WRAM_MENU_START+$94 +ram_cm_brb_secs = !ram_cm_brb_secs ; !WRAM_MENU_START+$96 +ram_cm_brb_mins = !ram_cm_brb_mins ; !WRAM_MENU_START+$98 +ram_cm_brb_screen = !ram_cm_brb_screen ; !WRAM_MENU_START+$9A +ram_cm_brb_timer_mode = !ram_cm_brb_timer_mode ; !WRAM_MENU_START+$9C +ram_cm_brb_scroll = !ram_cm_brb_scroll ; !WRAM_MENU_START+$9E +ram_cm_brb_scroll_X = !ram_cm_brb_scroll_X ; !WRAM_MENU_START+$A0 +ram_cm_brb_scroll_Y = !ram_cm_brb_scroll_Y ; !WRAM_MENU_START+$A2 +ram_cm_brb_scroll_H = !ram_cm_brb_scroll_H ; !WRAM_MENU_START+$A4 +ram_cm_brb_scroll_V = !ram_cm_brb_scroll_V ; !WRAM_MENU_START+$A6 +ram_cm_brb_scroll_timer = !ram_cm_brb_scroll_timer ; !WRAM_MENU_START+$A8 +ram_cm_brb_palette = !ram_cm_brb_palette ; !WRAM_MENU_START+$AA +ram_cm_brb_set_cycle = !ram_cm_brb_set_cycle ; !WRAM_MENU_START+$AC +ram_cm_brb_cycle_time = !ram_cm_brb_cycle_time ; !WRAM_MENU_START+$AE + +ram_cm_keyboard_buffer = !ram_cm_keyboard_buffer ; !WRAM_MENU_START+$90 ; $18 bytes + +ram_cm_manage_slots = !ram_cm_manage_slots ; !WRAM_MENU_START+$90 +ram_cm_selected_slot = !ram_cm_selected_slot ; !WRAM_MENU_START+$92 ; ^ FREE SPACE ^ up to +$CE ; Note: +$B8 to +$CE range also used as frames held counters From ca98c428a63234fdfed210b321228d4f69928c63 Mon Sep 17 00:00:00 2001 From: idle Date: Tue, 25 Mar 2025 00:53:49 -0500 Subject: [PATCH 02/43] Controller Shortcuts are now (almost) Awesome --- TODO.txt | 85 -- resources/cm_gfx.bin | Bin 4096 -> 4096 bytes resources/cm_gfx2.bin | Bin 4096 -> 4096 bytes src/crash.asm | 16 +- src/cutscenes.asm | 4 +- src/defines.asm | 182 ++-- src/fanfare.asm | 11 +- src/gamemode.asm | 2221 ++++++++++++++++++++++++++++++++++------- src/infohud.asm | 73 +- src/init.asm | 134 ++- src/layout.asm | 3 +- src/macros.asm | 27 +- src/main.asm | 2 +- src/mainmenu.asm | 298 +----- src/menu.asm | 387 +++++-- src/misc.asm | 20 - src/save.asm | 7 +- src/symbols.asm | 145 ++- src/tinystates.asm | 7 +- 19 files changed, 2502 insertions(+), 1120 deletions(-) delete mode 100644 TODO.txt diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 index 6b1b11a3..00000000 --- a/TODO.txt +++ /dev/null @@ -1,85 +0,0 @@ - -================================================================ -Porting features from IFB CustomROMBase branch -For other TODO items, recommend using the github issue system -================================================================ - -================================================================ -Features that are being ported now -================================================================ - -- Capture Cropping - -- Count Boss Damage - -- Demo Timer - -- Factory Reset option - -- Force Stand shortcut - -- Infinite Ammo - -- No Steam Collision option - -- Phantoon always visible - -- Random bubble SFX - -- Randomize on load - -- Randomize RNG shortcut - -- Reveal Boss Damage shortcut - -================================================================ -Features intentionally not ported -This isn't a forever list, nor is it an indictment -Most of these items are simply differences where both work -and there isn't much benefit in porting or backporting them -================================================================ - -- Resources folder structure and unusued resources - -- Order of included sources and bank freespace locations - -- Structure of defines.asm and main.asm (and separating printdebug.asm from main.asm) - -- The SM Practice Hack title screen (the difference helps identify which practice hack is being used) - -- Various sound effect macros - -- Walk Through Walls option and unfinished dboost infohud mode - -- Detect emulator inaccuracy developer option - -- The taller menu (this is available as a build option) - -- Leading > or arrow on menu items, or menuing layout and text differences in general - -- Differences in how menu options can be scrolled through - -- AREA_ID stored in custom presets - -- Additional custom flags in the preset data - -- Differences in room names - -- Differences in preset file names or organization - -- The separate ih_update_timers routine (too much duplication with ih_update_hud_code) - -- Tiny states fast flag (that was removed from main branch) - -- Differences in how gamemode is implemented - -- Differences in magic/space/loud pants implementation - -- Differences in how scroll offsets are fixed - -- Differences in how WRAM and SRAM are initialized - -- Differences in PAL debug movement implementation - -- Replacing TDC with LDA #$0000 - diff --git a/resources/cm_gfx.bin b/resources/cm_gfx.bin index d6423cd5093ae0eb5e0b9d6e8faf33a7cc74c7b4..98f06777e77da3b765069ec06e73bb838b6ac442 100644 GIT binary patch delta 66 zcmZorXi(T7z@dBmKL|4ZZw8X@|AWBq|K0x!|Ihya`oAQQ_ZiHu2J>Y%+j0c6PwwNF JnY@NS1OWchEExa* delta 66 zcmZorXi(T7z@hv8|M~xo{~3Y!{Qvj=|NlP@hK&E4fi#H!9!NI><-y{cZ8?J3Cr{#+ Jn!JiX3;^%wEBycf diff --git a/resources/cm_gfx2.bin b/resources/cm_gfx2.bin index 5f67c83f72bc8cdec04a4d1e3ea95ddc95542a2e..7091b64f1e521aeb5a140f671d03b010bb21b7b6 100644 GIT binary patch delta 66 zcmZorXi(T7z@dBmKL|4ZZw8X@|AWBq|K0x!|Ihya`oAQQ_ZiHu2J>Y%+j0c6PwwNF JnY@NS1OWchEExa* delta 66 zcmZorXi(T7z@hv8|M~xo{~3Y!{Qvj=|NlP@hK&E4fi#H!9!NI><-y{cZ8?J3Cr{#+ Jn!JiX3;^%wEBycf diff --git a/src/crash.asm b/src/crash.asm index 6ecbd2d1..6d079096 100644 --- a/src/crash.asm +++ b/src/crash.asm @@ -212,8 +212,8 @@ CrashViewer: STA !ram_crash_input : STA !ram_crash_input_new LDA #$0001 : STA !ram_crash_bg LDA !IH_CONTROLLER_PRI_NEW : STA !ram_crash_input_prev - LDA #$0A44 : STA !ram_crash_mem_viewer - LDA #$007E : STA !ram_crash_mem_viewer_bank + LDA.w !CRASH_INITIAL_ADDRESS : STA !ram_crash_mem_viewer + LDA.w !CRASH_INITIAL_ADDRESS>>16 : STA !ram_crash_mem_viewer_bank ; fall through to CrashLoop } @@ -247,16 +247,10 @@ CrashLoop: .skipSoftReset if !FEATURE_SD2SNES - ; check for load state shortcut - LDA !ram_crash_input : CMP !sram_ctrl_load_state : BNE .skipLoadState + ; check for load state shortcut (Select+Y+L) + LDA !ram_crash_input : CMP #$6020 : BNE .skipLoadState AND !ram_crash_input_new : BEQ .skipLoadState - LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .skipLoadState - ; prepare to jump to load_state - %a8() - LDA.b #gamemode_start>>16 : PHA : PLB - %a16() - PEA.w gamemode_start_return-1 - JML gamemode_shortcuts_load_state + JSL gamemode_load_state .skipLoadState endif diff --git a/src/cutscenes.asm b/src/cutscenes.asm index 41322eaf..4b0d3059 100644 --- a/src/cutscenes.asm +++ b/src/cutscenes.asm @@ -247,9 +247,7 @@ cutscenes_game_over: ; check for cutscene flag or whatever LDA !sram_cutscenes : BIT !CUTSCENE_SKIP_GAMEOVER : BEQ .game_over if !FEATURE_SD2SNES - ; check if valid savestate - LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .no_savestate - JML gamemode_shortcuts_load_state + JSL gamemode_load_state endif .no_savestate diff --git a/src/defines.asm b/src/defines.asm index 32173a16..b9b4d759 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -3,16 +3,40 @@ ; Work RAM ; --------- -!ram_tilemap_buffer = $7E5800 -!CRASHDUMP_TILEMAP_BUFFER = !ram_tilemap_buffer +; The crash buffer and initial address can be moved around as needed +; It is currently placed in the back half of the backup of BG2 tilemap during x-ray, +; which means it is unlikely to overwrite anything relevant for debugging +!CRASHDUMP_TILEMAP_BUFFER = !ram_tilemap_buffer ; 2048 bytes +!CRASH_INITIAL_ADDRESS = #$7E0A44 + +; Practice hack menu tilemap buffer +!ram_tilemap_buffer = $7EF500 ; 2048 bytes + +; Shortcut routine is written on boot and each time the menu closes, +; so it can use the same space as the practice hack menu tilemap buffer +!CTRL_SHORTCUT_ROUTINE = $7EF500 ; up to 1883 bytes or +$75A +!CTRL_SHORTCUT_TABLE = !CTRL_SHORTCUT_ROUTINE+$7B8 ; 48 bytes +!CTRL_SHORTCUT_TYPE = !CTRL_SHORTCUT_ROUTINE+$7E8 +!CTRL_SHORTCUT_PRI = !CTRL_SHORTCUT_ROUTINE+$7EA +!CTRL_SHORTCUT_SEC = !CTRL_SHORTCUT_ROUTINE+$7EC +!CTRL_SHORTCUT_JSL_WORD_LSB = !CTRL_SHORTCUT_ROUTINE+$7EE +!CTRL_SHORTCUT_JSL_WORD_MSB = !CTRL_SHORTCUT_ROUTINE+$7F0 +!CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP = !CTRL_SHORTCUT_ROUTINE+$7F2 +!CTRL_SHORTCUT_SEC_TO_DUAL_JUMP = !CTRL_SHORTCUT_ROUTINE+$7F4 +!CTRL_SHORTCUT_TABLE_PRI_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F6 +!CTRL_SHORTCUT_TABLE_SEC_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F8 +!CTRL_SHORTCUT_TABLE_DUAL_INDEX = !CTRL_SHORTCUT_ROUTINE+$7FA +; Shortcuts can skip remaining checks by replacing the return address word +!CTRL_SHORTCUT_SKIP_REMAINING_PEA = !CTRL_SHORTCUT_ROUTINE+$7FC +!CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE = $FCFC -!WRAM_BANK = !WRAM_START>>16 !WRAM_SIZE = #$0200 !WRAM_START = $7EFD00 !WRAM_PERSIST_START = $7EFD80 !WRAM_MENU_START = $7EFE00 !WRAM_END = $7EFF00 !CRASHDUMP = $7EFF00 +!WRAM_BANK = !WRAM_START>>16 ; These variables are NOT PERSISTENT across savestates -- ; they're saved and reloaded along with the game state. @@ -176,7 +200,7 @@ !ram_watch_edit_lock_right = !WRAM_PERSIST_START+$4C !ram_game_loop_extras = !WRAM_PERSIST_START+$4E -!ram_game_mode_extras = !WRAM_PERSIST_START+$50 +!ram_infinite_ammo = !WRAM_PERSIST_START+$50 !ram_suits_heat_damage_value = !WRAM_PERSIST_START+$52 !ram_sprite_feature_flags = !WRAM_PERSIST_START+$54 !ram_door_portal_flags = !WRAM_PERSIST_START+$56 @@ -194,7 +218,6 @@ !ram_display_backup = !WRAM_PERSIST_START+$6C !ram_phantoon_always_visible = !WRAM_PERSIST_START+$6E !ram_loadstate_rando_enable = !WRAM_PERSIST_START+$70 -!ram_infinite_ammo = !WRAM_PERSIST_START+$72 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -217,52 +240,49 @@ !ram_cm_menu_bank = !WRAM_MENU_START+$26 !ram_cm_horizontal_cursor = !WRAM_MENU_START+$28 -!ram_cm_etanks = !WRAM_MENU_START+$2A -!ram_cm_reserve = !WRAM_MENU_START+$2C -!ram_cm_leave = !WRAM_MENU_START+$2E -!ram_cm_input_counter = !WRAM_MENU_START+$30 -!ram_cm_last_nmi_counter = !WRAM_MENU_START+$32 - -!ram_cm_ctrl_mode = !WRAM_MENU_START+$34 -!ram_cm_ctrl_timer = !WRAM_MENU_START+$36 -!ram_cm_ctrl_last_input = !WRAM_MENU_START+$38 -!ram_cm_ctrl_assign = !WRAM_MENU_START+$3A -!ram_cm_ctrl_swap = !WRAM_MENU_START+$3C - -!ram_cm_slowdown_mode = !WRAM_MENU_START+$3E -!ram_cm_slowdown_frames = !WRAM_MENU_START+$40 - -!ram_cm_botwoon_rng = !WRAM_MENU_START+$42 -!ram_cm_botwoon_first = !WRAM_MENU_START+$44 -!ram_cm_botwoon_hidden = !WRAM_MENU_START+$46 -!ram_cm_botwoon_second = !WRAM_MENU_START+$48 -!ram_cm_botwoon_spit = !WRAM_MENU_START+$4A -!ram_cm_custom_preset_labels = !WRAM_MENU_START+$4C - -!ram_seed_X = !WRAM_MENU_START+$4E -!ram_seed_Y = !WRAM_MENU_START+$50 - -!ram_cm_sfxlib1 = !WRAM_MENU_START+$52 -!ram_cm_sfxlib2 = !WRAM_MENU_START+$54 -!ram_cm_sfxlib3 = !WRAM_MENU_START+$56 - -!ram_cm_fast_scroll_menu_selection = !WRAM_MENU_START+$58 -!ram_timers_autoupdate = !WRAM_MENU_START+$5A -!ram_cm_suit_properties = !WRAM_MENU_START+$5C - -!ram_cm_palette_border = !WRAM_MENU_START+$5E -!ram_cm_palette_headeroutline = !WRAM_MENU_START+$60 -!ram_cm_palette_text = !WRAM_MENU_START+$62 -!ram_cm_palette_background = !WRAM_MENU_START+$64 -!ram_cm_palette_numoutline = !WRAM_MENU_START+$66 -!ram_cm_palette_numfill = !WRAM_MENU_START+$68 -!ram_cm_palette_toggleon = !WRAM_MENU_START+$6A -!ram_cm_palette_seltext = !WRAM_MENU_START+$6C -!ram_cm_palette_seltextbg = !WRAM_MENU_START+$6E -!ram_cm_palette_numseloutline = !WRAM_MENU_START+$70 -!ram_cm_palette_numsel = !WRAM_MENU_START+$72 - -!ram_cm_gmode = !WRAM_MENU_START+$74 +!ram_cm_leave = !WRAM_MENU_START+$2A +!ram_cm_input_counter = !WRAM_MENU_START+$2C +!ram_cm_last_nmi_counter = !WRAM_MENU_START+$2E +!ram_cm_ctrl_mode = !WRAM_MENU_START+$30 +!ram_cm_custom_preset_labels = !WRAM_MENU_START+$32 + +!ram_cm_slowdown_mode = !WRAM_MENU_START+$34 +!ram_cm_slowdown_frames = !WRAM_MENU_START+$36 + +!ram_seed_X = !WRAM_MENU_START+$38 +!ram_seed_Y = !WRAM_MENU_START+$3A + +!ram_cm_fast_scroll_menu_selection = !WRAM_MENU_START+$3C +!ram_cm_suit_properties = !WRAM_MENU_START+$3E + +!ram_cm_palette_border = !WRAM_MENU_START+$40 +!ram_cm_palette_headeroutline = !WRAM_MENU_START+$42 +!ram_cm_palette_text = !WRAM_MENU_START+$44 +!ram_cm_palette_background = !WRAM_MENU_START+$46 +!ram_cm_palette_numoutline = !WRAM_MENU_START+$48 +!ram_cm_palette_numfill = !WRAM_MENU_START+$4A +!ram_cm_palette_toggleon = !WRAM_MENU_START+$4C +!ram_cm_palette_seltext = !WRAM_MENU_START+$4E +!ram_cm_palette_seltextbg = !WRAM_MENU_START+$50 +!ram_cm_palette_numseloutline = !WRAM_MENU_START+$52 +!ram_cm_palette_numsel = !WRAM_MENU_START+$54 + +!ram_cm_sfxlib1 = !WRAM_MENU_START+$56 +!ram_cm_sfxlib2 = !WRAM_MENU_START+$58 +!ram_cm_sfxlib3 = !WRAM_MENU_START+$5A + +if !FEATURE_SD2SNES +!ram_sram_savestates = !WRAM_MENU_START+$5C +endif + +!ram_timers_autoupdate = !WRAM_MENU_START+$5E +!ram_cm_gmode = !WRAM_MENU_START+$60 + +!ram_cm_botwoon_rng = !WRAM_MENU_START+$62 +!ram_cm_botwoon_first = !WRAM_MENU_START+$64 +!ram_cm_botwoon_hidden = !WRAM_MENU_START+$66 +!ram_cm_botwoon_second = !WRAM_MENU_START+$68 +!ram_cm_botwoon_spit = !WRAM_MENU_START+$68 ; ^ FREE SPACE ^ up to +$86 @@ -308,6 +328,8 @@ !ram_cm_wave = !WRAM_MENU_START+$A6 !ram_cm_spazer = !WRAM_MENU_START+$A8 !ram_cm_plasma = !WRAM_MENU_START+$AA +!ram_cm_etanks = !WRAM_MENU_START+$AC +!ram_cm_reserve = !WRAM_MENU_START+$AE !ram_cm_zeb1 = !WRAM_MENU_START+$90 !ram_cm_zeb2 = !WRAM_MENU_START+$92 @@ -326,6 +348,13 @@ !ram_cm_ceres_seconds = !WRAM_MENU_START+$90 !ram_cm_zebes_seconds = !WRAM_MENU_START+$92 +!ram_cm_ctrl_add_shortcut_slot = !WRAM_MENU_START+$90 +!ram_cm_ctrl_last_pri = !WRAM_MENU_START+$92 +!ram_cm_ctrl_last_sec = !WRAM_MENU_START+$94 +!ram_cm_ctrl_assign = !WRAM_MENU_START+$96 +!ram_cm_ctrl_swap = !WRAM_MENU_START+$98 +!ram_cm_ctrl_timer = !WRAM_MENU_START+$9A + !ram_cm_crop_mode = !WRAM_MENU_START+$90 !ram_cm_crop_tile = !WRAM_MENU_START+$92 @@ -439,30 +468,15 @@ ; SRAM ; ----- -!SRAM_VERSION = #$0019 +!SRAM_VERSION = #$001A !SRAM_START = $702000 !SRAM_SIZE = #$1000 !PRESET_SLOTS = $703000 !sram_initialized = !SRAM_START+$00 - -!sram_ctrl_menu = !SRAM_START+$02 -!sram_ctrl_kill_enemies = !SRAM_START+$04 -!sram_ctrl_full_equipment = !SRAM_START+$06 -!sram_ctrl_reset_segment_timer = !SRAM_START+$08 -!sram_ctrl_reset_segment_later = !SRAM_START+$0A -!sram_ctrl_load_state = !SRAM_START+$0C -!sram_ctrl_save_state = !SRAM_START+$0E -!sram_ctrl_load_last_preset = !SRAM_START+$10 -!sram_ctrl_random_preset = !SRAM_START+$12 -!sram_ctrl_save_custom_preset = !SRAM_START+$14 -!sram_ctrl_load_custom_preset = !SRAM_START+$16 -!sram_ctrl_inc_custom_preset = !SRAM_START+$18 -!sram_ctrl_dec_custom_preset = !SRAM_START+$1A -!sram_ctrl_toggle_tileviewer = !SRAM_START+$1C -!sram_ctrl_update_timers = !SRAM_START+$1E -; More ctrl shortcuts starting at $F0 +!sram_ctrl_shortcut_selections = !SRAM_START+$02 ; 30 bytes +; More ctrl shortcut selections starting at $EE !sram_artificial_lag = !SRAM_START+$20 !sram_rerandomize = !SRAM_START+$22 @@ -535,15 +549,10 @@ !sram_ceres_timer = !SRAM_START+$A0 !sram_zebes_timer = !SRAM_START+$A2 -; ^ FREE SPACE ^ up to +$EE +; ^ FREE SPACE ^ up to +$EC -!sram_ctrl_auto_save_state = !SRAM_START+$F0 -!sram_ctrl_toggle_spin_lock = !SRAM_START+$F2 -!sram_ctrl_randomize_rng = !SRAM_START+$F4 -!sram_ctrl_reveal_damage = !SRAM_START+$F6 -!sram_ctrl_force_stand = !SRAM_START+$F8 - -; ^ FREE SPACE ^ up to +$FE +; This is a continuation of sram_ctrl_shortcut_selections +!sram_ctrl_additional_selections = !SRAM_START+$D0 ; 18 bytes starting from +$EE !sram_presetequiprando = !SRAM_START+$100 !sram_presetequiprando_beampref = !SRAM_START+$102 @@ -559,6 +568,11 @@ !sram_loadstate_rando_supers = !SRAM_START+$116 !sram_loadstate_rando_powerbombs = !SRAM_START+$118 +; ^ FREE SPACE ^ up to +$13E + +!sram_ctrl_1_shortcut_inputs = !SRAM_START+$140 ; 96 bytes +!sram_ctrl_2_shortcut_inputs = !SRAM_START+$1A0 ; 96 bytes + ; ^ FREE SPACE ^ up to +$BA6 !sram_custom_header_normal = !SRAM_START+$BA8 ; $18 bytes @@ -635,22 +649,18 @@ !IH_MORPH_BALL_GREEN = #$10C9 !IH_STUCK_GREEN = #$106B -!IH_PAUSE = #$0100 ; right -!IH_SLOWDOWN = #$0400 ; down -!IH_SPEEDUP = #$0800 ; up -!IH_RESET = #$0200 ; left -!IH_STATUS_R = #$0010 ; r -!IH_STATUS_L = #$0020 ; l - !IH_INPUT_START = #$1000 +!IH_INPUT_DPAD = #$0F00 !IH_INPUT_UPDOWN = #$0C00 !IH_INPUT_UP = #$0800 !IH_INPUT_DOWN = #$0400 +!IH_INPUT_XLEFTRIGHTHELD = #$0341 !IH_INPUT_LEFTRIGHT = #$0300 !IH_INPUT_LEFT = #$0200 !IH_INPUT_RIGHT = #$0100 !IH_INPUT_HELD = #$0001 ; used by menu +!CTRL_AB = #$8080 !CTRL_B = #$8000 !CTRL_Y = #$4000 !CTRL_SELECT = #$2000 @@ -1095,6 +1105,7 @@ endif !DP_KB_Row = $1A !DP_KB_Control = $1C !DP_KB_Shift = $1E +!DP_Ctrl2Input = $1C ; 0x4 ; v single digit editing v !DP_DigitAddress = $20 ; 0x4 !DP_DigitValue = $24 @@ -1131,6 +1142,9 @@ else !FRAMERATE = #$003C endif +!CTRL_SHORTCUT_TYPE_MASK = #$007F +!CTRL_SHORTCUT_EXACT_MATCH = #$0080 + !SUIT_PROPERTIES_MASK = #$0007 !SUIT_PROPRETIES_PAL_DEBUG_FLAG = #$0008 diff --git a/src/fanfare.asm b/src/fanfare.asm index dc479e85..aa6e336a 100644 --- a/src/fanfare.asm +++ b/src/fanfare.asm @@ -294,11 +294,12 @@ if !FEATURE_SD2SNES LDA $4212 : BIT #$01 : BNE .wait_joypad %a16() - LDA $4218 : BEQ .done - CMP !sram_ctrl_load_state : BNE .done - LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .done - PHB : PHK : PLB - JML load_state + ; TODO re-enable load state, or maybe run the whole shortcut routine from here? + ; LDA $4218 : BEQ .done + ; CMP !sram_ctrl_load_state : BNE .done + ; LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .done + ; PHB : PHK : PLB + ; JML load_state .done endif diff --git a/src/gamemode.asm b/src/gamemode.asm index 229f2f05..58878054 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -3,7 +3,7 @@ org $82894B ; gamemode_shortcuts will either CLC or SEC ; to control if normal gameplay will happen on this frame - JSL gamemode_start : BCC resume_gameplay + JSL gamemode_start : BCS resume_gameplay BRA end_of_normal_gameplay resume_gameplay: @@ -24,26 +24,91 @@ endif %startfree(85) +if !FEATURE_SD2SNES +gamemode_door_transition: +{ + .checkloadstate + ; TODO re-enable load state, or maybe run the whole shortcut routine from here? + ; LDA !IH_CONTROLLER_PRI : BEQ .checktransition + ; CMP !sram_ctrl_load_state : BNE .checktransition + ; check if a saved state exists + ; LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .checktransition + ; PHB : PHK : PLB + ; JML load_state -gamemode_start: + .checktransition + ; check if door is done scrolling + LDA !DOOR_FINISHED_SCROLLING : BPL .checkloadstate + RTL +} + +gamemode_door_transtion_load_sprites: { - PHB + ; Check for auto-save mid-transition + LDA !ram_auto_save_state : BEQ .check + BMI .auto_save + TDC : STA !ram_auto_save_state + .auto_save + PHP : PHB PHK : PLB + JSL save_state + PLB : PLP + .done + JML $82E4A9 ; return to hijacked code + .check +if !FEATURE_PAL + JML $82E4A9 ; return to hijacked code +else + LDA !IH_CONTROLLER_PRI : CMP #$C0C0 : BNE .done + LDA !AREA_ID : BEQ .done : CMP #$0002 : BEQ .done + BRA .done ; disabled during beta testing phase + LDA #custom_intro_init : STA !CINEMATIC_FUNCTION_POINTER + LDA #$001E : STA !GAMEMODE + .end + JML $82E4A9 ; return to hijacked code +endif +} +endif - JSR gamemode_shortcuts - .return - %ai16() +gamemode_start: +{ + ; Set overflow and carry flags before calling routine + SEP #$41 + JSL !CTRL_SHORTCUT_ROUTINE PHP - BCS .skip_gameplay + BCC .skip_gameplay + ; Check if we need to reset the fading to pause state + BVS .done_pause + LDA !GAMEMODE : CMP #$000C : BNE .skip_gameplay_done_pause + LDA #$0008 : STA !GAMEMODE + ; Clear screen fade delay/counter + STZ !SCREEN_FADE_DELAY : STZ !SCREEN_FADE_COUNTER + + ; Brightness = $F (max) + LDA !REG_2100_BRIGHTNESS : ORA #$000F : STA !REG_2100_BRIGHTNESS + + .done_pause ; Overwritten logic JSL $8884B9 JSL ih_game_loop_code PLP - PLB + CLV RTL .skip_gameplay + ; Check if we need to reset the fading to pause state + BVS .skip_gameplay_done_pause + LDA !GAMEMODE : CMP #$000C : BNE .skip_gameplay_done_pause + LDA #$0008 : STA !GAMEMODE + + ; Clear screen fade delay/counter + STZ !SCREEN_FADE_DELAY : STZ !SCREEN_FADE_COUNTER + + ; Brightness = $F (max) + LDA !REG_2100_BRIGHTNESS : ORA #$000F : STA !REG_2100_BRIGHTNESS + + .skip_gameplay_done_pause ; Don't load presets or decrement counters if we're in credits LDA !GAMEMODE : CMP #$0027 : BEQ .skip_load @@ -55,7 +120,7 @@ gamemode_start: .skip_load PLP - PLB + CLV RTL .dec_rta @@ -83,470 +148,1864 @@ gamemode_start: BRA .skip_load } -gamemode_shortcuts: +gamemode_main_menu: { - LDA !IH_CONTROLLER_PRI_NEW : BNE .check_shortcuts - ; CLC so we won't skip normal gameplay - CLC : RTS - .check_shortcuts + ; Set IRQ vector + LDA !IRQ_CMD : PHA + LDA #$0004 : STA !IRQ_CMD - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_menu : CMP !sram_ctrl_menu : BNE .skip_menu - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_menu - JMP .menu - .skip_menu + ; Enter Main Menu + JSL cm_start -if !FEATURE_SD2SNES - LDA !IH_CONTROLLER_PRI : CMP !sram_ctrl_save_state : BNE .skip_save_state - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_save_state - JMP .save_state - .skip_save_state - - LDA !IH_CONTROLLER_PRI : CMP !sram_ctrl_load_state : BNE .skip_load_state - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_load_state - JMP .load_state - .skip_load_state - - LDA !IH_CONTROLLER_PRI : CMP !sram_ctrl_auto_save_state : BNE .skip_auto_save_state - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_auto_save_state - JMP .auto_save_state - .skip_auto_save_state -endif - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_load_last_preset : CMP !sram_ctrl_load_last_preset : BNE .skip_load_last_preset - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_load_last_preset - JMP .load_last_preset - .skip_load_last_preset - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_random_preset : CMP !sram_ctrl_random_preset : BNE .skip_random_preset - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_random_preset - JMP .random_preset - .skip_random_preset - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_save_custom_preset : CMP !sram_ctrl_save_custom_preset : BNE .skip_save_custom_preset - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_save_custom_preset - JMP .save_custom_preset - .skip_save_custom_preset - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_load_custom_preset : CMP !sram_ctrl_load_custom_preset : BNE .skip_load_custom_preset - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_load_custom_preset - JMP .load_custom_preset - .skip_load_custom_preset - - ; Check if any less common shortcuts are configured - LDA !ram_game_mode_extras : BNE .check_less_common_shortcuts - JMP .no_shortcuts - .check_less_common_shortcuts - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_inc_custom_preset : CMP !sram_ctrl_inc_custom_preset : BNE .skip_next_preset_slot - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_next_preset_slot - JMP .next_preset_slot - .skip_next_preset_slot - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_dec_custom_preset : CMP !sram_ctrl_dec_custom_preset : BNE .skip_prev_preset_slot - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_prev_preset_slot - JMP .prev_preset_slot - .skip_prev_preset_slot - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_full_equipment : CMP !sram_ctrl_full_equipment : BNE .skip_full_equipment - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_full_equipment - JMP .full_equipment - .skip_full_equipment - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_kill_enemies : CMP !sram_ctrl_kill_enemies : BNE .skip_kill_enemies - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_kill_enemies - JMP .kill_enemies - .skip_kill_enemies - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_reset_segment_timer : CMP !sram_ctrl_reset_segment_timer : BNE .skip_reset_segment_timer - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_reset_segment_timer - JMP .reset_segment_timer - .skip_reset_segment_timer - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_reset_segment_later : CMP !sram_ctrl_reset_segment_later : BNE .skip_reset_segment_later - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_reset_segment_later - JMP .reset_segment_later - .skip_reset_segment_later - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_toggle_tileviewer : CMP !sram_ctrl_toggle_tileviewer : BNE .skip_toggle_tileviewer - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_toggle_tileviewer - JMP .toggle_tileviewer - .skip_toggle_tileviewer - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_reveal_damage : CMP !sram_ctrl_reveal_damage : BNE .skip_reveal_damage - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_reveal_damage - JMP .reveal_damage - .skip_reveal_damage - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_randomize_rng : CMP !sram_ctrl_randomize_rng : BNE .skip_randomize_rng - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_randomize_rng - JMP .randomize_rng - .skip_randomize_rng - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_force_stand : CMP !sram_ctrl_force_stand : BNE .skip_force_stand - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_force_stand - JMP .force_stand - .skip_force_stand - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_update_timers : CMP !sram_ctrl_update_timers : BNE .skip_update_timers - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_update_timers - JMP .update_timers - .skip_update_timers - - LDA !IH_CONTROLLER_PRI : AND !sram_ctrl_toggle_spin_lock : CMP !sram_ctrl_toggle_spin_lock : BNE .skip_toggle_spin_lock - AND !IH_CONTROLLER_PRI_NEW : BEQ .skip_toggle_spin_lock - JMP .toggle_spin_lock - .skip_toggle_spin_lock - - .no_shortcuts - ; No shortcuts matched, CLC so we won't skip normal gameplay - CLC : RTS + ; Restore IRQ vector + PLA : STA !IRQ_CMD + + ; Skip remaining shortcuts + PLA : PEA !CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE + + ; Fallthrough to below RTL +} + +gamemode_placeholder: + RTL if !FEATURE_SD2SNES - .save_state -; This if statement is to prevent an assembler error from an unknown method. The one on the call to this -; prevents the button combo from being intercepted by the non-sd2snes rom +gamemode_save_state: +{ if !FEATURE_TINYSTATES ; Disallow tiny states outside of gameplay ; Most other gamemodes will crash on load LDA !GAMEMODE : CMP #$0020 : BEQ .save ; end of Ceres allowed - CMP #$0007 : BMI .save_state_fail + CMP #$0007 : BMI .not_allowed CMP #$001C : BMI .save - .save_state_fail - ; CLC to continue normal gameplay - LDA !sram_ctrl_save_state - CLC : JMP skip_pause + .not_allowed + RTL .save endif + PHP JSL save_state - %ai16() - LDA !ram_auto_save_state : BMI .clc - ; SEC to skip normal gameplay for one frame after saving state - SEC : RTS - .clc - ; CLC to continue normal gameplay after auto-saving in a door transition - CLC : RTS - - .load_state + PLP + RTL +} + +gamemode_load_state: +{ ; check if a saved state exists - LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .load_state_fail + LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .not_available JSL load_state - ; SEC to skip normal gameplay for one frame after loading state - SEC : RTS - .load_state_fail - ; CLC to continue normal gameplay - LDA !sram_ctrl_load_state - CLC : JMP skip_pause + ; Skip remaining shortcuts + PLA : PEA !CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE + + .not_available + RTL +} - .auto_save_state +gamemode_auto_save_state: +{ LDA #$0001 : STA !ram_auto_save_state - ; CLC to continue normal gameplay after setting savestate flag - LDA !sram_ctrl_auto_save_state - CLC : JMP skip_pause + RTL +} endif - .kill_enemies - JSL kill_enemies - ; CLC to continue normal gameplay after killing enemies - LDA !sram_ctrl_kill_enemies - CLC : JMP skip_pause - - .reset_segment_timer - LDA !sram_frame_counter_mode : BEQ .reset_segment_timer_rta - STZ !IGT_FRAMES : STZ !IGT_SECONDS - STZ !IGT_MINUTES : STZ !IGT_HOURS - .reset_segment_timer_rta - TDC : STA !ram_seg_rt_frames - STA !ram_seg_rt_seconds : STA !ram_seg_rt_minutes - %sfxconfirm() - ; CLC to continue normal gameplay after resetting segment timer - LDA !sram_ctrl_reset_segment_timer - CLC : JMP skip_pause - - .reset_segment_later - LDA #$FFFF : STA !ram_reset_segment_later - %sfxconfirm() - ; CLC to continue normal gameplay after setting reset flag - LDA !sram_ctrl_reset_segment_later - CLC : JMP skip_pause - - .full_equipment - LDA !SAMUS_HP_MAX : STA !SAMUS_HP - LDA !SAMUS_MISSILES_MAX : CMP !SAMUS_MISSILES : BCC .full_equip_done_missiles - STA !SAMUS_MISSILES - .full_equip_done_missiles - LDA !SAMUS_SUPERS_MAX : CMP !SAMUS_SUPERS : BCC .full_equip_done_supers - STA !SAMUS_SUPERS - .full_equip_done_supers - LDA !SAMUS_PBS_MAX : CMP !SAMUS_PBS : BCC .full_equip_done_pbs - STA !SAMUS_PBS - .full_equip_done_pbs - LDA !SAMUS_RESERVE_MAX : STA !SAMUS_RESERVE_ENERGY - %sfxconfirm() - ; CLC to continue normal gameplay after equipment refill - LDA !sram_ctrl_full_equipment - CLC : JMP skip_pause - - .toggle_tileviewer - LDA !ram_sprite_feature_flags : BIT !SPRITE_OOB_WATCH : BEQ .turnOnTileViewer - EOR !SPRITE_OOB_WATCH : STA !ram_sprite_feature_flags - ; CLC to continue normal gameplay after disabling OoB Tile Viewer - LDA !sram_ctrl_toggle_tileviewer - CLC : JMP skip_pause - - .turnOnTileViewer - ORA !SPRITE_OOB_WATCH : STA !ram_sprite_feature_flags - JSL upload_sprite_oob_tiles - ; CLC to continue normal gameplay after enabling OoB Tile Viewer - LDA !sram_ctrl_toggle_tileviewer - CLC : JMP skip_pause - - .reveal_damage if !FEATURE_VANILLAHUD else - LDA !sram_display_mode : CMP !IH_MODE_COUNTDAMAGE_INDEX : BEQ .unreveal_damage - STA !ram_display_backup - LDA !IH_MODE_COUNTDAMAGE_INDEX : STA !sram_display_mode - ; set ram_HUD_check to some value that cannot match the damage counter - ; conveniently the current value of A will work - STA !ram_HUD_check +gamemode_update_timers: +{ + JML ih_update_hud_early +} endif - %sfxconfirm() - ; CLC to continue normal gameplay after reveal damage - LDA !sram_ctrl_reveal_damage - CLC : JMP skip_pause - .unreveal_damage - LDA !ram_display_backup : STA !sram_display_mode - %sfxreset() - ; CLC to continue normal gameplay after unreveal damage - LDA !sram_ctrl_reveal_damage - CLC : JMP skip_pause - - .load_last_preset +gamemode_reload_preset: +{ ; Choose a random preset if zero - LDA !sram_last_preset : BEQ .random_preset : STA !ram_load_preset - ; SEC to skip normal gameplay for one frame after loading preset - SEC : RTS + LDA !sram_last_preset : BEQ gamemode_random_preset + STA !ram_load_preset + + ; Skip remaining shortcuts + PLA : PEA !CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE + RTL +} - .random_preset +gamemode_random_preset: +{ JSL LoadRandomPreset - ; SEC to skip normal gameplay for one frame after loading preset - SEC : RTS - .save_custom_preset + ; Skip remaining shortcuts + PLA : PEA !CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE + RTL +} + +gamemode_save_custom_preset: +{ ; check gamestate first - LDA !GAMEMODE : CMP #$0008 : BEQ .save_custom_safe - CMP #$000C : BMI .save_custom_not_safe - CMP #$0013 : BPL .save_custom_not_safe + LDA !GAMEMODE : CMP #$0008 : BEQ .safe + CMP #$000C : BMI .not_safe + CMP #$0013 : BPL .not_safe - .save_custom_safe + .safe JSL custom_preset_save - ; CLC to continue normal gameplay after saving preset %sfxconfirm() - LDA !sram_ctrl_save_custom_preset - CLC : JMP skip_pause + RTL - .load_custom_preset + .not_safe + %sfxfail() + RTL +} + +gamemode_load_custom_preset: +{ ; check if slot is populated first LDA !sram_custom_preset_slot %presetslotsize() - LDA !PRESET_SLOTS,X : CMP !SAFEWORD : BEQ .load_safe - - %sfxfail() - ; CLC to continue normal gameplay after failing to load preset - LDA !sram_ctrl_load_custom_preset - CLC : JMP skip_pause - - .save_custom_not_safe + LDA !PRESET_SLOTS,X : CMP !SAFEWORD : BEQ .safe %sfxfail() - ; CLC to continue normal gameplay after failing to save preset - LDA !sram_ctrl_save_custom_preset - CLC : JMP skip_pause + RTL - .load_safe + .safe STA !ram_custom_preset - JSL preset_load - ; SEC to skip normal gameplay for one frame after loading preset - SEC : RTS + JML preset_load +} - .next_preset_slot - LDA !sram_custom_preset_slot : CMP !TOTAL_PRESET_SLOTS : BNE .increment_slot +gamemode_increment_custom_preset: +{ + LDA !sram_custom_preset_slot : CMP !TOTAL_PRESET_SLOTS : BNE .increment LDA #$FFFF - .increment_slot + .increment INC : STA !sram_custom_preset_slot if !FEATURE_VANILLAHUD else ASL : TAX : LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$7C endif - LDA !sram_last_preset : BMI .done_preset_slot + LDA !sram_last_preset : BMI .done TDC : STA !sram_last_preset + .done %sfxnumber() - ; CLC to continue normal gameplay after incrementing preset slot - LDA !sram_ctrl_inc_custom_preset - CLC : JMP skip_pause + RTL +} - .prev_preset_slot - LDA !sram_custom_preset_slot : BNE .decrement_slot +gamemode_decrement_custom_preset: +{ + LDA !sram_custom_preset_slot : BNE .decrement LDA !TOTAL_PRESET_SLOTS+1 - .decrement_slot + .decrement DEC : STA !sram_custom_preset_slot if !FEATURE_VANILLAHUD else ASL : TAX : LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$7C endif - LDA !sram_last_preset : BMI .done_preset_slot + LDA !sram_last_preset : BMI .done TDC : STA !sram_last_preset - .done_preset_slot + .done %sfxnumber() - ; CLC to continue normal gameplay after decrementing preset slot - LDA !sram_ctrl_dec_custom_preset - CLC : JMP skip_pause + RTL +} + +gamemode_reset_segment_timer: +{ + LDA !sram_frame_counter_mode : BEQ .rta + STZ !IGT_FRAMES : STZ !IGT_SECONDS + STZ !IGT_MINUTES : STZ !IGT_HOURS + .rta + TDC : STA !ram_seg_rt_frames + STA !ram_seg_rt_seconds : STA !ram_seg_rt_minutes + %sfxconfirm() +if !FEATURE_VANILLAHUD + RTL +else + JML ih_update_hud_early +endif +} + +gamemode_reset_segment_later: +{ + LDA #$FFFF : STA !ram_reset_segment_later + %sfxconfirm() + RTL +} + +gamemode_full_equipment: +{ + LDA !SAMUS_HP_MAX : STA !SAMUS_HP + LDA !SAMUS_MISSILES_MAX : CMP !SAMUS_MISSILES : BCC .done_missiles + STA !SAMUS_MISSILES + .done_missiles + LDA !SAMUS_SUPERS_MAX : CMP !SAMUS_SUPERS : BCC .done_supers + STA !SAMUS_SUPERS + .done_supers + LDA !SAMUS_PBS_MAX : CMP !SAMUS_PBS : BCC .done_pbs + STA !SAMUS_PBS + .done_pbs + LDA !SAMUS_RESERVE_MAX : STA !SAMUS_RESERVE_ENERGY + %sfxconfirm() + RTL +} + +gamemode_kill_enemies: +{ + JML kill_enemies +} - .randomize_rng +gamemode_toggle_oob_tile_viewer: +{ + LDA !ram_sprite_feature_flags : BIT !SPRITE_OOB_WATCH : BEQ .turnOn + EOR !SPRITE_OOB_WATCH : STA !ram_sprite_feature_flags + RTL + + .turnOn + ORA !SPRITE_OOB_WATCH : STA !ram_sprite_feature_flags + JML upload_sprite_oob_tiles +} + +gamemode_randomize_rng: +{ JSL MenuRNG2 AND #$00FF : STA !FRAME_COUNTER_8BIT ; little extra for Phantoon JSL MenuRNG : STA !CACHED_RANDOM_NUMBER %sfxbeep() - ; CLC to continue normal gameplay after reseeding RNG - LDA !sram_ctrl_randomize_rng - CLC : JMP skip_pause - - .force_stand - JSL $90E2D4 ; Release Samus from Draygon - %sfxconfirm() - ; CLC to continue normal gameplay after forced stand - LDA !sram_ctrl_force_stand - CLC : JMP skip_pause + RTL +} - .update_timers if !FEATURE_VANILLAHUD else - JSL ih_update_hud_early +gamemode_reveal_damage: +{ + LDA !sram_display_mode : CMP !IH_MODE_COUNTDAMAGE_INDEX : BEQ .unreveal + STA !ram_display_backup + LDA !IH_MODE_COUNTDAMAGE_INDEX : STA !sram_display_mode + ; set ram_HUD_check to some value that cannot match the damage counter + ; conveniently the current value of A will work + STA !ram_HUD_check + %sfxconfirm() + RTL + + .unreveal + LDA !ram_display_backup : STA !sram_display_mode + %sfxreset() + RTL +} endif - ; CLC to continue normal gameplay after updating HUD timers - LDA !sram_ctrl_update_timers - CLC : JMP skip_pause - .toggle_spin_lock - LDA !sram_spin_lock : BEQ .turn_on_spin_lock - TDC - BRA .set_spin_lock - .turn_on_spin_lock - TDC : INC - .set_spin_lock - STA !sram_spin_lock - ; CLC to continue normal gameplay after toggling spin lock - LDA !sram_ctrl_toggle_spin_lock - CLC : JMP skip_pause - - .menu - ; Set IRQ vector - LDA !IRQ_CMD : PHA - LDA #$0004 : STA !IRQ_CMD +gamemode_force_stand: +{ + %sfxconfirm() + JML $90E2D4 ; Release Samus from Draygon +} + +gamemode_toggle_spin_lock: +{ + LDA !sram_spin_lock : BEQ .turnOn + TDC : STA !sram_spin_lock + RTL - LDA !sram_ctrl_menu - JSR skip_pause + .turnOn + LDA #$0001 : STA !sram_spin_lock + RTL +} - ; Enter MainMenu - JSL cm_start +gamemode_pause: +{ + TDC : STA !ram_slowdown_frames + DEC : STA !ram_slowdown_mode + RTL +} - ; Restore IRQ vector - PLA : STA !IRQ_CMD +gamemode_unpause: +{ + TDC : STA !ram_slowdown_mode : STA !ram_slowdown_frames + RTL +} - ; SEC to skip normal gameplay for one frame after handling the menu - SEC : RTS +gamemode_slowdown: +{ + LDA !ram_slowdown_mode : INC : STA !ram_slowdown_mode + RTL } -; If the current shortcut (register A) contains start, -; and the current game mode is $C (fading out to pause), set it to $8 (normal), -; so that shortcuts involving the start button don't trigger accidental pauses. -; Called after handling most controller shortcuts, except save/load state -; (because the user might want to practice gravity jumps or something) -; and load preset (because presets reset the game mode anyway). -skip_pause: +gamemode_speedup: { - PHP ; preserve carry - BIT !IH_INPUT_START : BEQ .done - LDA !GAMEMODE : CMP #$000C : BNE .done - LDA #$0008 : STA !GAMEMODE + LDA !ram_slowdown_mode : BEQ .done + DEC : STA !ram_slowdown_mode + .done + RTL +} - ; clear screen fade delay/counter - STZ !SCREEN_FADE_DELAY : STZ !SCREEN_FADE_COUNTER +if !FEATURE_VANILLAHUD +else +gamemode_increment_display_mode: +{ + LDA !sram_display_mode : INC + CMP !IH_MODE_COUNT : BNE .set + TDC + .set + STA !sram_display_mode + JML ih_update_status +} - ; Brightness = $F (max) - LDA !REG_2100_BRIGHTNESS : ORA #$000F : STA !REG_2100_BRIGHTNESS +gamemode_decrement_display_mode: +{ + LDA !sram_display_mode : DEC + CMP #$FFFF : BNE .set + LDA !IH_MODE_COUNT-1 + .set + STA !sram_display_mode + JML ih_update_status +} - .done - PLP - RTS +gamemode_increment_room_strat: +{ + LDA !sram_room_strat : INC + CMP !IH_ROOM_STRAT_COUNT : BNE .set + TDC + .set + STA !sram_room_strat + ; enable ROOM STRAT mode + LDA !IH_MODE_ROOMSTRAT_INDEX : STA !sram_display_mode + JML ih_update_status +} + +gamemode_decrement_room_strat: +{ + LDA !sram_room_strat : DEC + CMP #$FFFF : BNE .set + LDA !IH_ROOM_STRAT_COUNT-1 + .set + STA !sram_room_strat + ; enable ROOM STRAT mode + LDA !IH_MODE_ROOMSTRAT_INDEX : STA !sram_display_mode + JML ih_update_status +} + +gamemode_increment_super_hud: +{ + LDA !sram_superhud_bottom : INC + CMP !IH_SUPERHUD_BOTTOM_COUNT : BNE .set + TDC + .set + STA !sram_superhud_bottom + ; enable Super HUD + LDA !IH_MODE_ROOMSTRAT_INDEX : STA !sram_display_mode + TDC : STA !sram_room_strat + JML ih_update_status } +gamemode_decrement_super_hud: +{ + LDA !sram_superhud_bottom : DEC + CMP #$FFFF : BNE .set + LDA !IH_SUPERHUD_BOTTOM_COUNT-1 + .set + STA !sram_superhud_bottom + ; enable Super HUD + LDA !IH_MODE_ROOMSTRAT_INDEX : STA !sram_display_mode + TDC : STA !sram_room_strat + JML ih_update_status +} +endif + +; Write a customized routine based on ctrl shortcut selections +!GAMEMODE_CTRL_SHORTCUT_COUNT = #$001F +cm_write_ctrl_routine: +{ + ; No bounds check on X is done as we shouldn't exceed our buffer. + ; In fact, we are using the end of the buffer for temporary variables + ; and a table to track which shortcuts we still need to write. + PHB : PEA $7070 : PLB : PLB + TDC : TAX : TAY : STA !CTRL_SHORTCUT_TYPE + STA !CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP : STA !CTRL_SHORTCUT_SEC_TO_DUAL_JUMP + + ; Initialize category indices to 48 indicating no shortcut found. + LDA #$0030 : STA !CTRL_SHORTCUT_TABLE_DUAL_INDEX + STA !CTRL_SHORTCUT_TABLE_SEC_INDEX : STA !CTRL_SHORTCUT_TABLE_PRI_INDEX + %a8() + + ; As we check shortcuts, we need to remember if gameplay should be skipped, + ; and we need to remember if Start was used in an exact match shortcut. + ; Use carry flag for gameplay (initially set, clear if gameplay skipped). + ; Use overflow flag for start (initially set, clear if pause should be cancelled). + ; The flags are already set prior to entering routine, so we just need to + ; push flags to the stack, so that shortcut routines can pull-modify-push. + + ; PHP (skipping first INX, remember it should be #$0001 when we resume writing) + LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X + + ; Look for first shortcut of each category. + ; This time only we can directly check shortcut types since + ; we haven't written any shortcuts yet so we know written table is empty. + ; Also this time only, fully validate selections. + .initialFirstLoop + LDA.w !sram_ctrl_shortcut_selections,X : BEQ .initialFirstInvalid + STA !CTRL_SHORTCUT_TABLE,X : AND.b !CTRL_SHORTCUT_TYPE_MASK + BEQ .initialFirstInvalid : CMP.b !GAMEMODE_CTRL_SHORTCUT_COUNT : BPL .initialFirstInvalid +if !FEATURE_VANILLAHUD + CMP #$19 : BPL .initialFirstInvalid + CMP #$12 : BEQ .initialFirstInvalid + CMP #$05 : BEQ .initialFirstInvalid +else + CMP #$05 +endif + BPL .initialFirstCheckInputs + CMP #$01 : BEQ .initialFirstCheckInputs if !FEATURE_SD2SNES -gamemode_door_transition: + LDA !ram_sram_savestates : BNE .initialFirstCheckInputs +endif + .initialFirstInvalid + TDC : STA !CTRL_SHORTCUT_TABLE,X + BRA .initialFirstContinue + .initialFirstCheckInputs + TXA : ASL : TAX + LDY.w !sram_ctrl_1_shortcut_inputs,X : BEQ .initialFirstNoPri + LDY.w !sram_ctrl_2_shortcut_inputs,X : BEQ .initialFirstPri + TXA : LSR : TAX + LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BNE .initialFirstContinue + TXA : STA !CTRL_SHORTCUT_TABLE_DUAL_INDEX + BRA .initialFirstContinue + .initialFirstNoPri + LDY.w !sram_ctrl_2_shortcut_inputs,X : BNE .initialFirstSec + TXA : LSR : TAX + BRA .initialFirstInvalid + .initialFirstPri + TXA : LSR : TAX + LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 : BNE .initialFirstContinue + TXA : STA !CTRL_SHORTCUT_TABLE_PRI_INDEX + BRA .initialFirstContinue + .initialFirstSec + TXA : LSR : TAX + LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BNE .initialFirstContinue + TXA : STA !CTRL_SHORTCUT_TABLE_SEC_INDEX + .initialFirstContinue + INX : CPX #$001E : BEQ .initialSecondLoop + JMP .initialFirstLoop + + .initialSecondLoop + LDA.w !sram_ctrl_additional_selections,X : BEQ .initialSecondInvalid + STA !CTRL_SHORTCUT_TABLE,X : AND.b !CTRL_SHORTCUT_TYPE_MASK + BEQ .initialSecondInvalid : CMP.b !GAMEMODE_CTRL_SHORTCUT_COUNT : BPL .initialSecondInvalid +if !FEATURE_VANILLAHUD + CMP #$19 : BPL .initialSecondInvalid + CMP #$12 : BEQ .initialSecondInvalid + CMP #$05 : BEQ .initialSecondInvalid +else + CMP #$05 +endif + BPL .initialSecondCheckInputs + CMP #$01 : BEQ .initialSecondCheckInputs +if !FEATURE_SD2SNES + LDA !ram_sram_savestates : BNE .initialSecondCheckInputs +endif + .initialSecondInvalid + TDC : STA !CTRL_SHORTCUT_TABLE,X + BRA .initialSecondContinue + .initialSecondCheckInputs + TXA : ASL : TAX + LDY.w !sram_ctrl_1_shortcut_inputs,X : BEQ .initialSecondNoPri + LDY.w !sram_ctrl_2_shortcut_inputs,X : BEQ .initialSecondPri + TXA : LSR : TAX + LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BNE .initialSecondContinue + TXA : STA !CTRL_SHORTCUT_TABLE_DUAL_INDEX + BRA .initialSecondContinue + .initialSecondNoPri + LDY.w !sram_ctrl_2_shortcut_inputs,X : BNE .initialSecondSec + TXA : LSR : TAX + BRA .initialSecondInvalid + .initialSecondPri + TXA : LSR : TAX + LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 : BNE .initialSecondContinue + TXA : STA !CTRL_SHORTCUT_TABLE_PRI_INDEX + BRA .initialSecondContinue + .initialSecondSec + TXA : LSR : TAX + LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BNE .initialSecondContinue + TXA : STA !CTRL_SHORTCUT_TABLE_SEC_INDEX + .initialSecondContinue + INX : CPX #$0030 : BEQ .beginWriteShortcuts + JMP .initialSecondLoop + + .beginWriteShortcuts + ; Restore X to resume writing + LDX #$0001 + + ; Check if we have pri only shortcuts to write + LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 : BPL .noPriShortcuts + + ; Write initial check for new controller 1 input + ; LDA $8F + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8F : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Branch over either two or nine bytes + ; BNE + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Check if we have sec only or dual shortcuts to write + LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BMI .priToSecDualJump + LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BMI .priToSecDualJump + + ; No additional categories to check + ; Branch over two bytes (PLP : RTL) + LDA #$02 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$6B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JMP .priWriteShortcuts + + .priToSecDualJump + ; Branch over nine bytes + LDA #$09 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Write initial check for new controller 2 input + ; LDA $91 + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$91 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Branch over two bytes (PLP : RTL) + ; BNE $02 + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$02 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; PLP : RTL + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$6B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; JMP + LDA #$4C : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; We don't yet know where to jump to. + ; Save this position and we'll write it later. + ; We know X is an 8-bit value at this point. + TXA : STA !CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP : INX #2 + JMP .priWriteShortcuts + + .noPriShortcuts + ; Check if we have sec only shortcuts to write + LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BPL .onlyDualShortcuts + + ; Write initial check for new controller 2 input + ; LDA $91 + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$91 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Branch over either two or nine bytes + ; BNE + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Check if we have dual shortcuts to write + LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BMI .secToDualJump + + ; No additional categories to check + ; Branch over two bytes (PLP : RTL) + LDA #$02 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$6B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JMP .secWriteShortcuts + + .onlyDualShortcuts + ; Check if we have dual only shortcuts to write + LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BMI .onlyDualChecks + JMP .doneWriteShortcuts + + .secToDualJump + ; Branch over nine bytes + LDA #$09 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Write initial check for new controller 1 input + ; LDA $8F + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8F : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Branch over two bytes (PLP : RTL) + ; BNE $02 + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$02 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; PLP : RTL + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$6B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; JMP + LDA #$4C : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; We don't yet know where to jump to. + ; Save this position and we'll write it later. + ; We know X is an 8-bit value at this point. + TXA : STA !CTRL_SHORTCUT_SEC_TO_DUAL_JUMP : INX #2 + ; JMP + LDA #$4C : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; We don't yet know where to jump to. + ; Save this position and we'll write it later. + ; Since we may have written several primary shortcuts first, + ; we need to copy the full 16-bits from X. + %a16() : TXA : STA !CTRL_SHORTCUT_SEC_TO_DUAL_JUMP : %a8() : INX #2 + JMP .secWriteShortcuts + + .onlyDualChecks + ; Write dual only check for both controller inputs + ; LDA $8F + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8F : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; ORA $91 + LDA #$05 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$91 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Branch over two bytes (PLP : RTL) + ; BNE $02 + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$02 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; No additional categories to check + ; PLP and RTL + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$6B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JMP .dualWriteShortcuts + + .doneWriteShortcuts + ; Closing PLP and RTL (skipping final INX) + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$6B : STA !CTRL_SHORTCUT_ROUTINE,X + + ; Write the skip remaining routine (PLP : RTL) + LDA #$28 : STA !CTRL_SHORTCUT_SKIP_REMAINING_PEA+1 + LDA #$6B : STA !CTRL_SHORTCUT_SKIP_REMAINING_PEA+2 + + %a16() + PLB + RTL + + .priWriteShortcuts + ; Populate variables for current shortcut + %a16() : LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX + PHX : TAX : ASL : TAY + LDA.w !sram_ctrl_1_shortcut_inputs,Y : STA !CTRL_SHORTCUT_PRI + %a8() : LDA !CTRL_SHORTCUT_TABLE,X : STA !CTRL_SHORTCUT_TYPE + + ; Check for special case (single bit non exact match) + BMI .priWriteNotSpecial + %a16() : LDA !CTRL_SHORTCUT_PRI : DEC + AND !CTRL_SHORTCUT_PRI : BNE .priWriteNotSpecial + + ; Scan for other single bit non exact matches with same type, + ; and also for next pri only shortcut. + ; Don't forget to clear ourselves from the table and reset category index. + %a8() : LDA #$30 : STA !CTRL_SHORTCUT_TABLE_PRI_INDEX + TDC : STA !CTRL_SHORTCUT_TABLE,X + JMP .priWriteSpecialLoop + + .priWriteNotSpecial + ; Scan for duplicates, and also for next pri only shortcut. + ; Don't forget to clear ourselves from the table and reset category index. + %a8() : LDA #$30 : STA !CTRL_SHORTCUT_TABLE_PRI_INDEX + TDC : STA !CTRL_SHORTCUT_TABLE,X + .priWriteNormalLoop + INX : CPX #$0030 : BPL .priWriteNormal + INY #2 : LDA !CTRL_SHORTCUT_TABLE,X : BEQ .priWriteNormalLoop + CMP !CTRL_SHORTCUT_TYPE : BNE .priWriteNormalCheckPri + %a16() : LDA.w !sram_ctrl_2_shortcut_inputs,Y : %a8() : BNE .priWriteNormalLoop + %a16() : LDA.w !sram_ctrl_1_shortcut_inputs,Y + CMP !CTRL_SHORTCUT_PRI : %a8() : BNE .priWriteNormalCheckPri + TDC : STA !CTRL_SHORTCUT_TABLE,X + BRA .priWriteNormalLoop + .priWriteNormalCheckPri + LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 : BMI .priWriteNormalLoop + %a16() : LDA.w !sram_ctrl_2_shortcut_inputs,Y : %a8() : BNE .priWriteNormalLoop + TXA : STA !CTRL_SHORTCUT_TABLE_PRI_INDEX + BRA .priWriteNormalLoop + + .priWriteNormal + PLX + ; LDA $8B + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Check if this is exact match + LDA !CTRL_SHORTCUT_TYPE : BMI .priWriteMatch + ; AND !CTRL_SHORTCUT_PRI + LDA #$29 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + .priWriteMatch + ; CMP !CTRL_SHORTCUT_PRI + LDA #$C9 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BNE (value will be written later so do an extra INX) + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX #2 + ; AND $8F + LDA #$25 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8F : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BEQ + LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Determine how much to branch by + PHX : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX + LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB + LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB + LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .priWriteMatchClc + LDA !CTRL_SHORTCUT_PRI+1 : BIT #$10 : BNE .priWriteMatchClv + ; Simple JSL case, so branch by four, earlier branch by eight + PLX : LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE-$4,X + LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeJsl + JMP .nextPriWrite + + .priWriteMatchClc + LDA !CTRL_SHORTCUT_PRI+1 : BIT #$10 : BNE .priWriteMatchClcClv + ; PLP : CLC : PHP followed by JSL, so branch by seven, earlier branch by eleven + PLX : LDA #$0B : STA !CTRL_SHORTCUT_ROUTINE-$4,X + LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClcJsl + JMP .nextPriWrite + + .priWriteMatchClv + ; PLP : CLV : PHP followed by JSL, so branch by seven, earlier branch by eleven + PLX : LDA #$0B : STA !CTRL_SHORTCUT_ROUTINE-$4,X + LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClvJsl + JMP .nextPriWrite + + .priWriteMatchClcClv + ; PLP : REP $41 : PHP followed by JSL, so branch by eight, earlier branch by twelve + PLX : LDA #$0C : STA !CTRL_SHORTCUT_ROUTINE-$4,X + LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClcClvJsl + JMP .nextPriWrite + + .priWriteSpecialLoop + INX : CPX #$0030 : BPL .priWriteSpecial + INY #2 : LDA !CTRL_SHORTCUT_TABLE,X : BEQ .priWriteSpecialLoop + CMP !CTRL_SHORTCUT_TYPE : BNE .priWriteSpecialCheckPri + %a16() : LDA.w !sram_ctrl_2_shortcut_inputs,Y : %a8() : BNE .priWriteSpecialLoop + %a16() : LDA.w !sram_ctrl_1_shortcut_inputs,Y + DEC : AND.w !sram_ctrl_1_shortcut_inputs,Y : %a8() : BNE .priWriteSpecialCheckPri + %a16() : LDA.w !sram_ctrl_1_shortcut_inputs,Y + ORA !CTRL_SHORTCUT_PRI : STA !CTRL_SHORTCUT_PRI + %a8() : TDC : STA !CTRL_SHORTCUT_TABLE,X + BRA .priWriteSpecialLoop + .priWriteSpecialCheckPri + LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 : BMI .priWriteSpecialLoop + %a16() : LDA.w !sram_ctrl_2_shortcut_inputs,Y : %a8() : BNE .priWriteSpecialLoop + TXA : STA !CTRL_SHORTCUT_TABLE_PRI_INDEX + BRA .priWriteSpecialLoop + + .priWriteSpecial + PLX + ; LDA $8F + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8F : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BIT !CTRL_SHORTCUT_PRI + LDA #$89 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BEQ + LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Determine how much to branch by + PHX : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX + LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB + LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB + LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .priWriteSpecialClc + LDA !CTRL_SHORTCUT_PRI+1 : BIT #$10 : BNE .priWriteSpecialClv + ; Simple JSL case, so branch by four + PLX : LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeJsl + BRA .nextPriWrite + + .priWriteSpecialClc + LDA !CTRL_SHORTCUT_PRI+1 : BIT #$10 : BNE .priWriteSpecialClcClv + ; PLP : CLC : PHP followed by JSL, so branch by seven + PLX : LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClcJsl + BRA .nextPriWrite + + .priWriteSpecialClv + ; PLP : CLV : PHP followed by JSL, so branch by seven + PLX : LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClvJsl + BRA .nextPriWrite + + .priWriteSpecialClcClv + ; PLP : REP $41 : PHP followed by JSL, so branch by eight + PLX : LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClcClvJsl + + .nextPriWrite + LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 : BPL .donePriWrite + JMP .priWriteShortcuts + + .donePriNoSec + ; Check if we have dual shortcuts to write + LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BPL .donePriNoSecNoDual + + ; Write check for any controller 2 input + ; LDA $8D + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8D : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Branch over two bytes (PLP : RTL) + ; BNE $02 + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$02 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; PLP : RTL + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$6B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Write the jump location we skipped over earlier + %a16() : TXY : LDA !CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP : TAX + TYA : CLC : ADC.w #!CTRL_SHORTCUT_ROUTINE : STA !CTRL_SHORTCUT_ROUTINE,X + TYX : %a8() + JMP .dualWriteShortcuts + + .donePriNoSecNoDual + JMP .doneWriteShortcuts + + .donePriWrite + ; Check if we have sec only shortcuts to write + LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BPL .donePriNoSec + + ; Write check for new controller 2 input + ; LDA $91 + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$91 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Branch over either two or nine bytes + ; BNE + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Check if we have dual shortcuts to write + LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BMI .donePriJumpToDual + + ; No additional categories to check + ; Branch over two bytes (PLP : RTL) + LDA #$02 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$6B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Write the jump location we skipped over earlier + %a16() : TXY : LDA !CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP : TAX + TYA : CLC : ADC.w #!CTRL_SHORTCUT_ROUTINE : STA !CTRL_SHORTCUT_ROUTINE,X + TYX : %a8() + JMP .secWriteShortcuts + + .donePriJumpToDual + ; Branch over nine bytes + LDA #$09 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Write check for any controller 2 input + ; LDA $8D + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8D : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Branch over two bytes (PLP : RTL) + ; BNE $02 + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$02 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; PLP : RTL + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$6B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; JMP + LDA #$4C : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; We don't yet know where to jump to. + ; Save this position and we'll write it later. + ; Since we may have written several primary shortcuts first, + ; we need to copy the full 16-bits from X. + %a16() : TXA : STA !CTRL_SHORTCUT_SEC_TO_DUAL_JUMP : %a8() : INX #2 + + ; Write the jump location we skipped over earlier + %a16() : TXY : LDA !CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP : TAX + TYA : CLC : ADC.w #!CTRL_SHORTCUT_ROUTINE : STA !CTRL_SHORTCUT_ROUTINE,X + TYX : %a8() + JMP .secWriteShortcuts + + .secWriteShortcuts + ; Populate variables for current shortcut + %a16() : LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX + PHX : TAX : ASL : TAY + LDA.w !sram_ctrl_2_shortcut_inputs,Y : STA !CTRL_SHORTCUT_SEC + %a8() : LDA !CTRL_SHORTCUT_TABLE,X : STA !CTRL_SHORTCUT_TYPE + + ; Check for special case (single bit non exact match) + BMI .secWriteNotSpecial + %a16() : LDA !CTRL_SHORTCUT_SEC : DEC + AND !CTRL_SHORTCUT_SEC : BNE .secWriteNotSpecial + + ; Scan for other single bit non exact matches with same type, + ; and also for next sec only shortcut. + ; Don't forget to clear ourselves from the table and reset category index. + %a8() : LDA #$30 : STA !CTRL_SHORTCUT_TABLE_SEC_INDEX + TDC : STA !CTRL_SHORTCUT_TABLE,X + JMP .secWriteSpecialLoop + + .secWriteNotSpecial + ; Scan for duplicates, and also for next sec only shortcut. + ; Don't forget to clear ourselves from the table and reset category index. + %a8() : LDA #$30 : STA !CTRL_SHORTCUT_TABLE_SEC_INDEX + TDC : STA !CTRL_SHORTCUT_TABLE,X + .secWriteNormalLoop + INX : CPX #$0030 : BPL .secWriteNormal + INY #2 : LDA !CTRL_SHORTCUT_TABLE,X : BEQ .secWriteNormalLoop + CMP !CTRL_SHORTCUT_TYPE : BNE .secWriteNormalCheckSec + %a16() : LDA.w !sram_ctrl_1_shortcut_inputs,Y : %a8() : BNE .secWriteNormalLoop + %a16() : LDA.w !sram_ctrl_2_shortcut_inputs,Y + CMP !CTRL_SHORTCUT_SEC : %a8() : BNE .secWriteNormalCheckSec + TDC : STA !CTRL_SHORTCUT_TABLE,X + BRA .secWriteNormalLoop + .secWriteNormalCheckSec + LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BMI .secWriteNormalLoop + %a16() : LDA.w !sram_ctrl_1_shortcut_inputs,Y : %a8() : BNE .secWriteNormalLoop + TXA : STA !CTRL_SHORTCUT_TABLE_SEC_INDEX + BRA .secWriteNormalLoop + + .secWriteNormal + PLX + ; LDA $8D + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8D : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Check if this is exact match + LDA !CTRL_SHORTCUT_TYPE : BMI .secWriteMatch + ; AND !CTRL_SHORTCUT_SEC + LDA #$29 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_SEC : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_SEC+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + .secWriteMatch + ; CMP !CTRL_SHORTCUT_SEC + LDA #$C9 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_SEC : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_SEC+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BNE (value will be written later so do an extra INX) + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX #2 + ; AND $91 + LDA #$25 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$91 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BEQ + LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Determine how much to branch by + PHX : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX + LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB + LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB + LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .secWriteMatchClc + LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .secWriteMatchClv + ; Simple JSL case, so branch by four, earlier branch by eight + PLX : LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE-$4,X + LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeJsl + JMP .nextSecWrite + + .secWriteMatchClc + LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .secWriteMatchClcClv + ; PLP : CLC : PHP followed by JSL, so branch by seven, earlier branch by eleven + PLX : LDA #$0B : STA !CTRL_SHORTCUT_ROUTINE-$4,X + LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClcJsl + JMP .nextSecWrite + + .secWriteMatchClv + ; PLP : CLV : PHP followed by JSL, so branch by seven, earlier branch by eleven + PLX : LDA #$0B : STA !CTRL_SHORTCUT_ROUTINE-$4,X + LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClvJsl + JMP .nextSecWrite + + .secWriteMatchClcClv + ; PLP : REP $41 : PHP followed by JSL, so branch by eight, earlier branch by twelve + PLX : LDA #$0C : STA !CTRL_SHORTCUT_ROUTINE-$4,X + LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClcClvJsl + JMP .nextSecWrite + + .secWriteSpecialLoop + INX : CPX #$0030 : BPL .secWriteSpecial + INY #2 : LDA !CTRL_SHORTCUT_TABLE,X : BEQ .secWriteSpecialLoop + CMP !CTRL_SHORTCUT_TYPE : BNE .secWriteSpecialCheckSec + %a16() : LDA.w !sram_ctrl_1_shortcut_inputs,Y : %a8() : BNE .secWriteSpecialLoop + %a16() : LDA.w !sram_ctrl_2_shortcut_inputs,Y + DEC : AND.w !sram_ctrl_2_shortcut_inputs,Y : %a8() : BNE .secWriteSpecialCheckSec + %a16() : LDA.w !sram_ctrl_2_shortcut_inputs,Y + ORA !CTRL_SHORTCUT_SEC : STA !CTRL_SHORTCUT_SEC + %a8() : TDC : STA !CTRL_SHORTCUT_TABLE,X + BRA .secWriteSpecialLoop + .secWriteSpecialCheckSec + LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BMI .secWriteSpecialLoop + %a16() : LDA.w !sram_ctrl_1_shortcut_inputs,Y : %a8() : BNE .secWriteSpecialLoop + TXA : STA !CTRL_SHORTCUT_TABLE_SEC_INDEX + BRA .secWriteSpecialLoop + + .secWriteSpecial + PLX + ; LDA $91 + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$91 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BIT !CTRL_SHORTCUT_SEC + LDA #$89 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_SEC : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_SEC+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BEQ + LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Determine how much to branch by + PHX : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX + LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB + LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB + LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .secWriteSpecialClc + LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .secWriteSpecialClv + ; Simple JSL case, so branch by four + PLX : LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeJsl + BRA .nextSecWrite + + .secWriteSpecialClc + LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .secWriteSpecialClcClv + ; PLP : CLC : PHP followed by JSL, so branch by seven + PLX : LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClcJsl + BRA .nextSecWrite + + .secWriteSpecialClv + ; PLP : CLV : PHP followed by JSL, so branch by seven + PLX : LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClvJsl + BRA .nextSecWrite + + .secWriteSpecialClcClv + ; PLP : REP $41 : PHP followed by JSL, so branch by eight + PLX : LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClcClvJsl + + .nextSecWrite + LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BPL .doneSecWrite + JMP .secWriteShortcuts + + .doneSecWrite + ; Check if we have dual shortcuts to write + LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BMI .doneSecHasDual + JMP .doneWriteShortcuts + + .doneSecHasDual + ; Write check for any controller 1 input + ; LDA $8B + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Branch over two bytes (PLP : RTL) + ; BNE $02 + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$02 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; PLP : RTL + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$6B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Write the jump location we skipped over earlier + %a16() : TXY : LDA !CTRL_SHORTCUT_SEC_TO_DUAL_JUMP : TAX + TYA : CLC : ADC.w #!CTRL_SHORTCUT_ROUTINE : STA !CTRL_SHORTCUT_ROUTINE,X + TYX : %a8() + + .dualWriteShortcuts + ; Populate variables for current shortcut + %a16() : LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX + PHX : TAX : ASL : TAY + LDA.w !sram_ctrl_1_shortcut_inputs,Y : STA !CTRL_SHORTCUT_PRI + LDA.w !sram_ctrl_2_shortcut_inputs,Y : STA !CTRL_SHORTCUT_SEC + %a8() : LDA !CTRL_SHORTCUT_TABLE,X : STA !CTRL_SHORTCUT_TYPE + + ; Scan for duplicates, and also for next shortcut. + ; Don't forget to clear ourselves from the table and reset category index. + %a8() : LDA #$30 : STA !CTRL_SHORTCUT_TABLE_DUAL_INDEX + TDC : STA !CTRL_SHORTCUT_TABLE,X + .dualWriteNormalLoop + INX : CPX #$0030 : BPL .dualWriteNormal + INY #2 : LDA !CTRL_SHORTCUT_TABLE,X : BEQ .dualWriteNormalLoop + CMP !CTRL_SHORTCUT_TYPE : BNE .dualWriteNormalCheckDual + %a16() : LDA.w !sram_ctrl_1_shortcut_inputs,Y + CMP !CTRL_SHORTCUT_PRI : %a8() : BNE .dualWriteNormalCheckDual + %a16() : LDA.w !sram_ctrl_2_shortcut_inputs,Y + CMP !CTRL_SHORTCUT_SEC : %a8() : BNE .dualWriteNormalCheckDual + TDC : STA !CTRL_SHORTCUT_TABLE,X + BRA .dualWriteNormalLoop + .dualWriteNormalCheckDual + LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BMI .dualWriteNormalLoop + TXA : STA !CTRL_SHORTCUT_TABLE_DUAL_INDEX + BRA .dualWriteNormalLoop + + .dualWriteNormal + PLX + ; LDA $8B + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Check if this is exact match + LDA !CTRL_SHORTCUT_TYPE : BMI .dualWriteMatchPri + ; AND !CTRL_SHORTCUT_PRI + LDA #$29 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + .dualWriteMatchPri + ; CMP !CTRL_SHORTCUT_PRI + LDA #$C9 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BNE (value will be written later so do an extra INX) + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX #2 + ; LDA $8D + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8D : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Check if this is exact match + LDA !CTRL_SHORTCUT_TYPE : BMI .dualWriteMatchSec + ; AND !CTRL_SHORTCUT_SEC + LDA #$29 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_SEC : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_SEC+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + .dualWriteMatchSec + ; CMP !CTRL_SHORTCUT_SEC + LDA #$C9 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_SEC : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_SEC+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BNE (value will be written later so do an extra INX) + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX #2 + ; AND $91 + LDA #$25 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$91 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BNE $07 + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; LDA !CTRL_SHORTCUT_PRI + LDA #$A9 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; AND $8F + LDA #$25 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8F : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BEQ + LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Determine how much to branch by + PHX : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX + LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB + LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB + LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .dualWriteMatchClc + LDA !CTRL_SHORTCUT_PRI+1 : BIT #$10 : BNE .dualWriteMatchClv + LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .dualWriteMatchClv + ; Simple JSL case, so branch by four, earlier branches by 15 and 25 + PLX : LDA #$19 : STA !CTRL_SHORTCUT_ROUTINE-$15,X + LDA #$0F : STA !CTRL_SHORTCUT_ROUTINE-$B,X + LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeJsl + BRA .nextDualWrite + + .dualWriteMatchClc + LDA !CTRL_SHORTCUT_PRI+1 : BIT #$10 : BNE .dualWriteMatchClcClv + LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .dualWriteMatchClcClv + ; PLP : CLC : PHP followed by JSL, so branch by seven, earlier branches by 18 and 28 + PLX : LDA #$1C : STA !CTRL_SHORTCUT_ROUTINE-$15,X + LDA #$12 : STA !CTRL_SHORTCUT_ROUTINE-$B,X + LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClcJsl + BRA .nextDualWrite + + .dualWriteMatchClv + ; PLP : CLV : PHP followed by JSL, so branch by seven, earlier branches by 18 and 28 + PLX : LDA #$1C : STA !CTRL_SHORTCUT_ROUTINE-$15,X + LDA #$12 : STA !CTRL_SHORTCUT_ROUTINE-$B,X + LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClvJsl + BRA .nextDualWrite + + .dualWriteMatchClcClv + ; PLP : REP $41 : PHP followed by JSL, so branch by eight, earlier branches by 19 and 29 + PLX : LDA #$1D : STA !CTRL_SHORTCUT_ROUTINE-$15,X + LDA #$13 : STA !CTRL_SHORTCUT_ROUTINE-$B,X + LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + JSR .writeClcClvJsl + + .nextDualWrite + LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BPL .doneDualWrite + JMP .dualWriteShortcuts + + .doneDualWrite + JMP .doneWriteShortcuts + + ; The following four subroutines jumped into from within this method + .writeClvJsl + ; PLP + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; CLV + LDA #$B8 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; PHP + LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + ; Fallthrough + .writeJsl + ; JSL + LDA #$22 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_JSL_WORD_LSB : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_JSL_WORD_MSB : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #ctrl_shortcut_jsl_word_msb_table>>16 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + RTS + + .writeClcJsl + ; PLP + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; CLC + LDA #$18 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; PHP + LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + BRA .writeJsl + + .writeClcClvJsl + ; PLP + LDA #$28 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; REP $41 (equivalent of CLC : CLV) + LDA #$C2 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$41 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; PHP + LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + BRA .writeJsl +} + +cm_condense_ctrl_shortcuts: { - .checkloadstate - LDA !IH_CONTROLLER_PRI : BEQ .checktransition - CMP !sram_ctrl_load_state : BNE .checktransition - ; check if a saved state exists - LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .checktransition - PHB : PHK : PLB - JML load_state + PHB : PEA $7070 : PLB : PLB + LDA.w #!sram_ctrl_1_shortcut_inputs : STA $00 : STA $02 + LDA.w #!sram_ctrl_2_shortcut_inputs : STA $04 : STA $06 + TDC : TAX : TAY + + .firstLoop + LDA.w !sram_ctrl_shortcut_selections,X + AND !CTRL_SHORTCUT_TYPE_MASK : BEQ .firstSkip + LDA ($00) : ORA ($04) : BNE .firstCopyCheck + %a8() : STA.w !sram_ctrl_shortcut_selections,X : %a16() + BRA .firstSkip + .firstCopyCheck + LDA $00 : CMP $02 : BEQ .firstCopyDone + LDA ($00) : STA ($02) : LDA ($04) : STA ($06) + %a8() : LDA.w !sram_ctrl_shortcut_selections,X : STA.w !sram_ctrl_shortcut_selections,Y + TDC : STA.w !sram_ctrl_shortcut_selections,X + %a16() : STA ($00) : STA ($04) + .firstCopyDone + INY : INC $02 : INC $02 : INC $06 : INC $06 + .firstSkip + INX : INC $00 : INC $00 : INC $04 : INC $04 + CPX #$001E : BMI .firstLoop + + .secondLoop + LDA.w !sram_ctrl_additional_selections,X + AND !CTRL_SHORTCUT_TYPE_MASK : BEQ .secondSkip + LDA ($00) : ORA ($04) : BNE .secondCopyCheck + %a8() : STA.w !sram_ctrl_additional_selections,X : %a16() + BRA .secondSkip + .secondCopyCheck + LDA $00 : CMP $02 : BEQ .secondCopyDone + LDA ($00) : STA ($02) : LDA ($04) : STA ($06) + %a8() : CPY #$001E : BMI .secondToFirst + LDA.w !sram_ctrl_additional_selections,X : STA.w !sram_ctrl_additional_selections,Y + BRA .secondClear + .secondToFirst + LDA.w !sram_ctrl_additional_selections,X : STA.w !sram_ctrl_shortcut_selections,Y + .secondClear + TDC : STA.w !sram_ctrl_additional_selections,X + %a16() : STA ($00) : STA ($04) + .secondCopyDone + INY : INC $02 : INC $02 : INC $06 : INC $06 + .secondSkip + INX : INC $00 : INC $00 : INC $04 : INC $04 + CPX #$0030 : BMI .secondLoop - .checktransition - ; check if door is done scrolling - LDA !DOOR_FINISHED_SCROLLING : BPL .checkloadstate + PLB RTL } -gamemode_door_transtion_load_sprites: +if !FEATURE_SD2SNES +validate_sram_for_savestates: { - ; Check for auto-save mid-transition - LDA !ram_auto_save_state : BEQ .check - BMI .auto_save - TDC : STA !ram_auto_save_state - .auto_save - PHP : PHB - PHK : PLB - JSL save_state - PLB : PLP - .done - JML $82E4A9 ; return to hijacked code - .check -if !FEATURE_PAL - JML $82E4A9 ; return to hijacked code + ; check if required SRAM range is valid + ; writes to SRAM will mirror in other banks if not valid +if !FEATURE_TINYSTATES + LDA $737FFE : INC : STA $707FFE + CMP $737FFE : BNE .success else - LDA !IH_CONTROLLER_PRI : CMP #$C0C0 : BNE .done - LDA !AREA_ID : BEQ .done : CMP #$0002 : BEQ .done - LDA !sram_ctrl_menu : CMP #$C0C0 : BEQ .done - LDA !sram_ctrl_save_state : CMP #$C0C0 : BEQ .done - LDA !sram_ctrl_load_state : CMP #$C0C0 : BEQ .done - LDA !sram_ctrl_load_last_preset : CMP #$C0C0 : BEQ .done - LDA !sram_ctrl_full_equipment : CMP #$C0C0 : BEQ .done - LDA !sram_ctrl_kill_enemies : CMP #$C0C0 : BEQ .done - LDA !sram_ctrl_reset_segment_timer : CMP #$C0C0 : BEQ .done - LDA !sram_ctrl_reset_segment_later : CMP #$C0C0 : BEQ .done - LDA !sram_ctrl_random_preset : CMP #$C0C0 : BEQ .done - LDA !sram_ctrl_save_custom_preset : CMP #$C0C0 : BEQ .end - LDA !sram_ctrl_load_custom_preset : CMP #$C0C0 : BEQ .end - LDA !sram_ctrl_inc_custom_preset : CMP #$C0C0 : BEQ .end - LDA !sram_ctrl_dec_custom_preset : CMP #$C0C0 : BEQ .end - LDA !sram_ctrl_toggle_tileviewer : CMP #$C0C0 : BEQ .end - LDA !sram_ctrl_update_timers : CMP #$C0C0 : BEQ .end - LDA !sram_ctrl_auto_save_state : CMP #$C0C0 : BEQ .end - LDA !sram_ctrl_toggle_spin_lock : CMP #$C0C0 : BEQ .end - LDA !sram_ctrl_randomize_rng : CMP #$C0C0 : BEQ .end - LDA !sram_ctrl_reveal_damage : CMP #$C0C0 : BEQ .end - LDA !sram_ctrl_force_stand : CMP #$C0C0 : BEQ .end - LDA #custom_intro_init : STA !CINEMATIC_FUNCTION_POINTER - LDA #$001E : STA !GAMEMODE - .end - JML $82E4A9 ; return to hijacked code + LDA $777FFE : INC : STA $707FFE + CMP $777FFE : BNE .success endif + + ; double check +if !FEATURE_TINYSTATES + LDA $732FFE : INC : STA $702FFE + CMP $732FFE : BEQ .fail +else + LDA $772FFE : INC : STA $702FFE + CMP $772FFE : BEQ .fail +endif + + .success + LDA #$0001 : STA !ram_sram_savestates + RTL + + .fail + ; disable savestate controls + TDC : TAX : STA !ram_sram_savestates + %a8() + .firstLoop + LDA !sram_ctrl_shortcut_selections,X : ASL + CMP #$04 : BCC .firstContinue : CMP #$0A : BCS .firstContinue + TDC : STA !sram_ctrl_shortcut_selections,X + .firstContinue + INX : CPX #$001E : BMI .firstLoop + .secondLoop + LDA !sram_ctrl_additional_selections,X : ASL + CMP #$04 : BCC .secondContinue : CMP #$0A : BCS .secondContinue + TDC : STA !sram_ctrl_additional_selections,X + .secondContinue + INX : CPX #$0030 : BMI .secondLoop + .found + %a16() + RTL } endif + +; ------------------ +; Ctrl Shortcut Menu +; ------------------ + +CtrlShortcutMenu: + dw #ctrlshortcut_00 + dw #ctrlshortcut_01 + dw #ctrlshortcut_02 + dw #ctrlshortcut_03 + dw #ctrlshortcut_04 + dw #ctrlshortcut_05 + dw #ctrlshortcut_06 + dw #ctrlshortcut_07 + dw #ctrlshortcut_08 + dw #ctrlshortcut_09 + dw #ctrlshortcut_10 + dw #ctrlshortcut_11 + dw #ctrlshortcut_12 + dw #ctrlshortcut_13 + dw #ctrlshortcut_14 + dw #ctrlshortcut_15 + dw #ctrlshortcut_goto_page2 + dw #ctrlshortcut_goto_page3 + dw #ctrlshortcut_reset_defaults + dw #$0000 + %cm_header("CONTROLLER SHORTCUTS") + %cm_footer_ctrlshortcut("PRESS AND HOLD FOR 2 SEC", "TOGGLES EXACT MATCH") + +CtrlShortcutMenu2: + dw #ctrlshortcut_16 + dw #ctrlshortcut_17 + dw #ctrlshortcut_18 + dw #ctrlshortcut_19 + dw #ctrlshortcut_20 + dw #ctrlshortcut_21 + dw #ctrlshortcut_22 + dw #ctrlshortcut_23 + dw #ctrlshortcut_24 + dw #ctrlshortcut_25 + dw #ctrlshortcut_26 + dw #ctrlshortcut_27 + dw #ctrlshortcut_28 + dw #ctrlshortcut_29 + dw #ctrlshortcut_30 + dw #ctrlshortcut_31 + dw #ctrlshortcut_goto_page1 + dw #ctrlshortcut_goto_page3 + dw #ctrlshortcut_reset_defaults + dw #$0000 + %cm_header("CONTROLLER SHORTCUTS") + %cm_footer_ctrlshortcut("PRESS AND HOLD FOR 2 SEC", "TOGGLES EXACT MATCH") + +CtrlShortcutMenu3: + dw #ctrlshortcut_32 + dw #ctrlshortcut_33 + dw #ctrlshortcut_34 + dw #ctrlshortcut_35 + dw #ctrlshortcut_36 + dw #ctrlshortcut_37 + dw #ctrlshortcut_38 + dw #ctrlshortcut_39 + dw #ctrlshortcut_40 + dw #ctrlshortcut_41 + dw #ctrlshortcut_42 + dw #ctrlshortcut_43 + dw #ctrlshortcut_44 + dw #ctrlshortcut_45 + dw #ctrlshortcut_46 + dw #ctrlshortcut_47 + dw #ctrlshortcut_goto_page1 + dw #ctrlshortcut_goto_page2 + dw #ctrlshortcut_reset_defaults + dw #$0000 + %cm_header("CONTROLLER SHORTCUTS") + %cm_footer_ctrlshortcut("PRESS AND HOLD FOR 2 SEC", "TOGGLES EXACT MATCH") + +%cm_ctrl_shortcut(00) +%cm_ctrl_shortcut(01) +%cm_ctrl_shortcut(02) +%cm_ctrl_shortcut(03) +%cm_ctrl_shortcut(04) +%cm_ctrl_shortcut(05) +%cm_ctrl_shortcut(06) +%cm_ctrl_shortcut(07) +%cm_ctrl_shortcut(08) +%cm_ctrl_shortcut(09) +%cm_ctrl_shortcut(10) +%cm_ctrl_shortcut(11) +%cm_ctrl_shortcut(12) +%cm_ctrl_shortcut(13) +%cm_ctrl_shortcut(14) +%cm_ctrl_shortcut(15) +%cm_ctrl_shortcut(16) +%cm_ctrl_shortcut(17) +%cm_ctrl_shortcut(18) +%cm_ctrl_shortcut(19) +%cm_ctrl_shortcut(20) +%cm_ctrl_shortcut(21) +%cm_ctrl_shortcut(22) +%cm_ctrl_shortcut(23) +%cm_ctrl_shortcut(24) +%cm_ctrl_shortcut(25) +%cm_ctrl_shortcut(26) +%cm_ctrl_shortcut(27) +%cm_ctrl_shortcut(28) +%cm_ctrl_shortcut(29) +%cm_ctrl_shortcut(30) +%cm_ctrl_shortcut(31) +%cm_ctrl_shortcut(32) +%cm_ctrl_shortcut(33) +%cm_ctrl_shortcut(34) +%cm_ctrl_shortcut(35) +%cm_ctrl_shortcut(36) +%cm_ctrl_shortcut(37) +%cm_ctrl_shortcut(38) +%cm_ctrl_shortcut(39) +%cm_ctrl_shortcut(40) +%cm_ctrl_shortcut(41) +%cm_ctrl_shortcut(42) +%cm_ctrl_shortcut(43) +%cm_ctrl_shortcut(44) +%cm_ctrl_shortcut(45) +%cm_ctrl_shortcut(46) +%cm_ctrl_shortcut(47) + +ctrlshortcut_goto_page1: + %cm_adjacent_submenu("GOTO PAGE ONE", #CtrlShortcutMenu) + +ctrlshortcut_goto_page2: + %cm_adjacent_submenu("GOTO PAGE TWO", #CtrlShortcutMenu2) + +ctrlshortcut_goto_page3: + %cm_adjacent_submenu("GOTO PAGE THREE", #CtrlShortcutMenu3) + +ctrlshortcut_reset_defaults: + %cm_jsl("Reset to Defaults", .routine, #$0000) + .routine + %sfxreset() + JML init_sram_controller_shortcuts + +ctrl_add_shortcut: + %cm_submenu("Add Shortcut", #CtrlSelectShortcutTypeMenu) + +CtrlSelectShortcutTypeMenu: + dw #ctrl_add_main_menu +if !FEATURE_SD2SNES + dw #ctrl_add_save_state_dynamic + dw #ctrl_add_load_state_dynamic + dw #ctrl_add_auto_save_state_dynamic +endif +if !FEATURE_VANILLAHUD +else + dw #ctrl_add_update_timers +endif + dw #ctrl_add_reload_preset + dw #ctrl_add_random_preset + dw #ctrl_add_save_custom_preset + dw #ctrl_add_load_custom_preset + dw #ctrl_add_inc_custom_preset + dw #ctrl_add_dec_custom_preset + dw #ctrl_add_reset_segment_timer + dw #ctrl_add_reset_segment_later + dw #$FFFF + dw #ctrl_select_shortcut_goto_page2 + dw #ctrl_select_shortcut_goto_page3 + dw #$0000 + %cm_header("SELECT SHORTCUT TYPE") + +CtrlSelectShortcutTypeMenu2: + dw #ctrl_add_full_equipment + dw #ctrl_add_kill_enemies + dw #ctrl_add_toggle_tileviewer + dw #ctrl_add_randomize_rng +if !FEATURE_VANILLAHUD +else + dw #ctrl_add_reveal_damage +endif + dw #ctrl_add_force_stand + dw #ctrl_add_toggle_spin_lock + dw #$FFFF + dw #ctrl_select_shortcut_goto_page1 + dw #ctrl_select_shortcut_goto_page3 + dw #$0000 + %cm_header("SELECT SHORTCUT TYPE") + +CtrlSelectShortcutTypeMenu3: + dw #ctrl_add_pause + dw #ctrl_add_unpause + dw #ctrl_add_slowdown + dw #ctrl_add_speedup +if !FEATURE_VANILLAHUD +else + dw #ctrl_add_inc_display_mode + dw #ctrl_add_dec_display_mode + dw #ctrl_add_inc_room_strat + dw #ctrl_add_dec_room_strat + dw #ctrl_add_inc_super_hud + dw #ctrl_add_dec_super_hud +endif + dw #$FFFF + dw #ctrl_select_shortcut_goto_page1 + dw #ctrl_select_shortcut_goto_page2 + dw #$0000 + %cm_header("SELECT SHORTCUT TYPE") + +ctrl_select_shortcut_goto_page1: + %cm_adjacent_submenu("GOTO PAGE ONE", #CtrlSelectShortcutTypeMenu) + +ctrl_select_shortcut_goto_page2: + %cm_adjacent_submenu("GOTO PAGE TWO", #CtrlSelectShortcutTypeMenu2) + +ctrl_select_shortcut_goto_page3: + %cm_adjacent_submenu("GOTO PAGE THREE", #CtrlSelectShortcutTypeMenu3) + +if !FEATURE_SD2SNES +ctrl_add_save_state_dynamic: + dw !ACTION_DYNAMIC + dl #!ram_sram_savestates + dw #$0000 + dw #ctrl_add_save_state + +ctrl_add_load_state_dynamic: + dw !ACTION_DYNAMIC + dl #!ram_sram_savestates + dw #$0000 + dw #ctrl_add_load_state + +ctrl_add_auto_save_state_dynamic: + dw !ACTION_DYNAMIC + dl #!ram_sram_savestates + dw #$0000 + dw #ctrl_add_auto_save_state +endif + +ctrl_shortcut_text_table: + dw #ctrl_add_empty_dm_text + dw #ctrl_add_main_menu_dm_text +if !FEATURE_SD2SNES + dw #ctrl_add_save_state_dm_text + dw #ctrl_add_load_state_dm_text + dw #ctrl_add_auto_save_state_dm_text +else + dw #ctrl_add_empty_dm_text + dw #ctrl_add_empty_dm_text + dw #ctrl_add_empty_dm_text +endif +if !FEATURE_VANILLAHUD + dw #ctrl_add_empty_dm_text +else + dw #ctrl_add_update_timers_dm_text +endif + dw #ctrl_add_reload_preset_dm_text + dw #ctrl_add_random_preset_dm_text + dw #ctrl_add_save_custom_preset_dm_text + dw #ctrl_add_load_custom_preset_dm_text + dw #ctrl_add_inc_custom_preset_dm_text + dw #ctrl_add_dec_custom_preset_dm_text + dw #ctrl_add_reset_segment_timer_dm_text + dw #ctrl_add_reset_segment_later_dm_text + dw #ctrl_add_full_equipment_dm_text + dw #ctrl_add_kill_enemies_dm_text + dw #ctrl_add_toggle_tileviewer_dm_text + dw #ctrl_add_randomize_rng_dm_text +if !FEATURE_VANILLAHUD + dw #ctrl_add_empty_dm_text +else + dw #ctrl_add_reveal_damage_dm_text +endif + dw #ctrl_add_force_stand_dm_text + dw #ctrl_add_toggle_spin_lock_dm_text + dw #ctrl_add_pause_dm_text + dw #ctrl_add_unpause_dm_text + dw #ctrl_add_slowdown_dm_text + dw #ctrl_add_speedup_dm_text +if !FEATURE_VANILLAHUD + dw #ctrl_add_empty_dm_text + dw #ctrl_add_empty_dm_text + dw #ctrl_add_empty_dm_text + dw #ctrl_add_empty_dm_text + dw #ctrl_add_empty_dm_text + dw #ctrl_add_empty_dm_text +else + dw #ctrl_add_inc_display_mode_dm_text + dw #ctrl_add_dec_display_mode_dm_text + dw #ctrl_add_inc_room_strat_dm_text + dw #ctrl_add_dec_room_strat_dm_text + dw #ctrl_add_inc_super_hud_dm_text + dw #ctrl_add_dec_super_hud_dm_text +endif + +ctrl_shortcut_cancel_gameplay_table: + db $00 ; Empty + db $01 ; Main Menu + db $01 ; Save State + db $01 ; Load State + db $00 ; Auto Save State + db $00 ; Update Timers + db $01 ; Reload Preset + db $01 ; Random Preset + db $01 ; Save Custom Preset + db $01 ; Load Custom Preset + db $00 ; Increment Custom Preset + db $00 ; Decrement Custom Preset + db $00 ; Reset Segment Timer + db $00 ; Reset Segment Later + db $00 ; Full Equipment + db $00 ; Kill Enemies + db $00 ; Toggle OOB Tile Viewer + db $00 ; Randomize RNG + db $00 ; Reveal Damage + db $00 ; Force Stand + db $00 ; Toggle Spin Lock + db $00 ; Pause + db $00 ; Unpause + db $00 ; Slowdown + db $00 ; Speedup + db $00 ; Increment Display Mode + db $00 ; Decrement Display Mode + db $00 ; Increment Room Strat + db $00 ; Decrement Room Strat + db $00 ; Increment Super HUD + db $00 ; Decrement Super HUD + +ctrl_shortcut_jsl_word_lsb_table: + db #gamemode_placeholder + db #gamemode_main_menu +if !FEATURE_SD2SNES + db #gamemode_save_state + db #gamemode_load_state + db #gamemode_auto_save_state +else + db #gamemode_placeholder + db #gamemode_placeholder + db #gamemode_placeholder +endif +if !FEATURE_VANILLAHUD + db #gamemode_placeholder +else + db #gamemode_update_timers +endif + db #gamemode_reload_preset + db #gamemode_random_preset + db #gamemode_save_custom_preset + db #gamemode_load_custom_preset + db #gamemode_increment_custom_preset + db #gamemode_decrement_custom_preset + db #gamemode_reset_segment_timer + db #gamemode_reset_segment_later + db #gamemode_full_equipment + db #gamemode_kill_enemies + db #gamemode_toggle_oob_tile_viewer + db #gamemode_randomize_rng +if !FEATURE_VANILLAHUD + db #gamemode_placeholder +else + db #gamemode_reveal_damage +endif + db #gamemode_force_stand + db #gamemode_toggle_spin_lock + db #gamemode_pause + db #gamemode_unpause + db #gamemode_slowdown + db #gamemode_speedup +if !FEATURE_VANILLAHUD + db #gamemode_placeholder + db #gamemode_placeholder + db #gamemode_placeholder + db #gamemode_placeholder + db #gamemode_placeholder + db #gamemode_placeholder +else + db #gamemode_increment_display_mode + db #gamemode_decrement_display_mode + db #gamemode_increment_room_strat + db #gamemode_decrement_room_strat + db #gamemode_increment_super_hud + db #gamemode_decrement_super_hud +endif + +ctrl_shortcut_jsl_word_msb_table: + db #gamemode_placeholder>>8 + db #gamemode_main_menu>>8 +if !FEATURE_SD2SNES + db #gamemode_save_state>>8 + db #gamemode_load_state>>8 + db #gamemode_auto_save_state>>8 +else + db #gamemode_placeholder>>8 + db #gamemode_placeholder>>8 + db #gamemode_placeholder>>8 +endif +if !FEATURE_VANILLAHUD + db #gamemode_placeholder>>8 +else + db #gamemode_update_timers>>8 +endif + db #gamemode_reload_preset>>8 + db #gamemode_random_preset>>8 + db #gamemode_save_custom_preset>>8 + db #gamemode_load_custom_preset>>8 + db #gamemode_increment_custom_preset>>8 + db #gamemode_decrement_custom_preset>>8 + db #gamemode_reset_segment_timer>>8 + db #gamemode_reset_segment_later>>8 + db #gamemode_full_equipment>>8 + db #gamemode_kill_enemies>>8 + db #gamemode_toggle_oob_tile_viewer>>8 + db #gamemode_randomize_rng>>8 +if !FEATURE_VANILLAHUD + db #gamemode_placeholder>>8 +else + db #gamemode_reveal_damage>>8 +endif + db #gamemode_force_stand>>8 + db #gamemode_toggle_spin_lock>>8 + db #gamemode_pause>>8 + db #gamemode_unpause>>8 + db #gamemode_slowdown>>8 + db #gamemode_speedup>>8 +if !FEATURE_VANILLAHUD + db #gamemode_placeholder>>8 + db #gamemode_placeholder>>8 + db #gamemode_placeholder>>8 + db #gamemode_placeholder>>8 + db #gamemode_placeholder>>8 + db #gamemode_placeholder>>8 +else + db #gamemode_increment_display_mode>>8 + db #gamemode_decrement_display_mode>>8 + db #gamemode_increment_room_strat>>8 + db #gamemode_decrement_room_strat>>8 + db #gamemode_increment_super_hud>>8 + db #gamemode_decrement_super_hud>>8 +endif + +ctrl_add_empty: + %cm_jsl("", #ctrl_add_shortcut_select, #$0000) + +ctrl_add_main_menu: + %cm_jsl("Main Menu", #ctrl_add_shortcut_select, #$0081) + +if !FEATURE_SD2SNES +ctrl_add_save_state: + %cm_jsl("Save State", #ctrl_add_shortcut_select, #$0082) + +ctrl_add_load_state: + %cm_jsl("Load State", #ctrl_add_shortcut_select, #$0083) + +ctrl_add_auto_save_state: + %cm_jsl("Auto Save State", #ctrl_add_shortcut_select, #$0084) +endif + +if !FEATURE_VANILLAHUD +else +ctrl_add_update_timers: + %cm_jsl("Update Timers", #ctrl_add_shortcut_select, #$0005) +endif + +ctrl_add_reload_preset: + %cm_jsl("Reload Preset", #ctrl_add_shortcut_select, #$0086) + +ctrl_add_random_preset: + %cm_jsl("Random Preset", #ctrl_add_shortcut_select, #$0087) + +ctrl_add_save_custom_preset: + %cm_jsl("Save Cust Preset", #ctrl_add_shortcut_select, #$0088) + +ctrl_add_load_custom_preset: + %cm_jsl("Load Cust Preset", #ctrl_add_shortcut_select, #$0089) + +ctrl_add_inc_custom_preset: + %cm_jsl("Next Preset Slot", #ctrl_add_shortcut_select, #$008A) + +ctrl_add_dec_custom_preset: + %cm_jsl("Prev Preset Slot", #ctrl_add_shortcut_select, #$008B) + +ctrl_add_reset_segment_timer: + %cm_jsl("Reset Seg Timer", #ctrl_add_shortcut_select, #$000C) + +ctrl_add_reset_segment_later: + %cm_jsl("Reset Seg Later", #ctrl_add_shortcut_select, #$000D) + +ctrl_add_full_equipment: + %cm_jsl("Full Equipment", #ctrl_add_shortcut_select, #$000E) + +ctrl_add_kill_enemies: + %cm_jsl("Kill Enemies", #ctrl_add_shortcut_select, #$008F) + +ctrl_add_toggle_tileviewer: + %cm_jsl("Toggle OOB Tiles", #ctrl_add_shortcut_select, #$0010) + +ctrl_add_randomize_rng: + %cm_jsl("Randomize RNG", #ctrl_add_shortcut_select, #$0011) + +if !FEATURE_VANILLAHUD +else +ctrl_add_reveal_damage: + %cm_jsl("Toggle Boss Dmg", #ctrl_add_shortcut_select, #$0012) +endif + +ctrl_add_force_stand: + %cm_jsl("Force Stand", #ctrl_add_shortcut_select, #$0013) + +ctrl_add_toggle_spin_lock: + %cm_jsl("Toggle Spin Lock", #ctrl_add_shortcut_select, #$0014) + +ctrl_add_pause: + %cm_jsl("Pause", #ctrl_add_shortcut_select, #$0095) + +ctrl_add_unpause: + %cm_jsl("Unpause", #ctrl_add_shortcut_select, #$0096) + +ctrl_add_slowdown: + %cm_jsl("Slowdown", #ctrl_add_shortcut_select, #$0097) + +ctrl_add_speedup: + %cm_jsl("Speedup", #ctrl_add_shortcut_select, #$0098) + +if !FEATURE_VANILLAHUD +else +ctrl_add_inc_display_mode: + %cm_jsl("Next Status Mode", #ctrl_add_shortcut_select, #$0099) + +ctrl_add_dec_display_mode: + %cm_jsl("Prev Status Mode", #ctrl_add_shortcut_select, #$009A) + +ctrl_add_inc_room_strat: + %cm_jsl("Next Room Strat", #ctrl_add_shortcut_select, #$009B) + +ctrl_add_dec_room_strat: + %cm_jsl("Prev Room Strat", #ctrl_add_shortcut_select, #$009C) + +ctrl_add_inc_super_hud: + %cm_jsl("Next Super HUD", #ctrl_add_shortcut_select, #$009D) + +ctrl_add_dec_super_hud: + %cm_jsl("Prev Super HUD", #ctrl_add_shortcut_select, #$009E) +endif + +ctrl_add_shortcut_select: +{ + LDA !ram_cm_ctrl_add_shortcut_slot : TAX + CMP #$001E : BPL .additional + TYA : %a8() : STA !sram_ctrl_shortcut_selections,X + INX : CPX #$001E : BPL .secondLoop + .firstLoop + LDA !sram_ctrl_shortcut_selections,X : BEQ .foundNextOpenSlot + INX : CPX #$001E : BMI .firstLoop + .secondLoop + LDA !sram_ctrl_additional_selections,X : BEQ .foundNextOpenSlot + INX : CPX #$0030 : BMI .secondLoop + BRA .foundNextOpenSlot + + .additional + TYA : %a8() : STA !sram_ctrl_additional_selections,X + INX : CPX #$0030 : BMI .secondLoop + .foundNextOpenSlot + %a16() + TXA : STA !ram_cm_ctrl_add_shortcut_slot + JML cm_previous_menu +} + %endfree(85) diff --git a/src/infohud.asm b/src/infohud.asm index f77cf3ba..604b0bbb 100644 --- a/src/infohud.asm +++ b/src/infohud.asm @@ -329,8 +329,9 @@ endif JMP .done .pause - LDA !IH_CONTROLLER_PRI : CMP !sram_ctrl_menu : BNE .noMenu - LDA !IH_PAUSE : STA !IH_CONTROLLER_SEC_NEW + ; TODO make pause work properly + ; LDA !IH_CONTROLLER_PRI : CMP !sram_ctrl_menu : BNE .noMenu + ; LDA !IH_PAUSE : STA !IH_CONTROLLER_SEC_NEW BRA .frameAdvance .noMenu @@ -343,8 +344,9 @@ endif LDA !IH_CONTROLLER_SEC : EOR !IH_CONTROLLER_SEC_NEW : STA !ram_slowdown_controller_2 .checkFrameAdvance - LDA !IH_CONTROLLER_SEC_NEW : CMP !IH_PAUSE : BEQ .frameAdvance - CMP !IH_RESET : BNE .checkFreezeOnLoad + ; TODO make resume work properly + ; LDA !IH_CONTROLLER_SEC_NEW : CMP !IH_PAUSE : BEQ .frameAdvance + ; CMP !IH_RESET : BNE .checkFreezeOnLoad ; resume normal play TDC : STA !ram_slowdown_mode : STA !ram_slowdown_frames BRA .done @@ -1566,8 +1568,6 @@ ih_game_loop_code: LDA !ram_game_loop_extras : BNE .extrafeatures - .checkinputs - LDA !IH_CONTROLLER_SEC_NEW : BNE .handleinputs ; overwritten code + return JML $808111 @@ -1589,62 +1589,20 @@ ih_game_loop_code: JSR magic_pants .pants_done - LDA !ram_infinite_ammo : BEQ .checkinputs + LDA !ram_infinite_ammo : BEQ .infinite_ammo_done LDA !SAMUS_MISSILES_MAX : STA !SAMUS_MISSILES LDA !SAMUS_SUPERS_MAX : STA !SAMUS_SUPERS LDA !SAMUS_PBS_MAX : STA !SAMUS_PBS - BRA .checkinputs + .infinite_ammo_done - .handleinputs - CMP !IH_PAUSE : BEQ .toggle_pause - CMP !IH_SLOWDOWN : BEQ .toggle_slowdown - CMP !IH_SPEEDUP : BEQ .toggle_speedup - CMP !IH_RESET : BEQ .reset_slowdown -if !FEATURE_VANILLAHUD -else - CMP !IH_STATUS_R : BEQ .inc_statusdisplay - CMP !IH_STATUS_L : BEQ .dec_statusdisplay -endif - - .done - JML $808111 ; overwritten code + return - - .toggle_pause - TDC : STA !ram_slowdown_frames - DEC : STA !ram_slowdown_mode - BRA .done - - .toggle_slowdown - LDA !ram_slowdown_mode : INC : STA !ram_slowdown_mode - BRA .done - - .toggle_speedup - LDA !ram_slowdown_mode : BEQ .done - DEC : STA !ram_slowdown_mode - BRA .done - - .reset_slowdown - TDC : STA !ram_slowdown_mode : STA !ram_slowdown_frames - BRA .done + ; overwritten code + return + JML $808111 +} if !FEATURE_VANILLAHUD else - .inc_statusdisplay - LDA !sram_display_mode : INC - CMP !IH_MODE_COUNT : BNE .set_displaymode - TDC - BRA .set_displaymode - - .dec_statusdisplay - LDA !sram_display_mode : DEC - CMP #$FFFF : BNE .set_displaymode - LDA !IH_MODE_COUNT-1 - - .set_displaymode - STA !sram_display_mode - JSL init_print_segment_timer - - .update_status +ih_update_status: +{ TDC STA !ram_momentum_sum : STA !ram_momentum_count STA !ram_HUD_check @@ -1658,10 +1616,9 @@ else LDA !ram_seed_X : LSR STA !ram_HUD_top : STA !ram_HUD_middle STA !ram_HUD_top_counter : STA !ram_HUD_middle_counter - - JML $808111 ; overwritten code + return -endif ; !FEATURE_VANILLAHUD + JML init_print_segment_timer } +endif ; !FEATURE_VANILLAHUD metronome: { diff --git a/src/init.asm b/src/init.asm index 795284d4..e0247a5f 100644 --- a/src/init.asm +++ b/src/init.asm @@ -47,9 +47,6 @@ init_code: JSR (init_sram_routine_table,X) .sram_initialized -if !FEATURE_SD2SNES - JSL validate_sram_for_savestates -endif PLA ; Execute overwritten logic and return if !FEATURE_PAL @@ -106,10 +103,10 @@ init_sram_routine_table: dw init_sram_upgrade_16to17 dw init_sram_upgrade_17to18 dw init_sram_upgrade_18to19 + dw init_sram_upgrade_19to1A init_sram: { - JSL init_sram_controller_shortcuts LDA #$0015 : STA !sram_artificial_lag TDC : STA !sram_fanfare STA !sram_frame_counter_mode @@ -126,13 +123,10 @@ init_sram: LDA #$000A : STA !sram_metronome_tickrate .upgrade_9toA - TDC : STA !sram_ctrl_toggle_tileviewer - STA !sram_status_icons + TDC : STA !sram_status_icons STA !sram_suit_properties .upgrade_AtoB - TDC : STA !sram_ctrl_update_timers - .upgrade_BtoC TDC : STA !sram_top_display_mode STA !sram_room_layout @@ -166,7 +160,6 @@ endif .upgrade_11to12 JSL init_menu_customization - TDC : STA !sram_ctrl_auto_save_state .upgrade_12to13 TDC : STA !sram_custom_header @@ -194,7 +187,7 @@ endif LDA #$000A : STA !sram_presetequiprando_max_pbs .upgrade_16to17 - TDC : STA !sram_spin_lock : STA !sram_ctrl_toggle_spin_lock + TDC : STA !sram_spin_lock DEC : STA !sram_map_grid_alignment .upgrade_17to18 @@ -205,10 +198,7 @@ endif STA !sram_infidoppler_enabled .upgrade_18to19 - TDC : STA !sram_ctrl_randomize_rng - STA !sram_ctrl_reveal_damage - STA !sram_ctrl_force_stand - STA !sram_random_bubble_sfx + TDC : STA !sram_random_bubble_sfx STA !sram_loadstate_rando_energy STA !sram_loadstate_rando_reserves STA !sram_loadstate_rando_missiles @@ -218,34 +208,106 @@ endif LDA #$0100 : STA !sram_ceres_timer LDA #$0300 : STA !sram_zebes_timer + .upgrade_19to1A + JSL init_sram_controller_shortcuts + LDA !SRAM_VERSION : STA !sram_initialized RTS } init_sram_controller_shortcuts: { - ; branch called by ctrl_reset_defaults in mainmenu.asm - LDA #$3000 : STA !sram_ctrl_menu ; Start + Select - LDA #$6010 : STA !sram_ctrl_save_state ; Select + Y + R - LDA #$6020 : STA !sram_ctrl_load_state ; Select + Y + L - LDA #$5020 : STA !sram_ctrl_load_last_preset ; Start + Y + L - TDC : STA !sram_ctrl_full_equipment - STA !sram_ctrl_kill_enemies - STA !sram_ctrl_reset_segment_timer - STA !sram_ctrl_reset_segment_later - STA !sram_ctrl_random_preset - STA !sram_ctrl_save_custom_preset - STA !sram_ctrl_load_custom_preset - STA !sram_ctrl_inc_custom_preset - STA !sram_ctrl_dec_custom_preset - ; duplicates for reset defaults routine - STA !sram_ctrl_toggle_tileviewer - STA !sram_ctrl_update_timers - STA !sram_ctrl_auto_save_state - STA !sram_ctrl_toggle_spin_lock - STA !sram_ctrl_randomize_rng - STA !sram_ctrl_reveal_damage - STA !sram_ctrl_force_stand + TDC : TAX + .firstLoop + STA !sram_ctrl_shortcut_selections,X + STA !sram_ctrl_1_shortcut_inputs,X + STA !sram_ctrl_2_shortcut_inputs,X + INX : INX : CPX #$001E : BMI .firstLoop + .secondLoop + STA !sram_ctrl_additional_selections,X + STA !sram_ctrl_1_shortcut_inputs,X + STA !sram_ctrl_2_shortcut_inputs,X + INX : INX : CPX #$0030 : BMI .secondLoop + .thirdLoop + STA !sram_ctrl_1_shortcut_inputs,X + STA !sram_ctrl_2_shortcut_inputs,X + INX : INX : CPX #$0060 : BMI .thirdLoop + + %a8() + ; Main Menu + LDA #$81 : LDX #$0000 : STA !sram_ctrl_shortcut_selections,X +if !FEATURE_SD2SNES + LDA !ram_sram_savestates : BEQ .skipTypes + ; Save State + LDA #$82 : INX : STA !sram_ctrl_shortcut_selections,X + ; Load State + LDA #$83 : INX : STA !sram_ctrl_shortcut_selections,X + .skipTypes +endif + ; Reload Preset + LDA #$86 : INX : STA !sram_ctrl_shortcut_selections,X + ; Pause + LDA #$95 : INX : STA !sram_ctrl_shortcut_selections,X + ; Unpause + LDA #$96 : INX : STA !sram_ctrl_shortcut_selections,X + ; Slowdown + LDA #$97 : INX : STA !sram_ctrl_shortcut_selections,X + ; Speedup + LDA #$98 : INX : STA !sram_ctrl_shortcut_selections,X +if !FEATURE_VANILLAHUD +else + ; Increment Display Mode + LDA #$99 : INX : STA !sram_ctrl_shortcut_selections,X + ; Decrement Display Mode + LDA #$9A : INX : STA !sram_ctrl_shortcut_selections,X + ; Increment Room Strat + LDA #$9B : INX : STA !sram_ctrl_shortcut_selections,X + ; Decrement Room Strat + LDA #$9C : INX : STA !sram_ctrl_shortcut_selections,X + ; Increment Super HUD + LDA #$9D : INX : STA !sram_ctrl_shortcut_selections,X + ; Decrement Super HUD + LDA #$9E : INX : STA !sram_ctrl_shortcut_selections,X +endif + ; Add Shortcut + INX : TXA : STA !ram_cm_ctrl_add_shortcut_slot + + %a16() + ; Main Menu (Controller 1, Start + Select) + LDA #$3000 : LDX #$0000 : STA !sram_ctrl_1_shortcut_inputs,X +if !FEATURE_SD2SNES + LDA !ram_sram_savestates : BEQ .skipValues + ; Save State (Controller 1, Select + Y + R) + LDA #$6010 : INX #2 : STA !sram_ctrl_1_shortcut_inputs,X + ; Load State (Controller 1, Select + Y + L) + LDA #$6020 : INX #2 : STA !sram_ctrl_1_shortcut_inputs,X + .skipValues +endif + ; Reload Preset (Controller 1, Start + Y + L) + LDA #$5020 : INX #2 : STA !sram_ctrl_1_shortcut_inputs,X + ; Pause (Controller 2, Right) + LDA #$0100 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X + ; Unpause (Controller 2, Left) + LDA #$0200 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X + ; Slowdown (Controller 2, Down) + LDA #$0400 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X + ; Speedup (Controller 2, Up) + LDA #$0800 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X +if !FEATURE_VANILLAHUD +else + ; Increment Display Mode (Controller 2, R) + LDA #$0010 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X + ; Decrement Display Mode (Controller 2, L) + LDA #$0020 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X + ; Increment Room Strat (Controller 2, X + R) + LDA #$0050 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X + ; Decrement Room Strat (Controller 2, X + L) + LDA #$0060 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X + ; Increment Super HUD (Controller 2, A + R) + LDA #$0090 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X + ; Decrement Super HUD (Controller 2, A + L) + LDA #$00A0 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X +endif RTL } diff --git a/src/layout.asm b/src/layout.asm index 44056480..74babd26 100644 --- a/src/layout.asm +++ b/src/layout.asm @@ -2312,9 +2312,8 @@ else LDA !sram_display_mode : BNE .done LDA !IH_MODE_ROOMSTRAT_INDEX : STA !sram_display_mode LDA !IH_STRAT_MBHP_INDEX : STA !sram_room_strat - - .done endif ; !FEATURE_VANILLAHUD + .done RTS } diff --git a/src/macros.asm b/src/macros.asm index f98b6251..740cd2da 100644 --- a/src/macros.asm +++ b/src/macros.asm @@ -86,7 +86,18 @@ macro cm_footer(title) ; optional outlined text below the menu items .dm_footer table ../resources/header.tbl - dw #$F007 : db #$28, "", #$FF + dw #$F007 + db #$28, "<title>", #$FF +table ../resources/normal.tbl +endmacro + +macro cm_footer_ctrlshortcut(title1, title2) +; optional outlined text below the menu items + .dm_footer1 +table ../resources/header.tbl + dw #$F006 + db #$28, "<title1>", #$FF + db #$28, "<title2>", #$FF table ../resources/normal.tbl endmacro @@ -327,7 +338,7 @@ macro cm_adjacent_submenu(title, target) ; can only used for submenus and when already on a submenu %cm_jsl("<title>", #.routine, <target>) .routine - JSL cm_previous_menu + JSL cm_go_back_adjacent_submenu JML action_submenu endmacro @@ -360,15 +371,13 @@ table ../resources/normal.tbl db #$28, "<slot>", #$FF endmacro -macro cm_ctrl_shortcut(title, addr) -; configure controller shortcuts +macro cm_ctrl_shortcut(slot) +; Configure controller shortcuts +ctrlshortcut_<slot>: .dm_actionIndex dw !ACTION_CTRL_SHORTCUT - .dm_addr - dl <addr> ; 24bit RAM address to display/manipulate - .dm_text -table ../resources/normal.tbl - db #$28, "<title>", #$FF + .dm_slot + db <slot> endmacro macro cm_ctrl_input(title, addr, routine, argument) diff --git a/src/main.asm b/src/main.asm index c51316c4..92a39be3 100644 --- a/src/main.asm +++ b/src/main.asm @@ -16,7 +16,7 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 6 !VERSION_BUILD = 7 -!VERSION_REV = 1 +!VERSION_REV = 7 table ../resources/normal.tbl print "" diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 58396c80..16100205 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -84,6 +84,22 @@ action_game_mainmenu: ORA !ram_cm_ceres_seconds : STA !ram_cm_ceres_seconds LDA !sram_zebes_timer : AND #$000F ORA !ram_cm_zebes_seconds : STA !ram_cm_zebes_seconds + JMP action_mainmenu +} + +action_ctrlshortcut_mainmenu: +{ + TDC : TAX + %a8() + .firstLoop + LDA !sram_ctrl_shortcut_selections,X : BEQ .found + INX : CPX #$001E : BMI .firstLoop + .secondLoop + LDA !sram_ctrl_additional_selections,X : BEQ .found + INX : CPX #$0030 : BMI .secondLoop + .found + %a16() + TXA : STA !ram_cm_ctrl_add_shortcut_slot BRA action_mainmenu } @@ -94,6 +110,12 @@ action_crop_mainmenu: BRA action_mainmenu } +action_equipment_mainmenu: +{ + JSL cm_set_etanks_and_reserve + BRA action_mainmenu +} + action_preset_options_mainmenu: { ; Prepare elevator option @@ -162,7 +184,7 @@ action_submenu: BRA action_submenu_jump } -action_presets_submenu: +action_presets_mainmenu: { ; Increment stack pointer by 2, then store current menu LDA !MENU_STACK_INDEX : INC #2 : STA !MENU_STACK_INDEX : TAX @@ -182,12 +204,16 @@ action_submenu_jump: { ; Set cursor to top for new menus TDC : STA !ram_cm_cursor_stack,X - - %sfxmove() JSL cm_calculate_max JSL cm_colors - JSL cm_draw - RTL + + ; Perform the cm_move check + ; in case we shouldn't be on the first line + LDA #$0002 : STA !DP_Temp + LDY #$0000 : LDX !MENU_STACK_INDEX + LDA !ram_cm_menu_stack,X : STA !DP_MenuIndices + JSL cm_move_checkBlankLine + JML cm_draw } preset_category_submenus: @@ -271,7 +297,7 @@ if !FEATURE_SD2SNES dw #mm_goto_savestate endif dw #mm_goto_timecontrol - dw #mm_goto_ctrlsmenu + dw #mm_goto_ctrlshortcut dw #mm_goto_audiomenu dw #mm_goto_customize dw #mm_goto_cropmenu @@ -308,17 +334,17 @@ if !FEATURE_SD2SNES dw #SavestateMenu>>16 endif dw #SlowdownMenu>>16 - dw #CtrlMenu>>16 + dw #CtrlShortcutMenu>>16 dw #AudioMenu>>16 dw #CustomizeMenu>>16 dw #CaptureCroppingMenu>>16 dw #BRBMenu>>16 mm_goto_equipment: - %cm_mainmenu("Equipment", #EquipmentMenu) + %cm_jsl("Equipment", #action_equipment_mainmenu, #EquipmentMenu) mm_goto_presets: - %cm_jsl("Category Presets", #action_presets_submenu, #$0000) + %cm_jsl("Category Presets", #action_presets_mainmenu, #$0000) mm_goto_presets_menu: %cm_jsl("Preset Options", #action_preset_options_mainmenu, #PresetOptionsMenu) @@ -358,8 +384,8 @@ endif mm_goto_timecontrol: %cm_mainmenu("Slowdown Mode", #SlowdownMenu) -mm_goto_ctrlsmenu: - %cm_mainmenu("Controller Shortcuts", #CtrlMenu) +mm_goto_ctrlshortcut: + %cm_jsl("Controller Shortcuts", #action_ctrlshortcut_mainmenu, #CtrlShortcutMenu) mm_goto_audiomenu: %cm_mainmenu("Audio Menu", #AudioMenu) @@ -892,8 +918,7 @@ else .done endif endif - JSL cm_previous_menu - %setmenubank() + JSL cm_go_back_adjacent_submenu JML action_submenu ManagePresetsMenu: @@ -1060,17 +1085,13 @@ custompreset_goto_page3: %cm_adjacent_submenu("GOTO PAGE THREE", #CustomPresetsMenu3) managepreset_goto_page1: - %cm_jsl("GOTO PAGE ONE", .routine, #ManagePresetsMenu) - .routine - JSL cm_previous_menu - %setmenubank() - JML action_submenu + %cm_adjacent_submenu("GOTO PAGE ONE", #ManagePresetsMenu) managepreset_goto_page2: - %cm_jsl("GOTO PAGE TWO", managepreset_goto_page1_routine, #ManagePresetsMenu2) + %cm_adjacent_submenu("GOTO PAGE TWO", #ManagePresetsMenu2) managepreset_goto_page3: - %cm_jsl("GOTO PAGE THREE", managepreset_goto_page1_routine, #ManagePresetsMenu3) + %cm_adjacent_submenu("GOTO PAGE THREE", #ManagePresetsMenu3) endif endif @@ -1800,6 +1821,7 @@ ihstrat_mbhp: ihstrat_twocries: %cm_jsl("Two Cries Standup", #action_select_room_strat, #$0015) +!IH_ROOM_STRAT_COUNT = #$0016 action_select_room_strat: { TYA : STA !sram_room_strat @@ -2095,6 +2117,13 @@ ih_superhud_mbhp: ih_superhud_twocries: %cm_jsl("Two Cries Standup", #action_select_superhud_bottom, #$0027) +!IH_SUPERHUD_BOTTOM_COUNT = #$0028 +action_select_superhud_bottom: +{ + TYA : STA !sram_superhud_bottom + JML cm_previous_menu +} + ih_superhud_goto_page1: %cm_adjacent_submenu("GOTO PAGE ONE", #SuperHUDBottomMenu) @@ -2104,12 +2133,6 @@ ih_superhud_goto_page2: ih_superhud_goto_page3: %cm_adjacent_submenu("GOTO PAGE THREE", #SuperHUDBottomMenu3) -action_select_superhud_bottom: -{ - TYA : STA !sram_superhud_bottom - JML cm_previous_menu -} - ih_superhud_middle_selector: dw !ACTION_CHOICE dl #!sram_superhud_middle @@ -2965,168 +2988,6 @@ slowdown_frames: %cm_numfield("Slowdown (Lag) Frames", !ram_cm_slowdown_frames, 0, 120, 1, 4, #0) -; ---------- -; Ctrl Menu -; ---------- - -CtrlMenu: - dw #ctrl_menu - dw #$FFFF -if !FEATURE_SD2SNES - dw #ctrl_save_state - dw #ctrl_load_state - dw #ctrl_auto_save_state -endif - dw #ctrl_load_last_preset - dw #ctrl_random_preset - dw #ctrl_save_custom_preset - dw #ctrl_load_custom_preset - dw #ctrl_inc_custom_preset - dw #ctrl_dec_custom_preset - dw #ctrl_reset_segment_timer - dw #ctrl_reset_segment_later - dw #$FFFF - dw #ctrl_goto_page2 - dw #ctrl_clear_shortcuts - dw #ctrl_reset_defaults - dw #$0000 - %cm_header("CONTROLLER SHORTCUTS") - %cm_footer("PRESS AND HOLD FOR 2 SEC") - -CtrlMenu2: - dw #ctrl_menu - dw #$FFFF - dw #ctrl_full_equipment - dw #ctrl_kill_enemies - dw #ctrl_toggle_tileviewer - dw #ctrl_randomize_rng -if !FEATURE_VANILLAHUD -else - dw #ctrl_reveal_damage - dw #ctrl_update_timers -endif - dw #ctrl_force_stand - dw #ctrl_toggle_spin_lock - dw #$FFFF - dw #ctrl_goto_page1 - dw #ctrl_clear_shortcuts - dw #ctrl_reset_defaults - dw #$0000 - %cm_header("CONTROLLER SHORTCUTS") - %cm_footer("PRESS AND HOLD FOR 2 SEC") - -ctrl_menu: - %cm_ctrl_shortcut("Main Menu", !sram_ctrl_menu) - -ctrl_load_last_preset: - %cm_ctrl_shortcut("Reload Preset", !sram_ctrl_load_last_preset) - -if !FEATURE_SD2SNES -ctrl_save_state: - %cm_ctrl_shortcut("Save State", !sram_ctrl_save_state) - -ctrl_load_state: - %cm_ctrl_shortcut("Load State", !sram_ctrl_load_state) - -ctrl_auto_save_state: - %cm_ctrl_shortcut("Auto Save State", !sram_ctrl_auto_save_state) -endif - -ctrl_reset_segment_timer: - %cm_ctrl_shortcut("Reset Seg Timer", !sram_ctrl_reset_segment_timer) - -ctrl_reset_segment_later: - %cm_ctrl_shortcut("Reset Seg Later", !sram_ctrl_reset_segment_later) - -ctrl_full_equipment: - %cm_ctrl_shortcut("Full Equipment", !sram_ctrl_full_equipment) - -ctrl_kill_enemies: - %cm_ctrl_shortcut("Kill Enemies", !sram_ctrl_kill_enemies) - -ctrl_random_preset: - %cm_ctrl_shortcut("Random Preset", !sram_ctrl_random_preset) - -ctrl_save_custom_preset: - %cm_ctrl_shortcut("Save Cust Preset", !sram_ctrl_save_custom_preset) - -ctrl_load_custom_preset: - %cm_ctrl_shortcut("Load Cust Preset", !sram_ctrl_load_custom_preset) - -ctrl_inc_custom_preset: - %cm_ctrl_shortcut("Next Preset Slot", !sram_ctrl_inc_custom_preset) - -ctrl_dec_custom_preset: - %cm_ctrl_shortcut("Prev Preset Slot", !sram_ctrl_dec_custom_preset) - -ctrl_toggle_tileviewer: - %cm_ctrl_shortcut("Toggle OOB Tiles", !sram_ctrl_toggle_tileviewer) - -ctrl_randomize_rng: - %cm_ctrl_shortcut("Randomize RNG", !sram_ctrl_randomize_rng) - -if !FEATURE_VANILLAHUD -else -ctrl_reveal_damage: - %cm_ctrl_shortcut("Toggle Boss Dmg", !sram_ctrl_reveal_damage) - -ctrl_update_timers: - %cm_ctrl_shortcut("Update Timers", !sram_ctrl_update_timers) -endif - -ctrl_force_stand: - %cm_ctrl_shortcut("Force Stand", !sram_ctrl_force_stand) - -ctrl_toggle_spin_lock: - %cm_ctrl_shortcut("Toggle Spin Lock", !sram_ctrl_toggle_spin_lock) - -ctrl_clear_shortcuts: - %cm_jsl("Clear Shortcuts", .routine, #$0000) - .routine - TYA - STA !ram_game_mode_extras - STA !sram_ctrl_save_state - STA !sram_ctrl_load_state - STA !sram_ctrl_auto_save_state - STA !sram_ctrl_load_last_preset - STA !sram_ctrl_full_equipment - STA !sram_ctrl_kill_enemies - STA !sram_ctrl_random_preset - STA !sram_ctrl_save_custom_preset - STA !sram_ctrl_load_custom_preset - STA !sram_ctrl_inc_custom_preset - STA !sram_ctrl_dec_custom_preset - STA !sram_ctrl_reset_segment_timer - STA !sram_ctrl_reset_segment_later - STA !sram_ctrl_toggle_tileviewer - STA !sram_ctrl_randomize_rng - STA !sram_ctrl_reveal_damage - STA !sram_ctrl_update_timers - STA !sram_ctrl_force_stand - STA !sram_ctrl_toggle_spin_lock - ; menu to default, Start + Select - LDA #$3000 : STA !sram_ctrl_menu - %sfxconfirm() - RTL - -ctrl_reset_defaults: - %cm_jsl("Reset to Defaults", .routine, #$0000) - .routine - %sfxreset() - JSL init_sram_controller_shortcuts -if !FEATURE_SD2SNES - JML validate_sram_for_savestates -else - RTL -endif - -ctrl_goto_page1: - %cm_adjacent_submenu("GOTO PAGE ONE", #CtrlMenu) - -ctrl_goto_page2: - %cm_adjacent_submenu("GOTO PAGE TWO", #CtrlMenu2) - - ; --------------- ; Helper Routines ; --------------- @@ -3136,31 +2997,10 @@ init_wram_based_on_sram: JSL RandomizeOnLoad_Flag JSL init_suit_properties_ram JSL init_physics_ram - JSL init_print_segment_timer - ; Fallthrough to GameModeExtras -} - -GameModeExtras: -{ - ; Check if any less common shortcuts are configured - LDA !sram_ctrl_reset_segment_timer : BNE .enabled - LDA !sram_ctrl_reset_segment_later : BNE .enabled - LDA !sram_ctrl_kill_enemies : BNE .enabled - LDA !sram_ctrl_full_equipment : BNE .enabled - LDA !sram_ctrl_save_custom_preset : BNE .enabled - LDA !sram_ctrl_load_custom_preset : BNE .enabled - LDA !sram_ctrl_inc_custom_preset : BNE .enabled - LDA !sram_ctrl_dec_custom_preset : BNE .enabled - LDA !sram_ctrl_toggle_tileviewer : BNE .enabled - LDA !sram_ctrl_randomize_rng : BNE .enabled - LDA !sram_ctrl_reveal_damage : BNE .enabled - LDA !sram_ctrl_update_timers : BNE .enabled - LDA !sram_ctrl_force_stand : BNE .enabled - LDA !sram_ctrl_toggle_spin_lock : BNE .enabled - - .enabled - STA !ram_game_mode_extras - RTL +if !FEATURE_SD2SNES + JSL validate_sram_for_savestates +endif + JML init_print_segment_timer } GameLoopExtras: @@ -3178,38 +3018,6 @@ GameLoopExtras: RTL } -if !FEATURE_SD2SNES -validate_sram_for_savestates: -{ - ; check if required SRAM range is valid - ; writes to SRAM will mirror in other banks if not valid -if !FEATURE_TINYSTATES - LDA $737FFE : INC : STA $707FFE - CMP $737FFE : BEQ .double_check -else - LDA $777FFE : INC : STA $707FFE - CMP $777FFE : BEQ .double_check -endif - RTL - - .double_check - ; double check -if !FEATURE_TINYSTATES - LDA $732FFE : INC : STA $702FFE - CMP $732FFE : BEQ .fail -else - LDA $772FFE : INC : STA $702FFE - CMP $772FFE : BEQ .fail -endif - RTL - - .fail - ; disable savestate controls - TDC : STA !sram_ctrl_save_state : STA !sram_ctrl_load_state - RTL -} -endif - init_print_segment_timer: { if !FEATURE_VANILLAHUD diff --git a/src/menu.asm b/src/menu.asm index ef613ad8..7dacbeca 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -108,6 +108,7 @@ cm_boot: LDA #$0001 : STA !ram_minimap .check_preset + JSL cm_write_ctrl_routine LDA !ram_custom_preset : BNE .preset_load LDA !ram_load_preset : BEQ .main_game_loop @@ -152,20 +153,20 @@ cm_init: JSL initialize_ppu_long JSL cm_transfer_custom_tileset JSL cm_transfer_custom_cgram + JSL cm_condense_ctrl_shortcuts ; Set up menu state TDC : STA !MENU_STACK_INDEX : STA !ram_cm_cursor_stack - STA !ram_cm_horizontal_cursor - STA !ram_cm_ctrl_mode : STA !ram_cm_ctrl_timer + STA !ram_cm_horizontal_cursor : STA !ram_cm_ctrl_mode STA !ram_cm_leave : STA !ram_load_preset STA !IH_CONTROLLER_PRI_NEW : STA !IH_CONTROLLER_PRI + STA !IH_CONTROLLER_SEC_NEW : STA !IH_CONTROLLER_SEC LDA !FRAME_COUNTER : STA !ram_cm_input_counter LDA.w #MainMenu : STA !ram_cm_menu_stack LDA.w #MainMenu>>16 : STA !ram_cm_menu_bank JSL cm_calculate_max - JSL cm_set_etanks_and_reserve LDA !sram_suit_properties : AND !SUIT_PROPERTIES_MASK STA !ram_cm_suit_properties RTS @@ -177,6 +178,7 @@ cm_exit: JSL cm_transfer_original_tileset JSL overwrite_HUD_numbers JSL cm_transfer_original_cgram + JSL cm_write_ctrl_routine ; Update HUD (in case we added missiles etc.) LDA !ram_gametime_room : STA $C1 @@ -665,18 +667,41 @@ cm_tilemap_menu: .footer ; menu pointer + header pointer + 1 = footer TYA : CLC : ADC !DP_CurrentMenu : INC : STA !DP_CurrentMenu - LDA [!DP_CurrentMenu] : CMP #$F007 : BNE .done + LDA [!DP_CurrentMenu] : CMP #$F006 : BEQ .ctrlShortcutFooter : CMP #$F007 : BNE .done ; INC past #$F007 INC !DP_CurrentMenu : INC !DP_CurrentMenu : STZ !DP_Palette - ; Optional footer + if !FEATURE_TALLMENU LDX #$0686 else LDX #$0646 +endif + JMP cm_draw_text + + .ctrlShortcutFooter + ; INC past #$F006 + INC !DP_CurrentMenu : INC !DP_CurrentMenu : STZ !DP_Palette +if !FEATURE_TALLMENU + LDX #$0646 +else + LDX #$0606 endif JSR cm_draw_text - RTS + ; menu pointer + footer pointer + 1 = second footer + TYA : CLC : ADC !DP_CurrentMenu : INC : STA !DP_CurrentMenu + + ; the first part of the second line is custom +if !FEATURE_TALLMENU + LDX #$0694 +else + LDX #$0654 +endif + LDA #$6C80 : STA !ram_tilemap_buffer-$E,X + LDA #$285E : STA !ram_tilemap_buffer-$A,X + LDA #$2861 : STA !ram_tilemap_buffer-$8,X + LDA #$2C80 : STA !ram_tilemap_buffer-$4,X + JMP cm_draw_text .done ; no footer, back up two bytes @@ -1168,28 +1193,84 @@ draw_choice_jsl_text: .found ; go to jsl text - %a16() LDA [!DP_CurrentMenu] : CLC : ADC #$0006 : STA !DP_CurrentMenu JMP cm_draw_text } draw_ctrl_shortcut: { - ; grab the memory address (long) - LDA [!DP_CurrentMenu] : INC !DP_CurrentMenu : INC !DP_CurrentMenu : STA !DP_Address - LDA [!DP_CurrentMenu] : INC !DP_CurrentMenu : STA !DP_Address+2 + ; grab the slot number + LDA [!DP_CurrentMenu] : AND #$00FF + + ; at most one slot will allow a shortcut to be added + ; check if it is this one + CMP !ram_cm_ctrl_add_shortcut_slot : BNE .notAddShortcut - ; draw the text + LDA #ctrl_add_shortcut_dm_text : STA !DP_CurrentMenu %item_index_to_vram_index() - PHX - JSR cm_draw_text + JMP cm_draw_text + + .notAddShortcut + ; grab the inputs + ASL : TAX + LDA !sram_ctrl_1_shortcut_inputs,X : PHA + LDA !sram_ctrl_2_shortcut_inputs,X : PHA + + ; grab the shortcut type + TXA : LSR : TAX + CMP #$001E : BPL .additional + LDA !sram_ctrl_shortcut_selections,X + BIT !CTRL_SHORTCUT_EXACT_MATCH : BEQ .prepareText + + .prepareExactMatchText + ; select text from shortcut type + AND !CTRL_SHORTCUT_TYPE_MASK : BEQ .skipDraw + ASL : TAX : LDA.l ctrl_shortcut_text_table,X : STA !DP_CurrentMenu + + ; draw text + %item_index_to_vram_index() + PHX : JSR cm_draw_text : PLX + + ; draw preceding equals sign + LDA #$DB00 : ORA !DP_Palette : XBA + STA !ram_tilemap_buffer-$2,X : TXA + BRA .drawInputs + + .skipDraw + PLA : PLA + RTS + .additional + LDA !sram_ctrl_additional_selections,X + BIT !CTRL_SHORTCUT_EXACT_MATCH : BNE .prepareExactMatchText + + .prepareText + ; select text from shortcut type + AND !CTRL_SHORTCUT_TYPE_MASK : BEQ .skipDraw + ASL : TAX : LDA.l ctrl_shortcut_text_table,X : STA !DP_CurrentMenu + + ; draw text + %item_index_to_vram_index() + PHX : JSR cm_draw_text : PLA + + .drawInputs ; set position of inputs - PLA : CLC : ADC #$0022 : TAX + CLC : ADC #$0032 : TAX ; draw the inputs - LDA [!DP_Address] - JMP menu_ctrl_input_display + PLA : JSR menu_ctrl_2_input_display + PLA : JSR menu_ctrl_1_input_display + TXA : AND #$003F : CMP #$0038 : BNE .end + + ; draw dashes when input is empty + LDA #$CC00 : ORA !DP_Palette : XBA + STA !ram_tilemap_buffer,X + STA !ram_tilemap_buffer-$2,X + STA !ram_tilemap_buffer-$4,X + + .end + RTS + } draw_controller_input: @@ -1668,41 +1749,65 @@ cm_draw_text: ; Input Display ; -------------- -menu_ctrl_input_display: +menu_ctrl_2_input_display: ; X = pointer to tilemap area (STA !ram_tilemap_buffer,X) ; A = Controller word { - PHA - ; clear out tilemap area + PHA LDA !MENU_BLANK STA !ram_tilemap_buffer,X - STA !ram_tilemap_buffer+$2,X - STA !ram_tilemap_buffer+$4,X - STA !ram_tilemap_buffer+$6,X - STA !ram_tilemap_buffer+$8,X - STA !ram_tilemap_buffer+$A,X - STA !ram_tilemap_buffer+$C,X - STA !ram_tilemap_buffer+$E,X - STA !ram_tilemap_buffer+$10,X + STA !ram_tilemap_buffer-$2,X + STA !ram_tilemap_buffer-$4,X + STA !ram_tilemap_buffer-$6,X + STA !ram_tilemap_buffer-$8,X + STA !ram_tilemap_buffer-$A,X + STA !ram_tilemap_buffer-$C,X + STA !ram_tilemap_buffer-$E,X + STA !ram_tilemap_buffer-$10,X + STA !ram_tilemap_buffer-$12,X PLA XBA LDY #$0000 .loop - PHA - BIT #$0001 : BEQ .no_draw + BIT #$8000 : BEQ .no_draw - TYA : CLC : ADC #$0080 - XBA : ORA !DP_Palette : XBA - STA !ram_tilemap_buffer,X : INX #2 + PHA : TYA : ASL : PHX : TAX + LDA.l .table,X : ORA !DP_Palette : XBA + PLX : STA !ram_tilemap_buffer,X : DEX #2 : PLA .no_draw - PLA - INY : LSR : BNE .loop + INY : ASL : BNE .loop + RTS - .done + .table + dw #$A100, #$B800, #$AC00, #$B200, #$9400, #$9400, #$9400, #$9400 + dw #$A200, #$B900, #$8300, #$8200, #$F900, #$F980, #$FF40, #$FF00 +} + +menu_ctrl_1_input_display: +; X = pointer to tilemap area (STA !ram_tilemap_buffer,X) +; A = Controller word +{ + XBA + LDY #$0000 + .loop + BIT #$8000 : BEQ .no_draw + + PHA : TYA : ASL : PHX : TAX + LDA.l .table,X : ORA !DP_Palette : XBA + PLX : STA !ram_tilemap_buffer,X : DEX #2 : PLA + + .no_draw + INY : ASL : BNE .loop + LDA #$9400 : ORA !DP_Palette : XBA + STA !ram_tilemap_buffer,X RTS + + .table + dw #$8F00, #$8E00, #$8D00, #$8C00, #$9400, #$9400, #$9400, #$9400 + dw #$8700, #$8600, #$8500, #$8400, #$8180, #$8100, #$8040, #$8000 } @@ -1753,12 +1858,12 @@ cm_loop: .pressedDown LDA #$0002 - JSR cm_move + JSL cm_move BRA .redraw .pressedUp LDA #$FFFE - JSR cm_move + JSL cm_move BRA .redraw .pressedL @@ -1798,57 +1903,53 @@ cm_ctrl_mode: ; Held inputs are displayed until held for 120 frames { JSL $809459 ; Read controller input - LDA !IH_CONTROLLER_PRI ; set palette %a8() : LDA #$28 : STA !DP_Palette : %a16() - LDA !IH_CONTROLLER_PRI : BEQ .clear_and_draw - CMP !ram_cm_ctrl_last_input : BNE .clear_and_draw + LDA !IH_CONTROLLER_PRI : CMP !ram_cm_ctrl_last_pri : BNE .clear_and_draw + LDA !IH_CONTROLLER_SEC : CMP !ram_cm_ctrl_last_sec : BNE .clear_and_draw - ; Holding an input for more than one second + ; Holding an input for one second LDA !ram_cm_ctrl_timer : INC : STA !ram_cm_ctrl_timer - CMP.w #0060 : BNE .next_frame + CMP !FRAMERATE : BNE .next_frame - ; disallow inputs that match the menu shortcut - LDA !DP_CtrlInput : CMP.w #!sram_ctrl_menu : BEQ .store - LDA !IH_CONTROLLER_PRI : CMP !sram_ctrl_menu : BNE .store - %sfxfail() - ; set cursor position to 0 (menu shortcut) - LDX !MENU_STACK_INDEX - TDC : STA !ram_cm_cursor_stack,X + ; Disallow first Main Menu shortcut to be empty + LDA !IH_CONTROLLER_PRI : ORA !IH_CONTROLLER_SEC : BNE .store + LDA !DP_CtrlInput : CMP.w #!sram_ctrl_1_shortcut_inputs : BNE .store + + ; Store default Main Menu input to SRAM + LDA #$3000 : STA [!DP_CtrlInput] + TDC : STA [!DP_Ctrl2Input] + %sfxconfirm() BRA .exit .store ; Store controller input to SRAM LDA !IH_CONTROLLER_PRI : STA [!DP_CtrlInput] - JSL GameModeExtras -if !FEATURE_SD2SNES - JSL validate_sram_for_savestates -endif + LDA !IH_CONTROLLER_SEC : STA [!DP_Ctrl2Input] %sfxconfirm() BRA .exit .clear_and_draw - STA !ram_cm_ctrl_last_input TDC : STA !ram_cm_ctrl_timer ; Put text cursor in X LDX !MENU_STACK_INDEX - LDA !ram_cm_cursor_stack,X : ASL #5 : CLC : ADC #$0168 : TAX + LDA !ram_cm_cursor_stack,X : ASL #5 : CLC : ADC #$0178 : TAX ; Input display - LDA !IH_CONTROLLER_PRI - JSR menu_ctrl_input_display + LDA !IH_CONTROLLER_SEC : STA !ram_cm_ctrl_last_sec + JSR menu_ctrl_2_input_display + LDA !IH_CONTROLLER_PRI : STA !ram_cm_ctrl_last_pri + JSR menu_ctrl_1_input_display JSR cm_tilemap_transfer .next_frame RTS .exit - TDC : STA !ram_cm_ctrl_last_input - STA !ram_cm_ctrl_mode - STA !ram_cm_ctrl_timer + TDC : STA !ram_cm_ctrl_mode JSL cm_draw RTS } @@ -1863,7 +1964,7 @@ cm_edit_digits: AND #$8F80 : BEQ .redraw BIT !IH_INPUT_LEFTRIGHT : BNE .selecting BIT !IH_INPUT_UPDOWN : BNE .editing - BIT #$8080 : BEQ .redraw + BIT !CTRL_AB : BEQ .redraw ; exit if A or B pressed ; skip if JSL target is zero @@ -1995,7 +2096,7 @@ cm_edit_decimal_digits: AND #$8F80 : BEQ .redraw BIT !IH_INPUT_LEFTRIGHT : BNE .selecting BIT !IH_INPUT_UPDOWN : BNE .editing - BIT #$8080 : BEQ .redraw + BIT !CTRL_AB : BEQ .redraw ; exit if A or B pressed JMP .exit @@ -2548,6 +2649,15 @@ cm_previous_menu: JML cm_calculate_max } +cm_go_back_adjacent_submenu: +{ + ; make sure next time we go to a submenu, we start on the first line. + LDX !MENU_STACK_INDEX + TDC : STA !ram_cm_cursor_stack,X + DEX #2 : STX !MENU_STACK_INDEX + RTL +} + cm_go_back: { ; make sure next time we go to a submenu, we start on the first line. @@ -2602,25 +2712,52 @@ cm_get_inputs: JSL $809459 ; Read controller input .input_read - LDA !IH_CONTROLLER_PRI_NEW : BEQ .check_holding + LDA !IH_CONTROLLER_PRI_NEW : BEQ .check_input_sec LDA !input_held_delay : STA !ram_cm_input_timer ; Check if fast scroll button is held - LDA !IH_CONTROLLER_PRI : AND !sram_cm_fast_scroll_button : BEQ .return_input + LDA !IH_CONTROLLER_PRI : AND !sram_cm_fast_scroll_button : BEQ .return_input_pri ; Reduce delay to double the scroll delay - LDA !sram_cm_scroll_delay : ASL : CMP !input_held_delay : BPL .return_input + LDA !sram_cm_scroll_delay : ASL : CMP !input_held_delay : BPL .return_input_pri STA !ram_cm_input_timer - .return_input - ; Return the new input + .return_input_pri LDA !IH_CONTROLLER_PRI_NEW RTS + .check_input_sec + LDA !IH_CONTROLLER_SEC_NEW : BEQ .check_holding + + LDA !input_held_delay : STA !ram_cm_input_timer + + ; Check if fast scroll button is held + LDA !IH_CONTROLLER_SEC : AND !sram_cm_fast_scroll_button : BEQ .return_input_sec + + ; Reduce delay to double the scroll delay + LDA !sram_cm_scroll_delay : ASL : CMP !input_held_delay : BPL .return_input_sec + STA !ram_cm_input_timer + + .return_input_sec + LDA !IH_CONTROLLER_SEC_NEW + RTS + .check_holding - ; Check if we're holding the dpad - LDA !IH_CONTROLLER_PRI : AND #$0F00 : BEQ .noinput + LDA !IH_CONTROLLER_PRI : AND !IH_INPUT_DPAD : BEQ .check_holding_sec + + ; Decrement delay timer and check if it's zero + LDA !ram_cm_input_timer : DEC : STA !ram_cm_input_timer : BNE .noinput + + ; Set new delay, default is 2 + LDA !sram_cm_scroll_delay : STA !ram_cm_input_timer + + ; Return held input + LDA !IH_CONTROLLER_PRI : AND !IH_INPUT_DPAD : ORA !IH_INPUT_HELD + RTS + + .check_holding_sec + LDA !IH_CONTROLLER_SEC : AND !IH_INPUT_DPAD : BEQ .noinput ; Decrement delay timer and check if it's zero LDA !ram_cm_input_timer : DEC : STA !ram_cm_input_timer : BNE .noinput @@ -2629,7 +2766,7 @@ cm_get_inputs: LDA !sram_cm_scroll_delay : STA !ram_cm_input_timer ; Return held input - LDA !IH_CONTROLLER_PRI : AND #$0F00 : ORA !IH_INPUT_HELD + LDA !IH_CONTROLLER_SEC : AND !IH_INPUT_DPAD : ORA !IH_INPUT_HELD RTS .noinput @@ -2651,15 +2788,40 @@ cm_move: .inBounds STA !ram_cm_cursor_stack,X : TAY + .checkBlankLine ; check for blank menu line ($FFFF) - LDA [!DP_MenuIndices],Y : CMP #$FFFF : BNE .checkDynamic + LDA [!DP_MenuIndices],Y : CMP #$FFFF : BNE .checkCtrlShortcut .repeat ; repeat move to skip blank line LDA !DP_Temp : BRA cm_move - .checkDynamic + .checkCtrlShortcut STA !DP_CurrentMenu : LDA [!DP_CurrentMenu] + CMP !ACTION_CTRL_SHORTCUT : BNE .checkDynamic + + ; grab the shortcut slot + INC !DP_CurrentMenu : INC !DP_CurrentMenu + LDA [!DP_CurrentMenu] : AND #$00FF + DEC !DP_CurrentMenu : DEC !DP_CurrentMenu + + ; at most one slot will allow a shortcut to be added + ; check if it is this one + CMP !ram_cm_ctrl_add_shortcut_slot : BEQ .end + + ; grab the shortcut type + PHX : TAX + CMP #$001E : BPL .additionalCtrlShortcut + LDA !sram_ctrl_shortcut_selections,X + PLX : AND !CTRL_SHORTCUT_TYPE_MASK : BEQ .repeat + BRA .end + + .additionalCtrlShortcut + LDA !sram_ctrl_additional_selections,X + PLX : AND !CTRL_SHORTCUT_TYPE_MASK : BEQ .repeat + BRA .end + + .checkDynamic CMP !ACTION_DYNAMIC : BNE .end ; grab the memory address (long) @@ -2683,7 +2845,7 @@ cm_move: .end %sfxmove() - RTS + RTL } @@ -2857,7 +3019,7 @@ execute_numfield: AND #$00FF : STA !DP_Increment ; determine dpad direction - LDA !ram_cm_controller : BIT #$0200 : BNE .pressed_left + LDA !ram_cm_controller : BIT !IH_INPUT_LEFT : BNE .pressed_left ; pressed right, inc LDA [!DP_Address] : AND #$00FF : CLC : ADC !DP_Increment CMP !DP_Maximum : BCS .set_to_min @@ -2946,7 +3108,7 @@ execute_numfield_word: LDA !ram_cm_controller : BIT !IH_INPUT_LEFTRIGHT : BEQ .singleDigitEditing ; check direction held - BIT #$0200 : BNE .pressed_left + BIT !IH_INPUT_LEFT : BNE .pressed_left ; pressed right, inc LDA [!DP_DigitAddress] : CLC : ADC !DP_Increment CMP !DP_DigitMaximum : BCS .set_to_min @@ -3029,7 +3191,7 @@ execute_numfield_color: LDA [!DP_CurrentMenu] : INC !DP_CurrentMenu : INC !DP_CurrentMenu : STA !DP_JSLTarget ; determine dpad direction - LDA !ram_cm_controller : BIT #$0200 : BNE .pressed_left + LDA !ram_cm_controller : BIT !IH_INPUT_LEFT : BNE .pressed_left ; pressed right, inc LDA [!DP_Address] : INC : CMP #$0020 : BCS .set_to_min STA [!DP_Address] : BRA .jsl @@ -3071,7 +3233,7 @@ execute_choice: LDA [!DP_CurrentMenu] : INC !DP_CurrentMenu : INC !DP_CurrentMenu : STA !DP_JSLTarget ; we either increment or decrement - LDA !ram_cm_controller : BIT #$0200 : BNE .pressed_left + LDA !ram_cm_controller : BIT !IH_INPUT_LEFT : BNE .pressed_left ; pressed right LDA [!DP_Address] : INC : BRA .bounds_check @@ -3140,7 +3302,7 @@ execute_choice_jsl_text: LDA [!DP_CurrentMenu] : INC !DP_CurrentMenu : INC !DP_CurrentMenu : STA !DP_JSLTarget ; we either increment or decrement - LDA !ram_cm_controller : BIT #$0200 : BNE .pressed_left + LDA !ram_cm_controller : BIT !IH_INPUT_LEFT : BNE .pressed_left ; pressed right LDA [!DP_Address] : INC : BRA .bounds_check @@ -3193,37 +3355,64 @@ execute_choice_jsl_text: execute_ctrl_shortcut: { - ; < and > should do nothing here - ; also ignore the input held flag - LDA !ram_cm_controller : BIT #$0301 : BNE .end + ; ignore the input held flag + LDA !ram_cm_controller : BIT !IH_INPUT_HELD : BNE .end + BIT !IH_INPUT_LEFTRIGHT : BNE .toggleExactMatch - ; grab memory address (long) - LDA [!DP_CurrentMenu] : INC !DP_CurrentMenu : INC !DP_CurrentMenu : STA !DP_CtrlInput - LDA [!DP_CurrentMenu] : INC !DP_CurrentMenu : STA !DP_CtrlInput+2 + ; grab the slot number + LDA [!DP_CurrentMenu] : AND #$00FF - ; press X to delete a shortcut - LDA !ram_cm_controller : BIT !CTRL_X : BNE .reset_shortcut + ; at most one slot will allow a shortcut to be added + ; check if it is this one + CMP !ram_cm_ctrl_add_shortcut_slot : BNE .notAddShortcutText - ; enable ctrl mode to edit shortcuts - TDC : STA !ram_cm_ctrl_timer - INC : STA !ram_cm_ctrl_mode - RTS + ; in this case, ignore X input as well + LDA !ram_cm_controller : BIT !CTRL_X : BNE .end - .reset_shortcut - LDA.w #!sram_ctrl_menu : CMP !DP_CtrlInput : BEQ .end - %sfxconfirm() + ; Y = Argument + LDY #CtrlSelectShortcutTypeMenu - TDC : STA [!DP_CtrlInput] + LDX #$0000 + JSL action_submenu .end RTS + + .toggleExactMatch + ; grab the slot number + TDC : %a8() : LDA [!DP_CurrentMenu] + + ; grab the shortcut type + TAX : CMP #$1E : BPL .additionalExactMatch + LDA !sram_ctrl_shortcut_selections,X : BEQ .endExactMatch + EOR.b !CTRL_SHORTCUT_EXACT_MATCH : STA !sram_ctrl_shortcut_selections,X + BRA .endExactMatch + + .additionalExactMatch + LDA !sram_ctrl_additional_selections,X : BEQ .endExactMatch + EOR.b !CTRL_SHORTCUT_EXACT_MATCH : STA !sram_ctrl_additional_selections,X + + .endExactMatch + %a16() + RTS + + .notAddShortcutText + ; grab the input addresses + ASL : CLC : ADC.w #!sram_ctrl_1_shortcut_inputs : STA !DP_CtrlInput + ADC #$0060 : STA !DP_Ctrl2Input + LDA.w #!sram_ctrl_1_shortcut_inputs>>16 : STA !DP_CtrlInput+2 : STA !DP_Ctrl2Input+2 + + ; enable ctrl mode to edit shortcuts + TDC : STA !ram_cm_ctrl_timer + INC : STA !ram_cm_ctrl_mode + RTS } execute_controller_input: { ; <, > and X should do nothing here ; also ignore input held flag - LDA !ram_cm_controller : BIT #$0341 : BNE .end + LDA !ram_cm_controller : BIT !IH_INPUT_XLEFTRIGHTHELD : BNE .end ; store long address as short address for now LDA [!DP_CurrentMenu] : INC !DP_CurrentMenu : INC !DP_CurrentMenu : INC !DP_CurrentMenu @@ -3254,7 +3443,7 @@ execute_jsl: { ; <, > and X should do nothing here ; also ignore input held flag - LDA !ram_cm_controller : BIT #$0341 : BNE .end + LDA !ram_cm_controller : BIT !IH_INPUT_XLEFTRIGHTHELD : BNE .end ; !DP_JSLTarget = JSL target LDA [!DP_CurrentMenu] : INC !DP_CurrentMenu : INC !DP_CurrentMenu : STA !DP_JSLTarget @@ -3278,7 +3467,7 @@ execute_submenu: { ; <, > and X should do nothing here ; also ignore input held flag - LDA !ram_cm_controller : BIT #$0341 : BNE .end + LDA !ram_cm_controller : BIT !IH_INPUT_XLEFTRIGHTHELD : BNE .end ; !DP_JSLTarget = JSL target LDA [!DP_CurrentMenu] : INC !DP_CurrentMenu : INC !DP_CurrentMenu : STA !DP_JSLTarget @@ -3383,9 +3572,7 @@ else BRA .loadPage3 .done - JSL cm_previous_menu - ; set bank for manual submenu jump - LDA !DP_MenuIndices+2 : STA !ram_cm_menu_bank + JSL cm_go_back_adjacent_submenu JSL action_submenu endif endif diff --git a/src/misc.asm b/src/misc.asm index 11e97130..ba54f507 100644 --- a/src/misc.asm +++ b/src/misc.asm @@ -154,14 +154,6 @@ org $808F24 org $808F65 JML hook_set_music_data -if !FEATURE_PAL -org $82F067 -else -org $82F071 -endif - JSL IconCancelMenu - NOP - org $90D000 ; hijack, runs when a shinespark is activated JMP misc_shinespark_activation @@ -230,18 +222,6 @@ move_kraid_rocks_horizontally: JMP $8930 } -IconCancelMenu: -{ - ; Reset to default menu shortcut if L+R+Sl+X held - LDA !IH_CONTROLLER_PRI : CMP #$2060 : BNE .done - LDA #$3000 : STA !sram_ctrl_menu - - .done - ; overwritten code - LDA !IH_CONTROLLER_PRI_NEW : BIT #$1380 - RTL -} - %endfree(86) diff --git a/src/save.asm b/src/save.asm index cdd540bb..04714d11 100644 --- a/src/save.asm +++ b/src/save.asm @@ -347,9 +347,10 @@ load_return: %ai16() LDA !SRAM_SAVED_SP : TCS - ; rewrite inputs so that holding load won't keep loading, as well as rewriting saving input to loading input - LDA !IH_CONTROLLER_PRI : EOR !sram_ctrl_save_state : ORA !sram_ctrl_load_state - STA !IH_CONTROLLER_PRI : STA !IH_CONTROLLER_PRI_NEW : STA !IH_CONTROLLER_PRI_PREV + ; rewrite inputs so that holding load won't keep loading + TDC : STA !IH_CONTROLLER_PRI : STA !IH_CONTROLLER_SEC + DEC : STA !IH_CONTROLLER_PRI_NEW : STA !IH_CONTROLLER_SEC_NEW + STA !IH_CONTROLLER_PRI_PREV : STA !IH_CONTROLLER_SEC_PREV ; clear frame held counters TDC diff --git a/src/symbols.asm b/src/symbols.asm index ce18adc3..bb7fdc15 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -10,7 +10,16 @@ incsrc wram_symbols.asm ; Work RAM ; --------- -ram_tilemap_buffer = !ram_tilemap_buffer ; $7E5800 +; The crash buffer and initial address can be moved around as needed +; It is currently placed in the back half of the backup of BG2 tilemap during x-ray, +; which means it is unlikely to overwrite anything relevant for debugging + +; Practice hack menu tilemap buffer +ram_tilemap_buffer = !ram_tilemap_buffer ; $7EF500 ; 2048 bytes + +; Shortcut routine is written on boot and each time the menu closes, +; so it can use the same space as the practice hack menu tilemap buffer +; Shortcuts can skip remaining checks by replacing the return address word ; These variables are NOT PERSISTENT across savestates -- ; they're saved and reloaded along with the game state. @@ -174,7 +183,7 @@ ram_watch_edit_lock_left = !ram_watch_edit_lock_left ; !WRAM_PERSIST_START+$4A ram_watch_edit_lock_right = !ram_watch_edit_lock_right ; !WRAM_PERSIST_START+$4C ram_game_loop_extras = !ram_game_loop_extras ; !WRAM_PERSIST_START+$4E -ram_game_mode_extras = !ram_game_mode_extras ; !WRAM_PERSIST_START+$50 +ram_infinite_ammo = !ram_infinite_ammo ; !WRAM_PERSIST_START+$50 ram_suits_heat_damage_value = !ram_suits_heat_damage_value ; !WRAM_PERSIST_START+$52 ram_sprite_feature_flags = !ram_sprite_feature_flags ; !WRAM_PERSIST_START+$54 ram_door_portal_flags = !ram_door_portal_flags ; !WRAM_PERSIST_START+$56 @@ -192,7 +201,6 @@ ram_quickboot_spc_state = !ram_quickboot_spc_state ; !WRAM_PERSIST_START+$6A ram_display_backup = !ram_display_backup ; !WRAM_PERSIST_START+$6C ram_phantoon_always_visible = !ram_phantoon_always_visible ; !WRAM_PERSIST_START+$6E ram_loadstate_rando_enable = !ram_loadstate_rando_enable ; !WRAM_PERSIST_START+$70 -ram_infinite_ammo = !ram_infinite_ammo ; !WRAM_PERSIST_START+$72 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -215,52 +223,47 @@ ram_cm_controller = !ram_cm_controller ; !WRAM_MENU_START+$24 ram_cm_menu_bank = !ram_cm_menu_bank ; !WRAM_MENU_START+$26 ram_cm_horizontal_cursor = !ram_cm_horizontal_cursor ; !WRAM_MENU_START+$28 -ram_cm_etanks = !ram_cm_etanks ; !WRAM_MENU_START+$2A -ram_cm_reserve = !ram_cm_reserve ; !WRAM_MENU_START+$2C -ram_cm_leave = !ram_cm_leave ; !WRAM_MENU_START+$2E -ram_cm_input_counter = !ram_cm_input_counter ; !WRAM_MENU_START+$30 -ram_cm_last_nmi_counter = !ram_cm_last_nmi_counter ; !WRAM_MENU_START+$32 - -ram_cm_ctrl_mode = !ram_cm_ctrl_mode ; !WRAM_MENU_START+$34 -ram_cm_ctrl_timer = !ram_cm_ctrl_timer ; !WRAM_MENU_START+$36 -ram_cm_ctrl_last_input = !ram_cm_ctrl_last_input ; !WRAM_MENU_START+$38 -ram_cm_ctrl_assign = !ram_cm_ctrl_assign ; !WRAM_MENU_START+$3A -ram_cm_ctrl_swap = !ram_cm_ctrl_swap ; !WRAM_MENU_START+$3C - -ram_cm_slowdown_mode = !ram_cm_slowdown_mode ; !WRAM_MENU_START+$3E -ram_cm_slowdown_frames = !ram_cm_slowdown_frames ; !WRAM_MENU_START+$40 - -ram_cm_botwoon_rng = !ram_cm_botwoon_rng ; !WRAM_MENU_START+$42 -ram_cm_botwoon_first = !ram_cm_botwoon_first ; !WRAM_MENU_START+$44 -ram_cm_botwoon_hidden = !ram_cm_botwoon_hidden ; !WRAM_MENU_START+$46 -ram_cm_botwoon_second = !ram_cm_botwoon_second ; !WRAM_MENU_START+$48 -ram_cm_botwoon_spit = !ram_cm_botwoon_spit ; !WRAM_MENU_START+$4A -ram_cm_custom_preset_labels = !ram_cm_custom_preset_labels ; !WRAM_MENU_START+$4C - -ram_seed_X = !ram_seed_X ; !WRAM_MENU_START+$4E -ram_seed_Y = !ram_seed_Y ; !WRAM_MENU_START+$50 - -ram_cm_sfxlib1 = !ram_cm_sfxlib1 ; !WRAM_MENU_START+$52 -ram_cm_sfxlib2 = !ram_cm_sfxlib2 ; !WRAM_MENU_START+$54 -ram_cm_sfxlib3 = !ram_cm_sfxlib3 ; !WRAM_MENU_START+$56 - -ram_cm_fast_scroll_menu_selection = !ram_cm_fast_scroll_menu_selection ; !WRAM_MENU_START+$58 -ram_timers_autoupdate = !ram_timers_autoupdate ; !WRAM_MENU_START+$5A -ram_cm_suit_properties = !ram_cm_suit_properties ; !WRAM_MENU_START+$5C - -ram_cm_palette_border = !ram_cm_palette_border ; !WRAM_MENU_START+$5E -ram_cm_palette_headeroutline = !ram_cm_palette_headeroutline ; !WRAM_MENU_START+$60 -ram_cm_palette_text = !ram_cm_palette_text ; !WRAM_MENU_START+$62 -ram_cm_palette_background = !ram_cm_palette_background ; !WRAM_MENU_START+$64 -ram_cm_palette_numoutline = !ram_cm_palette_numoutline ; !WRAM_MENU_START+$66 -ram_cm_palette_numfill = !ram_cm_palette_numfill ; !WRAM_MENU_START+$68 -ram_cm_palette_toggleon = !ram_cm_palette_toggleon ; !WRAM_MENU_START+$6A -ram_cm_palette_seltext = !ram_cm_palette_seltext ; !WRAM_MENU_START+$6C -ram_cm_palette_seltextbg = !ram_cm_palette_seltextbg ; !WRAM_MENU_START+$6E -ram_cm_palette_numseloutline = !ram_cm_palette_numseloutline ; !WRAM_MENU_START+$70 -ram_cm_palette_numsel = !ram_cm_palette_numsel ; !WRAM_MENU_START+$72 - -ram_cm_gmode = !ram_cm_gmode ; !WRAM_MENU_START+$74 +ram_cm_leave = !ram_cm_leave ; !WRAM_MENU_START+$2A +ram_cm_input_counter = !ram_cm_input_counter ; !WRAM_MENU_START+$2C +ram_cm_last_nmi_counter = !ram_cm_last_nmi_counter ; !WRAM_MENU_START+$2E +ram_cm_ctrl_mode = !ram_cm_ctrl_mode ; !WRAM_MENU_START+$30 +ram_cm_custom_preset_labels = !ram_cm_custom_preset_labels ; !WRAM_MENU_START+$32 + +ram_cm_slowdown_mode = !ram_cm_slowdown_mode ; !WRAM_MENU_START+$34 +ram_cm_slowdown_frames = !ram_cm_slowdown_frames ; !WRAM_MENU_START+$36 + +ram_seed_X = !ram_seed_X ; !WRAM_MENU_START+$38 +ram_seed_Y = !ram_seed_Y ; !WRAM_MENU_START+$3A + +ram_cm_fast_scroll_menu_selection = !ram_cm_fast_scroll_menu_selection ; !WRAM_MENU_START+$3C +ram_cm_suit_properties = !ram_cm_suit_properties ; !WRAM_MENU_START+$3E + +ram_cm_palette_border = !ram_cm_palette_border ; !WRAM_MENU_START+$40 +ram_cm_palette_headeroutline = !ram_cm_palette_headeroutline ; !WRAM_MENU_START+$42 +ram_cm_palette_text = !ram_cm_palette_text ; !WRAM_MENU_START+$44 +ram_cm_palette_background = !ram_cm_palette_background ; !WRAM_MENU_START+$46 +ram_cm_palette_numoutline = !ram_cm_palette_numoutline ; !WRAM_MENU_START+$48 +ram_cm_palette_numfill = !ram_cm_palette_numfill ; !WRAM_MENU_START+$4A +ram_cm_palette_toggleon = !ram_cm_palette_toggleon ; !WRAM_MENU_START+$4C +ram_cm_palette_seltext = !ram_cm_palette_seltext ; !WRAM_MENU_START+$4E +ram_cm_palette_seltextbg = !ram_cm_palette_seltextbg ; !WRAM_MENU_START+$50 +ram_cm_palette_numseloutline = !ram_cm_palette_numseloutline ; !WRAM_MENU_START+$52 +ram_cm_palette_numsel = !ram_cm_palette_numsel ; !WRAM_MENU_START+$54 + +ram_cm_sfxlib1 = !ram_cm_sfxlib1 ; !WRAM_MENU_START+$56 +ram_cm_sfxlib2 = !ram_cm_sfxlib2 ; !WRAM_MENU_START+$58 +ram_cm_sfxlib3 = !ram_cm_sfxlib3 ; !WRAM_MENU_START+$5A + +ram_sram_savestates = !ram_sram_savestates ; !WRAM_MENU_START+$5C + +ram_timers_autoupdate = !ram_timers_autoupdate ; !WRAM_MENU_START+$5E +ram_cm_gmode = !ram_cm_gmode ; !WRAM_MENU_START+$60 + +ram_cm_botwoon_rng = !ram_cm_botwoon_rng ; !WRAM_MENU_START+$62 +ram_cm_botwoon_first = !ram_cm_botwoon_first ; !WRAM_MENU_START+$64 +ram_cm_botwoon_hidden = !ram_cm_botwoon_hidden ; !WRAM_MENU_START+$66 +ram_cm_botwoon_second = !ram_cm_botwoon_second ; !WRAM_MENU_START+$68 +ram_cm_botwoon_spit = !ram_cm_botwoon_spit ; !WRAM_MENU_START+$68 ; ^ FREE SPACE ^ up to +$86 @@ -306,6 +309,8 @@ ram_cm_ice = !ram_cm_ice ; !WRAM_MENU_START+$A4 ram_cm_wave = !ram_cm_wave ; !WRAM_MENU_START+$A6 ram_cm_spazer = !ram_cm_spazer ; !WRAM_MENU_START+$A8 ram_cm_plasma = !ram_cm_plasma ; !WRAM_MENU_START+$AA +ram_cm_etanks = !ram_cm_etanks ; !WRAM_MENU_START+$AC +ram_cm_reserve = !ram_cm_reserve ; !WRAM_MENU_START+$AE ram_cm_zeb1 = !ram_cm_zeb1 ; !WRAM_MENU_START+$90 ram_cm_zeb2 = !ram_cm_zeb2 ; !WRAM_MENU_START+$92 @@ -324,6 +329,13 @@ ram_cm_dummy_num = !ram_cm_dummy_num ; !WRAM_MENU_START+$9E ram_cm_ceres_seconds = !ram_cm_ceres_seconds ; !WRAM_MENU_START+$90 ram_cm_zebes_seconds = !ram_cm_zebes_seconds ; !WRAM_MENU_START+$92 +ram_cm_ctrl_add_shortcut_slot = !ram_cm_ctrl_add_shortcut_slot ; !WRAM_MENU_START+$90 +ram_cm_ctrl_last_pri = !ram_cm_ctrl_last_pri ; !WRAM_MENU_START+$92 +ram_cm_ctrl_last_sec = !ram_cm_ctrl_last_sec ; !WRAM_MENU_START+$94 +ram_cm_ctrl_assign = !ram_cm_ctrl_assign ; !WRAM_MENU_START+$96 +ram_cm_ctrl_swap = !ram_cm_ctrl_swap ; !WRAM_MENU_START+$98 +ram_cm_ctrl_timer = !ram_cm_ctrl_timer ; !WRAM_MENU_START+$9A + ram_cm_crop_mode = !ram_cm_crop_mode ; !WRAM_MENU_START+$90 ram_cm_crop_tile = !ram_cm_crop_tile ; !WRAM_MENU_START+$92 @@ -428,23 +440,8 @@ ram_infidoppler_suby = !ram_infidoppler_suby ; !END_OF_SINGLE_SCROLL_ROOM_LEVEL_ ; ----- sram_initialized = !sram_initialized ; !SRAM_START+$00 - -sram_ctrl_menu = !sram_ctrl_menu ; !SRAM_START+$02 -sram_ctrl_kill_enemies = !sram_ctrl_kill_enemies ; !SRAM_START+$04 -sram_ctrl_full_equipment = !sram_ctrl_full_equipment ; !SRAM_START+$06 -sram_ctrl_reset_segment_timer = !sram_ctrl_reset_segment_timer ; !SRAM_START+$08 -sram_ctrl_reset_segment_later = !sram_ctrl_reset_segment_later ; !SRAM_START+$0A -sram_ctrl_load_state = !sram_ctrl_load_state ; !SRAM_START+$0C -sram_ctrl_save_state = !sram_ctrl_save_state ; !SRAM_START+$0E -sram_ctrl_load_last_preset = !sram_ctrl_load_last_preset ; !SRAM_START+$10 -sram_ctrl_random_preset = !sram_ctrl_random_preset ; !SRAM_START+$12 -sram_ctrl_save_custom_preset = !sram_ctrl_save_custom_preset ; !SRAM_START+$14 -sram_ctrl_load_custom_preset = !sram_ctrl_load_custom_preset ; !SRAM_START+$16 -sram_ctrl_inc_custom_preset = !sram_ctrl_inc_custom_preset ; !SRAM_START+$18 -sram_ctrl_dec_custom_preset = !sram_ctrl_dec_custom_preset ; !SRAM_START+$1A -sram_ctrl_toggle_tileviewer = !sram_ctrl_toggle_tileviewer ; !SRAM_START+$1C -sram_ctrl_update_timers = !sram_ctrl_update_timers ; !SRAM_START+$1E -; More ctrl shortcuts starting at $F0 +sram_ctrl_shortcut_selections = !sram_ctrl_shortcut_selections ; !SRAM_START+$02 ; 30 bytes +; More ctrl shortcut selections starting at $EE sram_artificial_lag = !sram_artificial_lag ; !SRAM_START+$20 sram_rerandomize = !sram_rerandomize ; !SRAM_START+$22 @@ -517,15 +514,10 @@ sram_demo_timer = !sram_demo_timer ; !SRAM_START+$9E sram_ceres_timer = !sram_ceres_timer ; !SRAM_START+$A0 sram_zebes_timer = !sram_zebes_timer ; !SRAM_START+$A2 -; ^ FREE SPACE ^ up to +$EE +; ^ FREE SPACE ^ up to +$EC -sram_ctrl_auto_save_state = !sram_ctrl_auto_save_state ; !SRAM_START+$F0 -sram_ctrl_toggle_spin_lock = !sram_ctrl_toggle_spin_lock ; !SRAM_START+$F2 -sram_ctrl_randomize_rng = !sram_ctrl_randomize_rng ; !SRAM_START+$F4 -sram_ctrl_reveal_damage = !sram_ctrl_reveal_damage ; !SRAM_START+$F6 -sram_ctrl_force_stand = !sram_ctrl_force_stand ; !SRAM_START+$F8 - -; ^ FREE SPACE ^ up to +$FE +; This is a continuation of sram_ctrl_shortcut_selections +sram_ctrl_additional_selections = !sram_ctrl_additional_selections ; !SRAM_START+$D0 ; 18 bytes starting from +$EE sram_presetequiprando = !sram_presetequiprando ; !SRAM_START+$100 sram_presetequiprando_beampref = !sram_presetequiprando_beampref ; !SRAM_START+$102 @@ -541,6 +533,11 @@ sram_loadstate_rando_missiles = !sram_loadstate_rando_missiles ; !SRAM_START+$11 sram_loadstate_rando_supers = !sram_loadstate_rando_supers ; !SRAM_START+$116 sram_loadstate_rando_powerbombs = !sram_loadstate_rando_powerbombs ; !SRAM_START+$118 +; ^ FREE SPACE ^ up to +$13E + +sram_ctrl_1_shortcut_inputs = !sram_ctrl_1_shortcut_inputs ; !SRAM_START+$140 ; 96 bytes +sram_ctrl_2_shortcut_inputs = !sram_ctrl_2_shortcut_inputs ; !SRAM_START+$1A0 ; 96 bytes + ; ^ FREE SPACE ^ up to +$BA6 sram_custom_header_normal = !sram_custom_header_normal ; !SRAM_START+$BA8 ; $18 bytes diff --git a/src/tinystates.asm b/src/tinystates.asm index efa25fc5..a464830f 100644 --- a/src/tinystates.asm +++ b/src/tinystates.asm @@ -407,9 +407,10 @@ load_return: PEA $0000 : PLB : PLB - ; rewrite inputs so that holding load won't keep loading, as well as rewriting saving input to loading input - LDA !IH_CONTROLLER_PRI : EOR !sram_ctrl_save_state : ORA !sram_ctrl_load_state - STA !IH_CONTROLLER_PRI : STA !IH_CONTROLLER_PRI_NEW : STA !IH_CONTROLLER_PRI_PREV + ; rewrite inputs so that holding load won't keep loading + TDC : STA !IH_CONTROLLER_PRI : STA !IH_CONTROLLER_SEC + DEC : STA !IH_CONTROLLER_PRI_NEW : STA !IH_CONTROLLER_SEC_NEW + STA !IH_CONTROLLER_PRI_PREV : STA !IH_CONTROLLER_SEC_PREV ; clear frame held counters TDC From 59d24a10d482f49b3e891bc1efccb86b15026280 Mon Sep 17 00:00:00 2001 From: InsaneFirebat <InsaneFirebat@gmail.com> Date: Tue, 25 Mar 2025 19:52:32 -0400 Subject: [PATCH 03/43] BRB - change custom practice hack message --- src/BRBmenu.asm | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/BRBmenu.asm b/src/BRBmenu.asm index 29ed21c2..47b982f5 100644 --- a/src/BRBmenu.asm +++ b/src/BRBmenu.asm @@ -51,10 +51,10 @@ brb_menu_timer_mode: db #$FF brb_menu_timer_min: - %cm_numfield("Minutes on Timer", !ram_cm_brb_mins, 0, 99, 1, 5, #0) + %cm_numfield("Minutes on Timer", !ram_cm_brb_mins, 0, 99, 1, 2, #0) brb_menu_timer_sec: - %cm_numfield("Seconds on Timer", !ram_cm_brb_secs, 0, 59, 1, 5, #0) + %cm_numfield("Seconds on Timer", !ram_cm_brb_secs, 0, 59, 1, 2, #0) brb_menu_timer_clear: %cm_jsl("Clear Timer", .routine, #0) @@ -481,27 +481,6 @@ BRBTilemapAddress: dw #BRB_screen_06 dw #BRB_screen_07 -BRB_screen_01: - db #$28, " SM Speedrunning Wiki", #$FF - -BRB_screen_02: - db #$28, " SM Speedrunning Discord", #$FF - -BRB_screen_03: - db #$28, "Find the practice hack at", #$FF - -BRB_screen_04: - db #$28, " Control Schemes for SM", #$FF - -BRB_screen_05: - db #$28, "Support FUNtoon on Patreon", #$FF - -BRB_screen_06: - db #$28, " Crazy chain damage clips", #$FF - -BRB_screen_07: - db #$28, " Customized practice hacks", #$FF - BRBTilemapAddress2: dw #BRB_screen2_01 dw #BRB_screen2_02 @@ -511,27 +490,47 @@ BRBTilemapAddress2: dw #BRB_screen2_06 dw #BRB_screen2_07 +BRB_screen_01: + db #$28, " SM Speedrunning Wiki", #$FF BRB_screen2_01: db #$28, " wiki.supermetroid.run", #$FF + +BRB_screen_02: + db #$28, " SM Speedrunning Discord", #$FF BRB_screen2_02: db #$28, " SMDiscord.spazer.link", #$FF + +BRB_screen_03: + db #$28, "Find the practice hack at", #$FF BRB_screen2_03: db #$28, " smpractice.speedga.me", #$FF + +BRB_screen_04: + db #$28, " Control Schemes for SM", #$FF BRB_screen2_04: db #$28, " controls.spazer.link", #$FF + +BRB_screen_05: + db #$28, "Support FUNtoon on Patreon", #$FF BRB_screen2_05: ; !funtoonpatreon db #$28, " ", #$1A, "funtoonpatreon", #$FF + +BRB_screen_06: + db #$28, " Crazy chain damage clips", #$FF BRB_screen2_06: db #$28, " chain.spazer.link", #$FF + +BRB_screen_07: + db #$28, " Learn new SM strats at", #$FF BRB_screen2_07: - db #$28, " by InsaneFirebat", #$FF + db #$28, " crocomi.re", #$FF %endfree(8E) From c00d67e82b950c3b239879ff7808b46bfecd1e79 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Wed, 26 Mar 2025 01:21:16 -0500 Subject: [PATCH 04/43] Fixed bug, improved second controller handling, added splash screen --- src/BRBmenu.asm | 51 ++++++++++++++++++++++++- src/defines.asm | 12 ++++-- src/gamemode.asm | 96 ++++++++++++++++++++++++++++++++++-------------- src/init.asm | 8 +++- src/macros.asm | 2 +- src/mainmenu.asm | 9 +++-- src/menu.asm | 83 ++++++++++++++++++++++++++++++----------- src/symbols.asm | 3 +- 8 files changed, 201 insertions(+), 63 deletions(-) diff --git a/src/BRBmenu.asm b/src/BRBmenu.asm index 47b982f5..55ae9ee1 100644 --- a/src/BRBmenu.asm +++ b/src/BRBmenu.asm @@ -10,6 +10,10 @@ cm_brb_table: ; 1000h bytes transferred incbin ../resources/cm_brb_gfx.bin +%endfree(8E) + + +%startfree(A1) ; -------- ; BRB Menu @@ -182,9 +186,15 @@ cm_brb_loop: cm_draw_brb: { JSL cm_tilemap_bg_interior_long + LDA !ram_sram_detection : BNE .splash_screen JSR cm_tilemap_brb JSL cm_tilemap_transfer_long JMP cm_brb_scroll_BG3 + + .splash_screen + JSR cm_tilemap_splash_screen + JSL cm_tilemap_transfer_long + RTS } cm_tilemap_brb: @@ -287,6 +297,36 @@ cm_tilemap_brb: RTS } +cm_tilemap_splash_screen: +{ + ; Same bank for all of the BRB text + PHK : PHK : PLA : STA !DP_CurrentMenu+2 + + LDA !ram_sram_detection + CMP !SRAM_DETECTION_32KB : BEQ .legacy + CMP !SRAM_DETECTION_128KB : BEQ .tinystates + CMP !SRAM_DETECTION_ZSNES : BEQ .zsnes + BRK + + .legacy + LDA.w #BRB_legacy : STA !DP_CurrentMenu + LDX #$0286 + JSR cm_draw_brb_text + RTS + + .tinystates + LDA.w #BRB_tinystates : STA !DP_CurrentMenu + LDX #$0286 + JSR cm_draw_brb_text + RTS + + .zsnes + LDA.w #BRB_zsnes : STA !DP_CurrentMenu + LDX #$0286 + JSR cm_draw_brb_text + RTS +} + brb_handle_countup_timer: { LDA !ram_cm_brb_frames : INC : STA !ram_cm_brb_frames @@ -470,6 +510,15 @@ table ../resources/header.tbl BRB_common_2: db #$28, " Will Be Right Back", #$FF + +BRB_legacy: +db #$28, " SNES CLASSIC OR VC", #$FF + +BRB_tinystates: +db #$28, " SELECT MODERN EMULATORS", #$FF + +BRB_zsnes: +db #$28, " DO NOT USE ZSNES", #$FF table ../resources/normal.tbl BRBTilemapAddress: @@ -532,5 +581,5 @@ BRB_screen_07: BRB_screen2_07: db #$28, " crocomi.re", #$FF -%endfree(8E) +%endfree(A1) diff --git a/src/defines.asm b/src/defines.asm index b9b4d759..8666a238 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -6,7 +6,7 @@ ; The crash buffer and initial address can be moved around as needed ; It is currently placed in the back half of the backup of BG2 tilemap during x-ray, ; which means it is unlikely to overwrite anything relevant for debugging -!CRASHDUMP_TILEMAP_BUFFER = !ram_tilemap_buffer ; 2048 bytes +!CRASHDUMP_TILEMAP_BUFFER = $7E5800 ; 2048 bytes !CRASH_INITIAL_ADDRESS = #$7E0A44 ; Practice hack menu tilemap buffer @@ -271,9 +271,7 @@ !ram_cm_sfxlib2 = !WRAM_MENU_START+$58 !ram_cm_sfxlib3 = !WRAM_MENU_START+$5A -if !FEATURE_SD2SNES -!ram_sram_savestates = !WRAM_MENU_START+$5C -endif +!ram_sram_detection = !WRAM_MENU_START+$5C !ram_timers_autoupdate = !WRAM_MENU_START+$5E !ram_cm_gmode = !WRAM_MENU_START+$60 @@ -354,6 +352,7 @@ endif !ram_cm_ctrl_assign = !WRAM_MENU_START+$96 !ram_cm_ctrl_swap = !WRAM_MENU_START+$98 !ram_cm_ctrl_timer = !WRAM_MENU_START+$9A +!ram_cm_ctrl_savestates_allowed = !WRAM_MENU_START+$9C !ram_cm_crop_mode = !WRAM_MENU_START+$90 !ram_cm_crop_tile = !WRAM_MENU_START+$92 @@ -1145,6 +1144,11 @@ endif !CTRL_SHORTCUT_TYPE_MASK = #$007F !CTRL_SHORTCUT_EXACT_MATCH = #$0080 +; By default, value is zero and we assume there are no issues +!SRAM_DETECTION_32KB = #$0032 +!SRAM_DETECTION_128KB = #$0128 +!SRAM_DETECTION_ZSNES = #$0505 + !SUIT_PROPERTIES_MASK = #$0007 !SUIT_PROPRETIES_PAL_DEBUG_FLAG = #$0008 diff --git a/src/gamemode.asm b/src/gamemode.asm index 58878054..16fbec5a 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -549,7 +549,7 @@ endif BPL .initialFirstCheckInputs CMP #$01 : BEQ .initialFirstCheckInputs if !FEATURE_SD2SNES - LDA !ram_sram_savestates : BNE .initialFirstCheckInputs + LDA !ram_sram_detection : BEQ .initialFirstCheckInputs endif .initialFirstInvalid TDC : STA !CTRL_SHORTCUT_TABLE,X @@ -593,7 +593,7 @@ endif BPL .initialSecondCheckInputs CMP #$01 : BEQ .initialSecondCheckInputs if !FEATURE_SD2SNES - LDA !ram_sram_savestates : BNE .initialSecondCheckInputs + LDA !ram_sram_detection : BEQ .initialSecondCheckInputs endif .initialSecondInvalid TDC : STA !CTRL_SHORTCUT_TABLE,X @@ -825,7 +825,7 @@ endif LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX ; Determine how much to branch by - PHX : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX + PHX : TDC : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .priWriteMatchClc @@ -888,7 +888,7 @@ endif LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX ; Determine how much to branch by - PHX : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX + PHX : TDC : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .priWriteSpecialClc @@ -1065,7 +1065,7 @@ endif LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX ; Determine how much to branch by - PHX : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX + PHX : TDC : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .secWriteMatchClc @@ -1128,7 +1128,7 @@ endif LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX ; Determine how much to branch by - PHX : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX + PHX : TDC : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .secWriteSpecialClc @@ -1261,7 +1261,7 @@ endif LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX ; Determine how much to branch by - PHX : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX + PHX : TDC : LDA !CTRL_SHORTCUT_TYPE : AND.b !CTRL_SHORTCUT_TYPE_MASK : TAX LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .dualWriteMatchClc @@ -1396,35 +1396,75 @@ cm_condense_ctrl_shortcuts: RTL } -if !FEATURE_SD2SNES -validate_sram_for_savestates: +validate_sram: { + ; check if this is ZSNES + PHP : SEP #$28 + LDA #$FF : CLC : ADC #$FF + CMP #$64 : CLD : BNE .doneZSNES + PLP + LDA !SRAM_DETECTION_ZSNES : STA !ram_sram_detection + JMP .fail + + .doneZSNES + PLP + +if !FEATURE_SD2SNES ; check if required SRAM range is valid ; writes to SRAM will mirror in other banks if not valid -if !FEATURE_TINYSTATES + LDA $707FFE : PHA LDA $737FFE : INC : STA $707FFE - CMP $737FFE : BNE .success -else - LDA $777FFE : INC : STA $707FFE - CMP $777FFE : BNE .success -endif + CMP $737FFE : BNE .first128CheckPass ; double check -if !FEATURE_TINYSTATES + LDA $702FFE : PHA LDA $732FFE : INC : STA $702FFE - CMP $732FFE : BEQ .fail + CMP $732FFE : BNE .second128CheckPass + + ; 128kb check failed + PLA : STA $702FFE + PLA : STA $707FFE + LDA !SRAM_DETECTION_32KB : STA !ram_sram_detection + BRA .fail + + .second128CheckPass + PLA : STA $702FFE + .first128CheckPass + PLA : STA $707FFE + +if !FEATURE_TINYSTATES else - LDA $772FFE : INC : STA $702FFE - CMP $772FFE : BEQ .fail + LDA $737FFE : PHA + LDA $777FFE : INC : STA $737FFE + CMP $777FFE : BNE .first256CheckPass + + ; double check + LDA $732FFE : PHA + LDA $772FFE : INC : STA $732FFE + CMP $772FFE : BNE .second256CheckPass + + ; 256kb check failed + PLA : STA $732FFE + PLA : STA $737FFE + LDA !SRAM_DETECTION_128KB : STA !ram_sram_detection + BRA .fail + + .second256CheckPass + PLA : STA $732FFE + .first256CheckPass + PLA : STA $737FFE +endif endif - .success - LDA #$0001 : STA !ram_sram_savestates + ; success + TDC : STA !ram_sram_detection RTL .fail + LDA !sram_cutscenes : ORA !CUTSCENE_QUICKBOOT : STA !sram_cutscenes +if !FEATURE_SD2SNES ; disable savestate controls - TDC : TAX : STA !ram_sram_savestates + TDC : TAX %a8() .firstLoop LDA !sram_ctrl_shortcut_selections,X : ASL @@ -1440,9 +1480,9 @@ endif INX : CPX #$0030 : BMI .secondLoop .found %a16() +endif RTL } -endif ; ------------------ @@ -1662,19 +1702,19 @@ ctrl_select_shortcut_goto_page3: if !FEATURE_SD2SNES ctrl_add_save_state_dynamic: dw !ACTION_DYNAMIC - dl #!ram_sram_savestates + dl #!ram_cm_ctrl_savestates_allowed dw #$0000 dw #ctrl_add_save_state ctrl_add_load_state_dynamic: dw !ACTION_DYNAMIC - dl #!ram_sram_savestates + dl #!ram_cm_ctrl_savestates_allowed dw #$0000 dw #ctrl_add_load_state ctrl_add_auto_save_state_dynamic: dw !ACTION_DYNAMIC - dl #!ram_sram_savestates + dl #!ram_cm_ctrl_savestates_allowed dw #$0000 dw #ctrl_add_auto_save_state endif @@ -1986,8 +2026,8 @@ endif ctrl_add_shortcut_select: { - LDA !ram_cm_ctrl_add_shortcut_slot : TAX - CMP #$001E : BPL .additional + LDA !ram_cm_ctrl_add_shortcut_slot + TAX : CPX #$001E : BPL .additional TYA : %a8() : STA !sram_ctrl_shortcut_selections,X INX : CPX #$001E : BPL .secondLoop .firstLoop diff --git a/src/init.asm b/src/init.asm index e0247a5f..1b1e43ca 100644 --- a/src/init.asm +++ b/src/init.asm @@ -237,7 +237,7 @@ init_sram_controller_shortcuts: ; Main Menu LDA #$81 : LDX #$0000 : STA !sram_ctrl_shortcut_selections,X if !FEATURE_SD2SNES - LDA !ram_sram_savestates : BEQ .skipTypes + LDA !ram_sram_detection : BNE .skipTypes ; Save State LDA #$82 : INX : STA !sram_ctrl_shortcut_selections,X ; Load State @@ -246,6 +246,8 @@ if !FEATURE_SD2SNES endif ; Reload Preset LDA #$86 : INX : STA !sram_ctrl_shortcut_selections,X + ; Main Menu + LDA #$81 : INX : STA !sram_ctrl_shortcut_selections,X ; Pause LDA #$95 : INX : STA !sram_ctrl_shortcut_selections,X ; Unpause @@ -276,7 +278,7 @@ endif ; Main Menu (Controller 1, Start + Select) LDA #$3000 : LDX #$0000 : STA !sram_ctrl_1_shortcut_inputs,X if !FEATURE_SD2SNES - LDA !ram_sram_savestates : BEQ .skipValues + LDA !ram_sram_detection : BNE .skipValues ; Save State (Controller 1, Select + Y + R) LDA #$6010 : INX #2 : STA !sram_ctrl_1_shortcut_inputs,X ; Load State (Controller 1, Select + Y + L) @@ -285,6 +287,8 @@ if !FEATURE_SD2SNES endif ; Reload Preset (Controller 1, Start + Y + L) LDA #$5020 : INX #2 : STA !sram_ctrl_1_shortcut_inputs,X + ; Main Menu (Controller 2, Start + Select) + LDA #$3000 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X ; Pause (Controller 2, Right) LDA #$0100 : INX #2 : STA !sram_ctrl_2_shortcut_inputs,X ; Unpause (Controller 2, Left) diff --git a/src/macros.asm b/src/macros.asm index 740cd2da..d111766a 100644 --- a/src/macros.asm +++ b/src/macros.asm @@ -523,7 +523,7 @@ endmacro macro SDE_dec(label, address) ; increments or decrements an address based on controller input, used in cm_edit_decimal_digits - LDA !IH_CONTROLLER_PRI : BIT !IH_INPUT_UP : BNE .<label>_inc + LDA !IH_CONTROLLER_PRI : ORA !IH_CONTROLLER_SEC : BIT !IH_INPUT_UP : BNE .<label>_inc ; dec LDA <address> : DEC : BPL .store_<label> LDA #$0009 : BRA .store_<label> diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 16100205..63b4c838 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -89,7 +89,7 @@ action_game_mainmenu: action_ctrlshortcut_mainmenu: { - TDC : TAX + TDC : TAX : STA !ram_cm_ctrl_savestates_allowed %a8() .firstLoop LDA !sram_ctrl_shortcut_selections,X : BEQ .found @@ -100,6 +100,9 @@ action_ctrlshortcut_mainmenu: .found %a16() TXA : STA !ram_cm_ctrl_add_shortcut_slot + + LDA !ram_sram_detection : BNE action_mainmenu + INC : STA !ram_cm_ctrl_savestates_allowed BRA action_mainmenu } @@ -2997,9 +3000,7 @@ init_wram_based_on_sram: JSL RandomizeOnLoad_Flag JSL init_suit_properties_ram JSL init_physics_ram -if !FEATURE_SD2SNES - JSL validate_sram_for_savestates -endif + JSL validate_sram JML init_print_segment_timer } diff --git a/src/menu.asm b/src/menu.asm index 7dacbeca..d9a1a6a0 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -95,6 +95,29 @@ cm_boot: LDA #$04 : STA $212C ; Enable BG3; disable all else %a16() JSR cm_init + LDA !ram_sram_detection : BEQ .skip_splash_screen + + TDC : STA !ram_cm_brb + STA !ram_cm_brb_timer + STA !ram_cm_brb_frames + STA !ram_cm_brb_secs + STA !ram_cm_brb_mins + STA !ram_cm_brb_screen + STA !ram_cm_brb_timer_mode + STA !ram_cm_brb_scroll + STA !ram_cm_brb_scroll_X + STA !ram_cm_brb_scroll_Y + STA !ram_cm_brb_scroll_H + STA !ram_cm_brb_scroll_V + STA !ram_cm_brb_scroll_timer + ; Palette option is initialized to FFFF + DEC : STA !ram_cm_brb_palette + JSL cm_brb_loop + JSL cm_wait_for_lag_frame + JSL cm_transfer_custom_tileset + JSL refresh_cgram_long + + .skip_splash_screen JSL cm_draw JSR cm_loop @@ -1907,31 +1930,31 @@ cm_ctrl_mode: ; set palette %a8() : LDA #$28 : STA !DP_Palette : %a16() - LDA !IH_CONTROLLER_PRI : CMP !ram_cm_ctrl_last_pri : BNE .clear_and_draw - LDA !IH_CONTROLLER_SEC : CMP !ram_cm_ctrl_last_sec : BNE .clear_and_draw + LDA !IH_CONTROLLER_PRI : CMP !ram_cm_ctrl_last_pri : BNE .clearAndDraw + LDA !DP_Ctrl2Input : BEQ .skipInputCtrl2 + LDA !IH_CONTROLLER_SEC : CMP !ram_cm_ctrl_last_sec : BNE .clearAndDraw + .skipInputCtrl2 ; Holding an input for one second LDA !ram_cm_ctrl_timer : INC : STA !ram_cm_ctrl_timer - CMP !FRAMERATE : BNE .next_frame + CMP !FRAMERATE : BNE .nextFrame ; Disallow first Main Menu shortcut to be empty - LDA !IH_CONTROLLER_PRI : ORA !IH_CONTROLLER_SEC : BNE .store - LDA !DP_CtrlInput : CMP.w #!sram_ctrl_1_shortcut_inputs : BNE .store + LDA !DP_Ctrl2Input : BNE .store + LDA !IH_CONTROLLER_PRI : BNE .store ; Store default Main Menu input to SRAM LDA #$3000 : STA [!DP_CtrlInput] - TDC : STA [!DP_Ctrl2Input] - %sfxconfirm() BRA .exit .store ; Store controller input to SRAM LDA !IH_CONTROLLER_PRI : STA [!DP_CtrlInput] + LDA !DP_Ctrl2Input : BEQ .exit LDA !IH_CONTROLLER_SEC : STA [!DP_Ctrl2Input] - %sfxconfirm() BRA .exit - .clear_and_draw + .clearAndDraw TDC : STA !ram_cm_ctrl_timer ; Put text cursor in X @@ -1939,16 +1962,19 @@ cm_ctrl_mode: LDA !ram_cm_cursor_stack,X : ASL #5 : CLC : ADC #$0178 : TAX ; Input display + LDA !DP_Ctrl2Input : BEQ .skipDrawCtrl2 LDA !IH_CONTROLLER_SEC : STA !ram_cm_ctrl_last_sec JSR menu_ctrl_2_input_display + .skipDrawCtrl2 LDA !IH_CONTROLLER_PRI : STA !ram_cm_ctrl_last_pri JSR menu_ctrl_1_input_display JSR cm_tilemap_transfer - .next_frame + .nextFrame RTS .exit + %sfxconfirm() TDC : STA !ram_cm_ctrl_mode JSL cm_draw RTS @@ -2007,7 +2033,7 @@ cm_edit_digits: ; use horizontal cursor index to ADC/SBC LDA !ram_cm_horizontal_cursor : ASL : TAX ; determine which direction was pressed - LDA !IH_CONTROLLER_PRI : BIT !IH_INPUT_UP : BNE .incDecDigit + LDA !IH_CONTROLLER_PRI : ORA !IH_CONTROLLER_SEC : BIT !IH_INPUT_UP : BNE .incDecDigit TXA : CLC : ADC #$0008 : TAX .incDecDigit @@ -2328,7 +2354,7 @@ kb_handle_inputs: BIT !CTRL_B : BNE .input_backspace BIT !CTRL_Y : BNE .input_shift BIT !CTRL_A : BNE .bridge_A - LDA !IH_CONTROLLER_PRI : BIT !CTRL_X : BNE .input_X + LDA !IH_CONTROLLER_PRI : ORA !IH_CONTROLLER_SEC : BIT !CTRL_X : BNE .input_X RTS .bridge_A @@ -2448,7 +2474,7 @@ kb_handle_inputs: LDA #$0001 : STA !DP_KB_Index : STA !ram_cm_controller LDA #$FF28 : STA !ram_cm_keyboard_buffer ; clear previous input to prevent SFX spam - STZ !IH_CONTROLLER_PRI_PREV + STZ !IH_CONTROLLER_PRI_PREV : STZ !IH_CONTROLLER_SEC_PREV %sfxreset() RTS } @@ -2994,7 +3020,8 @@ execute_numfield: LDA !ram_cm_controller : AND !sram_cm_fast_scroll_button : BNE .skip_inc ; check if fast scroll button is held - LDA !IH_CONTROLLER_PRI : AND !sram_cm_fast_scroll_button : BEQ .check_held + LDA !IH_CONTROLLER_PRI : ORA !IH_CONTROLLER_SEC + AND !sram_cm_fast_scroll_button : BEQ .check_held ; grab normal increment multiplied by four and skip past both LDA [!DP_CurrentMenu] : ASL #2 : INC !DP_CurrentMenu : INC !DP_CurrentMenu BRA .store_increment @@ -3076,7 +3103,8 @@ execute_numfield_word: LDA !ram_cm_controller : AND !sram_cm_fast_scroll_button : BNE .skip_inc ; check if fast scroll button is held - LDA !IH_CONTROLLER_PRI : AND !sram_cm_fast_scroll_button : BEQ .check_held + LDA !IH_CONTROLLER_PRI : ORA !IH_CONTROLLER_SEC + AND !sram_cm_fast_scroll_button : BEQ .check_held ; grab normal increment multiplied by four and skip past both LDA [!DP_CurrentMenu] : ASL #2 : INC !DP_CurrentMenu : INC !DP_CurrentMenu INC !DP_CurrentMenu : INC !DP_CurrentMenu @@ -3399,11 +3427,22 @@ execute_ctrl_shortcut: .notAddShortcutText ; grab the input addresses ASL : CLC : ADC.w #!sram_ctrl_1_shortcut_inputs : STA !DP_CtrlInput - ADC #$0060 : STA !DP_Ctrl2Input + CMP #!sram_ctrl_1_shortcut_inputs : BEQ .firstShortcut + CLC : ADC #$0060 : STA !DP_Ctrl2Input LDA.w #!sram_ctrl_1_shortcut_inputs>>16 : STA !DP_CtrlInput+2 : STA !DP_Ctrl2Input+2 ; enable ctrl mode to edit shortcuts - TDC : STA !ram_cm_ctrl_timer + TDC : STA !ram_cm_ctrl_timer : STA !ram_cm_ctrl_last_pri : STA !ram_cm_ctrl_last_sec + INC : STA !ram_cm_ctrl_mode + RTS + + .firstShortcut + ; first shortcut limited to primary inputs only + LDA.w #!sram_ctrl_1_shortcut_inputs>>16 : STA !DP_CtrlInput+2 + TDC : STA !DP_Ctrl2Input : STA !DP_Ctrl2Input+2 + + ; enable ctrl mode to edit shortcuts + STA !ram_cm_ctrl_timer : STA !ram_cm_ctrl_last_pri : STA !ram_cm_ctrl_last_sec INC : STA !ram_cm_ctrl_mode RTS } @@ -3493,8 +3532,8 @@ execute_submenu: execute_custom_preset: { ; check if X or Y newly pressed - LDA !IH_CONTROLLER_PRI_NEW : BIT !CTRL_Y : BNE .toggleDisplay - LDA !IH_CONTROLLER_PRI_NEW : BIT !CTRL_X : BEQ .checkLeftRight + LDA !IH_CONTROLLER_PRI_NEW : ORA !IH_CONTROLLER_SEC_NEW : BIT !CTRL_Y : BNE .toggleDisplay + LDA !IH_CONTROLLER_PRI_NEW : ORA !IH_CONTROLLER_SEC_NEW : BIT !CTRL_X : BEQ .checkLeftRight ; enter keyboard editing mode ; get slot number * 2 in !DP_CtrlInput @@ -3537,7 +3576,7 @@ execute_custom_preset: .checkLeftRight ; change pages if left/right - LDA !IH_CONTROLLER_PRI : BIT !IH_INPUT_LEFTRIGHT : BNE .flipPage + LDA !IH_CONTROLLER_PRI : ORA !IH_CONTROLLER_SEC : BIT !IH_INPUT_LEFTRIGHT : BNE .flipPage ; set preset slot and return to the previous menu LDA [!DP_CurrentMenu] : AND #$00FF : STA !sram_custom_preset_slot @@ -3581,7 +3620,7 @@ endif execute_manage_presets: { - LDA !IH_CONTROLLER_PRI : BIT !IH_INPUT_LEFTRIGHT : BEQ .manageSlots + LDA !IH_CONTROLLER_PRI : ORA !IH_CONTROLLER_SEC : BIT !IH_INPUT_LEFTRIGHT : BEQ .manageSlots if !FEATURE_MAPSTATES ; Mapstates only has one page else @@ -3612,7 +3651,7 @@ endif .manageSlots ; are we deleting (X) or swapping? - LDA !IH_CONTROLLER_PRI_NEW : BIT !CTRL_X : BEQ .swapMode + LDA !IH_CONTROLLER_PRI_NEW : ORA !IH_CONTROLLER_SEC_NEW : BIT !CTRL_X : BEQ .swapMode ; check if preset exists LDA [!DP_CurrentMenu] : AND #$00FF : STA !ram_cm_selected_slot %presetslotsize() diff --git a/src/symbols.asm b/src/symbols.asm index bb7fdc15..99921512 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -254,7 +254,7 @@ ram_cm_sfxlib1 = !ram_cm_sfxlib1 ; !WRAM_MENU_START+$56 ram_cm_sfxlib2 = !ram_cm_sfxlib2 ; !WRAM_MENU_START+$58 ram_cm_sfxlib3 = !ram_cm_sfxlib3 ; !WRAM_MENU_START+$5A -ram_sram_savestates = !ram_sram_savestates ; !WRAM_MENU_START+$5C +ram_sram_detection = !ram_sram_detection ; !WRAM_MENU_START+$5C ram_timers_autoupdate = !ram_timers_autoupdate ; !WRAM_MENU_START+$5E ram_cm_gmode = !ram_cm_gmode ; !WRAM_MENU_START+$60 @@ -335,6 +335,7 @@ ram_cm_ctrl_last_sec = !ram_cm_ctrl_last_sec ; !WRAM_MENU_START+$94 ram_cm_ctrl_assign = !ram_cm_ctrl_assign ; !WRAM_MENU_START+$96 ram_cm_ctrl_swap = !ram_cm_ctrl_swap ; !WRAM_MENU_START+$98 ram_cm_ctrl_timer = !ram_cm_ctrl_timer ; !WRAM_MENU_START+$9A +ram_cm_ctrl_savestates_allowed = !ram_cm_ctrl_savestates_allowed ; !WRAM_MENU_START+$9C ram_cm_crop_mode = !ram_cm_crop_mode ; !WRAM_MENU_START+$90 ram_cm_crop_tile = !ram_cm_crop_tile ; !WRAM_MENU_START+$92 From 9191be30fb42144e75c1a6ddd233451df09efce7 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sat, 29 Mar 2025 11:07:22 -0500 Subject: [PATCH 05/43] Write ctrl shortcut routine if we don't quickboot to main menu --- src/init.asm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/init.asm b/src/init.asm index 1b1e43ca..79d17ae2 100644 --- a/src/init.asm +++ b/src/init.asm @@ -370,6 +370,7 @@ init_post_boot: JML cm_boot .done + JSL cm_write_ctrl_routine JML $82893D ; hijacked code: start main game loop } From 7e3e6ec35e8972a9f99f29d3e1d7fd6f6c9602b8 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sat, 29 Mar 2025 21:44:30 -0500 Subject: [PATCH 06/43] Implement loadstate variance as a separate toggle --- src/defines.asm | 2 +- src/init.asm | 6 ++++++ src/mainmenu.asm | 20 +++++++++----------- src/misc.asm | 13 ------------- src/save.asm | 2 +- src/symbols.asm | 2 +- src/tinystates.asm | 2 +- 7 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index 8666a238..5490424f 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -217,7 +217,6 @@ !ram_quickboot_spc_state = !WRAM_PERSIST_START+$6A !ram_display_backup = !WRAM_PERSIST_START+$6C !ram_phantoon_always_visible = !WRAM_PERSIST_START+$6E -!ram_loadstate_rando_enable = !WRAM_PERSIST_START+$70 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -566,6 +565,7 @@ !sram_loadstate_rando_missiles = !SRAM_START+$114 !sram_loadstate_rando_supers = !SRAM_START+$116 !sram_loadstate_rando_powerbombs = !SRAM_START+$118 +!sram_loadstate_rando_enable = !SRAM_START+$11A ; ^ FREE SPACE ^ up to +$13E diff --git a/src/init.asm b/src/init.asm index 79d17ae2..da4ed320 100644 --- a/src/init.asm +++ b/src/init.asm @@ -209,6 +209,12 @@ endif LDA #$0300 : STA !sram_zebes_timer .upgrade_19to1A + LDA !sram_loadstate_rando_energy + ORA !sram_loadstate_rando_reserves + ORA !sram_loadstate_rando_missiles + ORA !sram_loadstate_rando_supers + ORA !sram_loadstate_rando_powerbombs + STA !sram_loadstate_rando_enable JSL init_sram_controller_shortcuts LDA !SRAM_VERSION : STA !sram_initialized diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 63b4c838..04fbb19c 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -2913,6 +2913,7 @@ SavestateMenu: dw #save_middoorsave dw #save_alwayssave dw #$FFFF + dw #save_rando_enable dw #save_rando_energy dw #save_rando_reserves dw #save_rando_missiles @@ -2944,25 +2945,23 @@ save_delete: %sfxconfirm() RTL +save_rando_enable: + %cm_toggle("Variance on Load State", !sram_loadstate_rando_enable, #$01, #0) + save_rando_energy: - %cm_numfield("Energy Variance", !sram_loadstate_rando_energy, 0, 255, 1, 4, #save_rando_enable) + %cm_numfield("Energy Variance", !sram_loadstate_rando_energy, 0, 255, 1, 4, #0) save_rando_reserves: - %cm_numfield("Reserve Variance", !sram_loadstate_rando_reserves, 0, 255, 1, 4, #save_rando_enable) + %cm_numfield("Reserve Variance", !sram_loadstate_rando_reserves, 0, 255, 1, 4, #0) save_rando_missiles: - %cm_numfield("Missile Variance", !sram_loadstate_rando_missiles, 0, 230, 1, 4, #save_rando_enable) + %cm_numfield("Missile Variance", !sram_loadstate_rando_missiles, 0, 230, 1, 4, #0) save_rando_supers: - %cm_numfield("Super Missile Variance", !sram_loadstate_rando_supers, 0, 50, 1, 2, #save_rando_enable) + %cm_numfield("Super Missile Variance", !sram_loadstate_rando_supers, 0, 50, 1, 2, #0) save_rando_powerbombs: - %cm_numfield("Power Bomb Variance", !sram_loadstate_rando_powerbombs, 0, 50, 1, 2, #save_rando_enable) - -save_rando_enable: -{ - JML RandomizeOnLoad_Flag -} + %cm_numfield("Power Bomb Variance", !sram_loadstate_rando_powerbombs, 0, 50, 1, 2, #0) endif @@ -2997,7 +2996,6 @@ slowdown_frames: init_wram_based_on_sram: { - JSL RandomizeOnLoad_Flag JSL init_suit_properties_ram JSL init_physics_ram JSL validate_sram diff --git a/src/misc.asm b/src/misc.asm index ba54f507..f15f5ef4 100644 --- a/src/misc.asm +++ b/src/misc.asm @@ -606,19 +606,6 @@ RandomizeOnLoad: RTL } -RandomizeOnLoad_Flag: -{ - LDA !sram_loadstate_rando_energy : BNE .enable - LDA !sram_loadstate_rando_reserves : BNE .enable - LDA !sram_loadstate_rando_missiles : BNE .enable - LDA !sram_loadstate_rando_supers : BNE .enable - LDA !sram_loadstate_rando_powerbombs : BNE .enable - - .enable - STA !ram_loadstate_rando_enable - RTL -} - lock_samus_bowling: { LDA !sram_cutscenes : BIT !CUTSCENE_FAST_BOWLING : BNE .speedup diff --git a/src/save.asm b/src/save.asm index 04714d11..beacf1c7 100644 --- a/src/save.asm +++ b/src/save.asm @@ -103,7 +103,7 @@ post_load_state: .randomizeOnLoad ; Randomize energy/ammo? - LDA !ram_loadstate_rando_enable : BEQ .done + LDA !sram_loadstate_rando_enable : BEQ .done JSL RandomizeOnLoad .done diff --git a/src/symbols.asm b/src/symbols.asm index 99921512..cf4e3f8d 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -200,7 +200,6 @@ ram_turret_rng = !ram_turret_rng ; !WRAM_PERSIST_START+$68 ram_quickboot_spc_state = !ram_quickboot_spc_state ; !WRAM_PERSIST_START+$6A ram_display_backup = !ram_display_backup ; !WRAM_PERSIST_START+$6C ram_phantoon_always_visible = !ram_phantoon_always_visible ; !WRAM_PERSIST_START+$6E -ram_loadstate_rando_enable = !ram_loadstate_rando_enable ; !WRAM_PERSIST_START+$70 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -533,6 +532,7 @@ sram_loadstate_rando_reserves = !sram_loadstate_rando_reserves ; !SRAM_START+$11 sram_loadstate_rando_missiles = !sram_loadstate_rando_missiles ; !SRAM_START+$114 sram_loadstate_rando_supers = !sram_loadstate_rando_supers ; !SRAM_START+$116 sram_loadstate_rando_powerbombs = !sram_loadstate_rando_powerbombs ; !SRAM_START+$118 +sram_loadstate_rando_enable = !sram_loadstate_rando_enable ; !SRAM_START+$11A ; ^ FREE SPACE ^ up to +$13E diff --git a/src/tinystates.asm b/src/tinystates.asm index a464830f..23eb1a8a 100644 --- a/src/tinystates.asm +++ b/src/tinystates.asm @@ -142,7 +142,7 @@ post_load_state: .randomizeOnLoad ; Randomize energy/ammo? - LDA !ram_loadstate_rando_enable : BEQ .done + LDA !sram_loadstate_rando_enable : BEQ .done JSL RandomizeOnLoad .done From 8a3bd1f2b406b1e879de5e0180e9cf57f63bcbed Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 30 Mar 2025 23:07:23 -0500 Subject: [PATCH 07/43] Adjust keyboard ram location to avoid conflicts --- src/defines.asm | 24 ++++++++++++------------ src/symbols.asm | 24 ++++++++++++------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index 5490424f..bc7d38ba 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -297,8 +297,6 @@ !ram_cm_watch_enemy_side = !WRAM_MENU_START+$94 !ram_cm_watch_common_address = !WRAM_MENU_START+$96 -!ram_cm_preset_elevator = !WRAM_MENU_START+$90 - !ram_cm_door_dynamic = !WRAM_MENU_START+$90 !ram_cm_door_menu_value = !WRAM_MENU_START+$92 !ram_cm_door_menu_bank = !WRAM_MENU_START+$94 @@ -334,14 +332,6 @@ !ram_cm_zeb4 = !WRAM_MENU_START+$96 !ram_cm_zebmask = !WRAM_MENU_START+$98 -!ram_cm_custompalette_blue = !WRAM_MENU_START+$90 -!ram_cm_custompalette_green = !WRAM_MENU_START+$92 -!ram_cm_custompalette_red = !WRAM_MENU_START+$94 -!ram_cm_custompalette = !WRAM_MENU_START+$96 -!ram_cm_dummy_on = !WRAM_MENU_START+$9A -!ram_cm_dummy_off = !WRAM_MENU_START+$9C -!ram_cm_dummy_num = !WRAM_MENU_START+$9E - !ram_cm_ceres_seconds = !WRAM_MENU_START+$90 !ram_cm_zebes_seconds = !WRAM_MENU_START+$92 @@ -373,10 +363,20 @@ !ram_cm_brb_set_cycle = !WRAM_MENU_START+$AC !ram_cm_brb_cycle_time = !WRAM_MENU_START+$AE -!ram_cm_keyboard_buffer = !WRAM_MENU_START+$90 ; $18 bytes - !ram_cm_manage_slots = !WRAM_MENU_START+$90 !ram_cm_selected_slot = !WRAM_MENU_START+$92 +!ram_cm_preset_elevator = !WRAM_MENU_START+$94 + +; keyboard used by both presets and customize menus +!ram_cm_keyboard_buffer = !WRAM_MENU_START+$98 ; $18 bytes + +!ram_cm_custompalette_blue = !WRAM_MENU_START+$90 +!ram_cm_custompalette_green = !WRAM_MENU_START+$92 +!ram_cm_custompalette_red = !WRAM_MENU_START+$94 +!ram_cm_custompalette = !WRAM_MENU_START+$96 +!ram_cm_dummy_on = !WRAM_MENU_START+$AA +!ram_cm_dummy_off = !WRAM_MENU_START+$AC +!ram_cm_dummy_num = !WRAM_MENU_START+$AE ; ^ FREE SPACE ^ up to +$CE ; Note: +$B8 to +$CE range also used as frames held counters diff --git a/src/symbols.asm b/src/symbols.asm index cf4e3f8d..92fc9cb1 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -280,8 +280,6 @@ ram_cm_watch_enemy_index = !ram_cm_watch_enemy_index ; !WRAM_MENU_START+$92 ram_cm_watch_enemy_side = !ram_cm_watch_enemy_side ; !WRAM_MENU_START+$94 ram_cm_watch_common_address = !ram_cm_watch_common_address ; !WRAM_MENU_START+$96 -ram_cm_preset_elevator = !ram_cm_preset_elevator ; !WRAM_MENU_START+$90 - ram_cm_door_dynamic = !ram_cm_door_dynamic ; !WRAM_MENU_START+$90 ram_cm_door_menu_value = !ram_cm_door_menu_value ; !WRAM_MENU_START+$92 ram_cm_door_menu_bank = !ram_cm_door_menu_bank ; !WRAM_MENU_START+$94 @@ -317,14 +315,6 @@ ram_cm_zeb3 = !ram_cm_zeb3 ; !WRAM_MENU_START+$94 ram_cm_zeb4 = !ram_cm_zeb4 ; !WRAM_MENU_START+$96 ram_cm_zebmask = !ram_cm_zebmask ; !WRAM_MENU_START+$98 -ram_cm_custompalette_blue = !ram_cm_custompalette_blue ; !WRAM_MENU_START+$90 -ram_cm_custompalette_green = !ram_cm_custompalette_green ; !WRAM_MENU_START+$92 -ram_cm_custompalette_red = !ram_cm_custompalette_red ; !WRAM_MENU_START+$94 -ram_cm_custompalette = !ram_cm_custompalette ; !WRAM_MENU_START+$96 -ram_cm_dummy_on = !ram_cm_dummy_on ; !WRAM_MENU_START+$9A -ram_cm_dummy_off = !ram_cm_dummy_off ; !WRAM_MENU_START+$9C -ram_cm_dummy_num = !ram_cm_dummy_num ; !WRAM_MENU_START+$9E - ram_cm_ceres_seconds = !ram_cm_ceres_seconds ; !WRAM_MENU_START+$90 ram_cm_zebes_seconds = !ram_cm_zebes_seconds ; !WRAM_MENU_START+$92 @@ -356,10 +346,20 @@ ram_cm_brb_palette = !ram_cm_brb_palette ; !WRAM_MENU_START+$AA ram_cm_brb_set_cycle = !ram_cm_brb_set_cycle ; !WRAM_MENU_START+$AC ram_cm_brb_cycle_time = !ram_cm_brb_cycle_time ; !WRAM_MENU_START+$AE -ram_cm_keyboard_buffer = !ram_cm_keyboard_buffer ; !WRAM_MENU_START+$90 ; $18 bytes - ram_cm_manage_slots = !ram_cm_manage_slots ; !WRAM_MENU_START+$90 ram_cm_selected_slot = !ram_cm_selected_slot ; !WRAM_MENU_START+$92 +ram_cm_preset_elevator = !ram_cm_preset_elevator ; !WRAM_MENU_START+$94 + +; keyboard used by both presets and customize menus +ram_cm_keyboard_buffer = !ram_cm_keyboard_buffer ; !WRAM_MENU_START+$98 ; $18 bytes + +ram_cm_custompalette_blue = !ram_cm_custompalette_blue ; !WRAM_MENU_START+$90 +ram_cm_custompalette_green = !ram_cm_custompalette_green ; !WRAM_MENU_START+$92 +ram_cm_custompalette_red = !ram_cm_custompalette_red ; !WRAM_MENU_START+$94 +ram_cm_custompalette = !ram_cm_custompalette ; !WRAM_MENU_START+$96 +ram_cm_dummy_on = !ram_cm_dummy_on ; !WRAM_MENU_START+$AA +ram_cm_dummy_off = !ram_cm_dummy_off ; !WRAM_MENU_START+$AC +ram_cm_dummy_num = !ram_cm_dummy_num ; !WRAM_MENU_START+$AE ; ^ FREE SPACE ^ up to +$CE ; Note: +$B8 to +$CE range also used as frames held counters From 784dd4f03b6b3d2a81d16570c210c5d14f389e78 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 30 Mar 2025 23:17:21 -0500 Subject: [PATCH 08/43] Extend spacetime beam protection over ctrl shortcut routine --- src/misc.asm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/misc.asm b/src/misc.asm index f15f5ef4..b3425beb 100644 --- a/src/misc.asm +++ b/src/misc.asm @@ -851,14 +851,14 @@ spacetime_routine: INY #2 INX #2 : CPX #($7EF378-$7EC1C0) : BMI .loop_skip_sprite_object_ram - ; Check if Y will cause us to reach WRAM - TYA : CLC : ADC #(!WRAM_START-$7EF398) : CMP #$0000 : BPL .normal_load_loop + ; Check if Y will cause us to reach CTRL_SHORTCUT_ROUTINE + TYA : CLC : ADC #(!CTRL_SHORTCUT_ROUTINE-$7EF398) : CMP #$0000 : BPL .normal_load_loop ; It will, so run our own loop .loop_before_wram LDA [$00],Y : STA $7EC1C0,X INY #2 - INX #2 : CPX #(!WRAM_START-$7EC1C0) : BMI .loop_before_wram + INX #2 : CPX #(!CTRL_SHORTCUT_ROUTINE-$7EC1C0) : BMI .loop_before_wram ; Skip over WRAM ; Instead of load and store, load and load @@ -874,7 +874,7 @@ spacetime_routine: .overwrite_sprite_object_ram ; Check if Y will cause us to reach WRAM - TYA : CLC : ADC #(!WRAM_START-$7EEF98) : CMP #$0000 : BPL .normal_load_loop + TYA : CLC : ADC #(!CTRL_SHORTCUT_ROUTINE-$7EEF98) : CMP #$0000 : BPL .normal_load_loop BRA .loop_before_wram } endif From 215571bf4580880ea8834a68ab713a2118e9e3d5 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Mon, 31 Mar 2025 00:44:54 -0500 Subject: [PATCH 09/43] Replace hard-coded soft reset with ctrl shortcut --- src/gamemode.asm | 17 ++++++++++++++++- src/infohud.asm | 5 ++++- src/init.asm | 4 ++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/gamemode.asm b/src/gamemode.asm index 16fbec5a..e6eacbae 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -505,8 +505,14 @@ gamemode_decrement_super_hud: } endif +gamemode_soft_reset: +{ + STZ !DISABLE_SOUNDS + JML $808462 +} + ; Write a customized routine based on ctrl shortcut selections -!GAMEMODE_CTRL_SHORTCUT_COUNT = #$001F +!GAMEMODE_CTRL_SHORTCUT_COUNT = #$0020 cm_write_ctrl_routine: { ; No bounds check on X is done as we shouldn't exceed our buffer. @@ -540,6 +546,7 @@ cm_write_ctrl_routine: STA !CTRL_SHORTCUT_TABLE,X : AND.b !CTRL_SHORTCUT_TYPE_MASK BEQ .initialFirstInvalid : CMP.b !GAMEMODE_CTRL_SHORTCUT_COUNT : BPL .initialFirstInvalid if !FEATURE_VANILLAHUD + CMP #$1F : BPL .initialFirstCheckInputs CMP #$19 : BPL .initialFirstInvalid CMP #$12 : BEQ .initialFirstInvalid CMP #$05 : BEQ .initialFirstInvalid @@ -1630,6 +1637,7 @@ ctrl_add_shortcut: CtrlSelectShortcutTypeMenu: dw #ctrl_add_main_menu + dw #ctrl_add_soft_reset if !FEATURE_SD2SNES dw #ctrl_add_save_state_dynamic dw #ctrl_add_load_state_dynamic @@ -1774,6 +1782,7 @@ else dw #ctrl_add_inc_super_hud_dm_text dw #ctrl_add_dec_super_hud_dm_text endif + dw #ctrl_add_soft_reset_dm_text ctrl_shortcut_cancel_gameplay_table: db $00 ; Empty @@ -1807,6 +1816,7 @@ ctrl_shortcut_cancel_gameplay_table: db $00 ; Decrement Room Strat db $00 ; Increment Super HUD db $00 ; Decrement Super HUD + db $01 ; Soft Reset ctrl_shortcut_jsl_word_lsb_table: db #gamemode_placeholder @@ -1863,6 +1873,7 @@ else db #gamemode_increment_super_hud db #gamemode_decrement_super_hud endif + db #gamemode_soft_reset ctrl_shortcut_jsl_word_msb_table: db #gamemode_placeholder>>8 @@ -1919,6 +1930,7 @@ else db #gamemode_increment_super_hud>>8 db #gamemode_decrement_super_hud>>8 endif + db #gamemode_soft_reset>>8 ctrl_add_empty: %cm_jsl("", #ctrl_add_shortcut_select, #$0000) @@ -2024,6 +2036,9 @@ ctrl_add_dec_super_hud: %cm_jsl("Prev Super HUD", #ctrl_add_shortcut_select, #$009E) endif +ctrl_add_soft_reset: + %cm_jsl("Soft Reset", #ctrl_add_shortcut_select, #$009F) + ctrl_add_shortcut_select: { LDA !ram_cm_ctrl_add_shortcut_slot diff --git a/src/infohud.asm b/src/infohud.asm index 604b0bbb..5769a370 100644 --- a/src/infohud.asm +++ b/src/infohud.asm @@ -3,7 +3,10 @@ ; ======================================================= org $809490 - JMP $9497 ; skip resetting player 2 inputs + BRA $05 ; skip resetting player 2 inputs + +org $8094C2 + BRA $10 ; skip hard-coded soft reset shortcut org $8094DF PLP ; patch out resetting of controller 2 buttons and enable debug mode diff --git a/src/init.asm b/src/init.asm index da4ed320..98e1b96c 100644 --- a/src/init.asm +++ b/src/init.asm @@ -242,6 +242,8 @@ init_sram_controller_shortcuts: %a8() ; Main Menu LDA #$81 : LDX #$0000 : STA !sram_ctrl_shortcut_selections,X + ; Soft Reset + LDA #$9F : INX : STA !sram_ctrl_shortcut_selections,X if !FEATURE_SD2SNES LDA !ram_sram_detection : BNE .skipTypes ; Save State @@ -283,6 +285,8 @@ endif %a16() ; Main Menu (Controller 1, Start + Select) LDA #$3000 : LDX #$0000 : STA !sram_ctrl_1_shortcut_inputs,X + ; Soft Reset (Controller 1, Start + Select + L + R) + LDA #$3030 : INX #2 : STA !sram_ctrl_1_shortcut_inputs,X if !FEATURE_SD2SNES LDA !ram_sram_detection : BNE .skipValues ; Save State (Controller 1, Select + Y + R) From cac0e0f61f0f7a21679a1d4f04a130371d3d7bbc Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Mon, 31 Mar 2025 00:46:47 -0500 Subject: [PATCH 10/43] Further refinements for pseudo g-mode --- src/defines.asm | 1 + src/gamemenu.asm | 34 +++++++++++++++++++++++++--------- src/init.asm | 2 ++ src/main.asm | 2 +- src/mainmenu.asm | 15 ++++++++++++++- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index bc7d38ba..a9ab2ca9 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -966,6 +966,7 @@ !PALETTE_FX_INSTRUCTION_POINTER = $1EBD !PALETTE_FX_INSTRUCTION_TIMER = $1ECD !PALETTE_FX_TIMER = $1EDD +!ANIMATED_TILES_ENABLE = $1EF1 !CINEMATIC_FUNCTION_POINTER = $1F51 !DEMO_TIMER = $1F53 !DEMO_CURRENT_SET = $1F55 diff --git a/src/gamemenu.asm b/src/gamemenu.asm index 0a580685..2d542940 100644 --- a/src/gamemenu.asm +++ b/src/gamemenu.asm @@ -219,20 +219,36 @@ game_pacifist: %cm_toggle("Deal Zero Damage", !ram_pacifist, #$01, #0) game_debugplms: - %cm_toggle_bit("Pseudo G-Mode", !ram_cm_gmode, #$0001, #.routine) + %cm_toggle_bit_inverted("Pseudo G-Mode", !ram_cm_gmode, #$8000, #.routine) .routine - CMP #$0000 : BNE .enable - ; disable - LDA #$8000 + LDA !ram_cm_gmode STA !PALETTE_FX_ENABLE STA !PLM_ENABLE STA !ENEMY_PROJ_ENABLE + STA !ANIMATED_TILES_ENABLE + BEQ .xray_hdma +if !FEATURE_PAL + LDA #$E910 : STA !SAMUS_CONTROLLER_HANDLER +else + LDA #$E913 : STA !SAMUS_CONTROLLER_HANDLER +endif RTL - - .enable - STZ !PALETTE_FX_ENABLE - STZ !PLM_ENABLE - STZ !ENEMY_PROJ_ENABLE + .xray_hdma + LDX #$01FE : LDA #$00FF + .xray_loop + STA $7E9800,X + DEX #2 : BPL .xray_loop + LDA #$0001 : STA $0A88 + LDA #$9800 : STA $0A89 + STZ $0A8B + LDA #$98C8 : STA $0A8C + LDA #$0098 : STA $0A8E + LDA #$9990 : STA $0A8F +if !FEATURE_PAL + LDA #$E915 : STA !SAMUS_CONTROLLER_HANDLER +else + LDA #$E918 : STA !SAMUS_CONTROLLER_HANDLER +endif RTL game_debugprojectiles: diff --git a/src/init.asm b/src/init.asm index 98e1b96c..d66f6bd5 100644 --- a/src/init.asm +++ b/src/init.asm @@ -73,6 +73,8 @@ init_nonzero_wram: INC : STA !ram_cm_sfxlib1 STA !ram_cm_sfxlib2 : STA !ram_cm_sfxlib3 + LDA #$8000 : STA !ram_cm_gmode + JML init_wram_based_on_sram } diff --git a/src/main.asm b/src/main.asm index 92a39be3..e5f7033d 100644 --- a/src/main.asm +++ b/src/main.asm @@ -16,7 +16,7 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 6 !VERSION_BUILD = 7 -!VERSION_REV = 7 +!VERSION_REV = 8 table ../resources/normal.tbl print "" diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 04fbb19c..d354c599 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -34,6 +34,19 @@ action_brb_mainmenu: action_game_mainmenu: { + ; Attempt to update g-mode flag + LDA !PALETTE_FX_ENABLE : ORA !PLM_ENABLE + ORA !ENEMY_PROJ_ENABLE : ORA !ANIMATED_TILES_ENABLE + BEQ .set_gmode_flag + LDA !PALETTE_FX_ENABLE : AND !PLM_ENABLE + AND !ENEMY_PROJ_ENABLE : AND !ANIMATED_TILES_ENABLE + BEQ .init_timers + + .set_gmode_flag + ; If all four on or off, set g-mode flag accordingly + STA !ram_cm_gmode + + .init_timers ; Each hexadecimal nibble represents a decimal ; Convert to plain number to allow user to set it @@ -446,7 +459,7 @@ presets_custom_preset_slot: %cm_numfield("Custom Preset Slot", !sram_custom_preset_slot, 0, !TOTAL_PRESET_SLOTS, 1, 2, #.routine) .routine ; ignore if not A, X, or Y - LDA !IH_CONTROLLER_PRI_NEW : BIT #$40C0 : BNE .submenu + LDA !IH_CONTROLLER_PRI_NEW : ORA !IH_CONTROLLER_SEC_NEW : BIT #$40C0 : BNE .submenu LDA !sram_last_preset : BMI .exit TDC : STA !sram_last_preset .exit From d4db69bf063c413d5e75152e2166749d598357a4 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Mon, 31 Mar 2025 23:29:02 -0500 Subject: [PATCH 11/43] Add DEV shortcut --- src/gamemode.asm | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/gamemode.asm b/src/gamemode.asm index e6eacbae..fe1fbb74 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -511,8 +511,16 @@ gamemode_soft_reset: JML $808462 } +if !FEATURE_DEV +gamemode_dev_shortcut: +{ + ; Could put anything here for development purposes + BRK +} +endif + ; Write a customized routine based on ctrl shortcut selections -!GAMEMODE_CTRL_SHORTCUT_COUNT = #$0020 +!GAMEMODE_CTRL_SHORTCUT_COUNT = #$0021 cm_write_ctrl_routine: { ; No bounds check on X is done as we shouldn't exceed our buffer. @@ -1691,6 +1699,9 @@ else dw #ctrl_add_dec_room_strat dw #ctrl_add_inc_super_hud dw #ctrl_add_dec_super_hud +endif +if !FEATURE_DEV + dw #ctrl_add_dev_shortcut endif dw #$FFFF dw #ctrl_select_shortcut_goto_page1 @@ -1783,6 +1794,11 @@ else dw #ctrl_add_dec_super_hud_dm_text endif dw #ctrl_add_soft_reset_dm_text +if !FEATURE_DEV + dw #ctrl_add_dev_shortcut_dm_text +else + dw #ctrl_add_empty_dm_text +endif ctrl_shortcut_cancel_gameplay_table: db $00 ; Empty @@ -1817,6 +1833,7 @@ ctrl_shortcut_cancel_gameplay_table: db $00 ; Increment Super HUD db $00 ; Decrement Super HUD db $01 ; Soft Reset + db $01 ; DEV Shortcut ctrl_shortcut_jsl_word_lsb_table: db #gamemode_placeholder @@ -1874,6 +1891,11 @@ else db #gamemode_decrement_super_hud endif db #gamemode_soft_reset +if !FEATURE_DEV + db #gamemode_dev_shortcut +else + db #gamemode_placeholder +endif ctrl_shortcut_jsl_word_msb_table: db #gamemode_placeholder>>8 @@ -1931,6 +1953,11 @@ else db #gamemode_decrement_super_hud>>8 endif db #gamemode_soft_reset>>8 +if !FEATURE_DEV + db #gamemode_dev_shortcut>>8 +else + db #gamemode_placeholder>>8 +endif ctrl_add_empty: %cm_jsl("", #ctrl_add_shortcut_select, #$0000) @@ -2039,6 +2066,9 @@ endif ctrl_add_soft_reset: %cm_jsl("Soft Reset", #ctrl_add_shortcut_select, #$009F) +ctrl_add_dev_shortcut: + %cm_jsl("DEV Shortcut", #ctrl_add_shortcut_select, #$0020) + ctrl_add_shortcut_select: { LDA !ram_cm_ctrl_add_shortcut_slot From 71f0a116153668a1a7e049744a458d3b969e83fe Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Mon, 31 Mar 2025 23:55:00 -0500 Subject: [PATCH 12/43] Fix slow unpause issue caused by save state changing the bank --- src/gamemode.asm | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gamemode.asm b/src/gamemode.asm index fe1fbb74..a3628500 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -185,19 +185,24 @@ if !FEATURE_TINYSTATES .save endif PHP + PHB JSL save_state + PLB PLP + + ; Skip remaining shortcuts + PLA : PEA !CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE RTL } gamemode_load_state: { - ; check if a saved state exists + ; Check if a saved state exists LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .not_available - JSL load_state - ; Skip remaining shortcuts - PLA : PEA !CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE + ; We will not return from this method, + ; since loading the state includes loading the stack + JML load_state .not_available RTL From 532c46777e03b5ae6ca9a327e62ab00a2ff83820 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Tue, 1 Apr 2025 00:02:28 -0500 Subject: [PATCH 13/43] Revert unhelpful refinements to pseudo g-mode --- src/gamemenu.asm | 23 ----------------------- src/main.asm | 2 +- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/src/gamemenu.asm b/src/gamemenu.asm index 2d542940..e9a7a2ab 100644 --- a/src/gamemenu.asm +++ b/src/gamemenu.asm @@ -226,29 +226,6 @@ game_debugplms: STA !PLM_ENABLE STA !ENEMY_PROJ_ENABLE STA !ANIMATED_TILES_ENABLE - BEQ .xray_hdma -if !FEATURE_PAL - LDA #$E910 : STA !SAMUS_CONTROLLER_HANDLER -else - LDA #$E913 : STA !SAMUS_CONTROLLER_HANDLER -endif - RTL - .xray_hdma - LDX #$01FE : LDA #$00FF - .xray_loop - STA $7E9800,X - DEX #2 : BPL .xray_loop - LDA #$0001 : STA $0A88 - LDA #$9800 : STA $0A89 - STZ $0A8B - LDA #$98C8 : STA $0A8C - LDA #$0098 : STA $0A8E - LDA #$9990 : STA $0A8F -if !FEATURE_PAL - LDA #$E915 : STA !SAMUS_CONTROLLER_HANDLER -else - LDA #$E918 : STA !SAMUS_CONTROLLER_HANDLER -endif RTL game_debugprojectiles: diff --git a/src/main.asm b/src/main.asm index e5f7033d..73c347f8 100644 --- a/src/main.asm +++ b/src/main.asm @@ -16,7 +16,7 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 6 !VERSION_BUILD = 7 -!VERSION_REV = 8 +!VERSION_REV = 9 table ../resources/normal.tbl print "" From 75f590d14f85eff4817463238dd4ab151fc9eac7 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Tue, 1 Apr 2025 00:21:16 -0500 Subject: [PATCH 14/43] Fix hitboxes for frozen enemies with extended spritemaps --- src/defines.asm | 1 + src/spritefeat.asm | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index a9ab2ca9..cbfc825e 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -922,6 +922,7 @@ !ENEMY_TIMER = $0F90 !ENEMY_INIT_PARAM = $0F92 !ENEMY_PALETTE_INDEX = $0F96 +!ENEMY_FROZEN_TIMER = $0F9E !ENEMY_BANK = $0FA6 !ENEMY_FUNCTION_POINTER = $0FA8 !ENEMY_VAR_1 = $0FAA diff --git a/src/spritefeat.asm b/src/spritefeat.asm index bbff2bf4..195dc1e5 100644 --- a/src/spritefeat.asm +++ b/src/spritefeat.asm @@ -353,10 +353,13 @@ draw_enemy_hitbox: LDY !OAM_STACK_POINTER ; Y = OAM stack pointer .loopEnemies - ; skip enemy if extended spritemap or deleted enemy - LDA !ENEMY_EXTRA_PROPERTIES,X : AND #$0004 : BNE .skipEnemy + ; skip enemy if deleted LDA !ENEMY_PROPERTIES,X : AND #$0200 : BNE .skipEnemy + ; skip enemy if extended spritemap and not frozen + LDA !ENEMY_FROZEN_TIMER,X : BNE .checkOffscreen + LDA !ENEMY_EXTRA_PROPERTIES,X : AND #$0004 : BNE .skipEnemy + .checkOffscreen ; skip enemy if off-screen LDA !ENEMY_X,X : CLC : ADC !ENEMY_X_RADIUS,X CMP !LAYER1_X : BMI .skipEnemy @@ -425,7 +428,10 @@ draw_ext_spritemap_hitbox: LDY !OAM_STACK_POINTER ; Y = OAM stack pointer .loopEnemies - ; check if extended spritemap + ; skip enemy if deleted + LDA !ENEMY_PROPERTIES,X : AND #$0200 : BNE .nextEnemy + ; check if extended spritemap and not frozen + LDA !ENEMY_FROZEN_TIMER,X : BNE .nextEnemy LDA !ENEMY_EXTRA_PROPERTIES,X : AND #$0004 : BNE .extended .nextEnemy From f0cbbb67f321f47b2f954fbce7c594f8957a4665 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 6 Apr 2025 20:11:31 -0500 Subject: [PATCH 15/43] Improved integration of InfoHUD options and the Super HUD --- src/defines.asm | 11 +- src/gamemode.asm | 34 ++++- src/infohud.asm | 120 ++++++++++++++---- src/infohudmodes.asm | 287 ++++++++++++++++++++++++++++++++++++++++++- src/layout.asm | 10 +- src/main.asm | 2 +- src/mainmenu.asm | 156 ++++++++++++++++------- src/menu.asm | 2 + src/ramwatchmenu.asm | 23 ++-- src/spritefeat.asm | 4 +- src/symbols.asm | 11 +- 11 files changed, 555 insertions(+), 105 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index cbfc825e..a8096640 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -87,12 +87,12 @@ !ram_room_has_set_rng = !WRAM_START+$42 !ram_HUD_top = !WRAM_START+$44 !ram_HUD_middle = !WRAM_START+$46 -!ram_HUD_check = !WRAM_START+$48 +!ram_infidoppler_active = !WRAM_START+$48 !ram_roomstrat_counter = !WRAM_START+$4A !ram_roomstrat_state = !WRAM_START+$4C !ram_enemy_hp = !WRAM_START+$4E -!ram_mb_hp = !WRAM_START+$50 -!ram_shot_timer = !WRAM_START+$52 +!ram_HUD_top_counter = !WRAM_START+$50 +!ram_HUD_middle_counter = !WRAM_START+$52 !ram_shine_counter = !WRAM_START+$54 !ram_dash_counter = !WRAM_START+$56 @@ -102,7 +102,6 @@ !ram_activated_shine_duration = !WRAM_START+$5E !ram_watch_left_hud = !WRAM_START+$60 !ram_watch_right_hud = !WRAM_START+$62 -!ram_infidoppler_active = !WRAM_START+$64 ; ^ FREE SPACE ^ up to +$6C @@ -115,8 +114,8 @@ !ram_xpos = !WRAM_START+$6E !ram_ypos = !WRAM_START+$70 !ram_subpixel_pos = !WRAM_START+$72 -!ram_HUD_top_counter = !WRAM_START+$74 -!ram_HUD_middle_counter = !WRAM_START+$76 +!ram_HUD_check = !WRAM_START+$74 +!ram_shot_timer = !WRAM_START+$76 !ram_quickdrop_counter = !WRAM_START+$78 !ram_walljump_counter = !WRAM_START+$7A !ram_fail_sum = !WRAM_START+$7C diff --git a/src/gamemode.asm b/src/gamemode.asm index a3628500..65f1e740 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -377,19 +377,41 @@ if !FEATURE_VANILLAHUD else gamemode_reveal_damage: { - LDA !sram_display_mode : CMP !IH_MODE_COUNTDAMAGE_INDEX : BEQ .unreveal + LDA !sram_display_mode : CMP !IH_MODE_ROOMSTRAT_INDEX : BEQ .checkRoomStrat + CMP !IH_MODE_COUNTDAMAGE_INDEX : BNE .reveal + ; revert to prior mode + LDA !ram_display_backup : STA !sram_display_mode + %sfxreset() + JML init_print_segment_timer + + .revealRoomStrat + LDA !sram_display_mode + .reveal STA !ram_display_backup LDA !IH_MODE_COUNTDAMAGE_INDEX : STA !sram_display_mode ; set ram_HUD_check to some value that cannot match the damage counter ; conveniently the current value of A will work STA !ram_HUD_check %sfxconfirm() - RTL - - .unreveal - LDA !ram_display_backup : STA !sram_display_mode + JML init_print_segment_timer + + .checkRoomStrat + LDA !sram_room_strat : BNE .revealRoomStrat + ; handle Super HUD case + LDA !sram_superhud_bottom : CMP !IH_SUPERHUD_COUNTDAMAGE_BOTTOM_INDEX : BNE .revealSuperHUD + ; revert to prior Super HUD mode + LDA !ram_display_backup : STA !sram_superhud_bottom %sfxreset() - RTL + JML init_print_segment_timer + + .revealSuperHUD + STA !ram_display_backup + LDA !IH_SUPERHUD_COUNTDAMAGE_BOTTOM_INDEX : STA !sram_superhud_bottom + ; set ram_HUD_check to some value that cannot match the damage counter + ; conveniently the current value of A will work + STA !ram_HUD_check + %sfxconfirm() + JML init_print_segment_timer } endif diff --git a/src/infohud.asm b/src/infohud.asm index 5769a370..60334949 100644 --- a/src/infohud.asm +++ b/src/infohud.asm @@ -259,7 +259,11 @@ ih_get_item_code: PLY if !FEATURE_VANILLAHUD else + ; assume we are about to collect an item + ; adding an extra beam will increase item % by one + LDA !SAMUS_BEAMS_COLLECTED : PHA : ORA #$0010 : STA !SAMUS_BEAMS_COLLECTED JSL ih_update_hud_code + PLA : STA !SAMUS_BEAMS_COLLECTED endif JSL init_heat_damage_ram JSL init_physics_ram @@ -412,17 +416,24 @@ ih_after_room_transition: ; Check if MBHP needs to be disabled LDA !sram_display_mode : CMP !IH_MODE_ROOMSTRAT_INDEX : BNE .segmentTimer - LDA !sram_room_strat : CMP !IH_STRAT_MBHP_INDEX : BNE .segmentTimer + LDA !sram_room_strat : BEQ .checkSuperHUD + CMP !IH_STRAT_MBHP_INDEX : BNE .segmentTimer LDA !ROOM_ID : CMP.w #ROOM_MotherBrainRoom : BEQ .segmentTimer TDC : STA !sram_display_mode + BRA .segmentTimer + + .checkSuperHUD + LDA !sram_superhud_bottom : CMP !IH_SUPERHUD_MBHP_BOTTOM_INDEX : BNE .segmentTimer + LDA !ROOM_ID : CMP.w #ROOM_MotherBrainRoom : BEQ .segmentTimer + TDC : STA !sram_superhud_bottom .segmentTimer - LDA !ram_reset_segment_later : AND #$0001 : BEQ .updateHud + LDA !ram_reset_segment_later : AND #$0001 : BEQ .updateHUD TDC : STA !ram_reset_segment_later : STA !ram_lag_counter STA !ram_seg_rt_frames : STA !ram_seg_rt_seconds : STA !ram_seg_rt_minutes - .updateHud - JSL ih_update_hud_code + .updateHUD + JSL ih_update_hud_after_transition ; Reset realtime and gametime/transition timers TDC : STA !ram_realtime_room : STA !ram_transition_counter @@ -491,6 +502,11 @@ ih_before_room_transition: LDX #$00C2 LDA !sram_top_display_mode : BIT.b !TOP_HUD_VANILLA_BIT : BNE .vanillaDoorLag LDA !ram_minimap : BEQ .draw3 + LDA !sram_display_mode : CMP.b !IH_MODE_ROOMSTRAT_INDEX : BNE .drawDoorMM + LDA !sram_room_strat : BNE .drawDoorMM + %a16() + BRA .done + .drawDoorMM LDX #$0054 .draw3 TYA : JSR Draw3 @@ -701,16 +717,53 @@ ih_update_hud_before_transition: ; Bank 80 PEA $8080 : PLB : PLB - LDA !sram_display_mode : CMP !IH_MODE_ARMPUMP_INDEX : BNE .start + LDA !sram_display_mode : CMP !IH_MODE_ARMPUMP_INDEX : BNE ih_update_hud_after_transition_start ; Report armpump room totals + .armpump LDA !ram_momentum_sum : CLC : ADC !ram_momentum_count : LDX #$0088 : JSR Draw4 LDA !ram_fail_sum : CLC : ADC !ram_fail_count : LDX #$0092 : JSR Draw4 TDC : STA !ram_momentum_count : STA !ram_fail_count STA !ram_momentum_sum : STA !ram_fail_sum : STA !ram_roomstrat_counter + BRA ih_update_hud_code_start +} + +ih_update_hud_after_transition: +{ + PHX : PHY : PHP : PHB + ; Bank 80 + PEA $8080 : PLB : PLB .start - BRA ih_update_hud_code_start + LDA !sram_display_mode : CMP !IH_MODE_ROOMSTRAT_INDEX : BNE ih_update_hud_code_start + LDA !sram_room_strat : BNE ih_update_hud_code_start + + ; Update Super HUD lag counters + LDA !sram_superhud_top : CMP !IH_SUPERHUD_LAG_COUNTER_TOP_INDEX : BNE .middleHUD + LDA !sram_lag_counter_mode : BNE .topFullTime + LDA !ram_last_door_lag_frames + BRA .topDrawTime + .topFullTime + LDA !ram_last_realtime_door + .topDrawTime + LDX #$0014 : JSR Draw3 + TDC : STA !ram_HUD_top + + .middleHUD + LDA !sram_superhud_middle : CMP !IH_SUPERHUD_LAG_COUNTER_MIDDLE_INDEX : BNE .bottomHUD + LDA !sram_lag_counter_mode : BNE .middleFullTime + LDA !ram_last_door_lag_frames + BRA .middleDrawTime + .middleFullTime + LDA !ram_last_realtime_door + .middleDrawTime + LDX #$0054 : JSR Draw3 + TDC : STA !ram_HUD_middle + + ; Check armpump + .bottomHUD + LDA !sram_superhud_bottom : CMP !IH_SUPERHUD_ARMPUMP_BOTTOM_INDEX : BNE ih_update_hud_code_start + JMP ih_update_hud_before_transition_armpump } ih_update_hud_code: @@ -720,15 +773,19 @@ ih_update_hud_code: PEA $8080 : PLB : PLB .start - LDA !ram_minimap : BNE .mmHud + LDA !ram_minimap : BNE .mmHUD JMP .startUpdate .mmVanilla JMP .end - .mmHud + .mmHUD ; Map visible, so draw map counter over item% LDA !sram_top_display_mode : BIT !TOP_HUD_VANILLA_BIT : BNE .mmVanilla + LDA !sram_display_mode : CMP !IH_MODE_ROOMSTRAT_INDEX : BNE .mmTileCounter + LDA !sram_room_strat : BEQ .mmRoomTimer + + .mmTileCounter LDA !MAP_COUNTER : LDX #$0014 : JSR Draw3 LDA !ram_print_segment_timer : BEQ .mmRoomTimer @@ -761,6 +818,7 @@ ih_update_hud_code: LDA $C1 : ASL : TAX LDA HexToNumberGFX1,X : STA !HUD_TILEMAP+$B6 LDA HexToNumberGFX2,X : STA !HUD_TILEMAP+$B8 + LDA !IH_BLANK : STA !HUD_TILEMAP+$AE : STA !HUD_TILEMAP+$BA JMP .end .startUpdate @@ -795,16 +853,18 @@ ih_update_hud_code: ; 3 tiles between input display and missile icon ; skip item% if display mode = vspeed - LDA !sram_display_mode : CMP !IH_MODE_VSPEED_INDEX : BEQ .skipToLag LDA !sram_top_display_mode : BNE .skipToLag + LDA !sram_display_mode : CMP !IH_MODE_VSPEED_INDEX : BEQ .skipToLag + CMP !IH_MODE_ROOMSTRAT_INDEX : BNE .drawItemPercent + LDA !sram_room_strat : BEQ .skipToLag - ; Draw Item percent + .drawItemPercent ; Max HP and Reserves LDA !SAMUS_HP_MAX : CLC : ADC !SAMUS_RESERVE_MAX JSR CalcEtank : STA $C1 - ; Max Missiles, Supers & Power Bombs - LDA !SAMUS_MISSILES_MAX : CLC : ADC !SAMUS_SUPERS_MAX : CLC : ADC !SAMUS_PBS_MAX + ; Max Missiles, Supers and Power Bombs + LDA !SAMUS_MISSILES_MAX : CLC : ADC !SAMUS_SUPERS_MAX : ADC !SAMUS_PBS_MAX JSR CalcItem : CLC : ADC $C1 : STA $C1 ; Collected items @@ -931,17 +991,17 @@ ih_hud_vanilla_health: %a16() PEA $0000 : PLA ; wait for CPU math LDA $4214 : STA $14 - LDA $4216 : STA $12 + LDA $4216 : PHA LDA !SAMUS_HP_MAX : STA $4204 %a8() LDA #$64 : STA $4206 %a16() PEA $0000 : PLA ; wait for CPU math LDY #$0000 : LDA $4214 - INC : STA $16 + INC : STA $12 .loopTanks - DEC $16 : BEQ .drawEmptyTanks + DEC $12 : BEQ .drawEmptyTanks LDX #$3430 LDA $14 : BEQ .drawTankHealth DEC $14 : LDX #$2831 @@ -958,8 +1018,8 @@ ih_hud_vanilla_health: INY #2 : CPY #$001C : BMI .loopEmptyTanks .subtankHealth - LDA $12 : LDX #$0094 : JSR Draw2 - LDA $16 : BNE .subtankWhitespace + PLA : LDX #$0094 : JSR Draw2 + LDA $12 : BNE .subtankWhitespace ; Draw the leading zero LDA.w NumberGFXTable : STA !HUD_TILEMAP+$94 @@ -1086,7 +1146,11 @@ endif .reserves LDA !sram_top_display_mode : BEQ .statusIcons BIT !TOP_HUD_VANILLA_BIT : BNE .vanilla_check_health + LDA !sram_display_mode : CMP !IH_MODE_ROOMSTRAT_INDEX : BNE .checkReserves + LDA !sram_room_strat : BNE .checkReserves + RTL + .checkReserves LDA !SAMUS_RESERVE_MAX : BEQ .noReserves LDA !SAMUS_RESERVE_ENERGY : CMP !ram_reserves_last : BEQ .checkAuto STA !ram_reserves_last : LDX #$0014 : JSR Draw3 @@ -1099,11 +1163,11 @@ endif .autoOn LDA !SAMUS_RESERVE_ENERGY : BEQ .autoEmpty LDA !IH_RESERVE_AUTO : STA !HUD_TILEMAP+$1A - BRA .statusIcons + BRA .reservesStatusIcons .autoEmpty LDA !IH_RESERVE_EMPTY : STA !HUD_TILEMAP+$1A - BRA .statusIcons + BRA .reservesStatusIcons .noReserves LDA !IH_BLANK @@ -1111,6 +1175,10 @@ endif STA !HUD_TILEMAP+$18 : STA !HUD_TILEMAP+$1A ; Status Icons + .reservesStatusIcons + LDA !sram_status_icons : BNE .checkHealthBomb + RTL + .statusIcons LDA !sram_status_icons : BNE .checkSuperHUD RTL @@ -1148,25 +1216,25 @@ endif .checkSpark LDA !SAMUS_SHINE_TIMER : BEQ .clearSpark LDA !IH_SHINESPARK : STA !HUD_TILEMAP+$58 - BRA .checkReserves + BRA .checkReserveIcon .clearSpark LDA !IH_BLANK : STA !HUD_TILEMAP+$58 ; reserve tank - .checkReserves - LDA !SAMUS_RESERVE_MODE : CMP #$0001 : BNE .clearReserve + .checkReserveIcon + LDA !SAMUS_RESERVE_MODE : CMP #$0001 : BNE .clearReserveIcon LDA !SAMUS_RESERVE_ENERGY : BEQ .empty - LDA !SAMUS_RESERVE_MAX : BEQ .clearReserve + LDA !SAMUS_RESERVE_MAX : BEQ .clearReserveIcon LDA !IH_RESERVE_AUTO : STA !HUD_TILEMAP+$1A RTL .empty - LDA !SAMUS_RESERVE_MAX : BEQ .clearReserve + LDA !SAMUS_RESERVE_MAX : BEQ .clearReserveIcon LDA !IH_RESERVE_EMPTY : STA !HUD_TILEMAP+$1A RTL - .clearReserve + .clearReserveIcon LDA !IH_BLANK : STA !HUD_TILEMAP+$1A .end @@ -1613,7 +1681,7 @@ ih_update_status: STA !ram_armed_shine_duration STA !ram_fail_count : STA !ram_fail_sum INC - STA !ram_enemy_hp : STA !ram_mb_hp + STA !ram_enemy_hp STA !ram_dash_counter : STA !ram_shine_counter STA !ram_xpos : STA !ram_ypos : STA !ram_subpixel_pos LDA !ram_seed_X : LSR diff --git a/src/infohudmodes.asm b/src/infohudmodes.asm index a619ce19..87bf8188 100644 --- a/src/infohudmodes.asm +++ b/src/infohudmodes.asm @@ -181,7 +181,7 @@ else endif ; Suppress Samus HP display - ; The segment timer is also suppressed elsewhere just for shinetune + ; The segment timer is also suppressed elsewhere LDA !SAMUS_HP : STA !ram_last_hp ; Track Samus momentum @@ -206,6 +206,9 @@ endif BRA .shinetune_start .average_momentum + ; Do not print out momentum if Super HUD is enabled + LDA !sram_room_strat : BEQ .invalid_momentum + ; We have total momentum (x256) over 44 frames ; To get the average (x1024), divide by 11 LDA !ram_momentum_sum @@ -217,7 +220,7 @@ endif LDA $4214 : LDX #$0054 : JSR Draw4Hundredths .invalid_momentum - LDA #$FFFF : STA !ram_momentum_count + TDC : DEC : STA !ram_momentum_count BRA .shinetune_start .wait_for_stop @@ -989,6 +992,7 @@ status_quickdrop: status_walljump: { ; Suppress Samus HP display + ; The segment timer is also suppressed elsewhere LDA !SAMUS_HP : STA !ram_last_hp ; Check if it is time to calculate average climb speed @@ -1558,6 +1562,7 @@ superhud_bottom_table: dw status_cooldown dw status_shinetimer dw status_dashcounter + dw status_shinetune dw status_iframecounter dw status_spikesuit dw status_lagcounter @@ -1578,6 +1583,7 @@ superhud_bottom_table: dw status_tacotank dw status_pitdoor dw status_moondance + dw status_kraidradar dw status_gateglitch dw status_moatcwj dw status_robotflush @@ -1588,6 +1594,7 @@ superhud_bottom_table: dw status_snailclip dw status_wasteland dw status_ridleyai + dw status_kihuntermanip dw status_downbackzeb dw status_zebskip dw status_mbhp @@ -1605,6 +1612,10 @@ superhud_middle_table: dw middleHUD_cpuusage dw middleHUD_hspeed dw middleHUD_shottimer + dw middleHUD_itempercent + dw middleHUD_reserves + dw middleHUD_statusicons + dw middleHUD_tilecounter superhud_top_table: dw status_enemyhp_done @@ -1618,6 +1629,10 @@ superhud_top_table: dw topHUD_cpuusage dw topHUD_hspeed dw topHUD_shottimer + dw topHUD_itempercent + dw topHUD_reserves + dw topHUD_statusicons + dw topHUD_tilecounter middleHUD_chargetimer: { @@ -1959,6 +1974,272 @@ topHUD_shottimer: RTS } +middleHUD_itempercent: +{ + LDA !SAMUS_BEAMS_COLLECTED : CLC : ADC !SAMUS_HP_MAX : ADC !SAMUS_RESERVE_MAX + ADC !SAMUS_MISSILES_MAX : ADC !SAMUS_SUPERS_MAX : ADC !SAMUS_PBS_MAX + CMP !ram_HUD_middle_counter : BEQ .checkMajors + STA !ram_HUD_middle_counter : LDA !SAMUS_ITEMS_COLLECTED + BRA .calculate + + .checkMajors + LDA !SAMUS_ITEMS_COLLECTED : CMP !ram_HUD_middle : BEQ .done + + .calculate + STA !ram_HUD_middle + + ; Max HP and Reserves + LDA !SAMUS_HP_MAX : CLC : ADC !SAMUS_RESERVE_MAX + JSR CalcEtank : STA $C1 + + ; Max Missiles, Supers and Power Bombs + LDA !SAMUS_MISSILES_MAX : CLC : ADC !SAMUS_SUPERS_MAX : ADC !SAMUS_PBS_MAX + JSR CalcItem : CLC : ADC $C1 : STA $C1 + + ; Collected items + JSR CalcLargeItem : CLC : ADC $C1 : STA $C1 + + ; Collected beams and charge + JSR CalcBeams : CLC : ADC $C1 + + ; Percent counter -> decimal form and drawn on HUD + LDX #$0052 : JSR Draw3 + LDA !IH_PERCENT : STA !HUD_TILEMAP+$58 + + .done + RTS +} + +topHUD_itempercent: +{ + LDA !SAMUS_BEAMS_COLLECTED : CLC : ADC !SAMUS_HP_MAX : ADC !SAMUS_RESERVE_MAX + ADC !SAMUS_MISSILES_MAX : ADC !SAMUS_SUPERS_MAX : ADC !SAMUS_PBS_MAX + CMP !ram_HUD_top_counter : BEQ .checkMajors + STA !ram_HUD_top_counter : LDA !SAMUS_ITEMS_COLLECTED + BRA .calculate + + .checkMajors + LDA !SAMUS_ITEMS_COLLECTED : CMP !ram_HUD_top : BEQ .done + + .calculate + STA !ram_HUD_top + + ; Max HP and Reserves + LDA !SAMUS_HP_MAX : CLC : ADC !SAMUS_RESERVE_MAX + JSR CalcEtank : STA $C1 + + ; Max Missiles, Supers and Power Bombs + LDA !SAMUS_MISSILES_MAX : CLC : ADC !SAMUS_SUPERS_MAX : ADC !SAMUS_PBS_MAX + JSR CalcItem : CLC : ADC $C1 : STA $C1 + + ; Collected items + JSR CalcLargeItem : CLC : ADC $C1 : STA $C1 + + ; Collected beams and charge + JSR CalcBeams : CLC : ADC $C1 + + ; Percent counter -> decimal form and drawn on HUD + LDX #$0012 : JSR Draw3 + LDA !IH_PERCENT : STA !HUD_TILEMAP+$18 + + .done + RTS +} + +middleHUD_reserves: +{ + LDA !SAMUS_RESERVE_MAX : BEQ .noReserves + CMP !ram_HUD_middle : BEQ .checkReserves + STA !ram_HUD_middle : LDA !SAMUS_RESERVE_ENERGY + BRA .drawReserves + + .checkReserves + LDA !SAMUS_RESERVE_ENERGY : CMP !ram_HUD_middle_counter : BEQ .checkAuto + + .drawReserves + STA !ram_HUD_middle_counter : LDX #$0054 : JSR Draw3 + + .checkAuto + LDA !SAMUS_RESERVE_MODE : CMP #$0001 : BEQ .autoOn + LDA !IH_BLANK : STA !HUD_TILEMAP+$5A + RTS + + .autoOn + LDA !SAMUS_RESERVE_ENERGY : BEQ .autoEmpty + LDA !IH_RESERVE_AUTO : STA !HUD_TILEMAP+$5A + RTS + + .autoEmpty + LDA !IH_RESERVE_EMPTY : STA !HUD_TILEMAP+$5A + RTS + + .noReserves + CMP !ram_HUD_middle : BEQ .done + STA !ram_HUD_middle : LDA !IH_BLANK + STA !HUD_TILEMAP+$54 : STA !HUD_TILEMAP+$56 + STA !HUD_TILEMAP+$58 : STA !HUD_TILEMAP+$5A + + .done + RTS +} + +topHUD_reserves: +{ + LDA !SAMUS_RESERVE_MAX : BEQ .noReserves + CMP !ram_HUD_top : BEQ .checkReserves + STA !ram_HUD_top : LDA !SAMUS_RESERVE_ENERGY + BRA .drawReserves + + .checkReserves + LDA !SAMUS_RESERVE_ENERGY : CMP !ram_HUD_top_counter : BEQ .checkAuto + + .drawReserves + STA !ram_HUD_top_counter : LDX #$0014 : JSR Draw3 + + .checkAuto + LDA !SAMUS_RESERVE_MODE : CMP #$0001 : BEQ .autoOn + LDA !IH_BLANK : STA !HUD_TILEMAP+$1A + RTS + + .autoOn + LDA !SAMUS_RESERVE_ENERGY : BEQ .autoEmpty + LDA !IH_RESERVE_AUTO : STA !HUD_TILEMAP+$1A + RTS + + .autoEmpty + LDA !IH_RESERVE_EMPTY : STA !HUD_TILEMAP+$1A + RTS + + .noReserves + CMP !ram_HUD_top : BEQ .done + STA !ram_HUD_top : LDA !IH_BLANK + STA !HUD_TILEMAP+$14 : STA !HUD_TILEMAP+$16 + STA !HUD_TILEMAP+$18 : STA !HUD_TILEMAP+$1A + + .done + RTS +} + +middleHUD_statusicons: +{ + ; health bomb + LDA !HEALTH_BOMB_FLAG : BEQ .clearHealthBomb + LDA !SAMUS_HP : CMP #$0032 : BMI .inHealthBomb + LDA !IH_LETTER_E : STA !HUD_TILEMAP+$54 + BRA .checkElevator + + .inHealthBomb + LDA !IH_HEALTHBOMB : STA !HUD_TILEMAP+$54 + BRA .checkElevator + + .clearHealthBomb + LDA !IH_BLANK : STA !HUD_TILEMAP+$54 + + ; elevator + .checkElevator + LDA !ELEVATOR_PROPERTIES : BEQ .clearElevator + LDA !IH_ELEVATOR : STA !HUD_TILEMAP+$56 + BRA .checkSpark + + .clearElevator + LDA !IH_BLANK : STA !HUD_TILEMAP+$56 + + ; shinespark + .checkSpark + LDA !SAMUS_SHINE_TIMER : BEQ .clearSpark + LDA !IH_SHINESPARK : STA !HUD_TILEMAP+$58 + BRA .checkReserves + + .clearSpark + LDA !IH_BLANK : STA !HUD_TILEMAP+$58 + + ; reserve tank + .checkReserves + LDA !SAMUS_RESERVE_MODE : CMP #$0001 : BNE .clearReserve + LDA !SAMUS_RESERVE_ENERGY : BEQ .empty + LDA !SAMUS_RESERVE_MAX : BEQ .clearReserve + LDA !IH_RESERVE_AUTO : STA !HUD_TILEMAP+$5A + RTS + + .empty + LDA !SAMUS_RESERVE_MAX : BEQ .clearReserve + LDA !IH_RESERVE_EMPTY : STA !HUD_TILEMAP+$5A + RTS + + .clearReserve + LDA !IH_BLANK : STA !HUD_TILEMAP+$5A + RTS +} + +topHUD_statusicons: +{ + ; health bomb + LDA !HEALTH_BOMB_FLAG : BEQ .clearHealthBomb + LDA !SAMUS_HP : CMP #$0032 : BMI .inHealthBomb + LDA !IH_LETTER_E : STA !HUD_TILEMAP+$14 + BRA .checkElevator + + .inHealthBomb + LDA !IH_HEALTHBOMB : STA !HUD_TILEMAP+$14 + BRA .checkElevator + + .clearHealthBomb + LDA !IH_BLANK : STA !HUD_TILEMAP+$14 + + ; elevator + .checkElevator + LDA !ELEVATOR_PROPERTIES : BEQ .clearElevator + LDA !IH_ELEVATOR : STA !HUD_TILEMAP+$16 + BRA .checkSpark + + .clearElevator + LDA !IH_BLANK : STA !HUD_TILEMAP+$16 + + ; shinespark + .checkSpark + LDA !SAMUS_SHINE_TIMER : BEQ .clearSpark + LDA !IH_SHINESPARK : STA !HUD_TILEMAP+$18 + BRA .checkReserves + + .clearSpark + LDA !IH_BLANK : STA !HUD_TILEMAP+$18 + + ; reserve tank + .checkReserves + LDA !SAMUS_RESERVE_MODE : CMP #$0001 : BNE .clearReserve + LDA !SAMUS_RESERVE_ENERGY : BEQ .empty + LDA !SAMUS_RESERVE_MAX : BEQ .clearReserve + LDA !IH_RESERVE_AUTO : STA !HUD_TILEMAP+$1A + RTS + + .empty + LDA !SAMUS_RESERVE_MAX : BEQ .clearReserve + LDA !IH_RESERVE_EMPTY : STA !HUD_TILEMAP+$1A + RTS + + .clearReserve + LDA !IH_BLANK : STA !HUD_TILEMAP+$1A + RTS +} + +middleHUD_tilecounter: +{ + LDA !MAP_COUNTER : CMP !ram_HUD_middle : BEQ .done : STA !ram_HUD_middle + LDX #$0054 : JSR Draw3 + + .done + RTS +} + +topHUD_tilecounter: +{ + LDA !MAP_COUNTER : CMP !ram_HUD_top : BEQ .done : STA !ram_HUD_top + LDX #$0014 : JSR Draw3 + + .done + RTS +} + status_ceresridley: { ; displays number of shots until Ridley "dies" @@ -4631,7 +4912,7 @@ status_zebskip: status_mbhp: { - LDA !ENEMY_HP+$40 : CMP !ram_mb_hp : BEQ .done : STA !ram_mb_hp + LDA !ENEMY_HP+$40 : CMP !ram_HUD_check : BEQ .done : STA !ram_HUD_check LDX #$0088 : JSR Draw4 .done diff --git a/src/layout.asm b/src/layout.asm index 74babd26..2899ac11 100644 --- a/src/layout.asm +++ b/src/layout.asm @@ -2309,7 +2309,15 @@ layout_asm_mbhp: { if !FEATURE_VANILLAHUD else - LDA !sram_display_mode : BNE .done + LDA !sram_display_mode : BEQ .assignMBHP + CMP !IH_MODE_ROOMSTRAT_INDEX : BNE .done + LDA !sram_superhud_bottom : BNE .done + ; Switch Super HUD enemy HP to MB HP + LDA !IH_SUPERHUD_MBHP_BOTTOM_INDEX : STA !sram_superhud_bottom + RTS + + .assignMBHP + ; Switch enemy HP to MB HP LDA !IH_MODE_ROOMSTRAT_INDEX : STA !sram_display_mode LDA !IH_STRAT_MBHP_INDEX : STA !sram_room_strat endif ; !FEATURE_VANILLAHUD diff --git a/src/main.asm b/src/main.asm index 73c347f8..70c06cfd 100644 --- a/src/main.asm +++ b/src/main.asm @@ -16,7 +16,7 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 6 !VERSION_BUILD = 7 -!VERSION_REV = 9 +!VERSION_REV = 10 table ../resources/normal.tbl print "" diff --git a/src/mainmenu.asm b/src/mainmenu.asm index d354c599..52c34b18 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -1544,14 +1544,13 @@ else InfoHudMenu: dw #ih_goto_display_mode dw #ih_display_mode - dw #ih_display_mode_reward - dw #$FFFF dw #ih_goto_room_strat dw #ih_room_strat + dw #ih_goto_superhud + dw #ih_superhud_bottom_selector + dw #ih_display_mode_reward dw #$FFFF - dw #ih_superhud dw #ih_door_display_mode - dw #$FFFF dw #ih_goto_timer_settings dw #$FFFF dw #ih_minimap @@ -1605,6 +1604,7 @@ DisplayModeMenu2: dw #$0000 %cm_header("INFOHUD DISPLAY MODE") +; Enemy HP must always be the first display mode option ihmode_enemyhp: %cm_jsl("Enemy HP", #action_select_infohud_mode, #$0000) @@ -1769,7 +1769,7 @@ RoomStratMenu2: %cm_header("INFOHUD ROOM STRAT") %cm_footer("ROOM STRAT MUST BE ACTIVE") -; SuperHUD must always be the first room strat option +; Super HUD must always be the first room strat option ihstrat_superhud: %cm_jsl("Super HUD", #action_select_room_strat, #$0000) @@ -1885,7 +1885,7 @@ ih_room_strat: LDA !IH_MODE_ROOMSTRAT_INDEX : STA !sram_display_mode JML init_print_segment_timer -ih_superhud: +ih_goto_superhud: %cm_submenu("Configure Super HUD", #SuperHUDMenu) SuperHUDMenu: @@ -1913,6 +1913,7 @@ ih_superhud_bottom_selector: db #$28, " COOLDOWN", #$FF db #$28, " SHINESPARK", #$FF db #$28, " DASH", #$FF + db #$28, " SHINE TUNE", #$FF db #$28, " I FRAMES", #$FF db #$28, " SPIKESUIT", #$FF db #$28, "LAG COUNTER", #$FF @@ -1933,6 +1934,7 @@ ih_superhud_bottom_selector: db #$28, " TACO TANK", #$FF db #$28, " PIT DOOR", #$FF db #$28, " MOONDANCE", #$FF + db #$28, "KRAID RADAR", #$FF db #$28, "GATE GLITCH", #$FF db #$28, " MOAT CWJ", #$FF db #$28, "ROBOT FLUSH", #$FF @@ -1943,6 +1945,7 @@ ih_superhud_bottom_selector: db #$28, " SNAIL CLIP", #$FF db #$28, " WASTELAND", #$FF db #$28, " RIDLEY AI", #$FF + db #$28, " KIHUNTER", #$FF db #$28, " DBACK ZEB", #$FF db #$28, " ZEB SKIP", #$FF db #$28, " MB HP", #$FF @@ -1959,6 +1962,7 @@ SuperHUDBottomMenu: dw ih_superhud_cooldown dw ih_superhud_shinetimer dw ih_superhud_dashcounter + dw ih_superhud_shinetune dw ih_superhud_iframecounter dw ih_superhud_spikesuit dw ih_superhud_lagcounter @@ -1986,6 +1990,7 @@ SuperHUDBottomMenu2: dw ih_superhud_tacotank dw ih_superhud_pitdoor dw ih_superhud_moondance + dw ih_superhud_kraidradar dw ih_superhud_gateglitch dw ih_superhud_moatcwj dw ih_superhud_robotflush @@ -2003,6 +2008,7 @@ SuperHUDBottomMenu3: dw ih_superhud_snailclip dw ih_superhud_wasteland dw ih_superhud_ridleyai + dw ih_superhud_kihuntermanip dw ih_superhud_downbackzeb dw ih_superhud_zebskip dw ih_superhud_mbhp @@ -2013,6 +2019,7 @@ SuperHUDBottomMenu3: dw #$0000 %cm_header("SUPER HUD BOTTOM MODE") +; Enemy HP must always be the first Super HUD bottom option ih_superhud_enemyhp: %cm_jsl("Enemy HP", #action_select_superhud_bottom, #$0000) @@ -2031,109 +2038,124 @@ ih_superhud_shinetimer: ih_superhud_dashcounter: %cm_jsl("Dash Counter", #action_select_superhud_bottom, #$0005) +ih_superhud_shinetune: +!IH_SUPERHUD_SHINETUNE_BOTTOM_INDEX = #$0006 + %cm_jsl("Shine Tune", #action_select_infohud_mode, #$0006) + ih_superhud_iframecounter: - %cm_jsl("I-Frame Counter", #action_select_superhud_bottom, #$0006) + %cm_jsl("I-Frame Counter", #action_select_superhud_bottom, #$0007) ih_superhud_spikesuit: - %cm_jsl("Spikesuit Trainer", #action_select_superhud_bottom, #$0007) + %cm_jsl("Spikesuit Trainer", #action_select_superhud_bottom, #$0008) ih_superhud_lagcounter: - %cm_jsl("Lag Counter", #action_select_superhud_bottom, #$0008) + %cm_jsl("Lag Counter", #action_select_superhud_bottom, #$0009) ih_superhud_cpuusage: - %cm_jsl("CPU Usage", #action_select_superhud_bottom, #$0009) + %cm_jsl("CPU Usage", #action_select_superhud_bottom, #$000A) ih_superhud_hspeed: - %cm_jsl("Horizontal Speed", #action_select_superhud_bottom, #$000A) + %cm_jsl("Horizontal Speed", #action_select_superhud_bottom, #$000B) ih_superhud_vspeed: - %cm_jsl("Vertical Speed", #action_select_superhud_bottom, #$000B) + %cm_jsl("Vertical Speed", #action_select_superhud_bottom, #$000C) ih_superhud_quickdrop: - %cm_jsl("Quickdrop Trainer", #action_select_superhud_bottom, #$000C) + %cm_jsl("Quickdrop Trainer", #action_select_superhud_bottom, #$000D) ih_superhud_walljump: - %cm_jsl("Walljump Trainer", #action_select_superhud_bottom, #$000D) +!IH_SUPERHUD_WALLJUMP_BOTTOM_INDEX = #$000E + %cm_jsl("Walljump Trainer", #action_select_superhud_bottom, #$000E) ih_superhud_countdamage: - %cm_jsl("Boss Damage Counter", #action_select_superhud_bottom, #$000E) +!IH_SUPERHUD_COUNTDAMAGE_BOTTOM_INDEX = #$000F + %cm_jsl("Boss Damage Counter", #action_select_superhud_bottom, #$000F) ih_superhud_armpump: - %cm_jsl("Arm Pump Trainer", #action_select_superhud_bottom, #$000F) +!IH_SUPERHUD_ARMPUMP_BOTTOM_INDEX = #$0010 + %cm_jsl("Arm Pump Trainer", #action_select_superhud_bottom, #$0010) ih_superhud_pumpcounter: - %cm_jsl("Arm Pump Counter", #action_select_superhud_bottom, #$0010) + %cm_jsl("Arm Pump Counter", #action_select_superhud_bottom, #$0011) ih_superhud_xpos: - %cm_jsl("X Position", #action_select_superhud_bottom, #$0011) + %cm_jsl("X Position", #action_select_superhud_bottom, #$0012) ih_superhud_ypos: - %cm_jsl("Y Position", #action_select_superhud_bottom, #$0012) + %cm_jsl("Y Position", #action_select_superhud_bottom, #$0013) ih_superhud_shottimer: - %cm_jsl("Shot Timer", #action_select_superhud_bottom, #$0013) + %cm_jsl("Shot Timer", #action_select_superhud_bottom, #$0014) ih_superhud_ramwatch: - %cm_jsl("Custom RAM Watch", #action_select_superhud_bottom, #$0014) +!IH_SUPERHUD_RAMATCH_BOTTOM_INDEX = #$0015 + %cm_jsl("Custom RAM Watch", #action_select_superhud_bottom, #$0015) ih_superhud_ceresridley: - %cm_jsl("Ceres Ridley Hits", #action_select_superhud_bottom, #$0015) + %cm_jsl("Ceres Ridley Hits", #action_select_superhud_bottom, #$0016) ih_superhud_doorskip: - %cm_jsl("Parlor-Climb Door Skip", #action_select_superhud_bottom, #$0016) + %cm_jsl("Parlor-Climb Door Skip", #action_select_superhud_bottom, #$0017) ih_superhud_tacotank: - %cm_jsl("Taco Tank", #action_select_superhud_bottom, #$0017) + %cm_jsl("Taco Tank", #action_select_superhud_bottom, #$0018) ih_superhud_pitdoor: - %cm_jsl("Pit Room Right Door", #action_select_superhud_bottom, #$0018) + %cm_jsl("Pit Room Right Door", #action_select_superhud_bottom, #$0019) ih_superhud_moondance: - %cm_jsl("Moondance", #action_select_superhud_bottom, #$0019) + %cm_jsl("Moondance", #action_select_superhud_bottom, #$001A) + +ih_superhud_kraidradar: + %cm_jsl("Kraid Nail Radar", #action_select_room_strat, #$001B) ih_superhud_gateglitch: - %cm_jsl("Gate Glitch", #action_select_superhud_bottom, #$001A) + %cm_jsl("Gate Glitch", #action_select_superhud_bottom, #$001C) ih_superhud_moatcwj: - %cm_jsl("Moat CWJ", #action_select_superhud_bottom, #$001B) + %cm_jsl("Moat CWJ", #action_select_superhud_bottom, #$001D) ih_superhud_robotflush: - %cm_jsl("Robot Flush", #action_select_superhud_bottom, #$001C) + %cm_jsl("Robot Flush", #action_select_superhud_bottom, #$001E) ih_superhud_shinetopb: - %cm_jsl("Shine to PB", #action_select_superhud_bottom, #$001D) + %cm_jsl("Shine to PB", #action_select_superhud_bottom, #$001F) ih_superhud_elevatorcf: - %cm_jsl("Elevator Crystal Flash", #action_select_superhud_bottom, #$001E) + %cm_jsl("Elevator Crystal Flash", #action_select_superhud_bottom, #$0020) ih_superhud_botwooncf: - %cm_jsl("Botwoon Crystal Flash", #action_select_superhud_bottom, #$001F) + %cm_jsl("Botwoon Crystal Flash", #action_select_superhud_bottom, #$0021) ih_superhud_draygonai: - %cm_jsl("Draygon AI", #action_select_superhud_bottom, #$0020) + %cm_jsl("Draygon AI", #action_select_superhud_bottom, #$0022) ih_superhud_snailclip: - %cm_jsl("Aqueduct Snail Clip", #action_select_superhud_bottom, #$0021) + %cm_jsl("Aqueduct Snail Clip", #action_select_superhud_bottom, #$0023) ih_superhud_wasteland: - %cm_jsl("Wasteland Entry", #action_select_superhud_bottom, #$0022) + %cm_jsl("Wasteland Entry", #action_select_superhud_bottom, #$0024) ih_superhud_ridleyai: - %cm_jsl("Ridley AI", #action_select_superhud_bottom, #$0023) + %cm_jsl("Ridley AI", #action_select_superhud_bottom, #$0025) + +ih_superhud_kihuntermanip: + %cm_jsl("Kihunter Manipulation", #action_select_room_strat, #$0026) ih_superhud_downbackzeb: - %cm_jsl("Downback Zeb Skip", #action_select_superhud_bottom, #$0024) + %cm_jsl("Downback Zeb Skip", #action_select_superhud_bottom, #$0027) ih_superhud_zebskip: - %cm_jsl("Zeb Skip Indicator", #action_select_superhud_bottom, #$0025) + %cm_jsl("Zeb Skip Indicator", #action_select_superhud_bottom, #$0028) ih_superhud_mbhp: - %cm_jsl("Mother Brain HP", #action_select_superhud_bottom, #$0026) +!IH_SUPERHUD_MBHP_BOTTOM_INDEX = #$0029 + %cm_jsl("Mother Brain HP", #action_select_superhud_bottom, #$0029) ih_superhud_twocries: - %cm_jsl("Two Cries Standup", #action_select_superhud_bottom, #$0027) + %cm_jsl("Two Cries Standup", #action_select_superhud_bottom, #$002A) -!IH_SUPERHUD_BOTTOM_COUNT = #$0028 +!IH_SUPERHUD_BOTTOM_COUNT = #$002B action_select_superhud_bottom: { TYA : STA !sram_superhud_bottom @@ -2165,6 +2187,10 @@ ih_superhud_middle_selector: db #$28, " CPU USAGE", #$FF db #$28, "HORIZ SPEED", #$FF db #$28, " SHOT TIMER", #$FF + db #$28, " ITEM %", #$FF + db #$28, " RESERVES", #$FF + db #$28, "STATUS ICON", #$FF + db #$28, " MAP TILES", #$FF db #$FF ih_superhud_middle_submenu: @@ -2182,6 +2208,10 @@ SuperHUDMiddleMenu: dw ih_superhud_middle_cpuusage dw ih_superhud_middle_hspeed dw ih_superhud_middle_shottimer + dw ih_superhud_middle_itempercent + dw ih_superhud_middle_reserves + dw ih_superhud_middle_statusicons + dw ih_superhud_middle_tilecounter dw #$0000 %cm_header("SUPER HUD MIDDLE MODE") @@ -2206,6 +2236,7 @@ ih_superhud_middle_dashcounter: ih_superhud_middle_iframecounter: %cm_jsl("I-Frame Counter", #action_select_superhud_middle, #$0006) +!IH_SUPERHUD_LAG_COUNTER_MIDDLE_INDEX = #$0007 ih_superhud_middle_lagcounter: %cm_jsl("Lag Counter", #action_select_superhud_middle, #$0007) @@ -2218,6 +2249,18 @@ ih_superhud_middle_hspeed: ih_superhud_middle_shottimer: %cm_jsl("Shot Timer", #action_select_superhud_middle, #$000A) +ih_superhud_middle_itempercent: + %cm_jsl("Item Collection %", #action_select_superhud_middle, #$000B) + +ih_superhud_middle_reserves: + %cm_jsl("Reserves", #action_select_superhud_middle, #$000C) + +ih_superhud_middle_statusicons: + %cm_jsl("Status Icons", #action_select_superhud_middle, #$000D) + +ih_superhud_middle_tilecounter: + %cm_jsl("Map Tile Counter", #action_select_superhud_middle, #$000E) + action_select_superhud_middle: { TYA : STA !sram_superhud_middle @@ -2240,6 +2283,10 @@ ih_superhud_top_selector: db #$28, " CPU USAGE", #$FF db #$28, "HORIZ SPEED", #$FF db #$28, " SHOT TIMER", #$FF + db #$28, " ITEM %", #$FF + db #$28, " RESERVES", #$FF + db #$28, "STATUS ICON", #$FF + db #$28, " MAP TILES", #$FF db #$FF ih_superhud_top_submenu: @@ -2257,6 +2304,10 @@ SuperHUDTopMenu: dw ih_superhud_top_cpuusage dw ih_superhud_top_hspeed dw ih_superhud_top_shottimer + dw ih_superhud_top_itempercent + dw ih_superhud_top_reserves + dw ih_superhud_top_statusicons + dw ih_superhud_top_tilecounter dw #$0000 %cm_header("SUPER HUD TOP MODE") @@ -2281,6 +2332,7 @@ ih_superhud_top_dashcounter: ih_superhud_top_iframecounter: %cm_jsl("I-Frame Counter", #action_select_superhud_top, #$0006) +!IH_SUPERHUD_LAG_COUNTER_TOP_INDEX = #$0007 ih_superhud_top_lagcounter: %cm_jsl("Lag Counter", #action_select_superhud_top, #$0007) @@ -2293,6 +2345,18 @@ ih_superhud_top_hspeed: ih_superhud_top_shottimer: %cm_jsl("Shot Timer", #action_select_superhud_top, #$000A) +ih_superhud_top_itempercent: + %cm_jsl("Item Collection %", #action_select_superhud_top, #$000B) + +ih_superhud_top_reserves: + %cm_jsl("Reserves", #action_select_superhud_top, #$000C) + +ih_superhud_top_statusicons: + %cm_jsl("Status Icons", #action_select_superhud_top, #$000D) + +ih_superhud_top_tilecounter: + %cm_jsl("Map Tile Counter", #action_select_superhud_top, #$000E) + action_select_superhud_top: { TYA : STA !sram_superhud_top @@ -3037,12 +3101,18 @@ else if !INFOHUD_ALWAYS_SHOW_X_Y else ; Skip printing segment timer when shinetune or walljump enabled - LDA !sram_display_mode : CMP !IH_MODE_SHINETUNE_INDEX : BEQ .skip + LDA !sram_display_mode : CMP !IH_MODE_ROOMSTRAT_INDEX : BEQ .checkSuperHUD + CMP !IH_MODE_SHINETUNE_INDEX : BEQ .skip CMP !IH_MODE_WALLJUMP_INDEX : BEQ .skip - ; print + .print LDA #$0001 : STA !ram_print_segment_timer RTL + .checkSuperHUD + LDA !sram_room_strat : BNE .print + LDA !sram_superhud_bottom : CMP !IH_SUPERHUD_SHINETUNE_BOTTOM_INDEX : BEQ .skip + CMP !IH_SUPERHUD_WALLJUMP_BOTTOM_INDEX : BNE .print + .skip endif endif diff --git a/src/menu.asm b/src/menu.asm index d9a1a6a0..c9af1034 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -212,7 +212,9 @@ cm_exit: JSL $809B44 ; Handle HUD tilemap if !FEATURE_VANILLAHUD else + LDA #$FFFF : STA !ram_reserves_last JSL ih_update_hud_code + JSL ih_update_status endif LDA !ram_seed_X : STA !sram_seed_X LDA !ram_seed_Y : STA !sram_seed_Y diff --git a/src/ramwatchmenu.asm b/src/ramwatchmenu.asm index 10c5720f..eea43d2b 100644 --- a/src/ramwatchmenu.asm +++ b/src/ramwatchmenu.asm @@ -562,11 +562,7 @@ ramwatch_common_back: RTL ramwatch_enable: - %cm_jsl("Turn On RAM Watch", .routine, !IH_MODE_RAMWATCH_INDEX) - .routine - TYA : STA !sram_display_mode - %sfxconfirm() - JML init_print_segment_timer + %cm_jsl("Turn On RAM Watch", #action_HUD_ramwatch, #$0000) ramwatch_bank: %cm_numfield_hex("Select Bank", !ram_watch_bank, 0, 255, 1, 4, #0) @@ -608,9 +604,7 @@ ramwatch_execute_left: .setValue LDA !ram_watch_edit_left : STA [$C1] %a16() - LDA !IH_MODE_RAMWATCH_INDEX : STA !sram_display_mode - %sfxconfirm() - JML init_print_segment_timer + BRA action_HUD_ramwatch ramwatch_execute_right: %cm_jsl("Write to Right Address", #.routine, #$0000) @@ -622,9 +616,7 @@ ramwatch_execute_right: .setValue LDA !ram_watch_edit_right : STA [$C1] %a16() - LDA !IH_MODE_RAMWATCH_INDEX : STA !sram_display_mode - %sfxconfirm() - JML init_print_segment_timer + BRA action_HUD_ramwatch ramwatch_lock_left: %cm_toggle("Lock Left Value", !ram_watch_edit_lock_left, #$01, #action_HUD_ramwatch) @@ -634,7 +626,16 @@ ramwatch_lock_right: action_HUD_ramwatch: { + LDA !sram_display_mode : CMP !IH_MODE_ROOMSTRAT_INDEX : BNE .notSuperHUD + LDA !sram_room_strat : BEQ .superHUD + .notSuperHUD LDA !IH_MODE_RAMWATCH_INDEX : STA !sram_display_mode + %sfxconfirm() + JML init_print_segment_timer + + .superHUD + LDA !IH_SUPERHUD_RAMATCH_BOTTOM_INDEX : STA !sram_superhud_bottom + %sfxconfirm() JML init_print_segment_timer } diff --git a/src/spritefeat.asm b/src/spritefeat.asm index 195dc1e5..8d908c63 100644 --- a/src/spritefeat.asm +++ b/src/spritefeat.asm @@ -20,7 +20,7 @@ hook_standard_sprite_tiles: db $FF, $FF, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80 -%startfree(F0) +%startfree(87) ; This runs every frame before any other sprites are drawn, this is needed so we can get priority over everything else update_sprite_features: @@ -970,4 +970,4 @@ DrawMBHitbox: sprite_tiles: incbin "../resources/spritegfx.bin":0-600 -%endfree(F0) +%endfree(87) diff --git a/src/symbols.asm b/src/symbols.asm index 92fc9cb1..69d7cd8c 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -70,12 +70,12 @@ ram_magic_pants_pal3 = !ram_magic_pants_pal3 ; !WRAM_START+$40 ram_room_has_set_rng = !ram_room_has_set_rng ; !WRAM_START+$42 ram_HUD_top = !ram_HUD_top ; !WRAM_START+$44 ram_HUD_middle = !ram_HUD_middle ; !WRAM_START+$46 -ram_HUD_check = !ram_HUD_check ; !WRAM_START+$48 +ram_infidoppler_active = !ram_infidoppler_active ; !WRAM_START+$48 ram_roomstrat_counter = !ram_roomstrat_counter ; !WRAM_START+$4A ram_roomstrat_state = !ram_roomstrat_state ; !WRAM_START+$4C ram_enemy_hp = !ram_enemy_hp ; !WRAM_START+$4E -ram_mb_hp = !ram_mb_hp ; !WRAM_START+$50 -ram_shot_timer = !ram_shot_timer ; !WRAM_START+$52 +ram_HUD_top_counter = !ram_HUD_top_counter ; !WRAM_START+$50 +ram_HUD_middle_counter = !ram_HUD_middle_counter ; !WRAM_START+$52 ram_shine_counter = !ram_shine_counter ; !WRAM_START+$54 ram_dash_counter = !ram_dash_counter ; !WRAM_START+$56 @@ -85,7 +85,6 @@ ram_print_segment_timer = !ram_print_segment_timer ; !WRAM_START+$5C ram_activated_shine_duration = !ram_activated_shine_duration ; !WRAM_START+$5E ram_watch_left_hud = !ram_watch_left_hud ; !WRAM_START+$60 ram_watch_right_hud = !ram_watch_right_hud ; !WRAM_START+$62 -ram_infidoppler_active = !ram_infidoppler_active ; !WRAM_START+$64 ; ^ FREE SPACE ^ up to +$6C @@ -98,8 +97,8 @@ ram_infidoppler_active = !ram_infidoppler_active ; !WRAM_START+$64 ram_xpos = !ram_xpos ; !WRAM_START+$6E ram_ypos = !ram_ypos ; !WRAM_START+$70 ram_subpixel_pos = !ram_subpixel_pos ; !WRAM_START+$72 -ram_HUD_top_counter = !ram_HUD_top_counter ; !WRAM_START+$74 -ram_HUD_middle_counter = !ram_HUD_middle_counter ; !WRAM_START+$76 +ram_HUD_check = !ram_HUD_check ; !WRAM_START+$74 +ram_shot_timer = !ram_shot_timer ; !WRAM_START+$76 ram_quickdrop_counter = !ram_quickdrop_counter ; !WRAM_START+$78 ram_walljump_counter = !ram_walljump_counter ; !WRAM_START+$7A ram_fail_sum = !ram_fail_sum ; !WRAM_START+$7C From 40b76f6558c5dbe1fb38cd7e0a5873e1f68a19ea Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Thu, 10 Apr 2025 01:06:58 -0500 Subject: [PATCH 16/43] Initial pass at ridley RNG support --- src/cutscenes.asm | 84 ++++----- src/defines.asm | 96 ++++++++-- src/enemy_rng.asm | 426 +++++++++++++++++++++++++++++++++++++++++- src/infohud.asm | 36 ++-- src/infohudmodes.asm | 42 ++--- src/layout.asm | 4 +- src/mainmenu.asm | 435 +++++++++++++++++++++++++++++++++++-------- src/presets.asm | 2 +- src/symbols.asm | 39 ++-- 9 files changed, 959 insertions(+), 205 deletions(-) diff --git a/src/cutscenes.asm b/src/cutscenes.asm index 4b0d3059..ea35f7a1 100644 --- a/src/cutscenes.asm +++ b/src/cutscenes.asm @@ -1739,7 +1739,7 @@ cutscenes_mb_fast_init: ; If loading a preset, certain flags may already be set ; which allow MB to take damage, so setting value high, ; but also set below 18000 to avoid confusion with vanilla logic - LDA #$464F : STA !ENEMY_HP+$40 + LDA #$464F : STA !ENEMY_HP+!ENEMY_1_OFFSET ; If MB already defeated, reset health to full to simulate baby metroid refill LDA $7ED82D : BIT #$0002 : BEQ .end_refill @@ -1773,7 +1773,7 @@ endif cutscenes_mb_fake_death_pause: { - LDA !ENEMY_HP+$40 : BEQ .continue + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue LDA #$0001 : STA !ENEMY_VAR_5 .continue @@ -1788,7 +1788,7 @@ endif cutscenes_mb_fake_death_lock: { - LDA !ENEMY_HP+$40 : BEQ .continue + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue LDA #$0001 : STA !ENEMY_VAR_5 .continue @@ -1825,7 +1825,7 @@ endif STA !ENEMY_FUNCTION_POINTER LDA #$000C : STA !ENEMY_VAR_5 - LDA !ENEMY_HP+$40 : BEQ .continue + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue LDA #$0002 : STA !ENEMY_VAR_5 .continue @@ -1837,7 +1837,7 @@ endif cutscenes_mb_fake_death_unlock: { - LDA !ENEMY_HP+$40 : BEQ .continue + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue LDA #$0001 : STA !ENEMY_VAR_5 .continue @@ -1869,8 +1869,8 @@ endif cutscenes_mb_bottom_left_tube: { - LDA !ENEMY_HP+$40 : BEQ .continue - LDA #$0010 : STA !ENEMY_VAR_5+$40 + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue + LDA #$0010 : STA !ENEMY_VAR_5+!ENEMY_1_OFFSET .continue if !FEATURE_PAL @@ -1878,14 +1878,14 @@ if !FEATURE_PAL else LDA #$8983 endif - STA !ENEMY_VAR_4+$40 - JMP (!ENEMY_VAR_4+$40) + STA !ENEMY_VAR_4+!ENEMY_1_OFFSET + JMP (!ENEMY_VAR_4+!ENEMY_1_OFFSET) } cutscenes_mb_ceiling_column_9: { - LDA !ENEMY_HP+$40 : BEQ .continue - LDA #$0010 : STA !ENEMY_VAR_5+$40 + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue + LDA #$0010 : STA !ENEMY_VAR_5+!ENEMY_1_OFFSET .continue if !FEATURE_PAL @@ -1893,14 +1893,14 @@ if !FEATURE_PAL else LDA #$89B5 endif - STA !ENEMY_VAR_4+$40 - JMP (!ENEMY_VAR_4+$40) + STA !ENEMY_VAR_4+!ENEMY_1_OFFSET + JMP (!ENEMY_VAR_4+!ENEMY_1_OFFSET) } cutscenes_mb_ceiling_column_6: { - LDA !ENEMY_HP+$40 : BEQ .continue - LDA #$0010 : STA !ENEMY_VAR_5+$40 + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue + LDA #$0010 : STA !ENEMY_VAR_5+!ENEMY_1_OFFSET .continue if !FEATURE_PAL @@ -1908,14 +1908,14 @@ if !FEATURE_PAL else LDA #$89E7 endif - STA !ENEMY_VAR_4+$40 - JMP (!ENEMY_VAR_4+$40) + STA !ENEMY_VAR_4+!ENEMY_1_OFFSET + JMP (!ENEMY_VAR_4+!ENEMY_1_OFFSET) } cutscenes_mb_bottom_right_tube: { - LDA !ENEMY_HP+$40 : BEQ .continue - LDA #$0010 : STA !ENEMY_VAR_5+$40 + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue + LDA #$0010 : STA !ENEMY_VAR_5+!ENEMY_1_OFFSET .continue if !FEATURE_PAL @@ -1923,14 +1923,14 @@ if !FEATURE_PAL else LDA #$8A0F endif - STA !ENEMY_VAR_4+$40 - JMP (!ENEMY_VAR_4+$40) + STA !ENEMY_VAR_4+!ENEMY_1_OFFSET + JMP (!ENEMY_VAR_4+!ENEMY_1_OFFSET) } cutscenes_mb_bottom_middle_left_tube: { - LDA !ENEMY_HP+$40 : BEQ .continue - LDA #$0010 : STA !ENEMY_VAR_5+$40 + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue + LDA #$0010 : STA !ENEMY_VAR_5+!ENEMY_1_OFFSET .continue if !FEATURE_PAL @@ -1938,14 +1938,14 @@ if !FEATURE_PAL else LDA #$8A37 endif - STA !ENEMY_VAR_4+$40 - JMP (!ENEMY_VAR_4+$40) + STA !ENEMY_VAR_4+!ENEMY_1_OFFSET + JMP (!ENEMY_VAR_4+!ENEMY_1_OFFSET) } cutscenes_mb_ceiling_column_7: { - LDA !ENEMY_HP+$40 : BEQ .continue - LDA #$0010 : STA !ENEMY_VAR_5+$40 + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue + LDA #$0010 : STA !ENEMY_VAR_5+!ENEMY_1_OFFSET .continue if !FEATURE_PAL @@ -1953,14 +1953,14 @@ if !FEATURE_PAL else LDA #$8A69 endif - STA !ENEMY_VAR_4+$40 - JMP (!ENEMY_VAR_4+$40) + STA !ENEMY_VAR_4+!ENEMY_1_OFFSET + JMP (!ENEMY_VAR_4+!ENEMY_1_OFFSET) } cutscenes_mb_ceiling_column_8: { - LDA !ENEMY_HP+$40 : BEQ .continue - LDA #$0010 : STA !ENEMY_VAR_5+$40 + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .continue + LDA #$0010 : STA !ENEMY_VAR_5+!ENEMY_1_OFFSET .continue if !FEATURE_PAL @@ -1968,8 +1968,8 @@ if !FEATURE_PAL else LDA #$8A9B endif - STA !ENEMY_VAR_4+$40 - JMP (!ENEMY_VAR_4+$40) + STA !ENEMY_VAR_4+!ENEMY_1_OFFSET + JMP (!ENEMY_VAR_4+!ENEMY_1_OFFSET) } cutscenes_mb_setup_fight_or_escape: @@ -1986,12 +1986,12 @@ else endif .mb - LDA !ENEMY_HP+$40 : BEQ .init_health - TDC : STA !ENEMY_VAR_5 : STA !ENEMY_HP+$40 + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BEQ .init_health + TDC : STA !ENEMY_VAR_5 : STA !ENEMY_HP+!ENEMY_1_OFFSET BRA .continue .init_health - LDA #$4650 : STA !ENEMY_HP+$40 + LDA #$4650 : STA !ENEMY_HP+!ENEMY_1_OFFSET .continue if !FEATURE_PAL @@ -2005,7 +2005,7 @@ endif cutscenes_mb_pause_phase_2: { - LDA !ENEMY_HP+$40 : BNE .continue + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BNE .continue TDC : STA !ENEMY_VAR_5 LDA !sram_cutscenes : BIT !CUTSCENE_FAST_MB : BEQ .lower_acid LDA !sram_room_layout : BIT !ROOM_LAYOUT_DASH_RECALL : BEQ .continue @@ -2025,7 +2025,7 @@ endif cutscenes_mb_load_tiles_phase_2: { - LDA !ENEMY_HP+$40 : BNE .continue + LDA !ENEMY_HP+!ENEMY_1_OFFSET : BNE .continue TDC : STA !ENEMY_VAR_5 .continue @@ -2069,7 +2069,7 @@ cutscenes_mb_choose_phase_2_or_3: LDA #$0004 : STA $7E7800 ; 36000 health - LDA #$8CA0 : STA !ENEMY_HP+$40 + LDA #$8CA0 : STA !ENEMY_HP+!ENEMY_1_OFFSET ; Enable health-based palette TDC : STA $7E7860 : STA $7E7868 @@ -2091,7 +2091,7 @@ endif LDA #$0002 : STA $7E7800 ; 18000 health - LDA #$4650 : STA !ENEMY_HP+$40 + LDA #$4650 : STA !ENEMY_HP+!ENEMY_1_OFFSET if !FEATURE_PAL JMP $8EE1 else @@ -2195,7 +2195,7 @@ cutscenes_mb_death_brain_falling_fast: { ; Vanilla logic except add $40 instead of $20 LDA !ENEMY_VAR_5 : CLC : ADC #$0040 : STA !ENEMY_VAR_5 - XBA : AND #$00FF : CLC : ADC !ENEMY_Y+$40 + XBA : AND #$00FF : CLC : ADC !ENEMY_Y+!ENEMY_1_OFFSET CMP #$00C4 : BCC .rts if !FEATURE_PAL @@ -2205,7 +2205,7 @@ else endif .rts - STA !ENEMY_Y+$40 + STA !ENEMY_Y+!ENEMY_1_OFFSET RTS } diff --git a/src/defines.asm b/src/defines.asm index a8096640..b038fb3a 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -216,6 +216,8 @@ !ram_quickboot_spc_state = !WRAM_PERSIST_START+$6A !ram_display_backup = !WRAM_PERSIST_START+$6C !ram_phantoon_always_visible = !WRAM_PERSIST_START+$6E +!ram_ridley_rng_flags = !WRAM_PERSIST_START+$70 +!ram_ridley_rng_times_and_fireball = !WRAM_PERSIST_START+$72 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -304,9 +306,21 @@ !ram_cm_itempickups_chozo = !WRAM_MENU_START+$9A !ram_cm_itempickups_hidden = !WRAM_MENU_START+$9C -!ram_cm_phan_first_phase = !WRAM_MENU_START+$90 -!ram_cm_phan_second_phase = !WRAM_MENU_START+$92 -!ram_cm_turret_rng = !WRAM_MENU_START+$94 +!ram_cm_turret_rng = !WRAM_MENU_START+$90 +!ram_cm_phan_first_phase = !WRAM_MENU_START+$92 +!ram_cm_phan_second_phase = !WRAM_MENU_START+$94 + +!ram_cm_ridley_pogo_height = !WRAM_MENU_START+$92 +!ram_cm_ridley_lunge_pogo = !WRAM_MENU_START+$94 +!ram_cm_ridley_swoop_pogo = !WRAM_MENU_START+$96 +!ram_cm_ridley_ceres_ai = !WRAM_MENU_START+$98 +!ram_cm_ridley_hover_fireball = !WRAM_MENU_START+$9A +!ram_cm_ridley_backpogo_left = !WRAM_MENU_START+$9C +!ram_cm_ridley_backpogo_right = !WRAM_MENU_START+$9E +!ram_cm_ridley_pogo_time = !WRAM_MENU_START+$A0 +!ram_cm_ridley_pogo_time_value = !WRAM_MENU_START+$A2 +!ram_cm_ridley_hover_time = !WRAM_MENU_START+$A4 +!ram_cm_ridley_hover_time_value = !WRAM_MENU_START+$A6 !ram_cm_varia = !WRAM_MENU_START+$90 !ram_cm_gravity = !WRAM_MENU_START+$92 @@ -436,27 +450,12 @@ !LEVEL_DATA = $7F0002 ; Temporary stack written here since level data will be initialized afterwards +; There is room for 256 entries in the stack before risking leaving data behind, +; since even the smallest room has 512 bytes of level data !CATEGORY_PRESET_STACK = !LEVEL_DATA !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA = $7F0202 -; Phantoon infidoppler can use the next $200 of RAM, -; since the room outside phantoon's room is larger and will overwrite this data, -; so the only way this could have some impact is you went OOB -; either from Phantoon's room or after teleporting to another single scroll room, -; and then fell a long ways out of bounds - -; An array of 5 words, one per projectile, representing -; the distance Samus travelled horizontally before firing. -; The low byte of each word is integer pixels, -; and the high byte is fractional pixels. -; Yes, that sounds weird, but the math is a little easier. -!ram_infidoppler_offsets = !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA ; array of 5 words -!ram_infidoppler_x = !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA+$10 -!ram_infidoppler_subx = !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA+$12 -!ram_infidoppler_y = !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA+$14 -!ram_infidoppler_suby = !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA+$16 - ; Do not use RAM for variables at or beyond this point !LEVEL_BTS = $7F6402 @@ -972,6 +971,34 @@ !DEMO_CURRENT_SET = $1F55 !DEMO_CURRENT_SCENE = $1F57 +; In rooms with fewer enemies, some enemy RAM is available for use +!ENEMY_1_OFFSET = $40 +!ENEMY_2_OFFSET = $80 +!ENEMY_1E_OFFSET = $780 +!ENEMY_1F_OFFSET = $7C0 + +; An array of 5 words, one per projectile, representing +; the distance Samus travelled horizontally before firing. +; The low byte of each word is integer pixels, +; and the high byte is fractional pixels. +; Yes, that sounds weird, but the math is a little easier. +!eram_infidoppler_offsets = !ENEMY_VAR_1+!ENEMY_1E_OFFSET ; array of 5 words +!eram_infidoppler_x = !ENEMY_VAR_1+!ENEMY_1F_OFFSET +!eram_infidoppler_subx = !ENEMY_VAR_2+!ENEMY_1F_OFFSET +!eram_infidoppler_y = !ENEMY_VAR_3+!ENEMY_1F_OFFSET +!eram_infidoppler_suby = !ENEMY_VAR_4+!ENEMY_1F_OFFSET + +!eram_ceres_ridley_rng = !ENEMY_VAR_1+!ENEMY_1E_OFFSET +!eram_ridley_lunge_pogo_rng = !ENEMY_VAR_2+!ENEMY_1E_OFFSET +!eram_ridley_swoop_pogo_rng = !ENEMY_VAR_3+!ENEMY_1E_OFFSET +!eram_ridley_pogo_swoop_rng = !ENEMY_VAR_4+!ENEMY_1E_OFFSET +!eram_ridley_fireball_rng = !ENEMY_VAR_5+!ENEMY_1E_OFFSET +!eram_ridley_hover_time_rng = !ENEMY_VAR_1+!ENEMY_1F_OFFSET +!eram_ridley_pogo_time_rng = !ENEMY_VAR_2+!ENEMY_1F_OFFSET +!eram_ridley_pogo_height_rng = !ENEMY_VAR_3+!ENEMY_1F_OFFSET +!eram_ridley_backpogo_left_rng = !ENEMY_VAR_4+!ENEMY_1F_OFFSET +!eram_ridley_backpogo_right_rng = !ENEMY_VAR_5+!ENEMY_1F_OFFSET + !HUD_TILEMAP = $7EC600 !MAP_COUNTER = $7ECAE8 ; Not used in vanilla !SCROLLS = $7ECD20 @@ -1219,6 +1246,35 @@ endif !DOOR_PORTAL_HORIZONTAL_MIRRORING_BIT = #$0010 !DOOR_PORTAL_EXCLUDE_JUMP_MASK = #$FFF7 +!RIDLEY_RNG_POGO_HEIGHT_MASK = #$0007 +!RIDLEY_RNG_POGO_HEIGHT_INVERTED = #$FFF8 +!RIDLEY_RNG_BACKPOGO_LEFT_MASK = #$0038 +!RIDLEY_RNG_BACKPOGO_LEFT_INVERTED = #$FFC7 +!RIDLEY_RNG_75_25_LUNGE = #$0040 +!RIDLEY_RNG_75_25_POGO = #$0080 +!RIDLEY_RNG_75_25_MASK = #$00C0 +!RIDLEY_RNG_75_25_INVERTED = #$FF3F +!RIDLEY_RNG_CERES_FIREBALL = #$0100 +!RIDLEY_RNG_CERES_LUNGE = #$0200 +!RIDLEY_RNG_CERES_SWOOP = #$0300 +!RIDLEY_RNG_CERES_MASK = #$0700 +!RIDLEY_RNG_CERES_INVERTED = #$F8FF +!RIDLEY_RNG_BACKPOGO_RIGHT_MASK = #$3800 +!RIDLEY_RNG_BACKPOGO_RIGHT_INVERTED = #$C7FF +!RIDLEY_RNG_50_50_SWOOP = #$4000 +!RIDLEY_RNG_50_50_POGO = #$8000 +!RIDLEY_RNG_50_50_MASK = #$C000 +!RIDLEY_RNG_50_50_INVERTED = #$3FFF + +!RIDLEY_RNG_HOVER_TIME_MASK = #$003F +!RIDLEY_RNG_HOVER_TIME_INVERTED = #$FFC0 +!RIDLEY_RNG_ALL_FIREBALL = #$0040 +!RIDLEY_RNG_NO_FIREBALL = #$0080 +!RIDLEY_RNG_FIREBALL_MASK = #$00C0 +!RIDLEY_RNG_FIREBALL_INVERTED = #$FF3F +!RIDLEY_RNG_POGO_TIME_MASK = #$FF00 +!RIDLEY_RNG_POGO_TIME_INVERTED = #$00FF + !PROFILE_CUSTOM = #$0000 !PROFILE_Twitch = #$0001 !PROFILE_Default = #$0002 diff --git a/src/enemy_rng.asm b/src/enemy_rng.asm index 9bd1451b..e9916bc2 100644 --- a/src/enemy_rng.asm +++ b/src/enemy_rng.asm @@ -25,13 +25,13 @@ endif .enabled ; fake the fade in so it takes the same number of frames - LDA !ENEMY_VAR_3+$40 : INC - CMP !ENEMY_VAR_4+$40 : BCS .inc - STZ !ENEMY_VAR_4+$40 + LDA !ENEMY_VAR_3+!ENEMY_1_OFFSET : INC + CMP !ENEMY_VAR_4+!ENEMY_1_OFFSET : BCS .inc + STZ !ENEMY_VAR_4+!ENEMY_1_OFFSET SEC : RTS .inc - INC !ENEMY_VAR_4+$40 + INC !ENEMY_VAR_4+!ENEMY_1_OFFSET CLC : RTS } @@ -438,7 +438,7 @@ if !FEATURE_PAL else LDA $CD53,Y endif - STA !ENEMY_FUNCTION_POINTER+$40 + STA !ENEMY_FUNCTION_POINTER+!ENEMY_1_OFFSET JSL $808111 BIT #$0001 RTL @@ -468,7 +468,8 @@ if !FEATURE_PAL else LDA $CD53,Y endif - STA !ENEMY_FUNCTION_POINTER+$40 ; Intentional fallthrough to invert logic + STA !ENEMY_FUNCTION_POINTER+!ENEMY_1_OFFSET + ; Intentional fallthrough to invert logic } hook_phantoon_invert: @@ -542,7 +543,7 @@ endif BNE .round1 ; Save the pattern timer, check the direction, ; and set Phantoon's starting point and pattern index. - LSR : STA !ENEMY_FUNCTION_POINTER+$40 : BCS .round2left + LSR : STA !ENEMY_FUNCTION_POINTER+!ENEMY_1_OFFSET : BCS .round2left ; Right pattern LDA #$0088 : LDY #$00D0 @@ -559,7 +560,7 @@ endif .round1 ; Save the pattern timer and check the direction - LSR : STA !ENEMY_FUNCTION_POINTER+$40 + LSR : STA !ENEMY_FUNCTION_POINTER+!ENEMY_1_OFFSET BCS .round1left ; Round 1 right pattern @@ -996,6 +997,137 @@ endif RTS } +; Migrated from bank A6 since not enough freespace there +init_ceres_ridley_rng: +{ + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_CERES_MASK : BEQ .set_ceres_rng + CMP !RIDLEY_RNG_CERES_FIREBALL : BEQ .ceres_fireball + CMP !RIDLEY_RNG_CERES_LUNGE : BEQ .ceres_lunge + CMP !RIDLEY_RNG_CERES_SWOOP : BEQ .ceres_swoop + TDC : BRA .set_ceres_rng + + .ceres_fireball +if !FEATURE_PAL + LDA #$A792 +else + LDA #$A782 +endif + BRA .set_ceres_rng + + .ceres_lunge +if !FEATURE_PAL + LDA #$A84C +else + LDA #$A83C +endif + BRA .set_ceres_rng + + .ceres_swoop +if !FEATURE_PAL + LDA #$A8(D +else + LDA #$A88D +endif + + .set_ceres_rng + STA !eram_ceres_ridley_rng + RTL +} + +init_zebes_ridley_rng: +{ + LDA !ram_ridley_rng_flags + BIT !RIDLEY_RNG_75_25_LUNGE : BNE .set_75_25_lunge + BIT !RIDLEY_RNG_75_25_POGO : BNE .set_75_25_pogo +if !FEATURE_PAL + LDA #$B3BC +else + LDA #$B3AC +endif + BRA .set_75_25 + + .set_75_25_lunge +if !FEATURE_PAL + LDA #$B3EC +else + LDA #$B3DC +endif + BRA .set_75_25 + + .set_75_25_pogo +if !FEATURE_PAL + LDA #$B3CC +else + LDA #$B3BC +endif + + .set_75_25 + STA !eram_ridley_lunge_pogo_rng + + LDA !ram_ridley_rng_flags + BIT !RIDLEY_RNG_50_50_SWOOP : BNE .set_50_50_swoop + BIT !RIDLEY_RNG_50_50_POGO : BNE .set_50_50_pogo +if !FEATURE_PAL + LDA #$B3AC +else + LDA #$B39C +endif + STA !eram_ridley_swoop_pogo_rng +if !FEATURE_PAL + LDA #$B39C +else + LDA #$B38C +endif + BRA .set_50_50 + + .set_50_50_swoop + LDA #ridley_all_swoop_table + BRA .set_50_50_both + + .set_50_50_pogo +if !FEATURE_PAL + LDA #$B3CC +else + LDA #$B3BC +endif + + .set_50_50_both + STA !eram_ridley_swoop_pogo_rng + .set_50_50 + STA !eram_ridley_pogo_swoop_rng + + LDA !ram_ridley_rng_times_and_fireball + BIT !RIDLEY_RNG_ALL_FIREBALL : BNE .set_all_fireball + BIT !RIDLEY_RNG_NO_FIREBALL : BNE .set_no_fireball + TDC : BRA .set_fireball + + .set_all_fireball + LDA #$0081 + BRA .set_fireball + + .set_no_fireball + TDC : INC + + .set_fireball + STA !eram_ridley_fireball_rng + + LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_HOVER_TIME_MASK + STA !eram_ridley_hover_time_rng + + LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_POGO_TIME_MASK + XBA : STA !eram_ridley_pogo_time_rng + + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_POGO_HEIGHT_MASK + STA !eram_ridley_pogo_height_rng + + PHX : LDA !ram_ridley_rng_flags : LSR #2 : PHA + AND #$000E : TAX : LDA.l ridley_backpogo_threshold_table,X + STA !eram_ridley_backpogo_left_rng : PLA : XBA + AND #$000E : TAX : LDA.l ridley_backpogo_threshold_table,X + STA !eram_ridley_backpogo_right_rng : PLX + RTL +} + %endfree(A5) @@ -1031,6 +1163,261 @@ org $A6A360 endif LDA #ridley_init_hook +if !FEATURE_PAL +org $A6A72C +else +org $A6A71C +endif + BCC $0E ; overwrite a NOP to save one byte + +if !FEATURE_PAL +org $A6A73A +else +org $A6A72A +endif + BCC $55 ; branch to a different RTS since we overwrite the original + + ; See if Ceres Ridley RNG is fixed, requires five bytes + LDA !eram_ceres_ridley_rng : BNE ceres_ridley_set_ai + + ; Original vanilla RNG + LDA !CACHED_RANDOM_NUMBER : AND #$000F + ASL : TAX : LDA.w ceres_ridley_set_ai_table,X +ceres_ridley_set_ai: + STA !ENEMY_FUNCTION_POINTER + + ; We need to save five bytes, but we already saved one + ; Replacing LDA #$0000 with TDC saves two more + ; Jumping to another location that does STA $7E7800 : RTS saves two more + TDC +if !FEATURE_PAL + JMP $B4CE +else + JMP $B4BE +endif +ceres_ridley_set_ai_table: +%warnpc($A6A743, $A6A753) + +if !FEATURE_PAL +org $A6B36F +else +org $A6B35F +endif + LDY !eram_ridley_pogo_swoop_rng + +if !FEATURE_PAL +org $A6B385 +else +org $A6B375 +endif + LDY !eram_ridley_lunge_pogo_rng + +if !FEATURE_PAL +org $A6B38B +else +org $A6B37B +endif + LDY !eram_ridley_pogo_swoop_rng + +if !FEATURE_PAL +org $A6B396 +else +org $A6B386 +endif + LDY !eram_ridley_swoop_pogo_rng + +if !FEATURE_PAL +org $A6B3DC +else +org $A6B3CC +endif +ridley_all_hover_table: + ; move hover start back five bytes +if !FEATURE_PAL + dw $B5CF, $B5CF, $B5CF, $B5CF, $B5CF, $B5CF, $B5CF, $B5CF +else + dw $B5BF, $B5BF, $B5BF, $B5BF, $B5BF, $B5BF, $B5BF, $B5BF +endif + +if !FEATURE_PAL +org $A6B5CF +else +org $A6B5BF +endif + ; Vanilla logic from $A6:B5C4 + LDA #$000B : STA $7E201E + LDA #$0180 : STA $7E2012 +if !FEATURE_PAL + LDA #$B5F5 +else + LDA #$B5E5 +endif + STA !ENEMY_FUNCTION_POINTER + + ; Check if we have a fixed hover delay + LDA !eram_ridley_hover_time_rng : BNE $0A + + ; Continue to vanilla logic +%warnpc($A6B5D8, $A6B5E8) + +if !FEATURE_PAL +org $A6B605 + JMP $B69C +else ; Move jump by one byte due to below changes +org $A6B5F5 + JMP $B68C +endif + +if !FEATURE_PAL +org $A6B633 + JMP $B69C +else ; Move jump by one byte due to below changes +org $A6B623 + JMP $B68C +endif + +if !FEATURE_PAL +org $A6B651 +else +org $A6B641 +endif + ; We need to save five bytes, which we can do if we switch to 8-bit mode, + ; but this means we now need to save eleven bytes + ; Start by replacing LDX #$0000 with TDC : TAX (saved 1, spent 0) + TDC : TAX + ; Vanilla logic + LDA !SAMUS_Y : CMP #$0160 : BMI $03 + LDA #$0160 + STA $14 +if !FEATURE_PAL + JSR $B43E + JSR $D533 +else + JSR $B42E + JSR $D523 +endif + ; Replace LDA #$0001 with TDC : INC (saved 2, spent 0) + TDC : INC : STA $7E2004 + ; Switch to 8-bit mode (saved 2, spent 2) + %a8() + ; Skip AND #$00FF and reduce CMP #$0003 (saved 6, spent 2) + LDA !SAMUS_MOVEMENT_TYPE : CMP #$03 + BNE $23 + ; New logic (saved 6, spent 7) + LDA !eram_ridley_fireball_rng : BNE $03 + ; Original logic, but skip AND #$00FF and reduce #$0080 (saved 10, spent 7) + LDA !CACHED_RANDOM_NUMBER : CMP #$80 + ; Switch back to 16-bit mode (saved 10, spent 9) + %a16() + ; Vanilla logic + BCC $13 + LDA $7E781E : BNE $0D + LDA $7E7820 : DEC : BEQ $06 +if !FEATURE_PAL + LDA #$E711 + JSR $D43E +else + LDA #$E73A + JSR $D467 +endif + CLC : RTS + ; Switch back to 16-bit mode (saved 10, spent 11) + %a16() + SEC : RTS + ; Start into the next routine one byte later than vanilla + LDA #$00F0 : STA $7E2012 + LDA #$0010 : STA $7E201E + ; Replace LDA #$0001 with TDC : INC (saved 11, spent 11) + TDC : INC +%warnpc($A6B69C, $A6B6AC) + +if !FEATURE_PAL +org $A6B6BD +else ; Migrate vanilla routine up five bytes +org $A6B6AD +endif + BMI $1A + +if !FEATURE_PAL +org $A6B6C5 +else +org $A6B6B5 +endif + LDA.w ridley_acceleration_table,Y + +if !FEATURE_PAL +org $A6B6D9 + JSR $D92C + LDA #$B6E8 +else ; Migrate vanilla routine up five bytes +org $A6B6C9 + JSR $D955 + LDA #$B6D8 +endif + STA !ENEMY_FUNCTION_POINTER + LDA #$0020 : STA !ENEMY_VAR_5 + ; Start into the next routine five bytes earlier than vanilla + LDA !ENEMY_X : STA $12 + LDA #$0120 : STA $14 + LDX #$0000 : LDY #$0000 +if !FEATURE_PAL + JSR $D4FA +else + JSR $D523 +endif + DEC !ENEMY_VAR_5 : BPL $1D +if !FEATURE_PAL + JSR $CB0A + JSR ridley_set_pogo_height + LDA #$B71E +else + JSR $CB33 + JSR ridley_set_pogo_height + LDA #$B70E +endif + STA !ENEMY_FUNCTION_POINTER + ; Add new logic here + LDA !eram_ridley_pogo_time_rng : BNE $09 +%warnpc($A6B701, $A6B711) + + if !FEATURE_PAL +org $A6B772 +else +org $A6B762 +endif + JSR ridley_set_pogo_height + +if !FEATURE_PAL +org $A6B8EB +else +org $A6B8DB +endif + CMP !eram_ridley_backpogo_right_rng + +if !FEATURE_PAL +org $A6B90D +else +org $A6B8FD +endif + CMP !eram_ridley_backpogo_left_rng + +if !FEATURE_PAL +org $A6B93B +else +org $A6B92B +endif + LDA.w ridley_pogo_parameter_table,Y + +if !FEATURE_PAL +org $A6B95D +else +org $A6B94D +endif +ridley_set_pogo_height: + LDA !eram_ridley_pogo_height_rng : BEQ $BD + DEC : BRA $C0 +%warnpc($A6B959, $A6B969) + if !FEATURE_PAL org $A6EFA9 else @@ -1100,6 +1487,22 @@ endif %startfree(A6) +ridley_acceleration_table: + dw #$00B0, #$0080, #$0060 + +ridley_pogo_parameter_table: + dw #$000A, #$0010, #$0020, #$0030, #$0040, #$0050 + +ridley_all_swoop_table: +if !FEATURE_PAL + dw $B451, $B451, $B451, $B451, $B451, $B451, $B451, $B451 +else + dw $B441, $B441, $B441, $B441, $B441, $B441, $B441, $B441 +endif + +ridley_backpogo_threshold_table: + dw #$0555, #$0AAA, #$0FFF, #$1AA9, #$2AA8, #$4551, #$6FF9, #$0000 + ridley_reset_damagecounter: { TDC : STA !DAMAGE_COUNTER @@ -1108,7 +1511,9 @@ ridley_reset_damagecounter: ridley_init_hook: { - LDA !ROOM_ID : CMP.w #ROOM_CeresRidleyRoom : BNE .continue + LDA !ROOM_ID : CMP.w #ROOM_CeresRidleyRoom : BNE .not_ceres + JSL init_ceres_ridley_rng + LDA $7ED82E : BIT #$0001 : BEQ .continue ; Ceres Ridley is already dead, so skip to the escape @@ -1132,6 +1537,9 @@ endif STA !ENEMY_FUNCTION_POINTER JMP (!ENEMY_FUNCTION_POINTER) + .not_ceres + JSL init_zebes_ridley_rng + .continue if !FEATURE_PAL LDA #$A387 diff --git a/src/infohud.asm b/src/infohud.asm index 60334949..2b3d9010 100644 --- a/src/infohud.asm +++ b/src/infohud.asm @@ -1951,16 +1951,16 @@ infidoppler_hook_fire_missile: LDX $14 ; projectile index SEC - LDA !SAMUS_X_SUBPX : SBC !ram_infidoppler_subx - AND #$FF00 : STA !ram_infidoppler_offsets,X - LDA !SAMUS_X : SBC !ram_infidoppler_x - AND #$00FF : ORA !ram_infidoppler_offsets,X : STA !ram_infidoppler_offsets,X + LDA !SAMUS_X_SUBPX : SBC !eram_infidoppler_subx + AND #$FF00 : STA !eram_infidoppler_offsets,X + LDA !SAMUS_X : SBC !eram_infidoppler_x + AND #$00FF : ORA !eram_infidoppler_offsets,X : STA !eram_infidoppler_offsets,X - LDA !ram_infidoppler_x : STA !SAMUS_X - LDA !ram_infidoppler_subx : STA !SAMUS_X_SUBPX + LDA !eram_infidoppler_x : STA !SAMUS_X + LDA !eram_infidoppler_subx : STA !SAMUS_X_SUBPX - LDA !ram_infidoppler_y : STA !SAMUS_Y - LDA !ram_infidoppler_suby : STA !SAMUS_Y_SUBPX + LDA !eram_infidoppler_y : STA !SAMUS_Y + LDA !eram_infidoppler_suby : STA !SAMUS_Y_SUBPX .done DEC !SAMUS_MISSILES @@ -1994,21 +1994,23 @@ infidoppler_hook_projectile_collision: CPX #$0000 : BNE .no ; Is this phantoon? ; Is phantoon in a swoop? + LDA !ENEMY_VAR_5 if !FEATURE_PAL - LDA !ENEMY_VAR_5 : CMP #$D6AC : BNE .no + CMP #$D6AC else - LDA !ENEMY_VAR_5 : CMP #$D678 : BNE .no + CMP #$D678 endif + BNE .no ; Stop infidoppler if health is 100 or less LDA !ENEMY_HP : CMP #$0065 : BCC .disable ; Initialize infidoppler LDA #$FFFF : STA !ram_infidoppler_active - LDA !SAMUS_X : STA !ram_infidoppler_x - LDA !SAMUS_X_SUBPX : STA !ram_infidoppler_subx - LDA !SAMUS_Y : STA !ram_infidoppler_y - LDA !SAMUS_Y_SUBPX : STA !ram_infidoppler_suby + LDA !SAMUS_X : STA !eram_infidoppler_x + LDA !SAMUS_X_SUBPX : STA !eram_infidoppler_subx + LDA !SAMUS_Y : STA !eram_infidoppler_y + LDA !SAMUS_Y_SUBPX : STA !eram_infidoppler_suby BRA .no @@ -2017,7 +2019,7 @@ endif ; We've shot Phantoon with a missile in infidoppler mode. ; if projectile variable is 0, this missile has already hit - LDA !ram_infidoppler_offsets,X + LDA !eram_infidoppler_offsets,X BEQ .done ; Stop infidoppler if health is 100 or less @@ -2026,14 +2028,14 @@ endif ; Subtract projectile variable from missile position ; the LOW 8 bits are pixels, the HIGH 8 bits are fractional ; yes, it's weird. but it saves a couple XBAs - LDA !ram_infidoppler_offsets,X : PHA : AND #$FF00 : SEC + LDA !eram_infidoppler_offsets,X : PHA : AND #$FF00 : SEC EOR #$FFFF : ADC !SAMUS_PROJ_X_SUBPX,Y : STA !SAMUS_PROJ_X_SUBPX,Y PLA : AND #$00FF EOR #$FFFF : ADC !SAMUS_PROJ_X,Y : STA !SAMUS_PROJ_X,Y ; halve damage, since it will double hit LSR !SAMUS_PROJ_DAMAGE,X - TDC : STA !ram_infidoppler_offsets,X + TDC : STA !eram_infidoppler_offsets,X TAX : INC .done diff --git a/src/infohudmodes.asm b/src/infohudmodes.asm index 87bf8188..c98ecf74 100644 --- a/src/infohudmodes.asm +++ b/src/infohudmodes.asm @@ -3743,22 +3743,22 @@ status_robotflush: { ; Checking hit on first robot LDA !IH_BLANK : STA !HUD_TILEMAP+$88 - LDA !ENEMY_VAR_1+$40 : CMP #$0030 : BMI .checkfirstfall + LDA !ENEMY_VAR_1+!ENEMY_1_OFFSET : CMP #$0030 : BMI .checkfirstfall LDA #$0C3C : STA !HUD_TILEMAP+$88 .checkfirstfall LDA !IH_BLANK : STA !HUD_TILEMAP+$8A - LDA !ENEMY_Y+$40 : CMP #$0280 : BMI .checksecondhit + LDA !ENEMY_Y+!ENEMY_1_OFFSET : CMP #$0280 : BMI .checksecondhit LDA #$0C3C : STA !HUD_TILEMAP+$8A .checksecondhit LDA !IH_BLANK : STA !HUD_TILEMAP+$8C - LDA !ENEMY_VAR_1+$80 : CMP #$0030 : BMI .checksecondfall + LDA !ENEMY_VAR_1+!ENEMY_2_OFFSET : CMP #$0030 : BMI .checksecondfall LDA #$0C3D : STA !HUD_TILEMAP+$8C .checksecondfall LDA !IH_BLANK : STA !HUD_TILEMAP+$8E - LDA !ENEMY_VAR_5+$80 : CMP #$0280 : BMI .done + LDA !ENEMY_VAR_5+!ENEMY_2_OFFSET : CMP #$0280 : BMI .done LDA #$0C3D : STA !HUD_TILEMAP+$8E .done @@ -4521,13 +4521,13 @@ if !FEATURE_PAL ; B2 -> END dw $B303, $B331, $B3FC ; [$00+6] B3 dw $B408, $B451, $B465, $B4A3, $B4E1 ; [$06+A] B4 - dw $B526, $B564, $B5A4, $B5F5 ; [$10+8] B5 - dw $B623, $B6B7, $B6ED ; [$18+6] B6 - dw $B71E, $B7C9 ; [$1E+4] B7 + dw $B526, $B564, $B5A4, $B5CF, $B5F5 ; [$10+A] B5 (B5D4 moved back to B5CF to recover five bytes) + dw $B623, $B6B7, $B6E8 ; [$1A+6] B6 + dw $B71E, $B7C9 ; [$20+4] B7 ; B8, B9 -> END - dw $BAC7 ; [$22+2] BA - dw $BB9F, $BBD4 ; [$24+4] BB - dw $BC01, $BC3E, $BC64 ; [$28+6] BC + dw $BAC7 ; [$24+2] BA + dw $BB9F, $BBD4 ; [$26+4] BB + dw $BC01, $BC3E ; [$2A+4] BC dw $BD5E ; [$2E+2] BD ; BE, BF, C0, C1, C2, C3, C4 -> END dw $C50F, $C55F ; [$30+4] C5 @@ -4535,13 +4535,13 @@ else dw $B2F3 ; [$00+2] B2 dw $B321, $B3EC, $B3F8 ; [$02+6] B3 dw $B441, $B455, $B493, $B4D1 ; [$08+8] B4 - dw $B516, $B554, $B594, $B5E5 ; [$10+8] B5 - dw $B613, $B6A7, $B6DD ; [$18+6] B6 - dw $B70E, $B7B9 ; [$1E+4] B7 + dw $B516, $B554, $B594, $B5BF, $B5E5 ; [$10+A] B5 (B5C4 moved back to B5BF to recover five bytes) + dw $B613, $B6A7, $B6D8 ; [$1A+6] B6 + dw $B70E, $B7B9 ; [$20+4] B7 ; B8, B9 -> END - dw $BAB7 ; [$22+2] BA - dw $BB8F, $BBC4, $BBF1 ; [$24+6] BB - dw $BC2E, $BC54 ; [$2A+4] BC + dw $BAB7 ; [$24+2] BA + dw $BB8F, $BBC4, $BBF1 ; [$26+6] BB + dw $BC2E ; [$2C+2] BC dw $BD4E ; [$2E+2] BD ; BE, BF, C0, C1, C2, C3, C4 -> END dw $C538, $C588 ; [$30+4] C5 @@ -4552,12 +4552,12 @@ RidleyAI_prefix_table: ; Unused entries are filled with $32 (the last element in the table) to finish the search faster if !FEATURE_PAL ; B2 B3 B4 B5 B6 B7 BA BB BC BD - db $34, $00, $06, $10, $18, $1E, $34, $34, $22, $24, $28, $2E, $34, $34, $34, $34 + db $34, $00, $06, $10, $1A, $20, $34, $34, $24, $26, $2A, $2E, $34, $34, $34, $34 ; C5 db $34, $34, $34, $30, $34, $34, $34, $34, $34, $34, $34, $34, $34, $34, $34, $34 else ; B2 B3 B4 B5 B6 B7 BA BB BC BD - db $00, $02, $08, $10, $18, $1E, $34, $34, $22, $24, $2A, $2E, $34, $34, $34, $34 + db $00, $02, $08, $10, $1A, $20, $34, $34, $24, $26, $2C, $2E, $34, $34, $34, $34 ; C5 db $34, $34, $34, $30, $34, $34, $34, $34, $34, $34, $34, $34, $34, $34, $34, $34 endif @@ -4574,6 +4574,7 @@ RidleyAI_text_table: dw #RidleyAIText_B516 ; climb dw #RidleyAIText_B554 ; climbing dw #RidleyAIText_B594 ; swoop end + dw #RidleyAIText_B5C4 ; hover start dw #RidleyAIText_B5E5 ; hover dw #RidleyAIText_B613 ; hover spin dw #RidleyAIText_B6A7 ; pogo start @@ -4585,7 +4586,6 @@ RidleyAI_text_table: dw #RidleyAIText_BBC4 ; grab move dw #RidleyAIText_BBF1 ; dropping dw #RidleyAIText_BC2E ; dropped - dw #RidleyAIText_BC54 ; hover start dw #RidleyAIText_BD4E ; dodge power bomb dw #RidleyAIText_C538 ; dead move dw #RidleyAIText_C588 ; explode @@ -4605,6 +4605,7 @@ table ../resources/HUDfont.tbl .B516 : db "CLIMB" : db $FF .B554 : db "CLIMBING" : db $FF .B594 : db "SWOOP END" : db $FF + .B5C4 : db "HOVER START" : db $FF .B5E5 : db "HOVER" : db $FF .B613 : db "HOVER SPIN" : db $FF .B6A7 : db "POGO START" : db $FF @@ -4616,7 +4617,6 @@ table ../resources/HUDfont.tbl .BBC4 : db "GRAB MOVE" : db $FF .BBF1 : db "DROP SAMUS" : db $FF .BC2E : db "DROPPED" : db $FF - .BC54 : db "HOVER START" : db $FF .BD4E : db "DODGE PB" : db $FF .C538 : db "DEAD MOVE" : db $FF .C588 : db "EXPLODE" : db $FF @@ -4912,7 +4912,7 @@ status_zebskip: status_mbhp: { - LDA !ENEMY_HP+$40 : CMP !ram_HUD_check : BEQ .done : STA !ram_HUD_check + LDA !ENEMY_HP+!ENEMY_1_OFFSET : CMP !ram_HUD_check : BEQ .done : STA !ram_HUD_check LDX #$0088 : JSR Draw4 .done diff --git a/src/layout.asm b/src/layout.asm index 2899ac11..5be0cbfa 100644 --- a/src/layout.asm +++ b/src/layout.asm @@ -1328,7 +1328,7 @@ layout_asm_waterway_external: layout_asm_mb_external: { ; Replace MB enemy with maprando variant - LDA #layout_maprando_mb_enemy_header : STA !ENEMY_ID+$40 + LDA #layout_maprando_mb_enemy_header : STA !ENEMY_ID+!ENEMY_1_OFFSET ; Place the four barrier ceiling LDA #$82E6 : STA $7F016E : STA $7F0170 : STA $7F0172 @@ -2300,7 +2300,7 @@ layout_asm_mb_spawn_escape_door: dw $0600, $B677 ; Replace MB enemy with maprando variant - LDA #layout_maprando_mb_enemy_header : STA !ENEMY_ID+$40 + LDA #layout_maprando_mb_enemy_header : STA !ENEMY_ID+!ENEMY_1_OFFSET ; Fallthrough to Mother Brain HP } diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 52c34b18..c8d133db 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -2545,7 +2545,14 @@ endif ; !FEATURE_VANILLAHUD ; ---------- RngMenu: - dw #rng_goto_phanmenu + dw #rng_goto_phantoon + dw #rng_goto_ridley + dw #$FFFF + dw #rng_kraid_claw_rng + dw #rng_kraid_wait_rng + dw #$FFFF + dw #rng_crocomire_rng + dw #$FFFF dw #$FFFF dw #rng_botwoon_first dw #rng_botwoon_hidden @@ -2556,17 +2563,15 @@ RngMenu: dw #rng_draygon_rng_left dw #rng_turret_rng dw #$FFFF - dw #rng_crocomire_rng - dw #$FFFF - dw #rng_kraid_claw_rng - dw #rng_kraid_wait_rng - dw #$FFFF dw #rng_baby_rng dw #$0000 %cm_header("BOSS RNG CONTROL") -rng_goto_phanmenu: - %cm_jsl("Phantoon Menu", ih_prepare_phantoon_menu, #PhantoonMenu) +rng_goto_phantoon: + %cm_jsl("Phantoon Menu", rng_prepare_phantoon_menu, #RngPhantoonMenu) + +rng_goto_ridley: + %cm_jsl("Ridley Menu", rng_prepare_ridley_menu, #RngRidleyMenu) rng_botwoon_first: dw !ACTION_CHOICE @@ -2754,42 +2759,42 @@ rng_baby_rng: ; Phantoon Menu ; -------------- -ih_prepare_phantoon_menu: +rng_prepare_phantoon_menu: { LDA !ram_phantoon_rng_inverted : PHA - JSL phan_set_phan_first_phase - JSL phan_set_phan_second_phase + JSL rng_phan_set_phan_first_phase + JSL rng_phan_set_phan_second_phase PLA : STA !ram_phantoon_rng_inverted %setmenubank() JML action_submenu } -PhantoonMenu: - dw #phan_first_phase - dw #phan_fast_left_1 - dw #phan_mid_left_1 - dw #phan_slow_left_1 - dw #phan_fast_right_1 - dw #phan_mid_right_1 - dw #phan_slow_right_1 - dw #phan_second_phase - dw #phan_fast_left_2 - dw #phan_mid_left_2 - dw #phan_slow_left_2 - dw #phan_fast_right_2 - dw #phan_mid_right_2 - dw #phan_slow_right_2 - dw #phan_second_phase_inverted - dw #$FFFF - dw #phan_eyeclose - dw #phan_flamepattern - dw #phan_next_flamepattern - dw #phan_flame_direction - dw #phan_always_visible +RngPhantoonMenu: + dw #rng_phan_first_phase + dw #rng_phan_fast_left_1 + dw #rng_phan_mid_left_1 + dw #rng_phan_slow_left_1 + dw #rng_phan_fast_right_1 + dw #rng_phan_mid_right_1 + dw #rng_phan_slow_right_1 + dw #rng_phan_second_phase + dw #rng_phan_fast_left_2 + dw #rng_phan_mid_left_2 + dw #rng_phan_slow_left_2 + dw #rng_phan_fast_right_2 + dw #rng_phan_mid_right_2 + dw #rng_phan_slow_right_2 + dw #rng_phan_second_phase_inverted + dw #$FFFF + dw #rng_phan_eyeclose + dw #rng_phan_flamepattern + dw #rng_phan_next_flamepattern + dw #rng_phan_flame_direction + dw #rng_phan_always_visible dw #$0000 %cm_header("PHANTOON RNG CONTROL") -phan_first_phase: +rng_phan_first_phase: dw !ACTION_CHOICE dl #!ram_cm_phan_first_phase dw .routine @@ -2813,10 +2818,10 @@ phan_first_phase: db #$FF .routine ASL : TAX - LDA.l phan_phase_1_table,X : STA !ram_phantoon_rng_round_1 + LDA.l rng_phan_phase_1_table,X : STA !ram_phantoon_rng_round_1 RTL -phan_second_phase: +rng_phan_second_phase: dw !ACTION_CHOICE dl #!ram_cm_phan_second_phase dw .routine @@ -2840,39 +2845,39 @@ phan_second_phase: db #$FF .routine ASL : TAX - LDA.l phan_phase_2_table,X : STA !ram_phantoon_rng_round_2 + LDA.l rng_phan_phase_2_table,X : STA !ram_phantoon_rng_round_2 BEQ .set_inverted : TXA : BEQ .set_inverted LDA #$0002 .set_inverted STA !ram_phantoon_rng_inverted RTL -phan_phase_1_table: +rng_phan_phase_1_table: dw #$003F, #$0020, #$0008, #$0002, #$0010, #$0004, #$0001, #$0030 dw #$000C, #$0003, #$000F, #$0033, #$003C, #$002A, #$0015, #$0000 -phan_phase_2_table: +rng_phan_phase_2_table: dw #$003F, #$0020, #$0008, #$0002, #$0010, #$0004, #$0001, #$0030 dw #$000C, #$0003, #$0007, #$0023, #$0024, #$0022, #$0005, #$0000 -phan_set_phan_first_phase: +rng_phan_set_phan_first_phase: { LDX #$0000 LDA !ram_phantoon_rng_round_1 : BEQ .end_first_loop .first_loop - CMP.l phan_phase_1_table,X : BEQ .end_first_loop + CMP.l rng_phan_phase_1_table,X : BEQ .end_first_loop INX #2 : CPX #$001E : BNE .first_loop .end_first_loop TXA : LSR : STA !ram_cm_phan_first_phase RTL } -phan_set_phan_second_phase: +rng_phan_set_phan_second_phase: { LDX #$0000 LDA !ram_phantoon_rng_round_2 : BEQ .end_second_loop .second_loop - CMP.l phan_phase_2_table,X : BEQ .end_second_loop + CMP.l rng_phan_phase_2_table,X : BEQ .end_second_loop INX #2 : CPX #$001E : BNE .second_loop .end_second_loop TXA : LSR : STA !ram_cm_phan_second_phase @@ -2883,43 +2888,43 @@ phan_set_phan_second_phase: RTL } -phan_fast_left_1: - %cm_toggle_bit("#1 Fast Left", !ram_phantoon_rng_round_1, #$0020, phan_set_phan_first_phase) +rng_phan_fast_left_1: + %cm_toggle_bit("#1 Fast Left", !ram_phantoon_rng_round_1, #$0020, rng_phan_set_phan_first_phase) -phan_mid_left_1: - %cm_toggle_bit("#1 Mid Left", !ram_phantoon_rng_round_1, #$0008, phan_set_phan_first_phase) +rng_phan_mid_left_1: + %cm_toggle_bit("#1 Mid Left", !ram_phantoon_rng_round_1, #$0008, rng_phan_set_phan_first_phase) -phan_slow_left_1: - %cm_toggle_bit("#1 Slow Left", !ram_phantoon_rng_round_1, #$0002, phan_set_phan_first_phase) +rng_phan_slow_left_1: + %cm_toggle_bit("#1 Slow Left", !ram_phantoon_rng_round_1, #$0002, rng_phan_set_phan_first_phase) -phan_fast_right_1: - %cm_toggle_bit("#1 Fast Right", !ram_phantoon_rng_round_1, #$0010, phan_set_phan_first_phase) +rng_phan_fast_right_1: + %cm_toggle_bit("#1 Fast Right", !ram_phantoon_rng_round_1, #$0010, rng_phan_set_phan_first_phase) -phan_mid_right_1: - %cm_toggle_bit("#1 Mid Right", !ram_phantoon_rng_round_1, #$0004, phan_set_phan_first_phase) +rng_phan_mid_right_1: + %cm_toggle_bit("#1 Mid Right", !ram_phantoon_rng_round_1, #$0004, rng_phan_set_phan_first_phase) -phan_slow_right_1: - %cm_toggle_bit("#1 Slow Right", !ram_phantoon_rng_round_1, #$0001, phan_set_phan_first_phase) +rng_phan_slow_right_1: + %cm_toggle_bit("#1 Slow Right", !ram_phantoon_rng_round_1, #$0001, rng_phan_set_phan_first_phase) -phan_fast_left_2: - %cm_toggle_bit("#2 Fast Left", !ram_phantoon_rng_round_2, #$0020, phan_set_phan_second_phase) +rng_phan_fast_left_2: + %cm_toggle_bit("#2 Fast Left", !ram_phantoon_rng_round_2, #$0020, rng_phan_set_phan_second_phase) -phan_mid_left_2: - %cm_toggle_bit("#2 Mid Left", !ram_phantoon_rng_round_2, #$0008, phan_set_phan_second_phase) +rng_phan_mid_left_2: + %cm_toggle_bit("#2 Mid Left", !ram_phantoon_rng_round_2, #$0008, rng_phan_set_phan_second_phase) -phan_slow_left_2: - %cm_toggle_bit("#2 Slow Left", !ram_phantoon_rng_round_2, #$0002, phan_set_phan_second_phase) +rng_phan_slow_left_2: + %cm_toggle_bit("#2 Slow Left", !ram_phantoon_rng_round_2, #$0002, rng_phan_set_phan_second_phase) -phan_fast_right_2: - %cm_toggle_bit("#2 Fast Right", !ram_phantoon_rng_round_2, #$0010, phan_set_phan_second_phase) +rng_phan_fast_right_2: + %cm_toggle_bit("#2 Fast Right", !ram_phantoon_rng_round_2, #$0010, rng_phan_set_phan_second_phase) -phan_mid_right_2: - %cm_toggle_bit("#2 Mid Right", !ram_phantoon_rng_round_2, #$0004, phan_set_phan_second_phase) +rng_phan_mid_right_2: + %cm_toggle_bit("#2 Mid Right", !ram_phantoon_rng_round_2, #$0004, rng_phan_set_phan_second_phase) -phan_slow_right_2: - %cm_toggle_bit("#2 Slow Right", !ram_phantoon_rng_round_2, #$0001, phan_set_phan_second_phase) +rng_phan_slow_right_2: + %cm_toggle_bit("#2 Slow Right", !ram_phantoon_rng_round_2, #$0001, rng_phan_set_phan_second_phase) -phan_second_phase_inverted: +rng_phan_second_phase_inverted: dw !ACTION_CHOICE dl #!ram_phantoon_rng_inverted dw #$0000 @@ -2930,7 +2935,7 @@ phan_second_phase_inverted: db #$28, "t RANDOM", #$FF db #$FF -phan_eyeclose: +rng_phan_eyeclose: dw !ACTION_CHOICE dl #!ram_phantoon_rng_eyeclose dw #$0000 @@ -2941,7 +2946,7 @@ phan_eyeclose: db #$28, " FAST", #$FF db #$FF -phan_flamepattern: +rng_phan_flamepattern: dw !ACTION_CHOICE dl #!ram_phantoon_rng_flames dw #$0000 @@ -2953,7 +2958,7 @@ phan_flamepattern: db #$28, " 1424212", #$FF db #$FF -phan_next_flamepattern: +rng_phan_next_flamepattern: dw !ACTION_CHOICE dl #!ram_phantoon_rng_next_flames dw #$0000 @@ -2965,7 +2970,7 @@ phan_next_flamepattern: db #$28, " 1424212", #$FF db #$FF -phan_flame_direction: +rng_phan_flame_direction: dw !ACTION_CHOICE dl #!ram_phantoon_flame_direction dw #$0000 @@ -2975,10 +2980,294 @@ phan_flame_direction: db #$28, " RIGHT", #$FF db #$FF -phan_always_visible: +rng_phan_always_visible: %cm_toggle("Always Visible", !ram_phantoon_always_visible, #$01, #0) +; MB delay before rainbow beam? [$9CAD] +; MB idles when above red beam HP [$B622] +; MB walk/attack/red beam [$B634] +; MB choose attack? [$B68D] +; MB in air 50/50 onions or fries [$B6EF] +; MB ground 50/50 bomb or choose attack? [$B70C] +; MB bomb consider crouch? [$B781] +; MB bomb crouch? [$B7B7] +; MB stand up or lean down? [$C1B2, $C1C0] +; MB phase 3 attack? [$C227, $C22F] +; MB walking? [$C285, $C704] + +; -------------- +; Ridley Menu +; -------------- + +rng_prepare_ridley_menu: +{ + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_POGO_HEIGHT_MASK + STA !ram_cm_ridley_pogo_height + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_LEFT_MASK + LSR #3 : STA !ram_cm_ridley_backpogo_left + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_75_25_MASK + ASL #2 : XBA : STA !ram_cm_ridley_lunge_pogo + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_CERES_MASK + XBA : STA !ram_cm_ridley_ceres_ai + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_RIGHT_MASK + XBA : LSR #3 : STA !ram_cm_ridley_backpogo_right + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_50_50_MASK + XBA : ASL #2 : XBA : STA !ram_cm_ridley_swoop_pogo + LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_HOVER_TIME_MASK + STA !ram_cm_ridley_hover_time_value : BEQ .set_hover + TDC : INC + .set_hover + STA !ram_cm_ridley_hover_time + LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_FIREBALL_MASK + ASL #2 : XBA : STA !ram_cm_ridley_hover_fireball + LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_POGO_TIME_MASK + XBA : STA !ram_cm_ridley_pogo_time_value : BEQ .set_pogo + TDC : INC + .set_pogo + STA !ram_cm_ridley_pogo_time + %setmenubank() + JML action_submenu +} + +RngRidleyMenu: + dw #rng_ridley_ceres_ai + dw #$FFFF + dw #rng_ridley_lunge_pogo + dw #rng_ridley_swoop_pogo + dw #rng_ridley_backpogo_left + dw #rng_ridley_backpogo_right + dw #rng_ridley_pogo_height + dw #$FFFF + dw #rng_ridley_pogo_time + dw #rng_ridley_pogo_time_dynamic + dw #rng_ridley_hover_time + dw #rng_ridley_hover_time_dynamic + dw #rng_ridley_hover_fireball + dw #$0000 + %cm_header("RIDLEY RNG CONTROL") + +rng_ridley_ceres_ai: + dw !ACTION_CHOICE + dl #!ram_cm_ridley_ceres_ai + dw #.routine + db #$28, "Ceres Ridley AI", #$FF + db #$28, " VANILLA", #$FF + db #$28, " FIREBALL", #$FF + db #$28, " LUNGE", #$FF + db #$28, " SWOOP", #$FF + db #$FF + .routine + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_CERES_INVERTED + STA !ram_ridley_rng_flags + LDA !ram_cm_ridley_ceres_ai : XBA + ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags + LDA !ROOM_ID : CMP.w #ROOM_CeresRidleyRoom : BNE .done + JML init_ceres_ridley_rng + .done + RTL + +rng_ridley_lunge_pogo: + dw !ACTION_CHOICE + dl #!ram_cm_ridley_lunge_pogo + dw #.routine + db #$28, "75/25 Lunge/Pog", #$FF + db #$28, "o VANILLA", #$FF + db #$28, "o LUNGE", #$FF + db #$28, "o POGO", #$FF + db #$FF + .routine + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_75_25_INVERTED + STA !ram_ridley_rng_flags + LDA !ram_cm_ridley_lunge_pogo : XBA : LSR #2 + ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags + LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done + JML init_zebes_ridley_rng + .done + RTL + +rng_ridley_swoop_pogo: + dw !ACTION_CHOICE + dl #!ram_cm_ridley_swoop_pogo + dw #.routine + db #$28, "50/50 Swoop/Pog", #$FF + db #$28, "o VANILLA", #$FF + db #$28, "o SWOOP", #$FF + db #$28, "o POGO", #$FF + db #$FF + .routine + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_50_50_INVERTED + STA !ram_ridley_rng_flags + LDA !ram_cm_ridley_swoop_pogo : XBA : LSR #2 : XBA + ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags + LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done + JML init_zebes_ridley_rng + .done + RTL + +rng_ridley_backpogo_left: + dw !ACTION_CHOICE + dl #!ram_cm_ridley_backpogo_left + dw #.routine + db #$28, "Backpogo Facing", #$FF + db #$28, " Left 1x", #$FF + db #$28, " Left 2x", #$FF + db #$28, " Left 3x", #$FF + db #$28, " Left 5x", #$FF + db #$28, " Left 8x", #$FF + db #$28, " Left 13x", #$FF + db #$28, " Left 21x", #$FF + db #$28, " Left 0x", #$FF + db #$FF + .routine + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_LEFT_INVERTED + STA !ram_ridley_rng_flags + LDA !ram_cm_ridley_backpogo_left : ASL #3 + ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags + LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done + JML init_zebes_ridley_rng + .done + RTL + +rng_ridley_backpogo_right: + dw !ACTION_CHOICE + dl #!ram_cm_ridley_backpogo_right + dw #.routine + db #$28, "Backpogo Facing", #$FF + db #$28, " Right 1x", #$FF + db #$28, " Right 2x", #$FF + db #$28, " Right 3x", #$FF + db #$28, " Right 5x", #$FF + db #$28, " Right 8x", #$FF + db #$28, " Right 13x", #$FF + db #$28, " Right 21x", #$FF + db #$28, " Right 0x", #$FF + db #$FF + .routine + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_RIGHT_INVERTED + STA !ram_ridley_rng_flags + LDA !ram_cm_ridley_backpogo_right : XBA : ASL #3 + ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags + LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done + JML init_zebes_ridley_rng + .done + RTL + +rng_ridley_pogo_height: + dw !ACTION_CHOICE + dl #!ram_cm_ridley_pogo_height + dw #.routine + db #$28, "Pogo Height", #$FF + db #$28, " RANDOM", #$FF + db #$28, " LOWEST", #$FF + db #$28, " LOWER", #$FF + db #$28, " HIGHER", #$FF + db #$28, " HIGHEST", #$FF + db #$FF + .routine + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_POGO_HEIGHT_INVERTED + ORA !ram_cm_ridley_pogo_height : STA !ram_ridley_rng_flags + LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done + JML init_zebes_ridley_rng + .done + RTL + +rng_ridley_pogo_time: + dw !ACTION_CHOICE + dl #!ram_cm_ridley_pogo_time + dw #.routine + db #$28, "Pogo Time", #$FF + db #$28, " RANDOM", #$FF + db #$28, " FIXED", #$FF + db #$FF + .routine + LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_POGO_TIME_INVERTED + STA !ram_ridley_rng_times_and_fireball + LDA !ram_cm_ridley_pogo_time : BEQ .set_value + LDA !ram_cm_ridley_pogo_time_value : BNE .set_value + LDA #$0080 : STA !ram_cm_ridley_pogo_time_value + .set_value + XBA : ORA !ram_ridley_rng_times_and_fireball : STA !ram_ridley_rng_times_and_fireball + LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done + JML init_zebes_ridley_rng + .done + RTL + +rng_ridley_pogo_time_dynamic: + dw !ACTION_DYNAMIC + dl #!ram_cm_ridley_pogo_time + dw #$0000 + dw #rng_ridley_pogo_time_value + +rng_ridley_pogo_time_value: + %cm_numfield("Pogo Time Value", !ram_cm_ridley_pogo_time_value, 128, 191, 1, 4, #.routine) + .routine + LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_POGO_TIME_INVERTED + STA !ram_ridley_rng_times_and_fireball + LDA !ram_cm_ridley_pogo_time_value : XBA + ORA !ram_ridley_rng_times_and_fireball : STA !ram_ridley_rng_times_and_fireball + LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done + JML init_zebes_ridley_rng + .done + RTL + +rng_ridley_hover_time: + dw !ACTION_CHOICE + dl #!ram_cm_ridley_hover_time + dw #.routine + db #$28, "Hover Time", #$FF + db #$28, " RANDOM", #$FF + db #$28, " FIXED", #$FF + db #$FF + .routine + LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_HOVER_TIME_INVERTED + STA !ram_ridley_rng_times_and_fireball + LDA !ram_cm_ridley_hover_time : BEQ .set_value + LDA !ram_cm_ridley_hover_time_value : BNE .set_value + LDA #$0020 : STA !ram_cm_ridley_hover_time_value + .set_value + ORA !ram_ridley_rng_times_and_fireball : STA !ram_ridley_rng_times_and_fireball + LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done + JML init_zebes_ridley_rng + .done + RTL + +rng_ridley_hover_time_dynamic: + dw !ACTION_DYNAMIC + dl #!ram_cm_ridley_hover_time + dw #$0000 + dw #rng_ridley_hover_time_value + +rng_ridley_hover_time_value: + %cm_numfield("Hover Time Value", !ram_cm_ridley_hover_time_value, 32, 63, 1, 4, #.routine) + .routine + LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_HOVER_TIME_INVERTED + ORA !ram_cm_ridley_hover_time_value : STA !ram_ridley_rng_times_and_fireball + LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done + JML init_zebes_ridley_rng + .done + RTL + +rng_ridley_hover_fireball: + dw !ACTION_CHOICE + dl #!ram_cm_ridley_hover_fireball + dw #.routine + db #$28, "50/50 Fireball", #$FF + db #$28, " VANILLA", #$FF + db #$28, " ALWAYS", #$FF + db #$28, " NEVER", #$FF + db #$FF + .routine + LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_FIREBALL_INVERTED + STA !ram_ridley_rng_times_and_fireball + LDA !ram_cm_ridley_hover_fireball : XBA : LSR #2 + ORA !ram_ridley_rng_times_and_fireball : STA !ram_ridley_rng_times_and_fireball + LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done + JML init_zebes_ridley_rng + .done + RTL + + if !FEATURE_SD2SNES ; -------------- ; Savestate Menu diff --git a/src/presets.asm b/src/presets.asm index 593e3bd8..b92a5c61 100644 --- a/src/presets.asm +++ b/src/presets.asm @@ -139,7 +139,7 @@ endif ; If glass is broken, assume we should skip MB1 LDA $7ED820 : BIT #$0004 : BEQ .done ; Set health to 1 as a hint this was done by a preset - LDA #$0001 : STA !ENEMY_HP+$40 + LDA #$0001 : STA !ENEMY_HP+!ENEMY_1_OFFSET ; Reset segment timer now TDC : STA !ram_reset_segment_later STA !ram_seg_rt_frames : STA !ram_seg_rt_seconds diff --git a/src/symbols.asm b/src/symbols.asm index 69d7cd8c..c3874630 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -199,6 +199,8 @@ ram_turret_rng = !ram_turret_rng ; !WRAM_PERSIST_START+$68 ram_quickboot_spc_state = !ram_quickboot_spc_state ; !WRAM_PERSIST_START+$6A ram_display_backup = !ram_display_backup ; !WRAM_PERSIST_START+$6C ram_phantoon_always_visible = !ram_phantoon_always_visible ; !WRAM_PERSIST_START+$6E +ram_ridley_rng_flags = !ram_ridley_rng_flags ; !WRAM_PERSIST_START+$70 +ram_ridley_rng_times_and_fireball = !ram_ridley_rng_times_and_fireball ; !WRAM_PERSIST_START+$72 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -287,9 +289,21 @@ ram_cm_itempickups_visible = !ram_cm_itempickups_visible ; !WRAM_MENU_START+$98 ram_cm_itempickups_chozo = !ram_cm_itempickups_chozo ; !WRAM_MENU_START+$9A ram_cm_itempickups_hidden = !ram_cm_itempickups_hidden ; !WRAM_MENU_START+$9C -ram_cm_phan_first_phase = !ram_cm_phan_first_phase ; !WRAM_MENU_START+$90 -ram_cm_phan_second_phase = !ram_cm_phan_second_phase ; !WRAM_MENU_START+$92 -ram_cm_turret_rng = !ram_cm_turret_rng ; !WRAM_MENU_START+$94 +ram_cm_turret_rng = !ram_cm_turret_rng ; !WRAM_MENU_START+$90 +ram_cm_phan_first_phase = !ram_cm_phan_first_phase ; !WRAM_MENU_START+$92 +ram_cm_phan_second_phase = !ram_cm_phan_second_phase ; !WRAM_MENU_START+$94 + +ram_cm_ridley_pogo_height = !ram_cm_ridley_pogo_height ; !WRAM_MENU_START+$92 +ram_cm_ridley_lunge_pogo = !ram_cm_ridley_lunge_pogo ; !WRAM_MENU_START+$94 +ram_cm_ridley_swoop_pogo = !ram_cm_ridley_swoop_pogo ; !WRAM_MENU_START+$96 +ram_cm_ridley_ceres_ai = !ram_cm_ridley_ceres_ai ; !WRAM_MENU_START+$98 +ram_cm_ridley_hover_fireball = !ram_cm_ridley_hover_fireball ; !WRAM_MENU_START+$9A +ram_cm_ridley_backpogo_left = !ram_cm_ridley_backpogo_left ; !WRAM_MENU_START+$9C +ram_cm_ridley_backpogo_right = !ram_cm_ridley_backpogo_right ; !WRAM_MENU_START+$9E +ram_cm_ridley_pogo_time = !ram_cm_ridley_pogo_time ; !WRAM_MENU_START+$A0 +ram_cm_ridley_pogo_time_value = !ram_cm_ridley_pogo_time_value ; !WRAM_MENU_START+$A2 +ram_cm_ridley_hover_time = !ram_cm_ridley_hover_time ; !WRAM_MENU_START+$A4 +ram_cm_ridley_hover_time_value = !ram_cm_ridley_hover_time_value ; !WRAM_MENU_START+$A6 ram_cm_varia = !ram_cm_varia ; !WRAM_MENU_START+$90 ram_cm_gravity = !ram_cm_gravity ; !WRAM_MENU_START+$92 @@ -414,23 +428,8 @@ ram_crash_input_timer = !ram_crash_input_timer ; !CRASHDUMP+$66 ; then we won't be accurate to the vanilla game anymore ; Temporary stack written here since level data will be initialized afterwards - -; Phantoon infidoppler can use the next $200 of RAM, -; since the room outside phantoon's room is larger and will overwrite this data, -; so the only way this could have some impact is you went OOB -; either from Phantoon's room or after teleporting to another single scroll room, -; and then fell a long ways out of bounds - -; An array of 5 words, one per projectile, representing -; the distance Samus travelled horizontally before firing. -; The low byte of each word is integer pixels, -; and the high byte is fractional pixels. -; Yes, that sounds weird, but the math is a little easier. -ram_infidoppler_offsets = !ram_infidoppler_offsets ; !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA ; array of 5 words -ram_infidoppler_x = !ram_infidoppler_x ; !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA+$10 -ram_infidoppler_subx = !ram_infidoppler_subx ; !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA+$12 -ram_infidoppler_y = !ram_infidoppler_y ; !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA+$14 -ram_infidoppler_suby = !ram_infidoppler_suby ; !END_OF_SINGLE_SCROLL_ROOM_LEVEL_DATA+$16 +; There is room for 256 entries in the stack before risking leaving data behind, +; since even the smallest room has 512 bytes of level data ; Do not use RAM for variables at or beyond this point From d4156d976850ffb5257268d49f3c1b2fd169ad31 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sat, 12 Apr 2025 15:09:12 -0500 Subject: [PATCH 17/43] Split out platforms and move MiSTer up to 256k SRAM support --- src/enemy_rng.asm | 2 +- web/data/config.json | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/enemy_rng.asm b/src/enemy_rng.asm index e9916bc2..c197399e 100644 --- a/src/enemy_rng.asm +++ b/src/enemy_rng.asm @@ -1024,7 +1024,7 @@ endif .ceres_swoop if !FEATURE_PAL - LDA #$A8(D + LDA #$A89D else LDA #$A88D endif diff --git a/web/data/config.json b/web/data/config.json index 280c79a5..4a1945b8 100644 --- a/web/data/config.json +++ b/web/data/config.json @@ -17,8 +17,10 @@ "id": "platform", "name": "Platform", "options": [ - { "id": "sd2snes", "name": "SD2SNES, FXPAK, SuperNT, Snes9x 1.61+, BSNES v115"}, - { "id": "tinystates", "name": "MiSTer, Everdrive, Modern Emulators" }, + { "id": "sd2snes", "name": "SD2SNES, FXPAK" }, + { "id": "mister", "name": "MiSTer, SuperNT" }, + { "id": "bsnes", "name": "Snes9x 1.61+, BSNES v115"}, + { "id": "tinystates", "name": "Snes9x 1.60 or older, Everdrive" }, { "id": "emulator", "name": "SNES Classic, Virtual Console" } ] } @@ -28,7 +30,11 @@ { "platform": "emulator", "variant": "PAL", "file": "/patches/emulator-pal.ips", "size": 4194304}, { "platform": "sd2snes", "variant": "NTSC", "file": "/patches/sd2snes-ntsc.ips", "size": 4194304}, + { "platform": "mister", "variant": "NTSC", "file": "/patches/sd2snes-ntsc.ips", "size": 4194304}, + { "platform": "bsnes", "variant": "NTSC", "file": "/patches/sd2snes-ntsc.ips", "size": 4194304}, { "platform": "sd2snes", "variant": "PAL", "file": "/patches/sd2snes-pal.ips", "size": 4194304}, + { "platform": "mister", "variant": "PAL", "file": "/patches/sd2snes-pal.ips", "size": 4194304}, + { "platform": "bsnes", "variant": "PAL", "file": "/patches/sd2snes-pal.ips", "size": 4194304}, { "platform": "tinystates", "variant": "NTSC", "file": "/patches/tinystates-ntsc.ips", "size": 4194304}, { "platform": "tinystates", "variant": "PAL", "file": "/patches/tinystates-pal.ips", "size": 4194304} From 3058f0928503fea4ac722b9f374e93a5221be4c4 Mon Sep 17 00:00:00 2001 From: InsaneFirebat <InsaneFirebat@gmail.com> Date: Tue, 22 Apr 2025 14:37:37 -0400 Subject: [PATCH 18/43] Combine Zeb events and add speedbooster quake --- src/defines.asm | 6 +-- src/flagmenu.asm | 137 +++++++++++++++++------------------------------ src/symbols.asm | 6 +-- 3 files changed, 51 insertions(+), 98 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index b038fb3a..d3985667 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -339,11 +339,7 @@ !ram_cm_etanks = !WRAM_MENU_START+$AC !ram_cm_reserve = !WRAM_MENU_START+$AE -!ram_cm_zeb1 = !WRAM_MENU_START+$90 -!ram_cm_zeb2 = !WRAM_MENU_START+$92 -!ram_cm_zeb3 = !WRAM_MENU_START+$94 -!ram_cm_zeb4 = !WRAM_MENU_START+$96 -!ram_cm_zebmask = !WRAM_MENU_START+$98 +!ram_cm_zebmask = !WRAM_MENU_START+$90 !ram_cm_ceres_seconds = !WRAM_MENU_START+$90 !ram_cm_zebes_seconds = !WRAM_MENU_START+$92 diff --git a/src/flagmenu.asm b/src/flagmenu.asm index 8fa05a2f..7ece591a 100644 --- a/src/flagmenu.asm +++ b/src/flagmenu.asm @@ -827,64 +827,31 @@ eventflags_setmapstations: eventflags_prepare_events_menu: { - LDA $7ED820 : AND #$0038 : STA !ram_cm_zebmask - JSL eventflags_setup_zeb_ram + LDA $7ED820 : AND #$0038 + CMP #$0020 : BEQ .four + CMP #$0018 : BEQ .three + CMP #$0010 : BEQ .two + CMP #$0008 : BEQ .one + BRA .done + + .one + LDA #$0001 : BRA .done + .two + LDA #$0002 : BRA .done + .three + LDA #$0003 : BRA .done + .four + LDA #$0004 + + .done + STA !ram_cm_zebmask %setmenubank() JML action_submenu } -eventflags_set_zeb_ram: -{ - LDA $7ED820 : AND #$FFC7 - ORA !ram_cm_zebmask : STA $7ED820 - - ; Intentional fallthrough - LDA !ram_cm_zebmask -} - -eventflags_setup_zeb_ram: -{ - CMP #$0020 : BPL .zeb4 - CMP #$0018 : BPL .zeb3 - CMP #$0010 : BPL .zeb2 - CMP #$0008 : BPL .zeb1 - STA !ram_cm_zeb1 - .clear_zeb2 - STA !ram_cm_zeb2 - .clear_zeb3 - STA !ram_cm_zeb3 - .clear_zeb4 - STA !ram_cm_zeb4 - RTL - - .zeb4 - LDA #$0020 : STA !ram_cm_zeb4 - LDA #$0018 : STA !ram_cm_zeb3 - LDA #$0010 : STA !ram_cm_zeb2 - LDA #$0008 : STA !ram_cm_zeb1 - RTL - - .zeb3 - LDA #$0018 : STA !ram_cm_zeb3 - LDA #$0010 : STA !ram_cm_zeb2 - LDA #$0008 : STA !ram_cm_zeb1 - TDC - BRA .clear_zeb4 - - .zeb2 - LDA #$0010 : STA !ram_cm_zeb2 - LDA #$0008 : STA !ram_cm_zeb1 - TDC - BRA .clear_zeb3 - - .zeb1 - LDA #$0008 : STA !ram_cm_zeb1 - TDC - BRA .clear_zeb2 -} - EventsMenu: dw #events_zebesawake + dw #events_speedboostquake dw #events_maridiatubebroken dw #events_shaktool dw #events_chozoacid @@ -892,10 +859,7 @@ EventsMenu: dw #events_metroid2 dw #events_metroid3 dw #events_metroid4 - dw #events_zeb1 - dw #events_zeb2 - dw #events_zeb3 - dw #events_zeb4 + dw #events_zebettites dw #events_mb1glass dw #events_zebesexploding dw #events_animals @@ -911,6 +875,9 @@ EventsMenu: events_zebesawake: %cm_toggle_bit("Zebes Awake", $7ED820, #$0001, #0) +events_speedboostquake: + %cm_toggle_bit("Speedbooster Lavaquake", $7ED822, #$0020, #0) + events_maridiatubebroken: %cm_toggle_bit("Maridia Tube Broken", $7ED820, #$0800, #0) @@ -932,41 +899,35 @@ events_metroid3: events_metroid4: %cm_toggle_bit("4th Metroids Cleared", $7ED822, #$0008, #0) -events_zeb1: - %cm_toggle("1st Zebitite Cleared", !ram_cm_zeb1, #$08, #.routine) - .routine - LDA !ram_cm_zeb1 : BNE .set - TDC - .set - STA !ram_cm_zebmask - JML eventflags_set_zeb_ram - -events_zeb2: - %cm_toggle("2nd Zebitite Cleared", !ram_cm_zeb2, #$10, #.routine) +events_zebettites: + dw !ACTION_CHOICE + dl #!ram_cm_zebmask + dw .routine + db #$28, "Zebs Killed", #$FF + db #$28, " 0", #$FF + db #$28, " 1", #$FF + db #$28, " 2", #$FF + db #$28, " 3", #$FF + db #$28, " 4", #$FF + db #$FF .routine - LDA !ram_cm_zeb2 : BNE .set + CMP #$0000 : BEQ .done + CMP #$0001 : BEQ .one + CMP #$0002 : BEQ .two + CMP #$0003 : BEQ .three + + LDA #$0020 : BRA .done + .three + LDA #$0018 : BRA .done + .two + LDA #$0010 : BRA .done + .one LDA #$0008 - .set - STA !ram_cm_zebmask - JML eventflags_set_zeb_ram - -events_zeb3: - %cm_toggle("3rd Zebitite Cleared", !ram_cm_zeb3, #$18, #.routine) - .routine - LDA !ram_cm_zeb3 : BNE .set - LDA #$0010 - .set - STA !ram_cm_zebmask - JML eventflags_set_zeb_ram -events_zeb4: - %cm_toggle("4th Zebitite Cleared", !ram_cm_zeb4, #$20, #.routine) - .routine - LDA !ram_cm_zeb4 : BNE .set - LDA #$0018 - .set - STA !ram_cm_zebmask - JML eventflags_set_zeb_ram + .done + STA $C1 + LDA $7ED820 : AND #$FFC7 : ORA $C1 : STA $7ED820 + RTL events_mb1glass: %cm_toggle_bit("MB1 Glass Broken", $7ED820, #$0004, #0) diff --git a/src/symbols.asm b/src/symbols.asm index c3874630..5fb83c20 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -322,11 +322,7 @@ ram_cm_plasma = !ram_cm_plasma ; !WRAM_MENU_START+$AA ram_cm_etanks = !ram_cm_etanks ; !WRAM_MENU_START+$AC ram_cm_reserve = !ram_cm_reserve ; !WRAM_MENU_START+$AE -ram_cm_zeb1 = !ram_cm_zeb1 ; !WRAM_MENU_START+$90 -ram_cm_zeb2 = !ram_cm_zeb2 ; !WRAM_MENU_START+$92 -ram_cm_zeb3 = !ram_cm_zeb3 ; !WRAM_MENU_START+$94 -ram_cm_zeb4 = !ram_cm_zeb4 ; !WRAM_MENU_START+$96 -ram_cm_zebmask = !ram_cm_zebmask ; !WRAM_MENU_START+$98 +ram_cm_zebmask = !ram_cm_zebmask ; !WRAM_MENU_START+$90 ram_cm_ceres_seconds = !ram_cm_ceres_seconds ; !WRAM_MENU_START+$90 ram_cm_zebes_seconds = !ram_cm_zebes_seconds ; !WRAM_MENU_START+$92 From 037c3a83bae6c36693100b8ab1f008366c0cdd89 Mon Sep 17 00:00:00 2001 From: InsaneFirebat <InsaneFirebat@gmail.com> Date: Thu, 24 Apr 2025 09:57:22 -0400 Subject: [PATCH 19/43] Change Zebettites from choice to numfield --- src/flagmenu.asm | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/flagmenu.asm b/src/flagmenu.asm index 7ece591a..e444c6b1 100644 --- a/src/flagmenu.asm +++ b/src/flagmenu.asm @@ -900,16 +900,7 @@ events_metroid4: %cm_toggle_bit("4th Metroids Cleared", $7ED822, #$0008, #0) events_zebettites: - dw !ACTION_CHOICE - dl #!ram_cm_zebmask - dw .routine - db #$28, "Zebs Killed", #$FF - db #$28, " 0", #$FF - db #$28, " 1", #$FF - db #$28, " 2", #$FF - db #$28, " 3", #$FF - db #$28, " 4", #$FF - db #$FF + %cm_numfield("Zebs Killed", !ram_cm_zebmask, 0, 4, 1, 1, #.routine) .routine CMP #$0000 : BEQ .done CMP #$0001 : BEQ .one From cea24e43d0bfeb02c96e3b8ecdcd101a2bc20141 Mon Sep 17 00:00:00 2001 From: InsaneFirebat <InsaneFirebat@gmail.com> Date: Fri, 25 Apr 2025 17:58:05 -0400 Subject: [PATCH 20/43] Combine Metroids events Also fix events menu setup --- src/defines.asm | 1 + src/flagmenu.asm | 80 +++++++++++++++++++++++++++++++----------------- src/symbols.asm | 1 + 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index d3985667..94f345bf 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -340,6 +340,7 @@ !ram_cm_reserve = !WRAM_MENU_START+$AE !ram_cm_zebmask = !WRAM_MENU_START+$90 +!ram_cm_metmask = !WRAM_MENU_START+$92 !ram_cm_ceres_seconds = !WRAM_MENU_START+$90 !ram_cm_zebes_seconds = !WRAM_MENU_START+$92 diff --git a/src/flagmenu.asm b/src/flagmenu.asm index e444c6b1..b61a71b9 100644 --- a/src/flagmenu.asm +++ b/src/flagmenu.asm @@ -827,24 +827,42 @@ eventflags_setmapstations: eventflags_prepare_events_menu: { + ; Zebettites LDA $7ED820 : AND #$0038 - CMP #$0020 : BEQ .four - CMP #$0018 : BEQ .three - CMP #$0010 : BEQ .two - CMP #$0008 : BEQ .one - BRA .done + CMP #$0020 : BEQ .fourZeb + CMP #$0018 : BEQ .threeZeb + CMP #$0010 : BEQ .twoZeb + CMP #$0008 : BEQ .oneZeb + LDA #$0000 : BRA .doneZeb + .fourZeb + LDA #$0004 : BRA .doneZeb + .threeZeb + LDA #$0003 : BRA .doneZeb + .twoZeb + LDA #$0002 : BRA .doneZeb + .oneZeb + LDA #$0001 : BRA .doneZeb + .doneZeb + STA !ram_cm_zebmask - .one - LDA #$0001 : BRA .done - .two - LDA #$0002 : BRA .done - .three - LDA #$0003 : BRA .done - .four - LDA #$0004 + ; Metroids + LDA $7ED822 : AND #$000F + BIT #$0008 : BNE .fourMet + BIT #$0004 : BNE .threeMet + BIT #$0002 : BNE .twoMet + BIT #$0001 : BNE .oneMet + LDA #$0000 : BRA .doneMet + .fourMet + LDA #$0004 : BRA .doneMet + .threeMet + LDA #$0003 : BRA .doneMet + .twoMet + LDA #$0002 : BRA .doneMet + .oneMet + LDA #$0001 : BRA .doneMet + .doneMet + STA !ram_cm_metmask - .done - STA !ram_cm_zebmask %setmenubank() JML action_submenu } @@ -855,10 +873,7 @@ EventsMenu: dw #events_maridiatubebroken dw #events_shaktool dw #events_chozoacid - dw #events_metroid1 - dw #events_metroid2 - dw #events_metroid3 - dw #events_metroid4 + dw #events_metroids dw #events_zebettites dw #events_mb1glass dw #events_zebesexploding @@ -887,17 +902,26 @@ events_shaktool: events_chozoacid: %cm_toggle_bit("Chozo Lowered Acid", $7ED821, #$0010, #0) -events_metroid1: - %cm_toggle_bit("1st Metroids Cleared", $7ED822, #$0001, #0) - -events_metroid2: - %cm_toggle_bit("2nd Metroids Cleared", $7ED822, #$0002, #0) +events_metroids: + %cm_numfield("Metroid Rooms Cleared", !ram_cm_metmask, 0, 4, 1, 1, #.routine) + .routine + CMP #$0000 : BEQ .done + CMP #$0001 : BEQ .one + CMP #$0002 : BEQ .two + CMP #$0003 : BEQ .three -events_metroid3: - %cm_toggle_bit("3rd Metroids Cleared", $7ED822, #$0004, #0) + LDA #$000F : BRA .done + .three + LDA #$0007 : BRA .done + .two + LDA #$0003 : BRA .done + .one + LDA #$0001 : BRA .done -events_metroid4: - %cm_toggle_bit("4th Metroids Cleared", $7ED822, #$0008, #0) + .done + STA $C1 + LDA $7ED822 : AND #$FFF0 : ORA $C1 : STA $7ED822 + RTL events_zebettites: %cm_numfield("Zebs Killed", !ram_cm_zebmask, 0, 4, 1, 1, #.routine) diff --git a/src/symbols.asm b/src/symbols.asm index 5fb83c20..b4b8d831 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -323,6 +323,7 @@ ram_cm_etanks = !ram_cm_etanks ; !WRAM_MENU_START+$AC ram_cm_reserve = !ram_cm_reserve ; !WRAM_MENU_START+$AE ram_cm_zebmask = !ram_cm_zebmask ; !WRAM_MENU_START+$90 +ram_cm_metmask = !ram_cm_metmask ; !WRAM_MENU_START+$92 ram_cm_ceres_seconds = !ram_cm_ceres_seconds ; !WRAM_MENU_START+$90 ram_cm_zebes_seconds = !ram_cm_zebes_seconds ; !WRAM_MENU_START+$92 From 6bc2cef24bb306f49bb9880d9597e571ee364c3b Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 18 May 2025 15:30:43 -0500 Subject: [PATCH 21/43] Add Mother Brain RNG and refactor existing RNG routines --- src/cutscenes.asm | 77 ++++++ src/defines.asm | 235 +++++++++++----- src/enemy_rng.asm | 328 ++++++++++++++++++---- src/main.asm | 2 +- src/mainmenu.asm | 671 ++++++++++++++++++++++++++++++++-------------- src/symbols.asm | 96 +++---- 6 files changed, 1046 insertions(+), 363 deletions(-) diff --git a/src/cutscenes.asm b/src/cutscenes.asm index ea35f7a1..af5fd562 100644 --- a/src/cutscenes.asm +++ b/src/cutscenes.asm @@ -1730,6 +1730,83 @@ org $A9B5E1 endif JSL cutscenes_mb_custom_damage +if !FEATURE_PAL +org $A9B672 +else +org $A9B625 +endif + CMP !eram_mb_normal_walking_rng + +if !FEATURE_PAL +org $A9B684 +else +org $A9B637 +endif + CMP !eram_mb_ketchup_walking_rng + +if !FEATURE_PAL +org $A9B68C +else +org $A9B63F +endif + CMP !eram_mb_ketchup_rng + +if !FEATURE_PAL +org $A9B6B9 +else +org $A9B66C +endif + LDX !eram_mb_ground_attack_rng_table + +if !FEATURE_PAL +org $A9B6D2 +else +org $A9B685 +endif + LDX !eram_mb_close_attack_rng_table + +if !FEATURE_PAL +org $A9B742 +else +org $A9B6F5 +endif + CMP !eram_mb_air_rings_rng + +if !FEATURE_PAL +org $A9B75F +else +org $A9B712 +endif + CMP !eram_mb_ground_bomb_rng + +if !FEATURE_PAL +org $A9B7D1 +else +org $A9B784 +endif + CMP !eram_mb_try_bomb_crouch + +if !FEATURE_PAL +org $A9B808 +else +org $A9B7BB +endif + CMP !eram_mb_bomb_crouch + +if !FEATURE_PAL +org $A9BDC7 +else +org $A9BD7A +endif + CMP !eram_mb_damage_down_rng + +if !FEATURE_PAL +org $A9C282 +else +org $A9C235 +endif + CMP !eram_mb_phase3_attack_rng + %startfree(A9) diff --git a/src/defines.asm b/src/defines.asm index b038fb3a..ea08e59b 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -165,21 +165,22 @@ !ram_space_pants_enabled = !WRAM_PERSIST_START+$0C !ram_kraid_claw_rng = !WRAM_PERSIST_START+$0E !ram_kraid_wait_rng = !WRAM_PERSIST_START+$10 -!ram_botwoon_first = !WRAM_PERSIST_START+$12 -!ram_botwoon_second = !WRAM_PERSIST_START+$14 -!ram_botwoon_hidden = !WRAM_PERSIST_START+$16 -!ram_botwoon_spit = !WRAM_PERSIST_START+$18 -!ram_botwoon_rng = !WRAM_PERSIST_START+$1A +!ram_draygon_rng_left = !WRAM_PERSIST_START+$12 +!ram_draygon_rng_right = !WRAM_PERSIST_START+$14 +!ram_turret_rng = !WRAM_PERSIST_START+$16 +!ram_ridley_rng_flags = !WRAM_PERSIST_START+$18 +!ram_ridley_rng_times_and_fireball = !WRAM_PERSIST_START+$1A !ram_crocomire_rng = !WRAM_PERSIST_START+$1C -!ram_phantoon_rng_round_1 = !WRAM_PERSIST_START+$1E -!ram_phantoon_rng_round_2 = !WRAM_PERSIST_START+$20 -!ram_phantoon_rng_inverted = !WRAM_PERSIST_START+$22 -!ram_phantoon_rng_eyeclose = !WRAM_PERSIST_START+$24 -!ram_phantoon_rng_flames = !WRAM_PERSIST_START+$26 -!ram_phantoon_rng_next_flames = !WRAM_PERSIST_START+$28 -!ram_phantoon_flame_direction = !WRAM_PERSIST_START+$2A -!ram_draygon_rng_left = !WRAM_PERSIST_START+$2C -!ram_draygon_rng_right = !WRAM_PERSIST_START+$2E +!ram_phantoon_phase_rng = !WRAM_PERSIST_START+$1E +!ram_phantoon_eye_and_flames_rng = !WRAM_PERSIST_START+$20 +!ram_botwoon_rng = !WRAM_PERSIST_START+$22 +!ram_baby_rng = !WRAM_PERSIST_START+$24 +!ram_mb_rng = !WRAM_PERSIST_START+$26 + +!ram_itempickups_all = !WRAM_PERSIST_START+$28 +!ram_itempickups_visible = !WRAM_PERSIST_START+$2A +!ram_itempickups_chozo = !WRAM_PERSIST_START+$2C +!ram_itempickups_hidden = !WRAM_PERSIST_START+$2E !ram_suits_enemy_damage_check = !WRAM_PERSIST_START+$30 !ram_suits_heat_damage_check = !WRAM_PERSIST_START+$32 @@ -205,19 +206,9 @@ !ram_door_portal_flags = !WRAM_PERSIST_START+$56 !ram_door_source = !WRAM_PERSIST_START+$58 !ram_door_destination = !WRAM_PERSIST_START+$5A -!ram_itempickups_all = !WRAM_PERSIST_START+$5C -!ram_itempickups_visible = !WRAM_PERSIST_START+$5E -!ram_itempickups_chozo = !WRAM_PERSIST_START+$60 -!ram_itempickups_hidden = !WRAM_PERSIST_START+$62 -!ram_frames_held = !WRAM_PERSIST_START+$64 -!ram_baby_rng = !WRAM_PERSIST_START+$66 -!ram_turret_rng = !WRAM_PERSIST_START+$68 - -!ram_quickboot_spc_state = !WRAM_PERSIST_START+$6A -!ram_display_backup = !WRAM_PERSIST_START+$6C -!ram_phantoon_always_visible = !WRAM_PERSIST_START+$6E -!ram_ridley_rng_flags = !WRAM_PERSIST_START+$70 -!ram_ridley_rng_times_and_fireball = !WRAM_PERSIST_START+$72 +!ram_frames_held = !WRAM_PERSIST_START+$5C +!ram_quickboot_spc_state = !WRAM_PERSIST_START+$5E +!ram_display_backup = !WRAM_PERSIST_START+$60 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -276,12 +267,6 @@ !ram_timers_autoupdate = !WRAM_MENU_START+$5E !ram_cm_gmode = !WRAM_MENU_START+$60 -!ram_cm_botwoon_rng = !WRAM_MENU_START+$62 -!ram_cm_botwoon_first = !WRAM_MENU_START+$64 -!ram_cm_botwoon_hidden = !WRAM_MENU_START+$66 -!ram_cm_botwoon_second = !WRAM_MENU_START+$68 -!ram_cm_botwoon_spit = !WRAM_MENU_START+$68 - ; ^ FREE SPACE ^ up to +$86 !ram_cm_preserved_timers = !WRAM_MENU_START+$88 ; 8 bytes @@ -307,20 +292,37 @@ !ram_cm_itempickups_hidden = !WRAM_MENU_START+$9C !ram_cm_turret_rng = !WRAM_MENU_START+$90 -!ram_cm_phan_first_phase = !WRAM_MENU_START+$92 -!ram_cm_phan_second_phase = !WRAM_MENU_START+$94 - -!ram_cm_ridley_pogo_height = !WRAM_MENU_START+$92 -!ram_cm_ridley_lunge_pogo = !WRAM_MENU_START+$94 -!ram_cm_ridley_swoop_pogo = !WRAM_MENU_START+$96 -!ram_cm_ridley_ceres_ai = !WRAM_MENU_START+$98 -!ram_cm_ridley_hover_fireball = !WRAM_MENU_START+$9A -!ram_cm_ridley_backpogo_left = !WRAM_MENU_START+$9C -!ram_cm_ridley_backpogo_right = !WRAM_MENU_START+$9E -!ram_cm_ridley_pogo_time = !WRAM_MENU_START+$A0 -!ram_cm_ridley_pogo_time_value = !WRAM_MENU_START+$A2 -!ram_cm_ridley_hover_time = !WRAM_MENU_START+$A4 -!ram_cm_ridley_hover_time_value = !WRAM_MENU_START+$A6 +!ram_cm_botwoon_first_rng = !WRAM_MENU_START+$92 +!ram_cm_botwoon_hidden_rng = !WRAM_MENU_START+$94 +!ram_cm_botwoon_second_rng = !WRAM_MENU_START+$96 +!ram_cm_botwoon_spit_rng = !WRAM_MENU_START+$98 +!ram_cm_botwoon_after_spit_rng = !WRAM_MENU_START+$9A + +!ram_cm_phantoon_first_phase_rng = !WRAM_MENU_START+$9C +!ram_cm_phantoon_second_phase_rng = !WRAM_MENU_START+$9E +!ram_cm_phantoon_flip_rng = !WRAM_MENU_START+$A0 +!ram_cm_phantoon_eyeclose_rng = !WRAM_MENU_START+$A2 +!ram_cm_phantoon_flames_rng = !WRAM_MENU_START+$A4 +!ram_cm_phantoon_next_flames_rng = !WRAM_MENU_START+$A6 +!ram_cm_phantoon_flame_direction_rng = !WRAM_MENU_START+$A8 + +!ram_cm_ridley_pogo_height_rng = !WRAM_MENU_START+$9C +!ram_cm_ridley_lunge_pogo_rng = !WRAM_MENU_START+$9E +!ram_cm_ridley_swoop_pogo_rng = !WRAM_MENU_START+$A0 +!ram_cm_ridley_ceres_ai_rng = !WRAM_MENU_START+$A2 +!ram_cm_ridley_hover_fireball_rng = !WRAM_MENU_START+$A4 +!ram_cm_ridley_backpogo_rng = !WRAM_MENU_START+$A6 +!ram_cm_ridley_pogo_time_rng = !WRAM_MENU_START+$A8 +!ram_cm_ridley_pogo_time_value_rng = !WRAM_MENU_START+$AA +!ram_cm_ridley_hover_time_rng = !WRAM_MENU_START+$AC +!ram_cm_ridley_hover_time_value_rng = !WRAM_MENU_START+$AE + +!ram_cm_mb_walking_rng = !WRAM_MENU_START+$9C +!ram_cm_mb_ketchup_rng = !WRAM_MENU_START+$9E +!ram_cm_mb_damage_down_rng = !WRAM_MENU_START+$A0 +!ram_cm_mb_phase3_attack_rng = !WRAM_MENU_START+$A2 +!ram_cm_mb_normal_attack_rng = !WRAM_MENU_START+$A4 +!ram_cm_mb_bomb_crouch_rng = !WRAM_MENU_START+$A6 !ram_cm_varia = !WRAM_MENU_START+$90 !ram_cm_gravity = !WRAM_MENU_START+$92 @@ -974,6 +976,8 @@ ; In rooms with fewer enemies, some enemy RAM is available for use !ENEMY_1_OFFSET = $40 !ENEMY_2_OFFSET = $80 +!ENEMY_1C_OFFSET = $700 +!ENEMY_1D_OFFSET = $740 !ENEMY_1E_OFFSET = $780 !ENEMY_1F_OFFSET = $7C0 @@ -982,22 +986,49 @@ ; The low byte of each word is integer pixels, ; and the high byte is fractional pixels. ; Yes, that sounds weird, but the math is a little easier. -!eram_infidoppler_offsets = !ENEMY_VAR_1+!ENEMY_1E_OFFSET ; array of 5 words -!eram_infidoppler_x = !ENEMY_VAR_1+!ENEMY_1F_OFFSET -!eram_infidoppler_subx = !ENEMY_VAR_2+!ENEMY_1F_OFFSET -!eram_infidoppler_y = !ENEMY_VAR_3+!ENEMY_1F_OFFSET -!eram_infidoppler_suby = !ENEMY_VAR_4+!ENEMY_1F_OFFSET - -!eram_ceres_ridley_rng = !ENEMY_VAR_1+!ENEMY_1E_OFFSET -!eram_ridley_lunge_pogo_rng = !ENEMY_VAR_2+!ENEMY_1E_OFFSET -!eram_ridley_swoop_pogo_rng = !ENEMY_VAR_3+!ENEMY_1E_OFFSET -!eram_ridley_pogo_swoop_rng = !ENEMY_VAR_4+!ENEMY_1E_OFFSET -!eram_ridley_fireball_rng = !ENEMY_VAR_5+!ENEMY_1E_OFFSET -!eram_ridley_hover_time_rng = !ENEMY_VAR_1+!ENEMY_1F_OFFSET -!eram_ridley_pogo_time_rng = !ENEMY_VAR_2+!ENEMY_1F_OFFSET -!eram_ridley_pogo_height_rng = !ENEMY_VAR_3+!ENEMY_1F_OFFSET -!eram_ridley_backpogo_left_rng = !ENEMY_VAR_4+!ENEMY_1F_OFFSET -!eram_ridley_backpogo_right_rng = !ENEMY_VAR_5+!ENEMY_1F_OFFSET +!eram_infidoppler_offsets = !ENEMY_VAR_1+!ENEMY_1C_OFFSET ; array of 5 words +!eram_infidoppler_x = !ENEMY_VAR_1+!ENEMY_1D_OFFSET +!eram_infidoppler_subx = !ENEMY_VAR_2+!ENEMY_1D_OFFSET +!eram_infidoppler_y = !ENEMY_VAR_3+!ENEMY_1D_OFFSET +!eram_infidoppler_suby = !ENEMY_VAR_4+!ENEMY_1D_OFFSET +!eram_phantoon_always_visible = !ENEMY_VAR_5+!ENEMY_1D_OFFSET +!eram_phantoon_rng_round_1 = !ENEMY_VAR_1+!ENEMY_1E_OFFSET +!eram_phantoon_rng_round_2 = !ENEMY_VAR_2+!ENEMY_1E_OFFSET +!eram_phantoon_rng_flip = !ENEMY_VAR_3+!ENEMY_1E_OFFSET +!eram_phantoon_rng_eyeclose = !ENEMY_VAR_4+!ENEMY_1E_OFFSET +!eram_phantoon_rng_flames = !ENEMY_VAR_1+!ENEMY_1F_OFFSET +!eram_phantoon_rng_next_flames = !ENEMY_VAR_2+!ENEMY_1F_OFFSET +!eram_phantoon_rng_flame_direction = !ENEMY_VAR_3+!ENEMY_1F_OFFSET + +!eram_ceres_ridley_rng = !ENEMY_VAR_1+!ENEMY_1E_OFFSET +!eram_ridley_lunge_pogo_rng = !ENEMY_VAR_2+!ENEMY_1E_OFFSET +!eram_ridley_swoop_pogo_rng = !ENEMY_VAR_3+!ENEMY_1E_OFFSET +!eram_ridley_pogo_swoop_rng = !ENEMY_VAR_4+!ENEMY_1E_OFFSET +!eram_ridley_fireball_rng = !ENEMY_VAR_5+!ENEMY_1E_OFFSET +!eram_ridley_hover_time_rng = !ENEMY_VAR_1+!ENEMY_1F_OFFSET +!eram_ridley_pogo_time_rng = !ENEMY_VAR_2+!ENEMY_1F_OFFSET +!eram_ridley_pogo_height_rng = !ENEMY_VAR_3+!ENEMY_1F_OFFSET +!eram_ridley_backpogo_rng = !ENEMY_VAR_4+!ENEMY_1F_OFFSET + +!eram_mb_normal_walking_rng = !ENEMY_VAR_5+!ENEMY_1D_OFFSET +!eram_mb_ketchup_walking_rng = !ENEMY_VAR_1+!ENEMY_1E_OFFSET +!eram_mb_ketchup_rng = !ENEMY_VAR_2+!ENEMY_1E_OFFSET +!eram_mb_try_bomb_crouch = !ENEMY_VAR_3+!ENEMY_1E_OFFSET +!eram_mb_bomb_crouch = !ENEMY_VAR_4+!ENEMY_1E_OFFSET +!eram_mb_air_rings_rng = !ENEMY_VAR_5+!ENEMY_1E_OFFSET +!eram_mb_ground_bomb_rng = !ENEMY_VAR_1+!ENEMY_1F_OFFSET +!eram_mb_ground_attack_rng_table = !ENEMY_VAR_2+!ENEMY_1F_OFFSET +!eram_mb_close_attack_rng_table = !ENEMY_VAR_3+!ENEMY_1F_OFFSET +!eram_mb_damage_down_rng = !ENEMY_VAR_4+!ENEMY_1F_OFFSET +!eram_mb_phase3_attack_rng = !ENEMY_VAR_5+!ENEMY_1F_OFFSET + +!eram_botwoon_first_roll = !ENEMY_VAR_4+!ENEMY_1E_OFFSET +!eram_botwoon_all_pattern_rng = !ENEMY_VAR_5+!ENEMY_1E_OFFSET +!eram_botwoon_first_rng = !ENEMY_VAR_1+!ENEMY_1F_OFFSET +!eram_botwoon_hidden_rng = !ENEMY_VAR_2+!ENEMY_1F_OFFSET +!eram_botwoon_second_rng = !ENEMY_VAR_3+!ENEMY_1F_OFFSET +!eram_botwoon_spit_rng = !ENEMY_VAR_4+!ENEMY_1F_OFFSET +!eram_botwoon_after_spit_rng = !ENEMY_VAR_5+!ENEMY_1F_OFFSET !HUD_TILEMAP = $7EC600 !MAP_COUNTER = $7ECAE8 ; Not used in vanilla @@ -1246,21 +1277,38 @@ endif !DOOR_PORTAL_HORIZONTAL_MIRRORING_BIT = #$0010 !DOOR_PORTAL_EXCLUDE_JUMP_MASK = #$FFF7 -!RIDLEY_RNG_POGO_HEIGHT_MASK = #$0007 -!RIDLEY_RNG_POGO_HEIGHT_INVERTED = #$FFF8 -!RIDLEY_RNG_BACKPOGO_LEFT_MASK = #$0038 -!RIDLEY_RNG_BACKPOGO_LEFT_INVERTED = #$FFC7 +!PHANTOON_RNG_PHASE_1_MASK = #$003F +!PHANTOON_RNG_PHASE_1_INVERTED = #$FFC0 +!PHANTOON_RNG_FLIP_MASK = #$00C0 +!PHANTOON_RNG_FLIP_INVERTED = #$FF3F +!PHANTOON_RNG_PHASE_2_MASK = #$3F00 +!PHANTOON_RNG_PHASE_2_INVERTED = #$C0FF +!PHANTOON_RNG_PHASE_2_FLIP_INVERTED = #$C03F +!PHANTOON_RNG_VISIBLE_BIT = #$4000 +!PHANTOON_RNG_VISIBLE_INVERTED = #$BFFF + +!PHANTOON_RNG_FLAMES_MASK = #$0007 +!PHANTOON_RNG_FLAMES_INVERTED = #$FFF8 +!PHANTOON_RNG_FLAMES_PATH_MASK = #$00C0 +!PHANTOON_RNG_FLAMES_PATH_INVERTED = #$FF3F +!PHANTOON_RNG_FLAMES_NEXT_MASK = #$0700 +!PHANTOON_RNG_FLAMES_NEXT_INVERTED = #$F8FF +!PHANTOON_RNG_EYE_CLOSE_MASK = #$C000 +!PHANTOON_RNG_EYE_CLOSE_INVERTED = #$3FFF + +!RIDLEY_RNG_CERES_FIREBALL = #$0001 +!RIDLEY_RNG_CERES_LUNGE = #$0002 +!RIDLEY_RNG_CERES_SWOOP = #$0003 +!RIDLEY_RNG_CERES_MASK = #$0007 +!RIDLEY_RNG_CERES_INVERTED = #$FFF8 +!RIDLEY_RNG_POGO_HEIGHT_MASK = #$0038 +!RIDLEY_RNG_POGO_HEIGHT_INVERTED = #$FFC7 !RIDLEY_RNG_75_25_LUNGE = #$0040 !RIDLEY_RNG_75_25_POGO = #$0080 !RIDLEY_RNG_75_25_MASK = #$00C0 !RIDLEY_RNG_75_25_INVERTED = #$FF3F -!RIDLEY_RNG_CERES_FIREBALL = #$0100 -!RIDLEY_RNG_CERES_LUNGE = #$0200 -!RIDLEY_RNG_CERES_SWOOP = #$0300 -!RIDLEY_RNG_CERES_MASK = #$0700 -!RIDLEY_RNG_CERES_INVERTED = #$F8FF -!RIDLEY_RNG_BACKPOGO_RIGHT_MASK = #$3800 -!RIDLEY_RNG_BACKPOGO_RIGHT_INVERTED = #$C7FF +!RIDLEY_RNG_BACKPOGO_MASK = #$3F00 +!RIDLEY_RNG_BACKPOGO_INVERTED = #$C0FF !RIDLEY_RNG_50_50_SWOOP = #$4000 !RIDLEY_RNG_50_50_POGO = #$8000 !RIDLEY_RNG_50_50_MASK = #$C000 @@ -1275,6 +1323,45 @@ endif !RIDLEY_RNG_POGO_TIME_MASK = #$FF00 !RIDLEY_RNG_POGO_TIME_INVERTED = #$00FF +!MB_RNG_WALKING_MASK = #$0003 +!MB_RNG_WALKING_INVERTED = #$FFFC +!MB_RNG_KETCHUP_MASK = #$000C +!MB_RNG_KETCHUP_INVERTED = #$FFF3 +!MB_RNG_DAMAGE_DOWN_MASK = #$0030 +!MB_RNG_DAMAGE_DOWN_INVERTED = #$FFCF +!MB_RNG_PHASE3_ATTACK_RINGS = #$0080 +!MB_RNG_PHASE3_ATTACK_BOMBS = #$0100 +!MB_RNG_PHASE3_ATTACK_MASK = #$0180 +!MB_RNG_PHASE3_ATTACK_INVERTED = #$FE7F +!MB_RNG_NORMAL_ATTACK_MASK = #$0E00 +!MB_RNG_NORMAL_ATTACK_INVERTED = #$F1FF +!MB_RNG_BOMB_CROUCH_MASK = #$C000 +!MB_RNG_BOMB_CROUCH_INVERTED = #$3FFF + +; Each botwoon pattern can be #$00 (off), #$01, #$09, #$11, #$19 +; (except hidden pattern cannot be #$19) +; This corresponds to just three bits of information +; For efficiency this information can be overlapped, +; allowing for the spit value (#$00, #$04, #$08) to be included +; and also the after spit value in the most and least significant bits +!BOTWOON_RNG_FIRST_MASK = #$0032 ; #$0019 << 1 +!BOTWOON_RNG_FIRST_INVERTED = #$FFCD +!BOTWOON_RNG_FIRST_ENABLED = #$0002 +!BOTWOON_RNG_FIRST_VALUE = #$0030 +!BOTWOON_RNG_HIDDEN_MASK = #$0C80 ; #$1900 >> 1 +!BOTWOON_RNG_HIDDEN_INVERTED = #$F37F +!BOTWOON_RNG_HIDDEN_ENABLED = #$0080 +!BOTWOON_RNG_HIDDEN_VALUE = #$0C00 +!BOTWOON_RNG_SECOND_MASK = #$3200 ; #$1900 << 1 +!BOTWOON_RNG_SECOND_INVERTED = #$CDFF +!BOTWOON_RNG_SECOND_ENABLED = #$0200 +!BOTWOON_RNG_SECOND_VALUE = #$3000 +!BOTWOON_RNG_SPIT_MASK = #$000C +!BOTWOON_RNG_SPIT_INVERTED = #$FFF3 +!BOTWOON_RNG_AFTER_SPIT_ENABLED = #$8000 +!BOTWOON_RNG_AFTER_SPIT_MASK = #$8001 +!BOTWOON_RNG_AFTER_SPIT_INVERTED = #$7FFE + !PROFILE_CUSTOM = #$0000 !PROFILE_Twitch = #$0001 !PROFILE_Default = #$0002 diff --git a/src/enemy_rng.asm b/src/enemy_rng.asm index c197399e..de2ed609 100644 --- a/src/enemy_rng.asm +++ b/src/enemy_rng.asm @@ -15,7 +15,7 @@ org $A7893D endif phantoon_always_visible: { - LDA !ram_phantoon_always_visible : BNE .enabled + LDA !eram_phantoon_always_visible : BNE .enabled ; overwritten code if !FEATURE_PAL JMP $DBCE @@ -129,6 +129,67 @@ endif ; Botwoon hijack ; -------------- +if !FEATURE_PAL +org $A0F2CB +else +org $A0F2AB +endif + dw #botwoon_vanilla_main_ai + +if !FEATURE_PAL +org $B395BD +else +org $B395AD +endif + RTL + +if !FEATURE_PAL +org $B39677 +else +org $B39667 +endif + LDA #$0001 : STA !eram_botwoon_first_roll + ; fallthrough to initialize botwoon RNG + +init_botwoon_rng: +{ + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_SPIT_INVERTED : STA !eram_botwoon_all_pattern_rng + AND !BOTWOON_RNG_FIRST_MASK : LSR : STA !eram_botwoon_first_rng + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_HIDDEN_MASK + ASL : XBA : STA !eram_botwoon_hidden_rng + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_SECOND_MASK + LSR : XBA : STA !eram_botwoon_second_rng + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_SPIT_MASK : STA !eram_botwoon_spit_rng + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_AFTER_SPIT_MASK : STA !eram_botwoon_after_spit_rng + RTL +} + +; Vanilla main AI routine, just migrated +botwoon_vanilla_main_ai: +{ + LDX !ENEMY_INDEX +if !FEATURE_PAL + JSR $96D6 +else + JSR $96C6 +endif + JSR (!ENEMY_VAR_3,X) +if !FEATURE_PAL + JSR $983B +else + JSR $982B +endif + RTL +} +%warnpc($B396C6, $B396D6) + +if !FEATURE_PAL +org $B398D1 +else +org $B398C1 +endif + JSL hook_botwoon_spit + if !FEATURE_PAL org $B39953 else @@ -138,11 +199,12 @@ endif JSL hook_botwoon_move if !FEATURE_PAL -org $B398D1 +org $B39A2A else -org $B398C1 +org $B39A1A endif - JSL hook_botwoon_spit + ; $B3:9A1A 22 11 81 80 JSL $808111[$80:8111] + JSL hook_botwoon_move_after_spit ; --------------- @@ -273,6 +335,18 @@ endif JMP hook_baby_skip_rng +; ------------------- +; Mother Brain hijack +; ------------------- + +if !FEATURE_PAL +org $A9874A +else +org $A9873A +endif + JML hook_mb_init_rng + + ; ----------------- ; "Set rng" hijacks ; ----------------- @@ -375,6 +449,7 @@ hook_beetom_set_rng: ; $A7:D4AE 10 3D BPL $3D [$D4ED] ; else, return hook_phantoon_init: { + JSL init_phantoon_rng LDA !sram_cutscenes : AND !CUTSCENE_FAST_PHANTOON : BNE .skip_cutscene DEC !ENEMY_VAR_4,X @@ -394,6 +469,27 @@ else endif } +init_phantoon_rng: +{ + LDA !ram_phantoon_phase_rng : AND !PHANTOON_RNG_VISIBLE_BIT + STA !eram_phantoon_always_visible + LDA !ram_phantoon_phase_rng : AND !PHANTOON_RNG_PHASE_1_MASK + STA !eram_phantoon_rng_round_1 + LDA !ram_phantoon_phase_rng : AND !PHANTOON_RNG_PHASE_2_MASK + XBA : STA !eram_phantoon_rng_round_2 + LDA !ram_phantoon_phase_rng : AND !PHANTOON_RNG_FLIP_MASK + ASL #2 : XBA : STA !eram_phantoon_rng_flip + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_FLAMES_MASK + STA !eram_phantoon_rng_flames + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_FLAMES_PATH_MASK + ASL #2 : XBA : STA !eram_phantoon_rng_flame_direction + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_FLAMES_NEXT_MASK + XBA : STA !eram_phantoon_rng_next_flames + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_EYE_CLOSE_MASK + XBA : ASL #2 : XBA : STA !eram_phantoon_rng_eyeclose + RTL +} + ; Table of Phantoon pattern durations & directions ; bit 0 is direction, remaining bits are duration @@ -427,7 +523,7 @@ hook_phantoon_1st_rng: .rng ; If set to all-on or all-off, don't mess with RNG - LDA !ram_phantoon_rng_round_1 : BEQ .no_manip + LDA !eram_phantoon_rng_round_1 : BEQ .no_manip CMP #$003F : BNE choose_phantoon_pattern .no_manip @@ -457,7 +553,7 @@ endif hook_phantoon_2nd_rng: { ; If set to all-on or all-off, don't mess with RNG - LDA !ram_phantoon_rng_round_2 : BEQ .no_manip + LDA !eram_phantoon_rng_round_2 : BEQ .no_manip CMP #$003F : BNE choose_phantoon_pattern .no_manip @@ -469,28 +565,28 @@ else LDA $CD53,Y endif STA !ENEMY_FUNCTION_POINTER+!ENEMY_1_OFFSET - ; Intentional fallthrough to invert logic + ; Intentional fallthrough to flip logic } -hook_phantoon_invert: +hook_phantoon_flip: { - LDA !ram_phantoon_rng_inverted : BEQ .vanilla_inverted - CMP #$0001 : BEQ .inverted - CMP #$0002 : BEQ .not_inverted + LDA !eram_phantoon_rng_flip : BEQ .vanilla_flip + DEC : BEQ .flipped + DEC : BEQ .not_flipped ; Random LDA !CACHED_RANDOM_NUMBER : BIT #$0080 RTL - .inverted - LDA #$0000 : BIT #$0001 + .flipped + TDC : BIT #$0001 RTL - .not_inverted + .not_flipped LDA #$0001 : BIT #$0001 RTL - .vanilla_inverted + .vanilla_flip LDA !FRAME_COUNTER : BIT #$0001 RTL } @@ -556,7 +652,7 @@ endif STA !ENEMY_FUNCTION_POINTER ; Index into figure-8 movement table STY !ENEMY_X ; X position LDA #$0060 : STA !ENEMY_Y ; Y position - BRA hook_phantoon_invert + BRA hook_phantoon_flip .round1 ; Save the pattern timer and check the direction @@ -574,7 +670,7 @@ endif hook_phantoon_eyeclose: { - LDA !ram_phantoon_rng_eyeclose : BEQ .no_manip + LDA !eram_phantoon_rng_eyeclose : BEQ .no_manip DEC : ASL ; return with 0-slow, 2-mid, 4-fast RTL @@ -588,9 +684,9 @@ hook_phantoon_flame_pattern: { JSL $808111 ; Trying to preserve the number of RNG calls being done in the frame - LDA !ram_phantoon_rng_flames : TAY - LDA !ram_phantoon_rng_next_flames : STA !ram_phantoon_rng_flames - TYA : STA !ram_phantoon_rng_next_flames : BEQ .no_manip + LDA !eram_phantoon_rng_flames : TAY + LDA !eram_phantoon_rng_next_flames : STA !eram_phantoon_rng_flames + TYA : STA !eram_phantoon_rng_next_flames : BEQ .no_manip DEC RTL @@ -601,7 +697,7 @@ hook_phantoon_flame_pattern: hook_phantoon_flame_direction: { - LDA !ram_phantoon_flame_direction : BEQ .no_manip + LDA !eram_phantoon_rng_flame_direction : BEQ .no_manip DEC : BNE .right .left @@ -624,38 +720,45 @@ endif RTL } - hook_botwoon_move: { - LDA !ram_botwoon_rng : BEQ .no_manip + LDA !eram_botwoon_all_pattern_rng : BEQ .no_manip_maybe_first_roll + ; check if first round + LDA !eram_botwoon_first_roll : BNE .first_round ; 0 = head visible, 1 = behind wall LDA $7E8026 : BNE .hidden - ; check if first round, $7E8022 unused by Botwoon - LDA $7E8022 : BEQ .first_round + ; check if second round pattern fixed + LDA !eram_botwoon_second_rng : BEQ .no_manip ; preserve number of RNG calls in the frame JSL $808111 ; return chosen pattern - LDA !ram_botwoon_second + LDA !eram_botwoon_second_rng RTL .first_round + ; check if first round pattern fixed + LDA !eram_botwoon_first_rng : BEQ .no_manip_maybe_first_roll ; preserve number of RNG calls in the frame JSL $808111 ; mark first round complete - LDA #$0001 : STA $7E8022 + STZ !eram_botwoon_first_roll ; return chosen pattern - LDA !ram_botwoon_first + LDA !eram_botwoon_first_rng RTL .hidden - LDA !ram_botwoon_hidden : BEQ .no_manip + ; check if hidden round pattern fixed + LDA !eram_botwoon_hidden_rng : BEQ .no_manip ; preserve number of RNG calls in the frame JSL $808111 ; return chosen pattern - LDA !ram_botwoon_hidden + LDA !eram_botwoon_hidden_rng RTL + .no_manip_maybe_first_roll + ; mark first round complete + STZ !eram_botwoon_first_roll .no_manip ; return random pattern JML $808111 @@ -663,16 +766,22 @@ hook_botwoon_move: hook_botwoon_spit: { - LDA !ram_botwoon_spit : BEQ .no_manip + LDA !eram_botwoon_spit_rng : BEQ hook_botwoon_move_no_manip ; preserve number of RNG calls in the frame JSL $808111 ; return chosen pattern - LDA !ram_botwoon_spit + LDA !eram_botwoon_spit_rng RTL +} - .no_manip - ; return random pattern - JML $808111 +hook_botwoon_move_after_spit: +{ + LDA !eram_botwoon_after_spit_rng : BEQ hook_botwoon_move_no_manip + ; preserve number of RNG calls in the frame + JSL $808111 + ; return chosen pattern + LDA !eram_botwoon_after_spit_rng + RTL } %endfree(83) @@ -684,7 +793,7 @@ hook_crocomire_rng: { LDA !ram_crocomire_rng : BEQ .no_manip DEC : BEQ .step - LDA #$0000 ; return with <400 for swipe + TDC ; return with <400 for swipe RTS .step @@ -1118,16 +1227,33 @@ endif XBA : STA !eram_ridley_pogo_time_rng LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_POGO_HEIGHT_MASK - STA !eram_ridley_pogo_height_rng + LSR #3 : STA !eram_ridley_pogo_height_rng - PHX : LDA !ram_ridley_rng_flags : LSR #2 : PHA - AND #$000E : TAX : LDA.l ridley_backpogo_threshold_table,X - STA !eram_ridley_backpogo_left_rng : PLA : XBA - AND #$000E : TAX : LDA.l ridley_backpogo_threshold_table,X - STA !eram_ridley_backpogo_right_rng : PLX + PHX : LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_MASK + XBA : ASL : TAX : LDA.l ridley_backpogo_threshold_table,X + STA !eram_ridley_backpogo_rng : PLX RTL } +ridley_backpogo_threshold_table: + dw #$0555, #$0000 + dw #$FFFF, #$0AAA, #$0FFF + dw #$1554, #$1AA9, #$1FFE + dw #$2553, #$2AA8, #$2FFD + dw #$3552, #$3AA7, #$3FFC + dw #$4551, #$4AA6, #$4FFB + dw #$5550, #$5AA5, #$5FFA + dw #$654F, #$6AA4, #$6FF9 + dw #$754E, #$7AA3, #$7FF8 + dw #$854D, #$8AA2, #$8FF7 + dw #$954C, #$9AA1, #$9FF6 + dw #$A54B, #$AAA0, #$AFF5 + dw #$B54A, #$BA9F, #$BFF4 + dw #$C549, #$CA9E, #$CFF3 + dw #$D548, #$DA9D, #$DFF2 + dw #$E547, #$EA9C, #$EFF1 + dw #$F546, #$FA9B, #$FFF0 + %endfree(A5) @@ -1392,14 +1518,14 @@ org $A6B8EB else org $A6B8DB endif - CMP !eram_ridley_backpogo_right_rng + CMP !eram_ridley_backpogo_rng if !FEATURE_PAL org $A6B90D else org $A6B8FD endif - CMP !eram_ridley_backpogo_left_rng + CMP !eram_ridley_backpogo_rng if !FEATURE_PAL org $A6B93B @@ -1500,9 +1626,6 @@ else dw $B441, $B441, $B441, $B441, $B441, $B441, $B441, $B441 endif -ridley_backpogo_threshold_table: - dw #$0555, #$0AAA, #$0FFF, #$1AA9, #$2AA8, #$4551, #$6FF9, #$0000 - ridley_reset_damagecounter: { TDC : STA !DAMAGE_COUNTER @@ -1722,5 +1845,116 @@ else endif } +mb_ground_attack_max_rings_rng_table: + db #$00, #$FF, #$FF + +mb_ground_attack_max_fries_rng_table: + db #$00, #$00, #$FF + +mb_ground_attack_max_bombs_rng_table: + db #$00, #$00, #$00 + +mb_ground_attack_min_rings_rng_table: + db #$54, #$54, #$AA + +mb_ground_attack_min_fries_rng_table: + db #$54, #$AA, #$AA + +mb_ground_attack_min_bombs_rng_table: + db #$55, #$AA, #$FF + +mb_ground_attack_minimized_rng_table: + db #$FF, #$FF, #$FF + %endfree(A9) + +%startfree(AA) + +mb_normal_walking_rng_table: + dw #$1000, #$0000, #$FFFF, #$1000 + +mb_ketchup_walking_rng_table: + dw #$2000, #$FFFF, #$0000, #$2000 + +mb_damage_down_rng_table: + dw #$0FF0, #$1000, #$0000, #$0FF0 + +mb_ketchup_rng_table: + dw #$A000, #$FFFF, #$0000, #$A000 + +mb_air_rings_rng_table: + dw #$0080, #$0000, #$0080, #$0100, #$0100, #$0080, #$0000, #$0080 + +mb_ground_bomb_rng_table: + dw #$0080, #$0100, #$0000, #$0100, #$0080, #$0100, #$0080, #$0100 + +mb_ground_attack_rng_tables_table: +if !FEATURE_PAL + dw $B729 +else + dw $B6DC +endif + dw #mb_ground_attack_max_rings_rng_table + dw #mb_ground_attack_max_bombs_rng_table + dw #mb_ground_attack_max_fries_rng_table + dw #mb_ground_attack_min_rings_rng_table + dw #mb_ground_attack_min_bombs_rng_table + dw #mb_ground_attack_min_fries_rng_table + dw #mb_ground_attack_minimized_rng_table + +mb_close_attack_rng_tables_table: +if !FEATURE_PAL + dw $B72C +else + dw $B6DF +endif + dw #mb_ground_attack_max_rings_rng_table + dw #mb_ground_attack_max_bombs_rng_table + dw #mb_ground_attack_max_fries_rng_table + dw #mb_ground_attack_min_rings_rng_table + dw #mb_ground_attack_min_bombs_rng_table + dw #mb_ground_attack_min_fries_rng_table + dw #mb_ground_attack_minimized_rng_table + +mb_try_bomb_crouch_rng_table: + dw #$FF80, #$0000, #$FFFF, #$FF80 + +mb_bomb_crouch_rng_table: + dw #$8000, #$0000, #$FFFF, #$8000 + +init_mb_rng_from_menu: +{ + LDA !ENEMY_VAR_4 : PHA + JSL hook_mb_init_rng + PLA : STA !ENEMY_VAR_4 + RTL +} + +hook_mb_init_rng: +{ + LDA !ram_mb_rng : AND !MB_RNG_WALKING_MASK : ASL : TAX + LDA.l mb_normal_walking_rng_table,X : STA !eram_mb_normal_walking_rng + LDA.l mb_ketchup_walking_rng_table,X : STA !eram_mb_ketchup_walking_rng + LDA !ram_mb_rng : AND !MB_RNG_KETCHUP_MASK : LSR : TAX + LDA.l mb_ketchup_rng_table,X : STA !eram_mb_ketchup_rng + LDA !ram_mb_rng : AND !MB_RNG_DAMAGE_DOWN_MASK : LSR #3 : TAX + LDA.l mb_damage_down_rng_table,X : STA !eram_mb_damage_down_rng + LDA !ram_mb_rng : AND !MB_RNG_PHASE3_ATTACK_MASK + EOR !MB_RNG_PHASE3_ATTACK_RINGS : STA !eram_mb_phase3_attack_rng + LDA !ram_mb_rng : AND !MB_RNG_NORMAL_ATTACK_MASK : XBA : TAX + LDA.l mb_air_rings_rng_table,X : STA !eram_mb_air_rings_rng + LDA.l mb_ground_bomb_rng_table,X : STA !eram_mb_ground_bomb_rng + LDA.l mb_ground_attack_rng_tables_table,X : STA !eram_mb_ground_attack_rng_table + LDA.l mb_close_attack_rng_tables_table,X : STA !eram_mb_close_attack_rng_table + LDA !ram_mb_rng : AND !MB_RNG_BOMB_CROUCH_MASK : XBA : ASL #3 : XBA : TAX + LDA.l mb_try_bomb_crouch_rng_table,X : STA !eram_mb_try_bomb_crouch + LDA.l mb_bomb_crouch_rng_table,X : STA !eram_mb_bomb_crouch + + ; Overwritten logic + LDA #$000A : STA !ENEMY_VAR_4 + RTL +} + +%endfree(AA) + diff --git a/src/main.asm b/src/main.asm index 70c06cfd..79eedb40 100644 --- a/src/main.asm +++ b/src/main.asm @@ -16,7 +16,7 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 6 !VERSION_BUILD = 7 -!VERSION_REV = 10 +!VERSION_REV = 11 table ../resources/normal.tbl print "" diff --git a/src/mainmenu.asm b/src/mainmenu.asm index c8d133db..71c1003d 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -100,6 +100,32 @@ action_game_mainmenu: JMP action_mainmenu } +action_rng_mainmenu: +{ + LDA !ram_turret_rng : LSR : STA !ram_cm_turret_rng + TDC : STA !ram_cm_botwoon_first_rng + STA !ram_cm_botwoon_hidden_rng : STA !ram_cm_botwoon_second_rng + LDA !ram_botwoon_rng : BIT !BOTWOON_RNG_FIRST_ENABLED : BEQ .botwoonHidden + AND !BOTWOON_RNG_FIRST_VALUE : LSR #4 : INC + STA !ram_cm_botwoon_first_rng : LDA !ram_botwoon_rng + .botwoonHidden + BIT !BOTWOON_RNG_HIDDEN_ENABLED : BEQ .botwoonSecond + AND !BOTWOON_RNG_HIDDEN_VALUE : XBA : LSR #2 : INC + STA !ram_cm_botwoon_hidden_rng : LDA !ram_botwoon_rng + .botwoonSecond + BIT !BOTWOON_RNG_SECOND_ENABLED : BEQ .botwoonSpit + AND !BOTWOON_RNG_SECOND_VALUE : XBA : LSR #4 : INC + STA !ram_cm_botwoon_second_rng : LDA !ram_botwoon_rng + .botwoonSpit + AND !BOTWOON_RNG_SPIT_MASK : LSR #2 : STA !ram_cm_botwoon_spit_rng + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_AFTER_SPIT_MASK + BEQ .botwoonAfterSpit + EOR !BOTWOON_RNG_AFTER_SPIT_ENABLED : INC + .botwoonAfterSpit + STA !ram_cm_botwoon_after_spit_rng + JMP action_mainmenu +} + action_ctrlshortcut_mainmenu: { TDC : TAX : STA !ram_cm_ctrl_savestates_allowed @@ -154,12 +180,6 @@ action_layout_mainmenu: BRA action_mainmenu } -action_rng_mainmenu: -{ - LDA !ram_turret_rng : LSR : STA !ram_cm_turret_rng - BRA action_mainmenu -} - action_customize_mainmenu: { ; Set fast button selection @@ -2553,17 +2573,19 @@ RngMenu: dw #$FFFF dw #rng_crocomire_rng dw #$FFFF - dw #$FFFF dw #rng_botwoon_first dw #rng_botwoon_hidden dw #rng_botwoon_second dw #rng_botwoon_spit + dw #rng_botwoon_after_spit dw #$FFFF dw #rng_draygon_rng_right dw #rng_draygon_rng_left dw #rng_turret_rng dw #$FFFF dw #rng_baby_rng + dw #$FFFF + dw #rng_goto_mb dw #$0000 %cm_header("BOSS RNG CONTROL") @@ -2575,7 +2597,7 @@ rng_goto_ridley: rng_botwoon_first: dw !ACTION_CHOICE - dl #!ram_cm_botwoon_first + dl #!ram_cm_botwoon_first_rng dw #.routine db #$28, "Botwoon First", #$FF db #$28, " RANDOM", #$FF @@ -2585,23 +2607,21 @@ rng_botwoon_first: db #$28, " LL LEFT", #$FF db #$FF .routine - LDA !ram_cm_botwoon_first : BEQ .random - ; possible values are $01, $09, $11, $19 - ; the 1s bit will be dropped, used here for convenience - DEC : ASL #3 : INC - STA !ram_botwoon_first : STA !ram_botwoon_rng - RTL - .random - STA !ram_botwoon_first - LDA !ram_botwoon_second : BNE .set_rng - LDA !ram_botwoon_hidden - .set_rng + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_FIRST_INVERTED STA !ram_botwoon_rng + LDA !ram_cm_botwoon_first_rng : BEQ .checkRoom + ; possible values are $01, $09, $11, $19 + DEC : ASL #3 : INC : ASL + ORA !ram_botwoon_rng : STA !ram_botwoon_rng + .checkRoom + LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done + JML init_botwoon_rng + .done RTL rng_botwoon_hidden: dw !ACTION_CHOICE - dl #!ram_cm_botwoon_hidden + dl #!ram_cm_botwoon_hidden_rng dw #.routine db #$28, "Botwoon Hidden", #$FF db #$28, " RANDOM", #$FF @@ -2610,23 +2630,21 @@ rng_botwoon_hidden: db #$28, "LR BR TR RT", #$FF db #$FF .routine - LDA !ram_cm_botwoon_hidden : BEQ .random - ; possible values are $01, $09, $11 - ; the 1s bit will be dropped, used here for convenience - DEC : ASL #3 : INC - STA !ram_botwoon_hidden : STA !ram_botwoon_rng - RTL - .random - STA !ram_botwoon_hidden - LDA !ram_botwoon_first : BNE .set_rng - LDA !ram_botwoon_second - .set_rng + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_HIDDEN_INVERTED STA !ram_botwoon_rng + LDA !ram_cm_botwoon_hidden_rng : BEQ .checkRoom + ; possible values are $01, $09, $11 + DEC : ASL #3 : INC : XBA : LSR + ORA !ram_botwoon_rng : STA !ram_botwoon_rng + .checkRoom + LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done + JML init_botwoon_rng + .done RTL rng_botwoon_second: dw !ACTION_CHOICE - dl #!ram_cm_botwoon_second + dl #!ram_cm_botwoon_second_rng dw #.routine db #$28, "Botwoon Second", #$FF db #$28, " RANDOM", #$FF @@ -2636,23 +2654,21 @@ rng_botwoon_second: db #$28, "LL BB TT RR", #$FF db #$FF .routine - LDA !ram_cm_botwoon_second : BEQ .random - ; possible values are $01, $09, $11, $19 - ; the 1s bit will be dropped, used here for convenience - DEC : ASL #3 : INC - STA !ram_botwoon_second : STA !ram_botwoon_rng - RTL - .random - STA !ram_botwoon_second - LDA !ram_botwoon_first : BNE .set_rng - LDA !ram_botwoon_hidden - .set_rng + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_SECOND_INVERTED STA !ram_botwoon_rng + LDA !ram_cm_botwoon_second_rng : BEQ .checkRoom + ; possible values are $01, $09, $11, $19 + DEC : ASL #3 : INC : XBA : ASL + ORA !ram_botwoon_rng : STA !ram_botwoon_rng + .checkRoom + LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done + JML init_botwoon_rng + .done RTL rng_botwoon_spit: dw !ACTION_CHOICE - dl #!ram_cm_botwoon_spit + dl #!ram_cm_botwoon_spit_rng dw #.routine db #$28, "Botwoon Spit", #$FF db #$28, " RANDOM", #$FF @@ -2660,8 +2676,36 @@ rng_botwoon_spit: db #$28, "ALWAYS SPIT", #$FF db #$FF .routine + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_SPIT_INVERTED + STA !ram_botwoon_rng + LDA !ram_cm_botwoon_spit_rng : BEQ .checkRoom ; 0-4 = no spit, 6-E = spit - LDA !ram_cm_botwoon_spit : ASL #2 : STA !ram_botwoon_spit + ASL #2 : ORA !ram_botwoon_rng : STA !ram_botwoon_rng + .checkRoom + LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done + JML init_botwoon_rng + .done + RTL + +rng_botwoon_after_spit: + dw !ACTION_CHOICE + dl #!ram_cm_botwoon_after_spit_rng + dw #.routine + db #$28, "Botwoon After S", #$FF + db #$28, "pit RANDOM", #$FF + db #$28, "pit MOVE", #$FF + db #$28, "pit HIDE", #$FF + db #$FF + .routine + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_AFTER_SPIT_INVERTED + STA !ram_botwoon_rng + LDA !ram_cm_botwoon_after_spit_rng : BEQ .checkRoom + DEC : ORA !BOTWOON_RNG_AFTER_SPIT_ENABLED + ORA !ram_botwoon_rng : STA !ram_botwoon_rng + .checkRoom + LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done + JML init_botwoon_rng + .done RTL rng_draygon_rng_right: @@ -2754,6 +2798,9 @@ rng_baby_rng: db #$28, " LUNGE", #$FF db #$FF +rng_goto_mb: + %cm_jsl("Mother Brain Menu", rng_prepare_mb_menu, #RngMBMenu) + ; -------------- ; Phantoon Menu @@ -2761,10 +2808,19 @@ rng_baby_rng: rng_prepare_phantoon_menu: { - LDA !ram_phantoon_rng_inverted : PHA + LDA !ram_phantoon_phase_rng : PHA JSL rng_phan_set_phan_first_phase JSL rng_phan_set_phan_second_phase - PLA : STA !ram_phantoon_rng_inverted + PLA : STA !ram_phantoon_phase_rng + AND !PHANTOON_RNG_FLIP_MASK : ASL #2 : XBA : STA !ram_cm_phantoon_flip_rng + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_FLAMES_MASK + STA !ram_cm_phantoon_flames_rng + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_FLAMES_PATH_MASK + ASL #2 : XBA : STA !ram_cm_phantoon_flame_direction_rng + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_FLAMES_NEXT_MASK + XBA : STA !ram_cm_phantoon_next_flames_rng + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_EYE_CLOSE_MASK + XBA : ASL #2 : XBA : STA !ram_cm_phantoon_eyeclose_rng %setmenubank() JML action_submenu } @@ -2784,7 +2840,7 @@ RngPhantoonMenu: dw #rng_phan_fast_right_2 dw #rng_phan_mid_right_2 dw #rng_phan_slow_right_2 - dw #rng_phan_second_phase_inverted + dw #rng_phan_second_phase_flip dw #$FFFF dw #rng_phan_eyeclose dw #rng_phan_flamepattern @@ -2796,7 +2852,7 @@ RngPhantoonMenu: rng_phan_first_phase: dw !ACTION_CHOICE - dl #!ram_cm_phan_first_phase + dl #!ram_cm_phantoon_first_phase_rng dw .routine db #$28, "Phan 1st Phase", #$FF db #$28, " RANDOM", #$FF @@ -2818,12 +2874,18 @@ rng_phan_first_phase: db #$FF .routine ASL : TAX - LDA.l rng_phan_phase_1_table,X : STA !ram_phantoon_rng_round_1 + LDA !ram_phantoon_phase_rng : AND !PHANTOON_RNG_PHASE_1_INVERTED + STA !ram_phantoon_phase_rng + LDA.l rng_phan_phase_1_table,X + ORA !ram_phantoon_phase_rng : STA !ram_phantoon_phase_rng + LDA !ROOM_ID : CMP.w #ROOM_PhantoonRoom : BNE .done + JML init_phantoon_rng + .done RTL rng_phan_second_phase: dw !ACTION_CHOICE - dl #!ram_cm_phan_second_phase + dl #!ram_cm_phantoon_second_phase_rng dw .routine db #$28, "Phan 2nd Phase", #$FF db #$28, " RANDOM", #$FF @@ -2845,11 +2907,22 @@ rng_phan_second_phase: db #$FF .routine ASL : TAX - LDA.l rng_phan_phase_2_table,X : STA !ram_phantoon_rng_round_2 - BEQ .set_inverted : TXA : BEQ .set_inverted - LDA #$0002 - .set_inverted - STA !ram_phantoon_rng_inverted + ; Either set flip off or back to vanilla when changing second phase + ; By default assume vanilla + TDC : STA !ram_cm_phantoon_flip_rng + LDA !ram_phantoon_phase_rng : AND !PHANTOON_RNG_PHASE_2_FLIP_INVERTED + STA !ram_phantoon_phase_rng + LDA.l rng_phan_phase_2_table,X + ORA !ram_phantoon_phase_rng : STA !ram_phantoon_phase_rng + LDA.l rng_phan_phase_2_table,X + BEQ .done_flip : TXA : BEQ .done_flip + ; If setting phase 2 to non-vanilla value then turn flip off + LDA #$0002 : STA !ram_cm_phantoon_flip_rng + LDA !ram_phantoon_phase_rng : ORA #$0080 : STA !ram_phantoon_phase_rng + .done_flip + LDA !ROOM_ID : CMP.w #ROOM_PhantoonRoom : BNE .done + JML init_phantoon_rng + .done RTL rng_phan_phase_1_table: @@ -2857,99 +2930,132 @@ rng_phan_phase_1_table: dw #$000C, #$0003, #$000F, #$0033, #$003C, #$002A, #$0015, #$0000 rng_phan_phase_2_table: - dw #$003F, #$0020, #$0008, #$0002, #$0010, #$0004, #$0001, #$0030 - dw #$000C, #$0003, #$0007, #$0023, #$0024, #$0022, #$0005, #$0000 + dw #$3F00, #$2000, #$0800, #$0200, #$1000, #$0400, #$0100, #$3000 + dw #$0C00, #$0300, #$0F00, #$3300, #$3C00, #$2A00, #$1500, #$0000 rng_phan_set_phan_first_phase: { LDX #$0000 - LDA !ram_phantoon_rng_round_1 : BEQ .end_first_loop + LDA !ram_phantoon_phase_rng : AND !PHANTOON_RNG_PHASE_1_MASK + BEQ .end_first_loop .first_loop CMP.l rng_phan_phase_1_table,X : BEQ .end_first_loop INX #2 : CPX #$001E : BNE .first_loop .end_first_loop - TXA : LSR : STA !ram_cm_phan_first_phase + TXA : LSR : STA !ram_cm_phantoon_first_phase_rng + LDA !ROOM_ID : CMP.w #ROOM_PhantoonRoom : BNE .done + JML init_phantoon_rng + .done RTL } rng_phan_set_phan_second_phase: { - LDX #$0000 - LDA !ram_phantoon_rng_round_2 : BEQ .end_second_loop + ; Either set flip off or back to vanilla when changing second phase + ; By default assume vanilla + TDC : TAX : STA !ram_cm_phantoon_flip_rng + LDA !ram_phantoon_phase_rng : AND !PHANTOON_RNG_FLIP_INVERTED + STA !ram_phantoon_phase_rng : AND !PHANTOON_RNG_PHASE_2_MASK + BEQ .end_second_loop .second_loop CMP.l rng_phan_phase_2_table,X : BEQ .end_second_loop INX #2 : CPX #$001E : BNE .second_loop .end_second_loop - TXA : LSR : STA !ram_cm_phan_second_phase - BEQ .set_inverted : TXA : BEQ .set_inverted - LDA #$0002 - .set_inverted - STA !ram_phantoon_rng_inverted + TXA : LSR : STA !ram_cm_phantoon_second_phase_rng + BEQ .done_flip : TXA : BEQ .done_flip + ; If setting phase 2 to non-vanilla value then turn flip off + LDA #$0002 : STA !ram_cm_phantoon_flip_rng + LDA !ram_phantoon_phase_rng : ORA #$0080 : STA !ram_phantoon_phase_rng + .done_flip + LDA !ROOM_ID : CMP.w #ROOM_PhantoonRoom : BNE .done + JML init_phantoon_rng + .done RTL } +rng_phan_always_visible: + %cm_toggle_bit("Always Visible", !ram_phantoon_phase_rng, !PHANTOON_RNG_VISIBLE_BIT, rng_phan_set_phan_second_phase_done_flip) + rng_phan_fast_left_1: - %cm_toggle_bit("#1 Fast Left", !ram_phantoon_rng_round_1, #$0020, rng_phan_set_phan_first_phase) + %cm_toggle_bit("#1 Fast Left", !ram_phantoon_phase_rng, #$0020, rng_phan_set_phan_first_phase) rng_phan_mid_left_1: - %cm_toggle_bit("#1 Mid Left", !ram_phantoon_rng_round_1, #$0008, rng_phan_set_phan_first_phase) + %cm_toggle_bit("#1 Mid Left", !ram_phantoon_phase_rng, #$0008, rng_phan_set_phan_first_phase) rng_phan_slow_left_1: - %cm_toggle_bit("#1 Slow Left", !ram_phantoon_rng_round_1, #$0002, rng_phan_set_phan_first_phase) + %cm_toggle_bit("#1 Slow Left", !ram_phantoon_phase_rng, #$0002, rng_phan_set_phan_first_phase) rng_phan_fast_right_1: - %cm_toggle_bit("#1 Fast Right", !ram_phantoon_rng_round_1, #$0010, rng_phan_set_phan_first_phase) + %cm_toggle_bit("#1 Fast Right", !ram_phantoon_phase_rng, #$0010, rng_phan_set_phan_first_phase) rng_phan_mid_right_1: - %cm_toggle_bit("#1 Mid Right", !ram_phantoon_rng_round_1, #$0004, rng_phan_set_phan_first_phase) + %cm_toggle_bit("#1 Mid Right", !ram_phantoon_phase_rng, #$0004, rng_phan_set_phan_first_phase) rng_phan_slow_right_1: - %cm_toggle_bit("#1 Slow Right", !ram_phantoon_rng_round_1, #$0001, rng_phan_set_phan_first_phase) + %cm_toggle_bit("#1 Slow Right", !ram_phantoon_phase_rng, #$0001, rng_phan_set_phan_first_phase) rng_phan_fast_left_2: - %cm_toggle_bit("#2 Fast Left", !ram_phantoon_rng_round_2, #$0020, rng_phan_set_phan_second_phase) + %cm_toggle_bit("#2 Fast Left", !ram_phantoon_phase_rng, #$2000, rng_phan_set_phan_second_phase) rng_phan_mid_left_2: - %cm_toggle_bit("#2 Mid Left", !ram_phantoon_rng_round_2, #$0008, rng_phan_set_phan_second_phase) + %cm_toggle_bit("#2 Mid Left", !ram_phantoon_phase_rng, #$0800, rng_phan_set_phan_second_phase) rng_phan_slow_left_2: - %cm_toggle_bit("#2 Slow Left", !ram_phantoon_rng_round_2, #$0002, rng_phan_set_phan_second_phase) + %cm_toggle_bit("#2 Slow Left", !ram_phantoon_phase_rng, #$0200, rng_phan_set_phan_second_phase) rng_phan_fast_right_2: - %cm_toggle_bit("#2 Fast Right", !ram_phantoon_rng_round_2, #$0010, rng_phan_set_phan_second_phase) + %cm_toggle_bit("#2 Fast Right", !ram_phantoon_phase_rng, #$1000, rng_phan_set_phan_second_phase) rng_phan_mid_right_2: - %cm_toggle_bit("#2 Mid Right", !ram_phantoon_rng_round_2, #$0004, rng_phan_set_phan_second_phase) + %cm_toggle_bit("#2 Mid Right", !ram_phantoon_phase_rng, #$0400, rng_phan_set_phan_second_phase) rng_phan_slow_right_2: - %cm_toggle_bit("#2 Slow Right", !ram_phantoon_rng_round_2, #$0001, rng_phan_set_phan_second_phase) + %cm_toggle_bit("#2 Slow Right", !ram_phantoon_phase_rng, #$0100, rng_phan_set_phan_second_phase) -rng_phan_second_phase_inverted: +rng_phan_second_phase_flip: dw !ACTION_CHOICE - dl #!ram_phantoon_rng_inverted - dw #$0000 - db #$28, "2nd Phase Inver", #$FF - db #$28, "t VANILLA", #$FF - db #$28, "t ON", #$FF - db #$28, "t OFF", #$FF - db #$28, "t RANDOM", #$FF + dl #!ram_cm_phantoon_flip_rng + dw #.routine + db #$28, "2nd Phase Flip", #$FF + db #$28, " VANILLA", #$FF + db #$28, " ON", #$FF + db #$28, " OFF", #$FF + db #$28, " RANDOM", #$FF db #$FF + .routine + LDA !ram_phantoon_phase_rng : AND !PHANTOON_RNG_FLIP_INVERTED + STA !ram_phantoon_phase_rng + LDA !ram_cm_phantoon_flip_rng : XBA : LSR #2 + ORA !ram_phantoon_phase_rng : STA !ram_phantoon_phase_rng + LDA !ROOM_ID : CMP.w #ROOM_PhantoonRoom : BNE .done + JML init_phantoon_rng + .done + RTL rng_phan_eyeclose: dw !ACTION_CHOICE - dl #!ram_phantoon_rng_eyeclose - dw #$0000 + dl #!ram_cm_phantoon_eyeclose_rng + dw #.routine db #$28, "Phan Eye Close", #$FF db #$28, " RANDOM", #$FF db #$28, " SLOW", #$FF db #$28, " MID", #$FF db #$28, " FAST", #$FF db #$FF + .routine + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_EYE_CLOSE_INVERTED + STA !ram_phantoon_eye_and_flames_rng + LDA !ram_cm_phantoon_eyeclose_rng : XBA : LSR #2 : XBA + ORA !ram_phantoon_eye_and_flames_rng : STA !ram_phantoon_eye_and_flames_rng + LDA !ROOM_ID : CMP.w #ROOM_PhantoonRoom : BNE .done + JML init_phantoon_rng + .done + RTL rng_phan_flamepattern: dw !ACTION_CHOICE - dl #!ram_phantoon_rng_flames - dw #$0000 + dl #!ram_cm_phantoon_flames_rng + dw #.routine db #$28, "Phantoon Flames", #$FF db #$28, " RANDOM", #$FF db #$28, " 22222", #$FF @@ -2957,11 +3063,18 @@ rng_phan_flamepattern: db #$28, " 3333333", #$FF db #$28, " 1424212", #$FF db #$FF + .routine + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_FLAMES_INVERTED + ORA !ram_cm_phantoon_flames_rng : STA !ram_phantoon_eye_and_flames_rng + LDA !ROOM_ID : CMP.w #ROOM_PhantoonRoom : BNE .done + JML init_phantoon_rng + .done + RTL rng_phan_next_flamepattern: dw !ACTION_CHOICE - dl #!ram_phantoon_rng_next_flames - dw #$0000 + dl #!ram_cm_phantoon_next_flames_rng + dw #.routine db #$28, "Next Flames", #$FF db #$28, " RANDOM", #$FF db #$28, " 22222", #$FF @@ -2969,32 +3082,35 @@ rng_phan_next_flamepattern: db #$28, " 3333333", #$FF db #$28, " 1424212", #$FF db #$FF + .routine + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_FLAMES_NEXT_INVERTED + STA !ram_phantoon_eye_and_flames_rng + LDA !ram_cm_phantoon_next_flames_rng : XBA + ORA !ram_phantoon_eye_and_flames_rng : STA !ram_phantoon_eye_and_flames_rng + LDA !ROOM_ID : CMP.w #ROOM_PhantoonRoom : BNE .done + JML init_phantoon_rng + .done + RTL rng_phan_flame_direction: dw !ACTION_CHOICE - dl #!ram_phantoon_flame_direction - dw #$0000 + dl #!ram_cm_phantoon_flame_direction_rng + dw #.routine db #$28, "Flame Direction", #$FF db #$28, " RANDOM", #$FF db #$28, " LEFT", #$FF db #$28, " RIGHT", #$FF db #$FF + .routine + LDA !ram_phantoon_eye_and_flames_rng : AND !PHANTOON_RNG_FLAMES_PATH_INVERTED + STA !ram_phantoon_eye_and_flames_rng + LDA !ram_cm_phantoon_flame_direction_rng : XBA : LSR #2 + ORA !ram_phantoon_eye_and_flames_rng : STA !ram_phantoon_eye_and_flames_rng + LDA !ROOM_ID : CMP.w #ROOM_PhantoonRoom : BNE .done + JML init_phantoon_rng + .done + RTL -rng_phan_always_visible: - %cm_toggle("Always Visible", !ram_phantoon_always_visible, #$01, #0) - - -; MB delay before rainbow beam? [$9CAD] -; MB idles when above red beam HP [$B622] -; MB walk/attack/red beam [$B634] -; MB choose attack? [$B68D] -; MB in air 50/50 onions or fries [$B6EF] -; MB ground 50/50 bomb or choose attack? [$B70C] -; MB bomb consider crouch? [$B781] -; MB bomb crouch? [$B7B7] -; MB stand up or lean down? [$C1B2, $C1C0] -; MB phase 3 attack? [$C227, $C22F] -; MB walking? [$C285, $C704] ; -------------- ; Ridley Menu @@ -3002,31 +3118,29 @@ rng_phan_always_visible: rng_prepare_ridley_menu: { + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_CERES_MASK + STA !ram_cm_ridley_ceres_ai_rng LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_POGO_HEIGHT_MASK - STA !ram_cm_ridley_pogo_height - LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_LEFT_MASK - LSR #3 : STA !ram_cm_ridley_backpogo_left + LSR #3 : STA !ram_cm_ridley_pogo_height_rng LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_75_25_MASK - ASL #2 : XBA : STA !ram_cm_ridley_lunge_pogo - LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_CERES_MASK - XBA : STA !ram_cm_ridley_ceres_ai - LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_RIGHT_MASK - XBA : LSR #3 : STA !ram_cm_ridley_backpogo_right + ASL #2 : XBA : STA !ram_cm_ridley_lunge_pogo_rng + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_MASK + XBA : STA !ram_cm_ridley_backpogo_rng LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_50_50_MASK - XBA : ASL #2 : XBA : STA !ram_cm_ridley_swoop_pogo + XBA : ASL #2 : XBA : STA !ram_cm_ridley_swoop_pogo_rng LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_HOVER_TIME_MASK - STA !ram_cm_ridley_hover_time_value : BEQ .set_hover + STA !ram_cm_ridley_hover_time_value_rng : BEQ .set_hover TDC : INC .set_hover - STA !ram_cm_ridley_hover_time + STA !ram_cm_ridley_hover_time_rng LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_FIREBALL_MASK - ASL #2 : XBA : STA !ram_cm_ridley_hover_fireball + ASL #2 : XBA : STA !ram_cm_ridley_hover_fireball_rng LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_POGO_TIME_MASK - XBA : STA !ram_cm_ridley_pogo_time_value : BEQ .set_pogo + XBA : STA !ram_cm_ridley_pogo_time_value_rng : BEQ .set_pogo TDC : INC .set_pogo - STA !ram_cm_ridley_pogo_time - %setmenubank() + STA !ram_cm_ridley_pogo_time_rng + %setmenubank() JML action_submenu } @@ -3035,8 +3149,7 @@ RngRidleyMenu: dw #$FFFF dw #rng_ridley_lunge_pogo dw #rng_ridley_swoop_pogo - dw #rng_ridley_backpogo_left - dw #rng_ridley_backpogo_right + dw #rng_ridley_backpogo dw #rng_ridley_pogo_height dw #$FFFF dw #rng_ridley_pogo_time @@ -3049,7 +3162,7 @@ RngRidleyMenu: rng_ridley_ceres_ai: dw !ACTION_CHOICE - dl #!ram_cm_ridley_ceres_ai + dl #!ram_cm_ridley_ceres_ai_rng dw #.routine db #$28, "Ceres Ridley AI", #$FF db #$28, " VANILLA", #$FF @@ -3059,9 +3172,7 @@ rng_ridley_ceres_ai: db #$FF .routine LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_CERES_INVERTED - STA !ram_ridley_rng_flags - LDA !ram_cm_ridley_ceres_ai : XBA - ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags + ORA !ram_cm_ridley_ceres_ai_rng : STA !ram_ridley_rng_flags LDA !ROOM_ID : CMP.w #ROOM_CeresRidleyRoom : BNE .done JML init_ceres_ridley_rng .done @@ -3069,7 +3180,7 @@ rng_ridley_ceres_ai: rng_ridley_lunge_pogo: dw !ACTION_CHOICE - dl #!ram_cm_ridley_lunge_pogo + dl #!ram_cm_ridley_lunge_pogo_rng dw #.routine db #$28, "75/25 Lunge/Pog", #$FF db #$28, "o VANILLA", #$FF @@ -3079,7 +3190,7 @@ rng_ridley_lunge_pogo: .routine LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_75_25_INVERTED STA !ram_ridley_rng_flags - LDA !ram_cm_ridley_lunge_pogo : XBA : LSR #2 + LDA !ram_cm_ridley_lunge_pogo_rng : XBA : LSR #2 ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done JML init_zebes_ridley_rng @@ -3088,7 +3199,7 @@ rng_ridley_lunge_pogo: rng_ridley_swoop_pogo: dw !ACTION_CHOICE - dl #!ram_cm_ridley_swoop_pogo + dl #!ram_cm_ridley_swoop_pogo_rng dw #.routine db #$28, "50/50 Swoop/Pog", #$FF db #$28, "o VANILLA", #$FF @@ -3098,55 +3209,73 @@ rng_ridley_swoop_pogo: .routine LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_50_50_INVERTED STA !ram_ridley_rng_flags - LDA !ram_cm_ridley_swoop_pogo : XBA : LSR #2 : XBA - ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags - LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done - JML init_zebes_ridley_rng - .done - RTL - -rng_ridley_backpogo_left: - dw !ACTION_CHOICE - dl #!ram_cm_ridley_backpogo_left - dw #.routine - db #$28, "Backpogo Facing", #$FF - db #$28, " Left 1x", #$FF - db #$28, " Left 2x", #$FF - db #$28, " Left 3x", #$FF - db #$28, " Left 5x", #$FF - db #$28, " Left 8x", #$FF - db #$28, " Left 13x", #$FF - db #$28, " Left 21x", #$FF - db #$28, " Left 0x", #$FF - db #$FF - .routine - LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_LEFT_INVERTED - STA !ram_ridley_rng_flags - LDA !ram_cm_ridley_backpogo_left : ASL #3 + LDA !ram_cm_ridley_swoop_pogo_rng : XBA : LSR #2 : XBA ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done JML init_zebes_ridley_rng .done RTL -rng_ridley_backpogo_right: +rng_ridley_backpogo: dw !ACTION_CHOICE - dl #!ram_cm_ridley_backpogo_right + dl #!ram_cm_ridley_backpogo_rng dw #.routine - db #$28, "Backpogo Facing", #$FF - db #$28, " Right 1x", #$FF - db #$28, " Right 2x", #$FF - db #$28, " Right 3x", #$FF - db #$28, " Right 5x", #$FF - db #$28, " Right 8x", #$FF - db #$28, " Right 13x", #$FF - db #$28, " Right 21x", #$FF - db #$28, " Right 0x", #$FF + db #$28, "Backpogo", #$FF + db #$28, " VANILLA", #$FF + db #$28, " OFF", #$FF + db #$28, " MAX", #$FF + db #$28, " 2x", #$FF + db #$28, " 3x", #$FF + db #$28, " 4x", #$FF + db #$28, " 5x", #$FF + db #$28, " 6x", #$FF + db #$28, " 7x", #$FF + db #$28, " 8x", #$FF + db #$28, " 9x", #$FF + db #$28, " 10x", #$FF + db #$28, " 11x", #$FF + db #$28, " 12x", #$FF + db #$28, " 13x", #$FF + db #$28, " 14x", #$FF + db #$28, " 15x", #$FF + db #$28, " 16x", #$FF + db #$28, " 17x", #$FF + db #$28, " 18x", #$FF + db #$28, " 19x", #$FF + db #$28, " 20x", #$FF + db #$28, " 21x", #$FF + db #$28, " 22x", #$FF + db #$28, " 23x", #$FF + db #$28, " 24x", #$FF + db #$28, " 25x", #$FF + db #$28, " 26x", #$FF + db #$28, " 27x", #$FF + db #$28, " 28x", #$FF + db #$28, " 29x", #$FF + db #$28, " 30x", #$FF + db #$28, " 31x", #$FF + db #$28, " 32x", #$FF + db #$28, " 33x", #$FF + db #$28, " 34x", #$FF + db #$28, " 35x", #$FF + db #$28, " 36x", #$FF + db #$28, " 37x", #$FF + db #$28, " 38x", #$FF + db #$28, " 39x", #$FF + db #$28, " 40x", #$FF + db #$28, " 41x", #$FF + db #$28, " 42x", #$FF + db #$28, " 43x", #$FF + db #$28, " 44x", #$FF + db #$28, " 45x", #$FF + db #$28, " 46x", #$FF + db #$28, " 47x", #$FF + db #$28, " 48x", #$FF db #$FF .routine - LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_RIGHT_INVERTED + LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_BACKPOGO_INVERTED STA !ram_ridley_rng_flags - LDA !ram_cm_ridley_backpogo_right : XBA : ASL #3 + LDA !ram_cm_ridley_backpogo_rng : XBA ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done JML init_zebes_ridley_rng @@ -3155,7 +3284,7 @@ rng_ridley_backpogo_right: rng_ridley_pogo_height: dw !ACTION_CHOICE - dl #!ram_cm_ridley_pogo_height + dl #!ram_cm_ridley_pogo_height_rng dw #.routine db #$28, "Pogo Height", #$FF db #$28, " RANDOM", #$FF @@ -3166,7 +3295,9 @@ rng_ridley_pogo_height: db #$FF .routine LDA !ram_ridley_rng_flags : AND !RIDLEY_RNG_POGO_HEIGHT_INVERTED - ORA !ram_cm_ridley_pogo_height : STA !ram_ridley_rng_flags + STA !ram_ridley_rng_flags + LDA !ram_cm_ridley_pogo_height_rng : ASL #3 + ORA !ram_ridley_rng_flags : STA !ram_ridley_rng_flags LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done JML init_zebes_ridley_rng .done @@ -3174,7 +3305,7 @@ rng_ridley_pogo_height: rng_ridley_pogo_time: dw !ACTION_CHOICE - dl #!ram_cm_ridley_pogo_time + dl #!ram_cm_ridley_pogo_time_rng dw #.routine db #$28, "Pogo Time", #$FF db #$28, " RANDOM", #$FF @@ -3183,9 +3314,9 @@ rng_ridley_pogo_time: .routine LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_POGO_TIME_INVERTED STA !ram_ridley_rng_times_and_fireball - LDA !ram_cm_ridley_pogo_time : BEQ .set_value - LDA !ram_cm_ridley_pogo_time_value : BNE .set_value - LDA #$0080 : STA !ram_cm_ridley_pogo_time_value + LDA !ram_cm_ridley_pogo_time_rng : BEQ .set_value + LDA !ram_cm_ridley_pogo_time_value_rng : BNE .set_value + LDA #$0080 : STA !ram_cm_ridley_pogo_time_value_rng .set_value XBA : ORA !ram_ridley_rng_times_and_fireball : STA !ram_ridley_rng_times_and_fireball LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done @@ -3195,16 +3326,16 @@ rng_ridley_pogo_time: rng_ridley_pogo_time_dynamic: dw !ACTION_DYNAMIC - dl #!ram_cm_ridley_pogo_time + dl #!ram_cm_ridley_pogo_time_rng dw #$0000 dw #rng_ridley_pogo_time_value rng_ridley_pogo_time_value: - %cm_numfield("Pogo Time Value", !ram_cm_ridley_pogo_time_value, 128, 191, 1, 4, #.routine) + %cm_numfield("Pogo Time Value", !ram_cm_ridley_pogo_time_value_rng, 128, 191, 1, 4, #.routine) .routine LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_POGO_TIME_INVERTED STA !ram_ridley_rng_times_and_fireball - LDA !ram_cm_ridley_pogo_time_value : XBA + LDA !ram_cm_ridley_pogo_time_value_rng : XBA ORA !ram_ridley_rng_times_and_fireball : STA !ram_ridley_rng_times_and_fireball LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done JML init_zebes_ridley_rng @@ -3213,7 +3344,7 @@ rng_ridley_pogo_time_value: rng_ridley_hover_time: dw !ACTION_CHOICE - dl #!ram_cm_ridley_hover_time + dl #!ram_cm_ridley_hover_time_rng dw #.routine db #$28, "Hover Time", #$FF db #$28, " RANDOM", #$FF @@ -3222,9 +3353,9 @@ rng_ridley_hover_time: .routine LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_HOVER_TIME_INVERTED STA !ram_ridley_rng_times_and_fireball - LDA !ram_cm_ridley_hover_time : BEQ .set_value - LDA !ram_cm_ridley_hover_time_value : BNE .set_value - LDA #$0020 : STA !ram_cm_ridley_hover_time_value + LDA !ram_cm_ridley_hover_time_rng : BEQ .set_value + LDA !ram_cm_ridley_hover_time_value_rng : BNE .set_value + LDA #$0020 : STA !ram_cm_ridley_hover_time_value_rng .set_value ORA !ram_ridley_rng_times_and_fireball : STA !ram_ridley_rng_times_and_fireball LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done @@ -3234,15 +3365,15 @@ rng_ridley_hover_time: rng_ridley_hover_time_dynamic: dw !ACTION_DYNAMIC - dl #!ram_cm_ridley_hover_time + dl #!ram_cm_ridley_hover_time_rng dw #$0000 dw #rng_ridley_hover_time_value rng_ridley_hover_time_value: - %cm_numfield("Hover Time Value", !ram_cm_ridley_hover_time_value, 32, 63, 1, 4, #.routine) + %cm_numfield("Hover Time Value", !ram_cm_ridley_hover_time_value_rng, 32, 63, 1, 4, #.routine) .routine LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_HOVER_TIME_INVERTED - ORA !ram_cm_ridley_hover_time_value : STA !ram_ridley_rng_times_and_fireball + ORA !ram_cm_ridley_hover_time_value_rng : STA !ram_ridley_rng_times_and_fireball LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done JML init_zebes_ridley_rng .done @@ -3250,17 +3381,17 @@ rng_ridley_hover_time_value: rng_ridley_hover_fireball: dw !ACTION_CHOICE - dl #!ram_cm_ridley_hover_fireball + dl #!ram_cm_ridley_hover_fireball_rng dw #.routine - db #$28, "50/50 Fireball", #$FF - db #$28, " VANILLA", #$FF - db #$28, " ALWAYS", #$FF - db #$28, " NEVER", #$FF + db #$28, "Hover Fireball", #$FF + db #$28, " RANDOM", #$FF + db #$28, " MORE OFTEN", #$FF + db #$28, " LESS OFTEN", #$FF db #$FF .routine LDA !ram_ridley_rng_times_and_fireball : AND !RIDLEY_RNG_FIREBALL_INVERTED STA !ram_ridley_rng_times_and_fireball - LDA !ram_cm_ridley_hover_fireball : XBA : LSR #2 + LDA !ram_cm_ridley_hover_fireball_rng : XBA : LSR #2 ORA !ram_ridley_rng_times_and_fireball : STA !ram_ridley_rng_times_and_fireball LDA !ROOM_ID : CMP.w #ROOM_RidleyRoom : BNE .done JML init_zebes_ridley_rng @@ -3268,6 +3399,158 @@ rng_ridley_hover_fireball: RTL +; ----------------- +; Mother Brain Menu +; ----------------- + +rng_prepare_mb_menu: +{ + LDA !ram_mb_rng : AND !MB_RNG_WALKING_MASK + STA !ram_cm_mb_walking_rng + LDA !ram_mb_rng : AND !MB_RNG_KETCHUP_MASK + LSR #2 : STA !ram_cm_mb_ketchup_rng + LDA !ram_mb_rng : AND !MB_RNG_DAMAGE_DOWN_MASK + LSR #4 : STA !ram_cm_mb_damage_down_rng + LDA !ram_mb_rng : AND !MB_RNG_PHASE3_ATTACK_MASK + ASL : XBA : STA !ram_cm_mb_phase3_attack_rng + LDA !ram_mb_rng : AND !MB_RNG_NORMAL_ATTACK_MASK + LSR : XBA : STA !ram_cm_mb_normal_attack_rng + LDA !ram_mb_rng : AND !MB_RNG_BOMB_CROUCH_MASK + XBA : ASL #2 : XBA : STA !ram_cm_mb_bomb_crouch_rng + %setmenubank() + JML action_submenu +} + +RngMBMenu: + dw #rng_mb_walking + dw #rng_mb_normal_attack + dw #rng_mb_bomb_crouch + dw #rng_mb_ketchup + dw #$FFFF + dw #rng_mb_damage_down + dw #$FFFF + dw #rng_mb_phase3_attack + dw #$0000 + %cm_header("MOTHER BRAIN RNG CONTROL") + +rng_mb_walking: + dw !ACTION_CHOICE + dl #!ram_cm_mb_walking_rng + dw #.routine + db #$28, "Phase 2 Walking", #$FF + db #$28, " VANILLA", #$FF + db #$28, " MAXIMIZED", #$FF + db #$28, " MINIMIZED", #$FF + db #$FF + .routine + LDA !ram_mb_rng : AND !MB_RNG_WALKING_INVERTED + ORA !ram_cm_mb_walking_rng : STA !ram_mb_rng + LDA !ROOM_ID : CMP.w #ROOM_MotherBrainRoom : BNE .done + JML init_mb_rng_from_menu + .done + RTL + +rng_mb_normal_attack: + dw !ACTION_CHOICE + dl #!ram_cm_mb_normal_attack_rng + dw #.routine + db #$28, "Phase 2 Attack", #$FF + db #$28, " VANILLA", #$FF + db #$28, " MAX RINGS", #$FF + db #$28, " MAX BOMBS", #$FF + db #$28, " MAX FRIES", #$FF + db #$28, " MIN RINGS", #$FF + db #$28, " MIN BOMBS", #$FF + db #$28, " MIN FRIES", #$FF + db #$28, " MINIMIZED", #$FF + db #$FF + .routine + LDA !ram_mb_rng : AND !MB_RNG_NORMAL_ATTACK_INVERTED + STA !ram_mb_rng + LDA !ram_cm_mb_normal_attack_rng : ASL : XBA + ORA !ram_mb_rng : STA !ram_mb_rng + LDA !ROOM_ID : CMP.w #ROOM_MotherBrainRoom : BNE .done + JML init_mb_rng_from_menu + .done + RTL + +rng_mb_bomb_crouch: + dw !ACTION_CHOICE + dl #!ram_cm_mb_bomb_crouch_rng + dw #.routine + db #$28, "Bomb Crouch", #$FF + db #$28, " VANILLA", #$FF + db #$28, " MAXIMIZED", #$FF + db #$28, " MINIMIZED", #$FF + db #$FF + .routine + LDA !ram_mb_rng : AND !MB_RNG_BOMB_CROUCH_INVERTED + STA !ram_mb_rng + LDA !ram_cm_mb_bomb_crouch_rng : XBA : LSR #2 : XBA + ORA !ram_mb_rng : STA !ram_mb_rng + LDA !ROOM_ID : CMP.w #ROOM_MotherBrainRoom : BNE .done + JML init_mb_rng_from_menu + .done + RTL + +rng_mb_ketchup: + dw !ACTION_CHOICE + dl #!ram_cm_mb_ketchup_rng + dw #.routine + db #$28, "Ketchup", #$FF + db #$28, " VANILLA", #$FF + db #$28, " MAXIMIZED", #$FF + db #$28, " MINIMIZED", #$FF + db #$FF + .routine + LDA !ram_mb_rng : AND !MB_RNG_KETCHUP_INVERTED + STA !ram_mb_rng + LDA !ram_cm_mb_ketchup_rng : ASL #2 + ORA !ram_mb_rng : STA !ram_mb_rng + LDA !ROOM_ID : CMP.w #ROOM_MotherBrainRoom : BNE .done + JML init_mb_rng_from_menu + .done + RTL + +rng_mb_damage_down: + dw !ACTION_CHOICE + dl #!ram_cm_mb_damage_down_rng + dw #.routine + db #$28, "Damage Down", #$FF + db #$28, " VANILLA", #$FF + db #$28, " MAX RINGS", #$FF + db #$28, " MAX BOMBS", #$FF + db #$FF + .routine + LDA !ram_mb_rng : AND !MB_RNG_DAMAGE_DOWN_INVERTED + STA !ram_mb_rng + LDA !ram_cm_mb_damage_down_rng : ASL #4 + ORA !ram_mb_rng : STA !ram_mb_rng + LDA !ROOM_ID : CMP.w #ROOM_MotherBrainRoom : BNE .done + JML init_mb_rng_from_menu + .done + RTL + +rng_mb_phase3_attack: + dw !ACTION_CHOICE + dl #!ram_cm_mb_phase3_attack_rng + dw #.routine + db #$28, "Phase 3 Attack", #$FF + db #$28, " VANILLA", #$FF + db #$28, " MAX RINGS", #$FF + db #$28, " MAX BOMBS", #$FF + db #$FF + .routine + LDA !ram_mb_rng : AND !MB_RNG_PHASE3_ATTACK_INVERTED + STA !ram_mb_rng + LDA !ram_cm_mb_phase3_attack_rng : XBA : LSR + ORA !ram_mb_rng : STA !ram_mb_rng + LDA !ROOM_ID : CMP.w #ROOM_MotherBrainRoom : BNE .done + JML init_mb_rng_from_menu + .done + RTL + + if !FEATURE_SD2SNES ; -------------- ; Savestate Menu diff --git a/src/symbols.asm b/src/symbols.asm index c3874630..56ac4b14 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -148,21 +148,22 @@ ram_magic_pants_enabled = !ram_magic_pants_enabled ; !WRAM_PERSIST_START+$0A ram_space_pants_enabled = !ram_space_pants_enabled ; !WRAM_PERSIST_START+$0C ram_kraid_claw_rng = !ram_kraid_claw_rng ; !WRAM_PERSIST_START+$0E ram_kraid_wait_rng = !ram_kraid_wait_rng ; !WRAM_PERSIST_START+$10 -ram_botwoon_first = !ram_botwoon_first ; !WRAM_PERSIST_START+$12 -ram_botwoon_second = !ram_botwoon_second ; !WRAM_PERSIST_START+$14 -ram_botwoon_hidden = !ram_botwoon_hidden ; !WRAM_PERSIST_START+$16 -ram_botwoon_spit = !ram_botwoon_spit ; !WRAM_PERSIST_START+$18 -ram_botwoon_rng = !ram_botwoon_rng ; !WRAM_PERSIST_START+$1A +ram_draygon_rng_left = !ram_draygon_rng_left ; !WRAM_PERSIST_START+$12 +ram_draygon_rng_right = !ram_draygon_rng_right ; !WRAM_PERSIST_START+$14 +ram_turret_rng = !ram_turret_rng ; !WRAM_PERSIST_START+$16 +ram_ridley_rng_flags = !ram_ridley_rng_flags ; !WRAM_PERSIST_START+$18 +ram_ridley_rng_times_and_fireball = !ram_ridley_rng_times_and_fireball ; !WRAM_PERSIST_START+$1A ram_crocomire_rng = !ram_crocomire_rng ; !WRAM_PERSIST_START+$1C -ram_phantoon_rng_round_1 = !ram_phantoon_rng_round_1 ; !WRAM_PERSIST_START+$1E -ram_phantoon_rng_round_2 = !ram_phantoon_rng_round_2 ; !WRAM_PERSIST_START+$20 -ram_phantoon_rng_inverted = !ram_phantoon_rng_inverted ; !WRAM_PERSIST_START+$22 -ram_phantoon_rng_eyeclose = !ram_phantoon_rng_eyeclose ; !WRAM_PERSIST_START+$24 -ram_phantoon_rng_flames = !ram_phantoon_rng_flames ; !WRAM_PERSIST_START+$26 -ram_phantoon_rng_next_flames = !ram_phantoon_rng_next_flames ; !WRAM_PERSIST_START+$28 -ram_phantoon_flame_direction = !ram_phantoon_flame_direction ; !WRAM_PERSIST_START+$2A -ram_draygon_rng_left = !ram_draygon_rng_left ; !WRAM_PERSIST_START+$2C -ram_draygon_rng_right = !ram_draygon_rng_right ; !WRAM_PERSIST_START+$2E +ram_phantoon_phase_rng = !ram_phantoon_phase_rng ; !WRAM_PERSIST_START+$1E +ram_phantoon_eye_and_flames_rng = !ram_phantoon_eye_and_flames_rng ; !WRAM_PERSIST_START+$20 +ram_botwoon_rng = !ram_botwoon_rng ; !WRAM_PERSIST_START+$22 +ram_baby_rng = !ram_baby_rng ; !WRAM_PERSIST_START+$24 +ram_mb_rng = !ram_mb_rng ; !WRAM_PERSIST_START+$26 + +ram_itempickups_all = !ram_itempickups_all ; !WRAM_PERSIST_START+$28 +ram_itempickups_visible = !ram_itempickups_visible ; !WRAM_PERSIST_START+$2A +ram_itempickups_chozo = !ram_itempickups_chozo ; !WRAM_PERSIST_START+$2C +ram_itempickups_hidden = !ram_itempickups_hidden ; !WRAM_PERSIST_START+$2E ram_suits_enemy_damage_check = !ram_suits_enemy_damage_check ; !WRAM_PERSIST_START+$30 ram_suits_heat_damage_check = !ram_suits_heat_damage_check ; !WRAM_PERSIST_START+$32 @@ -188,19 +189,9 @@ ram_sprite_feature_flags = !ram_sprite_feature_flags ; !WRAM_PERSIST_START+$54 ram_door_portal_flags = !ram_door_portal_flags ; !WRAM_PERSIST_START+$56 ram_door_source = !ram_door_source ; !WRAM_PERSIST_START+$58 ram_door_destination = !ram_door_destination ; !WRAM_PERSIST_START+$5A -ram_itempickups_all = !ram_itempickups_all ; !WRAM_PERSIST_START+$5C -ram_itempickups_visible = !ram_itempickups_visible ; !WRAM_PERSIST_START+$5E -ram_itempickups_chozo = !ram_itempickups_chozo ; !WRAM_PERSIST_START+$60 -ram_itempickups_hidden = !ram_itempickups_hidden ; !WRAM_PERSIST_START+$62 -ram_frames_held = !ram_frames_held ; !WRAM_PERSIST_START+$64 -ram_baby_rng = !ram_baby_rng ; !WRAM_PERSIST_START+$66 -ram_turret_rng = !ram_turret_rng ; !WRAM_PERSIST_START+$68 - -ram_quickboot_spc_state = !ram_quickboot_spc_state ; !WRAM_PERSIST_START+$6A -ram_display_backup = !ram_display_backup ; !WRAM_PERSIST_START+$6C -ram_phantoon_always_visible = !ram_phantoon_always_visible ; !WRAM_PERSIST_START+$6E -ram_ridley_rng_flags = !ram_ridley_rng_flags ; !WRAM_PERSIST_START+$70 -ram_ridley_rng_times_and_fireball = !ram_ridley_rng_times_and_fireball ; !WRAM_PERSIST_START+$72 +ram_frames_held = !ram_frames_held ; !WRAM_PERSIST_START+$5C +ram_quickboot_spc_state = !ram_quickboot_spc_state ; !WRAM_PERSIST_START+$5E +ram_display_backup = !ram_display_backup ; !WRAM_PERSIST_START+$60 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -259,12 +250,6 @@ ram_sram_detection = !ram_sram_detection ; !WRAM_MENU_START+$5C ram_timers_autoupdate = !ram_timers_autoupdate ; !WRAM_MENU_START+$5E ram_cm_gmode = !ram_cm_gmode ; !WRAM_MENU_START+$60 -ram_cm_botwoon_rng = !ram_cm_botwoon_rng ; !WRAM_MENU_START+$62 -ram_cm_botwoon_first = !ram_cm_botwoon_first ; !WRAM_MENU_START+$64 -ram_cm_botwoon_hidden = !ram_cm_botwoon_hidden ; !WRAM_MENU_START+$66 -ram_cm_botwoon_second = !ram_cm_botwoon_second ; !WRAM_MENU_START+$68 -ram_cm_botwoon_spit = !ram_cm_botwoon_spit ; !WRAM_MENU_START+$68 - ; ^ FREE SPACE ^ up to +$86 ram_cm_preserved_timers = !ram_cm_preserved_timers ; !WRAM_MENU_START+$88 ; 8 bytes @@ -290,20 +275,37 @@ ram_cm_itempickups_chozo = !ram_cm_itempickups_chozo ; !WRAM_MENU_START+$9A ram_cm_itempickups_hidden = !ram_cm_itempickups_hidden ; !WRAM_MENU_START+$9C ram_cm_turret_rng = !ram_cm_turret_rng ; !WRAM_MENU_START+$90 -ram_cm_phan_first_phase = !ram_cm_phan_first_phase ; !WRAM_MENU_START+$92 -ram_cm_phan_second_phase = !ram_cm_phan_second_phase ; !WRAM_MENU_START+$94 - -ram_cm_ridley_pogo_height = !ram_cm_ridley_pogo_height ; !WRAM_MENU_START+$92 -ram_cm_ridley_lunge_pogo = !ram_cm_ridley_lunge_pogo ; !WRAM_MENU_START+$94 -ram_cm_ridley_swoop_pogo = !ram_cm_ridley_swoop_pogo ; !WRAM_MENU_START+$96 -ram_cm_ridley_ceres_ai = !ram_cm_ridley_ceres_ai ; !WRAM_MENU_START+$98 -ram_cm_ridley_hover_fireball = !ram_cm_ridley_hover_fireball ; !WRAM_MENU_START+$9A -ram_cm_ridley_backpogo_left = !ram_cm_ridley_backpogo_left ; !WRAM_MENU_START+$9C -ram_cm_ridley_backpogo_right = !ram_cm_ridley_backpogo_right ; !WRAM_MENU_START+$9E -ram_cm_ridley_pogo_time = !ram_cm_ridley_pogo_time ; !WRAM_MENU_START+$A0 -ram_cm_ridley_pogo_time_value = !ram_cm_ridley_pogo_time_value ; !WRAM_MENU_START+$A2 -ram_cm_ridley_hover_time = !ram_cm_ridley_hover_time ; !WRAM_MENU_START+$A4 -ram_cm_ridley_hover_time_value = !ram_cm_ridley_hover_time_value ; !WRAM_MENU_START+$A6 +ram_cm_botwoon_first_rng = !ram_cm_botwoon_first_rng ; !WRAM_MENU_START+$92 +ram_cm_botwoon_hidden_rng = !ram_cm_botwoon_hidden_rng ; !WRAM_MENU_START+$94 +ram_cm_botwoon_second_rng = !ram_cm_botwoon_second_rng ; !WRAM_MENU_START+$96 +ram_cm_botwoon_spit_rng = !ram_cm_botwoon_spit_rng ; !WRAM_MENU_START+$98 +ram_cm_botwoon_after_spit_rng = !ram_cm_botwoon_after_spit_rng ; !WRAM_MENU_START+$9A + +ram_cm_phantoon_first_phase_rng = !ram_cm_phantoon_first_phase_rng ; !WRAM_MENU_START+$9C +ram_cm_phantoon_second_phase_rng = !ram_cm_phantoon_second_phase_rng ; !WRAM_MENU_START+$9E +ram_cm_phantoon_flip_rng = !ram_cm_phantoon_flip_rng ; !WRAM_MENU_START+$A0 +ram_cm_phantoon_eyeclose_rng = !ram_cm_phantoon_eyeclose_rng ; !WRAM_MENU_START+$A2 +ram_cm_phantoon_flames_rng = !ram_cm_phantoon_flames_rng ; !WRAM_MENU_START+$A4 +ram_cm_phantoon_next_flames_rng = !ram_cm_phantoon_next_flames_rng ; !WRAM_MENU_START+$A6 +ram_cm_phantoon_flame_direction_rng = !ram_cm_phantoon_flame_direction_rng ; !WRAM_MENU_START+$A8 + +ram_cm_ridley_pogo_height_rng = !ram_cm_ridley_pogo_height_rng ; !WRAM_MENU_START+$9C +ram_cm_ridley_lunge_pogo_rng = !ram_cm_ridley_lunge_pogo_rng ; !WRAM_MENU_START+$9E +ram_cm_ridley_swoop_pogo_rng = !ram_cm_ridley_swoop_pogo_rng ; !WRAM_MENU_START+$A0 +ram_cm_ridley_ceres_ai_rng = !ram_cm_ridley_ceres_ai_rng ; !WRAM_MENU_START+$A2 +ram_cm_ridley_hover_fireball_rng = !ram_cm_ridley_hover_fireball_rng ; !WRAM_MENU_START+$A4 +ram_cm_ridley_backpogo_rng = !ram_cm_ridley_backpogo_rng ; !WRAM_MENU_START+$A6 +ram_cm_ridley_pogo_time_rng = !ram_cm_ridley_pogo_time_rng ; !WRAM_MENU_START+$A8 +ram_cm_ridley_pogo_time_value_rng = !ram_cm_ridley_pogo_time_value_rng ; !WRAM_MENU_START+$AA +ram_cm_ridley_hover_time_rng = !ram_cm_ridley_hover_time_rng ; !WRAM_MENU_START+$AC +ram_cm_ridley_hover_time_value_rng = !ram_cm_ridley_hover_time_value_rng ; !WRAM_MENU_START+$AE + +ram_cm_mb_walking_rng = !ram_cm_mb_walking_rng ; !WRAM_MENU_START+$9C +ram_cm_mb_ketchup_rng = !ram_cm_mb_ketchup_rng ; !WRAM_MENU_START+$9E +ram_cm_mb_damage_down_rng = !ram_cm_mb_damage_down_rng ; !WRAM_MENU_START+$A0 +ram_cm_mb_phase3_attack_rng = !ram_cm_mb_phase3_attack_rng ; !WRAM_MENU_START+$A2 +ram_cm_mb_normal_attack_rng = !ram_cm_mb_normal_attack_rng ; !WRAM_MENU_START+$A4 +ram_cm_mb_bomb_crouch_rng = !ram_cm_mb_bomb_crouch_rng ; !WRAM_MENU_START+$A6 ram_cm_varia = !ram_cm_varia ; !WRAM_MENU_START+$90 ram_cm_gravity = !ram_cm_gravity ; !WRAM_MENU_START+$92 From 3d04eab3d116ced6c2a32a867885b1768e86070c Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 18 May 2025 21:25:07 -0500 Subject: [PATCH 22/43] Added option to override all drop chance tables --- src/defines.asm | 13 +- src/enemy_rng.asm | 12 ++ src/mainmenu.asm | 403 +++++++++++++++++++++++++++------------------- src/symbols.asm | 13 +- 4 files changed, 266 insertions(+), 175 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index ea08e59b..d1905b8c 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -209,6 +209,7 @@ !ram_frames_held = !WRAM_PERSIST_START+$5C !ram_quickboot_spc_state = !WRAM_PERSIST_START+$5E !ram_display_backup = !WRAM_PERSIST_START+$60 +!ram_drop_chance_table = !WRAM_PERSIST_START+$62 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -292,11 +293,7 @@ !ram_cm_itempickups_hidden = !WRAM_MENU_START+$9C !ram_cm_turret_rng = !WRAM_MENU_START+$90 -!ram_cm_botwoon_first_rng = !WRAM_MENU_START+$92 -!ram_cm_botwoon_hidden_rng = !WRAM_MENU_START+$94 -!ram_cm_botwoon_second_rng = !WRAM_MENU_START+$96 -!ram_cm_botwoon_spit_rng = !WRAM_MENU_START+$98 -!ram_cm_botwoon_after_spit_rng = !WRAM_MENU_START+$9A +!ram_cm_drop_chances = !WRAM_MENU_START+$92 !ram_cm_phantoon_first_phase_rng = !WRAM_MENU_START+$9C !ram_cm_phantoon_second_phase_rng = !WRAM_MENU_START+$9E @@ -317,6 +314,12 @@ !ram_cm_ridley_hover_time_rng = !WRAM_MENU_START+$AC !ram_cm_ridley_hover_time_value_rng = !WRAM_MENU_START+$AE +!ram_cm_botwoon_first_rng = !WRAM_MENU_START+$9C +!ram_cm_botwoon_hidden_rng = !WRAM_MENU_START+$9E +!ram_cm_botwoon_second_rng = !WRAM_MENU_START+$A0 +!ram_cm_botwoon_spit_rng = !WRAM_MENU_START+$A2 +!ram_cm_botwoon_after_spit_rng = !WRAM_MENU_START+$A4 + !ram_cm_mb_walking_rng = !WRAM_MENU_START+$9C !ram_cm_mb_ketchup_rng = !WRAM_MENU_START+$9E !ram_cm_mb_damage_down_rng = !WRAM_MENU_START+$A0 diff --git a/src/enemy_rng.asm b/src/enemy_rng.asm index de2ed609..cb82e415 100644 --- a/src/enemy_rng.asm +++ b/src/enemy_rng.asm @@ -1,4 +1,16 @@ +if !FEATURE_PAL +org $86F14A +else +org $86F10E +endif + LDA !ram_drop_chance_table : BNE $10 + ; Since we replaced unnecessary logic, + ; we need to burn some cycles to compensate + BRA $00 : BRA $00 +%warnpc($86F118, $86F154) + + ; ---------------- ; Phantoon hijacks ; ---------------- diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 71c1003d..12b60bd1 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -1,4 +1,33 @@ +%startfree(B4) + +; No reason these drop tables can't overlap +all_power_bombs_drop_table: + db #$00 +all_supers_drop_table: + db #$00 +all_nothing_drop_table: + db #$00 +all_missiles_drop_table: + db #$00 +all_big_hp_drop_table: + db #$00 +all_small_hp_drop_table: + db #$FF, #$00, #$00, #$00, #$00, #$00 + +!DROP_CHANCE_TABLE_LENGTH = #$0007 +drop_chance_tables: + dw #$0000 + dw #all_small_hp_drop_table + dw #all_big_hp_drop_table + dw #all_missiles_drop_table + dw #all_nothing_drop_table + dw #all_supers_drop_table + dw #all_power_bombs_drop_table + +%endfree(B4) + + %startfree(B8) ; ------------ @@ -103,26 +132,13 @@ action_game_mainmenu: action_rng_mainmenu: { LDA !ram_turret_rng : LSR : STA !ram_cm_turret_rng - TDC : STA !ram_cm_botwoon_first_rng - STA !ram_cm_botwoon_hidden_rng : STA !ram_cm_botwoon_second_rng - LDA !ram_botwoon_rng : BIT !BOTWOON_RNG_FIRST_ENABLED : BEQ .botwoonHidden - AND !BOTWOON_RNG_FIRST_VALUE : LSR #4 : INC - STA !ram_cm_botwoon_first_rng : LDA !ram_botwoon_rng - .botwoonHidden - BIT !BOTWOON_RNG_HIDDEN_ENABLED : BEQ .botwoonSecond - AND !BOTWOON_RNG_HIDDEN_VALUE : XBA : LSR #2 : INC - STA !ram_cm_botwoon_hidden_rng : LDA !ram_botwoon_rng - .botwoonSecond - BIT !BOTWOON_RNG_SECOND_ENABLED : BEQ .botwoonSpit - AND !BOTWOON_RNG_SECOND_VALUE : XBA : LSR #4 : INC - STA !ram_cm_botwoon_second_rng : LDA !ram_botwoon_rng - .botwoonSpit - AND !BOTWOON_RNG_SPIT_MASK : LSR #2 : STA !ram_cm_botwoon_spit_rng - LDA !ram_botwoon_rng : AND !BOTWOON_RNG_AFTER_SPIT_MASK - BEQ .botwoonAfterSpit - EOR !BOTWOON_RNG_AFTER_SPIT_ENABLED : INC - .botwoonAfterSpit - STA !ram_cm_botwoon_after_spit_rng + LDA !DROP_CHANCE_TABLE_LENGTH-1 : ASL : TAX + .dropTableLoop + LDA.l drop_chance_tables,X : CMP !ram_drop_chance_table : BEQ .setDropChances + DEX #2 : BPL .dropTableLoop + TDC : TAX + .setDropChances + TXA : LSR : STA !ram_cm_drop_chances JMP action_mainmenu } @@ -2567,27 +2583,23 @@ endif ; !FEATURE_VANILLAHUD RngMenu: dw #rng_goto_phantoon dw #rng_goto_ridley + dw #rng_goto_botwoon + dw #rng_goto_mb dw #$FFFF dw #rng_kraid_claw_rng dw #rng_kraid_wait_rng dw #$FFFF dw #rng_crocomire_rng dw #$FFFF - dw #rng_botwoon_first - dw #rng_botwoon_hidden - dw #rng_botwoon_second - dw #rng_botwoon_spit - dw #rng_botwoon_after_spit - dw #$FFFF dw #rng_draygon_rng_right dw #rng_draygon_rng_left dw #rng_turret_rng dw #$FFFF dw #rng_baby_rng dw #$FFFF - dw #rng_goto_mb + dw #rng_drop_chances dw #$0000 - %cm_header("BOSS RNG CONTROL") + %cm_header("RNG CONTROL") rng_goto_phantoon: %cm_jsl("Phantoon Menu", rng_prepare_phantoon_menu, #RngPhantoonMenu) @@ -2595,118 +2607,46 @@ rng_goto_phantoon: rng_goto_ridley: %cm_jsl("Ridley Menu", rng_prepare_ridley_menu, #RngRidleyMenu) -rng_botwoon_first: - dw !ACTION_CHOICE - dl #!ram_cm_botwoon_first_rng - dw #.routine - db #$28, "Botwoon First", #$FF - db #$28, " RANDOM", #$FF - db #$28, " LB BOTTOM", #$FF - db #$28, " LT TOP", #$FF - db #$28, " LR RIGHT", #$FF - db #$28, " LL LEFT", #$FF - db #$FF - .routine - LDA !ram_botwoon_rng : AND !BOTWOON_RNG_FIRST_INVERTED - STA !ram_botwoon_rng - LDA !ram_cm_botwoon_first_rng : BEQ .checkRoom - ; possible values are $01, $09, $11, $19 - DEC : ASL #3 : INC : ASL - ORA !ram_botwoon_rng : STA !ram_botwoon_rng - .checkRoom - LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done - JML init_botwoon_rng - .done - RTL +rng_goto_botwoon: + %cm_jsl("Botwoon Menu", rng_prepare_botwoon_menu, #RngBotwoonMenu) -rng_botwoon_hidden: - dw !ACTION_CHOICE - dl #!ram_cm_botwoon_hidden_rng - dw #.routine - db #$28, "Botwoon Hidden", #$FF - db #$28, " RANDOM", #$FF - db #$28, "LB BL TL RL", #$FF - db #$28, "LT BT TB RB", #$FF - db #$28, "LR BR TR RT", #$FF - db #$FF - .routine - LDA !ram_botwoon_rng : AND !BOTWOON_RNG_HIDDEN_INVERTED - STA !ram_botwoon_rng - LDA !ram_cm_botwoon_hidden_rng : BEQ .checkRoom - ; possible values are $01, $09, $11 - DEC : ASL #3 : INC : XBA : LSR - ORA !ram_botwoon_rng : STA !ram_botwoon_rng - .checkRoom - LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done - JML init_botwoon_rng - .done - RTL +rng_goto_mb: + %cm_jsl("Mother Brain Menu", rng_prepare_mb_menu, #RngMBMenu) -rng_botwoon_second: +rng_kraid_claw_rng: dw !ACTION_CHOICE - dl #!ram_cm_botwoon_second_rng - dw #.routine - db #$28, "Botwoon Second", #$FF + dl #!ram_kraid_claw_rng + dw #$0000 + db #$28, "Kraid Claw RNG", #$FF db #$28, " RANDOM", #$FF - db #$28, "LB BL TL RL", #$FF - db #$28, "LT BT TB RB", #$FF - db #$28, "LR BR TR RT", #$FF - db #$28, "LL BB TT RR", #$FF + db #$28, " LAGGY", #$FF + db #$28, " LAGGIER", #$FF db #$FF - .routine - LDA !ram_botwoon_rng : AND !BOTWOON_RNG_SECOND_INVERTED - STA !ram_botwoon_rng - LDA !ram_cm_botwoon_second_rng : BEQ .checkRoom - ; possible values are $01, $09, $11, $19 - DEC : ASL #3 : INC : XBA : ASL - ORA !ram_botwoon_rng : STA !ram_botwoon_rng - .checkRoom - LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done - JML init_botwoon_rng - .done - RTL -rng_botwoon_spit: +rng_kraid_wait_rng: dw !ACTION_CHOICE - dl #!ram_cm_botwoon_spit_rng - dw #.routine - db #$28, "Botwoon Spit", #$FF + dl #!ram_kraid_wait_rng + dw #$0000 + db #$28, "Kraid Wait RNG", #$FF db #$28, " RANDOM", #$FF - db #$28, " NEVER SPIT", #$FF - db #$28, "ALWAYS SPIT", #$FF + db #$28, " 64", #$FF + db #$28, " 128", #$FF + db #$28, " 192", #$FF + db #$28, " 256", #$FF + db #$28, " 320", #$FF + db #$28, " 384", #$FF + db #$28, " 448", #$FF db #$FF - .routine - LDA !ram_botwoon_rng : AND !BOTWOON_RNG_SPIT_INVERTED - STA !ram_botwoon_rng - LDA !ram_cm_botwoon_spit_rng : BEQ .checkRoom - ; 0-4 = no spit, 6-E = spit - ASL #2 : ORA !ram_botwoon_rng : STA !ram_botwoon_rng - .checkRoom - LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done - JML init_botwoon_rng - .done - RTL -rng_botwoon_after_spit: +rng_crocomire_rng: dw !ACTION_CHOICE - dl #!ram_cm_botwoon_after_spit_rng - dw #.routine - db #$28, "Botwoon After S", #$FF - db #$28, "pit RANDOM", #$FF - db #$28, "pit MOVE", #$FF - db #$28, "pit HIDE", #$FF + dl #!ram_crocomire_rng + dw #$0000 + db #$28, "Crocomire RNG", #$FF + db #$28, " RANDOM", #$FF + db #$28, " STEP", #$FF + db #$28, " SWIPE", #$FF db #$FF - .routine - LDA !ram_botwoon_rng : AND !BOTWOON_RNG_AFTER_SPIT_INVERTED - STA !ram_botwoon_rng - LDA !ram_cm_botwoon_after_spit_rng : BEQ .checkRoom - DEC : ORA !BOTWOON_RNG_AFTER_SPIT_ENABLED - ORA !ram_botwoon_rng : STA !ram_botwoon_rng - .checkRoom - LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done - JML init_botwoon_rng - .done - RTL rng_draygon_rng_right: dw !ACTION_CHOICE @@ -2753,41 +2693,6 @@ rng_turret_rng: ASL : STA !ram_turret_rng RTL -rng_crocomire_rng: - dw !ACTION_CHOICE - dl #!ram_crocomire_rng - dw #$0000 - db #$28, "Crocomire RNG", #$FF - db #$28, " RANDOM", #$FF - db #$28, " STEP", #$FF - db #$28, " SWIPE", #$FF - db #$FF - -rng_kraid_claw_rng: - dw !ACTION_CHOICE - dl #!ram_kraid_claw_rng - dw #$0000 - db #$28, "Kraid Claw RNG", #$FF - db #$28, " RANDOM", #$FF - db #$28, " LAGGY", #$FF - db #$28, " LAGGIER", #$FF - db #$FF - -rng_kraid_wait_rng: - dw !ACTION_CHOICE - dl #!ram_kraid_wait_rng - dw #$0000 - db #$28, "Kraid Wait RNG", #$FF - db #$28, " RANDOM", #$FF - db #$28, " 64", #$FF - db #$28, " 128", #$FF - db #$28, " 192", #$FF - db #$28, " 256", #$FF - db #$28, " 320", #$FF - db #$28, " 384", #$FF - db #$28, " 448", #$FF - db #$FF - rng_baby_rng: dw !ACTION_CHOICE dl #!ram_baby_rng @@ -2798,8 +2703,23 @@ rng_baby_rng: db #$28, " LUNGE", #$FF db #$FF -rng_goto_mb: - %cm_jsl("Mother Brain Menu", rng_prepare_mb_menu, #RngMBMenu) +rng_drop_chances: + dw !ACTION_CHOICE + dl #!ram_cm_drop_chances + dw #.routine + db #$28, "All Drops", #$FF + db #$28, " VANILLA", #$FF + db #$28, " SMALL HEAL", #$FF + db #$28, " BIG HEAL", #$FF + db #$28, " MISSILES", #$FF + db #$28, " NOTHING", #$FF + db #$28, " SUPERS", #$FF + db #$28, "POWER BOMBS", #$FF + db #$FF + .routine + LDA !ram_cm_drop_chances : ASL : TAX + LDA.l drop_chance_tables,X : STA !ram_drop_chance_table + RTL ; -------------- @@ -3399,6 +3319,159 @@ rng_ridley_hover_fireball: RTL +; ------------ +; Botwoon Menu +; ------------ + +rng_prepare_botwoon_menu: +{ + TDC : STA !ram_cm_botwoon_first_rng + STA !ram_cm_botwoon_hidden_rng : STA !ram_cm_botwoon_second_rng + LDA !ram_botwoon_rng : BIT !BOTWOON_RNG_FIRST_ENABLED : BEQ .botwoonHidden + AND !BOTWOON_RNG_FIRST_VALUE : LSR #4 : INC + STA !ram_cm_botwoon_first_rng : LDA !ram_botwoon_rng + .botwoonHidden + BIT !BOTWOON_RNG_HIDDEN_ENABLED : BEQ .botwoonSecond + AND !BOTWOON_RNG_HIDDEN_VALUE : XBA : LSR #2 : INC + STA !ram_cm_botwoon_hidden_rng : LDA !ram_botwoon_rng + .botwoonSecond + BIT !BOTWOON_RNG_SECOND_ENABLED : BEQ .botwoonSpit + AND !BOTWOON_RNG_SECOND_VALUE : XBA : LSR #4 : INC + STA !ram_cm_botwoon_second_rng : LDA !ram_botwoon_rng + .botwoonSpit + AND !BOTWOON_RNG_SPIT_MASK : LSR #2 : STA !ram_cm_botwoon_spit_rng + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_AFTER_SPIT_MASK + BEQ .botwoonAfterSpit + EOR !BOTWOON_RNG_AFTER_SPIT_ENABLED : INC + .botwoonAfterSpit + STA !ram_cm_botwoon_after_spit_rng + %setmenubank() + JML action_submenu +} + +RngBotwoonMenu: + dw #rng_botwoon_first + dw #rng_botwoon_hidden + dw #rng_botwoon_second + dw #rng_botwoon_spit + dw #rng_botwoon_after_spit + dw #$0000 + %cm_header("BOTWOON RNG CONTROL") + +rng_botwoon_first: + dw !ACTION_CHOICE + dl #!ram_cm_botwoon_first_rng + dw #.routine + db #$28, "Botwoon First", #$FF + db #$28, " RANDOM", #$FF + db #$28, " LB BOTTOM", #$FF + db #$28, " LT TOP", #$FF + db #$28, " LR RIGHT", #$FF + db #$28, " LL LEFT", #$FF + db #$FF + .routine + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_FIRST_INVERTED + STA !ram_botwoon_rng + LDA !ram_cm_botwoon_first_rng : BEQ .checkRoom + ; possible values are $01, $09, $11, $19 + DEC : ASL #3 : INC : ASL + ORA !ram_botwoon_rng : STA !ram_botwoon_rng + .checkRoom + LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done + JML init_botwoon_rng + .done + RTL + +rng_botwoon_hidden: + dw !ACTION_CHOICE + dl #!ram_cm_botwoon_hidden_rng + dw #.routine + db #$28, "Botwoon Hidden", #$FF + db #$28, " RANDOM", #$FF + db #$28, "LB BL TL RL", #$FF + db #$28, "LT BT TB RB", #$FF + db #$28, "LR BR TR RT", #$FF + db #$FF + .routine + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_HIDDEN_INVERTED + STA !ram_botwoon_rng + LDA !ram_cm_botwoon_hidden_rng : BEQ .checkRoom + ; possible values are $01, $09, $11 + DEC : ASL #3 : INC : XBA : LSR + ORA !ram_botwoon_rng : STA !ram_botwoon_rng + .checkRoom + LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done + JML init_botwoon_rng + .done + RTL + +rng_botwoon_second: + dw !ACTION_CHOICE + dl #!ram_cm_botwoon_second_rng + dw #.routine + db #$28, "Botwoon Second", #$FF + db #$28, " RANDOM", #$FF + db #$28, "LB BL TL RL", #$FF + db #$28, "LT BT TB RB", #$FF + db #$28, "LR BR TR RT", #$FF + db #$28, "LL BB TT RR", #$FF + db #$FF + .routine + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_SECOND_INVERTED + STA !ram_botwoon_rng + LDA !ram_cm_botwoon_second_rng : BEQ .checkRoom + ; possible values are $01, $09, $11, $19 + DEC : ASL #3 : INC : XBA : ASL + ORA !ram_botwoon_rng : STA !ram_botwoon_rng + .checkRoom + LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done + JML init_botwoon_rng + .done + RTL + +rng_botwoon_spit: + dw !ACTION_CHOICE + dl #!ram_cm_botwoon_spit_rng + dw #.routine + db #$28, "Botwoon Spit", #$FF + db #$28, " RANDOM", #$FF + db #$28, " NEVER SPIT", #$FF + db #$28, "ALWAYS SPIT", #$FF + db #$FF + .routine + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_SPIT_INVERTED + STA !ram_botwoon_rng + LDA !ram_cm_botwoon_spit_rng : BEQ .checkRoom + ; 0-4 = no spit, 6-E = spit + ASL #2 : ORA !ram_botwoon_rng : STA !ram_botwoon_rng + .checkRoom + LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done + JML init_botwoon_rng + .done + RTL + +rng_botwoon_after_spit: + dw !ACTION_CHOICE + dl #!ram_cm_botwoon_after_spit_rng + dw #.routine + db #$28, "Botwoon After S", #$FF + db #$28, "pit RANDOM", #$FF + db #$28, "pit MOVE", #$FF + db #$28, "pit HIDE", #$FF + db #$FF + .routine + LDA !ram_botwoon_rng : AND !BOTWOON_RNG_AFTER_SPIT_INVERTED + STA !ram_botwoon_rng + LDA !ram_cm_botwoon_after_spit_rng : BEQ .checkRoom + DEC : ORA !BOTWOON_RNG_AFTER_SPIT_ENABLED + ORA !ram_botwoon_rng : STA !ram_botwoon_rng + .checkRoom + LDA !ROOM_ID : CMP.w #ROOM_BotwoonRoom : BNE .done + JML init_botwoon_rng + .done + RTL + + ; ----------------- ; Mother Brain Menu ; ----------------- diff --git a/src/symbols.asm b/src/symbols.asm index 56ac4b14..6ea1955d 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -192,6 +192,7 @@ ram_door_destination = !ram_door_destination ; !WRAM_PERSIST_START+$5A ram_frames_held = !ram_frames_held ; !WRAM_PERSIST_START+$5C ram_quickboot_spc_state = !ram_quickboot_spc_state ; !WRAM_PERSIST_START+$5E ram_display_backup = !ram_display_backup ; !WRAM_PERSIST_START+$60 +ram_drop_chance_table = !ram_drop_chance_table ; !WRAM_PERSIST_START+$62 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -275,11 +276,7 @@ ram_cm_itempickups_chozo = !ram_cm_itempickups_chozo ; !WRAM_MENU_START+$9A ram_cm_itempickups_hidden = !ram_cm_itempickups_hidden ; !WRAM_MENU_START+$9C ram_cm_turret_rng = !ram_cm_turret_rng ; !WRAM_MENU_START+$90 -ram_cm_botwoon_first_rng = !ram_cm_botwoon_first_rng ; !WRAM_MENU_START+$92 -ram_cm_botwoon_hidden_rng = !ram_cm_botwoon_hidden_rng ; !WRAM_MENU_START+$94 -ram_cm_botwoon_second_rng = !ram_cm_botwoon_second_rng ; !WRAM_MENU_START+$96 -ram_cm_botwoon_spit_rng = !ram_cm_botwoon_spit_rng ; !WRAM_MENU_START+$98 -ram_cm_botwoon_after_spit_rng = !ram_cm_botwoon_after_spit_rng ; !WRAM_MENU_START+$9A +ram_cm_drop_chances = !ram_cm_drop_chances ; !WRAM_MENU_START+$92 ram_cm_phantoon_first_phase_rng = !ram_cm_phantoon_first_phase_rng ; !WRAM_MENU_START+$9C ram_cm_phantoon_second_phase_rng = !ram_cm_phantoon_second_phase_rng ; !WRAM_MENU_START+$9E @@ -300,6 +297,12 @@ ram_cm_ridley_pogo_time_value_rng = !ram_cm_ridley_pogo_time_value_rng ; !WRAM_M ram_cm_ridley_hover_time_rng = !ram_cm_ridley_hover_time_rng ; !WRAM_MENU_START+$AC ram_cm_ridley_hover_time_value_rng = !ram_cm_ridley_hover_time_value_rng ; !WRAM_MENU_START+$AE +ram_cm_botwoon_first_rng = !ram_cm_botwoon_first_rng ; !WRAM_MENU_START+$9C +ram_cm_botwoon_hidden_rng = !ram_cm_botwoon_hidden_rng ; !WRAM_MENU_START+$9E +ram_cm_botwoon_second_rng = !ram_cm_botwoon_second_rng ; !WRAM_MENU_START+$A0 +ram_cm_botwoon_spit_rng = !ram_cm_botwoon_spit_rng ; !WRAM_MENU_START+$A2 +ram_cm_botwoon_after_spit_rng = !ram_cm_botwoon_after_spit_rng ; !WRAM_MENU_START+$A4 + ram_cm_mb_walking_rng = !ram_cm_mb_walking_rng ; !WRAM_MENU_START+$9C ram_cm_mb_ketchup_rng = !ram_cm_mb_ketchup_rng ; !WRAM_MENU_START+$9E ram_cm_mb_damage_down_rng = !ram_cm_mb_damage_down_rng ; !WRAM_MENU_START+$A0 From 7746ed937d7e3bfc535f24cf5c7a25b4c59ba666 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 18 May 2025 21:40:12 -0500 Subject: [PATCH 23/43] Fix water physics after collecting space jump --- src/fanfare.asm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fanfare.asm b/src/fanfare.asm index aa6e336a..1e75203d 100644 --- a/src/fanfare.asm +++ b/src/fanfare.asm @@ -337,8 +337,11 @@ hook_end_fanfare: LDA !sram_healthalarm : CMP #$0004 : BNE .done_health_alarm LDA #$0002 : JSL $80914D .done_health_alarm - PLY : PLX ; original logic - PLB : PLP : RTL + ; original logic + PLY : PLX + PLB : PLP + ; initialize water physics in case we just collected gravity or space jump + JML init_physics_ram } %endfree(85) From b859e4b233e57089eeeb7c841e6a47f5f97c68b0 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 18 May 2025 23:14:59 -0500 Subject: [PATCH 24/43] Fix Dachora room revisit category preset scrolls --- src/custompresets.asm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/custompresets.asm b/src/custompresets.asm index 2d8e4a4a..e68efd08 100644 --- a/src/custompresets.asm +++ b/src/custompresets.asm @@ -622,8 +622,8 @@ preset_scroll_fixes: CPX.w #ROOM_AlphaPowerBombRoom : BEQ .alpha_pbs CPX.w #ROOM_BelowSpazer : BEQ .below_spazer CPX.w #ROOM_WarehouseEntrance : BEQ .warehouse_entrance - CPX.w #ROOM_CaterpillarRoom : BEQ .caterpillar - BRA .topdone + CPX.w #ROOM_CaterpillarRoom : BNE .topdone + BRA .caterpillar .gauntlet_etank LDY !SAMUS_X : CPY #$0510 ; no fix if Xpos >= 1296 @@ -634,6 +634,8 @@ preset_scroll_fixes: .green_brin_main_shaft LDY !SAMUS_Y : CPY #$0700 ; no fix if Ypos < 1792 BMI .topdone + LDY !SAMUS_X : CPY #$0100 ; no fix if Xpos >= 256 + BPL .topdone INC : STA $CD3C BRA .topdone @@ -645,9 +647,10 @@ preset_scroll_fixes: .big_pink_pbs LDY !SAMUS_Y : CPY #$0136 ; no fix if Ypos >= 310 - BMI .topdone + BMI .big_pink_pbs_done STZ $CD21 STA $CD22 : STA $CD23 + .big_pink_pbs_done JMP .topdone .taco_tank_room From 063b4fba3d0aac116cf7a833d03aadfe396472a3 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 18 May 2025 23:24:46 -0500 Subject: [PATCH 25/43] Add Y1/Y2 support to Botwoon CF trainer --- src/infohudmodes.asm | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/infohudmodes.asm b/src/infohudmodes.asm index c98ecf74..67a6f634 100644 --- a/src/infohudmodes.asm +++ b/src/infohudmodes.asm @@ -3933,11 +3933,11 @@ endif ; Note by only checking the lower byte of Y position, ; the same check now works for the shaktool CF clip ; Arbitrary wait of 90 frames before checking - CMP #$005A : BMI .inc - LDA !SAMUS_X : CMP !ram_xpos : BNE .inc - LDA !SAMUS_Y : AND #$00FF : CMP #$00B7 : BNE .inc - LDA !SAMUS_Y_SPEED : CMP #$0000 : BNE .inc - LDA !SAMUS_Y_SUBSPEED : CMP #$0000 : BNE .inc + CMP #$005A : BMI .incNonZeroSpeed + LDA !SAMUS_X : CMP !ram_xpos : BNE .incNonZeroSpeed + LDA !SAMUS_Y : AND #$00FF : CMP #$00B7 : BNE .incNonZeroSpeed + LDA !SAMUS_Y_SPEED : CMP #$0000 : BNE .incNonZeroSpeed + LDA !SAMUS_Y_SUBSPEED : CMP #$0000 : BNE .incY2 LDA !IH_LETTER_Y : STA !HUD_TILEMAP+$8A BRA .timecheck @@ -3961,7 +3961,14 @@ endif LDA !SAMUS_Y : STA !ram_ypos RTS + .incY2 + LDA #$0002 + BRA .inc + + .incNonZeroSpeed + TDC .inc + STA !ram_quickdrop_counter ; Arbitrary give up waiting after 192 frames LDA !ram_roomstrat_state : CMP #$00C0 : BPL .reset INC : STA !ram_roomstrat_state @@ -3984,12 +3991,19 @@ endif LDA #!botwooncf_frame : SEC : SBC !ram_roomstrat_state ASL : TAY : LDA.w NumberGFXTable,Y : STA !HUD_TILEMAP+$8E LDA !IH_LETTER_E : STA !HUD_TILEMAP+$8C - ; Keep waiting if we are early + ; Keep waiting if we are early for a potential Y1 + LDA #$0001 BRA .inc .frameperfect + LDA !ram_quickdrop_counter : BNE .frameY1Y2 LDA !IH_LETTER_Y : STA !HUD_TILEMAP+$8C : STA !HUD_TILEMAP+$8E BRA .reset + + .frameY1Y2 + ASL : TAY : LDA.w NumberGFXTable,Y : STA !HUD_TILEMAP+$8E + LDA !IH_LETTER_Y : STA !HUD_TILEMAP+$8C + BRA .reset } status_snailclip: From 5446d4187684bb54d9ff3437cef7bb5402256830 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Mon, 26 May 2025 21:27:17 -0500 Subject: [PATCH 26/43] Finalize BRB splash screen logic --- src/BRBmenu.asm | 152 +++++++++++++++++++++++++++++++----------------- 1 file changed, 98 insertions(+), 54 deletions(-) diff --git a/src/BRBmenu.asm b/src/BRBmenu.asm index 55ae9ee1..8ebb37be 100644 --- a/src/BRBmenu.asm +++ b/src/BRBmenu.asm @@ -240,11 +240,11 @@ cm_tilemap_brb: ; Same bank for all of the BRB text PHK : PHK : PLA : STA !DP_CurrentMenu+2 - LDA.w #BRB_common_1 : STA !DP_CurrentMenu + LDA.w #BRB_common_line1 : STA !DP_CurrentMenu LDX #$01C6 JSR cm_draw_brb_text - LDA.w #BRB_common_2 : STA !DP_CurrentMenu + LDA.w #BRB_common_line2 : STA !DP_CurrentMenu LDX #$0286 JSR cm_draw_brb_text @@ -284,13 +284,13 @@ cm_tilemap_brb: ; Draw cycling text ; first cycled line LDA !ram_cm_brb_screen : ASL : TAX - LDA.l BRBTilemapAddress,X : STA !DP_CurrentMenu + LDA.l BRBTilemapTableLine1,X : STA !DP_CurrentMenu LDX #$04C6 JSR cm_draw_brb_text ; second cycled line LDA !ram_cm_brb_screen : ASL : TAX - LDA.l BRBTilemapAddress2,X : STA !DP_CurrentMenu + LDA.l BRBTilemapTableLine2,X : STA !DP_CurrentMenu LDX #$0586 JSR cm_draw_brb_text @@ -309,22 +309,44 @@ cm_tilemap_splash_screen: BRK .legacy - LDA.w #BRB_legacy : STA !DP_CurrentMenu - LDX #$0286 + LDA.w #BRB_legacy_line2 : STA !DP_CurrentMenu + LDX #$0406 JSR cm_draw_brb_text - RTS + LDA.w #BRB_legacy_line3 : STA !DP_CurrentMenu + LDX #$04C6 + JSR cm_draw_brb_text + BRA .splashLine4 .tinystates - LDA.w #BRB_tinystates : STA !DP_CurrentMenu - LDX #$0286 + LDA.w #BRB_tinystates_line2 : STA !DP_CurrentMenu + LDX #$0406 JSR cm_draw_brb_text - RTS + LDA.w #BRB_tinystates_line3 : STA !DP_CurrentMenu + LDX #$04C6 + JSR cm_draw_brb_text + BRA .splashLine4 .zsnes - LDA.w #BRB_zsnes : STA !DP_CurrentMenu - LDX #$0286 + LDA.w #BRB_zsnes_line2 : STA !DP_CurrentMenu + LDX #$0406 JSR cm_draw_brb_text - RTS + LDA.w #BRB_zsnes_line4 : STA !DP_CurrentMenu + LDX #$0586 + JSR cm_draw_brb_text + BRA .splashLine1 + + .splashLine4 + LDA.w #BRB_splash_line4 : STA !DP_CurrentMenu + LDX #$0586 + JSR cm_draw_brb_text + + .splashLine1 + LDA.w #BRB_splash_line1 : STA !DP_CurrentMenu + LDX #$0346 + JSR cm_draw_brb_text + LDA.w #BRB_splash_title : STA !DP_CurrentMenu + LDX #$01C6 + JMP cm_draw_brb_text } brb_handle_countup_timer: @@ -504,81 +526,103 @@ cm_brb_scroll_BG3: ; BRB Text Data ; ------------- -BRB_common_1: table ../resources/header.tbl +BRB_common_line1: db #$28, " The Streamer", #$FF - -BRB_common_2: +BRB_common_line2: db #$28, " Will Be Right Back", #$FF -BRB_legacy: -db #$28, " SNES CLASSIC OR VC", #$FF -BRB_tinystates: -db #$28, " SELECT MODERN EMULATORS", #$FF +BRB_splash_title: + db #$28, " Wrong Platform Selected", #$FF + -BRB_zsnes: -db #$28, " DO NOT USE ZSNES", #$FF +BRB_zsnes_line4: + db #$28, " DO NOT USE ZSNES", #$FF table ../resources/normal.tbl -BRBTilemapAddress: - dw #BRB_screen_01 - dw #BRB_screen_02 - dw #BRB_screen_03 - dw #BRB_screen_04 - dw #BRB_screen_05 - dw #BRB_screen_06 - dw #BRB_screen_07 - -BRBTilemapAddress2: - dw #BRB_screen2_01 - dw #BRB_screen2_02 - dw #BRB_screen2_03 - dw #BRB_screen2_04 - dw #BRB_screen2_05 - dw #BRB_screen2_06 - dw #BRB_screen2_07 - -BRB_screen_01: + +BRB_splash_line1: + db #$28, " You need to select", #$FF +BRB_splash_line4: + db #$28, " at smpractice.speedga.me", #$FF + + +BRB_legacy_line2: + db #$28, " SNES Classic or", #$FF +BRB_legacy_line3: + db #$28, " Virtual Console", #$FF + + +BRB_tinystates_line2: + db #$28, " Everdrive or", #$FF +BRB_tinystates_line3: + db #$28, " Snes9x 1.60 or older", #$FF + + +BRB_zsnes_line2: + db #$28, " another emulator", #$FF + + +BRBTilemapTableLine1: + dw #BRB_screen1_line1 + dw #BRB_screen2_line1 + dw #BRB_screen3_line1 + dw #BRB_screen4_line1 + dw #BRB_screen5_line1 + dw #BRB_screen6_line1 + dw #BRB_screen7_line1 + +BRBTilemapTableLine2: + dw #BRB_screen1_line2 + dw #BRB_screen2_line2 + dw #BRB_screen3_line2 + dw #BRB_screen4_line2 + dw #BRB_screen5_line2 + dw #BRB_screen6_line2 + dw #BRB_screen7_line2 + + +BRB_screen1_line1: db #$28, " SM Speedrunning Wiki", #$FF -BRB_screen2_01: +BRB_screen1_line2: db #$28, " wiki.supermetroid.run", #$FF -BRB_screen_02: +BRB_screen2_line1: db #$28, " SM Speedrunning Discord", #$FF -BRB_screen2_02: +BRB_screen2_line2: db #$28, " SMDiscord.spazer.link", #$FF -BRB_screen_03: +BRB_screen3_line1: db #$28, "Find the practice hack at", #$FF -BRB_screen2_03: +BRB_screen3_line2: db #$28, " smpractice.speedga.me", #$FF -BRB_screen_04: +BRB_screen4_line1: db #$28, " Control Schemes for SM", #$FF -BRB_screen2_04: +BRB_screen4_line2: db #$28, " controls.spazer.link", #$FF -BRB_screen_05: +BRB_screen5_line1: db #$28, "Support FUNtoon on Patreon", #$FF -BRB_screen2_05: +BRB_screen5_line2: ; !funtoonpatreon db #$28, " ", #$1A, "funtoonpatreon", #$FF -BRB_screen_06: +BRB_screen6_line1: db #$28, " Crazy chain damage clips", #$FF -BRB_screen2_06: +BRB_screen6_line2: db #$28, " chain.spazer.link", #$FF -BRB_screen_07: +BRB_screen7_line1: db #$28, " Learn new SM strats at", #$FF -BRB_screen2_07: +BRB_screen7_line2: db #$28, " crocomi.re", #$FF %endfree(A1) From dbff6aaa3e92dbd9c525e97bcfe8dfcd3f8a4306 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 8 Jun 2025 15:25:45 -0500 Subject: [PATCH 27/43] Start of ctrl shortcut routine slightly offset from tilemap buffer --- src/defines.asm | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index d1905b8c..baa9b382 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -14,20 +14,20 @@ ; Shortcut routine is written on boot and each time the menu closes, ; so it can use the same space as the practice hack menu tilemap buffer -!CTRL_SHORTCUT_ROUTINE = $7EF500 ; up to 1883 bytes or +$75A -!CTRL_SHORTCUT_TABLE = !CTRL_SHORTCUT_ROUTINE+$7B8 ; 48 bytes -!CTRL_SHORTCUT_TYPE = !CTRL_SHORTCUT_ROUTINE+$7E8 -!CTRL_SHORTCUT_PRI = !CTRL_SHORTCUT_ROUTINE+$7EA -!CTRL_SHORTCUT_SEC = !CTRL_SHORTCUT_ROUTINE+$7EC -!CTRL_SHORTCUT_JSL_WORD_LSB = !CTRL_SHORTCUT_ROUTINE+$7EE -!CTRL_SHORTCUT_JSL_WORD_MSB = !CTRL_SHORTCUT_ROUTINE+$7F0 -!CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP = !CTRL_SHORTCUT_ROUTINE+$7F2 -!CTRL_SHORTCUT_SEC_TO_DUAL_JUMP = !CTRL_SHORTCUT_ROUTINE+$7F4 -!CTRL_SHORTCUT_TABLE_PRI_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F6 -!CTRL_SHORTCUT_TABLE_SEC_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F8 -!CTRL_SHORTCUT_TABLE_DUAL_INDEX = !CTRL_SHORTCUT_ROUTINE+$7FA +!CTRL_SHORTCUT_ROUTINE = $7EF502 ; up to 1883 bytes or +$75A +!CTRL_SHORTCUT_TABLE = !CTRL_SHORTCUT_ROUTINE+$7B6 ; 48 bytes +!CTRL_SHORTCUT_TYPE = !CTRL_SHORTCUT_ROUTINE+$7E6 +!CTRL_SHORTCUT_PRI = !CTRL_SHORTCUT_ROUTINE+$7E8 +!CTRL_SHORTCUT_SEC = !CTRL_SHORTCUT_ROUTINE+$7EA +!CTRL_SHORTCUT_JSL_WORD_LSB = !CTRL_SHORTCUT_ROUTINE+$7EC +!CTRL_SHORTCUT_JSL_WORD_MSB = !CTRL_SHORTCUT_ROUTINE+$7EE +!CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP = !CTRL_SHORTCUT_ROUTINE+$7F0 +!CTRL_SHORTCUT_SEC_TO_DUAL_JUMP = !CTRL_SHORTCUT_ROUTINE+$7F2 +!CTRL_SHORTCUT_TABLE_PRI_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F4 +!CTRL_SHORTCUT_TABLE_SEC_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F6 +!CTRL_SHORTCUT_TABLE_DUAL_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F8 ; Shortcuts can skip remaining checks by replacing the return address word -!CTRL_SHORTCUT_SKIP_REMAINING_PEA = !CTRL_SHORTCUT_ROUTINE+$7FC +!CTRL_SHORTCUT_SKIP_REMAINING_PEA = !CTRL_SHORTCUT_ROUTINE+$7FA !CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE = $FCFC !WRAM_SIZE = #$0200 From 2afc74b700738175e9fc4d44c34b5845bee2591f Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 8 Jun 2025 15:26:41 -0500 Subject: [PATCH 28/43] Require blank input to be held for two seconds instead of just one --- src/defines.asm | 2 ++ src/menu.asm | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index baa9b382..6429c05f 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -1199,8 +1199,10 @@ endif if !FEATURE_PAL !FRAMERATE = #$0032 +!FRAMERATE_2X = #$0064 else !FRAMERATE = #$003C +!FRAMERATE_2X = #$0078 endif !CTRL_SHORTCUT_TYPE_MASK = #$007F diff --git a/src/menu.asm b/src/menu.asm index c9af1034..b2edc209 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -1925,7 +1925,8 @@ cm_loop: cm_ctrl_mode: ; This routine cuts off input handling in cm_loop to keep focus on the selected controller shortcut -; Held inputs are displayed until held for 120 frames +; Held inputs are displayed until held for one second +; If inputs blank then must be blank for two seconds { JSL $809459 ; Read controller input @@ -1939,8 +1940,16 @@ cm_ctrl_mode: .skipInputCtrl2 ; Holding an input for one second LDA !ram_cm_ctrl_timer : INC : STA !ram_cm_ctrl_timer - CMP !FRAMERATE : BNE .nextFrame + CMP !FRAMERATE : BNE .checkTwoSeconds + ; If input blank then we must hold it for two seconds + LDA !IH_CONTROLLER_PRI : ORA !IH_CONTROLLER_SEC : BNE .checkFirstShortcut + + .checkTwoSeconds + ; Holding an input for two seconds + CMP !FRAMERATE_2X : BNE .nextFrame + + .checkFirstShortcut ; Disallow first Main Menu shortcut to be empty LDA !DP_Ctrl2Input : BNE .store LDA !IH_CONTROLLER_PRI : BNE .store From b0f5d44c80a8789e02343698401b4ca5c818a5c0 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 22 Jun 2025 21:20:56 -0500 Subject: [PATCH 29/43] Enable the pause and unpause shortcuts --- src/defines.asm | 4 +++ src/gamemode.asm | 48 +++++++++++++++++++++++--- src/infohud.asm | 85 ++++++++++++++++++++++++++++++---------------- src/main.asm | 2 +- src/mainmenu.asm | 1 - src/menu.asm | 15 ++++---- src/save.asm | 8 ++--- src/tinystates.asm | 8 ++--- 8 files changed, 121 insertions(+), 50 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index 6429c05f..273190d2 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -1213,6 +1213,10 @@ endif !SRAM_DETECTION_128KB = #$0128 !SRAM_DETECTION_ZSNES = #$0505 +!SLOWDOWN_FRAME_ADVANCE = #$8000 +!SLOWDOWN_PAUSED_MAIN_MENU = #$FFFE +!SLOWDOWN_PAUSED = #$FFFF + !SUIT_PROPERTIES_MASK = #$0007 !SUIT_PROPRETIES_PAL_DEBUG_FLAG = #$0008 diff --git a/src/gamemode.asm b/src/gamemode.asm index 65f1e740..6c788382 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -61,10 +61,26 @@ if !FEATURE_PAL else LDA !IH_CONTROLLER_PRI : CMP #$C0C0 : BNE .done LDA !AREA_ID : BEQ .done : CMP #$0002 : BEQ .done - BRA .done ; disabled during beta testing phase - LDA #custom_intro_init : STA !CINEMATIC_FUNCTION_POINTER + PHX : PHP + %ai16() : TDC : TAX : %a8() + .firstLoop + LDA !sram_ctrl_shortcut_selections,X : BEQ .firstNext + %a16() : TXA : ASL : TAX + LDA !sram_ctrl_1_shortcut_inputs,X : CMP #$C0C0 : BEQ .end + TXA : LSR : TAX : %a8() + .firstNext + INX : CPX #$001E : BMI .firstLoop + .secondLoop + LDA !sram_ctrl_additional_selections,X : BEQ .secondNext + %a16() : TXA : ASL : TAX + LDA !sram_ctrl_1_shortcut_inputs,X : CMP #$C0C0 : BEQ .end + TXA : LSR : TAX : %a8() + .secondNext + INX : CPX #$0030 : BMI .secondLoop + %a16() : LDA #custom_intro_init : STA !CINEMATIC_FUNCTION_POINTER LDA #$001E : STA !GAMEMODE .end + PLP : PLX JML $82E4A9 ; return to hijacked code endif } @@ -150,6 +166,14 @@ gamemode_start: gamemode_main_menu: { + ; Check for paused states + LDA !ram_slowdown_mode : BPL .openMainMenu + CMP !SLOWDOWN_PAUSED_MAIN_MENU : BNE .paused + + ; Set slowdown mode to paused but allow menu to open + LDA !SLOWDOWN_PAUSED : STA !ram_slowdown_mode + + .openMainMenu ; Set IRQ vector LDA !IRQ_CMD : PHA LDA #$0004 : STA !IRQ_CMD @@ -159,7 +183,14 @@ gamemode_main_menu: ; Restore IRQ vector PLA : STA !IRQ_CMD + BRA .done + .paused + ; We are paused in the NMI routine, so we cannot open the menu here + ; Set flag so we know to open the menu later + LDA !SLOWDOWN_PAUSED_MAIN_MENU : STA !ram_slowdown_mode + + .done ; Skip remaining shortcuts PLA : PEA !CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE @@ -434,9 +465,14 @@ gamemode_toggle_spin_lock: gamemode_pause: { + LDA !ram_slowdown_mode : CMP !SLOWDOWN_PAUSED : BEQ .frameAdvance TDC : STA !ram_slowdown_frames DEC : STA !ram_slowdown_mode RTL + + .frameAdvance + LDA #$8000 : STA !ram_slowdown_mode + RTL } gamemode_unpause: @@ -447,13 +483,17 @@ gamemode_unpause: gamemode_slowdown: { - LDA !ram_slowdown_mode : INC : STA !ram_slowdown_mode + LDA !ram_slowdown_mode : BMI .done + CMP #$0078 : BPL .done + INC : STA !ram_slowdown_mode + LDA !ram_slowdown_frames : INC : STA !ram_slowdown_frames + .done RTL } gamemode_speedup: { - LDA !ram_slowdown_mode : BEQ .done + LDA !ram_slowdown_mode : BEQ .done : BMI .done DEC : STA !ram_slowdown_mode .done RTL diff --git a/src/infohud.asm b/src/infohud.asm index 2b3d9010..7dc71dfe 100644 --- a/src/infohud.asm +++ b/src/infohud.asm @@ -302,23 +302,29 @@ else LDA !ram_seg_rt_minutes : INC : STA !ram_seg_rt_minutes endif - ; Slowdown / Pause / Frame Advance on P2 Dpad + ; Slowdown / Pause / Frame Advance .doneTimer LDA !ram_slowdown_mode : BNE .slowdown JMP .done .slowdown - CMP #$FFFF : BEQ .pause + BMI .pause LDA !ram_slowdown_frames : BNE .delay ; reset slowdown timer and restore previous inputs LDA !ram_slowdown_mode : STA !ram_slowdown_frames LDA !ram_slowdown_controller_1 : STA !IH_CONTROLLER_PRI_PREV LDA !ram_slowdown_controller_2 : STA !IH_CONTROLLER_SEC_PREV - JSL $809459 ; Read controller input + + .skipDelay JMP .done + .delayDoorTransition + LDA !DOOR_FUNCTION_POINTER : CMP #optimized_fade_in : BCC .skipDelay + CMP #hijack_after_load_level_data : BEQ .skipDelay + BRA .keepDelay + .delay CMP !ram_slowdown_mode : BNE .decTimer @@ -326,6 +332,13 @@ endif LDA !IH_CONTROLLER_PRI : EOR !IH_CONTROLLER_PRI_NEW : STA !ram_slowdown_controller_1 LDA !IH_CONTROLLER_SEC : EOR !IH_CONTROLLER_SEC_NEW : STA !ram_slowdown_controller_2 + LDA !GAMEMODE : CMP #$0007 : BMI .skipDelay + CMP #$000B : BEQ .delayDoorTransition + CMP #$000D : BMI .keepDelay + CMP #$0012 : BEQ .keepDelay + CMP #$001B : BNE .skipDelay + + .keepDelay LDA !ram_slowdown_frames .decTimer @@ -336,34 +349,12 @@ endif JMP .done .pause - ; TODO make pause work properly - ; LDA !IH_CONTROLLER_PRI : CMP !sram_ctrl_menu : BNE .noMenu - ; LDA !IH_PAUSE : STA !IH_CONTROLLER_SEC_NEW - BRA .frameAdvance - - .noMenu - LDA !ram_slowdown_frames : BNE .checkFrameAdvance - ; remain paused, store inputs - INC : STA !ram_slowdown_frames - - .storeInputs - LDA !IH_CONTROLLER_PRI : EOR !IH_CONTROLLER_PRI_NEW : STA !ram_slowdown_controller_1 - LDA !IH_CONTROLLER_SEC : EOR !IH_CONTROLLER_SEC_NEW : STA !ram_slowdown_controller_2 - - .checkFrameAdvance - ; TODO make resume work properly - ; LDA !IH_CONTROLLER_SEC_NEW : CMP !IH_PAUSE : BEQ .frameAdvance - ; CMP !IH_RESET : BNE .checkFreezeOnLoad - ; resume normal play - TDC : STA !ram_slowdown_mode : STA !ram_slowdown_frames - BRA .done - - .checkFreezeOnLoad ; option to pause on loadstate - LDA !ram_freeze_on_load : BEQ .frozen - LDA !IH_CONTROLLER_PRI_NEW : BEQ .frozen + LDA !ram_freeze_on_load : BEQ .checkFrameAdvance + LDA !IH_CONTROLLER_PRI_NEW : BEQ .checkFrameAdvance ; unfreeze TDC : STA !ram_slowdown_mode : STA !ram_slowdown_frames + STA !ram_freeze_on_load if !FEATURE_SD2SNES LDA !SRAM_SEG_TIMER_F : STA !ram_seg_rt_frames LDA !SRAM_SEG_TIMER_S : STA !ram_seg_rt_seconds @@ -373,16 +364,50 @@ else STA !ram_seg_rt_seconds STA !ram_seg_rt_minutes endif - BRA .done + JMP .done + + .pauseDoorTransition + LDA !DOOR_FUNCTION_POINTER : CMP #optimized_fade_in : BCC .done + CMP #hijack_after_load_level_data : BEQ .done + BRA .keepPause + + .checkFrameAdvance + LDA !ram_slowdown_mode : CMP !SLOWDOWN_PAUSED : BNE .frameAdvance + LDA !GAMEMODE : CMP #$0007 : BMI .done + CMP #$000B : BEQ .pauseDoorTransition + CMP #$000D : BMI .keepPause + CMP #$0012 : BEQ .keepPause + CMP #$001B : BNE .done + + .keepPause + LDA !ram_slowdown_frames : BNE .frozen + INC : STA !ram_slowdown_frames + + ; we just ran a new frame, store previous inputs + LDA !IH_CONTROLLER_PRI : EOR !IH_CONTROLLER_PRI_NEW : STA !ram_slowdown_controller_1 + LDA !IH_CONTROLLER_SEC : EOR !IH_CONTROLLER_SEC_NEW : STA !ram_slowdown_controller_2 .frozen - ; request a lag frame + ; Set overflow and carry flags before calling routine + SEP #$41 + JSL !CTRL_SHORTCUT_ROUTINE + CLV + + ; Main menu doesn't work out the NMI routine, + ; so instead of running, it changes ram_slowdown_mode instead + ; Use this as a trigger to run the current frame + ; Also check for regular frame advance here + LDA !ram_slowdown_mode : CMP !SLOWDOWN_PAUSED_MAIN_MENU : BEQ .done + BMI .frameAdvance + + ; Request a lag frame %a8() : LDA #$01 : STA !NMI_REQUEST_FLAG : %a16() BRA .done .frameAdvance ; run a new frame TDC : STA !ram_slowdown_frames + DEC : STA !ram_slowdown_mode LDA !ram_slowdown_controller_1 : STA !IH_CONTROLLER_PRI_PREV LDA !ram_slowdown_controller_2 : STA !IH_CONTROLLER_SEC_PREV JSL $809459 ; Read controller input diff --git a/src/main.asm b/src/main.asm index 79eedb40..259238cf 100644 --- a/src/main.asm +++ b/src/main.asm @@ -16,7 +16,7 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 6 !VERSION_BUILD = 7 -!VERSION_REV = 11 +!VERSION_REV = 12 table ../resources/normal.tbl print "" diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 12b60bd1..fd2e86c4 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -3696,7 +3696,6 @@ SlowdownMenu: dw #slowdown_frames dw #$0000 %cm_header("SLOWDOWN MODE") - %cm_footer("PAUSE IS STILL WIP") slowdown_mode: dw !ACTION_CHOICE diff --git a/src/menu.asm b/src/menu.asm index b2edc209..da998764 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -162,16 +162,16 @@ cm_init: LDA !ram_seg_rt_minutes : STA !ram_cm_preserved_timers+6 ; Preserve and disable slowdown mode - TDC : STA !ram_cm_slowdown_mode : STA !ram_slowdown_frames - LDA !ram_slowdown_mode : BMI .paused + TDC : STA !ram_cm_slowdown_mode : STA !ram_cm_slowdown_frames + LDA !ram_slowdown_mode : BEQ .done_slowdown : BMI .paused STA !ram_cm_slowdown_frames - LDA !ram_slowdown_mode : BEQ .done_slowdown LDA #$0002 : STA !ram_cm_slowdown_mode BRA .done_slowdown + .paused LDA #$0001 : STA !ram_cm_slowdown_mode .done_slowdown - TDC : STA !ram_slowdown_mode + TDC : STA !ram_slowdown_mode : STA !ram_slowdown_frames JSL initialize_ppu_long JSL cm_transfer_custom_tileset @@ -249,10 +249,13 @@ endif ; Restore slowdown mode LDA !ram_cm_slowdown_mode : BEQ .done_slowdown DEC : BEQ .paused - LDA !ram_cm_slowdown_frames : BRA .done_slowdown + LDA !ram_cm_slowdown_frames + BRA .done_slowdown + .paused JSL EnsureSamusIsDrawn_long - LDA #$FFFF + LDA #$0001 : STA !ram_slowdown_frames + LDA !SLOWDOWN_PAUSED .done_slowdown STA !ram_slowdown_mode RTS diff --git a/src/save.asm b/src/save.asm index beacf1c7..0a1cf7df 100644 --- a/src/save.asm +++ b/src/save.asm @@ -88,10 +88,10 @@ post_load_state: ; Reload custom HUD number GFX JSL overwrite_HUD_numbers - LDA !SRAM_SLOWDOWN_MODE : CMP #$FFFF : BEQ .rng - AND #$00FF : STA !ram_slowdown_mode + LDA !SRAM_SLOWDOWN_MODE : STA !ram_slowdown_mode + TDC : STA !ram_slowdown_frames + STA !ram_slowdown_controller_1 : STA !ram_slowdown_controller_2 - .rng ; Rerandomize LDA !sram_save_has_set_rng : BNE .randomizeOnLoad LDA !sram_rerandomize : BEQ .randomizeOnLoad @@ -112,7 +112,7 @@ post_load_state: ; Freeze inputs if necessary LDA !ram_freeze_on_load : BEQ .return LDA !ram_slowdown_mode : BNE .return - LDA #$FFFF : STA !ram_slowdown_mode + LDA !SLOWDOWN_PAUSED : STA !ram_slowdown_mode INC : STA !ram_slowdown_controller_1 : STA !ram_slowdown_controller_2 INC : STA !ram_slowdown_frames ; Preserve segment timer during freeze diff --git a/src/tinystates.asm b/src/tinystates.asm index 23eb1a8a..5c82f30c 100644 --- a/src/tinystates.asm +++ b/src/tinystates.asm @@ -127,10 +127,10 @@ post_load_state: ; Reload custom HUD number GFX JSL overwrite_HUD_numbers - LDA !SRAM_SLOWDOWN_MODE : CMP #$FFFF : BEQ .rng - AND #$00FF : STA !ram_slowdown_mode + LDA !SRAM_SLOWDOWN_MODE : STA !ram_slowdown_mode + TDC : STA !ram_slowdown_frames + STA !ram_slowdown_controller_1 : STA !ram_slowdown_controller_2 - .rng ; Rerandomize LDA !sram_save_has_set_rng : BNE .randomizeOnLoad LDA !sram_rerandomize : BEQ .randomizeOnLoad @@ -151,7 +151,7 @@ post_load_state: ; Freeze inputs if necessary LDA !ram_freeze_on_load : BEQ .return LDA !ram_slowdown_mode : BNE .return - LDA #$FFFF : STA !ram_slowdown_mode + LDA !SLOWDOWN_PAUSED : STA !ram_slowdown_mode INC : STA !ram_slowdown_controller_1 : STA !ram_slowdown_controller_2 INC : STA !ram_slowdown_frames ; Preserve segment timer during freeze From 92c4efe0e60ae0dab9ac5bdc84d9a727cfb46695 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 22 Jun 2025 21:22:25 -0500 Subject: [PATCH 30/43] Fix energy/ammo refill message box timing --- src/fanfare.asm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fanfare.asm b/src/fanfare.asm index 1e75203d..812257ff 100644 --- a/src/fanfare.asm +++ b/src/fanfare.asm @@ -266,7 +266,8 @@ endif hook_message_box_wait: { LDA !sram_fanfare : BNE .fanfareloop - ; shorten message box length + ; shorten message box length if necessary + CPX #$0020 : BMI .nofanfareloop LDX #$0020 .nofanfareloop From 177bd3e41222b12155a605ac578627482112c7f1 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Tue, 24 Jun 2025 21:26:33 -0500 Subject: [PATCH 31/43] Use more RAM defines in code --- src/damage.asm | 94 ++++++++++++++++++++++++------------------------- src/defines.asm | 4 +++ 2 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/damage.asm b/src/damage.asm index 65dca29e..cc5a6b30 100644 --- a/src/damage.asm +++ b/src/damage.asm @@ -3,8 +3,8 @@ org $8DE37C AND !ram_suits_heat_damage_check : BNE $29 LDA !ram_suits_heat_damage_value : BEQ $23 - CLC : ADC $0A4E : STA $0A4E - BCC $03 : INC $0A50 + CLC : ADC !SAMUS_PERIODIC_SUBDAMAGE : STA !SAMUS_PERIODIC_SUBDAMAGE + BCC $03 : INC !SAMUS_PERIODIC_DAMAGE warnpc $8DE394 @@ -14,11 +14,11 @@ org $9081DB ; Everything else is vanilla but needs to be shifted down three bytes AND !SAMUS_LAVA_DAMAGE_SUITS CMP !SAMUS_LAVA_DAMAGE_SUITS : BEQ $2C - LDA $09DA : BIT #$0007 : BNE $0F - LDA $09C2 : CMP #$0047 : BMI $07 + LDA !IGT_FRAMES : BIT #$0007 : BNE $0F + LDA !SAMUS_HP : CMP #$0047 : BMI $07 LDA #$002D : JSL $809139 - LDA $0A4E : CLC : ADC $9E8B : STA $0A4E - LDA $0A50 : ADC $9E8D + LDA !SAMUS_PERIODIC_SUBDAMAGE : CLC : ADC $9E8B : STA !SAMUS_PERIODIC_SUBDAMAGE + LDA !SAMUS_PERIODIC_DAMAGE : ADC $9E8D ; Originally STA $0A50 and BRA $40 to $90824C ; Conveniently the command at $908249 is STA $0A50 so we can save three bytes BRA $3D @@ -143,10 +143,10 @@ endif suit_metroid_damage: { LDA #$C000 : STA $12 - LDA $09A2 : AND !ram_suits_enemy_damage_check : BEQ .checkGrav + LDA !SAMUS_ITEMS_EQUIPPED : AND !ram_suits_enemy_damage_check : BEQ .checkGrav LSR $12 .checkGrav - LDA $09A2 : BIT #$0020 : BEQ .noGrav + LDA !SAMUS_ITEMS_EQUIPPED : BIT #$0020 : BEQ .noGrav LSR $12 .noGrav ; Continue vanilla routine @@ -157,8 +157,8 @@ suit_metroid_damage: damage_overwritten_movement_routine: ; We overwrote an unnecessary JSR, a STZ command, and a jump to the movement routine - STZ $0A6E - JMP ($0A58) + STZ !SAMUS_CONTACT_DAMAGE_INDEX + JMP (!SAMUS_NORMAL_MOVEMENT_HANDLER) periodic_damage_table: if !FEATURE_PAL @@ -207,14 +207,14 @@ endif periodic_damage_balanced: { PHP : REP #$30 - LDA $0A78 : BEQ $03 + LDA !TIME_IS_FROZEN : BEQ $03 ; Nothing to do, jump back to vanilla routine if !FEATURE_PAL JMP $EA32 else JMP $EA35 endif - LDA $09A2 : BIT #$0001 : BNE $03 + LDA !SAMUS_ITEMS_EQUIPPED : BIT #$0001 : BNE $03 ; Either jump to gravity (75% reduction) or power suit (no reduction) if !FEATURE_PAL JMP $EA0E ; Varia not equipped @@ -228,7 +228,7 @@ endif periodic_damage_progressive: { PHP : REP #$30 - LDA $0A78 : BEQ $03 + LDA !TIME_IS_FROZEN : BEQ $03 ; Nothing to do, jump back to vanilla routine if !FEATURE_PAL JMP $EA32 @@ -236,18 +236,18 @@ else JMP $EA35 endif - LDA $09A2 : BIT #$0020 : BEQ .nogravity + LDA !SAMUS_ITEMS_EQUIPPED : BIT #$0020 : BEQ .nogravity ; Gravity equipped, so halve damage - LDA $0A4F : LSR - PHA : XBA : AND #$FF00 : STA $0A4E - PLA : XBA : AND #$00FF : STA $0A50 + LDA !SAMUS_PERIODIC_DAMAGECOMBINED : LSR + PHA : XBA : AND #$FF00 : STA !SAMUS_PERIODIC_SUBDAMAGE + PLA : XBA : AND #$00FF : STA !SAMUS_PERIODIC_DAMAGE .nogravity - LDA $09A2 : BIT #$0001 : BEQ .novaria + LDA !SAMUS_ITEMS_EQUIPPED : BIT #$0001 : BEQ .novaria ; Varia equipped, so halve damage - LDA $0A4F : LSR - PHA : XBA : AND #$FF00 : STA $0A4E - PLA : XBA : AND #$00FF : STA $0A50 + LDA !SAMUS_PERIODIC_DAMAGECOMBINED : LSR + PHA : XBA : AND #$FF00 : STA !SAMUS_PERIODIC_SUBDAMAGE + PLA : XBA : AND #$00FF : STA !SAMUS_PERIODIC_DAMAGE .novaria ; Jump back into the vanilla routine @@ -261,7 +261,7 @@ endif periodic_damage_dash_recall: { PHP : REP #$30 - LDA $0A78 : BEQ $03 + LDA !TIME_IS_FROZEN : BEQ $03 ; Nothing to do, jump back to vanilla routine if !FEATURE_PAL JMP $EA32 @@ -269,7 +269,7 @@ else JMP $EA35 endif - LDA $09A2 : BIT #$0001 : BEQ .novaria + LDA !SAMUS_ITEMS_EQUIPPED : BIT #$0001 : BEQ .novaria ; Jump back to gravity vanilla routine for 75% reduction if !FEATURE_PAL JMP $E9F9 @@ -278,11 +278,11 @@ else endif .novaria - LDA $09A2 : BIT #$0020 : BEQ .nogravity + LDA !SAMUS_ITEMS_EQUIPPED : BIT #$0020 : BEQ .nogravity ; Gravity equipped, so halve damage - LDA $0A4F : LSR - PHA : XBA : AND #$FF00 : STA $0A4E - PLA : XBA : AND #$00FF : STA $0A50 + LDA !SAMUS_PERIODIC_DAMAGECOMBINED : LSR + PHA : XBA : AND #$FF00 : STA !SAMUS_PERIODIC_SUBDAMAGE + PLA : XBA : AND #$00FF : STA !SAMUS_PERIODIC_DAMAGE .nogravity ; Jump back into the vanilla routine @@ -296,7 +296,7 @@ endif periodic_damage_heat_shield: { PHP : REP #$30 - LDA $0A78 : BEQ $03 + LDA !TIME_IS_FROZEN : BEQ $03 ; Nothing to do, jump back to vanilla routine if !FEATURE_PAL JMP $EA32 @@ -304,11 +304,11 @@ else JMP $EA35 endif - LDA $09A2 : BIT #$0020 : BEQ .nogravity + LDA !SAMUS_ITEMS_EQUIPPED : BIT #$0020 : BEQ .nogravity ; Gravity equipped, so halve damage - LDA $0A4F : LSR - PHA : XBA : AND #$FF00 : STA $0A4E - PLA : XBA : AND #$00FF : STA $0A50 + LDA !SAMUS_PERIODIC_DAMAGECOMBINED : LSR + PHA : XBA : AND #$FF00 : STA !SAMUS_PERIODIC_SUBDAMAGE + PLA : XBA : AND #$00FF : STA !SAMUS_PERIODIC_DAMAGE .nogravity ; Jump back into the vanilla routine @@ -329,12 +329,12 @@ healthalarm_turn_on_table: healthalarm_turn_on_improved: ; Do not sound alarm until below 30 combined health - LDA $09C2 : CLC : ADC $09D6 : CMP #$001E : BPL healthalarm_turn_on_done + LDA !SAMUS_HP : CLC : ADC !SAMUS_RESERVE_ENERGY : CMP #$001E : BPL healthalarm_turn_on_done healthalarm_turn_on_always_on: healthalarm_turn_on_pb_fix: ; Do not sound alarm if it won't play due to power bomb explosion - LDA $0592 : BMI healthalarm_turn_on_done + LDA !PB_EXPLOSION_STATUS : BMI healthalarm_turn_on_done healthalarm_turn_on_vanilla: LDA #$0002 : JSL $80914D @@ -356,7 +356,7 @@ healthalarm_turn_off_table: healthalarm_turn_off_improved: healthalarm_turn_off_pb_fix: ; Do not stop alarm if it won't stop due to power bomb explosion - LDA $0592 : BMI healthalarm_turn_off_done + LDA !PB_EXPLOSION_STATUS : BMI healthalarm_turn_off_done healthalarm_turn_off_vanilla: LDA #$0001 : JSL $80914D @@ -369,7 +369,7 @@ healthalarm_turn_off_done: healthalarm_turn_off_always_on: ; Do not sound alarm if it won't play due to power bomb explosion - LDA $0592 : BMI healthalarm_turn_off_done + LDA !PB_EXPLOSION_STATUS : BMI healthalarm_turn_off_done LDA #$0002 : JSL $80914D BRA healthalarm_turn_off_never @@ -394,32 +394,32 @@ damage_init_beam: ; so we can inject custom damage without a CPU hit PHP : PHB : PHK : PLB %ai16() - LDA $0C04,X : AND #$000F + LDA !SAMUS_PROJ_DIRECTION,X : AND #$000F ASL : STA $12 - LDA $0C18,X + LDA !SAMUS_PROJ_PROPERTIES,X BIT #$0010 : BNE .charged AND #$000F : ASL TAY : LDA $83C1,Y : TAY LDA !sram_custom_damage : BNE .nonVanillaUncharged - LDA $0000,Y : STA $0C2C,X + LDA $0000,Y : STA !SAMUS_PROJ_DAMAGE,X JMP $8048 .charged AND #$000F : ASL TAY : LDA $83D9,Y : TAY LDA !sram_custom_damage : BNE .nonVanillaCharged - LDA $0000,Y : STA $0C2C,X + LDA $0000,Y : STA !SAMUS_PROJ_DAMAGE,X JMP $8048 .nonVanillaUncharged DEC : BEQ .customUncharged .dashCharge0 - PHX : JSL compute_dash_charge_0_damage : PLX : STA $0C2C,X + PHX : JSL compute_dash_charge_0_damage : PLX : STA !SAMUS_PROJ_DAMAGE,X JMP $8048 .customUncharged - LDA !sram_custom_uncharge_damage : STA $0C2C,X + LDA !sram_custom_uncharge_damage : STA !SAMUS_PROJ_DAMAGE,X JMP $8048 .nonVanillaCharged @@ -428,23 +428,23 @@ damage_init_beam: DEC : BEQ .dashCharge1 DEC : BEQ .dashCharge2 DEC : BEQ .dashCharge3 - PHX : JSL compute_dash_charge_4_damage : PLX : STA $0C2C,X + PHX : JSL compute_dash_charge_4_damage : PLX : STA !SAMUS_PROJ_DAMAGE,X JMP $8048 .customCharged - LDA !sram_custom_charge_damage : STA $0C2C,X + LDA !sram_custom_charge_damage : STA !SAMUS_PROJ_DAMAGE,X JMP $8048 .dashCharge1 - PHX : JSL compute_dash_charge_1_damage : PLX : STA $0C2C,X + PHX : JSL compute_dash_charge_1_damage : PLX : STA !SAMUS_PROJ_DAMAGE,X JMP $8048 .dashCharge2 - PHX : JSL compute_dash_charge_2_damage : PLX : STA $0C2C,X + PHX : JSL compute_dash_charge_2_damage : PLX : STA !SAMUS_PROJ_DAMAGE,X JMP $8048 .dashCharge3 - PHX : JSL compute_dash_charge_3_damage : PLX : STA $0C2C,X + PHX : JSL compute_dash_charge_3_damage : PLX : STA !SAMUS_PROJ_DAMAGE,X JMP $8048 } diff --git a/src/defines.asm b/src/defines.asm index 273190d2..7d0ad39c 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -836,6 +836,9 @@ !SAMUS_LOCKED_HANDLER = $0A42 !SAMUS_MOVEMENT_HANDLER = $0A44 !SAMUS_SUBUNIT_ENERGY = $0A4C +!SAMUS_PERIODIC_SUBDAMAGE = $0A4E +!SAMUS_PERIODIC_DAMAGECOMBINED = $0A4F +!SAMUS_PERIODIC_DAMAGE = $0A50 !SAMUS_KNOCKBACK_DIRECTION = $0A54 !SAMUS_BOMB_JUMP_DIRECTION = $0A56 !SAMUS_NORMAL_MOVEMENT_HANDLER = $0A58 @@ -893,6 +896,7 @@ !SAMUS_PROJ_Y_SUBPX = $0BA0 !SAMUS_PROJ_RADIUS_X = $0BB4 !SAMUS_PROJ_RADIUS_Y = $0BC8 +!SAMUS_PROJ_DIRECTION = $0C04 !SAMUS_PROJ_PROPERTIES = $0C18 !SAMUS_PROJ_DAMAGE = $0C2C !SAMUS_COOLDOWN = $0CCC From 2ac9cb782780011773b56bfae16248e80ed47e13 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Tue, 24 Jun 2025 21:27:01 -0500 Subject: [PATCH 32/43] Force stand puts Samus into facing forward pose --- src/flagmenu.asm | 3 +-- src/misc.asm | 11 +++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/flagmenu.asm b/src/flagmenu.asm index 8fa05a2f..87c507c0 100644 --- a/src/flagmenu.asm +++ b/src/flagmenu.asm @@ -2633,9 +2633,8 @@ misc_killenemies: misc_forcestand: %cm_jsl("Force Samus to Stand Up", .routine, #0) .routine - JSL $90E2D4 ; bridge to: Release Samus from Draygon %sfxconfirm() - RTL + JML misc_force_stand_routine %endfree(85) diff --git a/src/misc.asm b/src/misc.asm index b3425beb..0a1d70f9 100644 --- a/src/misc.asm +++ b/src/misc.asm @@ -947,6 +947,17 @@ set_fade_in_door_function: JML $908E0F } +misc_force_stand_routine: +{ + ; Similar to $90:E2D4 routine, except use facing forward pose + PHP : PHB : PHK : PLB + LDA !SAMUS_ITEMS_EQUIPPED : AND #$0021 : BEQ .pose_chosen + LDA #$009B + .pose_chosen + JSR $E2F4 + PLB : PLP : RTL +} + %endfree(90) From ee7d33707e83ab89dd52a98d25f660a3c433b466 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sat, 28 Jun 2025 08:17:54 -0500 Subject: [PATCH 33/43] Run shortcut routine during door transition and fanfare --- src/fanfare.asm | 33 +++++++++++++++++++++++++++------ src/gamemode.asm | 36 ++++++++++++++++++++++-------------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/fanfare.asm b/src/fanfare.asm index 812257ff..a0861688 100644 --- a/src/fanfare.asm +++ b/src/fanfare.asm @@ -295,12 +295,33 @@ if !FEATURE_SD2SNES LDA $4212 : BIT #$01 : BNE .wait_joypad %a16() - ; TODO re-enable load state, or maybe run the whole shortcut routine from here? - ; LDA $4218 : BEQ .done - ; CMP !sram_ctrl_load_state : BNE .done - ; LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .done - ; PHB : PHK : PLB - ; JML load_state + ; Check if any input present + LDA $4218 : ORA $421A : BEQ .done + + ; We need to run the controller shortcut routine, but we can't save here + ; Set game mode to invalid value to signify we should not save + LDA !GAMEMODE : PHA + LDA #$0003 : STA !GAMEMODE + ; We need to update the controller input variables, so remember the original values + LDA !IH_CONTROLLER_PRI : PHA + LDA !IH_CONTROLLER_PRI_NEW : PHA + LDA !IH_CONTROLLER_SEC : PHA + LDA !IH_CONTROLLER_SEC_NEW : PHA + + LDA $4218 : STA !IH_CONTROLLER_PRI : STA !IH_CONTROLLER_PRI_NEW + LDA $421A : STA !IH_CONTROLLER_SEC : STA !IH_CONTROLLER_SEC_NEW + + ; Set overflow and carry flags before calling routine + PHP : SEP #$41 + JSL !CTRL_SHORTCUT_ROUTINE + PLP + + ; Restore controller inputs and gamemode + PLA : STA !IH_CONTROLLER_SEC_NEW + PLA : STA !IH_CONTROLLER_SEC + PLA : STA !IH_CONTROLLER_PRI_NEW + PLA : STA !IH_CONTROLLER_PRI + PLA : STA !GAMEMODE .done endif diff --git a/src/gamemode.asm b/src/gamemode.asm index 6c788382..9a5f1b3e 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -28,13 +28,18 @@ if !FEATURE_SD2SNES gamemode_door_transition: { .checkloadstate - ; TODO re-enable load state, or maybe run the whole shortcut routine from here? - ; LDA !IH_CONTROLLER_PRI : BEQ .checktransition - ; CMP !sram_ctrl_load_state : BNE .checktransition - ; check if a saved state exists - ; LDA !SRAM_SAVED_STATE : CMP !SAFEWORD : BNE .checktransition - ; PHB : PHK : PLB - ; JML load_state + ; We need to run the controller shortcut routine, but we can't save here + ; Set game mode to invalid value to signify we should not save + LDA !GAMEMODE : PHA + LDA #$0003 : STA !GAMEMODE + + ; Set overflow and carry flags before calling routine + PHP : SEP #$41 + JSL !CTRL_SHORTCUT_ROUTINE + PLP + + ; Restore gamemode + PLA : STA !GAMEMODE .checktransition ; check if door is done scrolling @@ -166,6 +171,9 @@ gamemode_start: gamemode_main_menu: { + ; Check if main menu not allowed + LDA !GAMEMODE : CMP #$0003 : BEQ gamemode_placeholder + ; Check for paused states LDA !ram_slowdown_mode : BPL .openMainMenu CMP !SLOWDOWN_PAUSED_MAIN_MENU : BNE .paused @@ -203,16 +211,14 @@ gamemode_placeholder: if !FEATURE_SD2SNES gamemode_save_state: { + ; Check if save not allowed + LDA !GAMEMODE : CMP #$0003 : BEQ .done if !FEATURE_TINYSTATES ; Disallow tiny states outside of gameplay ; Most other gamemodes will crash on load - LDA !GAMEMODE : CMP #$0020 : BEQ .save ; end of Ceres allowed - CMP #$0007 : BMI .not_allowed - CMP #$001C : BMI .save - - .not_allowed - RTL - + CMP #$0020 : BEQ .save + CMP #$0007 : BMI .done + CMP #$001C : BPL .done .save endif PHP @@ -223,6 +229,8 @@ endif ; Skip remaining shortcuts PLA : PEA !CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE + + .done RTL } From 7f85cef51bf115cd620aa2ed6cfe1a46c73aed6d Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Fri, 4 Jul 2025 17:01:14 -0500 Subject: [PATCH 34/43] Add four past values to shot timer infohud mode --- src/defines.asm | 6 ++++++ src/gamemode.asm | 2 +- src/infohud.asm | 3 ++- src/infohudmodes.asm | 23 +++++++++++++++++++++++ src/main.asm | 2 +- src/mainmenu.asm | 10 +++++++--- src/ramwatchmenu.asm | 2 +- src/symbols.asm | 6 ++++++ 8 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index 35c4eb54..fcdb72cb 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -121,6 +121,12 @@ !ram_fail_sum = !WRAM_START+$7C !ram_fail_count = !WRAM_START+$7E +; Shot timer also reuses values +!ram_shot_timer_past1 = !WRAM_START+$78 +!ram_shot_timer_past2 = !WRAM_START+$7A +!ram_shot_timer_past3 = !WRAM_START+$7C +!ram_shot_timer_past4 = !WRAM_START+$7E + ; Kihunter manip !ram_enemy0_last_xpos = !WRAM_START+$6E !ram_enemy0_last_ypos = !WRAM_START+$70 diff --git a/src/gamemode.asm b/src/gamemode.asm index 9a5f1b3e..16d4b56b 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -1601,7 +1601,7 @@ CtrlShortcutMenu: dw #ctrlshortcut_reset_defaults dw #$0000 %cm_header("CONTROLLER SHORTCUTS") - %cm_footer_ctrlshortcut("PRESS AND HOLD FOR 2 SEC", "TOGGLES EXACT MATCH") + %cm_footer_ctrlshortcut("PRESS AND HOLD FOR ONE SEC", "TOGGLES EXACT MATCH") CtrlShortcutMenu2: dw #ctrlshortcut_16 diff --git a/src/infohud.asm b/src/infohud.asm index 7dc71dfe..a17c14db 100644 --- a/src/infohud.asm +++ b/src/infohud.asm @@ -1701,7 +1701,8 @@ ih_update_status: { TDC STA !ram_momentum_sum : STA !ram_momentum_count - STA !ram_HUD_check + STA !ram_HUD_check : STA !ram_shot_timer + STA !ram_quickdrop_counter : STA !ram_walljump_counter STA !ram_roomstrat_counter : STA !ram_roomstrat_state STA !ram_armed_shine_duration STA !ram_fail_count : STA !ram_fail_sum diff --git a/src/infohudmodes.asm b/src/infohudmodes.asm index 67a6f634..770b6bdd 100644 --- a/src/infohudmodes.asm +++ b/src/infohudmodes.asm @@ -1420,7 +1420,25 @@ status_ypos: status_shottimer: { LDA !IH_CONTROLLER_PRI_NEW : AND !IH_INPUT_SHOT : BEQ .incShot + LDA !IH_BLANK : STA !HUD_TILEMAP+$AE + STA !HUD_TILEMAP+$B2 : STA !HUD_TILEMAP+$B6 + STA !HUD_TILEMAP+$BA : STA !HUD_TILEMAP+$BE + LDA !ram_shot_timer_past4 : BEQ .initPast + .doneInitPast + STA !HUD_TILEMAP+$BC + LDA !ram_shot_timer_past3 : STA !HUD_TILEMAP+$B8 : STA !ram_shot_timer_past4 + LDA !ram_shot_timer_past2 : STA !HUD_TILEMAP+$B4 : STA !ram_shot_timer_past3 + LDA !ram_shot_timer_past1 : STA !HUD_TILEMAP+$B0 : STA !ram_shot_timer_past2 LDA !ram_shot_timer : LDX #$0088 : JSR Draw4 + LDA !ram_shot_timer : CMP #$0042 : BPL .setX + ASL : TAX : LDA NumberGFXTable,X + BRA .setPast1 + + .setX + LDA !IH_LETTER_X + + .setPast1 + STA !ram_shot_timer_past1 TDC : STA !ram_shot_timer .incShot @@ -1428,6 +1446,11 @@ status_shottimer: LDA !ROOM_ID : CMP.w #ROOM_PhantoonRoom : BEQ .phantoon RTS + .initPast + LDA !IH_BLANK : STA !ram_shot_timer_past4 : STA !ram_shot_timer_past3 + STA !ram_shot_timer_past2 : STA !ram_shot_timer_past1 + BRA .doneInitPast + .phantoonCheckInit LDA !ENEMY_VAR_5 if !FEATURE_PAL diff --git a/src/main.asm b/src/main.asm index 259238cf..dd276b39 100644 --- a/src/main.asm +++ b/src/main.asm @@ -16,7 +16,7 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 6 !VERSION_BUILD = 7 -!VERSION_REV = 12 +!VERSION_REV = 13 table ../resources/normal.tbl print "" diff --git a/src/mainmenu.asm b/src/mainmenu.asm index fd2e86c4..d6ce9ea4 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -1711,6 +1711,7 @@ ihmode_ypos: %cm_jsl("Y Position", #action_select_infohud_mode, #$0014) ihmode_shottimer: +!IH_MODE_SHOTTIMER_INDEX = #$0015 %cm_jsl("Shot Timer", #action_select_infohud_mode, #$0015) ihmode_ramwatch: @@ -2121,10 +2122,11 @@ ih_superhud_ypos: %cm_jsl("Y Position", #action_select_superhud_bottom, #$0013) ih_superhud_shottimer: +!IH_SUPERHUD_SHOTTIMER_BOTTOM_INDEX = #$0014 %cm_jsl("Shot Timer", #action_select_superhud_bottom, #$0014) ih_superhud_ramwatch: -!IH_SUPERHUD_RAMATCH_BOTTOM_INDEX = #$0015 +!IH_SUPERHUD_RAMWATCH_BOTTOM_INDEX = #$0015 %cm_jsl("Custom RAM Watch", #action_select_superhud_bottom, #$0015) ih_superhud_ceresridley: @@ -3744,10 +3746,11 @@ if !FEATURE_VANILLAHUD else if !INFOHUD_ALWAYS_SHOW_X_Y else - ; Skip printing segment timer when shinetune or walljump enabled + ; Skip printing segment timer when shinetune or walljump or shot timer enabled LDA !sram_display_mode : CMP !IH_MODE_ROOMSTRAT_INDEX : BEQ .checkSuperHUD CMP !IH_MODE_SHINETUNE_INDEX : BEQ .skip CMP !IH_MODE_WALLJUMP_INDEX : BEQ .skip + CMP !IH_MODE_SHOTTIMER_INDEX : BEQ .skip .print LDA #$0001 : STA !ram_print_segment_timer RTL @@ -3755,7 +3758,8 @@ else .checkSuperHUD LDA !sram_room_strat : BNE .print LDA !sram_superhud_bottom : CMP !IH_SUPERHUD_SHINETUNE_BOTTOM_INDEX : BEQ .skip - CMP !IH_SUPERHUD_WALLJUMP_BOTTOM_INDEX : BNE .print + CMP !IH_SUPERHUD_WALLJUMP_BOTTOM_INDEX : BEQ .skip + CMP !IH_SUPERHUD_SHOTTIMER_BOTTOM_INDEX : BNE .print .skip endif diff --git a/src/ramwatchmenu.asm b/src/ramwatchmenu.asm index eea43d2b..2253c8f8 100644 --- a/src/ramwatchmenu.asm +++ b/src/ramwatchmenu.asm @@ -634,7 +634,7 @@ action_HUD_ramwatch: JML init_print_segment_timer .superHUD - LDA !IH_SUPERHUD_RAMATCH_BOTTOM_INDEX : STA !sram_superhud_bottom + LDA !IH_SUPERHUD_RAMWATCH_BOTTOM_INDEX : STA !sram_superhud_bottom %sfxconfirm() JML init_print_segment_timer } diff --git a/src/symbols.asm b/src/symbols.asm index 400f67fb..7dc7ed4b 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -104,6 +104,12 @@ ram_walljump_counter = !ram_walljump_counter ; !WRAM_START+$7A ram_fail_sum = !ram_fail_sum ; !WRAM_START+$7C ram_fail_count = !ram_fail_count ; !WRAM_START+$7E +; Shot timer also reuses values +ram_shot_timer_past1 = !ram_shot_timer_past1 ; !WRAM_START+$78 +ram_shot_timer_past2 = !ram_shot_timer_past2 ; !WRAM_START+$7A +ram_shot_timer_past3 = !ram_shot_timer_past3 ; !WRAM_START+$7C +ram_shot_timer_past4 = !ram_shot_timer_past4 ; !WRAM_START+$7E + ; Kihunter manip ram_enemy0_last_xpos = !ram_enemy0_last_xpos ; !WRAM_START+$6E ram_enemy0_last_ypos = !ram_enemy0_last_ypos ; !WRAM_START+$70 From 7110a57198fbb8744917f0781d330ab352c94ff7 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Fri, 4 Jul 2025 20:03:17 -0500 Subject: [PATCH 35/43] Fix skip gameover load preset scenario --- src/cutscenes.asm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cutscenes.asm b/src/cutscenes.asm index af5fd562..b464e631 100644 --- a/src/cutscenes.asm +++ b/src/cutscenes.asm @@ -253,6 +253,7 @@ endif .no_savestate ; reload last preset if it exists LDA !sram_last_preset : BEQ .save_file : STA !ram_load_preset + JSL preset_load BRA .skip_gameplay .save_file From 9050194b1c3a5d91a6a84515f7d5b56b0bf436d7 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sat, 5 Jul 2025 21:39:40 -0500 Subject: [PATCH 36/43] Use maprando baby cutscene with door portals --- src/defines.asm | 10 ++++ src/enemy_rng.asm | 132 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 136 insertions(+), 6 deletions(-) diff --git a/src/defines.asm b/src/defines.asm index fcdb72cb..3cb45d03 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -1040,6 +1040,16 @@ !eram_botwoon_spit_rng = !ENEMY_VAR_4+!ENEMY_1F_OFFSET !eram_botwoon_after_spit_rng = !ENEMY_VAR_5+!ENEMY_1F_OFFSET +!eram_baby_leaving_left = !ENEMY_VAR_2+!ENEMY_1E_OFFSET +!eram_baby_leaving_right = !ENEMY_VAR_3+!ENEMY_1E_OFFSET +!eram_baby_backing_off = !ENEMY_VAR_4+!ENEMY_1E_OFFSET +!eram_baby_rising_delay = !ENEMY_VAR_5+!ENEMY_1E_OFFSET +!eram_baby_after_drain_delay = !ENEMY_VAR_1+!ENEMY_1F_OFFSET +!eram_baby_target_x_pos = !ENEMY_VAR_2+!ENEMY_1F_OFFSET +!eram_baby_dead_hop_delay = !ENEMY_VAR_3+!ENEMY_1F_OFFSET +!eram_baby_hop_velocity_tables = !ENEMY_VAR_4+!ENEMY_1F_OFFSET +!eram_baby_initial_delay = !ENEMY_VAR_5+!ENEMY_1F_OFFSET + !HUD_TILEMAP = $7EC600 !MAP_COUNTER = $7ECAE8 ; Not used in vanilla !SCROLLS = $7ECD20 diff --git a/src/enemy_rng.asm b/src/enemy_rng.asm index cb82e415..bab75d4d 100644 --- a/src/enemy_rng.asm +++ b/src/enemy_rng.asm @@ -335,10 +335,61 @@ endif JSR hook_kraid_claw_rng +; ------------------- +; Mother Brain hijack +; ------------------- + +if !FEATURE_PAL +org $A9874A +else +org $A9873A +endif + JML hook_mb_init_rng + + ; ----------- ; Baby hijack ; ----------- +if !FEATURE_PAL +org $A9D963 +else +org $A9D916 +endif + LDA !eram_baby_dead_hop_delay + +if !FEATURE_PAL +org $A9D98E +else +org $A9D941 +endif + CLC : ADC !eram_baby_hop_velocity_tables : TAY + LDA $0000,Y : STA $7E7816,X + LDA $0008,Y : STA $7E7814,X + RTS +%warnpc($A9D961, $A9D9AE) + +if !FEATURE_PAL +org $A9F002 +else +org $A9EFB5 +endif + JML hook_baby_init + +if !FEATURE_PAL +org $A9F07E +else +org $A9F031 +endif + LDA !eram_baby_initial_delay + +if !FEATURE_PAL +org $A9F096 +else +org $A9F049 +endif + LDA !eram_baby_target_x_pos + if !FEATURE_PAL org $A9F21B else ; Baby skip rng @@ -346,17 +397,40 @@ org $A9F1CE endif JMP hook_baby_skip_rng +if !FEATURE_PAL +org $A9F2F5 +else +org $A9F2A8 +endif + LDA !eram_baby_after_drain_delay -; ------------------- -; Mother Brain hijack -; ------------------- +if !FEATURE_PAL +org $A9F307 +else +org $A9F2BA +endif + LDA !eram_baby_rising_delay if !FEATURE_PAL -org $A9874A +org $A9F333 else -org $A9873A +org $A9F2E6 endif - JML hook_mb_init_rng + LDA !eram_baby_backing_off + +if !FEATURE_PAL +org $A9F36B +else +org $A9F31E +endif + LDA !eram_baby_leaving_left + +if !FEATURE_PAL +org $A9F397 +else +org $A9F34A +endif + LDA !eram_baby_leaving_right ; ----------------- @@ -1857,6 +1931,14 @@ else endif } +baby_vanilla_hop_initial_velocities: + dw #$FE00, #$FE00, #$FE00, #$FC00 + dw #$01C0, #$0120, #$0120, #$0300 + +baby_maprando_hop_initial_velocities: + dw #$FE00, #$FE00, #$FC00, #$FE00 + dw #$0120, #$0250, #$0300, #$01C0 + mb_ground_attack_max_rings_rng_table: db #$00, #$FF, #$FF @@ -1968,5 +2050,43 @@ hook_mb_init_rng: RTL } +hook_baby_init: +{ +if !FEATURE_PAL + JSL $A9D343 +else ; Overridden logic + JSL $A9D2F6 +endif + + LDA !ram_door_portal_flags : AND !DOOR_PORTAL_MODE_MASK + CMP #$0002 : BNE .vanilla + LDA !ram_door_source : ASL : TAX + LDA portals_left_vanilla_table,X : CMP #$AA38 : BNE .vanilla + + ; Use maprando values + LDA #$0001 : STA !eram_baby_dead_hop_delay + LDA #baby_maprando_hop_initial_velocities : STA !eram_baby_hop_velocity_tables + LDA #$002C : STA !eram_baby_initial_delay + LDA #$01B0 : STA !eram_baby_target_x_pos + LDA #$0020 : STA !eram_baby_after_drain_delay + LDA #$0030 : STA !eram_baby_rising_delay + LDA #$0016 : STA !eram_baby_backing_off + STA !eram_baby_leaving_left + STA !eram_baby_leaving_right + RTL + + .vanilla + LDA #$0040 : STA !eram_baby_dead_hop_delay + LDA #baby_vanilla_hop_initial_velocities : STA !eram_baby_hop_velocity_tables + LDA #$01D0 : STA !eram_baby_initial_delay + LDA #$0248 : STA !eram_baby_target_x_pos + LDA #$0078 : STA !eram_baby_after_drain_delay + LDA #$00C0 : STA !eram_baby_rising_delay + LDA #$0058 : STA !eram_baby_backing_off + STA !eram_baby_leaving_left + LDA #$0100 : STA !eram_baby_leaving_right + RTL +} + %endfree(AA) From 52a71fe235edb6818e7f6d8acaf11fc5e9569f7a Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sat, 5 Jul 2025 21:40:06 -0500 Subject: [PATCH 37/43] Verify horizontal mirroring before flipping Samus in a door portal --- src/layout.asm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/layout.asm b/src/layout.asm index 5be0cbfa..c4f50258 100644 --- a/src/layout.asm +++ b/src/layout.asm @@ -284,11 +284,13 @@ hijack_after_load_level_data: ; Swap to left side of room if necessary LDA !SAMUS_X : BIT #$0080 : BEQ .checkRoom + LDA !ram_door_portal_flags : BIT !DOOR_PORTAL_HORIZONTAL_MIRRORING_BIT : BEQ .checkRoom JSL layout_swap_left_right BRA .checkRoom .checkSwapToRight LDA !SAMUS_X : BIT #$0080 : BNE .checkRoom + LDA !ram_door_portal_flags : BIT !DOOR_PORTAL_HORIZONTAL_MIRRORING_BIT : BEQ .checkRoom JSL layout_swap_left_right .checkRoom From 5bd364e437ab8b508b10f1bd8373702c4d02d6cf Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sat, 5 Jul 2025 21:40:56 -0500 Subject: [PATCH 38/43] Prepare for 2.7.0 release --- src/main.asm | 6 +++--- web/data/config.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.asm b/src/main.asm index dd276b39..f395dab0 100644 --- a/src/main.asm +++ b/src/main.asm @@ -14,9 +14,9 @@ lorom !RAW_TILE_GRAPHICS ?= 1 !VERSION_MAJOR = 2 -!VERSION_MINOR = 6 -!VERSION_BUILD = 7 -!VERSION_REV = 13 +!VERSION_MINOR = 7 +!VERSION_BUILD = 0 +!VERSION_REV = 0 table ../resources/normal.tbl print "" diff --git a/web/data/config.json b/web/data/config.json index 4a1945b8..34fb9cc3 100644 --- a/web/data/config.json +++ b/web/data/config.json @@ -1,6 +1,6 @@ { "name": "Super Metroid Practice Hack", - "version": "2.6.7.1", + "version": "2.7.0", "variants": ["NTSC", "PAL"], "base": { "NTSC": { From 0a1fbf1bb54981efd1fcfc06bee2d3ba07d2b11d Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 6 Jul 2025 08:22:03 -0500 Subject: [PATCH 39/43] Remove spore spawn camera scroll lock from top door in map rando --- src/defines.asm | 1 + src/enemy_rng.asm | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/defines.asm b/src/defines.asm index 3cb45d03..11600207 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -761,6 +761,7 @@ !ENEMY_POPULATION = $07CF !ENEMY_SET = $07D1 !ROOM_MAIN_ASM_POINTER = $07DF +!SCROLLING_FINISHED_HOOK = $07E9 !CERES_HDMA_DATA = $07EB !MUSIC_DATA = $07F3 !MUSIC_TRACK = $07F5 diff --git a/src/enemy_rng.asm b/src/enemy_rng.asm index bab75d4d..ca940eb9 100644 --- a/src/enemy_rng.asm +++ b/src/enemy_rng.asm @@ -261,6 +261,17 @@ endif JSR hook_draygon_damage +; ------------------ +; Spore Spawn hijack +; ------------------ +if !FEATURE_PAL +org $A5EADC +else +org $A5EAD7 +endif + JSR hook_spore_spawn_scroll + + ; ---------------- ; Crocomire hijack ; ---------------- @@ -1192,6 +1203,24 @@ endif RTS } +hook_spore_spawn_scroll: +{ + LDA !ram_door_portal_flags : AND !DOOR_PORTAL_MODE_MASK + CMP #$0002 : BNE .vanilla + LDA !ram_door_source : ASL : TAX + LDA portals_left_vanilla_table,X : CMP #$8E4A : BNE .vanilla + + ; In map rando when top door selected, + ; do not use a scroll hook for spore spawn + TDC + RTS + + .vanilla + ; Overwritten scrolling finished hook + LDA #$9589 + RTS +} + ; Migrated from bank A6 since not enough freespace there init_ceres_ridley_rng: { From 365340a78381b6fddbbebdd526f5f00dc959c545 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 6 Jul 2025 08:22:58 -0500 Subject: [PATCH 40/43] Remove crocomire red scrolls from left door in map rando --- src/enemy_rng.asm | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/enemy_rng.asm b/src/enemy_rng.asm index ca940eb9..67418a84 100644 --- a/src/enemy_rng.asm +++ b/src/enemy_rng.asm @@ -283,6 +283,13 @@ org $A48753 endif JSR hook_crocomire_rng +if !FEATURE_PAL +org $A48A9F +else +org $A48A8F +endif + JSR hook_crocomire_scroll + if !FEATURE_PAL org $A48CED else @@ -902,6 +909,23 @@ hook_crocomire_rng: RTS } +hook_crocomire_scroll: +{ + LDA !ram_door_portal_flags : AND !DOOR_PORTAL_MODE_MASK + CMP #$0002 : BNE .vanilla + LDA !ram_door_destination : ASL : TAX + LDA portals_right_vanilla_table,X : CMP #$93DE : BNE .vanilla + + ; In map rando when right door selected, + ; do not set red scrolls + LDA $7ECD20 + RTS + + .vanilla + TDC + RTS +} + hook_crocomire_damage: { LDA !sram_suppress_flashing : BIT !SUPPRESS_BOSS_DAMAGE_FLASH : BNE .suppress From f6740ea0214dd0ab58cb24213a08220954ee5fca Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 6 Jul 2025 12:57:26 -0500 Subject: [PATCH 41/43] Fix issue where sram initialized before validation flag set --- src/init.asm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/init.asm b/src/init.asm index d66f6bd5..b9eb672d 100644 --- a/src/init.asm +++ b/src/init.asm @@ -37,6 +37,7 @@ init_code: ; Initialize RAM (Bank 7E required) TDC : STA !ram_slowdown_mode + JSL validate_sram ; Check if we should initialize SRAM LDA !sram_initialized : CMP !SRAM_VERSION : BEQ .sram_initialized From e44f65ebbfd646e8e52218e4271ae578211e672c Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 6 Jul 2025 14:09:38 -0500 Subject: [PATCH 42/43] Fix Samus 32x32 grid projectiles --- src/spritefeat.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/spritefeat.asm b/src/spritefeat.asm index 8d908c63..c6673c9b 100644 --- a/src/spritefeat.asm +++ b/src/spritefeat.asm @@ -773,8 +773,8 @@ draw_samusproj_hitbox: JMP .skipProjectile .check32x32 - ; skip bombs ($0500), bomb explosions ($0501) and power bombs ($0300) - LDA !SAMUS_PROJ_PROPERTIES,X : BIT #$0701 : BNE .skip32x32 + ; Only show beams, missiles, and super missiles + LDA !SAMUS_PROJ_PROPERTIES,X : AND #$0F00 : CMP #$0300 : BPL .skip32x32 LDA !SAMUS_PROJ_X,X : CMP !LAYER1_X : BMI .skip32x32 LDA !LAYER1_X : CLC : ADC #$0100 : CMP !SAMUS_PROJ_X,X : BMI .skip32x32 From 132b2883ea53129244646215e2bf0c2a807819b4 Mon Sep 17 00:00:00 2001 From: idle <idlechild123@gmail.com> Date: Sun, 6 Jul 2025 15:15:53 -0500 Subject: [PATCH 43/43] Release 2.7.0 --- web/data/changelog.mdx | 9 +++++++++ web/data/help.mdx | 39 ++++++++++++++++++++++++++------------- web/data/infohudmode.mdx | 1 + 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/web/data/changelog.mdx b/web/data/changelog.mdx index 96f6c912..a707afcf 100644 --- a/web/data/changelog.mdx +++ b/web/data/changelog.mdx @@ -1,3 +1,12 @@ +# Version 2.7.x +- Controller shortcuts customizable, and menu works with second controller (2.7.0) +- SuperHUD has more options and better integration with other options (2.7.0) +- Ridley and Mother Brain RNG control added, and option to override Drop Chances (2.7.0) +- Practice hack detects and warns when platform incompatible with SRAM (2.7.0) +- Spore Spawn, Crocomire, and Baby cutscene more like map rando when using door portals (2.7.0) +- Shot timer now displays the previous four values in place of the segment timer (2.7.0) +- Various fixes and updates to presets and slowdown mode (2.7.0) + # Version 2.6.x - Optimize kraid rock projectiles to reduce lag when Kraid rises (2.6.0) - Use enemy ID to determine which enemies are cleared on preset load (2.6.0) diff --git a/web/data/help.mdx b/web/data/help.mdx index c1480a0d..50151ec0 100644 --- a/web/data/help.mdx +++ b/web/data/help.mdx @@ -120,10 +120,10 @@ If you experience crashes or severe glitches when using savestates, your platfor | **InfoHUD** | Configure the HUD | - Infohud Mode | Select the value from RAM to be displayed in the bottom-left of the HUD. | | [Click the link for more details.](/infohudmode) -| - Strat Reward SFX | Toggle a sound effect that plays when achieving certain HUD mode and room strats. | - Room Strat | Select which Room Strat to be displayed in the bottom-left of the HUD. | | This only works if "Room Strat" is selected as the above Infohud Mode. | - Configure Super HUD | Options to replace the item% and status icons and reserves area with other infohud modes, while still having a primary infohud mode or room strat. Compatible with most but not all other infohud modes and room strats. +| - Strat Reward SFX | Toggle a sound effect that plays when achieving certain HUD mode and room strats. | - Door HUD Mode | Configure the HUD mode that runs when touching a door transition. | | Only works when the normal HUD mode is set to Enemy HP. | - Minimap | Restores the game minimap, which also allows the pause menu map to be updated. When enabled, a map tile counter will also be displayed. @@ -212,18 +212,20 @@ If you experience crashes or severe glitches when using savestates, your platfor | | - Phan Flame Pattern: Choose one of four patterns for Phantoon's flames | | - Next Flame Pattern: Swaps with Phan Flame Pattern each time Phantoon chooses a pattern | | - Always Visible: Allows you to see how Phantoon moves after despawning and before raining down flames -| - Botwoon First | Choose the movement pattern for Botwoon's first cycle. The pattern names represent the hole Botwoon will the cycle at. -| - Botwoon Hidden | Choose the movement pattern for Botwoon's hidden cycle behind the background. Each pair of letters respresets the start and end position of the pattern. -| - Botwoon Second | Choose the movement pattern for Botwoon's second and subsequent cycles. Each pair of letters respresets the start and end position of the pattern. -| - Botwoon Spit | Choose whether Botwoon will spit projectiles or not, when possible -| - Draygon from Right | Choose Draygon's attack type from the right side of the room. Draygon will always 'swoop' after a 'goop'. -| - Draygon from Left | Choose Draygon's attack type from the left side of the room. Draygon will always 'swoop' after a 'goop'. -| - Draygon Turret | Choose which turret or turrets are allowed to fire, which may cause more or fewer projectiles to be fired depending on the setting and which turrets are destroyed. -| - Crocomire RNG | Set Crocomire to always step forward, or always swipe and shoot projectiles. +| - Ridley | Configure certain aspects of Ridley's behavior +| - Botwoon | Choose movemen patterns fro Botwoon's first cycle, hidden cycles, and second/subsequent cycles. +| | Each pair of letters respresets the start and end position of the pattern. +| - Mother Brain | Configure certain aspects of Mother Brain's behavior | - Kraid Claw RNG | Set Kraid's claws to spawn above or below. Kraid is laggier when coming out of the ground if both claws spawn below. | | **Note**: It is not possible for both claws to spawn above Kraid, so there will always be some lag generated by a claw below. | - Kraid Wait RNG | Set amount of frames Kraid waits before opening mouth at start of second phase, or between attacks during the first phase. +| - Crocomire RNG | Set Crocomire to always step forward, or always swipe and shoot projectiles. +| - Draygon from Right | Choose Draygon's attack type from the right side of the room. Draygon will always 'swoop' after a 'goop'. +| - Draygon from Left | Choose Draygon's attack type from the left side of the room. Draygon will always 'swoop' after a 'goop'. +| - Draygon Turret | Choose which turret or turrets are allowed to fire, which may cause more or fewer projectiles to be fired depending on the setting and which turrets are destroyed. | - Baby Skip RNG | Set the baby into a lunge state or force it to not lunge. +| - All Drops | Override the vanilla drop chance tables with one of six possible drops. +| | This can produce non-vanilla behavior, including enemies spawning drops that normally do not. | | | **Savestate Settings** | Features relating to the practice hack's built-in savestates. Not available on some platforms. | - Rerandomize | Toggles rerandomizing of RNG values upon loading a savestate. Automatically disabled in rooms with "seeded" RNG, but some of these situations may not be accounted for yet. @@ -235,8 +237,10 @@ If you experience crashes or severe glitches when using savestates, your platfor | | | **Slowdown Mode** | Set if practice hack is in slowdown mode and the number of lag frames it is set for. | | -| **Controller Shortcuts** | Set or change button combinations for activating features. Press X to unbind a shortcut. Press A to edit the shortcut and then hold the desired button combination until it turns pink. -| - Main Menu | Open the InfoHUD menu +| **Controller Shortcuts** | Set or change button combinations for activating features. Shortcuts may appear multiple times allowing different button combinations to trigger the same action. +| - Add Shortcut | Allows a new shortcut to be set. This option might be found on page 2 or 3 if prior pages are full. +| - Main Menu | Open the practice hack menu. +| - Soft Reset | Performs the soft reset (previously hard-coded Start+Select+L+R, but can now be modified). | - Save State | Sets the savestate. Not available on some platforms. | - Load State | Loads the savestate. Not available on some platforms. | - Auto Save State | Sets a flag to trigger a savestate in the middle of the next door transition. Not available on some platforms. @@ -255,8 +259,17 @@ If you experience crashes or severe glitches when using savestates, your platfor | - Toggle Boss Dmg | Toggle the damage counter infohud mode to be shown or hidden. | - Update Timers | Updates the HUD timers immediately. | - Force Stand | Force Samus into a standing position. -| - Toggle Spin Lock | Toggles Spin Lock. -| - Clear Shortcuts | Resets Main Menu shortcut to default and removes button combos for all others. +| - Toggle Spin Lock | Toggles the map rando Spin Lock feature. +| - Pause | Freeze gameplay. Can be used for frame advance by triggering pause while already paused. +| - Unpause | Unfreeze gameplay. +| - Slowdown | Adds lag frames per normal frame of gameplay. +| - Speedup | Removes slowdown frames. Cannot be used to run the gameplay at faster than 100%. +| - Next Status Mode | Increments the current InfoHUD mode. +| - Prev Status Mode | Decrements the current InfoHUD mode. +| - Next Room Strat | Increments the current Room Strat. +| - Prev Room Strat | Decrements the current Room Strat. +| - Next Super HUD | Increments the current SuperHUD bottom mode. +| - Prev Super HUD | Decrements the current SuperHUD bottom mode. | - Reset to Defaults | Resets controller shortcuts to their original defaults. | | | **Audio Menu** | Audio related settings and sound test menu. diff --git a/web/data/infohudmode.mdx b/web/data/infohudmode.mdx index 5655a544..9c259207 100644 --- a/web/data/infohudmode.mdx +++ b/web/data/infohudmode.mdx @@ -152,6 +152,7 @@ Displays the Y position in hexadecimal pixels. Also Samus HP is replaced by the ## Shot Timer Displays the number of frames between pressing the shoot button. +Also the segment timer is overwritten by a set of four numbers representing the previous four shot timer values.   Additionally if fighting Phantoon, the number of frames can be replaced by feedback on hitting Phantoon with a super missile on the magic frame that does not enrage Phantoon. Feedback is only given if Phantoon is hit with a super missile relatively near the time of eye open and when the super missile does not kill Phantoon.