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