diff --git a/BuGS/gameSegments.s b/BuGS/gameSegments.s index ef0d3de..b6a2467 100644 --- a/BuGS/gameSegments.s +++ b/BuGS/gameSegments.s @@ -17,13 +17,22 @@ gameSegments start SEGMENT_MAX_NUM equ 12 SEGMENT_MAX_OFFSET equ SEGMENT_MAX_NUM*2-2 -SEGMENT_STATE_NONE equ 0 -SEGMENT_STATE_HEAD equ 1 -SEGMENT_STATE_BODY equ 2 +SEGMENT_STATE_NONE equ 0 +SEGMENT_STATE_HEAD equ 1 +SEGMENT_STATE_POISONED_HEAD equ 2 +SEGMENT_STATE_BODY equ 3 SEGMENT_DIR_LEFT equ 0 SEGMENT_DIR_RIGHT equ 1 +SEGMENT_DIR_DOWN equ 0 +SEGMENT_DIR_UP equ 1 + +; You would think I would need "facing up" variants here also. When the centipede gets to the bottom of +; the screen, it starts traveling up again and when it turns, you would think it would face up. Turns out +; the real arcade system uses "facing down" sprites even when the centipede is moving up. So, I guess I +; will too. I suspect that the players tend not to notice because by the time the centipede is traveling +; up, they are pretty occupied by the fact that they are now surrounded by segments. SEGMENT_FACING_LEFT equ 0 SEGMENT_FACING_DOWN_LEFT equ 32 SEGMENT_FACING_DOWN equ 64 @@ -35,46 +44,55 @@ drawSegments entry ldx #SEGMENT_MAX_OFFSET drawSegments_nextSegment anop lda segmentStates,x - beq drawSegments_skipSegment + bne drawSegments_cont + jmp drawSegments_skipSegment - lda segmentFacing,x - clc - adc segmentSpriteOffset - tay - +drawSegments_cont anop + phx lda segmentStates,x - cmp #SEGMENT_STATE_HEAD - beq drawSegments_head + cmp #SEGMENT_STATE_BODY + bne drawSegments_head jsl segmentBodyJump bra drawSegments_handleTiles drawSegments_head anop jsl segmentHeadJump +; By the time we come back from segment*Jump, the X register no longer has the original 0-22 +; offset. Instead, we have a position offset which goes from 0-190. But that is good because +; we need to use that offset to update our dirty tiles. + drawSegments_handleTiles anop - lda #TILE_STATE_DIRTY - ldy segmentTileOffsetsUL,x - sta tileDirty,y - - ldy segmentTileOffsetsUR,x - sta tileDirty,y - - ldy segmentTileOffsetsLL,x - sta tileDirty,y - - ldy segmentTileOffsetsLR,x - sta tileDirty,y +; We do have to handle non-game tiles. When centipede reaches the bottom, new segements are +; added randomly in from the side. That segment needs to be clipped so we need to use non-game +; tiles to do that clipping for us. + _dirtyGameOrNonGameTileX segmentTileOffsetsUL + _dirtyGameOrNonGameTileX segmentTileOffsetsUR + _dirtyGameOrNonGameTileX segmentTileOffsetsLL + _dirtyGameOrNonGameTileX segmentTileOffsetsLR +; Get our original 0-22 offset we are iterating through that we pushed earlier because we know +; it was going to get trashed. + plx drawSegments_skipSegment anop dex dex - bpl drawSegments_nextSegment + bmi drawSegments_done + jmp drawSegments_nextSegment drawSegments_done anop rtl segmentHeadJump entry + lda segmentPosOffset,x + tax + + lda segmentFacing,x + clc + adc segmentSpriteOffset + tay + lda segmentScreenShifts,x beq segmentHeadJump_noShift @@ -99,6 +117,14 @@ segmentHeadJump_jumpInst anop nop segmentBodyJump entry + lda segmentPosOffset,x + tax + + lda segmentFacing,x + clc + adc segmentSpriteOffset + tay + lda segmentScreenShifts,x beq segmentBodyJump_noShift @@ -146,31 +172,44 @@ updateSegments_skipSpriteOffset anop addBodySegment entry - lda numSegments + lda #SEGMENT_MAX_NUM-1 + sec + sbc numSegments asl a tax lda #SEGMENT_STATE_BODY sta segmentStates,x + + txa + asl a + asl a + asl a + sta segmentPosOffset,x + tay - lda #SEGMENT_DIR_LEFT - sta segmentDirections,x + lda #SEGMENT_DIR_RIGHT + sta segmentHorizontalDir,y + + lda #SEGMENT_DIR_DOWN + sta segmentVerticalDir,y - lda #SEGMENT_FACING_LEFT - sta segmentFacing,x + lda #SEGMENT_FACING_RIGHT + sta segmentFacing,y lda tileScreenOffset,x sec sbc #3 - sta segmentScreenOffsets,x + sta segmentScreenOffsets,y - stz segmentScreenShifts,x + lda #0 + sta segmentScreenShifts,y txa - sta segmentTileOffsetsUL,x - sta segmentTileOffsetsUR,x - sta segmentTileOffsetsLL,x - sta segmentTileOffsetsLR,x + sta segmentTileOffsetsUL,y + sta segmentTileOffsetsUR,y + sta segmentTileOffsetsLL,y + sta segmentTileOffsetsLR,y inc numSegments @@ -178,31 +217,44 @@ addBodySegment entry addHeadSegment entry - lda numSegments + lda #SEGMENT_MAX_NUM-1 + sec + sbc numSegments asl a tax lda #SEGMENT_STATE_HEAD sta segmentStates,x - lda #SEGMENT_DIR_LEFT - sta segmentDirections,x + txa + asl a + asl a + asl a + sta segmentPosOffset,x + tay - lda #SEGMENT_FACING_LEFT - sta segmentFacing,x + lda #SEGMENT_DIR_RIGHT + sta segmentHorizontalDir,y + + lda #SEGMENT_DIR_DOWN + sta segmentVerticalDir,y + + lda #SEGMENT_FACING_RIGHT + sta segmentFacing,y lda tileScreenOffset,x sec sbc #3 - sta segmentScreenOffsets,x + sta segmentScreenOffsets,y - stz segmentScreenShifts,x + lda #0 + sta segmentScreenShifts,y txa - sta segmentTileOffsetsUL,x - sta segmentTileOffsetsUR,x - sta segmentTileOffsetsLL,x - sta segmentTileOffsetsLR,x + sta segmentTileOffsetsUL,y + sta segmentTileOffsetsUR,y + sta segmentTileOffsetsLL,y + sta segmentTileOffsetsLR,y inc numSegments @@ -216,15 +268,35 @@ shootSegment entry numSegments dc i2'0' +; The method used to track a segments position and other details on the screen are a bit +; funky. In order to have body segments follow a head segment, we keep information from +; the position of the head segment. The segmentPosOffset gives an offset into the other +; larger arrays (97 words) which describes the position of the segment. When a head is +; updated, the segmentPosOffset is decremented. That way, the previous positions are +; still there and body segments after that can reference it. +; +; We need at least 96 of them because a slow moving head segment goes through 8 positions +; before it can be re-used by the next body segment. If there are 12 segments max, we +; need (8*12) positions to ensure all segments can know where there position was and will +; be next. +; +; But I bump that count up to 97. When the segmentPosOffset is 0, the next one to use is +; the last. It is nice to assume that the previous position information is at (index + 2). +; That works all the time except when segmentPosOffset was 0 and now wraps around to 190 +; or ((96 - 1) * 2). When that happens, we copy the info from 0 to 192 or (96 *2). That +; way the code can safely assume that the old position information is in fact always at. +; (index + 2). segmentStates dc 12i2'SEGMENT_STATE_NONE' -segmentDirections dc 12i2'SEGMENT_DIR_RIGHT' -segmentFacing dc 12i2'SEGMENT_FACING_DOWN' -segmentScreenOffsets dc 12i2'0' -segmentScreenShifts dc 12i2'0' -segmentTileOffsetsUL dc 12i2'0' -segmentTileOffsetsUR dc 12i2'0' -segmentTileOffsetsLL dc 12i2'0' -segmentTileOffsetsLR dc 12i2'0' +segmentPosOffset dc 12i2'0' +segmentHorizontalDir dc 97i2'SEGMENT_DIR_RIGHT' +segmentVerticalDir dc 97i2'SEGMENT_DIR_DOWN' +segmentFacing dc 97i2'SEGMENT_FACING_DOWN' +segmentScreenOffsets dc 97i2'0' +segmentScreenShifts dc 97i2'0' +segmentTileOffsetsUL dc 97i2'0' +segmentTileOffsetsUR dc 97i2'0' +segmentTileOffsetsLL dc 97i2'0' +segmentTileOffsetsLR dc 97i2'0' SEGMENT_SPRITE_LAST_OFFSET gequ 7*4 segmentSpriteOffset dc i2'SEGMENT_SPRITE_LAST_OFFSET' diff --git a/BuGS/global.macros b/BuGS/global.macros index fb18cc0..0c7a89b 100644 --- a/BuGS/global.macros +++ b/BuGS/global.macros @@ -90,5 +90,31 @@ _dirtyGameTile_nonGame&SYSCNT anop iny sty numDirtyNonGameTiles +_dirtyGameTile_skip&SYSCNT anop + mend + + macro + _dirtyGameOrNonGameTileX &tileOffset + + ldy &tileOffset,x + cpy #RHS_FIRST_TILE_OFFSET + bge _dirtyGameTile_nonGame&SYSCNT + lda #TILE_STATE_DIRTY + sta tileDirty,y + bra _dirtyGameTile_skip&SYSCNT + +_dirtyGameTile_nonGame&SYSCNT anop + lda tileDirty,y + bne _dirtyGameTile_skip&SYSCNT + lda #TILE_STATE_DIRTY + sta tileDirty,y + + tya + ldy numDirtyNonGameTiles + sta dirtyNonGameTiles,y + iny + iny + sty numDirtyNonGameTiles + _dirtyGameTile_skip&SYSCNT anop mend diff --git a/BuGS/make/config.txt b/BuGS/make/config.txt index 4cf9182..6e02df5 100644 --- a/BuGS/make/config.txt +++ b/BuGS/make/config.txt @@ -8,7 +8,7 @@ s6d2 = s7d1 = /Users/jrand/Library/Developer/Xcode/DerivedData/BuGS-bffpexoblaghkzcbtjtzxeulnuto/Build/Products/Debug/BuGS.2mg -g_limit_speed = 3 +g_limit_speed = 0 bram1[00] = 00 00 00 01 00 00 0d 06 02 01 01 00 01 00 00 00