pokered/engine/palettes.asm
Antonio Niño Díaz 9ea25bc8cd Replace deprecated mnemonics by the correct ones
The old mnemonics generate warnings with new versions of rgbds. This
patch replaces them by the correct ones.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2017-06-09 22:54:09 +01:00

641 lines
11 KiB
NASM
Executable file

_RunPaletteCommand:
call GetPredefRegisters
ld a, b
cp $ff
jr nz, .next
ld a, [wDefaultPaletteCommand] ; use default command if command ID is $ff
.next
cp UPDATE_PARTY_MENU_BLK_PACKET
jp z, UpdatePartyMenuBlkPacket
ld l, a
ld h, 0
add hl, hl
ld de, SetPalFunctions
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
ld de, SendSGBPackets
push de
jp hl
SetPal_BattleBlack:
ld hl, PalPacket_Black
ld de, BlkPacket_Battle
ret
; uses PalPacket_Empty to build a packet based on mon IDs and health color
SetPal_Battle:
ld hl, PalPacket_Empty
ld de, wPalPacket
ld bc, $10
call CopyData
ld a, [wPlayerBattleStatus3]
ld hl, wBattleMonSpecies
call DeterminePaletteID
ld b, a
ld a, [wEnemyBattleStatus3]
ld hl, wEnemyMonSpecies2
call DeterminePaletteID
ld c, a
ld hl, wPalPacket + 1
ld a, [wPlayerHPBarColor]
add PAL_GREENBAR
ld [hli], a
inc hl
ld a, [wEnemyHPBarColor]
add PAL_GREENBAR
ld [hli], a
inc hl
ld a, b
ld [hli], a
inc hl
ld a, c
ld [hl], a
ld hl, wPalPacket
ld de, BlkPacket_Battle
ld a, SET_PAL_BATTLE
ld [wDefaultPaletteCommand], a
ret
SetPal_TownMap:
ld hl, PalPacket_TownMap
ld de, BlkPacket_WholeScreen
ret
; uses PalPacket_Empty to build a packet based the mon ID
SetPal_StatusScreen:
ld hl, PalPacket_Empty
ld de, wPalPacket
ld bc, $10
call CopyData
ld a, [wcf91]
cp VICTREEBEL + 1
jr c, .pokemon
ld a, $1 ; not pokemon
.pokemon
call DeterminePaletteIDOutOfBattle
push af
ld hl, wPalPacket + 1
ld a, [wStatusScreenHPBarColor]
add PAL_GREENBAR
ld [hli], a
inc hl
pop af
ld [hl], a
ld hl, wPalPacket
ld de, BlkPacket_StatusScreen
ret
SetPal_PartyMenu:
ld hl, PalPacket_PartyMenu
ld de, wPartyMenuBlkPacket
ret
SetPal_Pokedex:
ld hl, PalPacket_Pokedex
ld de, wPalPacket
ld bc, $10
call CopyData
ld a, [wcf91]
call DeterminePaletteIDOutOfBattle
ld hl, wPalPacket + 3
ld [hl], a
ld hl, wPalPacket
ld de, BlkPacket_Pokedex
ret
SetPal_Slots:
ld hl, PalPacket_Slots
ld de, BlkPacket_Slots
ret
SetPal_TitleScreen:
ld hl, PalPacket_Titlescreen
ld de, BlkPacket_Titlescreen
ret
; used mostly for menus and the Oak intro
SetPal_Generic:
ld hl, PalPacket_Generic
ld de, BlkPacket_WholeScreen
ret
SetPal_NidorinoIntro:
ld hl, PalPacket_NidorinoIntro
ld de, BlkPacket_NidorinoIntro
ret
SetPal_GameFreakIntro:
ld hl, PalPacket_GameFreakIntro
ld de, BlkPacket_GameFreakIntro
ld a, SET_PAL_GENERIC
ld [wDefaultPaletteCommand], a
ret
; uses PalPacket_Empty to build a packet based on the current map
SetPal_Overworld:
ld hl, PalPacket_Empty
ld de, wPalPacket
ld bc, $10
call CopyData
ld a, [wCurMapTileset]
cp CEMETERY
jr z, .PokemonTowerOrAgatha
cp CAVERN
jr z, .caveOrBruno
ld a, [wCurMap]
cp REDS_HOUSE_1F
jr c, .townOrRoute
cp UNKNOWN_DUNGEON_2
jr c, .normalDungeonOrBuilding
cp NAME_RATERS_HOUSE
jr c, .caveOrBruno
cp LORELEIS_ROOM
jr z, .Lorelei
cp BRUNOS_ROOM
jr z, .caveOrBruno
.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 palette ID is its map ID + 1
ld hl, wPalPacket + 1
ld [hld], a
ld de, BlkPacket_WholeScreen
ld a, SET_PAL_OVERWORLD
ld [wDefaultPaletteCommand], a
ret
.PokemonTowerOrAgatha
ld a, PAL_GREYMON - 1
jr .town
.caveOrBruno
ld a, PAL_CAVE - 1
jr .town
.Lorelei
xor a
jr .town
; used when a Pokemon is the only thing on the screen
; such as evolution, trading and the Hall of Fame
SetPal_PokemonWholeScreen:
push bc
ld hl, PalPacket_Empty
ld de, wPalPacket
ld bc, $10
call CopyData
pop bc
ld a, c
and a
ld a, PAL_BLACK
jr nz, .next
ld a, [wWholeScreenPaletteMonSpecies]
call DeterminePaletteIDOutOfBattle
.next
ld [wPalPacket + 1], a
ld hl, wPalPacket
ld de, BlkPacket_WholeScreen
ret
SetPal_TrainerCard:
ld hl, BlkPacket_TrainerCard
ld de, wTrainerCardBlkPacket
ld bc, $40
call CopyData
ld de, BadgeBlkDataLengths
ld hl, wTrainerCardBlkPacket + 2
ld a, [wObtainedBadges]
ld c, 8
.badgeLoop
srl a
push af
jr c, .haveBadge
; The player doens't have the badge, so zero the badge's blk data.
push bc
ld a, [de]
ld c, a
xor a
.zeroBadgeDataLoop
ld [hli], a
dec c
jr nz, .zeroBadgeDataLoop
pop bc
jr .nextBadge
.haveBadge
; The player does have the badge, so skip past the badge's blk data.
ld a, [de]
.skipBadgeDataLoop
inc hl
dec a
jr nz, .skipBadgeDataLoop
.nextBadge
pop af
inc de
dec c
jr nz, .badgeLoop
ld hl, PalPacket_TrainerCard
ld de, wTrainerCardBlkPacket
ret
SetPalFunctions:
dw SetPal_BattleBlack
dw SetPal_Battle
dw SetPal_TownMap
dw SetPal_StatusScreen
dw SetPal_Pokedex
dw SetPal_Slots
dw SetPal_TitleScreen
dw SetPal_NidorinoIntro
dw SetPal_Generic
dw SetPal_Overworld
dw SetPal_PartyMenu
dw SetPal_PokemonWholeScreen
dw SetPal_GameFreakIntro
dw SetPal_TrainerCard
; The length of the blk data of each badge on the Trainer Card.
; The Rainbow Badge has 3 entries because of its many colors.
BadgeBlkDataLengths:
db 6 ; Boulder Badge
db 6 ; Cascade Badge
db 6 ; Thunder Badge
db 6 * 3 ; Rainbow Badge
db 6 ; Soul Badge
db 6 ; Marsh Badge
db 6 ; Volcano Badge
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
and a ; is the mon index 0?
jr z, .skipDexNumConversion
push bc
predef IndexToPokedex
pop bc
ld a, [wd11e]
.skipDexNumConversion
ld e, a
ld d, 0
ld hl, MonsterPalettes ; not just for Pokemon, Trainers use it too
add hl, de
ld a, [hl]
ret
InitPartyMenuBlkPacket:
ld hl, BlkPacket_PartyMenu
ld de, wPartyMenuBlkPacket
ld bc, $30
jp CopyData
UpdatePartyMenuBlkPacket:
; Update the blk packet with the palette of the HP bar that is
; specified in [wWhichPartyMenuHPBar].
ld hl, wPartyMenuHPBarColors
ld a, [wWhichPartyMenuHPBar]
ld e, a
ld d, 0
add hl, de
ld e, l
ld d, h
ld a, [de]
and a
ld e, (1 << 2) | 1 ; green
jr z, .next
dec a
ld e, (2 << 2) | 2 ; yellow
jr z, .next
ld e, (3 << 2) | 3 ; red
.next
push de
ld hl, wPartyMenuBlkPacket + 8 + 1
ld bc, 6
ld a, [wWhichPartyMenuHPBar]
call AddNTimes
pop de
ld [hl], e
ret
SendSGBPacket:
;check number of packets
ld a,[hl]
and a,$07
ret z
; store number of packets in B
ld b,a
.loop2
; save B for later use
push bc
; disable ReadJoypad to prevent it from interfering with sending the packet
ld a, 1
ld [hDisableJoypadPolling], a
; send RESET signal (P14=LOW, P15=LOW)
xor a
ld [rJOYP],a
; set P14=HIGH, P15=HIGH
ld a,$30
ld [rJOYP],a
;load length of packets (16 bytes)
ld b,$10
.nextByte
;set bit counter (8 bits per byte)
ld e,$08
; get next byte in the packet
ld a,[hli]
ld d,a
.nextBit0
bit 0,d
; if 0th bit is not zero set P14=HIGH,P15=LOW (send bit 1)
ld a,$10
jr nz,.next0
; else (if 0th bit is zero) set P14=LOW,P15=HIGH (send bit 0)
ld a,$20
.next0
ld [rJOYP],a
; must set P14=HIGH,P15=HIGH between each "pulse"
ld a,$30
ld [rJOYP],a
; rotation will put next bit in 0th position (so we can always use command
; "bit 0,d" to fetch the bit that has to be sent)
rr d
; decrease bit counter so we know when we have sent all 8 bits of current byte
dec e
jr nz,.nextBit0
dec b
jr nz,.nextByte
; send bit 1 as a "stop bit" (end of parameter data)
ld a,$20
ld [rJOYP],a
; set P14=HIGH,P15=HIGH
ld a,$30
ld [rJOYP],a
xor a
ld [hDisableJoypadPolling],a
; wait for about 70000 cycles
call Wait7000
; restore (previously pushed) number of packets
pop bc
dec b
; return if there are no more packets
ret z
; else send 16 more bytes
jr .loop2
LoadSGB:
xor a
ld [wOnSGB], a
call CheckSGB
ret nc
ld a, 1
ld [wOnSGB], a
ld a, [wGBC]
and a
jr z, .notGBC
ret
.notGBC
di
call PrepareSuperNintendoVRAMTransfer
ei
ld a, 1
ld [wCopyingSGBTileData], a
ld de, ChrTrnPacket
ld hl, SGBBorderGraphics
call CopyGfxToSuperNintendoVRAM
xor a
ld [wCopyingSGBTileData], a
ld de, PctTrnPacket
ld hl, BorderPalettes
call CopyGfxToSuperNintendoVRAM
xor a
ld [wCopyingSGBTileData], a
ld de, PalTrnPacket
ld hl, SuperPalettes
call CopyGfxToSuperNintendoVRAM
call ClearVram
ld hl, MaskEnCancelPacket
jp SendSGBPacket
PrepareSuperNintendoVRAMTransfer:
ld hl, .packetPointers
ld c, 9
.loop
push bc
ld a, [hli]
push hl
ld h, [hl]
ld l, a
call SendSGBPacket
pop hl
inc hl
pop bc
dec c
jr nz, .loop
ret
.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
CheckSGB:
; Returns whether the game is running on an SGB in carry.
ld hl, MltReq2Packet
di
call SendSGBPacket
ld a, 1
ld [hDisableJoypadPolling], a
ei
call Wait7000
ld a, [rJOYP]
and $3
cp $3
jr nz, .isSGB
ld a, $20
ld [rJOYP], a
ld a, [rJOYP]
ld a, [rJOYP]
call Wait7000
call Wait7000
ld a, $30
ld [rJOYP], a
call Wait7000
call Wait7000
ld a, $10
ld [rJOYP], a
ld a, [rJOYP]
ld a, [rJOYP]
ld a, [rJOYP]
ld a, [rJOYP]
ld a, [rJOYP]
ld a, [rJOYP]
call Wait7000
call Wait7000
ld a, $30
ld [rJOYP], a
ld a, [rJOYP]
ld a, [rJOYP]
ld a, [rJOYP]
call Wait7000
call Wait7000
ld a, [rJOYP]
and $3
cp $3
jr nz, .isSGB
call SendMltReq1Packet
and a
ret
.isSGB
call SendMltReq1Packet
scf
ret
SendMltReq1Packet:
ld hl, MltReq1Packet
call SendSGBPacket
jp Wait7000
CopyGfxToSuperNintendoVRAM:
di
push de
call DisableLCD
ld a, $e4
ld [rBGP], a
ld de, vChars1
ld a, [wCopyingSGBTileData]
and a
jr z, .notCopyingTileData
call CopySGBBorderTiles
jr .next
.notCopyingTileData
ld bc, $1000
call CopyData
.next
ld hl, vBGMap0
ld de, $c
ld a, $80
ld c, $d
.loop
ld b, $14
.innerLoop
ld [hli], a
inc a
dec b
jr nz, .innerLoop
add hl, de
dec c
jr nz, .loop
ld a, $e3
ld [rLCDC], a
pop hl
call SendSGBPacket
xor a
ld [rBGP], a
ei
ret
Wait7000:
; Each loop takes 9 cycles so this routine actually waits 63000 cycles.
ld de, 7000
.loop
nop
nop
nop
dec de
ld a, d
or e
jr nz, .loop
ret
SendSGBPackets:
ld a, [wGBC]
and a
jr z, .notGBC
push de
call InitGBCPalettes
pop hl
call EmptyFunc5
ret
.notGBC
push de
call SendSGBPacket
pop hl
jp SendSGBPacket
InitGBCPalettes:
ld a, $80 ; index 0 with auto-increment
ld [rBGPI], a
inc hl
ld c, $20
.loop
ld a, [hli]
inc hl
add a
add a
add a
ld de, SuperPalettes
add e
jr nc, .noCarry
inc d
.noCarry
ld a, [de]
ld [rBGPD], a
dec c
jr nz, .loop
ret
EmptyFunc5:
ret
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
; the second 16 bytes contain bit planes 3 and 4.
; This function converts 2BPP planar data into this format by mapping
; 2BPP colors 0-3 to 4BPP colors 0-3. 4BPP colors 4-15 are not used.
ld b, 128
.tileLoop
; Copy bit planes 1 and 2 of the tile data.
ld c, 16
.copyLoop
ld a, [hli]
ld [de], a
inc de
dec c
jr nz, .copyLoop
; Zero bit planes 3 and 4.
ld c, 16
xor a
.zeroLoop
ld [de], a
inc de
dec c
jr nz, .zeroLoop
dec b
jr nz, .tileLoop
ret
INCLUDE "data/sgb_packets.asm"
INCLUDE "data/mon_palettes.asm"
INCLUDE "data/super_palettes.asm"
INCLUDE "data/sgb_border.asm"