diff --git a/src/defines.asm b/src/defines.asm index c6cbee01..572564a5 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -16,19 +16,24 @@ !ram_tilemap_buffer = $7EF500 ; 2048 bytes ; Shortcut routine is written on boot and each time the menu closes, -; so it can use the same space as the practice hack menu tilemap buffer -!CTRL_SHORTCUT_ROUTINE = $7EF502 ; up to 1883 bytes or +$75A -!CTRL_SHORTCUT_TABLE = !CTRL_SHORTCUT_ROUTINE+$7B6 ; 48 bytes -!CTRL_SHORTCUT_TYPE = !CTRL_SHORTCUT_ROUTINE+$7E6 -!CTRL_SHORTCUT_PRI = !CTRL_SHORTCUT_ROUTINE+$7E8 -!CTRL_SHORTCUT_SEC = !CTRL_SHORTCUT_ROUTINE+$7EA -!CTRL_SHORTCUT_JSL_WORD_LSB = !CTRL_SHORTCUT_ROUTINE+$7EC -!CTRL_SHORTCUT_JSL_WORD_MSB = !CTRL_SHORTCUT_ROUTINE+$7EE -!CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP = !CTRL_SHORTCUT_ROUTINE+$7F0 -!CTRL_SHORTCUT_SEC_TO_DUAL_JUMP = !CTRL_SHORTCUT_ROUTINE+$7F2 -!CTRL_SHORTCUT_TABLE_PRI_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F4 -!CTRL_SHORTCUT_TABLE_SEC_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F6 -!CTRL_SHORTCUT_TABLE_DUAL_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F8 +; so it can use the same space as the practice hack menu tilemap buffer. +!CTRL_SHORTCUT_ROUTINE = $7EF502 ; up to 1941 bytes or through +$796 +!CTRL_SHORTCUT_PRI_UPDATE_TIMERS = !CTRL_SHORTCUT_ROUTINE+$7B0 +!CTRL_SHORTCUT_TABLE = !CTRL_SHORTCUT_ROUTINE+$7B2 ; 48 bytes +!CTRL_SHORTCUT_TYPE = !CTRL_SHORTCUT_ROUTINE+$7E2 +!CTRL_SHORTCUT_PRI = !CTRL_SHORTCUT_ROUTINE+$7E4 +!CTRL_SHORTCUT_SEC = !CTRL_SHORTCUT_ROUTINE+$7E6 +!CTRL_SHORTCUT_JSL_WORD_LSB = !CTRL_SHORTCUT_ROUTINE+$7E8 +!CTRL_SHORTCUT_JSL_WORD_MSB = !CTRL_SHORTCUT_ROUTINE+$7EA +!CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP = !CTRL_SHORTCUT_ROUTINE+$7EC +!CTRL_SHORTCUT_SEC_TO_DUAL_JUMP = !CTRL_SHORTCUT_ROUTINE+$7EE +!CTRL_SHORTCUT_TABLE_PRI_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F0 +!CTRL_SHORTCUT_TABLE_SEC_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F2 +!CTRL_SHORTCUT_TABLE_DUAL_INDEX = !CTRL_SHORTCUT_ROUTINE+$7F4 +; The following tracking variables are for Update Timers, +; and they are only accurate and maintained enough to make that work +!CTRL_SHORTCUT_TRACKING_PRI_PREV = !CTRL_SHORTCUT_ROUTINE+$7F6 +!CTRL_SHORTCUT_TRACKING_LANDED = !CTRL_SHORTCUT_ROUTINE+$7F8 ; Shortcuts can skip remaining checks by replacing the return address word !CTRL_SHORTCUT_SKIP_REMAINING_PEA = !CTRL_SHORTCUT_ROUTINE+$7FA !CTRL_SHORTCUT_SKIP_REMAINING_PEA_VALUE = $FCFC @@ -197,8 +202,8 @@ !ram_suits_heat_damage_check = !WRAM_PERSIST_START+$32 !ram_pacifist = !WRAM_PERSIST_START+$34 !ram_freeze_on_load = !WRAM_PERSIST_START+$36 +!ram_drop_chance_table = !WRAM_PERSIST_START+$38 -!ram_spacetime_infohud = !WRAM_PERSIST_START+$38 !ram_watch_left_index = !WRAM_PERSIST_START+$3A !ram_watch_right_index = !WRAM_PERSIST_START+$3C !ram_watch_write_mode = !WRAM_PERSIST_START+$3E @@ -220,7 +225,6 @@ !ram_frames_held = !WRAM_PERSIST_START+$5C !ram_quickboot_spc_state = !WRAM_PERSIST_START+$5E !ram_display_backup = !WRAM_PERSIST_START+$60 -!ram_drop_chance_table = !WRAM_PERSIST_START+$62 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -361,6 +365,9 @@ !ram_cm_ceres_seconds = !WRAM_MENU_START+$90 !ram_cm_zebes_seconds = !WRAM_MENU_START+$92 +!ram_cm_sprites_spacetime = !WRAM_MENU_START+$90 +!ram_cm_sprites_xray = !WRAM_MENU_START+$92 + !ram_cm_ctrl_add_shortcut_slot = !WRAM_MENU_START+$90 !ram_cm_ctrl_last_pri = !WRAM_MENU_START+$92 !ram_cm_ctrl_last_sec = !WRAM_MENU_START+$94 @@ -369,6 +376,8 @@ !ram_cm_ctrl_timer = !WRAM_MENU_START+$9A !ram_cm_ctrl_savestates_allowed = !WRAM_MENU_START+$9C +!ram_cm_updatetimers_ctrl = !WRAM_MENU_START+$90 + !ram_cm_sfxlib1 = !WRAM_MENU_START+$90 !ram_cm_sfxlib2 = !WRAM_MENU_START+$92 !ram_cm_sfxlib3 = !WRAM_MENU_START+$94 @@ -475,7 +484,7 @@ ; SRAM ; ----- -!SRAM_VERSION = #$001D +!SRAM_VERSION = #$001E !SRAM_START = $702000 !SRAM_SIZE = #$1000 @@ -560,6 +569,8 @@ !sram_bonk_indicators = !SRAM_START+$A6 !sram_speed_booster_physics = !SRAM_START+$A8 !sram_fast_teleport = !SRAM_START+$AA +!sram_update_timers_ctrl_input = !SRAM_START+$AC +!sram_update_timers_options = !SRAM_START+$AE ; ^ FREE SPACE ^ up to +$EC @@ -979,7 +990,11 @@ !SAMUS_BOMB_SPREAD_CHARGE_TIMER = $0CD4 !SAMUS_POWER_BOMB_X = $0CE2 !SAMUS_POWER_BOMB_Y = $0CE4 +!OFFSCREEN_HDMA_INDEX = $0D1E !CURRENT_BLOCK_INDEX = $0DC4 +!SAMUS_VERTICAL_COLLISION_RESULT = $0DC6 +!SAMUS_X_SPEED_KILLED = $0DCE +!SAMUS_SOLID_COLLISION_FLAG = $0DD0 !PREVIOUS_CONTROLLER_PRI = $0DFE !PREVIOUS_CONTROLLER_PRI_NEW = $0E00 !ELEVATOR_PROPERTIES = $0E16 @@ -1363,6 +1378,20 @@ endif !SPRITE_ENEMY_PROJ = #$0020 !SPRITE_32x32_PROJ = #$0040 !SPRITE_OOB_WATCH = #$0080 +!SPRITE_HUD_SPACETIME = #$0100 +!SPRITE_HUD_XRAY = #$0200 +!SPRITE_HUD_SPACETIME_INVERTED = #$FEFF +!SPRITE_HUD_XRAY_INVERTED = #$FDFF + +!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE = $05 + +!UPDATE_TIMERS_ALWAYS = #$0001 +!UPDATE_TIMERS_ON_LANDED = #$0002 +!UPDATE_TIMERS_ON_PRESS = #$0004 +!UPDATE_TIMERS_ON_HOLD = #$0008 +!UPDATE_TIMERS_ON_PRESS_HOLD = #$000C +!UPDATE_TIMERS_ON_RELEASE = #$0010 +!UPDATE_TIMERS_ON_HOLD_RELEASE = #$0018 !CUTSCENE_SKIP_INTRO = #$0001 !CUTSCENE_SKIP_CERES_ARRIVAL = #$0002 diff --git a/src/freespace.asm b/src/freespace.asm index 1de2b78f..59c1cf66 100644 --- a/src/freespace.asm +++ b/src/freespace.asm @@ -248,7 +248,7 @@ endif !END_FREESPACE_CE = $CE0000+$10000 !END_FREESPACE_DE = $DE0000+$10000 !END_FREESPACE_DF = $DF0000+$10000 -!END_FREESPACE_E0 = $E00000+$10000 +!END_FREESPACE_E0 = $E00000+$E7E0 ; preserve_wram.asm !END_FREESPACE_E1 = $E10000+$10000 !END_FREESPACE_E2 = $E20000+$10000 !END_FREESPACE_E3 = $E30000+$10000 diff --git a/src/gamemode.asm b/src/gamemode.asm index 2ca4c808..fe284bce 100644 --- a/src/gamemode.asm +++ b/src/gamemode.asm @@ -23,7 +23,40 @@ org $82E526 endif +org $909453 + JSR gamemode_set_downward_collision_result + +org $909469 + JSR gamemode_set_downward_collision_result + +; Move $90E61B routine up to make room for patch +org $90E5FE + STZ !SAMUS_X_SPEED_KILLED + STZ !SAMUS_VERTICAL_COLLISION_RESULT + +org $90E60C + BEQ $F1 + +org $90E614 + BRA $EE +gamemode_set_downward_collision_result: + PHP : %ai16() + LDA !SAMUS_SOLID_COLLISION_FLAG : BEQ .continue + LDA #$0001 : STA !SAMUS_VERTICAL_COLLISION_RESULT + %ai8() + LDA !SAMUS_MOVEMENT_TYPE : TAX + LDA $E676,X : STA !SAMUS_VERTICAL_COLLISION_RESULT+1 + PLP + STA !CTRL_SHORTCUT_TRACKING_LANDED + RTS +warnpc $90E639 + +org $90E639 + .continue + + %startfree(85) + if !FEATURE_SD2SNES gamemode_door_transition: { @@ -642,8 +675,10 @@ cm_write_ctrl_routine: ; In fact, we are using the end of the buffer for temporary variables ; and a table to track which shortcuts we still need to write. PHB : PEA $7070 : PLB : PLB - TDC : TAX : TAY : STA !CTRL_SHORTCUT_TYPE + TDC : TAX : TAY : STA !CTRL_SHORTCUT_TYPE : STA !CTRL_SHORTCUT_PRI_UPDATE_TIMERS STA !CTRL_SHORTCUT_PRI_TO_SEC_DUAL_JUMP : STA !CTRL_SHORTCUT_SEC_TO_DUAL_JUMP + STA !CTRL_SHORTCUT_TRACKING_PRI_PREV + DEC : STA !CTRL_SHORTCUT_TRACKING_LANDED ; Initialize category indices to 48 indicating no shortcut found. LDA #$0030 : STA !CTRL_SHORTCUT_TABLE_DUAL_INDEX @@ -672,9 +707,9 @@ if !FEATURE_VANILLAHUD CMP #$1F : BPL .initialFirstCheckInputs CMP #$19 : BPL .initialFirstInvalid CMP #$12 : BEQ .initialFirstInvalid - CMP #$05 : BEQ .initialFirstInvalid + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE : BEQ .initialFirstInvalid else - CMP #$05 + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE endif BPL .initialFirstCheckInputs CMP #$01 : BEQ .initialFirstCheckInputs @@ -689,6 +724,13 @@ endif LDY.w !sram_ctrl_1_shortcut_inputs,X : BEQ .initialFirstNoPri LDY.w !sram_ctrl_2_shortcut_inputs,X : BEQ .initialFirstPri TXA : LSR : TAX +if !FEATURE_VANILLAHUD +else + LDA.w !CTRL_SHORTCUT_TABLE,X : AND.b !CTRL_SHORTCUT_TYPE_MASK + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE : BNE .initialFirstDualAccept + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ALWAYS : BNE .initialFirstInvalid + .initialFirstDualAccept +endif LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BNE .initialFirstContinue TXA : STA !CTRL_SHORTCUT_TABLE_DUAL_INDEX BRA .initialFirstContinue @@ -698,11 +740,25 @@ endif BRA .initialFirstInvalid .initialFirstPri TXA : LSR : TAX +if !FEATURE_VANILLAHUD +else + LDA.w !CTRL_SHORTCUT_TABLE,X : AND.b !CTRL_SHORTCUT_TYPE_MASK + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE : BNE .initialFirstPriAccept + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ALWAYS : BNE .initialFirstInvalid + .initialFirstPriAccept +endif LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 : BNE .initialFirstContinue TXA : STA !CTRL_SHORTCUT_TABLE_PRI_INDEX BRA .initialFirstContinue .initialFirstSec TXA : LSR : TAX +if !FEATURE_VANILLAHUD +else + LDA.w !CTRL_SHORTCUT_TABLE,X : AND.b !CTRL_SHORTCUT_TYPE_MASK + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE : BNE .initialFirstSecAccept + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ALWAYS : BNE .initialFirstInvalid + .initialFirstSecAccept +endif LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BNE .initialFirstContinue TXA : STA !CTRL_SHORTCUT_TABLE_SEC_INDEX .initialFirstContinue @@ -716,9 +772,9 @@ endif if !FEATURE_VANILLAHUD CMP #$19 : BPL .initialSecondInvalid CMP #$12 : BEQ .initialSecondInvalid - CMP #$05 : BEQ .initialSecondInvalid + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE : BEQ .initialSecondInvalid else - CMP #$05 + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE endif BPL .initialSecondCheckInputs CMP #$01 : BEQ .initialSecondCheckInputs @@ -733,6 +789,13 @@ endif LDY.w !sram_ctrl_1_shortcut_inputs,X : BEQ .initialSecondNoPri LDY.w !sram_ctrl_2_shortcut_inputs,X : BEQ .initialSecondPri TXA : LSR : TAX +if !FEATURE_VANILLAHUD +else + LDA.w !CTRL_SHORTCUT_TABLE,X : AND.b !CTRL_SHORTCUT_TYPE_MASK + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE : BNE .initialSecondDualAccept + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ALWAYS : BNE .initialSecondInvalid + .initialSecondDualAccept +endif LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BNE .initialSecondContinue TXA : STA !CTRL_SHORTCUT_TABLE_DUAL_INDEX BRA .initialSecondContinue @@ -742,11 +805,25 @@ endif BRA .initialSecondInvalid .initialSecondPri TXA : LSR : TAX +if !FEATURE_VANILLAHUD +else + LDA.w !CTRL_SHORTCUT_TABLE,X : AND.b !CTRL_SHORTCUT_TYPE_MASK + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE : BNE .initialSecondPriAccept + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ALWAYS : BNE .initialSecondInvalid + .initialSecondPriAccept +endif LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 : BNE .initialSecondContinue TXA : STA !CTRL_SHORTCUT_TABLE_PRI_INDEX BRA .initialSecondContinue .initialSecondSec TXA : LSR : TAX +if !FEATURE_VANILLAHUD +else + LDA.w !CTRL_SHORTCUT_TABLE,X : AND.b !CTRL_SHORTCUT_TYPE_MASK + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE : BNE .initialSecondSecAccept + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ALWAYS : BNE .initialSecondInvalid + .initialSecondSecAccept +endif LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BNE .initialSecondContinue TXA : STA !CTRL_SHORTCUT_TABLE_SEC_INDEX .initialSecondContinue @@ -757,6 +834,148 @@ endif ; Restore X to resume writing LDX #$0001 +if !FEATURE_VANILLAHUD +else + ; Check if we have an update timers shortcut to write + LDA !sram_update_timers_ctrl_input : BNE .updateTimers + LDA !sram_update_timers_ctrl_input+1 : BNE .updateTimers + + ; Check if we always update timers or update on landed + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ALWAYS : BNE .alwaysUpdateTimers + BIT.b !UPDATE_TIMERS_ON_LANDED : BEQ .doneUpdateTimers + JMP .updateTimersOnLanded + + .updateTimers + ; Check if we always update timers, or if we update on press and not hold + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ALWAYS : BNE .alwaysUpdateTimers + AND.b !UPDATE_TIMERS_ON_PRESS_HOLD : CMP.b !UPDATE_TIMERS_ON_PRESS : BNE .updateTimersOptions + + ; Record the desired on press options + %a16() : LDA.w !sram_update_timers_ctrl_input : STA !CTRL_SHORTCUT_PRI_UPDATE_TIMERS : %a8() + BRA .updateTimersOptions + + .alwaysUpdateTimers + ; Write simple JSL + LDA.l ctrl_shortcut_jsl_word_lsb_table+!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE + STA !CTRL_SHORTCUT_JSL_WORD_LSB + LDA.l ctrl_shortcut_jsl_word_msb_table+!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE + STA !CTRL_SHORTCUT_JSL_WORD_MSB + JSR .writeJsl + + .doneUpdateTimers + JMP .checkPriShortcuts + + .updateTimersOptions + LDA.w !sram_update_timers_options : AND.b !UPDATE_TIMERS_ON_HOLD_RELEASE + CMP.b !UPDATE_TIMERS_ON_HOLD : BEQ .updateTimersHold + CMP.b !UPDATE_TIMERS_ON_RELEASE : BEQ .updateTimersRelease + CMP.b !UPDATE_TIMERS_ON_HOLD_RELEASE : BEQ .updateTimersHoldRelease + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ON_LANDED + BEQ .doneUpdateTimers + JMP .updateTimersOnLanded + + .updateTimersHoldRelease + ; LDA !CTRL_SHORTCUT_TRACKING_PRI_PREV + LDA #$AF : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV>>8 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV>>16 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; ORA $8B + LDA #$05 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + BRA .updateTimersCtrlInput + + .updateTimersHold + ; LDA $8B + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + BRA .updateTimersCtrlInput + + .updateTimersRelease + ; LDA !CTRL_SHORTCUT_TRACKING_PRI_PREV + LDA #$AF : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV>>8 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV>>16 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; EOR $8B + LDA #$45 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; AND !CTRL_SHORTCUT_TRACKING_PRI_PREV + LDA #$2F : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV>>8 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV>>16 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + .updateTimersCtrlInput + ; BIT !sram_update_timers_ctrl_input + LDA #$89 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !sram_update_timers_ctrl_input : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !sram_update_timers_ctrl_input+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BEQ $04 or $06 + LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.w !sram_update_timers_options : AND.b !UPDATE_TIMERS_ON_LANDED + ORA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Write simple JSL + LDA.l ctrl_shortcut_jsl_word_lsb_table+!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE + STA !CTRL_SHORTCUT_JSL_WORD_LSB + LDA.l ctrl_shortcut_jsl_word_msb_table+!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE + STA !CTRL_SHORTCUT_JSL_WORD_MSB + JSR .writeJsl + + ; Write on landed check if option selected + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ON_LANDED : BNE .afterCtrlInputSkipLanded + JMP .updateTimersTrackPri + + .afterCtrlInputSkipLanded + ; BRA $0D + LDA #$80 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$0D : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + .updateTimersOnLanded + ; LDA !CTRL_SHORTCUT_TRACKING_LANDED + LDA #$AF : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_LANDED : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_LANDED>>8 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_LANDED>>16 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BIT #$0004 + LDA #$89 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$00 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BNE $04 + LDA #$D0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Write simple JSL + LDA.l ctrl_shortcut_jsl_word_lsb_table+!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE + STA !CTRL_SHORTCUT_JSL_WORD_LSB + LDA.l ctrl_shortcut_jsl_word_msb_table+!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE + STA !CTRL_SHORTCUT_JSL_WORD_MSB + JSR .writeJsl + + ; Reset on landed flag afterwards + ; LDA #$FFFF + LDA #$A9 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$FF : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$FF : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; STA !CTRL_SHORTCUT_TRACKING_LANDED + LDA #$8F : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_LANDED : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_LANDED>>8 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_LANDED>>16 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + .updateTimersTrackPri + ; Track previous input if necessary + LDA.w !sram_update_timers_options : BIT.b !UPDATE_TIMERS_ON_RELEASE : BEQ .checkPriShortcuts + ; LDA $8B + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8B : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; STA !CTRL_SHORTCUT_TRACKING_PRI_PREV + LDA #$8F : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV>>8 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA.b #!CTRL_SHORTCUT_TRACKING_PRI_PREV>>16 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + + .checkPriShortcuts +endif ; !FEATURE_VANILLAHUD ; Check if we have pri only shortcuts to write LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 : BPL .noPriShortcuts @@ -903,6 +1122,18 @@ endif %a16() : LDA !CTRL_SHORTCUT_PRI : DEC AND !CTRL_SHORTCUT_PRI : BNE .priWriteNotSpecial +if !FEATURE_VANILLAHUD +else + ; Check if we can combine with update timers on press option. + LDA !CTRL_SHORTCUT_PRI_UPDATE_TIMERS : BEQ .priWritePrepareSpecial + %a8() : LDA !CTRL_SHORTCUT_TYPE + CMP.b #!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE : BNE .priWritePrepareSpecial + %a16() : LDA !CTRL_SHORTCUT_PRI_UPDATE_TIMERS + ORA !CTRL_SHORTCUT_PRI : STA !CTRL_SHORTCUT_PRI + TDC : STA !CTRL_SHORTCUT_PRI_UPDATE_TIMERS + + .priWritePrepareSpecial +endif ; Scan for other single bit non exact matches with same type, ; and also for next pri only shortcut. ; Don't forget to clear ourselves from the table and reset category index. @@ -1022,34 +1253,51 @@ endif LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .priWriteSpecialClc - LDA !CTRL_SHORTCUT_PRI+1 : BIT #$10 : BNE .priWriteSpecialClv ; Simple JSL case, so branch by four PLX : LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX JSR .writeJsl BRA .nextPriWrite .priWriteSpecialClc - LDA !CTRL_SHORTCUT_PRI+1 : BIT #$10 : BNE .priWriteSpecialClcClv ; PLP : CLC : PHP followed by JSL, so branch by seven PLX : LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX JSR .writeClcJsl - BRA .nextPriWrite - - .priWriteSpecialClv - ; PLP : CLV : PHP followed by JSL, so branch by seven - PLX : LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX - JSR .writeClvJsl - BRA .nextPriWrite - - .priWriteSpecialClcClv - ; PLP : REP $41 : PHP followed by JSL, so branch by eight - PLX : LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX - JSR .writeClcClvJsl .nextPriWrite - LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 : BPL .donePriWrite + LDA !CTRL_SHORTCUT_TABLE_PRI_INDEX : CMP #$30 +if !FEATURE_VANILLAHUD + BPL .donePriWrite + JMP .priWriteShortcuts +else + BPL .checkPriUpdateTimers JMP .priWriteShortcuts + .checkPriUpdateTimers + ; Check if we have an update timers on press shortcut to write + LDA !CTRL_SHORTCUT_PRI_UPDATE_TIMERS : BNE .priWriteTimersOnPress + LDA !CTRL_SHORTCUT_PRI_UPDATE_TIMERS+1 : BNE .priWriteTimersOnPress + JMP .donePriWrite + + .priWriteTimersOnPress + ; LDA $8F + LDA #$A5 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$8F : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BIT !CTRL_SHORTCUT_PRI_UPDATE_TIMERS + LDA #$89 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI_UPDATE_TIMERS : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA !CTRL_SHORTCUT_PRI_UPDATE_TIMERS+1 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; BEQ $04 + LDA #$F0 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX + ; Write simple JSL + LDA.l ctrl_shortcut_jsl_word_lsb_table+!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE + STA !CTRL_SHORTCUT_JSL_WORD_LSB + LDA.l ctrl_shortcut_jsl_word_msb_table+!UPDATE_TIMERS_CTRL_SHORTCUT_TYPE + STA !CTRL_SHORTCUT_JSL_WORD_MSB + JSR .writeJsl + BRA .donePriWrite +endif ; !FEATURE_VANILLAHUD + .donePriNoSec ; Check if we have dual shortcuts to write LDA !CTRL_SHORTCUT_TABLE_DUAL_INDEX : CMP #$30 : BPL .donePriNoSecNoDual @@ -1199,7 +1447,6 @@ endif LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .secWriteMatchClc - LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .secWriteMatchClv ; Simple JSL case, so branch by four, earlier branch by eight PLX : LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE-$4,X LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX @@ -1207,27 +1454,12 @@ endif JMP .nextSecWrite .secWriteMatchClc - LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .secWriteMatchClcClv ; PLP : CLC : PHP followed by JSL, so branch by seven, earlier branch by eleven PLX : LDA #$0B : STA !CTRL_SHORTCUT_ROUTINE-$4,X LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX JSR .writeClcJsl JMP .nextSecWrite - .secWriteMatchClv - ; PLP : CLV : PHP followed by JSL, so branch by seven, earlier branch by eleven - PLX : LDA #$0B : STA !CTRL_SHORTCUT_ROUTINE-$4,X - LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX - JSR .writeClvJsl - JMP .nextSecWrite - - .secWriteMatchClcClv - ; PLP : REP $41 : PHP followed by JSL, so branch by eight, earlier branch by twelve - PLX : LDA #$0C : STA !CTRL_SHORTCUT_ROUTINE-$4,X - LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX - JSR .writeClcClvJsl - JMP .nextSecWrite - .secWriteSpecialLoop INX : CPX #$0030 : BPL .secWriteSpecial INY #2 : LDA !CTRL_SHORTCUT_TABLE,X : BEQ .secWriteSpecialLoop @@ -1262,30 +1494,17 @@ endif LDA.l ctrl_shortcut_jsl_word_lsb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_LSB LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .secWriteSpecialClc - LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .secWriteSpecialClv ; Simple JSL case, so branch by four PLX : LDA #$04 : STA !CTRL_SHORTCUT_ROUTINE,X : INX JSR .writeJsl BRA .nextSecWrite .secWriteSpecialClc - LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .secWriteSpecialClcClv ; PLP : CLC : PHP followed by JSL, so branch by seven PLX : LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX JSR .writeClcJsl BRA .nextSecWrite - .secWriteSpecialClv - ; PLP : CLV : PHP followed by JSL, so branch by seven - PLX : LDA #$07 : STA !CTRL_SHORTCUT_ROUTINE,X : INX - JSR .writeClvJsl - BRA .nextSecWrite - - .secWriteSpecialClcClv - ; PLP : REP $41 : PHP followed by JSL, so branch by eight - PLX : LDA #$08 : STA !CTRL_SHORTCUT_ROUTINE,X : INX - JSR .writeClcClvJsl - .nextSecWrite LDA !CTRL_SHORTCUT_TABLE_SEC_INDEX : CMP #$30 : BPL .doneSecWrite JMP .secWriteShortcuts @@ -1396,7 +1615,6 @@ endif LDA.l ctrl_shortcut_jsl_word_msb_table,X : STA !CTRL_SHORTCUT_JSL_WORD_MSB LDA.l ctrl_shortcut_cancel_gameplay_table,X : BNE .dualWriteMatchClc LDA !CTRL_SHORTCUT_PRI+1 : BIT #$10 : BNE .dualWriteMatchClv - LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .dualWriteMatchClv ; Simple JSL case, so branch by four, earlier branches by 15 and 25 PLX : LDA #$19 : STA !CTRL_SHORTCUT_ROUTINE-$15,X LDA #$0F : STA !CTRL_SHORTCUT_ROUTINE-$B,X @@ -1406,7 +1624,6 @@ endif .dualWriteMatchClc LDA !CTRL_SHORTCUT_PRI+1 : BIT #$10 : BNE .dualWriteMatchClcClv - LDA !CTRL_SHORTCUT_SEC+1 : BIT #$10 : BNE .dualWriteMatchClcClv ; PLP : CLC : PHP followed by JSL, so branch by seven, earlier branches by 18 and 28 PLX : LDA #$1C : STA !CTRL_SHORTCUT_ROUTINE-$15,X LDA #$12 : STA !CTRL_SHORTCUT_ROUTINE-$B,X @@ -2245,5 +2462,134 @@ ctrl_add_shortcut_select: JML cm_previous_menu } + +if !FEATURE_VANILLAHUD +else +; ------------------ +; Update Timers Menu +; ------------------ + +UpdateTimersMenu: + dw #update_timers_ctrl_inputs + dw #update_timers_customize_inputs + dw #$FFFF + dw #update_timers_on_press + dw #update_timers_on_hold + dw #update_timers_on_release + dw #$FFFF + dw #update_timers_on_landed + dw #$FFFF + dw #update_timers_always + dw #$0000 + %cm_header("UPDATE TIMERS") + +update_timers_ctrl_inputs: + dw !ACTION_CHOICE + dl #!ram_cm_updatetimers_ctrl + dw #.routine + db #$28, "Ctrl Inputs", #$FF + db #$28, " NONE", #$FF + db #$28, "FACE BUTTON", #$FF + db #$28, " L+R", #$FF + db #$28, " FACE+L+R", #$FF + db #$28, " D-PAD", #$FF + db #$28, " ANY", #$FF + db #$28, " CUSTOM", #$FF + db #$FF + .routine + LDA !ram_cm_updatetimers_ctrl : CMP #$0006 : BCS .done + ASL : TAX : LDA.l update_timers_ctrl_table,X + STA !sram_update_timers_ctrl_input + .done + RTL + +update_timers_customize_inputs: + %cm_submenu("Customize Ctrl Inputs", #UpdateTimersCtrlInputsMenu) + +update_timers_on_press: + %cm_toggle_bit("Update On Press", !sram_update_timers_options, !UPDATE_TIMERS_ON_PRESS, #0) + +update_timers_on_hold: + %cm_toggle_bit("Update On Hold", !sram_update_timers_options, !UPDATE_TIMERS_ON_HOLD, #0) + +update_timers_on_release: + %cm_toggle_bit("Update On Release", !sram_update_timers_options, !UPDATE_TIMERS_ON_RELEASE, #0) + +update_timers_on_landed: + %cm_toggle_bit("Update On Samus Landed", !sram_update_timers_options, !UPDATE_TIMERS_ON_LANDED, #0) + +update_timers_always: + %cm_toggle_bit("Update Every Frame", !sram_update_timers_options, !UPDATE_TIMERS_ALWAYS, #0) + +UpdateTimersCtrlInputsMenu: + dw #update_timers_ctrl_inputs + dw #$FFFF + dw #update_timers_ctrl_A + dw #update_timers_ctrl_B + dw #update_timers_ctrl_L + dw #update_timers_ctrl_R + dw #update_timers_ctrl_X + dw #update_timers_ctrl_Y + dw #update_timers_ctrl_start + dw #update_timers_ctrl_select + dw #update_timers_ctrl_left + dw #update_timers_ctrl_right + dw #update_timers_ctrl_up + dw #update_timers_ctrl_down + dw #$0000 + %cm_header("UPDATE TIMERS CTRL INPUTS") + +update_timers_ctrl_A: + %cm_toggle_bit("A", !sram_update_timers_ctrl_input, !CTRL_A, update_timers_set_cm_ctrl) + +update_timers_ctrl_B: + %cm_toggle_bit("B", !sram_update_timers_ctrl_input, !CTRL_B, update_timers_set_cm_ctrl) + +update_timers_ctrl_L: + %cm_toggle_bit("L", !sram_update_timers_ctrl_input, !CTRL_L, update_timers_set_cm_ctrl) + +update_timers_ctrl_R: + %cm_toggle_bit("R", !sram_update_timers_ctrl_input, !CTRL_R, update_timers_set_cm_ctrl) + +update_timers_ctrl_X: + %cm_toggle_bit("X", !sram_update_timers_ctrl_input, !CTRL_X, update_timers_set_cm_ctrl) + +update_timers_ctrl_Y: + %cm_toggle_bit("Y", !sram_update_timers_ctrl_input, !CTRL_Y, update_timers_set_cm_ctrl) + +update_timers_ctrl_start: + %cm_toggle_bit("Start", !sram_update_timers_ctrl_input, !IH_INPUT_START, update_timers_set_cm_ctrl) + +update_timers_ctrl_select: + %cm_toggle_bit("Select", !sram_update_timers_ctrl_input, !CTRL_SELECT, update_timers_set_cm_ctrl) + +update_timers_ctrl_left: + %cm_toggle_bit("Left", !sram_update_timers_ctrl_input, !IH_INPUT_LEFT, update_timers_set_cm_ctrl) + +update_timers_ctrl_right: + %cm_toggle_bit("Right", !sram_update_timers_ctrl_input, !IH_INPUT_RIGHT, update_timers_set_cm_ctrl) + +update_timers_ctrl_up: + %cm_toggle_bit("Up", !sram_update_timers_ctrl_input, !IH_INPUT_UP, update_timers_set_cm_ctrl) + +update_timers_ctrl_down: + %cm_toggle_bit("Down", !sram_update_timers_ctrl_input, !IH_INPUT_DOWN, update_timers_set_cm_ctrl) + +update_timers_ctrl_table: + dw #$0000, #$C0C0, #$0030, #$C0F0, #$0F00, #$FFF0 + +update_timers_set_cm_ctrl: +{ + LDX #$0000 + LDA !sram_update_timers_ctrl_input + .loop + CMP.l update_timers_ctrl_table,X : BEQ .end + INX #2 : CPX #$000C : BNE .loop + .end + TXA : LSR : STA !ram_cm_updatetimers_ctrl + RTL +} +endif ; !FEATURE_VANILLAHUD + %endfree(85) diff --git a/src/infohudmodes.asm b/src/infohudmodes.asm index 92d94c94..5f0c98c0 100644 --- a/src/infohudmodes.asm +++ b/src/infohudmodes.asm @@ -4387,6 +4387,7 @@ endif CMP.w #ROOM_ElevToBlueBrinstar : BEQ .morph CMP.w #ROOM_GreenBrinElevRoom : BEQ .greenbrin CMP.w #ROOM_DachoraRoom : BEQ .dachora + CMP.w #ROOM_StatuesRoom : BEQ .statues CMP.w #ROOM_LowerNorfairElevator : BEQ .lowernorfair CMP.w #ROOM_WarehouseEntrance : BEQ .warehouse LDA !IH_BLANK : STA !HUD_TILEMAP+$88 @@ -4412,6 +4413,11 @@ endif LDA #$008B : CMP !ram_ypos : BEQ .goodpb BRA .badpb + .statues + LDA #$0080 : CMP !ram_xpos : BEQ .questionpb + LDA #$019B : CMP !ram_ypos : BEQ .goodpb + BRA .badpb + .dachora LDA #$00AA : CMP !ram_ypos : BEQ .goodpb BRA .badpb diff --git a/src/init.asm b/src/init.asm index e5459a09..effc5ca8 100644 --- a/src/init.asm +++ b/src/init.asm @@ -34,7 +34,27 @@ init_code: ; Clear persistent RAM (except quickboot itself) if not already cleared PEA $807E : PLB - LDA.w !ram_quickboot_spc_state : BEQ .persistent_cleared + LDA.w !ram_quickboot_spc_state : BNE .clear_loop_start + + ; Sanity check persistent RAM + LDA.w !ram_magic_pants_enabled : ORA.w !ram_space_pants_enabled + CMP #$0004 : BCS .clear_loop_start + + LDA.w !ram_suits_heat_damage_value : AND #$0FFF : BNE .clear_loop_start + + ; If not heat shield, then top nibble should be non-zero + LDA !sram_suit_properties : AND !SUIT_PROPERTIES_MASK + CMP #$0005 : BEQ .check_drop_chance_table + LDA.w !ram_suits_heat_damage_value : BEQ .clear_loop_start + + .check_drop_chance_table + LDA.w !ram_drop_chance_table : BEQ .persistent_cleared + LDA.w !DROP_CHANCE_TABLE_LENGTH-1 : ASL : TAX + .drop_table_loop + LDA.l drop_chance_tables,X : CMP.w !ram_drop_chance_table : BEQ .persistent_cleared + DEX #2 : BPL .drop_table_loop + + .clear_loop_start ; This loop is based on WRAM_PERSIST_START LDX #$007E .clear_loop @@ -122,6 +142,8 @@ init_sram_routine_table: dw init_sram_upgrade_1Ato1B dw init_sram_upgrade_1Bto1C dw init_sram_upgrade_1Cto1D + dw init_sram_upgrade_1Dto1E + dw init_sram_fail init_sram: { @@ -262,8 +284,15 @@ endif .upgrade_1Cto1D TDC : INC : STA !sram_fast_teleport + .upgrade_1Dto1E + TDC : STA !sram_update_timers_ctrl_input + LDA !UPDATE_TIMERS_ON_PRESS : STA !sram_update_timers_options + LDA !SRAM_VERSION : STA !sram_initialized RTS + + .fail + BRK } init_sram_controller_shortcuts: diff --git a/src/main.asm b/src/main.asm index 6c202744..73540b83 100644 --- a/src/main.asm +++ b/src/main.asm @@ -10,14 +10,14 @@ lorom !FEATURE_VANILLAHUD ?= 0 !INFOHUD_ALWAYS_SHOW_X_Y ?= 0 !ORIGINAL_MESSAGE_TEXT ?= 0 -!PRESERVE_WRAM_DURING_SPACETIME ?= 1 +!PRESERVE_WRAM ?= 1 !RAW_TILE_GRAPHICS ?= 1 !ZSNES_SPLASHSCREEN_GRAPHICS ?= 1 !VERSION_MAJOR = 2 !VERSION_MINOR = 7 -!VERSION_BUILD = 5 -!VERSION_REV = 3 +!VERSION_BUILD = 6 +!VERSION_REV = 0 table ../resources/normal.tbl print "" @@ -47,9 +47,9 @@ if !ORIGINAL_MESSAGE_TEXT print "PRESERVE FANFARE MESSAGES" endif -if !PRESERVE_WRAM_DURING_SPACETIME +if !PRESERVE_WRAM else - print "WRAM NOT PRESERVED DURING SPACETIME" + print "WRAM NOT PRESERVED DURING SPACETIME OR XRAY" endif if !RAW_TILE_GRAPHICS @@ -109,6 +109,10 @@ incsrc fanfare.asm incsrc spriteprio.asm incsrc spritefeat.asm +if !PRESERVE_WRAM + incsrc preserve_wram.asm +endif + if !RAW_TILE_GRAPHICS incsrc tilegraphics.asm endif diff --git a/src/mainmenu.asm b/src/mainmenu.asm index cbe4a65e..fb32d86b 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -134,6 +134,17 @@ action_audio_mainmenu: JMP action_mainmenu } +action_sprites_mainmenu: +{ +if !PRESERVE_WRAM + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_SPACETIME + XBA : STA !ram_cm_sprites_spacetime + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY + XBA : LSR : STA !ram_cm_sprites_xray +endif + JMP action_mainmenu +} + action_ctrlshortcut_mainmenu: { TDC : TAX : STA !ram_cm_ctrl_savestates_allowed @@ -148,11 +159,21 @@ action_ctrlshortcut_mainmenu: %a16() TXA : STA !ram_cm_ctrl_add_shortcut_slot - LDA !ram_sram_detection : BNE action_mainmenu + LDA !ram_sram_detection : BNE .end INC : STA !ram_cm_ctrl_savestates_allowed + .end BRA action_mainmenu } +if !FEATURE_VANILLAHUD +else +action_updatetimers_mainmenu: +{ + JSL update_timers_set_cm_ctrl + BRA action_mainmenu +} +endif + action_crop_mainmenu: { ; Prepare crop modes @@ -354,6 +375,10 @@ if !FEATURE_SD2SNES endif dw #mm_goto_timecontrol dw #mm_goto_ctrlshortcut +if !FEATURE_VANILLAHUD +else + dw #mm_goto_updatetimers +endif dw #mm_goto_audiomenu dw #mm_goto_customize dw #mm_goto_cropmenu @@ -391,6 +416,10 @@ if !FEATURE_SD2SNES endif dw #SlowdownMenu>>16 dw #CtrlShortcutMenu>>16 +if !FEATURE_VANILLAHUD +else + dw #UpdateTimersMenu>>16 +endif dw #AudioMenu>>16 dw #CustomizeMenu>>16 dw #CaptureCroppingMenu>>16 @@ -421,7 +450,7 @@ mm_goto_infohud: endif mm_goto_sprites: - %cm_mainmenu("Sprite Features", #SpritesMenu) + %cm_jsl("Sprite Features", #action_sprites_mainmenu, #SpritesMenu) mm_goto_layout: %cm_jsl("Room Layout", #action_layout_mainmenu, #LayoutMenu) @@ -443,6 +472,12 @@ mm_goto_timecontrol: mm_goto_ctrlshortcut: %cm_jsl("Controller Shortcuts", #action_ctrlshortcut_mainmenu, #CtrlShortcutMenu) +if !FEATURE_VANILLAHUD +else +mm_goto_updatetimers: + %cm_jsl("Update Timers", #action_updatetimers_mainmenu, #UpdateTimersMenu) +endif + mm_goto_audiomenu: %cm_jsl("Audio Menu", #action_audio_mainmenu, #AudioMenu) @@ -1795,6 +1830,11 @@ SpritesMenu: dw #sprites_show_samusproj_hitbox dw #sprites_show_enemyproj_hitbox dw #sprites_show_proj_as_32x32 +if !PRESERVE_WRAM + dw #$FFFF + dw #sprites_hud_spacetime + dw #sprites_hud_xray +endif dw #$FFFF dw #sprites_oob_viewer dw #$0000 @@ -1824,6 +1864,38 @@ sprites_show_enemyproj_hitbox: sprites_show_proj_as_32x32: %cm_toggle_bit("32x32 Projectile Boxes", !ram_sprite_feature_flags, !SPRITE_32x32_PROJ, #0) +if !PRESERVE_WRAM +sprites_hud_spacetime: + dw !ACTION_CHOICE + dl #!ram_cm_sprites_spacetime + dw #.routine + db #$28, "Spacetime HUD", #$FF + db #$28, " VANILLA", #$FF + db #$28, " PRESERVED", #$FF + db #$FF + .routine + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_SPACETIME_INVERTED + STA !ram_sprite_feature_flags + LDA !ram_cm_sprites_spacetime : XBA + ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags + RTL + +sprites_hud_xray: + dw !ACTION_CHOICE + dl #!ram_cm_sprites_xray + dw #.routine + db #$28, "X-Ray HUD", #$FF + db #$28, " VANILLA", #$FF + db #$28, " PRESERVED", #$FF + db #$FF + .routine + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY_INVERTED + STA !ram_sprite_feature_flags + LDA !ram_cm_sprites_xray : XBA : ASL + ORA !ram_sprite_feature_flags : STA !ram_sprite_feature_flags + RTL +endif ; PRESERVE_WRAM + sprites_oob_viewer: %cm_toggle_bit("OoB Tile Viewer", !ram_sprite_feature_flags, !SPRITE_OOB_WATCH, .routine) .routine @@ -1856,9 +1928,6 @@ InfoHudMenu: dw #ih_dynamic_frames_held dw #ih_status_icons dw #ih_bonk_indicator -if !PRESERVE_WRAM_DURING_SPACETIME - dw #ih_spacetime_infohud -endif dw #$FFFF dw #ih_ram_watch dw #$0000 @@ -2889,15 +2958,6 @@ ih_status_icons: ih_bonk_indicator: %cm_toggle("Bonk Indicators", !sram_bonk_indicators, #$02, #0) -ih_spacetime_infohud: - dw !ACTION_CHOICE - dl #!ram_spacetime_infohud - dw #$0000 - db #$28, "Spacetime HUD", #$FF - db #$28, " VANILLA", #$FF - db #$28, " PRESERVED", #$FF - db #$FF - ih_ram_watch: %cm_jsl("Customize RAM Watch", #ih_prepare_ram_watch_menu, #RAMWatchMenu) diff --git a/src/menu.asm b/src/menu.asm index e8c7991c..c79a649f 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -1264,7 +1264,8 @@ draw_choice: BRA .loop_choices .loop_done - RTS + %a16() + RTS .found %a16() diff --git a/src/misc.asm b/src/misc.asm index 283297de..368053e6 100644 --- a/src/misc.asm +++ b/src/misc.asm @@ -79,15 +79,6 @@ zebes_planet_tile_data: dw #$0E2F -if !PRESERVE_WRAM_DURING_SPACETIME -org $90ACF6 - JSR original_load_beam_palette - -org $90AD18 - JMP spacetime_routine -endif - - ; Skips the waiting time after teleporting if !FEATURE_PAL org $90E874 @@ -159,11 +150,6 @@ hook_spc_engine_mute_track_4: db $30, $C9, $00, $00 -org $E0E7E0 ; Make EOR $E067E0 read $E0E0 to match vanilla behavior -hook_artificial_varia: - dw $E0E0 - - org $808F24 JSL hook_set_music_track BRA $00 @@ -400,6 +386,8 @@ endif STA $7F0A9A,X ; !SAMUS_LAVA_DAMAGE_SUITS STA $7F0B0E,X ; !DAMAGE_COUNTER +if !FEATURE_VANILLAHUD +else ; Check if door skip is selected LDA !sram_display_mode : CMP !IH_MODE_ROOMSTRAT_INDEX : BNE .check_sprite_flags LDA !sram_room_strat : BEQ .check_super_hud @@ -426,6 +414,7 @@ endif BEQ .draw_earthquake .check_sprite_flags +endif LDA !ram_sprite_feature_flags : BEQ .end ; Remove up to !OAM_HIGH @@ -1119,118 +1108,6 @@ stop_all_sounds: RTL } -if !PRESERVE_WRAM_DURING_SPACETIME -original_load_beam_palette: -{ - AND #$0FFF : ASL : TAY - LDA #$0090 : XBA : STA $01 - LDA $C3C9,Y : STA $00 - LDY #$0000 - LDX #$0000 - - .loop - LDA [$00],Y : STA $7EC1C0,X - INX #2 - INY #2 : CPY #$0020 : BMI .loop - RTS -} - -spacetime_routine: -{ - ; The normal routine shouldn't come here, but sanity check just in case - ; Also skips out if spacetime but Y value is positive - INY #2 : CPY #$0000 : BPL .normal_load_palette - - ; Sanity check that X is 0 (if not then do the original routine) - CPX #$0000 : BNE .normal_load_palette - - ; Check if Y will cause us to reach infohud - TYA : CLC : ADC #($7EC608-$7EC1E2) : CMP #$0000 : BPL .normal_load_palette - - ; We will reach infohud, so run our own loop - INX #2 - .loop_before_infohud - LDA [$00],Y : STA $7EC1C0,X - INY #2 - INX #2 : CPX #($7EC608-$7EC1C0) : BMI .loop_before_infohud - - ; Check if we should skip over infohud - LDA !ram_spacetime_infohud : BEQ .overwrite_infohud - - ; Skip over infohud - ; Instead of load and store, load and load - .loop_skip_infohud - LDA $7EC1C0,X - LDA [$00],Y - INY #2 - INX #2 : CPX #($7EC6C8-$7EC1C0) : BMI .loop_skip_infohud - - ; Check if we finished spacetime while skipping over infohud - CPY #$0020 : BMI .check_sprite_object_ram - RTS - - .overwrite_infohud - ; Check if Y will cause us to reach sprite object ram - TYA : CLC : ADC #($7EEF78-$7EC628) : CMP #$0000 : BMI .loop_before_sprite_object_ram - - .normal_load_loop - LDA [$00],Y : STA $7EC1C0,X - INY #2 - .normal_load_palette - INX #2 : CPY #$0020 : BMI .normal_load_loop - RTS - - .check_sprite_object_ram - ; Check if Y will cause us to reach sprite object ram - TYA : CLC : ADC #($7EEF78-$7EC6E8) : CMP #$0000 : BPL .normal_load_loop - - ; We will reach sprite object ram, so run our own loop - .loop_before_sprite_object_ram - LDA [$00],Y : STA $7EC1C0,X - INY #2 - INX #2 : CPX #($7EEF78-$7EC1C0) : BMI .loop_before_sprite_object_ram - - ; Check if we are copying from unmapped memory ($004500-$007FFF range) - ; If not then overwrite sprite object ram - TYA : ADC $00 : CMP #$4500 : BCC .overwrite_sprite_object_ram - CMP #$7C01 : BCS .overwrite_sprite_object_ram - - ; Skip over sprite object ram - ; Instead of load and store, load and load - .loop_skip_sprite_object_ram - LDA $7EC1C0,X - LDA [$00],Y - INY #2 - INX #2 : CPX #($7EF378-$7EC1C0) : BMI .loop_skip_sprite_object_ram - - ; Check if Y will cause us to reach DP_REGISTER_BACKUP_START - TYA : CLC : ADC #(!DP_REGISTER_BACKUP_START-$7EF398) : CMP #$0000 : BPL .normal_load_loop - - ; It will, so run our own loop - .loop_before_wram - LDA [$00],Y : STA $7EC1C0,X - INY #2 - INX #2 : CPX #(!DP_REGISTER_BACKUP_START-$7EC1C0) : BMI .loop_before_wram - - ; Skip over WRAM - ; Instead of load and store, load and load - .loop_skip_wram - LDA $7EC1C0,X - LDA [$00],Y - INY #2 - INX #2 : CPX #(!WRAM_END-$7EC1C0) : BMI .loop_skip_wram - - ; Check if we finished spacetime while skipping over WRAM - CPY #$0020 : BMI .normal_load_loop - RTS - - .overwrite_sprite_object_ram - ; Check if Y will cause us to reach WRAM - TYA : CLC : ADC #(!DP_REGISTER_BACKUP_START-$7EEF98) : CMP #$0000 : BPL .normal_load_loop - BRA .loop_before_wram -} -endif - misc_shinespark_activation: { ; store timer when shinespark activated diff --git a/src/preserve_wram.asm b/src/preserve_wram.asm new file mode 100644 index 00000000..5139bd16 --- /dev/null +++ b/src/preserve_wram.asm @@ -0,0 +1,2784 @@ + +org $90ACF6 + JSR original_load_beam_palette + +org $90AD18 + JMP spacetime_routine + + +%startfree(90) + +original_load_beam_palette: +{ + AND #$0FFF : ASL : TAY + LDA #$0090 : XBA : STA $01 + LDA $C3C9,Y : STA $00 + LDY #$0000 + LDX #$0000 + + .loop + LDA [$00],Y : STA $7EC1C0,X + INX #2 + INY #2 : CPY #$0020 : BMI .loop + RTS +} + +spacetime_routine: +{ + ; The normal routine shouldn't come here, but sanity check just in case + ; Also skips out if spacetime but Y value is positive + INY #2 : CPY #$0000 : BPL .normal_load_palette + + ; Sanity check that X is 0 (if not then do the original routine) + CPX #$0000 : BNE .normal_load_palette + + ; Check if Y will cause us to reach infohud + TYA : CLC : ADC #($7EC608-$7EC1E2) : CMP #$0000 : BPL .normal_load_palette + + ; We will reach infohud, so run our own loop + INX #2 + .loop_before_infohud + LDA [$00],Y : STA $7EC1C0,X + INY #2 + INX #2 : CPX #($7EC608-$7EC1C0) : BMI .loop_before_infohud + + ; Check if we should skip over infohud + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_SPACETIME : BEQ .overwrite_infohud + + ; Skip over infohud + ; Instead of load and store, load and load + .loop_skip_infohud + LDA $7EC1C0,X + LDA [$00],Y + INY #2 + INX #2 : CPX #($7EC6C8-$7EC1C0) : BMI .loop_skip_infohud + + ; Check if we finished spacetime while skipping over infohud + CPY #$0020 : BMI .check_sprite_object_ram + RTS + + .overwrite_infohud + ; Check if Y will cause us to reach sprite object ram + TYA : CLC : ADC #($7EEF78-$7EC628) : CMP #$0000 : BMI .loop_before_sprite_object_ram + + .normal_load_loop + LDA [$00],Y : STA $7EC1C0,X + INY #2 + .normal_load_palette + INX #2 : CPY #$0020 : BMI .normal_load_loop + RTS + + .check_sprite_object_ram + ; Check if Y will cause us to reach sprite object ram + TYA : CLC : ADC #($7EEF78-$7EC6E8) : CMP #$0000 : BPL .normal_load_loop + + ; We will reach sprite object ram, so run our own loop + .loop_before_sprite_object_ram + LDA [$00],Y : STA $7EC1C0,X + INY #2 + INX #2 : CPX #($7EEF78-$7EC1C0) : BMI .loop_before_sprite_object_ram + + ; Check if we are copying from unmapped memory ($004500-$007FFF range) + ; If not then overwrite sprite object ram + TYA : ADC $00 : CMP #$4500 : BCC .overwrite_sprite_object_ram + CMP #$7C01 : BCS .overwrite_sprite_object_ram + + ; Skip over sprite object ram + ; Instead of load and store, load and load + .loop_skip_sprite_object_ram + LDA $7EC1C0,X + LDA [$00],Y + INY #2 + INX #2 : CPX #($7EF378-$7EC1C0) : BMI .loop_skip_sprite_object_ram + + ; Check if Y will cause us to reach DP_REGISTER_BACKUP_START + TYA : CLC : ADC #(!DP_REGISTER_BACKUP_START-$7EF398) : CMP #$0000 : BPL .normal_load_loop + + ; It will, so run our own loop + .loop_before_wram + LDA [$00],Y : STA $7EC1C0,X + INY #2 + INX #2 : CPX #(!DP_REGISTER_BACKUP_START-$7EC1C0) : BMI .loop_before_wram + + ; Skip over WRAM + ; Instead of load and store, load and load + .loop_skip_wram + LDA $7EC1C0,X + LDA [$00],Y + INY #2 + INX #2 : CPX #(!WRAM_END-$7EC1C0) : BMI .loop_skip_wram + + ; Check if we finished spacetime while skipping over WRAM + CPY #$0020 : BMI .normal_load_loop + RTS + + .overwrite_sprite_object_ram + ; Check if Y will cause us to reach WRAM + TYA : CLC : ADC #(!DP_REGISTER_BACKUP_START-$7EEF98) : CMP #$0000 : BPL .normal_load_loop + BRA .loop_before_wram +} + +%endfree(90) + + +if !FEATURE_PAL +org $91BE0A +else +org $91BEB2 +endif + PLB + JMP (hook_xray_offscreen_table,X) +hook_xray_offscreen_table: + dw hook_xray_offscreen_aim_right + dw hook_xray_offscreen_aim_up + dw hook_xray_offscreen_aim_down + dw hook_xray_offscreen_aim_left + dw hook_xray_offscreen_horizontal + +if !FEATURE_PAL +org $91BEC9 +else +org $91BF71 +endif + RTL + +if !FEATURE_PAL +org $91BF79 +else +org $91C021 +endif + RTL + +if !FEATURE_PAL +org $91BFBA +else +org $91C062 +endif + RTL + +if !FEATURE_PAL +org $91C20E +else +org $91C2B6 +endif + RTL + +if !FEATURE_PAL +org $91C4A2 +else +org $91C54A +endif + RTL + +if !FEATURE_PAL +org $91C547 +else +org $91C5EF +endif + PLB + JMP (hook_xray_onscreen_table,X) +hook_xray_onscreen_table: + dw hook_xray_onscreen_aim_right + dw hook_xray_onscreen_aim_up + dw hook_xray_onscreen_aim_down + dw hook_xray_onscreen_aim_left + dw hook_xray_onscreen_horizontal + +if !FEATURE_PAL +org $91C5B7 +else +org $91C65F +endif + RTL + +if !FEATURE_PAL +org $91C618 +else +org $91C6C0 +endif + RTL + +if !FEATURE_PAL +org $91C66D +else +org $91C715 +endif + RTL + +if !FEATURE_PAL +org $91C7CB +else +org $91C873 +endif + RTL + +if !FEATURE_PAL +org $91C92B +else +org $91C9D3 +endif + RTL + + +%startfree(91) + +hook_xray_offscreen_aim_right: +{ + %ai16() + LDA $18 : DEC : ASL : TAY + CPY #$27F8 : BCS .preserve + .vanilla +if !FEATURE_PAL + JMP $BE22 +else + JMP $BECA +endif + + .preserve + CPY #$8008 : BCS .vanilla + JML xray_offscreen_aim_right +} + +hook_xray_offscreen_aim_left: +{ + %ai16() + LDA $18 : DEC : ASL : TAY + CPY #$27F8 : BCS .preserve + .vanilla +if !FEATURE_PAL + JMP $BED2 +else + JMP $BF7A +endif + + .preserve + CPY #$8008 : BCS .vanilla + JML xray_offscreen_aim_left +} + +hook_xray_offscreen_aim_up: +{ + %ai16() + LDA $18 : DEC : ASL : TAY + CPY #$27F8 : BCS .preserve + .vanilla +if !FEATURE_PAL + JMP $BF82 +else + JMP $C02A +endif + + .preserve + CPY #$8008 : BCS .vanilla + LDA $16 : STA $22 : STA $24 + LDA $1A : CMP #$00C0 : BMI .up_right + LDA $1C : CMP #$00C0 : BPL .up_left + + ; Protection not needed for straight up case since this should not happen +if !FEATURE_PAL + JMP $BF9B +else + JMP $C043 +endif + + .up_right + JML xray_offscreen_up_right + + .up_left + JML xray_offscreen_up_left + + .final + LDY $12 + CPY #$6708 : BCS .final_loop + CPY #$5CF8 : BCS .final_skip + CPY #$32EC : BCS .final_loop + CPY #$27FF : BCC .final_loop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .final_loop + .final_skip + LDA #$00FF + BRA .final_iny + + .final_loop + LDA #$00FF : STA [$00],Y + .final_iny + INY #2 : CPY #$01CC : BMI .final_loop + PLP + RTL +} + +hook_xray_offscreen_aim_down: +{ + %ai16() + LDA $18 : ASL : TAY + CPY #$27F8 : BCS .preserve + .vanilla +if !FEATURE_PAL + JMP $C1DE +else + JMP $C286 +endif + + .preserve + CPY #$8008 : BCS .vanilla + LDA $16 : STA $22 : STA $24 + LDA $1C : CMP #$0080 : BMI .down_right + LDA $1A : CMP #$0080 : BPL .down_left + + ; Protection not needed for straight down case since this should not happen +if !FEATURE_PAL + JMP $C1F7 +else + JMP $C29F +endif + + .down_right + JML xray_offscreen_down_right + + .down_left + JML xray_offscreen_down_left + + .final + LDY $12 + CPY #$6708 : BCS .final_first + CPY #$5CF8 : BCS .final_first_skip + CPY #$32EC : BCS .final_second + CPY #$27FF : BCC .final_third + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .final_third + BRA .final_second_skip + + .final_first + LDA #$00FF : STA [$00],Y + DEY #2 : BMI .final_end + .final_first_loop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .final_first_loop + .final_first_skip + DEY #2 : CPY #$5CF8 : BCS .final_first_skip + .final_second + LDA #$00FF + .final_second_loop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .final_second_loop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .final_third + .final_second_skip + DEY #2 : CPY #$27FF : BCS .final_second_skip + .final_third + LDA #$00FF + .final_third_loop + STA [$00],Y + DEY #2 : BPL .final_third_loop + .final_end + PLP + RTL +} + +hook_xray_offscreen_horizontal: +{ + %ai16() + LDA $18 : DEC : ASL : TAY + CPY #$27F8 : BCS .preserve + .vanilla +if !FEATURE_PAL + JMP $C473 +else + JMP $C51B +endif + + .preserve + CPY #$8008 : BCS .vanilla + JML xray_offscreen_horizontal +} + +hook_xray_onscreen_aim_right: +{ + %ai16() + LDA $18 : DEC : ASL : TAY + CPY #$27F8 : BCS .preserve + .vanilla +if !FEATURE_PAL + JMP $C55F +else + JMP $C607 +endif + + .preserve + CPY #$8008 : BCS .vanilla + JML xray_onscreen_aim_right +} + +hook_xray_onscreen_aim_left: +{ + %ai16() + LDA $18 : DEC : ASL : TAY + CPY #$27F8 : BCS .preserve + .vanilla +if !FEATURE_PAL + JMP $C5C0 +else + JMP $C668 +endif + + .preserve + CPY #$8008 : BCS .vanilla + JML xray_onscreen_aim_left +} + +hook_xray_onscreen_aim_up: +{ + %ai16() + LDA $18 : DEC : ASL : TAY + CPY #$27F8 : BCS .preserve + .vanilla +if !FEATURE_PAL + JMP $C621 +else + JMP $C6C9 +endif + + .preserve + CPY #$8008 : BCS .vanilla + CPY #$6708 : BCS .store + CPY #$5CF8 : BCS .skip + CPY #$32EC : BCS .store + CPY #$27FF : BCC .store : BEQ .store_one + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BNE .skip + .store + %a8() + LDA $17 : STA [$00],Y + INY + LDA $17 : STA [$00],Y + %a16() + DEY + .skip + DEY #2 + LDA $16 : STA $22 : STA $24 + LDA $1A : CMP #$00C0 : BMI .up_right + LDA $1C : CMP #$00C0 : BPL .up_left + + ; Protection not needed for straight up case since this should not happen +if !FEATURE_PAL + JMP $C64A +else + JMP $C6F2 +endif + + .store_one + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .store + %a8() + LDA $17 : STA [$00],Y + %a16() + BRA .skip + + .up_right + ; Kept in bank 91 due to using !OFFSCREEN_HDMA_INDEX + JMP xray_onscreen_up_right + + .up_left + JML xray_onscreen_up_left + + .final + LDA $18 : ASL : TAY + LDA [$00],Y : CMP #$00FF : BEQ .final_end + CPY #$6708 : BCS .final_loop + CPY #$5CF8 : BCS .final_skip + CPY #$32EC : BCS .final_loop + CPY #$27FF : BCC .final_loop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .final_loop + .final_skip + LDA #$00FF + BRA .final_iny + + .final_loop + LDA #$00FF : STA [$00],Y + .final_iny + INY #2 : CPY #$01CC : BMI .final_loop + .final_end + PLP + RTL +} + +hook_xray_onscreen_aim_down: +{ + %ai16() + LDA $18 : DEC : ASL : TAY + CPY #$27F8 : BCS .preserve + .vanilla +if !FEATURE_PAL + JMP $C782 +else + JMP $C82A +endif + + .preserve + CPY #$8008 : BCS .vanilla + CPY #$6708 : BCS .store + CPY #$5CF8 : BCS .skip + CPY #$32EC : BCS .store + CPY #$27FF : BCC .store : BEQ .store_one + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BNE .skip + .store + %a8() + LDA $17 : STA [$00],Y + INY + LDA $17 : STA [$00],Y + %a16() + .merge + INY + LDA $16 : STA $22 : STA $24 + LDA $1C : CMP #$0080 : BMI .down_right + LDA $1A : CMP #$0080 : BPL .down_left + + ; Protection not needed for straight down case since this should not happen +if !FEATURE_PAL + JMP $C7A9 +else + JMP $C851 +endif + + .store_one + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .store + %a8() + LDA $17 : STA [$00],Y + %a16() + .skip + INY + BRA .merge + + .down_right + ; Kept in bank 91 due to using !OFFSCREEN_HDMA_INDEX + JMP xray_onscreen_down_right + + .down_left + JML xray_onscreen_down_left + + .final + LDA $18 : DEC #2 : ASL : TAY + LDA [$00],Y : CMP #$00FF : BEQ .final_skip + CPY #$6708 : BCS .final_first + CPY #$5CF8 : BCS .final_first_skip + CPY #$32EC : BCS .final_second + CPY #$27FF : BCC .final_third + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .final_third + BRA .final_second_skip + + .final_skip + PLP + RTL + + .final_first + LDA #$00FF : STA [$00],Y + DEY #2 : BMI .final_end + .first_loop + LDA [$00],Y : CMP #$00FF : BEQ .final_end + LDA #$00FF : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .first_loop + .first_skip_loop + LDA [$00],Y : CMP #$00FF : BEQ .final_end + .final_first_skip + LDA #$00FF + DEY #2 : CPY #$5CF8 : BCS .first_skip_loop + .second_loop + LDA [$00],Y : CMP #$00FF : BEQ .final_end + .final_second + LDA #$00FF : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .second_loop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .third_loop + .second_skip_loop + LDA [$00],Y : CMP #$00FF : BEQ .final_end + .final_second_skip + LDA #$00FF + DEY #2 : CPY #$27FF : BCS .second_skip_loop + .third_loop + LDA [$00],Y : CMP #$00FF : BEQ .final_end + .final_third + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .third_loop + .final_end + PLP + RTL +} + +hook_xray_onscreen_horizontal: +{ + %ai16() + LDA $18 : DEC : ASL : TAY + CPY #$27F8 : BCS .preserve + .vanilla +if !FEATURE_PAL + JMP $C8F8 +else + JMP $C9A0 +endif + + .preserve + CPY #$8008 : BCS .vanilla + JML xray_onscreen_horizontal +} + +xray_onscreen_up_right: +{ + PHY + CPY #$6708 : BCC .leftContinue + LDA $22 : CLC : ADC $1E : STA $22 + BCS .firstLeftLostScreen + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BPL .leftOnscreenFirstLoop + .firstLeftEnd + JMP .leftEdgeEnd + + .firstLeftLostScreen + STY !OFFSCREEN_HDMA_INDEX + %a8() : LDA #$FF : STA [$00],Y + DEY #2 : BMI .firstLeftEnd + JMP .leftLostFirstLoop + + .leftContinue + CPY #$5CF8 : BCS .leftOnscreenFirstSkip + CPY #$32EC : BCS .leftOnscreenSecondLoop + CPY #$2800 : BCC .leftOnscreenThirdLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenThirdLoop + BRA .leftOnscreenSecondSkip + + .leftOnscreenFirstLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostFirst + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : CPY #$6708 : BCS .leftOnscreenFirstLoop + .leftOnscreenFirstSkip + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostFirstSkip + %a8() : LDA $23 : %a16() + DEY #2 : CPY #$5CF8 : BCS .leftOnscreenFirstSkip + .leftOnscreenSecondLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostSecond + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : CPY #$32EC : BCS .leftOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenThirdLoop + .leftOnscreenSecondSkip + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostSecondSkip + %a8() : LDA $23 : %a16() + DEY #2 : CPY #$2800 : BCS .leftOnscreenSecondSkip + .leftOnscreenThirdLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostThird + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BPL .leftOnscreenThirdLoop + BRA .leftEdgeEnd + + .leftLostFirst + STY !OFFSCREEN_HDMA_INDEX + %a8() : LDA #$FF + .leftLostFirstLoop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .leftLostFirstLoop + BRA .leftLostFirstSkipLoop + + .leftLostFirstSkip + STY !OFFSCREEN_HDMA_INDEX + %a8() : LDA #$FF + .leftLostFirstSkipLoop + DEY #2 : CPY #$5CF8 : BCS .leftLostFirstSkipLoop + BRA .leftLostSecondLoop + + .leftLostSecond + STY !OFFSCREEN_HDMA_INDEX + %a8() : LDA #$FF + .leftLostSecondLoop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .leftLostSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftLostThirdPrep + BRA .leftLostSecondSkipPrep + + .leftLostSecondSkip + STY !OFFSCREEN_HDMA_INDEX + .leftLostSecondSkipPrep + %a8() : LDA #$FF + .leftLostSecondSkipLoop + DEY #2 : CPY #$2800 : BCS .leftLostSecondSkipLoop + + .leftLostThird + STY !OFFSCREEN_HDMA_INDEX + .leftLostThirdPrep + %a8() : LDA #$FF + .leftLostThirdLoop + STA [$00],Y + DEY #2 : BPL .leftLostThirdLoop + + .leftEdgeEnd + %a16() + PLY : INY + CPY #$6708 : BCC .rightContinue + LDA $24 : CLC : ADC $20 : STA $24 + BCS .firstRightLostScreen + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : BPL .rightOnscreenFirstLoop + .firstRightEnd + JMP .rightEdgeEnd + + .firstRightLostScreen + %a8() : LDA #$FF : STA [$00],Y + DEY #2 : BMI .firstRightEnd + JMP .rightLostFirstLoop + + .rightContinue + CPY #$5CF8 : BCS .rightOnscreenFirstSkip + CPY #$32EC : BCS .rightOnscreenSecondLoop + CPY #$2800 : BCC .rightOnscreenThirdLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenThirdLoop + BRA .rightOnscreenSecondSkip + + .rightOnscreenFirstLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostFirst + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : CPY #$6708 : BCS .rightOnscreenFirstLoop + .rightOnscreenFirstSkip + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostFirstSkip + %a8() : LDA $25 : %a16() + DEY #2 : CPY #$5CF8 : BCS .rightOnscreenFirstSkip + .rightOnscreenSecondLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostSecond + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : CPY #$32EC : BCS .rightOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenThirdLoop + .rightOnscreenSecondSkip + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostSecondSkip + %a8() : LDA $25 : %a16() + DEY #2 : CPY #$2800 : BCS .rightOnscreenSecondSkip + .rightOnscreenThirdLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostThird + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : BPL .rightOnscreenThirdLoop + JMP .rightEdgeEnd + + .rightLostFirst + %a8() + .rightLostFirstLoop + LDA #$FF : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .rightLostFirstLoop + .rightLostFirstSkip + LDA #$EAFF ; in 8-bit mode this becomes LDA #$FF : NOP + DEY #2 : CPY #$5CF8 : BCS .rightLostFirstSkip + .rightLostSecond + %a8() + .rightLostSecondLoop + LDA #$FF : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .rightLostSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightLostThird + .rightLostSecondSkip + LDA #$EAFF ; in 8-bit mode this becomes LDA #$FF : NOP + DEY #2 : CPY #$2800 : BCS .rightLostSecondSkip + .rightLostThird + %a8() + .rightLostThirdLoop + LDA #$FF : STA [$00],Y + DEY #2 : BPL .rightLostThirdLoop + + LDY !OFFSCREEN_HDMA_INDEX : BEQ .rightEdgeEnd + DEY #2 : BMI .rightEdgeEnd + %a16() : LDA #$00FF + CPY #$6708 : BCS .finalFirstLoop + CPY #$5CF8 : BCS .finalFirstSkip + CPY #$32EC : BCS .finalSecondLoop + CPY #$27FF : BCC .finalThirdLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalThird + LDA #$00FF + BRA .finalSecondSkip + + .finalFirstLoop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .finalFirstLoop + .finalFirstSkip + DEY #2 : CPY #$5CF8 : BCS .finalFirstSkip + .finalSecondLoop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .finalSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalThird + .finalSecondSkip + DEY #2 : CPY #$27FF : BCS .finalSecondSkip + .finalThird + LDA #$00FF + .finalThirdLoop + STA [$00],Y + DEY #2 : BPL .finalThirdLoop + + .rightEdgeEnd + %a16() + JMP hook_xray_onscreen_aim_up_final +} + +xray_onscreen_down_right: +{ + PHY + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostScreen + CPY #$6708 : BCS .rightOnscreenStore + CPY #$5CF8 : BCS .rightOnscreenIny + CPY #$32EC : BCS .rightOnscreenStore + CPY #$27FF : BCC .rightOnscreenStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenStore + BRA .rightOnscreenIny + + .rightOnscreenLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostScreen + .rightOnscreenStore + LDA $25 : STA [$00],Y + .rightOnscreenIny + INY #2 : CPY #$01CC : BMI .rightOnscreenLoop + BRA .rightEdgeEnd + + .rightLostScreen + STY !OFFSCREEN_HDMA_INDEX + CPY #$6708 : BCS .rightLostStore + CPY #$5CF8 : BCS .rightLostSkip + CPY #$32EC : BCS .rightLostStore + CPY #$27FF : BCC .rightLostStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightLostStore + .rightLostSkip + LDA #$00FF + BRA .rightLostIny + + .rightLostStore + LDA #$00FF + .rightLostLoop + STA [$00],Y + .rightLostIny + INY #2 : CPY #$01CC : BMI .rightLostLoop + + .rightEdgeEnd + PLY : INY + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostScreen + CPY #$6708 : BCS .leftOnscreenStore + CPY #$5CF8 : BCS .leftOnscreenIny + CPY #$32EC : BCS .leftOnscreenStore + CPY #$2800 : BCC .leftOnscreenStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenStore + BRA .leftOnscreenIny + + .leftOnscreenLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostScreen + .leftOnscreenStore + %a8() : LDA $23 : STA [$00],Y : %a16() + .leftOnscreenIny + INY #2 : CPY #$01CC : BMI .leftOnscreenLoop + BRA .leftEdgeEnd + + .leftLostScreen + CPY #$6708 : BCS .leftLostStore + CPY #$5CF8 : BCS .leftLostSkip + CPY #$32EC : BCS .leftLostStore + CPY #$2800 : BCC .leftLostStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftLostStore + .leftLostSkip + %a8() + BRA .leftLostIny + + .leftLostStore + %a8() + .leftLostLoop + LDA #$FF : STA [$00],Y + .leftLostIny + INY #2 : CPY #$01CC : BMI .leftLostLoop + + %a16() + LDY !OFFSCREEN_HDMA_INDEX : BEQ .leftEdgeEnd + INY #2 : CPY #$01CC : BPL .leftEdgeEnd + CPY #$6708 : BCS .finalStore + CPY #$5CF8 : BCS .finalSkip + CPY #$32EC : BCS .finalStore + CPY #$27FF : BCC .finalStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalStore + .finalSkip + LDA #$00FF + BRA .finalIny + + .finalStore + LDA #$00FF + .finalLoop + STA [$00],Y + .finalIny + INY #2 : CPY #$01CC : BMI .finalLoop + .leftEdgeEnd + JMP hook_xray_onscreen_aim_down_final +} + +%endfree(91) + + +org $E0E7E0 +print pc, " preserve WRAM start" + +; Make EOR $E067E0 read $E0E0 to match vanilla behavior +hook_artificial_varia: + dw $E0E0 + +xray_offscreen_aim_right: +{ + LDA $16 : STA $22 : STA $24 + .leftOffscreenLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftFoundScreen + DEY #2 : BPL .leftOffscreenLoop + STZ $12 + JMP .leftEdgeEnd + + .leftFoundScreen + TYA : INC #2 : STA $12 + CPY #$6708 : BCS .leftFoundFirst + CPY #$5CF8 : BCS .leftFoundSkip + CPY #$32EC : BCS .leftFoundSecond + CPY #$27FF : BCC .leftFoundThird + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftFoundThird + DEY #2 : CPY #$27FF : BCC .leftFoundThirdContinue + JMP .leftOnscreenSecondSkip + + .leftFoundFirst + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 + LDA $22 : CLC : ADC $1E : STA $22 + BCS .firstLostScreen + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 : BPL .leftOnscreenFirstLoop + JMP .leftEdgeEnd + + .leftFoundSkip + DEY #2 + BRA .leftOnscreenFirstSkip + + .leftFoundSecond + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 + BRA .leftOnscreenSecondLoop + + .leftFoundThird + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 + .leftFoundThirdContinue + BRA .leftOnscreenThirdLoop + + .firstLostScreen + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .leftLostFirstLoop + JMP .leftEdgeEnd + + .leftOnscreenFirstLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostFirst + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .leftOnscreenFirstLoop + .leftOnscreenFirstSkip + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostFirstSkip + LDA $23 : ORA #$FF00 + DEY #2 : CPY #$5CF8 : BCS .leftOnscreenFirstSkip + .leftOnscreenSecondLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostSecond + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .leftOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenThirdLoop + .leftOnscreenSecondSkip + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostSecondSkip + LDA $23 : ORA #$FF00 + DEY #2 : CPY #$27FF : BCS .leftOnscreenSecondSkip + .leftOnscreenThirdLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostThirdLoop + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 : BPL .leftOnscreenThirdLoop + BRA .leftEdgeEnd + + .leftLostFirst + LDA #$00FF + .leftLostFirstLoop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .leftLostFirstLoop + .leftLostFirstSkip + LDA #$00FF + DEY #2 : CPY #$5CF8 : BCS .leftLostFirstSkip + .leftLostSecond + LDA #$00FF + .leftLostSecondLoop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .leftLostSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftLostThirdLoop + .leftLostSecondSkip + LDA #$00FF + DEY #2 : CPY #$27FF : BCS .leftLostSecondSkip + .leftLostThirdLoop + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .leftLostThirdLoop + + .leftEdgeEnd + LDA $18 : ASL : TAY + .rightOffscreenLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightFoundScreen + INY #2 : CPY #$01CC : BMI .rightOffscreenLoop + STY $14 + JMP .rightEdgeEnd + + .rightFoundScreen + TYA : DEC #2 : STA $14 + CPY #$6708 : BCS .rightFoundStore + CPY #$5CF8 : BCS .rightFoundSkip + CPY #$32EC : BCS .rightFoundStore + CPY #$27FF : BCC .rightFoundStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BNE .rightFoundSkip + .rightFoundStore + LDA $25 : ORA #$FF00 : STA [$00],Y + .rightFoundSkip + INY #2 + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostScreen + CPY #$6708 : BCS .rightOnscreenStore + CPY #$5CF8 : BCS .rightOnscreenIny + CPY #$32EC : BCS .rightOnscreenStore + CPY #$27FF : BCC .rightOnscreenStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenStore + BRA .rightOnscreenIny + + .rightOnscreenLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostScreen + .rightOnscreenStore + LDA $25 : ORA #$FF00 : STA [$00],Y + .rightOnscreenIny + INY #2 : CPY #$01CC : BMI .rightOnscreenLoop + BRA .rightEdgeEnd + + .rightLostScreen + CPY #$6708 : BCS .rightLostLoop + CPY #$5CF8 : BCS .rightLostSkip + CPY #$32EC : BCS .rightLostLoop + CPY #$27FF : BCC .rightLostLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightLostLoop + .rightLostSkip + LDA #$00FF + BRA .rightLostIny + + .rightLostLoop + LDA #$00FF : STA [$00],Y + .rightLostIny + INY #2 : CPY #$01CC : BMI .rightLostLoop + + .rightEdgeEnd + LDY $12 + CPY #$6708 : BCS .finalThirdLoop + CPY #$5CF8 : BCS .finalSecondSkip + CPY #$32EC : BCS .finalSecond + CPY #$27FF : BCC .finalFirst + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalSecond + BRA .finalFirstSkip + + .finalFirst + LDA $14 : CMP #$27FE : BCC .finalThirdLoop + .finalFirstLoop + LDA #$FF00 : STA [$00],Y + INY #2 : CPY #$27FE : BMI .finalFirstLoop : BEQ .finalFirstLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalSecond + .finalFirstSkip + LDA $14 : CMP #$32EC : BCC .finalSkipLoop + .finalFirstSkipLoop + LDA #$FF00 + INY #2 : CPY #$32EC : BMI .finalFirstSkipLoop : BEQ .finalFirstSkipLoop + .finalSecond + LDA $14 : CMP #$5CF8 : BCC .finalThirdLoop + .finalSecondLoop + LDA #$FF00 : STA [$00],Y + INY #2 : CPY #$5CF8 : BMI .finalSecondLoop : BEQ .finalSecondLoop + .finalSecondSkip + LDA $14 : CMP #$6708 : BCC .finalSkipLoop + .finalSecondSkipLoop + LDA #$FF00 + INY #2 : CPY #$6708 : BMI .finalSecondSkipLoop : BEQ .finalSecondSkipLoop + .finalThirdLoop + LDA #$FF00 : STA [$00],Y + INY #2 : CPY $14 : BMI .finalThirdLoop : BEQ .finalThirdLoop + PLP + RTL + + .finalSkipLoop + LDA #$FF00 : NOP + INY #2 : CPY $14 : BMI .finalSkipLoop : BEQ .finalSkipLoop + PLP + RTL +} + +xray_offscreen_aim_left: +{ + LDA $16 : STA $22 : STA $24 + .rightOffscreenLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightFoundScreen + DEY #2 : BPL .rightOffscreenLoop + STZ $12 + JMP .rightEdgeEnd + + .rightFoundScreen + TYA : INC #2 : STA $12 + CPY #$6708 : BCS .rightFoundFirst + CPY #$5CF8 : BCS .rightFoundSkip + CPY #$32EC : BCS .rightFoundSecond + CPY #$27FF : BCC .rightFoundThird + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightFoundThird + DEY #2 : CPY #$27FF : BCC .rightFoundThirdContinue + JMP .rightOnscreenSecondSkip + + .rightFoundFirst + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 + LDA $24 : SEC : SBC $20 : STA $24 + BCC .firstLostScreen + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 : BPL .rightOnscreenFirstLoop + JMP .rightEdgeEnd + + .rightFoundSkip + DEY #2 + BRA .rightOnscreenFirstSkip + + .rightFoundSecond + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 + BRA .rightOnscreenSecondLoop + + .rightFoundThird + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 + .rightFoundThirdContinue + BRA .rightOnscreenThirdLoop + + .firstLostScreen + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .rightLostFirstLoop + JMP .rightEdgeEnd + + .rightOnscreenFirstLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostFirst + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .rightOnscreenFirstLoop + .rightOnscreenFirstSkip + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostFirstSkip + LDA $24 : AND #$FF00 + DEY #2 : CPY #$5CF8 : BCS .rightOnscreenFirstSkip + .rightOnscreenSecondLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostSecond + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .rightOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenThirdLoop + .rightOnscreenSecondSkip + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostSecondSkip + LDA $24 : AND #$FF00 + DEY #2 : CPY #$27FF : BCS .rightOnscreenSecondSkip + .rightOnscreenThirdLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostThirdLoop + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 : BPL .rightOnscreenThirdLoop + BRA .rightEdgeEnd + + .rightLostFirst + LDA #$00FF + .rightLostFirstLoop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .rightLostFirstLoop + .rightLostFirstSkip + LDA #$00FF + DEY #2 : CPY #$5CF8 : BCS .rightLostFirstSkip + .rightLostSecond + LDA #$00FF + .rightLostSecondLoop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .rightLostSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightLostThirdLoop + .rightLostSecondSkip + LDA #$00FF + DEY #2 : CPY #$27FF : BCS .rightLostSecondSkip + .rightLostThirdLoop + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .rightLostThirdLoop + + .rightEdgeEnd + LDA $18 : ASL : TAY + .leftOffscreenLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftFoundScreen + INY #2 : CPY #$01CC : BMI .leftOffscreenLoop + STY $14 + JMP .leftEdgeEnd + + .leftFoundScreen + TYA : DEC #2 : STA $14 + CPY #$6708 : BCS .leftFoundStore + CPY #$5CF8 : BCS .leftFoundSkip + CPY #$32EC : BCS .leftFoundStore + CPY #$27FF : BCC .leftFoundStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BNE .leftFoundSkip + .leftFoundStore + LDA $22 : AND #$FF00 : STA [$00],Y + .leftFoundSkip + INY #2 + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostScreen + CPY #$6708 : BCS .leftOnscreenStore + CPY #$5CF8 : BCS .leftOnscreenIny + CPY #$32EC : BCS .leftOnscreenStore + CPY #$27FF : BCC .leftOnscreenStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenStore + BRA .leftOnscreenIny + + .leftOnscreenLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostScreen + .leftOnscreenStore + LDA $22 : AND #$FF00 : STA [$00],Y + .leftOnscreenIny + INY #2 : CPY #$01CC : BMI .leftOnscreenLoop + BRA .leftEdgeEnd + + .leftLostScreen + CPY #$6708 : BCS .leftLostLoop + CPY #$5CF8 : BCS .leftLostSkip + CPY #$32EC : BCS .leftLostLoop + CPY #$27FF : BCC .leftLostLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftLostLoop + .leftLostSkip + LDA #$00FF + BRA .leftLostIny + + .leftLostLoop + LDA #$00FF : STA [$00],Y + .leftLostIny + INY #2 : CPY #$01CC : BMI .leftLostLoop + + .leftEdgeEnd + LDY $12 + CPY #$6708 : BCS .finalThirdLoop + CPY #$5CF8 : BCS .finalSecondSkip + CPY #$32EC : BCS .finalSecond + CPY #$27FF : BCC .finalFirst + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalSecond + BRA .finalFirstSkip + + .finalFirst + LDA $14 : CMP #$27FE : BCC .finalThirdLoop + .finalFirstLoop + LDA #$FF00 : STA [$00],Y + INY #2 : CPY #$27FE : BMI .finalFirstLoop : BEQ .finalFirstLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalSecond + .finalFirstSkip + LDA $14 : CMP #$32EC : BCC .finalSkipLoop + .finalFirstSkipLoop + LDA #$FF00 + INY #2 : CPY #$32EC : BMI .finalFirstSkipLoop : BEQ .finalFirstSkipLoop + .finalSecond + LDA $14 : CMP #$5CF8 : BCC .finalThirdLoop + .finalSecondLoop + LDA #$FF00 : STA [$00],Y + INY #2 : CPY #$5CF8 : BMI .finalSecondLoop : BEQ .finalSecondLoop + .finalSecondSkip + LDA $14 : CMP #$6708 : BCC .finalSkipLoop + .finalSecondSkipLoop + LDA #$FF00 + INY #2 : CPY #$6708 : BMI .finalSecondSkipLoop : BEQ .finalSecondSkipLoop + .finalThirdLoop + LDA #$FF00 : STA [$00],Y + INY #2 : CPY $14 : BMI .finalThirdLoop : BEQ .finalThirdLoop + PLP + RTL + + .finalSkipLoop + LDA #$FF00 : NOP + INY #2 : CPY $14 : BMI .finalSkipLoop : BEQ .finalSkipLoop + PLP + RTL +} + +xray_offscreen_up_right: +{ + PHY + .leftOffscreenLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftFoundScreen + DEY #2 : BPL .leftOffscreenLoop + STZ $12 + JMP .leftEdgeEnd + + .leftFoundScreen + TYA : INC #2 : STA $12 + CPY #$6708 : BCS .leftFoundFirst + CPY #$5CF8 : BCS .leftFoundSkip + CPY #$32EC : BCS .leftFoundSecond + CPY #$2800 : BCC .leftFoundThird + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftFoundThird + DEY #2 : CPY #$2800 : BCC .leftFoundThirdContinue + JMP .leftOnscreenSecondSkip + + .leftFoundFirst + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BPL .leftOnscreenFirstLoop + .leftFoundEnd + LDA #$0002 : STA $12 + JMP .leftEdgeEnd + + .leftFoundSkip + DEY #2 + BRA .leftOnscreenFirstSkip + + .leftFoundSecond + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 + BRA .leftOnscreenSecondLoop + + .leftFoundThird + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BMI .leftFoundEnd + .leftFoundThirdContinue + BRA .leftOnscreenThirdLoop + + .leftOnscreenFirstLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostFirst + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : CPY #$6708 : BCS .leftOnscreenFirstLoop + .leftOnscreenFirstSkip + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostFirstSkip + %a8() : LDA $23 : %a16() + DEY #2 : CPY #$5CF8 : BCS .leftOnscreenFirstSkip + .leftOnscreenSecondLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostSecond + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : CPY #$32EC : BCS .leftOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenThirdLoop + .leftOnscreenSecondSkip + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostSecondSkip + %a8() : LDA $23 : %a16() + DEY #2 : CPY #$2800 : BCS .leftOnscreenSecondSkip + .leftOnscreenThirdLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostThird + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BPL .leftOnscreenThirdLoop + BRA .leftEdgeEnd + + .leftLostFirst + %a8() + .leftLostFirstLoop + LDA #$FF : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .leftLostFirstLoop + .leftLostFirstSkip + LDA #$EAFF ; in 8-bit mode this becomes LDA #$FF : NOP + DEY #2 : CPY #$5CF8 : BCS .leftLostFirstSkip + .leftLostSecond + %a8() + .leftLostSecondLoop + LDA #$FF : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .leftLostSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftLostThird + .leftLostSecondSkip + LDA #$EAFF ; in 8-bit mode this becomes LDA #$FF : NOP + DEY #2 : CPY #$2800 : BCS .leftLostSecondSkip + .leftLostThird + %a8() + .leftLostThirdLoop + LDA #$FF : STA [$00],Y + DEY #2 : BPL .leftLostThirdLoop + + .leftEdgeEnd + %a16() + PLY : INY + .rightOffscreenLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightFoundScreen + DEY #2 : BPL .rightOffscreenLoop + LDA #$0001 : STA $14 + JMP .rightEdgeEnd + + .rightFoundScreen + TYA : INC #2 : STA $14 + CPY #$6708 : BCS .rightFoundFirst + CPY #$5CF8 : BCS .rightFoundSkip + CPY #$32EC : BCS .rightFoundSecond + CPY #$2800 : BCC .rightFoundThird + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightFoundThird + DEY #2 : CPY #$2800 : BCC .rightFoundThirdContinue + JMP .rightOnscreenSecondSkip + + .rightFoundFirst + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : BPL .rightOnscreenFirstLoop + .rightFoundEnd + LDA #$0003 : STA $14 + JMP .rightEdgeEnd + + .rightFoundSkip + DEY #2 + BRA .rightOnscreenFirstSkip + + .rightFoundSecond + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 + BRA .rightOnscreenSecondLoop + + .rightFoundThird + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : BMI .rightFoundEnd + .rightFoundThirdContinue + BRA .rightOnscreenThirdLoop + + .rightOnscreenFirstLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostFirst + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : CPY #$6708 : BCS .rightOnscreenFirstLoop + .rightOnscreenFirstSkip + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostFirstSkip + %a8() : LDA $25 : %a16() + DEY #2 : CPY #$5CF8 : BCS .rightOnscreenFirstSkip + .rightOnscreenSecondLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostSecond + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : CPY #$32EC : BCS .rightOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenThirdLoop + .rightOnscreenSecondSkip + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostSecondSkip + %a8() : LDA $25 : %a16() + DEY #2 : CPY #$2800 : BCS .rightOnscreenSecondSkip + .rightOnscreenThirdLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostThird + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : BPL .rightOnscreenThirdLoop + BRA .rightEdgeEnd + + .rightLostFirst + %a8() + .rightLostFirstLoop + LDA #$FF : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .rightLostFirstLoop + .rightLostFirstSkip + LDA #$EAFF ; in 8-bit mode this becomes LDA #$FF : NOP + DEY #2 : CPY #$5CF8 : BCS .rightLostFirstSkip + .rightLostSecond + %a8() + .rightLostSecondLoop + LDA #$FF : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .rightLostSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightLostThird + .rightLostSecondSkip + LDA #$EAFF ; in 8-bit mode this becomes LDA #$FF : NOP + DEY #2 : CPY #$2800 : BCS .rightLostSecondSkip + .rightLostThird + %a8() + .rightLostThirdLoop + LDA #$FF : STA [$00],Y + DEY #2 : BPL .rightLostThirdLoop + + .rightEdgeEnd + LDY $12 + CPY #$6708 : BCS .finalThird + CPY #$5CF8 : BCS .finalSecondSkip + CPY #$32EC : BCS .finalSecond + CPY #$2800 : BCC .finalFirst + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalSecond + BRA .finalFirstSkip + + .finalFirst + LDA $14 : CMP #$2800 : BCC .finalThird + %a8() + .finalFirstLoop + LDA #$00 : STA [$00],Y + INY #2 : CPY #$2800 : BMI .finalFirstLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalSecond + .finalFirstSkip + LDA $14 : CMP #$32EC : BCC .finalSkip + .finalFirstSkipLoop + LDA #$0000 + INY #2 : CPY #$32EC : BMI .finalFirstSkipLoop + .finalSecond + LDA $14 : CMP #$5CF8 : BCC .finalThird + %a8() + .finalSecondLoop + LDA #$00 : STA [$00],Y + INY #2 : CPY #$5CF8 : BMI .finalSecondLoop + %a16() + .finalSecondSkip + LDA $14 : CMP #$6708 : BCC .finalSkip + .finalSecondSkipLoop + LDA #$0000 + INY #2 : CPY #$6708 : BMI .finalSecondSkipLoop + .finalThird + %a8() + .finalThirdLoop + LDA #$00 : STA [$00],Y + INY #2 : CPY $14 : BMI .finalThirdLoop + %a16() + LDA $14 : DEC : STA $12 + JML hook_xray_offscreen_aim_up_final + + .finalSkip + %a8() + .finalSkipLoop + LDA #$00 : NOP + INY #2 : CPY $14 : BMI .finalSkipLoop + %a16() + LDA $14 : DEC : STA $12 + JML hook_xray_offscreen_aim_up_final +} + +xray_offscreen_up_left: +{ + PHY + .leftOffscreenLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftFoundScreen + DEY #2 : BPL .leftOffscreenLoop + STZ $12 + JMP .leftEdgeEnd + + .leftFoundScreen + TYA : INC #2 : STA $12 + CPY #$6708 : BCS .leftFoundFirst + CPY #$5CF8 : BCS .leftFoundSkip + CPY #$32EC : BCS .leftFoundSecond + CPY #$2800 : BCC .leftFoundThird + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftFoundThird + DEY #2 : CPY #$2800 : BCC .leftFoundThirdContinue + JMP .leftOnscreenSecondSkip + + .leftFoundFirst + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BPL .leftOnscreenFirstLoop + .leftFoundEnd + LDA #$0002 : STA $12 + JMP .leftEdgeEnd + + .leftFoundSkip + DEY #2 + BRA .leftOnscreenFirstSkip + + .leftFoundSecond + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 + BRA .leftOnscreenSecondLoop + + .leftFoundThird + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BMI .leftFoundEnd + .leftFoundThirdContinue + BRA .leftOnscreenThirdLoop + + .leftOnscreenFirstLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostFirst + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : CPY #$6708 : BCS .leftOnscreenFirstLoop + .leftOnscreenFirstSkip + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostFirstSkip + %a8() : LDA $23 : %a16() + DEY #2 : CPY #$5CF8 : BCS .leftOnscreenFirstSkip + .leftOnscreenSecondLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostSecond + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : CPY #$32EC : BCS .leftOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenThirdLoop + .leftOnscreenSecondSkip + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostSecondSkip + %a8() : LDA $23 : %a16() + DEY #2 : CPY #$2800 : BCS .leftOnscreenSecondSkip + .leftOnscreenThirdLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostThird + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BPL .leftOnscreenThirdLoop + BRA .leftEdgeEnd + + .leftLostFirst + %a8() + .leftLostFirstLoop + LDA #$00 : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .leftLostFirstLoop + .leftLostFirstSkip + LDA #$EA00 ; in 8-bit mode this becomes LDA #$00 : NOP + DEY #2 : CPY #$5CF8 : BCS .leftLostFirstSkip + .leftLostSecond + %a8() + .leftLostSecondLoop + LDA #$00 : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .leftLostSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftLostThird + .leftLostSecondSkip + LDA #$EA00 ; in 8-bit mode this becomes LDA #$00 : NOP + DEY #2 : CPY #$2800 : BCS .leftLostSecondSkip + .leftLostThird + %a8() + .leftLostThirdLoop + LDA #$00 : STA [$00],Y + DEY #2 : BPL .leftLostThirdLoop + + .leftEdgeEnd + %a16() + PLY : INY + .rightOffscreenLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightFoundScreen + DEY #2 : BPL .rightOffscreenLoop + LDA #$0001 : STA $14 + JMP .rightEdgeEnd + + .rightFoundScreen + TYA : INC #2 : STA $14 + CPY #$6708 : BCS .rightFoundFirst + CPY #$5CF8 : BCS .rightFoundSkip + CPY #$32EC : BCS .rightFoundSecond + CPY #$2800 : BCC .rightFoundThird + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightFoundThird + DEY #2 : CPY #$2800 : BCC .rightFoundThirdContinue + JMP .rightOnscreenSecondSkip + + .rightFoundFirst + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BPL .rightOnscreenFirstLoop + .rightFoundEnd + LDA #$0003 : STA $14 + JMP .rightEdgeEnd + + .rightFoundSkip + DEY #2 + BRA .rightOnscreenFirstSkip + + .rightFoundSecond + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 + BRA .rightOnscreenSecondLoop + + .rightFoundThird + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BMI .rightFoundEnd + .rightFoundThirdContinue + BRA .rightOnscreenThirdLoop + + .rightOnscreenFirstLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostFirst + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : CPY #$6708 : BCS .rightOnscreenFirstLoop + .rightOnscreenFirstSkip + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostFirstSkip + %a8() : LDA $25 : %a16() + DEY #2 : CPY #$5CF8 : BCS .rightOnscreenFirstSkip + .rightOnscreenSecondLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostSecond + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : CPY #$32EC : BCS .rightOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenThirdLoop + .rightOnscreenSecondSkip + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostSecondSkip + %a8() : LDA $25 : %a16() + DEY #2 : CPY #$2800 : BCS .rightOnscreenSecondSkip + .rightOnscreenThirdLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostThird + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : BPL .rightOnscreenThirdLoop + BRA .rightEdgeEnd + + .rightLostFirst + %a8() + .rightLostFirstLoop + LDA #$00 : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .rightLostFirstLoop + .rightLostFirstSkip + LDA #$EA00 ; in 8-bit mode this becomes LDA #$00 : NOP + DEY #2 : CPY #$5CF8 : BCS .rightLostFirstSkip + .rightLostSecond + %a8() + .rightLostSecondLoop + LDA #$00 : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .rightLostSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightLostThird + .rightLostSecondSkip + LDA #$EA00 ; in 8-bit mode this becomes LDA #$00 : NOP + DEY #2 : CPY #$2800 : BCS .rightLostSecondSkip + .rightLostThird + %a8() + .rightLostThirdLoop + LDA #$00 : STA [$00],Y + DEY #2 : BPL .rightLostThirdLoop + + .rightEdgeEnd + LDY $14 + CPY #$6708 : BCS .finalThird + CPY #$5CF8 : BCS .finalSecondSkip + CPY #$32EC : BCS .finalSecond + CPY #$2800 : BCC .finalFirst + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalSecond + BRA .finalFirstSkip + + .finalFirst + LDA $12 : CMP #$2800 : BCC .finalThird + %a8() + .finalFirstLoop + LDA #$FF : STA [$00],Y + INY #2 : CPY #$2800 : BMI .finalFirstLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalSecond + .finalFirstSkip + LDA $12 : CMP #$32EC : BCC .finalSkip + .finalFirstSkipLoop + LDA #$FFFF + INY #2 : CPY #$32EC : BMI .finalFirstSkipLoop + .finalSecond + LDA $12 : CMP #$5CF8 : BCC .finalThird + %a8() + .finalSecondLoop + LDA #$FF : STA [$00],Y + INY #2 : CPY #$5CF8 : BMI .finalSecondLoop + %a16() + .finalSecondSkip + LDA $12 : CMP #$6708 : BCC .finalSkip + .finalSecondSkipLoop + LDA #$FFFF + INY #2 : CPY #$6708 : BMI .finalSecondSkipLoop + .finalThird + %a8() + .finalThirdLoop + LDA #$FF : STA [$00],Y + INY #2 : CPY $12 : BMI .finalThirdLoop + %a16() + JML hook_xray_offscreen_aim_up_final + + .finalSkip + %a8() + .finalSkipLoop + LDA #$FF : NOP + INY #2 : CPY $12 : BMI .finalSkipLoop + %a16() + JML hook_xray_offscreen_aim_up_final +} + +xray_offscreen_down_right: +{ + PHY + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightFoundFirst + INY #2 : CPY #$01CC : BPL .rightOffscreenEnd + .rightOffscreenLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightFoundStore + INY #2 : CPY #$01CC : BMI .rightOffscreenLoop + .rightOffscreenEnd + STY $12 + BRA .rightEdgeEnd + + .rightFoundFirst + TYA : DEC #2 : STA $12 + CPY #$6708 : BCS .rightFoundStore + CPY #$5CF8 : BCS .rightFoundSkip + CPY #$32EC : BCS .rightFoundStore + CPY #$27FF : BCC .rightFoundStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BNE .rightFoundSkip + .rightFoundStore + LDA $25 : STA [$00],Y + .rightFoundSkip + INY #2 : CPY #$01CC : BMI .rightOnscreenLoop + LDA #$01CA : STA $12 + BRA .rightEdgeEnd + + .rightOnscreenLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostScreenLoop + LDA $25 : STA [$00],Y + INY #2 : CPY #$01CC : BMI .rightOnscreenLoop + BRA .rightEdgeEnd + + .rightLostScreenLoop + LDA #$00FF : STA [$00],Y + INY #2 : CPY #$01CC : BMI .rightLostScreenLoop + + .rightEdgeEnd + PLY : INY + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftFoundFirst + INY #2 : CPY #$01CC : BPL .leftOffscreenEnd + .leftOffscreenLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftFoundStore + INY #2 : CPY #$01CC : BMI .leftOffscreenLoop + .leftOffscreenEnd + STY $14 + BRA .leftEdgeEnd + + .leftFoundFirst + TYA : DEC #2 : STA $14 + CPY #$6708 : BCS .leftFoundStore + CPY #$5CF8 : BCS .leftFoundSkip + CPY #$32EC : BCS .leftFoundStore + CPY #$2800 : BCC .leftFoundStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BNE .leftFoundSkip + .leftFoundStore + %a8() : LDA $23 : STA [$00],Y : %a16() + .leftFoundSkip + INY #2 : CPY #$01CC : BMI .leftOnscreenLoop + LDA #$01CB : STA $14 + BRA .leftEdgeEnd + + .leftOnscreenLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostScreen + %a8() : LDA $23 : STA [$00],Y : %a16() + INY #2 : CPY #$01CC : BMI .leftOnscreenLoop + BRA .leftEdgeEnd + + .leftLostScreen + %a8() + .leftLostScreenLoop + LDA #$FF : STA [$00],Y + INY #2 : CPY #$01CC : BMI .leftLostScreenLoop + %a16() + + .leftEdgeEnd + LDY $12 + CPY #$6708 : BCS .finalFirst + CPY #$5CF8 : BCS .finalFirstSkip + CPY #$32EC : BCS .finalSecond + CPY #$2800 : BCC .finalThird + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalThird + BRA .finalSecondSkip + + .finalFirst + LDA $14 : CMP #$6708 : BCS .finalThird + %a8() + .finalFirstLoop + LDA #$00 : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .finalFirstLoop + %a16() + .finalFirstSkip + LDA $14 : CMP #$5CF8 : BCS .finalSkip + .finalFirstSkipLoop + LDA #$0000 + DEY #2 : CPY #$5CF8 : BCS .finalFirstSkipLoop + .finalSecond + LDA $14 : CMP #$32EC : BCS .finalThird + %a8() + .finalSecondLoop + LDA #$00 : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .finalSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalThird + .finalSecondSkip + LDA $14 : CMP #$2800 : BCS .finalSkip + .finalSecondSkipLoop + LDA #$0000 + DEY #2 : CPY #$2800 : BCS .finalSecondSkipLoop + .finalThird + %a8() + .finalThirdLoop + LDA #$00 : STA [$00],Y + DEY #2 : CPY $14 : BPL .finalThirdLoop + %a16() + LDA $14 : DEC : STA $12 + JML hook_xray_offscreen_aim_down_final + + .finalSkip + %a8() + .finalSkipLoop + LDA #$00 : NOP + DEY #2 : CPY $14 : BPL .finalSkipLoop + %a16() + LDA $14 : DEC : STA $12 + JML hook_xray_offscreen_aim_down_final +} + +xray_offscreen_down_left: +{ + PHY + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightFoundFirst + INY #2 : CPY #$01CC : BPL .rightOffscreenEnd + .rightOffscreenLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightFoundStore + INY #2 : CPY #$01CC : BMI .rightOffscreenLoop + .rightOffscreenEnd + STY $12 + BRA .rightEdgeEnd + + .rightFoundFirst + TYA : DEC #2 : STA $12 + CPY #$6708 : BCS .rightFoundStore + CPY #$5CF8 : BCS .rightFoundSkip + CPY #$32EC : BCS .rightFoundStore + CPY #$27FF : BCC .rightFoundStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BNE .rightFoundSkip + .rightFoundStore + LDA $25 : STA [$00],Y + .rightFoundSkip + INY #2 : CPY #$01CC : BMI .rightOnscreenLoop + LDA #$01CA : STA $12 + BRA .rightEdgeEnd + + .rightOnscreenLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostScreenLoop + LDA $25 : STA [$00],Y + INY #2 : CPY #$01CC : BMI .rightOnscreenLoop + BRA .rightEdgeEnd + + .rightLostScreenLoop + LDA #$0000 : STA [$00],Y + INY #2 : CPY #$01CC : BMI .rightLostScreenLoop + + .rightEdgeEnd + PLY : INY + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftFoundFirst + INY #2 : CPY #$01CC : BPL .leftOffscreenEnd + .leftOffscreenLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftFoundStore + INY #2 : CPY #$01CC : BMI .leftOffscreenLoop + .leftOffscreenEnd + STY $14 + BRA .leftEdgeEnd + + .leftFoundFirst + TYA : DEC #2 : STA $14 + CPY #$6708 : BCS .leftFoundStore + CPY #$5CF8 : BCS .leftFoundSkip + CPY #$32EC : BCS .leftFoundStore + CPY #$2800 : BCC .leftFoundStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BNE .leftFoundSkip + .leftFoundStore + %a8() : LDA $23 : STA [$00],Y : %a16() + .leftFoundSkip + INY #2 : CPY #$01CC : BMI .leftOnscreenLoop + LDA #$01CB : STA $14 + BRA .leftEdgeEnd + + .leftOnscreenLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCS .leftLostScreen + %a8() : LDA $23 : STA [$00],Y : %a16() + INY #2 : CPY #$01CC : BMI .leftOnscreenLoop + BRA .leftEdgeEnd + + .leftLostScreen + %a8() + .leftLostScreenLoop + LDA #$00 : STA [$00],Y + INY #2 : CPY #$01CC : BMI .leftLostScreenLoop + %a16() + + .leftEdgeEnd + LDY $14 + CPY #$6708 : BCS .finalFirst + CPY #$5CF8 : BCS .finalFirstSkip + CPY #$32EC : BCS .finalSecond + CPY #$2800 : BCC .finalThird + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalThird + BRA .finalSecondSkip + + .finalFirst + LDA $12 : CMP #$6708 : BCS .finalThird + %a8() + .finalFirstLoop + LDA #$FF : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .finalFirstLoop + %a16() + .finalFirstSkip + LDA $12 : CMP #$5CF8 : BCS .finalSkip + .finalFirstSkipLoop + LDA #$FFFF + DEY #2 : CPY #$5CF8 : BCS .finalFirstSkipLoop + .finalSecond + LDA $12 : CMP #$32EC : BCS .finalThird + %a8() + .finalSecondLoop + LDA #$FF : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .finalSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalThird + .finalSecondSkip + LDA $12 : CMP #$2800 : BCS .finalSkip + .finalSecondSkipLoop + LDA #$FFFF + DEY #2 : CPY #$2800 : BCS .finalSecondSkipLoop + .finalThird + %a8() + .finalThirdLoop + LDA #$FF : STA [$00],Y + DEY #2 : CPY $12 : BPL .finalThirdLoop + %a16() + JML hook_xray_offscreen_aim_down_final + + .finalSkip + %a8() + .finalSkipLoop + LDA #$FF : NOP + DEY #2 : CPY $12 : BPL .finalSkipLoop + %a16() + JML hook_xray_offscreen_aim_down_final +} + +xray_offscreen_horizontal: +{ + CPY #$6708 : BCS .firstStore + CPY #$5CF8 : BCS .firstSkip + CPY #$32EC : BCS .secondStore + CPY #$27FF : BCC .thirdStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .thirdStore + DEY #2 : CPY #$27FF : BCC .thirdContinue + JMP .topSecondSkip + + .firstStore + LDA #$FF00 : STA [$00],Y + PHY : INY #2 + .firstBottomLoop + LDA [$00],Y : CMP #$00FF : BEQ .firstBottomEnd + LDA #$00FF : STA [$00],Y + INY #2 : CPY #$01CC : BMI .firstBottomLoop + .firstBottomEnd + PLY : DEY #2 + LDA [$00],Y : CMP #$00FF : BEQ .firstDone + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .topFirstLoop + .firstDone + JMP .topEnd + + .firstSkip + BRA .topFirstSkip + + .secondStore + LDA #$FF00 : STA [$00],Y + PHY : INY #2 + LDA [$00],Y : CMP #$00FF : BEQ .secondBottomEnd + LDA #$00FF : STA [$00],Y + .secondBottomEnd + PLY : DEY #2 + BRA .topSecondLoop + + .thirdStore + LDA #$FF00 : STA [$00],Y + PHY : INY #2 + LDA [$00],Y : CMP #$00FF : BEQ .thirdBottomEnd + CPY #$27FF : BCC .thirdBottomStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BNE .thirdBottomEnd + .thirdBottomStore + LDA #$00FF : STA [$00],Y + .thirdBottomEnd + PLY : DEY #2 + .thirdContinue + BRA .topThirdLoop + + .topFirstLoop + LDA [$00],Y : CMP #$00FF : BEQ .topEnd + LDA #$00FF : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .topFirstLoop + .topFirstSkip + LDA [$00],Y : CMP #$00FF + LDA #$00FF + DEY #2 : CPY #$5CF8 : BCS .topFirstSkip + .topSecondLoop + LDA [$00],Y : CMP #$00FF : BEQ .topEnd + LDA #$00FF : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .topSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .topThirdLoop + .topSecondSkip + LDA [$00],Y : CMP #$00FF + LDA #$00FF + DEY #2 : CPY #$27FF : BCS .topSecondSkip + .topThirdLoop + LDA [$00],Y : CMP #$00FF : BEQ .topEnd + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .topThirdLoop + + .topEnd + PLP + RTL +} + +xray_onscreen_aim_right: +{ + LDA $16 : STA $22 : STA $24 + CPY #$6708 : BCS .firstStore + CPY #$5CF8 : BCS .firstSkip + CPY #$32EC : BCS .secondStore + CPY #$27FF : BCC .thirdStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .thirdStore + DEY #2 : CPY #$27FF : BCC .thirdContinue + JMP .leftOnscreenSecondSkip + + .firstStore + LDA $17 : ORA #$FF00 : STA [$00],Y + DEY #2 + LDA $22 : CLC : ADC $1E : STA $22 + BCS .firstLostScreen + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 : BPL .leftOnscreenFirstLoop + JMP .leftEdgeEnd + + .firstSkip + DEY #2 + BRA .leftOnscreenFirstSkip + + .secondStore + LDA $17 : ORA #$FF00 : STA [$00],Y + DEY #2 + BRA .leftOnscreenSecondLoop + + .thirdStore + LDA $17 : ORA #$FF00 : STA [$00],Y + DEY #2 + .thirdContinue + BRA .leftOnscreenThirdLoop + + .firstLostScreen + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .leftLostFirstLoop + JMP .leftEdgeEnd + + .leftOnscreenFirstLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostFirst + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .leftOnscreenFirstLoop + .leftOnscreenFirstSkip + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostFirstSkip + LDA $23 : ORA #$FF00 + DEY #2 : CPY #$5CF8 : BCS .leftOnscreenFirstSkip + .leftOnscreenSecondLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostSecond + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .leftOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenThirdLoop + .leftOnscreenSecondSkip + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostSecondSkip + LDA $23 : ORA #$FF00 + DEY #2 : CPY #$27FF : BCS .leftOnscreenSecondSkip + .leftOnscreenThirdLoop + LDA $22 : CLC : ADC $1E : STA $22 + BCS .leftLostThirdLoop + LDA $23 : ORA #$FF00 : STA [$00],Y + DEY #2 : BPL .leftOnscreenThirdLoop + BRA .leftEdgeEnd + + .leftLostFirst + LDA #$00FF + .leftLostFirstLoop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .leftLostFirstLoop + .leftLostFirstSkip + LDA #$00FF + DEY #2 : CPY #$5CF8 : BCS .leftLostFirstSkip + .leftLostSecond + LDA #$00FF + .leftLostSecondLoop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .leftLostSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftLostThirdLoop + .leftLostSecondSkip + LDA #$00FF + DEY #2 : CPY #$27FF : BCS .leftLostSecondSkip + .leftLostThirdLoop + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .leftLostThirdLoop + + .leftEdgeEnd + LDA $18 : ASL : TAY + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostScreen + CPY #$6708 : BCS .rightOnscreenStore + CPY #$5CF8 : BCS .rightOnscreenIny + CPY #$32EC : BCS .rightOnscreenStore + CPY #$27FF : BCC .rightOnscreenStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenStore + BRA .rightOnscreenIny + + .rightOnscreenLoop + LDA $24 : CLC : ADC $20 : STA $24 + BCS .rightLostScreen + .rightOnscreenStore + LDA $25 : ORA #$FF00 : STA [$00],Y + .rightOnscreenIny + INY #2 : CPY #$01CC : BMI .rightOnscreenLoop + BRA .rightEdgeEnd + + .rightLostScreen + CPY #$6708 : BCS .rightLostLoop + CPY #$5CF8 : BCS .rightLostSkip + CPY #$32EC : BCS .rightLostLoop + CPY #$27FF : BCC .rightLostLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightLostLoop + .rightLostSkip + LDA #$00FF + BRA .rightLostIny + + .rightLostLoop + LDA #$00FF : STA [$00],Y + .rightLostIny + INY #2 : CPY #$01CC : BMI .rightLostLoop + + .rightEdgeEnd + PLP + RTL +} + +xray_onscreen_aim_left: +{ + LDA $16 : STA $22 : STA $24 + CPY #$6708 : BCS .firstStore + CPY #$5CF8 : BCS .firstSkip + CPY #$32EC : BCS .secondStore + CPY #$27FF : BCC .thirdStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .thirdStore + DEY #2 : CPY #$27FF : BCC .thirdContinue + JMP .rightOnscreenSecondSkip + + .firstStore + LDA $16 : AND #$FF00 : STA [$00],Y + DEY #2 + LDA $24 : SEC : SBC $20 : STA $24 + BCC .firstLostScreen + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 : BPL .rightOnscreenFirstLoop + JMP .rightEdgeEnd + + .firstSkip + DEY #2 + BRA .rightOnscreenFirstSkip + + .secondStore + LDA $16 : AND #$FF00 : STA [$00],Y + DEY #2 + BRA .rightOnscreenSecondLoop + + .thirdStore + LDA $16 : AND #$FF00 : STA [$00],Y + DEY #2 + .thirdContinue + BRA .rightOnscreenThirdLoop + + .firstLostScreen + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .rightLostFirstLoop + JMP .rightEdgeEnd + + .rightOnscreenFirstLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostFirst + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 : CPY #$6708 : BCS .rightOnscreenFirstLoop + .rightOnscreenFirstSkip + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostFirstSkip + LDA $24 : AND #$FF00 + DEY #2 : CPY #$5CF8 : BCS .rightOnscreenFirstSkip + .rightOnscreenSecondLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostSecond + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 : CPY #$32EC : BCS .rightOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenThirdLoop + .rightOnscreenSecondSkip + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostSecondSkip + LDA $24 : AND #$FF00 + DEY #2 : CPY #$27FF : BCS .rightOnscreenSecondSkip + .rightOnscreenThirdLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostThirdLoop + LDA $24 : AND #$FF00 : STA [$00],Y + DEY #2 : BPL .rightOnscreenThirdLoop + BRA .rightEdgeEnd + + .rightLostFirst + LDA #$00FF + .rightLostFirstLoop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .rightLostFirstLoop + .rightLostFirstSkip + LDA #$00FF + DEY #2 : CPY #$5CF8 : BCS .rightLostFirstSkip + .rightLostSecond + LDA #$00FF + .rightLostSecondLoop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .rightLostSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightLostThirdLoop + .rightLostSecondSkip + LDA #$00FF + DEY #2 : CPY #$27FF : BCS .rightLostSecondSkip + .rightLostThirdLoop + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .rightLostThirdLoop + + .rightEdgeEnd + LDA $18 : ASL : TAY + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostScreen + CPY #$6708 : BCS .leftOnscreenStore + CPY #$5CF8 : BCS .leftOnscreenIny + CPY #$32EC : BCS .leftOnscreenStore + CPY #$27FF : BCC .leftOnscreenStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenStore + BRA .leftOnscreenIny + + .leftOnscreenLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostScreen + .leftOnscreenStore + LDA $22 : AND #$FF00 : STA [$00],Y + .leftOnscreenIny + INY #2 : CPY #$01CC : BMI .leftOnscreenLoop + BRA .leftEdgeEnd + + .leftLostScreen + CPY #$6708 : BCS .leftLostLoop + CPY #$5CF8 : BCS .leftLostSkip + CPY #$32EC : BCS .leftLostLoop + CPY #$27FF : BCC .leftLostLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftLostLoop + .leftLostSkip + LDA #$00FF + BRA .leftLostIny + + .leftLostLoop + LDA #$00FF : STA [$00],Y + .leftLostIny + INY #2 : CPY #$01CC : BMI .leftLostLoop + + .leftEdgeEnd + PLP + RTL +} + +xray_onscreen_up_left: +{ + PHY + CPY #$6708 : BCC .leftContinue + LDA $22 : SEC : SBC $1E : STA $22 + BCC .firstLeftLostScreen + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BPL .leftOnscreenFirstLoop + .firstLeftEnd + JMP .leftEdgeEnd + + .firstLeftLostScreen + %a8() : LDA #$00 : STA [$00],Y + DEY #2 : BMI .firstLeftEnd + JMP .leftLostFirstLoop + + .leftContinue + CPY #$5CF8 : BCS .leftOnscreenFirstSkip + CPY #$32EC : BCS .leftOnscreenSecondLoop + CPY #$2800 : BCC .leftOnscreenThirdLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenThirdLoop + BRA .leftOnscreenSecondSkip + + .leftOnscreenFirstLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostFirst + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : CPY #$6708 : BCS .leftOnscreenFirstLoop + .leftOnscreenFirstSkip + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostFirstSkip + %a8() : LDA $23 : %a16() + DEY #2 : CPY #$5CF8 : BCS .leftOnscreenFirstSkip + .leftOnscreenSecondLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostSecond + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : CPY #$32EC : BCS .leftOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenThirdLoop + .leftOnscreenSecondSkip + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostSecondSkip + %a8() : LDA $23 : %a16() + DEY #2 : CPY #$2800 : BCS .leftOnscreenSecondSkip + .leftOnscreenThirdLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostThird + %a8() : LDA $23 : STA [$00],Y : %a16() + DEY #2 : BPL .leftOnscreenThirdLoop + BRA .leftEdgeEnd + + .leftLostFirst + %a8() : LDA #$00 + .leftLostFirstLoop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .leftLostFirstLoop + .leftLostFirstSkip + DEY #2 : CPY #$5CF8 : BCS .leftLostFirstSkip + .leftLostSecond + %a8() : LDA #$00 + .leftLostSecondLoop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .leftLostSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftLostThird + .leftLostSecondSkip + DEY #2 : CPY #$2800 : BCS .leftLostSecondSkip + .leftLostThird + %a8() : LDA #$00 + .leftLostThirdLoop + STA [$00],Y + DEY #2 : BPL .leftLostThirdLoop + + .leftEdgeEnd + %a16() + PLY : INY + CPY #$6708 : BCC .rightContinue + LDA $24 : SEC : SBC $20 : STA $24 + BCC .firstRightLostScreen + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : BPL .rightOnscreenFirstLoop + JMP .rightEdgeEnd + + .firstRightLostScreen + PHY + %a8() : LDA #$00 : STA [$00],Y + DEY #2 : BMI .firstRightLostFinal + JMP .rightLostFirstLoop + + .firstRightLostFinal + JMP .finalLost + + .rightContinue + CPY #$5CF8 : BCS .rightOnscreenFirstSkip + CPY #$32EC : BCS .rightOnscreenSecondLoop + CPY #$2800 : BCC .rightOnscreenThirdLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenThirdLoop + BRA .rightOnscreenSecondSkip + + .rightOnscreenFirstLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostFirst + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : CPY #$6708 : BCS .rightOnscreenFirstLoop + .rightOnscreenFirstSkip + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostFirstSkip + %a8() : LDA $25 : %a16() + DEY #2 : CPY #$5CF8 : BCS .rightOnscreenFirstSkip + .rightOnscreenSecondLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostSecond + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : CPY #$32EC : BCS .rightOnscreenSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenThirdLoop + .rightOnscreenSecondSkip + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostSecondSkip + %a8() : LDA $25 : %a16() + DEY #2 : CPY #$2800 : BCS .rightOnscreenSecondSkip + .rightOnscreenThirdLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostThird + %a8() : LDA $25 : STA [$00],Y : %a16() + DEY #2 : BPL .rightOnscreenThirdLoop + JMP .rightEdgeEnd + + .rightLostFirst + PHY + %a8() : LDA #$00 + .rightLostFirstLoop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .rightLostFirstLoop + BRA .rightLostFirstSkipLoop + + .rightLostFirstSkip + PHY + %a8() : LDA #$00 + .rightLostFirstSkipLoop + DEY #2 : CPY #$5CF8 : BCS .rightLostFirstSkipLoop + BRA .rightLostSecondLoop + + .rightLostSecond + PHY + %a8() : LDA #$00 + .rightLostSecondLoop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .rightLostSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightLostThirdPrep + BRA .rightLostSecondSkipPrep + + .rightLostSecondSkip + PHY + .rightLostSecondSkipPrep + %a8() : LDA #$00 + .rightLostSecondSkipLoop + DEY #2 : CPY #$2800 : BCS .rightLostSecondSkipLoop + + .rightLostThird + PHY + .rightLostThirdPrep + %a8() : LDA #$00 + .rightLostThirdLoop + STA [$00],Y + DEY #2 : BPL .rightLostThirdLoop + + .finalLost + %a8() : LDA #$FF + PLY : DEY + CPY #$6708 : BCS .finalFirst + CPY #$5CF8 : BCS .finalFirstSkip + CPY #$32EC : BCS .finalSecondLoop + CPY #$2800 : BCC .finalThirdLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalThird + LDA #$00FF + BRA .finalSecondSkip + + .finalFirst + STA [$00],Y + DEY #2 : BMI .rightEdgeEnd + .finalFirstLoop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .finalFirstLoop + .finalFirstSkip + DEY #2 : CPY #$5CF8 : BCS .finalFirstSkip + .finalSecondLoop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .finalSecondLoop + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalThird + .finalSecondSkip + DEY #2 : CPY #$2800 : BCS .finalSecondSkip + .finalThird + %a8() : LDA #$FF + .finalThirdLoop + STA [$00],Y + DEY #2 : BPL .finalThirdLoop + + .rightEdgeEnd + %a16() + JML hook_xray_onscreen_aim_up_final +} + +xray_onscreen_down_left: +{ + PHY + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostScreen + CPY #$6708 : BCS .rightOnscreenStore + CPY #$5CF8 : BCS .rightOnscreenIny + CPY #$32EC : BCS .rightOnscreenStore + CPY #$27FF : BCC .rightOnscreenStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightOnscreenStore + BRA .rightOnscreenIny + + .rightOnscreenLoop + LDA $24 : SEC : SBC $20 : STA $24 + BCC .rightLostScreen + .rightOnscreenStore + LDA $25 : STA [$00],Y + .rightOnscreenIny + INY #2 : CPY #$01CC : BMI .rightOnscreenLoop + BRA .rightEdgeEnd + + .rightLostScreen + CPY #$6708 : BCS .rightLostLoop + CPY #$5CF8 : BCS .rightLostSkip + CPY #$32EC : BCS .rightLostLoop + CPY #$27FF : BCC .rightLostLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .rightLostLoop + .rightLostSkip + LDA #$0000 + BRA .rightLostIny + + .rightLostLoop + LDA #$0000 : STA [$00],Y + .rightLostIny + INY #2 : CPY #$01CC : BMI .rightLostLoop + + .rightEdgeEnd + PLY : INY + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostScreen + CPY #$6708 : BCS .leftOnscreenStore + CPY #$5CF8 : BCS .leftOnscreenIny + CPY #$32EC : BCS .leftOnscreenStore + CPY #$2800 : BCC .leftOnscreenStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftOnscreenStore + BRA .leftOnscreenIny + + .leftOnscreenLoop + LDA $22 : SEC : SBC $1E : STA $22 + BCC .leftLostScreen + .leftOnscreenStore + %a8() : LDA $23 : STA [$00],Y : %a16() + .leftOnscreenIny + INY #2 : CPY #$01CC : BMI .leftOnscreenLoop + BRA .leftEdgeEnd + + .leftLostScreen + PHY + CPY #$6708 : BCS .leftLostStore + CPY #$5CF8 : BCS .leftLostSkip + CPY #$32EC : BCS .leftLostStore + CPY #$2800 : BCC .leftLostStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .leftLostStore + .leftLostSkip + %a8() : LDA #$00 + BRA .leftLostIny + + .leftLostStore + %a8() : LDA #$00 + .leftLostLoop + STA [$00],Y + .leftLostIny + INY #2 : CPY #$01CC : BMI .leftLostLoop + + PLY : DEY + CPY #$6708 : BCS .finalStore + CPY #$5CF8 : BCS .finalSkip + CPY #$32EC : BCS .finalStore + CPY #$2800 : BCC .finalStore + %a16() + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .finalPrep + %a8() + .finalSkip + LDA #$FF + BRA .finalIny + + .finalPrep + %a8() + .finalStore + LDA #$FF + .finalLoop + STA [$00],Y + .finalIny + INY #2 : CPY #$01CC : BMI .finalLoop + .leftEdgeEnd + %a16() + JML hook_xray_onscreen_aim_down_final +} + +xray_onscreen_horizontal: +{ + CPY #$6708 : BCS .firstStore + CPY #$5CF8 : BCS .topFirstSkip + CPY #$32EC : BCS .secondStore + CPY #$27FF : BCC .thirdStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .thirdStore + DEY #2 : CPY #$27FF : BCC .topThird + BRA .topSecondSkip + + .firstStore + LDA $12 : CMP #$0040 : BEQ .first40 + LDA $16 : AND #$FF00 + BRA .firstBottom + + .first40 + LDA $17 : ORA #$FF00 + .firstBottom + STA [$00],Y + PHY : INY #2 + LDA #$00FF + .firstBottomLoop + STA [$00],Y + INY #2 : CPY #$01CC : BMI .firstBottomLoop + PLY : DEY #2 + LDA #$00FF : STA [$00],Y + DEY #2 : BPL .topFirstLoop + BRA .topEnd + + .secondStore + LDA $12 : CMP #$0040 : BEQ .second40 + LDA $16 : AND #$FF00 + BRA .secondBottom + + .thirdStore + LDA $12 : CMP #$0040 : BEQ .third40 + LDA $16 : AND #$FF00 + BRA .thirdBottom + + .topFirstLoop + STA [$00],Y + DEY #2 : CPY #$6708 : BCS .topFirstLoop + .topFirstSkip + LDA #$00FF + DEY #2 : CPY #$5CF8 : BCS .topFirstSkip + .topSecondLoop + STA [$00],Y + DEY #2 : CPY #$32EC : BCS .topSecondLoop + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BEQ .topThird + .topSecondSkip + LDA #$00FF + DEY #2 : CPY #$27FF : BCS .topSecondSkip + .topThird + LDA #$00FF + .topThirdLoop + STA [$00],Y + DEY #2 : BPL .topThirdLoop + + .topEnd + PLP + RTL + + .second40 + LDA $17 : ORA #$FF00 + .secondBottom + STA [$00],Y + PHY : INY #2 + LDA #$00FF : STA [$00],Y + PLY : DEY #2 + LDA #$00FF + BRA .topSecondLoop + + .third40 + LDA $17 : ORA #$FF00 + .thirdBottom + STA [$00],Y + PHY : INY #2 + CPY #$27FF : BCC .thirdBottomStore + LDA !ram_sprite_feature_flags : AND !SPRITE_HUD_XRAY : BNE .thirdBottomEnd + .thirdBottomStore + LDA #$00FF : STA [$00],Y + .thirdBottomEnd + PLY : DEY #2 + BRA .topThird +} + +print pc, " preserve WRAM end" + diff --git a/src/symbols.asm b/src/symbols.asm index ccf85486..6abe357f 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -18,7 +18,9 @@ incsrc wram_symbols.asm ram_tilemap_buffer = !ram_tilemap_buffer ; $7EF500 ; 2048 bytes ; Shortcut routine is written on boot and each time the menu closes, -; so it can use the same space as the practice hack menu tilemap buffer +; so it can use the same space as the practice hack menu tilemap buffer. +; The following tracking variables are for Update Timers, +; and they are only accurate and maintained enough to make that work ; Shortcuts can skip remaining checks by replacing the return address word ; If WRAM_PERSIST_START is changed from $7EFD80 then also adjust init.asm @@ -177,8 +179,8 @@ ram_suits_enemy_damage_check = !ram_suits_enemy_damage_check ; !WRAM_PERSIST_STA ram_suits_heat_damage_check = !ram_suits_heat_damage_check ; !WRAM_PERSIST_START+$32 ram_pacifist = !ram_pacifist ; !WRAM_PERSIST_START+$34 ram_freeze_on_load = !ram_freeze_on_load ; !WRAM_PERSIST_START+$36 +ram_drop_chance_table = !ram_drop_chance_table ; !WRAM_PERSIST_START+$38 -ram_spacetime_infohud = !ram_spacetime_infohud ; !WRAM_PERSIST_START+$38 ram_watch_left_index = !ram_watch_left_index ; !WRAM_PERSIST_START+$3A ram_watch_right_index = !ram_watch_right_index ; !WRAM_PERSIST_START+$3C ram_watch_write_mode = !ram_watch_write_mode ; !WRAM_PERSIST_START+$3E @@ -200,7 +202,6 @@ ram_door_destination = !ram_door_destination ; !WRAM_PERSIST_START+$5A ram_frames_held = !ram_frames_held ; !WRAM_PERSIST_START+$5C ram_quickboot_spc_state = !ram_quickboot_spc_state ; !WRAM_PERSIST_START+$5E ram_display_backup = !ram_display_backup ; !WRAM_PERSIST_START+$60 -ram_drop_chance_table = !ram_drop_chance_table ; !WRAM_PERSIST_START+$62 ; ^ FREE SPACE ^ up to +$7C (!WRAM_START+$FC - !WRAM_PERSIST_START) @@ -341,6 +342,9 @@ ram_cm_metmask = !ram_cm_metmask ; !WRAM_MENU_START+$92 ram_cm_ceres_seconds = !ram_cm_ceres_seconds ; !WRAM_MENU_START+$90 ram_cm_zebes_seconds = !ram_cm_zebes_seconds ; !WRAM_MENU_START+$92 +ram_cm_sprites_spacetime = !ram_cm_sprites_spacetime ; !WRAM_MENU_START+$90 +ram_cm_sprites_xray = !ram_cm_sprites_xray ; !WRAM_MENU_START+$92 + ram_cm_ctrl_add_shortcut_slot = !ram_cm_ctrl_add_shortcut_slot ; !WRAM_MENU_START+$90 ram_cm_ctrl_last_pri = !ram_cm_ctrl_last_pri ; !WRAM_MENU_START+$92 ram_cm_ctrl_last_sec = !ram_cm_ctrl_last_sec ; !WRAM_MENU_START+$94 @@ -349,6 +353,8 @@ ram_cm_ctrl_swap = !ram_cm_ctrl_swap ; !WRAM_MENU_START+$98 ram_cm_ctrl_timer = !ram_cm_ctrl_timer ; !WRAM_MENU_START+$9A ram_cm_ctrl_savestates_allowed = !ram_cm_ctrl_savestates_allowed ; !WRAM_MENU_START+$9C +ram_cm_updatetimers_ctrl = !ram_cm_updatetimers_ctrl ; !WRAM_MENU_START+$90 + ram_cm_sfxlib1 = !ram_cm_sfxlib1 ; !WRAM_MENU_START+$90 ram_cm_sfxlib2 = !ram_cm_sfxlib2 ; !WRAM_MENU_START+$92 ram_cm_sfxlib3 = !ram_cm_sfxlib3 ; !WRAM_MENU_START+$94 @@ -527,6 +533,8 @@ sram_fast_pause = !sram_fast_pause ; !SRAM_START+$A4 sram_bonk_indicators = !sram_bonk_indicators ; !SRAM_START+$A6 sram_speed_booster_physics = !sram_speed_booster_physics ; !SRAM_START+$A8 sram_fast_teleport = !sram_fast_teleport ; !SRAM_START+$AA +sram_update_timers_ctrl_input = !sram_update_timers_ctrl_input ; !SRAM_START+$AC +sram_update_timers_options = !sram_update_timers_options ; !SRAM_START+$AE ; ^ FREE SPACE ^ up to +$EC diff --git a/web/data/changelog.mdx b/web/data/changelog.mdx index 9a28cf58..a0200758 100644 --- a/web/data/changelog.mdx +++ b/web/data/changelog.mdx @@ -46,6 +46,10 @@ - Small RAM watch adjustments and fix temperamental OOB tile viewer X-ray collection (2.7.5.2) - Rando preset updates and vertical speed now shows 1/256 pixels instead of 1/16 (2.7.5.3) - Added RAM watch common address and door skip displays $1842 value after block shuffler (2.7.5.3) +- Added option to protect InfoHUD during OOB x-ray usage (2.7.6) +- Elevator CF now supports the Status room elevator (2.7.6) +- Fix menu crash corner case and improve sanity checking on persistent WRAM (2.7.6) +- Added Update Timers menu (2.7.6) # Version 2.6.x - Optimize kraid rock projectiles to reduce lag when Kraid rises (2.6.0) diff --git a/web/data/config.json b/web/data/config.json index fed351d1..22d49125 100644 --- a/web/data/config.json +++ b/web/data/config.json @@ -1,6 +1,6 @@ { "name": "Super Metroid Practice Hack", - "version": "2.7.5.3", + "version": "2.7.6", "variants": ["NTSC", "PAL"], "base": { "NTSC": { diff --git a/web/data/help.mdx b/web/data/help.mdx index 98ee5411..f15f5e8a 100644 --- a/web/data/help.mdx +++ b/web/data/help.mdx @@ -271,6 +271,8 @@ If you experience crashes or severe glitches when using savestates, your platfor | - Prev Super HUD | Decrements the current Super HUD bottom mode. | - Reset to Defaults | Resets controller shortcuts to their original defaults. | | +| **Update Timers** | Set additional conditions to update the HUD timers, including on press, on hold, on release, when Samus lands, or on every frame. +| | | **Audio Menu** | Audio related settings and sound test menu. | - Music | Toggle the music off, on, or fast off which eliminates lag caused by loading music data. Preset off uses fast off when loading presets but otherwise uses regular off. | - Fanfare | Toggle the fanfare for collecting items. Set to force music to force fanfare to play even if music is off.