Skip to content

Add a new party menu icon

Rangi edited this page Oct 15, 2018 · 27 revisions

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
  2. Design its graphics
  3. Include and point to the graphics
  4. Use the icon for a Pokémon
  5. How to add a unique icon for each Pokémon

1. Define an icon constant

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

2. Design its graphics

Create gfx/icons/celebi.png:

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.

3. Include and point to the graphics

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"
 ...
 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:

 MonMenuIcons:
 	...
-	db ICON_HUMANSHAPE  ; CELEBI
+	db ICON_CELEBI      ; CELEBI

That's all!

Screenshots

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):

Screenshot

Or this set of the original 151 (plus Missingno!) by Emi Monserrate (here are its still frames). (Found via Eevee's proof of concept.)

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
+
+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:

 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
+	call GetIconBank
 	ret

 ...

 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 TAUROS ; last mon in Icons1
+	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

Clone this wiki locally