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