;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Overworld Event Debugger, by Koopster
;
;By turning on the debugger switch, pressing A/B/X/Y while standing on a level in the overworld will
;activate, respectively, the normal exit, secret exit 1, secret exit 2 or secret exit 3 and run the
;corresponding event instantly.
;
;The table below is to tell which exits are allowed for each translevel. If an exit isn't allowed,
;a "wrong" sound will play. You can set !freedom to 1 so any event is always allowed.
;
;To restore the original game's behavior, just set !debug to 0 and patch this again.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Debugger switch
;	Set it to 0 to remove the patch.

	!debug = 1

;Freedom switch
;	By turning this on, the table is ignored (except for $10-$FF values), and pressing any button on
;	any tile will activate any of the 4 events. Useful if you're just doing personal testing and not
;	using it for a contest/to show off an overworld.

	!freedom = 0

;Exits table
;	The default value ($00) doesn't allow for any exit. ADD to it (in HEX!):
;		+$01 to enable the normal exit
;		+$02 to enable the secret exit 1
;		+$04 to enable the secret exit 2
;		+$08 to enable the secret exit 3
;	Common: $01 = normal only, $03 = normal + secret 1, $07 = normal + secrets 1 & 2, $0F = all
;
;	$10-$FF = make the level enterable as normal

macro exits_table()
	Exits:
		db $00,$01,$03,$01,$01,$01,$01,$03		;levels 0-7
		db $01,$01,$00,$01,$01,$03,$03,$03		;levels 8-F
		db $01,$01,$01,$01,$01,$03,$01,$01		;levels 10-17
		db $03,$01,$01,$01,$01,$01,$01,$01		;levels 18-1F
		db $01,$03,$01,$01,$01            		;levels 20-24
		db     $07,$01,$03,$00,$01,$01,$03		;levels 101-107
		db $01,$01,$01,$01,$01,$01,$01,$03		;levels 108-10F
		db $01,$01,$01,$01,$01,$01,$03,$01		;levels 110-117
		db $01,$01,$01,$01,$01,$03,$03,$03		;levels 118-11F
		db $03,$03,$03,$03,$03,$00,$00,$01		;levels 120-127
		db $01,$01,$01,$00,$00,$01,$01,$00		;levels 128-12F
		db $00,$00,$00,$00,$00,$00,$00,$00		;levels 130-137
		db $00,$00,$00,$00                		;levels 138-13B
endmacro

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;END OF SETTINGS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;sa1 blabber

!addr = $0000
!bank = $800000
!7ED000 = $7ED000

if read1($00FFD5) == $23
	sa1rom
	!addr = $6000
	!bank = $000000
	!7ED000 = $40D000
endif

;hijack

org $049199
if !debug
	autoclean JML Debug
else
	if read3($049199+1) != $03BA50
		autoclean read3($049199+1)
	endif
	JSL $03BA50|!bank	;restore
endif

;patch

if !debug
	freedata

	Debug:
		REP #$30			;\
		LDX $0DD6|!addr		;|
		LDA $1F1F|!addr,x	;|
		STA $00				;|
		LDA $1F21|!addr,x	;|
		STA $02				;|
		LDA $0DB3|!addr		;|
		AND #$00FF			;|jslrts to routine to fetch the level we're standing on
		TAX					;|
		PHK					;|
		PEA .CalcReturn-1	;|
		PEA $8575-1			;|
		JML $049885			;|
	.CalcReturn				;/
		
		LDX $04				;\
		LDA !7ED000,x		;/get translevel value in A
		
		STA $13BF|!addr		;set translevel number, needed for stuff like the earthquake
		
		SEP #$30			;restore flags
		TAX					;use translevel number as index
		LDA.l Exits,x		;read data from our table
		BIT #$F0			;\
		BNE Vanilla			;/branch if it is a vanilla behavior value
		STA $00				;preserve it in $00
		
		LDA $05D608|!bank,x	;\
		STA $01				;/get event number
		
	;figure out which of the 4 buttons was pressed
		LDX #$01
		LDA $16
		ORA $18
		BMI PressedAB
	;pressed x or y
		INX
		BIT $18
		BVS GotButton		;proceed with x=2 if X
		INX
		BRA GotButton		;proceed with x=3 if Y
	PressedAB:
		LDA $16
		BMI GotButton		;proceed with x=1 if B
		DEX					;proceed with x=0 if A
		
	GotButton:
	if !freedom == 0
			LDA.l Bits,x		;\
			AND $00				;|check if the table allows us to run this event
			BEQ NotAllowed		;/
	endif
		
		INC $1DE9|!addr		;set event activation flag
		LDA $01				;\
		STA $1DEA|!addr		;/run specified event
		LDA #$01			;\
		STA $13D9|!addr		;/set overworld process as running an event
		INX					;\
		STX $0DD5|!addr		;/act as if running the specified exit. takes care of adding to event #
		BRA End
	
	if !freedom == 0
		NotAllowed:
			LDA #$2A			;\
			STA $1DFC|!addr		;/play "wrong" sound
	endif
	
	End:
		JML $0498FA|!bank	;jump to a return
		
	Vanilla:
		PEA $0491			;\
		PEA $9C00			;|
		PLA					;|set up "vanilla" lm routine call
		JML $03BA50|!bank	;/
	
	if !freedom == 0
		Bits:
			db $01,$02,$04,$08
	endif
		
			%exits_table()
endif 