Blame view

games/ninvaders/nInvaders.c 9.58 KB
8e1b403a   pifou   ajout des sources...
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
  /**
   * nInvaders - a space invaders clone for ncurses
   * Copyright (C) 2002-2003 Dettus
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   *
   * homepage: http://ninvaders.sourceforge.net
   * mailto: ninvaders-devel@lists.sourceforge.net
   *
   */
  
  
  #include <stdio.h>
  #include <string.h>
  #include <sys/time.h>
  #include "nInvaders.h"
  #include "player.h"
  #include "aliens.h"
  #include "ufo.h"
9299dd74   root   Programmation nIn...
32
33
34
35
36
  #include "arduino.h"
  #include <libusb-1.0/libusb.h>
  #include <stdlib.h>
  #include <signal.h>
  #include <unistd.h>
8e1b403a   pifou   ajout des sources...
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  
  #define FPS 50
  
  int lives;
  long score;
  int status; // status handled in timer
  
  #define GAME_LOOP 1
  #define GAME_NEXTLEVEL 2
  #define GAME_PAUSED 3
  #define GAME_OVER 4
  #define GAME_EXIT 5
  #define GAME_HIGHSCORE 6
  
0ed3f148   root   terminé !
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  libusb_device_handle *handle;
  struct libusb_endpoint_descriptor endpoint_desc_list[ENDPOINTS_NUMBER];
  int waitUSB = 0;
  
  void sendLives(){
  	uint8_t toSend = 0x00;
  	if(lives == 5) toSend = 0x1F;
  	else if(lives == 4) toSend = 0x0F;
  	else if(lives == 3) toSend = 0x07;
  	else if(lives == 2) toSend = 0x03;
  	else if(lives == 1) toSend = 0x01;
  	else if(lives == 0) toSend = 0x00;
  	if(handle != NULL && endpoint_desc_list != NULL && waitUSB == 0){
  		waitUSB = 1;
  		usleep(100000); // wait for endpoints to be free (100 ms)
  		sendData(0, toSend, handle, endpoint_desc_list);
  		waitUSB = 0;
  	}
  }
8e1b403a   pifou   ajout des sources...
70
71
72
73
74
75
76
77
78
79
80
81
82
83
  
  /**
   * initialize level: reset attributes of most units
   */
  static void initLevel()
  {
  	playerReset();
  	aliensReset();
  	ufoReset();
  	bunkersReset();
  	render();
  	drawscore();
  }
  
8e1b403a   pifou   ajout des sources...
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
148
149
150
151
152
153
154
  /**
   * evaluate command line parameters 
   */
  static void evaluateCommandLine(int argc, char **argv)
  {
  	
  	// -l : set skill level
  	if (argc == 3 && strcmp(argv[1], "-l") == 0) {
  		if (argv[2][0] >= '0' && argv[2][0] <= '9') {
  			skill_level = argv[2][0] - 48;
  		} else {
  			argc = 2;
  		}
  	}
  
  	// -gpl : show GNU GPL
  	if (argc == 2 && strcmp(argv[1], "-gpl") == 0) {
  		showGpl();
  	}
  
  	// wrong command line: show usage
  	if (argc == 2 || (argc == 3 && strcmp(argv[1], "-l") != 0)) {
  		showVersion();
  		showUsage();
  		exit(1);
  	}
  }
  
  
  static void finish(int sig)
  {
          endwin();
  	showGplShort();
  	
  	fprintf(stderr,"\n");
  	fprintf(stderr,"\n");
  	fprintf(stderr,"=========================================================================\n");
  	fprintf(stderr,"\n");
  	
  	fprintf(stderr,"Final score: %7.7ld, Final level: %2.2d\nFinal rating... ",score,level);
  	if (lives>0)
  		fprintf(stderr,"Quitter\n\n");
  	else if(score<5000)
  		fprintf(stderr,"Alien Fodder\n\n");
  	else if(score<7500)
  		fprintf(stderr,"Easy Target\n\n");
  	else if(score<10000)
  		fprintf(stderr,"Barely Mediocre\n\n");
  	else if(score<12500)
  		fprintf(stderr,"Shows Promise\n\n");
  	else if(score<15000)
  		fprintf(stderr,"Alien Blaster\n\n");
  	else if(score<20000)
  		fprintf(stderr,"Earth Defender\n\n");
  	else if(score>19999)
  		fprintf(stderr,"Supreme Protector\n\n");
  	
  	showVersion();
          exit(0);
  }
  
  
  void drawscore()
  {
  	statusDisplay(level, score, lives);
  }
  
  
  /**
   * reads input from keyboard and do action
   */
0ed3f148   root   terminé !
155
  void readInput()
8e1b403a   pifou   ajout des sources...
156
157
158
159
  {
  	int ch;
  	static int lastmove;
  
9299dd74   root   Programmation nIn...
160
  	timeout(100);
8e1b403a   pifou   ajout des sources...
161
  	ch = getch();		// get key pressed
0ed3f148   root   terminé !
162
163
164
165
166
167
168
169
170
171
172
  
  	static uint8_t data = 0;
  	if(ch == -1){ // keyboard first
  		usleep(1000000); // slow down inputs (100 ms)
  		if(handle != NULL && endpoint_desc_list != NULL && waitUSB == 0)
  			receiveData(2, &data, handle, endpoint_desc_list);
  		if(data != 0){
  			if((data & 0x10) == 0x10) ch = KEY_LEFT;
  			else if((data & 0x04) == 0x04) ch = KEY_RIGHT;
  			else if((data & 0x08) == 0x08) ch = ' ';
  			else return;
9299dd74   root   Programmation nIn...
173
  		}
0ed3f148   root   terminé !
174
  		else return;
9299dd74   root   Programmation nIn...
175
  	}
8e1b403a   pifou   ajout des sources...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  
  	switch (status) {
  
  	case GAME_PAUSED:
  
  		if (ch == 'p') {
  			status = GAME_LOOP;
  		}
  		break;
  		       
  	case GAME_HIGHSCORE:
  
  		if (ch == ' ') {
  			titleScreenClear();
  			level = 0;      // reset level
  			score = 0;      // reset score
  			lives = 3;      // restore lives
0ed3f148   root   terminé !
193
  			sendLives();
8e1b403a   pifou   ajout des sources...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
  			status = GAME_NEXTLEVEL;
  		} else if (ch == 'q') {	// quit game
  			status = GAME_EXIT;
  		}
  		break;
  
  	case GAME_OVER:
  		break; // don't do anything
  
  	default:
  
  		if (ch == 'l' || ch == KEY_RIGHT) {	// move player right
  			if (lastmove == 'l') {
  				playerTurboOn();	// enable Turbo
  			} else {
  				playerTurboOff();	// disable Turbo
  			}
  			playerMoveRight();		// move player
  			lastmove = 'l';			// remember last move for turbo mode
  		} else if (ch == 'h' || ch == KEY_LEFT) {	// move player left 
  			if (lastmove == 'h') {
  				playerTurboOn();	// enable Turbo
  			} else {
  				playerTurboOff();	// disable Turbo
  			}
  			playerMoveLeft();		// move player
  			lastmove = 'h';			// remember last move for turbo mode
  		} else if (ch == 'k' || ch == ' ') {	// shoot missile
  			playerLaunchMissile();
  		} else if (ch == 'p') {			// pause game until 'p' pressed again
  			// set status to game paused
  			status = GAME_PAUSED;
  		} else if (ch == 'W') {			// cheat: goto next level
  			status = GAME_NEXTLEVEL;
  		} else if (ch == 'L') {			// cheat: one more live
  			lives++;
0ed3f148   root   terminé !
230
  			sendLives();
8e1b403a   pifou   ajout des sources...
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  			drawscore();
  		} else if (ch == 'q') {	// quit game
  			status = GAME_EXIT;
  		} else {		// disable turbo mode if key is not kept pressed
  			lastmove = ' ';
  		}
  
  	} // switch
  	
  }
  	
  	
  /**
   * timer
   * this method is executed every 1 / FPS seconds  
   */
  void handleTimer()
  {
  	static int aliens_move_counter = 0; 
  	static int aliens_shot_counter = 0;
  	static int player_shot_counter = 0;
  	static int ufo_move_counter = 0;
  	static int title_animation_counter = 0;
  	static int game_over_counter = 0;
  	
  	switch (status) {
  		 
  	case GAME_NEXTLEVEL:    // go to next level
  		
  		level++;	// increase level
  
  		initLevel();	// initialize level
  		
  		aliens_move_counter = 0; 
  		aliens_shot_counter = 0;
  		player_shot_counter = 0;
  		ufo_move_counter = 0;
  		
  		weite = (shipnum+(skill_level*10)-(level*5)+5)/10;
  		
  		if (weite < 0) {
  			weite = 0;
  		}
  		
  		// change status and start game!
  		status = GAME_LOOP;
  
  	case GAME_LOOP:   	 // do game handling
  		
  		// move aliens			
  		if (aliens_move_counter == 0 && aliensMove() == 1) {
  			// aliens reached player
  			lives = 0;
0ed3f148   root   terminé !
284
  			sendLives();
8e1b403a   pifou   ajout des sources...
285
286
287
288
289
290
291
292
293
294
295
296
297
  			status = GAME_OVER;
  		}
  		
  		// move player missile			
  		if (player_shot_counter == 0 && playerMoveMissile() == 1) {
  			// no aliens left
  			status = GAME_NEXTLEVEL;
  		}
  		
  		// move aliens' missiles
  		if (aliens_shot_counter == 0 && aliensMissileMove() == 1) {
  			// player was hit
  			lives--;			// player looses one life
0ed3f148   root   terminé !
298
  			sendLives();
8e1b403a   pifou   ajout des sources...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
  			drawscore();	                // draw score
  			playerExplode();		// display some explosion graphics
  			if (lives == 0) {		// if no lives left ...
  				status = GAME_OVER;		// ... exit game
  			}
  		}
  		
  		// move ufo
  		if (ufo_move_counter == 0 && ufoShowUfo() == 1) {
  			ufoMoveLeft();			// move it one position to the left
  		}
  		
  		
  		if (aliens_shot_counter++ >= 5) {aliens_shot_counter=0;}     // speed of alien shot
  		if (player_shot_counter++ >= 1) {player_shot_counter=0;}     // speed of player shot
  		if (aliens_move_counter++ >= weite) {aliens_move_counter=0;} // speed of aliend
  		if (ufo_move_counter++ >= 3) {ufo_move_counter=0;}           // speed of ufo
  		
  		refreshScreen();
  		break;
  		
  	case GAME_PAUSED:    // game is paused
  		break;
  		
  	case GAME_OVER:      // game over
  		if (game_over_counter == 100) {
  			battleFieldClear();
  			status = GAME_HIGHSCORE;
  			game_over_counter = 0;
  		} else {
  			gameOverDisplay();
  			game_over_counter++;
  		}
  		break;
  		
  	case GAME_EXIT:      // exit game
  		finish(0);
  		break;
  		
  	case GAME_HIGHSCORE: // display highscore
  		if (title_animation_counter == 0) {
  			titleScreenDisplay();
  		}
  
  		if (title_animation_counter++ >= 6) {title_animation_counter = 0;} // speed of animation
  		break;
  		
  	}
  }
  
  
  /**
   * set up timer
   */
  void setUpTimer()
  {
  	struct itimerval myTimer;
  	struct sigaction myAction;
  	myTimer.it_value.tv_sec = 0;
  	myTimer.it_value.tv_usec = 1000000 / FPS;
  	myTimer.it_interval.tv_sec = 0;
  	myTimer.it_interval.tv_usec = 1000000 / FPS;
  	setitimer(ITIMER_REAL, &myTimer, NULL);
  	
  	myAction.sa_handler = &handleTimer;
  	myAction.sa_flags = SA_RESTART;
  	sigaction(SIGALRM, &myAction, NULL);
  }
  
  
9299dd74   root   Programmation nIn...
369
  int go = 1;
0ed3f148   root   terminé !
370
  /*void signalINT(int sig){
9299dd74   root   Programmation nIn...
371
372
373
  	if(sig == SIGINT){
  		go = 0;
  	}
0ed3f148   root   terminé !
374
  }*/
8e1b403a   pifou   ajout des sources...
375
376
  int main(int argc, char **argv)
  {
9299dd74   root   Programmation nIn...
377
378
  	libusb_context *context;
  	libusb_device **devices;
9299dd74   root   Programmation nIn...
379
  	struct libusb_config_descriptor *config_desc;
9299dd74   root   Programmation nIn...
380
381
382
383
384
  
  	// start
  	start(&context, &devices, &handle, &config_desc, endpoint_desc_list);
  
  	// singals
0ed3f148   root   terminé !
385
  	/*struct sigaction action;
9299dd74   root   Programmation nIn...
386
  	action.sa_handler = signalINT;
0ed3f148   root   terminé !
387
  	sigaction(SIGINT, &action, NULL);*/
9299dd74   root   Programmation nIn...
388
      
0ed3f148   root   terminé !
389
390
391
  	// nInvaders
  	weite = 0;
  	score = 0;
8e1b403a   pifou   ajout des sources...
392
  	lives = 3;
0ed3f148   root   terminé !
393
  	sendLives();
8e1b403a   pifou   ajout des sources...
394
395
396
397
398
399
400
401
402
403
404
405
406
  	level = 0;
  	skill_level = 1;
  
  	evaluateCommandLine(argc, argv);	// evaluate command line parameters
  	graphicEngineInit();			// initialize graphic engine
  	
  	// set up timer/ game handling
  	setUpTimer();		
  	status = GAME_HIGHSCORE;
  
  	// read keyboard input
  	do {
  		// do movements and key-checking
0ed3f148   root   terminé !
407
  		readInput(handle, endpoint_desc_list);
9299dd74   root   Programmation nIn...
408
409
410
411
  	} while (go);
  
  	// stop
  	stop(config_desc, handle, devices, context);
8e1b403a   pifou   ajout des sources...
412
413
414
415
416
417
418
419
420
421
422
423
424
425
  	
  	return 0;
  }
  
  
  void doScoring(int alienType)
  {
  	int points[4] = {500, 200, 150, 100};   	// 0: ufo, 1:red, 2:green, 3:blue
  	
  	score += points[alienType];		// every alien type does different scoring points
  	
  	// every 6000 pts player gets a new live
  	if (score % 6000 == 0){
  		lives++;
0ed3f148   root   terminé !
426
  		sendLives();
8e1b403a   pifou   ajout des sources...
427
428
429
430
  	}
  	
  	drawscore();	// display score
  }