Fixes for datatype size on amd64.
[crack-attack.git] / src / Game.h
blob6cd7bb48409dc9db2efd85ac14a4ad6007cc2e8b
1 /*
2 * Game.h
3 * Daniel Nelson - 8/24/0
5 * Copyright (C) 2000 Daniel Nelson
6 * Copyright (C) 2004 Andrew Sayman
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * Daniel Nelson - aluminumangel.org
23 * 174 W. 18th Ave.
24 * Columbus, OH 43210
27 #ifndef GAME_H
28 #define GAME_H
30 #include <iostream>
31 #include <vector>
32 #include <string>
33 #include <map>
34 //#include <climits>
35 //#include <cstdlib>
36 #include <cmath>
38 #ifdef __MINGW32__
39 # include <windows.h>
40 #endif
42 #include <GL/gl.h>
43 #include <GL/glut.h>
44 #include "glext.h"
46 #ifdef HAVE_CONFIG_H
47 # undef BR_PTHREAD
48 # include "config.h"
49 #endif
51 #include "Mode.h"
53 // null
54 #define null (0)
56 // no IEEE super pi
57 #define PI (3.14159265358979323846f)
58 #define SQRT_3 (1.73205080756887729352f)
60 // the name
61 #define GC_NAME "Crack Attack!"
62 #define GC_BINARY "crack-attack"
63 #define GC_VERSION "1.1.15-cvs"
65 // startup message
66 #define GC_MESSAGE GC_NAME " v" GC_VERSION "\n"
68 // directory delimiter
69 #ifndef _WIN32
70 # define GC_DD "/"
71 #else
72 # define GC_DD "\\"
73 #endif
75 // file constants
76 #ifndef _WIN32
77 # ifndef DATA_DIRECTORY
78 # define GC_DATA_DIRECTORY(x) "." GC_DD "data/" x
79 # define GC_MODEL_DIRECTORY(x) "." GC_DD "data/" x
80 # else
81 # define GC_DATA_DIRECTORY(x) DATA_DIRECTORY x
82 # define GC_MODEL_DIRECTORY(x) DATA_DIRECTORY x
83 # endif
84 # define GC_LOCAL_DATA_DIRECTORY GC_DD "." GC_BINARY GC_DD
85 # define GC_BINARY_LOCATION BINARY_DIRECTORY GC_DD GC_BINARY
86 #else
87 # define GC_DATA_DIRECTORY(x) ".." GC_DD "data" GC_DD x
88 # define GC_MODEL_DIRECTORY(x) ".." GC_DD "data" GC_DD x
89 # define GC_LOCAL_DATA_DIRECTORY ".." GC_DD "localdata" GC_DD
90 # define GC_BINARY_LOCATION GC_BINARY
91 #endif
92 #ifdef ENABLE_BINRELOC
93 # undef GC_DATA_DIRECTORY
94 # undef GC_BINARY_LOCATION
95 # undef GC_MODEL_DIRECTORY
96 # include "prefix.h"
97 # define GC_DATA_DIRECTORY_INTER br_strcat(DATADIR, GC_DD GC_BINARY GC_DD)
98 # define GC_MODEL_DIRECTORY_INTER br_strcat(DATADIR, GC_DD GC_BINARY GC_DD)
99 # define GC_DATA_DIRECTORY(x) br_strcat(GC_DATA_DIRECTORY_INTER, x)
100 # define GC_MODEL_DIRECTORY(x) br_strcat(GC_MODEL_DIRECTORY_INTER, x)
101 # define GC_BINARY_LOCATION br_strcat(BINDIR, GC_DD GC_BINARY)
102 #endif
103 #define GC_GARBAGE_TEX_FILE_NAME_BASE "garbage_flavor"
104 #define GC_GARBAGE_TEX_NUMBER_DIGITS (3)
105 #define GC_NUMBER_STANDARD_GARBAGE_TEX (6)
106 #define GC_GARBAGE_TEX_MAX_NUMBER (1000)
107 #define GC_GARBAGE_NET_TEX_FILE_NAME GC_GARBAGE_TEX_FILE_NAME_BASE \
108 "_net.png"
109 #define GC_GARBAGE_MY_TEX_FILE_NAME GC_GARBAGE_TEX_FILE_NAME_BASE \
110 "_my.png"
111 #define GC_LOGO_TEX_FILE_NAME GC_DATA_DIRECTORY("logo.png")
112 #define GC_X_LOGO_TEX_FILE_NAME GC_DATA_DIRECTORY("logo_x.png")
113 #define GC_GARBAGE_LOGO_TEX_FILE_NAME GC_DATA_DIRECTORY(\
114 GC_GARBAGE_TEX_FILE_NAME_BASE \
115 "_logo.png")
116 #define GC_GARBAGE_X_LOGO_TEX_FILE_NAME GC_DATA_DIRECTORY(\
117 GC_GARBAGE_TEX_FILE_NAME_BASE \
118 "_logo_x.png")
119 #define GC_COUNT_DOWN_GO_TEX_FILE_NAME GC_DATA_DIRECTORY("count_down_go.png")
120 #define GC_COUNT_DOWN_1_TEX_FILE_NAME GC_DATA_DIRECTORY("count_down_1.png")
121 #define GC_COUNT_DOWN_2_TEX_FILE_NAME GC_DATA_DIRECTORY("count_down_2.png")
122 #define GC_COUNT_DOWN_3_TEX_FILE_NAME GC_DATA_DIRECTORY("count_down_3.png")
123 #define GC_ANYKEY_TEX_FILE_NAME GC_DATA_DIRECTORY("message_anykey.png")
124 #define GC_WAITING_TEX_FILE_NAME GC_DATA_DIRECTORY("message_waiting.png")
125 #define GC_PAUSED_TEX_FILE_NAME GC_DATA_DIRECTORY("message_paused.png")
126 #define GC_WINNER_TEX_FILE_NAME GC_DATA_DIRECTORY("message_winner.png")
127 #define GC_LOSER_TEX_FILE_NAME GC_DATA_DIRECTORY("message_loser.png")
128 #define GC_GAME_OVER_TEX_FILE_NAME GC_DATA_DIRECTORY(\
129 "message_game_over.png")
130 #define GC_X_REC_FILE_NAME "score_record_x"
131 #define GC_REC_FILE_NAME "score_record"
132 #define GC_MULT_FILE_NAME "multiplier_record"
133 #define GC_DEFAULT_REC_FILE_NAME GC_DATA_DIRECTORY("default_record")
134 #define GC_DEFAULT_MULT_FILE_NAME GC_DATA_DIRECTORY("default_multiplier")
136 // random angle tables' size; must be power of two
137 #define GC_SIZE_RANDOM_ANGLE_TABLE (256)
139 // games per match
140 #define GC_GAMES_PER_MATCH (3)
142 // the play area dimensions; GC_SAFE_HEIGHT - 1 is the board height
143 #define GC_PLAY_WIDTH (6)
144 #define GC_PLAY_HEIGHT (45)
145 #define GC_SAFE_HEIGHT (13)
146 #define GC_GRID_SIZE (GC_PLAY_WIDTH * GC_PLAY_HEIGHT)
148 // object stores
149 #define GC_BLOCK_STORE_SIZE (GC_GRID_SIZE)
150 #define GC_GARBAGE_STORE_SIZE (2 * GC_PLAY_HEIGHT)
151 #define GC_COMBO_TABULATOR_STORE_SIZE (8)
152 #define GC_GARBAGE_QUEUE_SIZE (8)
154 // time steps per second
155 #define GC_STEPS_PER_SECOND (50)
157 // milliseconds per time step
158 #define GC_TIME_STEP_PERIOD (1000 / GC_STEPS_PER_SECOND)
160 // number of subdivisions per grid location
161 #define GC_STEPS_PER_GRID (60)
163 // names
164 #define GC_PLAYER_NAME_LENGTH (256)
165 #define GC_DEFAULT_PLAYER_NAME "NamelessOne"
167 // velocity of falling; must be a factor of GC_STEPS_PER_GRID
168 #define GC_FALL_VELOCITY (20)
170 // velocity and time length of swapping
171 #define GC_SWAP_VELOCITY (10)
172 #define GC_SWAP_DELAY (GC_STEPS_PER_GRID / GC_SWAP_VELOCITY)
174 // velocity of creep
175 #define GC_CREEP_DELAY (1200)
176 #define GC_CREEP_ADVANCE_TIMER_STEP GC_CREEP_DELAY
177 #define GC_CREEP_TIMER_STEP_INCREMENT (20)
178 #define GC_CREEP_INITIAL_TIMER_STEP GC_CREEP_TIMER_STEP_INCREMENT
179 #define GC_CREEP_MAX_TIMER_STEP (2400)
180 #define GC_CREEP_ADVANCE_VELOCITY (3)
181 #define GC_CREEP_INCREMENT_DELAY (10 * GC_STEPS_PER_SECOND)
183 // delay between safe height violation and loss
184 #define GC_LOSS_DELAY (7 * GC_STEPS_PER_SECOND)
185 #define GC_LOSS_DELAY_ELIMINATION (1 * GC_STEPS_PER_SECOND)
187 // time length between moves
188 #define GC_MOVE_DELAY (6)
190 // time length of block dying
191 #define GC_DYING_DELAY (90)
193 // time length of hanging
194 #define GC_HANG_DELAY (3)
196 // time length until popping, between popping, and after popping
197 #define GC_INTERNAL_POP_DELAY (15)
198 #define GC_INITIAL_POP_DELAY (50 + GC_INTERNAL_POP_DELAY)
199 #define GC_FINAL_POP_DELAY (50)
201 // minimum length of a elimination pattern
202 #define GC_MIN_PATTERN_LENGTH (3)
204 // chance of a creep row having a special block
205 #define GC_NO_SPECIAL_BLOCK_CHANCE_IN (3)
206 #define GC_X_NO_SPECIAL_BLOCK_CHANCE_IN (10)
208 // chance of garbage shattering to garbage
209 #define GC_GARBAGE_TO_GARBAGE_SHATTER (2)
211 // time length before garbage falls
212 #define GC_AVERAGE_GARBAGE_DROP_DELAY (300)
213 #define GC_SPREAD_GARBAGE_DROP_DELAY (40)
215 // time length of the introduction pause; should be multiple of 3
216 #define GC_START_PAUSE_DELAY (150)
218 // maximum height of a garbage block
219 #define GC_MAX_GARBAGE_HEIGHT (11)
221 // score constants
222 #define GC_MIN_PATTERN_SCORE (2)
223 #define GC_GRAY_SCORE (3)
224 #define GC_NUMBER_DIGITS (7)
225 #define GC_MIN_NUMBER_DIGITS_DISPLAYED (4)
226 #define GC_MAX_SCORE_INCREMENT_DELAY (12)
227 #define GC_MIN_SCORE_INCREMENT_DELAY (1)
228 #define GC_SCORE_DELAY_SLOPE (2)
229 #define GC_SCORE_REC_LENGTH (30)
230 #define GC_SCORE_DEFAULT_TOP_SCORE (600)
231 #define GC_SCORE_REC_DEFAULT_NAME "-----"
232 #define GC_SCORE_MULT_LENGTH (10)
234 // sine constants
235 #define GC_SINE_TABLE_LENGTH (100)
236 #define GC_SINE_TABLE_LOWER_BOUND (-PI / 2.0f)
237 #define GC_SINE_TABLE_STEP_WIDTH (PI / (GC_SINE_TABLE_LENGTH - 1))
239 // initial swapper location
240 #define GC_INITIAL_SWAPPER_LOCATION_X (GC_PLAY_WIDTH / 2 - 1)
241 #define GC_INITIAL_SWAPPER_LOCATION_Y (4)
243 // extreme constants
244 #define GC_INVISIBLE_MAX_ALPHA (330)
245 #define GC_INVISIBLE_MIN_ALPHA (-20)
246 #define GC_INVISIBLE_QUICK_DECAY_RATE (3)
247 #define GC_INVISIBLE_PULSE_CHANCE_IN (30)
248 #define GC_INVISIBLE_PULSE_STRENGTH (70)
249 #define GC_CRAZY_LONG_MODE_PERIOD (150)
250 #define GC_CRAZY_SHORT_MODE_PERIOD (50)
251 #define GC_MAX_WILD_NUMBER (3)
252 #define GC_WILD_PERIOD (180)
253 #define GC_WILD_POLYMORPH_PERIOD (60)
254 #define GC_MAX_SPECIAL_COLOR_NUMBER (6)
256 // control keys
257 #define GC_LEFT_KEY ('a')
258 #define GC_RIGHT_KEY ('d')
259 #define GC_UP_KEY ('w')
260 #define GC_DOWN_KEY ('s')
261 #define GC_SWAP_KEY ('k')
262 #define GC_ADVANCE_KEY ('l')
263 #define GC_PAUSE_KEY ('p')
265 // Constants for the game window height and width.
266 #define GC_RESOLUTION_0 (400)
267 #define GC_RESOLUTION_1 (570)
268 #define GC_RESOLUTION_2 (680)
269 #define GC_RESOLUTION_3 (970)
270 #define GC_RESOLUTION_4 (1170)
272 // insure that our communication int is the same length on all machines
273 #if (INT_MAX == 2147483647)
274 typedef unsigned int uint32;
275 #else
276 typedef unsigned short uint32;
277 #endif
279 // debug
280 #ifndef NDEBUG
281 # include <fstream>
282 # ifndef _WIN32
283 # define COLOR(n) "\33[1;" << (n) << "m"
284 # define NOCOLOR "\33[m"
285 # else
286 # define COLOR(n) ""
287 # define NOCOLOR ""
288 # endif
289 # define DOT(n) { std::cerr << COLOR(37 - n) \
290 << "." NOCOLOR << std::flush; }
291 # define DUMP(a) { std::cerr << COLOR(32) << "Dump: " \
292 __FILE__ ":" << __LINE__ << ": " \
293 NOCOLOR #a \
294 " = " << (a) << std::endl; }
295 # define PERIODIC_DUMP(a, b) { if (!(Game::time_step % a)) \
296 std::cerr << COLOR(32) << "Dump: " \
297 __FILE__ ":" << __LINE__ << ": " \
298 NOCOLOR #b \
299 " = " << (b) << std::endl; }
300 # define MESSAGE(a) { std::cerr << COLOR(33) << "Mesg: " \
301 __FILE__ ":" << __LINE__ << ": " \
302 NOCOLOR << a << std::endl; }
303 # ifndef _WIN32
304 # define MARK() { std::cerr << COLOR(35) << "Mark: " \
305 __FILE__ ":" << __LINE__ << ": " \
306 << __PRETTY_FUNCTION__ << NOCOLOR \
307 << std::endl; }
308 # else
309 # define MARK() { std::cerr << COLOR(35) << "Mark: " \
310 __FILE__ ":" << __LINE__ << ":" \
311 NOCOLOR << std::endl; }
312 # endif
313 # define ENDL() { std::cerr << COLOR(34) << "Endl: " \
314 __FILE__ ":" << __LINE__ << ":" \
315 NOCOLOR << std::endl; }
316 # define LOG(a) { std::ofstream log("log", \
317 std::ios::app); \
318 log << "Log: " __FILE__ ":" \
319 << __LINE__ << ": " << a \
320 << std::endl; }
321 #else
322 # define DOT(n) ((void) 0)
323 # define DUMP(a) ((void) 0)
324 # define PERIODIC_DUMP(a, b) ((void) 0)
325 # define MESSAGE(a) ((void) 0)
326 # define MARK() ((void) 0)
327 # define ENDL() ((void) 0)
328 # define LOG(a) ((void) 0)
329 #endif
331 // fix bad Visual C++ scoping
332 #ifdef _WIN32
333 # define for if (false) { } else for
334 #endif
336 // game states
338 // Playing.
339 #define GS_NORMAL (1 << 0)
340 // Normal playing, but we're paused.
341 #define GS_PAUSED (1 << 1)
342 // Signals a local unpausing to opponent; used only in communication signals.
343 #define GS_UNPAUSED (1 << 2)
344 // Normal playing, but we're paused because we've gotten ahead of our opponent;
345 // most likely due to a pause.
346 #define GS_SYNC_WAIT (1 << 3)
347 // We've lost, but we haven't heard confirmation from opponent; play continues.
348 #define GS_MAY_HAVE_LOST (1 << 4)
349 // Opponent lost; we've received the message and it predates our loss; play
350 // continues until level lights reach minimum.
351 #define GS_WON (1 << 5)
352 // We've lost and opponent confirms it; play continues until level lights reach
353 // minimum.
354 #define GS_LOST (1 << 6)
355 // We've won but we can't quite yet cause we must confirm our opponent's loss.
356 #define GS_MUST_CONFIRM_LOSS (1 << 7)
357 // We've confirmed our opponent's loss, but we have to wait a bit yet until
358 // he receives it.
359 #define GS_CONFIRMATION_HOLD (1 << 8)
360 // The level lights signaled it's time to end play. Now we must simply complete
361 // the current time step.
362 #define GS_END_PLAY (1 << 9)
363 // Used only for communication. The match has been conceded.
364 #define GS_CONCESSION (1 << 10)
366 // flavor of blocks; special color blocks must be last; wild and then gray must
367 // be directly after normal flavors; here to prevent header entanglements;
368 // the appearance chance of the various flavors can be found in
369 // BlockManager::newCreepBlock()
370 #define BF_NORMAL_1 ( 0)
371 #define BF_NORMAL_2 ( 1)
372 #define BF_NORMAL_3 ( 2)
373 #define BF_NORMAL_4 ( 3)
374 #define BF_NORMAL_5 ( 4)
375 #define BF_WILD ( 5)
376 #define BF_GRAY ( 6)
377 #define BF_BLACK ( 7)
378 #define BF_WHITE ( 8)
379 #define BF_SPECIAL_COLOR_1 ( 9)
380 #define BF_SPECIAL_COLOR_2 (10)
381 #define BF_SPECIAL_COLOR_3 (11)
382 #define BF_SPECIAL_COLOR_4 (12)
383 #define BF_SPECIAL_COLOR_5 (13)
384 #define BF_NUMBER_NORMAL (BF_NORMAL_5 + 1)
385 #define BF_NUMBER (BF_SPECIAL_COLOR_5 + 1)
386 #define BF_NUMBER_SPECIAL (BF_NUMBER - (BF_GRAY + 1))
387 #define BF_FINAL_GRAY_SPECIAL (BF_WHITE)
389 /* static */ class Game {
390 public:
391 static void initialize ( );
392 static void gameStart ( );
393 static void gameFinish ( );
394 static void cleanUp ( );
396 static void loss ( );
397 static void lossConfirmation ( );
398 static void aiPlayerLoss ( );
399 static void won ( );
400 static void netSignalPause ( );
401 static void netSignalUnpause ( );
402 static void syncPause ( int delay );
403 static void concession ( );
405 static void idlePlay ( );
406 static void idleMeta ( );
408 static inline void go ( )
410 previous_time = glutGet((GLenum) GLUT_ELAPSED_TIME);
413 static inline float sqrt ( float x )
415 * An OK approximation of sqrt() on [0, 1] which is correct at the boundaries.
416 * Since all I really want is the vague shape of sqrt() and perfection at 0
417 * and 1, this'll work perfectly.
419 * Generated by minimizing int_0^1{dx (sqrt{x} - a x + (1 - a) x)^2}.
422 return ((27.0f / 14.0f) - (13.0f / 14.0f) * x) * x;
425 static int state;
426 static int time_step;
427 static int awaking_count;
428 static int dying_count;
429 static int dying_count_2;
431 private:
432 static void buttonPause ( );
433 static void syncUnpause ( );
435 static int previous_time;
436 static int remaining_time;
437 static bool button_down_pause;
438 static bool step_play;
439 static int sync_wait;
440 static double lastframe;
443 #endif