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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
We will need to include our image files in [gfx/pics.asm](../blob/master/gfx/pics.asm). However, with this method they can be stored in any bank so long as each pokemon's front and back sprite stay together in the same bank. We will create a new section called `Pics 7` for our new pokemon.
```diff
...
ChannelerPic:: INCBIN "gfx/trainers/channeler.pic"
AgathaPic:: INCBIN "gfx/trainers/agatha.pic"
LancePic:: INCBIN "gfx/trainers/lance.pic"
+
+SECTION "Pics 7", ROMX
+
+CrobatPicFront:: INCBIN "gfx/pokemon/front/crobat.pic"
+CrobatPicBack:: INCBIN "gfx/pokemon/back/crobatb.pic"
```
This method does assume that the pics for fossil kabutops, fossil aerodactyl, and ghost are all included in the same back, so we will move them to `Pics 7` as well.
```diff
...
BeedrillPicBack:: INCBIN "gfx/pokemon/back/beedrillb.pic"
-FossilKabutopsPic:: INCBIN "gfx/pokemon/front/fossilkabutops.pic"
SECTION "Pics 4", ROMX
...
...
CharizardPicBack:: INCBIN "gfx/pokemon/back/charizardb.pic"
-FossilAerodactylPic:: INCBIN "gfx/pokemon/front/fossilaerodactyl.pic"
-GhostPic:: INCBIN "gfx/battle/ghost.pic"
OddishPicFront:: INCBIN "gfx/pokemon/front/oddish.pic"
...
...
SECTION "Pics 7", ROMX
CrobatPicFront:: INCBIN "gfx/pokemon/front/crobat.pic"
CrobatPicBack:: INCBIN "gfx/pokemon/back/crobatb.pic"
+FossilKabutopsPic:: INCBIN "gfx/pokemon/front/fossilkabutops.pic"
+FossilAerodactylPic:: INCBIN "gfx/pokemon/front/fossilaerodactyl.pic"
+GhostPic:: INCBIN "gfx/battle/ghost.pic"
```
Next we must change `UncompressMonSprite` in [home/pics.asm](../blob/master/home/pics.asm) to work with this new method.
```diff
UncompressMonSprite::
ld bc, wMonHeader
add hl, bc
ld a, [hli]
ld [wSpriteInputPtr], a ; fetch sprite input pointer
ld a, [hl]
ld [wSpriteInputPtr+1], a
-; define (by index number) the bank that a pokemon's image is in
-; index = MEW: bank $1
-; index = FOSSIL_KABUTOPS: bank $B
-; index < $1F: bank $9 ("Pics 1")
-; $1F ≤ index < $4A: bank $A ("Pics 2")
-; $4A ≤ index < $74: bank $B ("Pics 3")
-; $74 ≤ index < $99: bank $C ("Pics 4")
-; $99 ≤ index: bank $D ("Pics 5")
ld a, [wcf91]
- ld b, a
- cp MEW
- ld a, BANK(MewPicFront)
- jr z, .GotBank
- ld a, b
cp FOSSIL_KABUTOPS
+ jr z, .RecallBank
+ cp FOSSIL_AERODACTYL
+ jr z, .RecallBank
+ cp MON_GHOST
+ jr z, .RecallBank
+ ld a, [wMonHPicBank]
+ jr .GotBank
+.RecallBank
ld a, BANK(FossilKabutopsPic)
- jr z, .GotBank
- ld a, b
- cp TANGELA + 1
- ld a, BANK("Pics 1")
- jr c, .GotBank
- ld a, b
- cp MOLTRES + 1
- ld a, BANK("Pics 2")
- jr c, .GotBank
- ld a, b
- cp BEEDRILL + 2
- ld a, BANK("Pics 3")
- jr c, .GotBank
- ld a, b
- cp STARMIE + 1
- ld a, BANK("Pics 4")
- jr c, .GotBank
- ld a, BANK("Pics 5")
-
.GotBank
jp UncompressSpriteData
...
```
In case that's hard to read, here's what the function should look like when you're done:
```
UncompressMonSprite::
ld bc, wMonHeader
add hl, bc
ld a, [hli]
ld [wSpriteInputPtr], a ; fetch sprite input pointer
ld a, [hl]
ld [wSpriteInputPtr+1], a
ld a, [wcf91] ; XXX name for this ram location
cp FOSSIL_KABUTOPS
jr z, .RecallBank
cp FOSSIL_AERODACTYL
jr z, .RecallBank
cp MON_GHOST
jr z, .RecallBank
ld a, [wMonHPicBank]
jr .GotBank
.RecallBank
ld a, BANK(FossilKabutopsPic)
.GotBank
jp UncompressSpriteData
...
```
We will now need to add `wMonHPicBank` into (wram.asm)[../blob/master/wram.asm] just before the end of the mon header.
```diff
...
wMonHeader::
; In the ROM base stats data structure, this is the dex number, but it is
; overwritten with the internal index number after the header is copied to WRAM.
wMonHIndex:: db
wMonHBaseStats::
wMonHBaseHP:: db
wMonHBaseAttack:: db
wMonHBaseDefense:: db
wMonHBaseSpeed:: db
wMonHBaseSpecial:: db
wMonHTypes::
wMonHType1:: db
wMonHType2:: db
wMonHCatchRate:: db
wMonHBaseEXP:: db
wMonHSpriteDim:: db
wMonHFrontSprite:: dw
wMonHBackSprite:: dw
wMonHMoves:: ds NUM_MOVES
wMonHGrowthRate:: db
wMonHLearnset:: flag_array NUM_TMS + NUM_HMS
- ds 1
+wMonHPicBank:: db
wMonHeaderEnd::
...
```
Finally, we need to update each pokemon's base stat data with the bank of their picture. You could do this by individually changing each file, but don't. We can easily do this automatically by using [sed](https://www.gnu.org/software/sed/manual/sed.html). Simply run the following code in your terminal (note for Cygwin users: by default, paste is set to `shift+ins` instead of the `ctrl+v` you may be used to):
```
for f in data/pokemon/base_stats/*.asm; do
cat $f \
| tr '\n' '\v' \
| sed -E 's/dw (\w+), (\w+)(.+)(..)db [%01]+ ; padding/dw \1, \2\3\4db BANK(\1)\4assert BANK(\1) == BANK(\2)/g' \
| tr '\v' '\n' \
> $f.tmp;
mv -f $f.tmp $f;
done
```
and all your base stat files should now be properly updated.
```diff
db DEX_CROBAT ; pokedex id
db 85, 90, 80, 130, 80
; hp atk def spd spc
db POISON, FLYING ; type
db 90 ; catch rate
db 241 ; base exp
INCBIN "gfx/pokemon/front/crobat.pic", 0, 1 ; sprite dimensions
dw CrobatPicFront, CrobatPicBack
db LEECH_LIFE, SCREECH, BITE, SCREECH ; level 1 learnset
db GROWTH_MEDIUM_FAST ; growth rate
; tm/hm learnset
tmhm RAZOR_WIND, WHIRLWIND, TOXIC, TAKE_DOWN, DOUBLE_EDGE, \
HYPER_BEAM, RAGE, MEGA_DRAIN, MIMIC, DOUBLE_TEAM, \
BIDE, SWIFT, REST, SUBSTITUTE, FLY
; end
- db 0 ; padding
+ db BANK(CrobatPicFront)
+ assert BANK(CrobatPicFront) == BANK(CrobatPicBack)
```
|