SDL2 example
[mirrors/Programs.git] / c / pong / pong.c
CommitLineData
21c4e167
H
1/* hPong 0.3
2 * <~~Harvie 2oo8
3 * Released under Creative Commons
4 *
5 * Requirements:
6 * - stty
7 * - ansi terminal with resolution >= 80x24 characters
8 */
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <signal.h>
13
14//Settings
15char pixchar = '#';
16
17int turntime = 25; //Time of turn in ms (inverted speed)
18int debugturntime = 0; //Turntime for debuging
19
20unsigned char padsize = 1; //Size of pad
21char padspeed = 2; //Speed of pad (pixels per keypress)
22
23unsigned char ui_skill_l = 255; //Skill of UI = (0-255); 0=disabled, 255=godmode
24unsigned char ui_skill_r = 200; //Skill of UI = (0-255); 0=disabled, 255=godmode
25unsigned char debug = 0; //UI Debug mode
26
27unsigned char music = 0; //Enable music? (Bool)
28char music_cmd[] ="while true; do mplayer /usr/share/chiptunes/* >/dev/null 2>&1; done;";
29
30unsigned char arduino = 0; //Enable Arduino? (Bool)
31char arduinodev[] = "/dev/ttyUSB0";
32
33//Stadium
34unsigned char *stadium_bitmap[] = {
35"#### hPong 0.3 ################################################",
36"# | #",
37"# #",
38"# | #",
39"# #",
40"# | #",
41"# #",
42"# | #",
43"# #",
44"# | #",
45"# #",
46"# | #",
47"# #",
48"# | #",
49"# #",
50"# | #",
51"########################################### <~~Harvie 2oo8 ####"};
52char stadium_lines = 17; //15+2
53char stadium_width = 63; //60+2+1
54
55//Banners
56unsigned char banner_start[] =
57"\n\n\n\n\n\n\n\n\n\n\n"
58" ## #### by: <~~Harvie 2oo8\n"
59" ## # #\n"
60" ## ## ## #### ### #### ###\n"
61" ####### ###### # # # # # # #\n"
62" ## ## ## # ### # # ####\n"
63" ## ## ## #\n"
64" ## Press any key to start! ###\n";
65
66unsigned char banner_lose[] =
67"\n\n\n\n\n\n\n\n\n\n\n\n\n"
68" ### # # ### # # # ### #\n"
69" # # # # # # # # # #\n"
70" # # ### ### ### # # #\n"
71" # # # # # # # # #\n"
72" ### # # ### # # # # #\n"
73"\n"
74" Score: %d : %d\n"
75" (Press Any Key to continue...)\n";
76
77//Numbers
78char stadium_offset = 7;
79char score_space[] = " ";
80unsigned char *num_bitmaps[]={
81"#### ## ## ####", //0
82" # # # # #", //1...
83"### ##### ###",
84"### #### ####",
85" # # ### # ",
86"#### ### ####",
87"#### #### ####",
88"### # # # # ",
89"#### ##### ####",
90"#### #### ####"}; //9
91
92//Other Values
93char stadium_max; //Set by init()
94
95char ball_c = 1; //x
96char ball_l = 0; //y
97char ballmove_c = 1; //x
98char ballmove_l = 1; //y
99
100char player_l = 7; //Left
101char player_r = 7; //Right
102
103unsigned int score_l = 0;
104unsigned int score_r = 0;
105
106//Misc
107char loop=0;
108char temp;
109FILE *musicfd = NULL;
110FILE *arduinofd = NULL;
111
112//Functions
113void blank() {
114 printf("\033[2J"); //Clear screen
115 printf("\033[0;0H"); //L:C = 0:0
116}
117
118void quit() {
119 if(arduino) fclose(arduinofd);
120 ualarm(0, 0);
121 system("stty icanon");
122 blank();
123 printf("hPong exited! Scrore was %d : %d\n<~~Harvie 2oo8\n", score_l, score_r);
124 exit(255);
125 if(music) pclose(musicfd);
126}
127
128void music_start() {
129 if( (musicfd = popen(music_cmd, "r"))==NULL ) {
130 printf("Cannot initialize music\n");
131 quit();
132 }
133}
134
135void win(char player) {
136 switch(player) {
137 case 'l':
138 score_l++;
139 ball_l = 2; ball_c = stadium_width-3; ballmove_c = -1;
140 break;
141
142 case 'r':
143 score_r++;
144 ball_l = 2; ball_c = 3; ballmove_c = 1;
145 break;
146 }
147 blank();
148 printf(banner_lose, score_l, score_r);
149 if(!debug) sleep(1);
150 if(!arduino && (ui_skill_l == 0 || ui_skill_r == 0)) getchar();
151 blank();
152}
153
154void reset_scr() {
155 printf("\033[0;0H"); //L:C = 0:0
156}
157
158void pixel(char c, char line, char col) {
159 printf("\033[%d;%dH", line, col);
160 putchar(c);
161 printf("\033[0;0H"); //L:C = 0:0
162}
163
164void draw_stadium() {
165 unsigned char i, x, sl, sr;
166 sl = score_l%10; sr = score_r%10;
167 for(i=0;i<stadium_offset;i++) {
168 printf("\033[K");
169 if(i>=1 && i<=5) {
170 x = (i-1)*3;
171 printf("%s%c%c%c . %c%c%c", score_space,
172 num_bitmaps[sl][x], num_bitmaps[sl][x+1], num_bitmaps[sl][x+2],
173 num_bitmaps[sr][x], num_bitmaps[sr][x+1], num_bitmaps[sr][x+2]
174 );
175 }
176 putchar('\n');
177 }
178 for(i=0;i<stadium_lines;i++) printf("%s\033[K\n", stadium_bitmap[i]);
179 printf("\033[K");
180}
181
182void recalc() {
183 //UI - follow ball
184 if((unsigned char)rand() < ui_skill_l) { //Left
185 if(player_l < ball_l) player_l++;
186 if(player_l > ball_l) player_l--;
187 }
188
189 if((unsigned char)rand() < ui_skill_r) { //Right
190 if(player_r < ball_l) player_r++;
191 if(player_r > ball_l) player_r--;
192 }
193
194 //Move ball
195 ball_c += ballmove_c;
196 ball_l += ballmove_l;
197
198 //Pong (horizontal)
199 if(ball_c == 1) { //left
200 if(abs(ball_l-player_l) <= padsize+1) {
201 ballmove_c = -ballmove_c;
202 ball_c++;
203 } else {
204 win('r');
205 }
206 }
207
208 if(ball_c == stadium_width-3) { //right
209 if(abs(ball_l-player_r) <= padsize+1) {
210 ballmove_c = -ballmove_c;
211 ball_c--;
212 } else {
213 win('l');
214 }
215 }
216
217 //Bounce ball (vertical)
218 if(ball_l >= stadium_max || ball_l <= 0) ballmove_l = -ballmove_l;
219}
220
221void redraw() {
222 char i;
223 //Clear
224 reset_scr();
225
226 //Stadium
227 draw_stadium();
228
229 //Check player pos limits
230 if(player_r < 0) player_r = 0;
231 if(player_r > stadium_max) player_r = stadium_max;
232
233 if(player_l < 0) player_l = 0;
234 if(player_l > stadium_max) player_l = stadium_max;
235
236 //Pads
237 for(i=-padsize;i<padsize+1;i++) pixel(pixchar, stadium_offset+2+i+player_l, 2);
238 for(i=-padsize;i<padsize+1;i++) pixel(pixchar, stadium_offset+2+i+player_r, stadium_width-1);
239
240 //Ball
241 pixel(pixchar, stadium_offset+2+ball_l, 2+ball_c);
242 fflush(stdout);
243}
244
245void splash() {
246 blank();
247 puts(banner_start);
248 getchar();
249 blank();
250}
251
252void control(unsigned char key) {
253 switch(key) {
254 case 'A': player_r-=padspeed; break; //A = Arrow UP
255 case 'B': player_r+=padspeed; break; //B = Arrow DOWN
256 case 'q': case 'Q':
257 loop=0;
258 quit();
259 break;
260 case 'e': case 'E': player_l-=padspeed; break; //e key
261 case 'd': case 'D': player_l+=padspeed; break; //D key
262 }
263
264 redraw();
265}
266
267void alarm_handle(int signo) {
268 recalc();
269 redraw();
270 if(signo == SIGTERM || signo == SIGINT || signo == SIGQUIT) quit();
271}
272
273void init() {
274 //Blank screen
275 blank();
276 //Init random generator
277 srand(time(NULL));
278 //Disable both input buffers
279 setbuf(stdin, NULL);
280 system("stty -icanon");
281 //Handle alarm (timer)
282 signal(SIGALRM, alarm_handle);
283 signal(SIGINT, alarm_handle); signal(SIGTERM, alarm_handle); signal(SIGQUIT, alarm_handle);
284 //Compute lower sprite position in stadium
285 stadium_max = stadium_lines - 3;
286 //Debug mode
287 if(debug) turntime = debugturntime;
288 //Open Arduino
289 if( arduino&&((arduinofd=fopen(arduinodev,"rb"))==NULL) ) {
290 printf("Cannot open %s\n", arduinodev);
291 exit(255);
292 }
293}
294
295//Main... Short & simple ;)
296int main() {
297 init();
298 splash();
299
300 //Music
301 if(music) music_start();
302
303 loop = 1;
304 ualarm(turntime*1000+1, turntime*1000+1);
305 while(loop) {
306 if(arduino) player_r = getc(arduinofd); //Arduino
307 else control(getchar()); //Keyboard
308 }
309 quit();
310}
311
This page took 0.352168 seconds and 4 git commands to generate.