As anybody involved in writing software can tell you, project specifications will often change when new information becomes available.
When I started working on Collect, my plan was to use it for my presentation at Classic Game Fest. As I've progressed I've come to the realization that a full blown game is going to be just too much information for a one hour presentation. I decided that I'm going to leave the existing example in place and just add a few slides about Collect with a link to these blog entries for anybody who is interested.
Since I'm no longer planning to fit this project into a presentation, I've decided on a few changes:
Timer has decreased
One player variation will hide right player's score and use player1 as an additional box.
The Ball Object has a vertical delay feature. When used, the ball should be udpated on the same scanline as player0. Due to this, I've revised the 2LK to be like this:
In this build I've revised the Arena to be a little bit shorter to make room for the new timer display. The timer currently "ticks" once every 64 frames. Whenever it ticks, a bunch of byte rotatations are done to shorten the length of the timer bar.
Since there are 40 playfield pixels, the total playtime would be 40*64/60 = 42.7 seconds. We might decide that's too short of a play time. If so, we'll just change the tick to occur every 128 frames for 40*128/60 = 85.3 seconds of game time, or maybe even once very 256 frames for 40*256/60 = 170.7 seconds.
SetObjectColors has been modified to add a color for the timer bar. The Timer Bar and the Arena are both drawn using the playfield, so to make the Arena a different color than the Timer Bar I store the current Arena color in a RAM location.
For testing, I've set it up so the Right Difficulty switch is used to determine if the game is a one or two player game for which graphics to use for player1:
Right Difficulty = B
Right Difficulty = A
ROM
collect_20140704a.bin (2KB)
downloads: 71
Source
Collect_20140704a.zip (47.39KB)
downloads: 108
When I started working on Collect, my plan was to use it for my presentation at Classic Game Fest. As I've progressed I've come to the realization that a full blown game is going to be just too much information for a one hour presentation. I decided that I'm going to leave the existing example in place and just add a few slides about Collect with a link to these blog entries for anybody who is interested.
Since I'm no longer planning to fit this project into a presentation, I've decided on a few changes:
- Make Collect a 1-2 player game
- Add the Ball object to draw an additional box, especially useful for 2 player games
- Change Timer display to the right player's score
- Add a Timer Bar to indicate time remaining

Timer has decreased

One player variation will hide right player's score and use player1 as an additional box.

The Ball Object has a vertical delay feature. When used, the ball should be udpated on the same scanline as player0. Due to this, I've revised the 2LK to be like this:
- updates player1, playfield, precalc player0 for line 2
- updates player0, playfield, precalc player1 for line 1
- updates player1, playfield, precalcs player0, ball for line 2
- updates player0, ball, precalcs player 1, playfield for line 1
- updates player1, missile0, missile1, playfield, precalcs player0, missile0, missile1, ball for line 2
- updates player0, missile0, missile1, ball, precalcs player 1, missile0, missile1, playfield for line 1
- updates player1, missile1, playfield, precalcs player0, missile0, ball for line 2
- updates player0, missile0, ball, precalcs player1, missile1, playfield for line 1
In this build I've revised the Arena to be a little bit shorter to make room for the new timer display. The timer currently "ticks" once every 64 frames. Whenever it ticks, a bunch of byte rotatations are done to shorten the length of the timer bar.
DecrementTimer: lsr TimerPF+5 ; PF2 right side, reversed bits so shift right rol TimerPF+4 ; PF1 right side, normal bits so shift left ror TimerPF+3 ; PF0 right side, reversed bits so shift right lda TimerPF+3 ; only upper nybble used, so we need to put bit 3 into C lsr lsr lsr lsr ror TimerPF+2 ; PF2 left side, reversed bits so shift right rol TimerPF+1 ; PF1 left side, normal bits so shift left ror TimerPF ; PF0 left side, reversed bits so shift right rts
Since there are 40 playfield pixels, the total playtime would be 40*64/60 = 42.7 seconds. We might decide that's too short of a play time. If so, we'll just change the tick to occur every 128 frames for 40*128/60 = 85.3 seconds of game time, or maybe even once very 256 frames for 40*256/60 = 170.7 seconds.
SetObjectColors has been modified to add a color for the timer bar. The Timer Bar and the Arena are both drawn using the playfield, so to make the Arena a different color than the Timer Bar I store the current Arena color in a RAM location.
SetObjectColors: ldx #4 ; we're going to set 5 colors (0-4) ldy #4 ; default to the color entries in the table (0-4) lda SWCHB ; read the state of the console switches and #%00001000 ; test state of D3, the TV Type switch bne SOCloop ; if D3=1 then use color ldy #9 ; else use the b&w entries in the table (5-9) SOCloop: lda Colors,y ; get the color or b&w value sta COLUP0-1,x ; and set it dey ; decrease Y dex ; decrease X bne SOCloop ; Branch Not Equal to Zero lda Colors,y ; get the Arena color sta ArenaColor ; save in RAM for Kernal Usage rts ; ReTurn from Subroutine Colors: .byte $46 ; red - goes into COLUPF, color for Arena (after Timer is drawn) .byte $86 ; blue - goes into COLUP0, color for player0 and missile0 .byte $C6 ; green - goes into COLUP1, color for player1 and missile1 .byte $64 ; purple - goes into COLUPF, color for Timer .byte $00 ; black - goes into COLUBK, color for background .byte $0A ; light grey - goes into COLUPF, color for Arena (after Timer is drawn) .byte $0E ; white - goes into COLUP0, color for player0 and missile0 .byte $06 ; dark grey - goes into COLUP1, color for player1 and missile1 .byte $04 ; dark grey - goes into COLUPF, color for Timer .byte $00 ; black - goes into COLUBK, color for background
For testing, I've set it up so the Right Difficulty switch is used to determine if the game is a one or two player game for which graphics to use for player1:
ldx #0 bit SWCHB bpl TwoPlayer ldx #1 TwoPlayer: ; Player1Ptr = BoxGfx + HUMAN_HEIGHT - 1 - Y position lda ShapePtrLow,x sec sbc Temp sta Player1Ptr lda ShapePtrHi,x sbc #0 sta Player1Ptr+1 rts ShapePtrLow: .byte <(HumanGfx + HUMAN_HEIGHT - 1) .byte <(BoxGfx + HUMAN_HEIGHT - 1) ShapePtrHi: .byte >(HumanGfx + HUMAN_HEIGHT - 1) .byte >(BoxGfx + HUMAN_HEIGHT - 1)
Right Difficulty = B

Right Difficulty = A

ROM

downloads: 71
Source

downloads: 108
This is interesting:
It never occurred to me that you could cycle through registers like that but it makes sense since they are simply memory locations that happen to be next to each other, I assume..
And here, since these are performed consecutively, we're sharing the carry bit among each of the PF fields- right?
And, eventually, zeros will be fed into the fields one by one due to the initial LSR- correct?: