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