chiark / gitweb /
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();