1 /*
2 
3 	Z88DK base graphics libraries examples
4 	Colour version
5 
6 	A classic 2 players game, the opponents must trap each other.
7 
8 	Build options:
9 	-DJOYSTICK_DIALOG	- let the players choose their controllers
10 	-DPSG -lm			- PSG sound support (e.g. ZON-X on the ZX81, maths library is required)
11 
12 
13 	SPEED must be adjusted according to the CPU speed (e.g. must be around 500 on a ZX81)
14 
15 	zcc +trs80 -subtype=eg2000disk -lgfxeg2000 -create-app -DSPEED=1500 -DJOYSTICK_DIALOG -DDEFINE_JOYSTICK_TYPE csnakes.c
16 
17 */
18 
19 #include <games.h>
20 #include <graphics.h>
21 
22 #ifdef JOYSTICK_DIALOG
23 #include <stdio.h>
24 #endif
25 
26 #ifdef PSG
27 #include <psg.h>
28 #endif
29 
30 struct snake {
31     int joystick;
32     int direction;
33     int x;
34     int y;
35     int x_incr;
36     int y_incr;
37     int c;
38 };
39 
40 struct snake p1;
41 struct snake p2;
42 
43 int x, y;
44 
crash(int a,int b)45 void crash(int a, int b)
46 {
47     for (y = 0; y < 30; y++) {
48 
49         cplot(a + 1, b + 1, y & 3);
50         cplot(a - 1, b - 1, y & 3);
51         cplot(a - 1, b + 1, y & 3);
52         cplot(a + 1, b - 1, y & 3);
53 
54         for (x = 0; x < SPEED * 2; x++) {
55         }
56     }
57 }
58 
move_snake(struct snake * p)59 int move_snake(struct snake* p)
60 {
61 
62     if (p->direction & MOVE_RIGHT) {
63         p->x_incr = 1;
64         p->y_incr = 0;
65     }
66     if (p->direction & MOVE_LEFT) {
67         p->x_incr = -1;
68         p->y_incr = 0;
69     }
70     if (p->direction & MOVE_DOWN) {
71         p->y_incr = 1;
72         p->x_incr = 0;
73     }
74     if (p->direction & MOVE_UP) {
75         p->y_incr = -1;
76         p->x_incr = 0;
77     }
78 
79     p->x += p->x_incr;
80     p->y += p->y_incr;
81 
82     if (cpoint(p->x, p->y)!=0)
83         return (0);
84     cplot(p->x, p->y, p->c);
85 
86     p->direction = joystick(p->joystick);
87 
88     for (x = 0; x < SPEED; x++) {
89     };
90     return (1);
91 }
92 
play_game()93 int play_game()
94 {
95     while (1) {
96         if (move_snake(&p1) == 0) {
97 #ifdef PSG
98             psg_envelope(envD, psgT(10), chanAll); // set a fading volume envelope on all channels
99 #endif
100             crash(p1.x - p1.x_incr, p1.y - p1.y_incr);
101             return (1);
102         }
103 
104 #ifdef PSG
105         psg_tone(1, psgT(p1.x + p1.y + 10 * (15 + 2 * p1.x_incr + p1.y_incr)));
106 #endif
107 
108         if (move_snake(&p2) == 0) {
109 #ifdef PSG
110             psg_envelope(envD, psgT(10), chanAll); // set a fading volume envelope on all channels
111 #endif
112             crash(p2.x - p2.x_incr, p2.y - p2.y_incr);
113             return (2);
114         }
115 
116 #ifdef PSG
117         psg_tone(2, psgT(p2.x + p2.y + 12 * (15 + 2 * p2.x_incr + p2.y_incr)));
118 #endif
119     }
120 }
121 
main()122 main()
123 {
124 
125 #ifdef JOYSTICK_DIALOG
126 
127 
128     printf("%c\nLeft player controller:\n\n", 12);
129 
130     for (x = 0; x != GAME_DEVICES; x++)
131         printf("%u - %s\n", x + 1, joystick_type[x]);
132 
133     p1.joystick = 0;
134     while ((p1.joystick < 1) || (p1.joystick > GAME_DEVICES))
135         p1.joystick = getk() - 48;
136 
137     while (getk())
138         ;
139 
140     printf("%c\nRight player controller:\n\n", 12);
141 
142     for (x = 0; x != GAME_DEVICES; x++)
143         printf("%u - %s\n", x + 1, joystick_type[x]);
144 
145     p2.joystick = 0;
146     while ((p2.joystick < 1) || (p2.joystick > GAME_DEVICES))
147         p2.joystick = getk() - 48;
148 
149 #else
150 
151     p1.joystick = 1;
152     p2.joystick = 2;
153 
154 #endif
155 
156     while (1) {
157         cclg();
158 
159 
160 #ifdef PSG
161         psg_init();
162         psg_volume(1, 10);
163         psg_volume(2, 10);
164 #endif
165 
166         for (x = 0; x <= 127; x++) {
167             cplot(x, 0, 2);
168             cplot(x, 63, 2);
169         }
170         for (y = 0; y <= 63; y++) {
171             cplot(0, y, 2);
172             cplot(127, y, 2);
173         }
174 
175         p1.x = 127 / 5;
176         p1.y = 63 / 5;
177         p1.direction = MOVE_LEFT;
178         p1.x_incr = -1;
179         p1.y_incr = 0;
180         p1.c = 1;
181 
182         p2.x = 127 - 127 / 5;
183         p2.y = 63 - 63 / 5;
184         p2.direction = MOVE_RIGHT;
185         p2.x_incr = 1;
186         p2.y_incr = 0;
187 		p2.c = 3;
188 
189         play_game();
190     }
191 }
192