pokeyellow/home/vcopy.asm
dannye 324ae167d1
Some checks failed
CI / build (push) Has been cancelled
Merge branch 'master' of https://github.com/pret/pokered
2025-11-12 17:56:10 -06:00

424 lines
7.3 KiB
NASM

; this function seems to be used only once
; it store the address of a row and column of the VRAM background map in hl
; INPUT: h - row, l - column, b - high byte of background tile map address in VRAM
GetRowColAddressBgMap::
xor a
srl h
rr a
srl h
rr a
srl h
rr a
or l
ld l, a
ld a, b
or h
ld h, a
ret
; clears a VRAM background map with blank space tiles
; INPUT: h - high byte of background tile map address in VRAM
ClearBgMap::
ld a, ' '
jr .next
ld a, l
.next
ld de, TILEMAP_AREA
ld l, e
.loop
ld [hli], a
dec e
jr nz, .loop
dec d
jr nz, .loop
ret
; This function redraws a BG row of height 2 or a BG column of width 2.
; One of its main uses is redrawing the row or column that will be exposed upon
; scrolling the BG when the player takes a step. Redrawing only the exposed
; row or column is more efficient than redrawing the entire screen.
; However, this function is also called repeatedly to redraw the whole screen
; when necessary. It is also used in trade animation and elevator code.
RedrawRowOrColumn::
ldh a, [hRedrawRowOrColumnMode]
and a
ret z
ld b, a
xor a
ldh [hRedrawRowOrColumnMode], a
dec b
jr nz, .redrawRow
.redrawColumn
ld hl, wRedrawRowOrColumnSrcTiles
ldh a, [hRedrawRowOrColumnDest]
ld e, a
ldh a, [hRedrawRowOrColumnDest + 1]
ld d, a
ld c, SCREEN_HEIGHT
.loop1
ld a, [hli]
ld [de], a
inc de
ld a, [hli]
ld [de], a
ld a, TILEMAP_WIDTH - 1
add e
ld e, a
jr nc, .noCarry
inc d
.noCarry
; the following 4 lines wrap us from bottom to top if necessary
ld a, d
and $3
or $98
ld d, a
dec c
jr nz, .loop1
xor a
ldh [hRedrawRowOrColumnMode], a
ret
.redrawRow
ld hl, wRedrawRowOrColumnSrcTiles
ldh a, [hRedrawRowOrColumnDest]
ld e, a
ldh a, [hRedrawRowOrColumnDest + 1]
ld d, a
push de
call .DrawHalf ; draw upper half
pop de
ld a, TILEMAP_WIDTH ; width of VRAM background map
add e
ld e, a
; fall through and draw lower half
.DrawHalf
ld c, SCREEN_WIDTH / 2
.loop2
ld a, [hli]
ld [de], a
inc de
ld a, [hli]
ld [de], a
ld a, e
inc a
; the following 6 lines wrap us from the right edge to the left edge if necessary
and $1f
ld b, a
ld a, e
and $e0
or b
ld e, a
dec c
jr nz, .loop2
ret
; This function automatically transfers tile number data from the tile map at
; wTileMap to VRAM during V-blank. Note that it only transfers one third of the
; background per V-blank. It cycles through which third it draws.
; This transfer is turned off when walking around the map, but is turned
; on when talking to sprites, battling, using menus, etc. This is because
; the above function, RedrawRowOrColumn, is used when walking to
; improve efficiency.
AutoBgMapTransfer::
ldh a, [hAutoBGTransferEnabled]
and a
ret z
ld [hSPTemp], sp ; save stack pointer
ldh a, [hAutoBGTransferPortion]
and a
jr z, .transferTopThird
dec a
jr z, .transferMiddleThird
.transferBottomThird
hlcoord 0, 12
ld sp, hl
ldh a, [hAutoBGTransferDest + 1]
ld h, a
ldh a, [hAutoBGTransferDest]
ld l, a
ld de, 12 * TILEMAP_WIDTH
add hl, de
xor a ; TRANSFERTOP
jr .doTransfer
.transferTopThird
hlcoord 0, 0
ld sp, hl
ldh a, [hAutoBGTransferDest + 1]
ld h, a
ldh a, [hAutoBGTransferDest]
ld l, a
ld a, TRANSFERMIDDLE
jr .doTransfer
.transferMiddleThird
hlcoord 0, 6
ld sp, hl
ldh a, [hAutoBGTransferDest + 1]
ld h, a
ldh a, [hAutoBGTransferDest]
ld l, a
ld de, 6 * TILEMAP_WIDTH
add hl, de
ld a, TRANSFERBOTTOM
.doTransfer
ldh [hAutoBGTransferPortion], a ; store next portion
ld b, 6
TransferBgRows::
; unrolled loop and using pop for speed
REPT SCREEN_WIDTH / 2 - 1
pop de
ld [hl], e
inc l
ld [hl], d
inc l
ENDR
pop de
ld [hl], e
inc l
ld [hl], d
ld a, TILEMAP_WIDTH - (SCREEN_WIDTH - 1)
add l
ld l, a
jr nc, .ok
inc h
.ok
dec b
jr nz, TransferBgRows
ldh a, [hSPTemp]
ld l, a
ldh a, [hSPTemp + 1]
ld h, a
ld sp, hl
ret
; Copies [hVBlankCopyBGNumRows] rows from hVBlankCopyBGSource to hVBlankCopyBGDest.
; If hVBlankCopyBGSource is XX00, the transfer is disabled.
VBlankCopyBgMap::
ldh a, [hVBlankCopyBGSource] ; doubles as enabling byte
and a
ret z
ld [hSPTemp], sp ; save stack pointer
ldh a, [hVBlankCopyBGSource]
ld l, a
ldh a, [hVBlankCopyBGSource + 1]
ld h, a
ld sp, hl
ldh a, [hVBlankCopyBGDest]
ld l, a
ldh a, [hVBlankCopyBGDest + 1]
ld h, a
ldh a, [hVBlankCopyBGNumRows]
ld b, a
xor a
ldh [hVBlankCopyBGSource], a ; disable transfer so it doesn't continue next V-blank
jr TransferBgRows
VBlankCopyDouble::
; Copy [hVBlankCopyDoubleSize] 1bpp tiles
; from hVBlankCopyDoubleSource to hVBlankCopyDoubleDest.
; While we're here, convert to 2bpp.
; The process is straightforward:
; copy each byte twice.
ldh a, [hVBlankCopyDoubleSize]
and a
ret z
ld [hSPTemp], sp ; save stack pointer
ldh a, [hVBlankCopyDoubleSource]
ld l, a
ldh a, [hVBlankCopyDoubleSource + 1]
ld h, a
ld sp, hl
ldh a, [hVBlankCopyDoubleDest]
ld l, a
ldh a, [hVBlankCopyDoubleDest + 1]
ld h, a
ldh a, [hVBlankCopyDoubleSize]
ld b, a
xor a ; transferred
ldh [hVBlankCopyDoubleSize], a
.loop
REPT TILE_SIZE / 4 - 1
pop de
ld [hl], e
inc l
ld [hl], e
inc l
ld [hl], d
inc l
ld [hl], d
inc l
ENDR
pop de
ld [hl], e
inc l
ld [hl], e
inc l
ld [hl], d
inc l
ld [hl], d
inc hl
dec b
jr nz, .loop
ld [hVBlankCopyDoubleSource], sp
ld sp, hl ; load destination into sp to save time with ld [$xxxx], sp
ld [hVBlankCopyDoubleDest], sp
ldh a, [hSPTemp]
ld l, a
ldh a, [hSPTemp + 1]
ld h, a
ld sp, hl
ret
VBlankCopy::
; Copy [hVBlankCopySize] 2bpp tiles (or 16 * [hVBlankCopySize] tile map entries)
; from hVBlankCopySource to hVBlankCopyDest.
; Source and destination addresses are updated,
; so transfer can continue in subsequent calls.
ldh a, [hVBlankCopySize]
and a
ret z
ld [hSPTemp], sp
ldh a, [hVBlankCopySource]
ld l, a
ldh a, [hVBlankCopySource + 1]
ld h, a
ld sp, hl
ldh a, [hVBlankCopyDest]
ld l, a
ldh a, [hVBlankCopyDest + 1]
ld h, a
ldh a, [hVBlankCopySize]
ld b, a
xor a ; transferred
ldh [hVBlankCopySize], a
.loop
REPT TILE_SIZE / 2 - 1
pop de
ld [hl], e
inc l
ld [hl], d
inc l
ENDR
pop de
ld [hl], e
inc l
ld [hl], d
inc hl
dec b
jr nz, .loop
ld [hVBlankCopySource], sp
ld sp, hl
ld [hVBlankCopyDest], sp
ldh a, [hSPTemp]
ld l, a
ldh a, [hSPTemp + 1]
ld h, a
ld sp, hl
ret
UpdateMovingBgTiles::
; Animate water and flower
; tiles in the overworld.
ldh a, [hTileAnimations]
and a
ret z
ldh a, [rLY]
cp $90 ; check if not in vblank period??? (maybe if vblank is too long)
ret c
ldh a, [hMovingBGTilesCounter1]
inc a
ldh [hMovingBGTilesCounter1], a
cp 20
ret c
cp 21
jr z, .flower
; water
ld hl, vTileset tile $14
ld c, $10
ld a, [wMovingBGTilesCounter2]
inc a
and 7
ld [wMovingBGTilesCounter2], a
and 4
jr nz, .left
.right
ld a, [hl]
rrca
ld [hli], a
dec c
jr nz, .right
jr .done
.left
ld a, [hl]
rlca
ld [hli], a
dec c
jr nz, .left
.done
ldh a, [hTileAnimations]
rrca
ret nc
xor a
ldh [hMovingBGTilesCounter1], a
ret
.flower
xor a
ldh [hMovingBGTilesCounter1], a
ld a, [wMovingBGTilesCounter2]
and 3
cp 2
ld hl, FlowerTile1
jr c, .copy
ld hl, FlowerTile2
jr z, .copy
ld hl, FlowerTile3
.copy
ld de, vTileset tile $03
ld c, $10
.loop
ld a, [hli]
ld [de], a
inc de
dec c
jr nz, .loop
ret
FlowerTile1: INCBIN "gfx/tilesets/flower/flower1.2bpp"
FlowerTile2: INCBIN "gfx/tilesets/flower/flower2.2bpp"
FlowerTile3: INCBIN "gfx/tilesets/flower/flower3.2bpp"