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