Add a new party menu icon
This tutorial is for how to add a new party menu icon (the same icons are used outside the Day-Care). As an example, we'll add one for Celebi.
- Define an icon constant
- Design its graphics
- Include and point to the graphics
- Use the icon for a Pokémon
- How to add a unique icon for each Pokémon
Edit constants/icon_constants.asm:
; IconPointers indexes (see data/icon_pointers.asm)
const_def
const ICON_NULL
const ICON_POLIWAG
...
const ICON_BIGMON
+ const ICON_CELEBI
Create gfx/icons/celebi.png:
It needs to have two frames stacked vertically, each 16x16 pixels, and use four colors: black, white, light gray (#AAAAAA), and dark gray (#555555).
The example graphics are based on gfx/overworld/celebi, which are used for the Japanese- and Virtual Console–exclusive GS Ball event.
Edit data/icon_pointers.asm:
IconPointers:
; entries correspond to ICON_* constants
dw NullIcon
dw PoliwagIcon
...
dw BigmonIcon
+ dw CelebiIcon
And edit gfx/icons.asm:
Icons:
NullIcon:
PoliwagIcon: INCBIN "gfx/icons/poliwag.2bpp" ; 0x8ec0d
...
BigmonIcon: INCBIN "gfx/icons/bigmon.2bpp" ; 0x8fe8d
+CelebiIcon: INCBIN "gfx/icons/celebi.2bpp"
Edit data/pokemon/menu_icons.asm:
MonMenuIcons: ; 8eac4
...
- db ICON_HUMANSHAPE ; CELEBI
+ db ICON_CELEBI ; CELEBI
That's all!
It's common to want a unique icon for each Pokémon, like the ones from this set (here are its still frames):
But when you add all 251 icons at once, make
gives an error:
ERROR: main.asm(315) -> engine/gfx/mon_icons.asm(471) -> gfx/icons.asm(42):
Section 'bank23' is too big (max size = 0x4000 bytes).
That many icons won't fit in one ROM bank. We'll have to split them into multiple sections.
How many icons can fit in a bank? Well, a bank is $4000 = 16,384 bytes. An icon has two frames, each 16x16 pixels, encoded with two bits per pixel (hence "2bpp"), and eight bits are in a byte. So each icon uses 128 bytes, and 16,384 / 128 = 128 icons can fit in a bank. That means two banks will be enough for the 252 icons we need (251 Pokémon plus Egg).
Edit gfx/icons.asm:
-Icons:
-NullIcon:
-BulbasaurIcon: INCBIN "gfx/icons/bulbasaur.2bpp"
-...
-CelebiIcon: INCBIN "gfx/icons/celebi.2bpp"
+SECTION "Mon Icons 1", ROMX
+
+Icons1:
+NullIcon:
+BulbasaurIcon: INCBIN "gfx/icons/bulbasaur.2bpp"
+...
+TaurosIcon: INCBIN "gfx/icons/tauros.2bpp"
+
+SECTION "Mon Icons 2", ROMX
+
+Icons2:
+MagikarpIcon: INCBIN "gfx/icons/magikarp.2bpp"
+...
+CelebiIcon: INCBIN "gfx/icons/celebi.2bpp"
One section, "Mon Icons 1", contains icons #1 to #128. The next, "Mon Icons 2", contains #129 to #251 and Egg. When you run make
they'll automatically be placed in banks that fit. Make sure the species are separated in order, so that we can tell which section a Pokémon's icon belongs in just by whether its species is greater than 128.
Now edit engine/gfx/mon_icons.asm:
LoadOverworldMonIcon: ; 8e82b
ld a, e
+ push af
call ReadMonMenuIcon
ld l, a
ld h, 0
add hl, hl
ld de, IconPointers
add hl, de
ld a, [hli]
ld e, a
ld d, [hl]
- ld b, BANK(Icons)
- ld c, 8
+ pop af
+ call GetIconBank
ret
; 8e83f
...
GetIcon: ; 8ea1e
; Load icon graphics into VRAM starting from tile hl.
...
- lb bc, BANK(Icons), 8
+ call GetIconBank
call GetGFXUnlessMobile
pop hl
ret
; 8ea3f
+
+GetIconBank:
+ lb bc, BANK(Icons1), 8
+ cp MAGIKARP ; lowest species in "Mon Icons 2"
+ ret c
+ ld b, BANK(Icons2)
+ ret
Now all the icons will load correctly, in the party menu and in the overworld: