Blame view

games/ninvaders/nInvaders.c 9.67 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
  
  	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;
ced5f74a   root   sauvegarde avant ...
170
171
  			else if((data & 0x02) == 0x02) ch = KEY_RIGHT;
  			else if((data & 0x04) == 0x04) ch = ' ';
0ed3f148   root   terminé !
172
  			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
  			status = GAME_NEXTLEVEL;
ced5f74a   root   sauvegarde avant ...
195
196
197
  		} else if (ch == 'q') {	// quit
              lives = 0;
              sendLives(0);
8e1b403a   pifou   ajout des sources...
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
230
231
  			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é !
232
  			sendLives();
8e1b403a   pifou   ajout des sources...
233
234
  			drawscore();
  		} else if (ch == 'q') {	// quit game
ced5f74a   root   sauvegarde avant ...
235
236
              lives = 0;
              sendLives();
8e1b403a   pifou   ajout des sources...
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
284
285
286
287
  			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é !
288
  			sendLives();
8e1b403a   pifou   ajout des sources...
289
290
291
292
293
294
295
296
297
298
299
300
301
  			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é !
302
  			sendLives();
8e1b403a   pifou   ajout des sources...
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
369
370
371
372
  			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...
373
  int go = 1;
0ed3f148   root   terminé !
374
  /*void signalINT(int sig){
9299dd74   root   Programmation nIn...
375
376
377
  	if(sig == SIGINT){
  		go = 0;
  	}
0ed3f148   root   terminé !
378
  }*/
8e1b403a   pifou   ajout des sources...
379
380
  int main(int argc, char **argv)
  {
9299dd74   root   Programmation nIn...
381
382
  	libusb_context *context;
  	libusb_device **devices;
9299dd74   root   Programmation nIn...
383
  	struct libusb_config_descriptor *config_desc;
9299dd74   root   Programmation nIn...
384
385
386
387
388
  
  	// start
  	start(&context, &devices, &handle, &config_desc, endpoint_desc_list);
  
  	// singals
0ed3f148   root   terminé !
389
  	/*struct sigaction action;
9299dd74   root   Programmation nIn...
390
  	action.sa_handler = signalINT;
0ed3f148   root   terminé !
391
  	sigaction(SIGINT, &action, NULL);*/
9299dd74   root   Programmation nIn...
392
      
0ed3f148   root   terminé !
393
394
395
  	// nInvaders
  	weite = 0;
  	score = 0;
8e1b403a   pifou   ajout des sources...
396
  	lives = 3;
0ed3f148   root   terminé !
397
  	sendLives();
8e1b403a   pifou   ajout des sources...
398
399
400
401
402
403
404
405
406
407
408
409
410
  	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é !
411
  		readInput(handle, endpoint_desc_list);
9299dd74   root   Programmation nIn...
412
413
414
415
  	} while (go);
  
  	// stop
  	stop(config_desc, handle, devices, context);
8e1b403a   pifou   ajout des sources...
416
417
418
419
420
421
422
423
424
425
426
427
428
429
  	
  	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é !
430
  		sendLives();
8e1b403a   pifou   ajout des sources...
431
432
433
434
  	}
  	
  	drawscore();	// display score
  }