Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pret
GitHub Repository: pret/pokered
Path: blob/master/engine/gfx/palettes.asm
1271 views
1
_RunPaletteCommand:
2
call GetPredefRegisters
3
ld a, b
4
cp SET_PAL_DEFAULT
5
jr nz, .not_default
6
ld a, [wDefaultPaletteCommand]
7
.not_default
8
cp SET_PAL_PARTY_MENU_HP_BARS
9
jp z, UpdatePartyMenuBlkPacket
10
ld l, a
11
ld h, 0
12
add hl, hl
13
ld de, SetPalFunctions
14
add hl, de
15
ld a, [hli]
16
ld h, [hl]
17
ld l, a
18
ld de, SendSGBPackets
19
push de
20
jp hl
21
22
SetPal_BattleBlack:
23
ld hl, PalPacket_Black
24
ld de, BlkPacket_Battle
25
ret
26
27
; uses PalPacket_Empty to build a packet based on mon IDs and health color
28
SetPal_Battle:
29
ld hl, PalPacket_Empty
30
ld de, wPalPacket
31
ld bc, $10
32
call CopyData
33
ld a, [wPlayerBattleStatus3]
34
ld hl, wBattleMonSpecies
35
call DeterminePaletteID
36
ld b, a
37
ld a, [wEnemyBattleStatus3]
38
ld hl, wEnemyMonSpecies2
39
call DeterminePaletteID
40
ld c, a
41
ld hl, wPalPacket + 1
42
ld a, [wPlayerHPBarColor]
43
add PAL_GREENBAR
44
ld [hli], a
45
inc hl
46
ld a, [wEnemyHPBarColor]
47
add PAL_GREENBAR
48
ld [hli], a
49
inc hl
50
ld a, b
51
ld [hli], a
52
inc hl
53
ld a, c
54
ld [hl], a
55
ld hl, wPalPacket
56
ld de, BlkPacket_Battle
57
ld a, SET_PAL_BATTLE
58
ld [wDefaultPaletteCommand], a
59
ret
60
61
SetPal_TownMap:
62
ld hl, PalPacket_TownMap
63
ld de, BlkPacket_WholeScreen
64
ret
65
66
; uses PalPacket_Empty to build a packet based the mon ID
67
SetPal_StatusScreen:
68
ld hl, PalPacket_Empty
69
ld de, wPalPacket
70
ld bc, $10
71
call CopyData
72
ld a, [wCurPartySpecies]
73
cp NUM_POKEMON_INDEXES + 1
74
jr c, .pokemon
75
ld a, $1 ; not pokemon
76
.pokemon
77
call DeterminePaletteIDOutOfBattle
78
push af
79
ld hl, wPalPacket + 1
80
ld a, [wStatusScreenHPBarColor]
81
add PAL_GREENBAR
82
ld [hli], a
83
inc hl
84
pop af
85
ld [hl], a
86
ld hl, wPalPacket
87
ld de, BlkPacket_StatusScreen
88
ret
89
90
SetPal_PartyMenu:
91
ld hl, PalPacket_PartyMenu
92
ld de, wPartyMenuBlkPacket
93
ret
94
95
SetPal_Pokedex:
96
ld hl, PalPacket_Pokedex
97
ld de, wPalPacket
98
ld bc, $10
99
call CopyData
100
ld a, [wCurPartySpecies]
101
call DeterminePaletteIDOutOfBattle
102
ld hl, wPalPacket + 3
103
ld [hl], a
104
ld hl, wPalPacket
105
ld de, BlkPacket_Pokedex
106
ret
107
108
SetPal_Slots:
109
ld hl, PalPacket_Slots
110
ld de, BlkPacket_Slots
111
ret
112
113
SetPal_TitleScreen:
114
ld hl, PalPacket_Titlescreen
115
ld de, BlkPacket_Titlescreen
116
ret
117
118
; used mostly for menus and the Oak intro
119
SetPal_Generic:
120
ld hl, PalPacket_Generic
121
ld de, BlkPacket_WholeScreen
122
ret
123
124
SetPal_NidorinoIntro:
125
ld hl, PalPacket_NidorinoIntro
126
ld de, BlkPacket_NidorinoIntro
127
ret
128
129
SetPal_GameFreakIntro:
130
ld hl, PalPacket_GameFreakIntro
131
ld de, BlkPacket_GameFreakIntro
132
ld a, SET_PAL_GENERIC
133
ld [wDefaultPaletteCommand], a
134
ret
135
136
; uses PalPacket_Empty to build a packet based on the current map
137
SetPal_Overworld:
138
ld hl, PalPacket_Empty
139
ld de, wPalPacket
140
ld bc, $10
141
call CopyData
142
ld a, [wCurMapTileset]
143
cp CEMETERY
144
jr z, .PokemonTowerOrAgatha
145
cp CAVERN
146
jr z, .caveOrBruno
147
ld a, [wCurMap]
148
cp FIRST_INDOOR_MAP
149
jr c, .townOrRoute
150
cp CERULEAN_CAVE_2F
151
jr c, .normalDungeonOrBuilding
152
cp CERULEAN_CAVE_1F + 1
153
jr c, .caveOrBruno
154
cp LORELEIS_ROOM
155
jr z, .Lorelei
156
cp BRUNOS_ROOM
157
jr z, .caveOrBruno
158
.normalDungeonOrBuilding
159
ld a, [wLastMap] ; town or route that current dungeon or building is located
160
.townOrRoute
161
cp NUM_CITY_MAPS
162
jr c, .town
163
ld a, PAL_ROUTE - 1
164
.town
165
inc a ; a town's palette ID is its map ID + 1
166
ld hl, wPalPacket + 1
167
ld [hld], a
168
ld de, BlkPacket_WholeScreen
169
ld a, SET_PAL_OVERWORLD
170
ld [wDefaultPaletteCommand], a
171
ret
172
.PokemonTowerOrAgatha
173
ld a, PAL_GRAYMON - 1
174
jr .town
175
.caveOrBruno
176
ld a, PAL_CAVE - 1
177
jr .town
178
.Lorelei
179
xor a
180
jr .town
181
182
; used when a Pokemon is the only thing on the screen
183
; such as evolution, trading and the Hall of Fame
184
SetPal_PokemonWholeScreen:
185
push bc
186
ld hl, PalPacket_Empty
187
ld de, wPalPacket
188
ld bc, $10
189
call CopyData
190
pop bc
191
ld a, c
192
and a
193
ld a, PAL_BLACK
194
jr nz, .next
195
ld a, [wWholeScreenPaletteMonSpecies]
196
call DeterminePaletteIDOutOfBattle
197
.next
198
ld [wPalPacket + 1], a
199
ld hl, wPalPacket
200
ld de, BlkPacket_WholeScreen
201
ret
202
203
SetPal_TrainerCard:
204
ld hl, BlkPacket_TrainerCard
205
ld de, wTrainerCardBlkPacket
206
ld bc, $40
207
call CopyData
208
ld de, BadgeBlkDataLengths
209
ld hl, wTrainerCardBlkPacket + 2
210
ld a, [wObtainedBadges]
211
ld c, NUM_BADGES
212
.badgeLoop
213
srl a
214
push af
215
jr c, .haveBadge
216
; The player doesn't have the badge, so zero the badge's blk data.
217
push bc
218
ld a, [de]
219
ld c, a
220
xor a
221
.zeroBadgeDataLoop
222
ld [hli], a
223
dec c
224
jr nz, .zeroBadgeDataLoop
225
pop bc
226
jr .nextBadge
227
.haveBadge
228
; The player does have the badge, so skip past the badge's blk data.
229
ld a, [de]
230
.skipBadgeDataLoop
231
inc hl
232
dec a
233
jr nz, .skipBadgeDataLoop
234
.nextBadge
235
pop af
236
inc de
237
dec c
238
jr nz, .badgeLoop
239
ld hl, PalPacket_TrainerCard
240
ld de, wTrainerCardBlkPacket
241
ret
242
243
SetPalFunctions:
244
; entries correspond to SET_PAL_* constants
245
dw SetPal_BattleBlack
246
dw SetPal_Battle
247
dw SetPal_TownMap
248
dw SetPal_StatusScreen
249
dw SetPal_Pokedex
250
dw SetPal_Slots
251
dw SetPal_TitleScreen
252
dw SetPal_NidorinoIntro
253
dw SetPal_Generic
254
dw SetPal_Overworld
255
dw SetPal_PartyMenu
256
dw SetPal_PokemonWholeScreen
257
dw SetPal_GameFreakIntro
258
dw SetPal_TrainerCard
259
260
; The length of the blk data of each badge on the Trainer Card.
261
; The Rainbow Badge has 3 entries because of its many colors.
262
BadgeBlkDataLengths:
263
db 6 ; Boulder Badge
264
db 6 ; Cascade Badge
265
db 6 ; Thunder Badge
266
db 6 * 3 ; Rainbow Badge
267
db 6 ; Soul Badge
268
db 6 ; Marsh Badge
269
db 6 ; Volcano Badge
270
db 6 ; Earth Badge
271
272
DeterminePaletteID:
273
bit TRANSFORMED, a ; a is battle status 3
274
ld a, PAL_GRAYMON ; if the mon has used Transform, use Ditto's palette
275
ret nz
276
ld a, [hl]
277
DeterminePaletteIDOutOfBattle:
278
ld [wPokedexNum], a
279
and a ; is the mon index 0?
280
jr z, .skipDexNumConversion
281
push bc
282
predef IndexToPokedex
283
pop bc
284
ld a, [wPokedexNum]
285
.skipDexNumConversion
286
ld e, a
287
ld d, 0
288
ld hl, MonsterPalettes ; not just for Pokemon, Trainers use it too
289
add hl, de
290
ld a, [hl]
291
ret
292
293
InitPartyMenuBlkPacket:
294
ld hl, BlkPacket_PartyMenu
295
ld de, wPartyMenuBlkPacket
296
ld bc, $30
297
jp CopyData
298
299
UpdatePartyMenuBlkPacket:
300
; Update the blk packet with the palette of the HP bar that is
301
; specified in [wWhichPartyMenuHPBar].
302
ld hl, wPartyMenuHPBarColors
303
ld a, [wWhichPartyMenuHPBar]
304
ld e, a
305
ld d, 0
306
add hl, de
307
ld e, l
308
ld d, h
309
ld a, [de]
310
and a
311
ld e, (1 << 2) | 1 ; green
312
jr z, .next
313
dec a
314
ld e, (2 << 2) | 2 ; yellow
315
jr z, .next
316
ld e, (3 << 2) | 3 ; red
317
.next
318
push de
319
ld hl, wPartyMenuBlkPacket + 8 + 1
320
ld bc, 6
321
ld a, [wWhichPartyMenuHPBar]
322
call AddNTimes
323
pop de
324
ld [hl], e
325
ret
326
327
SendSGBPacket:
328
;check number of packets
329
ld a, [hl]
330
and $07
331
ret z
332
; store number of packets in B
333
ld b, a
334
.loop2
335
; save B for later use
336
push bc
337
; disable ReadJoypad to prevent it from interfering with sending the packet
338
ld a, 1
339
ldh [hDisableJoypadPolling], a
340
; send RESET signal (P14=LOW, P15=LOW)
341
xor a ; JOYP_SGB_START
342
ldh [rJOYP], a
343
; set P14=HIGH, P15=HIGH
344
ld a, JOYP_SGB_FINISH
345
ldh [rJOYP], a
346
;load length of packets (16 bytes)
347
ld b, 16
348
.nextByte
349
;set bit counter (8 bits per byte)
350
ld e, 8
351
; get next byte in the packet
352
ld a, [hli]
353
ld d, a
354
.nextBit0
355
bit 0, d
356
; if 0th bit is not zero set P14=HIGH, P15=LOW (send bit 1)
357
ld a, JOYP_SGB_ONE
358
jr nz, .next0
359
; else (if 0th bit is zero) set P14=LOW, P15=HIGH (send bit 0)
360
ld a, JOYP_SGB_ZERO
361
.next0
362
ldh [rJOYP], a
363
; must set P14=HIGH,P15=HIGH between each "pulse"
364
ld a, JOYP_SGB_FINISH
365
ldh [rJOYP], a
366
; rotation will put next bit in 0th position (so we can always use command
367
; "bit 0, d" to fetch the bit that has to be sent)
368
rr d
369
; decrease bit counter so we know when we have sent all 8 bits of current byte
370
dec e
371
jr nz, .nextBit0
372
dec b
373
jr nz, .nextByte
374
; send bit 0 as a "stop bit" (end of parameter data)
375
ld a, JOYP_SGB_ZERO
376
ldh [rJOYP], a
377
; set P14=HIGH,P15=HIGH
378
ld a, JOYP_SGB_FINISH
379
ldh [rJOYP], a
380
xor a
381
ldh [hDisableJoypadPolling], a
382
; wait for about 70000 cycles
383
call Wait7000
384
; restore (previously pushed) number of packets
385
pop bc
386
dec b
387
; return if there are no more packets
388
ret z
389
; else send 16 more bytes
390
jr .loop2
391
392
LoadSGB:
393
xor a
394
ld [wOnSGB], a
395
call CheckSGB
396
ret nc
397
ld a, 1
398
ld [wOnSGB], a
399
ld a, [wOnCGB]
400
and a
401
jr z, .notCGB
402
ret
403
.notCGB
404
di
405
call PrepareSuperNintendoVRAMTransfer
406
ei
407
ld a, 1
408
ld [wCopyingSGBTileData], a
409
ld de, ChrTrnPacket
410
ld hl, SGBBorderGraphics
411
call CopyGfxToSuperNintendoVRAM
412
xor a
413
ld [wCopyingSGBTileData], a
414
ld de, PctTrnPacket
415
ld hl, BorderPalettes
416
call CopyGfxToSuperNintendoVRAM
417
xor a
418
ld [wCopyingSGBTileData], a
419
ld de, PalTrnPacket
420
ld hl, SuperPalettes
421
call CopyGfxToSuperNintendoVRAM
422
call ClearVram
423
ld hl, MaskEnCancelPacket
424
jp SendSGBPacket
425
426
PrepareSuperNintendoVRAMTransfer:
427
ld hl, .packetPointers
428
ld c, 9
429
.loop
430
push bc
431
ld a, [hli]
432
push hl
433
ld h, [hl]
434
ld l, a
435
call SendSGBPacket
436
pop hl
437
inc hl
438
pop bc
439
dec c
440
jr nz, .loop
441
ret
442
443
.packetPointers
444
; Only the first packet is needed.
445
dw MaskEnFreezePacket
446
dw DataSndPacket1
447
dw DataSndPacket2
448
dw DataSndPacket3
449
dw DataSndPacket4
450
dw DataSndPacket5
451
dw DataSndPacket6
452
dw DataSndPacket7
453
dw DataSndPacket8
454
455
CheckSGB:
456
; Returns whether the game is running on an SGB in carry.
457
ld hl, MltReq2Packet
458
di
459
call SendSGBPacket
460
ld a, 1
461
ldh [hDisableJoypadPolling], a
462
ei
463
call Wait7000
464
ldh a, [rJOYP]
465
and JOYP_SGB_MLT_REQ
466
cp JOYP_SGB_MLT_REQ
467
jr nz, .isSGB
468
ld a, JOYP_SGB_ZERO
469
ldh [rJOYP], a
470
ldh a, [rJOYP]
471
ldh a, [rJOYP]
472
call Wait7000
473
call Wait7000
474
ld a, JOYP_SGB_FINISH
475
ldh [rJOYP], a
476
call Wait7000
477
call Wait7000
478
ld a, JOYP_SGB_ONE
479
ldh [rJOYP], a
480
ldh a, [rJOYP]
481
ldh a, [rJOYP]
482
ldh a, [rJOYP]
483
ldh a, [rJOYP]
484
ldh a, [rJOYP]
485
ldh a, [rJOYP]
486
call Wait7000
487
vc_hook Unknown_network_reset
488
call Wait7000
489
ld a, JOYP_SGB_FINISH
490
ldh [rJOYP], a
491
ldh a, [rJOYP]
492
ldh a, [rJOYP]
493
ldh a, [rJOYP]
494
call Wait7000
495
call Wait7000
496
ldh a, [rJOYP]
497
and JOYP_SGB_MLT_REQ
498
cp JOYP_SGB_MLT_REQ
499
jr nz, .isSGB
500
call SendMltReq1Packet
501
and a
502
ret
503
.isSGB
504
call SendMltReq1Packet
505
scf
506
ret
507
508
SendMltReq1Packet:
509
ld hl, MltReq1Packet
510
call SendSGBPacket
511
jp Wait7000
512
513
CopyGfxToSuperNintendoVRAM:
514
di
515
push de
516
call DisableLCD
517
ld a, $e4
518
ldh [rBGP], a
519
ld de, vChars1
520
ld a, [wCopyingSGBTileData]
521
and a
522
jr z, .notCopyingTileData
523
call CopySGBBorderTiles
524
jr .next
525
.notCopyingTileData
526
ld bc, 256 tiles
527
call CopyData
528
.next
529
ld hl, vBGMap0
530
ld de, TILEMAP_WIDTH - SCREEN_WIDTH
531
ld a, $80
532
ld c, (256 + SCREEN_WIDTH - 1) / SCREEN_WIDTH ; enough rows to fit 256 tiles
533
.loop
534
ld b, SCREEN_WIDTH
535
.innerLoop
536
ld [hli], a
537
inc a
538
dec b
539
jr nz, .innerLoop
540
add hl, de
541
dec c
542
jr nz, .loop
543
ld a, LCDC_DEFAULT
544
ldh [rLCDC], a
545
pop hl
546
call SendSGBPacket
547
xor a
548
ldh [rBGP], a
549
ei
550
ret
551
552
Wait7000:
553
; Each loop takes 9 cycles so this routine actually waits 63000 cycles.
554
ld de, 7000
555
.loop
556
nop
557
nop
558
nop
559
dec de
560
ld a, d
561
or e
562
jr nz, .loop
563
ret
564
565
SendSGBPackets:
566
ld a, [wOnCGB]
567
and a
568
jr z, .notCGB
569
push de
570
call InitCGBPalettes
571
pop hl
572
call EmptyFunc3
573
ret
574
.notCGB
575
push de
576
call SendSGBPacket
577
pop hl
578
jp SendSGBPacket
579
580
InitCGBPalettes:
581
ld a, $80 ; index 0 with auto-increment
582
ldh [rBGPI], a
583
inc hl
584
ld c, $20
585
.loop
586
ld a, [hli]
587
inc hl
588
add a
589
add a
590
add a
591
ld de, SuperPalettes
592
add e
593
jr nc, .noCarry
594
inc d
595
.noCarry
596
ld a, [de]
597
ldh [rBGPD], a
598
dec c
599
jr nz, .loop
600
ret
601
602
EmptyFunc3:
603
ret
604
605
CopySGBBorderTiles:
606
; SGB tile data is stored in a 4BPP planar format.
607
; Each tile is 32 bytes. The first 16 bytes contain bit planes 1 and 2, while
608
; the second 16 bytes contain bit planes 3 and 4.
609
; This function converts 2BPP planar data into this format by mapping
610
; 2BPP colors 0-3 to 4BPP colors 0-3. 4BPP colors 4-15 are not used.
611
ld b, 128
612
.tileLoop
613
; Copy bit planes 1 and 2 of the tile data.
614
ld c, 16
615
.copyLoop
616
ld a, [hli]
617
ld [de], a
618
inc de
619
dec c
620
jr nz, .copyLoop
621
622
; Zero bit planes 3 and 4.
623
ld c, 16
624
xor a
625
.zeroLoop
626
ld [de], a
627
inc de
628
dec c
629
jr nz, .zeroLoop
630
631
dec b
632
jr nz, .tileLoop
633
ret
634
635
INCLUDE "data/sgb/sgb_packets.asm"
636
637
INCLUDE "data/pokemon/palettes.asm"
638
639
INCLUDE "data/sgb/sgb_palettes.asm"
640
641
INCLUDE "data/sgb/sgb_border.asm"
642
643