1 #ifndef MAIN_DEFINE
2 #define MAIN_DEFINE
3 
4 /*
5  * atanks - obliterate each other with oversize weapons
6  * Copyright (C) 2003  Thomas Hudson
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.
12  *
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.
17  *
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.
21  * */
22 
23 #ifndef VERSION
24 #  error "VERSION information is missing. Fix Makefile."
25 #endif
26 
27 #ifdef GENTOO
28 #  ifndef DATA_DIR
29 #    define DATA_DIR "/usr/share/games/atanks"
30 #  endif // DATA_DIR
31 #endif // GENTOO
32 
33 #ifndef BUFFER_SIZE
34 # define BUFFER_SIZE 256
35 #endif
36 
37 
38 /// Important: debug.h not only detects which OS/compiler this is,
39 /// it puts an important fix with allegro on windows in place.
40 /// Therefore it *must* stay before the block including winalleg.h!
41 #include "debug.h"
42 
43 
44 // The windows port does some crazy stuff with int*_t types.
45 #if defined(ATANKS_IS_WINDOWS)
46 #  include <cstdint>
47 #  ifndef ALLEGRO_HAVE_STDINT_H
48 #    define ALLEGRO_HAVE_STDINT_H 1
49 #  endif // ALLEGRO_HAVE_STDINT_H
50 #  if !defined(ATANKS_SRC_ATANKS_CPP)
51 #    define ALLEGRO_NO_MAGIC_MAIN
52 #  endif // Not called from atanks.cpp
53 #endif // Windows build system
54 
55 #  include <allegro.h>
56 
57 #if defined(ATANKS_IS_WINDOWS)
58 #  include <winalleg.h>
59 #endif // windows
60 
61 
62 // For visual studio some "workarounds" must be put in place
63 #if defined(ATANKS_IS_MSVC)
64 #  define PATH_MAX MAX_PATH
65    // Needed for M_PIl to show up
66 #  if !defined(_USE_MATH_DEFINES)
67 #    define _USE_MATH_DEFINES 1
68 #  endif
69 #  include <cmath>
70 #else
71 #  include <unistd.h>
72 #  include <cmath>
73 #endif // Windows versus Linux
74 
75 
76 // Be sure M_PI and M_PIl are set:
77 #if !defined(M_PI)
78 #  define M_PI 3.14159265358979323846f
79 #endif
80 #if !defined(M_PIl)
81 #  define M_PIl 3.14159265358979323846L
82 #endif
83 
84 
85 #include <cstdlib>
86 #include <cstdio>
87 #include <cstring>
88 #include <ctime>
89 #include <iostream>
90 #include <fstream>
91 #include <string>
92 #include <chrono>
93 #include <thread>
94 #include <algorithm>
95 
96 
97 #include "globaltypes.h"
98 
99 
100 #define	DONE_IMAGE             11
101 #define	FAST_UP_ARROW_IMAGE    12
102 #define	UP_ARROW_IMAGE         13
103 #define	DOWN_ARROW_IMAGE       14
104 #define	FAST_DOWN_ARROW_IMAGE  15
105 
106 
107 #ifndef HAS_DIRENT
108 #  if defined(ATANKS_IS_MSVC)
109 #    include "extern/dirent.h"
110 #  else
111 #    include <dirent.h>
112 #  endif // Linux
113 #  define HAS_DIRENT 1
114 #endif // HAS_DIRENT
115 
116 
117 // Some more workarounds to compile using visual studio:
118 #if defined(ATANKS_IS_MSVC)
119 #  define snprintf         atanks_snprintf
120 #  define strncpy(d, s, c) strncpy_s(d, c+1, s, c)
121 #  define strncat(d, s, c) strncat_s(d, c+1, s, c)
122 #  define sscanf           sscanf_s
123 #  define access           _access
124 #  define F_OK             02
125 #  define R_OK             04
126 #  define W_OK             02
127 #  define strcasecmp       _stricmp
128 #  define strdup           _strdup
129 #  define unlink           _unlink
130 #  define mkdir            _mkdir
131 #endif
132 
133 // Note: See winclock.h why this is necessary
134 /// REMOVE_VS12_WORKAROUND
135 #if defined(ATANKS_IS_MSVC) && !defined(ATANKS_IS_AT_LEAST_MSVC13)
136 #define USLEEP(microseconds_) Sleep(microseconds_ / 1000);
137 #define MSLEEP(milliseconds_) Sleep(milliseconds_);
138 #else
139 #define USLEEP(microseconds_) std::this_thread::sleep_for(std::chrono::microseconds(microseconds_));
140 #define MSLEEP(milliseconds_) std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds_));
141 #endif // VS12 workaround
142 #define LINUX_SLEEP     MSLEEP(10)
143 #define LINUX_REST      MSLEEP(40)
144 
145 
146 using std::cerr;
147 using std::cout;
148 using std::endl;
149 using std::string;
150 
151 
152 // place to save config and save games
153 #if defined(ATANKS_IS_WINDOWS)
154 #  define HOME_DIR "AppData"
155 #elif defined(ATANKS_IS_LINUX)
156 #  define HOME_DIR "HOME"
157 #endif // Windows versus Linux
158 
159 #ifndef	DATA_DIR
160 #  define DATA_DIR "."
161 #endif
162 
163 #define MAX_OVERSHOOT 10000
164 
165 
166 // The nex few are some math helpers that shorten things dramatically.
167 #define SIGN(x_arg)   ((x_arg) < 0  ? -1  : 1 )
168 #define SIGNd(x_arg)  ((x_arg) < 0. ? -1. : 1.)
169 #define ROUND(x_arg)  static_cast<int32_t>( (x_arg) + (SIGNd(x_arg) * .5))
170 #define ROUNDu(x_arg) static_cast<uint32_t>((x_arg) + .5)
171 
172 #define FABSDISTANCE2(x1,y1,x2,y2) \
173 	std::sqrt(std::pow(static_cast<double>(x2) - static_cast<double>(x1), 2.) \
174 	        + std::pow(static_cast<double>(y2) - static_cast<double>(y1), 2.) )
175 #define FABSDISTANCE3(x1, y1, z1, x2, y2, z2) \
176 	std::sqrt(std::pow(static_cast<double>(x2) - static_cast<double>(x1), 2.) \
177 	        + std::pow(static_cast<double>(y2) - static_cast<double>(y1), 2.) \
178 	        + std::pow(static_cast<double>(z2) - static_cast<double>(z1), 2.) )
179 
180 #define ABSDISTANCE2(x1,y1,x2,y2)       ROUNDu(FABSDISTANCE2(x1,y1,x2,y2))
181 #define ABSDISTANCE3(x1,y1,z1,x2,y2,z2) ROUNDu(FABSDISTANCE3(x1,y1,z1,x2,y2,z2))
182 
183 #define DEG2RAD(degree_) (static_cast<double>(degree_) * M_PIl / 180. )
184 #define RAD2DEG(radian_) (static_cast<double>(radian_) * 180.  / M_PIl)
185 
186 
187 /** @brief show or hide the custom mouse cursor
188   *
189   * This macro can either hide the custom mouse cursor when @a where is set
190   * to nullptr, or draw it on @a where, which then must be a pointer to a
191   * BITMAP.
192   *
193   * This macro should be used to hide the custom mouse cursor before doing any
194   * drawing and to place the mouse cursor on @a where once all other drawing is
195   * done.
196   *
197   * If the OS mouse cursor is used, this macro does nothing.
198   *
199   * @param[in] where BITMAP pointer to draw the custom cursor on or nullptr to
200   * hide the custom mouse cursor.
201 **/
202 #define SHOW_MOUSE(where) { \
203 	if (!env.osMouse) { \
204 		if (where != nullptr) unscare_mouse(); \
205 		else scare_mouse(); \
206 		show_mouse(where); \
207 		/* Make the neccessary updates */ \
208 		if (where != nullptr) { \
209 			global.make_update (mouse_x, mouse_y, env.misc[0]->w, env.misc[0]->h); \
210 			global.make_update (lx, ly, env.misc[0]->w, env.misc[0]->h); \
211 			lx = mouse_x; \
212 			ly = mouse_y; \
213 		} \
214 	} \
215 }
216 
217 #define MAXPLAYERS    10
218 #define MAX_POWER   2000
219 #define MIN_POWER    100
220 #define MAX_ROUNDS 10000
221 
222 #define MENUHEIGHT 40
223 #define BOXED_TOP 41 // This is the highest non-border pixel in boxed mode
224 #define	BALLISTICS 52
225 #define	BEAMWEAPONS 3
226 #define WEAPONS (BALLISTICS + BEAMWEAPONS)
227 #define ITEMS 24
228 #define THINGS (WEAPONS + ITEMS)
229 #define	NATURALS 6
230 #define DIRT_FRAGMENT -1
231 #define RADII 6
232 #define MAXRADIUS 200
233 #define BUTTONFRAMES 2
234 
235 #define MENUBUTTONS 7
236 #define INGAMEBUTTONS 4
237 #define SPREAD 10
238 #define NAME_LEN 24
239 #define ADDRESS_LENGTH 16
240 
241 #define WAIT_AT_END_OF_ROUND 1 // second (enough with the new live score board)
242 
243 #define MAX_ITEM_NAME_LEN 127
244 #define MAX_ITEM_DESC_LEN 511
245 #define MAX_ITEMS_IN_STOCK 999999
246 #define MAX_MONEY_IN_WALLET 1000000000
247 
248 // Use these instead of the (most strict) defaults,
249 // But only where timing by memory fences do not matter.
250 #define ATOMIC_READ  std::memory_order_acquire
251 #define ATOMIC_WRITE std::memory_order_release
252 
253 
254 //turns
255 enum turnTypes
256 {
257 	TURN_HIGH = 0,
258 	TURN_LOW,
259 	TURN_RANDOM,
260 	TURN_SIMUL
261 };
262 
263 
264 struct POINT_t
265 {
266 	int32_t x = 0;
267 	int32_t y = 0;
268 
269 	explicit
POINT_tPOINT_t270 	POINT_t() { }
271 	POINT_t(int32_t x_, int32_t y_);
272 	POINT_t &operator=( const POINT_t &src );
273 };
274 
275 
276 struct BOX
277 {
278 	int32_t x = 0;
279 	int32_t y = 0;
280 	int32_t w = 0;
281 	int32_t h = 0;
282 
283 	explicit
BOXBOX284 	BOX () { }
285 	BOX (int32_t x_, int32_t y_, int32_t w_, int32_t h_);
286 	BOX &operator=(const BOX  &src);
287 	BOX &operator=(const BOX &&src);
288 
289 	void set(int32_t x_, int32_t y_, int32_t w_, int32_t h_);
290 };
291 
292 // Make the BOX usage easier:
293 bool operator==(const BOX &lhs, const BOX &rhs);
294 bool operator!=(const BOX &lhs, const BOX &rhs);
295 
296 
297 struct gradient
298 {
299 	RGB color;
300 	float point;
301 };
302 
303 
304 class WEAPON
305 {
306 public:
307 
308 	/* -----------------------------------
309 	 * --- Constructors and destructor ---
310 	 * -----------------------------------
311 	 */
312 
313 	explicit WEAPON();
314 
315 
316 	/* -----------------------------------
317 	 * --- Public methods              ---
318 	 * -----------------------------------
319 	 */
320 
321 	int32_t     getDelayDiv() const;
322 	const char* getDesc()     const;
323 	const char* getName()     const;
324 
325 	void setDesc(const char* desc_);
326 	void setName(const char* name_);
327 
328 
329 	/* -----------------------------------
330 	 * --- Public members              ---
331 	 * -----------------------------------
332 	 */
333 	int32_t cost            = 0;  //!< $ :))
334 	int32_t amt             = 0;  //!< number of weapons in one buying package
335 	double  mass            = 0.;
336 	double  drag            = 0.;
337 	int32_t radius          = 0;  //!< of the explosion
338 	int32_t sound           = 0;
339 	int32_t etime           = 0;
340 	int32_t damage          = 0;  //!< damage power
341 	int32_t picpoint        = 0;  //!< which picture do we show in flight?
342 	int32_t spread          = 0;  //!< number of weapons in the shot
343 	int32_t delay           = 0;  //!< volleys etc.
344 	int32_t noimpact        = 0;
345 	int32_t techLevel       = 0;
346 	int32_t warhead         = 0;  //!< Is it a warhead?
347 	int32_t numSubmunitions = 0;  //!< Number of submunitions
348 	int32_t submunition     = 0;  //!< The next stage
349 	double  impartVelocity  = 0.; //!< Impart velocity 0.0-1.0 to subs
350 	int32_t divergence      = 0;  //!< Total angle for submunition spread
351 	double  spreadVariation = 0.; //!< Uniform or random distribution
352 	                              //!< 0-1.0 (0=uniform, 1.0=random)
353 	                              //!< divergence at centre of range
354 	double  launchSpeed     = 0.; //!< Speed given to submunitions
355 	double  speedVariation  = 0.; //!< Uniform or random speed
356 	                              //!< 0-1.0 (0=uniform, 1.0=random)
357 	                              //!< launchSpeed at centre of range
358 	int32_t countdown       = 0;  //!< Set the countdown to this
359 	double  countVariation  = 0.; //!< Uniform or random countdown
360 	                              //!< 0-1.0 (0=uniform, 1.0=random)
361 	                              //!< countdown at centre of range
362 
363 
364 private:
365 
366 
367 	/* -----------------------------------
368 	 * --- Private members             ---
369 	 * -----------------------------------
370 	 */
371 
372 	char desc[MAX_ITEM_DESC_LEN + 1];
373 	char name[MAX_ITEM_NAME_LEN + 1];
374 };
375 
376 #define	MAX_ITEMVALS	10
377 class ITEM
378 {
379 public:
380 
381 	/* -----------------------------------
382 	 * --- Constructors and destructor ---
383 	 * -----------------------------------
384 	 */
385 
386 	explicit ITEM();
387 
388 
389 	/* -----------------------------------
390 	 * --- Public methods              ---
391 	 * -----------------------------------
392 	 */
393 
394 	const char* getDesc() const;
395 	const char* getName() const;
396 
397 	void setDesc(const char* desc_);
398 	void setName(const char* name_);
399 
400 
401 	/* -----------------------------------
402 	 * --- Public members              ---
403 	 * -----------------------------------
404 	 */
405 
406 	int32_t cost       = 0;
407 	int32_t amt        = 0;
408 	int32_t selectable = 0;
409 	int32_t techLevel  = 0;
410 	int32_t sound      = 0;
411 	double  vals[MAX_ITEMVALS];
412 
413 
414 private:
415 
416 
417 	/* -----------------------------------
418 	 * --- Private members             ---
419 	 * -----------------------------------
420 	 */
421 
422 	char desc[MAX_ITEM_DESC_LEN + 1];
423 	char name[MAX_ITEM_NAME_LEN + 1];
424 };
425 
426 
427 enum shieldVals
428 {
429 	SHIELD_ENERGY,
430 	SHIELD_REPULSION,
431 	SHIELD_RED,
432 	SHIELD_GREEN,
433 	SHIELD_BLUE,
434 	SHIELD_THICKNESS
435 };
436 
437 
438 enum selfDestructVals
439 {
440 	SELFD_TYPE = 0,
441 	SELFD_NUMBER
442 };
443 
444 
445 enum weaponType
446 {
447 	SML_MIS            =  0,
448 	MED_MIS            =  1,
449 	LRG_MIS            =  2,
450 	SML_NUKE           =  3,
451 	NUKE               =  4,
452 	DTH_HEAD           =  5,
453 	SML_SPREAD         =  6,
454 	MED_SPREAD         =  7,
455 	LRG_SPREAD         =  8,
456 	SUP_SPREAD         =  9,
457 	DTH_SPREAD         = 10,
458 	ARMAGEDDON         = 11,
459 	CHAIN_MISSILE      = 12,
460 	CHAIN_GUN          = 13,
461 	JACK_HAMMER        = 14,
462 	SHAPED_CHARGE      = 15,
463 	WIDE_BOY           = 16,
464 	CUTTER             = 17,
465 	SML_ROLLER         = 18,
466 	LRG_ROLLER         = 19,
467 	DTH_ROLLER         = 20,
468 	SMALL_MIRV         = 21,
469 	ARMOUR_PIERCING    = 22,
470 	CLUSTER            = 23,
471 	SUP_CLUSTER        = 24,
472 	FUNKY_BOMB         = 25,
473 	FUNKY_DEATH        = 26,
474 	FUNKY_BOMBLET      = 27,
475 	FUNKY_DEATHLET     = 28,
476 	BOMBLET            = 29,
477 	SUP_BOMBLET        = 30,
478 	BURROWER           = 31,
479 	PENETRATOR         = 32,
480 	SML_NAPALM         = 33,
481 	MED_NAPALM         = 34,
482 	LRG_NAPALM         = 35,
483 	NAPALM_JELLY       = 36,
484 	DRILLER            = 37,
485 	TREMOR             = 38,
486 	SHOCKWAVE          = 39,
487 	TECTONIC           = 40,
488 	RIOT_BOMB          = 41,
489 	HVY_RIOT_BOMB      = 42,
490 	RIOT_CHARGE        = 43,
491 	RIOT_BLAST         = 44,
492 	DIRT_BALL          = 45,
493 	LRG_DIRT_BALL      = 46,
494 	SUP_DIRT_BALL      = 47,
495 	SMALL_DIRT_SPREAD  = 48,
496 	CLUSTER_MIRV       = 49,
497 	PERCENT_BOMB       = 50,
498 	REDUCER            = 51, // Last ballistic
499 	SML_LAZER          = 52,
500 	MED_LAZER          = 53,
501 	LRG_LAZER          = 54, // Last weapon (WEAPONS == 55)
502 	SML_METEOR         = 55,
503 	MED_METEOR         = 56,
504 	LRG_METEOR         = 57,
505 	SML_LIGHTNING      = 58,
506 	MED_LIGHTNING      = 59,
507 	LRG_LIGHTNING      = 60 // Last natural
508 };
509 
510 
511 #define LAST_EXPLOSIVE DRILLER
512 
513 #define ITEM_NO_SHIELD   -1
514 enum itemType
515 {
516 	ITEM_TELEPORT             =  0, // 55 (weap_idx - WEAPONS)
517 	ITEM_SWAPPER              =  1, // 56
518 	ITEM_MASS_TELEPORT        =  2, // 57
519 	ITEM_FAN                  =  3, // 58
520 	ITEM_VENGEANCE            =  4, // 59
521 	ITEM_DYING_WRATH          =  5, // 60
522 	ITEM_FATAL_FURY           =  6, // 61
523 	ITEM_LGT_SHIELD           =  7,
524 	ITEM_MED_SHIELD           =  8,
525 	ITEM_HVY_SHIELD           =  9,
526 	ITEM_LGT_REPULSOR_SHIELD  = 10,
527 	ITEM_MED_REPULSOR_SHIELD  = 11,
528 	ITEM_HVY_REPULSOR_SHIELD  = 12,
529 	ITEM_ARMOUR               = 13,
530 	ITEM_PLASTEEL             = 14,
531 	ITEM_INTENSITY_AMP        = 15,
532 	ITEM_VIOLENT_FORCE        = 16,
533 	ITEM_SLICKP               = 17,
534 	ITEM_DIMPLEP              = 18,
535 	ITEM_PARACHUTE            = 19,
536 	ITEM_REPAIRKIT            = 20,
537 	ITEM_FUEL                 = 21, // 76
538 	ITEM_ROCKET               = 22, // 77
539 	ITEM_SDI                  = 23 // Last item
540 };
541 
542 #define SHIELD_COUNT		6
543 
544 //signals
545 #define	SIG_QUIT_GAME         -1
546 #define SIG_OK                 0
547 #define GLOBAL_COMMAND_QUIT   -1
548 #define GLOBAL_COMMAND_MENU    0
549 #define GLOBAL_COMMAND_OPTIONS 1
550 #define GLOBAL_COMMAND_PLAYERS 2
551 #define GLOBAL_COMMAND_CREDITS 3
552 #define	GLOBAL_COMMAND_HELP    4
553 #define GLOBAL_COMMAND_PLAY    5
554 #define GLOBAL_COMMAND_DEMO    6
555 #define GLOBAL_COMMAND_NETWORK 7
556 
557 
558 /** @enum eClasses
559   * @brief class definitions of everything from virtual objects up
560   *
561   * The ordering here determines the order of the drawing.
562 **/
563 enum eClasses
564 {
565 	CLASS_MISSILE = 0,
566 	CLASS_BEAM,
567 	CLASS_TANK,
568 	CLASS_TELEPORT,
569 	CLASS_DECOR_DIRT,
570 	CLASS_DECOR_SMOKE,
571 	CLASS_EXPLOSION,
572 	CLASS_FLOATTEXT,
573 	CLASS_COUNT
574 };
575 
576 
577 #ifndef HAS_TANK
578 class TANK; // forwarding if not known
579 #endif // HAS_TANK
580 
581 /// === Global functions used in several compilation units ====
582 void   drawMenuBackground(eBackgroundTypes backType, int32_t tOffset,
583                           int32_t numItems);
584 double interpolate       (double x1, double x2, double i);
585 double Noise             (int x);
586 double Noise2D           (int x, int y);
587 double perlin1DPoint     (double amplitude, double scale, double xo,
588                           double lambda, int octaves);
589 double perlin2DPoint     (double amplitude, double scale, double xo, double yo,
590                           double lambda, int octaves);
591 void   quickChange       (bool clearerror);
592 
593 #include "externs.h"
594 
595 #endif
596 
597