First pass on terrain craters

Also refactored collision/physics functions for improved appearance
This commit is contained in:
blondie7575 2017-09-13 07:53:40 -06:00
parent 015f4c2da1
commit 9a4d9e7fb7
9 changed files with 242 additions and 35 deletions

View File

@ -16,6 +16,7 @@
706DF1641F2D39F700AA6680 /* loader.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = loader.s; sourceTree = "<group>"; };
706DF1651F2D4A8100AA6680 /* terrain.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = terrain.s; sourceTree = "<group>"; };
7088096D1F2ECE8D00D4C950 /* GenerateRenderSpans.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = GenerateRenderSpans.py; sourceTree = "<group>"; };
709175C01F60D263008FAFAB /* GenerateCircles.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = GenerateCircles.py; sourceTree = "<group>"; };
7099E3841F41022100182A82 /* gameobject.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameobject.s; sourceTree = "<group>"; };
7099E3851F4107B100182A82 /* GenerateVRAMYOffset.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = GenerateVRAMYOffset.py; sourceTree = "<group>"; };
70A80FB01F43D7F200BD34C9 /* gamemanager.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gamemanager.s; sourceTree = "<group>"; };
@ -53,6 +54,7 @@
7059502B1F37A0BE00BBE90F /* GenerateVRAMTable.py */,
7099E3851F4107B100182A82 /* GenerateVRAMYOffset.py */,
700F21E01F4A3A5500D7007D /* GenerateTrigTables.py */,
709175C01F60D263008FAFAB /* GenerateCircles.py */,
);
sourceTree = "<group>";
};

49
GenerateCircles.py Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/env python3
import sys
import math
def main(argv):
minRadius = 3
maxRadius = 10
print ("circleTable:\t\t;-Y for each X, in words")
for radius in range(0,maxRadius+1):
if radius < minRadius:
print ("\t.addr 0")
else:
print ("\t.addr circleTable%d" % radius)
print()
for radius in range(minRadius,maxRadius+1):
print ("circleTable%d:" % radius)
print ("\t.word ",end="")
skipMinus1 = 0
for p in range(0,radius):
x = radius-p
y = (int)(math.sqrt(radius*radius - x*x))
if p==radius-1: # A fudge to make circles close better
y = radius
y*=-4 # Because X=words and we need -Y
print (y, end=",")
skipMinus1 = 0
for p in range(0,radius):
x = p+1
y = (int)(math.sqrt(radius*radius - x*x))
if p==0: # A fudge to make circles close better
y = radius
y*=-4 # Because X=words and we need -Y
if p==radius-1:
print(y)
else:
print (y, end=",")
if __name__ == "__main__":
main(sys.argv[1:])

Binary file not shown.

View File

@ -19,4 +19,5 @@ PARAML1 = $08
SCRATCH0 = $19
SCRATCH1 = $1a
SCRATCHL = $19 ; 16-bit version of scratch
SCRATCHL2 = $67 ; Second 16-bit scratch
PARAM24 = $67 ; 24-bit param (This is almost certainly messing up AppleSoft, but meh)

View File

@ -22,6 +22,21 @@ beginGameplay:
; Generate, compile, and clip terrain
jsr generateTerrain
; lda #40
; sta PARAML0
; lda #30
; sta PARAML1
; ldy #12
; jsr craterTerrain
; lda #74
; sta PARAML0
; lda #30
; sta PARAML1
; ldy #16
; jsr craterTerrain
jsr compileTerrain
jsr clipTerrain
@ -83,8 +98,9 @@ gameplayLoopFire:
gameplayLoopProjectiles:
sta KBDSTROBE
jsr unrenderProjectiles
jsr updateProjectiles
jsr updateProjectilePhysics
jsr renderProjectiles
jsr updateProjectileCollisions
lda turnRequested
beq gameplayLoopVictoryCondition

Binary file not shown.

View File

@ -30,10 +30,11 @@ GRAVITY = $ffff ; 8.8 fixed point
projectileTypes: ; Byte offsets into projectile type data structure
.word 50 ; Damage
.word 0,0,0 ; Padding
.word 12 ; Crater radius
.word 0,0 ; Padding
PT_DAMAGE = 0
PT_RADIUS = 2
.macro PROJECTILEPTR_Y
@ -133,17 +134,18 @@ fireProjectile:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; updateProjectiles
; updateProjectilePhysics
;
; Trashes SCRATCHL
;
updateProjectiles:
updateProjectilePhysics:
SAVE_AY
lda projectileData+GO_POSX
bpl updateProjectilesActive
jmp updateProjectilesDone
updateProjectilesActive:
lda projectileData+GO_POSX
bpl updateProjectilePhysicsActive
jmp updateProjectilePhysicsDone
updateProjectilePhysicsActive:
; Integrate gravity over velocity
lda projectileData+JD_VY
clc
@ -171,15 +173,11 @@ updateProjectilesActive:
lsr
lsr
sta projectileData+GO_POSX
bmi updateProjectilesOffWorld
bmi updateProjectilePhysicsDelete
cmp #TERRAINWIDTH-GAMEOBJECTWIDTH-1
bpl updateProjectilesOffWorld
bra updateProjectilesContinue
bpl updateProjectilePhysicsDelete
updateProjectilesOffWorld:
jmp updateProjectilesDelete
updateProjectilesContinue:
updateProjectilePhysicsContinue:
; Integrate Y velocity over position
lda projectileData+JD_VY
; Convert 8.8 to 12.4
@ -202,13 +200,31 @@ updateProjectilesContinue:
lsr
sta projectileData+GO_POSY
cmp #GAMEOBJECTHEIGHT
bmi updateProjectilesDelete
bmi updateProjectilePhysicsDelete
cmp #201
bpl updateProjectilesDelete
bpl updateProjectilePhysicsDelete
updateProjectilePhysicsDone:
RESTORE_AY
rts
updateProjectilePhysicsDelete:
jsr endProjectile
bra updateProjectilePhysicsDone
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; updateProjectileCollisions
;
; Trashes SCRATCHL
;
updateProjectileCollisions:
SAVE_AY
; Check for player collisions
ldy #0
lda projectileData+GO_POSX
bmi updateProjectileCollisionsDone ; Projectile not active
sta rectParams
lda projectileData+GO_POSY
sta rectParams+2
@ -217,17 +233,17 @@ updateProjectilesContinue:
lda #GAMEOBJECTHEIGHT
sta rectParams+6
updateProjectilesPlayerLoop:
updateProjectileCollisionsPlayerLoop:
iny
cpy #NUMPLAYERS
beq updateProjectilesPlayerDone
beq updateProjectileCollisionsPlayerDone
cpy currentPlayer
beq updateProjectilesPlayerLoop
beq updateProjectileCollisionsPlayerLoop
jsr playerIntersectRect
cmp #0
bne updateProjectilesPlayerHit
bne updateProjectileCollisionsPlayerHit
updateProjectilesPlayerDone:
updateProjectileCollisionsPlayerDone:
; Check for terrain collisions
lda projectileData+GO_POSX
@ -241,27 +257,36 @@ updateProjectilesPlayerDone:
jsr intersectRectTerrain
cmp #0
bne updateProjectilesTerrainHit
bne updateProjectileCollisionsTerrainHit
updateProjectilesDone:
updateProjectileCollisionsDone:
RESTORE_AY
rts
updateProjectilesDelete:
updateProjectileCollisionsPlayerHit:
jsr processPlayerImpact
jsr endProjectile
bra updateProjectileCollisionsDone
updateProjectileCollisionsTerrainHit:
jsr processTerrainImpact
jsr endProjectile
bra updateProjectileCollisionsDone
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; endProjectile
;
; Trashes A and Y
;
endProjectile:
ldy #0
jsr deleteProjectile
lda #1
sta turnRequested
lda #-1
sta projectileActive
bra updateProjectilesDone
updateProjectilesPlayerHit:
jsr processPlayerImpact
bra updateProjectilesDelete
updateProjectilesTerrainHit:
bra updateProjectilesDelete
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -348,3 +373,34 @@ processPlayerImpactDeath:
lda currentPlayer
sta gameOver
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; processTerrainImpact
;
; Trashes A,Y
;
processTerrainImpact:
ldy #0 ; Assume projectile 0
PROJECTILEPTR_Y
lda projectileData+GO_POSX,y
clc
adc #GAMEOBJECTWIDTH/2
sta PARAML0
lda projectileData+GO_POSY,y
sec
sbc #GAMEOBJECTHEIGHT
sta PARAML1
lda projectileData+JD_TYPE,y
tay
PROJECTILETYPEPTR_Y
lda projectileTypes+PT_RADIUS,y
tay
jsr craterTerrain
jsr compileTerrain
jsr clipTerrain
rts

View File

@ -152,3 +152,32 @@ vramYOffset:
.word $6400,$64a0,$6540,$65e0,$6680,$6720,$67c0,$6860,$6900,$69a0,$6a40,$6ae0,$6b80,$6c20,$6cc0,$6d60,$6e00,$6ea0,$6f40,$6fe0
.word $7080,$7120,$71c0,$7260,$7300,$73a0,$7440,$74e0,$7580,$7620,$76c0,$7760,$7800,$78a0,$7940,$79e0,$7a80,$7b20,$7bc0,$7c60
circleTable: ;-Y for each X, in words
.addr 0
.addr 0
.addr 0
.addr circleTable3
.addr circleTable4
.addr circleTable5
.addr circleTable6
.addr circleTable7
.addr circleTable8
.addr circleTable9
.addr circleTable10
circleTable3:
.word 0,-8,-12,-12,-8,0
circleTable4:
.word 0,-8,-12,-16,-16,-12,-8,0
circleTable5:
.word 0,-12,-16,-16,-20,-20,-16,-16,-12,0
circleTable6:
.word 0,-12,-16,-20,-20,-24,-24,-20,-20,-16,-12,0
circleTable7:
.word 0,-12,-16,-20,-24,-24,-28,-28,-24,-24,-20,-16,-12,0
circleTable8:
.word 0,-12,-20,-24,-24,-28,-28,-32,-32,-28,-28,-24,-24,-20,-12,0
circleTable9:
.word 0,-16,-20,-24,-28,-32,-32,-32,-36,-36,-32,-32,-32,-28,-24,-20,-16,0
circleTable10:
.word 0,-16,-24,-28,-32,-32,-36,-36,-36,-40,-40,-36,-36,-36,-32,-32,-28,-24,-16,0

View File

@ -47,6 +47,60 @@ renderRowComplete:
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; craterTerrain
;
; PARAML0 = X pos of center in pixels from logical left terrain edge
; PARAML1 = Y pos of center in pixels from bottom terrain edge
; Y = Radius of circle, in pixels
;
; Trashes SCRATCHL
craterTerrain:
SAVE_AX
lda #TERRAINWIDTH ; Convert X pos to terrain-right byte count
sec
sbc PARAML0
sty SCRATCHL ; Center width
sbc SCRATCHL
lsr
and #$fffe
clc
adc #terrainData
sta PARAML0
phy
tya ; Look up circle data
lsr
tay
lda circleTable,y
sta SCRATCHL
ply
craterTerrainLoop:
dey
dey
bmi craterTerrainDone
lda (SCRATCHL),y ; Fetch circle Y value
clc
adc PARAML1 ; Convert to terrain-space
sta SCRATCHL2
lda (PARAML0),y
cmp SCRATCHL2
bmi craterTerrainLoop
lda SCRATCHL2 ; Circle value is lower, so use that
sta (PARAML0),y
bra craterTerrainLoop
craterTerrainDone:
lda #1
sta terrainDirty
RESTORE_AX
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; clipTerrain
@ -272,7 +326,7 @@ generateTerrainLoop:
; Terrain data, stored as height values 4 pixels wide
; Terrain data, stored as height values 4 pixels wide (words)
terrainData:
.repeat TERRAINWIDTH/4 ; VISIBLETERRAINWIDTH