summaryrefslogtreecommitdiff
path: root/Customizable-Pokédex-Color.md
blob: 6290d3752eb7f71e3998328ba5ef14b1ce6228e5 (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
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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
Ever wanted the color of your Pokédex to be something besides red? This is rather simple to implement in pokecrystal. All that's needed is a WRAM byte, and reworking some already existing code. 

## 1. Create a WRAM Byte

Edit [wram.asm](../blob/master/wram.asm):

```diff

wPokegearFlags::
; bit 0: map
; bit 1: radio
; bit 2: phone
; bit 3: expn
; bit 7: on/off
	db
wRadioTuningKnob:: db
wLastDexMode:: db
-	ds 1
+wCurPokedexColor:: db ; current dex color
wWhichRegisteredItem:: db ; d95b
wRegisteredItem:: db ; d95c
```

To start we create a wram byte. `wLastDexMode` has room after it and is also used by [engine\pokedex\pokedex.asm](../blob/master/engine/pokedex/pokedex.asm).

## 2. Create Constants

Edit [constants\wram_constants.asm](../blob/master/constants/wram_constants.asm).

```diff
; wCurDexMode:: ; c7d4
	const_def
	const DEXMODE_NEW
	const DEXMODE_OLD
	const DEXMODE_ABC
	const DEXMODE_UNOWN
	
+; wPokedexColor
+	const_def
+	const DEXCOLOR_RED
+	const DEXCOLOR_BLUE
+	const DEXCOLOR_PURPLE
+	const DEXCOLOR_BROWN
+	const DEXCOLOR_GREEN
+	const DEXCOLOR_PINK
+	const DEXCOLOR_YELLOW
+	const DEXCOLOR_CYAN
+       const DEXCOLOR_GRAY
+	const DEXCOLOR_MEWTWO

; wMonType:: ; cf5f
	const_def
	const PARTYMON   ; 0
	const OTPARTYMON ; 1
	const BOXMON     ; 2
	const TEMPMON    ; 3
	const WILDMON    ; 4
```

Now we need some constants that'll be used to figure out which color is seleceted.

## 3. Add the Color Option

Edit [engine\pokedex\pokedex.asm](../blob/master/engine/pokedex/pokedex.asm).

```diff
; Pokedex_RunJumptable.Jumptable indexes
	const_def
	const DEXSTATE_MAIN_SCR
	const DEXSTATE_UPDATE_MAIN_SCR
	const DEXSTATE_DEX_ENTRY_SCR
	const DEXSTATE_UPDATE_DEX_ENTRY_SCR
	const DEXSTATE_REINIT_DEX_ENTRY_SCR
	const DEXSTATE_SEARCH_SCR
	const DEXSTATE_UPDATE_SEARCH_SCR
	const DEXSTATE_OPTION_SCR
	const DEXSTATE_UPDATE_OPTION_SCR
	const DEXSTATE_SEARCH_RESULTS_SCR
	const DEXSTATE_UPDATE_SEARCH_RESULTS_SCR
	const DEXSTATE_UNOWN_MODE
	const DEXSTATE_UPDATE_UNOWN_MODE
+	const DEXSTATE_COLOR_OPTION
+	const DEXSTATE_UPDATE_COLOR_OPTION
	const DEXSTATE_EXIT
```
First is to create the `const` DEXSTATEs that'll be used to determine the Color options screen.

```diff
.Jumptable:
; entries correspond to DEXSTATE_* constants
	dw Pokedex_InitMainScreen
	dw Pokedex_UpdateMainScreen
	dw Pokedex_InitDexEntryScreen
	dw Pokedex_UpdateDexEntryScreen
	dw Pokedex_ReinitDexEntryScreen
	dw Pokedex_InitSearchScreen
	dw Pokedex_UpdateSearchScreen
	dw Pokedex_InitOptionScreen
	dw Pokedex_UpdateOptionScreen
	dw Pokedex_InitSearchResultsScreen
	dw Pokedex_UpdateSearchResultsScreen
	dw Pokedex_InitUnownMode
	dw Pokedex_UpdateUnownMode
+	dw Pokedex_InitColorOption
+	dw Pokedex_UpdateColorOption
	dw Pokedex_Exit
```
And to create the jumptable data for those screens.

```diff
Pokedex_InitOptionScreen:
	xor a
	ldh [hBGMapMode], a
	call ClearSprites
	call Pokedex_DrawOptionScreenBG
	call Pokedex_InitArrowCursor
-	ld a, [wCurDexMode] ; Index of the topmost visible item in a scrolling menu ???
	ld [wDexArrowCursorPosIndex], a
	call Pokedex_DisplayModeDescription
	call WaitBGMap
	ld a, SCGB_POKEDEX_SEARCH_OPTION
	call Pokedex_GetSGBLayout
	call Pokedex_IncrementDexPointer
	ret
```
This is to make sure the options menu starts at the top of the screen whenever the player enters it. Otherwise it'd begin at the second option.

```diff
Pokedex_UpdateOptionScreen:
...

.NoUnownModeArrowCursorData:
-	db D_UP | D_DOWN, 3
-	dwcoord 2,  4 ; NEW
-	dwcoord 2,  6 ; OLD
-	dwcoord 2,  8 ; ABC
+	db D_UP | D_DOWN, 4
+	dwcoord 2,  3 ; NEW
+	dwcoord 2,  4 ; OLD
+	dwcoord 2,  5 ; ABC
+	dwcoord 2,  6 ; COLOR

.ArrowCursorData:
-	db D_UP | D_DOWN, 4
-	dwcoord 2,  4 ; NEW
-	dwcoord 2,  6 ; OLD
-	dwcoord 2,  8 ; ABC
-	dwcoord 2, 10 ; UNOWN
+	db D_UP | D_DOWN, 5
+	dwcoord 2,  3 ; NEW
+	dwcoord 2,  4 ; OLD
+	dwcoord 2,  5 ; ABC
+	dwcoord 2,  6 ; COLOR
+	dwcoord 2,  7 ; UNOWN
```

Here we're adding the color option to the cursor jumptable. You may notice that the `dwcoord` are changed as well. This is because in order to fit an extra option on the screen, along with a description of said option, we need to remove the space between each option.

```diff
.MenuActionJumptable:			   
	dw .MenuAction_NewMode
	dw .MenuAction_OldMode
	dw .MenuAction_ABCMode
+	dw .MenuAction_ColorOption
	dw .MenuAction_UnownMode
...
+.MenuAction_ColorOption
+	call Pokedex_BlackOutBG
+	ld a, DEXSTATE_COLOR_OPTION
+	ld [wJumptableIndex], a
+	ret	

.MenuAction_UnownMode:
	call Pokedex_BlackOutBG
	ld a, DEXSTATE_UNOWN_MODE
	ld [wJumptableIndex], a
	ret
```
Adding the Color option to the `.MenuActionJumptable`. As you can see, the menu action is a copy of the Unown Dex action, but it takes us to the color option instead.

```
Pokedex_InitColorOption:
	xor a
	ldh [hBGMapMode], a
	call ClearSprites
	call Pokedex_DrawColorScreenBG
	call Pokedex_InitArrowCursor
	ld a, [wCurPokedexColor]
	ld [wDexArrowCursorPosIndex], a
	call WaitBGMap
	ld a, SCGB_POKEDEX_SEARCH_OPTION
	call Pokedex_GetSGBLayout
	call Pokedex_IncrementDexPointer
	ret
```

Here is the actual color option screen code, that should be placed after `Pokedex_UnownModeUpdateCursorGfx` Its a modified `Pokedex_InitOptionScreen` that will also remember cursor's location on the screen.

```diff
Pokedex_DrawOptionScreenBG:
	call Pokedex_FillBackgroundColor2
	hlcoord 0, 2
	lb bc, 8, 18
	call Pokedex_PlaceBorder
	hlcoord 0, 12
	lb bc, 4, 18
	call Pokedex_PlaceBorder
	hlcoord 0, 1
	ld de, .Title
	call Pokedex_PlaceString				 
-	hlcoord 3, 4
-	ld de, .Modes
-	call PlaceString
+	hlcoord 3, 3
+	ld de, .NewMode
+	call PlaceString
+	hlcoord 3, 4
+	ld de, .OldMode
+	call PlaceString
+	hlcoord 3, 5
+	ld de, .AtoZMode
+	call PlaceString
+	hlcoord 3, 6
+	ld de, .Color
+	call PlaceString
	ld a, [wUnlockedUnownMode]
	and a
	ret z
-	hlcoord 3, 10
+       hlcoord 3, 7
	ld de, .UnownMode
	call PlaceString
	ret

.Title:
	db $3b, " OPTION ", $3c, -1
				 					
-.Modes:
-	db   "NEW #DEX MODE"
-	next "OLD #DEX MODE"
-	next "A to Z MODE"
-	db   "@"
-
+.NewMode:
+	db "NEW #DEX MODE@"
+
+.OldMode:
+	db "OLD #DEX MODE@"
+
+.AtoZMode:
+	db "A to Z MODE@"
+	
+.Color:
+	db "#DEX COLOR@"
+
.UnownMode:
	db "UNOWN MODE@"
```

This is where we add the text displayed by the dex in the options menu. We had to change it from `.Modes` since it would force there to be a space between each line of the options, this way we guarantee that each line will be uniform.

```
Pokedex_DrawColorScreenBG:
	call Pokedex_FillBackgroundColor2
	hlcoord 0, 2
	lb bc, 14, 18
	call Pokedex_PlaceBorder
	hlcoord 0, 1
	ld de, .Title
	call Pokedex_PlaceString
	hlcoord 3, 3
	ld de, .Red
	call Pokedex_PlaceString	
	hlcoord 3, 4
	ld de, .Blue
	call Pokedex_PlaceString
	hlcoord 3, 5
	ld de, .Purple
	call Pokedex_PlaceString
	hlcoord 3, 6
	ld de, .Brown
	call Pokedex_PlaceString
	hlcoord 3, 7
	ld de, .Green
	call Pokedex_PlaceString
	hlcoord 3, 8
	ld de, .Pink
	call Pokedex_PlaceString
	hlcoord 3, 9
	ld de, .Yellow
	call Pokedex_PlaceString
	hlcoord 3, 10
	ld de, .Cyan
	call Pokedex_PlaceString
	hlcoord 3, 11
	ld de, .Gray
	call Pokedex_PlaceString
	hlcoord 3, 12
	ld de, .Mewtwo
	call Pokedex_PlaceString
	ret

.Title:
	db $3b, " COLORS ", $3c, -1

.Red
	db "RED    ", $4f, -1
	
.Blue
	db "BLUE   ", $4f, -1

.Purple
	db "PURPLE ", $4f, -1

.Brown
	db "BROWN  ", $4f, -1

.Green
	db "GREEN  ", $4f, -1	
	
.Pink
	db "PINK   ", $4f, -1	
	
.Yellow
	db "YELLOW ", $4f, -1	
	
.Cyan
	db "CYAN   ", $4f, -1
	
.Gray
	db "GRAY   ", $4f, -1	
	
.Mewtwo
	db "MEWTWO ", $4f, -1	

Pokedex_UpdateColorOption:
	ld de, .ArrowCursorData
	call Pokedex_MoveArrowCursor
	ld hl, hJoyPressed
	ld a, [hl]
	and SELECT | B_BUTTON
	jr nz, .return_to_main_screen
	ld a, [hl]
	and A_BUTTON
	jr nz, .do_menu_action
	ret
	
.ArrowCursorData:
	db D_UP | D_DOWN, 10
	dwcoord 2,  3  ; Red
	dwcoord 2,  4  ; Blue
	dwcoord 2,  5  ; Purple
	dwcoord 2,  6  ; Brown
	dwcoord 2,  7  ; Green
	dwcoord 2,  8  ; Pink
	dwcoord 2,  9  ; Yellow	
	dwcoord 2,  10 ; Cyan
	dwcoord 2,  11 ; Gray
	dwcoord 2,  12 ; Mewtwo
	
.do_menu_action
	ld a, [wDexArrowCursorPosIndex]
	ld hl, .MenuActionJumptable
	call Pokedex_LoadPointer
	jp hl
	
.return_to_main_screen
	call Pokedex_BlackOutBG
	ld a, DEXSTATE_MAIN_SCR
	ld [wJumptableIndex], a
	ret	

.MenuActionJumptable:
	dw .MenuAction_Red
	dw .MenuAction_Blue
	dw .MenuAction_Purple
	dw .MenuAction_Brown
	dw .MenuAction_Green
	dw .MenuAction_Pink
	dw .MenuAction_Yellow
	dw .MenuAction_Cyan
	dw .MenuAction_Gray
	dw .MenuAction_Mewtwo
	
.MenuAction_Red
	ld b, DEXCOLOR_RED
	jr .ChangeColor
	
.MenuAction_Blue
	ld b, DEXCOLOR_BLUE
	jr .ChangeColor

.MenuAction_Purple
	ld b, DEXCOLOR_PURPLE
	jr .ChangeColor
	
.MenuAction_Brown
	ld b, DEXCOLOR_BROWN
	jr .ChangeColor

.MenuAction_Green
	ld b, DEXCOLOR_GREEN
	jr .ChangeColor

.MenuAction_Pink
	ld b, DEXCOLOR_PINK
	jr .ChangeColor
	
.MenuAction_Yellow
	ld b, DEXCOLOR_YELLOW
	jr .ChangeColor
	
.MenuAction_Cyan
	ld b, DEXCOLOR_CYAN
	jr .ChangeColor	
	
.MenuAction_Gray
	ld b, DEXCOLOR_GRAY
	jr .ChangeColor	

.MenuAction_Mewtwo
	ld b, DEXCOLOR_MEWTWO
	
.ChangeColor:
	ld a, [wCurPokedexColor]
	cp b
	jr z, .skip_changing_color

	ld a, b
	ld [wCurPokedexColor], a
	
.skip_changing_color
	call Pokedex_BlackOutBG
	ld a, DEXSTATE_COLOR_OPTION
	ld [wJumptableIndex], a
	ret
```
This should be placed immediately after `.UnownMode`. This is the bread and butter of the color options screen. So let's break it down into its parts:

`Pokedex_DrawColorScreenBG` Is actually what creates the color option screen. Its a copy of the already used `Pokedex_DrawOptionScreenBG`, just adjusted to what we need. `Pokedex_UpdateColorOption` is similarly a copy of `Pokedex_UpdateOptionScreen`, but modified to remove the extra window at the bottom, since the colors don't really need descriptions. Also it uses the same button actions as that screen. This is optional, but the reason we've added the Pokéball symbol beside each color option is because that is the only use of the lighter color in the palette, and will give the player an additional idea of what the color will look like on a whole, without having to completely leave the menu.

Now the `.MenuActionJumptable` is a copy of the same one used by the options screen to update the Pokédex mode its in, but modified in a way that it loads `wCurPokedexColor` we created earilier with one of the corresponding palettes and then updates the screen so to apply the color.

```diff
Pokedex_DisplayModeDescription:
	xor a
	ldh [hBGMapMode], a
	hlcoord 0, 12
	lb bc, 4, 18
	call Pokedex_PlaceBorder
	ld a, [wDexArrowCursorPosIndex]
	ld hl, .Modes
	call Pokedex_LoadPointer
	ld e, l
	ld d, h
	hlcoord 1, 14
	call PlaceString
	ld a, $1
	ldh [hBGMapMode], a
	ret

.Modes:
	dw .NewMode
	dw .OldMode
	dw .ABCMode
+	dw .Color
	dw .UnownMode

.NewMode:
	db   "<PK><MN> are listed by"
	next "evolution type.@"

.OldMode:
	db   "<PK><MN> are listed by"
	next "official type.@"

.ABCMode:
	db   "<PK><MN> are listed"
	next "alphabetically.@"

+.Color
+	db   "Change the color"
+	next "of the border.@"

.UnownMode:
	db   "UNOWN are listed"
	next "in catching order.@"
```

And finally this adds a desctription.

## 4. Making the Pokédex load the color

Now that everything's set up on the Pokédex side, we need it to actually load the correct color. Doing some digging reveals that what we need is located in:

[engine\gfx\cgb_layouts.asm](../blob/master/engine/gfx/cgb_layouts.asm).

Searching the file for the default Pokédex color (`PREDEFPAL_POKEDEX`) will show it in `_CGB_Pokedex`, `_CGB_PokedexSearchOption`, and `_CGB_PokedexUnownMode`.

```diff
_CGB_Pokedex:
	ld de, wBGPals1
-	ld a, PREDEFPAL_POKEDEX
+	ld a, [wCurPokedexColor]
+	cp DEXCOLOR_BLUE
+	jr nz, .Purple
+	ld a, PREDEFPAL_TRADE_TUBE
+	jr .setColor
+.Purple
+	cp DEXCOLOR_PURPLE
+	jr nz, .Brown
+	ld a, PREDEFPAL_RB_PURPLEMON
+	jr .setColor
+.Brown
+	cp DEXCOLOR_BROWN
+	jr nz, .Green
+	ld a, PREDEFPAL_RB_BROWNMON
+	jr .setColor
+.Green
+	cp DEXCOLOR_GREEN
+	jr nz, .Pink
+	ld a, PREDEFPAL_RB_GREENMON
+	jr .setColor
+.Pink
+	cp DEXCOLOR_PINK
+	jr nz, .Yellow
+	ld a, PREDEFPAL_RB_PINKMON
+	jr .setColor
+.Yellow
+	cp DEXCOLOR_YELLOW
+	jr nz, .Cyan
+	ld a, PREDEFPAL_RB_YELLOWMON
+	jr .setColor
+.Cyan
+	cp DEXCOLOR_CYAN
+	jr nz, .Gray
+	ld a, PREDEFPAL_RB_CYANMON
+	jr .setColor
+.Gray
+	cp DEXCOLOR_GRAY
+	jr nz, .Mewtwo
+	ld a, PREDEFPAL_CGB_BADGE
+	jr .setColor
+.Mewtwo
+	cp DEXCOLOR_MEWTWO
+	jr nz, .Red
+	ld a, PREDEFPAL_DIPLOMA
+	jr .setColor	
+.Red
+	ld a, PREDEFPAL_POKEDEX
+.setColor
	call GetPredefPal
	call LoadHLPaletteIntoDE ; dex interface palette
	ld a, [wCurPartySpecies]
	cp $ff
	jr nz, .is_pokemon
	ld hl, .PokedexQuestionMarkPalette
	call LoadHLPaletteIntoDE ; green question mark palette
	jr .got_palette
```

We replaced the inital load of `PREDEFPAL_POKEDEX` with a chain comparison that finds the correct color and sets it. Do this for the other two mentioned locations and your done. 

## 5. Closing

![Screenshot](https://i.imgur.com/lQKgCGq.png)

The palettes I used were the unused palettes of the original Pokémon sprites in Red/Blue, but you can use any palette you like. This also has freed up some space on the options screen to allow for other Pokédex modes in addition to what's already there!

TODO: Cursor color