shithub: pokecrystal

Download patch

ref: 316fa4b69558a1930a1a1ae44a40221a1ddd4f26
parent: 35219230960f0dc85c0cb6a5723877b247609e46
author: Rangi <[email protected]>
date: Mon Apr 19 12:31:37 EDT 2021

Use rgbds 0.5.0

--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,11 @@
 install:
   - |-
     ( cd
-        git clone -b v0.4.2 --depth=1 https://github.com/gbdev/rgbds
+        if [ "$TRAVIS_OS_NAME" = osx ]; then
+          HOMEBREW_NO_AUTO_UPDATE=1 brew install bison
+          export PATH="/usr/local/opt/bison/bin:$PATH"
+        fi
+        git clone -b v0.5.0 --depth=1 https://github.com/gbdev/rgbds
         sudo make -C rgbds install
         rm -rf rgbds
     )
--- a/FAQ.md
+++ b/FAQ.md
@@ -41,15 +41,15 @@
 
 ### "ERROR: `UNION` already defined"
 
-Download [**rgbds 0.4.2**][rgbds] or newer. Older versions will not work.
+Download [**rgbds 0.5.0**][rgbds] or newer. Older versions will not work.
 
 ### "ERROR: Macro not defined"
 
-Download [**rgbds 0.4.2**][rgbds] or newer. Older versions will not work.
+Download [**rgbds 0.5.0**][rgbds] or newer. Older versions will not work.
 
 ### "Expression must be 8-bit"
 
-Download [**rgbds 0.4.2**][rgbds] or newer. Older versions will not work.
+Download [**rgbds 0.5.0**][rgbds] or newer. Older versions will not work.
 
 ### "Segmentation fault" from `rgbgfx`
 
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -42,9 +42,9 @@
 
 Double click on the text that says "**Skip**" next to each package to select the most recent version to install.
 
-Then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/windows) for Windows with Cygwin to install **rgbds 0.4.2**.
+Then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/windows) for Windows with Cygwin to install **rgbds 0.5.0**.
 
-**Note:** If you already have an older rgbds, you will need to update to 0.4.2. Ignore this if you have never installed rgbds before. If a version newer than 0.4.2 does not work, try downloading 0.4.2.
+**Note:** If you already have an older rgbds, you will need to update to 0.5.0. Ignore this if you have never installed rgbds before. If a version newer than 0.5.0 does not work, try downloading 0.5.0.
 
 Now open the **Cygwin terminal** and enter the following commands.
 
@@ -67,7 +67,7 @@
 
 Open **Terminal** and prepare to enter commands.
 
-Then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/macos) for macOS to install **rgbds 0.4.2**.
+Then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/macos) for macOS to install **rgbds 0.5.0**.
 
 Now you're ready to [build **pokecrystal**](#build-pokecrystal).
 
@@ -84,7 +84,7 @@
 sudo apt-get install make gcc git
 ```
 
-Then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/source) to build **rgbds 0.4.2** from source.
+Then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/source) to build **rgbds 0.5.0** from source.
 
 ### OpenSUSE
 
@@ -94,7 +94,7 @@
 sudo zypper install make gcc git
 ```
 
-Then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/source) to build **rgbds 0.4.2** from source.
+Then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/source) to build **rgbds 0.5.0** from source.
 
 ### Arch Linux
 
@@ -104,9 +104,9 @@
 sudo pacman -S make gcc git rgbds
 ```
 
-Then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/arch) for Arch Linux to install **rgbds 0.4.2**.
+Then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/arch) for Arch Linux to install **rgbds 0.5.0**.
 
-If you want to compile and install **rgbds** yourself instead, then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/source) to build **rgbds 0.4.2** from source.
+If you want to compile and install **rgbds** yourself instead, then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/source) to build **rgbds 0.5.0** from source.
 
 ### Termux
 
@@ -122,7 +122,7 @@
 sudo apt install rgbds
 ```
 
-If you want to compile and install **rgbds** yourself instead, then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/source) to build **rgbds 0.4.2** from source.
+If you want to compile and install **rgbds** yourself instead, then follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/source) to build **rgbds 0.5.0** from source.
 
 ### Other distros
 
@@ -133,7 +133,7 @@
 - `git`
 - `rgbds`
 
-If `rgbds` is not available, you'll need to follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/source) to build **rgbds 0.4.2** from source.
+If `rgbds` is not available, you'll need to follow the [**rgbds** instructions](https://rgbds.gbdev.io/install/source) to build **rgbds 0.5.0** from source.
 
 Now you're ready to [build **pokecrystal**](#build-pokecrystal).
 
@@ -157,4 +157,16 @@
 
 ```bash
 make crystal11
+```
+
+### Build with a local rgbds version
+
+If you have different projects that require different versions of `rgbds`, it might not be convenient to install rgbds 0.5.0 globally. Instead, you can put its files in a directory within pokecrystal, such as `pokecrystal/rgbds-0.5.0/`. Then specify it when you run `make`:
+
+```bash
+make RGBDS=rgbds-0.5.0/
+```
+
+```bash
+make RGBDS=rgbds-0.5.0/ crystal11
 ```
--- a/constants/item_constants.asm
+++ b/constants/item_constants.asm
@@ -210,22 +210,13 @@
 ; - TM_\1: the item id, starting at $bf
 ; - \1_TMNUM: the learnable TM/HM flag, starting at 1
 ; - TM##_MOVE: alias for the move id, equal to the value of \1
-; The first usage also defines TM01 as the first TM item id.
-if !DEF(TM01)
-TM01 EQU const_value
-endc
-if __tmhm_value__ < 10
-MOVE_FOR_TM EQUS "TM0{d:__tmhm_value__}_MOVE"
-else
-MOVE_FOR_TM EQUS "TM{d:__tmhm_value__}_MOVE"
-endc
-MOVE_FOR_TM = \1
-PURGE MOVE_FOR_TM
 	const TM_\1
+TM{02d:__tmhm_value__}_MOVE = \1
 	add_tmnum \1
 ENDM
 
 ; see data/moves/tmhm_moves.asm for moves
+TM01 EQU const_value
 	add_tm DYNAMICPUNCH ; bf
 	add_tm HEADBUTT     ; c0
 	add_tm CURSE        ; c1
@@ -285,23 +276,13 @@
 ; - HM_\1: the item id, starting at $f3
 ; - \1_TMNUM: the learnable TM/HM flag, starting at 51
 ; - HM##_MOVE: alias for the move id, equal to the value of \1
-; The first usage also defines HM01 as the first TM item id.
-if !DEF(HM01)
-HM01 EQU const_value
-endc
-HM_VALUE EQU __tmhm_value__ - NUM_TMS
-if HM_VALUE < 10
-MOVE_FOR_HM EQUS "HM0{d:HM_VALUE}_MOVE"
-else
-MOVE_FOR_HM EQUS "HM{d:HM_VALUE}_MOVE"
-endc
-MOVE_FOR_HM = \1
-PURGE MOVE_FOR_HM
-PURGE HM_VALUE
 	const HM_\1
+HM_VALUE = __tmhm_value__ - NUM_TMS
+HM{02d:HM_VALUE}_MOVE = \1
 	add_tmnum \1
 ENDM
 
+HM01 EQU const_value
 	add_hm CUT          ; f3
 	add_hm FLY          ; f4
 	add_hm SURF         ; f5
@@ -315,18 +296,12 @@
 ; Defines two constants:
 ; - \1_TMNUM: the learnable TM/HM flag, starting at 58
 ; - MT##_MOVE: alias for the move id, equal to the value of \1
-MT_VALUE EQU __tmhm_value__ - NUM_TMS - NUM_HMS
-if MT_VALUE < 10
-MOVE_FOR_MT EQUS "MT0{d:MT_VALUE}_MOVE"
-else
-MOVE_FOR_MT EQUS "MT{d:MT_VALUE}_MOVE"
-endc
-MOVE_FOR_MT = \1
-PURGE MOVE_FOR_MT
-PURGE MT_VALUE
+MT_VALUE = __tmhm_value__ - NUM_TMS - NUM_HMS
+MT{02d:MT_VALUE}_MOVE = \1
 	add_tmnum \1
 ENDM
 
+MT01 EQU const_value
 	add_mt FLAMETHROWER
 	add_mt THUNDERBOLT
 	add_mt ICE_BEAM
--- a/constants/map_constants.asm
+++ b/constants/map_constants.asm
@@ -18,7 +18,7 @@
 ENDM
 
 endgroup: MACRO
-CURRENT_NUM_MAPGROUP_MAPS EQU __map_value__ - 1
+{CURRENT_NUM_MAPGROUP_MAPS} EQU __map_value__ - 1
 PURGE CURRENT_NUM_MAPGROUP_MAPS
 ENDM
 
--- a/data/moves/tmhm_moves.asm
+++ b/data/moves/tmhm_moves.asm
@@ -6,44 +6,21 @@
 	table_width 1, TMHMMoves
 
 ; TMs
-n = 1
-rept NUM_TMS
-if n < 10
-MOVE_FOR_TM EQUS "TM0{d:n}_MOVE"
-else
-MOVE_FOR_TM EQUS "TM{d:n}_MOVE"
-endc
-	db MOVE_FOR_TM
-PURGE MOVE_FOR_TM
-n = n + 1
+for n, 1, NUM_TMS + 1
+	db TM{02d:n}_MOVE
 endr
 	assert_table_length NUM_TMS
 
 ; HMs
-n = 1
-rept NUM_HMS
-if n < 10
-MOVE_FOR_HM EQUS "HM0{d:n}_MOVE"
-else
-MOVE_FOR_HM EQUS "HM{d:n}_MOVE"
-endc
-	db MOVE_FOR_HM
-PURGE MOVE_FOR_HM
-n = n + 1
+for n, 1, NUM_HMS + 1
+	db HM{02d:n}_MOVE
 endr
 	assert_table_length NUM_TMS + NUM_HMS
 
-; Move tutor
+; Move tutors
 n = 1
-rept NUM_TUTORS
-if n < 10
-MOVE_FOR_MT EQUS "MT0{d:n}_MOVE"
-else
-MOVE_FOR_MT EQUS "MT{d:n}_MOVE"
-endc
-	db MOVE_FOR_MT
-PURGE MOVE_FOR_MT
-n = n + 1
+for n, 1, NUM_TUTORS + 1
+	db MT{02d:n}_MOVE
 endr
 	assert_table_length NUM_TM_HM_TUTOR
 
--- a/data/pokemon/base_stats.asm
+++ b/data/pokemon/base_stats.asm
@@ -1,12 +1,8 @@
 ; used in data/pokemon/base_stats/*.asm
 tmhm: MACRO
 ; initialize bytes to 0
-n = 0
-rept (NUM_TM_HM_TUTOR + 7) / 8
-_TM_BYTE EQUS "_tm{d:n}"
-_TM_BYTE = 0
-PURGE _TM_BYTE
-n = n + 1
+for n, (NUM_TM_HM_TUTOR + 7) / 8
+_tm{d:n} = 0
 endr
 ; set bits of bytes
 rept _NARG
@@ -13,9 +9,7 @@
 	if DEF(\1_TMNUM)
 n = (\1_TMNUM - 1) / 8
 i = (\1_TMNUM - 1) % 8
-_TM_BYTE EQUS "_tm{d:n}"
-_TM_BYTE = _TM_BYTE | (1 << i)
-PURGE _TM_BYTE
+_tm{d:n} = _tm{d:n} | (1 << i)
 	else
 		fail "\1 is not a TM, HM, or tutor move"
 	endc
@@ -22,12 +16,8 @@
 	shift
 endr
 ; output bytes
-n = 0
-rept (NUM_TM_HM_TUTOR + 7) / 8
-_TM_BYTE EQUS "_tm{d:n}"
-	db _TM_BYTE
-PURGE _TM_BYTE
-n = n + 1
+for n, (NUM_TM_HM_TUTOR + 7) / 8
+	db _tm{d:n}
 endr
 ENDM
 
--- a/data/pokemon/unown_words.asm
+++ b/data/pokemon/unown_words.asm
@@ -1,8 +1,6 @@
 unownword: MACRO
-x = 1
-rept STRLEN(\1)
-	db STRSUB(\1, x, 1) - "A" + FIRST_UNOWN_CHAR
-x = x + 1
+for x, STRLEN(\1)
+	db STRSUB(\1, x + 1, 1) - "A" + FIRST_UNOWN_CHAR
 endr
 	db -1
 ENDM
--- a/engine/events/battle_tower/battle_tower.asm
+++ b/engine/events/battle_tower/battle_tower.asm
@@ -386,11 +386,9 @@
 	ld c, l
 	ld a, [hl]
 	and a
-x = $ff
-rept $ff - NUM_POKEMON
+for x, $ff, NUM_POKEMON, -1
 	jr z, .invalid
 	cp x
-x = x - 1
 endr
 	jr nz, .valid
 
--- a/engine/events/buena.asm
+++ b/engine/events/buena.asm
@@ -43,10 +43,8 @@
 
 .PasswordIndices:
 	db NUM_PASSWORDS_PER_CATEGORY
-x = 0
-rept NUM_PASSWORDS_PER_CATEGORY
+for x, NUM_PASSWORDS_PER_CATEGORY
 	db x
-x = x + 1
 endr
 	db -1
 
@@ -264,10 +262,8 @@
 
 .Prizes:
 	db NUM_BUENA_PRIZES
-x = 1
-rept NUM_BUENA_PRIZES
-	db x
-x = x + 1
+for x, NUM_BUENA_PRIZES
+	db x + 1
 endr
 	db -1
 
--- a/engine/events/print_unown_2.asm
+++ b/engine/events/print_unown_2.asm
@@ -95,17 +95,9 @@
 	jr nz, .loop_count
 	ret
 
-gbprinterrect: MACRO
-y = 0
-rept \1
-x = \1 * (\2 - 1) + y
-rept \2
-	dw wGameboyPrinter2bppSource tile x
-x = x - \2
+UnownPrinter_GBPrinterRectangle:
+for y, 7
+for x, 7 - 1, -1, -1
+	dw wGameboyPrinter2bppSource tile (x * 7 + y)
 endr
-y = y + 1
 endr
-ENDM
-
-UnownPrinter_GBPrinterRectangle:
-	gbprinterrect 7, 7
--- a/engine/games/unown_puzzle.asm
+++ b/engine/games/unown_puzzle.asm
@@ -721,10 +721,8 @@
 	ret
 
 .EnlargedTiles:
-x = 0
-rept 16
+for x, 16
 	db ((x & %1000) * %11000) + ((x & %0100) * %1100) + ((x & %0010) * %110) + ((x & %0001) * %11)
-x = x + 1
 endr
 
 UnownPuzzle_AddPuzzlePieceBorders:
--- a/engine/gfx/pic_animation.asm
+++ b/engine/gfx/pic_animation.asm
@@ -534,14 +534,10 @@
 .Sizes: db 4, 5, 7
 
 poke_anim_box: MACRO
-y = 7
-rept \1
-x = 7 - \1
-rept \1
-	db x + y
-x = x + 1
+for y, 1, \1 + 1
+for x, 7 - \1, 7
+	db y * 7 + x
 endr
-y = y + 7
 endr
 ENDM
 
--- a/engine/math/get_square_root.asm
+++ b/engine/math/get_square_root.asm
@@ -25,8 +25,6 @@
 	ret
 
 .Squares:
-x = 1
-rept NUM_SQUARE_ROOTS
-	dw x * x
-x = x + 1
+for x, 1, NUM_SQUARE_ROOTS + 1
+	dw x**2
 endr
--- a/engine/menus/intro_menu.asm
+++ b/engine/menus/intro_menu.asm
@@ -1309,8 +1309,7 @@
 _dx = 0
 endc
 	dbpixel \1, \2, _dx, 0
-	shift
-	shift
+	shift 2
 endr
 ENDM
 	; frame 0 y, x; frame 1 y, x
--- a/engine/movie/intro.asm
+++ b/engine/movie/intro.asm
@@ -1310,26 +1310,20 @@
 
 .BWFade:
 ; Fade between black and white.
-hue = 0
-rept 32
+for hue, 32
 	RGB hue, hue, hue
-hue = hue + 1
 endr
 
 .BlackLBlueFade:
 ; Fade between black and light blue.
-hue = 0
-rept 32
+for hue, 32
 	RGB 0, hue / 2, hue
-hue = hue + 1
 endr
 
 .BlackBlueFade:
 ; Fade between black and blue.
-hue = 0
-rept 32
+for hue, 32
 	RGB 0, 0, hue
-hue = hue + 1
 endr
 
 Intro_Scene20_AppearUnown:
--- a/engine/overworld/player_object.asm
+++ b/engine/overworld/player_object.asm
@@ -55,7 +55,6 @@
 ; A dummy map object used to initialize the player object.
 ; Shorter than the actual amount copied by two bytes.
 ; Said bytes seem to be unused.
-_NUM_OBJECT_EVENTS = 0
 	object_event -4, -4, SPRITE_CHRIS, SPRITEMOVEDATA_PLAYER, 15, 15, -1, -1, 0, OBJECTTYPE_SCRIPT, 0, 0, -1
 
 CopyDECoordsToMapObject::
--- a/engine/pokegear/pokegear.asm
+++ b/engine/pokegear/pokegear.asm
@@ -1004,11 +1004,9 @@
 
 PokegearPhone_UpdateCursor:
 	ld a, " "
-x = 4
-rept PHONE_DISPLAY_HEIGHT
-	hlcoord 1, x
+for y, PHONE_DISPLAY_HEIGHT
+	hlcoord 1, 4 + y * 2
 	ld [hl], a
-x = x + 2
 endr
 	hlcoord 1, 4
 	ld a, [wPokegearPhoneCursorPosition]
--- a/engine/pokemon/bills_pc.asm
+++ b/engine/pokemon/bills_pc.asm
@@ -2280,10 +2280,8 @@
 
 .Boxes:
 	db NUM_BOXES
-x = 1
-rept NUM_BOXES
-	db x
-x = x + 1
+for x, NUM_BOXES
+	db x + 1
 endr
 	db -1
 
--- a/macros/asserts.asm
+++ b/macros/asserts.asm
@@ -2,33 +2,27 @@
 
 table_width: MACRO
 CURRENT_TABLE_WIDTH = \1
-if DEF(CURRENT_TABLE_START)
-PURGE CURRENT_TABLE_START
-endc
 if _NARG == 2
-CURRENT_TABLE_START EQUS "\2"
+REDEF CURRENT_TABLE_START EQUS "\2"
 else
-CURRENT_TABLE_START EQUS "._table_width\@"
-CURRENT_TABLE_START:
+REDEF CURRENT_TABLE_START EQUS "._table_width\@"
+{CURRENT_TABLE_START}:
 endc
 ENDM
 
 assert_table_length: MACRO
 x = \1
-	assert x * CURRENT_TABLE_WIDTH == @ - CURRENT_TABLE_START, \
+	assert x * CURRENT_TABLE_WIDTH == @ - {CURRENT_TABLE_START}, \
 		"{CURRENT_TABLE_START}: expected {d:x} entries, each {d:CURRENT_TABLE_WIDTH} bytes"
 ENDM
 
 list_start: MACRO
 list_index = 0
-if DEF(CURRENT_LIST_START)
-PURGE CURRENT_LIST_START
-endc
 if _NARG == 1
-CURRENT_LIST_START EQUS "\1"
+REDEF CURRENT_LIST_START EQUS "\1"
 else
-CURRENT_LIST_START EQUS "._list_start\@"
-CURRENT_LIST_START:
+REDEF CURRENT_LIST_START EQUS "._list_start\@"
+{CURRENT_LIST_START}:
 endc
 ENDM
 
@@ -46,38 +40,26 @@
 
 def_grass_wildmons: MACRO
 ;\1: map id
-if DEF(CURRENT_GRASS_WILDMONS_MAP)
-PURGE CURRENT_GRASS_WILDMONS_MAP
-endc
-if DEF(CURRENT_GRASS_WILDMONS_LABEL)
-PURGE CURRENT_GRASS_WILDMONS_LABEL
-endc
-CURRENT_GRASS_WILDMONS_MAP EQUS "\1"
-CURRENT_GRASS_WILDMONS_LABEL EQUS "._def_grass_wildmons_\1"
-CURRENT_GRASS_WILDMONS_LABEL:
+REDEF CURRENT_GRASS_WILDMONS_MAP EQUS "\1"
+REDEF CURRENT_GRASS_WILDMONS_LABEL EQUS "._def_grass_wildmons_\1"
+{CURRENT_GRASS_WILDMONS_LABEL}:
 	map_id \1
 ENDM
 
 end_grass_wildmons: MACRO
-	assert GRASS_WILDDATA_LENGTH == @ - CURRENT_GRASS_WILDMONS_LABEL, \
+	assert GRASS_WILDDATA_LENGTH == @ - {CURRENT_GRASS_WILDMONS_LABEL}, \
 		"def_grass_wildmons {CURRENT_GRASS_WILDMONS_MAP}: expected {d:GRASS_WILDDATA_LENGTH} bytes"
 ENDM
 
 def_water_wildmons: MACRO
 ;\1: map id
-if DEF(CURRENT_WATER_WILDMONS_MAP)
-PURGE CURRENT_WATER_WILDMONS_MAP
-endc
-if DEF(CURRENT_WATER_WILDMONS_LABEL)
-PURGE CURRENT_WATER_WILDMONS_LABEL
-endc
-CURRENT_WATER_WILDMONS_MAP EQUS "\1"
-CURRENT_WATER_WILDMONS_LABEL EQUS "._def_water_wildmons_\1"
-CURRENT_WATER_WILDMONS_LABEL:
+REDEF CURRENT_WATER_WILDMONS_MAP EQUS "\1"
+REDEF CURRENT_WATER_WILDMONS_LABEL EQUS "._def_water_wildmons_\1"
+{CURRENT_WATER_WILDMONS_LABEL}:
 	map_id \1
 ENDM
 
 end_water_wildmons: MACRO
-	assert WATER_WILDDATA_LENGTH == @ - CURRENT_WATER_WILDMONS_LABEL, \
+	assert WATER_WILDDATA_LENGTH == @ - {CURRENT_WATER_WILDMONS_LABEL}, \
 		"def_water_wildmons {CURRENT_WATER_WILDMONS_MAP}: expected {d:WATER_WILDDATA_LENGTH} bytes"
 ENDM
--- a/macros/data.asm
+++ b/macros/data.asm
@@ -70,24 +70,16 @@
 endr
 ENDM
 
-dx: MACRO
-x = 8 * ((\1) - 1)
-rept \1
-	db ((\2) >> x) & $ff
-x = x - 8
-endr
-ENDM
-
 dt: MACRO ; three-byte (big-endian)
-	dx 3, \1
+	db LOW((\1) >> 16), HIGH(\1), LOW(\1)
 ENDM
 
 dd: MACRO ; four-byte (big-endian)
-	dx 4, \1
+	db HIGH((\1) >> 16), LOW((\1) >> 16), HIGH(\1), LOW(\1)
 ENDM
 
 bigdw: MACRO ; big-endian word
-	dx 2, \1 ; db HIGH(\1), LOW(\1)
+	db HIGH(\1), LOW(\1)
 ENDM
 
 dba: MACRO ; dbw bank, address
--- a/macros/scripts/maps.asm
+++ b/macros/scripts/maps.asm
@@ -8,12 +8,9 @@
 object_const_def EQUS "const_def 2"
 
 def_scene_scripts: MACRO
-if DEF(_NUM_SCENE_SCRIPTS)
-	PURGE _NUM_SCENE_SCRIPTS
-endc
-_NUM_SCENE_SCRIPTS EQUS "_NUM_SCENE_SCRIPTS_\@"
-	db _NUM_SCENE_SCRIPTS
-_NUM_SCENE_SCRIPTS = 0
+REDEF _NUM_SCENE_SCRIPTS EQUS "_NUM_SCENE_SCRIPTS_\@"
+	db {_NUM_SCENE_SCRIPTS}
+{_NUM_SCENE_SCRIPTS} = 0
 ENDM
 
 scene_script: MACRO
@@ -20,16 +17,13 @@
 ;\1: script pointer
 	dw \1
 	dw 0 ; filler
-_NUM_SCENE_SCRIPTS = _NUM_SCENE_SCRIPTS + 1
+{_NUM_SCENE_SCRIPTS} = {_NUM_SCENE_SCRIPTS} + 1
 ENDM
 
 def_callbacks: MACRO
-if DEF(_NUM_CALLBACKS)
-	PURGE _NUM_CALLBACKS
-endc
-_NUM_CALLBACKS EQUS "_NUM_CALLBACKS_\@"
-	db _NUM_CALLBACKS
-_NUM_CALLBACKS = 0
+REDEF _NUM_CALLBACKS EQUS "_NUM_CALLBACKS_\@"
+	db {_NUM_CALLBACKS}
+{_NUM_CALLBACKS} = 0
 ENDM
 
 callback: MACRO
@@ -36,16 +30,13 @@
 ;\1: type: a MAPCALLBACK_* constant
 ;\2: script pointer
 	dbw \1, \2
-_NUM_CALLBACKS = _NUM_CALLBACKS + 1
+{_NUM_CALLBACKS} = {_NUM_CALLBACKS} + 1
 ENDM
 
 def_warp_events: MACRO
-if DEF(_NUM_WARP_EVENTS)
-	PURGE _NUM_WARP_EVENTS
-endc
-_NUM_WARP_EVENTS EQUS "_NUM_WARP_EVENTS_\@"
-	db _NUM_WARP_EVENTS
-_NUM_WARP_EVENTS = 0
+REDEF _NUM_WARP_EVENTS EQUS "_NUM_WARP_EVENTS_\@"
+	db {_NUM_WARP_EVENTS}
+{_NUM_WARP_EVENTS} = 0
 ENDM
 
 warp_event: MACRO
@@ -55,16 +46,13 @@
 ;\4: warp destination: starts at 1
 	db \2, \1, \4
 	map_id \3
-_NUM_WARP_EVENTS = _NUM_WARP_EVENTS + 1
+{_NUM_WARP_EVENTS} = {_NUM_WARP_EVENTS} + 1
 ENDM
 
 def_coord_events: MACRO
-if DEF(_NUM_COORD_EVENTS)
-	PURGE _NUM_COORD_EVENTS
-endc
-_NUM_COORD_EVENTS EQUS "_NUM_COORD_EVENTS_\@"
-	db _NUM_COORD_EVENTS
-_NUM_COORD_EVENTS = 0
+REDEF _NUM_COORD_EVENTS EQUS "_NUM_COORD_EVENTS_\@"
+	db {_NUM_COORD_EVENTS}
+{_NUM_COORD_EVENTS} = 0
 ENDM
 
 coord_event: MACRO
@@ -76,16 +64,13 @@
 	db 0 ; filler
 	dw \4
 	dw 0 ; filler
-_NUM_COORD_EVENTS = _NUM_COORD_EVENTS + 1
+{_NUM_COORD_EVENTS} = {_NUM_COORD_EVENTS} + 1
 ENDM
 
 def_bg_events: MACRO
-if DEF(_NUM_BG_EVENTS)
-	PURGE _NUM_BG_EVENTS
-endc
-_NUM_BG_EVENTS EQUS "_NUM_BG_EVENTS_\@"
-	db _NUM_BG_EVENTS
-_NUM_BG_EVENTS = 0
+REDEF _NUM_BG_EVENTS EQUS "_NUM_BG_EVENTS_\@"
+	db {_NUM_BG_EVENTS}
+{_NUM_BG_EVENTS} = 0
 ENDM
 
 bg_event: MACRO
@@ -95,16 +80,13 @@
 ;\4: script pointer
 	db \2, \1, \3
 	dw \4
-_NUM_BG_EVENTS = _NUM_BG_EVENTS + 1
+{_NUM_BG_EVENTS} = {_NUM_BG_EVENTS} + 1
 ENDM
 
 def_object_events: MACRO
-if DEF(_NUM_OBJECT_EVENTS)
-	PURGE _NUM_OBJECT_EVENTS
-endc
-_NUM_OBJECT_EVENTS EQUS "_NUM_OBJECT_EVENTS_\@"
-	db _NUM_OBJECT_EVENTS
-_NUM_OBJECT_EVENTS = 0
+REDEF _NUM_OBJECT_EVENTS EQUS "_NUM_OBJECT_EVENTS_\@"
+	db {_NUM_OBJECT_EVENTS}
+{_NUM_OBJECT_EVENTS} = 0
 ENDM
 
 object_event: MACRO
@@ -135,7 +117,10 @@
 	dw \9
 	shift
 	dw \9
-_NUM_OBJECT_EVENTS = _NUM_OBJECT_EVENTS + 1
+; the dummy PlayerObjectTemplate object_event has no def_object_events
+if DEF(_NUM_OBJECT_EVENTS)
+{_NUM_OBJECT_EVENTS} = {_NUM_OBJECT_EVENTS} + 1
+endc
 ENDM
 
 trainer: MACRO
--- a/mobile/fixed_words.asm
+++ b/mobile/fixed_words.asm
@@ -4048,11 +4048,7 @@
 ; parameter: number of words
 	db \1
 ; 12 words per page (0-based indexing)
-x = \1 / 12
-if \1 % 12 == 0
-x = x - 1
-endc
-	db x
+	db (\1 - 1) / 12
 ENDM
 	macro_11f220 18 ; 01: Types
 	macro_11f220 36 ; 02: Greetings
@@ -4076,10 +4072,10 @@
 ; These arrays are expanded dynamically to accomodate
 ; any Pokemon you've seen that starts with each kana.
 macro_11f23c: MACRO
-	dw x - w3_d000, \1
+	dw w3_d012 - w3_d000 + x, \1
 x = x + 2 * \1
 ENDM
-x = $d012 ; w3_d012
+x = 0
 	macro_11f23c $2f ; a
 	macro_11f23c $1e ; i
 	macro_11f23c $11 ; u
@@ -4124,6 +4120,5 @@
 	macro_11f23c $02 ; re
 	macro_11f23c $02 ; ro
 	macro_11f23c $15 ; wa
-x = $d000 ; w3_d000
-	macro_11f23c $09 ; end
+	dw NULL,     $09 ; end
 .End
--- a/mobile/mobile_12.asm
+++ b/mobile/mobile_12.asm
@@ -593,10 +593,8 @@
 
 .Items:
 	db 46
-x = 0
-rept 46
+for x, 46
 	db x
-x = x + 1
 endr
 	db -1
 
--- a/mobile/mobile_46.asm
+++ b/mobile/mobile_46.asm
@@ -5240,24 +5240,18 @@
 	ret
 
 Unknown_11a89a:
-x = 0
-rept 16
+for x, 16
 	bcd x % 100, x / 100
-x = x + 1
 endr
 
 Unknown_11a8ba:
-x = 0
-rept 16
+for x, 0, 16**2, 16
 	bcd x % 100, x / 100
-x = x + 16
 endr
 
 Unknown_11a8da:
-x = 0
-rept 16
+for x, 0, 16**3, 16**2
 	bcd x % 100, x / 100
-x = x + 256
 endr
 
 BattleTowerRoomMenu_WriteMessage:
--- a/mobile/mobile_5f.asm
+++ b/mobile/mobile_5f.asm
@@ -1601,17 +1601,13 @@
 	ret
 
 Unknown_17da8c:
-x = 0
-rept 8
+for x, 8
 	db 1 << x
-x = x + 1
 endr
 
 Unknown_17da94:
-x = 0
-rept 8
+for x, 8
 	db $ff ^ (1 << x)
-x = x + 1
 endr
 
 Function17da9c:
--- a/rgbdscheck.asm
+++ b/rgbdscheck.asm
@@ -1,14 +1,18 @@
-; pokecrystal requires rgbds 0.4.2 or newer.
 MAJOR EQU 0
-MINOR EQU 4
-PATCH EQU 2
+MINOR EQU 5
+PATCH EQU 0
 
-if !DEF(__RGBDS_MAJOR__) || !DEF(__RGBDS_MINOR__) || !DEF(__RGBDS_PATCH__)
-	fail "pokecrystal requires rgbds 0.4.2 or newer."
-else
-if (__RGBDS_MAJOR__ < MAJOR) || \
+wrong_rgbds: MACRO
+	fail "pokecrystal requires rgbds v0.5.0 or newer."
+ENDM
+
+IF !DEF(__RGBDS_MAJOR__) || !DEF(__RGBDS_MINOR__) || !DEF(__RGBDS_PATCH__)
+	wrong_rgbds
+ELSE
+IF (__RGBDS_MAJOR__ < MAJOR) || \
 	(__RGBDS_MAJOR__ == MAJOR && __RGBDS_MINOR__ < MINOR) || \
-	(__RGBDS_MAJOR__ == MAJOR && __RGBDS_MINOR__ == MINOR && __RGBDS_PATCH__ < PATCH)
-	fail "pokecrystal requires rgbds 0.4.2 or newer."
-endc
-endc
+	(__RGBDS_MAJOR__ == MAJOR && __RGBDS_MINOR__ == MINOR && __RGBDS_PATCH__ < PATCH) || \
+	(__RGBDS_MAJOR__ == MAJOR && __RGBDS_MINOR__ == MINOR && __RGBDS_PATCH__ == PATCH && DEF(__RGBDS_RC__))
+	wrong_rgbds
+ENDC
+ENDC
--- a/tools/unnamed.py
+++ b/tools/unnamed.py
@@ -82,7 +82,7 @@
     elif magic == b'RGB9':
         obj_ver = 10 + unpack_file("<I", f)[0]
 
-    if obj_ver not in [6, 10, 11, 12, 13, 15, 16]:
+    if obj_ver not in [6, 10, 11, 12, 13, 15, 16, 17]:
         print("Error: File '%s' is of an unknown format." % objfile, file=stderr)
         exit(1)
 
@@ -89,7 +89,7 @@
     num_symbols = unpack_file("<I", f)[0]
     unpack_file("<I", f) # skip num sections
 
-    if obj_ver in [16]:
+    if obj_ver in [16, 17]:
         node_filenames = []
         num_nodes = unpack_file("<I", f)[0]
         for x in range(num_nodes):
@@ -109,7 +109,7 @@
         sym_type = symtype(unpack_file("<B", f)[0] & 0x7f)
         if sym_type == symtype.IMPORT:
             continue
-        if obj_ver in [16]:
+        if obj_ver in [16, 17]:
             sym_fileno = unpack_file("<I", f)[0]
             sym_filename = node_filenames[sym_fileno]
         else: