mirror of
https://github.com/pret/pokegold-spaceworld.git
synced 2026-09-26 13:32:48 -04:00
e1659ecd41
Addresses of sections will now be added to the linkerscript via `org`, and the section name will be the path/to/file. If there is more than one section in the file, then add a @SectionName after the path/to/file to describe the section.
617 lines
12 KiB
NASM
617 lines
12 KiB
NASM
INCLUDE "constants.asm"
|
|
|
|
SECTION "home/vcopy.asm", ROM0
|
|
|
|
RedrawRowOrColumn:: ; 123a (0:123a)
|
|
; 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.
|
|
; This also implements the flashlight drawing distance effect, which takes
|
|
; multiple frames in either direction to complete
|
|
ldh a, [hRedrawRowOrColumnMode]
|
|
and a
|
|
ret z
|
|
cp $03
|
|
jr nc, .flashlight_effect
|
|
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
|
|
.col_loop
|
|
ld a, [hli]
|
|
ld [de], a
|
|
inc de
|
|
ld a, [hli]
|
|
ld [de], a
|
|
ld a, BG_MAP_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 HIGH(vBGMap1 - vBGMap0 - $01)
|
|
or HIGH(vBGMap0)
|
|
ld d, a
|
|
dec c
|
|
jr nz, .col_loop
|
|
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
|
|
pop de
|
|
ld a, BG_MAP_WIDTH ; width of VRAM background map
|
|
add e
|
|
ld e, a
|
|
; fallthrough (draw lower half)
|
|
|
|
.DrawHalf
|
|
ld c, SCREEN_WIDTH / 2
|
|
.row_loop
|
|
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 BG_MAP_WIDTH - 1 ; mask lower address bits
|
|
ld b, a
|
|
ld a, e
|
|
and ($FF ^ (BG_MAP_WIDTH - 1)) ; mask upper address bits
|
|
or b
|
|
ld e, a
|
|
dec c
|
|
jr nz, .row_loop
|
|
ret
|
|
.flashlight_effect
|
|
dec a
|
|
dec a
|
|
dec a
|
|
ld c, a
|
|
ld b, $00
|
|
ld hl, .flashlight_effect_table
|
|
add hl, bc
|
|
add hl, bc
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
jp hl
|
|
|
|
.flashlight_effect_table
|
|
dw RedrawFlashlightRow0 ; $1310
|
|
dw RedrawFlashlightRow0 ; $1310
|
|
dw RedrawFlashlightColumn0 ; $12C3
|
|
dw RedrawFlashlightColumn0 ; $12C3
|
|
dw RedrawFlashlightRow1 ; $1329
|
|
dw RedrawFlashlightRow1 ; $1329
|
|
dw RedrawFlashlightColumn1 ; $12DC
|
|
dw RedrawFlashlightColumn1 ; $12DC
|
|
dw RedrawFlashlightRow2 ; $1335
|
|
dw RedrawFlashlightRow2 ; $1335
|
|
dw RedrawFlashlightColumn2 ; $12E8
|
|
dw RedrawFlashlightColumn2 ; $12E8
|
|
dw RedrawFlashlightRow3 ; $134E
|
|
dw RedrawFlashlightRow3 ; $134E
|
|
dw RedrawFlashlightColumn3 ; $1301
|
|
dw RedrawFlashlightColumn3 ; $1301
|
|
|
|
RedrawFlashlightColumn0:: ; 12c3 (0:12c3)
|
|
ldh a, [hSCX]
|
|
and $07
|
|
ret nz ; wait till we moved one complete tile in X
|
|
ld a, [wRedrawFlashlightDst0]
|
|
ld e, a
|
|
ld a, [wRedrawFlashlightDst0 + 1]
|
|
ld d, a
|
|
ld a, [wRedrawFlashlightSrc0]
|
|
ld l, a
|
|
ld a, [wRedrawFlashlightSrc0 + 1]
|
|
ld h, a
|
|
call _RedrawFlashlightColumn
|
|
ret
|
|
|
|
RedrawFlashlightColumn1:: ; 12dc (0:12dc)
|
|
ld a, [wRedrawFlashlightBlackDst0]
|
|
ld e, a
|
|
ld a, [wRedrawFlashlightBlackDst0 + 1]
|
|
ld d, a
|
|
call _RedrawFlashlightColumnBlack
|
|
ret
|
|
; 0x12e8
|
|
|
|
RedrawFlashlightColumn2:: ; 12e8 (0:12e8)
|
|
ldh a, [hSCX]
|
|
and $0f
|
|
ret nz ; wait till we moved two complete tiles in X
|
|
ld a, [wRedrawFlashlightDst1]
|
|
ld e, a
|
|
ld a, [wRedrawFlashlightDst1 + 1]
|
|
ld d, a
|
|
ld a, [wRedrawFlashlightSrc1]
|
|
ld l, a
|
|
ld a, [wRedrawFlashlightSrc1 + 1]
|
|
ld h, a
|
|
call _RedrawFlashlightColumn
|
|
ret
|
|
|
|
RedrawFlashlightColumn3:: ; 1301 (0:1301)
|
|
ld a, [wRedrawFlashlightBlackDst1]
|
|
ld e, a
|
|
ld a, [wRedrawFlashlightBlackDst1 + 1]
|
|
ld d, a
|
|
call _RedrawFlashlightColumnBlack
|
|
xor a
|
|
ldh [hRedrawRowOrColumnMode], a ; end flashlight redraw
|
|
ret
|
|
|
|
RedrawFlashlightRow0:: ; 1310 (0:1310)
|
|
ldh a, [hSCY]
|
|
and $07
|
|
ret nz ; wait till we moved one complete tile in Y
|
|
ld a, [wRedrawFlashlightDst0]
|
|
ld e, a
|
|
ld a, [wRedrawFlashlightDst0 + 1]
|
|
ld d, a
|
|
ld a, [wRedrawFlashlightSrc0]
|
|
ld l, a
|
|
ld a, [wRedrawFlashlightSrc0 + 1]
|
|
ld h, a
|
|
call _RedrawFlashlightRow
|
|
ret
|
|
|
|
RedrawFlashlightRow1:: ; 1329 (0:1329)
|
|
ld a, [wRedrawFlashlightBlackDst0]
|
|
ld e, a
|
|
ld a, [wRedrawFlashlightBlackDst0 + 1]
|
|
ld d, a
|
|
call _RedrawFlashlightRowBlack
|
|
ret
|
|
; 0x12e8
|
|
|
|
RedrawFlashlightRow2:: ; 1335 (0:1335)
|
|
ldh a, [hSCY]
|
|
and $0f
|
|
ret nz ; wait till we moved two complete tiles in Y
|
|
ld a, [wRedrawFlashlightDst1]
|
|
ld e, a
|
|
ld a, [wRedrawFlashlightDst1 + 1]
|
|
ld d, a
|
|
ld a, [wRedrawFlashlightSrc1]
|
|
ld l, a
|
|
ld a, [wRedrawFlashlightSrc1 + 1]
|
|
ld h, a
|
|
call _RedrawFlashlightRow
|
|
ret
|
|
|
|
RedrawFlashlightRow3:: ; 134e (0:134e)
|
|
ld a, [wRedrawFlashlightBlackDst1]
|
|
ld e, a
|
|
ld a, [wRedrawFlashlightBlackDst1 + 1]
|
|
ld d, a
|
|
call _RedrawFlashlightRowBlack
|
|
xor a
|
|
ldh [hRedrawRowOrColumnMode], a ; end flashlight redraw
|
|
ret
|
|
|
|
_RedrawFlashlightColumn:: ; 135d (0:135d)
|
|
ld a, [wRedrawFlashlightWidthHeight]
|
|
add a
|
|
ld c, a
|
|
.loop
|
|
ld a, [hli]
|
|
ld [de], a
|
|
ld a, SCREEN_WIDTH - 1
|
|
add l
|
|
ld l, a
|
|
jr nc, .noCarryScreen
|
|
inc h
|
|
.noCarryScreen
|
|
ld a, BG_MAP_WIDTH
|
|
add e
|
|
ld e, a
|
|
jr nc, .noCarryBG
|
|
inc d
|
|
.noCarryBG
|
|
; the following 4 lines wrap us from bottom to top if necessary
|
|
ld a, d
|
|
and HIGH(vBGMap1 - vBGMap0 - $01)
|
|
or HIGH(vBGMap0)
|
|
ld d, a
|
|
dec c
|
|
jr nz, .loop
|
|
ldh a, [hRedrawRowOrColumnMode]
|
|
add $04 ; inc by 4, because flashlight redraw
|
|
ldh [hRedrawRowOrColumnMode], a ; has four directions
|
|
ret
|
|
|
|
_RedrawFlashlightRow:: ; 1382 (0:1382)
|
|
ld a, [wRedrawFlashlightWidthHeight]
|
|
ld c, a
|
|
.loop
|
|
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 BG_MAP_WIDTH - 1 ; mask lower address bits
|
|
ld b, a
|
|
ld a, e
|
|
and ($FF ^ (BG_MAP_WIDTH - 1)) ; mask upper address bits
|
|
or b
|
|
ld e, a
|
|
dec c
|
|
jr nz, .loop
|
|
ldh a, [hRedrawRowOrColumnMode]
|
|
add $04 ; inc by 4, because flashlight redraw
|
|
ldh [hRedrawRowOrColumnMode], a ; has four directions
|
|
ret
|
|
|
|
_RedrawFlashlightColumnBlack:: ; 139f (0:139f)
|
|
ld l, e
|
|
ld h, d
|
|
ld b, "■"
|
|
ld de, BG_MAP_WIDTH
|
|
ld a, [wRedrawFlashlightWidthHeight]
|
|
add a
|
|
ld c, a
|
|
.loop
|
|
ld [hl], b
|
|
add hl, de
|
|
; the following 4 lines wrap us from bottom to top if necessary
|
|
ld a, h
|
|
and HIGH(vBGMap1 - vBGMap0 - $01)
|
|
or HIGH(vBGMap0)
|
|
ld h, a
|
|
dec c
|
|
jr nz, .loop
|
|
ldh a, [hRedrawRowOrColumnMode]
|
|
add $04 ; inc by 4, because flashlight redraw
|
|
ldh [hRedrawRowOrColumnMode], a ; has four directions
|
|
ret
|
|
|
|
_RedrawFlashlightRowBlack:: ; 13bd (0:13bd)
|
|
ld l, e
|
|
ld h, d
|
|
ld b, "■"
|
|
ld a, [wRedrawFlashlightWidthHeight]
|
|
ld c, a
|
|
.loop
|
|
ld [hl], b
|
|
inc hl
|
|
ld [hl], b
|
|
ld a, l
|
|
inc a
|
|
; the following 6 lines wrap us from the right edge to the left edge if necessary
|
|
and BG_MAP_WIDTH - 1 ; mask lower address bits
|
|
ld d, a
|
|
ld a, l
|
|
and ($FF ^ (BG_MAP_WIDTH - 1)) ; mask upper address bits
|
|
or d
|
|
ld l, a
|
|
dec c
|
|
jr nz, .loop
|
|
ldh a, [hRedrawRowOrColumnMode]
|
|
add $04 ; inc by 4, because flashlight redraw
|
|
ldh [hRedrawRowOrColumnMode], a ; has four directions
|
|
ret
|
|
|
|
WaitForAutoBgMapTransfer:: ; 13dc (0:13dc)
|
|
.loop
|
|
ldh a, [hBGMapMode]
|
|
and a
|
|
ret z
|
|
ldh a, [hBGMapTransferPosition]
|
|
and a
|
|
jr z, .done
|
|
call DelayFrame
|
|
jr .loop
|
|
.done
|
|
xor a
|
|
ldh [hBGMapMode], a
|
|
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:: ; 13ee (0:13ee)
|
|
ldh a, [hBGMapMode]
|
|
and a
|
|
ret z
|
|
ld [hSPTemp], sp
|
|
ldh a, [hBGMapTransferPosition]
|
|
and a
|
|
jr z, .transferTopThird
|
|
dec a
|
|
jr z, .transferMiddleThird
|
|
.transferBottomThird
|
|
coord hl, 0, 12
|
|
ld sp, hl
|
|
ldh a, [hBGMapAddress + 1]
|
|
ld h, a
|
|
ldh a, [hBGMapAddress]
|
|
ld l, a
|
|
ld de, 12 * BG_MAP_WIDTH
|
|
add hl, de
|
|
xor a
|
|
jr .doTransfer
|
|
.transferTopThird
|
|
coord hl, 0, 0
|
|
ld sp, hl
|
|
ldh a, [hBGMapAddress + 1]
|
|
ld h, a
|
|
ldh a, [hBGMapAddress]
|
|
ld l, a
|
|
ld a, $01
|
|
jr .doTransfer
|
|
.transferMiddleThird
|
|
coord hl, 0, 6
|
|
ld sp, hl
|
|
ldh a, [hBGMapAddress + 1]
|
|
ld h, a
|
|
ldh a, [hBGMapAddress]
|
|
ld l, a
|
|
ld de, 6 * BG_MAP_WIDTH
|
|
add hl, de
|
|
ld a, $02
|
|
.doTransfer
|
|
ldh [hBGMapTransferPosition], a
|
|
ld a, $06 ; 6 rows of SCREEN_WIDTH each
|
|
; fallthrough
|
|
|
|
TransferBgRows:: ; 1430 (0:1430)
|
|
ld bc, BG_MAP_WIDTH - SCREEN_WIDTH + 1
|
|
.loop
|
|
|
|
rept SCREEN_WIDTH / 2 - 1 ; two bytes per pop minus last block
|
|
pop de
|
|
ld [hl], e
|
|
inc l
|
|
ld [hl], d
|
|
inc l
|
|
endr
|
|
|
|
pop de
|
|
ld [hl], e
|
|
inc l
|
|
ld [hl], d
|
|
add hl, bc
|
|
dec a
|
|
jr nz, .loop
|
|
ldh a, [hSPTemp]
|
|
ld l, a
|
|
ldh a, [hSPTemp + 1]
|
|
ld h, a
|
|
ld sp, hl
|
|
ret
|
|
|
|
VBlankCopyDouble:: ; 1470 (0:1470)
|
|
; Copy [wVBCopyDoubleSize] 1bpp tiles
|
|
; from wVBCopyDoubleSrc to wVBCopyDoubleDst.
|
|
; wVBCopyDoubleDst must be aligned to 0x10 bytes.
|
|
|
|
; While we're here, convert to 2bpp.
|
|
; The process is straightforward:
|
|
; copy each byte twice.
|
|
ld a, [wVBCopyDoubleSize]
|
|
and a
|
|
ret z
|
|
ld [hSPTemp], sp
|
|
ld hl, wVBCopyDoubleSrc
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
ld sp, hl
|
|
ld hl, wVBCopyDoubleDst
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
ld a, [wVBCopyDoubleSize]
|
|
ld b, a
|
|
xor a
|
|
ld [wVBCopyDoubleSize], a
|
|
.loop
|
|
|
|
rept 16/4 - 1 ; 16 bytes per 2bpp tile at 2 bytes per pop
|
|
pop de ; copied twice minus last block
|
|
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 a, l
|
|
ld [wVBCopyDoubleDst], a
|
|
ld a, h
|
|
ld [wVBCopyDoubleDst + 1], a
|
|
ld [wVBCopyDoubleSrc], sp
|
|
ldh a, [hSPTemp]
|
|
ld l, a
|
|
ldh a, [hSPTemp + 1]
|
|
ld h, a
|
|
ld sp, hl
|
|
ret
|
|
|
|
VBlankCopy:: ; 14c7 (0:14c7)
|
|
; Copy 16 * [wVBCopySize] bytes
|
|
; from wVBCopySrc to wVBCopyDst.
|
|
; wVBCopyDst must be aligned to 0x10 bytes.
|
|
|
|
; Source and destination addresses are updated,
|
|
; so transfer can continue in subsequent calls.
|
|
ld a, [wVBCopySize]
|
|
and a
|
|
ret z
|
|
ld [hSPTemp], sp
|
|
ld hl, wVBCopySrc
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
ld sp, hl
|
|
ld hl, wVBCopyDst
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
ld a, [wVBCopySize]
|
|
ld b, a
|
|
xor a
|
|
ld [wVBCopySize], a
|
|
.loop
|
|
|
|
rept 16/2 - 1 ; 16 bytes per transfer at 2 bytes per pop
|
|
pop de ; minus last block
|
|
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 a, l
|
|
ld [wVBCopyDst], a
|
|
ld a, h
|
|
ld [wVBCopyDst + 1], a
|
|
ld [wVBCopySrc], sp
|
|
ldh a, [hSPTemp]
|
|
ld l, a
|
|
ldh a, [hSPTemp + 1]
|
|
ld h, a
|
|
ld sp, hl
|
|
ret
|
|
|
|
AnimateTileset:: ; 1522 (0:1522)
|
|
ldh a, [hROMBank]
|
|
push af
|
|
ld a, BANK(AnimateTilesetImpl)
|
|
call Bankswitch
|
|
call AnimateTilesetImpl
|
|
pop af
|
|
jp Bankswitch
|
|
; 0x1531
|
|
|
|
EnableSprites:: ; 1531 (0:1531)
|
|
nop
|
|
ld hl, rLCDC
|
|
set rLCDC_SPRITES_ENABLE, [hl]
|
|
ret
|
|
; 0x1538
|
|
|
|
TransferToolgearRow: ; 1538 (0:1538)
|
|
; TransferToolgearRow
|
|
; Copy second line of toolgear to window
|
|
ld a, [wToolgearFlags]
|
|
bit 0, a
|
|
ret z
|
|
bit 7, a
|
|
ret nz
|
|
bit 2, a
|
|
res 2, a
|
|
ret z
|
|
ld [wToolgearFlags], a
|
|
ld [hSPTemp], sp
|
|
bgcoord hl, 0, 1, wToolgearBuffer
|
|
ld sp, hl
|
|
bgcoord hl, 0, 1, vBGMap1
|
|
ld a, $01
|
|
jp TransferBgRows
|
|
|
|
VBlankCopyFar:: ; 1558 (0:1558)
|
|
; Copy 0x10 * [wVBCopyFarSize] bytes
|
|
; from wVBCopyFarSrcBank::wVBCopyFarSrc to wVBCopyFarDst.
|
|
; wVBCopyFarDst must be aligned to 0x10 bytes.
|
|
|
|
; Source and destination addresses are updated,
|
|
; so transfer can continue in subsequent calls.
|
|
ld a, [wVBCopyFarSize]
|
|
and a
|
|
ret z
|
|
ld a, [wVBCopyFarSrcBank]
|
|
call Bankswitch
|
|
ld [hSPTemp], sp
|
|
ld hl, wVBCopyFarSrc
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
ld sp, hl
|
|
ld hl, wVBCopyFarDst
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
ld a, [wVBCopyFarSize]
|
|
ld b, a
|
|
xor a
|
|
ld [wVBCopyFarSize], a
|
|
.loop
|
|
rept 16/2 - 1 ; 16 bytes per transfer at 2 bytes per pop
|
|
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 [wVBCopyFarSrc], sp
|
|
ld sp, hl
|
|
ld [wVBCopyFarDst], sp
|
|
ldh a, [hSPTemp]
|
|
ld l, a
|
|
ldh a, [hSPTemp + 1]
|
|
ld h, a
|
|
ld sp, hl
|
|
ret
|
|
; 0x15b5 |