Dirt clod creation and explosion working

This commit is contained in:
blondie7575 2020-01-05 15:11:14 -08:00
parent 9baa167896
commit 48f2e17491
9 changed files with 373 additions and 4 deletions

View File

@ -35,6 +35,8 @@
70E9D8611F2BD95400555C19 /* gscats.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gscats.s; sourceTree = "<group>"; };
70E9D8621F2BD95400555C19 /* macros.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = macros.s; sourceTree = "<group>"; };
70E9D8631F2BD95400555C19 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
70F011D023B91B2900C8873F /* dirt.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = dirt.s; sourceTree = "<group>"; };
70F011D123B989B800C8873F /* random.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = random.s; sourceTree = "<group>"; };
70F0869F1F413A89002446C3 /* player.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = player.s; sourceTree = "<group>"; };
70F086A01F4230CB002446C3 /* utility.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = utility.s; sourceTree = "<group>"; };
70FE79D21F8814A600E0095C /* MerlinToCA65.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = MerlinToCA65.sh; sourceTree = "<group>"; };
@ -49,11 +51,13 @@
70E9D8601F2BD95400555C19 /* graphics.s */,
70E9D8621F2BD95400555C19 /* macros.s */,
7099E3841F41022100182A82 /* gameobject.s */,
70F011D123B989B800C8873F /* random.s */,
706DF1641F2D39F700AA6680 /* loader.s */,
700FFAFB1F40F3BF00A442DE /* font.s */,
7002647320CD78C40015B184 /* smallNumbers.s */,
706DF1651F2D4A8100AA6680 /* terrain.s */,
705AAFA920040B0D001BB0ED /* terrain_e1.s */,
70F011D023B91B2900C8873F /* dirt.s */,
70C073091F5BAA3E009844A9 /* collision.s */,
70F086A01F4230CB002446C3 /* utility.s */,
700C39C51F2E5CA800C24F9C /* tables.s */,
@ -114,6 +118,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
);
mainGroup = 70E9D8541F2BD8EF00555C19;

298
dirt.s Normal file
View File

@ -0,0 +1,298 @@
;
; dirt
;
; Created by Quinn Dunki on 12/29/19
;
MAXPARTICLES = 64
.macro PARTICLEPTR_XY
txa ; Pointer to particle structure from index
asl
asl
asl
asl
tay
.endmacro
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; createDirtExplosion
;
; Simulate a bunch of dirt flying everywhere
;
; PARAML0 = X pos of circle left edge
; PARAML1 = Y pos of circle center
; PARAML2 = Radius (16 bits)
;
; Trashes SCRATCHL,SCRATCHL2,CACHEDATA
;
createDirtExplosion:
SAVE_AXY
lda #1
sta dirtExplosionActive
lda #120
sta PARAML0
lda #100
sta PARAML1
lda #3
sta PARAML2
asl
sta CACHEDATA ; Cache diameter
ldx #0
ldy #0
createDirtExplosionLoop:
jsr createDirtExplosionColumn
inc PARAML0
inc PARAML0
iny
cpy CACHEDATA
bne createDirtExplosionLoop
RESTORE_AXY
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; createDirtExplosionColumn
;
; Create one column of a starting dirt explosion circle
; X = Particle index to start filling from
; Y = Local X index of column
; PARAML0 = X pos of column
; PARAML1 = Y pos of circle center
; PARAML2 = Radius (16 bits)
;
; X=> Last particle index we filled in +1
; Trashse SCRATCHL,SCRATCHL2
;
createDirtExplosionColumn:
SAVE_AY
lda PARAML2
pha
stx SCRATCHL2 ; Cache particle index
phy ; Look up circle table for our radius
lda PARAML2
asl
tay
lda circleTable,y
sta SCRATCHL
; Find starting Y from circle table
pla
asl
tay
lda (SCRATCHL),y
tax ; Row counter
pha
eor #$ffff
inc
sta PARAML2 ; Row counter end
pla
clc
adc PARAML1
sta SCRATCHL ; Current Y position
createDirtExplosionColumnLoop:
phx ; Find pointer to next particle to fill out
ldx SCRATCHL2
PARTICLEPTR_XY
plx
; X position - Always the same
lda PARAML0
sta dirtParticles+DP_POSX,y
asl ; Convert to 12.4
asl
asl
asl
sta dirtParticles+DP_PRECISEX,y
; Y position - Iterates from computed cache
lda SCRATCHL
sta dirtParticles+DP_POSY,y
asl ; Convert to 12.4
asl
asl
asl
sta dirtParticles+DP_PRECISEY,y
; X velocity. Need half to be negative. I feel like there
; should be a clever branchless way to do this, but I couldn't
; come up with it.
jsr random
lda RANDOM
bmi createDirtExplosionColumnLoopNegX
and #$00ff
bra createDirtExplosionColumnLoopNowY
createDirtExplosionColumnLoopNegX:
ora #$ff00
createDirtExplosionColumnLoopNowY:
sta dirtParticles+DP_VX,y
; Y velocity
jsr random
lda RANDOM
and #$00ff
ora #$0100
sta dirtParticles+DP_VY,y
; Advance to next particle
inc SCRATCHL2
inc SCRATCHL
inx
cpx PARAML2
bmi createDirtExplosionColumnLoop
; Gather return values
ldx SCRATCHL2
pla
sta PARAML2
RESTORE_AY
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; renderDirtExplosion
;
; Update and render the current dirt explosion
;
renderDirtExplosion:
SAVE_AXY
lda dirtExplosionActive
beq renderDirtExplosionDone
ldx #0
renderDirtExplosionLoop:
PARTICLEPTR_XY
jsr updateDirtParticle
inx ; Advance array pointer to next particle
cpx #MAXPARTICLES
bne renderDirtExplosionLoop
renderDirtExplosionDone:
RESTORE_AXY
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; updateDirtParticle
;
; Y = Offset to particle in array
; Update and render the current dirt explosion
;
; Trashes SCRATCHL,PARAML0
updateDirtParticle:
SAVE_AXY
lda dirtParticles+DP_POSX,y
bmi updateDirtParticleDone ; Particle is dead
; Erase old position
lda #dirtParticles ; Calculate pointer to struct
sta PARAML0
clc
tya
adc PARAML0
sta PARAML0
jsr vramPtr
lda #00
sta SHADOWVRAMBANK,x
; Integrate gravity over velocity
lda dirtParticles+DP_VY,y
clc
adc #GRAVITY
sta dirtParticles+DP_VY,y
; Integrate X velocity over position
lda dirtParticles+DP_VX,y
; Convert 8.8 to 12.4
cmp #$8000
ror
cmp #$8000
ror
cmp #$8000
ror
cmp #$8000
ror
clc
adc dirtParticles+DP_PRECISEX,y
sta dirtParticles+DP_PRECISEX,y
; Convert to integer for rendering
lsr
lsr
lsr
lsr
sta dirtParticles+DP_POSX,y
; Integrate Y velocity over position
lda dirtParticles+DP_VY,y
; Convert 8.8 to 12.4
cmp #$8000
ror
cmp #$8000
ror
cmp #$8000
ror
cmp #$8000
ror
clc
adc dirtParticles+DP_PRECISEY,y
sta dirtParticles+DP_PRECISEY,y
; Convert to integer for rendering
lsr
lsr
lsr
lsr
sta dirtParticles+DP_POSY,y
; Draw new position
jsr vramPtr ; PARAML0 still holds struct pointer
cpx #$ffff
beq updateDirtParticleKill
lda #$11
sta SHADOWVRAMBANK,x
updateDirtParticleDone:
RESTORE_AXY
rts
updateDirtParticleKill:
lda #-1
sta dirtParticles+DP_POSX,y
bra updateDirtParticleDone
dirtExplosionActive:
.word 0
dirtParticles:
.repeat MAXPARTICLES
.word -1 ; Pos X in pixels
.word 100 ; Pos Y in pixels
.word $a00 ; Pos X (12.4 fixed point)
.word $640 ; Pos Y (12.4 fixed point)
.word $ff00 ; Velocity X (8.8 fixed point)
.word $100 ; Velocity Y (8.8 fixed point)
.word 0,0 ; Pad to 16 bytes
.endrepeat
DP_POSX = 0 ; Byte offsets into dirtParticles data structure
DP_POSY = 2
DP_PRECISEX = 4
DP_PRECISEY = 6
DP_VX = 8
DP_VY = 10

View File

@ -21,6 +21,7 @@ PARAM2 = $08
PARAM3 = $09
PARAML0 = $06 ; 16-bit versions of params
PARAML1 = $08
PARAML2 = $d0
SCRATCH0 = $19
SCRATCH1 = $1a
SCRATCHL = $19 ; 16-bit version of scratch
@ -33,7 +34,9 @@ STACKPTR = $70 ; Cache for stack pointer in fast graphics
SHADOWREGISTER = $72 ; Cache for shadow register in fast graphics
STACKREGISTER = $73 ; Cache for stack register in fast graphics
lastCompiledTerrainY = $75 ; The highest Y value that the compiled renderer must handle
RANDOM = $ce ; 16 bit random number
RANDOML = $ce ; Low byte of random number generator
RANDOMH = $cf ; High byte of random number generator
; Terrain constants

View File

@ -9,6 +9,9 @@ NUMPLAYERS = 2
beginGameplay:
; Initialize random numbers
lda #1
jsr seedRandom
; Set up palette for terrain and players
lda #basePalette
@ -132,7 +135,7 @@ gameplayLoopRender:
; Render the terrain if needed
lda terrainDirty
beq gameplayLoopProjectiles
beq gameplayLoopExplosions
; jsl renderTerrainSpans ; Part of the now disabled fill-mode renderer
jsr renderTerrain
stz terrainDirty
@ -140,6 +143,10 @@ gameplayLoopRender:
; Render players
jsr renderPlayers
gameplayLoopExplosions:
; Render explosions
jsr renderDirtExplosion
gameplayLoopProjectiles:
; BORDER_COLOR #$3

View File

@ -58,7 +58,7 @@ placeGameObjectOnTerrain:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; vramPtr
;
; PARAML0 = Pointer to X,Y (16 bits each)
; PARAML0 = Pointer to X,Y (16 bits each, Y is bottom relative)
; X => Offset to upper left corner of VRAM, or ffff if offscreen
;
; Trashes SCRATCHL

Binary file not shown.

View File

@ -35,6 +35,7 @@ quitGame:
jml (PRODOSRETURN)
.include "random.s"
.include "graphics.s"
.include "font.s"
.include "smallNumbers.s"
@ -49,7 +50,7 @@ quitGame:
.include "fan.s"
.include "projectile.s"
.include "inventory.s"
.include "dirt.s"
endMainBank2:

View File

@ -222,6 +222,9 @@ allocProjectileDone:
;
;
fireProjectile:
jsr createDirtExplosion
rts
SAVE_AXY
; Allocate a projectile

52
random.s Normal file
View File

@ -0,0 +1,52 @@
;
; random.s
; GSCats
;
; Created by Quinn Dunki on 12/29/19.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; random
; A => Random 8 bits
; Y => Less random 8 bits
;
; Taken from https://codebase64.org/doku.php?id=base:16bit_xorshift_random_generator
; This routine is not very fast, but it'll do for now. It's intended
; for 6502 so we're making due with it.
;
rng_zp_low = RANDOML
rng_zp_high = RANDOMH
random:
SAVE_AXY
EMULATION
LDA rng_zp_high
LSR
LDA rng_zp_low
ROR
EOR rng_zp_high
STA rng_zp_high ; high part of x ^= x << 7 done
ROR ; A has now x >> 9 and high bit comes from low byte
EOR rng_zp_low
STA rng_zp_low ; x ^= x >> 9 and the low part of x ^= x << 7 done
EOR rng_zp_high
STA rng_zp_high ; x ^= x << 8 done
NATIVE
RESTORE_AXY
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; seedRandom
; A = Seed
;
; Taken from https://codebase64.org/doku.php?id=base:16bit_xorshift_random_generator
;
seedRandom:
SAVE_AXY
EMULATION
STA rng_zp_low
LDA #0
STA rng_zp_high
NATIVE
RESTORE_AXY
rts