summaryrefslogtreecommitdiff
path: root/Add-a-new-party-menu-icon.md
blob: bf8fcae9da51b2afa5ff3ccd9395cbda1df3ec87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
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](../tree/master/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](../blob/master/data/icon_pointers.asm):

```diff
 IconPointers:
 ; entries correspond to ICON_* constants
 	dw NullIcon
 	dw PoliwagIcon
 	...
 	dw BigmonIcon
+	dw CelebiIcon
```

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:
 	...
-	db ICON_HUMANSHAPE  ; CELEBI
+	db ICON_CELEBI      ; CELEBI
```

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
+	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](screenshots/251-unique-icons.png)