docs
[mirrors/Programs.git] / c / ninvaders-0.1.1 / view.c
CommitLineData
21c4e167
H
1/**
2 * nInvaders - a space invaders clone for ncurses
3 * Copyright (C) 2002-2003 Dettus
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * homepage: http://ninvaders.sourceforge.net
20 * mailto: ninvaders-devel@lists.sourceforge.net
21 *
22 */
23
24
25#include "view.h"
26#include "globals.h"
27#include <stdlib.h>
28#include <unistd.h>
29#include <signal.h>
30
31#define RED 1
32#define GREEN 2
33#define YELLOW 3
34#define BLUE 4
35#define CYAN 5
36#define MAGENTA 6
37#define WHITE 7
38
39WINDOW *wBattleField;
40WINDOW *wEmpty;
41WINDOW *wScores;
42
43WINDOW *wPlayer;
44WINDOW *wPlayerMissile;
45WINDOW *wAliens;
46WINDOW *wAliensMissile;
47WINDOW *wBunkers;
48WINDOW *wGameOver;
49WINDOW *wUfo;
50WINDOW *wStatus;
51WINDOW *wTitleScreen;
52
53/**
54 * initialize player sprites
55 */
56static void playerInit()
57{
58 wPlayer = newpad(1, PLAYERWIDTH); // new pad with appropriate size
59 wclear(wPlayer); // clear pad
60 wattrset(wPlayer,COLOR_PAIR(YELLOW)); // set color
61 waddstr(wPlayer,"/-^-\\"); // set sprite
62}
63
64
65/**
66 * display player sprite
67 */
68void playerDisplay(int x, int y)
69{
70 copywin(wPlayer,wBattleField,0,0,y,x,y,x+PLAYERWIDTH-1,0);
71}
72
73
74/**
75 * clear player sprite
76 */
77void playerClear(int x, int y)
78{
79 copywin(wEmpty,wBattleField,0,0,y,x,y,x+PLAYERWIDTH-1,0);
80}
81
82
83/**
84 * initialize missile sprites
85 */
86static void playerMissileInit()
87{
88 wPlayerMissile = newpad(1, 1); // new pad with appropriate size
89 wclear(wPlayerMissile); // clear pad
90 wattrset(wPlayerMissile,COLOR_PAIR(WHITE)); // set color
91 waddch(wPlayerMissile,'!'); // set sprite
92 wrefresh(wPlayerMissile);
93}
94
95
96/**
97 * display missile sprite
98 */
99void playerMissileDisplay(int x, int y)
100{
101 copywin(wPlayerMissile,wBattleField,0,0,y,x,y,x,0);
102}
103
104
105/**
106 * clear missile sprite
107 */
108void playerMissileClear(int x, int y)
109{
110 copywin(wEmpty,wBattleField,0,0,y,x,y,x,0);
111}
112
113
114/**
115 * some explosion animation
116 */
117void playerExplosionDisplay(int x, int y)
118{
119 WINDOW* wPlayerExplosion;
120 char playerExplosionChars[16+1]="@~`.,^#*-_=\\/%{}";
121 int t,s;
122
123 wPlayerExplosion=newpad(1,PLAYERWIDTH); // new pad
124 wattrset(wPlayerExplosion,COLOR_PAIR(YELLOW)); // set color
125
126 for(t=0;t<5;t++){ // 5 frames
127 wclear(wPlayerExplosion); // clear pad
128 for(s=0;s<PLAYERWIDTH;s++){
129 waddch(wPlayerExplosion,playerExplosionChars[rand()%16]); // sprite
130 }
131
132 copywin(wPlayerExplosion,wBattleField,0,0,y,x,y,x+PLAYERWIDTH-1,0); // display explostion
133 wrefresh(wBattleField); // refresh battelfield to display explosion frames
134 doSleep(100000); // play animation not too fast
135 }
136
137
138} // todo: kann man bestimmt noch besser machen.
139
140
141/**
142 * initialize aliens sprites
143 */
144static void aliensInit()
145{
146 wAliens = newpad(ALIENS_MAX_NUMBER_Y*2,ALIENS_MAX_NUMBER_X*3);
147 wclear(wAliens);
148}
149
150
151/**
152 * display aliens sprite
153 */
154void aliensDisplay(int x, int y, int wid, int hgt)
155{
156 copywin(wAliens,wBattleField,0,0,y,x,y+hgt,x+wid+2,0);
157}
158
159
160/**
161 * clear aliens sprite
162 */
163void aliensClear(int x, int y, int wid, int hgt)
164{
165 copywin(wEmpty,wBattleField,0,0,y,x,y+hgt,x+wid+2,0);
166}
167
168
169/**
170 * initialize missile sprites
171 */
172static void aliensMissileInit()
173{
174 wAliensMissile = newpad(1, 1); // new pad
175 wclear(wAliensMissile); // clear pad
176 wattrset(wAliensMissile, COLOR_PAIR(CYAN)); // set color
177 waddch(wAliensMissile, ':'); // set sprite
178}
179
180
181/**
182 * display missile sprite
183 */
184void aliensMissileDisplay(int x, int y)
185{
186 copywin(wAliensMissile,wBattleField,0,0,y,x,y,x,0);
187}
188
189
190/**
191 * clear missile sprite
192 */
193void aliensMissileClear(int x, int y)
194{
195 copywin(wEmpty,wBattleField,0,0,y,x,y,x,0);
196}
197
198
199/**
200 * refresh aliens sprite
201 */
202void aliensRefresh(int level, int *pAliens)
203{
204 static int frame = 0; // used for animation; mod 2 == 0: frame1, mod2 == 1: frame2
205 int k,row;
206 int c = 0;
207 int alienType = 0;
208 char ships[2][9][3+1] = {
209 {",^,", "_O-", "-o-", "o=o", "<O>", "_x_", "*^*", "\\_/", "o o"},
210 {".-.", "-O_", "/o\\", "o-o", "<o>", "-x-", "o^o", "/~\\", "oo "}
211 };
212 int colors[9] = {RED, GREEN, BLUE, RED, YELLOW, WHITE, WHITE, YELLOW, RED};
213
214 wclear(wAliens); // clear pad
215 wattrset(wAliens,COLOR_PAIR(RED)); // set color
216
217 frame++; // next frame
218
219 // draw alien if there is one
220 for (row = 0; row < ALIENS_MAX_NUMBER_Y*2; row++) {
221 for (k = 0; k < ALIENS_MAX_NUMBER_X; k++) {
222 if ((row % 2) == 0) { // display aliens every even row
223 alienType = *(pAliens + c * (ALIENS_MAX_NUMBER_X) + k); // get type of alien //alienBlock[c][k]
224
225 if (alienType != 0) { // if there is an alien to display
226 wattrset(wAliens,COLOR_PAIR(colors[alienType-1])); // set color
227 waddch(wAliens,ships[frame%2][alienType-1+(3*((level-1)%3))][0]); // set char1
228 waddch(wAliens,ships[frame%2][alienType-1+(3*((level-1)%3))][1]); // set char2
229 waddch(wAliens,ships[frame%2][alienType-1+(3*((level-1)%3))][2]); // set char3
230 if (alienType > 4) {
231 *(pAliens + c * ALIENS_MAX_NUMBER_X + k) = (alienType + 1) % 9;
232 } // todo: what's that? If alien_type > 4 then do a modulo operation???
233 } else {
234 waddstr(wAliens," "); // no alien
235 }
236
237 } else {
238 waddstr(wAliens," "); // no aliens at odd rows
239 }
240 }
241 if ((row % 2) == 1) {c++;} // goto next row at alienblock
242 }
243}
244
245
246/**
247 * initialize bunkers sprites
248 */
249static void bunkersInit()
250{
251 wBunkers = newpad(BUNKERHEIGHT, BUNKERWIDTH); // new pad data
252 wclear(wBunkers);
253}
254
255
256/**
257 * display bunkers sprite
258 * needs pointer to bunker-array
259 */
260void bunkersDisplay(int *pBunker)
261{
262 int l, k;
263 wclear(wBunkers);
264 wattrset(wBunkers,COLOR_PAIR(CYAN));
265 for (l=0;l<BUNKERHEIGHT;l++) {
266 for (k=0;k<BUNKERWIDTH;k++) {
267 if (*(pBunker + (l * (BUNKERWIDTH + 1)) + k) == 1) { //if (pBunker[l][k]==1) {
268 waddch(wBunkers,'#');
269 } else {
270 waddch(wBunkers,' ');
271 }
272 }
273 }
274
275 copywin(wBunkers, wBattleField, 0, 0, BUNKERY, BUNKERX, BUNKERY + BUNKERHEIGHT - 1, BUNKERX + BUNKERWIDTH - 1, 0);
276}
277
278
279/**
280 * clear bunkers sprite
281 */
282void bunkersClear()
283{
284 copywin(wEmpty, wBattleField, 0, 0, BUNKERY, BUNKERX, BUNKERY + BUNKERHEIGHT - 1, BUNKERX + BUNKERWIDTH - 1, 0);
285}
286
287
288/**
289 * clear one element of bunkers sprite at position (x, y)
290 */
291void bunkersClearElement(int x, int y)
292{
293 copywin(wEmpty, wBattleField, 0, 0, y, x, y, x, 0);
294}
295
296
297/**
298 * set actual sprite for ufo animation
299 */
300void ufoRefresh()
301{
302 char ufo[4][6] = {"<o o>", "<oo >", "<o o>", "< oo>"};
303 static int frame = 0;
304
305 wclear(wUfo);
306 wattrset(wUfo, COLOR_PAIR(MAGENTA));
307 waddstr(wUfo, ufo[frame % 4]);
308
309 frame++;
310}
311
312
313/**
314 * initialize ufo sprite
315 */
316static void ufoInit()
317{
318 wUfo = newpad(1, UFOWIDTH); // new pad with appropriate size
319 wclear(wUfo); // clear pad
320 wattrset(wUfo, COLOR_PAIR(MAGENTA)); // set color
321}
322
323
324/**
325 * display ufo sprite
326 */
327void ufoDisplay(int x, int y)
328{
329 copywin(wUfo, wBattleField, 0, 0, y, x, y, x + UFOWIDTH - 1, 0);
330}
331
332
333/**
334 * clear ufo sprite
335 */
336void ufoClear(int x, int y)
337{
338 copywin(wEmpty, wBattleField, 0, 0, y, x, y, x + UFOWIDTH - 1, 0);
339}
340
341
342/**
343 * initialize gameover graphic
344 */
345static void gameOverInit()
346{
347 // init game-over banner
348 wGameOver = newpad(13, 31);
349 wclear(wGameOver);
350 wattrset(wGameOver, COLOR_PAIR(WHITE));
351 waddstr(wGameOver, " ");
352 waddstr(wGameOver, " ##### #### ## ## ###### ");
353 waddstr(wGameOver, " ## ## ## ####### ## ");
354 waddstr(wGameOver, " ## ### ###### ## # ## ##### ");
355 waddstr(wGameOver, " ## ## ## ## ## ## ## ");
356 waddstr(wGameOver, " ##### ## ## ## ## ###### ");
357 waddstr(wGameOver, " ");
358 waddstr(wGameOver, " #### ## ## ###### ###### ");
359 waddstr(wGameOver, " ## ## ## ## ## ## ## ");
360 waddstr(wGameOver, " ## ## ## ## ##### ###### ");
361 waddstr(wGameOver, " ## ## ## ## ## ## ## ");
362 waddstr(wGameOver, " #### ### ###### ## ## ");
363 waddstr(wGameOver, " ");
364}
365
366/**
367 * display game over graphic
368 */
369void gameOverDisplay()
370{
371 int x = (SCREENWIDTH / 2) - (31 / 2);
372 int y = (SCREENHEIGHT / 2) - (13 / 2);
373 copywin(wGameOver, wBattleField, 0, 0, y, x, y + 12, x + 30, 0);
374 wrefresh(wBattleField);
375}
376
377
378/**
379 * initialize title screen
380 */
381static void titleScreenInit()
382{
383 wTitleScreen = newpad(SCREENHEIGHT, SCREENWIDTH);
384 wclear(wTitleScreen);
385}
386
387
388/**
389 * display title screen
390 */
391void titleScreenDisplay()
392{
393 static int frame = 0;
394 int x, y;
395 int i;
396 WINDOW *wTitleText;
397 WINDOW *wAliens;
398 WINDOW *wStartText;
399 char ufo[4][6] = {"<o o>", "<oo >", "<o o>", "< oo>"};
400 char aliens[2][9][3+1] = {
401 {",^,", "_O-", "-o-", "o=o", "<O>", "_x_", "*^*", "\\_/", "o o"},
402 {".-.", "-O_", "/o\\", "o-o", "<o>", "-x-", "o^o", "/~\\", "oo "}
403 };
404 int score[3] = {200, 150, 100};
405 int colors[9] = {RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE};
406 char buffer[12];
407 static int alien_type = 0;
408
409 wTitleText = newpad(4, 41);
410 wclear(wTitleText);
411 wattrset(wTitleText, COLOR_PAIR(YELLOW));
412 waddstr(wTitleText, " ____ __ ");
413 waddstr(wTitleText, " ___ / _/__ _ _____ ___/ /__ _______");
414 waddstr(wTitleText, " / _ \\_/ // _ \\ |/ / _ `/ _ / -_) __(_-<");
415 waddstr(wTitleText, "/_//_/___/_//_/___/\\_,_/\\_,_/\\__/_/ /___/");
416
417 frame++;
418 wAliens = newpad(7, 11);
419 wclear(wAliens);
420 snprintf(buffer, sizeof(buffer),"%s = 500", ufo[frame % 4]);
421 wattrset(wAliens, COLOR_PAIR(MAGENTA));
422 waddstr(wAliens, buffer);
423 if ((frame = frame % 60) == 0) {
424 alien_type = 0;
425 } else if (frame == 20) {
426 alien_type = 3;
427 } else if (frame == 40) {
428 alien_type = 6;
429 }
430 for (i = alien_type; i < alien_type + 3; i++) {
431 waddstr(wAliens, " ");
432 snprintf(buffer, sizeof(buffer), "%s = %d", aliens[frame % 2][i], score[i % 3]);
433 wattrset(wAliens, COLOR_PAIR(colors[i]));
434 waddstr(wAliens, buffer);
435 }
436
437 wStartText = newpad(1, 20);
438 wclear(wStartText);
439 wattrset(wStartText, COLOR_PAIR(RED));
440 waddstr(wStartText, "Press SPACE to start");
441
442 x = (SCREENWIDTH / 2) - (41 / 2);
443 y = 0;
444 copywin(wTitleText, wTitleScreen, 0, 0, y, x, y + 3, x + 40, 0);
445
446 x = (SCREENWIDTH / 2) - (11 / 2);
447 y = 8;
448 copywin(wAliens, wTitleScreen, 0, 0, y, x , y + 6, x + 10, 0);
449
450 x = (SCREENWIDTH / 2) - (20 / 2);
451 y = SCREENHEIGHT - 2;
452 copywin(wStartText, wTitleScreen, 0, 0, y, x, y, x + 19, 0);
453
454 copywin(wTitleScreen, wBattleField, 0, 0, 0, 0, SCREENHEIGHT-1, SCREENWIDTH-1, 0);
455
456 wrefresh(wBattleField);
457}
458
459
460/**
461 * clear title screen
462 */
463void titleScreenClear()
464{
465 battleFieldClear();
466}
467
468
469/**
470 * initialize scores
471 */
472void statusInit()
473{
474 wStatus = newpad(1, 55);
475 wclear(wStatus);
476}
477
478
479/**
480 * display scores
481 */
482void statusDisplay(int level, int score, int lives)
483{
484 int t, xOffset;
485 char strStatus[55];
486 // "Level: 01 Score: 0001450 Lives: /-\ /-\ /-\ /-\ /-\ "
487 // "1234567890123456789012345678901234567890123456789012"
488
489
490 xOffset = (SCREENWIDTH / 2) - 24;
491
492
493
494 sprintf (strStatus, "Level: %2.2d Score: %2.7d Lives: ", level, score);
495
496 wclear(wStatus);
497 wattrset(wStatus, COLOR_PAIR(RED));
498 waddstr(wStatus, strStatus);
499
500 // show maximal five lives
501 for (t = 1; ((t <= 5) && (t < lives)); t++){
502 waddstr(wStatus, "/-\\ ");
503 }
504
505 copywin(wStatus, wBattleField, 0, 0, SCREENHEIGHT-1, xOffset, SCREENHEIGHT-1, xOffset + 54, 0);
506
507
508}
509
510
511/**
512 * initialize battlefield
513 */
514static void battleFieldInit()
515{
516 wEmpty = newpad(SCREENHEIGHT, SCREENWIDTH);
517 wclear(wEmpty);
518
519 wBattleField = newwin(SCREENHEIGHT, SCREENWIDTH, 0, 0); // new window
520 wclear(wBattleField); // clear window
521 mvwin(wBattleField, 0, 0); // move window
522}
523
524
525/**
526 * clear battlefield
527 */
528void battleFieldClear()
529{
530 copywin(wEmpty,wBattleField,0,0,0,0,SCREENHEIGHT-1,SCREENWIDTH-1,0);
531}
532
533
534/**
535 * refresh screen so that modified graphic buffers get visible
536 */
537void refreshScreen()
538{
539 redrawwin(wBattleField); // needed to display graphics properly at startup on some terminals
540 wrefresh(wBattleField);
541
542}
543
544
545/**
546 * do proper cleanup
547 */
548static void finish(int sig)
549{
550 endwin(); // <curses.h> reset terminal into proper non-visual mode
551 exit(0);
552}
553
554
555/**
556 * initialize n_courses
557 */
558void graphicEngineInit()
559{
560 (void) signal(SIGINT, finish); // <signal.h> on signal "SIGINT" call method "finish"
561 (void) initscr(); // <curses.h> do initialization work
562 keypad(stdscr, TRUE); // <curses.h> enable keypad for input
563 (void) nonl(); // <curses.h> disable translation return/ newline for detection of return key
564 (void) cbreak(); // <curses.h> do not buffer typed characters, use at once
565 (void) noecho(); // <curses.h> do not echo typed characters
566 start_color(); // <curses.h> use colors
567 init_pair(RED, COLOR_RED, COLOR_BLACK); // <curses.h> define color-pair
568 init_pair(GREEN, COLOR_GREEN, COLOR_BLACK); // <curses.h> define color-pair
569 init_pair(YELLOW, COLOR_YELLOW, COLOR_BLACK); // <curses.h> define color-pair
570 init_pair(BLUE, COLOR_BLUE, COLOR_BLACK); // <curses.h> define color-pair
571 init_pair(CYAN, COLOR_CYAN, COLOR_BLACK); // <curses.h> define color-pair
572 init_pair(MAGENTA, COLOR_MAGENTA, COLOR_BLACK); // <curses.h> define color-pair
573 init_pair(WHITE, COLOR_WHITE, COLOR_BLACK); // <curses.h> define color-pair
574
575 //timeout(0); // <curses.h> do not wait for input
576
577 // initialize sprites
578 battleFieldInit();
579 playerInit();
580 playerMissileInit();
581 aliensInit();
582 aliensMissileInit();
583 bunkersInit();
584 ufoInit();
585 gameOverInit();
586 statusInit();
587 titleScreenInit();
588}
589
This page took 0.756404 seconds and 4 git commands to generate.