1 /* game.c - play the game
2 *
3 * Copyright 1999, 2000 Jochen Voss */
4
5 static const char rcsid[] = "$Id: game.c 4839 2003-04-13 16:50:02Z voss $";
6
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <signal.h>
12
13 #include "moon-buggy.h"
14
15
16 struct mode *game_mode;
17 struct mode *crash_mode;
18
19
20 int crash_detected; /* a crash is in progress */
21 static int level; /* the current level (crash_mode only) */
22 static int lives; /* cars left (including the current one) */
23 static int score; /* points we already got */
24 int stakes; /* points to get, when we reach the ground */
25
26
27 void
adjust_score(int val)28 adjust_score (int val)
29 /* Add VAL to the score and display the result. */
30 {
31 if (crash_detected) return;
32 score += val;
33 mvwprintw (status, 0, car_base-7, "score: %-8d", score);
34 wnoutrefresh (status);
35 }
36
37 void
print_lives(void)38 print_lives (void)
39 {
40 mvwprintw (status, 0, car_base-20, "lives: %d", lives);
41 wnoutrefresh (status);
42 }
43
44 /**********************************************************************
45 * game mode
46 */
47
48 void
print_game_over(int blink)49 print_game_over (int blink)
50 {
51 #ifdef A_BLINK
52 if (blink) wattron (moon, A_BLINK);
53 #endif
54 mvwaddstr (moon, LINES-11, car_base-1, "GAME OVER");
55 #ifdef A_BLINK
56 if (blink) wattroff (moon, A_BLINK);
57 #endif
58 wnoutrefresh (moon);
59 }
60
61 static void
game_enter(int seed)62 game_enter (int seed)
63 {
64 clock_reset ();
65
66 if (seed == 0) {
67 level = 0;
68 score = 0;
69 lives = 3;
70 werase (status);
71 wnoutrefresh (status);
72 }
73
74 resize_ground (1);
75 level_start (level);
76
77 crash_detected = 0;
78 stakes = 0;
79 initialise_buggy ();
80 start_scrolling (1);
81 }
82
83 static void
game_leave(void)84 game_leave (void)
85 {
86 --lives;
87 level = current_level ();
88 extinguish_laser ();
89 remove_meteors ();
90 }
91
92 static void
game_redraw(void)93 game_redraw (void)
94 {
95 resize_meteors ();
96 resize_laser ();
97 resize_ground (0);
98
99 print_ground ();
100 adjust_score (0);
101 print_lives ();
102 print_buggy ();
103 }
104
105 static void
key_handler(game_time t,int val)106 key_handler (game_time t, int val)
107 {
108 switch (val) {
109 case 1:
110 if (! crash_detected && can_jump()) jump (t);
111 break;
112 case 2:
113 if (! crash_detected) fire_laser (t);
114 break;
115 case 3:
116 lives = 1;
117 print_message ("aborted at user's request");
118 mode_change (crash_mode, 0);
119 break;
120 }
121 }
122
123 static void
signal_handler(int signum)124 signal_handler (int signum)
125 {
126 switch (signum) {
127 case SIGTSTP:
128 if (lives > 1) lives = 1;
129 if (! crash_detected) crash_detected = 1;
130 print_message ("GAME OVER (suspended)");
131 break;
132 case SIGCONT:
133 print_message ("GAME OVER (suspended)");
134 break;
135 }
136 }
137
138 /**********************************************************************
139 * crash mode
140 */
141
142 static int lives_flag;
143
144 static void
leave_crash_mode(game_time t,void * client_data)145 leave_crash_mode (game_time t, void *client_data)
146 /* This function is a possible callback argument to `add_event'.
147 * It switch control back to either `game_mode' or `highscore_mode'.
148 * The arguments T and CLIENT_DATA are ignored. */
149 {
150 if (lives > 0) {
151 mode_change (game_mode, 1);
152 } else {
153 score_set (score, level+1);
154 mode_change (highscore_mode, 0);
155 }
156 }
157
158 static void
print_lives_h(game_time t,void * client_data)159 print_lives_h (game_time t, void *client_data)
160 /* This function is a callback argument to `add_event'.
161 * It updates the number of lives display. */
162 {
163 print_lives ();
164 lives_flag = 1;
165 }
166
167 static void
crash_enter(int seed)168 crash_enter (int seed)
169 {
170 clock_reset ();
171 lives_flag = 0;
172 add_event (1.2, print_lives_h, NULL);
173 add_event (2.0, leave_crash_mode, NULL);
174 print_buggy ();
175 if (lives <= 0) print_game_over (1);
176 }
177
178 static void
crash_redraw(void)179 crash_redraw (void)
180 {
181 resize_ground (0);
182
183 print_ground ();
184 print_buggy ();
185 adjust_score (0);
186 if (lives_flag) print_lives ();
187 }
188
189 static void
crash_key_handler(game_time t,int val)190 crash_key_handler (game_time t, int val)
191 {
192 if (t < 0.5) return;
193
194 switch (val) {
195 case 1:
196 leave_crash_mode (0, NULL);
197 break;
198 case 3:
199 lives = 0;
200 leave_crash_mode (0, NULL);
201 break;
202 }
203 }
204
205 void
setup_game_mode(void)206 setup_game_mode (void)
207 {
208 game_mode = new_mode ();
209 game_mode->enter = game_enter;
210 game_mode->leave = game_leave;
211 game_mode->redraw = game_redraw;
212 game_mode->keypress = key_handler;
213 game_mode->signal = signal_handler;
214 mode_add_key (game_mode, mbk_jump, "jump", 1);
215 mode_add_key (game_mode, mbk_fire, "fire", 2);
216 mode_add_key (game_mode, mbk_end, "abort game", 3);
217 mode_complete (game_mode);
218
219 crash_mode = new_mode ();
220 crash_mode->enter = crash_enter;
221 crash_mode->redraw = crash_redraw;
222 crash_mode->keypress = crash_key_handler;
223 mode_add_key (crash_mode, mbk_start, "continue", 1);
224 mode_add_key (crash_mode, mbk_end, "abort game", 3);
225 mode_complete (crash_mode);
226 }
227