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