mirror of https://github.com/AbePralle/FGB.git
7715 lines
188 KiB
NASM
7715 lines
188 KiB
NASM
;***************************************************************************
|
|
;* Gfx.asm - graphics support routines
|
|
;* 12.17.99 by Abe Pralle
|
|
;*
|
|
;***************************************************************************
|
|
|
|
INCLUDE "Source/Defs.inc"
|
|
INCLUDE "Source/Levels.inc"
|
|
INCLUDE "Source/Start.inc"
|
|
|
|
MAX_PER_TURN EQU 32
|
|
|
|
|
|
|
|
FAST_SCROLL_THRESHOLD EQU 2
|
|
|
|
|
|
SECTION "Graphics",ROM0
|
|
;---------------------------------------------------------------------
|
|
; Routine: InitGfx
|
|
; Description: Sets up some basic graphics stuff - One time
|
|
;---------------------------------------------------------------------
|
|
InitGfx::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
;set up game state
|
|
ld a,$ff
|
|
ld [amLinkMaster],a
|
|
xor a
|
|
ld [lastLinkAction],a
|
|
ld [amChangingMap],a
|
|
ld [heroesPresent],a
|
|
|
|
ld a,(hero0_data & $ff)
|
|
ld [curHeroAddressL],a
|
|
|
|
ld a,(HERO_BA_FLAG | HERO_BS_FLAG | HERO_HAIKU_FLAG)
|
|
ld [heroesAvailable],a
|
|
|
|
xor a
|
|
ld [heroesUsed],a
|
|
ld [randomLoc],a
|
|
ldio [musicEnabled],a
|
|
ld [musicBank],a
|
|
ld [musicAddress],a
|
|
ld [musicAddress+1],a
|
|
ld [heroesLocked],a
|
|
ld [hero0_puffCount],a
|
|
ld [hero1_puffCount],a
|
|
ld [inLoadMethod],a
|
|
|
|
ld c,16
|
|
ld hl,inventory
|
|
.clearInventory
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.clearInventory
|
|
|
|
;ld a,%10100001
|
|
;ld [inventory],a
|
|
;ld a,%00000011
|
|
;ld [inventory+1],a
|
|
|
|
xor a
|
|
ld [musicOverride1],a
|
|
ld [musicOverride4],a
|
|
|
|
ld a,64
|
|
ld [fadeRange],a
|
|
|
|
ld a,APPOMATTOXMAPINDEX
|
|
ld [appomattoxMapIndex],a
|
|
|
|
ld a,BANK(init_flightCodes)
|
|
call SetActiveROM
|
|
ld a,FLIGHTCODEBANK
|
|
ld bc,256
|
|
ld de,flightCode
|
|
ld hl,init_flightCodes
|
|
call MemCopy
|
|
|
|
xor a
|
|
ldio [dmaLoad],a
|
|
ld [displayType],a
|
|
|
|
ld a,1
|
|
ldio [curROMBank],a
|
|
|
|
call DisplayOff
|
|
call SetupSpriteHandler
|
|
|
|
;sound off
|
|
xor a
|
|
ldio [$ff26],a
|
|
|
|
;envelopes to zero
|
|
xor a
|
|
ldio [$ff12],a ;zero envelope all instruments
|
|
ldio [$ff17],a
|
|
ldio [$ff1c],a
|
|
ldio [$ff21],a
|
|
|
|
;turn on sound master control
|
|
ld a,$80
|
|
ldio [$ff26],a
|
|
ld a,$ff
|
|
ldio [$ff24],a ;full volume both channels
|
|
ldio [$ff25],a ;all sounds to both channels
|
|
|
|
;setup vector to hblank
|
|
ld a,$c3
|
|
ld [hblankVector],a ;opcode of jp
|
|
ld hl,OnHBlank
|
|
ld a,l
|
|
ld [hblankVector+1],a
|
|
ld a,h
|
|
ld [hblankVector+2],a
|
|
|
|
;enable VBlank interrupts
|
|
ld a,[$ffff]
|
|
or 1
|
|
ld [$ffff],a
|
|
|
|
;turn LCD on
|
|
ld a,%11000011
|
|
ld [$ff40], a ;lcdc control
|
|
|
|
;clear all level states to zero
|
|
ld a,LEVELSTATEBANK
|
|
ld [$ff70],a
|
|
ld c,0 ;loop 256 times
|
|
ld hl,levelState
|
|
xor a
|
|
.clearStateLoop
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.clearStateLoop
|
|
|
|
ld a,1 ;fade from white the first time
|
|
ld [standardFadeColor],a
|
|
|
|
;enable interrupts
|
|
ei
|
|
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: VMemCopy
|
|
; Arguments: a - VRAM bank of destination
|
|
; c - number of 16-byte blocks (tiles) to copy
|
|
; de - dest
|
|
; hl - source
|
|
; Alters: af
|
|
; [$ff4f] VRAM bank
|
|
; Description: Copies bytes from source to destination in VRAM.
|
|
; If screen is active it utilizes DMA loading, otherwise
|
|
; a normal copy is performed. DMA copies exceeding
|
|
; 2048 bytes may produce weird results.
|
|
;---------------------------------------------------------------------
|
|
VMemCopy::
|
|
push bc
|
|
push de
|
|
push hl
|
|
push af
|
|
|
|
;test if screen is on
|
|
ldio a,[$ff40]
|
|
and %10000000
|
|
jr nz,.screenIsOn
|
|
|
|
.screenIsOff
|
|
pop af
|
|
ldio [$ff4f],a ;switch VRAM bank
|
|
|
|
.setLoop
|
|
ld b,16
|
|
.bytesLoop
|
|
ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
dec b
|
|
jr nz,.bytesLoop
|
|
|
|
dec c
|
|
jr nz,.setLoop
|
|
jr .done
|
|
|
|
.screenIsOn ;copy using DMA
|
|
pop af
|
|
call InitDMALoad
|
|
call WaitDMALoad
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: MemSet
|
|
; Arguments: a - RAM bank of destination
|
|
; bc - length in bytes
|
|
; d - byte to set to
|
|
; hl - dest
|
|
; Alters: af
|
|
; [$ff70] RAM bank
|
|
; Description: Sets each byte in the range to be the specified value.
|
|
;---------------------------------------------------------------------
|
|
MemSet::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ldio [$ff70],a
|
|
|
|
.loop ld a,d
|
|
ld [hl+],a
|
|
dec bc
|
|
xor a
|
|
cp b
|
|
jr nz,.loop
|
|
cp c
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: MemCopy
|
|
; Arguments: a - RAM bank
|
|
; bc - non-zero length in bytes
|
|
; de - destination starting address
|
|
; hl - source start address
|
|
; Alters: af
|
|
; [$ff70] RAM bank
|
|
; Description: Copies each of "bc" # of bytes from source to dest.
|
|
; Alters the RAM bank to specified but does not revert
|
|
; to original during or after copying.
|
|
;---------------------------------------------------------------------
|
|
MemCopy::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ldio [$ff70],a ;set RAM
|
|
|
|
.copy ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
xor a
|
|
dec bc
|
|
cp b
|
|
jr nz,.copy
|
|
cp c
|
|
jr nz,.copy
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: InitDMALoad
|
|
; Arguments: a - VRAM bank of destination
|
|
; c - length in multiples of 16 bytes
|
|
; de - dest
|
|
; hl - source
|
|
; Alters: af
|
|
; Description: Preps appropriate variables for DMA transfer to take
|
|
; place on VBlank. Note may be called multiple times
|
|
; (er, twice) to set up values for bank 0 and bank 1
|
|
; transfer. Note that transfers for bank 0 and bank 1
|
|
; combined should not exceed 2048 bytes (and perhaps
|
|
; a bit less)
|
|
;---------------------------------------------------------------------
|
|
InitDMALoad::
|
|
or a
|
|
jr nz,.prepBank1
|
|
|
|
.prepBank0
|
|
ld a,l
|
|
ld [dmaLoadSrc0],a
|
|
ld a,h
|
|
ld [dmaLoadSrc0+1],a
|
|
|
|
ld a,e
|
|
ld [dmaLoadDest0],a
|
|
ld a,d
|
|
ld [dmaLoadDest0+1],a
|
|
|
|
ld a,c
|
|
dec a
|
|
ld [dmaLoadLen0],a
|
|
|
|
ldio a,[dmaLoad]
|
|
or 1
|
|
ldio [dmaLoad],a
|
|
ret
|
|
|
|
.prepBank1
|
|
ld a,l
|
|
ld [dmaLoadSrc1],a
|
|
ld a,h
|
|
ld [dmaLoadSrc1+1],a
|
|
|
|
ld a,e
|
|
ld [dmaLoadDest1],a
|
|
ld a,d
|
|
ld [dmaLoadDest1+1],a
|
|
|
|
ld a,c
|
|
dec a
|
|
ld [dmaLoadLen1],a
|
|
|
|
ldio a,[dmaLoad]
|
|
or 2
|
|
ldio [dmaLoad],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: WaitDMALoad
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
WaitDMALoad::
|
|
push bc
|
|
push de
|
|
push hl
|
|
.wait
|
|
ldio a,[dmaLoad]
|
|
and %11
|
|
jr nz,.wait
|
|
|
|
call GetInput
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: DMALoad
|
|
; Arguments: a - VRAM bank of destination
|
|
; c - byte length / 16
|
|
; hl - source
|
|
; de - dest
|
|
; Alters: af
|
|
; Description: Combines InitDMALoad and WaitDMALoad.
|
|
;---------------------------------------------------------------------
|
|
DMALoad::
|
|
call InitDMALoad
|
|
call WaitDMALoad
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: DisplayOff
|
|
; Arguments:
|
|
; Alters: af
|
|
; Description: Waits for VBlank then turns of the display
|
|
;---------------------------------------------------------------------
|
|
DisplayOff::
|
|
;skip if the display is off already
|
|
ld a,[$ff40]
|
|
and %10000000
|
|
ret z
|
|
|
|
;turn display off
|
|
ld a,[$ffff] ;get interrupts enabled
|
|
push af ;save original value
|
|
and %11111110 ;turn off vblank interrupt
|
|
ld [$ffff],a ;"interrupt THIS!"
|
|
.wait ld a,[$ff44] ;get line being drawn
|
|
cp 144 ;wait until line is >= 144
|
|
jr c,.wait
|
|
ld a,[$ff40] ;LCDC register
|
|
and %01111111 ;turn off screen
|
|
ld [$ff40],a
|
|
pop af ;retrieve original interrupt settings
|
|
ld [$ffff],a
|
|
|
|
.waitVRAM
|
|
ld a,[$ff41] ;STAT register
|
|
and %00000010 ;bit 1 needs to be zero to access VRAM
|
|
jr nz,.waitVRAM
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Subroutine: LoadNextLevel
|
|
; Arguments:
|
|
; Alters: af
|
|
; Description: Does all the prep work of setting up the next level
|
|
; based on arguments stored in memory
|
|
;---------------------------------------------------------------------
|
|
LoadNextLevel::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
.reload
|
|
ld a,1
|
|
ld [amChangingMap],a
|
|
|
|
;xor a
|
|
;ld [timeToChangeLevel],a
|
|
|
|
;save old level's level state
|
|
ld a,LEVELSTATEBANK
|
|
ld [$ff70],a
|
|
ld a,[curLevelStateIndex]
|
|
ld l,a
|
|
ld h,((levelState>>8) & $ff)
|
|
ldio a,[mapState]
|
|
or a
|
|
jr nz,.stateNotZero
|
|
ld a,1
|
|
.stateNotZero
|
|
ld [hl],a
|
|
|
|
;clear joystick input
|
|
xor a
|
|
ld [curJoy0],a
|
|
ld [curJoy1],a
|
|
ldio [jiggleDuration],a
|
|
ld [jiggleType],a ;normal jiggle
|
|
|
|
call PrepLevel
|
|
ld a,[timeToChangeLevel]
|
|
or a
|
|
jr nz,.reload
|
|
|
|
;set interrupt controller flag so the interrupt will happen
|
|
ld a,[$ffff] ;interrupt enable control register
|
|
or %00000011 ;enable vblank and hblank interrupts
|
|
ld [$ffff],a ;store that back in the IEC
|
|
|
|
call DrawMapToBackBuffer
|
|
|
|
;ld b,METHOD_CHECK
|
|
;call IterateAllLists
|
|
|
|
;initialize some values
|
|
xor a
|
|
ldio [backBufferReady],a
|
|
|
|
xor a
|
|
ld [amChangingMap],a
|
|
|
|
ei ;enable interrupts
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: PrepLevel
|
|
; Description: Sets up some basic graphics stuff
|
|
;---------------------------------------------------------------------
|
|
PrepLevel::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
;reset some stuff
|
|
xor a
|
|
ld [levelCheckSkip],a
|
|
ld [levelCheckSkip+1],a
|
|
ld [levelCheckSkip+2],a
|
|
ld [levelCheckSkip+3],a
|
|
ld a,MAX_PER_TURN
|
|
ld [iterateNumObjects],a
|
|
|
|
ld hl,timeToChangeLevel
|
|
ld a,[hl]
|
|
ld [hl],0
|
|
cp 2 ;2=skip init & load in next
|
|
jp z,.loadMap
|
|
|
|
;restore default vector to hblank
|
|
ld hl,OnHBlank
|
|
call InstallHBlankHandler
|
|
|
|
xor a
|
|
ldh [$ff43], a ;set screen offsets to 0
|
|
ldh [$ff42], a
|
|
|
|
xor a
|
|
ldh [$ff4a], a ;set window offsets to 7,0
|
|
ld a,7
|
|
ldh [$ff4b], a
|
|
|
|
xor a
|
|
ld [specialFX],a
|
|
ld [paletteBufferReady],a
|
|
ld [mapColor],a
|
|
ld [mapColor+1],a
|
|
ld [bgAttributes],a
|
|
ld [bgTileMap],a
|
|
ld [checkInputInMainLoop],a
|
|
ld [dialogJoyIndex],a
|
|
ld [heroJoyIndex],a
|
|
ld [hero0_index],a
|
|
ld [hero1_index],a
|
|
ld [heroesIdle],a
|
|
ld [allIdle],a
|
|
ld [mapDialogClassIndex],a
|
|
ld [dialogSettings],a ;no border, no press B
|
|
ld [amShowingDialog],a
|
|
ld [objTimerBase],a
|
|
ld [objTimer60ths],a
|
|
ld [heroTimerBase],a
|
|
ld [heroTimerBase],a
|
|
ld [lineZeroHorizontalOffset],a
|
|
ld [samplePlaying],a
|
|
ld [guardAlarm],a
|
|
ld [dialogNPC_speakerIndex],a
|
|
ld [dialogNPC_heroIndex],a
|
|
ld [dialogBalloonClassIndex],a
|
|
ld [envEffectType],a
|
|
|
|
;clear the horizontal offsets
|
|
ld bc,144
|
|
ld d,0
|
|
ld hl,horizontalOffset
|
|
ld a,TILEINDEXBANK
|
|
call MemSet
|
|
|
|
ld a,1
|
|
ld [canJoinMap],a
|
|
|
|
ld de,0
|
|
call SetDialogSkip
|
|
call SetDialogForward
|
|
|
|
;---------------------------
|
|
xor a
|
|
;turn all sounds off
|
|
ldio [$ff12],a ;sound 1 envelope
|
|
ldio [$ff17],a ;sound 2 envelope
|
|
ldio [$ff1a],a ;sound 3 output
|
|
ldio [$ff21],a ;sound 4 envelope
|
|
|
|
ld a,$ff
|
|
ld [$ff24],a ;full volume both channels
|
|
;---------------------------
|
|
|
|
ld a,$ff
|
|
ld [dialogSpeakerIndex],a
|
|
|
|
;ld a,$21 ;fast=2, slow=1
|
|
;ld a,$22 ;fast=2, slow=2
|
|
ld a,$42
|
|
ldio [scrollSpeed],a
|
|
|
|
;set up each entry of bgTileMap to be its own index for a
|
|
;speed trick in the map redraw
|
|
ld c,0
|
|
ld hl,bgTileMap
|
|
xor a
|
|
.initBGTileMap
|
|
ld [hl+],a
|
|
inc a
|
|
dec c
|
|
jr nz,.initBGTileMap
|
|
|
|
ld a,%00100111 ;background palette colors
|
|
ld [$ff47],a
|
|
|
|
ld a,1
|
|
ld [scrollSprites],a
|
|
|
|
call LoadGraphics
|
|
|
|
;go back to VRAM bank zero
|
|
xor a ;Switch to tile map
|
|
ld [$ff00+$4f],a ;(VRAM bank 0)
|
|
|
|
call SetupGamePalettes
|
|
|
|
;load in inventory items tiles 246-254
|
|
ld a,BANK(BGTiles1024)
|
|
call SetActiveROM
|
|
ld a,1
|
|
;xor a
|
|
ld c,9 ;#characters
|
|
ld de,$8f60
|
|
ld hl,BGTiles1024+$3f70
|
|
call VMemCopy
|
|
|
|
call LoadFont
|
|
|
|
ld a,1
|
|
ld c,1 ;1 character
|
|
ld de,$8ff0
|
|
ld hl,blankTileData
|
|
call VMemCopy
|
|
|
|
;set up hblank interrupt
|
|
ld a,143
|
|
ld [$ff45],a ;set lyc
|
|
xor a
|
|
ld [hblankFlag],a ;don't show dialog window
|
|
ld a,[$ff0f] ;clear LCDC interrupt flag
|
|
and %11111101
|
|
ld [$ff0f],a
|
|
|
|
ld a,119
|
|
ldio [hblankWinOn],a
|
|
ld a,143
|
|
ldio [hblankWinOff],a
|
|
|
|
ld a,%00001100 ;setup stat for lyc = ly
|
|
ld [$ff41],a
|
|
|
|
ld a,[$ffff] ;enable hblank interrupt
|
|
or %00000010
|
|
ld [$ffff],a
|
|
|
|
ld a,$98
|
|
ld [backBufferDestHighByte],a
|
|
|
|
call ResetSprites
|
|
|
|
.loadMap
|
|
; load in a map
|
|
ld a,BANK(ResetList)
|
|
call SetActiveROM
|
|
call ResetList
|
|
call ClearFGBGFlags
|
|
|
|
ld hl,curLevelIndex
|
|
ld a,[hl+]
|
|
ld h,[hl]
|
|
ld l,a
|
|
call LoadMap
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
LoadFont::
|
|
;load in font into $8c80 (tiles 200-253)
|
|
ld a,BANK(fontData)
|
|
call SetActiveROM
|
|
xor a
|
|
ld c,62 ;# characters
|
|
ld de,$8c00
|
|
ld hl,fontData
|
|
jp VMemCopy
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupSpriteHandler
|
|
; Description: Copies the routine required for sprite DMA to high
|
|
; RAM and initializes the sprites to off
|
|
;---------------------------------------------------------------------
|
|
SetupSpriteHandler::
|
|
ld hl,oamHandlerStart ;src addr
|
|
ld de,SpriteDMAHandler ;dest addr
|
|
ld c,(oamHandlerFinish - oamHandlerStart) ;# of bytes
|
|
|
|
.loop ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
call ResetSprites
|
|
|
|
ret
|
|
|
|
oamHandlerStart:
|
|
ld a,((spriteOAMBuffer>>8) & $ff) ;addr of start (in $100's)
|
|
ld [$ff00+$46],a ;start sprite dma
|
|
ld a,$28 ;start a delay loop
|
|
.wait dec a
|
|
jr nz,.wait
|
|
ret
|
|
oamHandlerFinish:
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupCommonColor
|
|
; Arguments: b - Color Spec for entry to set up
|
|
; de - color for entry
|
|
; Description: Sets all 8 palettes (bg AND sprite) to have the same
|
|
; colors for the specified entry.
|
|
; Note: The format specification should have bit 7 set so it
|
|
; auto-selects the next palette
|
|
;---------------------------------------------------------------------
|
|
SetupCommonColor::
|
|
push af
|
|
push bc
|
|
push hl
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
ld a,b
|
|
|
|
ld h,((gamePalette>>8) & $ff)
|
|
and %00000110 ;color # * 2
|
|
add (gamePalette & $ff)
|
|
ld l,a
|
|
|
|
ld a,b
|
|
|
|
ld c,16
|
|
|
|
.loop
|
|
ld a,e ;Get low byte of color
|
|
ld [hl+],a ;store it in game palette
|
|
|
|
ld a,d ;Get high byte of color
|
|
ld [hl+],a ;store in game palette
|
|
|
|
ld a,l ;skip next 3 colors in game palette
|
|
add 6
|
|
ld l,a
|
|
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupGamePalettes
|
|
; Description: Sets up [gamePalette] the in-game colors but sets
|
|
; the actual hardware to be all standard
|
|
;---------------------------------------------------------------------
|
|
SetupGamePalettes:
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
ld a,%10000000 ;color specs
|
|
ld [$ff68],a
|
|
ld [$ff6a],a
|
|
|
|
ld bc,$0000 ;standard fade color
|
|
ld hl,standardFadeColor
|
|
ld a,[hl]
|
|
ld [hl],0
|
|
or a
|
|
jr z,.fadeColorSet
|
|
|
|
ld bc,$7fff ;color 1 = white
|
|
|
|
.fadeColorSet
|
|
ld hl,.stdPaletteData
|
|
ld de,gamePalette
|
|
ld a,32 ;set up 64 bytes (32 colors)
|
|
|
|
|
|
.loop push af
|
|
ld a,[hl+]
|
|
ld [de],a ;copy of palette
|
|
inc de
|
|
ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
|
|
ld a,c
|
|
ld [$ff69],a ;bg palette
|
|
ld [$ff6b],a ;fg palette
|
|
|
|
ld a,b
|
|
ld [$ff69],a ;bg palette
|
|
ld [$ff6b],a ;fg palette
|
|
|
|
pop af
|
|
dec a
|
|
jr nz,.loop
|
|
|
|
;repeat for FG colors
|
|
ld hl,.stdPaletteData
|
|
ld c,32 ;set up 64 bytes (32 colors)
|
|
|
|
.loopFG ld a,[hl+]
|
|
ld [de],a ;copy of palette
|
|
inc de
|
|
ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
|
|
dec c
|
|
jr nz,.loopFG
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
|
|
ret
|
|
|
|
.stdPaletteData
|
|
DW $0000, $2108, $4210, $7fff ;Palette 0 (Grey)
|
|
DW $0000, $000A, $001f, $7fff ;Palette 1 (Red)
|
|
DW $0000, $5000, $7e00, $7fff ;Palette 2 (Blue)
|
|
DW $0000, $0140, $03e0, $7fff ;Palette 3 (Green)
|
|
DW $0000, $4008, $5192, $7fff ;Palette 4 (Purple)
|
|
DW $0000, $01cd, $03fe, $7fff ;Palette 5 (Yellow)
|
|
DW $0000, $00d1, $09ff, $7fff ;Palette 6 (Brown)
|
|
DW $0000, $4412, $799c, $7fff ;Palette 7 (Fuscia)
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routines: IndexToPointerDE
|
|
; IndexToPointerHL
|
|
; Arguments: a - index 1-255 of object
|
|
; Returns: de/hl - pointer $d010-$dff0 to object
|
|
;---------------------------------------------------------------------
|
|
IndexToPointerDE::
|
|
swap a
|
|
jr z,.null
|
|
ld e,a
|
|
and %00001111
|
|
add $d0
|
|
ld d,a
|
|
ld a,e
|
|
and %11110000
|
|
ld e,a
|
|
ret
|
|
.null
|
|
ld de,0
|
|
ret
|
|
|
|
IndexToPointerHL::
|
|
swap a
|
|
jr z,.null
|
|
ld l,a
|
|
and %00001111
|
|
add $d0
|
|
ld h,a
|
|
ld a,l
|
|
and %11110000
|
|
ld l,a
|
|
ret
|
|
.null
|
|
ld hl,0
|
|
ret
|
|
|
|
|
|
SECTION "TileCopyRoutines",ROM0
|
|
;---------------------------------------------------------------------
|
|
; Routines: AddHL16
|
|
; AddDE16
|
|
; Alters: af, (hl or de)
|
|
;---------------------------------------------------------------------
|
|
AddHL16::
|
|
ld a,l
|
|
add 16
|
|
ld l,a
|
|
ret nc
|
|
inc h
|
|
ret
|
|
AddDE16::
|
|
ld a,e
|
|
add 16
|
|
ld e,a
|
|
ret nc
|
|
inc d
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routines: TileIndexLToAddressHL
|
|
; TileIndexEToAddressDE
|
|
; Arguments: l/e - tile index (0-255)
|
|
; Returns: hl/de - address of tile index ($9000 +/- index*16)
|
|
;---------------------------------------------------------------------
|
|
TileIndexLToAddressHL:
|
|
push af
|
|
|
|
;shift "l" 4 left and into a
|
|
xor a ;clear a to zero (new high byte)
|
|
sla l ;shift into carry
|
|
rla ;carry into a
|
|
sla l ;repeat total of 4 times
|
|
rla ;carry into a
|
|
sla l
|
|
rla
|
|
sla l
|
|
rla
|
|
or $90 ;add base addr of $9000
|
|
cp $98 ;>=$9800?
|
|
jr c,.allSet
|
|
|
|
sub $10 ;signed #'s means >$9800 should be $8800+
|
|
|
|
.allSet
|
|
ld h,a ;a into h; hl is now $9000+/-offset
|
|
|
|
pop af
|
|
ret
|
|
|
|
TileIndexEToAddressDE:
|
|
push af
|
|
|
|
;shift "e" 4 left and into a
|
|
xor a ;clear a to zero (new high byte)
|
|
sla e ;shift into carry
|
|
rla ;carry into a
|
|
sla e ;repeat total of 4 times
|
|
rla ;carry into a
|
|
sla e
|
|
rla
|
|
sla e
|
|
rla
|
|
or $90 ;add base addr of $9000
|
|
cp $98
|
|
jr c,.allSet
|
|
|
|
sub $10
|
|
|
|
.allSet
|
|
ld d,a ;a into d; de is now $9000+/-offset
|
|
|
|
pop af
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: TileCopyRotateCCW
|
|
; Arguments: l - Source tile index (0-255)
|
|
; e - Dest tile index
|
|
; Description: Copies pixels from source tile to dest tile, rotating
|
|
; 90 degrees counter clock-wise in the process
|
|
; Note: Assumes VRAM to be already accessible
|
|
;---------------------------------------------------------------------
|
|
TileCopyRotateCCW:
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call TileCopyIndicesToAddresses
|
|
|
|
;Set up outer loop
|
|
ld a,8 ;outer loop 8 times
|
|
|
|
;Beginning of outer loop / Set up inner loop
|
|
.outer1 push de ;save source start
|
|
push af ;save outer loop counter
|
|
ld a,8 ;inner loop 8 times
|
|
|
|
.inner1 push af ;save loop counter on stack
|
|
ld a,[de] ;get next even byte
|
|
rrca
|
|
rl b
|
|
ld [de],a
|
|
inc de
|
|
ld a,[de] ;get next odd byte
|
|
rrca
|
|
rl c
|
|
ld [de],a
|
|
inc de
|
|
|
|
pop af ;retrieve loop counter
|
|
dec a
|
|
jr nz,.inner1
|
|
|
|
|
|
ld a,b ;save next two bytes of result
|
|
ld [hl+],a
|
|
ld a,c
|
|
ld [hl+],a
|
|
|
|
pop af ;retrieve outer loop counter
|
|
pop de ;reset srcptr to start of tile
|
|
dec a
|
|
jr nz,.outer1
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routines: TileCopy
|
|
; TileCopyShiftLeft
|
|
; TileCopyShiftRight
|
|
; TileCopyShiftLeftOverlay
|
|
; TileCopyShiftRightOverlay
|
|
; TileCopyShiftUp
|
|
; TileCopyShiftDown
|
|
; Arguments: e - Source tile index (0-15)
|
|
; l - Dest tile index (0-15)
|
|
; Description: Copies tiles while shifting 4 pixels in the specified
|
|
; direction (except for plain TileCopy). Tile patterns
|
|
; should be stored in $c000-$c0ff. "Overlay" routines
|
|
; OR the source with the destination.
|
|
;---------------------------------------------------------------------
|
|
TileCopy:
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call TileCopyIndicesToAddresses
|
|
|
|
ld c,16 ;loop 16 times
|
|
.loop ld a,[de] ;get a byte
|
|
inc de
|
|
ld [hl+],a ;put it in dest
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
TileCopyShiftLeft:
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call TileCopyIndicesToAddresses
|
|
|
|
ld c,16 ;loop 16 times
|
|
.loop ld a,[de] ;get a byte
|
|
inc de
|
|
swap a ;flip nibbles
|
|
and $f0 ;clear out lower four bits
|
|
ld [hl+],a ;put it in dest
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
TileCopyShiftRight:
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call TileCopyIndicesToAddresses
|
|
|
|
ld c,16 ;loop 16 times
|
|
.loop ld a,[de] ;get a byte
|
|
inc de
|
|
swap a ;flip nibbles
|
|
and $0f ;clear out upper four bits
|
|
ld [hl+],a ;put it in dest
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
TileCopyShiftLeftOverlay:
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call TileCopyIndicesToAddresses
|
|
|
|
ld c,16 ;loop 16 times
|
|
.loop ld a,[de] ;get a byte
|
|
inc de
|
|
swap a ;flip nibbles
|
|
and $f0 ;clear out lower four bits
|
|
or [hl] ;combine with dest
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
TileCopyShiftRightOverlay:
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
;Get tile addresses
|
|
call TileCopyIndicesToAddresses
|
|
|
|
ld c,16 ;loop 16 times
|
|
.loop ld a,[de] ;get a byte
|
|
inc de
|
|
swap a ;flip nibbles
|
|
and $0f ;clear out upper four bits
|
|
or [hl] ;combine with dest
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
TileCopyIndicesToAddresses:
|
|
push bc
|
|
ld c,4
|
|
ld h,0
|
|
ld d,0
|
|
.loop
|
|
sla l
|
|
rl h
|
|
sla e
|
|
rl d
|
|
dec c
|
|
jr nz,.loop
|
|
pop bc
|
|
ld a,((backBuffer>>8) & $ff)
|
|
add a,h
|
|
ld h,a
|
|
ld a,((backBuffer>>8) & $ff)
|
|
add a,d
|
|
ld d,a
|
|
ret
|
|
|
|
TileCopyShiftUp:
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call TileCopyIndicesToAddresses
|
|
|
|
ld a,e ;source += 8
|
|
add 8
|
|
ld e,a
|
|
|
|
ld c,8 ;loop 8 times
|
|
.loop ld a,[de] ;get a byte
|
|
inc de
|
|
ld [hl+],a ;put it in dest
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
;clear 4 rows (8 bytes)
|
|
ld c,8
|
|
xor a
|
|
.clear
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.clear
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
TileCopyShiftDown:
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call TileCopyIndicesToAddresses
|
|
|
|
;clear 4 rows (8 bytes)
|
|
ld c,8
|
|
xor a
|
|
.clear
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.clear
|
|
|
|
ld c,8 ;loop 8 times
|
|
.loop ld a,[de] ;get a byte
|
|
inc de
|
|
ld [hl+],a ;put it in dest
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: DuplicateTilesToSpriteMem
|
|
; Arguments: a - number of tiles to duplicate (1+)
|
|
; c - index of first tile in tile mem
|
|
; Alters: af
|
|
; Description: Copies {a} number of tiles (a*16 bytes) from $c000
|
|
; (backBuffer) to $8000 + c*16.
|
|
; Note: Uses current VRAM bank
|
|
;---------------------------------------------------------------------
|
|
DuplicateTilesToSpriteMem:
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld b,a ;tiles remaining
|
|
|
|
;de = $8000 + c*16
|
|
ld a,c
|
|
swap a
|
|
and %00001111
|
|
add $80
|
|
ld d,a
|
|
|
|
ld a,c
|
|
swap a
|
|
and %11110000
|
|
ld e,a
|
|
|
|
;hl = $c000
|
|
ld hl,backBuffer
|
|
|
|
.next_tile
|
|
;tiles 128-255 are in VRAM shared between sprites and tiles
|
|
;and do not need to be copied.
|
|
ld a,c
|
|
cp 128
|
|
jr nc,.after_copy
|
|
|
|
push bc
|
|
ld c,1 ;1*16 bytes
|
|
ld a,1 ;VRAM bank 1
|
|
call VMemCopy
|
|
pop bc
|
|
|
|
.after_copy
|
|
;de+=16, hl+=16
|
|
call AddHL16
|
|
call AddDE16
|
|
|
|
;tileNum++, tilesRemaining--
|
|
inc c
|
|
dec b
|
|
jr nz,.next_tile
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
IF 0
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld b,a
|
|
ld l,c
|
|
call TileIndexLToAddressHL
|
|
|
|
.next_tile
|
|
ld a,h
|
|
cp $90
|
|
jr c,.no_copy_necessary
|
|
|
|
;dest addr = source addr - $1000
|
|
ld a,h
|
|
sub $10
|
|
ld d,a
|
|
ld e,l
|
|
|
|
;source addr
|
|
ld hl,$c000
|
|
ld c,16
|
|
|
|
.copy ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
dec c
|
|
jr nz,.copy
|
|
jr .after_copy
|
|
|
|
.no_copy_necessary
|
|
ld de,16
|
|
add hl,de
|
|
|
|
.after_copy
|
|
dec b
|
|
jr nz,.next_tile
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
ENDC
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: GenerateFacings
|
|
; Arguments: a - index (0-255) of the first of two consecutive
|
|
; tiles (frame1 and frame2) which should be facing
|
|
; east. Tiles should be located at $c000
|
|
; (backBuffer).
|
|
; [curObjWidthHeight] - copy of FG attribute flags
|
|
; Description: Creates the following tiles at $9000-$97ff (indices
|
|
; 0-127) and $8800-$8fff (128-255):
|
|
; a - North facing, frame 1
|
|
; a+1 - Top half of North facing, frame 2
|
|
; a+2 - Bottom half of North facing, frame 2
|
|
; a+3...a+5 - East facing (frame1, left frame2, right
|
|
; frame2)
|
|
;
|
|
; Duplicates any tiles in area $9000-$9800 into
|
|
; $8000-$8800 for tile<->sprite purposes
|
|
;---------------------------------------------------------------------
|
|
GenerateFacings::
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld c,a ;starting index
|
|
|
|
ldio a,[curObjWidthHeight] ;retrieve flags
|
|
bit BIT_2X2,a
|
|
jr z,.generate1x1
|
|
jp .generate2x2
|
|
|
|
.generate1x1
|
|
ld a,[curObjWidthHeight] ;attribute flags
|
|
bit BIT_NOROTATE,a
|
|
jr nz,.createNonRotatedSprites
|
|
|
|
.createRotatedSprites
|
|
;create non-split frames for sprites
|
|
ld e,0 ;source index
|
|
ld l,2 ;dest index
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
inc l
|
|
call TileCopyRotateCCW
|
|
jr .copyTilesToSpriteMem
|
|
|
|
.createNonRotatedSprites
|
|
;create non-split frames for sprites
|
|
ld e,0 ;source index
|
|
ld l,2 ;dest index
|
|
call TileCopy
|
|
inc e
|
|
inc l
|
|
call TileCopy
|
|
|
|
.copyTilesToSpriteMem
|
|
ld a,4
|
|
call DuplicateTilesToSpriteMem
|
|
|
|
;East-facing frames
|
|
ld e,0 ;source index in e
|
|
ld l,3 ;dest index in l
|
|
call TileCopy
|
|
inc e ;source to next frame
|
|
inc l ;set dest index to next frame
|
|
call TileCopyShiftRight
|
|
inc l
|
|
call TileCopyShiftLeft
|
|
|
|
ld a,[curObjWidthHeight] ;attribute flags
|
|
bit BIT_NOROTATE,a
|
|
jr nz,.copyNorthNoRotate
|
|
|
|
;North facings
|
|
ld l,0 ;dest is +0 (North)
|
|
ld e,3 ;Set source ptr to +3 (East)
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
inc l
|
|
inc l
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
dec l
|
|
call TileCopyRotateCCW
|
|
jr .copyBufferToVMem
|
|
|
|
.copyNorthNoRotate
|
|
ld e,1
|
|
ld l,6
|
|
call TileCopy
|
|
ld e,6
|
|
ld l,1
|
|
call TileCopyShiftDown
|
|
inc l
|
|
call TileCopyShiftUp
|
|
|
|
.copyBufferToVMem
|
|
;Copy 6 tiles beginning at $c000+ to $9000+(c*16).
|
|
;Next location after $97f0 is $8800.
|
|
ld a,c
|
|
cp 122 ;122+6 < 128
|
|
jr c,.copySet ;to $9000+
|
|
|
|
cp 128
|
|
jr nc,.copySet ;to $8800+
|
|
|
|
.copyOneByOne ;split across different banks
|
|
ld e,c
|
|
call TileIndexEToAddressDE ;destination
|
|
ld hl,$c000 ;source
|
|
|
|
ld b,6 ;tiles to copy
|
|
ld c,1 ;copy 16 bytes at a time
|
|
|
|
.nextTile
|
|
ld a,1 ;VRAM Bank 1
|
|
call VMemCopy
|
|
call AddDE16
|
|
call AddHL16
|
|
ld a,d
|
|
cp $98
|
|
jr nz,.destPtrOkay
|
|
ld d,$88
|
|
.destPtrOkay
|
|
dec b
|
|
jr nz,.nextTile
|
|
jp .done
|
|
|
|
.copySet
|
|
ld e,a
|
|
call TileIndexEToAddressDE
|
|
ld hl,$c000
|
|
ld c,6 ;6*16
|
|
ld a,1
|
|
call VMemCopy
|
|
jp .done
|
|
|
|
.generate2x2
|
|
;East-facing 2x2
|
|
ld e,0 ;source index in e
|
|
ld l,10 ;dest index in l
|
|
call TileCopy
|
|
inc e
|
|
inc l
|
|
call TileCopy
|
|
inc e
|
|
inc l
|
|
call TileCopy
|
|
inc e
|
|
inc l
|
|
call TileCopy
|
|
|
|
inc e
|
|
inc l
|
|
call TileCopyShiftRight
|
|
inc l
|
|
call TileCopyShiftLeft
|
|
inc e
|
|
call TileCopyShiftRightOverlay
|
|
inc l
|
|
call TileCopyShiftLeft
|
|
|
|
inc e
|
|
inc l
|
|
call TileCopyShiftRight
|
|
inc l
|
|
call TileCopyShiftLeft
|
|
inc e
|
|
call TileCopyShiftRightOverlay
|
|
inc l
|
|
call TileCopyShiftLeft
|
|
|
|
ld e,10
|
|
ld l,2
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
ld l,0
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
ld l,3
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
ld l,1
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
ld l,8
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
ld l,6
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
ld l,4
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
ld l,9
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
ld l,7
|
|
call TileCopyRotateCCW
|
|
inc e
|
|
ld l,5
|
|
call TileCopyRotateCCW
|
|
|
|
;Copy 20 tiles beginning at $c000+ to $9000+(c*16).
|
|
;Next location after $97f0 is $8800.
|
|
ld a,c
|
|
cp 108 ;108+20 < 128
|
|
jr c,.copySet20 ;to $9000+
|
|
|
|
cp 128
|
|
jr nc,.copySet20 ;to $8800+
|
|
|
|
.copyOneByOne20 ;split across different banks
|
|
ld e,c
|
|
call TileIndexEToAddressDE ;destination
|
|
ld hl,$c000 ;source
|
|
|
|
ld b,20 ;tiles to copy
|
|
ld c,1 ;copy 16 bytes at a time
|
|
|
|
.nextTile20
|
|
ld a,1 ;VRAM Bank 1
|
|
call VMemCopy
|
|
call AddDE16
|
|
call AddHL16
|
|
ld a,d
|
|
cp $98
|
|
jr nz,.destPtrOkay20
|
|
ld d,$88
|
|
.destPtrOkay20
|
|
dec b
|
|
jr nz,.nextTile20
|
|
jr .done
|
|
|
|
.copySet20
|
|
ld e,a
|
|
call TileIndexEToAddressDE
|
|
ld hl,$c000
|
|
ld c,20 ;20*16
|
|
ld a,1
|
|
call VMemCopy
|
|
jp .done
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
SECTION "Graphics2",ROM0
|
|
;---------------------------------------------------------------------
|
|
; Routine: LoadGraphics
|
|
; Arguments:
|
|
;---------------------------------------------------------------------
|
|
LoadGraphics:
|
|
ld a,BANK(BGTiles)
|
|
call SetActiveROM
|
|
|
|
;switch to vram bank 1
|
|
ld a,1
|
|
;ld [$ff4f],a
|
|
call .loadBlank
|
|
|
|
;switch to vram bank 0
|
|
xor a
|
|
;ld [$ff4f],a
|
|
call .loadBlank
|
|
|
|
;load 86 explosion sprites
|
|
ld a,MAP0ROM
|
|
call SetActiveROM
|
|
xor a
|
|
ld c,86 ;#sprites
|
|
ld de,$8000
|
|
ld hl,explosionSprites
|
|
call VMemCopy
|
|
|
|
IF 0
|
|
;load 80 explosion sprites
|
|
ld a,MAP0ROM
|
|
call SetActiveROM
|
|
ld hl,explosionSprites
|
|
ld de,$8000
|
|
ld b,80 ;# sprites
|
|
.outer ld c,16 ;16 bytes each
|
|
.inner ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
dec c
|
|
jr nz,.inner
|
|
dec b
|
|
jr nz,.outer
|
|
ENDC
|
|
|
|
ret
|
|
|
|
.loadBlank
|
|
;load a blank tile to tile 0 of VRAM bank "a"
|
|
;xor a
|
|
ld c,1 ;1 tile
|
|
ld de,$9000
|
|
ld hl,BGTiles ;1st tile is blank
|
|
call VMemCopy
|
|
ret
|
|
|
|
IF 0
|
|
ld hl,blankTile ;address to get graphics from
|
|
ld de, $9000 ;destination address (Tile VRAM)
|
|
ld c, 1 * 16 ;copy 1 tile of 16 bytes
|
|
.loop ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
dec c
|
|
jr nz,.loop
|
|
ret
|
|
ENDC
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: LoadSprites
|
|
; Arguments: a - ROM bank containing sprites
|
|
; c - number of sprites to load
|
|
; hl - starting addr of sprites to load
|
|
; de - dest addr of sprites to load
|
|
; Alters: af
|
|
; Description: Loads specified number of sprites to VRAM bank 0
|
|
; specified location. Switches back to CLASSROM when
|
|
; done. Must be done on VBLANK or when display is off
|
|
;---------------------------------------------------------------------
|
|
LoadSprites::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call SetActiveROM
|
|
xor a ;VRAM bank 0
|
|
ld [$ff4f],a
|
|
|
|
.outer ld b,16 ;copy 16 bytes
|
|
.inner ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
dec b
|
|
jr nz,.inner
|
|
dec c
|
|
jr nz,.outer
|
|
|
|
ld a,CLASSROM
|
|
call SetActiveROM
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: PrepareForInitialMapDraw
|
|
; Description: Sets relevant variables so the map can be drawn
|
|
;---------------------------------------------------------------------
|
|
PrepareForInitialMapDraw::
|
|
call AdjustCameraToHero
|
|
call RestrictCameraToBounds
|
|
|
|
ld hl,mapLeft
|
|
ld a,[desiredMapLeft]
|
|
ld [hl+],a ;mapLeft
|
|
add 20
|
|
ld [hl+],a ;mapRight
|
|
inc a
|
|
ld [hl+],a ;mapRightPlusOne
|
|
|
|
ld a,[desiredMapTop]
|
|
ld [hl+],a ;mapTop
|
|
add 18
|
|
ld [hl+],a ;mapBottom
|
|
inc a
|
|
ld [hl+],a ;mapBottomPlusOne
|
|
|
|
xor a
|
|
ld [curPixelOffset_x],a
|
|
ld [curPixelOffset_y],a
|
|
ld [desiredPixelOffset_x],a
|
|
ld [desiredPixelOffset_y],a
|
|
ld [scrollAccelState_x],a
|
|
ld [scrollAccelState_y],a
|
|
|
|
;set up a table for speedy AI
|
|
;east offset is +1
|
|
ld a,1
|
|
ld [mapOffsetEast],a ;low byte
|
|
xor a
|
|
ld [mapOffsetEast+1],a ;high byte
|
|
|
|
;west offset is -1
|
|
ld a,$ff
|
|
ld [mapOffsetWest],a
|
|
ld [mapOffsetWest+1],a
|
|
|
|
;south offset is +pitch
|
|
xor a
|
|
ld [mapOffsetSouth+1],a
|
|
ld a,[mapPitch]
|
|
ld [mapOffsetSouth],a
|
|
|
|
;north offset is -pitch
|
|
cpl
|
|
inc a
|
|
ld [mapOffsetNorth],a
|
|
ld a,$ff
|
|
ld [mapOffsetNorth+1],a
|
|
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: AdjustCameraToHero
|
|
; Arguments: None.
|
|
; Description: Centers camera on hero, then adjusts so that maximum
|
|
; amount of space on in all 4 directions is visible
|
|
;
|
|
;---------------------------------------------------------------------
|
|
AdjustCameraToHero::
|
|
ld a,[displayType]
|
|
or a
|
|
jr z,.mapType
|
|
|
|
;cinema type
|
|
xor a
|
|
ld [camera_i],a
|
|
ld [camera_j],a
|
|
ret
|
|
|
|
.mapType
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld a,OBJBANK ;Get Location of hero
|
|
ld [$ff70],a
|
|
|
|
;hl = &heroX_object
|
|
LDHL_CURHERODATA HERODATA_OBJ
|
|
|
|
ld a,[hl+]
|
|
ld e,a
|
|
ld a,[hl]
|
|
ld d,a
|
|
|
|
ld a,[de]
|
|
ld l,a
|
|
ld [tempL],a
|
|
inc de
|
|
ld a,[de]
|
|
ld h,a
|
|
ld [tempH],a
|
|
|
|
call ConvertLocHLToXY ;convert to x,y indices
|
|
ld a,h
|
|
ld [camera_i],a
|
|
ld a,l
|
|
ld [camera_j],a
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
ldio a,[firstMonster]
|
|
ld c,a ;c class of first monster
|
|
|
|
;find nearest wall to the north of location
|
|
ld a,[tempL] ;hl will track location
|
|
ld l,a
|
|
ld a,[tempH]
|
|
ld h,a
|
|
ld b,0 ;b will track north offset
|
|
ld d,$ff ;de = -pitch
|
|
ld a,[mapPitch]
|
|
cpl
|
|
add 1
|
|
ld e,a
|
|
push hl
|
|
|
|
.nloop add hl,de
|
|
inc b
|
|
ld a,[hl]
|
|
or a
|
|
jr z,.nloop ;nothing at all here
|
|
cp c ;found something, check if monster
|
|
jr nc,.nloop ;don't count monsters
|
|
call GetBGAttributes
|
|
and (BG_FLAG_WALKOVER|BG_FLAG_SHOOTOVER)
|
|
ld a,MAPBANK
|
|
ldio [$ff70],a
|
|
jr nz,.nloop
|
|
|
|
;b is tile distance of closest wall to the north
|
|
pop hl ;retrieve original location
|
|
push bc ;save north count b
|
|
ld b,0 ;b counts clear tiles to south
|
|
ld d,0 ;de is offset to go south
|
|
ld a,[mapPitch]
|
|
ld e,a
|
|
push hl ;push original location again
|
|
|
|
.sloop add hl,de
|
|
inc b
|
|
ld a,[hl]
|
|
or a
|
|
jr z,.sloop
|
|
cp c
|
|
jr nc,.sloop
|
|
call GetBGAttributes
|
|
and (BG_FLAG_WALKOVER|BG_FLAG_SHOOTOVER)
|
|
ld a,MAPBANK
|
|
ldio [$ff70],a
|
|
jr nz,.sloop
|
|
|
|
;now b is distance of closest wall to south
|
|
pop hl ;retrieve original location
|
|
ld a,b
|
|
pop bc ;retrieve north distance
|
|
ld c,a ;b=north, c=south dist
|
|
|
|
;---------------Scroll Camera South---------------------------
|
|
;while(s_dist >= 10 && n_dist<8){
|
|
; move camera to south;
|
|
; south dist--;
|
|
; north dist++;
|
|
;}
|
|
.cam_south_loop
|
|
ld a,c ;s_dist >= 10?
|
|
cp 10
|
|
jr c,.cam_south_loopDone
|
|
|
|
ld a,b
|
|
cp 7
|
|
jr nc,.cam_south_loopDone ;n_dist < 8?
|
|
|
|
call .moveCameraSouth
|
|
jr .cam_south_loop
|
|
|
|
.cam_south_loopDone
|
|
|
|
;---------------Scroll Camera North---------------------------
|
|
;while(n_dist >= 9 && s_dist<9){
|
|
; move camera to north;
|
|
; south dist++;
|
|
; north dist--;
|
|
;}
|
|
.cam_north_loop
|
|
ld a,b ;n_dist >= 9?
|
|
cp 9
|
|
jr c,.cam_north_loopDone
|
|
|
|
ld a,c
|
|
cp 9
|
|
jr nc,.cam_north_loopDone ;s_dist < 9?
|
|
|
|
call .moveCameraNorth
|
|
jr .cam_north_loop
|
|
|
|
.cam_north_loopDone
|
|
ld a,c ;save distances for later use
|
|
ld [distToWall_S],a
|
|
ld a,b
|
|
ld [distToWall_N],a
|
|
|
|
;----------------------------
|
|
; Handle east/west scrolling
|
|
;----------------------------
|
|
ld b,0 ;b counts clear tiles to west
|
|
ld d,h ;save hl in de
|
|
ld e,l
|
|
ldio a,[firstMonster]
|
|
ld c,a
|
|
dec hl
|
|
|
|
.wloop inc b
|
|
ld a,[hl-] ;get location
|
|
or a
|
|
jr z,.wloop ;loop if empty
|
|
cp c
|
|
jr nc,.wloop ;loop if monster
|
|
call GetBGAttributes
|
|
and (BG_FLAG_WALKOVER|BG_FLAG_SHOOTOVER)
|
|
ld a,MAPBANK
|
|
ldio [$ff70],a
|
|
jr nz,.wloop
|
|
|
|
;now b is distance of closest wall to west
|
|
ld h,d ;set hl back to original location
|
|
ld l,e
|
|
ld d,b ;store west distance in d
|
|
ld b,0
|
|
inc hl
|
|
|
|
.eloop inc b
|
|
ld a,[hl+] ;get location
|
|
or a
|
|
jr z,.eloop ;loop if empty
|
|
cp c
|
|
jr nc,.eloop ;loop if monster
|
|
call GetBGAttributes
|
|
and (BG_FLAG_WALKOVER|BG_FLAG_SHOOTOVER)
|
|
ld a,MAPBANK
|
|
ldio [$ff70],a
|
|
jr nz,.eloop
|
|
|
|
;now b is distance of closest wall to east
|
|
ld c,b ;b=west, c=east dist
|
|
ld b,d
|
|
|
|
;---------------Scroll Camera East----------------------------
|
|
;while(e_dist >= 11 && w_dist<9){
|
|
; move camera to east;
|
|
; east dist--;
|
|
; west dist++;
|
|
;}
|
|
.cam_east_loop
|
|
ld a,c ;e_dist >= 11?
|
|
cp 11
|
|
jr c,.cam_east_loopDone
|
|
|
|
ld a,b
|
|
cp 9
|
|
jr nc,.cam_east_loopDone ;w_dist < 10?
|
|
|
|
ld a,[camera_i]
|
|
inc a
|
|
ld [camera_i],a
|
|
dec c
|
|
inc b
|
|
jr .cam_east_loop
|
|
|
|
.cam_east_loopDone
|
|
|
|
;---------------Scroll Camera West----------------------------
|
|
;while(w_dist >= 10 && e_dist<10){
|
|
; move camera to west;
|
|
; east dist++;
|
|
; west dist--;
|
|
;}
|
|
.cam_west_loop
|
|
ld a,b ;w_dist >= 10?
|
|
cp 10
|
|
jr c,.cam_west_loopDone
|
|
|
|
ld a,c
|
|
cp 9
|
|
jr nc,.cam_west_loopDone ;e_dist < 10?
|
|
|
|
ld a,[camera_i]
|
|
dec a
|
|
ld [camera_i],a
|
|
inc c
|
|
dec b
|
|
jr .cam_west_loop
|
|
|
|
.cam_west_loopDone
|
|
ld a,c ;save distances for later use
|
|
ld [distToWall_E],a
|
|
ld a,b
|
|
ld [distToWall_W],a
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
.moveCameraSouth
|
|
ld a,[camera_j]
|
|
inc a
|
|
ld [camera_j],a
|
|
dec c
|
|
inc b
|
|
ret
|
|
|
|
.moveCameraNorth
|
|
ld a,[camera_j]
|
|
dec a
|
|
ld [camera_j],a
|
|
inc c
|
|
dec b
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: GentleCameraAdjust
|
|
; Arguments: None.
|
|
; Description: Adjusts the camera to the hero but then goes with the
|
|
; old camera position if it doesn't make much difference
|
|
;---------------------------------------------------------------------
|
|
GentleCameraAdjust::
|
|
ld a,[displayType]
|
|
or a
|
|
ret nz ;done if cinema display type
|
|
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
;save previous camera i,j
|
|
ld a,[camera_i]
|
|
ld b,a
|
|
ld a,[camera_j]
|
|
ld c,a
|
|
push bc
|
|
|
|
call AdjustCameraToHero
|
|
|
|
pop bc ;retrieve old camera coords
|
|
ld a,[camera_i]
|
|
cp b
|
|
jr z,.checkCamera_j ;new_i==old_i, don't bother
|
|
jr c,.new_i_lt_old_i
|
|
|
|
;new i > old i
|
|
sub b ;d = new_i - old_i
|
|
ld d,a
|
|
ld a,[distToWall_E] ;a = dist_E + offset
|
|
add d
|
|
cp 11
|
|
jr c,.useOldCamera_i ;only good if east dist < 11
|
|
jr .checkCamera_j
|
|
|
|
.new_i_lt_old_i
|
|
;new i < old i
|
|
sub b ;d = old_i - new_i
|
|
cpl
|
|
inc a
|
|
ld d,a
|
|
|
|
ld a,[distToWall_W]
|
|
add d
|
|
cp 9
|
|
jr c,.useOldCamera_i ;only good if west dist < 10
|
|
jr .checkCamera_j
|
|
|
|
.useOldCamera_i
|
|
;we can use the old camera pos and be less jerky
|
|
ld a,b
|
|
ld [camera_i],a
|
|
|
|
.checkCamera_j
|
|
ld a,[camera_j]
|
|
cp c
|
|
jr z,.done ;new_j==old_j, don't bother
|
|
jr c,.new_j_lt_old_j
|
|
|
|
;new j > old j
|
|
sub c ;d = new_j - old_j
|
|
ld d,a
|
|
ld a,[distToWall_S] ;a = dist_S + offset
|
|
add d
|
|
cp 10
|
|
jr c,.useOldCamera_j ;only good if south dist < 10
|
|
jr .done
|
|
|
|
.new_j_lt_old_j
|
|
;new j < old j
|
|
sub c ;d = old_j - new_j
|
|
cpl
|
|
inc a
|
|
ld d,a
|
|
|
|
ld a,[distToWall_N]
|
|
add d
|
|
cp 9
|
|
jr c,.useOldCamera_j ;only good if north dist < 9
|
|
jr .done
|
|
|
|
.useOldCamera_j
|
|
;we can use the old camera pos and be less jerky
|
|
ld a,c
|
|
ld [camera_j],a
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: RestrictCameraToBounds
|
|
; Arguments: None.
|
|
;---------------------------------------------------------------------
|
|
RestrictCameraToBounds::
|
|
ld a,[displayType]
|
|
or a
|
|
jr nz,.cinemaType
|
|
|
|
push hl
|
|
|
|
;set map left/right based on camera_i
|
|
ld a,[camera_i]
|
|
sub 9
|
|
jr z,.left_le_0
|
|
jr nc,.left_gt_0
|
|
|
|
.left_le_0
|
|
ld a,1 ;set to 1 if < 1
|
|
|
|
.left_gt_0
|
|
ld hl,mapMaxLeft
|
|
cp [hl]
|
|
jr z,.left_le_max
|
|
jr c,.left_le_max
|
|
|
|
ld a,[hl] ;left = maxLeft
|
|
|
|
.left_le_max
|
|
ld [desiredMapLeft],a
|
|
|
|
;now see about top/bottom boundaries using camera_j
|
|
ld a,[camera_j]
|
|
sub 8
|
|
jr z,.top_le_0
|
|
jr nc,.top_gt_0
|
|
|
|
.top_le_0
|
|
ld a,1 ;set to one if less than one
|
|
|
|
.top_gt_0
|
|
ld hl,mapMaxTop
|
|
cp [hl]
|
|
jr z,.top_le_max
|
|
jr c,.top_le_max
|
|
|
|
ld a,[hl] ;top = maxTop
|
|
|
|
.top_le_max
|
|
ld [desiredMapTop],a
|
|
|
|
pop hl
|
|
ret
|
|
|
|
.cinemaType
|
|
push hl
|
|
|
|
;set map left/right based on camera_i
|
|
ld a,[camera_i]
|
|
sub 9
|
|
jr z,.left_ge_0
|
|
jr nc,.left_ge_0
|
|
|
|
.left_lt_0
|
|
xor a ;set to 0 if < 0
|
|
|
|
.left_ge_0
|
|
ld hl,mapMaxLeft
|
|
cp [hl]
|
|
jr z,.left_le_max2
|
|
jr c,.left_le_max2
|
|
|
|
ld a,[hl] ;left = maxLeft
|
|
|
|
.left_le_max2
|
|
ld [desiredMapLeft],a
|
|
|
|
;now see about top/bottom boundaries using camera_j
|
|
ld a,[camera_j]
|
|
sub 8
|
|
jr z,.top_ge_0
|
|
jr nc,.top_ge_0
|
|
|
|
.top_lt_0
|
|
xor a ;set to zero if less than zero
|
|
|
|
.top_ge_0
|
|
ld hl,mapMaxTop
|
|
cp [hl]
|
|
jr z,.top_le_max2
|
|
jr c,.top_le_max2
|
|
|
|
ld a,[hl] ;top = maxTop
|
|
|
|
.top_le_max2
|
|
ld [desiredMapTop],a
|
|
|
|
pop hl
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: ScrollToCamera
|
|
; Description: Scrolls from old camera view to new camera position.
|
|
; Increments of 2 pixels if difference < 4 tiles,
|
|
; increments of 4 pixels if >= 4 tiles
|
|
; Update: Uses [scrollSpeed][7:4] for fast, [3:0] slow
|
|
; instead of 4 and 2.
|
|
;---------------------------------------------------------------------
|
|
ScrollToCamera::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
;calculate tiles different in x & store in d
|
|
ld a,[mapLeft]
|
|
ld b,a
|
|
ld a,[desiredMapLeft]
|
|
sub b
|
|
jr nc,.gotPositiveXDiff
|
|
cpl
|
|
inc a
|
|
.gotPositiveXDiff
|
|
ld d,a
|
|
|
|
;calculate tiles different in y & store in e
|
|
ld a,[mapTop]
|
|
ld b,a
|
|
ld a,[desiredMapTop]
|
|
sub b
|
|
jr nc,.gotPositiveYDiff
|
|
cpl
|
|
inc a
|
|
.gotPositiveYDiff
|
|
ld e,a
|
|
|
|
;setup d,e with x-pixel step-size and max value
|
|
push de
|
|
ld a,d
|
|
cp FAST_SCROLL_THRESHOLD
|
|
jr c,.setupXForSlow
|
|
ld a,[scrollAccelState_x]
|
|
or a
|
|
jr z,.setupXForSlow
|
|
|
|
;get fast scroll speed in 9
|
|
ldio a,[scrollSpeed]
|
|
swap a
|
|
and $0f
|
|
ld d,a
|
|
;ld a,8
|
|
;sub d
|
|
;ld e,a
|
|
;ld d,4
|
|
;ld e,4
|
|
|
|
;ld a,[desiredPixelOffset_x] ;make sure its a multiple of 4
|
|
;and %00000100
|
|
;ld [desiredPixelOffset_x],a
|
|
|
|
jr .checkLeft
|
|
.setupXForSlow
|
|
;get slow scroll speed in d
|
|
ldio a,[scrollSpeed]
|
|
and $0f
|
|
ld d,a
|
|
|
|
.checkLeft
|
|
;make sure current pixel offset is an even multiple of the speed
|
|
;offset &= ~(speed - 1)
|
|
;off mask off dec cpl
|
|
;1 - and %111 0001 0000 1111
|
|
;2 - and %110 0010 0001 1110
|
|
;4 - and %100 0100 0011 1100
|
|
;8 - and %000 1000 0111 1000
|
|
ld a,d
|
|
dec a
|
|
|
|
;first scroll sprites right by value to be masked off
|
|
ld e,a
|
|
ld hl,desiredPixelOffset_x
|
|
ld a,[hl]
|
|
and e
|
|
push de
|
|
ld d,a
|
|
call ScrollSpritesRight
|
|
pop de
|
|
ld a,e
|
|
cpl
|
|
and %00000111
|
|
ld e,a
|
|
ld a,[hl]
|
|
and e
|
|
ld [hl],a
|
|
ld a,8
|
|
sub d
|
|
ld e,a
|
|
|
|
|
|
;ld a,[desiredPixelOffset_x] ;make sure its a multiple of 4
|
|
;and %00000100
|
|
;ld [desiredPixelOffset_x],a
|
|
|
|
ld a,[mapLeft]
|
|
ld b,a
|
|
ld a,[desiredMapLeft]
|
|
cp b
|
|
jr z,.checkPixelOffset
|
|
|
|
jr c,.desired_lt_current
|
|
jr .desired_gt_current
|
|
|
|
.checkPixelOffset
|
|
ld a,[desiredPixelOffset_x]
|
|
or a
|
|
jr z,.x_offsetOkay
|
|
|
|
push af
|
|
ld a,[scrollSprites]
|
|
or a
|
|
jr z,.afterScrollRight1
|
|
call ScrollSpritesRight
|
|
.afterScrollRight1
|
|
pop af
|
|
jr .scrollPixelsLeft
|
|
|
|
.x_offsetOkay
|
|
;reset accelleration if no scroll
|
|
xor a
|
|
ld [scrollAccelState_x],a
|
|
|
|
jr .leftRightAdjustDone
|
|
|
|
.desired_gt_current
|
|
;desired is > current
|
|
ld a,[scrollSprites]
|
|
or a
|
|
jr z,.afterScrollSpritesLeft1
|
|
call ScrollSpritesLeft
|
|
.afterScrollSpritesLeft1
|
|
ld a,[desiredPixelOffset_x]
|
|
cp e
|
|
jr nc,.atMaxLeftPixelOffset
|
|
|
|
add d
|
|
ld [desiredPixelOffset_x],a
|
|
jr .leftRightAdjustDone
|
|
|
|
.atMaxLeftPixelOffset
|
|
ld hl,scrollAccelState_x
|
|
inc [hl]
|
|
xor a
|
|
ld [desiredPixelOffset_x],a
|
|
ld a,b
|
|
inc a
|
|
jr .recalcMapLeftRight
|
|
|
|
.desired_lt_current
|
|
ld a,[scrollSprites]
|
|
or a
|
|
jr z,.afterScrollSpritesRight2
|
|
call ScrollSpritesRight
|
|
.afterScrollSpritesRight2
|
|
ld a,[desiredPixelOffset_x]
|
|
or a
|
|
jr z,.atMinLeftPixelOffset
|
|
|
|
.scrollPixelsLeft
|
|
sub d
|
|
ld [desiredPixelOffset_x],a
|
|
|
|
or a
|
|
jr nz,.leftRightAdjustDone
|
|
ld hl,scrollAccelState_x
|
|
inc [hl]
|
|
|
|
jr .leftRightAdjustDone
|
|
|
|
.atMinLeftPixelOffset
|
|
ld a,e
|
|
ld [desiredPixelOffset_x],a
|
|
ld a,b
|
|
dec a
|
|
|
|
.recalcMapLeftRight
|
|
ld hl,mapLeft
|
|
ld [hl+],a ;mapLeft, mapRight, mapRight+1
|
|
add 20
|
|
ld [hl+],a
|
|
inc a
|
|
ld [hl+],a
|
|
|
|
.leftRightAdjustDone
|
|
;setup d,e with y-pixel step-size and max value
|
|
pop de
|
|
ld a,e
|
|
cp FAST_SCROLL_THRESHOLD
|
|
jr c,.setupYForSlow
|
|
or a
|
|
jr z,.setupYForSlow
|
|
|
|
ldio a,[scrollSpeed]
|
|
swap a
|
|
and $0f
|
|
ld d,a
|
|
ld a,8
|
|
sub d
|
|
ld e,a
|
|
;ld d,4
|
|
;ld e,4
|
|
;ld a,[desiredPixelOffset_y] ;make sure its a multiple of 4
|
|
;and %00000100
|
|
;ld [desiredPixelOffset_y],a
|
|
jr .checkTop
|
|
.setupYForSlow
|
|
ldio a,[scrollSpeed]
|
|
and $0f
|
|
ld d,a
|
|
ld a,8
|
|
sub d
|
|
ld e,a
|
|
;ld d,2
|
|
;ld e,6
|
|
|
|
.checkTop
|
|
;make sure current pixel offset is an even multiple of the speed
|
|
;offset &= ~(speed - 1)
|
|
;1 - and %111 0001 0000 1111
|
|
;2 - and %110 0010 0001 1110
|
|
;4 - and %100 0100 0011 1100
|
|
;8 - and %000 1000 0111 1000
|
|
|
|
ld a,d
|
|
dec a
|
|
|
|
;first scroll sprites down by value to be masked off to snap
|
|
;them to the new grid
|
|
ld e,a
|
|
ld hl,desiredPixelOffset_y
|
|
ld a,[hl]
|
|
and e
|
|
push de
|
|
ld d,a
|
|
call ScrollSpritesDown
|
|
pop de
|
|
ld a,e
|
|
|
|
cpl
|
|
and %00000111
|
|
ld e,a
|
|
ld a,[hl]
|
|
and e
|
|
ld [hl],a
|
|
ld a,8
|
|
sub d
|
|
ld e,a
|
|
|
|
ld a,[mapTop]
|
|
ld b,a
|
|
ld a,[desiredMapTop]
|
|
cp b
|
|
jr z,.checkPixelOffsetTB
|
|
jr c,.desired_tb_lt_current
|
|
jr .desired_tb_gt_current
|
|
|
|
.checkPixelOffsetTB
|
|
ld a,[desiredPixelOffset_y]
|
|
or a
|
|
jr z,.y_offsetOkay
|
|
|
|
push af
|
|
ld a,[scrollSprites]
|
|
or a
|
|
jr z,.afterScrollSpritesDown1
|
|
call ScrollSpritesDown
|
|
.afterScrollSpritesDown1
|
|
pop af
|
|
jr .scrollPixelsUp
|
|
|
|
.y_offsetOkay
|
|
;reset accelleration if no scroll
|
|
xor a
|
|
ld [scrollAccelState_y],a
|
|
|
|
jr .topBottomAdjustDone
|
|
|
|
.desired_tb_gt_current
|
|
;desired is > current
|
|
ld a,[scrollSprites]
|
|
or a
|
|
jr z,.afterScrollSpritesUp1
|
|
call ScrollSpritesUp
|
|
.afterScrollSpritesUp1
|
|
ld a,[desiredPixelOffset_y]
|
|
cp e
|
|
jr nc,.atMaxTopPixelOffset
|
|
|
|
add d
|
|
ld [desiredPixelOffset_y],a
|
|
jr .topBottomAdjustDone
|
|
|
|
.atMaxTopPixelOffset
|
|
ld hl,scrollAccelState_y
|
|
inc [hl]
|
|
|
|
xor a
|
|
ld [desiredPixelOffset_y],a
|
|
ld a,b
|
|
inc a
|
|
jr .recalcMapTopBottom
|
|
|
|
.desired_tb_lt_current
|
|
ld a,[scrollSprites]
|
|
or a
|
|
jr z,.afterScrollSpritesDown2
|
|
call ScrollSpritesDown
|
|
.afterScrollSpritesDown2
|
|
ld a,[desiredPixelOffset_y]
|
|
or a
|
|
jr z,.atMinTopPixelOffset
|
|
|
|
.scrollPixelsUp
|
|
sub d
|
|
ld [desiredPixelOffset_y],a
|
|
|
|
or a
|
|
jr nz,.topBottomAdjustDone
|
|
ld hl,scrollAccelState_y
|
|
inc [hl]
|
|
|
|
jr .topBottomAdjustDone
|
|
|
|
.atMinTopPixelOffset
|
|
ld a,e
|
|
ld [desiredPixelOffset_y],a
|
|
ld a,b
|
|
dec a
|
|
|
|
.recalcMapTopBottom
|
|
ld hl,mapTop
|
|
ld [hl+],a ;mapTop, mapBottom, mapBottom+1
|
|
add 18
|
|
ld [hl+],a
|
|
inc a
|
|
ld [hl+],a
|
|
|
|
.topBottomAdjustDone
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routines: ScrollSpritesLeft
|
|
; ScrollSpritesRight
|
|
; ScrollSpritesUp
|
|
; ScrollSpritesDown
|
|
; Arguments: d - pixels to scroll
|
|
; Alters: af
|
|
; Description: Scrolls each of the 40 sprites (if their y-pos!=0)
|
|
; "d" # of pixels in the desired direction.
|
|
;---------------------------------------------------------------------
|
|
ScrollSpritesLeft::
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
xor a
|
|
sub d
|
|
ld d,a
|
|
jr ScrollSpritesLRCommon
|
|
|
|
ScrollSpritesRight::
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ScrollSpritesLRCommon:
|
|
ld hl,spriteOAMBuffer
|
|
ld bc,3
|
|
ld e,40
|
|
|
|
.loop ld a,[hl+]
|
|
or a
|
|
jr z,.afterChange ;sprite inactive
|
|
|
|
ld a,[hl]
|
|
add d
|
|
ld [hl],a
|
|
|
|
.afterChange
|
|
add hl,bc
|
|
dec e
|
|
jr nz,.loop
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
ScrollSpritesUp::
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
xor a
|
|
sub d
|
|
ld d,a
|
|
jr ScrollSpritesUDCommon
|
|
|
|
ScrollSpritesDown::
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ScrollSpritesUDCommon:
|
|
ld hl,spriteOAMBuffer
|
|
ld bc,4
|
|
ld e,40
|
|
|
|
.loop ld a,[hl]
|
|
or a
|
|
jr z,.afterChange ;sprite inactive
|
|
|
|
add d
|
|
ld [hl],a
|
|
|
|
.afterChange
|
|
add hl,bc
|
|
dec e
|
|
jr nz,.loop
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: DrawMapToBackBuffer
|
|
; Description: Sets relevant variables so the map can be drawn
|
|
; Note: Uses [temp] to store tile attributes
|
|
;---------------------------------------------------------------------
|
|
DrawMapToBackBuffer::
|
|
ld a,[displayType]
|
|
or a
|
|
jr z,.mapType
|
|
|
|
jp DrawCinemaToBackBuffer
|
|
|
|
.mapType
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call SetupDrawCommon
|
|
|
|
.outer push bc ;save vertical count "b" on stack
|
|
push de ;save starting ptr to dest (hl) and source (de)
|
|
push hl
|
|
|
|
;----copy 21 bg tiles into backBuffer/attributeBuffer
|
|
;save starting point, copy tile pattern numbers
|
|
push de
|
|
push hl
|
|
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
ld b,((bgTileMap>>8) & $ff)
|
|
|
|
call .copy7BGTiles
|
|
call .copy7BGTiles
|
|
call .copy7BGTiles
|
|
|
|
;start over copying attributes
|
|
pop hl
|
|
pop de
|
|
push de
|
|
push hl
|
|
|
|
ld a,h ;backBuffer -> attributeBuffer
|
|
add 3
|
|
ld h,a
|
|
ld b,((bgAttributes>>8) & $ff)
|
|
call .copy7BGAttributes
|
|
call .copy7BGAttributes
|
|
call .copy7BGAttributes
|
|
|
|
;back to start again
|
|
pop hl
|
|
pop de
|
|
push de
|
|
push hl
|
|
|
|
;recopy FG tiles from shadow buffers
|
|
ld a,TILESHADOWBANK
|
|
ld [$ff70],a
|
|
|
|
ldio a,[firstMonster]
|
|
ld b,a
|
|
|
|
call .copy7FGTiles
|
|
call .copy7FGTiles
|
|
call .copy7FGTiles
|
|
|
|
pop hl
|
|
pop de
|
|
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
ld a,h
|
|
add 3
|
|
ld h,a
|
|
|
|
call .copy7FGAttributes
|
|
call .copy7FGAttributes
|
|
call .copy7FGAttributes
|
|
|
|
;row done
|
|
|
|
;---begin old code 3--------------------------------------------------
|
|
IF 0
|
|
|
|
;copy tile patterns & attributes for any BG tiles to ---------
|
|
;tile & attribute shadow buffers
|
|
|
|
;save starting point
|
|
push de
|
|
push hl
|
|
|
|
;use hl for map source / shadow buffer dest
|
|
ld h,d
|
|
ld l,e
|
|
|
|
;setup loop
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
ldio a,[firstMonster]
|
|
ld b,a
|
|
ld c,21
|
|
|
|
.copyBGTiles
|
|
ld a,[hl]
|
|
cp b
|
|
jr c,.isBGTile
|
|
inc hl
|
|
dec c
|
|
jr nz,.copyBGTiles
|
|
jr .copyBGTilesDone
|
|
|
|
.isBGTile
|
|
ld d,((bgTileMap>>8) & $ff)
|
|
ld e,a
|
|
ld a,TILESHADOWBANK
|
|
ld [$ff70],a
|
|
ld a,[de]
|
|
ld [hl],a
|
|
ld a,ATTRSHADOWBANK
|
|
ld [$ff70],a
|
|
ld d,((bgAttributes>>8) & $ff)
|
|
ld a,[de]
|
|
and %00000111
|
|
ld [hl+],a
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
dec c
|
|
jr nz,.copyBGTiles
|
|
|
|
.copyBGTilesDone
|
|
;retrieve starting point & save again
|
|
pop hl
|
|
pop de
|
|
push de
|
|
push hl
|
|
|
|
;copy set of 21 bytes from TILESHADOWBANK to backBuffer
|
|
ld a,TILESHADOWBANK
|
|
ld [$ff70],a
|
|
call .copy21
|
|
|
|
;retrieve starting point
|
|
pop hl
|
|
pop de
|
|
|
|
;copy set of 21 bytes from ATTRSHADOWBANK to backBuffer
|
|
ld a,h
|
|
add 3
|
|
ld h,a
|
|
ld a,ATTRSHADOWBANK
|
|
ld [$ff70],a
|
|
call .copy21
|
|
|
|
ENDC
|
|
;row done
|
|
;----end old code 3---------------------------------------------------
|
|
|
|
|
|
;------begin old code 2-----------------------------------------------
|
|
IF 0
|
|
;copy tile pattern numbers from map/buffer to backBuffer
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
ldio a,[firstMonster] ;get index of first fg class
|
|
ld b,a
|
|
ld c,21
|
|
push de
|
|
push hl
|
|
|
|
.copyTileNumbers
|
|
ld a,[de] ;next class number from map
|
|
cp b
|
|
jr nc,.isFGTile
|
|
|
|
;lookup tile used for background
|
|
push bc
|
|
ld b,((bgTileMap>>8) & $ff)
|
|
ld c,a
|
|
ld a,[bc]
|
|
ld [hl+],a
|
|
inc de
|
|
pop bc
|
|
|
|
dec c
|
|
jr nz,.copyTileNumbers
|
|
jr .setupCopyAttributes
|
|
|
|
.isFGTile
|
|
;lookup class number in tile shadow buffer
|
|
;push bc
|
|
ld a,TILESHADOWBANK
|
|
ld [$ff70],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
dec c
|
|
jr nz,.copyTileNumbers
|
|
|
|
.setupCopyAttributes
|
|
pop hl ;go back to start of line
|
|
pop de
|
|
ld a,h ;copy to attributeBuffer
|
|
add 3
|
|
ld h,a
|
|
ld c,21 ;loop 21 times
|
|
|
|
.copyAttributes
|
|
ld a,[de] ;next class number from map
|
|
cp b
|
|
jr nc,.isFGAttribute
|
|
|
|
;BG Attribute
|
|
push bc
|
|
ld b,((bgAttributes>>8) & $ff)
|
|
ld c,a
|
|
ld a,[bc]
|
|
and %00000111
|
|
ld [hl+],a
|
|
inc de
|
|
pop bc
|
|
dec c
|
|
jr nz,.copyAttributes
|
|
jr .rowDone
|
|
|
|
.isFGAttribute
|
|
ld a,ATTRSHADOWBANK
|
|
ld [$ff70],a
|
|
ld a,[de]
|
|
ld [hl+],a
|
|
inc de
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
dec c
|
|
jr nz,.copyAttributes
|
|
|
|
.rowDone
|
|
ENDC
|
|
;------end old code 2-----------------------------------------------
|
|
|
|
|
|
;old loop code
|
|
;-------old code begin------------------------------------------------
|
|
IF 0
|
|
ld a,MAPBANK ;set RAM bank to the map bank
|
|
ld [$ff70],a
|
|
ld c,21 ;times to loop horizontally
|
|
|
|
.inner push bc
|
|
ld a,[de] ;load a tile index from level map
|
|
cp b ;index of first monster
|
|
jr c,.isBGTile ;< first monster
|
|
|
|
.isFGTile
|
|
;retrieve FG tile info from shadow buffers parallel to main map
|
|
ld a,ATTRSHADOWBANK ;set RAM bank to the attribute shadow bank
|
|
ld [$ff70],a
|
|
ld a,[de] ;attributes
|
|
ldio [temp],a
|
|
ld a,TILESHADOWBANK ;set RAM bank to the tile shadow bank
|
|
ld [$ff70],a
|
|
ld a,[de] ;tile to draw
|
|
inc de
|
|
ld [hl],a ;store tile in backBuffer
|
|
ld a,MAPBANK ;set RAM bank to the map bank
|
|
ld [$ff70],a
|
|
jr .gotTile
|
|
|
|
.isBGTile
|
|
inc de
|
|
or a
|
|
jr z,.isNullTile
|
|
ld c,a
|
|
;ld a,TILEINDEXBANK ;select RAM bank of tile index maps
|
|
;ld [$ff70],a
|
|
ld b,((bgAttributes>>8)&$ff)
|
|
ld a,[bc] ;attributes for this tile
|
|
and %00000111 ;get palette only
|
|
ldio [temp],a ;store for later
|
|
ld b,((bgTileMap>>8)&$ff) ;get ptr to tile to draw in bc
|
|
ld a,[bc] ;get tile to draw
|
|
ld [hl],a ;store tile in backBuffer
|
|
jr .gotTile
|
|
|
|
.isNullTile
|
|
ld [temp],a ;attributes zero
|
|
ld [hl],a ;store tile in backBuffer
|
|
|
|
.gotTile
|
|
push hl
|
|
ld a,h
|
|
add 3 ;768 bytes to get from backbuffer to attr buffer
|
|
ld h,a
|
|
|
|
ld a,[temp] ;get attributes for this tile
|
|
ld [hl],a ;store attribute in buffer
|
|
|
|
pop hl ;back to map buffer
|
|
|
|
.afterDrawTile
|
|
inc hl
|
|
|
|
;inner loop termination test
|
|
pop bc
|
|
dec c
|
|
jr nz,.inner
|
|
ENDC
|
|
;-------old code end--------------------------------------------------
|
|
|
|
pop hl ;retrieve initial pointers
|
|
pop de
|
|
|
|
ld a,[mapPitch] ;mapPtr += mapPitch
|
|
add e
|
|
ld e,a
|
|
jr nc,.hlNoCarry
|
|
inc d
|
|
.hlNoCarry
|
|
|
|
ld a,32 ;bgTileMapPtr += 32
|
|
add l
|
|
ld l,a
|
|
jr nc,.deNoCarry
|
|
inc h
|
|
.deNoCarry
|
|
|
|
;loop the outer loop again?
|
|
pop bc
|
|
dec b
|
|
jr nz,.outer
|
|
|
|
call PostDrawCommon
|
|
|
|
.done ;map is drawn, bitch
|
|
ld a,MAPBANK ;set RAM bank to the map bank
|
|
ld [$ff00+$70],a
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
.copy7BGTiles
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
ld [hl+],a
|
|
ret
|
|
|
|
.copy7BGAttributes
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
and %00000111
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
and %00000111
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
and %00000111
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
and %00000111
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
and %00000111
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
and %00000111
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[bc]
|
|
and %00000111
|
|
ld [hl+],a
|
|
ret
|
|
|
|
.copy7FGTiles
|
|
ld a,[hl]
|
|
cp b
|
|
jr c,.notMonster0
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
.notMonster0
|
|
inc hl
|
|
inc de
|
|
ld a,[hl]
|
|
cp b
|
|
jr c,.notMonster1
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
.notMonster1
|
|
inc hl
|
|
inc de
|
|
ld a,[hl]
|
|
cp b
|
|
jr c,.notMonster2
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
.notMonster2
|
|
inc hl
|
|
inc de
|
|
ld a,[hl]
|
|
cp b
|
|
jr c,.notMonster3
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
.notMonster3
|
|
inc hl
|
|
inc de
|
|
ld a,[hl]
|
|
cp b
|
|
jr c,.notMonster4
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
.notMonster4
|
|
inc hl
|
|
inc de
|
|
ld a,[hl]
|
|
cp b
|
|
jr c,.notMonster5
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
.notMonster5
|
|
inc hl
|
|
inc de
|
|
ld a,[hl]
|
|
cp b
|
|
jr c,.notMonster6
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
.notMonster6
|
|
inc hl
|
|
inc de
|
|
ret
|
|
|
|
.copy7FGAttributes
|
|
ld a,[de]
|
|
cp b
|
|
jr c,.fgNotMonster0
|
|
ld a,ATTRSHADOWBANK
|
|
ld [$ff70],a
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
.fgNotMonster0
|
|
inc hl
|
|
inc de
|
|
ld a,[de]
|
|
cp b
|
|
jr c,.fgNotMonster1
|
|
ld a,ATTRSHADOWBANK
|
|
ld [$ff70],a
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
.fgNotMonster1
|
|
inc hl
|
|
inc de
|
|
ld a,[de]
|
|
cp b
|
|
jr c,.fgNotMonster2
|
|
ld a,ATTRSHADOWBANK
|
|
ld [$ff70],a
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
.fgNotMonster2
|
|
inc hl
|
|
inc de
|
|
ld a,[de]
|
|
cp b
|
|
jr c,.fgNotMonster3
|
|
ld a,ATTRSHADOWBANK
|
|
ld [$ff70],a
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
.fgNotMonster3
|
|
inc hl
|
|
inc de
|
|
ld a,[de]
|
|
cp b
|
|
jr c,.fgNotMonster4
|
|
ld a,ATTRSHADOWBANK
|
|
ld [$ff70],a
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
.fgNotMonster4
|
|
inc hl
|
|
inc de
|
|
ld a,[de]
|
|
cp b
|
|
jr c,.fgNotMonster5
|
|
ld a,ATTRSHADOWBANK
|
|
ld [$ff70],a
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
.fgNotMonster5
|
|
inc hl
|
|
inc de
|
|
ld a,[de]
|
|
cp b
|
|
jr c,.fgNotMonster6
|
|
ld a,ATTRSHADOWBANK
|
|
ld [$ff70],a
|
|
ld a,[de] ;get monster tile
|
|
ld [hl],a
|
|
ld a,MAPBANK
|
|
ld [$ff70],a
|
|
.fgNotMonster6
|
|
inc hl
|
|
inc de
|
|
ret
|
|
|
|
IF 0
|
|
;loop unrolled for max speed
|
|
.copy21
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
ret
|
|
ENDC
|
|
|
|
SetupDrawCommon:
|
|
;set VRAM bank to zero
|
|
ld a,MAPBANK
|
|
ld [$ff00+$4f],a
|
|
|
|
;find address to start getting tile indices from
|
|
ld a,[mapPitchMinusOne]
|
|
ld c,a
|
|
ld a,[mapTop]
|
|
ld e,a
|
|
xor a
|
|
|
|
.jTimesPitch
|
|
sla e ;times two
|
|
rla ;carry from low bit into high bit
|
|
srl c ;c is pitch-1, counter of how many times to shift
|
|
jr nz,.jTimesPitch
|
|
ld d,a ;high byte into d; de is now == j * pitch
|
|
|
|
ld a,[mapLeft]
|
|
add e
|
|
ld e,a ;de is now (j*pitch) + i
|
|
ld hl,map ;add in base address of map
|
|
add hl,de
|
|
ld d,h
|
|
ld e,l
|
|
|
|
;get memory address of backBuffer in hl
|
|
ld hl,backBuffer
|
|
|
|
;start looping
|
|
ld b,19 ;times to loop vertically
|
|
ret
|
|
|
|
PostDrawCommon:
|
|
;if the map is scrolled as far as possible right and/or down we
|
|
;need to clear the right and/or bottom border so the jiggle effect
|
|
;won't look goofy
|
|
ld a,[mapMaxLeft]
|
|
ld b,a
|
|
ld a,[mapLeft]
|
|
cp b
|
|
jr c,.rightBorderOkay
|
|
|
|
;set up vertical loop clearing tiles to zero
|
|
ld hl,(backBuffer + 20)
|
|
ld de,32
|
|
ld c,19
|
|
xor a
|
|
|
|
.vloop ld [hl],a
|
|
add hl,de
|
|
dec c
|
|
jr nz,.vloop
|
|
|
|
.rightBorderOkay
|
|
;does bottom border need clearing?
|
|
ld a,[mapMaxTop]
|
|
ld b,a
|
|
ld a,[mapTop]
|
|
cp b
|
|
jr c,.done
|
|
|
|
;set up horizontal loop clearing tiles to zero
|
|
ld hl,(backBuffer + (32*18))
|
|
ld c,21
|
|
xor a
|
|
|
|
.hloop ld [hl+],a
|
|
dec c
|
|
jr nz,.hloop
|
|
|
|
.done
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: DrawCinemaToBackBuffer
|
|
; Alters: af
|
|
; Description: Sets relevant variables so the map can be drawn
|
|
; Note: Uses [temp] to store tile attributes
|
|
;---------------------------------------------------------------------
|
|
DrawCinemaToBackBuffer::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call SetupDrawCommon
|
|
|
|
.outer push de ;save starting ptr to dest (hl) and source (de)
|
|
push hl
|
|
ld c,21 ;times to loop horizontally
|
|
|
|
.inner push bc
|
|
;retrieve tile info from shadow buffers parallel to main map
|
|
ld a,ATTRSHADOWBANK ;set RAM bank to the attribute shadow bank
|
|
ld [$ff70],a
|
|
ld a,[de] ;attributes
|
|
ldio [temp],a
|
|
ld a,TILESHADOWBANK ;set RAM bank to the tile shadow bank
|
|
ld [$ff70],a
|
|
ld a,[de] ;tile to draw
|
|
inc de
|
|
|
|
ld [hl],a ;store tile in backBuffer
|
|
push hl
|
|
ld a,h
|
|
add 3 ;768 bytes to get from backbuffer to attr buffer
|
|
ld h,a
|
|
ld a,[temp] ;get attributes for this tile
|
|
ld [hl],a ;store attribute in buffer
|
|
pop hl ;back to map buffer
|
|
.afterDrawTile
|
|
inc hl
|
|
|
|
;inner loop termination test
|
|
pop bc
|
|
dec c
|
|
jr nz,.inner
|
|
|
|
pop hl ;retrieve initial pointers
|
|
pop de
|
|
|
|
ld a,[mapPitch] ;mapPtr += mapPitch
|
|
add e
|
|
ld e,a
|
|
jr nc,.hlNoCarry
|
|
inc d
|
|
.hlNoCarry
|
|
|
|
ld a,32 ;bgTileMapPtr += 32
|
|
add l
|
|
ld l,a
|
|
jr nc,.deNoCarry
|
|
inc h
|
|
.deNoCarry
|
|
|
|
;loop the outer loop again?
|
|
dec b
|
|
jr nz,.outer
|
|
|
|
call PostDrawCommon
|
|
|
|
.done ;map is drawn, bitch
|
|
ld a,MAPBANK ;set RAM bank to the map bank
|
|
ld [$ff00+$70],a
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: ShowTitle
|
|
; Arguments: de - pointer to text
|
|
; Description: Shows the text centered on-screen and waits until
|
|
; the user presses a button to continue.
|
|
; Alters: a,hl
|
|
;---------------------------------------------------------------------
|
|
ShowTitle::
|
|
push bc
|
|
|
|
ld a,[de] ;length of text
|
|
inc de
|
|
ld c,a
|
|
ld hl,spriteOAMBuffer+3
|
|
|
|
.loop
|
|
xor a ;sprite attributes
|
|
ld [hl-],a
|
|
ld a,[de] ;letter
|
|
inc de
|
|
ld [hl-],a
|
|
ld a,16 ;calculate x coordinate
|
|
sub c
|
|
sla a ;times 8 for pixels
|
|
sla a
|
|
sla a
|
|
ld [hl-],a ;y coordinate
|
|
ld a,80
|
|
ld [hl],a
|
|
ld a,l ;add 7 to hl
|
|
add 7
|
|
ld l,a
|
|
ld a,h
|
|
adc 0
|
|
ld h,a
|
|
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routines: SetSpeakerToFirstHero
|
|
; Arguments: None.
|
|
; Returns: c - index of first hero present
|
|
; [dialogSpeakerIndex]
|
|
; [dialogJoyIndex]
|
|
; Alters: af, c
|
|
; Description: Finds the first hero on the map and sets up
|
|
; some dialog parameters based on who it is.
|
|
;---------------------------------------------------------------------
|
|
SetSpeakerToFirstHero::
|
|
push de
|
|
push hl
|
|
xor a
|
|
ld hl,hero0_index
|
|
call .setParameters
|
|
or a
|
|
jr nz,.done
|
|
|
|
ld a,1
|
|
ld hl,hero1_index
|
|
call .setParameters
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
ret
|
|
|
|
.setParameters
|
|
ld [dialogJoyIndex],a
|
|
ld a,[hl-] ;get hero index
|
|
or a ;non-zero?
|
|
ret z ;not present
|
|
|
|
ld c,a ;class index
|
|
ld de,HERODATA_TYPE
|
|
add hl,de
|
|
ld a,[hl]
|
|
ld [dialogSpeakerIndex],a ;flag indicating speaker
|
|
ld a,1 ;operation successful
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routines: SetSpeakerFromHeroIndex
|
|
; Arguments: c - index of speaking hero
|
|
; Returns: [dialogSpeakerIndex]
|
|
; [dialogJoyIndex]
|
|
; Alters: af
|
|
; Description:
|
|
;---------------------------------------------------------------------
|
|
SetSpeakerFromHeroIndex::
|
|
push de
|
|
push hl
|
|
|
|
ld hl,hero0_index
|
|
ld a,[hl-]
|
|
cp c
|
|
ld a,0
|
|
jr nz,.setHero1
|
|
|
|
call .setParameters
|
|
jr .done
|
|
|
|
.setHero1
|
|
ld a,1
|
|
ld hl,hero1_data
|
|
call .setParameters
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
ret
|
|
|
|
.setParameters
|
|
ld [dialogJoyIndex],a
|
|
ld de,HERODATA_TYPE
|
|
add hl,de
|
|
ld a,[hl]
|
|
ld [dialogSpeakerIndex],a ;flag indicating speaker
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetPressBDialog
|
|
;---------------------------------------------------------------------
|
|
SetPressBDialog:
|
|
ld a,DLG_BORDER | DLG_PRESSB
|
|
ld [dialogSettings],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetDialogJoy::
|
|
; Arguments: None.
|
|
; Returns: hl - pointer to appropriate joy inputs
|
|
; Alters: af,hl
|
|
;---------------------------------------------------------------------
|
|
SetDialogJoy::
|
|
ld a,[displayType]
|
|
cp 1
|
|
jr z,.cinemaType
|
|
ld a,[canJoinMap]
|
|
cp 2 ;asynchronous join?
|
|
jr z,.cinemaType
|
|
|
|
ld hl,curInput0
|
|
ld a,[dialogJoyIndex]
|
|
or a
|
|
ret z
|
|
inc hl
|
|
ret
|
|
|
|
.cinemaType
|
|
ld hl,myJoy
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: CheckDialogContinue
|
|
; Arguments: None.
|
|
; Returns: a - 1 if done (B is pressed), 0 if not done
|
|
; Alters: af
|
|
; Description: Calls CheckDialogSkip and then sees if button B of
|
|
; the speaker's joystick is pressed.
|
|
;---------------------------------------------------------------------
|
|
CheckDialogContinue::
|
|
push hl
|
|
call CheckSkip
|
|
|
|
call SetDialogJoy
|
|
|
|
ld a,[dialogSettings]
|
|
and DLG_WAITRELEASE
|
|
jr nz,.waitRelease
|
|
|
|
ld a,[hl]
|
|
and JOY_B
|
|
jr z,.returnFalse
|
|
|
|
ld hl,dialogSettings
|
|
set DLG_WAITRELEASE_BIT,[hl]
|
|
jr .returnFalse
|
|
|
|
.waitRelease
|
|
ld a,[hl]
|
|
and JOY_B
|
|
jr nz,.returnFalse
|
|
|
|
ld hl,dialogSettings
|
|
res DLG_WAITRELEASE_BIT,[hl]
|
|
|
|
bit DLG_CLEARSKIP_BIT,[hl]
|
|
jr z,.afterClearSkip
|
|
|
|
res DLG_CLEARSKIP_BIT,[hl]
|
|
push hl
|
|
ld de,0
|
|
call SetDialogSkip
|
|
pop hl
|
|
|
|
.afterClearSkip
|
|
bit DLG_NOCLEAR_BIT,[hl]
|
|
res DLG_NOCLEAR_BIT,[hl]
|
|
jr nz,.returnTrue
|
|
|
|
call ClearDialog
|
|
|
|
.returnTrue
|
|
ld a,1
|
|
jr .done
|
|
|
|
|
|
.returnFalse
|
|
xor a
|
|
.done
|
|
pop hl
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routines: ShowDialogAtTop
|
|
; ShowDialogAtTopNoWait
|
|
; ShowDialogAtBottom
|
|
; ShowDialogAtBottomNoWait
|
|
; ClearDialog
|
|
; Arguments: [dialogBank] - bank containing text
|
|
; c - class index of speaking character
|
|
; de - pointer to gtx text
|
|
; Description: Shows the text centered at the top or bottom dialog
|
|
; bar & waits until the user presses a button to
|
|
; continue.
|
|
; Alters: none
|
|
; Note: Format of gtx:
|
|
; BYTE number of lines
|
|
; REPT[nLines]:
|
|
; BYTE spaces to center
|
|
; BYTE num chars in line
|
|
; BYTE[nChars] characters
|
|
;---------------------------------------------------------------------
|
|
ShowDialogNPC::
|
|
ld a,[dialogNPC_heroIndex]
|
|
ld c,a
|
|
call SetSpeakerFromHeroIndex
|
|
ld a,[dialogNPC_speakerIndex]
|
|
ld c,a
|
|
call ShowDialogAtTop
|
|
call ClearDialog
|
|
ret
|
|
|
|
ShowDialogHero::
|
|
ld a,[dialogNPC_heroIndex]
|
|
ld c,a
|
|
call SetSpeakerFromHeroIndex
|
|
call ShowDialogAtBottom
|
|
call ClearDialog
|
|
ret
|
|
|
|
ShowDialogAtTop::
|
|
ld a,[dialogBank]
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call ChooseFromDialogAlternates
|
|
|
|
ld b,0 ;lines to skip at top
|
|
call ShowDialogCommon
|
|
call ShowDialogAtTopCommon
|
|
call ShowDialogWait
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
ShowDialogAtTopNoWait::
|
|
ld a,[dialogBank]
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call ChooseFromDialogAlternates
|
|
|
|
ld b,0 ;lines to skip at top
|
|
call ShowDialogCommon
|
|
call ShowDialogAtTopCommon
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
ShowDialogAtTopCommon::
|
|
call DrawDialogBorderAtBottom
|
|
call GfxBlitBackBufferToWindow
|
|
|
|
xor a
|
|
ldh [$ff4a], a ;set window y position
|
|
|
|
ld a,[de] ;number of lines
|
|
rlca ;times 8 = pixels for window
|
|
rlca
|
|
rlca
|
|
add 7
|
|
ld [hblankWinOff],a
|
|
|
|
ld a,143
|
|
ld [hblankWinOn],a
|
|
|
|
ld a,[hblankFlag]
|
|
bit 1,a
|
|
jr nz,.afterSetLYC
|
|
|
|
ld a,143
|
|
ld [$ff45],a ;lyc
|
|
ld a,[hblankFlag]
|
|
|
|
.afterSetLYC
|
|
or %10 ;allow window to show
|
|
ld [hblankFlag],a
|
|
|
|
ld a,OBJROM
|
|
call SetActiveROM
|
|
ret
|
|
|
|
ShowDialogAtBottom::
|
|
ld a,[dialogBank]
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call ChooseFromDialogAlternates
|
|
|
|
ld b,1 ;lines to skip at top
|
|
call ShowDialogCommon
|
|
call ShowDialogAtBottomCommon
|
|
call ShowDialogWait
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
ShowDialogAtBottomNoWait::
|
|
ld a,[dialogBank]
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
call ChooseFromDialogAlternates
|
|
|
|
ld b,1 ;lines to skip at top
|
|
call ShowDialogCommon
|
|
call ShowDialogAtBottomCommon
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
ShowDialogAtBottomCommon::
|
|
call DrawDialogBorderAtTop
|
|
call GfxBlitBackBufferToWindow
|
|
|
|
ld a,143
|
|
ld [hblankWinOff],a
|
|
|
|
;set window y pos. Req'd for actual GBC, not emulator
|
|
ld a,[de] ;# lines
|
|
cpl
|
|
add 1+17 ;(max lines) - (text lines+1)
|
|
rlca
|
|
rlca
|
|
rlca ;times 8
|
|
ldh [$ff4a], a ;set window y position
|
|
|
|
ld a,[de] ;number of lines
|
|
rlca ;times 8 = pixels for window
|
|
rlca
|
|
rlca
|
|
add 8
|
|
cpl ;make negative (+1), subtract from 143
|
|
add 144 ;+1 2's compl, +143
|
|
ld [hblankWinOn],a
|
|
|
|
ld a,[hblankFlag]
|
|
bit 1,a
|
|
jr nz,.afterSetLYC
|
|
|
|
ld a,[hblankWinOn]
|
|
ld [$ff45],a ;lyc
|
|
ld a,[hblankFlag]
|
|
|
|
.afterSetLYC
|
|
or %10 ;allow window to show
|
|
ld [hblankFlag],a
|
|
|
|
ld a,OBJROM
|
|
call SetActiveROM
|
|
ret
|
|
|
|
ClearDialog::
|
|
push af
|
|
xor a
|
|
ld [amShowingDialog],a
|
|
|
|
ld a,[hblankFlag] ;turn off dialog box and window
|
|
and %11111101
|
|
ld [hblankFlag],a
|
|
call VWait
|
|
;call InstallGamePalette
|
|
ld a,1
|
|
ldio [paletteBufferReady],a
|
|
call VWait
|
|
pop af
|
|
ret
|
|
|
|
ShowDialogWait::
|
|
;change both heroes to idle
|
|
ld a,[heroesIdle]
|
|
push af
|
|
ld a,1
|
|
ld [heroesIdle],a
|
|
|
|
call .waitInputZero
|
|
|
|
.wait
|
|
call UpdateObjects
|
|
call RedrawMap
|
|
call CheckDialogContinue
|
|
or a
|
|
jr z,.wait
|
|
|
|
;call .waitInput
|
|
;call .waitInputZero
|
|
|
|
pop af
|
|
ld [heroesIdle],a
|
|
|
|
ret
|
|
|
|
.waitInputZero
|
|
DialogWaitInputZero::
|
|
call UpdateObjects
|
|
call RedrawMap
|
|
ld h,((curInput0>>8) & $ff)
|
|
ld a,[dialogJoyIndex]
|
|
add (curInput0 & $ff)
|
|
ld l,a
|
|
ld a,[hl]
|
|
and %11110000
|
|
jr nz,DialogWaitInputZero
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routines: ShowDialogCommon
|
|
; Arguments: a - bank message is in
|
|
; b - lines to skip at top
|
|
; c - class index of speaking character
|
|
; de - pointer to gtx text beginning with #lines
|
|
; Description:
|
|
; Alters: af
|
|
; Note: Format of gtx:
|
|
; BYTE number of lines
|
|
; REPT[nLines]:
|
|
; BYTE spaces to center
|
|
; BYTE num chars in line
|
|
; BYTE[nChars] characters
|
|
;---------------------------------------------------------------------
|
|
ShowDialogCommon::
|
|
push de
|
|
push bc ;save class index of speaking character
|
|
|
|
call SetActiveROM
|
|
|
|
ld a,1
|
|
ld [amShowingDialog],a
|
|
|
|
;wait until the backbuffer is blitted
|
|
.waitBackBuffer
|
|
ldio a,[backBufferReady]
|
|
or a
|
|
jr z,.canMessWithBackBuffer
|
|
|
|
call VWait
|
|
jr .waitBackBuffer
|
|
|
|
.canMessWithBackBuffer
|
|
;clear the backbuffer and attribute buffer for given #lines
|
|
ld a,[de] ;b = number of lines + 1
|
|
add 1
|
|
ld b,a
|
|
ld hl,backBuffer
|
|
|
|
.clearLines
|
|
call ClearGTXLine
|
|
push bc
|
|
ld bc,32
|
|
add hl,bc
|
|
pop bc
|
|
dec b
|
|
jr nz,.clearLines
|
|
;xor a
|
|
;.outer1 ld c,32
|
|
;.inner1 ld [hl+],a
|
|
;dec c
|
|
;jr nz,.inner1
|
|
;dec b
|
|
;jr nz,.outer1
|
|
|
|
;ld a,[de] ;b = number of lines + 1
|
|
;add 1
|
|
;ld b,a
|
|
;ld hl,attributeBuffer
|
|
;xor a
|
|
;.outer2 ld c,32
|
|
;.inner2 ld [hl+],a
|
|
;dec c
|
|
;jr nz,.inner2
|
|
;dec b
|
|
;jr nz,.outer2
|
|
|
|
;adjust hl down a line?
|
|
pop bc
|
|
push bc
|
|
ld hl,backBuffer
|
|
bit 0,b
|
|
jr z,.hlOkay
|
|
ld bc,32
|
|
add hl,bc
|
|
.hlOkay
|
|
|
|
;for each line of text...
|
|
ld a,[de] ;b = number of lines
|
|
inc de
|
|
ld b,a
|
|
|
|
.line
|
|
call WriteGTXLine
|
|
|
|
;go to next line
|
|
dec b
|
|
jr nz,.line
|
|
|
|
;retrieve class index of speaking character and
|
|
;blit that tile to the top-left corner of the buffer
|
|
pop bc
|
|
call DrawTileToTLCorner
|
|
;call GfxBlitBackBufferToWindow
|
|
pop de
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: ClearGTXLine
|
|
; Arguments:
|
|
; hl - backbuffer location to draw at
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
ClearGTXLine::
|
|
push bc
|
|
push hl
|
|
|
|
push hl
|
|
|
|
;clear backbuffer
|
|
xor a
|
|
ld c,32
|
|
.loop ld [hl+],a
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
;clear attr buffer
|
|
xor a
|
|
pop hl
|
|
ld bc,$300
|
|
add hl,bc
|
|
ld c,32
|
|
.loop2 ld [hl+],a
|
|
dec c
|
|
jr nz,.loop2
|
|
|
|
pop hl
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: WriteGTXLine
|
|
; Arguments: de - pointer to gtx text beginning with centerSpaces
|
|
; hl - location to draw at
|
|
; Alters: hl,de
|
|
;---------------------------------------------------------------------
|
|
WriteGTXLine::
|
|
;advance hl spaces required to center text
|
|
push bc
|
|
ld b,0
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
add hl,bc
|
|
|
|
;get the char count for this line
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
or a
|
|
jr z,.afterLoop
|
|
|
|
;copy the characters to the buffer
|
|
.loop ld a,[de]
|
|
inc de
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
.afterLoop
|
|
;advance hl to next line
|
|
ld a,l
|
|
and ~31
|
|
add 32
|
|
ld l,a
|
|
ld a,0
|
|
adc h
|
|
ld h,a
|
|
|
|
pop bc
|
|
ret
|
|
|
|
|
|
GfxBlitBackBufferToWindow::
|
|
;xor a
|
|
;ld c,38 ;38*16 = 608
|
|
;ld de,$9c00 ;dest = window map memory
|
|
;ld hl,$c000 ;source
|
|
;call VMemCopy
|
|
;ret
|
|
|
|
ld a,$9c ;copy to window map memory
|
|
ldio [backBufferDestHighByte],a
|
|
ld a,1
|
|
ldio [backBufferReady],a
|
|
.vwait call VWait
|
|
ldio a,[backBufferReady] ;wait until buffer is copied
|
|
or a
|
|
jr nz,.vwait
|
|
ld a,$98 ;go back to copying to bg map memory
|
|
ldio [backBufferDestHighByte],a
|
|
ret
|
|
|
|
GfxShowStandardTextBox::
|
|
;set interrupt to turn window off at bottom of screen
|
|
ld a,143
|
|
ld [hblankWinOff],a
|
|
|
|
;set window y pos. Req'd for actual GBC, not emulator
|
|
ld a,96
|
|
ldh [$ff4a], a ;set window y position
|
|
ld [hblankWinOn],a
|
|
|
|
ld a,[hblankFlag]
|
|
bit 1,a
|
|
jr nz,.afterSetLYC
|
|
|
|
ld a,[hblankWinOn]
|
|
ld [$ff45],a ;lyc
|
|
ld a,[hblankFlag]
|
|
|
|
.afterSetLYC
|
|
or %10 ;allow window to show
|
|
ld [hblankFlag],a
|
|
ret
|
|
|
|
DrawDialogBorderAtTop:
|
|
push hl
|
|
ld hl,$c000 ;9c00
|
|
call DrawDialogBorder
|
|
pop hl
|
|
ret
|
|
|
|
DrawDialogBorderAtBottom:
|
|
push de
|
|
push hl
|
|
ld hl,$c000 ;9c00
|
|
ld a,[de] ;num lines
|
|
ld d,a
|
|
xor a
|
|
srl d
|
|
rra
|
|
srl d
|
|
rra
|
|
srl d
|
|
rra
|
|
ld e,a
|
|
add hl,de
|
|
call DrawDialogBorder
|
|
pop hl
|
|
pop de
|
|
ret
|
|
|
|
DrawDialogBorder:
|
|
push bc
|
|
push hl
|
|
|
|
ld a,[dialogSettings]
|
|
and DLG_BORDER
|
|
jr z,.done
|
|
|
|
;draw border at edge
|
|
push hl
|
|
|
|
;xor a
|
|
;ldio [$ff4f],a ;VRAM bank
|
|
|
|
ld c,20
|
|
ld a,252
|
|
.drawBorder
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.drawBorder
|
|
|
|
dec hl
|
|
ld a,[dialogSettings]
|
|
and DLG_PRESSB
|
|
jr z,.clearBG
|
|
|
|
ld [hl],253
|
|
|
|
.clearBG
|
|
pop hl
|
|
|
|
;clear bg attributes
|
|
ld bc,$300
|
|
add hl,bc
|
|
|
|
;ld a,1
|
|
;ldio [$ff4f],a ;VRAM bank
|
|
|
|
ld c,20
|
|
xor a
|
|
.clearBGLoop
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.clearBGLoop
|
|
|
|
.done
|
|
pop hl
|
|
pop bc
|
|
ret
|
|
|
|
DrawTileToTLCorner: ;class index in c, 1 line down in b
|
|
.drawTile
|
|
ld hl,backBuffer
|
|
bit 0,b
|
|
jr z,.hlOkay
|
|
ld l,32
|
|
.hlOkay
|
|
ld a,c
|
|
or a
|
|
jr z,.useNullTile ;use null tile
|
|
|
|
ld a,TILEINDEXBANK
|
|
ld [$ff70],a
|
|
|
|
ld b,((fgAttributes>>8) & $ff)
|
|
ld a,[bc]
|
|
bit 5,a ;2x2 monster?
|
|
jr nz,.speaker2x2
|
|
|
|
and %00000111
|
|
or %00001000 ;coming from bank 1
|
|
ld h,((attributeBuffer>>8) & $ff)
|
|
ld [hl],a
|
|
|
|
ld h,((backBuffer>>8) & $ff)
|
|
ld b,((fgTileMap>>8) & $ff)
|
|
ld a,[bc] ;a is tile to draw
|
|
add 3 ;get right-facing
|
|
ld [hl],a
|
|
|
|
ret
|
|
|
|
.speaker2x2
|
|
and %00000111 ;color
|
|
or %00001000 ;coming from bank 1
|
|
push hl
|
|
push hl
|
|
ld h,((attributeBuffer>>8) & $ff)
|
|
ld [hl+],a
|
|
ld [hl+],a
|
|
push de
|
|
ld de,30
|
|
add hl,de
|
|
pop de
|
|
ld [hl+],a
|
|
ld [hl-],a
|
|
|
|
ld h,((backBuffer>>8) & $ff)
|
|
ld b,((fgTileMap>>8) & $ff)
|
|
ld a,[bc] ;a is tile to draw
|
|
add 12 ;get right-facing
|
|
ld [hl+],a
|
|
inc a
|
|
ld [hl+],a
|
|
pop hl
|
|
sub 3
|
|
ld [hl+],a
|
|
inc a
|
|
ld [hl+],a
|
|
pop hl
|
|
|
|
;kludge for two-color BRAINIAC
|
|
ld a,[dialogSettings]
|
|
bit DLG_BRAINIAC_BIT,a
|
|
ret z
|
|
|
|
res DLG_BRAINIAC_BIT,a
|
|
ld [dialogSettings],a
|
|
ld h,((attributeBuffer>>8) & $ff)
|
|
inc hl
|
|
ld a,8+3 ;green color from bank 1
|
|
ld [hl],a
|
|
push de
|
|
ld de,32
|
|
add hl,de
|
|
pop de
|
|
ld [hl+],a
|
|
|
|
ret
|
|
|
|
|
|
.useNullTile
|
|
xor a
|
|
ld [hl],a
|
|
ld h,((attributeBuffer>>8) & $ff)
|
|
ld [hl],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: ChooseFromDialogAlternates
|
|
; Arguments: de - pointer to gtx text
|
|
; Returns: de - adjusted pointer
|
|
; Alters: de
|
|
; Description: de points to start of an indeterminate number of
|
|
; byte triplets of the form:
|
|
; [mask] [offsetL] [offsetH]
|
|
; This routine finds a mask that (when ANDed) matches
|
|
; the value in [dialogSpeakerIndex] and jumps to the
|
|
; gtx alternate beginning at the given offset. The
|
|
; offset given for the cursor being at a position of
|
|
; 1 past [offsetH] of the matching triplet.
|
|
;---------------------------------------------------------------------
|
|
ChooseFromDialogAlternates:
|
|
push af
|
|
push bc
|
|
push hl
|
|
|
|
call SetActiveROM
|
|
|
|
ld h,d
|
|
ld l,e
|
|
|
|
ld a,[dialogSpeakerIndex]
|
|
ld c,a
|
|
|
|
.attemptMatch
|
|
ld a,[hl+] ;mask
|
|
and c
|
|
jr nz,.foundMatch
|
|
|
|
inc hl ;skip offset to look at next mask
|
|
inc hl
|
|
jr .attemptMatch
|
|
|
|
.foundMatch
|
|
ld a,[hl+] ;retrieve offset to start of gtx proper
|
|
ld e,a
|
|
ld a,[hl+]
|
|
ld d,a
|
|
add hl,de
|
|
|
|
ld d,h
|
|
ld e,l
|
|
|
|
pop hl
|
|
pop bc
|
|
pop af
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: CheckSkip
|
|
; Arguments: None.
|
|
; Returns: Nothing.
|
|
; Alters: af
|
|
; Description: Intended for use in cinemas and in-game dialog,
|
|
; resets the pc and sp to an address set with
|
|
; SetDialogSkip. Sets to the skip address if start is
|
|
; pushed, to fast-forward address if B is pushed.
|
|
;---------------------------------------------------------------------
|
|
CheckSkip::
|
|
push hl
|
|
|
|
ld a,[displayType]
|
|
cp 1
|
|
jr z,.cinemaType
|
|
ld a,[canJoinMap] ;asynchronous join?
|
|
cp 2
|
|
jr z,.cinemaType
|
|
|
|
ld hl,curInput0
|
|
ld a,[dialogJoyIndex] ;0 or 1
|
|
add l
|
|
ld l,a
|
|
jr .afterSetJoy
|
|
|
|
.cinemaType
|
|
ld hl,myJoy
|
|
|
|
.afterSetJoy
|
|
ld a,[hl] ;get the input
|
|
and JOY_START
|
|
jr nz,.startPressed
|
|
|
|
ld a,[hl]
|
|
and JOY_B
|
|
jr z,.done ;no buttons pushed
|
|
|
|
.abPressed
|
|
push hl
|
|
ld hl,levelCheckSkip ;fast forward address
|
|
jr .restore
|
|
|
|
.startPressed
|
|
push hl
|
|
ld hl,levelCheckSkip+2 ;skip address
|
|
|
|
.restore
|
|
ld a,[hl]
|
|
or a
|
|
jr nz,.addressOkay
|
|
inc hl
|
|
ld a,[hl-]
|
|
or a
|
|
jr nz,.addressOkay
|
|
|
|
pop hl
|
|
jr .done
|
|
|
|
.addressOkay
|
|
;make the class/object ROM the current
|
|
ld a,OBJROM
|
|
call SetActiveROM
|
|
xor a
|
|
ld e,[hl]
|
|
ld [hl],a
|
|
inc hl
|
|
ld d,[hl]
|
|
ld [hl],a
|
|
pop hl
|
|
cp d
|
|
jr nz,.addrOkay
|
|
cp e
|
|
jr z,.done ;null address
|
|
|
|
.addrOkay
|
|
ld a,$f0
|
|
call WaitInputZero
|
|
|
|
;reset all one-shot dialog options
|
|
ld hl,dialogSettings
|
|
res DLG_BRAINIAC_BIT,[hl]
|
|
res DLG_NOCLEAR_BIT,[hl]
|
|
res DLG_CLEARSKIP_BIT,[hl]
|
|
|
|
;restore stack pointer
|
|
ld a,[levelCheckStackPos]
|
|
ld l,a
|
|
ld a,[levelCheckStackPos+1]
|
|
ld h,a
|
|
ld sp,hl
|
|
|
|
;push return address on stack and go there
|
|
push de
|
|
ret
|
|
|
|
.done
|
|
pop hl
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: Delay
|
|
; Arguments: a - number of 1/60 seconds to delay
|
|
; Alters: af
|
|
; Description: Updates and displays objects for specified number of
|
|
; 1/60 seconds. Jumps to [levelCheckSkip] if start
|
|
; button is pressed if addr is non-null.
|
|
;---------------------------------------------------------------------
|
|
Delay::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
|
|
.delay push af
|
|
call UpdateObjects
|
|
call RedrawMap
|
|
|
|
call CheckSkip
|
|
.keepGoing
|
|
pop af
|
|
dec a
|
|
jr nz,.delay
|
|
|
|
.waitBlit
|
|
ldio a,[backBufferReady]
|
|
or a
|
|
jr nz,.waitBlit
|
|
|
|
;if we're in a cinema and we get a YANK from the remote player
|
|
;then we need to kill into the cinema script
|
|
ld a,[timeToChangeLevel]
|
|
or a
|
|
jr z,.done
|
|
|
|
ld a,[inLoadMethod]
|
|
or a
|
|
jr z,.done
|
|
|
|
call BlackoutPalette
|
|
ld a,[loadStackPosL]
|
|
ld l,a
|
|
ld a,[loadStackPosH]
|
|
ld h,a
|
|
ld sp,hl
|
|
jp AfterLoadLevelMethod
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: GetRandomNumZeroToN
|
|
; Arguments: a - maximum desired random number "N"
|
|
; Returns: a - random number between 0 and N
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
GetRandomNumZeroToN::
|
|
or a
|
|
ret z
|
|
|
|
push bc
|
|
push hl
|
|
|
|
inc a
|
|
jr z,.handleFF
|
|
ld b,a ;b is N
|
|
|
|
PUSHROM
|
|
ld a,BANK(randomTable)
|
|
call SetActiveROM
|
|
|
|
ld hl,randomLoc
|
|
inc [hl]
|
|
ld l,[hl]
|
|
ld h,((randomTable>>8) & $ff)
|
|
|
|
ld a,[hl]
|
|
bit 7,b
|
|
jr nz,.loop ;N+1>=128
|
|
|
|
;divide raw number by two until it's less than limit*2
|
|
ld c,b
|
|
sla c ;c = (limit * 2) + 1
|
|
inc c
|
|
.fastReduce
|
|
cp c ;a < limit*2 + 1?
|
|
jr c,.loop ;yes, go to slower precision work
|
|
srl a ;a/=2
|
|
jr .fastReduce
|
|
|
|
.loop cp b ;subtract N while r > N
|
|
jr c,.done
|
|
sub b
|
|
jr .loop
|
|
|
|
.done
|
|
ld b,a
|
|
POPROM
|
|
ld a,b
|
|
pop hl
|
|
pop bc
|
|
ret
|
|
|
|
.handleFF
|
|
PUSHROM
|
|
ld a,BANK(randomTable)
|
|
call SetActiveROM
|
|
|
|
ld hl,randomLoc
|
|
inc [hl]
|
|
ld l,[hl]
|
|
ld h,((randomTable>>8) & $ff)
|
|
|
|
ld a,[hl]
|
|
ld b,a
|
|
POPROM
|
|
ld a,b
|
|
pop hl
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: GetRandomNumMask
|
|
; Arguments: a - bit mask for random number
|
|
; Returns: a - random number
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
GetRandomNumMask::
|
|
push bc
|
|
push hl
|
|
|
|
ld b,a ;b is bitmask
|
|
|
|
PUSHROM
|
|
ld a,BANK(randomTable)
|
|
call SetActiveROM
|
|
|
|
ld hl,randomLoc
|
|
inc [hl]
|
|
ld l,[hl]
|
|
ld h,((randomTable>>8) & $ff)
|
|
|
|
ld a,[hl]
|
|
and b
|
|
|
|
.done
|
|
ld b,a
|
|
POPROM
|
|
ld a,b
|
|
pop hl
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupFadeFromWhite
|
|
; Arguments: a - steps
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetupFadeFromWhite::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
push af
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
;set cur palette to be all white
|
|
ld hl,fadeCurPalette
|
|
call FadeCommonSetPaletteToWhite
|
|
|
|
;set final palette to be copy of current game palette
|
|
ld hl,gamePalette
|
|
ld de,fadeFinalPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
pop af
|
|
call FadeInit
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
FadeCommonSetPaletteToWhite::
|
|
ld c,64
|
|
.loop
|
|
ld a,$ff
|
|
ld [hl+],a
|
|
ld a,$7f
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.loop
|
|
ret
|
|
|
|
CopyPalette64::
|
|
FadeCommonCopyPalette::
|
|
push bc
|
|
push de
|
|
push hl
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
ld c,128
|
|
.loop ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
dec c
|
|
jr nz,.loop
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
CopyPalette32::
|
|
push bc
|
|
push de
|
|
push hl
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
ld c,64
|
|
.loop ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
dec c
|
|
jr nz,.loop
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: InstallGamePalette
|
|
; Arguments: None.
|
|
; Alters: af
|
|
; Description: Sets gamePalette to be installed to the hardware
|
|
; on the next VBlank.
|
|
;---------------------------------------------------------------------
|
|
InstallGamePalette::
|
|
push hl
|
|
push de
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
ld a,1
|
|
ldio [paletteBufferReady],a
|
|
.wait
|
|
ldio a,[paletteBufferReady] ;wait for vblank to install it
|
|
or a
|
|
jr nz,.wait
|
|
|
|
pop de
|
|
pop hl
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupFadeToWhite
|
|
; Arguments: a - steps
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetupFadeToWhite::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
push af
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
;set final palette to be all white
|
|
ld hl,fadeFinalPalette
|
|
call FadeCommonSetPaletteToWhite
|
|
|
|
;set cur palette to be copy of current game palette
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
pop af
|
|
call FadeInit
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupFadeFromBlack
|
|
; Arguments: a - steps
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetupFadeFromStandard::
|
|
SetupFadeFromBlack::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
push af
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
;set cur palette to be all white
|
|
ld hl,fadeCurPalette
|
|
call FadeCommonSetPaletteToBlack
|
|
|
|
;set final palette to be copy of current game palette
|
|
ld hl,gamePalette
|
|
ld de,fadeFinalPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
pop af
|
|
call FadeInit
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupFadeToBlack
|
|
; Arguments: a - steps
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetupFadeToStandard::
|
|
SetupFadeToBlack::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
push af
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
;set final palette to be all black
|
|
ld hl,fadeFinalPalette
|
|
call FadeCommonSetPaletteToBlack
|
|
|
|
;set cur palette to be copy of current game palette
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
pop af
|
|
call FadeInit
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
FadeCommonSetPaletteToBlack::
|
|
ld c,64
|
|
xor a
|
|
.loop
|
|
ld [hl+],a
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.loop
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupFadeFromBlackBGOnly
|
|
; Arguments: a - steps
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetupFadeFromBlackBGOnly::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
push af
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
;set cur palette to be all black
|
|
ld hl,fadeCurPalette
|
|
call FadeCommonSetPaletteToBlackBGOnly
|
|
|
|
;set final palette to be copy of current game palette
|
|
ld hl,gamePalette
|
|
ld de,fadeFinalPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
ld a,32
|
|
ld [fadeRange],a
|
|
|
|
pop af
|
|
call FadeInit
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: BlackoutPalette
|
|
; Arguments:
|
|
; Alters: af
|
|
; Description: Sets fadeCurPalette and final palette to all black
|
|
;---------------------------------------------------------------------
|
|
BlackoutPalette::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
ld hl,fadeFinalPalette
|
|
call FadeCommonSetPaletteToBlack
|
|
|
|
ld hl,fadeCurPalette
|
|
call FadeCommonSetPaletteToBlack
|
|
|
|
;turn off any existing fade
|
|
ld hl,specialFX
|
|
res 0,[hl] ;reset fade bit
|
|
|
|
;install the current palette on the next VBlank
|
|
ld a,1
|
|
ldio [paletteBufferReady],a
|
|
.wait
|
|
ldio a,[paletteBufferReady] ;wait for vblank to install it
|
|
or a
|
|
jr nz,.wait
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupFadeToBlackBGOnly
|
|
; Arguments: a - steps
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetupFadeToBlackBGOnly::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
push af
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
ld hl,gamePalette
|
|
ld de,fadeFinalPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
;set final palette BG Colors to be all black
|
|
ld hl,fadeFinalPalette
|
|
call FadeCommonSetPaletteToBlackBGOnly
|
|
|
|
;set cur palette to be copy of current game palette
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
ld a,32
|
|
ld [fadeRange],a
|
|
|
|
pop af
|
|
call FadeInit
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
FadeCommonSetPaletteToBlackBGOnly::
|
|
ld c,32
|
|
xor a
|
|
.loop
|
|
ld [hl+],a
|
|
ld [hl+],a
|
|
dec c
|
|
jr nz,.loop
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupFadeFromSaturated
|
|
; Arguments: a - steps
|
|
; b - amount of saturation (white) to start at
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetupFadeFromSaturated::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
push af
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
;copy game palette to starting palette and ending palette
|
|
ld hl,gamePalette
|
|
ld de,fadeFinalPalette
|
|
call FadeCommonCopyPalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
ld l,b ;saturation
|
|
|
|
;add saturation to each color
|
|
ld h,64
|
|
.setup call FadeCommonGetColor
|
|
dec de
|
|
dec de
|
|
call GetRedComponent
|
|
call .saturate
|
|
call SetRedComponent
|
|
call GetGreenComponent
|
|
call .saturate
|
|
call SetGreenComponent
|
|
call GetBlueComponent
|
|
call .saturate
|
|
call SetBlueComponent
|
|
|
|
;save color
|
|
ld a,c
|
|
ld [de],a
|
|
inc de
|
|
ld a,b
|
|
ld [de],a
|
|
inc de
|
|
|
|
dec h
|
|
jr nz,.setup
|
|
|
|
pop af
|
|
call FadeInit
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
.saturate
|
|
add l
|
|
bit 7,l
|
|
jr nz,.satneg
|
|
cp 32 ;over the limit?
|
|
ret c
|
|
|
|
ld a,$1f
|
|
ret
|
|
|
|
.satneg
|
|
xor a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupFadeToGamePalette
|
|
; Arguments: a - steps
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetupFadeToGamePalette::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
push af
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
;set final palette to be current game palette
|
|
ld hl,gamePalette
|
|
ld de,fadeFinalPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
pop af
|
|
call FadeInit
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetupFadeToHalfbrite
|
|
; Arguments: a - steps
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetupFadeToHalfbrite::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
push af
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
;set final palette to be halfbrite game palette
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
ld c,64
|
|
.copyHalfbrite
|
|
push bc
|
|
ld a,[hl+]
|
|
ld c,a
|
|
ld a,[hl-]
|
|
ld b,a
|
|
call GetRedComponent
|
|
srl a
|
|
call SetRedComponent
|
|
call GetGreenComponent
|
|
srl a
|
|
call SetGreenComponent
|
|
call GetBlueComponent
|
|
srl a
|
|
call SetBlueComponent
|
|
ld a,c
|
|
ld [hl+],a
|
|
ld a,b
|
|
ld [hl+],a
|
|
pop bc
|
|
dec c
|
|
jr nz,.copyHalfbrite
|
|
|
|
;set cur palette to be copy of current game palette
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
pop af
|
|
call FadeInit
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: FadeCommonGetColor
|
|
; Arguments: de - ptr to next color
|
|
; Returns: bc - next color
|
|
; Alters: af,de
|
|
;---------------------------------------------------------------------
|
|
FadeCommonGetColor:
|
|
ld a,[de]
|
|
inc de
|
|
ld c,a
|
|
ld a,[de]
|
|
inc de
|
|
ld b,a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: FadeInit
|
|
; Arguments: a - number of steps
|
|
; [fadeCurPalette], [fadeFinalPalette] already setup
|
|
; with palettes to fade between
|
|
; Alters: af
|
|
; Description: Sets up and uses fadeDelta[32*3]
|
|
; and fadeError[32*3].
|
|
; FadeStep must then be called every vblank until
|
|
; [specialFX:0] becomes zero.
|
|
;---------------------------------------------------------------------
|
|
FadeInit::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld [fadeSteps],a
|
|
ld [fadeStepsToGo],a
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
;for each color component, difference is (c2-c1)
|
|
;subtract each element of fadeCurPalette from fadeFinalPalette
|
|
;and store separate RGB offsets in fadeDelta.
|
|
;fadeCurPalette RGB elements in fadeCurRGB.
|
|
|
|
;clear out fadeError and fadeDelta
|
|
ld hl,fadeError
|
|
ld de,fadeDelta
|
|
ld c,192
|
|
xor a
|
|
.clearError
|
|
ld [hl+],a
|
|
ld [de],a
|
|
inc de
|
|
dec c
|
|
jr nz,.clearError
|
|
|
|
;begin by storing each color component of each color in
|
|
;fadeCurPalette into fadeDelta
|
|
ld a,64
|
|
ld hl,fadeDelta
|
|
ld de,fadeCurPalette
|
|
|
|
.copyCurToDelta
|
|
push af
|
|
call FadeCommonGetColor
|
|
call GetRedComponent
|
|
ld [hl+],a
|
|
call GetGreenComponent
|
|
ld [hl+],a
|
|
call GetBlueComponent
|
|
ld [hl+],a
|
|
pop af
|
|
dec a
|
|
jr nz,.copyCurToDelta
|
|
|
|
;copy fadeDelta[192] to fadeCurRGB[192].
|
|
;ld hl,fadeDelta
|
|
;ld de,fadeCurRGB
|
|
;ld c,192
|
|
;.copyToCurRGB
|
|
;ld a,[hl+]
|
|
;ld [de],a
|
|
;inc de
|
|
;dec c
|
|
;jr nz,.copyToCurRGB
|
|
|
|
;fadeDelta[...] = fadeFinalPalette[...] - fadeDelta[...]
|
|
ld a,64
|
|
ld hl,fadeDelta
|
|
ld de,fadeFinalPalette
|
|
|
|
.findStep
|
|
push af
|
|
call FadeCommonGetColor
|
|
call GetRedComponent
|
|
sub [hl]
|
|
ld [hl+],a
|
|
call GetGreenComponent
|
|
sub [hl]
|
|
ld [hl+],a
|
|
call GetBlueComponent
|
|
sub [hl]
|
|
ld [hl+],a
|
|
pop af
|
|
dec a
|
|
jr nz,.findStep
|
|
|
|
|
|
;indicate we've got a fade goin on
|
|
ld a,FX_FADE
|
|
ld [specialFX],a
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: FadeStep
|
|
; Alters: af
|
|
; Description: Peforms the next step of the fade in progress.
|
|
; Should only be called if [specialFX] & FX_FADE is 1.
|
|
; fadeRange is reset to 64 afterwards.
|
|
;---------------------------------------------------------------------
|
|
FadeStep::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
.waitReady
|
|
ldio a,[paletteBufferReady] ;wait for vblank
|
|
or a
|
|
jr nz,.waitReady
|
|
|
|
;loop 64 times, adding the fade delta for each component
|
|
;to the error. If error >= 32:
|
|
; error -= 32;
|
|
; increment component;
|
|
;Then flag the newly created palette to be displayed
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
ld a,[fadeStepsToGo]
|
|
dec a
|
|
ld [fadeStepsToGo],a
|
|
jr z,.lastFade
|
|
|
|
;ld c,64
|
|
;ld hl,fadeError
|
|
;ld de,fadeCurRGB
|
|
;
|
|
;.fadeInner
|
|
;ld a,[de] ;red component
|
|
;call .addDeltaToError
|
|
;ld [de],a
|
|
;inc de
|
|
;
|
|
;ld a,[de] ;green component
|
|
;call .addDeltaToError
|
|
;ld [de],a
|
|
;inc de
|
|
|
|
;ld a,[de] ;blue component
|
|
;call .addDeltaToError
|
|
;ld [de],a
|
|
;inc de
|
|
;;dec c
|
|
;jr nz,.fadeInner
|
|
|
|
;copy RGB palette to 15-bit palette
|
|
;ld a,64
|
|
;ld bc,0
|
|
;ld hl,fadeCurRGB
|
|
;ld de,fadeCurPalette
|
|
;.RGBtoCur
|
|
;push af
|
|
;ld a,[hl+]
|
|
;call SetRedComponent
|
|
;ld a,[hl+]
|
|
;call SetGreenComponent
|
|
;ld a,[hl+]
|
|
;call SetBlueComponent
|
|
;ld a,c
|
|
;ld [de],a
|
|
;inc de
|
|
;ld a,b
|
|
;ld [de],a
|
|
;inc de
|
|
;pop af
|
|
;dec a
|
|
;jr nz,.RGBtoCur
|
|
|
|
|
|
ld a,[fadeRange]
|
|
ld hl,fadeError
|
|
ld de,fadeCurPalette
|
|
|
|
.fadeInner
|
|
push af
|
|
|
|
;get current color in bc, though keep de where it was
|
|
call FadeCommonGetColor
|
|
dec de
|
|
dec de
|
|
|
|
call GetRedComponent
|
|
call .addDeltaToError
|
|
call SetRedComponent ;store component
|
|
|
|
call GetGreenComponent
|
|
call .addDeltaToError
|
|
call SetGreenComponent ;store component
|
|
|
|
call GetBlueComponent
|
|
call .addDeltaToError
|
|
call SetBlueComponent ;store component
|
|
|
|
;store back in cur table
|
|
ld a,c
|
|
ld [de],a
|
|
inc de
|
|
ld a,b
|
|
ld [de],a
|
|
inc de
|
|
|
|
pop af
|
|
dec a
|
|
jr nz,.fadeInner
|
|
|
|
.install
|
|
;make mapColor the current color 0
|
|
ld de,mapColor
|
|
ld hl,fadeCurPalette
|
|
ld a,[hl+]
|
|
ld [de],a
|
|
inc de
|
|
ld a,[hl+]
|
|
ld [de],a
|
|
|
|
;install the current palette on the next VBlank
|
|
ld a,1
|
|
ldio [paletteBufferReady],a
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
|
|
.lastFade
|
|
;finally copy actual palette
|
|
ld hl,fadeFinalPalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
|
|
ld a,64
|
|
ld [fadeRange],a
|
|
|
|
xor a
|
|
ld [specialFX],a
|
|
jr .install
|
|
|
|
.addDeltaToError
|
|
;accepts: a - color value
|
|
;returns: a - new color value
|
|
push bc
|
|
push af
|
|
|
|
ld a,[fadeSteps]
|
|
ld b,a
|
|
cpl
|
|
add 1
|
|
ld c,a
|
|
|
|
push hl
|
|
push de
|
|
ld de,$ff40 ;-192
|
|
add hl,de
|
|
pop de
|
|
|
|
ld a,[hl]
|
|
pop hl
|
|
|
|
bit 7,a ;negative?
|
|
jr nz,.negative
|
|
|
|
.positive
|
|
add a,[hl]
|
|
cp b
|
|
jr c,.done
|
|
|
|
;>=32
|
|
ld c,0
|
|
.while_pos_ge_32
|
|
sub b
|
|
inc c
|
|
cp b
|
|
jr nc,.while_pos_ge_32
|
|
|
|
ld [hl+],a
|
|
pop af
|
|
add c
|
|
pop bc
|
|
ret
|
|
|
|
.negative
|
|
add a,[hl]
|
|
cp c
|
|
jr nc,.done
|
|
|
|
;<= -32
|
|
ld b,0
|
|
.while_neg_le_n32
|
|
sub c
|
|
inc b
|
|
cp c
|
|
jr c,.while_neg_le_n32
|
|
ld [hl+],a
|
|
pop af
|
|
sub b
|
|
pop bc
|
|
ret
|
|
|
|
.done
|
|
ld [hl+],a
|
|
pop af
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetColor0AllPalettes
|
|
; Arguments: bc - color to set to
|
|
; hl - ptr to start of palettes
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetColor0AllPalettes::
|
|
push de
|
|
push hl
|
|
|
|
ld d,16
|
|
.loop ld a,c
|
|
ld [hl+],a
|
|
ld a,b
|
|
ld [hl+],a
|
|
ld a,l
|
|
add 6
|
|
ld l,a
|
|
dec d
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop de
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetColors123AllPalettes
|
|
; Arguments: bc - color to set to
|
|
; hl - ptr to start of palettes
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetColors123AllPalettes::
|
|
push de
|
|
push hl
|
|
|
|
ld d,16
|
|
.loop
|
|
inc hl
|
|
inc hl
|
|
ld e,3
|
|
.inner
|
|
ld a,c
|
|
ld [hl+],a
|
|
ld a,b
|
|
ld [hl+],a
|
|
dec e
|
|
jr nz,.inner
|
|
|
|
dec d
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop de
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: LighteningOut
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
LighteningOut::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
;white background
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
ld hl,fadeCurPalette
|
|
ld bc,$7fff
|
|
call SetColor0AllPalettes
|
|
ld a,128
|
|
ldio [paletteBufferReady],a
|
|
|
|
ld c,3
|
|
call .pause
|
|
|
|
ld bc,0
|
|
ld hl,fadeCurPalette
|
|
call SetColors123AllPalettes
|
|
|
|
ld a,128
|
|
ldio [paletteBufferReady],a
|
|
|
|
ld c,7
|
|
call .pause
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
.pause call VWait
|
|
dec c
|
|
jr nz,.pause
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: LighteningIn
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
LighteningIn::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld a,FADEBANK
|
|
ld [$ff70],a
|
|
|
|
;black fg on white background
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
ld hl,fadeCurPalette
|
|
ld bc,$7fff
|
|
call SetColor0AllPalettes
|
|
ld bc,0
|
|
call SetColors123AllPalettes
|
|
|
|
ld a,128
|
|
ldio [paletteBufferReady],a
|
|
|
|
ld c,7
|
|
call .pause
|
|
|
|
;normal fg on white background
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
ld hl,fadeCurPalette
|
|
ld bc,$7fff
|
|
call SetColor0AllPalettes
|
|
|
|
ld a,128
|
|
ldio [paletteBufferReady],a
|
|
|
|
ld c,3
|
|
call .pause
|
|
|
|
;normal
|
|
ld hl,gamePalette
|
|
ld de,fadeCurPalette
|
|
call FadeCommonCopyPalette
|
|
ld a,128
|
|
ldio [paletteBufferReady],a
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
.pause call VWait
|
|
dec c
|
|
jr nz,.pause
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routines: GetRedComponent
|
|
; GetGreenComponent
|
|
; GetBlueComponent
|
|
; SetRedComponent
|
|
; SetGreenComponent
|
|
; SetBlueComponent
|
|
; Arguments: Get: bc - 15 bit BGR value
|
|
; Set: bc - 15 bit BGR value, a - value to set
|
|
; Returns: Get: a - color component
|
|
; Alters: af, bc
|
|
;---------------------------------------------------------------------
|
|
GetRedComponent::
|
|
ld a,c
|
|
and %00011111
|
|
ret
|
|
|
|
GetGreenComponent::
|
|
push de
|
|
ld a,b
|
|
IF 1
|
|
ld e,c
|
|
sla e
|
|
rla
|
|
sla e
|
|
rla
|
|
sla e
|
|
rla
|
|
and %00011111
|
|
pop de
|
|
ret
|
|
ENDC
|
|
|
|
IF 0
|
|
ld e,c
|
|
sla e
|
|
rl d
|
|
sla e
|
|
rl d
|
|
sla e
|
|
rl d
|
|
ld a,d
|
|
and %00011111
|
|
pop de
|
|
ret
|
|
ENDC
|
|
|
|
GetBlueComponent::
|
|
ld a,b
|
|
rrca
|
|
rrca
|
|
and %00011111
|
|
ret
|
|
|
|
SetRedComponent::
|
|
push af
|
|
ld a,c
|
|
and %11100000
|
|
ld c,a
|
|
pop af
|
|
or c
|
|
ld c,a
|
|
ret
|
|
|
|
SetGreenComponent::
|
|
push de
|
|
ld d,a
|
|
rrca
|
|
rrca
|
|
rrca
|
|
and %00000011
|
|
ld e,a
|
|
|
|
ld a,b
|
|
and %01111100
|
|
or e
|
|
ld b,a
|
|
|
|
ld a,d
|
|
swap a
|
|
rlca
|
|
and %11100000
|
|
ld d,a
|
|
|
|
ld a,c
|
|
and %00011111
|
|
or d
|
|
ld c,a
|
|
|
|
pop de
|
|
ret
|
|
|
|
SetBlueComponent::
|
|
push af
|
|
ld a,b
|
|
and %00000011
|
|
ld b,a
|
|
pop af
|
|
rlca
|
|
rlca
|
|
or b
|
|
ld b,a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: PlaySound
|
|
; Arguments: hl - addr of table 1st byte of which indicates sound
|
|
; type (1-4) and remainder is data specific to that
|
|
; type.
|
|
; Alters: af, hl
|
|
;---------------------------------------------------------------------
|
|
PlaySound::
|
|
ld a,[hl+]
|
|
cp 1
|
|
jr nz,.check2
|
|
|
|
xor a
|
|
ld [musicOverride1],a
|
|
call PlaySoundChannel1
|
|
ld a,3
|
|
ld [musicOverride1],a
|
|
ret
|
|
.check2
|
|
cp 2
|
|
jr nz,.check4
|
|
call PlaySoundChannel2
|
|
ret
|
|
.check4
|
|
cp 4
|
|
jr nz,.done
|
|
|
|
xor a
|
|
ld [musicOverride4],a
|
|
call PlaySoundChannel4
|
|
ld a,3
|
|
ld [musicOverride4],a
|
|
ret
|
|
|
|
.done
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: PlaySoundChannel1
|
|
; Arguments: hl - addr of 5 sound bytes for sweep, duty/len,
|
|
; envelope, freq_lo, and freq_high
|
|
; Alters: af, hl
|
|
;---------------------------------------------------------------------
|
|
PlaySoundChannel1::
|
|
ld a,[musicOverride1]
|
|
or a
|
|
ret nz
|
|
|
|
.playSound
|
|
ld a,[hl+]
|
|
ldio [$ff10],a
|
|
ld a,[hl+]
|
|
ldio [$ff11],a
|
|
ld a,[hl+]
|
|
ldio [$ff12],a
|
|
ld a,[hl+]
|
|
ldio [$ff13],a
|
|
ld a,[hl+]
|
|
ldio [$ff14],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: PlaySoundChannel2
|
|
; Arguments: hl - addr of 4 sound bytes for duty/len,
|
|
; envelope, freq_lo, and freq_high
|
|
; Alters: af, hl
|
|
;---------------------------------------------------------------------
|
|
PlaySoundChannel2::
|
|
ld a,[hl+]
|
|
ldio [$ff16],a
|
|
ld a,[hl+]
|
|
ldio [$ff17],a
|
|
ld a,[hl+]
|
|
ldio [$ff18],a
|
|
ld a,[hl+]
|
|
ldio [$ff19],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: PlaySoundChannel3
|
|
; Arguments: hl - addr of 4 sound bytes channel 4
|
|
; Alters: af, hl
|
|
;---------------------------------------------------------------------
|
|
PlaySoundChannel3::
|
|
ld a,$80
|
|
ldio [$ff1a],a
|
|
ld a,[hl+]
|
|
ldio [$ff1b],a
|
|
ld a,[hl+]
|
|
ldio [$ff1c],a
|
|
ld a,[hl+]
|
|
ldio [$ff1d],a
|
|
ld a,[hl+]
|
|
ldio [$ff1e],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: PlaySoundChannel4
|
|
; Arguments: hl - addr of 4 sound bytes for length, envelope,
|
|
; frequency, and consecutive
|
|
; Alters: af, hl
|
|
;---------------------------------------------------------------------
|
|
PlaySoundChannel4::
|
|
ld a,[musicOverride4]
|
|
or a
|
|
ret nz
|
|
|
|
.playSound
|
|
ld a,[hl+]
|
|
ldio [$ff20],a
|
|
ld a,[hl+]
|
|
ldio [$ff21],a
|
|
ld a,[hl+]
|
|
ldio [$ff22],a
|
|
ld a,[hl+]
|
|
ldio [$ff23],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: WaitInput
|
|
; Arguments: a - button mask [7:4] buttons, [3:0] dpad
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
WaitInput::
|
|
push bc
|
|
push de
|
|
ld b,a
|
|
.wait
|
|
push bc
|
|
push hl
|
|
call UpdateObjects
|
|
call RedrawMap
|
|
pop hl
|
|
pop bc
|
|
ld h,((curJoy0>>8) & $ff)
|
|
ld a,[dialogJoyIndex]
|
|
add (curJoy0 & $ff)
|
|
ld l,a
|
|
ld a,[hl]
|
|
and b
|
|
jr z,.wait
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: WaitInputZero
|
|
; Arguments: a - button mask [7:4] buttons, [3:0] dpad
|
|
; hl - address of joystick button code to check
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
WaitInputZero::
|
|
push bc
|
|
push de
|
|
ld b,a
|
|
.wait
|
|
push bc
|
|
push hl
|
|
call UpdateObjects
|
|
call RedrawMap
|
|
pop hl
|
|
pop bc
|
|
ld a,[hl]
|
|
and b
|
|
jr nz,.wait
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: WaitInputClick
|
|
; Arguments: a - button mask [7:4] buttons, [3:0] dpad
|
|
; Alters: af
|
|
; Description: WaitInputZero
|
|
; WaitInput
|
|
; WaitInputZero
|
|
;---------------------------------------------------------------------
|
|
WaitInputClick::
|
|
push bc
|
|
push hl
|
|
|
|
ld b,a
|
|
ld hl,myJoy
|
|
call WaitInputZero
|
|
ld a,b
|
|
call WaitInput
|
|
ld a,b
|
|
call WaitInputZero
|
|
|
|
pop hl
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: ResetSprites
|
|
; Arguments: none
|
|
; Alters: af
|
|
; Description: Sets all spritesUsed flags to false and sets each
|
|
; sprite y position in the OAM buffer to zero.
|
|
;---------------------------------------------------------------------
|
|
ResetSprites::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
;clear sprites used table
|
|
ld a,TILEINDEXBANK
|
|
ld [$ff70],a
|
|
|
|
ld hl,spritesUsed
|
|
xor a
|
|
ld c,40
|
|
.clr2 ld [hl+],a
|
|
dec c
|
|
jr nz,.clr2
|
|
|
|
;clear sprites
|
|
ld hl,spriteOAMBuffer
|
|
ld c,40
|
|
ld de,3
|
|
.clr3
|
|
ld [hl+],a
|
|
add hl,de
|
|
dec c
|
|
jr nz,.clr3
|
|
|
|
xor a
|
|
ld [oamFindPos],a
|
|
ld a,40
|
|
ld [numFreeSprites],a
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: AllocateSprite
|
|
; Arguments: none
|
|
; Returns: a - 00-9C=success (lowptr), ff=failure
|
|
; Alters: af
|
|
; Description: Loops through spritesUsed flag table, finds a free
|
|
; sprite, and returns that sprite's loPtr.
|
|
;---------------------------------------------------------------------
|
|
AllocateSprite::
|
|
;any free sprites?
|
|
ld a,[numFreeSprites]
|
|
or a
|
|
jr nz,.freeSpriteExists
|
|
|
|
ld a,$ff
|
|
ret
|
|
|
|
.freeSpriteExists
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
dec a
|
|
ld [numFreeSprites],a
|
|
|
|
;we know there's at least one free sprite so start at
|
|
;the the search position (which is guaranteed to be
|
|
;<= pos of first free) and loop till we find it
|
|
|
|
ld a,TILEINDEXBANK
|
|
ld [$ff70],a
|
|
|
|
ld h,((spritesUsed>>8)&$ff)
|
|
ld a,[oamFindPos]
|
|
ld l,a
|
|
|
|
.loop ld a,[hl+] ;get sprite used flag
|
|
or a
|
|
jr nz,.loop ;not free
|
|
|
|
.foundSprite
|
|
dec hl
|
|
ld a,1 ;mark sprite as used
|
|
ld [hl],a
|
|
|
|
ld a,l ;return loptr in a
|
|
inc a
|
|
ld [oamFindPos],a
|
|
|
|
ld a,l
|
|
|
|
;change 1-byte offset to 4-byte offset (loPtr)
|
|
rlca ;times 2
|
|
rlca ;times 2 again
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: FreeSprite
|
|
; Arguments: a - loptr to sprite
|
|
; Alters: af
|
|
; Description: Sets the sprite's YPOS to zero
|
|
; Flags the sprite as unused
|
|
; oamFindPos = min(thisPos, oamFindPos)
|
|
; numFreeSprites++
|
|
;---------------------------------------------------------------------
|
|
FreeSprite::
|
|
;if loptr is $ff then don't bother
|
|
cp $ff
|
|
ret z
|
|
|
|
push hl
|
|
|
|
ld l,a
|
|
ld h,((spriteOAMBuffer>>8) & $ff)
|
|
|
|
xor a
|
|
ld [hl],a ;ypos to zero
|
|
|
|
ld a,TILEINDEXBANK
|
|
ld [$ff70],a
|
|
|
|
rrc l ;convert loptr to sprite index
|
|
rrc l
|
|
ld h,((spritesUsed>>8) & $ff)
|
|
|
|
xor a
|
|
ld [hl],a ;clear sprite used flag
|
|
|
|
;set find pos to be mininum
|
|
ld a,[oamFindPos]
|
|
cp l
|
|
jr c,.findPosIsMin
|
|
|
|
ld a,l
|
|
ld [oamFindPos],a
|
|
|
|
.findPosIsMin
|
|
;add one to # of free sprites
|
|
ld hl,numFreeSprites
|
|
inc [hl]
|
|
|
|
pop hl
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: CreateMetaSprite
|
|
; Arguments:
|
|
; bc - width (b) and height (c) of metasprite, in 8x8
|
|
; tiles.
|
|
; d - initial pattern number for first sprite.
|
|
; e - default attributes for each sprite.
|
|
; hl - ptr to location to store metasprite info. Should
|
|
; be w*h + 1 in size.
|
|
; [metaSprite_x], [metaSprite_y] - location of TL corner
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
CreateMetaSprite::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld a,[metaSprite_x]
|
|
ld [metaSprite_first_x],a
|
|
|
|
;calculate width times height
|
|
push bc
|
|
xor a
|
|
.calcTotalSize
|
|
add a,b
|
|
dec c
|
|
jr nz,.calcTotalSize
|
|
pop bc
|
|
|
|
;store total sprites used in metaSpriteInfo
|
|
ld [hl+],a
|
|
|
|
;go through and allocate each sprite, set it up, and store its
|
|
;loptr in the metaSpriteInfo
|
|
push bc
|
|
.height pop af ;setup width from original value
|
|
push af
|
|
ld b,a
|
|
ld a,[metaSprite_first_x]
|
|
ld [metaSprite_x],a
|
|
|
|
.width call AllocateSprite
|
|
ld [hl+],a ;save loptr
|
|
|
|
;set up sprite
|
|
push hl
|
|
ld l,a
|
|
ld h,((spriteOAMBuffer>>8) & $ff)
|
|
ld a,[metaSprite_y]
|
|
ld [hl+],a
|
|
ld a,[metaSprite_x]
|
|
ld [hl+],a
|
|
add 8
|
|
ld [metaSprite_x],a
|
|
ld a,d ;pattern number
|
|
ld [hl+],a
|
|
inc d
|
|
ld [hl],e ;attributes
|
|
pop hl
|
|
|
|
dec b
|
|
jr nz,.width
|
|
|
|
ld a,[metaSprite_y]
|
|
add 8
|
|
ld [metaSprite_y],a
|
|
dec c
|
|
jr nz,.height
|
|
|
|
.done
|
|
pop bc
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: CreateMetaSpriteUsingMask
|
|
; Arguments:
|
|
; bc - width (b) and height (c) of metasprite, in 8x8
|
|
; tiles.
|
|
; d - initial pattern number for first sprite.
|
|
; e - default attributes for each sprite.
|
|
; hl - ptr to location to store metasprite info. Should
|
|
; be w*h + 1 in size and location 1+ should contain
|
|
; a zero if its corresponding sprite is not to
|
|
; be allocated after all.
|
|
; [metaSprite_x], [metaSprite_y] - location of TL corner
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
CreateMetaSpriteUsingMask::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld a,[metaSprite_x]
|
|
ld [metaSprite_first_x],a
|
|
|
|
;calculate width times height
|
|
push bc
|
|
xor a
|
|
.calcTotalSize
|
|
add a,b
|
|
dec c
|
|
jr nz,.calcTotalSize
|
|
pop bc
|
|
|
|
;store total sprites used in metaSpriteInfo
|
|
ld [hl+],a
|
|
|
|
;go through and allocate each sprite marked with non-zero,
|
|
;set it up, and store its loptr in the metaSpriteInfo
|
|
push bc
|
|
.height pop af ;setup width from original value
|
|
push af
|
|
ld b,a
|
|
ld a,[metaSprite_first_x]
|
|
ld [metaSprite_x],a
|
|
|
|
.width ld a,[hl] ;load flag from destination
|
|
or a
|
|
ld a,$ff
|
|
jr z,.afterAllocate
|
|
call AllocateSprite
|
|
|
|
.afterAllocate
|
|
ld [hl+],a ;save loptr
|
|
|
|
cp $ff
|
|
jr z,.afterSetup
|
|
|
|
;set up sprite
|
|
push hl
|
|
ld l,a
|
|
ld h,((spriteOAMBuffer>>8) & $ff)
|
|
ld a,[metaSprite_y]
|
|
ld [hl+],a
|
|
ld a,[metaSprite_x]
|
|
ld [hl+],a
|
|
ld a,d ;pattern number
|
|
ld [hl+],a
|
|
ld [hl],e ;attributes
|
|
pop hl
|
|
|
|
.afterSetup
|
|
ld a,[metaSprite_x]
|
|
add 8
|
|
ld [metaSprite_x],a
|
|
inc d
|
|
dec b
|
|
jr nz,.width
|
|
|
|
ld a,[metaSprite_y]
|
|
add 8
|
|
ld [metaSprite_y],a
|
|
dec c
|
|
jr nz,.height
|
|
|
|
.done
|
|
pop bc
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: ScrollMetaSprite
|
|
; Arguments: bc - x (b) and y (c) offset to scroll each sprite.
|
|
; hl - ptr to metaSpriteInfo created with
|
|
; CreateMetaSprite
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
ScrollMetaSprite::
|
|
push de
|
|
|
|
ld a,[hl+] ;number of sprites
|
|
.loop
|
|
push af
|
|
ld a,[hl+] ;loptr to sprite
|
|
ld e,a
|
|
ld d,((spriteOAMBuffer>>8) & $ff)
|
|
|
|
ld a,[de] ;get the y position
|
|
add c ;add y offset
|
|
ld [de],a
|
|
inc de
|
|
ld a,[de] ;get the x position
|
|
add b ;add x offset
|
|
ld [de],a
|
|
inc de
|
|
|
|
pop af
|
|
dec a
|
|
jr nz,.loop
|
|
pop de
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetMetaSpritePos
|
|
; Arguments: bc - desired x (b) and y (c) pixel position in sprite
|
|
; coords
|
|
; hl - ptr to metaSpriteInfo created with
|
|
; CreateMetaSprite
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
SetMetaSpritePos::
|
|
push bc
|
|
|
|
push hl
|
|
|
|
inc hl ;go to y pos of first sprite
|
|
ld l,[hl]
|
|
ld h,((spriteOAMBuffer>>8) & $ff)
|
|
|
|
ld a,c ;desired y pos
|
|
sub [hl]
|
|
ld c,a ;becomes offset to scroll
|
|
|
|
inc hl
|
|
ld a,b
|
|
sub [hl]
|
|
ld b,a ;becomes offset to scroll
|
|
|
|
pop hl
|
|
|
|
call ScrollMetaSprite
|
|
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: FreeMetaSprite
|
|
; Arguments: hl - ptr to metaSpriteInfo created with
|
|
; CreateMetaSprite
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
FreeMetaSprite::
|
|
push bc
|
|
push hl
|
|
|
|
ld a,[hl+] ;number of sprites
|
|
ld c,a
|
|
|
|
.freeASprite
|
|
ld a,[hl+] ;get loptr
|
|
call FreeSprite
|
|
dec c
|
|
jr nz,.freeASprite
|
|
|
|
pop hl
|
|
pop bc
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: CreateBigExplosion
|
|
; Arguments: bc - tile width and height of explosion area
|
|
; d - max sprites (must be >0)
|
|
; e - flags for allowed explosion types:
|
|
; :0 - small round explosions
|
|
; :1 - shrapnel plus
|
|
; :2 - big (2x2) round explosions (4 sprites ea)
|
|
; hl - TL map corner (e.g. $d0ca) of explosion
|
|
; [bulletColor]
|
|
; Returns: Nothing.
|
|
; Alters: af
|
|
; Description: Creates a big explosion of randomly dispersed smaller
|
|
; explosions within the given area.
|
|
;
|
|
;---------------------------------------------------------------------
|
|
CreateBigExplosion::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
;limit the number of sprites according to the system's
|
|
;resources
|
|
ld a,[numFreeSprites]
|
|
cp d
|
|
jr nc,.numSpritesOkay
|
|
ld d,a
|
|
.numSpritesOkay
|
|
or a
|
|
jr nz,.continue
|
|
jp .done
|
|
.continue
|
|
call ConvertLocHLToXY
|
|
ld a,[bulletColor]
|
|
|
|
.loop ;limit myself to smaller explosions if I have less than 4
|
|
;sprites left
|
|
push af
|
|
push hl
|
|
|
|
ld a,d
|
|
cp 4
|
|
jr nc,.afterLimitToSmaller
|
|
res 2,e ;remove larger fr possible explosions flags
|
|
ld a,e
|
|
or a
|
|
jr nz,.afterLimitToSmaller
|
|
ld d,1
|
|
jr .afterCreateExplosion
|
|
.afterLimitToSmaller
|
|
|
|
;select random tile position within area
|
|
|
|
;width
|
|
ld a,b
|
|
dec a
|
|
call GetRandomNumZeroToN
|
|
add h
|
|
ld h,a
|
|
|
|
;height
|
|
ld a,c
|
|
dec a
|
|
call GetRandomNumZeroToN
|
|
add l
|
|
ld l,a
|
|
|
|
call ConvertXYToLocHL
|
|
ld a,l
|
|
ld [bulletLocation],a
|
|
ld a,h
|
|
ld [bulletLocation+1],a
|
|
|
|
;choose random explosion
|
|
ld a,e
|
|
call GetRandomNumMask
|
|
bit 2,a
|
|
jr z,.checkType1
|
|
|
|
.isType2
|
|
bit 2,e ;this type allowed?
|
|
jr z,.isType0
|
|
;type two - big 2x2 explosion
|
|
ld a,6
|
|
ld [bulletColor],a
|
|
|
|
push bc
|
|
ld b,32
|
|
call .create2x2Frame
|
|
inc hl
|
|
call .create2x2Frame
|
|
push de
|
|
ld d,0
|
|
ld a,[mapPitch]
|
|
ld e,a
|
|
add hl,de
|
|
pop de
|
|
dec hl
|
|
call .create2x2Frame
|
|
inc hl
|
|
call .create2x2Frame
|
|
pop bc
|
|
|
|
dec d
|
|
dec d
|
|
dec d
|
|
jr .afterCreateExplosion
|
|
|
|
.checkType1
|
|
bit 1,a
|
|
jr z,.isType0
|
|
|
|
.isType1
|
|
bit 1,e ;this type allowed?
|
|
jr z,.isType2
|
|
;type one - shrapnel
|
|
ld a,64
|
|
jr .determinedFrame
|
|
|
|
.isType0 ;default
|
|
bit 0,e ;this type allowed?
|
|
jr z,.isType1
|
|
;type zero - small round explosion
|
|
ld a,5
|
|
ld [bulletColor],a
|
|
ld a,16
|
|
|
|
.determinedFrame
|
|
push bc
|
|
ld b,a
|
|
call CreateExplosion
|
|
call .offsetSprite
|
|
pop bc
|
|
|
|
.afterCreateExplosion
|
|
pop hl
|
|
.beforeRestoreColor
|
|
pop af
|
|
ld [bulletColor],a
|
|
|
|
dec d
|
|
jr z,.done
|
|
jp .loop
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
.offsetSprite
|
|
or a
|
|
ret z
|
|
push de
|
|
push hl
|
|
call IndexToPointerHL ;get ptr to explosion class
|
|
ld a,OBJBANK
|
|
ldio [$ff70],a
|
|
ld de,OBJ_SPRITELO
|
|
add hl,de
|
|
ld l,[hl]
|
|
ld h,((spriteOAMBuffer>>8) & $ff)
|
|
ld a,%111
|
|
call GetRandomNumMask
|
|
add [hl]
|
|
ld [hl+],a
|
|
ld a,%111
|
|
call GetRandomNumMask
|
|
add [hl]
|
|
ld [hl],a
|
|
pop hl
|
|
pop de
|
|
ret
|
|
|
|
.create2x2Frame
|
|
ld a,l
|
|
ld [bulletLocation],a
|
|
ld a,h
|
|
ld [bulletLocation+1],a
|
|
call CreateExplosion
|
|
ld a,b
|
|
add 8
|
|
ld b,a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: BlitMap
|
|
; Arguments: bc - tile width and height of area to copy
|
|
; de - destination XY coords
|
|
; hl - source XY coords
|
|
; Returns: Nothing.
|
|
; Alters: af
|
|
; Description: Copies a section of the current map, not overwriting
|
|
; any objects
|
|
;---------------------------------------------------------------------
|
|
BlitMap::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
push hl
|
|
ld h,d
|
|
ld l,e
|
|
call ConvertXYToLocHL
|
|
ld d,h
|
|
ld e,l
|
|
pop hl
|
|
call ConvertXYToLocHL
|
|
ld a,MAPBANK
|
|
ldio [$ff70],a
|
|
|
|
.blitMapOuter
|
|
push bc
|
|
push de
|
|
push hl
|
|
ldio a,[firstMonster]
|
|
ld c,a
|
|
|
|
.blitMapInner
|
|
ld a,[de]
|
|
cp c ;< first monster?
|
|
jr nc,.blitSkip
|
|
|
|
ld a,[hl]
|
|
ld [de],a
|
|
.blitSkip
|
|
inc hl
|
|
inc de
|
|
dec b
|
|
jr nz,.blitMapInner
|
|
|
|
pop hl
|
|
pop de
|
|
push hl
|
|
ld a,[mapPitch]
|
|
ld h,0
|
|
ld l,a
|
|
add hl,de
|
|
ld d,h
|
|
ld e,l
|
|
pop hl
|
|
ld a,[mapPitch]
|
|
ld b,0
|
|
ld c,a
|
|
add hl,bc
|
|
|
|
pop bc
|
|
dec c
|
|
jr nz,.blitMapOuter
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: ConvertLocHLToXY
|
|
; Arguments: hl - location ($D000-$DFFF)
|
|
; Returns: hl - h = x index, l = y index
|
|
; Alters: a,hl
|
|
; Description: x = location & (pitch-1)
|
|
; y = (location - $D000) / pitch
|
|
;---------------------------------------------------------------------
|
|
ConvertLocHLToXY::
|
|
ld a,[mapPitchMinusOne]
|
|
and l
|
|
push af ;push a (x index) on stack
|
|
|
|
ld a,h ;subtract $D000 from hl by adding $3000
|
|
add $30
|
|
ld h,a
|
|
ld a,[mapPitchMinusOneComplement] ;times to left-shift
|
|
.shift rlca ;shift a bit left out of a
|
|
jr nc,.shiftDone ;hl<<=1 if bits left in a
|
|
sla l
|
|
rl h
|
|
jr .shift
|
|
|
|
.shiftDone
|
|
ld l,h
|
|
pop af
|
|
ld h,a ;h = x index, l = y index
|
|
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: ConvertXYToLocHL
|
|
; Arguments: hl - h = x index, l = y index
|
|
; Returns: hl - location ptr ($D000-$DFFF)
|
|
; Alters: a,hl
|
|
; Description: hl = $d000 + (y * pitch) + x
|
|
; Instead of having y in the LoByte and left-shifting it
|
|
; by the bits in the pitch, we'll put y in the HiByte
|
|
; and right-shift it by 8-bitsInPitch. Fewer ops.
|
|
;---------------------------------------------------------------------
|
|
ConvertXYToLocHL::
|
|
push de
|
|
|
|
;multiply y*pitch
|
|
ld a,[mapPitchMinusOneComplement]
|
|
ld d,l
|
|
ld e,0
|
|
|
|
.shift rlca ;if bits left in A then keep shifting
|
|
jr nc,.shiftDone
|
|
srl d
|
|
rr e
|
|
jr .shift
|
|
|
|
.shiftDone
|
|
ld l,h ;add x + $d000
|
|
ld h,$d0
|
|
add hl,de
|
|
|
|
pop de
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: LCheckGetVectorToState
|
|
; Arguments: hl - address of method table
|
|
; Returns: hl - methodTable[mapState]
|
|
; Alters: af,hl
|
|
; Description: Use the VECTORTOSTATE macro.
|
|
;---------------------------------------------------------------------
|
|
LCheckGetVectorToState::
|
|
push de
|
|
ldio a,[mapState]
|
|
ld d,0
|
|
ld e,a
|
|
sla e
|
|
rl d
|
|
add hl,de
|
|
pop de
|
|
ld a,[hl+]
|
|
ld h,[hl]
|
|
ld l,a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SaveIdle
|
|
; Arguments: None.
|
|
; Returns:
|
|
; Alters: af,hl
|
|
; Description: Saves the current state of [heroesIdle] and [allIdle]
|
|
; in [dialogIdleSettings] and activates both idle
|
|
; settings
|
|
;---------------------------------------------------------------------
|
|
SaveIdle::
|
|
ld a,[heroesIdle]
|
|
rlca
|
|
ld hl,allIdle
|
|
or [hl]
|
|
ld [dialogIdleSettings],a
|
|
|
|
ld a,1
|
|
ld [heroesIdle],a
|
|
ld [allIdle],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: RestoreIdle
|
|
; Arguments: None.
|
|
; Returns:
|
|
; Alters: af,hl
|
|
; Description: Restores the idle settings to what they were previous
|
|
; to SaveIdle
|
|
;---------------------------------------------------------------------
|
|
RestoreIdle::
|
|
ld a,[dialogIdleSettings]
|
|
push af
|
|
and 1
|
|
ld [allIdle],a
|
|
pop af
|
|
srl a
|
|
ld [heroesIdle],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: MakeIdle
|
|
; Arguments: None.
|
|
; Returns:
|
|
; Alters: af
|
|
; Description: Sets [heroesIdle] and [allIdle] to 1
|
|
;---------------------------------------------------------------------
|
|
MakeIdle::
|
|
ld a,1
|
|
ld [heroesIdle],a
|
|
ld [allIdle],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: MakeNonIdle
|
|
; Arguments: None.
|
|
; Returns:
|
|
; Alters: af
|
|
; Description: Sets [heroesIdle] and [allIdle] to 0
|
|
;---------------------------------------------------------------------
|
|
MakeNonIdle::
|
|
xor a
|
|
ld [heroesIdle],a
|
|
ld [allIdle],a
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: UseAlternatePalette
|
|
; Arguments: None.
|
|
; Returns: Nothing.
|
|
; Alters: af
|
|
; Description: Darkens colors 1 & 2 of each palette, intended for
|
|
; use on the light-background maps.
|
|
;---------------------------------------------------------------------
|
|
UseAlternatePalette::
|
|
push bc
|
|
push hl
|
|
|
|
ld a,FADEBANK
|
|
ldio [$ff70],a
|
|
|
|
ld c,16
|
|
ld hl,gamePalette+2
|
|
.loop call .halve
|
|
call .halve
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
dec c
|
|
jr nz,.loop
|
|
|
|
pop hl
|
|
pop bc
|
|
ret
|
|
|
|
.halve
|
|
ld a,[hl+] ;color[i]>>=1;
|
|
ld b,a
|
|
ld a,[hl]
|
|
rrca
|
|
rr b
|
|
and %00111101
|
|
ld [hl-],a
|
|
ld a,b
|
|
and %11101111
|
|
ld [hl+],a
|
|
inc hl
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: GetMyHero
|
|
; Arguments: None.
|
|
; Returns: a - class index of local hero (i.e. not remote)
|
|
; hl - pointer to hero0_data or hero1_data approprately
|
|
; Alters: af, hl
|
|
;---------------------------------------------------------------------
|
|
GetMyHero::
|
|
ld a,[amLinkMaster]
|
|
cp 0
|
|
jr z,.getHero1
|
|
|
|
;get hero zero if link master
|
|
ld a,[hero0_index]
|
|
ld hl,hero0_data
|
|
ret
|
|
|
|
.getHero1
|
|
ld a,[hero1_index]
|
|
ld hl,hero1_data
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: GetBGAttributes
|
|
; Arguments: a - class index
|
|
; Alters: af
|
|
; Returns: a - attributes for given class index
|
|
; Returns full set off attributes including:
|
|
; [2:0] - color FLAG_PALETTE
|
|
; [3] - can walk over FLAG_WALKOVER
|
|
; [4] - can shoot over FLAG_SHOOTOVER
|
|
;---------------------------------------------------------------------
|
|
GetBGAttributes::
|
|
push hl
|
|
ld l,a
|
|
ld h,((bgAttributes>>8) & $ff)
|
|
ld a,TILEINDEXBANK
|
|
ldio [$ff70],a
|
|
ld a,[hl]
|
|
pop hl
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: UpdateDialogBalloons
|
|
; Arguments: de - intial pos in [spritesUsed]
|
|
; hl - initial pos in spriteOAMBuffer
|
|
; Alters: af, de, hl
|
|
;---------------------------------------------------------------------
|
|
UpdateDialogBalloons::
|
|
ld a,[amShowingDialog]
|
|
or a
|
|
ret nz ;no balloons during dialog
|
|
|
|
ldio a,[updateTimer]
|
|
and %00010000
|
|
ret z ;all blank
|
|
|
|
push bc
|
|
call FindNextFreeSprite
|
|
jr z,.done
|
|
ld a,[dialogBalloonClassIndex]
|
|
ld c,a
|
|
call GetFirst
|
|
.setNextBalloon
|
|
or a
|
|
jr z,.done
|
|
|
|
call PutBalloonAboveObject
|
|
|
|
;remake de from hl
|
|
push de
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
call .remakeDEfromHL
|
|
call FindNextFreeSprite
|
|
pop de
|
|
jr z,.done
|
|
|
|
call GetNextObject
|
|
jr .setNextBalloon
|
|
|
|
.done
|
|
call .remakeDEfromHL
|
|
pop bc
|
|
ret
|
|
|
|
.remakeDEfromHL
|
|
ld a,l ;e = l/4
|
|
rrca
|
|
rrca
|
|
ld e,a
|
|
ld d,((spritesUsed>>8)&$ff)
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: DisableDialogBalloons
|
|
; Arguments: a - mask of objects (up to 8) to disable. %101
|
|
; would disable the first and third speakers, etc.
|
|
; Speakers after the eigth are disabled.
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
DisableDialogBalloons::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld b,a
|
|
|
|
ld a,[dialogBalloonClassIndex]
|
|
or a
|
|
jr z,.done
|
|
|
|
ld c,a
|
|
call GetFirst
|
|
.disableNext
|
|
or a
|
|
jr z,.done
|
|
|
|
ld a,b
|
|
or a
|
|
jr z,.disableAfter8
|
|
|
|
and 1
|
|
jr z,.continue
|
|
|
|
ld a,1
|
|
call SetMisc
|
|
|
|
.continue
|
|
srl b
|
|
call GetNextObject
|
|
jr .disableNext
|
|
|
|
.disableAfter8
|
|
ld b,8
|
|
ld a,[dialogBalloonClassIndex]
|
|
ld c,a
|
|
call GetFirst
|
|
.find9th
|
|
or a
|
|
jr z,.done
|
|
|
|
call GetNextObject
|
|
dec b
|
|
jr nz,.find9th
|
|
|
|
.disableAfter8Next
|
|
or a
|
|
jr z,.done
|
|
|
|
ld a,1
|
|
call SetMisc
|
|
|
|
call GetNextObject
|
|
jr .disableAfter8Next
|
|
|
|
.done
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: FindNextFreeSprite
|
|
; Arguments: de - ptr to position within spritesUsed to begin
|
|
; resetting
|
|
; hl - ptr to sprite OAM buffer corresponding to
|
|
; de
|
|
; Alters: af,de,hl
|
|
; Returns: a - 0 on failure
|
|
;---------------------------------------------------------------------
|
|
FindNextFreeSprite:
|
|
ld a,e
|
|
cp 40
|
|
jr nc,.notFound
|
|
|
|
push bc
|
|
ld a,TILEINDEXBANK
|
|
ldio [$ff70],a
|
|
ld bc,4
|
|
|
|
.checkNext
|
|
ld a,[de]
|
|
or a
|
|
jr z,.foundIt
|
|
|
|
inc de
|
|
add hl,bc
|
|
ld a,e
|
|
cp 40
|
|
jr c,.checkNext
|
|
|
|
pop bc
|
|
.notFound
|
|
xor a
|
|
ret
|
|
|
|
.foundIt
|
|
ld a,1
|
|
or a
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: PutBalloonAboveObject
|
|
; Arguments: de - ptr to object
|
|
; hl - ptr to sprite OAM buffer
|
|
; Alters: af
|
|
;---------------------------------------------------------------------
|
|
PutBalloonAboveObject:
|
|
push de
|
|
push hl
|
|
|
|
ld [hl],0 ;zero sprite in case we don't use it
|
|
push hl
|
|
call GetMisc
|
|
pop hl
|
|
or a
|
|
jr nz,.done ;already spoke
|
|
call GetCurLocation
|
|
call ConvertLocHLToSpriteCoords
|
|
ld d,h
|
|
ld e,l
|
|
pop hl
|
|
push hl
|
|
ld a,e
|
|
or a
|
|
jr z,.afterAdjustCoords ;leave zero at zero
|
|
|
|
sub 8
|
|
ld e,a
|
|
ld a,d
|
|
add 8
|
|
ld d,a
|
|
|
|
.afterAdjustCoords
|
|
ld [hl],e ;y coord
|
|
inc hl
|
|
ld [hl],d ;x coord
|
|
inc hl
|
|
ld a,80 ;pattern number
|
|
ld [hl+],a
|
|
xor a
|
|
ld [hl],a ;palette/etc
|
|
.done
|
|
pop hl
|
|
pop de
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: ResetFreeSprites
|
|
; Arguments: de - ptr to position within spritesUsed to begin
|
|
; resetting
|
|
; hl - ptr to sprite OAM buffer corresponding to
|
|
; de
|
|
; Alters: af,de,hl
|
|
; Returns: Nothing.
|
|
; Description: Sets y=0 of all sprites after initial position not
|
|
; flagged as in use; necessary for resetting
|
|
; environmental effects
|
|
;---------------------------------------------------------------------
|
|
ResetFreeSprites::
|
|
ld a,e
|
|
cp 40
|
|
ret nc
|
|
|
|
push bc
|
|
|
|
ld a,TILEINDEXBANK
|
|
ldio [$ff70],a
|
|
ld bc,4
|
|
|
|
.resetNext
|
|
ld a,[de]
|
|
or a
|
|
jr nz,.afterReset
|
|
|
|
ld [hl],a ;ypos = 0
|
|
|
|
.afterReset
|
|
add hl,bc
|
|
inc de
|
|
ld a,e
|
|
cp 40
|
|
jr c,.resetNext
|
|
|
|
pop bc
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: SetEnvEffect
|
|
; Arguments: a - env effect such as ENV_RAIN
|
|
; Alters: af
|
|
; Returns: Nothing.
|
|
; Description: Sets an environmental effect and quickly updates it
|
|
; a number of times to be in full swing by the time
|
|
; the player sees it
|
|
;---------------------------------------------------------------------
|
|
SetEnvEffect::
|
|
push bc
|
|
ld [envEffectType],a
|
|
|
|
ld c,16
|
|
.updateEffect
|
|
call UpdateEnvEffect
|
|
dec c
|
|
jr nz,.updateEffect
|
|
|
|
pop bc
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
; Routine: UpdateEnvEffect
|
|
; Arguments: None.
|
|
; Alters: af
|
|
; Returns: Nothing.
|
|
; Description: Sets unused sprites to be dialog/rain/snow etc based
|
|
; on [envEffectType]. Calls UpdateDialogBalloons and
|
|
; ResetFreeSprites
|
|
;---------------------------------------------------------------------
|
|
UpdateEnvEffect::
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
ld de,spritesUsed
|
|
ld hl,spriteOAMBuffer
|
|
|
|
ld c,0
|
|
|
|
ld a,[dialogBalloonClassIndex]
|
|
or a
|
|
jr z,.afterUpdateBalloons
|
|
|
|
inc c
|
|
call nz,UpdateDialogBalloons
|
|
|
|
.afterUpdateBalloons
|
|
ld a,[envEffectType]
|
|
or a
|
|
jr z,.afterEffect
|
|
|
|
ldio a,[randomLoc]
|
|
push af
|
|
ld a,[asyncRandLoc]
|
|
ldio [randomLoc],a
|
|
ld a,[envEffectType]
|
|
call .updateAppropriate
|
|
ldio a,[randomLoc]
|
|
ldio [asyncRandLoc],a
|
|
pop af
|
|
ldio [randomLoc],a
|
|
|
|
.afterEffect
|
|
call ResetFreeSprites
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
.updateAppropriate
|
|
inc c
|
|
|
|
cp ENV_RAIN
|
|
jr nz,.checkSnow
|
|
|
|
ld d,e
|
|
LONGCALLNOARGS EnvRain
|
|
ret
|
|
|
|
.checkSnow
|
|
cp ENV_SNOW
|
|
jr nz,.checkDirt
|
|
|
|
ld d,e
|
|
LONGCALLNOARGS EnvSnow
|
|
ret
|
|
|
|
.checkDirt
|
|
cp ENV_DIRT
|
|
jr nz,.checkClouds
|
|
|
|
ld d,e
|
|
LONGCALLNOARGS EnvDirt
|
|
ret
|
|
|
|
.checkClouds
|
|
cp ENV_CLOUDS
|
|
jr nz,.checkWindySnow
|
|
|
|
ld d,e
|
|
LONGCALLNOARGS EnvClouds
|
|
ret
|
|
|
|
.checkWindySnow
|
|
cp ENV_WINDYSNOW
|
|
jr nz,.checkCounter
|
|
|
|
ld d,e
|
|
LONGCALLNOARGS EnvWindySnow
|
|
ret
|
|
|
|
.checkCounter
|
|
cp ENV_COUNTER
|
|
jr nz,.checkDisco
|
|
|
|
;reset first two sprites to y=16
|
|
ld hl,spriteOAMBuffer
|
|
ld de,4
|
|
ld [hl],16
|
|
add hl,de
|
|
ld [hl],16
|
|
ret
|
|
|
|
.checkDisco
|
|
cp ENV_DISCO
|
|
ret nz
|
|
|
|
LONGCALLNOARGS EnvDisco
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
SECTION "GfxSupport",ROMX
|
|
;---------------------------------------------------------------------
|
|
EnvRain:
|
|
call EnvSetupDEHL
|
|
ld b,0
|
|
.nextDrop
|
|
call FindNextFreeSprite
|
|
ret z
|
|
|
|
inc b
|
|
|
|
ld a,[hl]
|
|
or a
|
|
jr nz,.updatePosition
|
|
|
|
.newDrop
|
|
;create new raindrop
|
|
ld a,63
|
|
call GetRandomNumMask
|
|
cpl
|
|
add 16
|
|
ld [hl+],a ;ypos
|
|
|
|
ld a,255
|
|
call GetRandomNumMask
|
|
;add 8
|
|
;ld [hl],a
|
|
;ld a,63
|
|
;call GetRandomNumMask
|
|
;add [hl]
|
|
;sub 64
|
|
ld [hl+],a ;xpos
|
|
|
|
ld [hl],81 ;pattern
|
|
inc hl
|
|
ld [hl],2 ;palette
|
|
inc hl
|
|
inc de
|
|
jr .nextDrop
|
|
|
|
.updatePosition
|
|
ld a,[hl]
|
|
add 8
|
|
ld [hl],a
|
|
and 184
|
|
cp 184
|
|
jr nz,.afterRemove
|
|
|
|
.remove
|
|
ld [hl],0
|
|
.afterRemove
|
|
inc hl
|
|
ld a,[hl]
|
|
add 4
|
|
ld [hl+],a
|
|
ld a,[hl+]
|
|
cp 81 ;rain pattern
|
|
jr z,.dropOkay
|
|
|
|
;change into a rain sprite
|
|
dec hl
|
|
ld [hl],81
|
|
inc hl
|
|
ld [hl],2
|
|
|
|
;push hl
|
|
;dec hl
|
|
;dec hl
|
|
;ld [hl],0 ;reset sprite
|
|
;pop hl
|
|
|
|
.dropOkay
|
|
inc hl
|
|
inc de
|
|
jp .nextDrop
|
|
|
|
EnvSnow:
|
|
call EnvSetupDEHL
|
|
ld b,0
|
|
.nextFlake
|
|
call FindNextFreeSprite
|
|
ret z
|
|
|
|
inc b
|
|
|
|
ld a,[hl]
|
|
or a
|
|
jr nz,.updatePosition
|
|
|
|
.newFlake
|
|
;create new snowflake
|
|
ld a,63
|
|
call GetRandomNumMask
|
|
cpl
|
|
add 16
|
|
ld [hl+],a ;ypos
|
|
|
|
ld a,255
|
|
call GetRandomNumMask
|
|
;add 8
|
|
;ld [hl],a
|
|
;ld a,63
|
|
;call GetRandomNumMask
|
|
;add [hl]
|
|
;sub 10
|
|
ld [hl+],a ;xpos
|
|
|
|
ld [hl],74 ;pattern
|
|
inc hl
|
|
ld [hl],0 ;palette
|
|
inc hl
|
|
inc de
|
|
jr .nextFlake
|
|
|
|
.updatePosition
|
|
ld a,[hl]
|
|
;add 4
|
|
inc a
|
|
ld [hl],a
|
|
and 184
|
|
cp 184
|
|
jr nz,.afterRemove
|
|
|
|
.remove
|
|
ld [hl],0
|
|
.afterRemove
|
|
;get deltax offset for this flake mem loc + y loc
|
|
ld a,l
|
|
rrca
|
|
rrca
|
|
add [hl] ;plus y coord
|
|
and 63
|
|
|
|
push hl
|
|
add (flakeSineTable & $ff)
|
|
ld l,a
|
|
ld a,0
|
|
adc ((flakeSineTable>>8)&$ff)
|
|
ld h,a
|
|
ld a,[hl]
|
|
pop hl
|
|
inc hl
|
|
add [hl]
|
|
ld [hl+],a ;new x coord
|
|
ld a,[hl+]
|
|
cp 74 ;flake pattern
|
|
jr z,.flakeOkay
|
|
|
|
;change into a snowflake sprite
|
|
dec hl
|
|
ld [hl],74
|
|
inc hl
|
|
ld [hl],0
|
|
|
|
;push hl
|
|
;dec hl
|
|
;dec hl
|
|
;ld [hl],0 ;reset sprite
|
|
;pop hl
|
|
|
|
.flakeOkay
|
|
inc hl
|
|
inc de
|
|
jp .nextFlake
|
|
|
|
|
|
EnvDirt:
|
|
call EnvSetupDEHL
|
|
ld b,0
|
|
.nextGrit
|
|
call FindNextFreeSprite
|
|
ret z
|
|
|
|
inc b
|
|
|
|
ld a,[hl]
|
|
or a
|
|
jr nz,.updatePosition
|
|
|
|
.newGrit
|
|
;create new sand
|
|
ld a,127
|
|
call GetRandomNumMask
|
|
ld [hl],a ;ypos
|
|
ld a,31
|
|
call GetRandomNumMask
|
|
add [hl]
|
|
sub 10
|
|
ld [hl+],a
|
|
|
|
ld a,63
|
|
call GetRandomNumMask
|
|
cpl
|
|
add 8
|
|
ld [hl+],a ;xpos
|
|
|
|
ld [hl],72 ;pattern
|
|
inc hl
|
|
ld [hl],6 ;palette
|
|
inc hl
|
|
inc de
|
|
jr .nextGrit
|
|
|
|
.updatePosition
|
|
ld a,l ;y += (-1,0,1,2)
|
|
rrca
|
|
rrca
|
|
and %11
|
|
sub 1
|
|
add [hl]
|
|
ld [hl+],a
|
|
|
|
ld a,[hl]
|
|
add 8
|
|
ld [hl+],a
|
|
and 184
|
|
cp 184
|
|
jr nz,.afterRemove
|
|
|
|
.remove
|
|
push hl
|
|
dec hl
|
|
dec hl
|
|
ld [hl],0
|
|
pop hl
|
|
.afterRemove
|
|
ld a,[hl+]
|
|
cp 72 ;grit pattern
|
|
jr z,.gritOkay
|
|
|
|
push hl
|
|
dec hl
|
|
dec hl
|
|
dec hl
|
|
ld [hl],0 ;reset sprite
|
|
pop hl
|
|
|
|
.gritOkay
|
|
inc hl
|
|
inc de
|
|
jp .nextGrit
|
|
|
|
EnvWindySnow:
|
|
call EnvSetupDEHL
|
|
ld b,0
|
|
.nextFlake
|
|
call FindNextFreeSprite
|
|
ret z
|
|
|
|
inc b
|
|
|
|
ld a,[hl]
|
|
or a
|
|
jr nz,.updatePosition
|
|
|
|
.newFlake
|
|
;create new flake
|
|
ld a,127
|
|
call GetRandomNumMask
|
|
ld [hl],a ;ypos
|
|
ld a,31
|
|
call GetRandomNumMask
|
|
add [hl]
|
|
sub 10
|
|
ld [hl+],a
|
|
|
|
ld a,63
|
|
call GetRandomNumMask
|
|
cpl
|
|
add 168
|
|
ld [hl+],a ;xpos
|
|
|
|
ld [hl],74 ;pattern
|
|
inc hl
|
|
ld [hl],0 ;palette
|
|
inc hl
|
|
inc de
|
|
jr .nextFlake
|
|
|
|
.updatePosition
|
|
ld a,l ;y += (-1,0,1,2)
|
|
rrca
|
|
rrca
|
|
and %11
|
|
sub 1
|
|
add [hl]
|
|
ld [hl+],a
|
|
|
|
ld a,[hl]
|
|
sub 8
|
|
ld [hl+],a
|
|
and 248
|
|
cp 248
|
|
jr nz,.afterRemove
|
|
|
|
.remove
|
|
push hl
|
|
dec hl
|
|
dec hl
|
|
ld [hl],0
|
|
pop hl
|
|
.afterRemove
|
|
ld a,[hl+]
|
|
cp 74 ;flake pattern
|
|
jr z,.flakeOkay
|
|
|
|
;change into a snowflake sprite
|
|
dec hl
|
|
ld [hl],74
|
|
inc hl
|
|
ld [hl],0
|
|
|
|
;push hl
|
|
;dec hl
|
|
;dec hl
|
|
;dec hl
|
|
;ld [hl],0 ;reset sprite
|
|
;pop hl
|
|
|
|
.flakeOkay
|
|
inc hl
|
|
inc de
|
|
jp .nextFlake
|
|
|
|
EnvClouds:
|
|
call EnvSetupDEHL
|
|
ld b,0
|
|
.nextCloud
|
|
call FindNextFreeSprite
|
|
ret z
|
|
|
|
inc b
|
|
|
|
ld a,[hl]
|
|
or a
|
|
jr nz,.updatePosition
|
|
|
|
ld a,b
|
|
and %11
|
|
jr nz,.addToCloud
|
|
|
|
;one in 8 chance of creating a cloud
|
|
ld a,1
|
|
call GetRandomNumMask
|
|
or a
|
|
jr z,.newCloud
|
|
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
inc de
|
|
jr .nextCloud
|
|
|
|
.newCloud
|
|
;create new cloud
|
|
ld a,144
|
|
call GetRandomNumZeroToN
|
|
add 16
|
|
ld [hl+],a ;ypos
|
|
ld [$c01e],a
|
|
|
|
ld a,63
|
|
call GetRandomNumMask
|
|
cpl
|
|
ld [hl+],a ;xpos
|
|
ld [$c01f],a
|
|
|
|
ld a,3
|
|
call GetRandomNumMask
|
|
add 82
|
|
ld [hl+],a ;pattern
|
|
ld [hl],4 ;palette
|
|
inc hl
|
|
inc de
|
|
jr .nextCloud
|
|
|
|
.addToCloud
|
|
push de
|
|
ld a,7
|
|
call GetRandomNumMask
|
|
ld d,a
|
|
ld a,[$c01e]
|
|
add d
|
|
ld [hl+],a ;ypos
|
|
|
|
ld a,7
|
|
call GetRandomNumMask
|
|
ld d,a
|
|
ld a,[$c01f]
|
|
add d
|
|
ld [hl+],a ;xpos
|
|
|
|
ld a,3
|
|
call GetRandomNumMask
|
|
add 82
|
|
ld [hl+],a ;pattern
|
|
ld [hl],4 ;palette
|
|
inc hl
|
|
pop de
|
|
inc de
|
|
jr .nextCloud
|
|
|
|
.updatePosition
|
|
inc hl
|
|
;bit 2,l
|
|
;jr z,.updateOnTimer
|
|
jr .updateOnTimer
|
|
inc [hl]
|
|
jr .afterIncr
|
|
.updateOnTimer
|
|
ldio a,[updateTimer]
|
|
and 1
|
|
jr z,.afterIncr
|
|
inc [hl]
|
|
.afterIncr
|
|
ld a,[hl]
|
|
cp 178
|
|
jr nz,.afterRemove
|
|
|
|
dec hl
|
|
ld [hl],0
|
|
inc hl
|
|
.afterRemove
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
inc de
|
|
jp .nextCloud
|
|
|
|
EnvSetupDEHL:
|
|
ld d,((spritesUsed>>8)&$ff)
|
|
ld a,e
|
|
rlca
|
|
rlca
|
|
ld l,a
|
|
ld h,((spriteOAMBuffer>>8)&$ff)
|
|
ret
|
|
|
|
flakeSineTable:
|
|
DB $ff,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
|
|
DB 0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0
|
|
DB 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$ff
|
|
DB 0,0,$ff,0,0,$ff,0,0,$ff,0,$ff,0,0,$ff,0,0
|
|
|
|
;---------------------------------------------------------------------
|
|
; EnvDisco
|
|
; Uses binary data "discoLights" to set all colors to purple in
|
|
; drawing buffer except where lights are flashing. Uses levelVars[0]
|
|
; to determine current frame
|
|
;---------------------------------------------------------------------
|
|
EnvDisco:
|
|
push bc
|
|
push de
|
|
push hl
|
|
|
|
;setup hl to point to light data for appropriate frame
|
|
ld de,20*18
|
|
ld hl,discoLights
|
|
ld a,[levelVars]
|
|
or a
|
|
jr z,.frameSet
|
|
|
|
.times360
|
|
add hl,de
|
|
dec a
|
|
jr nz,.times360
|
|
|
|
.frameSet
|
|
ld de,attributeBuffer
|
|
ld b,18 ;18 rows
|
|
.outer
|
|
ld c,20 ;20 columns
|
|
.inner
|
|
ld a,[hl+]
|
|
or a
|
|
jr nz,.afterSetColor
|
|
|
|
ld a,[de]
|
|
or %111
|
|
ld [de],a
|
|
|
|
.afterSetColor
|
|
inc de
|
|
|
|
dec c
|
|
jr nz,.inner
|
|
|
|
push hl
|
|
ld hl,12
|
|
add hl,de
|
|
ld d,h
|
|
ld e,l
|
|
pop hl
|
|
|
|
dec b
|
|
jr nz,.outer
|
|
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
ret
|
|
|
|
discoLights:
|
|
INCBIN "Data/discolights.dat"
|
|
|
|
;Not in HOME
|
|
|
|
;---------------------------------------------------------------------
|
|
SECTION "FontSection",ROMX,BANK[MAP0ROM],ALIGN[4]
|
|
fontData:
|
|
INCBIN "Data/font.bin"
|
|
|
|
blankTileData:
|
|
DW 0,0,0,0,0,0,0,0
|
|
|
|
explosionSprites:
|
|
INCBIN "Data/Sprites/explosions0-85.bin"
|
|
|
|
SECTION "ReservedSpriteDMAHandler",HRAM[$FF80]
|
|
SpriteDMAHandler::
|
|
DS (oamHandlerFinish - oamHandlerStart)
|
|
|
|
;---------------------------------------------------------------------
|
|
SECTION "GfxSupportSection",ROMX[$4000]
|
|
;---------------------------------------------------------------------
|
|
;$4000
|
|
randomTable:
|
|
DB $9f,$d2,$e6,$e7,$70,$db,$11,$63,$6b,$37,$99,$98,$30,$9c,$d9,$35
|
|
DB $65,$af,$56,$ee,$b1,$00,$fd,$c7,$61,$48,$df,$45,$2e,$41,$6d,$9b
|
|
DB $13,$40,$d8,$fa,$91,$02,$29,$e0,$cb,$5d,$28,$fb,$2f,$77,$ea,$f9
|
|
DB $7e,$92,$5b,$75,$b5,$fc,$ae,$a2,$71,$cc,$a9,$3f,$7f,$7d,$ad,$7c
|
|
DB $73,$a5,$f8,$03,$9e,$25,$f6,$e8,$4d,$33,$b3,$44,$aa,$26,$08,$6e
|
|
DB $82,$97,$96,$19,$c8,$b4,$ba,$d3,$1f,$d0,$f5,$06,$54,$86,$49,$e2
|
|
DB $69,$43,$0b,$b0,$f1,$83,$a8,$9d,$38,$42,$ef,$e4,$74,$12,$20,$a0
|
|
DB $55,$01,$66,$23,$3d,$51,$c0,$79,$10,$de,$eb,$d5,$09,$8e,$5e,$67
|
|
DB $4a,$7a,$3e,$4b,$68,$8d,$e9,$62,$1b,$dd,$da,$bb,$53,$22,$3c,$b6
|
|
DB $ff,$81,$24,$8b,$d4,$6f,$d7,$9a,$d6,$21,$f4,$0a,$b2,$bc,$a7,$36
|
|
DB $34,$64,$c5,$a6,$4e,$b9,$f3,$0e,$f0,$3b,$cd,$0d,$17,$ec,$1a,$8a
|
|
DB $e3,$16,$93,$05,$c9,$14,$c1,$cf,$52,$2c,$1e,$bf,$88,$27,$1d,$f7
|
|
DB $5c,$ac,$ab,$3a,$bd,$a1,$f2,$04,$e5,$2d,$e1,$c2,$15,$fe,$8c,$6a
|
|
DB $2b,$84,$1c,$d1,$47,$c6,$58,$c3,$0f,$ce,$5f,$90,$8f,$76,$60,$0c
|
|
DB $94,$2a,$6c,$89,$39,$46,$18,$95,$7b,$dc,$b7,$72,$78,$5a,$57,$ca
|
|
DB $4f,$a4,$59,$07,$32,$c4,$ed,$b8,$50,$85,$a3,$31,$4c,$87,$80,$be
|
|
|
|
;0=star 1=moon 2=flower 3=crouton 4=i 5=monkey 6=wrench 7=man
|
|
;$4100
|
|
init_flightCodes:
|
|
DB $0f
|
|
DB $00,$00,$06
|
|
DB $00,$00,$23
|
|
DB $00,$00,$29
|
|
DB $00,$00,$3a
|
|
DB $00,$00,$47
|
|
DB $00,$00,$59
|
|
DB $00,$00,$66
|
|
DB $00,$00,$a3
|
|
DB $00,$00,$a8
|
|
DB $00,$00,$0a
|
|
DB $00,$00,$3d
|
|
DB $63,$02,$71 ;initial landing star flower wrench crouton
|
|
DB $33,$53,$81 ;mouse landing monkey crouton crouton crouton
|
|
DB $65,$70,$c7 ;farm landing man star wrench monkey
|
|
DB $12,$01,$55 ;palace star moon moon flower
|
|
DB $00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
|
|
|