From 632b5f606df103dd7abea0fe17ea79b25c7deacb Mon Sep 17 00:00:00 2001 From: idle Date: Sun, 9 Mar 2025 15:55:42 -0500 Subject: [PATCH 1/6] Port remaining features from IFB practice hack --- TODO.txt | 16 +- layout/layoutmenutemplate.asm | 9 +- src/BRBmenu.asm | 2 +- src/crash.asm | 6 +- src/cropmenu.asm | 174 +++++++++++++++ src/customizemenu.asm | 112 +++++++++- src/damage.asm | 33 +-- src/defines.asm | 39 +++- src/demos.asm | 18 -- src/enemy_rng.asm | 131 ++++++++++++ src/flagmenu.asm | 34 +-- src/freespace.asm | 3 +- src/gamemenu.asm | 32 ++- src/gamemode.asm | 65 +++++- src/infohud.asm | 31 +-- src/infohudmodes.asm | 218 ++++++++++--------- src/init.asm | 25 ++- src/layout.asm | 2 +- src/layoutmenu.asm | 9 +- src/main.asm | 7 +- src/mainmenu.asm | 216 ++++++++++++++----- src/menu.asm | 19 +- src/misc.asm | 383 ++++++++++++++++++++++++++++++++++ src/presets.asm | 5 + src/ramwatchmenu.asm | 4 +- src/save.asm | 9 +- src/symbols.asm | 19 +- src/tinystates.asm | 9 +- 28 files changed, 1340 insertions(+), 290 deletions(-) create mode 100644 src/cropmenu.asm diff --git a/TODO.txt b/TODO.txt index 58103be3..6b1b11a3 100644 --- a/TODO.txt +++ b/TODO.txt @@ -5,7 +5,7 @@ For other TODO items, recommend using the github issue system ================================================================ ================================================================ -Features that have not been ported yet +Features that are being ported now ================================================================ - Capture Cropping @@ -24,6 +24,8 @@ Features that have not been ported yet - Phantoon always visible +- Random bubble SFX + - Randomize on load - Randomize RNG shortcut @@ -39,7 +41,7 @@ and there isn't much benefit in porting or backporting them - Resources folder structure and unusued resources -- Order of included sources +- Order of included sources and bank freespace locations - Structure of defines.asm and main.asm (and separating printdebug.asm from main.asm) @@ -47,9 +49,15 @@ and there isn't much benefit in porting or backporting them - Various sound effect macros -- Walk Through Walls option +- 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 -- Leading > or arrow on menu items, or menuing differences in general +- Differences in how menu options can be scrolled through - AREA_ID stored in custom presets diff --git a/layout/layoutmenutemplate.asm b/layout/layoutmenutemplate.asm index 9de07540..48fc9b71 100644 --- a/layout/layoutmenutemplate.asm +++ b/layout/layoutmenutemplate.asm @@ -1,5 +1,4 @@ -pushpc %startfree(E4) ; ------------------------- @@ -9,8 +8,8 @@ pushpc LayoutMenu: dw #layout_itempickups - dw #$FFFF dw #layout_bombtorizodoor + dw #layout_steamcollision dw #layout_magnetstairs dw #layout_arearando dw #layout_antisoftlock @@ -322,8 +321,11 @@ layout_bombtorizodoor: db #$28, "r SLOW", #$FF db #$FF +layout_steamcollision: + %cm_toggle_bit("Remove Steam Collision", !sram_room_layout, !ROOM_LAYOUT_NO_STEAM_COLLISION, #0) + layout_magnetstairs: - %cm_toggle_bit("Remove Magnet Stairs", !sram_room_layout, !ROOM_LAYOUT_MAGNET_STAIRS, #0) + %cm_toggle_bit("Remove Magnet Stairs", !sram_room_layout, !ROOM_LAYOUT_NO_MAGNET_STAIRS, #0) layout_arearando: %cm_toggle_bit("Area Rando Patches", !sram_room_layout, !ROOM_LAYOUT_AREA_RANDO, #0) @@ -870,4 +872,3 @@ portals_down_vanilla_table: %endfree(E4) -pullpc diff --git a/src/BRBmenu.asm b/src/BRBmenu.asm index 124a7a7b..29ed21c2 100644 --- a/src/BRBmenu.asm +++ b/src/BRBmenu.asm @@ -76,7 +76,7 @@ brb_menu_palette_cycle: %cm_toggle_bit_inverted("Cycle Palettes", !ram_cm_brb_palette, #$FFFF, #0) brb_menu_scroll: - %cm_toggle("Screen Scrolling", !ram_cm_brb_scroll, #$0001, #0) + %cm_toggle("Screen Scrolling", !ram_cm_brb_scroll, #$01, #0) brb_menu_music_toggle: dw !ACTION_CHOICE diff --git a/src/crash.asm b/src/crash.asm index ae7e46c3..6ecbd2d1 100644 --- a/src/crash.asm +++ b/src/crash.asm @@ -7,8 +7,6 @@ ; This resource adds a crash handler to dump data to SRAM ; whenever one of these "crash vectors" is triggered -pushpc - ; Hijack generic crash handler org $808573 hook_crash_handler: @@ -185,7 +183,7 @@ COPHandler: %endfree(80) -pullpc +%startfree(89) CrashViewer: { @@ -1125,3 +1123,5 @@ CrashTextInfo11: ; Press LRSlSt to soft reset db "Press ", #$8D, #$8C, #$85, #$84, " to soft reset", #$FF +%endfree(89) + diff --git a/src/cropmenu.asm b/src/cropmenu.asm new file mode 100644 index 00000000..30032ce4 --- /dev/null +++ b/src/cropmenu.asm @@ -0,0 +1,174 @@ + +%startfree(8E) + +; ---------------- +; Capture Cropping +; ---------------- + +CaptureCroppingMenu: + dw #ccm_launch_crop_mode + dw #$FFFF + dw #ccm_crop_mode + dw #ccm_crop_tile + dw #$0000 + %cm_header("CAPTURE CROPPING MODE") + +ccm_launch_crop_mode: + %cm_jsl("Capture Crop Mode", .routine, #0) + .routine + JSL cm_crop_mode + JML refresh_cgram_long + +ccm_crop_mode: + dw !ACTION_CHOICE + dl #!ram_cm_crop_mode + dw #$0000 + db #$28, "Drawing Method", #$FF + db #$28, " BORDER", #$FF + db #$28, " FILL", #$FF + db #$FF + +ccm_crop_tile: + dw !ACTION_CHOICE + dl #!ram_cm_crop_tile + dw #$0000 + db #$28, "Cropping Tile", #$FF + db #$28, " ", #$90, #$FF + db #$28, " ", #$91, #$FF + db #$FF + +cm_crop_mode: +{ + PHP : %a16() : %i8() + + ; turn on forced blank + LDX #$80 : STX $2100 + + ; fix BG3 scroll offset + LDX #$FF : STX $2112 + LDX #$03 : STX $2112 + + TDC : STA !ram_crash_palette + + ; pattern or solid color? + LDA !ram_cm_crop_tile : BEQ .boxes + LDA #$2891 : STA $C1 + BRA .draw + + .boxes + LDA #$2890 : STA $C1 + + .draw + ; wait for lag frame + LDX !NMI_COUNTER : CPX !NMI_COUNTER : BEQ .draw + + ; draw around the border or fill the screen? + LDA !ram_cm_crop_mode : BNE .fill + JSR cm_crop_border + BRA .drawingdone + + .fill + JSR cm_crop_fill + + .drawingdone + ; turn off forced blank + LDX #$0F : STX $2100 + + .loop + ; Make sure we don't read joysticks twice in the same frame + ; wait for lag frame + LDX !NMI_COUNTER : CPX !NMI_COUNTER : BEQ .loop + LDA !FRAME_COUNTER : CMP !ram_cm_input_counter : PHP + STA !ram_cm_input_counter + PLP : BNE .inputRead + JSL $809459 ; Read controller input + + .inputRead + LDA !IH_CONTROLLER_PRI_NEW : BEQ .loop + CMP !CTRL_B : BEQ .end + CMP !CTRL_L : BEQ .decPalette + CMP !CTRL_R : BEQ .incPalette + BRA .loop + + .decPalette + LDA !ram_crash_palette : BNE .decSetPalette + LDA #$0008 + .decSetPalette + DEC : STA !ram_crash_palette + JSL crash_cgram_transfer + BRA .loop + + .incPalette + LDA !ram_crash_palette : CMP #$0007 : BMI .incSetPalette + LDA #$FFFF + .incSetPalette + INC : STA !ram_crash_palette + JSL crash_cgram_transfer + BRA .loop + + .end + ; restore BG3 scroll offset + LDA !REG_2112_BG3_Y + %ai8() + LDX #$80 : STX $2100 + STA $2112 : XBA : STA $2112 + LDX #$0F : STX $2100 + + PLP + RTL +} + +cm_crop_border: +{ + ; top + LDX #$80 : STX $2115 + LDA #$5800 : STA $2116 + LDA $C1 : LDX #$00 + .topLoop + STA $2118 + INX : CPX #$20 : BNE .topLoop + + ; bottom + LDX #$80 : STX $2115 + LDA #$5B60 : STA $2116 + LDA $C1 : LDX #$00 + .bottomLoop + STA $2118 + INX : CPX #$40 : BNE .bottomLoop + + ; left + LDX #$81 : STX $2115 + LDA #$5820 : STA $2116 + LDA $C1 : LDX #$00 + .leftLoop + STA $2118 + INX : CPX #$1D : BNE .leftLoop + + ; right + LDX #$81 : STX $2115 + LDA #$583F : STA $2116 + LDA $C1 : LDX #$00 + .rightLoop + STA $2118 + INX : CPX #$1D : BNE .rightLoop + + RTS +} + +cm_crop_fill: +{ + LDX #$80 : STX $2115 + LDA #$5800 : STA $2116 + PHP : %i16() + LDA $C1 : LDX #$0400 + + .loop + STA $2118 + DEX : BPL .loop + + PLP + RTS +} + +%endfree(8E) + diff --git a/src/customizemenu.asm b/src/customizemenu.asm index a90fe3f6..2f37193f 100644 --- a/src/customizemenu.asm +++ b/src/customizemenu.asm @@ -1,5 +1,4 @@ -pushpc %startfree(E4) ; ---------- @@ -10,6 +9,7 @@ AudioMenu: dw #audio_music_toggle dw #audio_fanfare_toggle dw #audio_health_alarm + dw #audio_bubble_sfx dw #$FFFF dw #mc_customsfx dw #$FFFF @@ -72,8 +72,23 @@ audio_health_alarm: db #$28, "m ALWAYS ON", #$FF db #$FF +audio_bubble_sfx: + dw !ACTION_CHOICE + dl #!sram_random_bubble_sfx + dw #$0000 + db #$28, "Random Bubble S", #$FF + db #$28, "FX VANILLA", #$FF + db #$28, "FX OFF", #$FF + db #$28, "FX LOW 1", #$FF + db #$28, "FX LOW 2", #$FF + db #$28, "FX LOW 3", #$FF + db #$28, "FX HIGH 1", #$FF + db #$28, "FX HIGH 2", #$FF + db #$28, "FX HIGH 3", #$FF + db #$FF + audio_goto_music: - %cm_submenu("Music Selection", #MusicSelectMenu1) + %cm_submenu("Music Selection", #MusicSelectMenu) audio_sfx_lib1: %cm_numfield_sound("Library One Sound", !ram_cm_sfxlib1, 1, 66, 1, 4, .routine) @@ -100,7 +115,7 @@ audio_sfx_silence: .routine JML stop_all_sounds -MusicSelectMenu1: +MusicSelectMenu: dw #audio_music_title1 dw #audio_music_title2 dw #audio_music_intro @@ -252,7 +267,7 @@ audio_music_galaxypeace: %cm_jsl("The Galaxy is at Peace", #audio_playmusic, #$4205) audio_music_goto_1: - %cm_adjacent_submenu("GOTO PAGE TWO", #MusicSelectMenu1) + %cm_adjacent_submenu("GOTO PAGE TWO", #MusicSelectMenu) audio_playmusic: { @@ -291,11 +306,13 @@ CustomizeMenu: dw #mc_menuscroll_delay dw #$FFFF dw #mc_customheader + dw #$FFFF + dw #mc_factory_reset dw #$0000 %cm_header("CUSTOMIZE PRACTICE MENU") mc_menubackground: - %cm_toggle("Menu Background", !sram_menu_background, #$0001, #0) + %cm_toggle("Menu Background", !sram_menu_background, #$01, #0) mc_custompalettes_menu: %cm_submenu("Customize Menu Palette", #CustomPalettesMenu) @@ -644,10 +661,10 @@ custompalettes_dec_blue: %cm_numfield("Decimal Blue", !ram_cm_custompalette_blue, 0, 31, 1, 2, #MixRGB) mc_dummy_on: - %cm_toggle("Example Toggle ON", !ram_cm_dummy_on, #$0001, #0) + %cm_toggle("Example Toggle ON", !ram_cm_dummy_on, #$01, #0) mc_dummy_off: - %cm_toggle("Example Toggle OFF", !ram_cm_dummy_off, #$0001, #0) + %cm_toggle("Example Toggle OFF", !ram_cm_dummy_off, #$01, #0) mc_dummy_hexnum: %cm_numfield_hex("Example Hex Number", !ram_cm_dummy_num, 0, 255, 1, 8, #0) @@ -714,6 +731,83 @@ custompalettes_background_test: %cm_numfield_hex_word("Background", !sram_palette_background, #$7FFF, #0) +; ------------- +; Factory Reset +; ------------- + +mc_factory_reset: + %cm_submenu("Factory Reset", #FactoryResetConfirm) + +FactoryResetConfirm: + dw #mc_factory_reset_abort + dw #$FFFF + dw #mc_factory_reset_keep_presets + dw #mc_factory_reset_delete_presets + dw #$0000 + %cm_header("KEEP CUSTOM PRESETS?") + %cm_footer("THIS WILL REBOOT THE GAME") + +mc_factory_reset_abort: + %cm_jsl("ABORT", #.routine, #$0000) + .routine + %sfxgoback() + JML cm_previous_menu + +mc_factory_reset_keep_presets: + %cm_jsl("Yes, keep my presets", #action_factory_reset, #$0000) + +mc_factory_reset_delete_presets: + %cm_jsl("No, mark them as empty", .routine, #$0000) + .routine + TYX : TXA ; LDA/X/Y #$0000 + .loop + STA !PRESET_SLOTS,X ; overwrite "5AFE" words + ; inc and multiply Y by $200/$100 for next slot index + INY : TYA : %presetslotsize() + TDC : CPY !TOTAL_PRESET_SLOTS : BNE .loop + ; continue into action_factory_reset + +action_factory_reset: +{ + ; Wipe standard practice hack memory + TDC : LDX !WRAM_SIZE-2 + .wram_loop + STA !WRAM_START,X + DEX #2 : BPL .wram_loop + + ; Wipe stored practice hack memory + LDX !SRAM_SIZE-2 + .sram_loop + STA !SRAM_START,X + DEX #2 : BPL .sram_loop + + ; Mark practice hack SRAM as invalid + STA !sram_initialized + + ; silence audio + JSL !MUSIC_ROUTINE + JSL stop_all_sounds + + ; wait for music queue to clear + STZ !MUSIC_QUEUE_TIMERS : STZ !MUSIC_QUEUE_TIMERS+$2 + STZ !MUSIC_QUEUE_TIMERS+$4 : STZ !MUSIC_QUEUE_TIMERS+$6 + STZ !MUSIC_QUEUE_TIMERS+$8 : STZ !MUSIC_QUEUE_TIMERS+$A + STZ !MUSIC_QUEUE_TIMERS+$C : STZ !MUSIC_QUEUE_TIMERS+$E + STZ !MUSIC_QUEUE_NEXT : STZ !MUSIC_QUEUE_START + STZ !MUSIC_ENTRY : STZ !MUSIC_TIMER + + ; wait for NMI + .nmi_loop + JSL $808EF4 : BCC .reboot + JSL $808338 ; wait for NMI + BRA .nmi_loop + + ; Reboot + .reboot + JML $80841C +} + + ; --------------- ; Custom Sound FX ; --------------- @@ -912,7 +1006,6 @@ cm_colors: .done PLB : PLP RTL -} .ColorMenuTable ; the order of this table must match the menu order @@ -927,6 +1020,7 @@ cm_colors: dw ColorMenuTable_toggleon dw ColorMenuTable_border dw ColorMenuTable_background +} ; macro routines to load an SRAM address into A/X ColorMenuTable_text: @@ -1201,4 +1295,4 @@ EXAKTProfileTable: } %endfree(AE) -pullpc + diff --git a/src/damage.asm b/src/damage.asm index 418dc08b..65dca29e 100644 --- a/src/damage.asm +++ b/src/damage.asm @@ -516,13 +516,6 @@ dash_charge_4_damage_table: %endfree(93) -if !FEATURE_PAL -org $A0A872 -else ; general damage hijack -org $A0A862 -endif - JSR EnemyDamage - if !FEATURE_PAL org $A0A55C else ; shinespark damage @@ -537,17 +530,26 @@ org $A0A62B endif JSR EnemyDamagePowerBomb +if !FEATURE_PAL +org $A0A872 +else ; general damage hijack +org $A0A862 +endif + JSR EnemyDamage + %startfree(A0) EnemyDamage: { LDA !ram_pacifist : BNE .no_damage - LDA $0F8C,X ; original code + LDA !DAMAGE_COUNTER : CLC : ADC $187A : STA !DAMAGE_COUNTER + LDA !ENEMY_HP,X ; original code RTS .no_damage - PLA ; pull return address and jump past storing enemy hp + ; pull return address and jump past saving enemy hp + PLA if !FEATURE_PAL JMP $A8CA else @@ -558,11 +560,13 @@ endif EnemyDamageShinespark: { LDA !ram_pacifist : BNE .no_damage - LDA $0F8C,X ; original code + LDA !DAMAGE_COUNTER : CLC : ADC $12 : STA !DAMAGE_COUNTER + LDA !ENEMY_HP,X ; original code RTS .no_damage - PLA ; pull return address and jump past storing enemy hp + ; pull return address and jump past saving enemy hp + PLA if !FEATURE_PAL JMP $A86A else @@ -573,16 +577,19 @@ endif EnemyDamagePowerBomb: { LDA !ram_pacifist : BNE .no_damage - LDA $0F8C,X ; original code + LDA !DAMAGE_COUNTER : CLC : ADC $12 : STA !DAMAGE_COUNTER + LDA !ENEMY_HP,X ; original code RTS .no_damage - PLA ; pull return address and jump past storing enemy hp + ; pull return address and jump past saving enemy hp + PLA if !FEATURE_PAL JMP $A64C else JMP $A63C endif +} %endfree(A0) diff --git a/src/defines.asm b/src/defines.asm index 22ae06db..103145ed 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -190,9 +190,10 @@ !ram_turret_rng = !WRAM_PERSIST_START+$68 !ram_quickboot_spc_state = !WRAM_PERSIST_START+$6A - ; 0: SPC load completed/not requested - ; 1: SPC load requested - ; ROM address: routine to perform next initialization step +!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) @@ -321,6 +322,9 @@ !ram_cm_dummy_off = !WRAM_MENU_START+$8C !ram_cm_dummy_num = !WRAM_MENU_START+$8E +!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 @@ -431,9 +435,10 @@ ; SRAM ; ----- -!SRAM_VERSION = #$0018 +!SRAM_VERSION = #$0019 !SRAM_START = $702000 +!SRAM_SIZE = #$1000 !PRESET_SLOTS = $703000 !sram_initialized = !SRAM_START+$00 @@ -521,11 +526,16 @@ !sram_superhud_middle = !SRAM_START+$96 !sram_superhud_top = !SRAM_START+$98 !sram_infidoppler_enabled = !SRAM_START+$9A +!sram_random_bubble_sfx = !SRAM_START+$9C +!sram_demo_timer = !SRAM_START+$9E ; ^ FREE SPACE ^ up to +$EE !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 @@ -537,6 +547,11 @@ !sram_presetequiprando_max_supers = !SRAM_START+$10A !sram_presetequiprando_max_pbs = !SRAM_START+$10C !sram_display_mode_reward = !SRAM_START+$10E +!sram_loadstate_rando_energy = !SRAM_START+$110 +!sram_loadstate_rando_reserves = !SRAM_START+$112 +!sram_loadstate_rando_missiles = !SRAM_START+$114 +!sram_loadstate_rando_supers = !SRAM_START+$116 +!sram_loadstate_rando_powerbombs = !SRAM_START+$118 ; ^ FREE SPACE ^ up to +$BA6 @@ -549,11 +564,11 @@ !sram_custom_preset_names_tinystates = !SRAM_START+$E50 ; $180 bytes ; SM specific things -!SRAM_MUSIC_DATA = !SRAM_START+$0FD0 -!SRAM_MUSIC_TRACK = !SRAM_START+$0FD2 -!SRAM_SOUND_TIMER = !SRAM_START+$0FD4 +!SRAM_MUSIC_DATA = !SRAM_START+$FD0 +!SRAM_MUSIC_TRACK = !SRAM_START+$FD2 +!SRAM_SOUND_TIMER = !SRAM_START+$FD4 -; ^ FREE SPACE ^ up to +$0FFE +; ^ FREE SPACE ^ up to +$FFE ; -------------- @@ -835,6 +850,7 @@ !SAMUS_Y_RADIUS = $0B00 !SAMUS_COLLISION_DIRECTION = $0B02 !SAMUS_SPRITEMAP_X = $0B04 +!DAMAGE_COUNTER = $0B0C ; Not used in vanilla !SAMUS_PREVIOUS_X = $0B10 !SAMUS_PREVIOUS_X_SUBPX = $0B12 !SAMUS_PREVIOUS_Y = $0B14 @@ -886,6 +902,8 @@ !ENEMY_HP = $0F8C !ENEMY_SPRITEMAP = $0F8E !ENEMY_TIMER = $0F90 +!ENEMY_INIT_PARAM = $0F92 +!ENEMY_PALETTE_INDEX = $0F96 !ENEMY_BANK = $0FA6 !ENEMY_FUNCTION_POINTER = $0FA8 !ENEMY_VAR_1 = $0FAA @@ -893,6 +911,8 @@ !ENEMY_VAR_3 = $0FAE !ENEMY_VAR_4 = $0FB0 !ENEMY_VAR_5 = $0FB2 +!ENEMY_PARAM_1 = $0FB4 +!ENEMY_PARAM_2 = $0FB6 !EARTHQUAKE_TYPE = $183E !EARTHQUAKE_TIMER = $1840 !SAMUS_IFRAME_TIMER = $18A8 @@ -1102,7 +1122,7 @@ endif !SUIT_PROPERTIES_MASK = #$0007 !SUIT_PROPRETIES_PAL_DEBUG_FLAG = #$0008 -!ROOM_LAYOUT_MAGNET_STAIRS = #$0001 +!ROOM_LAYOUT_NO_MAGNET_STAIRS = #$0001 !ROOM_LAYOUT_AREA_RANDO = #$0002 !ROOM_LAYOUT_ANTISOFTLOCK = #$0004 !ROOM_LAYOUT_DASH_RECALL = #$0008 @@ -1112,6 +1132,7 @@ endif !ROOM_LAYOUT_VARIA_TWEAKS = #$0010 !ROOM_LAYOUT_DASH_RECALL_OR_VARIA_TWEAKS = #$0018 !ROOM_LAYOUT_ANY_RANDO = #$001E +!ROOM_LAYOUT_NO_STEAM_COLLISION = #$0020 !SPRITE_SAMUS_HITBOX = #$0001 !SPRITE_ENEMY_HITBOX = #$0002 diff --git a/src/demos.asm b/src/demos.asm index 76d30fe7..db9ccb6e 100644 --- a/src/demos.asm +++ b/src/demos.asm @@ -142,24 +142,6 @@ endif EndOfIntroDemo: -; Reduce time to start demos -if !FEATURE_PAL -org $8B9B2B - LDA #$00F0 -else -org $8B9B5B - LDA #$012C -endif - -if !FEATURE_PAL -org $8B9EEA - LDA #$00F0 -else -org $8B9F1A - LDA #$012C -endif - - ; unlock the fourth demo set ; normally requires watching credits org $808262 diff --git a/src/enemy_rng.asm b/src/enemy_rng.asm index 8dc4b5dd..9bd1451b 100644 --- a/src/enemy_rng.asm +++ b/src/enemy_rng.asm @@ -8,6 +8,48 @@ org $8699EB JSL hook_phantoon_flame_direction BRA $05 +if !FEATURE_PAL +org $A7894D +else ; Overwrite unused instruction list +org $A7893D +endif +phantoon_always_visible: +{ + LDA !ram_phantoon_always_visible : BNE .enabled + ; overwritten code +if !FEATURE_PAL + JMP $DBCE +else + JMP $DB9A +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 + SEC : RTS + + .inc + INC !ENEMY_VAR_4+$40 + CLC : RTS +} + +phantoon_reset_damagecounter: +{ + TDC : STA !DAMAGE_COUNTER + STZ !ENEMY_TIMER,X ; overwritten code + RTS +} +%warnpc($A789F3, $A78A03) + +if !FEATURE_PAL +org $A7CE98 +else ; hijack, Phantoon AI init +org $A7CE64 +endif + JSR phantoon_reset_damagecounter + if !FEATURE_PAL org $A7D00A else ; Phantoon flame pattern @@ -46,6 +88,13 @@ endif JSL hook_phantoon_1st_rng BRA $10 +if !FEATURE_PAL +org $A7D4AD +else +org $A7D479 +endif + JSR phantoon_always_visible + if !FEATURE_PAL org $A7D6B9 else @@ -961,6 +1010,13 @@ endif CPX #$0006 : BEQ $0A LDA !ENEMY_PROPERTIES +if !FEATURE_PAL +org $A6A18C +else ; hijack, Ridley AI init +org $A6A17C +endif + JSR ridley_reset_damagecounter + if !FEATURE_PAL org $A6A302 else @@ -975,6 +1031,49 @@ org $A6A360 endif LDA #ridley_init_hook +if !FEATURE_PAL +org $A6EFA9 +else +org $A6EFD2 +endif +; Overwrite end of steam ai init (also used by zebes steam) +ceres_steam_ai_init: + LDA !sram_room_layout : BIT !ROOM_LAYOUT_NO_STEAM_COLLISION : BNE .noCollision + + ; vanilla palette index + LDA #$0A00 + + .setPaletteIndex + STA !ENEMY_PALETTE_INDEX,X + JSL $808111 : AND #$001F + INC : STA !ENEMY_VAR_3,X + LDA !ENEMY_PARAM_1,X : ASL : TAY + LDA.w SteamInstructionListPointers,Y + STA !ENEMY_INIT_PARAM,X + LDA.w SteamInitialFunctionPointers,Y + STA !ENEMY_FUNCTION_POINTER,X + RTL + + .noCollision + ; Use a different palette index + LDA #$0800 + BRA .setPaletteIndex +%warnpc($A6F00D, $A6EFE4) + +if !FEATURE_PAL +org $A6F016 +else +org $A6F03F +endif +hook_ceres_steam_touch_ai: + LDX $0E54 + LDA #$7FFF : STA !ENEMY_HP + LDA !sram_room_layout : BIT !ROOM_LAYOUT_NO_STEAM_COLLISION : BNE .noCollision + JML $A0A477 + .noCollision + RTL +%warnpc($A6F059, $A6F030) + ; Fix ceres ridley door instruction list to keep door visible when skipping ridley fight if !FEATURE_PAL org $A6F533 @@ -1001,6 +1100,12 @@ endif %startfree(A6) +ridley_reset_damagecounter: +{ + TDC : STA !DAMAGE_COUNTER + RTS +} + ridley_init_hook: { LDA !ROOM_ID : CMP.w #ROOM_CeresRidleyRoom : BNE .continue @@ -1083,6 +1188,32 @@ else dw $80ED, $F598 endif +SteamInstructionListPointers: + dw #ceres_steam_up_instruction_list +if !FEATURE_PAL + dw $F058, $F08C, $F0C0, $F058, $F0C0 +else + dw $F081, $F0B5, $F0E9, $F081, $F0E9 +endif + +SteamInitialFunctionPointers: +if !FEATURE_PAL + dw $F015, $F015, $F015, $F015, $EFF0, $EFF0 +else ; Use a different RTL since we overwrote the one being used + dw $F03E, $F03E, $F03E, $F03E, $F019, $F019 +endif + +ceres_steam_up_instruction_list: +if !FEATURE_PAL + dw $F0F4 + dw $0001, $F119 + dw $F0FE, #ceres_steam_up_instruction_list, $F038 +else + dw $F11D + dw $0001, $F142 + dw $F127, #ceres_steam_up_instruction_list, $F061 +endif + %endfree(A6) diff --git a/src/flagmenu.asm b/src/flagmenu.asm index 8bf6ecc3..8fa05a2f 100644 --- a/src/flagmenu.asm +++ b/src/flagmenu.asm @@ -933,7 +933,7 @@ events_metroid4: %cm_toggle_bit("4th Metroids Cleared", $7ED822, #$0008, #0) events_zeb1: - %cm_toggle("1st Zebitite Cleared", !ram_cm_zeb1, #$0008, #.routine) + %cm_toggle("1st Zebitite Cleared", !ram_cm_zeb1, #$08, #.routine) .routine LDA !ram_cm_zeb1 : BNE .set TDC @@ -942,7 +942,7 @@ events_zeb1: JML eventflags_set_zeb_ram events_zeb2: - %cm_toggle("2nd Zebitite Cleared", !ram_cm_zeb2, #$0010, #.routine) + %cm_toggle("2nd Zebitite Cleared", !ram_cm_zeb2, #$10, #.routine) .routine LDA !ram_cm_zeb2 : BNE .set LDA #$0008 @@ -951,7 +951,7 @@ events_zeb2: JML eventflags_set_zeb_ram events_zeb3: - %cm_toggle("3rd Zebitite Cleared", !ram_cm_zeb3, #$0018, #.routine) + %cm_toggle("3rd Zebitite Cleared", !ram_cm_zeb3, #$18, #.routine) .routine LDA !ram_cm_zeb3 : BNE .set LDA #$0010 @@ -960,7 +960,7 @@ events_zeb3: JML eventflags_set_zeb_ram events_zeb4: - %cm_toggle("4th Zebitite Cleared", !ram_cm_zeb4, #$0020, #.routine) + %cm_toggle("4th Zebitite Cleared", !ram_cm_zeb4, #$20, #.routine) .routine LDA !ram_cm_zeb4 : BNE .set LDA #$0018 @@ -2337,10 +2337,10 @@ MiscMenu: %cm_header("MISC OPTIONS") misc_bluesuit: - %cm_toggle("Blue Suit", !SAMUS_DASH_COUNTER, #$0004, #0) + %cm_toggle("Blue Suit", !SAMUS_DASH_COUNTER, #$04, #0) misc_flashsuit: - %cm_toggle("Flash Suit", !SAMUS_SHINE_TIMER, #$0001, #0) + %cm_toggle("Flash Suit", !SAMUS_SHINE_TIMER, #$01, #0) misc_hyperbeam: %cm_toggle_bit("Hyper Beam", !SAMUS_HYPER_BEAM, #$8000, #.routine) @@ -2384,7 +2384,7 @@ misc_gooslowdown: %cm_numfield("Goo Slowdown", $7E0A66, 0, 4, 1, 1, #0) misc_healthbomb: - %cm_toggle("Health Bomb Flag", !SAMUS_HEALTH_WARNING, #$0001, #0) + %cm_toggle("Health Bomb Flag", !SAMUS_HEALTH_WARNING, #$01, #0) misc_magicpants: dw !ACTION_CHOICE @@ -2409,7 +2409,7 @@ misc_spacepants: db #$FF misc_metronome: - %cm_toggle("Metronome", !ram_metronome, #$0001, GameLoopExtras) + %cm_toggle("Metronome", !ram_metronome, #$01, GameLoopExtras) misc_metronome_tickrate: %cm_numfield("Metronome Tickrate", !sram_metronome_tickrate, 1, 255, 1, 8, #.routine) @@ -2552,10 +2552,10 @@ misc_double_jump: %cm_toggle_bit("Double Jump", !sram_double_jump, #$0200, init_physics_ram) misc_spin_lock: - %cm_toggle("Spin Lock", !sram_spin_lock, #$0001, #0) + %cm_toggle("Spin Lock", !sram_spin_lock, #$01, #0) misc_infidoppler: - %cm_toggle("Phantoon Infi-Doppler", !sram_infidoppler_enabled, #$0001, #0) + %cm_toggle("Phantoon Infi-Doppler", !sram_infidoppler_enabled, #$01, #0) init_physics_ram: { @@ -2637,19 +2637,5 @@ misc_forcestand: %sfxconfirm() RTL -GameLoopExtras: -{ - ; This allows us to maintain a baseline for CPU timing - ; without restricting our ability to add non-essential features - ; Set the flag if any of these features are enabled - LDA !ram_magic_pants_enabled : BNE .enabled - LDA !ram_space_pants_enabled : BNE .enabled - LDA !ram_metronome - - .enabled - STA !ram_game_loop_extras - RTL -} - %endfree(85) diff --git a/src/freespace.asm b/src/freespace.asm index a53f9e6f..b9f71bbe 100644 --- a/src/freespace.asm +++ b/src/freespace.asm @@ -7,7 +7,8 @@ !START_FREESPACE_80 = $80CD8E ; $3232 !START_FREESPACE_81 = $81EF1A ; $FE6 !START_FREESPACE_82 = $82F70F ; $8F1 -!START_FREESPACE_83 = $83AD66 ; $529A +; Logic expects custom doors are placed at or after $83C000 +!START_FREESPACE_83 = $83C000 ; $529A !START_FREESPACE_84 = $84EFD9 ; $1027 (PAL) !START_FREESPACE_85 = $859643 ; $69BF !START_FREESPACE_86 = $86F4E2 ; $B1E (PAL) diff --git a/src/gamemenu.asm b/src/gamemenu.asm index 2c1d4e36..c6b3a447 100644 --- a/src/gamemenu.asm +++ b/src/gamemenu.asm @@ -12,6 +12,7 @@ GameMenu: dw #game_goto_controls dw #$FFFF dw #game_cutscenes + dw #game_demo_wait_timer dw #game_fast_doors_toggle dw #game_fast_elevators dw #$FFFF @@ -25,20 +26,20 @@ endif dw #game_clear_minimap dw #game_map_grid_alignment dw #$0000 - %cm_header("GAME") + %cm_header("GAME OPTIONS") game_alternatetext: if !FEATURE_PAL - %cm_toggle("French Text", $7E09E2, #$0001, #0) + %cm_toggle("French Text", $7E09E2, #$01, #0) else - %cm_toggle("Japanese Text", $7E09E2, #$0001, #0) + %cm_toggle("Japanese Text", $7E09E2, #$01, #0) endif game_moonwalk: - %cm_toggle("Moon Walk", $7E09E4, #$0001, #0) + %cm_toggle("Moon Walk", $7E09E4, #$01, #0) game_iconcancel: - %cm_toggle("Icon Cancel", $7E09EA, #$0001, #0) + %cm_toggle("Icon Cancel", $7E09EA, #$01, #0) game_goto_controls: %cm_submenu("Controller Setting Mode", #ControllerSettingMenu) @@ -46,11 +47,14 @@ game_goto_controls: game_cutscenes: %cm_submenu("Cutscenes and Effects", #CutscenesMenu) +game_demo_wait_timer: + %cm_numfield_word("Demo Timer (frames)", !sram_demo_timer, 1, 9999, 1, 20, #0) + game_fast_doors_toggle: - %cm_toggle("Fast Doors", !sram_fast_doors, #$0001, #0) + %cm_toggle("Fast Doors", !sram_fast_doors, #$01, #0) game_fast_elevators: - %cm_toggle("Fast Elevators", !sram_fast_elevators, #$0001, #0) + %cm_toggle("Fast Elevators", !sram_fast_elevators, #$01, #0) game_goto_debug: %cm_submenu("Debug Settings", #DebugMenu) @@ -69,7 +73,7 @@ game_top_HUD_mode: db #$FF game_minimap: - %cm_toggle("Minimap", !ram_minimap, #$0001, #0) + %cm_toggle("Minimap", !ram_minimap, #$01, #0) endif game_clear_minimap: @@ -111,6 +115,7 @@ DebugMenu: dw #game_paldebug dw #game_debugbrightness dw #game_invincibility + dw #game_infiniteammo dw #game_pacifist dw #$FFFF dw #game_debugplms @@ -121,7 +126,7 @@ DebugMenu: %cm_header("DEBUG SETTINGS") game_debugmode: - %cm_toggle("Debug Mode", !DEBUG_MODE, #$0001, #0) + %cm_toggle("Debug Mode", !DEBUG_MODE, #$01, #0) game_paldebug: %cm_toggle_inverted("PAL Debug Movement", !PAL_DEBUG_MOVEMENT, #$0001, .routine) @@ -136,13 +141,18 @@ game_paldebug: RTL game_debugbrightness: - %cm_toggle("Debug CPU Brightness", $7E0DF4, #$0001, #0) + %cm_toggle("Debug CPU Brightness", $7E0DF4, #$01, #0) game_invincibility: %cm_toggle_bit("Invincibility", $7E0DE0, #$0007, #0) +game_infiniteammo: + %cm_toggle("Infinite Ammo", !ram_infinite_ammo, #$01, .routine) + .routine + JML GameLoopExtras + game_pacifist: - %cm_toggle("Deal Zero Damage", !ram_pacifist, #$0001, #0) + %cm_toggle("Deal Zero Damage", !ram_pacifist, #$01, #0) game_debugplms: %cm_toggle_bit_inverted("Pseudo G-Mode", $7E1C23, #$8000, #0) diff --git a/src/gamemode.asm b/src/gamemode.asm index 13fd0b42..0eca9370 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -172,6 +172,21 @@ endif 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 @@ -259,9 +274,15 @@ endif .full_equipment LDA !SAMUS_HP_MAX : STA !SAMUS_HP - LDA !SAMUS_MISSILES_MAX : STA !SAMUS_MISSILES - LDA !SAMUS_SUPERS_MAX : STA !SAMUS_SUPERS - LDA !SAMUS_PBS_MAX : STA !SAMUS_PBS + 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 @@ -282,6 +303,25 @@ endif LDA !sram_ctrl_toggle_tileviewer CLC : JMP skip_pause + .reveal_damage + 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 + %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 ; Choose a random preset if zero LDA !sram_last_preset : BEQ .random_preset : STA !ram_load_preset @@ -362,6 +402,22 @@ endif LDA !sram_ctrl_dec_custom_preset CLC : JMP skip_pause + .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 + .update_timers if !FEATURE_VANILLAHUD else @@ -478,6 +534,9 @@ else 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 diff --git a/src/infohud.asm b/src/infohud.asm index 09e27b09..0b2c49f0 100644 --- a/src/infohud.asm +++ b/src/infohud.asm @@ -283,7 +283,7 @@ else LDA !ram_realtime_room : INC : STA !ram_realtime_room ; Segment real timer - LDA !ram_seg_rt_frames : INC : STA !ram_seg_rt_frames : CMP #$003C : BNE .doneTimer + LDA !ram_seg_rt_frames : INC : STA !ram_seg_rt_frames : CMP !FRAMERATE : BNE .doneTimer TDC : STA !ram_seg_rt_frames LDA !ram_seg_rt_seconds : INC : STA !ram_seg_rt_seconds : CMP #$003C : BNE .doneTimer TDC : STA !ram_seg_rt_seconds @@ -513,8 +513,8 @@ ih_before_room_transition: dw #$0000 ; off/dummy dw status_door_hspeed dw status_door_vspeed - dw status_chargetimer - dw status_shinetimer + dw status_door_chargetimer + dw status_door_shinetimer dw status_door_dashcounter dw status_door_xpos dw status_door_ypos @@ -545,8 +545,8 @@ ih_unpause: ; RT seg LDA !ram_seg_rt_frames : CLC : ADC #$0029 : STA !ram_seg_rt_frames - CMP #$003C : BCC .updateHUD - SEC : SBC #$003C : STA !ram_seg_rt_frames + CMP !FRAMERATE : BCC .updateHUD + SEC : SBC !FRAMERATE : STA !ram_seg_rt_frames LDA !ram_seg_rt_seconds : INC : STA !ram_seg_rt_seconds CMP #$003C : BCC .updateHUD @@ -595,6 +595,7 @@ else ; overwritten code JSL $90F084 endif + TDC : STA !DAMAGE_COUNTER JML ih_update_hud_early } @@ -617,6 +618,7 @@ ih_mb2_segment_rainbow: ; runs during baby spawn routine for MB2 STA $7E7854 ; overwritten code + TDC : STA !DAMAGE_COUNTER JML ih_update_hud_early } @@ -1072,7 +1074,7 @@ endif ; Reserve energy counter .reserves LDA !sram_top_display_mode : BEQ .statusIcons - CMP !TOP_HUD_VANILLA_BIT : BNE .vanilla_check_health + BIT !TOP_HUD_VANILLA_BIT : BNE .vanilla_check_health LDA !SAMUS_RESERVE_MAX : BEQ .noReserves LDA !SAMUS_RESERVE_ENERGY : CMP !ram_reserves_last : BEQ .checkAuto @@ -1142,7 +1144,6 @@ endif ; reserve tank .checkReserves - LDA !sram_top_display_mode : BNE .end LDA !SAMUS_RESERVE_MODE : CMP #$0001 : BNE .clearReserve LDA !SAMUS_RESERVE_ENERGY : BEQ .empty LDA !SAMUS_RESERVE_MAX : BEQ .clearReserve @@ -1569,20 +1570,23 @@ ih_game_loop_code: JSR metronome .metronome_done - .pants - LDA !ram_magic_pants_enabled : XBA : ORA !ram_space_pants_enabled : BEQ .checkinputs + LDA !ram_magic_pants_enabled : XBA : ORA !ram_space_pants_enabled : BEQ .pants_done BIT #$00FF : BEQ .magicpants ; if spacepants are disabled, handle magicpants BIT #$FF00 : BEQ .spacepants ; if magicpants are disabled, handle spacepants ; both are enabled, check Samus movement type to decide LDA !SAMUS_MOVEMENT_TYPE : AND #$00FF : CMP #$0001 : BEQ .magicpants ; check if running - .spacepants JSR space_pants - BRA .checkinputs - + BRA .pants_done .magicpants JSR magic_pants + .pants_done + + LDA !ram_infinite_ammo : BEQ .checkinputs + LDA !SAMUS_MISSILES_MAX : STA !SAMUS_MISSILES + LDA !SAMUS_SUPERS_MAX : STA !SAMUS_SUPERS + LDA !SAMUS_PBS_MAX : STA !SAMUS_PBS BRA .checkinputs .handleinputs @@ -1645,7 +1649,8 @@ else STA !ram_enemy_hp : STA !ram_mb_hp STA !ram_dash_counter : STA !ram_shine_counter STA !ram_xpos : STA !ram_ypos : STA !ram_subpixel_pos - LDA !ram_seed_X : LSR : STA !ram_HUD_top : STA !ram_HUD_middle + 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 diff --git a/src/infohudmodes.asm b/src/infohudmodes.asm index 06c7ecc4..a619ce19 100644 --- a/src/infohudmodes.asm +++ b/src/infohudmodes.asm @@ -21,6 +21,7 @@ dw status_vspeed dw status_quickdrop dw status_walljump + dw status_countdamage dw status_armpump dw status_pumpcounter dw status_xpos @@ -935,100 +936,6 @@ endif RTS } -status_door_hspeed: -{ - ; subspeed + submomentum into low byte of Hspeed - LDA !SAMUS_X_SUBRUNSPEED : CLC : ADC !SAMUS_X_SUBMOMENTUM - AND #$FF00 : XBA : STA !ram_momentum_sum - - ; speed + momentum + carry into high byte of Hspeed - LDA !SAMUS_X_RUNSPEED : ADC !SAMUS_X_MOMENTUM - AND #$00FF : XBA : ORA !ram_momentum_sum - - ; draw whole number in decimal - AND #$FF00 : XBA - STA $4204 - %a8() - ; divide by 10 - LDA #$0A : STA $4206 - %a16() - PEA $0000 : PLA ; wait for CPU math - - ; draw integer speed value - LDA $4214 : BEQ .blanktens - ; tens digit - ASL : TAX - LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$88 - ; ones digit - LDA $4216 : ASL : TAX - LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$8A - BRA .subspeed - - .blanktens - ; ones digit - LDA $4216 : ASL : TAX - LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$8A - ; tens digit - LDA !IH_BLANK : STA !HUD_TILEMAP+$88 - - .subspeed - LDA !IH_DECIMAL : STA !HUD_TILEMAP+$8C - - ; draw fraction in hex - LDA !ram_momentum_sum : AND #$00F0 : LSR #3 : TAX - LDA.l HexGFXTable,X : STA !HUD_TILEMAP+$8E - - .done - RTS -} - -status_door_vspeed: -{ - ; draw two digits of speed in decimal form - LDA !SAMUS_Y_SPEED : STA $4204 - %a8() - ; divide by 10 - LDA #$0A : STA $4206 - %a16() - PEA $0000 : PLA ; wait for CPU math - LDA $4214 : BEQ .blanktens - ASL : TAX - LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$88 - - ; Ones digit - LDA $4216 : ASL : TAY - LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$8A - BRA .subspeed - - .blanktens - LDA $4216 : ASL : TAX - LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$88 - LDA !IH_BLANK : STA !HUD_TILEMAP+$8A - - .subspeed - LDA !IH_DECIMAL : STA !HUD_TILEMAP+$8A - - LDA !SAMUS_Y_SUBSPEED : XBA : AND #$00F0 : LSR #3 : TAY - LDA.l HexGFXTable,X : STA !HUD_TILEMAP+$8C - - RTS -} - -status_door_dashcounter: -{ - LDA !SAMUS_DASH_COUNTER : LDX #$0088 : JMP Draw4 -} - -status_door_xpos: -{ - LDA !SAMUS_X : LDX #$0088 : JMP Draw4Hex -} - -status_door_ypos: -{ - LDA !SAMUS_Y : LDX #$0088 : JMP Draw4Hex -} - status_quickdrop: { LDA !IH_CONTROLLER_PRI_NEW : AND !IH_INPUT_LEFT : BNE .leftright @@ -1358,6 +1265,15 @@ endif JMP .drawjumpcounter } +status_countdamage: +{ + LDA !DAMAGE_COUNTER : CMP !ram_HUD_check : BEQ .done : STA !ram_HUD_check + LDX #$0088 : JSR Draw4 + + .done + RTS +} + status_armpump: { ; Store Samus HP so it doesn't overwrite our HUD @@ -1650,6 +1566,7 @@ superhud_bottom_table: dw status_vspeed dw status_quickdrop dw status_walljump + dw status_countdamage dw status_armpump dw status_pumpcounter dw status_xpos @@ -4989,3 +4906,116 @@ status_twocries_nosb: RTS } +status_door_hspeed: +{ + ; subspeed + submomentum into low byte of Hspeed + LDA !SAMUS_X_SUBRUNSPEED : CLC : ADC !SAMUS_X_SUBMOMENTUM + AND #$FF00 : XBA : STA !ram_momentum_sum + + ; speed + momentum + carry into high byte of Hspeed + LDA !SAMUS_X_RUNSPEED : ADC !SAMUS_X_MOMENTUM + AND #$00FF : XBA : ORA !ram_momentum_sum + + ; draw whole number in decimal + AND #$FF00 : XBA + STA $4204 + %a8() + ; divide by 10 + LDA #$0A : STA $4206 + %a16() + PEA $0000 : PLA ; wait for CPU math + + ; draw integer speed value + LDA $4214 : BEQ .blanktens + ; tens digit + ASL : TAX + LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$88 + ; ones digit + LDA $4216 : ASL : TAX + LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$8A + BRA .subspeed + + .blanktens + ; ones digit + LDA $4216 : ASL : TAX + LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$8A + ; tens digit + LDA !IH_BLANK : STA !HUD_TILEMAP+$88 + + .subspeed + LDA !IH_DECIMAL : STA !HUD_TILEMAP+$8C + + ; draw fraction in hex + LDA !ram_momentum_sum : AND #$00F0 : LSR #3 : TAX + LDA.l HexGFXTable,X : STA !HUD_TILEMAP+$8E + + .done + RTS +} + +status_door_vspeed: +{ + ; draw two digits of speed in decimal form + LDA !SAMUS_Y_SPEED : STA $4204 + %a8() + ; divide by 10 + LDA #$0A : STA $4206 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4214 : BEQ .blanktens + ASL : TAX + LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$88 + + ; Ones digit + LDA $4216 : ASL : TAY + LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$8A + BRA .subspeed + + .blanktens + LDA $4216 : ASL : TAX + LDA.l NumberGFXTable,X : STA !HUD_TILEMAP+$88 + LDA !IH_BLANK : STA !HUD_TILEMAP+$8A + + .subspeed + LDA !IH_DECIMAL : STA !HUD_TILEMAP+$8A + + LDA !SAMUS_Y_SUBSPEED : XBA : AND #$00F0 : LSR #3 : TAY + LDA.l HexGFXTable,X : STA !HUD_TILEMAP+$8C + + RTS +} + +status_door_chargetimer: +{ + LDA !SAMUS_CHARGE_TIMER : CMP #$003C : BPL .charged + LDA #$003C : SEC : SBC !SAMUS_CHARGE_TIMER + LDX #$0088 : JMP Draw4 + + .charged + LDA !IH_BLANK : STA !HUD_TILEMAP+$88 : STA !HUD_TILEMAP+$8A + LDA !IH_SHINESPARK : STA !HUD_TILEMAP+$8C + LDA !SAMUS_CHARGE_TIMER : SEC : SBC #$003C + ASL : TAX : LDA NumberGFXTable,X : STA !HUD_TILEMAP+$8E + RTS +} + +status_door_shinetimer: +{ + LDA !ram_armed_shine_duration : LDX #$0088 : JMP Draw4 +} + +status_door_dashcounter: +{ + LDA !SAMUS_DASH_COUNTER : LDX #$0088 : JMP Draw4 +} + +status_door_xpos: +{ + LDA !SAMUS_X : LDX #$0088 : JMP Draw4Hex +} + +status_door_ypos: +{ + LDA !SAMUS_Y : LDX #$0088 : JMP Draw4Hex +} + diff --git a/src/init.asm b/src/init.asm index 4003db62..b41164bf 100644 --- a/src/init.asm +++ b/src/init.asm @@ -69,13 +69,12 @@ init_nonzero_wram: LDA !sram_seed_X : STA !ram_seed_X LDA !sram_seed_Y : STA !ram_seed_Y - TDC - STA !ram_watch_left_index : STA !ram_watch_right_index - STA !ram_cm_watch_enemy_side + TDC : STA !ram_cm_watch_enemy_side STA !ram_cm_watch_enemy_property : STA !ram_cm_watch_enemy_index + STA !ram_watch_left_index : STA !ram_watch_right_index - LDA #$0001 : STA !ram_cm_dummy_on - STA !ram_cm_sfxlib1 : STA !ram_cm_sfxlib2 : STA !ram_cm_sfxlib3 + INC : STA !ram_cm_sfxlib1 + STA !ram_cm_sfxlib2 : STA !ram_cm_sfxlib3 JML init_wram_based_on_sram } @@ -106,6 +105,7 @@ init_sram_routine_table: dw init_sram_upgrade_15to16 dw init_sram_upgrade_16to17 dw init_sram_upgrade_17to18 + dw init_sram_upgrade_18to19 init_sram: { @@ -204,6 +204,18 @@ endif STA !sram_superhud_top 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 + STA !sram_loadstate_rando_energy + STA !sram_loadstate_rando_reserves + STA !sram_loadstate_rando_missiles + STA !sram_loadstate_rando_supers + STA !sram_loadstate_rando_powerbombs + LDA #$0384 : STA !sram_demo_timer + LDA !SRAM_VERSION : STA !sram_initialized RTS } @@ -229,6 +241,9 @@ init_sram_controller_shortcuts: 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 RTL } diff --git a/src/layout.asm b/src/layout.asm index f0b18b52..a8b0edf0 100644 --- a/src/layout.asm +++ b/src/layout.asm @@ -2164,7 +2164,7 @@ layout_asm_magnetstairs: { PHP %ai16() - LDA !sram_room_layout : BIT !ROOM_LAYOUT_MAGNET_STAIRS : BEQ layout_asm_magnetstairs_done + LDA !sram_room_layout : BIT !ROOM_LAYOUT_NO_MAGNET_STAIRS : BEQ layout_asm_magnetstairs_done ; Modify graphics to indicate magnet stairs removed %a8() diff --git a/src/layoutmenu.asm b/src/layoutmenu.asm index 420d8ed1..d461c49a 100644 --- a/src/layoutmenu.asm +++ b/src/layoutmenu.asm @@ -1,5 +1,4 @@ -pushpc %startfree(E4) ; ------------------------- @@ -15,8 +14,8 @@ pushpc LayoutMenu: dw #layout_itempickups - dw #$FFFF dw #layout_bombtorizodoor + dw #layout_steamcollision dw #layout_magnetstairs dw #layout_arearando dw #layout_antisoftlock @@ -328,8 +327,11 @@ layout_bombtorizodoor: db #$28, "r SLOW", #$FF db #$FF +layout_steamcollision: + %cm_toggle_bit("Remove Steam Collision", !sram_room_layout, !ROOM_LAYOUT_NO_STEAM_COLLISION, #0) + layout_magnetstairs: - %cm_toggle_bit("Remove Magnet Stairs", !sram_room_layout, !ROOM_LAYOUT_MAGNET_STAIRS, #0) + %cm_toggle_bit("Remove Magnet Stairs", !sram_room_layout, !ROOM_LAYOUT_NO_MAGNET_STAIRS, #0) layout_arearando: %cm_toggle_bit("Area Rando Patches", !sram_room_layout, !ROOM_LAYOUT_AREA_RANDO, #0) @@ -4276,4 +4278,3 @@ layout_updown_downdoor: %endfree(E4) -pullpc diff --git a/src/main.asm b/src/main.asm index ad7523e6..534b85a9 100644 --- a/src/main.asm +++ b/src/main.asm @@ -15,8 +15,8 @@ lorom !VERSION_MAJOR = 2 !VERSION_MINOR = 6 -!VERSION_BUILD = 6 -!VERSION_REV = 1 +!VERSION_BUILD = 7 +!VERSION_REV = 0 table ../resources/normal.tbl print "" @@ -83,10 +83,9 @@ else endif endif -incsrc gamemode.asm incsrc minimap.asm incsrc menu.asm -incsrc BRBmenu.asm +incsrc gamemode.asm incsrc roomnames.asm incsrc clearenemies.asm incsrc demos.asm diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 305bfa6b..3cc05b2a 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -5,7 +5,7 @@ ; Menu Helpers ; ------------ -action_brb_menu: +action_brb_mainmenu: { ; Since BRB ram is shared with other menu ram, ; clear all of the values so they are initially sane @@ -32,6 +32,13 @@ action_brb_menu: BRA action_mainmenu } +action_crop_mainmenu: +{ + ; Prepare crop modes + TDC : STA !ram_cm_crop_mode : STA !ram_cm_crop_tile + BRA action_mainmenu +} + action_preset_options_mainmenu: { ; Prepare elevator option @@ -212,6 +219,7 @@ endif dw #mm_goto_ctrlsmenu dw #mm_goto_audiomenu dw #mm_goto_customize + dw #mm_goto_cropmenu dw #mm_goto_brbmenu dw #$0000 %cm_version_header("SM PRACTICE HACK") @@ -248,6 +256,7 @@ endif dw #CtrlMenu>>16 dw #AudioMenu>>16 dw #CustomizeMenu>>16 + dw #CaptureCroppingMenu>>16 dw #BRBMenu>>16 mm_goto_equipment: @@ -260,18 +269,18 @@ mm_goto_presets_menu: %cm_jsl("Preset Options", #action_preset_options_mainmenu, #PresetOptionsMenu) mm_goto_teleport: - %cm_mainmenu("Teleport", #TeleportMenu) + %cm_mainmenu("Save Stations", #TeleportMenu) mm_goto_events: %cm_mainmenu("Event Flags", #EventFlagsMenu) mm_goto_misc: - %cm_mainmenu("Misc", #MiscMenu) + %cm_mainmenu("Misc Options", #MiscMenu) if !FEATURE_VANILLAHUD else mm_goto_infohud: - %cm_jsl("Infohud", #action_infohud_mainmenu, #InfoHudMenu) + %cm_jsl("InfoHUD", #action_infohud_mainmenu, #InfoHudMenu) endif mm_goto_sprites: @@ -301,10 +310,13 @@ mm_goto_audiomenu: %cm_mainmenu("Audio Menu", #AudioMenu) mm_goto_customize: - %cm_jsl("Menu Customization", #action_customize_mainmenu, #CustomizeMenu) + %cm_jsl("Customize Practice Menu", #action_customize_mainmenu, #CustomizeMenu) + +mm_goto_cropmenu: + %cm_jsl("Capture Cropping Mode", #action_crop_mainmenu, #CaptureCroppingMenu) mm_goto_brbmenu: - %cm_jsl("Be Right Back Menu", #action_brb_menu, #BRBMenu) + %cm_jsl("Be Right Back Menu", #action_brb_mainmenu, #BRBMenu) ; ------------------- @@ -433,7 +445,7 @@ presets_load_random: if !FEATURE_DEV presets_random_preset_rng: - %cm_toggle("Presets In Order", !ram_random_preset_rng, #$0001, #0) + %cm_toggle("Presets In Order", !ram_random_preset_rng, #$01, #0) endif presets_equip_rando_menu: @@ -1489,6 +1501,7 @@ DisplayModeMenu: %cm_header("INFOHUD DISPLAY MODE") DisplayModeMenu2: + dw ihmode_countdamage dw ihmode_armpump dw ihmode_pumpcounter dw ihmode_xpos @@ -1542,37 +1555,41 @@ ihmode_hspeed: %cm_jsl("Horizontal Speed", #action_select_infohud_mode, #$000C) ihmode_vspeed: -!IH_MODE_VSPEED_INDEX = #$000F +!IH_MODE_VSPEED_INDEX = #$000D %cm_jsl("Vertical Speed", #action_select_infohud_mode, #$000D) ihmode_quickdrop: %cm_jsl("Quickdrop Trainer", #action_select_infohud_mode, #$000E) ihmode_walljump: -!IH_MODE_WALLJUMP_INDEX = #$0011 +!IH_MODE_WALLJUMP_INDEX = #$000F %cm_jsl("Walljump Trainer", #action_select_infohud_mode, #$000F) +ihmode_countdamage: +!IH_MODE_COUNTDAMAGE_INDEX = #$0010 + %cm_jsl("Boss Damage Counter", #action_select_infohud_mode, #$0010) + ihmode_armpump: -!IH_MODE_ARMPUMP_INDEX = #$0012 - %cm_jsl("Arm Pump Trainer", #action_select_infohud_mode, #$0010) +!IH_MODE_ARMPUMP_INDEX = #$0011 + %cm_jsl("Arm Pump Trainer", #action_select_infohud_mode, #$0011) ihmode_pumpcounter: - %cm_jsl("Arm Pump Counter", #action_select_infohud_mode, #$0011) + %cm_jsl("Arm Pump Counter", #action_select_infohud_mode, #$0012) ihmode_xpos: - %cm_jsl("X Position", #action_select_infohud_mode, #$0012) + %cm_jsl("X Position", #action_select_infohud_mode, #$0013) ihmode_ypos: - %cm_jsl("Y Position", #action_select_infohud_mode, #$0013) + %cm_jsl("Y Position", #action_select_infohud_mode, #$0014) ihmode_shottimer: - %cm_jsl("Shot Timer", #action_select_infohud_mode, #$0014) + %cm_jsl("Shot Timer", #action_select_infohud_mode, #$0015) ihmode_ramwatch: -!IH_MODE_RAMWATCH_INDEX = #$0015 - %cm_jsl("Custom RAM Watch", #action_select_infohud_mode, #$0015) +!IH_MODE_RAMWATCH_INDEX = #$0016 + %cm_jsl("Custom RAM Watch", #action_select_infohud_mode, #$0016) -!IH_MODE_COUNT = #$0016 +!IH_MODE_COUNT = #$0017 action_select_infohud_mode: { TYA : STA !sram_display_mode @@ -1607,6 +1624,7 @@ ih_display_mode: db #$28, " VERT SPEED", #$FF db #$28, " QUICK DROP", #$FF db #$28, " WALL JUMP", #$FF + db #$28, "DMG COUNTER", #$FF db #$28, " ARM PUMP", #$FF db #$28, " PUMP COUNT", #$FF db #$28, " X POSITION", #$FF @@ -1618,7 +1636,7 @@ ih_display_mode: JML init_print_segment_timer ih_display_mode_reward: - %cm_toggle("Strat Reward SFX", !sram_display_mode_reward, #$0001, #0) + %cm_toggle("Strat Reward SFX", !sram_display_mode_reward, #$01, #0) ih_goto_room_strat: %cm_submenu("Select Room Strat", #RoomStratMenu) @@ -1810,6 +1828,7 @@ ih_superhud_bottom_selector: db #$28, " VERT SPEED", #$FF db #$28, " QUICK DROP", #$FF db #$28, " WALL JUMP", #$FF + db #$28, "DMG COUNTER", #$FF db #$28, " ARM PUMP", #$FF db #$28, " PUMP COUNT", #$FF db #$28, " X POSITION", #$FF @@ -1855,8 +1874,7 @@ SuperHUDBottomMenu: dw ih_superhud_vspeed dw ih_superhud_quickdrop dw ih_superhud_walljump - dw ih_superhud_armpump - dw ih_superhud_pumpcounter + dw ih_superhud_countdamage dw #$FFFF dw ih_superhud_goto_page2 dw ih_superhud_goto_page3 @@ -1864,6 +1882,8 @@ SuperHUDBottomMenu: %cm_header("SUPER HUD BOTTOM MODE") SuperHUDBottomMenu2: + dw ih_superhud_armpump + dw ih_superhud_pumpcounter dw ih_superhud_xpos dw ih_superhud_ypos dw ih_superhud_shottimer @@ -1942,80 +1962,83 @@ ih_superhud_quickdrop: ih_superhud_walljump: %cm_jsl("Walljump Trainer", #action_select_superhud_bottom, #$000D) +ih_superhud_countdamage: + %cm_jsl("Boss Damage Counter", #action_select_superhud_bottom, #$000E) + ih_superhud_armpump: - %cm_jsl("Arm Pump Trainer", #action_select_superhud_bottom, #$000E) + %cm_jsl("Arm Pump Trainer", #action_select_superhud_bottom, #$000F) ih_superhud_pumpcounter: - %cm_jsl("Arm Pump Counter", #action_select_superhud_bottom, #$000F) + %cm_jsl("Arm Pump Counter", #action_select_superhud_bottom, #$0010) ih_superhud_xpos: - %cm_jsl("X Position", #action_select_superhud_bottom, #$0010) + %cm_jsl("X Position", #action_select_superhud_bottom, #$0011) ih_superhud_ypos: - %cm_jsl("Y Position", #action_select_superhud_bottom, #$0011) + %cm_jsl("Y Position", #action_select_superhud_bottom, #$0012) ih_superhud_shottimer: - %cm_jsl("Shot Timer", #action_select_superhud_bottom, #$0012) + %cm_jsl("Shot Timer", #action_select_superhud_bottom, #$0013) ih_superhud_ramwatch: - %cm_jsl("Custom RAM Watch", #action_select_superhud_bottom, #$0013) + %cm_jsl("Custom RAM Watch", #action_select_superhud_bottom, #$0014) ih_superhud_ceresridley: - %cm_jsl("Ceres Ridley Hits", #action_select_superhud_bottom, #$0014) + %cm_jsl("Ceres Ridley Hits", #action_select_superhud_bottom, #$0015) ih_superhud_doorskip: - %cm_jsl("Parlor-Climb Door Skip", #action_select_superhud_bottom, #$0015) + %cm_jsl("Parlor-Climb Door Skip", #action_select_superhud_bottom, #$0016) ih_superhud_tacotank: - %cm_jsl("Taco Tank", #action_select_superhud_bottom, #$0016) + %cm_jsl("Taco Tank", #action_select_superhud_bottom, #$0017) ih_superhud_pitdoor: - %cm_jsl("Pit Room Right Door", #action_select_superhud_bottom, #$0017) + %cm_jsl("Pit Room Right Door", #action_select_superhud_bottom, #$0018) ih_superhud_moondance: - %cm_jsl("Moondance", #action_select_superhud_bottom, #$0018) + %cm_jsl("Moondance", #action_select_superhud_bottom, #$0019) ih_superhud_gateglitch: - %cm_jsl("Gate Glitch", #action_select_superhud_bottom, #$0019) + %cm_jsl("Gate Glitch", #action_select_superhud_bottom, #$001A) ih_superhud_moatcwj: - %cm_jsl("Moat CWJ", #action_select_superhud_bottom, #$001A) + %cm_jsl("Moat CWJ", #action_select_superhud_bottom, #$001B) ih_superhud_robotflush: - %cm_jsl("Robot Flush", #action_select_superhud_bottom, #$001B) + %cm_jsl("Robot Flush", #action_select_superhud_bottom, #$001C) ih_superhud_shinetopb: - %cm_jsl("Shine to PB", #action_select_superhud_bottom, #$001C) + %cm_jsl("Shine to PB", #action_select_superhud_bottom, #$001D) ih_superhud_elevatorcf: - %cm_jsl("Elevator Crystal Flash", #action_select_superhud_bottom, #$001D) + %cm_jsl("Elevator Crystal Flash", #action_select_superhud_bottom, #$001E) ih_superhud_botwooncf: - %cm_jsl("Botwoon Crystal Flash", #action_select_superhud_bottom, #$001E) + %cm_jsl("Botwoon Crystal Flash", #action_select_superhud_bottom, #$001F) ih_superhud_draygonai: - %cm_jsl("Draygon AI", #action_select_superhud_bottom, #$001F) + %cm_jsl("Draygon AI", #action_select_superhud_bottom, #$0020) ih_superhud_snailclip: - %cm_jsl("Aqueduct Snail Clip", #action_select_superhud_bottom, #$0020) + %cm_jsl("Aqueduct Snail Clip", #action_select_superhud_bottom, #$0021) ih_superhud_wasteland: - %cm_jsl("Wasteland Entry", #action_select_superhud_bottom, #$0021) + %cm_jsl("Wasteland Entry", #action_select_superhud_bottom, #$0022) ih_superhud_ridleyai: - %cm_jsl("Ridley AI", #action_select_superhud_bottom, #$0022) + %cm_jsl("Ridley AI", #action_select_superhud_bottom, #$0023) ih_superhud_downbackzeb: - %cm_jsl("Downback Zeb Skip", #action_select_superhud_bottom, #$0023) + %cm_jsl("Downback Zeb Skip", #action_select_superhud_bottom, #$0024) ih_superhud_zebskip: - %cm_jsl("Zeb Skip Indicator", #action_select_superhud_bottom, #$0024) + %cm_jsl("Zeb Skip Indicator", #action_select_superhud_bottom, #$0025) ih_superhud_mbhp: - %cm_jsl("Mother Brain HP", #action_select_superhud_bottom, #$0025) + %cm_jsl("Mother Brain HP", #action_select_superhud_bottom, #$0026) ih_superhud_twocries: - %cm_jsl("Two Cries Standup", #action_select_superhud_bottom, #$0026) + %cm_jsl("Two Cries Standup", #action_select_superhud_bottom, #$0027) ih_superhud_goto_page1: %cm_adjacent_submenu("GOTO PAGE ONE", #SuperHUDBottomMenu) @@ -2256,7 +2279,7 @@ ih_reset_seg_item_touch: if !FEATURE_VANILLAHUD else ih_minimap: - %cm_toggle("Minimap", !ram_minimap, #$0001, #0) + %cm_toggle("Minimap", !ram_minimap, #$01, #0) ih_top_HUD_mode: !TOP_HUD_RESERVES_INDEX = #$0001 @@ -2335,7 +2358,7 @@ ih_frames_held_down: %cm_toggle_bit("Down", !ram_frames_held, !IH_INPUT_DOWN, #0) ih_status_icons: - %cm_toggle("Status Icons", !sram_status_icons, #1, #.routine) + %cm_toggle("Status Icons", !sram_status_icons, #$01, #.routine) .routine LDA !IH_BLANK : STA !HUD_TILEMAP+$54 : STA !HUD_TILEMAP+$56 : STA !HUD_TILEMAP+$58 RTL @@ -2591,7 +2614,6 @@ PhantoonMenu: dw #phan_fast_right_1 dw #phan_mid_right_1 dw #phan_slow_right_1 - dw #$FFFF dw #phan_second_phase dw #phan_fast_left_2 dw #phan_mid_left_2 @@ -2605,6 +2627,7 @@ PhantoonMenu: dw #phan_flamepattern dw #phan_next_flamepattern dw #phan_flame_direction + dw #phan_always_visible dw #$0000 %cm_header("PHANTOON RNG CONTROL") @@ -2794,6 +2817,9 @@ phan_flame_direction: db #$28, " RIGHT", #$FF db #$FF +phan_always_visible: + %cm_toggle("Always Visible", !ram_phantoon_always_visible, #$01, #0) + if !FEATURE_SD2SNES ; -------------- @@ -2805,6 +2831,12 @@ SavestateMenu: dw #save_freeze dw #save_middoorsave dw #save_alwayssave + dw #$FFFF + dw #save_rando_energy + dw #save_rando_reserves + dw #save_rando_missiles + dw #save_rando_supers + dw #save_rando_powerbombs if !FEATURE_DEV dw #$FFFF dw #save_delete @@ -2813,10 +2845,10 @@ endif %cm_header("SAVESTATE SETTINGS") save_rerandomize: - %cm_toggle("Rerandomize", !sram_rerandomize, #$0001, #0) + %cm_toggle("Rerandomize", !sram_rerandomize, #$01, #0) save_freeze: - %cm_toggle("Freeze on Load State", !ram_freeze_on_load, #$0001, #0) + %cm_toggle("Freeze on Load State", !ram_freeze_on_load, #$01, #0) save_middoorsave: %cm_toggle_bit("Auto-Save Mid-Door", !ram_auto_save_state, #$0001, #0) @@ -2830,6 +2862,26 @@ save_delete: TYA : STA !SRAM_SAVED_STATE %sfxconfirm() RTL + +save_rando_energy: + %cm_numfield("Energy Variance", !sram_loadstate_rando_energy, 0, 255, 1, 4, #save_rando_enable) + +save_rando_reserves: + %cm_numfield("Reserve Variance", !sram_loadstate_rando_reserves, 0, 255, 1, 4, #save_rando_enable) + +save_rando_missiles: + %cm_numfield("Missile Variance", !sram_loadstate_rando_missiles, 0, 230, 1, 4, #save_rando_enable) + +save_rando_supers: + %cm_numfield("Super Missile Variance", !sram_loadstate_rando_supers, 0, 50, 1, 2, #save_rando_enable) + +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 +} endif @@ -2864,6 +2916,7 @@ slowdown_frames: CtrlMenu: dw #ctrl_menu + dw #$FFFF if !FEATURE_SD2SNES dw #ctrl_save_state dw #ctrl_load_state @@ -2877,11 +2930,30 @@ endif 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 @@ -2889,7 +2961,7 @@ endif %cm_footer("PRESS AND HOLD FOR 2 SEC") ctrl_menu: - %cm_ctrl_shortcut("Main menu", !sram_ctrl_menu) + %cm_ctrl_shortcut("Main Menu", !sram_ctrl_menu) ctrl_load_last_preset: %cm_ctrl_shortcut("Reload Preset", !sram_ctrl_load_last_preset) @@ -2935,8 +3007,20 @@ 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) @@ -2960,7 +3044,10 @@ ctrl_clear_shortcuts: 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 @@ -2978,6 +3065,12 @@ 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 @@ -2985,6 +3078,7 @@ endif init_wram_based_on_sram: { + JSL RandomizeOnLoad_Flag JSL init_suit_properties_ram JSL init_physics_ram JSL init_print_segment_timer @@ -3003,7 +3097,10 @@ GameModeExtras: 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 @@ -3011,6 +3108,21 @@ GameModeExtras: RTL } +GameLoopExtras: +{ + ; This allows us to maintain a baseline for CPU timing + ; without restricting our ability to add non-essential features + ; Set the flag if any of these features are enabled + LDA !ram_magic_pants_enabled : BNE .enabled + LDA !ram_space_pants_enabled : BNE .enabled + LDA !ram_metronome : BNE .enabled + LDA !ram_infinite_ammo + + .enabled + STA !ram_game_loop_extras + RTL +} + if !FEATURE_SD2SNES validate_sram_for_savestates: { diff --git a/src/menu.asm b/src/menu.asm index 2fb8732a..3be095a1 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -3,6 +3,8 @@ ; Main menu ; --------- +incsrc BRBmenu.asm +incsrc cropmenu.asm incsrc customizemenu.asm incsrc flagmenu.asm incsrc gamemenu.asm @@ -1139,8 +1141,7 @@ draw_choice: .found %a16() - JSR cm_draw_text - RTS + JMP cm_draw_text } draw_choice_jsl_text: @@ -1169,8 +1170,7 @@ draw_choice_jsl_text: ; go to jsl text %a16() LDA [!DP_CurrentMenu] : CLC : ADC #$0006 : STA !DP_CurrentMenu - JSR cm_draw_text - RTS + JMP cm_draw_text } draw_ctrl_shortcut: @@ -1189,9 +1189,7 @@ draw_ctrl_shortcut: ; draw the inputs LDA [!DP_Address] - JSR menu_ctrl_input_display - - RTS + JMP menu_ctrl_input_display } draw_controller_input: @@ -1254,8 +1252,7 @@ draw_submenu: ; draw text normally %item_index_to_vram_index() - JSR cm_draw_text - RTS + JMP cm_draw_text } draw_custom_preset: @@ -2712,7 +2709,7 @@ cm_execute: INC !DP_CurrentMenu : INC !DP_CurrentMenu ; Execute action - JSR (cm_execute_action_table,X) + JMP (cm_execute_action_table,X) .end RTS @@ -3387,6 +3384,8 @@ else .done JSL cm_previous_menu + ; set bank for manual submenu jump + LDA !DP_MenuIndices+2 : STA !ram_cm_menu_bank JSL action_submenu endif endif diff --git a/src/misc.asm b/src/misc.asm index 2bfbfdef..11e97130 100644 --- a/src/misc.asm +++ b/src/misc.asm @@ -245,8 +245,92 @@ IconCancelMenu: %endfree(86) +org $88B439 + JMP misc_lava_bubble_sfx + +org $908176 + JMP misc_water_bubble_sfx + + +%startfree(88) + +misc_lava_bubble_sfx: +{ + LDA !sram_random_bubble_sfx : BNE .override + + ; Vanilla logic + LDA !CACHED_RANDOM_NUMBER : AND #$0007 + TAY : LDA $B3A1,Y : AND #$00FF + + .play + JSL $8090CB + JMP $B44A + + .override + PHX : ASL : TAX : JMP (.table,X) + + .table + dw .return + dw .return + dw .play12 + dw .play13 + dw .play14 + dw .play12 + dw .play13 + dw .play14 + + .return + PLX : JMP $B44A + + .play12 + PLX : LDA #$0012 : BRA .play + + .play13 + PLX : LDA #$0013 : BRA .play + + .play14 + PLX : LDA #$0014 : BRA .play +} + +%endfree(88) + + %startfree(90) +misc_water_bubble_sfx: +{ + LDA !sram_random_bubble_sfx : BNE .override + + ; Vanilla logic + JSL $808111 : BIT #$0001 : BEQ .high + + .low + LDA #$000F + BRA .play + + .high + LDA #$0011 + + .play + JSL $8090CB + + .return + JMP $818B + + .override + ASL : TAX : JMP (.table,X) + + .table + dw .return + dw .return + dw .low + dw .low + dw .low + dw .high + dw .high + dw .high +} + hook_set_music_track: { STZ !MUSIC_TRACK+1 @@ -278,6 +362,283 @@ hook_set_music_data: JML $808F89 } +RandomizeOnLoad: +; Allows users to configure a range of variation in energy/ammo +{ + ; randomize energy on loadstate + LDA !sram_loadstate_rando_energy : BEQ .reserves + %a8() + ; treat low byte of seed as a signed value + LDA !ram_seed_X : BMI .subEnergy + .loopAddEnergy + ; check if it's within the chosen range + CMP !sram_loadstate_rando_energy : BEQ .addAndSetEnergy : BCS .oorAddEnergy + .addAndSetEnergy + ; within range, add it to energy + %a16() ; assuming high byte is clean from flag check + CLC : ADC !SAMUS_HP : STA !SAMUS_HP + BRA .doneEnergy + .oorAddEnergy + ; subtract chosen range from seed and try again + SBC !sram_loadstate_rando_energy ; carry was already set + BRA .loopAddEnergy + + .subEnergy + ; seed was negative, invert it to positive + EOR #$FF : INC + .loopSubEnergy + ; check if it's within the chosen range + CMP !sram_loadstate_rando_energy : BEQ .subAndSetEnergy : BCS .oorSubEnergy + .subAndSetEnergy + ; within range, subtract it from energy + %a16() + STA $C1 + LDA !SAMUS_HP : SEC : SBC $C1 : STA !SAMUS_HP + BRA .doneEnergy + .oorSubEnergy + ; subtract chosen range from seed and try again + SBC !sram_loadstate_rando_energy ; carry was already set + BRA .loopSubEnergy + + .dontDie + ; minimum of 1 energy + LDA #$0001 : STA !SAMUS_HP + + .doneEnergy + ; check if energy is negative + LDA !SAMUS_HP : BEQ .dontDie : BMI .dontDie + ; check if energy exceeded max + CMP !SAMUS_HP_MAX : BCC .doneEnergyRerandomize + LDA !SAMUS_HP_MAX : STA !SAMUS_HP + .doneEnergyRerandomize + ; this normally only runs while the menu is open + JSL MenuRNG + + .reserves + ; skip if no reserve tanks + LDA !SAMUS_RESERVE_MAX : BEQ .missiles + LDA !sram_loadstate_rando_reserves : BEQ .missiles + ; feature enabled + %a8() + ; treat low byte of seed as a signed value + LDA !ram_seed_X : BMI .subReserves + .loopAddReserves + ; check if it's within the chosen range + CMP !sram_loadstate_rando_reserves : BEQ .addAndSetReserves : BCS .oorAddReserves + .addAndSetReserves + ; within range, add it to reserves + %a16() ; assuming high byte is clean from flag check + CLC : ADC !SAMUS_RESERVE_ENERGY : STA !SAMUS_RESERVE_ENERGY + BRA .doneReserves + .oorAddReserves + ; subtract chosen range from seed and try again + SBC !sram_loadstate_rando_reserves ; carry was already set + BRA .loopAddReserves + + .subReserves + ; seed was negative, invert it to positive + EOR #$FF : INC + .loopSubReserves + ; check if it's within the chosen range + CMP !sram_loadstate_rando_reserves : BEQ .subAndSetReserves : BCS .oorSubReserves + .subAndSetReserves + ; within range, subtract it from reserves + %a16() + STA $C1 + LDA !SAMUS_RESERVE_ENERGY : SEC : SBC $C1 : STA !SAMUS_RESERVE_ENERGY + BRA .doneReserves + .oorSubReserves + ; subtract chosen range from seed and try again + SBC !sram_loadstate_rando_reserves ; carry was already set + BRA .loopSubReserves + + .minReserves + ; minimum of 0 reserves + STZ !SAMUS_RESERVE_ENERGY + + .doneReserves + ; check if reserves is negative + LDA !SAMUS_RESERVE_ENERGY : BMI .minReserves + ; check if reserves exceeded max + CMP !SAMUS_RESERVE_MAX : BCC .doneReservesRerandomize + LDA !SAMUS_RESERVE_MAX : STA !SAMUS_RESERVE_ENERGY + .doneReservesRerandomize + ; this normally only runs while the menu is open + JSL MenuRNG + + .missiles + ; skip if no missile tanks + LDA !SAMUS_MISSILES_MAX : BEQ .supers + LDA !sram_loadstate_rando_missiles : BEQ .supers + ; feature enabled + %a8() + ; treat low byte of seed as a signed value + LDA !ram_seed_X : BMI .subMissiles + .loopAddMissiles + ; check if it's within the chosen range + CMP !sram_loadstate_rando_missiles : BEQ .addAndSetMissiles : BCS .oorAddMissiles + .addAndSetMissiles + ; within range, add it to missiles + %a16() ; assuming high byte is clean from flag check + CLC : ADC !SAMUS_MISSILES : STA !SAMUS_MISSILES + BRA .doneMissiles + .oorAddMissiles + ; subtract chosen range from seed and try again + SBC !sram_loadstate_rando_missiles ; carry was already set + BRA .loopAddMissiles + + .subMissiles + ; seed was negative, invert it to positive + EOR #$FF : INC + .loopSubMissiles + ; check if it's within the chosen range + CMP !sram_loadstate_rando_missiles : BEQ .subAndSetMissiles : BCS .oorSubMissiles + .subAndSetMissiles + ; within range, subtract it from missiles + %a16() + STA $C1 + LDA !SAMUS_MISSILES : SEC : SBC $C1 : STA !SAMUS_MISSILES + BRA .doneMissiles + .oorSubMissiles + ; subtract chosen range from seed and try again + SBC !sram_loadstate_rando_missiles ; carry was already set + BRA .loopSubMissiles + + .minMissiles + ; minimum of 0 missiles + STZ !SAMUS_MISSILES + + .doneMissiles + ; check if missiles is negative + LDA !SAMUS_MISSILES : BMI .minMissiles + ; check if missiles exceeded max + CMP !SAMUS_MISSILES_MAX : BCC .doneMissilesRerandomize + LDA !SAMUS_MISSILES_MAX : STA !SAMUS_MISSILES + .doneMissilesRerandomize + ; this normally only runs while the menu is open + JSL MenuRNG + + .supers + ; skip if no super missile tanks + LDA !SAMUS_SUPERS_MAX : BEQ .powerbombs + LDA !sram_loadstate_rando_supers : BEQ .powerbombs + ; feature enabled + %a8() + ; treat low byte of seed as a signed value + LDA !ram_seed_X : BMI .subSupers + .loopAddSupers + ; check if it's within the chosen range + CMP !sram_loadstate_rando_supers : BEQ .addAndSetSupers : BCS .oorAddSupers + .addAndSetSupers + ; within range, add it to supers + %a16() ; assuming high byte is clean from flag check + CLC : ADC !SAMUS_SUPERS : STA !SAMUS_SUPERS + BRA .doneSupers + .oorAddSupers + ; subtract chosen range from seed and try again + SBC !sram_loadstate_rando_supers ; carry was already set + BRA .loopAddSupers + + .subSupers + ; seed was negative, invert it to positive + EOR #$FF : INC + .loopSubSupers + ; check if it's within the chosen range + CMP !sram_loadstate_rando_supers : BEQ .subAndSetSupers : BCS .oorSubSupers + .subAndSetSupers + ; within range, subtract it from supers + %a16() + STA $C1 + LDA !SAMUS_SUPERS : SEC : SBC $C1 : STA !SAMUS_SUPERS + BRA .doneSupers + .oorSubSupers + ; subtract chosen range from seed and try again + SBC !sram_loadstate_rando_supers ; carry was already set + BRA .loopSubSupers + + .minSupers + ; minimum of 0 supers + STZ !SAMUS_SUPERS + + .doneSupers + ; check if supers is negative + LDA !SAMUS_SUPERS : BMI .minSupers + ; check if supers exceeded max + CMP !SAMUS_SUPERS_MAX : BCC .doneSupersRerandomize + LDA !SAMUS_SUPERS_MAX : STA !SAMUS_SUPERS + .doneSupersRerandomize + ; this normally only runs while the menu is open + JSL MenuRNG + + .powerbombs + ; skip if no power bomb tanks + LDA !SAMUS_PBS_MAX : BEQ .exit + LDA !sram_loadstate_rando_powerbombs : BEQ .exit + ; feature enabled + %a8() + ; treat low byte of seed as a signed value + LDA !ram_seed_X : BMI .subPBs + .loopAddPBs + ; check if it's within the chosen range + CMP !sram_loadstate_rando_powerbombs : BEQ .addAndSetPBs : BCS .oorAddPBs + .addAndSetPBs + ; within range, add it to power bombs + %a16() ; assuming high byte is clean from flag check + CLC : ADC !SAMUS_PBS : STA !SAMUS_PBS + BRA .donePBs + .oorAddPBs + ; subtract chosen range from seed and try again + SBC !sram_loadstate_rando_powerbombs ; carry was already set + BRA .loopAddPBs + + .subPBs + ; seed was negative, invert it to positive + EOR #$FF : INC + .loopSubPBs + ; check if it's within the chosen range + CMP !sram_loadstate_rando_powerbombs : BEQ .subAndSetPBs : BCS .oorSubPBs + .subAndSetPBs + ; within range, subtract it from power bombs + %a16() + STA $C1 + LDA !SAMUS_PBS : SEC : SBC $C1 : STA !SAMUS_PBS + BRA .donePBs + .oorSubPBs + ; subtract chosen range from seed and try again + SBC !sram_loadstate_rando_powerbombs ; carry was already set + BRA .loopSubPBs + + .minPBs + ; minimum of 0 power bombs + STZ !SAMUS_PBS + + .donePBs + ; check if power bombs is negative + LDA !SAMUS_PBS : BMI .minPBs + ; check if power bombs exceeded max + CMP !SAMUS_PBS_MAX : BCC .donePBsRerandomize + LDA !SAMUS_PBS_MAX : STA !SAMUS_PBS + .donePBsRerandomize + ; this normally only runs while the menu is open + JSL MenuRNG + + .exit + 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 @@ -622,8 +983,30 @@ set_fade_in_door_function: %endfree(90) +if !FEATURE_PAL +org $8B9EEA +else ; runs when title intro completes +org $8B9F1A +endif + JSR DemoWaitTimer + +if !FEATURE_PAL +org $8B9B2B +else ; runs when title intro is interrupted +org $8B9B5B +endif + JSR DemoWaitTimer + + %startfree(8B) +DemoWaitTimer: +{ + ; initial demo wait timer + LDA !sram_demo_timer + RTS +} + fade_in_skip_draw: { ; Copy start of $82E737 diff --git a/src/presets.asm b/src/presets.asm index 80798975..593e3bd8 100644 --- a/src/presets.asm +++ b/src/presets.asm @@ -269,8 +269,13 @@ startgame_seg_timer: ; 20 frames more if the file was new ; initializing to 1:50 for now TDC : STA !ram_seg_rt_minutes +if !FEATURE_PAL + INC : INC : STA !ram_seg_rt_seconds + LDA #$000A : STA !ram_seg_rt_frames +else INC : STA !ram_seg_rt_seconds LDA #$0032 : STA !ram_seg_rt_frames +endif JML $808924 ; overwritten code } diff --git a/src/ramwatchmenu.asm b/src/ramwatchmenu.asm index 869ff6af..10c5720f 100644 --- a/src/ramwatchmenu.asm +++ b/src/ramwatchmenu.asm @@ -627,10 +627,10 @@ ramwatch_execute_right: JML init_print_segment_timer ramwatch_lock_left: - %cm_toggle("Lock Left Value", !ram_watch_edit_lock_left, #$0001, #action_HUD_ramwatch) + %cm_toggle("Lock Left Value", !ram_watch_edit_lock_left, #$01, #action_HUD_ramwatch) ramwatch_lock_right: - %cm_toggle("Lock Right Value", !ram_watch_edit_lock_right, #$0001, #action_HUD_ramwatch) + %cm_toggle("Lock Right Value", !ram_watch_edit_lock_right, #$01, #action_HUD_ramwatch) action_HUD_ramwatch: { diff --git a/src/save.asm b/src/save.asm index 1ce28438..cdd540bb 100644 --- a/src/save.asm +++ b/src/save.asm @@ -93,14 +93,19 @@ post_load_state: .rng ; Rerandomize - LDA !sram_save_has_set_rng : BNE .done - LDA !sram_rerandomize : BEQ .done + LDA !sram_save_has_set_rng : BNE .randomizeOnLoad + LDA !sram_rerandomize : BEQ .randomizeOnLoad LDA !SRAM_SAVED_RNG : STA !CACHED_RANDOM_NUMBER LDA !SRAM_SAVED_FRAME_COUNTER : STA !FRAME_COUNTER LDA !sram_seed_X : STA !ram_seed_X LDA !sram_seed_Y : STA !ram_seed_Y JSL MenuRNG ; rerandomize hack RNG + .randomizeOnLoad + ; Randomize energy/ammo? + LDA !ram_loadstate_rando_enable : BEQ .done + JSL RandomizeOnLoad + .done JSL init_wram_based_on_sram diff --git a/src/symbols.asm b/src/symbols.asm index 0d75cf9b..e6b0cd26 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -188,6 +188,10 @@ 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_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) @@ -316,6 +320,9 @@ 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_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 @@ -501,11 +508,16 @@ sram_superhud_bottom = !sram_superhud_bottom ; !SRAM_START+$94 sram_superhud_middle = !sram_superhud_middle ; !SRAM_START+$96 sram_superhud_top = !sram_superhud_top ; !SRAM_START+$98 sram_infidoppler_enabled = !sram_infidoppler_enabled ; !SRAM_START+$9A +sram_random_bubble_sfx = !sram_random_bubble_sfx ; !SRAM_START+$9C +sram_demo_timer = !sram_demo_timer ; !SRAM_START+$9E ; ^ FREE SPACE ^ up to +$EE 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 @@ -517,6 +529,11 @@ sram_presetequiprando_max_missiles = !sram_presetequiprando_max_missiles ; !SRAM sram_presetequiprando_max_supers = !sram_presetequiprando_max_supers ; !SRAM_START+$10A sram_presetequiprando_max_pbs = !sram_presetequiprando_max_pbs ; !SRAM_START+$10C sram_display_mode_reward = !sram_display_mode_reward ; !SRAM_START+$10E +sram_loadstate_rando_energy = !sram_loadstate_rando_energy ; !SRAM_START+$110 +sram_loadstate_rando_reserves = !sram_loadstate_rando_reserves ; !SRAM_START+$112 +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 ; ^ FREE SPACE ^ up to +$BA6 @@ -530,6 +547,6 @@ sram_custom_preset_names_tinystates = !sram_custom_preset_names_tinystates ; !SR ; SM specific things -; ^ FREE SPACE ^ up to +$0FFE +; ^ FREE SPACE ^ up to +$FFE ; -------------- diff --git a/src/tinystates.asm b/src/tinystates.asm index 34dd0ee4..efa25fc5 100644 --- a/src/tinystates.asm +++ b/src/tinystates.asm @@ -132,14 +132,19 @@ post_load_state: .rng ; Rerandomize - LDA !sram_save_has_set_rng : BNE .done - LDA !sram_rerandomize : BEQ .done + LDA !sram_save_has_set_rng : BNE .randomizeOnLoad + LDA !sram_rerandomize : BEQ .randomizeOnLoad LDA !SRAM_SAVED_RNG : STA !CACHED_RANDOM_NUMBER LDA !SRAM_SAVED_FRAME_COUNTER : STA !FRAME_COUNTER LDA !sram_seed_X : STA !ram_seed_X LDA !sram_seed_Y : STA !ram_seed_Y JSL MenuRNG ; rerandomize hack RNG + .randomizeOnLoad + ; Randomize energy/ammo? + LDA !ram_loadstate_rando_enable : BEQ .done + JSL RandomizeOnLoad + .done JSL init_wram_based_on_sram From 4a292093b3a2b593ba3247cc74cc79df952c934f Mon Sep 17 00:00:00 2001 From: idle Date: Fri, 14 Mar 2025 20:51:05 -0500 Subject: [PATCH 2/6] Fix small zebetites --- resources/ntsc_to_pal_abridged_pseudo_patch.txt | 10 ++++++++-- src/fanfare.asm | 4 ++-- src/freespace.asm | 7 ++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/resources/ntsc_to_pal_abridged_pseudo_patch.txt b/resources/ntsc_to_pal_abridged_pseudo_patch.txt index 1f0f9d32..91cc35ea 100644 --- a/resources/ntsc_to_pal_abridged_pseudo_patch.txt +++ b/resources/ntsc_to_pal_abridged_pseudo_patch.txt @@ -63,6 +63,12 @@ org $80FFD9 ; Bank 81 ;======================================================= +; Freespace +org $81EF1A + +; Thanks +org $81FF00 + ; Freespace org $81FF60 @@ -2673,7 +2679,7 @@ org $9BC645 org $9BCBFB ; Samus tiles -org $9BCBFB +org $9BE000 ; Freespace (used by SpriteSomething) org $9BFDA0 @@ -4887,7 +4893,7 @@ org $C2B5E4 org $C2B6BB ; Freespace -org $CEB22D +org $CEB22E ;======================================================= ; Bank CF diff --git a/src/fanfare.asm b/src/fanfare.asm index a5aaedb3..dc479e85 100644 --- a/src/fanfare.asm +++ b/src/fanfare.asm @@ -43,9 +43,9 @@ original_button_tilemap_offset_table: dw #$8436, #$8289, EndFanfareText dw #$8436, #$8289, EndFanfareText -%startfree(85) ;;; Message text must be listed in order +org $859643 table ../resources/HUDfont.tbl EnemiesKilledText: dw #$000E, #$000E, #$000E, #$000E, #$000E, #$000E @@ -204,7 +204,7 @@ SpecialButtonTilemapOffsets: dw #$0000 ; 25h: dw #$0000 ; 26h: Reserved -%endfree(85) +warnpc $85A000 endif diff --git a/src/freespace.asm b/src/freespace.asm index b9f71bbe..30b4f59b 100644 --- a/src/freespace.asm +++ b/src/freespace.asm @@ -10,7 +10,8 @@ ; Logic expects custom doors are placed at or after $83C000 !START_FREESPACE_83 = $83C000 ; $529A !START_FREESPACE_84 = $84EFD9 ; $1027 (PAL) -!START_FREESPACE_85 = $859643 ; $69BF +; Leave space for custom fanfare text to immediately follow vanilla text +!START_FREESPACE_85 = $85A000 ; $69BF !START_FREESPACE_86 = $86F4E2 ; $B1E (PAL) !START_FREESPACE_87 = $87C964 ; $369C !START_FREESPACE_88 = $88EE32 ; $11CE @@ -44,7 +45,7 @@ endif !START_FREESPACE_A3 = $A3F32D ; $CD3 (PAL) !START_FREESPACE_A4 = $A4F6D9 ; $927 (PAL) !START_FREESPACE_A5 = $A5F99F ; $661 (PAL) -!START_FREESPACE_A6 = $A6FE93 ; $16D (PAL) +!START_FREESPACE_A6 = $A6FEBC ; $144 !START_FREESPACE_A7 = $A7FFB6 ; $4A (PAL) !START_FREESPACE_A8 = $A8F9CD ; $633 (PAL) !START_FREESPACE_A9 = $A9FBBD ; $443 (PAL) @@ -64,7 +65,7 @@ endif !START_FREESPACE_B8 = $B88000 ; $8000 !START_FREESPACE_CE = $CEB22E ; $4DD2 !START_FREESPACE_DE = $DED1C0 ; $2E40 -!START_FREESPACE_DF = $DF8000 ; $8000 +!START_FREESPACE_DF = $DFD500 ; $2B21 !START_FREESPACE_E0 = $E08000 ; $8000 !START_FREESPACE_E1 = $E18000 ; $8000 !START_FREESPACE_E2 = $E28000 ; $8000 From eb4dcf5f892ba4af17444c78be04913aa80aaa40 Mon Sep 17 00:00:00 2001 From: idle Date: Fri, 14 Mar 2025 20:56:34 -0500 Subject: [PATCH 3/6] Add options to set escape timer starting values --- src/defines.asm | 7 ++++++ src/gamemenu.asm | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ src/gamemode.asm | 3 +++ src/infohud.asm | 30 +++++++++++++++++++++++ src/init.asm | 2 ++ src/mainmenu.asm | 57 +++++++++++++++++++++++++++++++++++++++++- src/symbols.asm | 5 ++++ 7 files changed, 167 insertions(+), 1 deletion(-) diff --git a/src/defines.asm b/src/defines.asm index 103145ed..a78c2285 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -322,6 +322,9 @@ !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 @@ -528,6 +531,8 @@ !sram_infidoppler_enabled = !SRAM_START+$9A !sram_random_bubble_sfx = !SRAM_START+$9C !sram_demo_timer = !SRAM_START+$9E +!sram_ceres_timer = !SRAM_START+$A0 +!sram_zebes_timer = !SRAM_START+$A2 ; ^ FREE SPACE ^ up to +$EE @@ -762,6 +767,8 @@ !DOOR_FINISHED_SCROLLING = $0931 !CERES_STATUS = $093F !TIMER_STATUS = $0943 +!TIMER_CENTISECONDS = $0945 +!TIMER_SECONDS_MINUTES = $0946 !CURRENT_SAVE_FILE = $0952 !GAMEMODE = $0998 !DOOR_FUNCTION_POINTER = $099C diff --git a/src/gamemenu.asm b/src/gamemenu.asm index c6b3a447..dbbdaa31 100644 --- a/src/gamemenu.asm +++ b/src/gamemenu.asm @@ -13,6 +13,8 @@ GameMenu: dw #$FFFF dw #game_cutscenes dw #game_demo_wait_timer + dw #game_ceres_escape_timer + dw #game_zebes_escape_timer dw #game_fast_doors_toggle dw #game_fast_elevators dw #$FFFF @@ -50,6 +52,68 @@ game_cutscenes: game_demo_wait_timer: %cm_numfield_word("Demo Timer (frames)", !sram_demo_timer, 1, 9999, 1, 20, #0) +game_ceres_escape_timer: + %cm_numfield_word("Ceres Timer (seconds)", !ram_cm_ceres_seconds, 1, 5999, 1, 20, .routine) + .routine + LDA !ram_cm_ceres_seconds : STA $4204 + %a8() + LDA.b #$0A : STA $4206 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : STA !sram_ceres_timer + LDA $4214 : BEQ .end + STA $4204 + %a8() + LDA.b #$06 : STA $4206 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : ASL #4 + ORA !sram_ceres_timer : STA !sram_ceres_timer + LDA $4214 : BEQ .end + STA $4204 + %a8() + LDA.b #$0A : STA $4206 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : XBA + ORA !sram_ceres_timer : STA !sram_ceres_timer + LDA $4214 : BEQ .end + XBA : ASL #4 + ORA !sram_ceres_timer : STA !sram_ceres_timer + .end + RTL + +game_zebes_escape_timer: + %cm_numfield_word("Zebes Timer (seconds)", !ram_cm_zebes_seconds, 1, 5999, 1, 20, .routine) + .routine + LDA !ram_cm_zebes_seconds : STA $4204 + %a8() + LDA.b #$0A : STA $4206 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : STA !sram_zebes_timer + LDA $4214 : BEQ .end + STA $4204 + %a8() + LDA.b #$06 : STA $4206 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : ASL #4 + ORA !sram_zebes_timer : STA !sram_zebes_timer + LDA $4214 : BEQ .end + %a8() + STA $4204 + LDA.b #$0A : STA $4206 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : XBA + ORA !sram_zebes_timer : STA !sram_zebes_timer + LDA $4214 : BEQ .end + XBA : ASL #4 + ORA !sram_zebes_timer : STA !sram_zebes_timer + .end + RTL + game_fast_doors_toggle: %cm_toggle("Fast Doors", !sram_fast_doors, #$01, #0) diff --git a/src/gamemode.asm b/src/gamemode.asm index 0eca9370..229f2f05 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -304,12 +304,15 @@ endif 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 +endif %sfxconfirm() ; CLC to continue normal gameplay after reveal damage LDA !sram_ctrl_reveal_damage diff --git a/src/infohud.asm b/src/infohud.asm index 0b2c49f0..dcd5c950 100644 --- a/src/infohud.asm +++ b/src/infohud.asm @@ -15,6 +15,11 @@ org $8095FC ; hijack, end of NMI routine to update realtime frames org $809609 ; inc counter if NMI lag branch INC !REALTIME_LAG_COUNTER +org $809DFD +hook_start_escape_timers: + dw #ih_set_ceres_timer + dw #ih_set_zebes_timer + if !FEATURE_VANILLAHUD else org $809B48 ; hijack, HUD routine (game timer by Quote58) @@ -2103,6 +2108,30 @@ endif JMP $9B51 } +ih_set_ceres_timer: +{ + JSL $809E93 + LDA !sram_ceres_timer + JSL $809E8C + LDA #$8003 + STA !TIMER_STATUS + CLC + RTS +} + +ih_set_zebes_timer: +{ + JSL $809E93 + LDA !sram_zebes_timer + JSL $809E8C + LDA #$8003 + STA !TIMER_STATUS + CLC + RTS +} + +if !FEATURE_VANILLAHUD +else NumberGFXTable: dw #$0C09, #$0C00, #$0C01, #$0C02, #$0C03, #$0C04, #$0C05, #$0C06, #$0C07, #$0C08 dw #$0C70, #$0C71, #$0C72, #$0C73, #$0C74, #$0C75, #$0C78, #$0C79, #$0C7A, #$0C7B @@ -2144,6 +2173,7 @@ HexToNumberGFX2: dw #$0C09, #$0C00, #$0C01, #$0C02, #$0C03, #$0C04, #$0C05, #$0C06, #$0C07, #$0C08 dw #$0C09, #$0C00, #$0C01, #$0C02, #$0C03, #$0C04, #$0C05, #$0C06, #$0C07, #$0C08 dw #$0C09, #$0C00, #$0C01, #$0C02, #$0C03, #$0C04, #$0C05, #$0C06, #$0C07, #$0C08 +endif %endfree(80) diff --git a/src/init.asm b/src/init.asm index b41164bf..795284d4 100644 --- a/src/init.asm +++ b/src/init.asm @@ -215,6 +215,8 @@ endif STA !sram_loadstate_rando_supers STA !sram_loadstate_rando_powerbombs LDA #$0384 : STA !sram_demo_timer + LDA #$0100 : STA !sram_ceres_timer + LDA #$0300 : STA !sram_zebes_timer LDA !SRAM_VERSION : STA !sram_initialized RTS diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 3cc05b2a..58396c80 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -29,6 +29,61 @@ action_brb_mainmenu: ; Set reasonable cycle time values LDA #$000A : STA !ram_cm_brb_set_cycle LDA #$0258 : STA !ram_cm_brb_cycle_time + JMP action_mainmenu +} + +action_game_mainmenu: +{ + ; Each hexadecimal nibble represents a decimal + ; Convert to plain number to allow user to set it + + ; Start with most significant nibble, divide by 512, multiply by 75 + LDA !sram_ceres_timer : AND #$F000 : XBA : LSR + %a8() + STA $4202 : LDA #$4B : STA $4203 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : STA !ram_cm_ceres_seconds + LDA !sram_zebes_timer : AND #$F000 : XBA : LSR + %a8() + STA $4202 : LDA #$4B : STA $4203 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : STA !ram_cm_zebes_seconds + + ; Next nibble, divide by 256, multiply by 60 + LDA !sram_ceres_timer : AND #$0F00 : XBA + %a8() + STA $4202 : LDA #$3C : STA $4203 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : CLC : ADC !ram_cm_ceres_seconds : STA !ram_cm_ceres_seconds + LDA !sram_zebes_timer : AND #$0F00 : XBA + %a8() + STA $4202 : LDA #$3C : STA $4203 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : CLC : ADC !ram_cm_zebes_seconds : STA !ram_cm_zebes_seconds + + ; Next nibble, divide by 8, multiply by 5 + LDA !sram_ceres_timer : AND #$00F0 : LSR #3 + %a8() + STA $4202 : LDA #$05 : STA $4203 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : CLC : ADC !ram_cm_ceres_seconds : STA !ram_cm_ceres_seconds + LDA !sram_zebes_timer : AND #$00F0 : LSR #3 + %a8() + STA $4202 : LDA #$05 : STA $4203 + %a16() + PEA $0000 : PLA ; wait for CPU math + LDA $4216 : CLC : ADC !ram_cm_zebes_seconds : STA !ram_cm_zebes_seconds + + ; Least significant nibble + LDA !sram_ceres_timer : AND #$000F + 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 BRA action_mainmenu } @@ -290,7 +345,7 @@ mm_goto_layout: %cm_jsl("Room Layout", #action_layout_mainmenu, #LayoutMenu) mm_goto_gamemenu: - %cm_mainmenu("Game Options", #GameMenu) + %cm_jsl("Game Options", #action_game_mainmenu, #GameMenu) mm_goto_rngmenu: %cm_jsl("RNG Control", #action_rng_mainmenu, #RngMenu) diff --git a/src/symbols.asm b/src/symbols.asm index e6b0cd26..3d602a3d 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -320,6 +320,9 @@ 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 @@ -510,6 +513,8 @@ sram_superhud_top = !sram_superhud_top ; !SRAM_START+$98 sram_infidoppler_enabled = !sram_infidoppler_enabled ; !SRAM_START+$9A sram_random_bubble_sfx = !sram_random_bubble_sfx ; !SRAM_START+$9C 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 From a236aa1d521f5ff4fa52da7fa34f66a422c4ed3a Mon Sep 17 00:00:00 2001 From: idle Date: Sat, 15 Mar 2025 15:04:12 -0500 Subject: [PATCH 4/6] Door portals enable map rando layout modifications --- src/layout.asm | 394 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 352 insertions(+), 42 deletions(-) diff --git a/src/layout.asm b/src/layout.asm index a8b0edf0..44056480 100644 --- a/src/layout.asm +++ b/src/layout.asm @@ -294,13 +294,10 @@ hijack_after_load_level_data: .checkRoom ; Several rooms need to be handled before the door scroll LDA !ROOM_ID : CMP #ROOM_EastTunnel : BEQ .eastTunnel + CMP #ROOM_MainStreet : BEQ .mainStreet CMP #ROOM_PantsRoom : BEQ .pantsRoom - CMP #ROOM_BelowBotwoonETank : BNE .done - - LDA !sram_room_layout : BIT !ROOM_LAYOUT_AREA_RANDO : BEQ .done - JSL layout_asm_aqueductfarmsandpit_external - - .done + CMP #ROOM_BelowBotwoonETank : BEQ .belowBotwoonETank + CMP #ROOM_MotherBrainRoom : BEQ .mb JMP $E38E .eastTunnel @@ -308,10 +305,31 @@ hijack_after_load_level_data: JSL layout_asm_easttunnel_external JMP $E38E + .mainStreet + LDA !ram_door_portal_flags : AND !DOOR_PORTAL_MODE_MASK : CMP #$0002 : BNE .done + LDA !ram_door_source : ASL : TAX + LDA portals_left_vanilla_table,X : CMP #$A3CC : BNE .done + JSL layout_asm_mainstreet_external + JMP $E38E + .pantsRoom LDA !sram_room_layout : BIT !ROOM_LAYOUT_DASH_RECALL : BEQ .done JSL layout_asm_pants_external JMP $E38E + + .belowBotwoonETank + LDA !sram_room_layout : BIT !ROOM_LAYOUT_AREA_RANDO : BEQ .done + JSL layout_asm_aqueductfarmsandpit_external + + .done + JMP $E38E + + .mb + LDA !ram_door_portal_flags : AND !DOOR_PORTAL_MODE_MASK : CMP #$0002 : BNE .done + LDA !ram_door_source : ASL : TAX + LDA portals_left_vanilla_table,X : CMP #$AA80 : BNE .done + JSL layout_asm_mb_external + JMP $E38E } hijack_door_closing_plm: @@ -430,15 +448,30 @@ hook_layout_asm_pants_to_pants: dw #$8000 dw #layout_asm_pants_to_pants_scrolls +; Tourian Escape 1 right door +org $83AA96 +hook_layout_asm_motherbrain_door1: + dw #layout_asm_mb_to_tourian + ; Mother Brain right door org $83AAD2 hook_layout_asm_rinkashaft_door2: dw #layout_asm_mbhp +; Mother Brain left door direction (keep door open) +org $83AAE3 +hook_layout_direction_tourianescape1_door0: + db $00 + ; Mother Brain left door org $83AAEA hook_layout_asm_tourianescape1_door0: - dw #layout_asm_mbhp + dw #layout_asm_mb_spawn_escape_door + +; Tourian Escape 1 bottom door +org $83AB02 +hook_layout_asm_tourianescape2_door0: + dw #layout_asm_tourianescape1 ; Magnet Stairs left door org $83AB6E @@ -1050,6 +1083,25 @@ layout_asm_easttunnel_external: RTL } +layout_asm_mainstreet_external: +{ + ; Expand tunnel entrance + LDA #$8D21 : STA $7F0E3A + LDA #$892D : STA $7F0E3C : STA $7F0E3E : STA $7F0E40 + LDA #$8522 : STA $7F0E9A : STA $7F0EFA + LDA #$8D23 : STA $7F0F5A + LDA #$812D : STA $7F101C : STA $7F101E : STA $7F1020 + LDA #$00FF : STA $7F0E9C : STA $7F0EFC : STA $7F0F5C + STA $7F0E9E : STA $7F0EFE : STA $7F0F5E : STA $7F0FBE + LDA #$90FF : STA $7F0EA0 : STA $7F0F00 : STA $7F0F60 : STA $7F0FC0 + + ; Set door BTS + %a8() + LDA #$04 : STA $7F6B51 : STA $7F6B81 : STA $7F6BB1 + %a16() + RTL +} + layout_asm_plasma_external: { ; Add platform and surrounding decoration @@ -1273,12 +1325,81 @@ layout_asm_waterway_external: RTL } +layout_asm_mb_external: +{ + ; Replace MB enemy with maprando variant + LDA #layout_maprando_mb_enemy_header : STA !ENEMY_ID+$40 + + ; Place the four barrier ceiling + LDA #$82E6 : STA $7F016E : STA $7F0170 : STA $7F0172 + LDA #$8AE8 : STA $7F01EE : STA $7F01F0 : STA $7F01F2 : STA $7F01F4 + INC : STA $7F016C + + ; Place the four barrier floor + LDA #$82E8 : STA $7F056E : STA $7F0570 : STA $7F0572 : STA $7F0574 + LDA #$82E0 : STA $7F05EE : STA $7F05F0 : STA $7F05F2 : STA $7F05F4 + INC : STA $7F06EE : STA $7F06F4 + LDA #$830F : STA $7F066E : STA $7F0674 + + ; Clear slopes + TDC : STA $7F64B7 : STA $7F64B9 + STA $7F66BC : STA $7F66BE : STA $7F6778 : STA $7F677A + LDA #$8351 : STA $7F0576 + LDA #$82EF : STA $7F0578 : STA $7F057A + LDA #$830B : STA $7F057C + + ; Place barriers depending on boss flags + LDA $7ED828 : BIT #$0100 : BNE .kraid_dead + LDA $7ED82A : BIT #$0100 : BNE .phantoon_dead + LDA $7ED82C : BIT #$0001 : BNE .two_or_three_alive + LDA $7ED82A : BIT #$0001 : BNE .three_alive + LDA #$830F : STA $7F026E : STA $7F02EE : STA $7F036E + STA $7F03EE : STA $7F046E : STA $7F04EE + BRA .three_alive + + .phantoon_dead + LDA $7ED82C : BIT #$0001 : BEQ .two_or_three_alive + .one_or_two_alive + LDA $7ED82A : BIT #$0001 : BNE .one_alive + BRA .two_alive + + .kraid_dead + LDA $7ED82A : BIT #$0100 : BNE .kraid_phantoon_dead + LDA $7ED82C : BIT #$0001 : BNE .one_or_two_alive + .two_or_three_alive + LDA $7ED82A : BIT #$0001 : BNE .two_alive + + .three_alive + LDA #$830F : STA $7F0270 : STA $7F02F0 : STA $7F0370 + STA $7F03F0 : STA $7F0470 : STA $7F04F0 + + .two_alive + LDA #$830F : STA $7F0272 : STA $7F02F2 : STA $7F0372 + STA $7F03F2 : STA $7F0472 : STA $7F04F2 + BRA .one_alive + + .kraid_phantoon_dead + LDA $7ED82C : BIT #$0001 : BEQ .one_or_two_alive + LDA $7ED82A : BIT #$0001 : BNE .all_dead + + .one_alive + LDA #$830F : STA $7F0274 : STA $7F02F4 : STA $7F0374 + STA $7F03F4 : STA $7F0474 : STA $7F04F4 + + .all_dead + RTL +} + %endfree(83) -; Allow debug save stations to be used -org $848D0C - AND #$000F +; Ignore bombs for bomb torizo with VARIA tweaks +org $848258 +layout_bomb_torizo_finish_crumbling: + INC $1D27,X : INC $1D27,X + LDA #$D356 : STA $1CD7,X + RTS +warnpc $848270 ; Relocate grey door preinstruction table and add new type that has no prerequisite to begin flashing org $848C4F @@ -1286,21 +1407,27 @@ layout_grey_door_preinstruction_table: dw $BDD4, $BDE3, $BDF2, $BE01, $BE1C, $BE1F, $BE30, $BDB2 warnpc $848C7C -org $84BE43 - LDA layout_grey_door_preinstruction_table,Y +; Allow debug save stations to be used +org $848D0C + AND #$000F -; Ignore bombs for bomb torizo with VARIA tweaks -org $848258 -layout_bomb_torizo_finish_crumbling: - INC $1D27,X : INC $1D27,X - LDA #$D356 : STA $1CD7,X - RTS -warnpc $848270 +; Instruction set to restore MB escape wall +org $8494C9 +layout_restore_mb_escape_wall: + dw $8004, $8B0F, $8AE8, $82E8, $830F + db $01, $00 + dw $8004, $8B0F, $8AE8, $82E8, $830F + dw $0000 +warnpc $849505 org $84AADF layout_save_station_mini_entry: dw $B5EE, #layout_save_station_mini_instructions +org $84AC01 +hook_layout_restore_mb_escape_wall: + dw #layout_restore_mb_escape_wall + org $84BA4C layout_bomb_grey_door_original_instructions: @@ -1335,25 +1462,13 @@ warnpc $84BAF4 org $84BAF8 dw layout_bomb_grey_door_new_instructions -org $84D33B -layout_bomb_torizo_crumbling_preinstruction: - LDA !sram_room_layout : BIT !ROOM_LAYOUT_VARIA_TWEAKS : BNE layout_bomb_torizo_end_preinstruction - LDA !SAMUS_ITEMS_COLLECTED : AND #$1000 : BEQ layout_bomb_torizo_end_preinstruction - -layout_bomb_torizo_start_crumbling: - LDA #$0001 : STA $7EDE1C,X - JMP layout_bomb_torizo_finish_crumbling - -layout_bomb_torizo_end_preinstruction: -warnpc $84D356 +org $84BE43 + LDA layout_grey_door_preinstruction_table,Y -if !FEATURE_PAL -org $84E543 -else -org $84E53D -endif -hook_layout_bomb_set_room_argument: - dw #layout_bomb_set_room_argument +; Allow spazer blocks to be shot +org $84D014 +layout_spazer_block_plm_entry: + dw #layout_spazer_block_plm, $CBB7 ; Ignore picky chozo in DASH or VARIA tweaks org $84D18F @@ -1375,10 +1490,17 @@ warnpc $84D1C1 org $84D1DE layout_picky_chozo_end: -; Allow spazer blocks to be shot -org $84D014 -layout_spazer_block_plm_entry: - dw #layout_spazer_block_plm, $CBB7 +org $84D33B +layout_bomb_torizo_crumbling_preinstruction: + LDA !sram_room_layout : BIT !ROOM_LAYOUT_VARIA_TWEAKS : BNE layout_bomb_torizo_end_preinstruction + LDA !SAMUS_ITEMS_COLLECTED : AND #$1000 : BEQ layout_bomb_torizo_end_preinstruction + +layout_bomb_torizo_start_crumbling: + LDA #$0001 : STA $7EDE1C,X + JMP layout_bomb_torizo_finish_crumbling + +layout_bomb_torizo_end_preinstruction: +warnpc $84D356 org $84D476 layout_spazer_block_plm: @@ -1391,6 +1513,14 @@ layout_spazer_block_plm: } warnpc $84D490 +if !FEATURE_PAL +org $84E543 +else +org $84E53D +endif +hook_layout_bomb_set_room_argument: + dw #layout_bomb_set_room_argument + ; Fix Morph Ball Hidden/Chozo PLM's if !FEATURE_PAL org $84E8D4 @@ -1467,6 +1597,17 @@ layout_bomb_grey_door_check_fast: RTS } +layout_fix_mb_escape_wall: +{ + ; Overwritten logic + STA !ENEMY_FUNCTION_POINTER + + ; Custom PLM that restores escape wall + JSL $8483D7 + dw $0600, $B66F + RTL +} + %endfree(84) @@ -1861,6 +2002,11 @@ org $8FD0AF hook_layout_asm_crabtunnel: dw #layout_asm_crabtunnel +; Mt Everest setup asm +org $8FD0DE +hook_layout_asm_mteverest: + dw #layout_asm_mteverest + ; Red Fish setup asm org $8FD129 hook_layout_asm_redfish: @@ -1921,6 +2067,11 @@ org $8FDCDB hook_layout_asm_big_boy: dw #layout_asm_big_boy +; Mother Brain state check asm +org $8FDD67 +hook_layout_asm_mb_state_check: + dw #layout_asm_mb_state_check + ; Tourian escape 2 main asm org $8FDE99 hook_layout_main_asm_tourian_escape_2: @@ -2123,6 +2274,37 @@ layout_asm_cutscene_g4skip: RTS } +layout_asm_maprando_mb_header: + dl $CDDEDE + db $0E, $00, $00 + dw $A0A4, #layout_asm_maprando_mb_enemies, #layout_asm_maprando_mb_enemy_set + dw $C1C1, $DDC0, $0000, $0000, $C84F, $E48A, $C91E + +layout_asm_mb_state_check: +{ + 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 #$AA80 : BNE .vanilla + LDX #layout_asm_maprando_mb_header + JMP $E5E6 + .vanilla + LDX #$DD6E + JMP $E5E6 +} + +layout_asm_mb_spawn_escape_door: +{ + ; Spawn Mother Brain's room escape door + JSL $8483D7 + dw $0600, $B677 + + ; Replace MB enemy with maprando variant + LDA #layout_maprando_mb_enemy_header : STA !ENEMY_ID+$40 + + ; Fallthrough to Mother Brain HP +} + layout_asm_mbhp: { if !FEATURE_VANILLAHUD @@ -2136,6 +2318,36 @@ endif ; !FEATURE_VANILLAHUD RTS } +layout_asm_mb_to_tourian: +{ + LDA !ram_door_portal_flags : AND !DOOR_PORTAL_MODE_MASK + CMP #$0002 : BNE layout_asm_mbhp_done + LDA !ram_door_source : ASL : TAX + LDA portals_left_vanilla_table,X : CMP #$AAE0 : BNE layout_asm_mbhp_done + + ; Set door direction to keep gate from appearing + LDA #$0001 : STA !DOOR_DIRECTION + + ; Fallthrough to delete gate PLM +} + +layout_asm_tourianescape1_remove_plm: +{ + ; Relocate and delete gate PLM that blocks the door + LDA #$05BE : STA $1CD3 + LDA #!PLM_DELETE : STA $1D73 + RTS +} + +layout_asm_tourianescape1: +{ + LDA !ram_door_portal_flags : AND !DOOR_PORTAL_MODE_MASK + CMP #$0002 : BNE layout_asm_mbhp_done + LDA !ram_door_source : ASL : TAX + LDA portals_left_vanilla_table,X : CMP #$AAE0 : BEQ layout_asm_tourianescape1_remove_plm + RTS +} + layout_asm_ceres_ridley_state_check: { LDA !TIMER_STATUS : BEQ .noTimer @@ -2411,11 +2623,34 @@ layout_asm_crabtunnel_done: layout_asm_crabtunnel_savestation_plm_data: db #$DF, #$AA, #$07, #$0D, #$05, #$00 +layout_asm_mteverest: +{ + PHP + %ai16() + + LDA !ram_door_portal_flags : AND !DOOR_PORTAL_MODE_MASK + CMP #$0002 : BNE layout_asm_crabtunnel_done + LDA !ram_door_destination : ASL : TAX + LDA portals_right_vanilla_table,X : CMP #$A45C : BNE layout_asm_crabtunnel_done + + ; Expand hidden door and space in front of door + LDA #$911D : STA $7F1CA2 : STA $7F1D62 : STA $7F1E22 + LDA #$011D : STA $7F1CA4 : STA $7F1D64 : STA $7F1E24 : STA $7F1EE4 + STA $7F1CA6 : STA $7F1D66 : STA $7F1E26 : STA $7F1EE6 + + %a8() + LDA #$04 : STA $7F7252 : STA $7F72B2 : STA $7F7312 +} + +layout_asm_mteverest_done: + PLP + RTS + layout_asm_easttunnel: { PHP %ai16() - LDA !sram_room_layout : BIT !ROOM_LAYOUT_AREA_RANDO : BEQ layout_asm_crabtunnel_done + LDA !sram_room_layout : BIT !ROOM_LAYOUT_AREA_RANDO : BEQ layout_asm_mteverest_done ; Add flashing door PLMs PHX : LDX #layout_asm_easttunnel_lower_door_plm_data @@ -3546,32 +3781,107 @@ layout_asm_pants_to_pants_scrolls: %endfree(8F) +%startfree(A0) + +layout_maprando_mb_enemy_header: +if !FEATURE_PAL + dw $1000, $9482, $4650, $0078, $0010, $0010, $00A9, $0000 + dw $000A, $8715, $0001, $0000, $879B, $800F, $879B, $8041 + dw $0000, $0000, $0000, $0000, $8797, $0000, $0000, $0000 + dw $B613, $B554, $0000, $8000, $05B7, $F49A +else + dw $1000, $9472, $4650, $0078, $0010, $0010, $00A9, $0000 + dw $000A, $8705, $0001, $0000, $878B, $800F, $878B, $8041 + dw $0000, $0000, $0000, $0000, $8787, $0000, $0000, $0000 + dw $B5C6, $B507, $0000, $8000, $05B7, $F49A +endif + dw layout_maprando_mb_vulnerabilities, $0000 + +%endfree(A0) + + %startfree(A1) layout_asm_plasma_dash_enemies: +if !FEATURE_PAL + dw $F6B3, #$0100, #$0080, #$0000, #$2000, #$0004, #$8001, #$0020 + dw $F6B3, #$0080, #$01D0, #$0000, #$2000, #$0004, #$8000, #$0030 + dw $F6B3, #$01B0, #$01D0, #$0000, #$2000, #$0004, #$8001, #$0030 + dw $F3B3, #$0030, #$0180, #$0000, #$2000, #$0004, #$0000, #$01A0 + dw $F3B3, #$01D0, #$0130, #$0000, #$2000, #$0004, #$0001, #$01A0 + dw $F6B3, #$0078, #$0280, #$0000, #$2000, #$0004, #$8001, #$0080 +else dw $F693, #$0100, #$0080, #$0000, #$2000, #$0004, #$8001, #$0020 dw $F693, #$0080, #$01D0, #$0000, #$2000, #$0004, #$8000, #$0030 dw $F693, #$01B0, #$01D0, #$0000, #$2000, #$0004, #$8001, #$0030 dw $F393, #$0030, #$0180, #$0000, #$2000, #$0004, #$0000, #$01A0 dw $F393, #$01D0, #$0130, #$0000, #$2000, #$0004, #$0001, #$01A0 dw $F693, #$0078, #$0280, #$0000, #$2000, #$0004, #$8001, #$0080 +endif db #$FF, #$FF, #$06 layout_asm_statues_oob_viewer_enemies: +if !FEATURE_PAL + dw $D75F, #$0080, #$01B0, #$0000, #$2C00, #$0000, #$0000, #$0240 +else dw $D73F, #$0080, #$01B0, #$0000, #$2C00, #$0000, #$0000, #$0240 +endif + db #$FF, #$FF, #$00 + +layout_asm_maprando_mb_enemies: +if !FEATURE_PAL + dw $EC9F, #$0081, #$006F, #$0000, #$2800, #$0004, #$0000, #$0000 +else + dw $EC7F, #$0081, #$006F, #$0000, #$2800, #$0004, #$0000, #$0000 +endif + dw #layout_maprando_mb_enemy_header + dw #$0081, #$006F, #$0000, #$2800, #$0004, #$0000, #$0000 +if !FEATURE_PAL + dw $E29F, #$0081, #$0000, #$0000, #$2000, #$0000, #$0000, #$0000 + dw $D25F, #$0337, #$0036, #$0000, #$6000, #$0000, #$0001, #$0000 + dw $D25F, #$0337, #$00A6, #$0000, #$6000, #$0000, #$0002, #$0000 + dw $D25F, #$0277, #$001C, #$0000, #$6000, #$0000, #$0003, #$0000 +else + dw $E27F, #$0081, #$0000, #$0000, #$2000, #$0000, #$0000, #$0000 + dw $D23F, #$0337, #$0036, #$0000, #$6000, #$0000, #$0001, #$0000 + dw $D23F, #$0337, #$00A6, #$0000, #$6000, #$0000, #$0002, #$0000 + dw $D23F, #$0277, #$001C, #$0000, #$6000, #$0000, #$0003, #$0000 +endif db #$FF, #$FF, #$00 %endfree(A1) +; Restore escape wall after MB1 in case of left entry +org $ADE3D1 + JSL layout_fix_mb_escape_wall + + %startfree(B4) layout_asm_plasma_dash_enemy_set: +if !FEATURE_PAL + dw $F6B3, #$0001, $F3B3, #$0002 +else dw $F693, #$0001, $F393, #$0002 +endif db #$FF, #$FF, #$00 layout_asm_statues_oob_viewer_enemy_set: db #$FF, #$FF, #$00 +layout_asm_maprando_mb_enemy_set: + dw #layout_maprando_mb_enemy_header, #$0001 +if !FEATURE_PAL + dw $D25F, #$0002, $EC9F, #$0001 +else + dw $D23F, #$0002, $EC7F, #$0001 +endif + db #$FF, #$FF, #$00 + +layout_maprando_mb_vulnerabilities: + db #$80, #$80, #$80, #$80, #$80, #$80, #$80, #$80, #$80, #$80, #$80, #$80 + db #$82, #$84, #$80, #$80, #$80, #$80, #$80, #$02, #$80, #$80 + %endfree(B4) From 45ecdee7aaefaa4fbd01770d7629ac1723690020 Mon Sep 17 00:00:00 2001 From: idle Date: Sat, 15 Mar 2025 15:40:23 -0500 Subject: [PATCH 5/6] Fix Door HUD mode issues --- src/infohud.asm | 24 ++++++++++++------------ src/infohudmodes.asm | 30 ++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/infohud.asm b/src/infohud.asm index dcd5c950..e7a5d3d3 100644 --- a/src/infohud.asm +++ b/src/infohud.asm @@ -1246,14 +1246,14 @@ Draw2: LDA #$0A : STA $4206 %a16() PEA $0000 : PLA ; wait for CPU math - LDA $4214 : STA $16 ; tens + LDA $4214 : STA $12 ; tens ; Ones digit LDA $4216 : ASL : TAY LDA.w NumberGFXTable,Y : STA !HUD_TILEMAP+2,X ; Tens digit - LDA $16 : BEQ .blanktens : ASL : TAY + LDA $12 : BEQ .blanktens : ASL : TAY LDA.w NumberGFXTable,Y : STA !HUD_TILEMAP,X .done @@ -1274,13 +1274,13 @@ Draw3: LDA #$0A : STA $4206 %a16() PEA $0000 : PLA ; wait for CPU math - LDA $4214 : STA $16 ; tens + LDA $4214 : STA $12 ; tens ; Ones digit LDA $4216 : ASL : TAY LDA.w NumberGFXTable,Y : STA !HUD_TILEMAP+4,X - LDA $16 : BEQ .blanktens + LDA $12 : BEQ .blanktens STA $4204 %a8() @@ -1288,14 +1288,14 @@ Draw3: LDA #$0A : STA $4206 %a16() PEA $0000 : PLA ; wait for CPU math - LDA $4214 : STA $14 ; hundreds + LDA $4214 : STA $12 ; hundreds ; Tens digit LDA $4216 : ASL : TAY LDA.w NumberGFXTable,Y : STA !HUD_TILEMAP+2,X ; Hundreds digit - LDA $14 : BEQ .blankhundreds : ASL : TAY + LDA $12 : BEQ .blankhundreds : ASL : TAY LDA.w NumberGFXTable,Y : STA !HUD_TILEMAP,X .done @@ -1320,13 +1320,13 @@ Draw4: LDA #$0A : STA $4206 %a16() PEA $0000 : PLA ; wait for CPU math - LDA $4214 : STA $16 ; tens + LDA $4214 : STA $12 ; tens ; Ones digit LDA $4216 : ASL : TAY LDA.w NumberGFXTable,Y : STA !HUD_TILEMAP+6,X - LDA $16 : BEQ .blanktens + LDA $12 : BEQ .blanktens STA $4204 %a8() @@ -1334,13 +1334,13 @@ Draw4: LDA #$0A : STA $4206 %a16() PEA $0000 : PLA ; wait for CPU math - LDA $4214 : STA $14 ; hundreds + LDA $4214 : STA $12 ; hundreds ; Tens digit LDA $4216 : ASL : TAY LDA.w NumberGFXTable,Y : STA !HUD_TILEMAP+4,X - LDA $14 : BEQ .blankhundreds + LDA $12 : BEQ .blankhundreds STA $4204 %a8() @@ -1454,13 +1454,13 @@ Draw4Hundredths: LDA #$0A : STA $4206 ; divide by 10 %a16() PEA $0000 : PLA ; wait for CPU math - LDA $4214 : STA $14 ; hundreds + LDA $4214 : STA $12 ; hundreds ; Tens digit LDA $4216 : ASL : TAY LDA.w NumberGFXTable,Y : STA !HUD_TILEMAP+6,X - LDA $14 : BEQ .zerohundreds + LDA $12 : BEQ .zerohundreds STA $4204 %a8() diff --git a/src/infohudmodes.asm b/src/infohudmodes.asm index a619ce19..036fd395 100644 --- a/src/infohudmodes.asm +++ b/src/infohudmodes.asm @@ -4908,6 +4908,8 @@ status_twocries_nosb: status_door_hspeed: { + LDA $12 : PHA + ; subspeed + submomentum into low byte of Hspeed LDA !SAMUS_X_SUBRUNSPEED : CLC : ADC !SAMUS_X_SUBMOMENTUM AND #$FF00 : XBA : STA !ram_momentum_sum @@ -4950,11 +4952,14 @@ status_door_hspeed: LDA.l HexGFXTable,X : STA !HUD_TILEMAP+$8E .done + PLA : STA $12 RTS } status_door_vspeed: { + LDA $12 : PHA + ; draw two digits of speed in decimal form LDA !SAMUS_Y_SPEED : STA $4204 %a8() @@ -4982,11 +4987,14 @@ status_door_vspeed: LDA !SAMUS_Y_SUBSPEED : XBA : AND #$00F0 : LSR #3 : TAY LDA.l HexGFXTable,X : STA !HUD_TILEMAP+$8C + PLA : STA $12 RTS } status_door_chargetimer: { + LDA $12 : PHA + LDA !SAMUS_CHARGE_TIMER : CMP #$003C : BPL .charged LDA #$003C : SEC : SBC !SAMUS_CHARGE_TIMER LDX #$0088 : JMP Draw4 @@ -4996,26 +5004,40 @@ status_door_chargetimer: LDA !IH_SHINESPARK : STA !HUD_TILEMAP+$8C LDA !SAMUS_CHARGE_TIMER : SEC : SBC #$003C ASL : TAX : LDA NumberGFXTable,X : STA !HUD_TILEMAP+$8E + + PLA : STA $12 RTS } status_door_shinetimer: { - LDA !ram_armed_shine_duration : LDX #$0088 : JMP Draw4 + LDA $12 : PHA + LDA !ram_armed_shine_duration : LDX #$0088 : JSR Draw4 + PLA : STA $12 + RTS } status_door_dashcounter: { - LDA !SAMUS_DASH_COUNTER : LDX #$0088 : JMP Draw4 + LDA $12 : PHA + LDA !SAMUS_DASH_COUNTER : LDX #$0088 : JSR Draw4 + PLA : STA $12 + RTS } status_door_xpos: { - LDA !SAMUS_X : LDX #$0088 : JMP Draw4Hex + LDA $12 : PHA + LDA !SAMUS_X : LDX #$0088 : JSR Draw4Hex + PLA : STA $12 + RTS } status_door_ypos: { - LDA !SAMUS_Y : LDX #$0088 : JMP Draw4Hex + LDA $12 : PHA + LDA !SAMUS_Y : LDX #$0088 : JSR Draw4Hex + PLA : STA $12 + RTS } From 842778f672355ae2906361bc4375cedd3b6f7bdb Mon Sep 17 00:00:00 2001 From: idle Date: Sat, 15 Mar 2025 19:53:21 -0500 Subject: [PATCH 6/6] Release 2.6.7 --- web/data/changelog.mdx | 3 ++ web/data/config.json | 2 +- web/data/help.mdx | 37 ++++++++++++++++----- web/data/infohudmode.mdx | 71 +++++++++++++++++++++++++++------------- 4 files changed, 81 insertions(+), 32 deletions(-) diff --git a/web/data/changelog.mdx b/web/data/changelog.mdx index 46da2350..5a4cb487 100644 --- a/web/data/changelog.mdx +++ b/web/data/changelog.mdx @@ -27,6 +27,9 @@ - Added Super HUD and various other infohud modes and room strats (2.6.6) - Added custom HUD number graphics and Be Right Back screen (2.6.6) - Fix issue with savestate settings auto-save options (2.6.6.1) +- Port remaining features from IFB practice hack (2.6.7) +- Small fixes and added option to set escape timer starting values (2.6.7) +- Door portals enable map rando layout modifications (2.6.7) # Version 2.5.x - Added a separate version of savestates for MiSTer, Everdrives, and most modern emulators (not SNES Classic/VC) (2.5.0) diff --git a/web/data/config.json b/web/data/config.json index 55213413..3d7c555d 100644 --- a/web/data/config.json +++ b/web/data/config.json @@ -1,6 +1,6 @@ { "name": "Super Metroid Practice Hack", - "version": "2.6.6.1", + "version": "2.6.7", "variants": ["NTSC", "PAL"], "base": { "NTSC": { diff --git a/web/data/help.mdx b/web/data/help.mdx index 9a54ac4c..c1480a0d 100644 --- a/web/data/help.mdx +++ b/web/data/help.mdx @@ -86,11 +86,11 @@ If you experience crashes or severe glitches when using savestates, your platfor | | Only enable this if you are applying custom room palettes. | - Compressed Tables | Use built-in compressed tile tables when loading presets. | | -| **Teleport** | Warp to any save station or hidden debug load station +| **Save Stations** | Warp to any save station or hidden debug load station | | -| **Events** | Toggle event flags for events, bosses, items, doors, and map stations +| **Event Flags** | Toggle event flags for events, bosses, items, doors, and map stations | | -| **Misc** | Toggle extra features +| **Misc Options** | Toggle extra features | - Blue Suit | Give Samus the Blue Suit | - Flash Suit | Give Samus the Flash Suit (aka Spike Suit) | - Hyper Beam | Toggle Hyper Beam @@ -117,14 +117,16 @@ If you experience crashes or severe glitches when using savestates, your platfor | - Kill Enemies | Kills all non-solid enemies in the current room | - Force Samus to Stand Up | Forces Samus into a standing pose | | -| **Infohud** | Configure the HUD +| **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. | - 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. | - Top-Left Display | Choose item collection percentage, reserve energy, or vanilla health to be displayed at the top-left of the HUD. | | The vanilla options also compresses the viewable area so it is more suitable for practice on an curved CRT monitor or TV. | | Vanilla+ allows infohud mode or roomstrat to overwrite the energy text while Vanilla simply shows the energy text. @@ -135,7 +137,7 @@ If you experience crashes or severe glitches when using savestates, your platfor | - Artificial Lag | Select a value to adjust how much lag occurs during normal gameplay. | | This is to compensate for the lack of a minimap on the HUD which would normally consume CPU cycles. | - Customize RAM Watch | Setup addresses to be monitored by the RAM Watch HUD mode. Address 1 will appear in the bottom-left corner of the HUD, while Address 2 appears just to the right of Address 1. Memory at these locations can be edited by configuring a Value and selecting 'Write to Address'. Toggle 'Lock Value' to automatically write the value once every frame. RAM Watch must must be the selected HUD mode to continue writing to the address. Only one byte of hex can be configured at a time in the menu. 'Hi' refers to the first byte, while 'Lo' refers to the second. Set the Hi Address to 0D and the Lo Address to EC to monitor the memory address $0DEC, which stores the counter for Samus direction changes while held by Draygon (among other uses). You can find lists of known RAM addresses by selecting 'Select Common Addresses'. -| **Timer Settings** | Located within the Infohud menu +| **Timer Settings** | Located within the InfoHUD menu | - Frame Counters | Toggle the room timer in the top-right of the HUD between realtime, gametime, and "speedrun time". | | - Speedrun time is like realtime, except it includes time that was skipped due to practice hack features like shortened item fanfares, boss intros, door transitions, or elevators. This way, rooms and segments measured in the practice hack can be accurately compared to times from an actual run. | - Transition Lag | Toggle the door time to include the full length of the room transition. @@ -157,7 +159,8 @@ If you experience crashes or severe glitches when using savestates, your platfor | **Room Layout** | Modify the room layout, usually to help practice rando scenarios. | - Item Pickups | Option to replace all items with a specific item. Can also be done by icon type (visible, chozo orb, hidden). | - Bomb Torizo Door | Control Bomb Torizo Door oscillator, whether door waits 40 (fast) or 41 (slow) frames before closing after collecting bombs. -| - Remove Magnet Stairs | Adds slope tiles to prevent the magnet stairs effect. +| - Remove Steam Collision | Makes Ceres and Zebes escape steam intangible, and also changes the color of the steam indicating this option is enabled. +| - Remove Magnet Stairs | Adds slope tiles to prevent the magnet stairs effect, and also modifies the stair decoration indicating this option is enabled. | - Area Rando Patches | Room modifications as you would see in a VARIA area randomizer. | - Anti-Softlock Patches | Room modifications as you would see in a typical VARIA randomizer. | - VARIA Tweaks | Room modifications as you would see with VARIA tweaks enabled. @@ -171,23 +174,30 @@ If you experience crashes or severe glitches when using savestates, your platfor | - Select Portal Destination | Choose the other portal connection, also the one used for Next Door Jump To Dest. | - Select Portal Door | Choose a pair of aligned left/right or up/down portal connections. Note that some up doors do not exist in the vanilla game (some of the ones requiring you to go up through falling sand) so those cannot be travelled going up. | | -| **Game** | Toggle game options +| **Game Options** | Toggle game options | - Japanese/French Text | Standard game option to toggle between English and Japanese text (NTSC) or between German and French text (PAL). | - Moon Walk | Standard game option for Moon Walk. | - Icon Cancel | Standard game option for Icon Cancel. | - Controller Setting Mode | Allows controller bindings to be updated. | - Cutscenes and Effects | Turn off specific cutscenes, or make specific game sequences faster. | | Also includes karafruit's options to disable or reduce flashing effects. +| - Demo Timer | Set the amount of time you have to wait on the title screen before demos begin. +| - Ceres Timer | Override the initial starting time of 60 seconds to escape Ceres. +| - Zebes Timer | Override the initial starting time of 180 seconds to escape Zebes. | - Fast Doors | Toggle for fast doors similar to some randomizers. | - Fast Elevators | Toggle for fast elevators similar to some randomizers. +| - Top-Left Display | Choose item collection percentage, reserve energy, or vanilla health to be displayed at the top-left of the HUD. +| | The vanilla options also compresses the viewable area so it is more suitable for practice on an curved CRT monitor or TV. +| | Vanilla+ allows infohud mode or roomstrat to overwrite the energy text while Vanilla simply shows the energy text. | - 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. | - Clear Minimap | Clears the map tile counter and all minimap data. | - Force Map Grid Aligned | When set, prevents vanilla bug where pause menu map can become horizontally misaligned with the grid behind the map. -| **Debug Settings** | Located within the Game menu +| **Debug Settings** | Located within the Game Options menu | - Debug Mode | Toggles the debug mode. Note that debug mode shortcuts and features may not be well supported in the practice rom. | - PAL Debug Movement | Gives Samus extra movement correlated to the dpad input. | - Debug CPU Brightness | Toggles a built-in debug feature to darken the screen after the game is done processing the next frame. Useful for estimating CPU usage. | - Invincibility | Prevents Samus from taking damage or knockback. +| - Infinite Ammo | Sets ammo to maximum values and keeps it there. | - Deal Zero Damage | Reduces Samus' attack damage to zero, allowing for never-ending boss battles. | - Pseudo G-Mode | Disables PLMs to imitate the primary effect of G-Mode. | - Enable Projectiles | Toggles a built-in debug feature to disable enemy projectiles. @@ -201,6 +211,7 @@ If you experience crashes or severe glitches when using savestates, your platfor | | - Phan Eye Close: Choose how long Phantoon's eye will remain open after a ring of flames | | - 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. @@ -220,6 +231,7 @@ If you experience crashes or severe glitches when using savestates, your platfor | | It also resets the segment timer. Beware that since it leverages the existing frame advance feature, toggling this on changes the way frame advance works. | - Auto-Save Mid Door | Creates a savestate in the middle of the next door transition. | - Auto-Save Every Door | Creates a savestate in the middle of every door transition. +| - Energy/Ammo Variance | Set ranges allowing resources to vary randomly when you reload a savestate. | | | **Slowdown Mode** | Set if practice hack is in slowdown mode and the number of lag frames it is set for. | | @@ -239,7 +251,10 @@ If you experience crashes or severe glitches when using savestates, your platfor | - Full Equipment | Refills your energy and ammo to their current max capacities. | - Kill Enemies | Instantly deletes all enemies in the current room. | - Toggle OOB Tiles | Toggles the OOB Tile Viewer. +| - Randomize RNG | Force a reroll of the RNG routine. +| - 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. | - Reset to Defaults | Resets controller shortcuts to their original defaults. @@ -253,13 +268,14 @@ If you experience crashes or severe glitches when using savestates, your platfor | | PB Fix = Defers trigger during power bomb explosions, which fixes issue where the alarm may not turn on or turn off. | | Improved = PB Fix + only triggers on with health+reserves is less than 30 (same requirements as initiating health bomb). | | Always On = Self-explanatory. +| - Random Bubble SFX | Option to turn these vanilla sound effects while underwater or in lava off, or to specify which sound is played. | - Customize Menu Sound | Customize sounds that the practice hack menu makes. | - Music Selection | Play any music track from a list. | - Library One/Two/Three Sound | Choose a sound effect to play from one of the three collections. Sounds from Libraries two and three usually depend on a partiular music track. | | Press Y to play the selected sound effect. | - Silence Sound FX | Stops all sound effects. This is useful for certain sound effects that loop, such as Mother Brain's rainbow beam. | | -| **Customize Menu** | Change color palettes and sound effects used by the practice hack menus. +| **Customize Practice Menu** | Change color palettes and sound effects used by the practice hack menus. | - Menu Background | Toggle the background of the menu on or off. The background will always be drawn in the pause menu and Ceres Elevator Room. | - Customize Menu Palette | Customize the color palettes of each element of the menu. There are three sets of options for editing colors. The Hexadecimal set is an approximation of traditional 24bit RGB values. The Decimal set is a simplified version with a scale of 0-31 for each color. The SNES BGR set is the 15bit color value used internally, which is also how it's displayed in the "Screenshot To Share Colors" submenu. Example menu items are provided to show your changes in real time. | - Menu Palette | Cycle through a list of pre-made palette profiles from the community. Select CUSTOM to edit your own palettes. @@ -270,6 +286,9 @@ If you experience crashes or severe glitches when using savestates, your platfor | - Fast-Scroll Button | Choose between holding X or Y to make numbers scroll at 4x speed, or disable this feature and scroll at pre-defined increments. | - Menu Scroll Delay | Set the number of frames before scrolling to the next menu item when Up or Down are held. | - Customize Menu Header | Type a customized header for the main menu, up to 23 characters. Set it blank to restore the default header. +| - Factory Reset | Clears WRAM and SRAM used by the practice hack allowing for a reset to default settings, which an option to keep custom presets. +| | +| **Capture Cropping Mode** | Put a border around the screen to help with cropping or monitor adjustments. | | | **Be Right Back Menu** | Put a BRB screen, with various options including a countdown timer for your estimated return (timer begins counting up when it expires). diff --git a/web/data/infohudmode.mdx b/web/data/infohudmode.mdx index dc7a1d53..5655a544 100644 --- a/web/data/infohudmode.mdx +++ b/web/data/infohudmode.mdx @@ -24,19 +24,19 @@ Displays the HP of the first enemy. Most useful for boss fights, although Mother ## Room Strat Allows you to select a Room Strat instead of an Infohud Mode. See below section for the various Room Strats. -## Charge +## Charge Timer Counts down the frames from the time you press shot until the time the beam would be charged, after which it will count up the number of extra frames applied towards charging the beam. The timer resets if you let go of the shot button, and begins counting up the frames shot was released to the left of the charge timer. -## X Factor +## X-Factor Timer Counts down the frames from the time you press shoot until the time the SBA (Special Beam Attack) would activate. The timer resets if you let go of the shoot button or if the SBA activates. -## Cooldown +## Cooldown Timer Counts down the frames from time you activate a weapon or lay a bomb until the time you can fire again. -## Shinespark +## Shinespark Timer Counts down the frames from the time you charge a shinespark until the time the charge runs out, after which it will count up the number of frames you were late to the left of the shinespark timer. If you activate the shinespark in time, it will display the number of frames that were remaining, with 1 indicating there were no frames to spare. -## Dash +## Dash Counter Displays the speed boost counter. This number can be between 0 and 4. When building a shinespark charge, each successful tap (or held dash button) will increment the dash counter. ## Shine Tune @@ -58,10 +58,10 @@ There is also an "average starting momentum" number printed out which gives some Even a single stutter will lower this number from above 2 to below 2, but you can reduce the number further with more stutters. It also accounts for the amount of the time the dpad was released, since each frame the dpad is released while decelerating, Samus moves an extra pixel forward, so shorter releases of the dpad are more optimal. -## I Frames +## I-Frame Counter Counts down the invulnerability frames after Samus takes damage. -## Spikesuit +## Spikesuit Trainer Displays feedback on the two inputs required to generate a spikesuit. It assumes you will be taking damage from spikes which give 60 I-frames and 10 frames of knockback. The feedback is as follows:   First two characters = Feedback on the unmorph: @@ -83,16 +83,10 @@ Counts up lag frames in real time. Resets after each door transition. ## CPU Usage Counts down the number of scanlines that were drawn during processing of the next frame. The screen has a resolution of 256x224, so at 60 fps, 224 scanlines must be drawn every 1/60th of a second. This count is converted to a percentage to get a sense of the lag. The higher the percentage, the closer we were to not finishing processing in time. If processing does not finish in time, then the game must draw the current frame again and this is a lag frame. If the percentage is a low number, then it is likely the game lagged with most of the work done during the previous frame and a small amount of work left over for the next frame. -## X Position -Displays the X position in pixels. Also Samus HP is replaced by the subpixels in hexadecimal. - -## Y Position -Displays the Y position in pixels. Also Samus HP is replaced by the subpixels in hexadecimal. - -## Horiz Speed +## Horizontal Speed Displays the horizontal speed combined with momentum in pixels. Also Samus HP is replaced by the subpixels in hexadecimal. -## Vert Speed +## Vertical Speed Displays the vertical speed in pixels. Initial jump speed will displayed as a three digit hex value, overwriting the item collection percentage. Samus HP will be overwritten with space jump feedback:   First two characters = Number of frames that the jump button was held. @@ -102,7 +96,7 @@ Last two characters = Feedback on the time when you jumped, with respect to spac - Y# indicates you made a valid space jump. On NTSC, you normally have 23 frames, but if underwater you have 41 frames. On PAL, you normally have 19 frames, but if underwater you have 28 frames. - L# indicates you were late where the number tells you how many frames you were late. -## Quick Drop +## Quickdrop Trainer Displays the number of frames between pressing a left or right input and another left or right input, if the number of frames is between 1 and 20. If a down input is pressed, then feedback on mid-air morph bomb spread will be given:   First two characters = Feedback on mid-air morph while beam is charged: @@ -110,7 +104,7 @@ First two characters = Feedback on mid-air morph while beam is charged: - YY indicates you attempted to morph on the correct frame. - L# indicates you were late where the number tells you how many frames you were late. -## Wall Jump +## Walljump Trainer Displays the number of frames between pressing a left or right input and pressing the jump button, if the number of frames is between 1 and 20. To walljump this number should be between 2 and 9 inclusive, although on PAL 8 does not work due to Samus' animation running out and being in the incorrect pose on that particular frame. Also, if the number of frames is 7-9 (a delayed walljump) and the walljump is taking place in WRITG or Bubble Mountain or Mt. Everest, then additional information may be presented if you appear to be making hi-jump-less walljump attempts (also known as the hypo jump): @@ -138,12 +132,24 @@ First two characters = Feedback on the walljump: Note that the namihe does not pull Samus in like a wall does (subpixels are not reset), so while a delayed walljump is preferred (it matters if you jump from a higher position), walljumps off of the namihe do not provide the traditional 2-9 frame window for walljumps. -## Arm Pump +## Boss Damage Counter +Counts the amount of damage dealt to a boss. + +## Arm Pump Trainer Displays the number of armpumps (pose changes) per second, and the number of wasted angle down and/or angle up inputs per second. An input is considered wasted if it does not change the pose, or if both angle down and angle up are changed on the same frame. When exiting the room, the totals for the room are displayed. Note that the specific pose is not actually checked, so other actions performed by Samus may be counted. +## Arm Pump Counter +Displays the number of consecutive single-frame armpumps. This is shown as a rolling count in order to have time to stop pumping and observe when a larger number is achieved. + +## X Position +Displays the X position in hexadecimal pixels. Also Samus HP is replaced by the subpixels in hexadecimal. + +## Y Position +Displays the Y position in hexadecimal pixels. Also Samus HP is replaced by the subpixels in hexadecimal. + ## Shot Timer Displays the number of frames between pressing the shoot button.   @@ -162,10 +168,16 @@ It is still possible to avoid an enrage though, if you cam stand close to Phanto Phantoon's hitbox expands upon moving around, so standing close to Phantoon can cause Samus to take damage and knockback if Phantoon starts moving early due to the fast eye close, which can prevent the super missile from firing and hitting Phantoon. -## RAM Watch -Displays the value of two configurable memory addresses in bank $7E, $7F, or the first bank of SRAM. Values can also be "locked" or rewritten each frame while the RAM Watch HUD mode is enabled. These addresses and values can be configured in the 'Customize RAM Watch' submenu. +## Custom RAM Watch +Displays the value of two configurable memory addresses in any bank. Values can also be "locked" or rewritten each frame while the RAM Watch HUD mode is enabled. These addresses and values can be configured in the 'Customize RAM Watch' submenu. # Room strat features +## 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. + +## Ceres Ridley Hits +Display number of hits Ceres Ridley has taken. Ceres Ridley fly away conditions are upon Samus health dropping below 30 or upon hitting Ridley 100 times, at which point Ridley drops the baby metroid before recollecting it and flying away. + ## Parlor-Climb Door Skip Provides feedback on attempts to get out of bounds while falling through the door from parlor to climb:   @@ -210,6 +222,9 @@ Last two characters = Feedback on the time when you expanded your hitbox to grab Unfortunately even if you are coming in with a Y3 73 jump, you only get one chance to grab the tank. It does not matter if you choose Y1, Y2, or Y3 to attempt the grab, as it will come down to the collision oscillator. When Samus expands her hitbox, she will contact both the tank and the ceiling, but the game will only check one of the tiles. If it checks the ceiling tile, it will push Samus down and out of the ceiling and she will not be able to grab the tank on the next frame. +## Pit Room Right Door +Yes or No indicator on whether or not this flashing gray door has been opened. + ## Moondance (currently only supported on NTSC) Provides feedback on moondance (Dachora room) or tasdance (Green Brinstar Main Shaft room): @@ -239,6 +254,12 @@ Last four characters = The time between presses and releases during the turns (e - YY indicates you hit one of the frame perfect inputs. - L# indicates you were late where the number tells you how many frames you were late. +## Kraid Nail Radar +Feedback on both Samus position and on Kraid's fingernails. +For Samus position, if you successfully perform the bomb bounce setup for KQK, then the Samus indicator will turn green. +For Kraid's fingernails, the indicators show if the nails are moving around and in what directions. If both are moving indicating both are below, then Kraid will be laggier than if just one nail is moving. +Using a power bomb or wave beam shots to kill nails below Samus may cause one of them to respawn above Samus and reduce Kraid lag. It is not possible to spawn both nails above Samus. + ## Gate Glitch Provides feedback on attempts to open a left-facing gate from the right side:   @@ -331,7 +352,7 @@ Last two characters = Feedback on your timing in returning to the correct positi Note: Snail clip works with three pixels on NTSC and five pixels on PAL. However because the snail moves 1.25 pixels per frame on NTSC and roughly 1.5 pixels per frame on PAL, it works out to only 3 frames on NTSC and 3 or 4 frames on PAL. Without Hi-Jump Boots equipped, it's only a 2-frame window on both NTSC and PAL. -## Wasteland (currently only supported on NTSC) +## Wasteland Entry (currently only supported on NTSC) Provides feedback on the timing of bombs during wasteland entry from kihunter shaft. This assumes a normalized entry (roll off ledge in prior room, press against left side of door, continue holding left). If you do this, then you should see a pair of Y's after entry (although it may be possible to fool this check to give Y's even if the setup is off, for example not pressing against the left side of the door). The first block of four characters (two characters for each bomb) is for a simple roll into the room, requiring a high hop from the third hopper (second one on the ground): @@ -350,6 +371,9 @@ Note: The trainer doesn't verify that the bombs break open the tunnel. For examp ## Ridley AI Prints the name of Ridley's current AI routine on the bottom-right of the HUD to assist with finding manipulation strategies. Ridley's HP is displayed on the left until it reaches zero, at which point it will start counting Ridley's "death grab" attempts until Ridley explodes. +## Kihunter Manipulation +Indicators on how the Kihunters are moving in the Red Kihunter Shaft, with Yes/No indicators on whether or not they are in a good position in order to travel from the bottom to the top of the room. + ## Downback Zeb Skip Provides feedback on downback zeb skip attempts:   @@ -357,10 +381,13 @@ Provides feedback on downback zeb skip attempts: - Second character = Feedback on your vertical subpixel normalization. A Y indicates your vertical subpixel was correctly normalized; an N indicates it was not. (If you're getting an N here, the most likely cause is that you're holding forward during knockback from the Rinka and getting a downwards damage boost, which you do not want.) - Third character = number of frames between knockback ending and the start of your downback. Values of 1-4, 6-10, or 13-14 are "good frames" that result in a successful clip, while 0, 5, 11-12, and 15+ are "bad frames" that will result in a failed attempt. +## Zeb Skip Indicator +Indicators useful for Zeb Skip. The yellow indicator is replaced by an I-Frame counter when Samus takes damage, since I-Frames are needed to get past a zebitite. When the green indicator appears, it means that Samus has correctly moved far enough left where she is at least one pixel inside the zebitite. + ## Mother Brain HP Displays the HP of the second enemy. Most useful for the Mother Brain fight since Mother Brain uses the second enemy slot. -## Two Cries (currently only supported on NTSC) +## Two Cries Standup (currently only supported on NTSC) Provides feedback on attempts to manipulate Mother Brain into a fast sitdown animation (baby detaches after just two cries) while performing the standup glitch. This assumes you are using the method starting from angle-crouch jump, aim down while below Mother Brain's head (stay in this pose the entire time you are at or above head level), morph into an automatic springball jump, and unmorph while falling. You can also do this strat without springball by using a buffered auto-jump into a quick morph, but the trick is more difficult as there are fewer frames that work.