shithub: pokered

Download patch

ref: 9878f01e29b1443d6c894c1332cbf381fa12646e
parent: ccb01731fe8cd44ae4c8840ee8ddc02e6bdea97e
author: Rangi <remy.oukaour+rangi42@gmail.com>
date: Fri Jul 3 12:37:47 EDT 2020

Organize macros/ like pokecrystal

While doing so I replaced the StopAllMusic macro with a SFX_STOP_ALL_MUSIC constant and applied it throughout the code.

diff: cannot open b/macros/scripts//null: file does not exist: 'b/macros/scripts//null'
--- a/audio/play_battle_music.asm
+++ b/audio/play_battle_music.asm
@@ -2,9 +2,9 @@
 	xor a
 	ld [wAudioFadeOutControl], a
 	ld [wLowHealthAlarm], a
-	dec a
+	dec a ; SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
-	call PlaySound ; stop music
+	call PlaySound
 	call DelayFrame
 	ld c, BANK(Music_GymLeaderBattle)
 	ld a, [wGymLeaderNo]
--- a/audio/pokedex_rating_sfx.asm
+++ b/audio/pokedex_rating_sfx.asm
@@ -10,7 +10,7 @@
 	jr .getSfxPointer
 .gotSfxPointer
 	push bc
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySoundWaitForCurrent
 	pop bc
--- a/constants.asm
+++ b/constants.asm
@@ -29,6 +29,7 @@
 INCLUDE "constants/list_constants.asm"
 INCLUDE "constants/map_constants.asm"
 INCLUDE "constants/map_data_constants.asm"
+INCLUDE "constants/map_object_constants.asm"
 INCLUDE "constants/hide_show_constants.asm"
 INCLUDE "constants/credits_constants.asm"
 INCLUDE "constants/audio_constants.asm"
--- a/constants/audio_constants.asm
+++ b/constants/audio_constants.asm
@@ -1,3 +1,29 @@
+; pitch
+	const_def
+	const C_ ; 0
+	const C# ; 1
+	const D_ ; 2
+	const D# ; 3
+	const E_ ; 4
+	const F_ ; 5
+	const F# ; 6
+	const G_ ; 7
+	const G# ; 8
+	const A_ ; 9
+	const A# ; A
+	const B_ ; B
+
+; channel
+	const_def
+	const Ch1 ; 0
+	const Ch2 ; 1
+	const Ch3 ; 2
+	const Ch4 ; 3
+	const Ch5 ; 4
+	const Ch6 ; 5
+	const Ch7 ; 6
+	const Ch8 ; 7
+
 ; HW sound channel register base addresses
 HW_CH1_BASE EQU (rNR10 % $100)
 HW_CH2_BASE EQU ((rNR21 % $100) - 1)
--- a/constants/map_data_constants.asm
+++ b/constants/map_data_constants.asm
@@ -7,3 +7,8 @@
 WEST  EQU 2
 SOUTH EQU 4
 NORTH EQU 8
+
+; tileset environments
+INDOOR  EQU 0
+CAVE    EQU 1
+OUTDOOR EQU 2
--- /dev/null
+++ b/constants/map_object_constants.asm
@@ -1,0 +1,14 @@
+; different kinds of people events
+ITEM    EQU $80
+TRAINER EQU $40
+
+WALK EQU $FE
+STAY EQU $FF
+
+DOWN  EQU $D0
+UP    EQU $D1
+LEFT  EQU $D2
+RIGHT EQU $D3
+NONE  EQU $FF
+
+BOULDER_MOVEMENT_BYTE_2 EQU $10
--- a/constants/music_constants.asm
+++ b/constants/music_constants.asm
@@ -238,3 +238,5 @@
 	music_const SFX_SLOTS_NEW_SPIN,     SFX_Slots_New_Spin
 	music_const SFX_SHOOTING_STAR,      SFX_Shooting_Star
 MAX_SFX_ID_3 EQUS "SFX_SHOOTING_STAR"
+
+SFX_STOP_ALL_MUSIC EQU $ff
--- a/constants/sprite_data_constants.asm
+++ b/constants/sprite_data_constants.asm
@@ -1,9 +1,3 @@
-; different kinds of people events
-ITEM    EQU $80
-TRAINER EQU $40
-
-BOULDER_MOVEMENT_BYTE_2 EQU $10
-
 ; sprite facing directions
 SPRITE_FACING_DOWN  EQU $00
 SPRITE_FACING_UP    EQU $04
--- a/data/tilesets/tileset_headers.asm
+++ b/data/tilesets/tileset_headers.asm
@@ -1,3 +1,11 @@
+tileset: MACRO
+	db BANK(\2)   ; BANK(GFX)
+	dw \1, \2, \3 ; Block, GFX, Coll
+	db \4, \5, \6 ; counter tiles
+	db \7         ; grass tile
+	db \8         ; permission (indoor, cave, outdoor)
+ENDM
+
 Tilesets:
 	tileset Overworld_Block,   Overworld_GFX,   Overworld_Coll,   $FF,$FF,$FF, $52, OUTDOOR
 	tileset RedsHouse1_Block,  RedsHouse1_GFX,  RedsHouse1_Coll,  $FF,$FF,$FF, $FF, INDOOR
--- a/engine/battle/core.asm
+++ b/engine/battle/core.asm
@@ -958,7 +958,7 @@
 
 PlayBattleVictoryMusic:
 	push af
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySoundWaitForCurrent
 	ld c, BANK(Music_DefeatedTrainer)
--- a/engine/events/hidden_objects/bills_house_pc.asm
+++ b/engine/events/hidden_objects/bills_house_pc.asm
@@ -52,7 +52,7 @@
 	TX_FAR _BillsHouseInitiatedText
 	TX_BLINK
 	TX_ASM
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	ld c, 16
--- a/engine/events/hidden_objects/safari_game.asm
+++ b/engine/events/hidden_objects/safari_game.asm
@@ -27,7 +27,7 @@
 	call EnableAutoTextBoxDrawing
 	xor a
 	ld [wAudioFadeOutControl], a
-	dec a
+	dec a ; SFX_STOP_ALL_MUSIC
 	call PlaySound
 	ld c, BANK(SFX_Safari_Zone_PA)
 	ld a, SFX_SAFARI_ZONE_PA
--- a/engine/items/item_effects.asm
+++ b/engine/items/item_effects.asm
@@ -1844,8 +1844,8 @@
 	and a
 	jr nz, .done
 ; play out-of-battle pokeflute music
-	ld a, $ff
-	call PlaySound ; turn off music
+	ld a, SFX_STOP_ALL_MUSIC
+	call PlaySound
 	ld a, SFX_POKEFLUTE
 	ld c, BANK(SFX_Pokeflute)
 	call PlayMusic
--- a/engine/link/cable_club.asm
+++ b/engine/link/cable_club.asm
@@ -139,7 +139,7 @@
 	call Serial_ExchangeBytes
 	ld a, (1 << SERIAL) | (1 << TIMER) | (1 << VBLANK)
 	ld [rIE], a
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	call PlaySound
 	ld a, [hSerialConnectionStatus]
 	cp USING_INTERNAL_CLOCK
@@ -261,7 +261,7 @@
 	ld [wUnusedCF8D + 1], a
 	xor a
 	ld [wTradeCenterPointerTableIndex], a
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	call PlaySound
 	ld a, [hSerialConnectionStatus]
 	cp USING_INTERNAL_CLOCK
--- a/engine/movie/credits.asm
+++ b/engine/movie/credits.asm
@@ -21,7 +21,7 @@
 	ld a, %11000000
 	ld [rBGP], a
 	call EnableLCD
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	call PlaySoundWaitForCurrent
 	ld c, BANK(Music_Credits)
 	ld a, MUSIC_CREDITS
--- a/engine/movie/evolution.asm
+++ b/engine/movie/evolution.asm
@@ -9,7 +9,7 @@
 	xor a
 	ld [wLowHealthAlarm], a
 	ld [wChannelSoundIDs + Ch5], a
-	dec a
+	dec a ; SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	ld a, $1
@@ -67,7 +67,7 @@
 	ld a, [wEvoNewSpecies]
 .done
 	ld [wWholeScreenPaletteMonSpecies], a
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	ld a, [wWholeScreenPaletteMonSpecies]
--- a/engine/movie/oak_speech/oak_speech.asm
+++ b/engine/movie/oak_speech/oak_speech.asm
@@ -32,8 +32,8 @@
 	jp CopyData
 
 OakSpeech:
-	ld a, $FF
-	call PlaySound ; stop music
+	ld a, SFX_STOP_ALL_MUSIC
+	call PlaySound
 	ld a, BANK(Music_Routes2)
 	ld c, a
 	ld a, MUSIC_ROUTES2
@@ -133,9 +133,9 @@
 	ld [wAudioSavedROMBank], a
 	ld a, 10
 	ld [wAudioFadeOutControl], a
-	ld a, $FF
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
-	call PlaySound ; stop music
+	call PlaySound
 	pop af
 	ld [H_LOADEDROMBANK], a
 	ld [MBC1RomBank], a
--- a/engine/overworld/elevator.asm
+++ b/engine/overworld/elevator.asm
@@ -4,7 +4,7 @@
 	ld de, SCREEN_HEIGHT * $20
 	call ShakeElevatorRedrawRow
 	call Delay3
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	call PlaySound
 	ld a, [hSCY]
 	ld d, a
@@ -27,7 +27,7 @@
 	jr nz, .shakeLoop
 	ld a, d
 	ld [hSCY], a
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	call PlaySound
 	ld c, BANK(SFX_Safari_Zone_PA)
 	ld a, SFX_SAFARI_ZONE_PA
--- a/engine/overworld/healing_machine.asm
+++ b/engine/overworld/healing_machine.asm
@@ -17,7 +17,7 @@
 	call CopyHealingMachineOAM
 	ld a, 4
 	ld [wAudioFadeOutControl], a
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 .waitLoop
@@ -38,7 +38,7 @@
 	cp BANK(Audio3_UpdateMusic)
 	ld [wAudioSavedROMBank], a
 	jr nz, .next
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	ld a, BANK(Music_PkmnHealed)
--- a/home.asm
+++ b/home.asm
@@ -939,7 +939,7 @@
 	ld b, a
 	xor a
 	ld [wAudioFadeOutControl], a
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	ld a, [wAudioSavedROMBank]
@@ -2506,7 +2506,7 @@
 	ret nz
 	xor a
 	ld [wAudioFadeOutControl], a
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	call PlaySound
 	ld a, BANK(Music_MeetEvilTrainer)
 	ld [wAudioROMBank], a
--- a/home/overworld.asm
+++ b/home/overworld.asm
@@ -772,7 +772,7 @@
 
 StopMusic::
 	ld [wAudioFadeOutControl], a
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 .wait
--- a/macros.asm
+++ b/macros.asm
@@ -1,5 +1,11 @@
-INCLUDE "macros/asm_macros.asm"
-INCLUDE "macros/data_macros.asm"
-INCLUDE "macros/text_macros.asm"
-INCLUDE "macros/audio_macros.asm"
-INCLUDE "macros/event_macros.asm"
+INCLUDE "macros/enum.asm"
+INCLUDE "macros/predef.asm"
+INCLUDE "macros/farcall.asm"
+INCLUDE "macros/data.asm"
+INCLUDE "macros/code.asm"
+INCLUDE "macros/coords.asm"
+
+INCLUDE "macros/scripts/audio.asm"
+INCLUDE "macros/scripts/maps.asm"
+INCLUDE "macros/scripts/events.asm"
+INCLUDE "macros/scripts/text.asm"
--- a/macros/asm_macros.asm
+++ /dev/null
@@ -1,192 +1,0 @@
-
-lb: MACRO ; r, hi, lo
-	ld \1, ((\2) & $ff) << 8 + ((\3) & $ff)
-ENDM
-
-homecall: MACRO
-	ld a, [H_LOADEDROMBANK]
-	push af
-	ld a, BANK(\1)
-	ld [H_LOADEDROMBANK], a
-	ld [MBC1RomBank], a
-	call \1
-	pop af
-	ld [H_LOADEDROMBANK], a
-	ld [MBC1RomBank], a
-ENDM
-
-farcall EQUS "callba"
-
-callba: MACRO
-	ld b, BANK(\1)
-	ld hl, \1
-	call Bankswitch
-ENDM
-
-callab: MACRO
-	ld hl, \1
-	ld b, BANK(\1)
-	call Bankswitch
-ENDM
-
-jpba: MACRO
-	ld b, BANK(\1)
-	ld hl, \1
-	jp Bankswitch
-ENDM
-
-jpab: MACRO
-	ld hl, \1
-	ld b, BANK(\1)
-	jp Bankswitch
-ENDM
-
-validateCoords: MACRO
-	IF \1 >= SCREEN_WIDTH
-		fail "x coord out of range"
-	ENDC
-	IF \2 >= SCREEN_HEIGHT
-		fail "y coord out of range"
-	ENDC
-ENDM
-
-;\1 = r
-;\2 = X
-;\3 = Y
-;\4 = which tilemap (optional)
-coord: MACRO
-	validateCoords \2, \3
-	IF _NARG >= 4
-		ld \1, \4 + SCREEN_WIDTH * \3 + \2
-	ELSE
-		ld \1, wTileMap + SCREEN_WIDTH * \3 + \2
-	ENDC
-ENDM
-
-;\1 = X
-;\2 = Y
-;\3 = which tilemap (optional)
-aCoord: MACRO
-	validateCoords \1, \2
-	IF _NARG >= 3
-		ld a, [\3 + SCREEN_WIDTH * \2 + \1]
-	ELSE
-		ld a, [wTileMap + SCREEN_WIDTH * \2 + \1]
-	ENDC
-ENDM
-
-;\1 = X
-;\2 = Y
-;\3 = which tilemap (optional)
-Coorda: MACRO
-	validateCoords \1, \2
-	IF _NARG >= 3
-		ld [\3 + SCREEN_WIDTH * \2 + \1], a
-	ELSE
-		ld [wTileMap + SCREEN_WIDTH * \2 + \1], a
-	ENDC
-ENDM
-
-;\1 = X
-;\2 = Y
-;\3 = which tilemap (optional)
-dwCoord: MACRO
-	validateCoords \1, \2
-	IF _NARG >= 3
-		dw \3 + SCREEN_WIDTH * \2 + \1
-	ELSE
-		dw wTileMap + SCREEN_WIDTH * \2 + \1
-	ENDC
-ENDM
-
-;\1 = r
-;\2 = X
-;\3 = Y
-;\4 = map width
-overworldMapCoord: MACRO
-	ld \1, wOverworldMap + ((\2) + 3) + (((\3) + 3) * ((\4) + (3 * 2)))
-ENDM
-
-; macro for two nibbles
-dn: MACRO
-	db (\1 << 4 | \2)
-ENDM
-
-; macro for putting a byte then a word
-dbw: MACRO
-	db \1
-	dw \2
-ENDM
-
-dba: MACRO
-	dbw BANK(\1), \1
-ENDM
-
-dwb: MACRO
-	dw \1
-	db \2
-ENDM
-
-dab: MACRO
-	dwb \1, BANK(\1)
-ENDM
-
-dbbw: MACRO
-	db \1, \2
-	dw \3
-ENDM
-
-; Predef macro.
-predef_const: MACRO
-	const \1PredefID
-ENDM
-
-add_predef: MACRO
-\1Predef::
-	db BANK(\1)
-	dw \1
-ENDM
-
-predef_id: MACRO
-	ld a, (\1Predef - PredefPointers) / 3
-ENDM
-
-predef: MACRO
-	predef_id \1
-	call Predef
-ENDM
-
-predef_jump: MACRO
-	predef_id \1
-	jp Predef
-ENDM
-
-tx_pre_const: MACRO
-	const \1_id
-ENDM
-
-add_tx_pre: MACRO
-\1_id:: dw \1
-ENDM
-
-db_tx_pre: MACRO
-	db (\1_id - TextPredefs) / 2 + 1
-ENDM
-
-tx_pre_id: MACRO
-	ld a, (\1_id - TextPredefs) / 2 + 1
-ENDM
-
-tx_pre: MACRO
-	tx_pre_id \1
-	call PrintPredefTextID
-ENDM
-
-tx_pre_jump: MACRO
-	tx_pre_id \1
-	jp PrintPredefTextID
-ENDM
-
-ldPal: MACRO
-	ld \1, \2 << 6 | \3 << 4 | \4 << 2 | \5
-ENDM
--- a/macros/audio_macros.asm
+++ /dev/null
@@ -1,214 +1,0 @@
-
-StopAllMusic: MACRO
-	ld a, $ff
-	call PlaySound
-ENDM
-
-Ch1    EQU 0
-Ch2    EQU 1
-Ch3    EQU 2
-Ch4    EQU 3
-Ch5    EQU 4
-Ch6    EQU 5
-Ch7    EQU 6
-Ch8    EQU 7
-
-audio_header: MACRO
-	db (_NARG - 2) << 6 | \2
-	dw \1_\2
-	IF _NARG > 2
-		db \3
-		dw \1_\3
-	ENDC
-	IF _NARG > 3
-		db \4
-		dw \1_\4
-	ENDC
-	IF _NARG > 4
-		db \5
-		dw \1_\5
-	ENDC
-ENDM
-
-; arguments: length [0, 7], pitch change [-7, 7]
-; length: length of time between pitch shifts
-;         sometimes used with a value >7 in which case the MSB is ignored
-; pitch change: positive value means increase in pitch, negative value means decrease in pitch
-;               small magnitude means quick change, large magnitude means slow change
-;               in signed magnitude representation, so a value of 8 is the same as (negative) 0
-pitch_sweep: MACRO
-	db $10
-	IF \2 < 0
-		db (\1 << 4) | (%1000 | (\2 * -1))
-	ELSE
-		db (\1 << 4) | \2
-	ENDC
-ENDM
-
-; arguments: length [0, 15], volume [0, 15], fade [-7, 7], frequency
-; fade: positive value means decrease in volume, negative value means increase in volume
-;       small magnitude means quick change, large magnitude means slow change
-;       in signed magnitude representation, so a value of 8 is the same as (negative) 0
-square_note: MACRO
-	db $20 | \1
-	IF \3 < 0
-		db (\2 << 4) | (%1000 | (\3 * -1))
-	ELSE
-		db (\2 << 4) | \3
-	ENDC
-	dw \4
-ENDM
-
-; arguments: length [0, 15], volume [0, 15], fade [-7, 7], frequency
-; fade: positive value means decrease in volume, negative value means increase in volume
-;       small magnitude means quick change, large magnitude means slow change
-;       in signed magnitude representation, so a value of 8 is the same as (negative) 0
-noise_note: MACRO
-	db $20 | \1
-	IF \3 < 0
-		db (\2 << 4) | (%1000 | (\3 * -1))
-	ELSE
-		db (\2 << 4) | \3
-	ENDC
-	db \4
-ENDM
-
-C_ EQU $0
-C# EQU $1
-D_ EQU $2
-D# EQU $3
-E_ EQU $4
-F_ EQU $5
-F# EQU $6
-G_ EQU $7
-G# EQU $8
-A_ EQU $9
-A# EQU $A
-B_ EQU $B
-
-; arguments: pitch, length [1, 16]
-note: MACRO
-	db (\1 << 4) | (\2 - 1)
-ENDM
-
-; arguments: instrument [1, 19], length [1, 16]
-drum_note: MACRO
-	db $B0 | (\2 - 1)
-	db \1
-ENDM
-
-; arguments: instrument, length [1, 16]
-; like drum_note but one 1 byte instead of 2
-; can only be used with instruments 1-10, excluding 2
-; unused
-drum_note_short: MACRO
-	db (\1 << 4) | (\2 - 1)
-ENDM
-
-; arguments: length [1, 16]
-rest: MACRO
-	db $C0 | (\1 - 1)
-ENDM
-
-; arguments: speed [0, 15], volume [0, 15], fade [-7, 7]
-; fade: positive value means decrease in volume, negative value means increase in volume
-;       small magnitude means quick change, large magnitude means slow change
-;       in signed magnitude representation, so a value of 8 is the same as (negative) 0
-note_type: MACRO
-	db $D0 | \1
-	IF \3 < 0
-		db (\2 << 4) | (%1000 | (\3 * -1))
-	ELSE
-		db (\2 << 4) | \3
-	ENDC
-ENDM
-
-; arguments: speed [0, 15]
-drum_speed: MACRO
-	db $D0 | \1
-ENDM
-
-; arguments: octave [1, 8]
-octave: MACRO
-	db $E8 - \1
-ENDM
-
-; when enabled, effective frequency used is incremented by 1
-toggle_perfect_pitch: MACRO
-	db $E8
-ENDM
-
-; arguments: delay [0, 255], depth [0, 15], rate [0, 15]
-; delay: time delay until vibrato effect begins
-; depth: amplitude of vibrato wave
-; rate: frequency of vibrato wave
-vibrato: MACRO
-	db $EA
-	db \1
-	db (\2 << 4) | \3
-ENDM
-
-; arguments: length [1, 256], octave [1, 8], pitch
-pitch_slide: MACRO
-	db $EB
-	db \1 - 1
-	db ((8 - \2) << 4) | \3
-ENDM
-
-; arguments: duty cycle [0, 3] (12.5%, 25%, 50%, 75%)
-duty_cycle: MACRO
-	db $EC
-	db \1
-ENDM
-
-; arguments: tempo [0, $ffff]
-; used to calculate note delay counters
-; so a smaller value means music plays faster
-; ideally should be set to $100 or less to guarantee no overflow
-; if larger than $100, large note speed or note length values might cause overflow
-; stored in big endian
-tempo: MACRO
-	db $ED
-	db \1 / $100
-	db \1 % $100
-ENDM
-
-; arguments: left output enable mask, right output enable mask
-stereo_panning: MACRO
-	db $EE
-	db (\1 << 4) | \2
-ENDM
-
-; arguments: left master volume [0, 7], right master volume [0, 7]
-volume: MACRO
-	db $F0
-	db (\1 << 4) | \2
-ENDM
-
-; when enabled, the sfx data is interpreted as music data
-execute_music: MACRO
-	db $F8
-ENDM
-
-; arguments: duty cycle 1, duty cycle 2, duty cycle 3, duty cycle 4
-duty_cycle_pattern: MACRO
-	db $FC
-	db \1 << 6 | \2 << 4 | \3 << 2 | \4
-ENDM
-
-; arguments: address
-sound_call: MACRO
-	db $FD
-	dw \1
-ENDM
-
-; arguments: count, address
-sound_loop: MACRO
-	db $FE
-	db \1
-	dw \2
-ENDM
-
-sound_ret: MACRO
-	db $FF
-ENDM
--- /dev/null
+++ b/macros/code.asm
@@ -1,0 +1,9 @@
+; Syntactic sugar macros
+
+lb: MACRO ; r, hi, lo
+	ld \1, ((\2) & $ff) << 8 + ((\3) & $ff)
+ENDM
+
+ldPal: MACRO
+	ld \1, \2 << 6 | \3 << 4 | \4 << 2 | \5
+ENDM
--- /dev/null
+++ b/macros/coords.asm
@@ -1,0 +1,65 @@
+validateCoords: MACRO
+	IF \1 >= SCREEN_WIDTH
+		fail "x coord out of range"
+	ENDC
+	IF \2 >= SCREEN_HEIGHT
+		fail "y coord out of range"
+	ENDC
+ENDM
+
+;\1 = r
+;\2 = X
+;\3 = Y
+;\4 = which tilemap (optional)
+coord: MACRO
+	validateCoords \2, \3
+	IF _NARG >= 4
+		ld \1, \4 + SCREEN_WIDTH * \3 + \2
+	ELSE
+		ld \1, wTileMap + SCREEN_WIDTH * \3 + \2
+	ENDC
+ENDM
+
+;\1 = X
+;\2 = Y
+;\3 = which tilemap (optional)
+aCoord: MACRO
+	validateCoords \1, \2
+	IF _NARG >= 3
+		ld a, [\3 + SCREEN_WIDTH * \2 + \1]
+	ELSE
+		ld a, [wTileMap + SCREEN_WIDTH * \2 + \1]
+	ENDC
+ENDM
+
+;\1 = X
+;\2 = Y
+;\3 = which tilemap (optional)
+Coorda: MACRO
+	validateCoords \1, \2
+	IF _NARG >= 3
+		ld [\3 + SCREEN_WIDTH * \2 + \1], a
+	ELSE
+		ld [wTileMap + SCREEN_WIDTH * \2 + \1], a
+	ENDC
+ENDM
+
+;\1 = X
+;\2 = Y
+;\3 = which tilemap (optional)
+dwCoord: MACRO
+	validateCoords \1, \2
+	IF _NARG >= 3
+		dw \3 + SCREEN_WIDTH * \2 + \1
+	ELSE
+		dw wTileMap + SCREEN_WIDTH * \2 + \1
+	ENDC
+ENDM
+
+;\1 = r
+;\2 = X
+;\3 = Y
+;\4 = map width
+overworldMapCoord: MACRO
+	ld \1, wOverworldMap + ((\2) + 3) + (((\3) + 3) * ((\4) + (3 * 2)))
+ENDM
--- /dev/null
+++ b/macros/data.asm
@@ -1,0 +1,62 @@
+; Value macros
+
+percent EQUS "* $ff / 100"
+
+bcd2: MACRO
+	dn ((\1) / 1000) % 10, ((\1) / 100) % 10
+	dn ((\1) / 10) % 10, (\1) % 10
+ENDM
+
+bcd3: MACRO
+	dn ((\1) / 100000) % 10, ((\1) / 10000) % 10
+	dn ((\1) / 1000) % 10, ((\1) / 100) % 10
+	dn ((\1) / 10) % 10, (\1) % 10
+ENDM
+
+coins equs "bcd2"
+money equs "bcd3"
+
+RGB: MACRO
+	dw (\3 << 10 | \2 << 5 | \1)
+ENDM
+
+tmlearn: MACRO
+x = 0
+	REPT _NARG
+IF \1 != 0
+x = x | (1 << ((\1 - 1) % 8))
+ENDC
+	SHIFT
+	ENDR
+	db x
+ENDM
+
+
+; Constant data (db, dw, dl) macros
+
+dn: MACRO ; nybbles
+	db (\1 << 4 | \2)
+ENDM
+
+dbw: MACRO
+	db \1
+	dw \2
+ENDM
+
+dba: MACRO
+	dbw BANK(\1), \1
+ENDM
+
+dwb: MACRO
+	dw \1
+	db \2
+ENDM
+
+dab: MACRO
+	dwb \1, BANK(\1)
+ENDM
+
+dbbw: MACRO
+	db \1, \2
+	dw \3
+ENDM
--- a/macros/data_macros.asm
+++ /dev/null
@@ -1,253 +1,0 @@
-
-; Constant enumeration is useful for monsters, items, moves, etc.
-const_def: MACRO
-if _NARG >= 1
-const_value = \1
-else
-const_value = 0
-endc
-ENDM
-
-const: MACRO
-\1 EQU const_value
-const_value = const_value + 1
-ENDM
-
-; data format macros
-
-percent EQUS "* $ff / 100"
-
-bcd2: MACRO
-	dn ((\1) / 1000) % 10, ((\1) / 100) % 10
-	dn ((\1) / 10) % 10, (\1) % 10
-ENDM
-
-bcd3: MACRO
-	dn ((\1) / 100000) % 10, ((\1) / 10000) % 10
-	dn ((\1) / 1000) % 10, ((\1) / 100) % 10
-	dn ((\1) / 10) % 10, (\1) % 10
-ENDM
-
-coins equs "bcd2"
-money equs "bcd3"
-
-;\1 = Map Width
-;\2 = Rows above (Y-blocks)
-;\3 = X movement (X-blocks)
-EVENT_DISP: MACRO
-	dw (wOverworldMap + 7 + (\1) + ((\1) + 6) * ((\2) >> 1) + ((\3) >> 1)) ; Ev.Disp
-	db \2,\3 ;Y,X
-ENDM
-
-FLYWARP_DATA: MACRO
-	EVENT_DISP \1,\2,\3
-	db ((\2) & $01) ;sub-block Y
-	db ((\3) & $01) ;sub-block X
-ENDM
-
-; external map entry macro
-EMAP: MACRO ; emap x-coordinate,y-coordinate,textpointer
-; the appearance of towns and routes in the town map, indexed by map id
-	; nybble: y-coordinate
-	; nybble: x-coordinate
-	; word  : pointer to map name
-	dn \2, \1
-	dw \3
-ENDM
-
-; internal map entry macro
-IMAP: MACRO ; imap mapid_less_than,x-coordinate,y-coordinate,textpointer
-; the appearance of buildings and dungeons in the town map
-	; byte  : maximum map id subject to this rule
-	; nybble: y-coordinate
-	; nybble: x-coordinate
-	; word  : pointer to map name
-	db \1 + 1
-	dn \3, \2
-	dw \4
-ENDM
-
-; tilesets' headers macro
-tileset: MACRO
-	db BANK(\2)   ; BANK(GFX)
-	dw \1, \2, \3 ; Block, GFX, Coll
-	db \4, \5, \6 ; counter tiles
-	db \7         ; grass tile
-	db \8         ; permission (indoor, cave, outdoor)
-ENDM
-
-INDOOR  EQU 0
-CAVE    EQU 1
-OUTDOOR EQU 2
-
-RGB: MACRO
-	dw (\3 << 10 | \2 << 5 | \1)
-ENDM
-
-WALK EQU $FE
-STAY EQU $FF
-
-DOWN  EQU $D0
-UP    EQU $D1
-LEFT  EQU $D2
-RIGHT EQU $D3
-NONE  EQU $FF
-
-;\1 sprite id
-;\2 x position
-;\3 y position
-;\4 movement (WALK/STAY)
-;\5 range or direction
-;\6 text id
-;\7 items only: item id
-;\7 trainers only: trainer class/pokemon id
-;\8 trainers only: trainer number/pokemon level
-object: MACRO
-	db \1
-	db \3 + 4
-	db \2 + 4
-	db \4
-	db \5
-	IF (_NARG > 7)
-		db TRAINER | \6
-		db \7
-		db \8
-	ELSE
-		IF (_NARG > 6)
-			db ITEM | \6
-			db \7
-		ELSE
-			db \6
-		ENDC
-	ENDC
-ENDM
-
-;\1 x position
-;\2 y position
-;\3 destination warp id
-;\4 destination map (-1 = wLastMap)
-warp: MACRO
-	db \2, \1, \3, \4
-ENDM
-
-;\1 x position
-;\2 y position
-;\3 sign id
-sign: MACRO
-	db \2, \1, \3
-ENDM
-
-;\1 x position
-;\2 y position
-;\3 map width
-warp_to: MACRO
-	EVENT_DISP \3, \2, \1
-ENDM
-
-map_header: MACRO
-;\1: map name
-;\2: map id
-;\3: tileset
-;\4: connections: combo of NORTH, SOUTH, WEST, and/or EAST, or 0 for none
-CURRENT_MAP_WIDTH = \2_WIDTH
-CURRENT_MAP_HEIGHT = \2_HEIGHT
-CURRENT_MAP_OBJECT EQUS "\1_Object"
-\1_h::
-	db \3
-	db CURRENT_MAP_HEIGHT, CURRENT_MAP_WIDTH
-	dw \1_Blocks
-	dw \1_TextPointers
-	dw \1_Script
-	db \4
-ENDM
-
-end_map_header: MACRO
-	dw CURRENT_MAP_OBJECT
-PURGE CURRENT_MAP_WIDTH
-PURGE CURRENT_MAP_HEIGHT
-PURGE CURRENT_MAP_OBJECT
-ENDM
-
-; Connections go in order: north, south, west, east
-connection: MACRO
-;\1: direction
-;\2: map name
-;\3: map id
-;\4: offset of the target map relative to the current map
-;    (x offset for east/west, y offset for north/south)
-
-; Calculate tile offsets for source (current) and target maps
-_src = 0
-_tgt = (\4) + 3
-if _tgt < 2
-_src = -_tgt
-_tgt = 0
-endc
-
-if "\1" == "north"
-_blk = \3_WIDTH * (\3_HEIGHT - 3) + _src
-_map = _tgt
-_win = (\3_WIDTH + 6) * \3_HEIGHT + 1
-_y = \3_HEIGHT * 2 - 1
-_x = (\4) * -2
-_len = CURRENT_MAP_WIDTH + 3 - (\4)
-if _len > \3_WIDTH
-_len = \3_WIDTH
-endc
-
-elif "\1" == "south"
-_blk = _src
-_map = (CURRENT_MAP_WIDTH + 6) * (CURRENT_MAP_HEIGHT + 3) + _tgt
-_win = \3_WIDTH + 7
-_y = 0
-_x = (\4) * -2
-_len = CURRENT_MAP_WIDTH + 3 - (\4)
-if _len > \3_WIDTH
-_len = \3_WIDTH
-endc
-
-elif "\1" == "west"
-_blk = (\3_WIDTH * _src) + \3_WIDTH - 3
-_map = (CURRENT_MAP_WIDTH + 6) * _tgt
-_win = (\3_WIDTH + 6) * 2 - 6
-_y = (\4) * -2
-_x = \3_WIDTH * 2 - 1
-_len = CURRENT_MAP_HEIGHT + 3 - (\4)
-if _len > \3_HEIGHT
-_len = \3_HEIGHT
-endc
-
-elif "\1" == "east"
-_blk = (\3_WIDTH * _src)
-_map = (CURRENT_MAP_WIDTH + 6) * _tgt + CURRENT_MAP_WIDTH + 3
-_win = \3_WIDTH + 7
-_y = (\4) * -2
-_x = 0
-_len = CURRENT_MAP_HEIGHT + 3 - (\4)
-if _len > \3_HEIGHT
-_len = \3_HEIGHT
-endc
-
-else
-fail "Invalid direction for 'connection'."
-endc
-
-	db \3
-	dw \2_Blocks + _blk
-	dw wOverworldMap + _map
-	db _len - _src
-	db \3_WIDTH
-	db _y, _x
-	dw wOverworldMap + _win
-ENDM
-
-tmlearn: MACRO
-x = 0
-	REPT _NARG
-IF \1 != 0
-x = x | (1 << ((\1 - 1) % 8))
-ENDC
-	SHIFT
-	ENDR
-	db x
-ENDM
--- /dev/null
+++ b/macros/enum.asm
@@ -1,0 +1,43 @@
+; Enumerate variables
+
+enum_start: MACRO
+if _NARG >= 1
+__enum__ = \1
+else
+__enum__ = 0
+endc
+if _NARG >= 2
+__enumdir__ = \2
+else
+__enumdir__ = 1
+endc
+ENDM
+
+enum: MACRO
+\1 EQU __enum__
+__enum__ = __enum__ + __enumdir__
+ENDM
+
+enum_set: MACRO
+__enum__ = \1
+ENDM
+
+; Enumerate constants
+
+const_def: MACRO
+if _NARG >= 1
+const_value = \1
+else
+const_value = 0
+endc
+ENDM
+
+const: MACRO
+\1 EQU const_value
+const_value = const_value + 1
+ENDM
+
+shift_const: MACRO
+\1 EQU (1 << const_value)
+const_value = const_value + 1
+ENDM
--- a/macros/event_macros.asm
+++ /dev/null
@@ -1,441 +1,0 @@
-;\1 = event index
-;\2 = return result in carry instead of zero flag
-CheckEvent: MACRO
-event_byte = ((\1) / 8)
-	ld a, [wEventFlags + event_byte]
-
-	IF _NARG > 1
-		IF ((\1) % 8) == 7
-			add a
-		ELSE
-			REPT ((\1) % 8) + 1
-				rrca
-			ENDR
-		ENDC
-	ELSE
-		bit (\1) % 8, a
-	ENDC
-	ENDM
-
-;\1 = event index
-CheckEventReuseA: MACRO
-	IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld a, [wEventFlags + event_byte]
-	ENDC
-
-	bit (\1) % 8, a
-	ENDM
-
-;\1 = event index
-;\2 = event index of the last event used before the branch
-CheckEventAfterBranchReuseA: MACRO
-event_byte = ((\2) / 8)
-	IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld a, [wEventFlags + event_byte]
-	ENDC
-
-	bit (\1) % 8, a
-	ENDM
-
-;\1 = reg
-;\2 = event index
-;\3 = event index this event is relative to (optional, this is needed when there is a fixed flag address)
-EventFlagBit: MACRO
-	IF _NARG > 2
-		ld \1, ((\3) % 8) + ((\2) - (\3))
-	ELSE
-		ld \1, (\2) % 8
-	ENDC
-	ENDM
-
-;\1 = reg
-;\2 = event index
-EventFlagAddress: MACRO
-event_byte = ((\2) / 8)
-	ld \1, wEventFlags + event_byte
-	ENDM
-
-;\1 = event index
-CheckEventHL: MACRO
-event_byte = ((\1) / 8)
-	ld hl, wEventFlags + event_byte
-	bit (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-CheckEventReuseHL: MACRO
-IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	bit (\1) % 8, [hl]
-	ENDM
-
-; dangerous, only use when HL is guaranteed to be the desired value
-;\1 = event index
-CheckEventForceReuseHL: MACRO
-event_byte = ((\1) / 8)
-	bit (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-;\2 = event index of the last event used before the branch
-CheckEventAfterBranchReuseHL: MACRO
-event_byte = ((\2) / 8)
-IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	bit (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-CheckAndSetEvent: MACRO
-event_byte = ((\1) / 8)
-	ld hl, wEventFlags + event_byte
-	bit (\1) % 8, [hl]
-	set (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-CheckAndResetEvent: MACRO
-event_byte = ((\1) / 8)
-	ld hl, wEventFlags + event_byte
-	bit (\1) % 8, [hl]
-	res (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-CheckAndSetEventA: MACRO
-	ld a, [wEventFlags + ((\1) / 8)]
-	bit (\1) % 8, a
-	set (\1) % 8, a
-	ld [wEventFlags + ((\1) / 8)], a
-	ENDM
-
-;\1 = event index
-CheckAndResetEventA: MACRO
-	ld a, [wEventFlags + ((\1) / 8)]
-	bit (\1) % 8, a
-	res (\1) % 8, a
-	ld [wEventFlags + ((\1) / 8)], a
-	ENDM
-
-;\1 = event index
-SetEvent: MACRO
-event_byte = ((\1) / 8)
-	ld hl, wEventFlags + event_byte
-	set (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-SetEventReuseHL: MACRO
-	IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	set (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-;\2 = event index of the last event used before the branch
-SetEventAfterBranchReuseHL: MACRO
-event_byte = ((\2) / 8)
-IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	set (\1) % 8, [hl]
-	ENDM
-
-; dangerous, only use when HL is guaranteed to be the desired value
-;\1 = event index
-SetEventForceReuseHL: MACRO
-event_byte = ((\1) / 8)
-	set (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-;\2 = event index
-;\3, \4, ... = additional (optional) event indices
-SetEvents: MACRO
-	SetEvent \1
-	rept (_NARG + -1)
-	SetEventReuseHL \2
-	shift
-	endr
-	ENDM
-
-;\1 = event index
-ResetEvent: MACRO
-event_byte = ((\1) / 8)
-	ld hl, wEventFlags + event_byte
-	res (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-ResetEventReuseHL: MACRO
-	IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	res (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-;\2 = event index of the last event used before the branch
-ResetEventAfterBranchReuseHL: MACRO
-event_byte = ((\2) / 8)
-IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	res (\1) % 8, [hl]
-	ENDM
-
-; dangerous, only use when HL is guaranteed to be the desired value
-;\1 = event index
-ResetEventForceReuseHL: MACRO
-event_byte = ((\1) / 8)
-	res (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-;\2 = event index
-;\3 = event index (optional)
-ResetEvents: MACRO
-	ResetEvent \1
-	rept (_NARG + -1)
-	ResetEventReuseHL \2
-	shift
-	endr
-	ENDM
-
-;\1 = event index
-;\2 = number of bytes away from the base address (optional, for matching the ROM)
-dbEventFlagBit: MACRO
-	IF _NARG > 1
-		db ((\1) % 8) + ((\2) * 8)
-	ELSE
-		db ((\1) % 8)
-	ENDC
-	ENDM
-
-;\1 = event index
-;\2 = number of bytes away from the base address (optional, for matching the ROM)
-dwEventFlagAddress: MACRO
-	IF _NARG > 1
-		dw wEventFlags + ((\1) / 8) - (\2)
-	ELSE
-		dw wEventFlags + ((\1) / 8)
-	ENDC
-	ENDM
-
-;\1 = start
-;\2 = end
-SetEventRange: MACRO
-event_start_byte = ((\1) / 8)
-event_end_byte = ((\2) / 8)
-
-	IF event_end_byte < event_start_byte
-		FAIL "Incorrect argument order in SetEventRange."
-	ENDC
-
-	IF event_start_byte == event_end_byte
-		ld a, [wEventFlags + event_start_byte]
-		or (1 << (((\2) % 8) + 1)) - (1 << ((\1) % 8))
-		ld [wEventFlags + event_start_byte], a
-	ELSE
-event_fill_start = event_start_byte + 1
-event_fill_count = event_end_byte - event_start_byte - 1
-
-		IF ((\1) % 8) == 0
-event_fill_start = event_fill_start + -1
-event_fill_count = event_fill_count + 1
-		ELSE
-			ld a, [wEventFlags + event_start_byte]
-			or $ff - ((1 << ((\1) % 8)) - 1)
-			ld [wEventFlags + event_start_byte], a
-		ENDC
-
-		IF ((\2) % 8) == 7
-event_fill_count = event_fill_count + 1
-		ENDC
-
-		IF event_fill_count == 1
-			ld hl, wEventFlags + event_fill_start
-			ld [hl], $ff
-		ENDC
-
-		IF event_fill_count > 1
-			ld a, $ff
-			ld hl, wEventFlags + event_fill_start
-
-			REPT event_fill_count + -1
-				ld [hli], a
-			ENDR
-
-			ld [hl], a
-		ENDC
-
-		IF ((\2) % 8) == 0
-			ld hl, wEventFlags + event_end_byte
-			set 0, [hl]
-		ELSE
-			IF ((\2) % 8) != 7
-				ld a, [wEventFlags + event_end_byte]
-				or (1 << (((\2) % 8) + 1)) - 1
-				ld [wEventFlags + event_end_byte], a
-			ENDC
-		ENDC
-	ENDC
-	ENDM
-
-;\1 = start
-;\2 = end
-;\3 = assume a is 0 if present
-ResetEventRange: MACRO
-event_start_byte = ((\1) / 8)
-event_end_byte = ((\2) / 8)
-
-	IF event_end_byte < event_start_byte
-		FAIL "Incorrect argument order in ResetEventRange."
-	ENDC
-
-	IF event_start_byte == event_end_byte
-		ld a, [wEventFlags + event_start_byte]
-		and ~((1 << (((\2) % 8) + 1)) - (1 << ((\1) % 8))) & $ff
-		ld [wEventFlags + event_start_byte], a
-	ELSE
-event_fill_start = event_start_byte + 1
-event_fill_count = event_end_byte - event_start_byte - 1
-
-		IF ((\1) % 8) == 0
-event_fill_start = event_fill_start + -1
-event_fill_count = event_fill_count + 1
-		ELSE
-			ld a, [wEventFlags + event_start_byte]
-			and ~($ff - ((1 << ((\1) % 8)) - 1)) & $ff
-			ld [wEventFlags + event_start_byte], a
-		ENDC
-
-		IF ((\2) % 8) == 7
-event_fill_count = event_fill_count + 1
-		ENDC
-
-		IF event_fill_count == 1
-			ld hl, wEventFlags + event_fill_start
-			ld [hl], 0
-		ENDC
-
-		IF event_fill_count > 1
-			ld hl, wEventFlags + event_fill_start
-
-			; force xor a if we just to wrote to it above
-			IF (_NARG < 3) || (((\1) % 8) != 0)
-				xor a
-			ENDC
-
-			REPT event_fill_count + -1
-				ld [hli], a
-			ENDR
-
-			ld [hl], a
-		ENDC
-
-		IF ((\2) % 8) == 0
-			ld hl, wEventFlags + event_end_byte
-			res 0, [hl]
-		ELSE
-			IF ((\2) % 8) != 7
-				ld a, [wEventFlags + event_end_byte]
-				and ~((1 << (((\2) % 8) + 1)) - 1) & $ff
-				ld [wEventFlags + event_end_byte], a
-			ENDC
-		ENDC
-	ENDC
-	ENDM
-
-; returns whether both events are set in Z flag
-; This is counter-intuitive because the other event checks set the Z flag when
-; the event is not set, but this sets the Z flag when the event is set.
-;\1 = event index 1
-;\2 = event index 2
-;\3 = try to reuse a (optional)
-CheckBothEventsSet: MACRO
-	IF ((\1) / 8) == ((\2) / 8)
-		IF (_NARG < 3) || (((\1) / 8) != event_byte)
-event_byte = ((\1) / 8)
-			ld a, [wEventFlags + ((\1) / 8)]
-		ENDC
-		and (1 << ((\1) % 8)) | (1 << ((\2) % 8))
-		cp (1 << ((\1) % 8)) | (1 << ((\2) % 8))
-	ELSE
-		; This case doesn't happen in the original ROM.
-		IF ((\1) % 8) == ((\2) % 8)
-			push hl
-			ld a, [wEventFlags + ((\1) / 8)]
-			ld hl, wEventFlags + ((\2) / 8)
-			and [hl]
-			cpl
-			bit ((\1) % 8), a
-			pop hl
-		ELSE
-			push bc
-			ld a, [wEventFlags + ((\1) / 8)]
-			and (1 << ((\1) % 8))
-			ld b, a
-			ld a, [wEventFlags + ((\2) / 8)]
-			and (1 << ((\2) % 8))
-			or b
-			cp (1 << ((\1) % 8)) | (1 << ((\2) % 8))
-			pop bc
-		ENDC
-	ENDC
-	ENDM
-
-; returns the complement of whether either event is set in Z flag
-;\1 = event index 1
-;\2 = event index 2
-CheckEitherEventSet: MACRO
-	IF ((\1) / 8) == ((\2) / 8)
-		ld a, [wEventFlags + ((\1) / 8)]
-		and (1 << ((\1) % 8)) | (1 << ((\2) % 8))
-	ELSE
-		; This case doesn't happen in the original ROM.
-		IF ((\1) % 8) == ((\2) % 8)
-			push hl
-			ld a, [wEventFlags + ((\1) / 8)]
-			ld hl, wEventFlags + ((\2) / 8)
-			or [hl]
-			bit ((\1) % 8), a
-			pop hl
-		ELSE
-			push bc
-			ld a, [wEventFlags + ((\1) / 8)]
-			and (1 << ((\1) % 8))
-			ld b, a
-			ld a, [wEventFlags + ((\2) / 8)]
-			and (1 << ((\2) % 8))
-			or b
-			pop bc
-		ENDC
-	ENDC
-	ENDM
-
-; for handling fixed event bits when events are inserted/removed
-;\1 = event index
-;\2 = fixed flag bit
-AdjustEventBit: MACRO
-	IF ((\1) % 8) != (\2)
-		add ((\1) % 8) - (\2)
-	ENDC
-	ENDM
--- /dev/null
+++ b/macros/farcall.asm
@@ -1,0 +1,37 @@
+farcall EQUS "callba"
+
+callba: MACRO
+	ld b, BANK(\1)
+	ld hl, \1
+	call Bankswitch
+ENDM
+
+callab: MACRO
+	ld hl, \1
+	ld b, BANK(\1)
+	call Bankswitch
+ENDM
+
+jpba: MACRO
+	ld b, BANK(\1)
+	ld hl, \1
+	jp Bankswitch
+ENDM
+
+jpab: MACRO
+	ld hl, \1
+	ld b, BANK(\1)
+	jp Bankswitch
+ENDM
+
+homecall: MACRO
+	ld a, [H_LOADEDROMBANK]
+	push af
+	ld a, BANK(\1)
+	ld [H_LOADEDROMBANK], a
+	ld [MBC1RomBank], a
+	call \1
+	pop af
+	ld [H_LOADEDROMBANK], a
+	ld [MBC1RomBank], a
+ENDM
--- /dev/null
+++ b/macros/predef.asm
@@ -1,0 +1,49 @@
+predef_const: MACRO
+	const \1PredefID
+ENDM
+
+add_predef: MACRO
+\1Predef::
+	db BANK(\1)
+	dw \1
+ENDM
+
+predef_id: MACRO
+	ld a, (\1Predef - PredefPointers) / 3
+ENDM
+
+predef: MACRO
+	predef_id \1
+	call Predef
+ENDM
+
+predef_jump: MACRO
+	predef_id \1
+	jp Predef
+ENDM
+
+tx_pre_const: MACRO
+	const \1_id
+ENDM
+
+add_tx_pre: MACRO
+\1_id:: dw \1
+ENDM
+
+db_tx_pre: MACRO
+	db (\1_id - TextPredefs) / 2 + 1
+ENDM
+
+tx_pre_id: MACRO
+	ld a, (\1_id - TextPredefs) / 2 + 1
+ENDM
+
+tx_pre: MACRO
+	tx_pre_id \1
+	call PrintPredefTextID
+ENDM
+
+tx_pre_jump: MACRO
+	tx_pre_id \1
+	jp PrintPredefTextID
+ENDM
--- /dev/null
+++ b/macros/scripts/audio.asm
@@ -1,0 +1,186 @@
+audio_header: MACRO
+	db (_NARG - 2) << 6 | \2
+	dw \1_\2
+	IF _NARG > 2
+		db \3
+		dw \1_\3
+	ENDC
+	IF _NARG > 3
+		db \4
+		dw \1_\4
+	ENDC
+	IF _NARG > 4
+		db \5
+		dw \1_\5
+	ENDC
+ENDM
+
+; arguments: length [0, 7], pitch change [-7, 7]
+; length: length of time between pitch shifts
+;         sometimes used with a value >7 in which case the MSB is ignored
+; pitch change: positive value means increase in pitch, negative value means decrease in pitch
+;               small magnitude means quick change, large magnitude means slow change
+;               in signed magnitude representation, so a value of 8 is the same as (negative) 0
+pitch_sweep: MACRO
+	db $10
+	IF \2 < 0
+		db (\1 << 4) | (%1000 | (\2 * -1))
+	ELSE
+		db (\1 << 4) | \2
+	ENDC
+ENDM
+
+; arguments: length [0, 15], volume [0, 15], fade [-7, 7], frequency
+; fade: positive value means decrease in volume, negative value means increase in volume
+;       small magnitude means quick change, large magnitude means slow change
+;       in signed magnitude representation, so a value of 8 is the same as (negative) 0
+square_note: MACRO
+	db $20 | \1
+	IF \3 < 0
+		db (\2 << 4) | (%1000 | (\3 * -1))
+	ELSE
+		db (\2 << 4) | \3
+	ENDC
+	dw \4
+ENDM
+
+; arguments: length [0, 15], volume [0, 15], fade [-7, 7], frequency
+; fade: positive value means decrease in volume, negative value means increase in volume
+;       small magnitude means quick change, large magnitude means slow change
+;       in signed magnitude representation, so a value of 8 is the same as (negative) 0
+noise_note: MACRO
+	db $20 | \1
+	IF \3 < 0
+		db (\2 << 4) | (%1000 | (\3 * -1))
+	ELSE
+		db (\2 << 4) | \3
+	ENDC
+	db \4
+ENDM
+
+; arguments: pitch, length [1, 16]
+note: MACRO
+	db (\1 << 4) | (\2 - 1)
+ENDM
+
+; arguments: instrument [1, 19], length [1, 16]
+drum_note: MACRO
+	db $B0 | (\2 - 1)
+	db \1
+ENDM
+
+; arguments: instrument, length [1, 16]
+; like drum_note but one 1 byte instead of 2
+; can only be used with instruments 1-10, excluding 2
+; unused
+drum_note_short: MACRO
+	db (\1 << 4) | (\2 - 1)
+ENDM
+
+; arguments: length [1, 16]
+rest: MACRO
+	db $C0 | (\1 - 1)
+ENDM
+
+; arguments: speed [0, 15], volume [0, 15], fade [-7, 7]
+; fade: positive value means decrease in volume, negative value means increase in volume
+;       small magnitude means quick change, large magnitude means slow change
+;       in signed magnitude representation, so a value of 8 is the same as (negative) 0
+note_type: MACRO
+	db $D0 | \1
+	IF \3 < 0
+		db (\2 << 4) | (%1000 | (\3 * -1))
+	ELSE
+		db (\2 << 4) | \3
+	ENDC
+ENDM
+
+; arguments: speed [0, 15]
+drum_speed: MACRO
+	db $D0 | \1
+ENDM
+
+; arguments: octave [1, 8]
+octave: MACRO
+	db $E8 - \1
+ENDM
+
+; when enabled, effective frequency used is incremented by 1
+toggle_perfect_pitch: MACRO
+	db $E8
+ENDM
+
+; arguments: delay [0, 255], depth [0, 15], rate [0, 15]
+; delay: time delay until vibrato effect begins
+; depth: amplitude of vibrato wave
+; rate: frequency of vibrato wave
+vibrato: MACRO
+	db $EA
+	db \1
+	db (\2 << 4) | \3
+ENDM
+
+; arguments: length [1, 256], octave [1, 8], pitch
+pitch_slide: MACRO
+	db $EB
+	db \1 - 1
+	db ((8 - \2) << 4) | \3
+ENDM
+
+; arguments: duty cycle [0, 3] (12.5%, 25%, 50%, 75%)
+duty_cycle: MACRO
+	db $EC
+	db \1
+ENDM
+
+; arguments: tempo [0, $ffff]
+; used to calculate note delay counters
+; so a smaller value means music plays faster
+; ideally should be set to $100 or less to guarantee no overflow
+; if larger than $100, large note speed or note length values might cause overflow
+; stored in big endian
+tempo: MACRO
+	db $ED
+	db \1 / $100
+	db \1 % $100
+ENDM
+
+; arguments: left output enable mask, right output enable mask
+stereo_panning: MACRO
+	db $EE
+	db (\1 << 4) | \2
+ENDM
+
+; arguments: left master volume [0, 7], right master volume [0, 7]
+volume: MACRO
+	db $F0
+	db (\1 << 4) | \2
+ENDM
+
+; when enabled, the sfx data is interpreted as music data
+execute_music: MACRO
+	db $F8
+ENDM
+
+; arguments: duty cycle 1, duty cycle 2, duty cycle 3, duty cycle 4
+duty_cycle_pattern: MACRO
+	db $FC
+	db \1 << 6 | \2 << 4 | \3 << 2 | \4
+ENDM
+
+; arguments: address
+sound_call: MACRO
+	db $FD
+	dw \1
+ENDM
+
+; arguments: count, address
+sound_loop: MACRO
+	db $FE
+	db \1
+	dw \2
+ENDM
+
+sound_ret: MACRO
+	db $FF
+ENDM
--- /dev/null
+++ b/macros/scripts/events.asm
@@ -1,0 +1,471 @@
+;\1 = event index
+;\2 = return result in carry instead of zero flag
+CheckEvent: MACRO
+event_byte = ((\1) / 8)
+	ld a, [wEventFlags + event_byte]
+
+	IF _NARG > 1
+		IF ((\1) % 8) == 7
+			add a
+		ELSE
+			REPT ((\1) % 8) + 1
+				rrca
+			ENDR
+		ENDC
+	ELSE
+		bit (\1) % 8, a
+	ENDC
+ENDM
+
+
+;\1 = event index
+CheckEventReuseA: MACRO
+	IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld a, [wEventFlags + event_byte]
+	ENDC
+
+	bit (\1) % 8, a
+ENDM
+
+
+;\1 = event index
+;\2 = event index of the last event used before the branch
+CheckEventAfterBranchReuseA: MACRO
+event_byte = ((\2) / 8)
+	IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld a, [wEventFlags + event_byte]
+	ENDC
+
+	bit (\1) % 8, a
+ENDM
+
+
+;\1 = reg
+;\2 = event index
+;\3 = event index this event is relative to (optional, this is needed when there is a fixed flag address)
+EventFlagBit: MACRO
+	IF _NARG > 2
+		ld \1, ((\3) % 8) + ((\2) - (\3))
+	ELSE
+		ld \1, (\2) % 8
+	ENDC
+ENDM
+
+
+;\1 = reg
+;\2 = event index
+EventFlagAddress: MACRO
+event_byte = ((\2) / 8)
+	ld \1, wEventFlags + event_byte
+ENDM
+
+
+;\1 = event index
+CheckEventHL: MACRO
+event_byte = ((\1) / 8)
+	ld hl, wEventFlags + event_byte
+	bit (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+CheckEventReuseHL: MACRO
+IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	bit (\1) % 8, [hl]
+ENDM
+
+
+; dangerous, only use when HL is guaranteed to be the desired value
+;\1 = event index
+CheckEventForceReuseHL: MACRO
+event_byte = ((\1) / 8)
+	bit (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+;\2 = event index of the last event used before the branch
+CheckEventAfterBranchReuseHL: MACRO
+event_byte = ((\2) / 8)
+IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	bit (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+CheckAndSetEvent: MACRO
+event_byte = ((\1) / 8)
+	ld hl, wEventFlags + event_byte
+	bit (\1) % 8, [hl]
+	set (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+CheckAndResetEvent: MACRO
+event_byte = ((\1) / 8)
+	ld hl, wEventFlags + event_byte
+	bit (\1) % 8, [hl]
+	res (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+CheckAndSetEventA: MACRO
+	ld a, [wEventFlags + ((\1) / 8)]
+	bit (\1) % 8, a
+	set (\1) % 8, a
+	ld [wEventFlags + ((\1) / 8)], a
+ENDM
+
+
+;\1 = event index
+CheckAndResetEventA: MACRO
+	ld a, [wEventFlags + ((\1) / 8)]
+	bit (\1) % 8, a
+	res (\1) % 8, a
+	ld [wEventFlags + ((\1) / 8)], a
+ENDM
+
+
+;\1 = event index
+SetEvent: MACRO
+event_byte = ((\1) / 8)
+	ld hl, wEventFlags + event_byte
+	set (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+SetEventReuseHL: MACRO
+	IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	set (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+;\2 = event index of the last event used before the branch
+SetEventAfterBranchReuseHL: MACRO
+event_byte = ((\2) / 8)
+IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	set (\1) % 8, [hl]
+ENDM
+
+
+; dangerous, only use when HL is guaranteed to be the desired value
+;\1 = event index
+SetEventForceReuseHL: MACRO
+event_byte = ((\1) / 8)
+	set (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+;\2 = event index
+;\3, \4, ... = additional (optional) event indices
+SetEvents: MACRO
+	SetEvent \1
+	rept (_NARG + -1)
+	SetEventReuseHL \2
+	shift
+	endr
+ENDM
+
+
+;\1 = event index
+ResetEvent: MACRO
+event_byte = ((\1) / 8)
+	ld hl, wEventFlags + event_byte
+	res (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+ResetEventReuseHL: MACRO
+	IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	res (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+;\2 = event index of the last event used before the branch
+ResetEventAfterBranchReuseHL: MACRO
+event_byte = ((\2) / 8)
+IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	res (\1) % 8, [hl]
+ENDM
+
+
+; dangerous, only use when HL is guaranteed to be the desired value
+;\1 = event index
+ResetEventForceReuseHL: MACRO
+event_byte = ((\1) / 8)
+	res (\1) % 8, [hl]
+ENDM
+
+
+;\1 = event index
+;\2 = event index
+;\3 = event index (optional)
+ResetEvents: MACRO
+	ResetEvent \1
+	rept (_NARG + -1)
+	ResetEventReuseHL \2
+	shift
+	endr
+ENDM
+
+
+;\1 = event index
+;\2 = number of bytes away from the base address (optional, for matching the ROM)
+dbEventFlagBit: MACRO
+	IF _NARG > 1
+		db ((\1) % 8) + ((\2) * 8)
+	ELSE
+		db ((\1) % 8)
+	ENDC
+ENDM
+
+
+;\1 = event index
+;\2 = number of bytes away from the base address (optional, for matching the ROM)
+dwEventFlagAddress: MACRO
+	IF _NARG > 1
+		dw wEventFlags + ((\1) / 8) - (\2)
+	ELSE
+		dw wEventFlags + ((\1) / 8)
+	ENDC
+ENDM
+
+
+;\1 = start
+;\2 = end
+SetEventRange: MACRO
+event_start_byte = ((\1) / 8)
+event_end_byte = ((\2) / 8)
+
+	IF event_end_byte < event_start_byte
+		FAIL "Incorrect argument order in SetEventRange."
+	ENDC
+
+	IF event_start_byte == event_end_byte
+		ld a, [wEventFlags + event_start_byte]
+		or (1 << (((\2) % 8) + 1)) - (1 << ((\1) % 8))
+		ld [wEventFlags + event_start_byte], a
+	ELSE
+event_fill_start = event_start_byte + 1
+event_fill_count = event_end_byte - event_start_byte - 1
+
+		IF ((\1) % 8) == 0
+event_fill_start = event_fill_start + -1
+event_fill_count = event_fill_count + 1
+		ELSE
+			ld a, [wEventFlags + event_start_byte]
+			or $ff - ((1 << ((\1) % 8)) - 1)
+			ld [wEventFlags + event_start_byte], a
+		ENDC
+
+		IF ((\2) % 8) == 7
+event_fill_count = event_fill_count + 1
+		ENDC
+
+		IF event_fill_count == 1
+			ld hl, wEventFlags + event_fill_start
+			ld [hl], $ff
+		ENDC
+
+		IF event_fill_count > 1
+			ld a, $ff
+			ld hl, wEventFlags + event_fill_start
+
+			REPT event_fill_count + -1
+				ld [hli], a
+			ENDR
+
+			ld [hl], a
+		ENDC
+
+		IF ((\2) % 8) == 0
+			ld hl, wEventFlags + event_end_byte
+			set 0, [hl]
+		ELSE
+			IF ((\2) % 8) != 7
+				ld a, [wEventFlags + event_end_byte]
+				or (1 << (((\2) % 8) + 1)) - 1
+				ld [wEventFlags + event_end_byte], a
+			ENDC
+		ENDC
+	ENDC
+ENDM
+
+
+;\1 = start
+;\2 = end
+;\3 = assume a is 0 if present
+ResetEventRange: MACRO
+event_start_byte = ((\1) / 8)
+event_end_byte = ((\2) / 8)
+
+	IF event_end_byte < event_start_byte
+		FAIL "Incorrect argument order in ResetEventRange."
+	ENDC
+
+	IF event_start_byte == event_end_byte
+		ld a, [wEventFlags + event_start_byte]
+		and ~((1 << (((\2) % 8) + 1)) - (1 << ((\1) % 8))) & $ff
+		ld [wEventFlags + event_start_byte], a
+	ELSE
+event_fill_start = event_start_byte + 1
+event_fill_count = event_end_byte - event_start_byte - 1
+
+		IF ((\1) % 8) == 0
+event_fill_start = event_fill_start + -1
+event_fill_count = event_fill_count + 1
+		ELSE
+			ld a, [wEventFlags + event_start_byte]
+			and ~($ff - ((1 << ((\1) % 8)) - 1)) & $ff
+			ld [wEventFlags + event_start_byte], a
+		ENDC
+
+		IF ((\2) % 8) == 7
+event_fill_count = event_fill_count + 1
+		ENDC
+
+		IF event_fill_count == 1
+			ld hl, wEventFlags + event_fill_start
+			ld [hl], 0
+		ENDC
+
+		IF event_fill_count > 1
+			ld hl, wEventFlags + event_fill_start
+
+			; force xor a if we just to wrote to it above
+			IF (_NARG < 3) || (((\1) % 8) != 0)
+				xor a
+			ENDC
+
+			REPT event_fill_count + -1
+				ld [hli], a
+			ENDR
+
+			ld [hl], a
+		ENDC
+
+		IF ((\2) % 8) == 0
+			ld hl, wEventFlags + event_end_byte
+			res 0, [hl]
+		ELSE
+			IF ((\2) % 8) != 7
+				ld a, [wEventFlags + event_end_byte]
+				and ~((1 << (((\2) % 8) + 1)) - 1) & $ff
+				ld [wEventFlags + event_end_byte], a
+			ENDC
+		ENDC
+	ENDC
+ENDM
+
+
+; returns whether both events are set in Z flag
+; This is counter-intuitive because the other event checks set the Z flag when
+; the event is not set, but this sets the Z flag when the event is set.
+;\1 = event index 1
+;\2 = event index 2
+;\3 = try to reuse a (optional)
+CheckBothEventsSet: MACRO
+	IF ((\1) / 8) == ((\2) / 8)
+		IF (_NARG < 3) || (((\1) / 8) != event_byte)
+event_byte = ((\1) / 8)
+			ld a, [wEventFlags + ((\1) / 8)]
+		ENDC
+		and (1 << ((\1) % 8)) | (1 << ((\2) % 8))
+		cp (1 << ((\1) % 8)) | (1 << ((\2) % 8))
+	ELSE
+		; This case doesn't happen in the original ROM.
+		IF ((\1) % 8) == ((\2) % 8)
+			push hl
+			ld a, [wEventFlags + ((\1) / 8)]
+			ld hl, wEventFlags + ((\2) / 8)
+			and [hl]
+			cpl
+			bit ((\1) % 8), a
+			pop hl
+		ELSE
+			push bc
+			ld a, [wEventFlags + ((\1) / 8)]
+			and (1 << ((\1) % 8))
+			ld b, a
+			ld a, [wEventFlags + ((\2) / 8)]
+			and (1 << ((\2) % 8))
+			or b
+			cp (1 << ((\1) % 8)) | (1 << ((\2) % 8))
+			pop bc
+		ENDC
+	ENDC
+ENDM
+
+
+; returns the complement of whether either event is set in Z flag
+;\1 = event index 1
+;\2 = event index 2
+CheckEitherEventSet: MACRO
+	IF ((\1) / 8) == ((\2) / 8)
+		ld a, [wEventFlags + ((\1) / 8)]
+		and (1 << ((\1) % 8)) | (1 << ((\2) % 8))
+	ELSE
+		; This case doesn't happen in the original ROM.
+		IF ((\1) % 8) == ((\2) % 8)
+			push hl
+			ld a, [wEventFlags + ((\1) / 8)]
+			ld hl, wEventFlags + ((\2) / 8)
+			or [hl]
+			bit ((\1) % 8), a
+			pop hl
+		ELSE
+			push bc
+			ld a, [wEventFlags + ((\1) / 8)]
+			and (1 << ((\1) % 8))
+			ld b, a
+			ld a, [wEventFlags + ((\2) / 8)]
+			and (1 << ((\2) % 8))
+			or b
+			pop bc
+		ENDC
+	ENDC
+ENDM
+
+
+; for handling fixed event bits when events are inserted/removed
+;\1 = event index
+;\2 = fixed flag bit
+AdjustEventBit: MACRO
+	IF ((\1) % 8) != (\2)
+		add ((\1) % 8) - (\2)
+	ENDC
+ENDM
+
--- /dev/null
+++ b/macros/scripts/maps.asm
@@ -1,0 +1,184 @@
+;\1 map width
+;\2 Rows above (Y-blocks)
+;\3 X movement (X-blocks)
+EVENT_DISP: MACRO
+	dw (wOverworldMap + 7 + (\1) + ((\1) + 6) * ((\2) >> 1) + ((\3) >> 1)) ; Ev.Disp
+	db \2,\3 ;Y,X
+ENDM
+
+FLYWARP_DATA: MACRO
+	EVENT_DISP \1,\2,\3
+	db ((\2) & $01) ;sub-block Y
+	db ((\3) & $01) ;sub-block X
+ENDM
+
+; external map entry macro
+EMAP: MACRO ; emap x-coordinate,y-coordinate,textpointer
+; the appearance of towns and routes in the town map, indexed by map id
+	; nybble: y-coordinate
+	; nybble: x-coordinate
+	; word  : pointer to map name
+	dn \2, \1
+	dw \3
+ENDM
+
+; internal map entry macro
+IMAP: MACRO ; imap mapid_less_than,x-coordinate,y-coordinate,textpointer
+; the appearance of buildings and dungeons in the town map
+	; byte  : maximum map id subject to this rule
+	; nybble: y-coordinate
+	; nybble: x-coordinate
+	; word  : pointer to map name
+	db \1 + 1
+	dn \3, \2
+	dw \4
+ENDM
+
+;\1 sprite id
+;\2 x position
+;\3 y position
+;\4 movement (WALK/STAY)
+;\5 range or direction
+;\6 text id
+;\7 items only: item id
+;\7 trainers only: trainer class/pokemon id
+;\8 trainers only: trainer number/pokemon level
+object: MACRO
+	db \1
+	db \3 + 4
+	db \2 + 4
+	db \4
+	db \5
+	IF (_NARG > 7)
+		db TRAINER | \6
+		db \7
+		db \8
+	ELSE
+		IF (_NARG > 6)
+			db ITEM | \6
+			db \7
+		ELSE
+			db \6
+		ENDC
+	ENDC
+ENDM
+
+;\1 x position
+;\2 y position
+;\3 destination warp id
+;\4 destination map (-1 = wLastMap)
+warp: MACRO
+	db \2, \1, \3, \4
+ENDM
+
+;\1 x position
+;\2 y position
+;\3 sign id
+sign: MACRO
+	db \2, \1, \3
+ENDM
+
+;\1 x position
+;\2 y position
+;\3 map width
+warp_to: MACRO
+	EVENT_DISP \3, \2, \1
+ENDM
+
+;\1 map name
+;\2 map id
+;\3 tileset
+;\4 connections: combo of NORTH, SOUTH, WEST, and/or EAST, or 0 for none
+map_header: MACRO
+CURRENT_MAP_WIDTH = \2_WIDTH
+CURRENT_MAP_HEIGHT = \2_HEIGHT
+CURRENT_MAP_OBJECT EQUS "\1_Object"
+\1_h::
+	db \3
+	db CURRENT_MAP_HEIGHT, CURRENT_MAP_WIDTH
+	dw \1_Blocks
+	dw \1_TextPointers
+	dw \1_Script
+	db \4
+ENDM
+
+; Comes after map_header and connection macros
+end_map_header: MACRO
+	dw CURRENT_MAP_OBJECT
+PURGE CURRENT_MAP_WIDTH
+PURGE CURRENT_MAP_HEIGHT
+PURGE CURRENT_MAP_OBJECT
+ENDM
+
+; Connections go in order: north, south, west, east
+;\1 direction
+;\2 map name
+;\3 map id
+;\4 offset of the target map relative to the current map
+;   (x offset for east/west, y offset for north/south)
+connection: MACRO
+
+; Calculate tile offsets for source (current) and target maps
+_src = 0
+_tgt = (\4) + 3
+if _tgt < 2
+_src = -_tgt
+_tgt = 0
+endc
+
+if "\1" == "north"
+_blk = \3_WIDTH * (\3_HEIGHT - 3) + _src
+_map = _tgt
+_win = (\3_WIDTH + 6) * \3_HEIGHT + 1
+_y = \3_HEIGHT * 2 - 1
+_x = (\4) * -2
+_len = CURRENT_MAP_WIDTH + 3 - (\4)
+if _len > \3_WIDTH
+_len = \3_WIDTH
+endc
+
+elif "\1" == "south"
+_blk = _src
+_map = (CURRENT_MAP_WIDTH + 6) * (CURRENT_MAP_HEIGHT + 3) + _tgt
+_win = \3_WIDTH + 7
+_y = 0
+_x = (\4) * -2
+_len = CURRENT_MAP_WIDTH + 3 - (\4)
+if _len > \3_WIDTH
+_len = \3_WIDTH
+endc
+
+elif "\1" == "west"
+_blk = (\3_WIDTH * _src) + \3_WIDTH - 3
+_map = (CURRENT_MAP_WIDTH + 6) * _tgt
+_win = (\3_WIDTH + 6) * 2 - 6
+_y = (\4) * -2
+_x = \3_WIDTH * 2 - 1
+_len = CURRENT_MAP_HEIGHT + 3 - (\4)
+if _len > \3_HEIGHT
+_len = \3_HEIGHT
+endc
+
+elif "\1" == "east"
+_blk = (\3_WIDTH * _src)
+_map = (CURRENT_MAP_WIDTH + 6) * _tgt + CURRENT_MAP_WIDTH + 3
+_win = \3_WIDTH + 7
+_y = (\4) * -2
+_x = 0
+_len = CURRENT_MAP_HEIGHT + 3 - (\4)
+if _len > \3_HEIGHT
+_len = \3_HEIGHT
+endc
+
+else
+fail "Invalid direction for 'connection'."
+endc
+
+	db \3
+	dw \2_Blocks + _blk
+	dw wOverworldMap + _map
+	db _len - _src
+	db \3_WIDTH
+	db _y, _x
+	dw wOverworldMap + _win
+ENDM
--- /dev/null
+++ b/macros/scripts/text.asm
@@ -1,0 +1,78 @@
+text   EQUS "db $00," ; Start writing text.
+next   EQUS "db $4e," ; Move a line down.
+line   EQUS "db $4f," ; Start writing at the bottom line.
+para   EQUS "db $51," ; Start a new paragraph.
+cont   EQUS "db $55," ; Scroll to the next line.
+done   EQUS "db $57"  ; End a text box.
+prompt EQUS "db $58"  ; Prompt the player to end a text box (initiating some other event).
+
+page   EQUS "db $49,"     ; Start a new Pokedex page.
+dex    EQUS "db $5f, $50" ; End a Pokedex entry.
+
+TX_RAM: MACRO
+; prints text to screen
+; \1: RAM address to read from
+	db $1
+	dw \1
+ENDM
+
+TX_BCD: MACRO
+; \1: RAM address to read from
+; \2: number of bytes + print flags
+	db $2
+	dw \1
+	db \2
+ENDM
+
+TX_LINE    EQUS "db $05"
+TX_BLINK   EQUS "db $06"
+;TX_SCROLL EQUS "db $07"
+TX_ASM     EQUS "db $08"
+
+TX_NUM: MACRO
+; print a big-endian decimal number.
+; \1: address to read from
+; \2: number of bytes to read
+; \3: number of digits to display
+	db $09
+	dw \1
+	db \2 << 4 | \3
+ENDM
+
+TX_DELAY              EQUS "db $0a"
+TX_SFX_ITEM_1         EQUS "db $0b"
+TX_SFX_LEVEL_UP       EQUS "db $0b"
+;TX_ELLIPSES          EQUS "db $0c"
+TX_WAIT               EQUS "db $0d"
+;TX_SFX_DEX_RATING    EQUS "db $0e"
+TX_SFX_ITEM_2         EQUS "db $10"
+TX_SFX_KEY_ITEM       EQUS "db $11"
+TX_SFX_CAUGHT_MON     EQUS "db $12"
+TX_SFX_DEX_PAGE_ADDED EQUS "db $13"
+TX_CRY_NIDORINA       EQUS "db $14"
+TX_CRY_PIDGEOT        EQUS "db $15"
+;TX_CRY_DEWGONG       EQUS "db $16"
+
+TX_FAR: MACRO
+	db $17
+	dw \1
+	db BANK(\1)
+ENDM
+
+TX_VENDING_MACHINE         EQUS "db $f5"
+TX_CABLE_CLUB_RECEPTIONIST EQUS "db $f6"
+TX_PRIZE_VENDOR            EQUS "db $f7"
+TX_POKECENTER_PC           EQUS "db $f9"
+TX_PLAYERS_PC              EQUS "db $fc"
+TX_BILLS_PC                EQUS "db $fd"
+
+TX_MART: MACRO
+	db $FE, _NARG
+	REPT _NARG
+	db \1
+	SHIFT
+	ENDR
+	db $FF
+ENDM
+
+TX_POKECENTER_NURSE        EQUS "db $ff"
--- a/macros/text_macros.asm
+++ /dev/null
@@ -1,80 +1,0 @@
-
-; text macros
-text   EQUS "db $00," ; Start writing text.
-next   EQUS "db $4e," ; Move a line down.
-line   EQUS "db $4f," ; Start writing at the bottom line.
-para   EQUS "db $51," ; Start a new paragraph.
-cont   EQUS "db $55," ; Scroll to the next line.
-done   EQUS "db $57"  ; End a text box.
-prompt EQUS "db $58"  ; Prompt the player to end a text box (initiating some other event).
-
-page   EQUS "db $49,"     ; Start a new Pokedex page.
-dex    EQUS "db $5f, $50" ; End a Pokedex entry.
-
-TX_RAM: MACRO
-; prints text to screen
-; \1: RAM address to read from
-	db $1
-	dw \1
-ENDM
-
-TX_BCD: MACRO
-; \1: RAM address to read from
-; \2: number of bytes + print flags
-	db $2
-	dw \1
-	db \2
-ENDM
-
-TX_LINE    EQUS "db $05"
-TX_BLINK   EQUS "db $06"
-;TX_SCROLL EQUS "db $07"
-TX_ASM     EQUS "db $08"
-
-TX_NUM: MACRO
-; print a big-endian decimal number.
-; \1: address to read from
-; \2: number of bytes to read
-; \3: number of digits to display
-	db $09
-	dw \1
-	db \2 << 4 | \3
-ENDM
-
-TX_DELAY              EQUS "db $0a"
-TX_SFX_ITEM_1         EQUS "db $0b"
-TX_SFX_LEVEL_UP       EQUS "db $0b"
-;TX_ELLIPSES          EQUS "db $0c"
-TX_WAIT               EQUS "db $0d"
-;TX_SFX_DEX_RATING    EQUS "db $0e"
-TX_SFX_ITEM_2         EQUS "db $10"
-TX_SFX_KEY_ITEM       EQUS "db $11"
-TX_SFX_CAUGHT_MON     EQUS "db $12"
-TX_SFX_DEX_PAGE_ADDED EQUS "db $13"
-TX_CRY_NIDORINA       EQUS "db $14"
-TX_CRY_PIDGEOT        EQUS "db $15"
-;TX_CRY_DEWGONG       EQUS "db $16"
-
-TX_FAR: MACRO
-	db $17
-	dw \1
-	db BANK(\1)
-ENDM
-
-TX_VENDING_MACHINE         EQUS "db $f5"
-TX_CABLE_CLUB_RECEPTIONIST EQUS "db $f6"
-TX_PRIZE_VENDOR            EQUS "db $f7"
-TX_POKECENTER_PC           EQUS "db $f9"
-TX_PLAYERS_PC              EQUS "db $fc"
-TX_BILLS_PC                EQUS "db $fd"
-
-TX_MART: MACRO
-	db $FE, _NARG
-	REPT _NARG
-	db \1
-	SHIFT
-	ENDR
-	db $FF
-ENDM
-
-TX_POKECENTER_NURSE        EQUS "db $ff"
--- a/scripts/CeruleanCity.asm
+++ b/scripts/CeruleanCity.asm
@@ -64,7 +64,7 @@
 	ld a, [wWalkBikeSurfState]
 	and a
 	jr z, .asm_19512
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 .asm_19512
@@ -171,7 +171,7 @@
 	ld a, $1
 	ld [hSpriteIndexOrTextID], a
 	call DisplayTextID
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	callba Music_RivalAlternateStart
--- a/scripts/OaksLab.asm
+++ b/scripts/OaksLab.asm
@@ -510,7 +510,7 @@
 	xor a
 	ld [hJoyHeld], a
 	call EnableAutoTextBoxDrawing
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	callba Music_RivalAlternateStart
@@ -611,7 +611,7 @@
 	xor a ; NPC_MOVEMENT_DOWN
 	call FillMemory
 	ld [hl], $ff
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	callba Music_RivalAlternateStart
--- a/scripts/PalletTown.asm
+++ b/scripts/PalletTown.asm
@@ -27,8 +27,8 @@
 	ld [hJoyHeld], a
 	ld a, PLAYER_DIR_DOWN
 	ld [wPlayerMovingDirection], a
-	ld a, $FF
-	call PlaySound ; stop music
+	ld a, SFX_STOP_ALL_MUSIC
+	call PlaySound
 	ld a, BANK(Music_MeetProfOak)
 	ld c, a
 	ld a, MUSIC_MEET_PROF_OAK ; “oak appears” music
--- a/scripts/PewterPokecenter.asm
+++ b/scripts/PewterPokecenter.asm
@@ -21,7 +21,8 @@
 	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
 	ld hl, .Text
 	call PrintText
-	StopAllMusic
+	ld a, SFX_STOP_ALL_MUSIC
+	call PlaySound
 	ld c, 32
 	call DelayFrames
 	ld hl, JigglypuffFacingDirections
--- a/scripts/PokemonTower2F.asm
+++ b/scripts/PokemonTower2F.asm
@@ -22,7 +22,7 @@
 	ld hl, CoordsData_6055e
 	call ArePlayerCoordsInArray
 	ret nc
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	ld c, BANK(Music_MeetRival)
@@ -76,7 +76,7 @@
 	ld a, $1
 	ld [H_SPRITEINDEX], a
 	call MoveSprite
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	callba Music_RivalAlternateStart
--- a/scripts/Route22.asm
+++ b/scripts/Route22.asm
@@ -88,7 +88,7 @@
 	ld a, [wWalkBikeSurfState]
 	and a
 	jr z, .asm_50f4e
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 .asm_50f4e
@@ -167,7 +167,7 @@
 	ld a, $1
 	ld [hSpriteIndexOrTextID], a
 	call DisplayTextID
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	callba Music_RivalAlternateStart
@@ -241,11 +241,11 @@
 	ld a, [wWalkBikeSurfState]
 	and a
 	jr z, .skipYVisibilityTesta
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 .skipYVisibilityTesta
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	callba Music_RivalAlternateTempo
@@ -326,7 +326,7 @@
 	ld a, $2
 	ld [hSpriteIndexOrTextID], a
 	call DisplayTextID
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	callba Music_RivalAlternateStartAndTempo
--- a/scripts/SSAnne2F.asm
+++ b/scripts/SSAnne2F.asm
@@ -24,7 +24,7 @@
 	ld hl, CoordsData_61411
 	call ArePlayerCoordsInArray
 	ret nc
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	ld c, BANK(Music_MeetRival)
@@ -145,7 +145,7 @@
 	ld a, $2
 	ld [H_SPRITEINDEX], a
 	call MoveSprite
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	callba Music_RivalAlternateStart
--- a/scripts/SSAnneCaptainsRoom.asm
+++ b/scripts/SSAnneCaptainsRoom.asm
@@ -48,7 +48,7 @@
 	cp BANK(Audio3_UpdateMusic)
 	ld [wAudioSavedROMBank], a
 	jr nz, .asm_61908
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	ld a, Bank(Music_PkmnHealed)
--- a/scripts/SilphCo7F.asm
+++ b/scripts/SilphCo7F.asm
@@ -130,7 +130,7 @@
 	ld [wJoyIgnore], a
 	ld a, PLAYER_DIR_DOWN
 	ld [wPlayerMovingDirection], a
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	ld c, BANK(Music_MeetRival)
@@ -219,7 +219,7 @@
 	ld a, $f
 	ld [hSpriteIndexOrTextID], a
 	call DisplayTextID
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wNewSoundID], a
 	call PlaySound
 	callba Music_RivalAlternateStart
--- a/scripts/VermilionDock.asm
+++ b/scripts/VermilionDock.asm
@@ -38,7 +38,7 @@
 
 VermilionDock_1db9b:
 	SetEventForceReuseHL EVENT_SS_ANNE_LEFT
-	ld a, $ff
+	ld a, SFX_STOP_ALL_MUSIC
 	ld [wJoyIgnore], a
 	ld [wNewSoundID], a
 	call PlaySound