1 // Apricots header file 2 // Author: M.D.Snellgrove 3 // Date: 26/3/2002 4 // History: 5 6 // Changes by M Harman for Windows version, June 2003: 7 // Necessary changes to function prototypes for various reasons. 8 // I had to initialise the Airbase definitions with constructors; Borland 9 // doesn't seem to like initialising structures with the nested {}. 10 11 // Changes by M Snellgrove 6/7/2003 12 // Function drand48() renamed drand() and is now located in file all.cpp 13 14 // Changes by M Snellgrove 30/7/2003 15 // smoketype object added, g.smoke is now a linkedlist <smoketype> 16 17 // Changes by M Snellgrove 3/8/2003 18 // TICK_INTERVAL moved here and set to 20 19 20 #include <SDL.h> 21 #include <cstdlib> 22 #include <ctime> 23 #include <cmath> 24 #include <cstring> 25 #include "shape.h" 26 #include "linkedlist.h" 27 #include "sampleio.h" 28 #include "SDLfont.h" 29 using namespace std; 30 31 // Global constants 32 33 const int GAME_WIDTH = 2400; 34 const int GAME_HEIGHT = 320; 35 const int MAP_W = GAME_WIDTH / 32; 36 const int MAP_H = GAME_HEIGHT / 32; 37 const double GAME_SPEED = 0.5; 38 const int TICK_INTERVAL = 20; 39 const double PI = 3.141592; 40 41 // Default data directory path (current directory) 42 43 #ifndef AP_PATH 44 #define AP_PATH "./" 45 #endif 46 47 // Datatypes 48 49 struct building{ 50 int type; // 0 = none, 1 = tree, 2 = tower, 3 = building, 4 = radar, 5 = gun 51 int id; 52 int x; 53 int y; 54 int image; 55 int deadimage; 56 int points; 57 int side; 58 int towersize; 59 int shrapnelimage; 60 int shrapnelimage2; 61 }; 62 63 // Building definitions 64 65 const building NB = {0,0,0,0,0,0,0,0,0,0,0}; // null building 66 const building CONTROLTOWER = {3, 0, 0, 0, 69, 73, 240, 0, 0, 140, 225}; 67 const building FUEL = {3, 0, 0, 0, 71, 75, 60, 0, 0, 140, 140}; 68 const building HANGAR = {3, 0, 0, 0, 70, 74, 160, 0, 0, 228, 140}; 69 const building GUN = {5, 0, 0, 0, 166, 170, 200, 0, 0, 140, 140}; 70 const building RADAR = {4, 0, 0, 0, 238, 246, 120, 0, 0, 140, 225}; 71 const building TOWER = {2, 0, 0, 0, 0, 0, 0, 0, 0, 140, 140}; 72 const building POWERSTATION = {3, 0, 0, 0, 112, 113, 80, 0, 0, 140, 140}; 73 const building COOLINGTOWER_LEFT = {3, 0, 0, 0, 108, 111, 60, 0, 0, 140, 225}; 74 const building COOLINGTOWER_MIDDLE = {3, 0, 0, 0, 109, 111, 60, 0, 0, 140, 225}; 75 const building COOLINGTOWER_RIGHT = {3, 0, 0, 0, 110, 111, 60, 0, 0, 140, 225}; 76 const building FACTORY = {3, 0, 0, 0, 72, 76, 100, 0, 0, 140, 140}; 77 const building CIVILIAN_1 = {3, 0, 0, 0, 194, 195, -30, 0, 0, 222, 222}; 78 const building CIVILIAN_2 = {3, 0, 0, 0, 200, 201, -60, 0, 0, 225, 219}; 79 const building CIVILIAN_3 = {3, 0, 0, 0, 202, 203, -40, 0, 0, 219, 140}; 80 const building FIRTREE = {1, 0, 0, 0, 258, 259, -10, 0, 0, 143, 143}; 81 const building PALMTREE = {1, 0, 0, 0, 192, 193, -10, 0, 0, 143, 222}; 82 83 struct firetype{ 84 int x; 85 int y; 86 int time; 87 int type; 88 }; 89 90 struct smoketype{ 91 int x; 92 double y; 93 int time; 94 }; 95 96 struct lasertype{ 97 int x; 98 int y; 99 int image; 100 int time; 101 }; 102 103 struct radartype{ 104 int x; 105 int y; 106 int image; 107 int rotate; 108 int xpos; 109 int id; 110 }; 111 112 struct guntype{ 113 int x; 114 int y; 115 int d; 116 int ammo; 117 int firedelay; 118 int side; 119 int xpos; 120 int reload; 121 int rotate; 122 int id; 123 int target; 124 }; 125 126 struct falltype{ 127 double x; 128 double y; 129 double xs; 130 double ys; 131 int image; 132 int side; 133 int type; // 0 = treebits, 1 = shrapnel, 2 = large bits, 3 = bomb 134 int bombrotate; 135 int rotatedelay; 136 }; 137 138 struct shottype{ 139 double x; 140 double y; 141 double xs; 142 double ys; 143 int side; 144 int time; 145 }; 146 147 struct map{ 148 int image[MAP_W][MAP_H]; 149 int groundheight[MAP_W]; 150 building b[MAP_W*2]; 151 int realheight[MAP_W*2+1]; 152 int smoothheight[MAP_W*2+1]; 153 int steepheight[MAP_W*2+1]; 154 shape ground; 155 }; 156 157 struct info{ 158 int planetype; 159 int basetype; 160 int control; 161 }; 162 163 struct drakmstype{ 164 double x; 165 double y; 166 double xs; 167 int exist; 168 int targetx; 169 int damage; 170 int launchdelay; 171 int movedelay; 172 bool lgun; 173 bool rgun; 174 int targetmod; 175 int fightersout; 176 bool fighter[3]; 177 }; 178 179 struct drakguntype{ 180 int type; 181 int x; 182 int y; 183 int d; 184 int time; 185 int rotate; 186 int reload; 187 int target; 188 int image[17]; 189 }; 190 191 struct airbase{ 192 int runwayx; 193 int runwaylength; 194 int size; 195 int planepos; 196 int planed; 197 int mapx; 198 int planex; 199 int planey; 200 building buildlist[15]; 201 202 // Explicit constructor required else Borland C++ Compiler gives errors airbaseairbase203 airbase() { 204 } 205 206 airbase(int runwayx,int runwaylength,int size,int planepos,int planed,int mapx,int planex,int planey, 207 building b0 = NB, 208 building b1 = NB, 209 building b2 = NB, 210 building b3 = NB, 211 building b4 = NB, 212 building b5 = NB, 213 building b6 = NB, 214 building b7 = NB, 215 building b8 = NB, 216 building b9 = NB, 217 building b10 = NB, 218 building b11 = NB, 219 building b12 = NB, 220 building b13 = NB, 221 building b14 = NB 222 ){ 223 this->runwayx = runwayx; 224 this->runwaylength = runwaylength; 225 this->size = size; 226 this->planepos = planepos; 227 this->planed = planed; 228 this->mapx = mapx; 229 this->planex = planex; 230 this->planey = planey; 231 this->buildlist[0] = b0; 232 this->buildlist[1] = b1; 233 this->buildlist[2] = b2; 234 this->buildlist[3] = b3; 235 this->buildlist[4] = b4; 236 this->buildlist[5] = b5; 237 this->buildlist[6] = b6; 238 this->buildlist[7] = b7; 239 this->buildlist[8] = b8; 240 this->buildlist[9] = b9; 241 this->buildlist[10] = b10; 242 this->buildlist[11] = b11; 243 this->buildlist[12] = b12; 244 this->buildlist[13] = b13; 245 this->buildlist[14] = b14; 246 } 247 }; 248 249 struct plane{ 250 double x; 251 double y; 252 double xs; 253 double ys; 254 double s; 255 int d; 256 int control; 257 int land; 258 int state; 259 int crash; 260 int id; 261 int side; 262 int image; 263 int rotate; 264 int maxrotate; 265 bool boost; 266 bool burner; 267 bool hide; 268 bool stealth; 269 int shotdelay; 270 int ammo; 271 int maxammo; 272 int bombs; 273 int maxbombs; 274 int shrapnelimage; 275 int enginesample; 276 bool drak; 277 int score; 278 int targetscore; 279 int coms; // 280 int targetx; // 281 int targety; // Computer AI stuff 282 int cruiseheight; // 283 int gunthreat; // 284 }; 285 286 struct planeclone{ 287 double x; 288 double y; 289 double xs; 290 double ys; 291 int d; 292 int image; 293 int state; 294 bool hide; 295 int id; 296 int side; 297 bool collide; 298 int scoreloss; 299 int buildingwin; 300 }; 301 302 struct gamedata{ 303 int planes; 304 int towers; 305 int guns; 306 int buildings; 307 int trees; 308 int players; 309 int targetscore; 310 int mission; 311 int winner; 312 plane* player1; 313 plane* player2; 314 airbase base[7]; 315 info planeinfo[7]; 316 SDL_Surface *physicalscreen; 317 SDL_Surface *virtualscreen; 318 SDL_Surface *gamescreen; 319 shape images[319]; 320 map gamemap; 321 linkedlist <radartype> radar; 322 linkedlist <guntype> gun; 323 linkedlist <plane> p; 324 linkedlist <planeclone> dp; 325 linkedlist <firetype> explosion; 326 linkedlist <firetype> flame; 327 linkedlist <smoketype> smoke; 328 linkedlist <falltype> fall; 329 linkedlist <shottype> shot; 330 sampleio sound; 331 SDLfont whitefont; 332 SDLfont greenfont; 333 double accel[17]; 334 double xmove[17]; 335 double ymove[17]; 336 int xboost[17]; 337 int yboost[17]; 338 int bombimage[17]; 339 int drakoption; 340 bool drak; 341 drakmstype drakms; 342 linkedlist <drakguntype> drakgun; 343 linkedlist <lasertype> laser; 344 }; 345 346 // Airbase definitions 347 348 const airbase EMPTY_AIRBASE(0,0,0,0,0,0,0,0); 349 const airbase STANDARD_AIRBASE(48,80,4,48,13,0,0,0,CONTROLTOWER,RADAR,GUN,NB,NB,NB,NB,NB,NB,FUEL,HANGAR); 350 const airbase REVERSED_AIRBASE(32,80,4,96,5,0,0,0,HANGAR,FUEL,NB,NB,NB,NB,NB, 351 NB,GUN,RADAR,CONTROLTOWER); 352 const airbase LITTLE_AIRBASE(16,80,2,16,13,0,0,0,CONTROLTOWER,NB, 353 NB,NB,NB,NB,NB); 354 const airbase LONG_AIRBASE(16,192,6,16,13,0,0,0,CONTROLTOWER,NB,NB,NB,NB,NB, 355 NB,NB,NB,NB,NB,NB,NB,NB,HANGAR); 356 const airbase ORIGINAL_AIRBASE(32,80,3,32,13,0,0,0,CONTROLTOWER,RADAR,NB, 357 NB,NB,NB,NB,NB,HANGAR); 358 const airbase SHOOTY_AIRBASE(80,80,6,80,13,0,0,0,GUN,FUEL,GUN,CONTROLTOWER, 359 RADAR,NB,NB,NB,NB,NB,NB,HANGAR,GUN,FUEL,GUN); 360 const airbase TWOGUN_AIRBASE(48,96,5,128,5,0,0,0,RADAR,GUN,HANGAR,NB,NB, 361 NB,NB,NB,NB,NB,CONTROLTOWER,GUN,RADAR); 362 363 // Sample definitions 364 365 const int SOUND_ENGINE = 0; 366 const int SOUND_JET = 1; 367 const int SOUND_EXPLODE = 2; 368 const int SOUND_GROUNDHIT = 3; 369 const int SOUND_FUELEXPLODE = 4; 370 const int SOUND_SHOT = 5; 371 const int SOUND_GUNSHOT = 6; 372 const int SOUND_BOMB = 7; 373 const int SOUND_SPLASH = 8; 374 const int SOUND_LASER = 9; 375 const int SOUND_STALL = 10; 376 const int SOUND_GUNSHOT2 = 11; 377 const int SOUND_BURNER = 12; 378 const int SOUND_FINISH = 13; 379 380 // Plane definitions 381 382 const plane SPITFIRE = {0.0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 383 122, 0, int(3/GAME_SPEED)-1, 384 false, false, false, false, 0, 8, 8, 4, 4, 143, 385 SOUND_ENGINE, false, 0, 0, 0, 0, 0, 0, 0}; 386 const plane JET = {0.0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 387 76, 0, int(2/GAME_SPEED)-1, 388 false, true, false, false, 0, 12, 12, 5, 5, 140, 389 SOUND_JET, false, 0, 0, 0, 0, 0, 0, 0}; 390 const plane STEALTH = {0.0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 391 174, 0, int(4/GAME_SPEED)-1, 392 false, false, false, true, 0, 3, 3, 6, 6, 235, 393 SOUND_JET, false, 0, 0, 0, 0, 0, 0, 0}; 394 const plane DRAK_FIGHTER = {0.0, 0.0, 0.0, 2.0*GAME_SPEED, 2.0*GAME_SPEED, 9, 0, 2, 1, 0, 0, 0, 395 259, 0, int(1/GAME_SPEED)-1, 396 false, true, false, false, 0, 1000, 1000, 0, 0, 235, 397 SOUND_JET, true, 0, 0, 0, 0, 0, 0, 0}; 398 399 400 // Drak mothership initial state 401 402 const drakmstype DRAKMSINIT = {0.0, -32.0, 0.0, 0, 0, 0, 0, int(200/GAME_SPEED), true, true, 0, 0, 403 {false, false, false}}; 404 405 const drakguntype DGUN_LASER_LEFT = {-1, 24, 27, 0, 0, 0, 0, 0,{305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 406 0, 0, 0, 0, 0, 0, 0}}; 407 const drakguntype DGUN_LASER_RIGHT = {1, 56, 27, 0, 0, 0, 0, 0,{305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 408 0, 0, 0, 0, 0, 0, 0}}; 409 const drakguntype DGUN_TOP_LEFT = {0, 2, -3, 1, 0, 0, 0, 0,{0, 281, 280, 279, 278, 277, 0, 0, 0, 410 0, 0, 0, 0, 0, 284, 283, 282}}; 411 const drakguntype DGUN_TOP_RIGHT = {0, 78, -3, 1, 0, 0, 0, 0,{0, 281, 280, 279, 278, 0, 0, 0, 0, 412 0, 0, 0, 0, 285, 284, 283, 282}}; 413 const drakguntype DGUN_SIDE_LEFT = {0, -4, 20, 7, 0, 0, 0, 0,{0, 0, 0, 0, 287, 288, 289, 290, 414 291, 292, 293, 294, 0, 0, 0, 0, 0}}; 415 const drakguntype DGUN_SIDE_RIGHT = {0, 84, 20, 11, 0, 0, 0, 0,{0, 0, 0, 0, 0, 0, 0, 303, 302, 416 301, 300, 299, 298, 297, 296, 0, 0}}; 417 418 // Function prototypes 419 420 void setup_game(gamedata &); 421 422 void init_data(gamedata &); 423 424 void drawall(gamedata &); 425 426 void game(gamedata &); 427 428 void all(gamedata &); 429 430 int wrap(int, int, int); 431 432 int limit(int, int, int); 433 434 double dlimit(double, double, double); 435 436 int sign(int); 437 438 void draw_dither(SDL_Surface *, int, int, int, int); 439 440 void computer_ai(gamedata &, plane &, int &, int &, bool &); 441 442 void detect_collisions(gamedata &); 443 444 void killbuilding(gamedata &, building &); 445 446 void killtower(gamedata &, building &, double, double, int, int); 447 448 void setup_intelligence(map &); 449 450 bool fall_collision(gamedata &, falltype &); 451 452 void gunshoot(guntype &, linkedlist <shottype> &, sampleio &, double[17], 453 double[17]); 454 455 void finish_game(gamedata &); 456 457 void setup_draks(drakmstype &, linkedlist <drakguntype> &); 458 459 void drak_main(gamedata &); 460 461 double drand(); 462