summaryrefslogtreecommitdiff
path: root/home.asm
diff options
context:
space:
mode:
Diffstat (limited to 'home.asm')
-rw-r--r--home.asm1628
1 files changed, 9 insertions, 1619 deletions
diff --git a/home.asm b/home.asm
index dd2433ad..e3d4309b 100644
--- a/home.asm
+++ b/home.asm
@@ -909,30 +909,7 @@ InterlaceMergeSpriteBuffers:: ; 16ea (0:16ea)
jp CopyVideoData
-Underground_Coll:: INCBIN "gfx/tilesets/underground.tilecoll"
-Overworld_Coll:: INCBIN "gfx/tilesets/overworld.tilecoll"
-RedsHouse1_Coll::
-RedsHouse2_Coll:: INCBIN "gfx/tilesets/reds_house.tilecoll"
-Mart_Coll::
-Pokecenter_Coll:: INCBIN "gfx/tilesets/pokecenter.tilecoll"
-Dojo_Coll::
-Gym_Coll:: INCBIN "gfx/tilesets/gym.tilecoll"
-Forest_Coll:: INCBIN "gfx/tilesets/forest.tilecoll"
-House_Coll:: INCBIN "gfx/tilesets/house.tilecoll"
-ForestGate_Coll::
-Museum_Coll::
-Gate_Coll:: INCBIN "gfx/tilesets/gate.tilecoll"
-Ship_Coll:: INCBIN "gfx/tilesets/ship.tilecoll"
-ShipPort_Coll:: INCBIN "gfx/tilesets/ship_port.tilecoll"
-Cemetery_Coll:: INCBIN "gfx/tilesets/cemetery.tilecoll"
-Interior_Coll:: INCBIN "gfx/tilesets/interior.tilecoll"
-Cavern_Coll:: INCBIN "gfx/tilesets/cavern.tilecoll"
-Lobby_Coll:: INCBIN "gfx/tilesets/lobby.tilecoll"
-Mansion_Coll:: INCBIN "gfx/tilesets/mansion.tilecoll"
-Lab_Coll:: INCBIN "gfx/tilesets/lab.tilecoll"
-Club_Coll:: INCBIN "gfx/tilesets/club.tilecoll"
-Facility_Coll:: INCBIN "gfx/tilesets/facility.tilecoll"
-Plateau_Coll:: INCBIN "gfx/tilesets/plateau.tilecoll"
+INCLUDE "data/collision.asm"
FarCopyData2::
@@ -1166,781 +1143,10 @@ ClearScreen::
INCLUDE "home/text.asm"
-
-
-; 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:: ; 1cdd (0:1cdd)
- 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:: ; 1cf0 (0:1cf0)
- ld a," "
- jr .next
- ld a,l
-.next
- ld de,$400 ; size of VRAM background map
- ld l,e
-.loop
- ld [hli],a
- dec e
- jr nz,.loop
- dec d
- jr nz,.loop
- ret
-
-; When the player takes a step, a row or column of 2x2 tile blocks at the edge
-; of the screen toward which they moved is exposed and has to be redrawn.
-; This function does the redrawing.
-RedrawExposedScreenEdge:: ; 1d01 (0:1d01)
- ld a,[H_SCREENEDGEREDRAW]
- and a
- ret z
- ld b,a
- xor a
- ld [H_SCREENEDGEREDRAW],a
- dec b
- jr nz,.redrawRow
-.redrawColumn
- ld hl,wScreenEdgeTiles
- ld a,[H_SCREENEDGEREDRAWADDR]
- ld e,a
- ld a,[H_SCREENEDGEREDRAWADDR + 1]
- ld d,a
- ld c,18 ; screen height
-.loop1
- ld a,[hli]
- ld [de],a
- inc de
- ld a,[hli]
- ld [de],a
- ld a,31
- 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 a,$03
- or a,$98
- ld d,a
- dec c
- jr nz,.loop1
- xor a
- ld [H_SCREENEDGEREDRAW],a
- ret
-.redrawRow
- ld hl,wScreenEdgeTiles
- ld a,[H_SCREENEDGEREDRAWADDR]
- ld e,a
- ld a,[H_SCREENEDGEREDRAWADDR + 1]
- ld d,a
- push de
- call .drawHalf ; draw upper half
- pop de
- ld a,32 ; width of VRAM background map
- add e
- ld e,a
- ; draw lower half
-.drawHalf
- ld c,10
-.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 a,$1f
- ld b,a
- ld a,e
- and a,$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, RedrawExposedScreenEdge, is used when walking to
-; improve efficiency.
-AutoBgMapTransfer:: ; 1d57 (0:1d57)
- ld a,[H_AUTOBGTRANSFERENABLED]
- and a
- ret z
- ld hl,[sp + 0]
- ld a,h
- ld [H_SPTEMP],a
- ld a,l
- ld [H_SPTEMP + 1],a ; save stack pinter
- ld a,[H_AUTOBGTRANSFERPORTION]
- and a
- jr z,.transferTopThird
- dec a
- jr z,.transferMiddleThird
-.transferBottomThird
- FuncCoord 0,12
- ld hl,Coord
- ld sp,hl
- ld a,[H_AUTOBGTRANSFERDEST + 1]
- ld h,a
- ld a,[H_AUTOBGTRANSFERDEST]
- ld l,a
- ld de,(12 * 32)
- add hl,de
- xor a ; TRANSFERTOP
- jr .doTransfer
-.transferTopThird
- FuncCoord 0,0
- ld hl,Coord
- ld sp,hl
- ld a,[H_AUTOBGTRANSFERDEST + 1]
- ld h,a
- ld a,[H_AUTOBGTRANSFERDEST]
- ld l,a
- ld a,TRANSFERMIDDLE
- jr .doTransfer
-.transferMiddleThird
- FuncCoord 0,6
- ld hl,Coord
- ld sp,hl
- ld a,[H_AUTOBGTRANSFERDEST + 1]
- ld h,a
- ld a,[H_AUTOBGTRANSFERDEST]
- ld l,a
- ld de,(6 * 32)
- add hl,de
- ld a,TRANSFERBOTTOM
-.doTransfer
- ld [H_AUTOBGTRANSFERPORTION],a ; store next portion
- ld b,6
-
-TransferBgRows:: ; 1d9e (0:1d9e)
-; unrolled loop and using pop for speed
-
- rept 20 / 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
-
-i ld a, 32 - (20 - 1)
- add l
- ld l, a
- jr nc, .ok
- inc h
-.ok
- dec b
- jr nz, TransferBgRows
-
- ld a, [H_SPTEMP]
- ld h, a
- ld a, [H_SPTEMP + 1]
- ld l, a
- ld sp, hl
- ret
-
-; Copies [H_VBCOPYBGNUMROWS] rows from H_VBCOPYBGSRC to H_VBCOPYBGDEST.
-; If H_VBCOPYBGSRC is XX00, the transfer is disabled.
-VBlankCopyBgMap:: ; 1de1 (0:1de1)
- ld a,[H_VBCOPYBGSRC] ; doubles as enabling byte
- and a
- ret z
- ld hl,[sp + 0]
- ld a,h
- ld [H_SPTEMP],a
- ld a,l
- ld [H_SPTEMP + 1],a ; save stack pointer
- ld a,[H_VBCOPYBGSRC]
- ld l,a
- ld a,[H_VBCOPYBGSRC + 1]
- ld h,a
- ld sp,hl
- ld a,[H_VBCOPYBGDEST]
- ld l,a
- ld a,[H_VBCOPYBGDEST + 1]
- ld h,a
- ld a,[H_VBCOPYBGNUMROWS]
- ld b,a
- xor a
- ld [H_VBCOPYBGSRC],a ; disable transfer so it doesn't continue next V-blank
- jr TransferBgRows
-
-
-VBlankCopyDouble::
-; Copy [H_VBCOPYDOUBLESIZE] 1bpp tiles
-; from H_VBCOPYDOUBLESRC to H_VBCOPYDOUBLEDEST.
-
-; While we're here, convert to 2bpp.
-; The process is straightforward:
-; copy each byte twice.
-
- ld a, [H_VBCOPYDOUBLESIZE]
- and a
- ret z
-
- ld hl, [sp + 0]
- ld a, h
- ld [H_SPTEMP], a
- ld a, l
- ld [H_SPTEMP + 1], a
-
- ld a, [H_VBCOPYDOUBLESRC]
- ld l, a
- ld a, [H_VBCOPYDOUBLESRC + 1]
- ld h, a
- ld sp, hl
-
- ld a, [H_VBCOPYDOUBLEDEST]
- ld l, a
- ld a, [H_VBCOPYDOUBLEDEST + 1]
- ld h, a
-
- ld a, [H_VBCOPYDOUBLESIZE]
- ld b, a
- xor a ; transferred
- ld [H_VBCOPYDOUBLESIZE], a
-
-.loop
- rept 3
- 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 a, l
- ld [H_VBCOPYDOUBLEDEST], a
- ld a, h
- ld [H_VBCOPYDOUBLEDEST + 1], a
-
- ld hl, [sp + 0]
- ld a, l
- ld [H_VBCOPYDOUBLESRC], a
- ld a, h
- ld [H_VBCOPYDOUBLESRC + 1], a
-
- ld a, [H_SPTEMP]
- ld h, a
- ld a, [H_SPTEMP + 1]
- ld l, a
- ld sp, hl
-
- ret
-
-
-VBlankCopy::
-; Copy [H_VBCOPYSIZE] 2bpp tiles
-; from H_VBCOPYSRC to H_VBCOPYDEST.
-
-; Source and destination addresses
-; are updated, so transfer can
-; continue in subsequent calls.
-
- ld a, [H_VBCOPYSIZE]
- and a
- ret z
-
- ld hl, [sp + 0]
- ld a, h
- ld [H_SPTEMP], a
- ld a, l
- ld [H_SPTEMP + 1], a
-
- ld a, [H_VBCOPYSRC]
- ld l, a
- ld a, [H_VBCOPYSRC + 1]
- ld h, a
- ld sp, hl
-
- ld a, [H_VBCOPYDEST]
- ld l, a
- ld a, [H_VBCOPYDEST + 1]
- ld h, a
-
- ld a, [H_VBCOPYSIZE]
- ld b, a
- xor a ; transferred
- ld [H_VBCOPYSIZE], a
-
-.loop
- rept 7
- 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 a, l
- ld [H_VBCOPYDEST], a
- ld a, h
- ld [H_VBCOPYDEST + 1], a
-
- ld hl, [sp + 0]
- ld a, l
- ld [H_VBCOPYSRC], a
- ld a, h
- ld [H_VBCOPYSRC + 1], a
-
- ld a, [H_SPTEMP]
- ld h, a
- ld a, [H_SPTEMP + 1]
- ld l, a
- ld sp, hl
-
- ret
-
-
-UpdateMovingBgTiles::
-; Animate water and flower
-; tiles in the overworld.
-
- ld a, [$ffd7]
- and a
- ret z
-
- ld a, [$ffd8]
- inc a
- ld [$ffd8], a
- cp $14
- ret c
- cp $15
- jr z, .flower
-
- ld hl, vTileset + $14 * $10
- ld c, $10
-
- ld a, [wd085]
- inc a
- and 7
- ld [wd085], 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
- ld a, [$ffd7]
- rrca
- ret nc
- xor a
- ld [$ffd8], a
- ret
-
-.flower
- xor a
- ld [$ffd8], a
-
- ld a, [wd085]
- and 3
- cp 2
- ld hl, FlowerTile1
- jr c, .copy
- ld hl, FlowerTile2
- jr z, .copy
- ld hl, FlowerTile3
-.copy
- ld de, vTileset + $3 * $10
- 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"
-
-
-SoftReset::
- call StopAllSounds
- call GBPalWhiteOut
- ld c, $20
- call DelayFrames
- ; fallthrough
-
-Init::
-; Program init.
-
-rLCDC_DEFAULT EQU %11100011
-; * LCD enabled
-; * Window tile map at $9C00
-; * Window display enabled
-; * BG and window tile data at $8800
-; * BG tile map at $9800
-; * 8x8 OBJ size
-; * OBJ display enabled
-; * BG display enabled
-
- di
-
- xor a
- ld [rIF], a
- ld [rIE], a
- ld [$ff43], a
- ld [$ff42], a
- ld [$ff01], a
- ld [$ff02], a
- ld [$ff4b], a
- ld [$ff4a], a
- ld [$ff06], a
- ld [$ff07], a
- ld [$ff47], a
- ld [$ff48], a
- ld [$ff49], a
-
- ld a, rLCDC_ENABLE_MASK
- ld [rLCDC], a
- call DisableLCD
-
- ld sp, wStack
-
- ld hl, $c000 ; start of WRAM
- ld bc, $2000 ; size of WRAM
-.loop
- ld [hl], 0
- inc hl
- dec bc
- ld a, b
- or c
- jr nz, .loop
-
- call ClearVram
-
- ld hl, $ff80
- ld bc, $ffff - $ff80
- call FillMemory
-
- call ClearSprites
-
- ld a, Bank(WriteDMACodeToHRAM)
- ld [H_LOADEDROMBANK], a
- ld [MBC3RomBank], a
- call WriteDMACodeToHRAM
-
- xor a
- ld [$ffd7], a
- ld [$ff41], a
- ld [$ffae], a
- ld [$ffaf], a
- ld [$ff0f], a
- ld a, 1 << VBLANK + 1 << TIMER + 1 << SERIAL
- ld [rIE], a
-
- ld a, 144 ; move the window off-screen
- ld [$ffb0], a
- ld [rWY], a
- ld a, 7
- ld [rWX], a
-
- ld a, $ff
- ld [$ffaa], a
-
- ld h, vBGMap0 / $100
- call ClearBgMap
- ld h, vBGMap1 / $100
- call ClearBgMap
-
- ld a, rLCDC_DEFAULT
- ld [rLCDC], a
- ld a, 16
- ld [hSoftReset], a
- call StopAllSounds
-
- ei
-
- ld a, $40 ; PREDEF_SGB_BORDER
- call Predef
-
- ld a, $1f
- ld [wc0ef], a
- ld [wc0f0], a
- ld a, $9c
- ld [$ffbd], a
- xor a
- ld [$ffbc], a
- dec a
- ld [wcfcb], a
-
- ld a, $32 ; PREDEF_INTRO
- call Predef
-
- call DisableLCD
- call ClearVram
- call GBPalNormal
- call ClearSprites
- ld a, rLCDC_DEFAULT
- ld [rLCDC], a
-
- jp SetDefaultNamesBeforeTitlescreen
-
-ClearVram:
- ld hl, $8000
- ld bc, $2000
- xor a
- jp FillMemory
-
-
-StopAllSounds::
- ld a, Bank(Func_9876)
- ld [wc0ef], a
- ld [wc0f0], a
- xor a
- ld [wMusicHeaderPointer], a
- ld [wc0ee], a
- ld [wcfca], a
- dec a
- jp PlaySound
-
-
-VBlank::
-
- push af
- push bc
- push de
- push hl
-
- ld a, [H_LOADEDROMBANK]
- ld [wd122], a
-
- ld a, [$ffae]
- ld [rSCX], a
- ld a, [$ffaf]
- ld [rSCY], a
-
- ld a, [wd0a0]
- and a
- jr nz, .ok
- ld a, [$ffb0]
- ld [rWY], a
-.ok
-
- call AutoBgMapTransfer
- call VBlankCopyBgMap
- call RedrawExposedScreenEdge
- call VBlankCopy
- call VBlankCopyDouble
- call UpdateMovingBgTiles
- call $ff80 ; hOAMDMA
- ld a, Bank(PrepareOAMData)
- ld [H_LOADEDROMBANK], a
- ld [MBC3RomBank], a
- call PrepareOAMData
-
- ; VBlank-sensitive operations end.
-
- call Random
-
- ld a, [H_VBLANKOCCURRED]
- and a
- jr z, .vblanked
- xor a
- ld [H_VBLANKOCCURRED], a
-.vblanked
-
- ld a, [H_FRAMECOUNTER]
- and a
- jr z, .decced
- dec a
- ld [H_FRAMECOUNTER], a
-.decced
-
- call Func_28cb
-
- ld a, [wc0ef] ; music ROM bank
- ld [H_LOADEDROMBANK], a
- ld [MBC3RomBank], a
-
- cp BANK(Func_9103)
- jr nz, .notbank2
-.bank2
- call Func_9103
- jr .afterMusic
-.notbank2
- cp 8
- jr nz, .bank1F
-.bank8
- call Func_2136e
- call Func_21879
- jr .afterMusic
-.bank1F
- call Func_7d177
-.afterMusic
-
- callba Func_18dee ; keep track of time played
-
- ld a, [$fff9]
- and a
- call z, ReadJoypad
-
- ld a, [wd122]
- ld [H_LOADEDROMBANK], a
- ld [MBC3RomBank], a
-
- pop hl
- pop de
- pop bc
- pop af
- reti
-
-
-DelayFrame::
-; Wait for the next vblank interrupt.
-; As a bonus, this saves battery.
-
-NOT_VBLANKED EQU 1
-
- ld a, NOT_VBLANKED
- ld [H_VBLANKOCCURRED], a
-.halt
- halt
- ld a, [H_VBLANKOCCURRED]
- and a
- jr nz, .halt
- ret
-
-
-; These routines manage gradual fading
-; (e.g., entering a doorway)
-LoadGBPal::
- ld a, [wd35d] ;tells if cur.map is dark (requires HM5_FLASH?)
- ld b, a
- ld hl, FadePal4
- ld a, l
- sub b
- ld l, a
- jr nc, .ok
- dec h
-.ok
- ld a, [hli]
- ld [rBGP], a
- ld a, [hli]
- ld [rOBP0], a
- ld a, [hli]
- ld [rOBP1], a
- ret
-
-GBFadeOut1::
- ld hl, FadePal1
- ld b, 4
- jr GBFadeOutCommon
-
-GBFadeOut2::
- ld hl, FadePal6
- ld b, 3
-
-GBFadeOutCommon::
- ld a, [hli]
- ld [rBGP], a
- ld a, [hli]
- ld [rOBP0], a
- ld a, [hli]
- ld [rOBP1], a
- ld c, 8
- call DelayFrames
- dec b
- jr nz, GBFadeOutCommon
- ret
-
-GBFadeIn1::
- ld hl, FadePal4 + 2
- ld b, 4
- jr GBFadeInCommon
-
-GBFadeIn2::
- ld hl, FadePal7 + 2
- ld b, 3
-
-GBFadeInCommon::
- ld a, [hld]
- ld [rOBP1], a
- ld a, [hld]
- ld [rOBP0], a
- ld a, [hld]
- ld [rBGP], a
- ld c, 8
- call DelayFrames
- dec b
- jr nz, GBFadeInCommon
- ret
-
-FadePal1:: db %11111111, %11111111, %11111111
-FadePal2:: db %11111110, %11111110, %11111000
-FadePal3:: db %11111001, %11100100, %11100100
-FadePal4:: db %11100100, %11010000, %11100000
-; rBGP rOBP0 rOBP1
-FadePal5:: db %11100100, %11010000, %11100000
-FadePal6:: db %10010000, %10000000, %10010000
-FadePal7:: db %01000000, %01000000, %01000000
-FadePal8:: db %00000000, %00000000, %00000000
+INCLUDE "home/vcopy.asm"
+INCLUDE "home/init.asm"
+INCLUDE "home/vblank.asm"
+INCLUDE "home/fade.asm"
Serial:: ; 2125 (0:2125)
@@ -2248,193 +1454,14 @@ Func_22fa:: ; 22fa (0:22fa)
ld [$ff02], a
ret
+
; timer interrupt is apparently not invoked anyway
Timer:: ; 2306 (0:2306)
reti
-Func_2307:: ; 2307 (0:2307)
- call WaitForSoundToFinish
- xor a
- ld c, a
- ld d, a
- ld [wcfca], a
- jr asm_2324
-
-Func_2312:: ; 2312 (0:2312)
- ld c, $a
- ld d, $0
- ld a, [wd72e]
- bit 5, a
- jr z, asm_2324
- xor a
- ld [wcfca], a
- ld c, $8
- ld d, c
-asm_2324:: ; 2324 (0:2324)
- ld a, [wd700]
- and a
- jr z, .asm_2343
- cp $2
- jr z, .asm_2332
- ld a, MUSIC_BIKE_RIDING
- jr .asm_2334
-.asm_2332
- ld a, MUSIC_SURFING
-.asm_2334
- ld b, a
- ld a, d
- and a
- ld a, Bank(Func_7d8ea)
- jr nz, .asm_233e
- ld [wc0ef], a
-.asm_233e
- ld [wc0f0], a
- jr .asm_234c
-.asm_2343
- ld a, [wd35b]
- ld b, a
- call Func_2385
- jr c, .asm_2351
-.asm_234c
- ld a, [wcfca]
- cp b
- ret z
-.asm_2351
- ld a, c
- ld [wMusicHeaderPointer], a
- ld a, b
- ld [wcfca], a
- ld [wc0ee], a
- jp PlaySound
-
-Func_235f:: ; 235f (0:235f)
- ld a, [wc0ef]
- ld b, a
- cp $2
- jr nz, .checkForBank08
-.bank02
- ld hl, Func_9103
- jr .asm_2378
-.checkForBank08
- cp $8
- jr nz, .bank1F
-.bank08
- ld hl, Func_21879
- jr .asm_2378
-.bank1F
- ld hl, Func_7d177
-.asm_2378
- ld c, $6
-.asm_237a
- push bc
- push hl
- call Bankswitch
- pop hl
- pop bc
- dec c
- jr nz, .asm_237a
- ret
-Func_2385:: ; 2385 (0:2385)
- ld a, [wd35c]
- ld e, a
- ld a, [wc0ef]
- cp e
- jr nz, .asm_2394
- ld [wc0f0], a
- and a
- ret
-.asm_2394
- ld a, c
- and a
- ld a, e
- jr nz, .asm_239c
- ld [wc0ef], a
-.asm_239c
- ld [wc0f0], a
- scf
- ret
+INCLUDE "home/audio.asm"
-PlayMusic:: ; 23a1 (0:23a1)
- ld b, a
- ld [wc0ee], a
- xor a
- ld [wMusicHeaderPointer], a
- ld a, c
- ld [wc0ef], a
- ld [wc0f0], a
- ld a, b
-
-; plays music specified by a. If value is $ff, music is stopped
-PlaySound:: ; 23b1 (0:23b1)
- push hl
- push de
- push bc
- ld b, a
- ld a, [wc0ee]
- and a
- jr z, .asm_23c8
- xor a
- ld [wc02a], a
- ld [wc02b], a
- ld [wc02c], a
- ld [wc02d], a
-.asm_23c8
- ld a, [wMusicHeaderPointer]
- and a
- jr z, .asm_23e3
- ld a, [wc0ee]
- and a
- jr z, .asm_2425
- xor a
- ld [wc0ee], a
- ld a, [wcfca]
- cp $ff
- jr nz, .asm_2414
- xor a
- ld [wMusicHeaderPointer], a
-.asm_23e3
- xor a
- ld [wc0ee], a
- ld a, [H_LOADEDROMBANK]
- ld [$ffb9], a
- ld a, [wc0ef]
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- cp $2
- jr nz, .checkForBank08
-.bank02
- ld a, b
- call Func_9876
- jr .asm_240b
-.checkForBank08
- cp $8
- jr nz, .bank1F
-.bank08
- ld a, b
- call Func_22035
- jr .asm_240b
-.bank1F
- ld a, b
- call Func_7d8ea
-.asm_240b
- ld a, [$ffb9]
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- jr .asm_2425
-.asm_2414
- ld a, b
- ld [wcfca], a
- ld a, [wMusicHeaderPointer]
- ld [wcfc8], a
- ld [wcfc9], a
- ld a, b
- ld [wMusicHeaderPointer], a
-.asm_2425
- pop bc
- pop de
- pop hl
- ret
UpdateSprites:: ; 2429 (0:2429)
ld a, [wcfcb]
@@ -2486,597 +1513,9 @@ Predef5CText:: ; 24f4 (0:24f4)
call Predef
jp TextScriptEnd
-; bankswitches and runs _UncompressSpriteData
-; bank is given in a, sprite input stream is pointed to in W_SPRITEINPUTPTR
-UncompressSpriteData:: ; 24fd (0:24fd)
- ld b, a
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, b
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ld a, $a
- ld [$0], a
- xor a
- ld [$4000], a
- call _UncompressSpriteData
- pop af
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ret
-; initializes necessary data to load a sprite and runs UncompressSpriteDataLoop
-_UncompressSpriteData:: ; 251a (0:251a)
- ld hl, S_SPRITEBUFFER1
- ld c, (2*SPRITEBUFFERSIZE) % $100
- ld b, (2*SPRITEBUFFERSIZE) / $100
- xor a
- call FillMemory ; clear sprite buffer 1 and 2
- ld a, $1
- ld [W_SPRITEINPUTBITCOUNTER], a
- ld a, $3
- ld [W_SPRITEOUTPUTBITOFFSET], a
- xor a
- ld [W_SPRITECURPOSX], a
- ld [W_SPRITECURPOSY], a
- ld [W_SPRITELOADFLAGS], a ; wd0a8
- call ReadNextInputByte ; first byte of input determines sprite width (high nybble) and height (low nybble) in tiles (8x8 pixels)
- ld b, a
- and $f
- add a
- add a
- add a
- ld [W_SPRITEHEIGHT], a
- ld a, b
- swap a
- and $f
- add a
- add a
- add a
- ld [W_SPRITEWITDH], a
- call ReadNextInputBit
- ld [W_SPRITELOADFLAGS], a ; initialite bit1 to 0 and bit0 to the first input bit
- ; this will load two chunks of data to S_SPRITEBUFFER1 and S_SPRITEBUFFER2
- ; bit 0 decides in which one the first chunk is placed
- ; fall through
+INCLUDE "home/pic.asm"
-; uncompresses a chunk from the sprite input data stream (pointed to at wd0da) into S_SPRITEBUFFER1 or S_SPRITEBUFFER2
-; each chunk is a 1bpp sprite. A 2bpp sprite consist of two chunks which are merged afterwards
-; note that this is an endless loop which is terminated during a call to MoveToNextBufferPosition by manipulating the stack
-UncompressSpriteDataLoop:: ; 2556 (0:2556)
- ld hl, S_SPRITEBUFFER1
- ld a, [W_SPRITELOADFLAGS] ; wd0a8
- bit 0, a
- jr z, .useSpriteBuffer1 ; check which buffer to use
- ld hl, S_SPRITEBUFFER2
-.useSpriteBuffer1
- call StoreSpriteOutputPointer
- ld a, [W_SPRITELOADFLAGS] ; wd0a8
- bit 1, a
- jr z, .startDecompression ; check if last iteration
- call ReadNextInputBit ; if last chunk, read 1-2 bit unpacking mode
- and a
- jr z, .unpackingMode0 ; 0 -> mode 0
- call ReadNextInputBit ; 1 0 -> mode 1
- inc a ; 1 1 -> mode 2
-.unpackingMode0
- ld [W_SPRITEUNPACKMODE], a
-.startDecompression
- call ReadNextInputBit
- and a
- jr z, .readRLEncodedZeros ; if first bit is 0, the input starts with zeroes, otherwise with (non-zero) input
-.readNextInput
- call ReadNextInputBit
- ld c, a
- call ReadNextInputBit
- sla c
- or c ; read next two bits into c
- and a
- jr z, .readRLEncodedZeros ; 00 -> RLEncoded zeroes following
- call WriteSpriteBitsToBuffer ; otherwise write input to output and repeat
- call MoveToNextBufferPosition
- jr .readNextInput
-.readRLEncodedZeros
- ld c, $0 ; number of zeroes it length encoded, the number
-.countConsecutiveOnesLoop ; of consecutive ones determines the number of bits the number has
- call ReadNextInputBit
- and a
- jr z, .countConsecutiveOnesFinished
- inc c
- jr .countConsecutiveOnesLoop
-.countConsecutiveOnesFinished
- ld a, c
- add a
- ld hl, LengthEncodingOffsetList
- add l
- ld l, a
- jr nc, .noCarry
- inc h
-.noCarry
- ld a, [hli] ; read offset that is added to the number later on
- ld e, a ; adding an offset of 2^length - 1 makes every integer uniquely
- ld d, [hl] ; representable in the length encoding and saves bits
- push de
- inc c
- ld e, $0
- ld d, e
-.readNumberOfZerosLoop ; reads the next c+1 bits of input
- call ReadNextInputBit
- or e
- ld e, a
- dec c
- jr z, .readNumberOfZerosDone
- sla e
- rl d
- jr .readNumberOfZerosLoop
-.readNumberOfZerosDone
- pop hl ; add the offset
- add hl, de
- ld e, l
- ld d, h
-.writeZerosLoop
- ld b, e
- xor a ; write 00 to buffer
- call WriteSpriteBitsToBuffer
- ld e, b
- call MoveToNextBufferPosition
- dec de
- ld a, d
- and a
- jr nz, .continueLoop
- ld a, e
- and a
-.continueLoop
- jr nz, .writeZerosLoop
- jr .readNextInput
-
-; moves output pointer to next position
-; also cancels the calling function if the all output is done (by removing the return pointer from stack)
-; and calls postprocessing functions according to the unpack mode
-MoveToNextBufferPosition:: ; 25d8 (0:25d8)
- ld a, [W_SPRITEHEIGHT]
- ld b, a
- ld a, [W_SPRITECURPOSY]
- inc a
- cp b
- jr z, .curColumnDone
- ld [W_SPRITECURPOSY], a
- ld a, [W_SPRITEOUTPUTPTR]
- inc a
- ld [W_SPRITEOUTPUTPTR], a
- ret nz
- ld a, [W_SPRITEOUTPUTPTR+1]
- inc a
- ld [W_SPRITEOUTPUTPTR+1], a
- ret
-.curColumnDone
- xor a
- ld [W_SPRITECURPOSY], a
- ld a, [W_SPRITEOUTPUTBITOFFSET]
- and a
- jr z, .bitOffsetsDone
- dec a
- ld [W_SPRITEOUTPUTBITOFFSET], a
- ld hl, W_SPRITEOUTPUTPTRCACHED
- ld a, [hli]
- ld [W_SPRITEOUTPUTPTR], a
- ld a, [hl]
- ld [W_SPRITEOUTPUTPTR+1], a
- ret
-.bitOffsetsDone
- ld a, $3
- ld [W_SPRITEOUTPUTBITOFFSET], a
- ld a, [W_SPRITECURPOSX]
- add $8
- ld [W_SPRITECURPOSX], a
- ld b, a
- ld a, [W_SPRITEWITDH]
- cp b
- jr z, .allColumnsDone
- ld a, [W_SPRITEOUTPUTPTR]
- ld l, a
- ld a, [W_SPRITEOUTPUTPTR+1]
- ld h, a
- inc hl
- jp StoreSpriteOutputPointer
-.allColumnsDone
- pop hl
- xor a
- ld [W_SPRITECURPOSX], a
- ld a, [W_SPRITELOADFLAGS] ; wd0a8
- bit 1, a
- jr nz, .done ; test if there is one more sprite to go
- xor $1
- set 1, a
- ld [W_SPRITELOADFLAGS], a ; wd0a8
- jp UncompressSpriteDataLoop
-.done
- jp UnpackSprite
-
-; writes 2 bits (from a) to the output buffer (pointed to from W_SPRITEOUTPUTPTR)
-WriteSpriteBitsToBuffer:: ; 2649 (0:2649)
- ld e, a
- ld a, [W_SPRITEOUTPUTBITOFFSET]
- and a
- jr z, .offset0
- cp $2
- jr c, .offset1
- jr z, .offset2
- rrc e ; offset 3
- rrc e
- jr .offset0
-.offset1
- sla e
- sla e
- jr .offset0
-.offset2
- swap e
-.offset0
- ld a, [W_SPRITEOUTPUTPTR]
- ld l, a
- ld a, [W_SPRITEOUTPUTPTR+1]
- ld h, a
- ld a, [hl]
- or e
- ld [hl], a
- ret
-
-; reads next bit from input stream and returns it in a
-ReadNextInputBit:: ; 2670 (0:2670)
- ld a, [W_SPRITEINPUTBITCOUNTER]
- dec a
- jr nz, .curByteHasMoreBitsToRead
- call ReadNextInputByte
- ld [W_SPRITEINPUTCURBYTE], a
- ld a, $8
-.curByteHasMoreBitsToRead
- ld [W_SPRITEINPUTBITCOUNTER], a
- ld a, [W_SPRITEINPUTCURBYTE]
- rlca
- ld [W_SPRITEINPUTCURBYTE], a
- and $1
- ret
-
-; reads next byte from input stream and returns it in a
-ReadNextInputByte:: ; 268b (0:268b)
- ld a, [W_SPRITEINPUTPTR]
- ld l, a
- ld a, [W_SPRITEINPUTPTR+1]
- ld h, a
- ld a, [hli]
- ld b, a
- ld a, l
- ld [W_SPRITEINPUTPTR], a
- ld a, h
- ld [W_SPRITEINPUTPTR+1], a
- ld a, b
- ret
-
-; the nth item is 2^n - 1
-LengthEncodingOffsetList:: ; 269f (0:269f)
- dw %0000000000000001
- dw %0000000000000011
- dw %0000000000000111
- dw %0000000000001111
- dw %0000000000011111
- dw %0000000000111111
- dw %0000000001111111
- dw %0000000011111111
- dw %0000000111111111
- dw %0000001111111111
- dw %0000011111111111
- dw %0000111111111111
- dw %0001111111111111
- dw %0011111111111111
- dw %0111111111111111
- dw %1111111111111111
-
-; unpacks the sprite data depending on the unpack mode
-UnpackSprite:: ; 26bf (0:26bf)
- ld a, [W_SPRITEUNPACKMODE]
- cp $2
- jp z, UnpackSpriteMode2
- and a
- jp nz, XorSpriteChunks
- ld hl, S_SPRITEBUFFER1
- call SpriteDifferentialDecode
- ld hl, S_SPRITEBUFFER2
- ; fall through
-
-; decodes differential encoded sprite data
-; input bit value 0 preserves the current bit value and input bit value 1 toggles it (starting from initial value 0).
-SpriteDifferentialDecode:: ; 26d4 (0:26d4)
- xor a
- ld [W_SPRITECURPOSX], a
- ld [W_SPRITECURPOSY], a
- call StoreSpriteOutputPointer
- ld a, [W_SPRITEFLIPPED]
- and a
- jr z, .notFlipped
- ld hl, DecodeNybble0TableFlipped
- ld de, DecodeNybble1TableFlipped
- jr .storeDecodeTablesPointers
-.notFlipped
- ld hl, DecodeNybble0Table
- ld de, DecodeNybble1Table
-.storeDecodeTablesPointers
- ld a, l
- ld [W_SPRITEDECODETABLE0PTR], a
- ld a, h
- ld [W_SPRITEDECODETABLE0PTR+1], a
- ld a, e
- ld [W_SPRITEDECODETABLE1PTR], a
- ld a, d
- ld [W_SPRITEDECODETABLE1PTR+1], a
- ld e, $0 ; last decoded nybble, initialized to 0
-.decodeNextByteLoop
- ld a, [W_SPRITEOUTPUTPTR]
- ld l, a
- ld a, [W_SPRITEOUTPUTPTR+1]
- ld h, a
- ld a, [hl]
- ld b, a
- swap a
- and $f
- call DifferentialDecodeNybble ; decode high nybble
- swap a
- ld d, a
- ld a, b
- and $f
- call DifferentialDecodeNybble ; decode low nybble
- or d
- ld b, a
- ld a, [W_SPRITEOUTPUTPTR]
- ld l, a
- ld a, [W_SPRITEOUTPUTPTR+1]
- ld h, a
- ld a, b
- ld [hl], a ; write back decoded data
- ld a, [W_SPRITEHEIGHT]
- add l ; move on to next column
- jr nc, .noCarry
- inc h
-.noCarry
- ld [W_SPRITEOUTPUTPTR], a
- ld a, h
- ld [W_SPRITEOUTPUTPTR+1], a
- ld a, [W_SPRITECURPOSX]
- add $8
- ld [W_SPRITECURPOSX], a
- ld b, a
- ld a, [W_SPRITEWITDH]
- cp b
- jr nz, .decodeNextByteLoop ; test if current row is done
- xor a
- ld e, a
- ld [W_SPRITECURPOSX], a
- ld a, [W_SPRITECURPOSY] ; move on to next row
- inc a
- ld [W_SPRITECURPOSY], a
- ld b, a
- ld a, [W_SPRITEHEIGHT]
- cp b
- jr z, .done ; test if all rows finished
- ld a, [W_SPRITEOUTPUTPTRCACHED]
- ld l, a
- ld a, [W_SPRITEOUTPUTPTRCACHED+1]
- ld h, a
- inc hl
- call StoreSpriteOutputPointer
- jr .decodeNextByteLoop
-.done
- xor a
- ld [W_SPRITECURPOSY], a
- ret
-
-; decodes the nybble stored in a. Last decoded data is assumed to be in e (needed to determine if initial value is 0 or 1)
-DifferentialDecodeNybble:: ; 276d (0:276d)
- srl a ; c=a%2, a/=2
- ld c, $0
- jr nc, .evenNumber
- ld c, $1
-.evenNumber
- ld l, a
- ld a, [W_SPRITEFLIPPED]
- and a
- jr z, .notFlipped ; determine if initial value is 0 or one
- bit 3, e ; if flipped, consider MSB of last data
- jr .selectLookupTable
-.notFlipped
- bit 0, e ; else consider LSB
-.selectLookupTable
- ld e, l
- jr nz, .initialValue1 ; load the appropriate table
- ld a, [W_SPRITEDECODETABLE0PTR]
- ld l, a
- ld a, [W_SPRITEDECODETABLE0PTR+1]
- jr .tableLookup
-.initialValue1
- ld a, [W_SPRITEDECODETABLE1PTR]
- ld l, a
- ld a, [W_SPRITEDECODETABLE1PTR+1]
-.tableLookup
- ld h, a
- ld a, e
- add l
- ld l, a
- jr nc, .noCarry
- inc h
-.noCarry
- ld a, [hl]
- bit 0, c
- jr nz, .selectLowNybble
- swap a ; select high nybble
-.selectLowNybble
- and $f
- ld e, a ; update last decoded data
- ret
-
-DecodeNybble0Table:: ; 27a7 (0:27a7)
- dn $0, $1
- dn $3, $2
- dn $7, $6
- dn $4, $5
- dn $f, $e
- dn $c, $d
- dn $8, $9
- dn $b, $a
-DecodeNybble1Table:: ; 27af (0:27af)
- dn $f, $e
- dn $c, $d
- dn $8, $9
- dn $b, $a
- dn $0, $1
- dn $3, $2
- dn $7, $6
- dn $4, $5
-DecodeNybble0TableFlipped:: ; 27b7 (0:27b7)
- dn $0, $8
- dn $c, $4
- dn $e, $6
- dn $2, $a
- dn $f, $7
- dn $3, $b
- dn $1, $9
- dn $d, $5
-DecodeNybble1TableFlipped:: ; 27bf (0:27bf)
- dn $f, $7
- dn $3, $b
- dn $1, $9
- dn $d, $5
- dn $0, $8
- dn $c, $4
- dn $e, $6
- dn $2, $a
-
-; combines the two loaded chunks with xor (the chunk loaded second is the destination). The source chunk is differeintial decoded beforehand.
-XorSpriteChunks:: ; 27c7 (0:27c7)
- xor a
- ld [W_SPRITECURPOSX], a
- ld [W_SPRITECURPOSY], a
- call ResetSpriteBufferPointers
- ld a, [W_SPRITEOUTPUTPTR] ; points to buffer 1 or 2, depending on flags
- ld l, a
- ld a, [W_SPRITEOUTPUTPTR+1]
- ld h, a
- call SpriteDifferentialDecode ; decode buffer 1 or 2, depending on flags
- call ResetSpriteBufferPointers
- ld a, [W_SPRITEOUTPUTPTR] ; source buffer, points to buffer 1 or 2, depending on flags
- ld l, a
- ld a, [W_SPRITEOUTPUTPTR+1]
- ld h, a
- ld a, [W_SPRITEOUTPUTPTRCACHED] ; destination buffer, points to buffer 2 or 1, depending on flags
- ld e, a
- ld a, [W_SPRITEOUTPUTPTRCACHED+1]
- ld d, a
-.xorChunksLoop
- ld a, [W_SPRITEFLIPPED]
- and a
- jr z, .notFlipped
- push de
- ld a, [de]
- ld b, a
- swap a
- and $f
- call ReverseNybble ; if flipped reverse the nybbles in the destination buffer
- swap a
- ld c, a
- ld a, b
- and $f
- call ReverseNybble
- or c
- pop de
- ld [de], a
-.notFlipped
- ld a, [hli]
- ld b, a
- ld a, [de]
- xor b
- ld [de], a
- inc de
- ld a, [W_SPRITECURPOSY]
- inc a
- ld [W_SPRITECURPOSY], a ; go to next row
- ld b, a
- ld a, [W_SPRITEHEIGHT]
- cp b
- jr nz, .xorChunksLoop ; test if column finished
- xor a
- ld [W_SPRITECURPOSY], a
- ld a, [W_SPRITECURPOSX]
- add $8
- ld [W_SPRITECURPOSX], a ; go to next column
- ld b, a
- ld a, [W_SPRITEWITDH]
- cp b
- jr nz, .xorChunksLoop ; test if all columns finished
- xor a
- ld [W_SPRITECURPOSX], a
- ret
-
-; reverses the bits in the nybble given in register a
-ReverseNybble:: ; 2837 (0:2837)
- ld de, NybbleReverseTable
- add e
- ld e, a
- jr nc, .asm_283f
- inc d
-.asm_283f
- ld a, [de]
- ret
-
-; resets sprite buffer pointers to buffer 1 and 2, depending on W_SPRITELOADFLAGS
-ResetSpriteBufferPointers:: ; 2841 (0:2841)
- ld a, [W_SPRITELOADFLAGS] ; wd0a8
- bit 0, a
- jr nz, .buffer2Selected
- ld de, S_SPRITEBUFFER1
- ld hl, S_SPRITEBUFFER2
- jr .storeBufferPointers
-.buffer2Selected
- ld de, S_SPRITEBUFFER2
- ld hl, S_SPRITEBUFFER1
-.storeBufferPointers
- ld a, l
- ld [W_SPRITEOUTPUTPTR], a
- ld a, h
- ld [W_SPRITEOUTPUTPTR+1], a
- ld a, e
- ld [W_SPRITEOUTPUTPTRCACHED], a
- ld a, d
- ld [W_SPRITEOUTPUTPTRCACHED+1], a
- ret
-
-; maps each nybble to its reverse
-NybbleReverseTable:: ; 2867 (0:2867)
- db $0, $8, $4, $c, $2, $a, $6 ,$e, $1, $9, $5, $d, $3, $b, $7 ,$f
-
-; combines the two loaded chunks with xor (the chunk loaded second is the destination). Both chunks are differeintial decoded beforehand.
-UnpackSpriteMode2:: ; 2877 (0:2877)
- call ResetSpriteBufferPointers
- ld a, [W_SPRITEFLIPPED]
- push af
- xor a
- ld [W_SPRITEFLIPPED], a ; temporarily clear flipped flag for decoding the destination chunk
- ld a, [W_SPRITEOUTPUTPTRCACHED]
- ld l, a
- ld a, [W_SPRITEOUTPUTPTRCACHED+1]
- ld h, a
- call SpriteDifferentialDecode
- call ResetSpriteBufferPointers
- pop af
- ld [W_SPRITEFLIPPED], a
- jp XorSpriteChunks
-
-; stores hl into the output pointers
-StoreSpriteOutputPointer:: ; 2897 (0:2897)
- ld a, l
- ld [W_SPRITEOUTPUTPTR], a
- ld [W_SPRITEOUTPUTPTRCACHED], a
- ld a, h
- ld [W_SPRITEOUTPUTPTR+1], a
- ld [W_SPRITEOUTPUTPTRCACHED+1], a
- ret
ResetPlayerSpriteData:: ; 28a6 (0:28a6)
ld hl, wSpriteStateData1
@@ -6721,56 +5160,7 @@ Random::
ret
-Predef::
-; Call predefined function a.
-; To preserve other registers, have the
-; destination call GetPredefRegisters.
-
- ; Save the predef id for GetPredefPointer.
- ld [wPredefID], a
-
- ; A hack for LoadDestinationWarpPosition.
- ; See Func_c754 (predef $19).
- ld a, [H_LOADEDROMBANK]
- ld [wPredefParentBank], a
-
- push af
- ld a, BANK(GetPredefPointer)
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
-
- call GetPredefPointer
-
- ld a, [wPredefBank]
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
-
- ld de, .done
- push de
- jp [hl]
-.done
-
- pop af
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ret
-
-GetPredefRegisters::
-; Restore the contents of register pairs
-; when GetPredefPointer was called.
- ld a, [wPredefRegisters + 0]
- ld h, a
- ld a, [wPredefRegisters + 1]
- ld l, a
- ld a, [wPredefRegisters + 2]
- ld d, a
- ld a, [wPredefRegisters + 3]
- ld e, a
- ld a, [wPredefRegisters + 4]
- ld b, a
- ld a, [wPredefRegisters + 5]
- ld c, a
- ret
+INCLUDE "home/predef.asm"
Func_3ead:: ; 3ead (0:3ead)