summaryrefslogtreecommitdiff
path: root/engine/gfx/palettes.asm
diff options
context:
space:
mode:
Diffstat (limited to 'engine/gfx/palettes.asm')
-rw-r--r--engine/gfx/palettes.asm561
1 files changed, 518 insertions, 43 deletions
diff --git a/engine/gfx/palettes.asm b/engine/gfx/palettes.asm
index a43c66ba..b480c6d0 100644
--- a/engine/gfx/palettes.asm
+++ b/engine/gfx/palettes.asm
@@ -30,11 +30,17 @@ SetPal_Battle:
ld de, wPalPacket
ld bc, $10
call CopyData
- ld a, [wPlayerBattleStatus3]
ld hl, wBattleMonSpecies
+ ld a, [hl]
+ and a
+ jr z, .asm_71ef9
+ ld hl, wPartyMon1
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+.asm_71ef9
call DeterminePaletteID
ld b, a
- ld a, [wEnemyBattleStatus3]
ld hl, wEnemyMonSpecies2
call DeterminePaletteID
ld c, a
@@ -155,6 +161,10 @@ SetPal_Overworld:
jr z, .Lorelei
cp BRUNOS_ROOM
jr z, .caveOrBruno
+ cp TRADE_CENTER
+ jr z, .trade_center_colosseum
+ cp COLOSSEUM
+ jr z, .trade_center_colosseum
.normalDungeonOrBuilding
ld a, [wLastMap] ; town or route that current dungeon or building is located
.townOrRoute
@@ -178,6 +188,9 @@ SetPal_Overworld:
.Lorelei
xor a
jr .town
+.trade_center_colosseum
+ ld a, PAL_GREYMON - 1
+ jr .town
; used when a Pokemon is the only thing on the screen
; such as evolution, trading and the Hall of Fame
@@ -240,6 +253,16 @@ SetPal_TrainerCard:
ld de, wTrainerCardBlkPacket
ret
+SendUnknownPalPacket_7205d::
+ ld hl, UnknownPalPacket_72811
+ ld de, BlkPacket_WholeScreen
+ ret
+
+SendUnknownPalPacket_72064::
+ ld hl, UnknownPalPacket_72821
+ ld de, UnknownPacket_72751
+ ret
+
SetPalFunctions:
; entries correspond to SET_PAL_* constants
dw SetPal_BattleBlack
@@ -256,6 +279,8 @@ SetPalFunctions:
dw SetPal_PokemonWholeScreen
dw SetPal_GameFreakIntro
dw SetPal_TrainerCard
+ dw SendUnknownPalPacket_7205d
+ dw SendUnknownPalPacket_72064
; The length of the blk data of each badge on the Trainer Card.
; The Rainbow Badge has 3 entries because of its many colors.
@@ -270,9 +295,6 @@ BadgeBlkDataLengths:
db 6 ; Earth Badge
DeterminePaletteID:
- bit TRANSFORMED, a ; a is battle status 3
- ld a, PAL_GREYMON ; if the mon has used Transform, use Ditto's palette
- ret nz
ld a, [hl]
DeterminePaletteIDOutOfBattle:
ld [wd11e], a
@@ -290,6 +312,132 @@ DeterminePaletteIDOutOfBattle:
ld a, [hl]
ret
+YellowIntroPaletteAction::
+ ld a, e
+ and a
+ jr nz, .asm_720bd
+ ld hl, PalPacket_Generic
+ ldh a, [hGBC]
+ and a
+ jp z, SendSGBPacket
+ jp InitGBCPalettes
+
+.asm_720bd
+ ld hl, UnknownPalPacket_72811
+ ldh a, [hGBC]
+ and a
+ jp z, SendSGBPacket
+ call InitGBCPalettes
+ ld hl, PalPacket_Generic
+ inc hl
+ ld a, [hli]
+ call GetGBCBasePalAddress
+ ld a, e
+ ld [wGBCBasePalPointers + 2], a
+ ld a, d
+ ld [wGBCBasePalPointers + 2 + 1], a
+ xor a ; CONVERT_BGP
+ call DMGPalToGBCPal
+ ld a, 1
+ call TransferCurBGPData
+ ret
+
+LoadOverworldPikachuFrontpicPalettes::
+ ld hl, PalPacket_Empty
+ ld de, wPalPacket
+ ld bc, $10
+ call CopyData
+ call GetPal_Pikachu
+ ld hl, wPartyMenuBlkPacket
+ ld [hl], a
+ ld hl, wPartyMenuBlkPacket + 2
+ ld a, $26
+ ld [hl], a
+ ld hl, wPalPacket
+ ldh a, [hGBC]
+ and a
+ jr nz, .cgb_1
+ call SendSGBPacket
+ jr .okay_1
+
+.cgb_1
+ call InitGBCPalettes
+.okay_1
+ ld hl, BlkPacket_WholeScreen
+ ld de, wPalPacket
+ ld bc, $10
+ call CopyData
+ ld hl, wPartyMenuBlkPacket + 2
+ ld a, $5
+ ld [hli], a
+ ld a, $7
+ ld [hli], a
+ ld a, $6
+ ld [hli], a
+ ld a, $b
+ ld [hli], a
+ ld a, $a
+ ld [hl], a
+ ld hl, wPalPacket
+ ldh a, [hGBC]
+ and a
+ jr nz, .cgb_2
+ call SendSGBPacket
+ jr .okay_2
+
+.cgb_2
+ call InitGBCPalettes
+.okay_2
+ ret
+
+GetPal_Pikachu::
+; similar to SetPal_Overworld
+ ld a, [wCurMapTileset]
+ cp CEMETERY
+ jr z, .PokemonTowerOrAgatha
+ cp CAVERN
+ jr z, .caveOrBruno
+ ld a, [wCurMap]
+ cp REDS_HOUSE_1F
+ jr c, .townOrRoute
+ cp CERULEAN_CAVE_2F
+ jr c, .normalDungeonOrBuilding
+ cp NAME_RATERS_HOUSE
+ jr c, .caveOrBruno
+ cp LORELEIS_ROOM
+ jr z, .Lorelei
+ cp BRUNOS_ROOM
+ jr z, .caveOrBruno
+ cp TRADE_CENTER
+ jr z, .battleOrTradeCenter
+ cp COLOSSEUM
+ jr z, .battleOrTradeCenter
+.normalDungeonOrBuilding
+ ld a, [wLastMap] ; town or route that current dungeon or building is located
+.townOrRoute
+ cp SAFFRON_CITY + 1
+ jr c, .town
+ ld a, PAL_ROUTE - 1
+.town
+ inc a ; a town's pallete ID is its map ID + 1
+ ret
+
+.PokemonTowerOrAgatha
+ ld a, PAL_GREYMON - 1
+ jr .town
+
+.caveOrBruno
+ ld a, PAL_CAVE - 1
+ jr .town
+
+.Lorelei
+ xor a ; PAL_PALLET - 1
+ jr .town
+
+.battleOrTradeCenter
+ ld a, PAL_GREYMON - 1
+ jr .town
+
InitPartyMenuBlkPacket:
ld hl, BlkPacket_PartyMenu
ld de, wPartyMenuBlkPacket
@@ -325,6 +473,14 @@ UpdatePartyMenuBlkPacket:
ret
SendSGBPacket:
+ ld a, 1
+ ldh [hDisableJoypadPolling], a ; don't poll joypad while sending packet
+ call _SendSGBPacket
+ xor a
+ ldh [hDisableJoypadPolling], a
+ ret
+
+_SendSGBPacket:
;check number of packets
ld a, [hl]
and $07
@@ -334,9 +490,6 @@ SendSGBPacket:
.loop2
; save B for later use
push bc
-; disable ReadJoypad to prevent it from interfering with sending the packet
- ld a, 1
- ldh [hDisableJoypadPolling], a
; send RESET signal (P14=LOW, P15=LOW)
xor a
ldh [rJOYP], a
@@ -377,8 +530,6 @@ SendSGBPacket:
; set P14=HIGH,P15=HIGH
ld a, $30
ldh [rJOYP], a
- xor a
- ldh [hDisableJoypadPolling], a
; wait for about 70000 cycles
call Wait7000
; restore (previously pushed) number of packets
@@ -393,14 +544,17 @@ LoadSGB:
xor a
ld [wOnSGB], a
call CheckSGB
- ret nc
- ld a, 1
- ld [wOnSGB], a
- ld a, [wGBC]
+ jr c, .onSGB
+ ldh a, [hGBC]
and a
- jr z, .notGBC
+ jr z, .onDMG
+ ld a, $1
+ ld [wOnSGB], a
+.onDMG
ret
-.notGBC
+.onSGB
+ ld a, $1
+ ld [wOnSGB], a
di
call PrepareSuperNintendoVRAMTransfer
ei
@@ -443,23 +597,19 @@ PrepareSuperNintendoVRAMTransfer:
.packetPointers
; Only the first packet is needed.
dw MaskEnFreezePacket
- dw DataSnd_72548
- dw DataSnd_72558
- dw DataSnd_72568
- dw DataSnd_72578
- dw DataSnd_72588
- dw DataSnd_72598
- dw DataSnd_725a8
- dw DataSnd_725b8
+ dw DataSnd_728a1
+ dw DataSnd_728b1
+ dw DataSnd_728c1
+ dw DataSnd_728d1
+ dw DataSnd_728e1
+ dw DataSnd_728f1
+ dw DataSnd_72901
+ dw DataSnd_72911
CheckSGB:
; Returns whether the game is running on an SGB in carry.
ld hl, MltReq2Packet
- di
call SendSGBPacket
- ld a, 1
- ldh [hDisableJoypadPolling], a
- ei
call Wait7000
ldh a, [rJOYP]
and $3
@@ -515,6 +665,7 @@ CopyGfxToSuperNintendoVRAM:
call DisableLCD
ld a, $e4
ldh [rBGP], a
+ call _UpdateGBCPal_BGP_CheckDMG
ld de, vChars1
ld a, [wCopyingSGBTileData]
and a
@@ -545,6 +696,7 @@ CopyGfxToSuperNintendoVRAM:
call SendSGBPacket
xor a
ldh [rBGP], a
+ call _UpdateGBCPal_BGP_CheckDMG
ei
ret
@@ -562,13 +714,17 @@ Wait7000:
ret
SendSGBPackets:
- ld a, [wGBC]
+ ldh a, [hGBC]
and a
jr z, .notGBC
push de
call InitGBCPalettes
pop hl
- call EmptyFunc3
+ call InitGBCPalettes
+ ldh a, [rLCDC]
+ and rLCDC_ENABLE_MASK
+ ret z
+ call Delay3
ret
.notGBC
push de
@@ -577,30 +733,349 @@ SendSGBPackets:
jp SendSGBPacket
InitGBCPalettes:
- ld a, $80 ; index 0 with auto-increment
- ldh [rBGPI], a
- inc hl
- ld c, $20
-.loop
- ld a, [hli]
+ ld a, [hl]
+ and $f8
+ cp $20
+ jp z, TranslatePalPacketToBGMapAttributes
+
inc hl
+
+index = 0
+
+ REPT NUM_ACTIVE_PALS
+ IF index > 0
+ pop hl
+ ENDC
+
+ ld a, [hli]
+ inc hl
+
+ IF index < NUM_ACTIVE_PALS - 1
+ push hl
+ ENDC
+
+ call GetGBCBasePalAddress
+ ld a, e
+ ld [wGBCBasePalPointers + index * 2], a
+ ld a, d
+ ld [wGBCBasePalPointers + index * 2 + 1], a
+
+ xor a ; CONVERT_BGP
+ call DMGPalToGBCPal
+ ld a, index
+ call TransferCurBGPData
+
+ ld a, CONVERT_OBP0
+ call DMGPalToGBCPal
+ ld a, index
+ call TransferCurOBPData
+
+ ld a, CONVERT_OBP1
+ call DMGPalToGBCPal
+ ld a, index + 4
+ call TransferCurOBPData
+
+index = index + 1
+ ENDR
+
+ ret
+
+GetGBCBasePalAddress::
+; Input: a = palette ID
+; Output: de = palette address
+ push hl
+ ld l, a
+ xor a
+ ld h, a
+ add hl, hl
+ add hl, hl
+ add hl, hl
+ ld de, GBCBasePalettes
+ add hl, de
+ ld a, l
+ ld e, a
+ ld a, h
+ ld d, a
+ pop hl
+ ret
+
+DMGPalToGBCPal::
+; Populate wGBCPal with colors from a base palette, selected using one of the
+; DMG palette registers.
+; Input:
+; a = which DMG palette register
+; de = address of GBC base palette
+ and a
+ jr nz, .notBGP
+ ldh a, [rBGP]
+ ld [wLastBGP], a
+ jr .convert
+.notBGP
+ dec a
+ jr nz, .notOBP0
+ ldh a, [rOBP0]
+ ld [wLastOBP0], a
+ jr .convert
+.notOBP0
+ ldh a, [rOBP1]
+ ld [wLastOBP1], a
+.convert
+color_index = 0
+ REPT NUM_PAL_COLORS
+ ld b, a
+ and %11
+ call .GetColorAddress
+ ld a, [hli]
+ ld [wGBCPal + color_index * 2], a
+ ld a, [hl]
+ ld [wGBCPal + color_index * 2 + 1], a
+
+ IF color_index < NUM_PAL_COLORS - 1
+ ld a, b
+ rrca
+ rrca
+ ENDC
+
+color_index = color_index + 1
+ ENDR
+ ret
+
+.GetColorAddress:
add a
+ ld l, a
+ xor a
+ ld h, a
+ add hl, de
+ ret
+
+TransferCurBGPData::
+ push de
+ add a
+ add a
+ add a
+ or $80 ; auto-increment
+ ldh [rBGPI], a
+ ld de, rBGPD
+ ld hl, wGBCPal
+ ld b, %10 ; mask for non-V-blank/non-H-blank STAT mode
+ ldh a, [rLCDC]
+ and rLCDC_ENABLE_MASK
+ jr nz, .lcdEnabled
+ REPT NUM_PAL_COLORS
+ call TransferPalColorLCDDisabled
+ ENDR
+ jr .done
+.lcdEnabled
+ REPT NUM_PAL_COLORS
+ call TransferPalColorLCDEnabled
+ ENDR
+.done
+ pop de
+ ret
+
+BufferBGPPal::
+; Copy wGBCPal to palette a in wBGPPalsBuffer.
+ push de
add a
add a
- ld de, SuperPalettes
- add e
- jr nc, .noCarry
- inc d
-.noCarry
+ add a
+ ld l, a
+ xor a
+ ld h, a
+ ld de, wBGPPalsBuffer
+ add hl, de
+ ld de, wGBCPal
+ ld c, PALETTE_SIZE
+.loop
ld a, [de]
- ldh [rBGPD], a
+ ld [hli], a
+ inc de
dec c
jr nz, .loop
+ pop de
ret
-EmptyFunc3:
+TransferBGPPals::
+; Transfer the buffered BG palettes.
+ ldh a, [rLCDC]
+ and rLCDC_ENABLE_MASK
+ jr z, .lcdDisabled
+ di
+.waitLoop
+ ldh a, [rLY]
+ cp 144
+ jr c, .waitLoop
+.lcdDisabled
+ call .DoTransfer
+ ei
ret
+.DoTransfer:
+ xor a
+ or $80 ; auto-increment
+ ldh [rBGPI], a
+ ld de, rBGPD
+ ld hl, wBGPPalsBuffer
+ ld c, 4 * PALETTE_SIZE
+.loop
+ ld a, [hli]
+ ld [de], a
+ dec c
+ jr nz, .loop
+ ret
+
+TransferCurOBPData:
+ push de
+ add a
+ add a
+ add a
+ or $80 ; auto-increment
+ ldh [rOBPI], a
+ ld de, rOBPD
+ ld hl, wGBCPal
+ ld b, %10 ; mask for non-V-blank/non-H-blank STAT mode
+ ldh a, [rLCDC]
+ and rLCDC_ENABLE_MASK
+ jr nz, .lcdEnabled
+ REPT NUM_PAL_COLORS
+ call TransferPalColorLCDDisabled
+ ENDR
+ jr .done
+.lcdEnabled
+ REPT NUM_PAL_COLORS
+ call TransferPalColorLCDEnabled
+ ENDR
+.done
+ pop de
+ ret
+
+TransferPalColorLCDEnabled:
+; Transfer a palette color while the LCD is enabled.
+
+; In case we're already in H-blank or V-blank, wait for it to end. This is a
+; precaution so that the transfer doesn't extend past the blanking period.
+ ldh a, [rSTAT]
+ and b
+ jr z, TransferPalColorLCDEnabled
+
+; Wait for H-blank or V-blank to begin.
+.notInBlankingPeriod
+ ldh a, [rSTAT]
+ and b
+ jr nz, .notInBlankingPeriod
+; fall through
+
+TransferPalColorLCDDisabled:
+; Transfer a palette color while the LCD is disabled.
+ ld a, [hli]
+ ld [de], a
+ ld a, [hli]
+ ld [de], a
+ ret
+
+_UpdateGBCPal_BGP_CheckDMG::
+ ldh a, [hGBC]
+ and a
+ ret z
+; fall through
+
+_UpdateGBCPal_BGP::
+index = 0
+
+ REPT NUM_ACTIVE_PALS
+ ld a, [wGBCBasePalPointers + index * 2]
+ ld e, a
+ ld a, [wGBCBasePalPointers + index * 2 + 1]
+ ld d, a
+ xor a ; CONVERT_BGP
+ call DMGPalToGBCPal
+ ld a, index
+ call BufferBGPPal
+
+index = index + 1
+ ENDR
+
+ call TransferBGPPals
+ ret
+
+_UpdateGBCPal_OBP::
+index = 0
+
+ REPT NUM_ACTIVE_PALS
+ ld a, [wGBCBasePalPointers + index * 2]
+ ld e, a
+ ld a, [wGBCBasePalPointers + index * 2 + 1]
+ ld d, a
+ ld a, c
+ call DMGPalToGBCPal
+ ld a, c
+ dec a
+ rlca
+ rlca
+
+ IF index > 0
+ IF index == 1
+ inc a
+ ELSE
+ add index
+ ENDC
+ ENDC
+
+ call TransferCurOBPData
+
+index = index + 1
+ ENDR
+
+ ret
+
+TranslatePalPacketToBGMapAttributes::
+; translate the SGB pal packets into something usable for the GBC
+ push hl
+ pop de
+ ld hl, PalPacketPointers
+ ld a, [hli]
+ ld c, a
+.loop
+ ld a, e
+.innerLoop
+ cp [hl]
+ jr z, .checkHighByte
+ inc hl
+ inc hl
+ dec c
+ jr nz, .innerLoop
+ ret
+.checkHighByte
+; the low byte of pointer matched, so check the high byte
+ inc hl
+ ld a, d
+ cp [hl]
+ jr z, .foundMatchingPointer
+ inc hl
+ dec c
+ jr nz, .loop
+ ret
+.foundMatchingPointer
+ farcall LoadBGMapAttributes
+ ret
+
+PalPacketPointers::
+ db (palPacketPointersEnd - palPacketPointers) / 2
+palPacketPointers:
+ dw BlkPacket_WholeScreen
+ dw BlkPacket_Battle
+ dw BlkPacket_StatusScreen
+ dw BlkPacket_Pokedex
+ dw BlkPacket_Slots
+ dw BlkPacket_Titlescreen
+ dw BlkPacket_NidorinoIntro
+ dw wPartyMenuBlkPacket
+ dw wTrainerCardBlkPacket
+ dw BlkPacket_GameFreakIntro
+ dw wPalPacket
+ dw UnknownPacket_72751
+palPacketPointersEnd:
+
CopySGBBorderTiles:
; SGB tile data is stored in a 4BPP planar format.
; Each tile is 32 bytes. The first 16 bytes contain bit planes 1 and 2, while