1 // Apricots setup routine
2 // Author: M.D.Snellgrove
3 // Date: 24/3/2002
4 // History:
5 
6 // Changes by M Harman for Windows version, June 2003:
7 //   Changes for graphics related stuff.
8 
9 #include "apricots.h"
10 
11 // Create airbases
12 
create_airbases(airbase base[],info planeinfo[],int planes)13 void create_airbases(airbase base[], info planeinfo[], int planes){
14 
15   base[0] = EMPTY_AIRBASE;
16   for (int n=1;n<=planes;n++){
17     switch(planeinfo[n].basetype){
18       case 1:
19         base[n] = STANDARD_AIRBASE;
20         break;
21       case 2:
22         base[n] = REVERSED_AIRBASE;
23         break;
24       case 3:
25         base[n] = LITTLE_AIRBASE;
26         break;
27       case 4:
28         base[n] = LONG_AIRBASE;
29         break;
30       case 5:
31         base[n] = ORIGINAL_AIRBASE;
32         break;
33       case 6:
34         base[n] = SHOOTY_AIRBASE;
35         break;
36       case 7:
37         base[n] = TWOGUN_AIRBASE;
38         break;
39     }
40   }
41 
42 }
43 
44 // Land generation randomizer
45 
randomland(int landa,int landb)46 int randomland(int landa, int landb){
47 
48   if (drand() > 0.5) return landa;
49   return landb;
50 
51 }
52 
53 // Create the game map
54 
setup_map(map & gamemap,int planes,airbase base[],bool flatground[])55 void setup_map(map &gamemap, int planes, airbase base[], bool flatground[]){
56 
57 // Arrange airbase flags (to pin out airbase locations)
58   int airbaseflag[MAP_W];
59   for (int x1=0;x1<MAP_W;x1++){
60     airbaseflag[x1] = 0;
61   }
62 // Pin out locations (in reverse order)
63 //   airbaseflag = 1 (airbase), 2 (1 space to left), 3 (2 spaces to left)
64   for (int n=planes;n>=1;n--){
65     if (planes > 1) base[n].mapx = 4 + (MAP_W-13)*(n-1)/(planes-1);
66                else base[n].mapx = 4;
67     airbaseflag[base[n].mapx-2] = 3;
68     airbaseflag[base[n].mapx-1] = 2;
69     for (int i=0;i<=base[n].size;i++){
70       airbaseflag[base[n].mapx+i] = 1;
71     }
72   }
73 
74 // Set ground default as unflat
75   for (int i=0;i<MAP_W*2;i++){
76     flatground[i] = false;
77   }
78 
79 // Clear gamemap
80   for(int x2=0; x2<MAP_W; x2++){
81     for(int y=0; y<MAP_H; y++){
82       gamemap.image[x2][y] = 0;
83     }
84   }
85 
86 // Setup landtypes
87   const int HILAND = 0;
88   const int LOLAND = 1;
89   const int BEACH = 2;
90   const int PORTLEFT = 3;
91   const int PORTRIGHT = 4;
92   const int SEA = 5;
93 
94   int height = 0;
95   int land = 0;
96 
97 // Do left of map
98   int r;
99   r = int(drand() * 4.0);
100   int y1;
101   switch(r){
102     case 0: case 1: case 2:
103       height = MAP_H - 1 - r;
104       land = randomland(HILAND,LOLAND);
105       for (y1=0;y1<height;y1++){
106         gamemap.image[0][y1] = 2;
107       }
108       gamemap.image[0][height] = 14-(10*land);
109       break;
110     case 3:
111       height = MAP_H - 1;
112       land = SEA;
113       for (y1=0; y1<height;y1++){
114         gamemap.image[0][y1] = 2;
115       }
116       gamemap.image[0][height] = 28;
117       break;
118   }
119   gamemap.groundheight[0] = 0;
120 
121 // Do middle portion of map
122   for (int x=1; x<MAP_W-1;x++){
123     switch(land){
124       case HILAND:
125         gamemap.groundheight[x] = 32 * height + 9;
126         flatground[x*2] = true;
127         r = int(drand() * 6.0);
128         if ((airbaseflag[x] == 2) && (height == MAP_H-3)) r = 5;
129         if ((airbaseflag[x] == 2) && (height == MAP_H-2) &&
130             ((r == 2) || (r == 4))) r = 5;
131         if (airbaseflag[x] == 1) r = 0;
132         if ((height == MAP_H-3) && ((r == 2) || (r == 4))) r = 0;
133         if ((height == MAP_H-1) && (r == 5)) r = 0;
134         switch(r){
135           case 0:
136             gamemap.image[x][height] = 9;
137             flatground[x*2+1] = true;
138             break;
139           case 1:
140             gamemap.image[x][height] = 8;
141             land = LOLAND;
142             break;
143           case 2:
144             gamemap.image[x][height] = 10;
145             gamemap.image[x][height-1] = 11;
146             height--;
147             land = LOLAND;
148             break;
149           case 3:
150             gamemap.image[x][height] = 20;
151             land = LOLAND;
152             break;
153           case 4:
154             gamemap.image[x][height] = 15;
155             land = randomland(HILAND,LOLAND);
156             gamemap.image[x][height-1] = 19-(2*land);
157             height--;
158             break;
159           case 5:
160             gamemap.image[x][height] = 18;
161             if ((height != MAP_H-2) || (drand()>0.33) ||
162                 (airbaseflag[x] == 2)){
163               land = randomland(HILAND,LOLAND);
164               gamemap.image[x][height+1] = 14-(10*land);
165               height++;
166             }else{
167               land = SEA;
168               gamemap.image[x][height+1] = 28;
169               height++;
170             }
171             break;
172         }
173         break;
174 
175       case LOLAND:
176         gamemap.groundheight[x] = 32 * height + 22;
177         flatground[x*2] = true;
178         r = int(drand() * 6.0);
179         if ((airbaseflag[x] == 2) && (height == MAP_H-3))
180            r = 2 + 3 * int(drand() * 2.0);
181         if ((airbaseflag[x] == 2) && (height == MAP_H-2) && (r == 4)) r = 5;
182         if (airbaseflag[x] == 1) r = 0;
183         if ((height == MAP_H-3) && (r == 4)) r = 0;
184         if ((height == MAP_H-1) && (r == 5)) r = 2;
185         if (((airbaseflag[x] == 2) || (x == MAP_W-2)) && (height == MAP_H-1) &&
186             (r == 2)) r = 0;
187         switch(r){
188           case 0:
189             gamemap.image[x][height] = 5;
190             flatground[x*2+1] = true;
191             break;
192           case 1:
193             gamemap.image[x][height] = 7;
194             land = HILAND;
195             break;
196           case 2:
197             if (height < MAP_H-1){
198               gamemap.image[x][height] = 13;
199               gamemap.image[x][height+1] = 12;
200               height++;
201               land = HILAND;
202             }else{
203               land = randomland(BEACH,PORTLEFT);
204               if (airbaseflag[x] == 3) land = BEACH;
205               gamemap.image[x][height] = 6+(8*land);
206               if (land == PORTLEFT) flatground[x*2+1] = true;
207             }
208             break;
209           case 3:
210             gamemap.image[x][height] = 21;
211             land = HILAND;
212             break;
213           case 4:
214             gamemap.image[x][height] = 6;
215             land = randomland(HILAND,LOLAND);
216             gamemap.image[x][height-1] = 19-(2*land);
217             height--;
218             break;
219           case 5:
220             gamemap.image[x][height] = 16;
221             if ((height != MAP_H-2) || (drand()>0.33) ||
222                 (airbaseflag[x] == 2)){
223               land = randomland(HILAND,LOLAND);
224               gamemap.image[x][height+1] = 14-(10*land);
225               height++;
226             }else{
227               land = SEA;
228               gamemap.image[x][height+1] = 28;
229               height++;
230             }
231             break;
232         }
233         break;
234 
235       case BEACH:
236         gamemap.groundheight[x] = GAME_HEIGHT - 4;
237         flatground[x*2] = true;
238         r = int(drand() * 3.0);
239         if ((airbaseflag[x] > 1) || (x == MAP_W-2)) r = 1;
240         switch(r){
241           case 0:
242             gamemap.image[x][height] = 24;
243             flatground[x*2+1] = true;
244             break;
245           case 1:
246             gamemap.image[x][height] = 23;
247             land = LOLAND;
248             break;
249           case 2:
250             gamemap.image[x][height] = 25;
251             land = SEA;
252             break;
253         }
254         break;
255 
256       case PORTLEFT:
257         gamemap.groundheight[x] = GAME_HEIGHT - 10;
258         flatground[x*2] = true;
259         r = int(drand() * 3.0);
260         if ((airbaseflag[x] > 1) || (x == MAP_W-2)) r = 1;
261         switch(r){
262           case 0:
263             gamemap.image[x][height] = 32;
264             flatground[x*2+1] = true;
265             break;
266           case 1: case 2:
267             gamemap.image[x][height] = 33;
268             land = SEA;
269             break;
270         }
271         break;
272 
273       case PORTRIGHT:
274         gamemap.groundheight[x] = GAME_HEIGHT - 10;
275         flatground[x*2] = true;
276         r = int(drand() * 3.0);
277         if ((airbaseflag[x] > 1) || (x == MAP_W-2)) r = 1;
278         switch(r){
279           case 0:
280             gamemap.image[x][height] = 32;
281             flatground[x*2+1] = true;
282             break;
283           case 1: case 2:
284             gamemap.image[x][height] = 31;
285             land = LOLAND;
286             flatground[x*2+1] = true;
287             break;
288         }
289         break;
290 
291       case SEA:
292         gamemap.groundheight[x] = GAME_HEIGHT - 2;
293         r = int(drand() * 4.0);
294         if (airbaseflag[x] == 2) r = 3;
295         if (airbaseflag[x] == 3) r = 2;
296         if ((r == 2) && (x == MAP_W-2)) r = 0;
297         switch(r){
298           case 0: case 1:
299             gamemap.image[x][height] = 27;
300             break;
301           case 2:
302             land = randomland(BEACH,PORTRIGHT);
303             gamemap.image[x][height] = 18+(4*land);
304             break;
305           case 3:
306             gamemap.image[x][height] = 29;
307             land = randomland(HILAND,LOLAND);
308             gamemap.image[x][height-1] = 19-(2*land);
309             height--;
310             break;
311         }
312         break;
313     }
314   }
315 
316 // Do right of map
317   switch(land){
318     case HILAND:
319       gamemap.image[MAP_W-1][height] = 15;
320       gamemap.groundheight[MAP_W-1] = 32 * height + 9;
321       flatground[(MAP_W-1)*2] = true;
322       break;
323     case LOLAND:
324       gamemap.image[MAP_W-1][height] = 6;
325       gamemap.groundheight[MAP_W-1] = 32 * height + 22;
326       flatground[(MAP_W-1)*2] = true;
327       break;
328     case SEA:
329       gamemap.image[MAP_W-1][height] = 29;
330       gamemap.groundheight[MAP_W-1] = GAME_HEIGHT - 2;
331       break;
332   }
333   for (int y=0;y<height;y++){
334     gamemap.image[MAP_W-1][y] = 3;
335   }
336 
337 // Fill in ground
338   for (int x3=0;x3<MAP_W;x3++){
339     int y = MAP_H - 1;
340     while (gamemap.image[x3][y] == 0){
341       gamemap.image[x3][y] = 1;
342       y--;
343     }
344   }
345 
346 }
347 
348 // Setup the buildings and airbases and scenery
349 
setup_buildings(gamedata & g,bool flatground[])350 void setup_buildings(gamedata &g, bool flatground[]){
351 
352 // Clear building array
353   for (int x=0;x<MAP_W*2;x++){
354     g.gamemap.b[x].type = 0;
355   }
356 
357 // Place airbases
358   int radarcount = 0;
359   int guncount = 0;
360   for (int n1=1;n1<=g.planes;n1++){
361     g.base[n1].planex = 32 * g.base[n1].mapx + g.base[n1].planepos;
362     g.base[n1].planey = g.gamemap.groundheight[g.base[n1].mapx] - 12;
363     for(int x=0;x<=(g.base[n1].size+1)*2;x++){
364       int px = x + g.base[n1].mapx*2;
365       flatground[px] = false;
366       if (g.base[n1].buildlist[x].type != 0){
367         g.gamemap.b[px] = g.base[n1].buildlist[x];
368         g.gamemap.b[px].x = px * 16 - 8;
369         g.gamemap.b[px].y = g.gamemap.groundheight[g.base[n1].mapx] - 16;
370         g.gamemap.b[px].side = n1;
371         if (g.gamemap.b[px].type == 4){ //radar
372           radarcount++;
373           radartype newradar = {g.gamemap.b[px].x,g.gamemap.b[px].y,238,0,
374                          px,radarcount};
375           g.radar.add(newradar);
376           g.gamemap.b[px].id = radarcount;
377         }
378         if (g.gamemap.b[px].type == 5){ //gun
379           guncount++;
380           guntype newgun = {g.gamemap.b[px].x,g.gamemap.b[px].y,4,3,0,n1,px,0,0,
381                        guncount,0};
382           g.gun.add(newgun);
383           g.gamemap.b[px].id = guncount;
384         }
385       }
386     }
387   }
388 
389 // Count spaces for buildings/trees etc
390   int spaces = 0;
391   for (int x1=0;x1<MAP_W*2;x1++){
392     if (flatground[x1]){
393       spaces++;
394     }
395   }
396 
397 // Place towers
398   int n = g.towers;
399   while ((n>0) && (spaces>0)){
400     int x;
401     do{
402       x = int(drand()*MAP_W*2.0);
403     } while (!flatground[x]);
404     flatground[x] = false;
405     g.gamemap.b[x] = TOWER;
406     g.gamemap.b[x].x = x * 16 - 8;
407     g.gamemap.b[x].y = g.gamemap.groundheight[x/2] - 16;
408     int towersize = int(drand()*4.0)+2;
409     int heightexcess = towersize - (g.gamemap.groundheight[x/2]/16) +
410                          MAP_H*2  - 8;
411     if (heightexcess > 0) towersize -= heightexcess;
412     g.gamemap.b[x].towersize = towersize;
413     spaces--;
414     n--;
415   }
416 
417 // Place guns
418   n = g.guns;
419   while ((n>0) && (spaces>0)){
420     int x;
421     do{
422       x = int(drand()*MAP_W*2.0);
423     } while (!flatground[x]);
424     flatground[x] = false;
425     g.gamemap.b[x] = GUN;
426     g.gamemap.b[x].x = x * 16 - 8;
427     g.gamemap.b[x].y = g.gamemap.groundheight[x/2] - 16;
428     guncount++;
429     guntype newgun = {g.gamemap.b[x].x,g.gamemap.b[x].y,4,3,0,0,x,0,0,
430                        guncount,0};
431     g.gun.add(newgun);
432     g.gamemap.b[x].id = guncount;
433     spaces--;
434     n--;
435   }
436 
437 
438 
439 // Place buildings
440   n = g.buildings;
441   bool powerstation = false;
442   while ((n>0) && (spaces>0)){
443     int x;
444     do{
445       x = int(drand()*MAP_W*2.0);
446     } while (!flatground[x]);
447     if ((flatground[x-1]) && (flatground[x+1]) &&
448         ((drand()<0.2) || (!powerstation))){ // powerstation
449       bool bigpowerstation = false;
450       if ((x>1) && (x<MAP_W*2-2)){ //bigpowerstation
451         if ((flatground[x-2]) && (flatground[x+2])){
452           bigpowerstation = true;
453           g.gamemap.b[x-2] = COOLINGTOWER_LEFT;
454           g.gamemap.b[x-1] = COOLINGTOWER_MIDDLE;
455           g.gamemap.b[x] = POWERSTATION;
456           g.gamemap.b[x+1] = COOLINGTOWER_MIDDLE;
457           g.gamemap.b[x+2] = COOLINGTOWER_RIGHT;
458           for(int px=x-2;px<=x+2;px++){
459             g.gamemap.b[px].x = px * 16 - 8;
460             g.gamemap.b[px].y = g.gamemap.groundheight[x/2] - 16;
461             flatground[px] = false;
462           }
463           spaces -= 5;
464           n--;
465         }
466       }
467       if (!bigpowerstation){ //smallpowerstation
468         g.gamemap.b[x-1] = COOLINGTOWER_LEFT;
469         g.gamemap.b[x] = POWERSTATION;
470         g.gamemap.b[x+1] = COOLINGTOWER_RIGHT;
471         for(int px=x-1;px<=x+1;px++){
472           g.gamemap.b[px].x = px * 16 - 8;
473           g.gamemap.b[px].y = g.gamemap.groundheight[x/2] - 16;
474           flatground[px] = false;
475         }
476         spaces -= 3;
477         n--;
478       }
479     }else { //buildings
480       int r = int(drand() * 6.0);
481       switch(r){
482         case 0:
483           g.gamemap.b[x] = CIVILIAN_1;
484           break;
485         case 1:
486           g.gamemap.b[x] = CIVILIAN_2;
487           break;
488         case 2:
489           g.gamemap.b[x] = CIVILIAN_3;
490           break;
491         case 3: case 4: case 5:
492           g.gamemap.b[x] = FACTORY;
493           break;
494       }
495       g.gamemap.b[x].x = x * 16 - 8;
496       g.gamemap.b[x].y = g.gamemap.groundheight[x/2] - 16;
497       flatground[x] = false;
498       spaces--;
499       n--;
500     }
501   }
502 
503 // Place trees
504   n = g.trees;
505   while ((n>0) && (spaces>0)){
506 
507     int x;
508     do{
509       x = int(drand()*MAP_W*2.0);
510     } while (!flatground[x]);
511     flatground[x] = false;
512     int mapunderneath = g.gamemap.image[x/2][MAP_H-1];
513     if ((mapunderneath<30) || ((x%2==0) && (mapunderneath==30))){
514       if(g.gamemap.groundheight[x/2]<GAME_HEIGHT-5){ // firtree
515         g.gamemap.b[x] = FIRTREE;
516         g.gamemap.b[x].y = g.gamemap.groundheight[x/2] - 24;
517       }else{ // palmtree
518         g.gamemap.b[x] = PALMTREE;
519         g.gamemap.b[x].y = g.gamemap.groundheight[x/2] - 16;
520       }
521       g.gamemap.b[x].x = x * 16 - 8;
522       n--;
523     }
524     spaces--;
525   }
526 
527 }
528 
529 // Draw mapblocks
draw_mapblocks(int image[MAP_W][MAP_H],SDL_Surface * gamescreen,shape images[])530 void draw_mapblocks(int image[MAP_W][MAP_H], SDL_Surface *gamescreen,
531                     shape images[]){
532 
533   //gl_setcontext(&gamescreen);
534   for(int x=0; x<MAP_W; x++){
535     for(int y=0; y<MAP_H; y++){
536       if (image[x][y] > 0){
537         images[image[x][y]].blit(gamescreen,x*32, y*32);
538       }
539 
540     }
541   }
542 
543 
544 }
545 
546 // Draw the map onto the gamescreen
547 
draw_map(int image[MAP_W][MAP_H],SDL_Surface * gamescreen,shape images[],shape & ground)548 void draw_map(int image[MAP_W][MAP_H], SDL_Surface *gamescreen,
549               shape images[], shape &ground){
550 
551   //gl_setcontext(&gamescreen);
552 // First setup the ground collision map
553   SDL_Rect rect;
554     rect.x = 0;
555     rect.y = 0;
556     rect.w = GAME_WIDTH;
557     rect.h = GAME_HEIGHT;
558   SDL_FillRect(gamescreen, &rect, 0);
559   draw_mapblocks(image, gamescreen, images);
560   ground.grab(gamescreen, 0, 0, GAME_WIDTH, GAME_HEIGHT);
561 
562 // Now do the gamescreen properly
563 // Set the background sky blue (colour 16)
564   SDL_FillRect(gamescreen, &rect, 16);
565   draw_dither(gamescreen, 0, 0, GAME_WIDTH, GAME_HEIGHT);
566   draw_mapblocks(image, gamescreen, images);
567 
568 
569 }
570 
571 // Draw the buildings, trees and towers
572 
draw_buildings(building b[],SDL_Surface * gamescreen,shape images[])573 void draw_buildings(building b[], SDL_Surface *gamescreen, shape images[]){
574 
575   //gl_setcontext(&gamescreen);
576   for (int x=0;x<MAP_W*2;x++){
577     if ((b[x].type == 1) || (b[x].type == 3)){ // buildings and trees
578       //images[b[x].image].blit(gamescreen,b[x].x,b[x].y);
579       images[b[x].image].blit(gamescreen,b[x].x,b[x].y);
580 
581     }
582     if (b[x].type == 2){ // tower
583       images[196].blit(gamescreen,b[x].x,b[x].y);
584       for (int y=1;y<=b[x].towersize;y++){
585          images[197].blit(gamescreen,b[x].x,b[x].y-16*y);
586       }
587     }
588   }
589 
590 }
591 
592 // Draw the runways
593 
draw_runways(airbase base[],int planes,int groundheight[],SDL_Surface * gamescreen)594 void draw_runways(airbase base[], int planes, int groundheight[],
595                  SDL_Surface *gamescreen){
596 
597   //gl_setcontext(&gamescreen);
598   for(int n=1;n<=planes;n++){
599     /*gl_fillbox(base[n].mapx*32+base[n].runwayx, groundheight[base[n].mapx]-1,
600                base[n].runwaylength,2,3);*/
601     SDL_Rect rect;
602       rect.x = base[n].mapx*32+base[n].runwayx;
603       rect.y = groundheight[base[n].mapx]-1;
604       rect.w = base[n].runwaylength;
605       rect.h = 2;
606     SDL_FillRect(gamescreen, &rect, 3);
607     for(int m=0;m<base[n].runwaylength/16;m++){
608       /*gl_hline(base[n].mapx*32+base[n].runwayx+m*16+4,
609                groundheight[base[n].mapx]-1,
610                base[n].mapx*32+base[n].runwayx+m*16+12,1);*/
611       SDL_Rect rect;
612         rect.x = base[n].mapx*32+base[n].runwayx+m*16+4;
613         rect.y = groundheight[base[n].mapx]-1;
614         rect.w = 8;
615         rect.h = 1;
616       SDL_FillRect(gamescreen,&rect,1);
617     }
618   }
619 
620 }
621 
622 // Setup intelligence maps
623 
setup_intelligence(map & gamemap)624 void setup_intelligence(map &gamemap){
625 
626 // Setup realheight map
627   for(int x=0;x<=MAP_W*2;x++){
628     if ((x>1) && (x<=MAP_W*2-2)){
629       gamemap.realheight[x] = gamemap.groundheight[x/2] - 16;
630       if (gamemap.b[x].type > 0) gamemap.realheight[x] -= 24;
631       if (gamemap.b[x].type == 2){
632         gamemap.realheight[x] -= (gamemap.b[x].towersize*16);
633       }
634       if (gamemap.realheight[x] < 0) gamemap.realheight[x] = 0;
635     }else{
636       gamemap.realheight[x] = GAME_HEIGHT;
637     }
638     gamemap.smoothheight[x] = gamemap.realheight[x];
639     gamemap.steepheight[x] = gamemap.realheight[x];
640   }
641 // Construct smoothmap
642   int x1 = 1;
643   do{
644     while(gamemap.smoothheight[x1-1]-gamemap.smoothheight[x1] > 16){
645       gamemap.smoothheight[x1-1] = gamemap.smoothheight[x1]+16;
646       x1--;
647     }
648     if(gamemap.smoothheight[x1+1]-gamemap.smoothheight[x1] > 16){
649       gamemap.smoothheight[x1+1] = gamemap.smoothheight[x1]+16;
650     }
651     x1++;
652   }while (x1 < MAP_W*2);
653 // Construct steepmap
654   x1 = 1;
655   do{
656     while(gamemap.steepheight[x1-1]-gamemap.steepheight[x1] > 32){
657       gamemap.steepheight[x1-1] = gamemap.steepheight[x1]+32;
658       x1--;
659     }
660     if(gamemap.steepheight[x1+1]-gamemap.steepheight[x1] > 32){
661       gamemap.steepheight[x1+1] = gamemap.steepheight[x1]+32;
662     }
663     x1++;
664   }while (x1 < MAP_W*2);
665 
666 }
667 
668 // Draw dither in specified box located at position x,y
669 // NB draws only on existing sky blue
670 
draw_dither(SDL_Surface * gamescreen,int xbox,int ybox,int w,int h)671 void draw_dither(SDL_Surface *gamescreen,
672                  int xbox, int ybox, int w, int h){
673 
674   //gl_setcontext(&gamescreen);
675 
676 // Plot dither
677   if( SDL_MUSTLOCK(gamescreen) != 0 )
678     SDL_LockSurface(gamescreen);
679   Uint8 *pixels = (Uint8 *)gamescreen->pixels;
680   int xstart = limit(xbox, 0, GAME_WIDTH);
681   int xend = limit(xbox+w, 0, GAME_WIDTH);
682   int ystart = limit(ybox, 0, GAME_HEIGHT);
683   int yend = limit(ybox+h, 0, GAME_HEIGHT);
684   for (int x=xstart; x<xend;x++){
685     for (int y=ystart;y<yend;y++){
686       if( x < 0 || x >= GAME_WIDTH || y < 0 || y >= GAME_HEIGHT ) {
687         printf("!\n");
688       }
689       int getcolour = pixels[y * gamescreen->pitch + x];
690       if ((getcolour == 9) || (getcolour == 16)){ // If skyblue
691         double ditherfactor = double(y) * 25.0 / (GAME_HEIGHT-32);
692         int colour = 40 - int(ditherfactor);
693         double chance = ditherfactor - int(ditherfactor);
694         if (drand()<chance) colour--;
695         if (colour < 16) colour = 16;
696         pixels[y * gamescreen->pitch + x] = colour;
697       }
698     }
699   }
700   if( SDL_MUSTLOCK(gamescreen) != 0 )
701     SDL_UnlockSurface(gamescreen);
702 
703 }
704 
705 // Setup planes
706 
setup_planes(linkedlist<plane> & p,linkedlist<planeclone> & dp,airbase base[],int planes,info planeinfo[],plane * & player1,plane * & player2)707 void setup_planes(linkedlist <plane> &p, linkedlist <planeclone> &dp,
708                   airbase base[], int planes, info planeinfo[],
709                   plane* &player1, plane* &player2){
710 
711   p.reset();
712   dp.reset();
713   player1 = 0;
714   player2 = 0;
715 
716   for (int n=1;n<=planes;n++){
717 // Create plane
718     plane newplane;
719     switch(planeinfo[n].planetype){
720       case 1:
721         newplane = SPITFIRE;
722         break;
723       case 2:
724         newplane = JET;
725         break;
726       case 3:
727         newplane = STEALTH;
728         break;
729     }
730     newplane.x = base[n].planex;
731     newplane.y = base[n].planey;
732     newplane.d = base[n].planed;
733     newplane.control = planeinfo[n].control;
734     newplane.id = n;
735     newplane.side = n;
736     node <plane> * planenode = p.add(newplane);
737 // Create planeclone
738     planeclone newclone;
739     newclone.x = newplane.x;
740     newclone.y = newplane.y;
741     newclone.xs = newplane.xs;
742     newclone.ys = newplane.ys;
743     newclone.d = newplane.d;
744     newclone.image = newplane.image;
745     newclone.state = 0;
746     newclone.hide = false;
747     newclone.id = newplane.id;
748     newclone.side = newplane.side;
749     newclone.collide = false;
750     newclone.scoreloss = 0;
751     newclone.buildingwin = 0;
752 
753     for (int i=1;i<=planes;i++){
754        if (i != n){
755          for(int x=0;x<=(base[i].size+1)*2;x++){
756            if (base[i].buildlist[x].type != 0){
757              newclone.buildingwin ++;
758            }
759          }
760        }
761     }
762     dp.add(newclone);
763 // Set player pointers
764     if (planeinfo[n].control == 1) player1 = &(planenode->value);
765     if (planeinfo[n].control == 2) player2 = &(planenode->value);
766   }
767 
768 }
769 
770 // Main game setup routine
771 
setup_game(gamedata & g)772 void setup_game(gamedata &g){
773 
774   create_airbases(g.base, g.planeinfo, g.planes);
775   bool flatground[MAP_W*2];
776   setup_map(g.gamemap, g.planes, g.base, flatground);
777   setup_buildings(g, flatground);
778   setup_intelligence(g.gamemap);
779 
780   draw_map(g.gamemap.image, g.gamescreen, g.images, g.gamemap.ground);
781   draw_buildings(g.gamemap.b, g.gamescreen, g.images);
782   draw_runways(g.base, g.planes, g.gamemap.groundheight, g.gamescreen);
783   setup_planes(g.p, g.dp, g.base, g.planes, g.planeinfo, g.player1, g.player2);
784 
785 // Drak options
786   g.drak = ((g.drakoption == 2) || ((g.drakoption == 1) && (int(drand()*20) == 10)));
787   if (g.drak){
788     setup_draks(g.drakms, g.drakgun);
789   }else{
790     g.drakms.exist = 0;
791   }
792 
793 // Reset winner flag
794   g.winner = 0;
795 
796 }
797 
798