2024-04-16 21:04:45 -06:00
|
|
|
INCLUDE "hardware.inc"
|
|
|
|
INCLUDE "sprobjs_lib.asm"
|
|
|
|
|
|
|
|
SECTION "Header", ROM0[$100]
|
|
|
|
|
|
|
|
jp Init
|
|
|
|
|
|
|
|
ds $150 - @, 0 ; Make room for the header
|
|
|
|
|
2024-04-18 01:48:36 -06:00
|
|
|
SECTION "Main", ROM0
|
2024-04-16 21:04:45 -06:00
|
|
|
Init:
|
|
|
|
; Shut down audio circuitry
|
|
|
|
ld a, 0
|
|
|
|
ld [rNR52], a
|
|
|
|
|
|
|
|
; Do not turn the LCD off outside of VBlank
|
|
|
|
WaitVBlank:
|
|
|
|
ld a, [rLY]
|
|
|
|
cp 144
|
|
|
|
jp c, WaitVBlank
|
|
|
|
|
|
|
|
; Turn the LCD off
|
|
|
|
ld a, 0
|
|
|
|
ld [rLCDC], a
|
|
|
|
|
|
|
|
; Initialize Sprite Object Library
|
|
|
|
call InitSprObjLib
|
|
|
|
|
|
|
|
; Reset hardware OAM
|
|
|
|
xor a, a
|
|
|
|
ld b, 160
|
|
|
|
ld hl, _OAMRAM
|
|
|
|
.resetOAM
|
|
|
|
ld [hli], a
|
|
|
|
dec b
|
|
|
|
jr nz, .resetOAM
|
|
|
|
|
|
|
|
; Copy cat sprite
|
|
|
|
ld de, GfxCat
|
|
|
|
ld hl, $8000
|
|
|
|
ld bc, GfxCat.end - GfxCat
|
|
|
|
call Memcopy
|
|
|
|
|
|
|
|
; Reset positions
|
2024-04-18 01:48:36 -06:00
|
|
|
ld hl, wMetaspritePosition.x
|
2024-04-19 14:03:13 -06:00
|
|
|
ld a, $10
|
2024-04-18 01:48:36 -06:00
|
|
|
ld [wMetaspritePosition.x], a
|
2024-04-19 14:03:13 -06:00
|
|
|
ld a, $0
|
2024-04-18 01:48:36 -06:00
|
|
|
ld [wMetaspritePosition.x + 1], a
|
|
|
|
|
|
|
|
ld hl, wMetaspritePosition.y
|
2024-04-19 14:03:13 -06:00
|
|
|
ld a, $10
|
2024-04-18 01:48:36 -06:00
|
|
|
ld [wMetaspritePosition.y], a
|
2024-04-19 14:03:13 -06:00
|
|
|
ld a, $01
|
2024-04-18 01:48:36 -06:00
|
|
|
ld [wMetaspritePosition.y + 1], a
|
|
|
|
|
|
|
|
ld hl, wMetaspritePosition.z
|
2024-04-19 14:03:13 -06:00
|
|
|
ld a, $00
|
2024-04-18 01:48:36 -06:00
|
|
|
ld [wMetaspritePosition.z], a
|
2024-04-19 14:03:13 -06:00
|
|
|
ld a, $0
|
2024-04-18 01:48:36 -06:00
|
|
|
ld [wMetaspritePosition.z + 1], a
|
2024-04-16 21:04:45 -06:00
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
; Reset velocity
|
|
|
|
ld hl, wMetaspriteVelocity.x
|
|
|
|
ld a, $0
|
|
|
|
ld [wMetaspriteVelocity.x], a
|
|
|
|
ld a, $0
|
|
|
|
ld [wMetaspriteVelocity.x + 1], a
|
|
|
|
|
|
|
|
ld hl, wMetaspriteVelocity.y
|
|
|
|
ld a, $0
|
|
|
|
ld [wMetaspriteVelocity.y], a
|
|
|
|
ld a, $0
|
|
|
|
ld [wMetaspriteVelocity.y + 1], a
|
|
|
|
|
|
|
|
ld hl, wMetaspriteVelocity.z
|
|
|
|
ld a, $0
|
|
|
|
ld [wMetaspriteVelocity.z], a
|
|
|
|
ld a, $0
|
|
|
|
ld [wMetaspriteVelocity.z + 1], a
|
|
|
|
|
2024-04-19 15:05:59 -06:00
|
|
|
ld hl, wMetaspriteVelocity.boost
|
|
|
|
ld a, $0
|
|
|
|
ld [wMetaspriteVelocity.boost], a
|
|
|
|
ld [wMetaspriteVelocity.boosting], a
|
|
|
|
|
2024-04-16 21:04:45 -06:00
|
|
|
; Copy the tile data
|
|
|
|
ld de, Tiles
|
|
|
|
ld hl, $9000
|
|
|
|
ld bc, TilesEnd - Tiles
|
|
|
|
call Memcopy
|
|
|
|
|
|
|
|
; Copy the tilemap
|
|
|
|
ld de, Tilemap
|
|
|
|
ld hl, $9800
|
|
|
|
ld bc, TilemapEnd - Tilemap
|
|
|
|
call Memcopy
|
2024-04-19 17:53:22 -06:00
|
|
|
|
2024-04-16 21:04:45 -06:00
|
|
|
|
|
|
|
; Turn the LCD on
|
|
|
|
ld a, LCDCF_ON | LCDCF_BGON | LCDCF_OBJON | LCDCF_OBJ8
|
|
|
|
ld [rLCDC], a
|
|
|
|
|
|
|
|
; During the first (blank) frame, initialize display registers
|
|
|
|
ld a, %11100100
|
|
|
|
ld [rBGP], a
|
|
|
|
ld [rOBP0], a
|
|
|
|
ld [rOBP1], a
|
|
|
|
|
|
|
|
; Enable vblank interrupt
|
|
|
|
ld a, IEF_VBLANK
|
|
|
|
ldh [rIE], a
|
|
|
|
; Clear interrupt register to 0
|
|
|
|
xor a, a
|
|
|
|
ldh [rIF], a
|
|
|
|
; Enable interrupts
|
|
|
|
ei
|
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
Main::
|
2024-04-16 21:04:45 -06:00
|
|
|
call ResetShadowOAM
|
2024-04-18 01:48:36 -06:00
|
|
|
call UpdateJoypadState
|
2024-04-19 14:03:13 -06:00
|
|
|
call HandleInput
|
|
|
|
call HandlePhysics
|
|
|
|
call HandleRender
|
2024-04-18 01:48:36 -06:00
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
halt
|
|
|
|
nop
|
|
|
|
|
|
|
|
jp Main
|
|
|
|
|
|
|
|
HandleInput::
|
2024-04-18 01:48:36 -06:00
|
|
|
ld a, [wJoypadState]
|
|
|
|
bit PADB_LEFT, a
|
|
|
|
jr nz, .leftend
|
|
|
|
|
|
|
|
ld a, [wMetaspritePosition.x]
|
|
|
|
add a, 16
|
|
|
|
ld b, a
|
|
|
|
ld [wMetaspritePosition.x], a
|
|
|
|
ld a, [wMetaspritePosition.x+1]
|
|
|
|
adc 0
|
|
|
|
ld c, a
|
|
|
|
ld [wMetaspritePosition.x+1], a
|
|
|
|
.leftend:
|
|
|
|
|
|
|
|
ld a, [wJoypadState]
|
|
|
|
bit PADB_RIGHT, a
|
|
|
|
jr nz, .rightend
|
|
|
|
|
|
|
|
ld a, [wMetaspritePosition.x]
|
|
|
|
sub a, 16
|
|
|
|
ld b, a
|
|
|
|
ld [wMetaspritePosition.x], a
|
|
|
|
ld a, [wMetaspritePosition.x+1]
|
|
|
|
sbc 0
|
|
|
|
ld c, a
|
|
|
|
ld [wMetaspritePosition.x+1], a
|
|
|
|
.rightend:
|
|
|
|
|
|
|
|
ld a, [wJoypadState]
|
|
|
|
bit PADB_UP, a
|
|
|
|
jr nz, .upend
|
|
|
|
|
|
|
|
ld a, [wMetaspritePosition.y]
|
|
|
|
add a, 16
|
|
|
|
ld b, a
|
|
|
|
ld [wMetaspritePosition.y], a
|
|
|
|
ld a, [wMetaspritePosition.y+1]
|
|
|
|
adc 0
|
|
|
|
ld c, a
|
|
|
|
ld [wMetaspritePosition.y+1], a
|
|
|
|
.upend:
|
|
|
|
|
|
|
|
ld a, [wJoypadState]
|
|
|
|
bit PADB_DOWN, a
|
|
|
|
jr nz, .downend
|
|
|
|
|
|
|
|
ld a, [wMetaspritePosition.y]
|
|
|
|
sub a, 16
|
|
|
|
ld b, a
|
|
|
|
ld [wMetaspritePosition.y], a
|
|
|
|
ld a, [wMetaspritePosition.y+1]
|
|
|
|
sbc 0
|
|
|
|
ld c, a
|
|
|
|
ld [wMetaspritePosition.y+1], a
|
|
|
|
.downend:
|
|
|
|
|
2024-04-19 15:05:59 -06:00
|
|
|
; Skip jump code if not on ground
|
|
|
|
ld a, [wMetaspritePosition.z]
|
|
|
|
ld b, a
|
|
|
|
ld a, [wMetaspritePosition.z + 1]
|
|
|
|
or a, b
|
|
|
|
jr nz, .jumpend
|
|
|
|
|
|
|
|
; While on ground, set boost
|
|
|
|
ld a, $8
|
|
|
|
ld [wMetaspriteVelocity.boost], a
|
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
ld a, [wJoypadPressed]
|
2024-04-18 01:48:36 -06:00
|
|
|
bit PADB_A, a
|
2024-04-19 15:05:59 -06:00
|
|
|
jr z, .boostclear
|
2024-04-18 01:48:36 -06:00
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
ld a, [wMetaspriteVelocity.z]
|
2024-04-19 15:05:59 -06:00
|
|
|
sub a, $20
|
2024-04-18 01:48:36 -06:00
|
|
|
ld b, a
|
2024-04-19 14:03:13 -06:00
|
|
|
ld [wMetaspriteVelocity.z], a
|
|
|
|
ld a, [wMetaspriteVelocity.z+1]
|
|
|
|
sbc a, $00
|
2024-04-18 01:48:36 -06:00
|
|
|
ld c, a
|
2024-04-19 14:03:13 -06:00
|
|
|
ld [wMetaspriteVelocity.z+1], a
|
2024-04-19 15:05:59 -06:00
|
|
|
jr .boostend
|
2024-04-19 09:07:20 -06:00
|
|
|
.jumpend:
|
2024-04-19 15:05:59 -06:00
|
|
|
ld a, [wJoypadState]
|
|
|
|
bit PADB_A, a
|
|
|
|
jr z, .boostclear
|
|
|
|
ld a, $FF
|
|
|
|
ld [wMetaspriteVelocity.boosting], a
|
|
|
|
jr .boostend
|
|
|
|
.boostclear:
|
|
|
|
ld a, $00
|
|
|
|
ld [wMetaspriteVelocity.boosting], a
|
|
|
|
.boostend:
|
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
ret
|
2024-04-18 01:48:36 -06:00
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
HandleRender::
|
2024-04-19 09:07:20 -06:00
|
|
|
; Render the player
|
2024-04-18 01:48:36 -06:00
|
|
|
; load de
|
|
|
|
ld a, [wMetaspritePosition.x]
|
2024-04-16 21:04:45 -06:00
|
|
|
ld e, a
|
2024-04-18 01:48:36 -06:00
|
|
|
ld a, [wMetaspritePosition.x + 1]
|
2024-04-16 21:04:45 -06:00
|
|
|
ld d, a
|
2024-04-18 01:48:36 -06:00
|
|
|
|
|
|
|
; load bc
|
|
|
|
ld a, [wMetaspritePosition.z]
|
|
|
|
ld c, a
|
|
|
|
ld a, [wMetaspritePosition.y]
|
2024-04-19 14:03:13 -06:00
|
|
|
add a, c
|
2024-04-18 01:48:36 -06:00
|
|
|
ld c, a
|
|
|
|
ld a, [wMetaspritePosition.z + 1]
|
|
|
|
ld b, a
|
|
|
|
ld a, [wMetaspritePosition.y + 1]
|
2024-04-19 14:03:13 -06:00
|
|
|
adc a, b
|
2024-04-18 01:48:36 -06:00
|
|
|
ld b, a
|
|
|
|
|
2024-04-16 21:04:45 -06:00
|
|
|
ld hl, CatMetasprite
|
|
|
|
call RenderMetasprite
|
|
|
|
|
2024-04-19 09:07:20 -06:00
|
|
|
; Render the shadow
|
|
|
|
; load de
|
|
|
|
ld a, [wMetaspritePosition.x]
|
|
|
|
ld e, a
|
|
|
|
ld a, [wMetaspritePosition.x + 1]
|
|
|
|
ld d, a
|
|
|
|
|
|
|
|
; load bc
|
|
|
|
ld a, [wMetaspritePosition.y]
|
|
|
|
ld c, a
|
|
|
|
ld a, [wMetaspritePosition.y + 1]
|
|
|
|
ld b, a
|
|
|
|
|
|
|
|
ld hl, ShadowMetasprite
|
|
|
|
call RenderMetasprite
|
2024-04-19 14:03:13 -06:00
|
|
|
ret
|
2024-04-19 09:07:20 -06:00
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
HandlePhysics::
|
2024-04-19 09:07:20 -06:00
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
; Skip gravity if on ground
|
|
|
|
ld a, [wMetaspritePosition.z]
|
|
|
|
ld b, a
|
|
|
|
ld a, [wMetaspritePosition.z + 1]
|
|
|
|
or a, b
|
|
|
|
jr z, .endGravity
|
|
|
|
|
2024-04-19 15:05:59 -06:00
|
|
|
; Skip gravity if boosting
|
|
|
|
ld a, [wMetaspriteVelocity.boosting]
|
|
|
|
ld b, a
|
|
|
|
ld a, [wMetaspriteVelocity.boost]
|
|
|
|
and a, b
|
|
|
|
cp 0
|
|
|
|
jr z, .startGravity
|
|
|
|
ld a, [wMetaspriteVelocity.boost]
|
|
|
|
dec a
|
|
|
|
ld [wMetaspriteVelocity.boost], a
|
|
|
|
jr .endGravity
|
|
|
|
|
|
|
|
.startGravity
|
2024-04-19 14:03:13 -06:00
|
|
|
; Apply gravity
|
|
|
|
ld a, [wMetaspriteVelocity.z]
|
2024-04-19 15:05:59 -06:00
|
|
|
add a, $04
|
2024-04-19 14:03:13 -06:00
|
|
|
ld [wMetaspriteVelocity.z], a
|
|
|
|
ld a, [wMetaspriteVelocity.z+1]
|
|
|
|
adc a, $00
|
|
|
|
ld [wMetaspriteVelocity.z+1], a
|
|
|
|
.endGravity:
|
|
|
|
|
2024-04-16 21:04:45 -06:00
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
; Calculate new z, place in bc
|
|
|
|
ld a, [wMetaspriteVelocity.z]
|
|
|
|
ld c, a
|
|
|
|
ld a, [wMetaspritePosition.z]
|
|
|
|
add c
|
2024-04-19 15:05:59 -06:00
|
|
|
ld c, a
|
2024-04-19 14:03:13 -06:00
|
|
|
ld a, [wMetaspriteVelocity.z + 1]
|
|
|
|
ld b, a
|
|
|
|
ld a, [wMetaspritePosition.z + 1]
|
|
|
|
adc b
|
2024-04-19 15:05:59 -06:00
|
|
|
ld b, a
|
2024-04-19 14:03:13 -06:00
|
|
|
|
|
|
|
; If z is greater than or equal to 0, pos/vel to 0
|
2024-04-19 15:05:59 -06:00
|
|
|
jr nz, .endLanding
|
|
|
|
jr nc, .endLanding
|
2024-04-19 14:03:13 -06:00
|
|
|
.startLanding
|
|
|
|
ld a, 0
|
2024-04-19 15:05:59 -06:00
|
|
|
ld [wMetaspritePosition.z], a
|
|
|
|
ld [wMetaspritePosition.z+1], a
|
2024-04-19 14:03:13 -06:00
|
|
|
ld [wMetaspriteVelocity.z], a
|
|
|
|
ld [wMetaspriteVelocity.z+1], a
|
2024-04-19 15:05:59 -06:00
|
|
|
ld b, a
|
|
|
|
ld c, a
|
2024-04-19 14:03:13 -06:00
|
|
|
.endLanding
|
2024-04-16 21:04:45 -06:00
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
; Update z position
|
|
|
|
ld a, c
|
|
|
|
ld [wMetaspritePosition.z], a
|
|
|
|
ld a, b
|
|
|
|
ld [wMetaspritePosition.z+1], a
|
2024-04-16 21:04:45 -06:00
|
|
|
|
|
|
|
ret
|
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
SECTION "Joypad Routine", ROM0
|
2024-04-18 01:48:36 -06:00
|
|
|
UpdateJoypadState::
|
|
|
|
ld hl, rP1
|
|
|
|
ld [hl], P1F_GET_BTN
|
|
|
|
; Read button state twice to ensure we get the proper state
|
|
|
|
ld a, [hl]
|
|
|
|
ld a, [hl]
|
|
|
|
ld [hl], P1F_GET_DPAD
|
|
|
|
cpl ; Inputs are active low - invert so it makes more sense
|
|
|
|
and PADF_A | PADF_B | PADF_SELECT | PADF_START
|
|
|
|
ld c, a ; Store lower 4 button bits in c
|
|
|
|
|
|
|
|
; On real hardware, rP1 needs to be read 8 times to ensure proper state is read
|
|
|
|
ld b, 8
|
|
|
|
.dpadDebounceLoop:
|
|
|
|
ld a, [hl]
|
|
|
|
dec b
|
|
|
|
jr nz, .dpadDebounceLoop
|
|
|
|
ld [hl], P1F_GET_NONE ; Disable joypad inputs
|
|
|
|
|
|
|
|
swap a ; Swap the nibbles to store dpad in upper 4 bits
|
|
|
|
cpl ; invert the bits
|
|
|
|
and PADF_RIGHT | PADF_LEFT | PADF_UP | PADF_DOWN
|
|
|
|
or c
|
|
|
|
ld c, a
|
|
|
|
|
|
|
|
; Compare with previously stored state
|
|
|
|
ld hl, wJoypadState
|
|
|
|
xor [hl]
|
|
|
|
and c
|
|
|
|
ld [wJoypadPressed], a
|
|
|
|
ld a, c
|
|
|
|
ld [wJoypadState], a
|
|
|
|
ret
|
|
|
|
|
2024-04-19 14:03:13 -06:00
|
|
|
SECTION "MemCopy Routine", ROM0
|
|
|
|
Memcopy::
|
|
|
|
dec bc
|
|
|
|
inc b
|
|
|
|
inc c
|
|
|
|
.loop:
|
|
|
|
ld a, [de]
|
|
|
|
ld [hli], a
|
|
|
|
inc de
|
|
|
|
dec c
|
|
|
|
jr nz, .loop
|
|
|
|
dec b
|
|
|
|
jr nz, .loop
|
|
|
|
ret
|
2024-04-16 21:04:45 -06:00
|
|
|
|
|
|
|
SECTION "VBlank Interrupt", ROM0[$0040]
|
|
|
|
VBlankInterrupt:
|
|
|
|
; Store registers to prevent clobbering
|
|
|
|
push af
|
|
|
|
push bc
|
|
|
|
push de
|
|
|
|
push hl
|
|
|
|
jp VBlankHandler
|
|
|
|
|
|
|
|
SECTION "VBlank Handler", ROM0
|
|
|
|
VBlankHandler:
|
|
|
|
ldh a, [hFrameCounter]
|
|
|
|
|
|
|
|
/*
|
|
|
|
bit 5, a
|
|
|
|
|
|
|
|
ld a, %11100100
|
|
|
|
|
|
|
|
jr z, .skipCpl
|
|
|
|
cpl ; Invert a
|
|
|
|
.skipCpl:
|
|
|
|
ldh [rBGP], a
|
|
|
|
*/
|
|
|
|
|
|
|
|
ld a, HIGH(wShadowOAM)
|
|
|
|
call hOAMDMA
|
|
|
|
|
|
|
|
; Reset registers to orignal state
|
|
|
|
pop hl
|
|
|
|
pop de
|
|
|
|
pop bc
|
|
|
|
pop af
|
|
|
|
reti
|
|
|
|
|
|
|
|
SECTION "Frame Counter", HRAM
|
|
|
|
hFrameCounter:
|
|
|
|
db
|
|
|
|
|
|
|
|
|
|
|
|
SECTION "Tile data", ROM0
|
|
|
|
|
|
|
|
Tiles:
|
2024-04-19 17:53:22 -06:00
|
|
|
INCBIN "tileset.2bpp"
|
2024-04-16 21:04:45 -06:00
|
|
|
TilesEnd:
|
|
|
|
|
|
|
|
SECTION "Tilemap", ROM0
|
|
|
|
|
|
|
|
Tilemap:
|
2024-04-19 17:53:22 -06:00
|
|
|
INCBIN "tileset.tilemap"
|
2024-04-16 21:04:45 -06:00
|
|
|
TilemapEnd:
|
|
|
|
|
|
|
|
SECTION "Graphics", ROM0
|
|
|
|
GfxCat:
|
2024-04-19 17:53:22 -06:00
|
|
|
INCBIN "sprites.2bpp"
|
2024-04-16 21:04:45 -06:00
|
|
|
.end::
|
|
|
|
|
|
|
|
CatMetasprite:
|
2024-04-19 17:53:22 -06:00
|
|
|
db 0, 0, 2, 0
|
|
|
|
db 8, 0, 6, 0
|
2024-04-18 01:48:36 -06:00
|
|
|
db 128
|
2024-04-16 21:04:45 -06:00
|
|
|
|
2024-04-19 09:07:20 -06:00
|
|
|
ShadowMetasprite:
|
2024-04-19 17:53:22 -06:00
|
|
|
db 12, 0, 1, 0
|
2024-04-19 09:07:20 -06:00
|
|
|
db 128
|
2024-04-16 21:04:45 -06:00
|
|
|
|
2024-04-19 09:07:20 -06:00
|
|
|
SECTION "Position Vars", WRAM0
|
2024-04-16 21:04:45 -06:00
|
|
|
; Q12.4 fixed-point X posiition
|
2024-04-19 14:03:13 -06:00
|
|
|
wMetaspritePosition::
|
2024-04-18 01:48:36 -06:00
|
|
|
.x:
|
|
|
|
dw
|
|
|
|
.y:
|
|
|
|
dw
|
|
|
|
.z:
|
|
|
|
dw
|
2024-04-16 21:04:45 -06:00
|
|
|
|
|
|
|
; Q4.4 fixed-point velocity
|
|
|
|
wMetaspriteVelocity::
|
2024-04-19 14:03:13 -06:00
|
|
|
.x:
|
|
|
|
dw
|
|
|
|
.y:
|
|
|
|
dw
|
|
|
|
.z:
|
|
|
|
dw
|
2024-04-19 15:05:59 -06:00
|
|
|
.boost:
|
|
|
|
db
|
|
|
|
.boosting:
|
|
|
|
db
|
2024-04-18 01:48:36 -06:00
|
|
|
|
|
|
|
SECTION "Joypad Vars", WRAM0
|
|
|
|
wJoypadState:
|
|
|
|
ds 1
|
|
|
|
wJoypadPressed:
|
|
|
|
ds 1
|