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. ## Contents 1. [Define an icon constant](#1-define-an-icon-constant) 2. [Design its graphics](#2-design-its-graphics) 3. [Include and point to the graphics](#3-include-and-point-to-the-graphics) 4. [Use the icon for a Pokémon](#4-use-the-icon-for-a-pokémon) 5. [How to add a unique icon for each Pokémon](#5-how-to-add-a-unique-icon-for-each-pokémon) ## 1. Define an icon constant Edit [constants/icon_constants.asm](../blob/master/constants/icon_constants.asm): ```diff ; IconPointers indexes (see data/icon_pointers.asm) const_def const ICON_NULL const ICON_POLIWAG ... const ICON_BIGMON + const ICON_CELEBI ``` ## 2. Design its graphics Create **gfx/icons/celebi.png**: ![gfx/icons/celebi.png](screenshots/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.png](../blob/master/gfx/overworld/celebi.png), which is used for the Japanese- and Virtual Console–exclusive GS Ball event. ## 3. Include and point to the graphics Edit [data/icon_pointers.asm](../blob/master/data/icon_pointers.asm): ```diff IconPointers: ; entries correspond to ICON_* constants table_width 2, IconPointers dw NullIcon dw PoliwagIcon ... dw BigmonIcon + dw CelebiIcon assert_table_length NUM_ICONS + 1 ``` And edit [gfx/icons.asm](../blob/master/gfx/icons.asm): ```diff Icons: NullIcon: PoliwagIcon: INCBIN "gfx/icons/poliwag.2bpp" ... BigmonIcon: INCBIN "gfx/icons/bigmon.2bpp" +CelebiIcon: INCBIN "gfx/icons/celebi.2bpp" ``` ## 4. Use the icon for a Pokémon Edit [data/pokemon/menu_icons.asm](../blob/master/data/pokemon/menu_icons.asm): ```diff MonMenuIcons: table_width 1, MonMenuIcons ... - db ICON_HUMANSHAPE ; CELEBI + db ICON_CELEBI ; CELEBI assert_table_length NUM_POKEMON ``` That's all! ![Screenshots](screenshots/celebi-icon.png) ## 5. How to add a unique icon for each Pokémon It's common to want a unique icon for each Pokémon, like the ones from this set ([here are its still frames](screenshots/minidex.png)): ![Screenshot](screenshots/minidex.gif) Or [this set](https://twitter.com/emimonserrate/status/861218520184623105) of the original 151 (plus Missingno!) by Emi Monserrate ([here are its still frames](screenshots/pokemon-rb-emi-party-icons.png)). (Found via [Eevee's proof of concept](https://github.com/eevee/pokered/tree/new-icons).) 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](../blob/master/gfx/icons.asm): ```diff -Icons: -NullIcon: -BulbasaurIcon: INCBIN "gfx/icons/bulbasaur.2bpp" -... -CelebiIcon: INCBIN "gfx/icons/celebi.2bpp" +SECTION "Mon Icons 1", ROMX + +NullIcon: +BulbasaurIcon: INCBIN "gfx/icons/bulbasaur.2bpp" +... +TaurosIcon: INCBIN "gfx/icons/tauros.2bpp" + +SECTION "Mon Icons 2", ROMX + +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](../blob/master/engine/gfx/mon_icons.asm): ```diff LoadOverworldMonIcon: ld a, e call ReadMonMenuIcon + ld [wCurIcon], a 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 - ret + jp GetIconBank ... GetIcon: ; Load icon graphics into VRAM starting from tile hl. ... - lb bc, BANK(Icons), 8 + call GetIconBank call GetGFXUnlessMobile pop hl ret + +GetIconBank: + ld a, [wCurIcon] + cp MAGIKARP ; first icon in Icons2 + lb bc, BANK("Mon Icons 1"), 8 + ret c + ld b, BANK("Mon Icons 2") + ret ``` Now all the icons will load correctly, in the party menu and in the overworld: ![Screenshot](screenshots/251-unique-icons.png)