332 lines
4.9 KiB
NASM
332 lines
4.9 KiB
NASM
INCLUDE "hardware.inc"
|
|
INCLUDE "utils.inc"
|
|
|
|
SPRITE_ANIM_DELAY EQU 6
|
|
REPEAT_START_DELAY EQU 16
|
|
REPEAT_DELAY EQU 3
|
|
|
|
SECTION "Edit memory", HRAM
|
|
SelectX: ds 1
|
|
SelectY: ds 1
|
|
Down: ds 1
|
|
RepeatDelay: ds 1
|
|
SpriteAnimation: ds 1
|
|
SpriteDelay: ds 1
|
|
|
|
EXPORT InitEdit
|
|
SECTION "Init edit", ROM0
|
|
InitEdit:
|
|
ld a, SCRN_X_B
|
|
ldh [SelectX], a
|
|
ld a, SCRN_Y_B
|
|
ldh [SelectY], a
|
|
xor a
|
|
ldh [Down], a
|
|
ld a, REPEAT_START_DELAY
|
|
ldh [RepeatDelay], a
|
|
xor a
|
|
ldh [SpriteAnimation], a
|
|
ld a, SPRITE_ANIM_DELAY
|
|
ldh [SpriteDelay], a
|
|
ret
|
|
|
|
EXPORT EditOldBuffer
|
|
SECTION "Edit old buffer", ROM0
|
|
EditOldBuffer:
|
|
; compute cursor X position
|
|
ldh a, [SelectX]
|
|
sla a
|
|
sla a
|
|
add a, 7
|
|
ld b, a
|
|
|
|
; compute cursor Y position
|
|
ldh a, [SelectY]
|
|
sla a
|
|
sla a
|
|
add a, 15
|
|
ld c, a
|
|
|
|
; update and load sprite animation
|
|
ldh a, [SpriteDelay]
|
|
dec a
|
|
ldh [SpriteDelay], a
|
|
jr nz, .same
|
|
ldh a, [SpriteAnimation]
|
|
inc a
|
|
cp a, (SpriteTilesEnd - SpriteTiles) / 16
|
|
jr nz, .writeAnim
|
|
ld a, 0
|
|
.writeAnim
|
|
ldh [SpriteAnimation], a
|
|
ld a, SPRITE_ANIM_DELAY
|
|
ldh [SpriteDelay], a
|
|
.same
|
|
ldh a, [SpriteAnimation]
|
|
ld d, a
|
|
|
|
; update sprite in OAM
|
|
SetSprite 0, b, c, d, 0
|
|
|
|
; toggle targeted cell if A pressed
|
|
ldh a, [JoypadDown]
|
|
and a, PADF_A
|
|
call nz, ToggleCell
|
|
|
|
; clear if SELECT pressed
|
|
ldh a, [JoypadDown]
|
|
and a, PADF_SELECT
|
|
call nz, Clear
|
|
|
|
; reset input
|
|
xor a
|
|
ldh [Down], a
|
|
|
|
; if a direction is pressed, handle repeat
|
|
ldh a, [JoypadPressed]
|
|
and JOYPAD_DIRECTIONS
|
|
ld b, a
|
|
jr z, .addDown
|
|
|
|
; check if time to repeat
|
|
ldh a, [RepeatDelay]
|
|
dec a
|
|
ldh [RepeatDelay], a
|
|
jr nz, .addDown
|
|
|
|
; reset repeat delay and add pressed to inputs
|
|
ld a, REPEAT_DELAY
|
|
ldh [RepeatDelay], a
|
|
ld a, b
|
|
ldh [Down], a
|
|
|
|
; add just down keys
|
|
.addDown
|
|
ldh a, [JoypadDown]
|
|
and JOYPAD_DIRECTIONS
|
|
ld b, a
|
|
ldh a, [Down]
|
|
or a, b
|
|
ldh [Down], a
|
|
|
|
ldh a, [JoypadPressed]
|
|
or a
|
|
jr nz, .do
|
|
|
|
ld a, REPEAT_START_DELAY
|
|
ldh [RepeatDelay], a
|
|
|
|
.do
|
|
; check left direction
|
|
ldh a, [Down]
|
|
and a, PADF_LEFT
|
|
jr z, .endLeft
|
|
ldh a, [SelectX]
|
|
and a
|
|
jr z, .endLeft
|
|
dec a
|
|
ldh [SelectX], a
|
|
.endLeft
|
|
|
|
; check up direction
|
|
ldh a, [Down]
|
|
and a, PADF_UP
|
|
jr z, .endUp
|
|
ldh a, [SelectY]
|
|
and a
|
|
jr z, .endUp
|
|
dec a
|
|
ldh [SelectY], a
|
|
.endUp
|
|
|
|
; check right direction
|
|
ldh a, [Down]
|
|
and a, PADF_RIGHT
|
|
jr z, .endRight
|
|
ldh a, [SelectX]
|
|
cp a, 39
|
|
jr nc, .endRight
|
|
inc a
|
|
ldh [SelectX], a
|
|
.endRight
|
|
|
|
; check down direction
|
|
ldh a, [Down]
|
|
and a, PADF_DOWN
|
|
jr z, .endDown
|
|
ldh a, [SelectY]
|
|
cp a, 35
|
|
jr nc, .endDown
|
|
inc a
|
|
ldh [SelectY], a
|
|
.endDown
|
|
|
|
ret
|
|
|
|
SECTION "Value to flag", ROM0, ALIGN[8]
|
|
Flag: db 1, 2, 4, 8
|
|
|
|
; \1: horizontal stride
|
|
MoveToCell: MACRO
|
|
; move pointer to 2x2 cell group
|
|
ldh a, [SelectY]
|
|
sra a
|
|
jr z, .addX\@
|
|
ld c, a
|
|
ld de, \1
|
|
.mul\@
|
|
add hl, de
|
|
dec c
|
|
jr nz, .mul\@
|
|
.addX\@
|
|
xor a
|
|
ld d, a
|
|
ldh a, [SelectX]
|
|
sra a
|
|
ld e, a
|
|
add hl, de
|
|
ENDM
|
|
|
|
SECTION "Toggle cell", ROM0
|
|
ToggleCell:
|
|
; compute cell number in 2x2 cell group
|
|
ldh a, [SelectX]
|
|
and a, 1
|
|
ld b, a
|
|
ldh a, [SelectY]
|
|
and a, 1
|
|
sla a
|
|
or a, b
|
|
|
|
; transform cell number to bit mask in 2x2 cell
|
|
ld d, HIGH(Flag)
|
|
ld e, a
|
|
ld a, [de]
|
|
ld b, a
|
|
|
|
; go to 2x2 cell in video buffer
|
|
ldh a, [Video]
|
|
ld l, a
|
|
ldh a, [Video + 1]
|
|
xor a, %100
|
|
ld h, a
|
|
MoveToCell SCRN_VX_B
|
|
|
|
; toggle bit
|
|
ld a, [hl]
|
|
xor a, b
|
|
ld [hl], a
|
|
|
|
; go to 2x2 cell in automata buffer
|
|
ldh a, [Progress]
|
|
ld l, a
|
|
ldh a, [Old]
|
|
ld h, a
|
|
MoveToCell SCRN_X_B
|
|
|
|
; toggle bit
|
|
ld a, [hl]
|
|
xor a, b
|
|
ld [hl], a
|
|
|
|
; do sound based on new value
|
|
and a, b
|
|
jr nz, .pulse
|
|
|
|
; do noisy sound
|
|
.noise
|
|
xor a
|
|
ldh [rNR41], a ; sound length
|
|
ld a, $F2
|
|
ldh [rNR42], a ; init volume + envelope sweep
|
|
ld a, $82
|
|
ldh [rNR43], a ; frequency
|
|
ld a, $80
|
|
ldh [rNR44], a ; start
|
|
ret
|
|
|
|
; do pulsy sound
|
|
.pulse
|
|
xor a
|
|
ldh [rNR10], a ; sweep
|
|
ld a, (%01 << 6) + 30
|
|
ldh [rNR11], a ; pattern + sound length
|
|
ld a, $F1
|
|
ldh [rNR12], a ; init volume + envelope sweep
|
|
FREQUENCY = 100
|
|
ld a, LOW(PULSE_FREQUENCY)
|
|
ldh [rNR13], a
|
|
ld a, SOUND_START | HIGH(PULSE_FREQUENCY)
|
|
ldh [rNR14], a
|
|
ret
|
|
|
|
SECTION "Clear buffers", ROM0
|
|
Clear:
|
|
; load old buffer address and store into rendered
|
|
ldh a, [Progress]
|
|
ld l, a
|
|
ld [Rendered], a
|
|
ldh a, [Old]
|
|
ld h, a
|
|
ld [Rendered + 1], a
|
|
|
|
; clear old buffer
|
|
ld bc, SCRN_X_B * SCRN_Y_B
|
|
ld d, 0
|
|
call MemorySet
|
|
|
|
; play long noise
|
|
xor a
|
|
ldh [rNR41], a ; set sound duration
|
|
ld a, $F4
|
|
ldh [rNR42], a ; set volume with long sweep
|
|
ld a, $72
|
|
ldh [rNR43], a ; set frequency
|
|
ld a, $80
|
|
ldh [rNR44], a ; start
|
|
|
|
; render cleared buffer
|
|
call StartRender
|
|
|
|
; disable sprites
|
|
HaltAndClearInterrupts
|
|
ldh a, [rLCDC]
|
|
and a, ~LCDCF_OBJON
|
|
ldh [rLCDC], a
|
|
|
|
; shake background
|
|
ld d, HIGH(Random)
|
|
ld e, LOW(Random)
|
|
ld b, 16
|
|
.shake
|
|
HaltAndClearInterrupts
|
|
ld a, [de]
|
|
ldh [rSCX], a
|
|
|
|
inc e
|
|
ld a, e
|
|
and a, $7
|
|
ld e, a
|
|
|
|
ld a, [de]
|
|
ldh [rSCY], a
|
|
|
|
inc e
|
|
ld a, e
|
|
and a, $7
|
|
ld e, a
|
|
|
|
dec b
|
|
jr nz, .shake
|
|
|
|
call WaitRender
|
|
|
|
; reset scrolling and enable sprites again
|
|
xor a
|
|
ldh [rSCX], a
|
|
ldh [rSCY], a
|
|
ldh a, [rLCDC]
|
|
or a, LCDCF_OBJON
|
|
ldh [rLCDC], a
|
|
|
|
ret |