Revision 517b1a45

View differences:

main.c
29 29
#define A2 		PC2
30 30
#define A3 		PC3
31 31

  
32
// note that both controllers are on the same port, the reason is
33
// controllerOffset for faster input handling
32 34
#define CONTROLLER0_PORT   D
33 35
#define CONTROLLER0_LEFT   PD7
34 36
#define CONTROLLER0_RIGHT  PD6
35 37
#define CONTROLLER0_DOWN   PD5
36 38
#define CONTROLLER0_ROTATE PD4
39
#define CONTROLLER1_PORT   D
40
#define CONTROLLER1_LEFT   PD3
41
#define CONTROLLER1_RIGHT  PD2
42
#define CONTROLLER1_DOWN   PD1
43
#define CONTROLLER1_ROTATE PD0
37 44

  
38 45
// control mappings for atari joystick
39 46
#define LEFT   0b0001
40
#define DOWN   0b1000
47
#define DOWN   0b0100
41 48
#define RIGHT  0b0010
42
#define ROTATE 0b0100
49
#define ROTATE 0b1000
43 50

  
44 51
#define TICKS 40
45
#define NUMBER_OF_PLAYERS 1
52
#define NUMBER_OF_PLAYERS 2
46 53

  
47 54
struct player;
48 55

  
......
60 67
	volatile int8_t gameAreaEnd;
61 68
	volatile sprite_t sprite;
62 69
	volatile uint8_t mirrored;
70
	volatile uint8_t controllerOffset;
71
	volatile uint8_t controllerInputMask;
63 72
	} player_t;
64 73

  
65 74
int main(void);
......
80 89
void moveSpriteHorizontal(volatile sprite_t *sprite, int8_t dir); // -1 if left, 1 if right
81 90
void handleGamepadInput(player_t* player, uint8_t input);
82 91
inline void printLine(int16_t line, uint8_t round, sprite_t* sprite);
83
static inline void drawGameArea(player_t* player);
92
static inline void drawGameArea(player_t player[NUMBER_OF_PLAYERS]);
84 93
void gameOver(player_t* player);
85 94
void setNewSprite(sprite_t* sprite);
86 95
void drawScore(uint16_t* score, uint8_t round);
......
100 109
	// move > rotate > down
101 110
	DDR(CONTROLLER0_PORT) &= ~((1<<CONTROLLER0_LEFT) | (1<<CONTROLLER0_RIGHT) | (1<<CONTROLLER0_DOWN) | (1<<CONTROLLER0_ROTATE));
102 111
	PORT(CONTROLLER0_PORT) |= (1<<CONTROLLER0_LEFT) | (1<<CONTROLLER0_RIGHT) | (1<<CONTROLLER0_DOWN) | (1<<CONTROLLER0_ROTATE);
112
	DDR(CONTROLLER1_PORT) &= ~((1<<CONTROLLER1_LEFT) | (1<<CONTROLLER1_RIGHT) | (1<<CONTROLLER1_DOWN) | (1<<CONTROLLER1_ROTATE));
113
	PORT(CONTROLLER1_PORT) |= (1<<CONTROLLER1_LEFT) | (1<<CONTROLLER1_RIGHT) | (1<<CONTROLLER1_DOWN) | (1<<CONTROLLER1_ROTATE);
103 114
	// address lines:
104 115
	DDR(ADDRESS_PORT) |= (1<<A3) | (1<<A2) | (1<<A1) | (1<<A0);
105 116

  
......
107 118
	player[0].score = 0;
108 119
	player[0].gameAreaStart = 0;
109 120
	player[0].gameAreaEnd = 43;
121
	setNewSprite((sprite_t*)&(player[0].sprite));
110 122
	player[0].sprite.owner = (player_t*)&player[0];
111 123
	player[0].mirrored = 0;
112
	setNewSprite((sprite_t*)&(player[0].sprite));
113

  
124
	player[0].controllerInputMask = (1<<CONTROLLER0_LEFT) | (1<<CONTROLLER0_DOWN) | (1<<CONTROLLER0_RIGHT) | (1<<CONTROLLER0_ROTATE);
125
	player[0].controllerOffset = 4;
126
	// next one
127
	player[1].score = 0;
128
	player[1].gameAreaStart = 46;
129
	player[1].gameAreaEnd = 89;
130
	setNewSprite((sprite_t*)&(player[1].sprite));
131
	player[1].sprite.owner = (player_t*)&player[1];
132
	player[1].mirrored = 1;
133
	player[1].controllerInputMask = (1<<CONTROLLER1_LEFT) | (1<<CONTROLLER1_DOWN) | (1<<CONTROLLER1_RIGHT) | (1<<CONTROLLER1_ROTATE);
134
	player[1].controllerOffset = 0;
114 135
	while(1){
115
		for(uint8_t playerNumber = 0; playerNumber < NUMBER_OF_PLAYERS; playerNumber++){
116
			for(uint8_t delay = 0; delay < TICKS; delay++){
117
				drawGameArea((player_t*)&player[playerNumber]);
118
				if(delay%20 == 0){
136
		for(uint8_t delay = 0; delay < TICKS; delay++){
137
			drawGameArea((player_t*)player);
138
			if(delay%(TICKS/(NUMBER_OF_PLAYERS+1)) == 0){
139
				for(uint8_t playerNumber = 0; playerNumber < NUMBER_OF_PLAYERS; playerNumber++){ //fair handing of input
119 140
					handleGamepadInput((player_t*)&player[playerNumber],
120
								((~PIN(CONTROLLER0_PORT))&
121
									( (1<<CONTROLLER0_LEFT)
122
									| (1<<CONTROLLER0_DOWN)
123
									| (1<<CONTROLLER0_RIGHT)
124
									| (1<<CONTROLLER0_ROTATE))
125
								)>>4);
141
								((~PIN(CONTROLLER0_PORT))& player[playerNumber].controllerInputMask)
142
									>>player[playerNumber].controllerOffset);
126 143
				}
127 144
			}
145
		}
146
		for(uint8_t playerNumber = 0; playerNumber < NUMBER_OF_PLAYERS; playerNumber++){
128 147
			moveSpriteDown((sprite_t*)&(player[playerNumber].sprite));
129 148
			clearCompleteLines((player_t*)&player[playerNumber]);
130 149
			moveFlyingRowsDown((player_t*)&player[playerNumber]);
......
140 159
	keypressCounter++;
141 160
}
142 161

  
143
void gameOver(player_t* player){ // TODO FIXME
144
	for(int16_t line = (*player).gameAreaStart; line < (*player).gameAreaEnd; line++){
145
		lines[line] = 0xffff;
146
		drawGameArea(player);
147
	}
148
	for(int16_t line = (*player).gameAreaEnd-1; line >= (*player).gameAreaStart; line--){
162
void gameOver(player_t* player){
163
	for(int16_t line = (*player).gameAreaEnd; line >= (*player).gameAreaStart; line--){
149 164
		lines[line] = 0x0000;
150
		drawGameArea(player);
151 165
	}
152 166
	(*player).score = 0;
153 167
	setNewSprite((sprite_t*)&((*player).sprite));
......
162 176
	}
163 177
}
164 178

  
165
static inline void drawGameArea(player_t* player){ // TODO needs changes for real multiplayer
179
static inline void drawGameArea(player_t player[NUMBER_OF_PLAYERS]){
166 180
	for(uint8_t round = 0; round < 16; round++){
167
		for(int16_t line = (*player).gameAreaStart; line <= (*player).gameAreaEnd; line++){
168
			printLine(line, round, (sprite_t*)&((*player).sprite));
169
		}
170
		drawScore((uint16_t*)&((*player).score), round);
171
		drawScore((uint16_t*)&((*player).score), round); // don't mirror the score, so it's easier to compare
172
		for(int16_t line = (*player).gameAreaEnd; line >= (*player).gameAreaStart; line--){
173
			printLine(line, 15-round, (sprite_t*)&((*player).sprite));
181
		for(uint8_t playerNumber = 0; playerNumber < NUMBER_OF_PLAYERS; playerNumber++){
182
			if(player[playerNumber].mirrored){
183
				drawScore((uint16_t*)&(player[playerNumber].score), round); // don't mirror the score, so it's easier to compare
184
				for(int16_t line = player[playerNumber].gameAreaEnd; line >= player[playerNumber].gameAreaStart; line--){
185
					printLine(line, 15-round, (sprite_t*)&(player[playerNumber].sprite));
186
				}
187
			}
188
			else{
189
				for(int16_t line = player[playerNumber].gameAreaStart; line <= player[playerNumber].gameAreaEnd; line++){
190
					printLine(line, round, (sprite_t*)&(player[playerNumber].sprite));
191
				}
192
				drawScore((uint16_t*)&(player[playerNumber].score), round);
193
			}
174 194
		}
175 195
		OE();
176 196
		_delay_us(80);
......
300 320
}
301 321

  
302 322
void moveFlyingRowsDown(player_t* player){
303
	for(uint8_t line = (*player).gameAreaStart; line <= (*player).gameAreaEnd; line++){
323
	for(uint8_t line = (*player).gameAreaStart; line <= (*player).gameAreaEnd-1; line++){
304 324
		if(lines[line] == 0x0000){ // TODO maybe add clear effect with green line?
305 325
			lines[line] = lines[line+1];
306 326
			// blank line to propagate movement

Also available in: Unified diff