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