summaryrefslogtreecommitdiff
path: root/engine/gfx
diff options
context:
space:
mode:
Diffstat (limited to 'engine/gfx')
-rwxr-xr-xengine/gfx/animated_objects.asm394
-rw-r--r--engine/gfx/bg_map_attributes.asm219
-rwxr-xr-xengine/gfx/palettes.asm34
-rw-r--r--engine/gfx/sprite_oam.asm2
4 files changed, 631 insertions, 18 deletions
diff --git a/engine/gfx/animated_objects.asm b/engine/gfx/animated_objects.asm
new file mode 100755
index 00000000..971af6b5
--- /dev/null
+++ b/engine/gfx/animated_objects.asm
@@ -0,0 +1,394 @@
+ClearObjectAnimationBuffers:
+ ld hl, wAnimatedObjectsData
+ ld bc, wAnimatedObjectsDataEnd - wAnimatedObjectsData
+ xor a
+ call FillMemory
+ ret
+
+RunObjectAnimations:
+ ld hl, wAnimatedObjectDataStructs
+ ld e, 10
+.loop
+ ld a, [hl]
+ and a
+ jr z, .next
+ ld c, l
+ ld b, h
+ push hl
+ push de
+ call ExecuteCurrentAnimatedObjectCallback
+ call UpdateCurrentAnimatedObjectFrame
+ pop de
+ pop hl
+ jr c, .quit
+.next
+ ld bc, $10
+ add hl, bc
+ dec e
+ jr nz, .loop
+ ld a, [wCurrentAnimatedObjectOAMBufferOffset]
+ ld l, a
+ ld h, HIGH(wOAMBuffer)
+.deinit_unused_oam_loop
+ ld a, l
+ cp LOW(wOAMBufferEnd)
+ jr nc, .quit
+ xor a
+ ld [hli], a
+ jr .deinit_unused_oam_loop
+
+.quit
+ ret
+
+SpawnAnimatedObject:
+ push de
+ push af
+ ld hl, wAnimatedObjectDataStructs
+ ld e, 10
+.loop
+ ld a, [hl]
+ and a
+ jr z, .init
+ ld bc, $10
+ add hl, bc
+ dec e
+ jr nz, .loop
+ pop af
+ pop de
+ scf
+ ret
+
+.init
+ pop af
+ ld c, l
+ ld b, h
+ ld hl, wNumLoadedAnimatedObjects
+ inc [hl]
+ ld e, a
+ ld d, $0
+ ld a, [wAnimatedObjectSpawnStateDataPointer]
+ ld l, a
+ ld a, [wAnimatedObjectSpawnStateDataPointer + 1]
+ ld h, a
+ add hl, de
+ add hl, de
+ add hl, de
+ ld e, l
+ ld d, h
+ ld hl, $0
+ add hl, bc
+ ld a, [wNumLoadedAnimatedObjects]
+ ld [hli], a
+ ld a, [de]
+ ld [hli], a
+ inc de
+ ld a, [de]
+ ld [hli], a
+ inc de
+ xor a
+ ld [hli], a
+ pop de
+ ld hl, $4
+ add hl, bc
+ ld a, e
+ ld [hli], a
+ ld a, d
+ ld [hli], a
+ xor a
+ ld [hli], a
+ ld [hli], a
+ xor a
+ ld [hli], a
+ ld [hli], a
+ dec a
+ ld [hli], a
+ xor a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ret
+
+MaskCurrentAnimatedObjectStruct:
+ ld hl, $0
+ add hl, bc
+ ld [hl], $0
+ ret
+
+MaskAllAnimatedObjectStructs:
+ ld hl, wAnimatedObjectDataStructs
+ ld e, 10
+.loop
+ ld [hl], $0
+ ld bc, $10
+ add hl, bc
+ dec e
+ jr nz, .loop
+ ret
+
+UpdateCurrentAnimatedObjectFrame:
+ xor a
+ ld [wCurAnimatedObjectOAMAttributes], a
+ ld hl, $3
+ add hl, bc
+ ld a, [hli]
+ ld [wCurrentAnimatedObjectVTileOffset], a
+ ld a, [hli]
+ ld [wCurrentAnimatedObjectXCoord], a
+ ld a, [hli]
+ ld [wCurrentAnimatedObjectYCoord], a
+ ld a, [hli]
+ ld [wCurrentAnimatedObjectXOffset], a
+ ld a, [hl]
+ ld [wCurrentAnimatedObjectYOffset], a
+ call UpdateDurationTimerAndFrameStateForCurrentAnimatedObject
+ cp $fd
+ jr z, .finish
+ cp $fc
+ jr z, .delete_animation
+ call GetCurrentAnimatedObjectOAMDataPointer
+ ld a, [wCurrentAnimatedObjectVTileOffset]
+ add [hl]
+ ld [wCurrentAnimatedObjectVTileOffset], a
+ inc hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ push bc
+ ld a, [wCurrentAnimatedObjectOAMBufferOffset]
+ ld e, a
+ ld d, HIGH(wOAMBuffer)
+ ld a, [hli]
+ ld c, a
+.loop
+ ld a, [wCurrentAnimatedObjectYCoord]
+ ld b, a
+ ld a, [wCurrentAnimatedObjectYOffset]
+ add b
+ ld b, a
+ ld a, [wAnimatedObjectGlobalYOffset]
+ add b
+ ld b, a
+ call GetCurrentAnimatedObjectTileYCoordinate
+ add b
+ ld [de], a
+ inc hl
+ inc de
+ ld a, [wCurrentAnimatedObjectXCoord]
+ ld b, a
+ ld a, [wCurrentAnimatedObjectXOffset]
+ add b
+ ld b, a
+ ld a, [wAnimatedObjectGlobalXOffset]
+ add b
+ ld b, a
+ call GetCurrentAnimatedObjectTileXCoordinate
+ add b
+ ld [de], a
+ inc hl
+ inc de
+ ld a, [wCurrentAnimatedObjectVTileOffset]
+ add [hl]
+ ld [de], a
+ inc hl
+ inc de
+ call SetCurrentAnimatedObjectOAMAttributes
+ ld b, a
+ ld a, [wc634]
+ cp $7
+ ld a, b
+ jr z, .skip_load
+ ld [de], a
+.skip_load
+ inc hl
+ inc de
+ ld a, e
+ ld [wCurrentAnimatedObjectOAMBufferOffset], a
+ cp LOW(wOAMBufferEnd)
+ jr nc, .oam_is_full
+ dec c
+ jr nz, .loop
+ pop bc
+ jr .finish
+
+.delete_animation
+ call MaskCurrentAnimatedObjectStruct
+.finish
+ and a
+ ret
+
+.oam_is_full
+ pop bc
+ scf
+ ret
+
+GetCurrentAnimatedObjectTileYCoordinate:
+ push hl
+ ld a, [hl]
+ ld hl, wCurAnimatedObjectOAMAttributes
+ bit 6, [hl]
+ jr z, .no_flip
+ add $8
+ xor $ff
+ inc a
+.no_flip
+ pop hl
+ ret
+
+GetCurrentAnimatedObjectTileXCoordinate:
+ push hl
+ ld a, [hl]
+ ld hl, wCurAnimatedObjectOAMAttributes
+ bit 5, [hl]
+ jr z, .no_flip
+ add $8
+ xor $ff
+ inc a
+.no_flip
+ pop hl
+ ret
+
+SetCurrentAnimatedObjectOAMAttributes:
+ ld a, [wCurAnimatedObjectOAMAttributes]
+ ld b, a
+ ld a, [hl]
+ xor b
+ and $e0
+ ld b, a
+ ld a, [hl]
+ and $10
+ or b
+ bit 4, a
+ ret z
+ or $4
+ ret
+
+GetCurrentAnimatedObjectOAMDataPointer:
+ ld e, a
+ ld d, $0
+ ld a, [wAnimatedObjectOAMDataPointer]
+ ld l, a
+ ld a, [wAnimatedObjectOAMDataPointer + 1]
+ ld h, a
+ add hl, de
+ add hl, de
+ add hl, de
+ ret
+
+SetCurrentAnimatedObjectCallbackAndResetFrameStateRegisters:
+ ld hl, $1
+ add hl, bc
+ ld [hl], a
+ ld hl, $8
+ add hl, bc
+ ld [hl], $0
+ ld hl, $9
+ add hl, bc
+ ld [hl], $0
+ ld hl, $a
+ add hl, bc
+ ld [hl], $ff
+ ret
+
+UpdateDurationTimerAndFrameStateForCurrentAnimatedObject:
+.loop
+ ld hl, $8
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .next_frame
+ dec [hl]
+ call GetPointerToCurrentAnimatedObjectFrameScript
+ ld a, [hli]
+ push af
+ jr .finish
+
+.next_frame
+ ld hl, $a
+ add hl, bc
+ inc [hl]
+ call GetPointerToCurrentAnimatedObjectFrameScript
+ ld a, [hli]
+ cp $fe
+ jr z, .restart_anim
+ cp $ff
+ jr z, .hold_last_frame_state
+ push af
+ ld a, [hl]
+ push hl
+ and $3f
+ ld hl, $9
+ add hl, bc
+ add [hl]
+ ld hl, $8
+ add hl, bc
+ ld [hl], a
+ pop hl
+.finish
+ ld a, [hl]
+ and $c0
+ srl a
+ ld [wCurAnimatedObjectOAMAttributes], a
+ pop af
+ ret
+
+.hold_last_frame_state
+ xor a
+ ld hl, $8
+ add hl, bc
+ ld [hl], a
+ ld hl, $a
+ add hl, bc
+ dec [hl]
+ dec [hl]
+ jr .loop
+
+.restart_anim
+ xor a
+ ld hl, $8
+ add hl, bc
+ ld [hl], a
+ dec a
+ ld hl, $a
+ add hl, bc
+ ld [hl], a
+ jr .loop
+
+GetPointerToCurrentAnimatedObjectFrameScript:
+ ld hl, $1
+ add hl, bc
+ ld e, [hl]
+ ld d, $0
+ ld a, [wAnimatedObjectFramesDataPointer]
+ ld l, a
+ ld a, [wAnimatedObjectFramesDataPointer + 1]
+ ld h, a
+ add hl, de
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, $a
+ add hl, bc
+ ld l, [hl]
+ ld h, $0
+ add hl, hl
+ add hl, de
+ ret
+
+ExecuteCurrentAnimatedObjectCallback:
+ ld hl, $2
+ add hl, bc
+ ld e, [hl]
+ ld d, $0
+ ld a, [wAnimatedObjectJumptablePointer]
+ ld l, a
+ ld a, [wAnimatedObjectJumptablePointer + 1]
+ ld h, a
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
diff --git a/engine/gfx/bg_map_attributes.asm b/engine/gfx/bg_map_attributes.asm
new file mode 100644
index 00000000..6f81af63
--- /dev/null
+++ b/engine/gfx/bg_map_attributes.asm
@@ -0,0 +1,219 @@
+INCLUDE "data/cgb/bg_map_attributes.asm"
+
+LoadBGMapAttributes::
+ ld hl, BGMapAttributesPointers
+ ld a, c ; c = which packet
+ push af ; save for later (to determine if we're handling the trainer card or party menu)
+ dec a ; read this code as:
+ add a ; dec a
+ ld e, a ; add a
+ xor a ; ld e, a
+ ld d, a ; ld d, 0
+ add hl, de ; add hl, de
+ ld a, [hli] ; ld a, [hli]
+ ld e, a ; ld h, [hl]
+ ld a, [hl] ; ld l, a
+ ld h, a
+ ld a, e
+ ld l, a
+
+ di
+ ld a, $1
+ ldh [rVBK], a
+ push hl
+ ld a, [hl]
+ ld c, a ; save attribute count for later
+ ld de, $10
+ add hl, de
+ ld a, h
+ ldh [rHDMA1], a
+ ld a, l
+ ldh [rHDMA2], a
+ ld de, vBGMap0
+ ld a, d
+ ldh [rHDMA3], a
+ ld a, e
+ ldh [rHDMA4], a
+
+ ldh a, [rLCDC]
+ and rLCDC_ENABLE_MASK ; is LCD off?
+ jr z, .lcdOff ; if off, transfer immediately
+; wait for VBlank if LCD is on
+.waitForVBlankLoop1
+ ldh a, [rLY]
+ cp $90
+ jr nz, .waitForVBlankLoop1
+.waitForAccessibleVRAMLoop1
+ ldh a, [rSTAT]
+ and %10 ; are we in HBlank or VBlank?
+ jr nz, .waitForAccessibleVRAMLoop1 ; loop until we're in a safe period to transfer to VRAM
+.lcdOff
+ ld a, c ; number of BG attributes to transfer, plus 1 times 16
+ ldh [rHDMA5], a ; initiate transfer
+ call Func_3082 ; update audio so it doesn't "lag"
+ pop hl
+ ld a, [hli]
+ ld c, a ; number of BG attributes to transfer, plus 1 times 16
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a ; offset of the attributes
+ add hl, de ; hl = new pointer
+ ld a, h
+ ldh [rHDMA1], a
+ ld a, l
+ ldh [rHDMA2], a
+ ld de, vBGMap1 ; copy to vBGMap1
+ ld a, d
+ ldh [rHDMA3], a
+ ld a, e
+ ldh [rHDMA4], a
+; LCD check again
+ ldh a, [rLCDC]
+ and rLCDC_ENABLE_MASK ; is LCD off?
+ jr z, .lcdOff2 ; if off, transfer immediately
+; wait for VBlank if LCD is on
+.waitForVBlankLoop2
+ ldh a, [rLY]
+ cp $90
+ jr nz, .waitForVBlankLoop2
+.waitForAccessibleVRAMLoop2
+ ldh a, [rSTAT]
+ and %10 ; are we in HBlank or VBlank?
+ jr nz, .waitForAccessibleVRAMLoop2 ; loop until we're in a safe period to transfer to VRAM
+.lcdOff2
+ ld a, c
+ ldh [rHDMA5], a
+ pop af
+ dec a
+ dec a
+ dec a
+ dec a
+ jr nz, .checkIfHandlingPartyMenu
+ call HandleBadgeFaceAttributes
+ jr .done
+.checkIfHandlingPartyMenu
+ dec a
+ call z, HandlePartyHPBarAttributes
+.done
+ call Func_3082
+ ldh a, [rIF]
+ res VBLANK, a
+ ldh [rIF], a
+ xor a
+ ldh [rVBK], a
+ ei
+ ret
+
+BGMapAttributesPointers:
+ dw BGMapAttributes_Unknown1
+ dw BGMapAttributes_Unknown2
+ dw BGMapAttributes_GameFreakIntro
+ dw BGMapAttributes_TrainerCard
+ dw BGMapAttributes_PartyMenu
+ dw BGMapAttributes_NidorinoIntro
+ dw BGMapAttributes_TitleScreen
+ dw BGMapAttributes_Slots
+ dw BGMapAttributes_Pokedex
+ dw BGMapAttributes_StatusScreen
+ dw BGMapAttributes_Battle
+ dw BGMapAttributes_WholeScreen
+ dw BGMapAttributes_Unknown13
+
+HandleBadgeFaceAttributes:
+; zero out the attributes if the player doesn't have the respective badge
+; BOULDERBADGE
+ ld hl, vBGMap1 + $183
+ ld de, wTrainerCardBadgeAttributes + 6 * 0
+ ld a, [de]
+ and a
+ call z, ZeroOutCurrentBadgeAttributes
+; CASCADEBADGE
+ ld hl, vBGMap1 + $187
+ ld de, wTrainerCardBadgeAttributes + 6 * 1
+ ld a, [de]
+ and a
+ call z, ZeroOutCurrentBadgeAttributes
+; THUNDERBADGE
+ ld hl, vBGMap1 + $18b
+ ld de, wTrainerCardBadgeAttributes + 6 * 2
+ ld a, [de]
+ and a
+ call z, ZeroOutCurrentBadgeAttributes
+; RAINBOWBADGE
+ ld hl, vBGMap1 + $18f
+ ld de, wTrainerCardBadgeAttributes + 6 * 3
+ ld a, [de]
+ and a
+ call z, ZeroOutCurrentBadgeAttributes
+; SOULBADGE
+ ld hl, vBGMap1 + $1e3
+ ld de, wTrainerCardBadgeAttributes + 6 * 6
+ ld a, [de]
+ and a
+ call z, ZeroOutCurrentBadgeAttributes
+; MARSHBADGE
+ ld hl, vBGMap1 + $1e7
+ ld de, wTrainerCardBadgeAttributes + 6 * 7
+ ld a, [de]
+ and a
+ call z, ZeroOutCurrentBadgeAttributes
+; VOLCANOBADGE
+ ld hl, vBGMap1 + $1eb
+ ld de, wTrainerCardBadgeAttributes + 6 * 8
+ ld a, [de]
+ and a
+ call z, ZeroOutCurrentBadgeAttributes
+; EARTHBADGE
+ ld hl, vBGMap1 + $1ef
+ ld de, wTrainerCardBadgeAttributes + 6 * 9
+ ld a, [de]
+ and a
+ call z, ZeroOutCurrentBadgeAttributes
+ ret
+
+ZeroOutCurrentBadgeAttributes:
+ push hl
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld bc, $1f
+ add hl, bc
+ ld [hli], a
+ ld [hl], a
+ pop hl
+ ret
+
+HandlePartyHPBarAttributes:
+; hp bars require 3 (green, orange, red) colours, when there are only 2 "free" colours per palette
+; therefore, we must transfer individual bg attributes where the locations of the hp bars are in vram
+ ld hl, vBGMap1 + $25 ; location of start of the HP bar in vram
+ ld de, wPartyHPBarAttributes
+ ld c, PARTY_LENGTH
+.loop
+ push bc
+ push hl
+ ld a, [de]
+ and $3 ; 4 possible palettes
+REPT 7 ; hp bar length in tiles
+ ld [hli], a
+ENDR
+ pop hl
+ ld bc, $40 ; get 2nd party location
+ add hl, bc
+ push hl
+
+ push de ; (inefficiently) copy de to hl
+ pop hl
+
+ ld bc, $6
+ add hl, bc ; get the next palette
+
+ push hl
+ pop de ; copy back to de
+
+ pop hl
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
diff --git a/engine/gfx/palettes.asm b/engine/gfx/palettes.asm
index dd723afa..c08992d3 100755
--- a/engine/gfx/palettes.asm
+++ b/engine/gfx/palettes.asm
@@ -752,7 +752,7 @@ index = 0
ld a, [hli]
inc hl
- IF index < (NUM_ACTIVE_PALS + -1)
+ IF index < NUM_ACTIVE_PALS - 1
push hl
ENDC
@@ -823,7 +823,7 @@ DMGPalToGBCPal::
ld [wLastOBP1], a
.convert
color_index = 0
- REPT NUM_COLORS
+ REPT NUM_PAL_COLORS
ld b, a
and %11
call .GetColorAddress
@@ -832,7 +832,7 @@ color_index = 0
ld a, [hl]
ld [wGBCPal + color_index * 2 + 1], a
- IF color_index < (NUM_COLORS + -1)
+ IF color_index < NUM_PAL_COLORS - 1
ld a, b
rrca
rrca
@@ -863,14 +863,14 @@ TransferCurBGPData::
ldh a, [rLCDC]
and rLCDC_ENABLE_MASK
jr nz, .lcdEnabled
- rept NUM_COLORS
- call TransferPalColorLCDDisabled
- endr
+ REPT NUM_PAL_COLORS
+ call TransferPalColorLCDDisabled
+ ENDR
jr .done
.lcdEnabled
- rept NUM_COLORS
- call TransferPalColorLCDEnabled
- endr
+ REPT NUM_PAL_COLORS
+ call TransferPalColorLCDEnabled
+ ENDR
.done
pop de
ret
@@ -887,7 +887,7 @@ BufferBGPPal::
ld de, wBGPPalsBuffer
add hl, de
ld de, wGBCPal
- ld c, PAL_SIZE
+ ld c, PALETTE_SIZE
.loop
ld a, [de]
ld [hli], a
@@ -918,7 +918,7 @@ TransferBGPPals::
ldh [rBGPI], a
ld de, rBGPD
ld hl, wBGPPalsBuffer
- ld c, 4 * PAL_SIZE
+ ld c, 4 * PALETTE_SIZE
.loop
ld a, [hli]
ld [de], a
@@ -939,14 +939,14 @@ TransferCurOBPData:
ldh a, [rLCDC]
and rLCDC_ENABLE_MASK
jr nz, .lcdEnabled
- rept NUM_COLORS
- call TransferPalColorLCDDisabled
- endr
+ REPT NUM_PAL_COLORS
+ call TransferPalColorLCDDisabled
+ ENDR
jr .done
.lcdEnabled
- rept NUM_COLORS
- call TransferPalColorLCDEnabled
- endr
+ REPT NUM_PAL_COLORS
+ call TransferPalColorLCDEnabled
+ ENDR
.done
pop de
ret
diff --git a/engine/gfx/sprite_oam.asm b/engine/gfx/sprite_oam.asm
index 01b2c412..b62d9d4b 100644
--- a/engine/gfx/sprite_oam.asm
+++ b/engine/gfx/sprite_oam.asm
@@ -153,7 +153,7 @@ PrepareOAMData::
cp c
ret nc
ld l, a
- ld h, wOAMBuffer / $100
+ ld h, HIGH(wOAMBuffer)
ld a, c
ld de, $4 ; entry size
ld b, $a0