1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
#include <conio.h>
#include <stdio.h>
#include <c64.h>
#include <joystick.h>
#include <stdint.h>
struct screen {
unsigned char grid[25][40];
};
enum direction {
UP,
DOWN,
LEFT,
RIGHT,
};
struct player {
char x;
char y;
enum direction dir;
unsigned char joy;
unsigned char prev_joy;
unsigned char next_char;
};
#define SCREEN (*(struct screen*) 0x0400)
#define SCREEN_AT(x, y) (SCREEN.grid[y][x])
#define MAX_PLAYERS 2
#define EMPTY '\x20'
#define PLAYER '\x71'
#define CHR_V '\x42'+128
#define CHR_H '\x43'+128
#define CHR_DR '\xed'+128
#define CHR_RD '\xee'+128
#define CHR_UR '\xf0'+128
#define CHR_RU '\xfd'+128
static void update_player(struct player *p) {
/* has direction been changed? */
if (p->joy == p->prev_joy) {
if (p->dir == DOWN || p->dir == UP) {
p->next_char = CHR_V;
} else if (p->dir == LEFT || p->dir == RIGHT) {
p->next_char = CHR_H;
}
return;
}
if (JOY_UP(p->joy) && p->dir != DOWN) {
switch (p->dir) {
case RIGHT: p->next_char = CHR_RU; break;
case LEFT: p->next_char = CHR_DR; break;
}
p->dir = UP;
} else if (JOY_DOWN(p->joy) && p->dir != UP) {
switch (p->dir) {
case RIGHT: p->next_char = CHR_RD; break;
case LEFT: p->next_char = CHR_UR; break;
}
p->dir = DOWN;
} else if (JOY_LEFT(p->joy) && p->dir != RIGHT) {
switch (p->dir) {
case UP: p->next_char = CHR_RD; break;
case DOWN: p->next_char = CHR_RU; break;
}
p->dir = LEFT;
} else if (JOY_RIGHT(p->joy) && p->dir != LEFT) {
switch (p->dir) {
case UP: p->next_char = CHR_UR; break;
case DOWN: p->next_char = CHR_DR; break;
}
p->dir = RIGHT;
}
p->prev_joy = p->joy;
}
static char move_player(struct player *p) {
int res = 1;
SCREEN_AT(p->x, p->y) = p->next_char;
switch (p->dir) {
case UP: p->y--; break;
case DOWN: p->y++; break;
case LEFT: p->x--; break;
case RIGHT: p->x++; break;
}
if (SCREEN_AT(p->x, p->y) != EMPTY || p->x < 0 || p->x >= 40 || p->y < 0 || p->y >= 25) {
res = 0;
}
SCREEN_AT(p->x, p->y) = PLAYER;
return res;
}
static void play_game(char n_players) {
uint16_t busy_wait = 300;
struct player players[MAX_PLAYERS] = {
{ 5, 12, RIGHT, 0, 0, CHR_H },
{ 35, 12, LEFT, 0, 0, CHR_H },
};
clrscr();
while(1) {
char i;
uint16_t n;
for (i=0; i<n_players; i++) {
if (!move_player(&players[i])) {
return;
}
}
/* "sleep" for a bit, but keep reading joystick changes */
for (n=0; n<busy_wait; n++) {
for (i=0; i<n_players; i++) {
char tmp = joy_read(i);
if (tmp) {
players[i].joy = tmp;
}
}
}
for (i=0; i<n_players; i++) {
update_player(&players[i]);
}
}
}
int main() {
joy_install(joy_static_stddrv);
/* use uppercase character set */
*((unsigned char*)0xD018) = 0x14;
while(1) {
play_game(2);
printf("game over!");
}
}
|