1 // Emacs style mode select -*- C++ -*-
2 //---------------------------------------------------------------------------
3 //
4 // $Id: swinit.c,v 1.5.2.2 2003/06/08 18:16:38 fraggle Exp $
5 //
6 // Copyright(C) 1984-2000 David L. Clark
7 // Copyright(C) 2001-2003 Simon Howard
8 //
9 // This program is free software; you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License as published by the
11 // Free Software Foundation; either version 2 of the License, or (at your
12 // option) any later version. This program is distributed in the hope that
13 // it will be useful, but WITHOUT ANY WARRANTY; without even the implied
14 // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 // the GNU General Public License for more details. You should have
16 // received a copy of the GNU General Public License along with this
17 // program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 // Place - Suite 330, Boston, MA 02111-1307, USA.
19 //
20 //---------------------------------------------------------------------------
21 //
22 // swinit - SW initialization
23 //
24 //---------------------------------------------------------------------------
25
26 #include <ctype.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <time.h>
30 #include <SDL.h>
31
32 #include "pcsound.h"
33 #include "timer.h"
34 #include "video.h"
35
36 #include "sw.h"
37 #include "swasynio.h"
38 #include "swcollsn.h"
39 #include "swconf.h"
40 #include "swdisp.h"
41 #include "swend.h"
42 #include "swinit.h"
43 #include "swgames.h"
44 #include "swground.h"
45 #include "swgrpha.h"
46 #include "swmain.h"
47 #include "swmisc.h"
48 #include "swmove.h"
49 #include "swobject.h"
50 #include "swsound.h"
51 #include "swsymbol.h"
52 #include "swtitle.h"
53 #include "swutil.h"
54
55 static int savescore; /* save players score on restart */
56 static BOOL ghost; /* ghost display flag */
57 static int starting_level = 0;
58 static int conf_explosions = 1;
59
60 static char helptxt[] =
61 "\n"
62 "SDL Sopwith " VERSION "\n"
63 "Copyright (C) 1984-2000 David L. Clark\n"
64 "Copyright (C) 2001 Simon Howard\n"
65 "Copyright (C) 2012 Jesse Smith\n"
66 "\n"
67 "Usage: sopwith [options]\n"
68 "The options are:\n"
69 " -n : novice single player\n"
70 " -s : single player\n"
71 " -c : single player against computer\n"
72 " -x : enable missiles\n"
73 " -q : begin game with sound off (default)\n"
74 " -p : turn sound on\n"
75 " -g#: start at level #\n"
76 " -e : turn off big explosions\n"
77 "\n"
78 "Video:\n"
79 " -f : fullscreen\n"
80 " -2 : double scale window\n"
81 "\n"
82 #ifdef TCPIP
83 "Networking: \n"
84 " -l : listen for connection\n"
85 " -j <host> : connect to a listening host\n"
86 #endif
87 ;
88
89 // old options
90 // " -m : multiple players on a network\n"
91 //" -a : 2 players over asynchrounous communications line\n"
92 //" (Only one of -n, -s, -c, -a may be specified)\n"
93 //" -k : keyboard only\n"
94 //" -j : joystick and keyboard\n"
95 //" (Only one of -k and -j may be specified)\n"
96 //// " -i : IBM PC keyboard\n"
97 // " -r : resets the multiuser communications file after an abnormal"
98 // " end of a game"
99 // " -d*: overrides the default drive C as the device containing the"
100 // " communications file"
101 //" -p#: overrides asynchronous port 1 as the asynchrounous port\n"
102 //" to use\n"
103
initwobj()104 static void initwobj()
105 {
106 int x;
107 OBJECTS *ob;
108 OLDWDISP *ow;
109
110 ow = wdisp;
111 ob = nobjects;
112 for (x = 0; x < MAX_OBJS; ++x, ow++, ob++)
113 ow->ow_xorplot = ob->ob_drwflg = ob->ob_delflg = 0;
114
115 for (x = 0; x < MAX_TARG; ++x) {
116 ob = targets[x];
117 if (ob && ob->ob_state != FINISHED)
118 dispwobj(ob);
119 }
120
121 }
122
123
124 // sdh 28/10/2001: moved auxdisp graphic functions into swgrpha.c
125
initobjs()126 static void initobjs()
127 {
128 OBJECTS *ob;
129 int o;
130
131 topobj.ob_xnext = topobj.ob_next = &botobj;
132 botobj.ob_xprev = botobj.ob_prev = &topobj;
133 topobj.ob_x = -32767;
134 botobj.ob_x = 32767;
135
136 objbot = objtop = deltop = delbot = NULL;
137 objfree = ob = nobjects;
138
139 for (o = 0; o < MAX_OBJS; ++o) {
140 ob->ob_next = ob + 1;
141 (ob++)->ob_index = o;
142 }
143
144 (--ob)->ob_next = NULL;
145 }
146
147
initgrnd()148 static void initgrnd()
149 {
150 // sdh 16/11/200; removed movmem
151
152 memcpy(ground, orground, sizeof(GRNDTYPE) * MAX_X);
153 }
154
initseed()155 static void initseed()
156 {
157 srand(clock());
158 explseed = rand() % 65536;
159
160 // sdh 28/4/2002: removed atari and ibm code
161 }
162
163
164
165 //
166 // status bar code
167 //
168
initscore()169 static void initscore()
170 {
171 if (savescore) {
172 nobjects[0].ob_score = savescore;
173 savescore = 0;
174 }
175
176 dispscore(&nobjects[0]);
177 if (playmode == PLAYMODE_ASYNCH)
178 dispscore(&nobjects[1]);
179 }
180
181
182
183
dispgge(int x,int cury,int maxy,int clr)184 static void dispgge(int x, int cury, int maxy, int clr)
185 {
186 int y;
187
188 if (ghost)
189 return;
190
191 cury = cury * 10 / maxy - 1;
192 if (cury > 9)
193 cury = 9;
194 for (y = 0; y <= cury; ++y)
195 Vid_PlotPixel(x, y, clr);
196 for (; y <= 9; ++y)
197 Vid_PlotPixel(x, y, 0);
198 }
199
200 // sdh 26/10/2001: merged guage functions into a single function
201
dispguages(OBJECTS * ob)202 void dispguages(OBJECTS *ob)
203 {
204 int x = GUAGEX;
205 int sep = conf_missiles ? 3 : 5;
206
207 // crashes/lives
208
209 dispgge(x += sep, maxcrash - ob->ob_crashcnt, maxcrash, ob->ob_clr);
210
211 // fuel
212
213 dispgge(x += sep, ob->ob_life >> 4, MAXFUEL >> 4, ob->ob_clr);
214
215 // bombs
216
217 dispgge(x += sep, ob->ob_bombs, MAXBOMBS, 3 - ob->ob_clr);
218
219 // bullets
220
221 dispgge(x += sep, ob->ob_rounds, MAXROUNDS, 3);
222
223 if (conf_missiles) {
224
225 // missiles
226
227 dispgge(x += sep, ob->ob_missiles, MAXMISSILES, ob->ob_clr);
228
229 // starburst (flares)
230
231 dispgge(x += sep, ob->ob_bursts, MAXBURSTS, 3 - ob->ob_clr);
232 }
233 }
234
235
dispworld()236 static void dispworld()
237 {
238 int x, y, dx, maxh, sx;
239
240 dx = 0;
241 sx = SCR_CENTR;
242
243 maxh = 0;
244 y = 0;
245
246 // draw ground
247
248 for (x = 0; x < MAX_X; ++x) {
249
250 if (ground[x] > maxh)
251 maxh = ground[x];
252
253 if ((++dx) == WRLD_RSX) {
254 maxh /= WRLD_RSY;
255 if (maxh == y)
256 Vid_PlotPixel(sx, maxh, 7);
257 else if (maxh > y)
258 for (++y; y <= maxh; ++y)
259 Vid_PlotPixel(sx, y, 7);
260 else
261 for (--y; y >= maxh; --y)
262 Vid_PlotPixel(sx, y, 7);
263 y = maxh;
264 Vid_PlotPixel(sx, 0, 11);
265 ++sx;
266 dx = maxh = 0;
267 }
268 }
269
270 // map border
271
272 maxh = MAX_Y / WRLD_RSY;
273 for (y = 0; y <= maxh; ++y) {
274 Vid_PlotPixel(SCR_CENTR, y, 11);
275 Vid_PlotPixel(sx, y, 11);
276 }
277
278 // border of status bar
279
280 for (x = 0; x < SCR_WDTH; ++x)
281 Vid_PlotPixel(x, (SCR_MNSH + 2), 7);
282
283 Vid_Update();
284 }
285
286
287
initdisp(BOOL reset)288 void initdisp(BOOL reset)
289 {
290 OBJECTS *ob;
291 OBJECTS ghostob;
292
293 splatox = oxsplatted = 0;
294 if (!reset) {
295 clrdispa();
296 setadisp();
297 dispworld();
298 swtitlf();
299 ghost = FALSE;
300 }
301 movedisp();
302 setvdisp();
303 initwobj();
304 initscore();
305
306 ob = &nobjects[player];
307 if (ghost) {
308 ghostob.ob_type = DUMMYTYPE;
309 //ghostob.ob_symhgt = ghostob.ob_symwdt = 8;
310 ghostob.ob_clr = ob->ob_clr;
311 ghostob.ob_newsym = symbol_ghost; // sdh 27/6/2002
312 swputsym(GHOSTX, 12, &ghostob);
313 } else {
314 // sdh 26/10/2001: merged guages into a single function
315
316 dispguages(ob);
317 }
318 dispinit = TRUE;
319 }
320
321
322 //
323 // object creation
324 //
325
326
327 // static int inits[2] = { 0, 7 };
328 static int inits[4] = { 0, 7, 1, 6 };
329 static int initc[4] = { 0, 7, 1, 6 };
330 static int initm[8] = { 0, 7, 3, 4, 2, 5, 1, 6 };
331
332 // plane
333
initpln(OBJECTS * obp)334 OBJECTS *initpln(OBJECTS * obp)
335 {
336 OBJECTS *ob;
337 int x, height, minx, maxx, n;
338
339 if (!obp)
340 ob = allocobj();
341 else
342 ob = obp;
343
344 switch (playmode) {
345 case PLAYMODE_SINGLE:
346 case PLAYMODE_NOVICE:
347 n = inits[ob->ob_index];
348 break;
349 case PLAYMODE_ASYNCH:
350 n = initm[ob->ob_index];
351 break;
352 case PLAYMODE_COMPUTER:
353 n = initc[ob->ob_index];
354 break;
355 default:
356 return NULL;
357 }
358
359 ob->ob_type = PLANE;
360
361 ob->ob_x = currgame->gm_x[n];
362 minx = ob->ob_x;
363 maxx = ob->ob_x + 20;
364 height = 0;
365 for (x = minx; x <= maxx; ++x)
366 if (ground[x] > height)
367 height = ground[x];
368 ob->ob_y = height + 13;
369 ob->ob_lx = ob->ob_ly = ob->ob_speed = ob->ob_flaps = ob->ob_accel
370 = ob->ob_hitcount = ob->ob_bdelay = ob->ob_mdelay
371 = ob->ob_bsdelay = 0;
372 setdxdy(ob, 0, 0);
373 ob->ob_orient = currgame->gm_orient[n];
374 ob->ob_angle = (ob->ob_orient) ? (ANGLES / 2) : 0;
375 ob->ob_target = ob->ob_firing = ob->ob_mfiring = NULL;
376 ob->ob_bombing = ob->ob_bfiring = ob->ob_home = FALSE;
377 ob->ob_newsym = symbol_plane[ob->ob_orient][0]; // sdh 27/6/2002
378 //ob->ob_symhgt = SYM_HGHT;
379 //ob->ob_symwdt = SYM_WDTH;
380 ob->ob_athome = TRUE;
381 if (!obp || ob->ob_state == CRASHED
382 || ob->ob_state == GHOSTCRASHED) {
383 ob->ob_rounds = MAXROUNDS;
384 ob->ob_bombs = MAXBOMBS;
385 ob->ob_missiles = MAXMISSILES;
386 ob->ob_bursts = MAXBURSTS;
387 ob->ob_life = MAXFUEL;
388 }
389 if (!obp) {
390 ob->ob_score = ob->ob_updcount = ob->ob_crashcnt
391 = endsts[ob->ob_index] = 0;
392 compnear[ob->ob_index] = NULL;
393 insertx(ob, &topobj);
394 } else {
395 deletex(ob);
396 insertx(ob, ob->ob_xnext);
397 }
398
399 if (playmode == PLAYMODE_ASYNCH && ob->ob_crashcnt >= maxcrash) {
400 ob->ob_state = GHOST;
401 if (ob->ob_index == player)
402 ghost = TRUE;
403 } else
404 ob->ob_state = FLYING;
405
406 return (ob);
407 }
408
409
410
411 // player
412
initplyr(OBJECTS * obp)413 void initplyr(OBJECTS * obp)
414 {
415 OBJECTS *ob;
416 OBJECTS *initpln();
417
418 ob = initpln(obp);
419 if (!obp) {
420 ob->ob_drawf = dispplyr;
421 ob->ob_movef = moveplyr;
422 ob->ob_clr = ob->ob_index % 2 + 1;
423 ob->ob_owner = ob;
424 oobjects[ob->ob_index] = *ob; // sdh 16/11: removed movmem
425 goingsun = FALSE;
426 endcount = 0;
427 }
428
429 displx = ob->ob_x - SCR_CENTR;
430
431 swflush();
432 }
433
434 // computer opponent
435
initcomp(OBJECTS * obp)436 void initcomp(OBJECTS * obp)
437 {
438 OBJECTS *ob;
439 OBJECTS *initpln();
440
441 ob = initpln(obp);
442 if (!obp) {
443 ob->ob_drawf = dispcomp;
444 ob->ob_movef = movecomp;
445 ob->ob_clr = 2;
446 if (playmode != PLAYMODE_ASYNCH)
447 ob->ob_owner = &nobjects[1];
448 else if (ob->ob_index == 1)
449 ob->ob_owner = ob;
450 else
451 ob->ob_owner = ob - 2;
452 oobjects[ob->ob_index] = *ob; // sdh 16/11: removed movmem
453 }
454 if (playmode == PLAYMODE_SINGLE || playmode == PLAYMODE_NOVICE) {
455 ob->ob_state = FINISHED;
456 deletex(ob);
457 }
458 }
459
460
isrange(int x,int y,int ax,int ay)461 static int isrange(int x, int y, int ax, int ay)
462 {
463 int dx, dy, t;
464
465 dy = abs(y - ay);
466 dy += dy >> 1;
467 dx = abs(x - ax);
468
469 if (dx > 100 || dy > 100)
470 return -1;
471
472 if (dx < dy) {
473 t = dx;
474 dx = dy;
475 dy = t;
476 }
477
478 return (7 * dx + 4 * dy) / 8;
479 }
480
481 // bullet
482
initshot(OBJECTS * obop,OBJECTS * targ)483 void initshot(OBJECTS * obop, OBJECTS * targ)
484 {
485 OBJECTS *ob, *obo = obop;
486 int nangle, nspeed, dx, dy, r, bspeed, x, y;
487
488 if (!targ && !compplane && !obo->ob_rounds)
489 return;
490
491 ob = allocobj();
492
493 if (!ob)
494 return;
495
496 obo = obop;
497 if (playmode != PLAYMODE_NOVICE)
498 --obo->ob_rounds;
499
500 bspeed = BULSPEED + gamenum;
501
502 if (targ) {
503 x = targ->ob_x + (targ->ob_dx << 2);
504 y = targ->ob_y + (targ->ob_dy << 2);
505 dx = x - obo->ob_x;
506 dy = y - obo->ob_y;
507
508 r = isrange(x, y, obo->ob_x, obo->ob_y);
509 if (r < 1) {
510 deallobj(ob);
511 return;
512 }
513 ob->ob_dx = (dx * bspeed) / r;
514 ob->ob_dy = (dy * bspeed) / r;
515 ob->ob_ldx = ob->ob_ldy = 0;
516 } else {
517 nspeed = obo->ob_speed + bspeed;
518 nangle = obo->ob_angle;
519 setdxdy(ob, nspeed * COS(nangle), nspeed * SIN(nangle));
520 }
521
522 ob->ob_type = SHOT;
523 ob->ob_x = obo->ob_x + SYM_WDTH / 2;
524 ob->ob_y = obo->ob_y - SYM_HGHT / 2;
525 ob->ob_lx = obo->ob_lx;
526 ob->ob_ly = obo->ob_ly;
527
528 ob->ob_life = BULLIFE;
529 ob->ob_owner = obo;
530 ob->ob_clr = obo->ob_clr;
531 ob->ob_newsym = &symbol_pixel; // sdh 27/6/2002
532 //ob->ob_symhgt = ob->ob_symwdt = 1;
533 ob->ob_drawf = NULL;
534 ob->ob_movef = moveshot;
535 ob->ob_speed = 0;
536
537 insertx(ob, obo);
538
539 }
540
541 // bomb
542
initbomb(OBJECTS * obop)543 void initbomb(OBJECTS * obop)
544 {
545 OBJECTS *ob, *obo = obop;
546 int angle;
547
548 if ((!compplane && !obo->ob_bombs) || obo->ob_bdelay)
549 return;
550
551 ob = allocobj();
552 if (!ob)
553 return;
554
555 if (playmode != PLAYMODE_NOVICE)
556 --obo->ob_bombs;
557
558 obo->ob_bdelay = 10;
559
560 ob->ob_type = BOMB;
561 ob->ob_state = FALLING;
562 ob->ob_dx = obo->ob_dx;
563 ob->ob_dy = obo->ob_dy;
564
565 if (obo->ob_orient)
566 angle = (obo->ob_angle + (ANGLES / 4)) % ANGLES;
567 else
568 angle = (obo->ob_angle + (3 * ANGLES / 4)) % ANGLES;
569
570 ob->ob_x = obo->ob_x + ((COS(angle) * 10) >> 8) + 4;
571 ob->ob_y = obo->ob_y + ((SIN(angle) * 10) >> 8) - 4;
572 ob->ob_lx = ob->ob_ly = ob->ob_ldx = ob->ob_ldy = 0;
573
574 ob->ob_life = BOMBLIFE;
575 ob->ob_owner = obo;
576 ob->ob_clr = obo->ob_clr;
577 ob->ob_newsym = symbol_bomb[0]; // sdh 27/6/2002
578 //ob->ob_symhgt = ob->ob_symwdt = 8;
579 ob->ob_drawf = dispbomb;
580 ob->ob_movef = movebomb;
581
582 insertx(ob, obo);
583
584 }
585
586 // missile
587
initmiss(OBJECTS * obop)588 void initmiss(OBJECTS * obop)
589 {
590 OBJECTS *ob, *obo = obop;
591 int angle, nspeed;
592
593 if (obo->ob_mdelay || !obo->ob_missiles || !conf_missiles)
594 return;
595
596 ob = allocobj();
597 if (!ob)
598 return;
599
600 if (playmode != PLAYMODE_NOVICE)
601 --obo->ob_missiles;
602
603 obo->ob_mdelay = 5;
604
605 ob->ob_type = MISSILE;
606 ob->ob_state = FLYING;
607
608 angle = ob->ob_angle = obo->ob_angle;
609 ob->ob_x = obo->ob_x + (COS(angle) >> 4) + 4;
610 ob->ob_y = obo->ob_y + (SIN(angle) >> 4) - 4;
611 ob->ob_lx = ob->ob_ly = 0;
612 ob->ob_speed = nspeed = gmaxspeed + (gmaxspeed >> 1);
613 setdxdy(ob, nspeed * COS(angle), nspeed * SIN(angle));
614
615 ob->ob_life = MISSLIFE;
616 ob->ob_owner = obo;
617 ob->ob_clr = obo->ob_clr;
618 ob->ob_newsym = symbol_missile[0]; // sdh 27/6/2002
619 //ob->ob_symhgt = ob->ob_symwdt = 8;
620 ob->ob_drawf = dispmiss;
621 ob->ob_movef = movemiss;
622 ob->ob_target = obo->ob_mfiring;
623 ob->ob_orient = ob->ob_accel = ob->ob_flaps = 0;
624
625 insertx(ob, obo);
626
627 }
628
629
630 // starburst
631
initburst(OBJECTS * obop)632 void initburst(OBJECTS * obop)
633 {
634 OBJECTS *ob, *obo = obop;
635 int angle;
636
637 if (obo->ob_bsdelay || !obo->ob_bursts || !conf_missiles)
638 return;
639
640 ob = allocobj();
641 if (!ob)
642 return;
643
644 ob->ob_bsdelay = 5;
645
646 if (playmode != PLAYMODE_NOVICE)
647 --obo->ob_bursts;
648
649 ob->ob_type = STARBURST;
650 ob->ob_state = FALLING;
651
652 if (obo->ob_orient)
653 angle = (obo->ob_angle + (3 * ANGLES / 8)) % ANGLES;
654 else
655 angle = (obo->ob_angle + (5 * ANGLES / 8)) % ANGLES;
656
657 setdxdy(ob, gminspeed * COS(angle), gminspeed * SIN(angle));
658 ob->ob_dx += obo->ob_dx;
659 ob->ob_dy += obo->ob_dy;
660
661 ob->ob_x = obo->ob_x + ((COS(angle) * 10) >> 10) + 4;
662 ob->ob_y = obo->ob_y + ((SIN(angle) * 10) >> 10) - 4;
663 ob->ob_lx = ob->ob_ly = 0;
664
665 ob->ob_life = BURSTLIFE;
666 ob->ob_owner = obo;
667 ob->ob_clr = obo->ob_clr;
668 ob->ob_newsym = symbol_burst[0]; // sdh 27/6/2002
669 //ob->ob_symhgt = ob->ob_symwdt = 8;
670 ob->ob_drawf = dispburst;
671 ob->ob_movef = moveburst;
672
673 insertx(ob, obo);
674
675 }
676
677 // building/target
678
inittarg()679 static void inittarg()
680 {
681 OBJECTS *ob;
682 int x, i;
683 int *tx, *tt;
684 int minh, maxh, aveh, minx, maxx;
685
686 tx = currgame->gm_xtarg;
687 tt = currgame->gm_ttarg;
688
689 if (playmode != PLAYMODE_ASYNCH) {
690 numtarg[0] = 0;
691 numtarg[1] = MAX_TARG - 3;
692 } else {
693 numtarg[0] = numtarg[1] = MAX_TARG / 2;
694 }
695
696 for (i = 0; i < MAX_TARG; ++i, ++tx, ++tt) {
697 targets[i] = ob = allocobj();
698 minx = ob->ob_x = *tx;
699 maxx = ob->ob_x + 15;
700 minh = 999;
701 maxh = 0;
702 for (x = minx; x <= maxx; ++x) {
703 if (ground[x] > maxh)
704 maxh = ground[x];
705 if (ground[x] < minh)
706 minh = ground[x];
707 }
708 aveh = (minh + maxh) / 2;
709
710 while ((ob->ob_y = aveh + 16) >= MAX_Y)
711 --aveh;
712
713 for (x = minx; x <= maxx; ++x)
714 ground[x] = aveh;
715
716 ob->ob_dx = ob->ob_dy = ob->ob_lx = ob->ob_ly = ob->ob_ldx
717 = ob->ob_ldy = ob->ob_angle = ob->ob_hitcount = 0;
718 ob->ob_type = TARGET;
719 ob->ob_state = STANDING;
720 ob->ob_orient = *tt;
721 ob->ob_life = i;
722
723 if (playmode != PLAYMODE_ASYNCH)
724 ob->ob_owner =
725 &nobjects[(i < MAX_TARG / 2
726 && i > MAX_TARG / 2 - 4)
727 ? 0 : 1];
728 else
729 ob->ob_owner = &nobjects[i >= (MAX_TARG / 2)];
730 ob->ob_clr = ob->ob_owner->ob_clr;
731 ob->ob_newsym = symbol_targets[0]; // sdh 27/6/2002
732 //ob->ob_symhgt = ob->ob_symwdt = 16;
733 ob->ob_drawf = disptarg;
734 ob->ob_movef = movetarg;
735
736 insertx(ob, &topobj);
737 }
738 }
739
740 // explosion
741
initexpl(OBJECTS * obop,int small)742 void initexpl(OBJECTS * obop, int small)
743 {
744 OBJECTS *ob, *obo = obop;
745 int i, ic, speed;
746 // int life;
747 int obox, oboy, obodx, obody, oboclr;
748 obtype_t obotype;
749 BOOL mansym;
750 int orient;
751
752 obox = obo->ob_x + (obo->ob_newsym->w / 2);
753 oboy = obo->ob_y + (obo->ob_newsym->h / 2);
754 obodx = obo->ob_dx >> 2;
755 obody = obo->ob_dy >> 2;
756 oboclr = obo->ob_clr;
757
758 obotype = obo->ob_type;
759 if (obotype == TARGET && obo->ob_orient == 2) {
760 ic = 1;
761 // adding in option here for large oil tank explosions
762 // - Jesse
763 if (conf_explosions)
764 speed = gminspeed * 4 / 3;
765 else
766 speed = gminspeed;
767 } else {
768 ic = small ? 6 : 2;
769 speed = gminspeed >> ((explseed & 7) != 7);
770 }
771 mansym = obotype == PLANE
772 && (obo->ob_state == FLYING || obo->ob_state == WOUNDED);
773
774 for (i = 1; i <= 15; i += ic) {
775 ob = allocobj();
776 if (!ob)
777 return;
778
779 ob->ob_type = EXPLOSION;
780
781 setdxdy(ob, COS(i) * speed, SIN(i) * speed);
782 ob->ob_dx += obodx;
783 ob->ob_dy += obody;
784
785 ob->ob_x = obox + ob->ob_dx;
786 ob->ob_y = oboy + ob->ob_dy;
787 explseed *= ob->ob_x * ob->ob_y;
788 explseed += 7491;
789 if (!explseed)
790 explseed = 74917777;
791
792 ob->ob_life = EXPLLIFE;
793 orient = ob->ob_orient = (explseed & 0x01C0) >> 6;
794 if (mansym && (!orient || orient == 7)) {
795 mansym = orient = ob->ob_orient = 0;
796 ob->ob_dx = obodx;
797 ob->ob_dy = -gminspeed;
798 }
799
800 ob->ob_lx = ob->ob_ly = ob->ob_hitcount = ob->ob_speed = 0;
801 ob->ob_owner = obo;
802 ob->ob_clr = oboclr;
803 ob->ob_newsym = symbol_debris[0]; // sdh 27/6/2002
804 //ob->ob_symhgt = ob->ob_symwdt = 8;
805 ob->ob_drawf = dispexpl;
806 ob->ob_movef = moveexpl;
807
808 if (orient)
809 initsound(ob, S_EXPLOSION);
810
811 insertx(ob, obo);
812 }
813 }
814
815 // smoke from falling plane
816
initsmok(OBJECTS * obop)817 void initsmok(OBJECTS * obop)
818 {
819 OBJECTS *ob, *obo=obop;
820
821 ob = allocobj();
822 if (!ob)
823 return;
824
825 ob->ob_type = SMOKE;
826
827 ob->ob_x = obo->ob_x + 8;
828 ob->ob_y = obo->ob_y - 8;
829 ob->ob_dx = obo->ob_dx;
830 ob->ob_dy = obo->ob_dy;
831 ob->ob_lx = ob->ob_ly = ob->ob_ldx = ob->ob_ldy = 0;
832 ob->ob_life = SMOKELIFE;
833 ob->ob_owner = obo;
834 ob->ob_drawf = NULL;
835 ob->ob_movef = movesmok;
836 ob->ob_clr = obo->ob_clr;
837 }
838
839
840
841
842
843 // birds
844
initflck()845 static void initflck()
846 {
847 static int ifx[] =
848 { MINFLCKX, MINFLCKX + 1000, MAXFLCKX - 1000, MAXFLCKX };
849 static int ify[] = { MAX_Y - 1, MAX_Y - 1, MAX_Y - 1, MAX_Y - 1 };
850 static int ifdx[] = { 2, 2, -2, -2 };
851 OBJECTS *ob;
852 int i, j;
853
854 // sdh 28/10/2001: option to disable animals
855
856 if (playmode == PLAYMODE_NOVICE || !conf_animals)
857 return;
858
859 for (i = 0; i < MAX_FLCK; ++i) {
860
861 ob = allocobj();
862 if (!ob)
863 return;
864
865 ob->ob_type = FLOCK;
866 ob->ob_state = FLYING;
867 ob->ob_x = ifx[i];
868 ob->ob_y = ify[i];
869 ob->ob_dx = ifdx[i];
870 ob->ob_dy = ob->ob_lx = ob->ob_ly = ob->ob_ldx =
871 ob->ob_ldy = 0;
872 ob->ob_orient = 0;
873 ob->ob_life = FLOCKLIFE;
874 ob->ob_owner = ob;
875 ob->ob_newsym = symbol_flock[0]; // sdh 27/6/2002
876 //ob->ob_symhgt = ob->ob_symwdt = 16;
877 ob->ob_drawf = dispflck;
878 ob->ob_movef = moveflck;
879 ob->ob_clr = 9;
880 insertx(ob, &topobj);
881 for (j = 0; j < MAX_BIRD; ++j)
882 initbird(ob, 1);
883 }
884 }
885
886 // single bird
887
initbird(OBJECTS * obop,int i)888 void initbird(OBJECTS * obop, int i)
889 {
890 OBJECTS *ob, *obo = obop;
891 static int ibx[] = { 8, 3, 0, 6, 7, 14, 10, 12 };
892 static int iby[] = { 16, 1, 8, 3, 12, 10, 7, 14 };
893 static int ibdx[] = { -2, 2, -3, 3, -1, 1, 0, 0 };
894 static int ibdy[] = { -1, -2, -1, -2, -1, -2, -1, -2 };
895
896 ob = allocobj();
897 if (!ob)
898 return;
899
900 ob->ob_type = BIRD;
901
902 ob->ob_x = obo->ob_x + ibx[i];
903 ob->ob_y = obo->ob_y - iby[i];
904 ob->ob_dx = ibdx[i];
905 ob->ob_dy = ibdy[i];
906 ob->ob_orient = ob->ob_lx = ob->ob_ly = ob->ob_ldx = ob->ob_ldy =
907 0;
908 ob->ob_life = BIRDLIFE;
909 ob->ob_owner = obo;
910 ob->ob_newsym = symbol_bird[0]; // sdh 27/6/2002
911 //ob->ob_symhgt = 2;
912 //ob->ob_symwdt = 4;
913 ob->ob_drawf = dispbird;
914 ob->ob_movef = movebird;
915 ob->ob_clr = obo->ob_clr;
916 insertx(ob, obo);
917 }
918
919 // oxen
920
initoxen()921 static void initoxen()
922 {
923 OBJECTS *ob;
924 int i;
925 static int iox[] = { 1376, 1608 };
926 static int ioy[] = { 80, 91 };
927
928 // sdh 28/10/2001: option to disable animals
929
930 if (playmode == PLAYMODE_NOVICE || !conf_animals) {
931 for (i = 0; i < MAX_OXEN; ++i)
932 targets[MAX_TARG + i] = NULL;
933 return;
934 }
935
936 for (i = 0; i < MAX_OXEN; ++i) {
937 ob = allocobj();
938 if (!ob)
939 return;
940
941 targets[MAX_TARG + i] = ob;
942
943 ob->ob_type = OX;
944 ob->ob_state = STANDING;
945 ob->ob_x = iox[i];
946 ob->ob_y = ioy[i];
947 ob->ob_orient = ob->ob_lx = ob->ob_ly = ob->ob_ldx =
948 ob->ob_ldy = ob->ob_dx = ob->ob_dy = 0;
949 ob->ob_owner = ob;
950 //ob->ob_symhgt = 16;
951 //ob->ob_symwdt = 16;
952 ob->ob_newsym = symbol_ox[0]; // sdh 27/6/2002
953 ob->ob_drawf = NULL;
954 ob->ob_movef = moveox;
955 ob->ob_clr = 1;
956 insertx(ob, &topobj);
957 }
958 }
959
960
961
962
initgdep()963 static void initgdep()
964 {
965 gmaxspeed = MAX_SPEED + gamenum;
966 gminspeed = MIN_SPEED + gamenum;
967
968 targrnge = 150;
969 if (gamenum < 6)
970 targrnge -= 15 * (6 - gamenum);
971 targrnge *= targrnge;
972 }
973
974 // sdh 27/10/2001: created
975
swinitlevel()976 void swinitlevel()
977 {
978 if (playmode == PLAYMODE_ASYNCH)
979 init1asy();
980
981 // sdh 16/11/2001: this needs to be reset with each new game
982 // to keep netgames in sync if we have already played
983
984 countmove = 0;
985
986 // sdh: dont carry hud splats forward from previous games
987
988 splatox = splatbird = shothole = 0;
989
990 initsndt();
991 initgrnd();
992 initobjs();
993
994 if (keydelay == -1)
995 keydelay = 1;
996
997 if (playmode == PLAYMODE_ASYNCH) {
998 maxcrash = MAXCRASH * 2;
999 init2asy();
1000 } else {
1001 maxcrash = MAXCRASH;
1002 currgame = &swgames[0];
1003
1004 // single player
1005
1006 initplyr(NULL);
1007 initcomp(NULL);
1008 initcomp(NULL);
1009 initcomp(NULL);
1010 }
1011
1012 inittarg();
1013
1014 if (currgame->gm_specf)
1015 (*currgame->gm_specf) ();
1016
1017 initdisp(NO);
1018 initflck();
1019 initoxen();
1020 initgdep();
1021
1022 inplay = TRUE;
1023 }
1024
swrestart()1025 void swrestart()
1026 {
1027 OBJECTS *ob;
1028 int inc;
1029 int time;
1030
1031 if (endsts[player] == WINNER) {
1032 ob = &nobjects[player];
1033 inc = 0;
1034 while (ob->ob_crashcnt++ < maxcrash) {
1035 ob->ob_score += (inc += 25);
1036 setvdisp();
1037 dispguages(ob);
1038 dispscore(ob);
1039
1040 Vid_Update();
1041
1042 // sdh 27/10/2001: use new time code for delay
1043
1044 time = Timer_GetMS();
1045 while(Timer_GetMS() < time + 200);
1046 }
1047 ++gamenum;
1048 savescore = ob->ob_score;
1049 } else {
1050 // gamenum = 0;
1051 // allow variable start level -- Jesse
1052 gamenum = starting_level;
1053 savescore = 0;
1054
1055 // sh 28/10/2001: go back to the title screen
1056
1057 playmode = PLAYMODE_UNSET;
1058 }
1059
1060 // sdh 27/10/2001: moved all level init stuff into swinitlevel
1061
1062 longjmp(envrestart, 0);
1063 }
1064
1065 // global argv/argc
1066
1067 int g_argc;
1068 char **g_argv;
1069
1070 // init game
1071
swinit(int argc,char * argv[])1072 void swinit(int argc, char *argv[])
1073 {
1074 BOOL n = FALSE;
1075 BOOL s = FALSE;
1076 BOOL c = FALSE;
1077 BOOL a = FALSE;
1078 BOOL k = FALSE;
1079 int modeset = 0, keyset;
1080 int i;
1081
1082 // store global argc/argv
1083
1084 g_argc = argc;
1085 g_argv = argv;
1086
1087 #if 0
1088 // old getflags code
1089 if (getflags(&argc, &argv,
1090 /*---- 96/12/27------
1091 "n&s&c&m&a&k&i&j&q&h*v*r&d*f*n*t#w&y#e&g#x&:",
1092 &n, &s, &c, &m, &a, &k, &ibmkeybd, &joystick, &soundflg,
1093 &histout, &histin, &reset, &device,
1094 &multfile, &cmndfile, &multtick, &hires, &keydelay,
1095 &repflag, &gamenum, &missok )
1096 ------ 96/12/27----*/
1097 /*---- 99/01/24------
1098 "n&s&c&m&a&k&j&q&h*v*r&d*f*t#w&y#e&g#x&:",
1099 &n, &s, &c, &m, &a, &k, &joystick, &soundflg,
1100 &histout, &histin, &reset, &device,
1101 &multfile, &multtick, &hires, &keydelay,
1102 &repflag, &gamenum, &missok )
1103 ------ 99/01/24----*/
1104 "n&s&c&a&k&j&q&x&:",
1105 &n, &s, &c, &a, &k, &joystick, &soundflg,
1106 &missok) || ((modeset = n + s + c + a) > 1)
1107 || ((keyset = joystick + k) > 1)) {
1108 disphelp(helptxt);
1109 exit(1);
1110 }
1111 #endif
1112
1113 // sdh 29/10/2001: load config from configuration file
1114
1115 soundflg = 1; // assume off by default
1116 swloadconf();
1117
1118 for (i=1; i<argc; ++i) {
1119 if (!strcasecmp(argv[i], "-n"))
1120 n = 1;
1121 else if (!strcasecmp(argv[i], "-s"))
1122 s = 1;
1123 else if (!strcasecmp(argv[i], "-c"))
1124 c = 1;
1125 else if (!strcasecmp(argv[i], "-f"))
1126 vid_fullscreen = 1;
1127 else if (!strncasecmp(argv[i], "-g", 2))
1128 {
1129 sscanf(& (argv[i][2]), "%d", &starting_level);
1130 gamenum = starting_level;
1131 }
1132 else if (!strcasecmp(argv[i], "-2"))
1133 vid_double_size = 1;
1134 else if (!strcasecmp(argv[i], "-q"))
1135 soundflg = 1;
1136 else if (!strcasecmp(argv[i], "-p"))
1137 soundflg = 0;
1138 else if (!strcasecmp(argv[i], "-x"))
1139 conf_missiles = 1;
1140 else if (!strcasecmp(argv[i], "-e"))
1141 conf_explosions = 0;
1142 else
1143 #ifdef TCPIP
1144 if (!strcasecmp(argv[i], "-l")) {
1145 a = 1;
1146 asynmode = ASYN_LISTEN;
1147 } else if (!strcasecmp(argv[i], "-j")) {
1148 if (++i < argc) {
1149 a = 1;
1150 asynmode = ASYN_CONNECT;
1151 strcpy(asynhost, argv[i]);
1152 } else {
1153 fprintf(stderr, "insufficient arguments to -j\n");
1154 exit(-1);
1155 }
1156 } else
1157 #endif
1158 {
1159 puts(helptxt);
1160 exit(0);
1161 }
1162 }
1163
1164 modeset = n | s | c | a;
1165 keyset = joystick + k;
1166
1167 soundflg = !soundflg;
1168 if (modeset && keyset)
1169 titleflg = TRUE;
1170
1171 movemax = 15;
1172 initseed();
1173
1174 // sdh 27/6/2002: generate symbol objects
1175
1176 symbol_generate();
1177
1178 // initialise video
1179
1180 Vid_Init();
1181 Vid_SetBuf();
1182
1183 // dont init speaker if started with -q (quiet)
1184 if (soundflg)
1185 Speaker_Init(); // init pc speaker
1186
1187 // explseed = histinit( explseed );
1188 initsndt();
1189 initgrnd(); // needed for title screen
1190
1191 // sdh 26/03/2002: remove swinitgrph
1192
1193 // set playmode if we can, from command line options
1194
1195 playmode =
1196 n ? PLAYMODE_NOVICE :
1197 s ? PLAYMODE_SINGLE :
1198 c ? PLAYMODE_COMPUTER :
1199 a ? PLAYMODE_ASYNCH :
1200 PLAYMODE_UNSET;
1201
1202 // sdh 28/10/2001: moved getmode into swmain
1203 // sdh 27/10/2001: moved all level init stuff into swinitlevel
1204
1205 // make mouse disappear
1206 SDL_ShowCursor(SDL_DISABLE);
1207 }
1208
1209 //---------------------------------------------------------------------------
1210 //
1211 // $Log: swinit.c,v $
1212 // Revision 1.5.2.2 2003/06/08 18:16:38 fraggle
1213 // Fix networking and some compile bugs
1214 //
1215 // Revision 1.5.2.1 2003/06/08 17:08:17 fraggle
1216 // Fix variable declared in wrong place
1217 //
1218 // Revision 1.5 2003/06/04 17:13:26 fraggle
1219 // Remove disprx, as it is implied from displx anyway.
1220 //
1221 // Revision 1.4 2003/06/04 15:33:53 fraggle
1222 // Store global argc/argv for gtk_init
1223 //
1224 // Revision 1.3 2003/04/05 22:44:04 fraggle
1225 // Remove some useless functions from headers, make them static if they
1226 // are not used by other files
1227 //
1228 // Revision 1.2 2003/04/05 22:31:29 fraggle
1229 // Remove PLAYMODE_MULTIPLE and swnetio.c
1230 //
1231 // Revision 1.1.1.1 2003/02/14 19:03:13 fraggle
1232 // Initial Sourceforge CVS import
1233 //
1234 //
1235 // sdh 14/2/2003: change license header to GPL
1236 // sdh 27/06/2002: move symbols to new sopsym_t format,
1237 // remove references to symwdt, symhgt
1238 // sdh 27/03/2002: move old drawing functions to new ones (pntsym, pntcol)
1239 // sdh 26/03/2002: change CGA_ to Vid_
1240 // sdh 16/11/2001: TCPIP #define to disable TCP/IP support
1241 // sdh 16/11/2001: fix out of sync error
1242 // sdh 29/10/2001: load game options from config file
1243 // sdh 28/10/2001: extra game options
1244 // sdh 28/10/2001: game init restructured: swinitlevel now initialises the
1245 // level, getmode is called from main
1246 // sdh 26/10/2001: merge guages into a single function
1247 // sdh 24/10/2001: fix auxdisp buffer
1248 // sdh 23/10/2001: fixed arguments help list and rewrote argument checking
1249 // to support new network features
1250 // sdh 21/10/2001: use new obtype_t and obstate_t
1251 // sdh 21/10/2001: rearranged headers, added cvs tags
1252 // sdh 21/10/2001: reformatted with indent, adjusted some code by hand
1253 // to be more readable
1254 // sdh 19/10/2001: removed all extern definitions, these are now in headers
1255 // shuffled some functions around to shut up compiler
1256 // sdh 18/10/2001: converted all functions in this file to ANSI-style
1257 // arguments from k&r
1258 //
1259 // 2000-10-29 Copyright update.
1260 // Comment out multiplayer selection on startup.
1261 // 99-01-24 1999 copyright.
1262 // Disable network support.
1263 // 96-12-26 New network version.
1264 // Remove keyboard prompts. Speed up game a bit.
1265 // 87-04-09 Fix to initial missile path.
1266 // Delay between starbursts
1267 // 87-04-06 Computer plane avoiding oxen.
1268 // 87-04-05 Less x-movement in explosions
1269 // 87-04-04 Missile and starburst support
1270 // 87-03-31 Less x-movement in explosions
1271 // 87-03-31 Missiles
1272 // 87-03-30 Novice player.
1273 // 87-03-12 Wounded airplanes.
1274 // 87-03-11 Smaller fuel tank explosions.
1275 // 87-03-09 Microsoft compiler.
1276 // 87-01-09 BMB standard help text.
1277 // Multiple serial ports.
1278 // 85-10-31 Atari
1279 // 84-02-02 Development
1280 //
1281 //---------------------------------------------------------------------------
1282
1283