1 /*
2 **
3 ** INIT.C
4 **
5 */
6
7 #include <stdio.h>
8 #include <math.h>
9 #include <stdlib.h>
10 #include <time.h>
11 #include <X11/Xlib.h>
12 #include <X11/Xutil.h>
13
14 #include "oids.h"
15 #include "bitmaps.h"
16
17 struct linkage link = { 0 };
18
19 /*
20 ** MAIN_MENU
21 **
22 */
main_menu()23 void main_menu()
24 {
25
26 int slc, c, y, i;
27
28 X_frontbuf();
29 X_clear();
30
31 slc = 1;
32
33 do {
34
35 X_color(BLUE);
36
37 X_string("X O I D S !", (int) (vdevice.sizeSy / 5));
38
39 for (i=0;i<mm_num_items;i++) {
40 if (i == slc) {
41 X_color(WHITE);
42 } else {
43 X_color(RED);
44 }
45 y = (int) (vdevice.sizeSy / 3 + (vdevice.sizeSy / 20) * i);
46 X_string(mm_items[i], y);
47 }
48
49 c = X_get_menu_keys();
50
51 switch (c) {
52
53 case UPARROW:
54 if (--slc < 0) slc = mm_num_items - 1;
55 break;
56 case DOWNARROW:
57 if (++slc > mm_num_items - 1) slc = 0;
58 break;
59 default:
60 break;
61 }
62
63 if (c == ENTER && slc == 3) {
64 options_menu();
65 c = 0;
66 }
67
68 X_update(0);
69
70 } while (c != ENTER);
71
72 switch (slc) {
73
74 case 0:
75 num_players = 1;
76 P->lives = 5;
77 P->next = P->next_draw = NULL;
78 coop = 0;
79 break;
80 case 1:
81 num_players = 2;
82 P->next = P->next_draw = &P[1];
83 coop = 0;
84 break;
85 case 2:
86 num_players = 2;
87 P->next = P->next_draw = &P[1];
88 coop = 1;
89 P->x = (int) link.length * sin(link.ang) + link.x;
90 P->y = (int) link.length * cos(link.ang) + link.y;
91 P->next->x = link.x - (int) link.length * sin(link.ang);
92 P->next->y = link.y - (int) link.length * cos(link.ang);
93 break;
94 case 3:
95 break;
96 case 4:
97 X_exit();
98 exit(0);
99 break;
100 default:
101 break;
102 }
103
104 X_clear();
105 X_backbuf();
106
107 } /* end MAIN_MENU */
108
109
110
111 /*
112 ** OPTIONS_MENU
113 **
114 */
options_menu()115 void options_menu()
116 {
117
118 int slc, c, y, i, goal;
119 char spd_str[6], gs[50], *erase_str;
120
121 X_frontbuf();
122 X_clear();
123
124 slc = 0;
125 goal = goal_score;
126
127 do {
128
129 X_color(BLUE);
130
131 X_string("O P T I O N S", (int) (vdevice.sizeSy / 5));
132 X_string("(Use arrow keys and ENTER to select)", (int) (vdevice.sizeSy / 5 + 25));
133
134 sprintf(spd_str, "%d%%", 100 - (int) (delay / 20));
135 sprintf(gs, "%s", goal_str[goal]);
136
137 for (i=0;i<om_num_items;i++) {
138 if (i == slc) {
139 X_color(WHITE);
140 } else {
141 X_color(RED);
142 }
143 y = (int) (vdevice.sizeSy / 3 + (vdevice.sizeSy / 10) * i);
144 X_string(om_items[i], y);
145
146 if (i == 0) X_string(spd_str, y + (int) (vdevice.sizeSy / 20));
147 if (i == 1) X_string(gs, y + (int) (vdevice.sizeSy / 20));
148
149 }
150
151 c = X_get_menu_keys();
152
153 switch (c) {
154
155 case UPARROW:
156 if (--slc < 0) slc = om_num_items - 1;
157 break;
158 case DOWNARROW:
159 if (++slc > om_num_items - 1) slc = 0;
160 break;
161 case LEFTARROW:
162 if (slc == 0 && delay < 2000) {
163 delay += 20;
164 erase_str = spd_str;
165 }
166
167 if (slc == 1) {
168 if (--goal < 0) goal = 3;
169 erase_str = gs;
170 }
171
172 break;
173 case RIGHTARROW:
174 if (slc == 0 && delay > 0) {
175 delay -= 20;
176 erase_str = spd_str;
177 }
178
179 if (slc == 1) {
180 if (++goal > 3) goal = 0;
181 erase_str = gs;
182 }
183
184 break;
185 default:
186 break;
187 }
188
189 if (slc < 2 && (c == LEFTARROW || c == RIGHTARROW)) {
190 y = (int) (vdevice.sizeSy / 3 + (vdevice.sizeSy / 10) * slc);
191 X_color(BLACK);
192 X_string(erase_str, y + (int) (vdevice.sizeSy / 20));
193 }
194
195 X_update(0);
196
197 } while (!(c == ENTER && slc == om_num_items-1));
198
199 goal_score = goal;
200
201 X_clear();
202
203 } /* end OPTIONS_MENU */
204
205
206 /*
207 ** INIT_ALL_OBJECTS
208 **
209 */
init_all_objects(pass)210 void init_all_objects(pass)
211 int pass;
212 {
213
214 int i,j;
215
216
217 /* Call the "random" number generator a few times */
218
219 for (i=0;i<30;i++) r_num = random_num(0.0, 1.0);
220
221
222 /* Starfield */
223
224 init_starfield();
225
226 /* Link */
227
228 link.length = LINK_LENGTH;
229 link.ang = PI / 4;
230 link.ang_vec = 0.0;
231 link.x = vdevice.sizeSy / 2;
232 link.y = vdevice.sizeSx / 2;
233 link.x_vec = 0.0;
234 link.y_vec = 0.0;
235
236 /* Shards */
237
238
239 for (j=0;j<4;j++) {
240
241 if (!pass) Shrd[j] = init_object(NUM_SHARDS, MAPS_PER_360, shard1_xpm);
242
243 for (i=0;i<NUM_SHARDS;i++) {
244 Shrd[j][i].x = random_num(0.0, (float) vdevice.sizeSx);
245 Shrd[j][i].y = random_num(0.0, (float) vdevice.sizeSy);
246 Shrd[j][i].rotation = i*2+1;
247 Shrd[j][i].max_dying = (unsigned int) random_num((float) CARNAGE_LIFE, (float) (CARNAGE_LIFE - CARNAGE_LIFE / 2));
248 Shrd[j][i].kill_func = kill_shard;
249 Shrd[j][i].mass = 0.2;
250 Shrd[j][i].burst_color = CYAN;
251 if (j == 1) {
252 Shrd[j][i].pixmap_data[0] = shard2_xpm;
253 Shrd[j][i].burst_color = RED;
254 } else if (j == 2) {
255 Shrd[j][i].pixmap_data[0] = wreck1_xpm;
256 Shrd[j][i].burst_color = GREEN;
257 } else if (j == 3) {
258 Shrd[j][i].pixmap_data[0] = bolt_xpm;
259 Shrd[j][i].burst_color = BLUE;
260 }
261 }
262
263 if (!pass) X_spin_pixmap360(Shrd[j]);
264
265 }
266
267
268 /* Player */
269
270
271 if (!pass) P = init_object(MAX_PLAYERS, MAPS_PER_360, player1_xpm);
272
273 for (i=0;i<MAX_PLAYERS;i++) {
274 P[i].x = random_num(0.0, (float) vdevice.sizeSx);
275 P[i].y = random_num(0.0, (float) vdevice.sizeSy);
276
277 P[i].kill_func = explode_object;
278 if (!pass) P[i].death_sprite = Shrd[i];
279 P[i].num_death_sprites = NUM_SHARDS;
280 P[i].max_exploding = CARNAGE_LIFE + 25;
281 P[i].max_dying = DYING_TIME;
282 P[i].max_speed = P_MAX_SPEED;
283 if (!pass) P[i].S = init_shots();
284 P[i].shot_color = P[i].burst_color = CYAN;
285 P[i].value = 500;
286 P[i].score = 0;
287 P[i].shots_fired = 0;
288 P[i].shots = 0;
289 P[i].hits = 0;
290 if (!pass) sprintf(P[i].name, "Player %d", i+1);
291
292
293 }
294
295 if (!pass) X_spin_pixmap360(P);
296
297 P[1].pixmap_data[0] = player2_xpm;
298 if (!pass) X_spin_pixmap360(P->next);
299 P[1].shot_color = P[1].burst_color = YELLOW;
300
301
302 /* Slurb */
303
304
305 if (!pass) Slrb = init_object(1, MAPS_PER_360, slurb_xpm);
306
307 Slrb[0].x = random_num(0.0, (float) vdevice.sizeSx);
308 Slrb[0].y = random_num(0.0, (float) vdevice.sizeSy);
309
310 Slrb[0].kill_func = explode_object;
311 if (!pass) Slrb[0].death_sprite = Shrd[2];
312 Slrb[0].num_death_sprites = NUM_SHARDS;
313 Slrb[0].max_exploding = CARNAGE_LIFE + 25;
314 Slrb[0].max_dying = DYING_TIME;
315 Slrb[0].max_speed = P_MAX_SPEED;
316 if (!pass) Slrb[0].S = init_shots();
317 Slrb[0].shot_color = Slrb[0].burst_color = GREEN;
318 Slrb[0].value = 500;
319 Slrb[0].score = 0;
320 Slrb[0].shots_fired = 0;
321 Slrb[0].shots = 0;
322 Slrb[0].hits = 0;
323 Slrb[0].state = DEAD;
324 if (!pass) sprintf(Slrb[0].name, "Slurb");
325
326 if (!pass) X_spin_pixmap360(Slrb);
327
328
329 /* Homer */
330
331 if (!pass) Homer = init_object(1, MAPS_PER_360, homer_xpm);
332
333 Homer[0].x = random_num(0.0, (float) vdevice.sizeSx);
334 Homer[0].y = random_num(0.0, (float) vdevice.sizeSy);
335
336 Homer[0].kill_func = destroy_homer;
337 if (!pass) Homer[0].death_sprite = NULL;
338 Homer[0].num_death_sprites = 0;
339 Homer[0].max_exploding = 0;
340 Homer[0].rotation = 0;
341 Homer[0].max_dying = 0;
342 Homer[0].max_speed = H_MAX_SPEED;
343 if (!pass) Homer[0].S = NULL;
344 Homer[0].shot_color = Homer[0].burst_color = RED;
345 Homer[0].value = 800;
346 Homer[0].score = 0;
347 Homer[0].shots_fired = 0;
348 Homer[0].shots = 0;
349 Homer[0].hits = 0;
350 Homer[0].state = DEAD;
351 if (!pass) sprintf(Homer[0].name, "Homer");
352
353 if (!pass) X_spin_pixmap360(Homer);
354
355
356 /* Resurrector */
357
358 if (!pass) Resur = init_object(1, MAPS_PER_360, resurr_xpm);
359
360 Resur[0].x = random_num(0.0, (float) vdevice.sizeSx);
361 Resur[0].y = random_num(0.0, (float) vdevice.sizeSy);
362
363 Resur[0].kill_func = explode_object;
364 if (!pass) Resur[0].death_sprite = Shrd[3];
365 Resur[0].num_death_sprites = NUM_SHARDS;
366 Resur[0].max_exploding = CARNAGE_LIFE + 25;
367 Resur[0].rotation = 0;
368 Resur[0].max_dying = 0;
369 Resur[0].max_speed = P_MAX_SPEED;
370 if (!pass) Resur[0].S = NULL;
371 Resur[0].shot_color = Resur[0].burst_color = BLUE;
372 Resur[0].value = 400;
373 Resur[0].score = 0;
374 Resur[0].shots_fired = 0;
375 Resur[0].shots = 0;
376 Resur[0].hits = 0;
377 Resur[0].state = DEAD;
378 if (!pass) sprintf(Resur[0].name, "Resurrector");
379
380 if (!pass) X_spin_pixmap360(Resur);
381
382
383 /* Flame */
384
385 if (!pass) Flame = init_object(1, 2, flame1_xpm);
386
387 Flame[0].kill_func = NULL;
388 if (!pass) Flame[0].death_sprite = NULL;
389 Flame[0].num_death_sprites = 0;
390 Flame[0].max_exploding = 0;
391 Flame[0].rotation = 0;
392 Flame[0].max_dying = 0;
393 Flame[0].max_speed = 0;
394 if (!pass) Flame[0].S = NULL;
395 Flame[0].shot_color = Flame[0].burst_color = BLACK;
396 Flame[0].value = 0;
397 Flame[0].score = 0;
398 Flame[0].shots_fired = 0;
399 Flame[0].shots = 0;
400 Flame[0].hits = 0;
401 Flame[0].state = NORMAL;
402 if (!pass) sprintf(Flame[0].name, "Flame");
403 Flame[0].pixmap_data[1] = flame2_xpm;
404
405
406 /* Power Up */
407
408
409 if (!pass) Power_Up = init_object(1, 2, laser1_xpm);
410
411 Power_Up[0].x = random_num(0.0, (float) vdevice.sizeSx);
412 Power_Up[0].y = random_num(0.0, (float) vdevice.sizeSy);
413
414 Power_Up[0].kill_func = destroy_object;
415 if (!pass) Power_Up[0].death_sprite = NULL;
416 Power_Up[0].num_death_sprites = 0;
417 Power_Up[0].max_exploding = 0;
418 Power_Up[0].max_dying = 0;
419 Power_Up[0].max_speed = P_MAX_SPEED;
420 Power_Up[0].rotation = SML_OID_ROT;
421 if (!pass) Power_Up[0].S = NULL;
422 Power_Up[0].shot_color = Power_Up[0].burst_color = GREEN;
423 Power_Up[0].value = 0;
424 Power_Up[0].score = 0;
425 Power_Up[0].shots_fired = 0;
426 Power_Up[0].shots = 0;
427 Power_Up[0].hits = 0;
428 Power_Up[0].state = DEAD;
429 if (!pass) sprintf(Power_Up[0].name, "Power Up");
430
431 Power_Up[0].pixmap_data[1] = laser2_xpm;
432
433
434 /* Metamorphosis */
435
436 if (!pass) Meta = init_object(1, 1, meta_xpm);
437
438 Meta[0].x = random_num(0.0, (float) vdevice.sizeSx);
439 Meta[0].y = random_num(0.0, (float) vdevice.sizeSy);
440
441 Meta[0].kill_func = destroy_object;
442 if (!pass) Meta[0].death_sprite = NULL;
443 Meta[0].num_death_sprites = 0;
444 Meta[0].max_exploding = 0;
445 Meta[0].max_dying = 0;
446 Meta[0].max_speed = P_MAX_SPEED;
447 Meta[0].rotation = 0;
448 if (!pass) Meta[0].S = NULL;
449 Meta[0].shot_color = Meta[0].burst_color = BLUE;
450 Meta[0].value = 0;
451 Meta[0].score = 0;
452 Meta[0].shots_fired = 0;
453 Meta[0].shots = 0;
454 Meta[0].hits = 0;
455 Meta[0].state = DEAD;
456 if (!pass) sprintf(Meta[0].name, "Metamorphosis");
457
458
459
460 /* Small Oids */
461
462
463 for (j=0;j<MAX_BIG_OIDS * OID_DIVIDE;j++) {
464
465 if (!pass) Sml_O[j] = init_object(OID_DIVIDE, OIDS_PER_360, sml_oid_xpm);
466
467 for (i=0;i<OID_DIVIDE;i++) {
468
469 Sml_O[j][i].y_vec = 4.0 * random_num(-2.0, 2.0);
470 Sml_O[j][i].x_vec = 4.0 * random_num(-2.0, 2.0);
471
472 Sml_O[j][i].rotation = SML_OID_ROT;
473 Sml_O[j][i].max_speed = SO_MAX_SPEED;
474 Sml_O[j][i].state = NORMAL;
475
476 Sml_O[j][i].kill_func = destroy_oid;
477
478 Sml_O[j][i].curr_map = (int) random_num(0.0, (float) OIDS_PER_360 - 2);
479 Sml_O[j][i].mass = 1;
480
481 Sml_O[j][i].value = 400;
482
483 Sml_O[j][i].burst_color = WHITE;
484
485 }
486
487 if (!pass) X_spin_pixmap360(Sml_O[j]);
488
489 }
490
491
492
493 /* Medium Oids */
494
495
496 for (j=0;j<MAX_BIG_OIDS;j++) {
497
498 if (!pass) Med_O[j] = init_object(OID_DIVIDE, OIDS_PER_360, med_oid_xpm);
499
500 for (i=0;i<OID_DIVIDE;i++) {
501
502 Med_O[j][i].y_vec = 2.0 * random_num(-2.0, 2.0);
503 Med_O[j][i].x_vec = 2.0 * random_num(-2.0, 2.0);
504
505 Med_O[j][i].rotation = MED_OID_ROT;
506 Med_O[j][i].max_speed = MO_MAX_SPEED;
507 Med_O[j][i].state = NORMAL;
508
509 Med_O[j][i].kill_func = destroy_oid;
510
511 if (!pass) Med_O[j][i].death_sprite = Sml_O[j * OID_DIVIDE + i];
512 Med_O[j][i].num_death_sprites = OID_DIVIDE;
513 Med_O[j][i].max_exploding = 2000;
514
515 Med_O[j][i].curr_map = (int) random_num(0.0, (float) OIDS_PER_360 - 2);
516 Med_O[j][i].mass = 3;
517
518 Med_O[j][i].value = 200;
519
520 Med_O[j][i].burst_color = WHITE;
521
522 }
523
524 if (!pass) X_spin_pixmap360(Med_O[j]);
525
526 }
527
528
529
530
531 /* Big Oids */
532
533
534 if (!pass) Big_O = init_object(MAX_BIG_OIDS, OIDS_PER_360, big_oid_xpm);
535
536
537 for (i=0;i<MAX_BIG_OIDS;i++) {
538
539 /* Don't want oids TOO close to player at start! */
540
541 Big_O[i].x = random_num(0.0, (float) vdevice.sizeSx);
542 Big_O[i].y = random_num(0.0, (float) vdevice.sizeSy);
543
544 Big_O[i].y_vec = random_num(-2.0, 2.0);
545 Big_O[i].x_vec = random_num(-2.0, 2.0);
546
547 Big_O[i].rotation = BIG_OID_ROT;
548 Big_O[i].max_speed = BO_MAX_SPEED;
549 Big_O[i].state = NORMAL;
550
551 Big_O[i].kill_func = destroy_oid;
552
553 if (!pass) Big_O[i].death_sprite = Med_O[i];
554 Big_O[i].num_death_sprites = OID_DIVIDE;
555 Big_O[i].max_exploding = 2000;
556
557 Big_O[i].curr_map = (int) random_num(0.0, (float) OIDS_PER_360 - 2);
558 Big_O[i].mass = 5;
559
560 Big_O[i].value = 100;
561
562 Big_O[i].burst_color = WHITE;
563
564 }
565
566 for (i=INIT_BIG_OIDS;i<MAX_BIG_OIDS;i++) Big_O[i].state = DEAD;
567
568 if (!pass) {
569 X_spin_pixmap360(Big_O);
570 }
571
572
573 } /* end INIT_ALL_OBJECTS */
574
575
576 /*
577 ** INIT_OBJECT
578 **
579 ** Sets default properties of an object.
580 */
init_object(elems,n_maps,data)581 Sprite *init_object(elems, n_maps, data)
582 int elems, n_maps;
583 char **data;
584 {
585
586 int i;
587 Sprite *obj_ptr;
588
589 obj_ptr = (Sprite *) calloc(elems, sizeof(Sprite));
590
591 for (i=0;i<elems;i++) {
592
593 sscanf(data[0], "%d %d", &obj_ptr[i].width, &obj_ptr[i].height);
594
595 obj_ptr[i].ho2 = obj_ptr[i].height / 2;
596 obj_ptr[i].wo2 = obj_ptr[i].width / 2;
597
598 obj_ptr[i].pixmap_data = (char ***) calloc(n_maps, sizeof(char **));
599 obj_ptr[i].pixmaps = (Pixmap *) calloc(n_maps, sizeof(Pixmap));
600 obj_ptr[i].clipmasks = (Pixmap *) calloc(n_maps, sizeof(Pixmap));
601 obj_ptr[i].pixmap_data[0] = data;
602 obj_ptr[i].num_pixmaps = n_maps;
603
604 obj_ptr[i].delta_angle = (2*PI) / obj_ptr[i].num_pixmaps;
605
606 obj_ptr[i].num_members = elems;
607
608 obj_ptr[i].mass = 1;
609
610 obj_ptr[i].wpn = GUN;
611
612 obj_ptr[i].max_speed = 50;
613
614 obj_ptr[i].rot_dir = 2 * (int)(random_num(0.8, 2.2)) - 3;
615
616 if (i>0) {
617 obj_ptr[i-1].next = obj_ptr[i-1].next_draw = &obj_ptr[i];
618 }
619
620 }
621
622 return(obj_ptr);
623
624 } /* end INIT_OBJECT */
625
626
627 /*
628 ** INIT_SHOTS
629 **
630 */
init_shots()631 struct Shot **init_shots()
632 {
633 int i;
634 struct Shot **sh;
635
636 sh = (struct Shot **) calloc(10, sizeof(struct Shot *));
637
638 for (i=0;i<10;i++) {
639 sh[i] = (struct Shot *) calloc(1, sizeof(struct Shot));
640 }
641
642 return(sh);
643
644 } /* end INIT_SHOTS */
645
646
647
648 /*
649 ** INIT_STARFIELD
650 **
651 */
init_starfield()652 void init_starfield()
653 {
654
655 int i;
656
657 for (i=0;i<NUM_STARS;i++) {
658 starfield[i].x = (int) random_num(0.0, 600.0);
659 starfield[i].y = (int) random_num(0.0, 400.0);
660 }
661
662 } /* end INIT_STARFIELD */
663