diff options
Diffstat (limited to 'macros')
-rwxr-xr-x | macros/asm_macros.asm | 188 | ||||
-rwxr-xr-x | macros/audio_macros.asm | 277 | ||||
-rwxr-xr-x | macros/data_macros.asm | 220 | ||||
-rwxr-xr-x | macros/event_macros.asm | 441 | ||||
-rwxr-xr-x | macros/text_macros.asm | 80 |
5 files changed, 1206 insertions, 0 deletions
diff --git a/macros/asm_macros.asm b/macros/asm_macros.asm new file mode 100755 index 00000000..5cf5a809 --- /dev/null +++ b/macros/asm_macros.asm @@ -0,0 +1,188 @@ + +lb: MACRO ; r, hi, lo + ld \1, (\2) << 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 diff --git a/macros/audio_macros.asm b/macros/audio_macros.asm new file mode 100755 index 00000000..71304bf8 --- /dev/null +++ b/macros/audio_macros.asm @@ -0,0 +1,277 @@ + +StopAllMusic: MACRO + ld a, $ff + call PlaySound +ENDM + +Ch0 EQU 0 +Ch1 EQU 1 +Ch2 EQU 2 +Ch3 EQU 3 +Ch4 EQU 4 +Ch5 EQU 5 +Ch6 EQU 6 +Ch7 EQU 7 + +audio: 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 + +unknownsfx0x10: MACRO + db $10 + db \1 +ENDM + +unknownsfx0x20: MACRO + db $20 | \1 + db \2 + db \3 + db \4 +ENDM + +unknownnoise0x20: MACRO + db $20 | \1 + db \2 + db \3 +ENDM + +;format: pitch length (in 16ths) +C_: MACRO + db $00 | (\1 - 1) +ENDM + +C#: MACRO + db $10 | (\1 - 1) +ENDM + +D_: MACRO + db $20 | (\1 - 1) +ENDM + +D#: MACRO + db $30 | (\1 - 1) +ENDM + +E_: MACRO + db $40 | (\1 - 1) +ENDM + +F_: MACRO + db $50 | (\1 - 1) +ENDM + +F#: MACRO + db $60 | (\1 - 1) +ENDM + +G_: MACRO + db $70 | (\1 - 1) +ENDM + +G#: MACRO + db $80 | (\1 - 1) +ENDM + +A_: MACRO + db $90 | (\1 - 1) +ENDM + +A#: MACRO + db $A0 | (\1 - 1) +ENDM + +B_: MACRO + db $B0 | (\1 - 1) +ENDM + +;format: instrument length (in 16ths) +snare1: MACRO + db $B0 | (\1 - 1) + db $01 +ENDM + +snare2: MACRO + db $B0 | (\1 - 1) + db $02 +ENDM + +snare3: MACRO + db $B0 | (\1 - 1) + db $03 +ENDM + +snare4: MACRO + db $B0 | (\1 - 1) + db $04 +ENDM + +snare5: MACRO + db $B0 | (\1 - 1) + db $05 +ENDM + +triangle1: MACRO + db $B0 | (\1 - 1) + db $06 +ENDM + +triangle2: MACRO + db $B0 | (\1 - 1) + db $07 +ENDM + +snare6: MACRO + db $B0 | (\1 - 1) + db $08 +ENDM + +snare7: MACRO + db $B0 | (\1 - 1) + db $09 +ENDM + +snare8: MACRO + db $B0 | (\1 - 1) + db $0A +ENDM + +snare9: MACRO + db $B0 | (\1 - 1) + db $0B +ENDM + +cymbal1: MACRO + db $B0 | (\1 - 1) + db $0C +ENDM + +cymbal2: MACRO + db $B0 | (\1 - 1) + db $0D +ENDM + +cymbal3: MACRO + db $B0 | (\1 - 1) + db $0E +ENDM + +mutedsnare1: MACRO + db $B0 | (\1 - 1) + db $0F +ENDM + +triangle3: MACRO + db $B0 | (\1 - 1) + db $10 +ENDM + +mutedsnare2: MACRO + db $B0 | (\1 - 1) + db $11 +ENDM + +mutedsnare3: MACRO + db $B0 | (\1 - 1) + db $12 +ENDM + +mutedsnare4: MACRO + db $B0 | (\1 - 1) + db $13 +ENDM + +;format: rest length (in 16ths) +rest: MACRO + db $C0 | (\1 - 1) +ENDM + +; format: notetype speed, volume, fade +notetype: MACRO + db $D0 | \1 + db (\2 << 4) | \3 +ENDM + +dspeed: MACRO + db $D0 | \1 +ENDM + +octave: MACRO + db $E8 - \1 +ENDM + +toggleperfectpitch: MACRO + db $E8 +ENDM + +;format: vibrato delay, rate, depth +vibrato: MACRO + db $EA + db \1 + db (\2 << 4) | \3 +ENDM + +pitchbend: MACRO + db $EB + db \1 + db \2 +ENDM + +duty: MACRO + db $EC + db \1 +ENDM + +tempo: MACRO + db $ED + db \1 / $100 + db \1 % $100 +ENDM + +stereopanning: MACRO + db $EE + db \1 +ENDM + +volume: MACRO + db $F0 + db (\1 << 4) | \2 +ENDM + +executemusic: MACRO + db $F8 +ENDM + +dutycycle: MACRO + db $FC + db \1 +ENDM + +;format: callchannel address +callchannel: MACRO + db $FD + dw \1 +ENDM + +;format: loopchannel count, address +loopchannel: MACRO + db $FE + db \1 + dw \2 +ENDM + +endchannel: MACRO + db $FF +ENDM diff --git a/macros/data_macros.asm b/macros/data_macros.asm new file mode 100755 index 00000000..e24ae20e --- /dev/null +++ b/macros/data_macros.asm @@ -0,0 +1,220 @@ + +; Constant enumeration is useful for monsters, items, moves, etc. +const_def: MACRO +const_value = 0 +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 (byte) = current map id +;\2 (byte) = connected map id +;\3 (byte) = x movement of connection strip +;\4 (byte) = connection strip offset +;\5 (word) = connected map blocks pointer +NORTH_MAP_CONNECTION: MACRO + db \2 ; map id + dw \5 + (\2_WIDTH * (\2_HEIGHT - 3)) + \4; "Connection Strip" location + dw wOverworldMap + 3 + \3 ; current map position + IF (\1_WIDTH < \2_WIDTH) + db \1_WIDTH - \3 + 3 ; width of connection strip + ELSE + db \2_WIDTH - \4 ; width of connection strip + ENDC + db \2_WIDTH ; map width + db (\2_HEIGHT * 2) - 1 ; y alignment (y coordinate of player when entering map) + db (\3 - \4) * -2 ; x alignment (x coordinate of player when entering map) + dw wOverworldMap + 1 + (\2_HEIGHT * (\2_WIDTH + 6)) ; window (position of the upper left block after entering the map) +ENDM + +;\1 (byte) = current map id +;\2 (byte) = connected map id +;\3 (byte) = x movement of connection strip +;\4 (byte) = connection strip offset +;\5 (word) = connected map blocks pointer +;\6 (flag) = add 3 to width of connection strip (why?) +SOUTH_MAP_CONNECTION: MACRO + db \2 ; map id + dw \5 + \4 ; "Conection Strip" location + dw wOverworldMap + 3 + (\1_HEIGHT + 3) * (\1_WIDTH + 6) + \3 ; current map position + IF (\1_WIDTH < \2_WIDTH) + IF (_NARG > 5) + db \1_WIDTH - \3 + 3 ; width of connection strip + ELSE + db \1_WIDTH - \3 ; width of connection strip + ENDC + ELSE + db \2_WIDTH - \4 ; width of connection strip + ENDC + db \2_WIDTH ; map width + db 0 ; y alignment (y coordinate of player when entering map) + db (\3 - \4) * -2 ; x alignment (x coordinate of player when entering map) + dw wOverworldMap + 7 + \2_WIDTH ; window (position of the upper left block after entering the map) +ENDM + +;\1 (byte) = current map id +;\2 (byte) = connected map id +;\3 (byte) = y movement of connection strip +;\4 (byte) = connection strip offset +;\5 (word) = connected map blocks pointer +WEST_MAP_CONNECTION: MACRO + db \2 ; map id + dw \5 + (\2_WIDTH * \4) + \2_WIDTH - 3 ; "Connection Strip" location + dw wOverworldMap + (\1_WIDTH + 6) * (\3 + 3) ; current map position + IF (\1_HEIGHT < \2_HEIGHT) + db \1_HEIGHT - \3 + 3 ; height of connection strip + ELSE + db \2_HEIGHT - \4 ; height of connection strip + ENDC + db \2_WIDTH ; map width + db (\3 - \4) * -2 ; y alignment + db (\2_WIDTH * 2) - 1 ; x alignment + dw wOverworldMap + 6 + (2 * \2_WIDTH) ; window (position of the upper left block after entering the map) +ENDM + +;\1 (byte) = current map id +;\2 (byte) = connected map id +;\3 (byte) = y movement of connection strip +;\4 (byte) = connection strip offset +;\5 (word) = connected map blocks pointer +;\6 (flag) = add 3 to height of connection strip (why?) +EAST_MAP_CONNECTION: MACRO + db \2 ; map id + dw \5 + (\2_WIDTH * \4) ; "Connection Strip" location + dw wOverworldMap - 3 + (\1_WIDTH + 6) * (\3 + 4) ; current map position + IF (\1_HEIGHT < \2_HEIGHT) + IF (_NARG > 5) + db \1_HEIGHT - \3 + 3 ; height of connection strip + ELSE + db \1_HEIGHT - \3 ; height of connection strip + ENDC + ELSE + db \2_HEIGHT - \4 ; height of connection strip + ENDC + db \2_WIDTH ; map width + db (\3 - \4) * -2 ; y alignment + db 0 ; x alignment + dw wOverworldMap + 7 + \2_WIDTH ; window (position of the upper left block after entering the map) +ENDM + +tmlearn: MACRO +x = 0 + REPT _NARG +IF \1 != 0 +x = x | (1 << ((\1 - 1) % 8)) +ENDC + SHIFT + ENDR + db x +ENDM diff --git a/macros/event_macros.asm b/macros/event_macros.asm new file mode 100755 index 00000000..20027209 --- /dev/null +++ b/macros/event_macros.asm @@ -0,0 +1,441 @@ +;\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 diff --git a/macros/text_macros.asm b/macros/text_macros.asm new file mode 100755 index 00000000..21e02634 --- /dev/null +++ b/macros/text_macros.asm @@ -0,0 +1,80 @@ + +; 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" |