7eccdf50dd978223a9902a0a6089e28955015f0c
[newkind] / alg_main.c
1 /*
2 * Elite - The New Kind.
3 *
4 * Reverse engineered from the BBC disk version of Elite.
5 * Additional material by C.J.Pinder.
6 *
7 * The original Elite code is (C) I.Bell & D.Braben 1984.
8 * This version re-engineered in C by C.J.Pinder 1999-2001.
9 *
10 * email: <christian@newkind.co.uk>
11 *
12 *
13 */
14
15 /*
16 * alg_main.c
17 *
18 * Allegro version of the main game handler.
19 */
20
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <math.h>
25 #include <ctype.h>
26 #include <time.h>
27 #include <stdlib.h>
28
29 #include "allegro.h"
30
31 #include "config.h"
32 #include "gfx.h"
33 #include "main.h"
34 #include "vector.h"
35 #include "alg_data.h"
36 #include "elite.h"
37 #include "docked.h"
38 #include "intro.h"
39 #include "shipdata.h"
40 #include "shipface.h"
41 #include "space.h"
42 #include "sound.h"
43 #include "threed.h"
44 #include "swat.h"
45 #include "random.h"
46 #include "options.h"
47 #include "stars.h"
48 #include "missions.h"
49 #include "pilot.h"
50 #include "file.h"
51 #include "keyboard.h"
52
53
54
55 int old_cross_x, old_cross_y;
56 int cross_timer;
57
58 int draw_lasers;
59 int mcount;
60 int message_count;
61 char message_string[80];
62 int rolling;
63 int climbing;
64 int game_paused;
65 int have_joystick;
66 int identify;
67 int scanner_zoom = 1;
68 int remap_keys;
69
70 int find_input;
71 char find_name[20];
72
73
74
75 /*
76 * Initialise the game parameters.
77 */
78
79 void initialise_game(void)
80 {
81 set_rand_seed (time(NULL));
82 current_screen = SCR_INTRO_ONE;
83
84 restore_saved_commander();
85
86 flight_speed = 1;
87 flight_roll = 0;
88 flight_climb = 0;
89 docked = 1;
90 front_shield = 255;
91 aft_shield = 255;
92 energy = 255;
93 draw_lasers = 0;
94 mcount = 0;
95 hyper_ready = 0;
96 detonate_bomb = 0;
97 find_input = 0;
98 witchspace = 0;
99 game_paused = 0;
100 auto_pilot = 0;
101
102 create_new_stars();
103 clear_universe();
104
105 cross_x = -1;
106 cross_y = -1;
107 cross_timer = 0;
108
109
110 myship.max_speed = 40; /* 0.27 Light Mach */
111 myship.max_roll = 31;
112 myship.max_climb = 8; /* CF 8 */
113 myship.max_fuel = 70; /* 7.0 Light Years */
114 }
115
116
117 void finish_game (void)
118 {
119 finish = 1;
120 game_over = 2;
121 }
122
123
124
125
126
127
128
129 /*
130 * Move the planet chart cross hairs to specified position.
131 */
132
133
134 void move_cross (int dx, int dy)
135 {
136 cross_timer = 5;
137
138 if (kbd_ctrl_pressed) {
139 dx *= 4;
140 dy *= 4;
141 }
142
143 if (current_screen == SCR_SHORT_RANGE)
144 {
145 cross_x += (dx * 4);
146 cross_y += (dy * 4);
147 return;
148 }
149
150 if (current_screen == SCR_GALACTIC_CHART)
151 {
152 cross_x += (dx * 2);
153 cross_y += (dy * 2);
154
155 if (cross_x < 1)
156 cross_x = 1;
157
158 if (cross_x > 510)
159 cross_x = 510;
160
161 if (cross_y < 37)
162 cross_y = 37;
163
164 if (cross_y > 293)
165 cross_y = 293;
166 }
167 }
168
169
170 /*
171 * Draw the cross hairs at the specified position.
172 */
173
174 void draw_cross (int cx, int cy)
175 {
176 if (current_screen == SCR_SHORT_RANGE)
177 {
178 gfx_set_clip_region (1, 37, 510, 339);
179 xor_mode (TRUE);
180 gfx_draw_colour_line (cx - 16, cy, cx + 16, cy, GFX_COL_RED);
181 gfx_draw_colour_line (cx, cy - 16, cx, cy + 16, GFX_COL_RED);
182 xor_mode (FALSE);
183 gfx_set_clip_region (1, 1, 510, 383);
184 return;
185 }
186
187 if (current_screen == SCR_GALACTIC_CHART)
188 {
189 gfx_set_clip_region (1, 37, 510, 293);
190 xor_mode (TRUE);
191 gfx_draw_colour_line (cx - 8, cy, cx + 8, cy, GFX_COL_RED);
192 gfx_draw_colour_line (cx, cy - 8, cx, cy + 8, GFX_COL_RED);
193 xor_mode (FALSE);
194 gfx_set_clip_region (1, 1, 510, 383);
195 }
196 }
197
198
199
200 void draw_laser_sights(void)
201 {
202 int laser = 0;
203 int x1,y1,x2,y2;
204
205 switch (current_screen)
206 {
207 case SCR_FRONT_VIEW:
208 gfx_display_centre_text (32, "Front View", 120, GFX_COL_WHITE);
209 laser = cmdr.front_laser;
210 break;
211
212 case SCR_REAR_VIEW:
213 gfx_display_centre_text (32, "Rear View", 120, GFX_COL_WHITE);
214 laser = cmdr.rear_laser;
215 break;
216
217 case SCR_LEFT_VIEW:
218 gfx_display_centre_text (32, "Left View", 120, GFX_COL_WHITE);
219 laser = cmdr.left_laser;
220 break;
221
222 case SCR_RIGHT_VIEW:
223 gfx_display_centre_text (32, "Right View", 120, GFX_COL_WHITE);
224 laser = cmdr.right_laser;
225 break;
226 }
227
228
229 if (laser)
230 {
231 x1 = 128 * GFX_SCALE;
232 y1 = (96-8) * GFX_SCALE;
233 y2 = (96-16) * GFX_SCALE;
234
235 gfx_draw_colour_line (x1-1, y1, x1-1, y2, GFX_COL_GREY_1);
236 gfx_draw_colour_line (x1, y1, x1, y2, GFX_COL_WHITE);
237 gfx_draw_colour_line (x1+1, y1, x1+1, y2, GFX_COL_GREY_1);
238
239 y1 = (96+8) * GFX_SCALE;
240 y2 = (96+16) * GFX_SCALE;
241
242 gfx_draw_colour_line (x1-1, y1, x1-1, y2, GFX_COL_GREY_1);
243 gfx_draw_colour_line (x1, y1, x1, y2, GFX_COL_WHITE);
244 gfx_draw_colour_line (x1+1, y1, x1+1, y2, GFX_COL_GREY_1);
245
246 x1 = (128-8) * GFX_SCALE;
247 y1 = 96 * GFX_SCALE;
248 x2 = (128-16) * GFX_SCALE;
249
250 gfx_draw_colour_line (x1, y1-1, x2, y1-1, GFX_COL_GREY_1);
251 gfx_draw_colour_line (x1, y1, x2, y1, GFX_COL_WHITE);
252 gfx_draw_colour_line (x1, y1+1, x2, y1+1, GFX_COL_GREY_1);
253
254 x1 = (128+8) * GFX_SCALE;
255 x2 = (128+16) * GFX_SCALE;
256
257 gfx_draw_colour_line (x1, y1-1, x2, y1-1, GFX_COL_GREY_1);
258 gfx_draw_colour_line (x1, y1, x2, y1, GFX_COL_WHITE);
259 gfx_draw_colour_line (x1, y1+1, x2, y1+1, GFX_COL_GREY_1);
260 }
261 }
262
263
264 static void roll_left(void)
265 {
266 if (flight_roll < 0)
267 flight_roll = 0;
268 else
269 {
270 increase_flight_roll();
271 increase_flight_roll();
272 rolling = 1;
273 }
274 }
275
276 static void roll_right(void)
277 {
278 if (flight_roll > 0)
279 flight_roll = 0;
280 else
281 {
282 decrease_flight_roll();
283 decrease_flight_roll();
284 rolling = 1;
285 }
286 }
287
288 static void climb(void)
289 {
290 if (flight_climb < 0)
291 flight_climb = 0;
292 else
293 {
294 increase_flight_climb();
295 }
296 climbing = 1;
297 }
298
299 static void dive(void)
300 {
301 if (flight_climb > 0)
302 flight_climb = 0;
303 else
304 {
305 decrease_flight_climb();
306 }
307 climbing = 1;
308 }
309
310 void arrow_right (void)
311 {
312 switch (current_screen)
313 {
314 case SCR_MARKET_PRICES:
315 buy_stock();
316 break;
317
318 case SCR_SETTINGS:
319 select_right_setting();
320 break;
321
322 case SCR_SHORT_RANGE:
323 case SCR_GALACTIC_CHART:
324 move_cross(1, 0);
325 break;
326
327 case SCR_FRONT_VIEW:
328 roll_right();
329 break;
330 case SCR_REAR_VIEW:
331 if (remap_keys) roll_left(); else roll_right();
332 break;
333 case SCR_RIGHT_VIEW:
334 if (remap_keys) climb(); else roll_right();
335 break;
336 case SCR_LEFT_VIEW:
337 if (remap_keys) dive(); else roll_right();
338 break;
339 }
340 }
341
342
343 void arrow_left (void)
344 {
345 switch (current_screen)
346 {
347 case SCR_MARKET_PRICES:
348 sell_stock();
349 break;
350
351 case SCR_SETTINGS:
352 select_left_setting();
353 break;
354
355 case SCR_SHORT_RANGE:
356 case SCR_GALACTIC_CHART:
357 move_cross (-1, 0);
358 break;
359
360 case SCR_FRONT_VIEW:
361 roll_left();
362 break;
363 case SCR_REAR_VIEW:
364 if (remap_keys) roll_right(); else roll_left();
365 break;
366 case SCR_RIGHT_VIEW:
367 if (remap_keys) dive(); else roll_left();
368 break;
369 case SCR_LEFT_VIEW:
370 if (remap_keys) climb(); else roll_left();
371 break;
372 }
373 }
374
375
376 void arrow_up (void)
377 {
378 switch (current_screen)
379 {
380 case SCR_MARKET_PRICES:
381 select_previous_stock();
382 break;
383
384 case SCR_EQUIP_SHIP:
385 select_previous_equip();
386 break;
387
388 case SCR_OPTIONS:
389 select_previous_option();
390 break;
391
392 case SCR_SETTINGS:
393 select_up_setting();
394 break;
395
396 case SCR_SHORT_RANGE:
397 case SCR_GALACTIC_CHART:
398 move_cross (0, -1);
399 break;
400
401 case SCR_FRONT_VIEW:
402 dive();
403 break;
404 case SCR_REAR_VIEW:
405 if (remap_keys) climb(); else dive();
406 break;
407 case SCR_RIGHT_VIEW:
408 if (remap_keys) roll_right(); else dive();
409 break;
410 case SCR_LEFT_VIEW:
411 if (remap_keys) roll_left(); else dive();
412 break;
413 }
414 }
415
416
417
418 void arrow_down (void)
419 {
420 switch (current_screen)
421 {
422 case SCR_MARKET_PRICES:
423 select_next_stock();
424 break;
425
426 case SCR_EQUIP_SHIP:
427 select_next_equip();
428 break;
429
430 case SCR_OPTIONS:
431 select_next_option();
432 break;
433
434 case SCR_SETTINGS:
435 select_down_setting();
436 break;
437
438 case SCR_SHORT_RANGE:
439 case SCR_GALACTIC_CHART:
440 move_cross (0, 1);
441 break;
442
443 case SCR_FRONT_VIEW:
444 climb();
445 break;
446 case SCR_REAR_VIEW:
447 if (remap_keys) dive(); else climb();
448 break;
449 case SCR_RIGHT_VIEW:
450 if (remap_keys) roll_left(); else climb();
451 break;
452 case SCR_LEFT_VIEW:
453 if (remap_keys) roll_right(); else climb();
454 break;
455
456 }
457 }
458
459
460 void return_pressed (void)
461 {
462 switch (current_screen)
463 {
464 case SCR_EQUIP_SHIP:
465 buy_equip();
466 break;
467
468 case SCR_OPTIONS:
469 do_option();
470 break;
471
472 case SCR_SETTINGS:
473 toggle_setting();
474 break;
475 }
476 }
477
478
479 void y_pressed (void)
480 {
481 switch (current_screen)
482 {
483 case SCR_QUIT:
484 finish_game();
485 break;
486 case SCR_RESTART:
487 game_over = 2;
488 break;
489 }
490 }
491
492
493 void n_pressed (void)
494 {
495 switch (current_screen)
496 {
497 case SCR_QUIT:
498 case SCR_RESTART:
499 if (docked)
500 display_commander_status();
501 else
502 current_screen = SCR_FRONT_VIEW;
503 break;
504 }
505 }
506
507
508 void d_pressed (void)
509 {
510 switch (current_screen)
511 {
512 case SCR_GALACTIC_CHART:
513 case SCR_SHORT_RANGE:
514 show_distance_to_planet();
515 break;
516
517 case SCR_FRONT_VIEW:
518 case SCR_REAR_VIEW:
519 case SCR_RIGHT_VIEW:
520 case SCR_LEFT_VIEW:
521 if (auto_pilot)
522 disengage_auto_pilot();
523 break;
524 }
525 }
526
527
528 void f_pressed (void)
529 {
530 if ((current_screen == SCR_GALACTIC_CHART) ||
531 (current_screen == SCR_SHORT_RANGE))
532 {
533 find_input = 1;
534 *find_name = '\0';
535 gfx_clear_text_area();
536 gfx_display_text (16, 340, "Planet Name?");
537 }
538 }
539
540
541 void add_find_char (int letter)
542 {
543 char str[40];
544
545 if (strlen (find_name) == 16)
546 return;
547
548 str[0] = toupper (letter);
549 str[1] = '\0';
550 strcat (find_name, str);
551
552 sprintf (str, "Planet Name? %s", find_name);
553 gfx_clear_text_area ();
554 gfx_display_text(16, 340, str);
555 }
556
557
558 void delete_find_char (void)
559 {
560 char str[40];
561 int len;
562
563 len = strlen (find_name);
564 if (len == 0)
565 return;
566
567 find_name[len - 1] = '\0';
568
569 sprintf (str, "Planet Name? %s", find_name);
570 gfx_clear_text_area();
571 gfx_display_text(16, 340, str);
572 }
573
574 void o_pressed()
575 {
576 switch (current_screen)
577 {
578 case SCR_GALACTIC_CHART:
579 case SCR_SHORT_RANGE:
580 move_cursor_to_origin();
581 break;
582 }
583 }
584
585
586 void auto_dock (void)
587 {
588 struct univ_object ship;
589
590 ship.location.x = 0;
591 ship.location.y = 0;
592 ship.location.z = 0;
593
594 set_init_matrix (ship.rotmat);
595 ship.rotmat[2].z = 1;
596 ship.rotmat[0].x = -1;
597 ship.type = -96;
598 ship.velocity = flight_speed;
599 ship.acceleration = 0;
600 ship.bravery = 0;
601 ship.rotz = 0;
602 ship.rotx = 0;
603
604 auto_pilot_ship (&ship);
605
606 if (ship.velocity > 22)
607 flight_speed = 22;
608 else
609 flight_speed = ship.velocity;
610
611 if (ship.acceleration > 0)
612 {
613 flight_speed++;
614 if (flight_speed > 22)
615 flight_speed = 22;
616 }
617
618 if (ship.acceleration < 0)
619 {
620 flight_speed--;
621 if (flight_speed < 1)
622 flight_speed = 1;
623 }
624
625 if (ship.rotx == 0)
626 flight_climb = 0;
627
628 if (ship.rotx < 0)
629 {
630 increase_flight_climb();
631
632 if (ship.rotx < -1)
633 increase_flight_climb();
634 }
635
636 if (ship.rotx > 0)
637 {
638 decrease_flight_climb();
639
640 if (ship.rotx > 1)
641 decrease_flight_climb();
642 }
643
644 if (ship.rotz == 127)
645 flight_roll = -14;
646 else
647 {
648 if (ship.rotz == 0)
649 flight_roll = 0;
650
651 if (ship.rotz > 0)
652 {
653 increase_flight_roll();
654
655 if (ship.rotz > 1)
656 increase_flight_roll();
657 }
658
659 if (ship.rotz < 0)
660 {
661 decrease_flight_roll();
662
663 if (ship.rotz < -1)
664 decrease_flight_roll();
665 }
666 }
667 }
668
669
670 void run_escape_sequence (void)
671 {
672 int i;
673 int newship;
674 Matrix rotmat;
675
676 current_screen = SCR_ESCAPE_POD;
677
678 flight_speed = 1;
679 flight_roll = 0;
680 flight_climb = 0;
681
682 set_init_matrix (rotmat);
683 rotmat[2].z = 1.0;
684
685 newship = add_new_ship (SHIP_COBRA3, 0, 0, 200, rotmat, -127, -127);
686 universe[newship].velocity = 7;
687 snd_play_sample (SND_LAUNCH);
688
689 for (i = 0; i < 90; i++)
690 {
691 if (i == 40)
692 {
693 universe[newship].flags |= FLG_DEAD;
694 snd_play_sample (SND_EXPLODE);
695 }
696
697 gfx_set_clip_region (1, 1, 510, 383);
698 gfx_clear_display();
699 update_starfield();
700 update_universe();
701
702 universe[newship].location.x = 0;
703 universe[newship].location.y = 0;
704 universe[newship].location.z += 2;
705
706 gfx_display_centre_text (358, "Escape pod launched - Ship auto-destuct initiated.", 120, GFX_COL_WHITE);
707
708 update_console();
709 gfx_update_screen();
710 }
711
712
713 while ((ship_count[SHIP_CORIOLIS] == 0) &&
714 (ship_count[SHIP_DODEC] == 0))
715 {
716 auto_dock();
717
718 if ((abs(flight_roll) < 3) && (abs(flight_climb) < 3))
719 {
720 for (i = 0; i < MAX_UNIV_OBJECTS; i++)
721 {
722 if (universe[i].type != 0)
723 universe[i].location.z -= 1500;
724 }
725
726 }
727
728 warp_stars = 1;
729 gfx_set_clip_region (1, 1, 510, 383);
730 gfx_clear_display();
731 update_starfield();
732 update_universe();
733 update_console();
734 gfx_update_screen();
735 }
736
737 abandon_ship();
738 }
739
740 static int cheat_arg = 0;
741 static void check_cheat_keys(void)
742 {
743 int i;
744
745 if (!kbd_ctrl_pressed)
746 return;
747
748 for (i = 0; i < 10; i++) {
749 if (old_key[KEY_0 + i] == 1) {
750 cheat_arg = cheat_arg * 10 + i;
751 goto ok;
752 }
753 }
754
755 if (old_key[KEY_C] == 1)
756 goto done;
757
758 if (docked)
759 return;
760
761 if (old_key[KEY_S] == 1) {
762 if (cheat_arg < NO_OF_SHIPS) {
763 int un = create_other_ship(cheat_arg);
764 if (un != -1)
765 universe[un].flags |= FLG_TARGET;
766 goto done;
767 }
768 }
769
770 if (old_key[KEY_D] == 1) {
771 game_paused = 0;
772 snd_play_sample (SND_DOCK);
773 dock_player();
774 current_screen = SCR_BREAK_PATTERN;
775 goto done;
776 }
777
778 return;
779 done:
780 cheat_arg = 0;
781 ok:
782 snd_play_sample(SND_BEEP);
783 return;
784 }
785
786 void handle_flight_keys (void)
787 {
788 int keyasc;
789
790 if (docked &&
791 ((current_screen == SCR_MARKET_PRICES) ||
792 (current_screen == SCR_OPTIONS) ||
793 (current_screen == SCR_SETTINGS) ||
794 (current_screen == SCR_EQUIP_SHIP)))
795 kbd_read_key();
796
797 kbd_poll_keyboard();
798
799 if (have_joystick)
800 {
801 poll_joystick();
802
803 if (joy[0].stick[0].axis[1].d1)
804 arrow_up();
805
806 if (joy[0].stick[0].axis[1].d2)
807 arrow_down();
808
809 if (joy[0].stick[0].axis[0].d1)
810 arrow_left();
811
812 if (joy[0].stick[0].axis[0].d2)
813 arrow_right();
814
815 if (joy[0].button[0].b)
816 kbd_fire_pressed = 1;
817
818 if (joy[0].button[1].b)
819 kbd_inc_speed_pressed = 1;
820
821 if (joy[0].button[2].b)
822 kbd_dec_speed_pressed = 1;
823 }
824
825
826 if (game_paused)
827 {
828 if (kbd_resume_pressed)
829 game_paused = 0;
830 else
831 check_cheat_keys();
832 return;
833 }
834
835 if (kbd_F1_pressed)
836 {
837 find_input = 0;
838
839 if (docked)
840 launch_player();
841 else
842 {
843 if (current_screen != SCR_FRONT_VIEW)
844 {
845 current_screen = SCR_FRONT_VIEW;
846 flip_stars();
847 }
848 }
849 }
850
851 if (kbd_F2_pressed)
852 {
853 find_input = 0;
854
855 if (!docked)
856 {
857 if (current_screen != SCR_REAR_VIEW)
858 {
859 current_screen = SCR_REAR_VIEW;
860 flip_stars();
861 }
862 }
863 }
864
865 if (kbd_F3_pressed)
866 {
867 find_input = 0;
868
869 if (!docked)
870 {
871 if (current_screen != SCR_LEFT_VIEW)
872 {
873 current_screen = SCR_LEFT_VIEW;
874 flip_stars();
875 }
876 }
877 }
878
879 if (kbd_F4_pressed)
880 {
881 find_input = 0;
882
883 if (docked)
884 equip_ship();
885 else
886 {
887 if (current_screen != SCR_RIGHT_VIEW)
888 {
889 current_screen = SCR_RIGHT_VIEW;
890 flip_stars();
891 }
892 }
893 }
894
895
896 if (kbd_F5_pressed)
897 {
898 find_input = 0;
899 old_cross_x = -1;
900 display_galactic_chart();
901 }
902
903 if (kbd_F6_pressed)
904 {
905 find_input = 0;
906 old_cross_x = -1;
907 display_short_range_chart();
908 }
909
910 if (kbd_F7_pressed)
911 {
912 find_input = 0;
913 display_data_on_planet();
914 }
915
916 if (kbd_F8_pressed && (!witchspace))
917 {
918 find_input = 0;
919 display_market_prices();
920 }
921
922 if (kbd_F9_pressed)
923 {
924 find_input = 0;
925 display_commander_status();
926 }
927
928 if (kbd_F10_pressed)
929 {
930 find_input = 0;
931 display_inventory();
932 }
933
934 if (kbd_F11_pressed)
935 {
936 find_input = 0;
937 display_options();
938 }
939
940 if (find_input)
941 {
942 keyasc = kbd_read_key();
943
944 if (kbd_enter_pressed)
945 {
946 find_input = 0;
947 find_planet_by_name (find_name);
948 return;
949 }
950
951 if (kbd_backspace_pressed)
952 {
953 delete_find_char();
954 return;
955 }
956
957 if (isalpha(keyasc))
958 add_find_char (keyasc);
959
960 return;
961 }
962
963 if (kbd_y_pressed)
964 y_pressed();
965
966 if (kbd_n_pressed)
967 n_pressed();
968
969 if (kbd_i_pressed == 1)
970 identify = !identify;
971 if (kbd_zoom_pressed == 1)
972 scanner_zoom ^= 3;
973
974 if (kbd_fire_pressed)
975 {
976 if ((!docked) && (draw_lasers == 0))
977 draw_lasers = fire_laser();
978 }
979
980 if (kbd_dock_pressed)
981 {
982 if (!docked && cmdr.docking_computer)
983 {
984 if ((universe[1].type == SHIP_CORIOLIS ||
985 universe[1].type == SHIP_DODEC) &&
986 (universe[1].flags & FLG_ANGRY))
987 info_message("Docking permission refused");
988 else if (instant_dock)
989 engage_docking_computer();
990 else
991 engage_auto_pilot();
992 }
993 }
994
995 if (kbd_d_pressed)
996 d_pressed();
997
998 if (kbd_ecm_pressed)
999 {
1000 if (!docked && cmdr.ecm)
1001 activate_ecm(1);
1002 }
1003
1004 if (kbd_find_pressed)
1005 f_pressed ();
1006
1007 if (kbd_hyperspace_pressed && (!docked))
1008 {
1009 if (kbd_ctrl_pressed)
1010 start_galactic_hyperspace();
1011 else
1012 start_hyperspace();
1013 }
1014
1015 if (kbd_jump_pressed && (!docked) && (!witchspace))
1016 {
1017 jump_warp();
1018 }
1019
1020 if (kbd_fire_missile_pressed)
1021 {
1022 if (!docked)
1023 fire_missile();
1024 }
1025
1026 if (kbd_origin_pressed)
1027 o_pressed();
1028
1029 if (kbd_pause_pressed) {
1030 cheat_arg = 0;
1031 game_paused = 1;
1032 }
1033
1034 if (kbd_target_missile_pressed)
1035 {
1036 if (!docked)
1037 arm_missile();
1038 }
1039
1040 if (kbd_unarm_missile_pressed)
1041 {
1042 if (!docked)
1043 unarm_missile();
1044 }
1045
1046 if (kbd_inc_speed_pressed)
1047 {
1048 if (!docked)
1049 {
1050 if (flight_speed < myship.max_speed)
1051 flight_speed++;
1052 }
1053 }
1054
1055 if (kbd_dec_speed_pressed)
1056 {
1057 if (!docked)
1058 {
1059 if (flight_speed > 1)
1060 flight_speed--;
1061 }
1062 }
1063
1064 if (kbd_up_pressed)
1065 arrow_up();
1066
1067 if (kbd_down_pressed)
1068 arrow_down();
1069
1070 if (kbd_left_pressed)
1071 arrow_left();
1072
1073 if (kbd_right_pressed)
1074 arrow_right();
1075
1076 if (kbd_enter_pressed)
1077 return_pressed();
1078
1079 if (kbd_energy_bomb_pressed && kbd_ctrl_pressed)
1080 {
1081 if ((!docked) && (cmdr.energy_bomb))
1082 {
1083 detonate_bomb = 1;
1084 cmdr.energy_bomb = 0;
1085 }
1086 }
1087
1088 if (kbd_escape_pressed && kbd_ctrl_pressed)
1089 {
1090 if ((!docked) && (cmdr.escape_pod) && (!witchspace))
1091 run_escape_sequence();
1092 }
1093 }
1094
1095
1096
1097 void set_commander_name (char *path)
1098 {
1099 char *fname, *cname;
1100 int i;
1101
1102 fname = get_filename (path);
1103 cname = cmdr.name;
1104
1105 for (i = 0; i < 31; i++)
1106 {
1107 if (!isalnum(*fname))
1108 break;
1109
1110 *cname++ = toupper(*fname++);
1111 }
1112
1113 *cname = '\0';
1114 }
1115
1116
1117 void save_commander_screen (void)
1118 {
1119 char path[255];
1120 int okay;
1121 int rv;
1122
1123 current_screen = SCR_SAVE_CMDR;
1124
1125 gfx_clear_display();
1126 gfx_display_centre_text (10, "SAVE COMMANDER", 140, GFX_COL_GOLD);
1127 gfx_draw_line (0, 36, 511, 36);
1128 gfx_update_screen();
1129
1130 strcpy (path, cmdr.name);
1131 strcat (path, ".nkc");
1132
1133 okay = gfx_request_file ("Save Commander", path, "nkc");
1134
1135 if (!okay)
1136 {
1137 display_options();
1138 return;
1139 }
1140
1141 rv = save_commander_file (path);
1142
1143 if (rv)
1144 {
1145 gfx_display_centre_text (175, "Error Saving Commander!", 140, GFX_COL_GOLD);
1146 return;
1147 }
1148
1149 gfx_display_centre_text (175, "Commander Saved.", 140, GFX_COL_GOLD);
1150
1151 set_commander_name (path);
1152 saved_cmdr = cmdr;
1153 saved_cmdr.ship_x = docked_planet.d;
1154 saved_cmdr.ship_y = docked_planet.b;
1155 }
1156
1157
1158 void load_commander_screen (void)
1159 {
1160 char path[255];
1161 int rv;
1162
1163 gfx_clear_display();
1164 gfx_display_centre_text (10, "LOAD COMMANDER", 140, GFX_COL_GOLD);
1165 gfx_draw_line (0, 36, 511, 36);
1166 gfx_update_screen();
1167
1168
1169 strcpy (path, "jameson.nkc");
1170
1171 rv = gfx_request_file ("Load Commander", path, "nkc");
1172
1173 if (rv == 0)
1174 return;
1175
1176 rv = load_commander_file (path);
1177
1178 if (rv)
1179 {
1180 saved_cmdr = cmdr;
1181 gfx_display_centre_text (175, "Error Loading Commander!", 140, GFX_COL_GOLD);
1182 gfx_display_centre_text (200, "Press any key to continue.", 140, GFX_COL_GOLD);
1183 gfx_update_screen();
1184 readkey();
1185 return;
1186 }
1187
1188 restore_saved_commander();
1189 set_commander_name (path);
1190 saved_cmdr = cmdr;
1191 update_console();
1192 }
1193
1194
1195
1196 void run_first_intro_screen (void)
1197 {
1198 current_screen = SCR_INTRO_ONE;
1199
1200 snd_play_midi (SND_ELITE_THEME, TRUE);
1201
1202 initialise_intro1();
1203 identify = 0;
1204
1205 for (;;)
1206 {
1207 update_intro1();
1208
1209 gfx_update_screen();
1210
1211 kbd_poll_keyboard();
1212
1213 if (kbd_y_pressed)
1214 {
1215 snd_stop_midi();
1216 load_commander_screen();
1217 break;
1218 }
1219
1220 if (kbd_n_pressed)
1221 {
1222 snd_stop_midi();
1223 break;
1224 }
1225 }
1226
1227 }
1228
1229
1230
1231 void run_second_intro_screen (void)
1232 {
1233 current_screen = SCR_INTRO_TWO;
1234
1235 snd_play_midi (SND_BLUE_DANUBE, TRUE);
1236
1237 identify = 0;
1238 initialise_intro2();
1239
1240 flight_speed = 3;
1241 flight_roll = 0;
1242 flight_climb = 0;
1243
1244 for (;;)
1245 {
1246 update_intro2();
1247
1248 gfx_update_screen();
1249
1250 kbd_poll_keyboard();
1251
1252 if (kbd_space_pressed)
1253 break;
1254 }
1255
1256 snd_stop_midi();
1257 }
1258
1259
1260
1261 /*
1262 * Draw the game over sequence.
1263 */
1264
1265 void run_game_over_screen()
1266 {
1267 int i;
1268 int newship;
1269 Matrix rotmat;
1270 int type;
1271
1272 current_screen = SCR_GAME_OVER;
1273 gfx_set_clip_region (1, 1, 510, 383);
1274
1275 flight_speed = 6;
1276 flight_roll = 0;
1277 flight_climb = 0;
1278 identify = 0;
1279 clear_universe();
1280
1281 set_init_matrix (rotmat);
1282
1283 newship = add_new_ship (SHIP_COBRA3, 0, 0, -400, rotmat, 0, 0);
1284 universe[newship].flags |= FLG_DEAD;
1285
1286 for (i = 0; i < 5; i++)
1287 {
1288 type = (rand255() & 1) ? SHIP_CARGO : SHIP_ALLOY;
1289 newship = add_new_ship (type, (rand255() & 63) - 32,
1290 (rand255() & 63) - 32, -400, rotmat, 0, 0);
1291 universe[newship].rotz = ((rand255() * 2) & 255) - 128;
1292 universe[newship].rotx = ((rand255() * 2) & 255) - 128;
1293 universe[newship].velocity = rand255() & 15;
1294 }
1295
1296
1297 for (i = 0; i < 100; i++)
1298 {
1299 gfx_clear_display();
1300 update_starfield();
1301 update_universe();
1302 gfx_display_centre_text (190, "GAME OVER", 140, GFX_COL_GOLD);
1303 gfx_update_screen();
1304 }
1305 }
1306
1307
1308
1309
1310 /*
1311 * Draw a break pattern (for launching, docking and hyperspacing).
1312 * Just draw a very simple one for the moment.
1313 */
1314
1315 void display_break_pattern (void)
1316 {
1317 int i;
1318
1319 gfx_set_clip_region (1, 1, 510, 383);
1320 gfx_clear_display();
1321
1322 for (i = 0; i < 20; i++)
1323 {
1324 gfx_draw_circle (256, 192, 30 + i * 15, GFX_COL_WHITE);
1325 gfx_update_screen();
1326 }
1327
1328
1329 if (docked)
1330 {
1331 check_mission_brief();
1332 display_commander_status();
1333 update_console();
1334 }
1335 else
1336 current_screen = SCR_FRONT_VIEW;
1337 }
1338
1339
1340 void info_message (char *message)
1341 {
1342 strcpy (message_string, message);
1343 message_count = 37;
1344 // snd_play_sample (SND_BEEP);
1345 }
1346
1347
1348
1349
1350
1351
1352 void initialise_allegro (void)
1353 {
1354 allegro_init();
1355 install_keyboard();
1356 install_timer();
1357 install_mouse();
1358
1359 have_joystick = 0;
1360
1361 if (install_joystick(JOY_TYPE_AUTODETECT) == 0)
1362 {
1363 have_joystick = (num_joysticks > 0);
1364 }
1365 }
1366
1367
1368
1369 int main()
1370 {
1371 initialise_allegro();
1372 read_config_file();
1373
1374 if (gfx_graphics_startup() == 1)
1375 {
1376 return 1;
1377 }
1378
1379 /* Start the sound system... */
1380 snd_sound_startup();
1381
1382 /* Do any setup necessary for the keyboard... */
1383 kbd_keyboard_startup();
1384
1385 finish = 0;
1386 auto_pilot = 0;
1387
1388 while (!finish)
1389 {
1390 game_over = 0;
1391 initialise_game();
1392 dock_player();
1393
1394 update_console();
1395
1396 current_screen = SCR_FRONT_VIEW;
1397 run_first_intro_screen();
1398 run_second_intro_screen();
1399
1400 old_cross_x = -1;
1401 old_cross_y = -1;
1402
1403 dock_player ();
1404 display_commander_status ();
1405
1406 while (!game_over)
1407 {
1408 snd_update_sound();
1409 gfx_update_screen();
1410 gfx_set_clip_region (1, 1, 510, 383);
1411
1412 rolling = 0;
1413 climbing = 0;
1414
1415 handle_flight_keys ();
1416
1417 if (game_paused)
1418 continue;
1419
1420 if (message_count > 0)
1421 message_count--;
1422
1423 if (!rolling)
1424 {
1425 if (flight_roll > 0)
1426 decrease_flight_roll();
1427
1428 if (flight_roll < 0)
1429 increase_flight_roll();
1430 }
1431
1432 if (!climbing)
1433 {
1434 if (flight_climb > 0)
1435 decrease_flight_climb();
1436
1437 if (flight_climb < 0)
1438 increase_flight_climb();
1439 }
1440
1441
1442 if (!docked)
1443 {
1444 gfx_acquire_screen();
1445
1446 if ((current_screen == SCR_FRONT_VIEW) || (current_screen == SCR_REAR_VIEW) ||
1447 (current_screen == SCR_LEFT_VIEW) || (current_screen == SCR_RIGHT_VIEW) ||
1448 (current_screen == SCR_INTRO_ONE) || (current_screen == SCR_INTRO_TWO) ||
1449 (current_screen == SCR_GAME_OVER))
1450 {
1451 gfx_clear_display();
1452 update_starfield();
1453 }
1454
1455 if (auto_pilot)
1456 {
1457 auto_dock();
1458 if ((mcount & 127) == 0)
1459 info_message ("Docking Computers On");
1460 }
1461
1462 update_universe ();
1463
1464 if (docked)
1465 {
1466 update_console();
1467 gfx_release_screen();
1468 continue;
1469 }
1470
1471 if ((current_screen == SCR_FRONT_VIEW) || (current_screen == SCR_REAR_VIEW) ||
1472 (current_screen == SCR_LEFT_VIEW) || (current_screen == SCR_RIGHT_VIEW))
1473 {
1474 if (draw_lasers)
1475 {
1476 draw_laser_lines();
1477 draw_lasers--;
1478 }
1479
1480 draw_laser_sights();
1481 }
1482
1483 if (message_count > 0)
1484 gfx_display_centre_text (358, message_string, 120, GFX_COL_WHITE);
1485
1486 if (hyper_ready)
1487 {
1488 display_hyper_status();
1489 if ((mcount & 3) == 0)
1490 {
1491 countdown_hyperspace();
1492 }
1493 }
1494
1495 gfx_release_screen();
1496
1497 mcount--;
1498 if (mcount < 0)
1499 mcount = 255;
1500
1501 if ((mcount & 7) == 0)
1502 regenerate_shields();
1503
1504 if ((mcount & 31) == 10)
1505 {
1506 if (energy < 50)
1507 {
1508 info_message ("ENERGY LOW");
1509 snd_play_sample (SND_BEEP);
1510 }
1511
1512 update_altitude();
1513 }
1514
1515 if ((mcount & 31) == 20)
1516 update_cabin_temp();
1517
1518 if ((mcount == 0) && (!witchspace))
1519 random_encounter();
1520
1521 cool_laser();
1522 time_ecm();
1523
1524 update_console();
1525 }
1526
1527 if (current_screen == SCR_BREAK_PATTERN)
1528 display_break_pattern();
1529
1530 if (cross_timer > 0)
1531 {
1532 cross_timer--;
1533 if (cross_timer == 0)
1534 {
1535 show_distance_to_planet();
1536 }
1537 }
1538
1539 if ((cross_x != old_cross_x) ||
1540 (cross_y != old_cross_y))
1541 {
1542 if (old_cross_x != -1)
1543 draw_cross (old_cross_x, old_cross_y);
1544
1545 old_cross_x = cross_x;
1546 old_cross_y = cross_y;
1547
1548 draw_cross (old_cross_x, old_cross_y);
1549 }
1550 }
1551
1552 if (game_over < 2)
1553 run_game_over_screen();
1554 }
1555
1556 snd_sound_shutdown();
1557
1558 gfx_graphics_shutdown ();
1559
1560 return 0;
1561 }
1562
1563 END_OF_MAIN();