2 * Elite - The New Kind.
4 * Reverse engineered from the BBC disk version of Elite.
5 * Additional material by C.J.Pinder.
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.
10 * email: <christian@newkind.co.uk>
18 * Allegro version of the main game handler.
55 int old_cross_x
, old_cross_y
;
61 char message_string
[80];
78 * Initialise the game parameters.
81 void initialise_game(void)
83 set_rand_seed (time(NULL
));
84 current_screen
= SCR_INTRO_ONE
;
86 restore_saved_commander();
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 */
119 void finish_game (void)
132 * Move the planet chart cross hairs to specified position.
136 void move_cross (int dx
, int dy
)
140 if (kbd_ctrl_pressed
) {
145 if (current_screen
== SCR_SHORT_RANGE
)
152 if (current_screen
== SCR_GALACTIC_CHART
)
173 * Draw the cross hairs at the specified position.
176 void draw_cross (int cx
, int cy
)
178 if (current_screen
== SCR_SHORT_RANGE
)
180 gfx_set_clip_region (1, 37, 510, 339);
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
);
185 gfx_set_clip_region (1, 1, 510, 383);
189 if (current_screen
== SCR_GALACTIC_CHART
)
191 gfx_set_clip_region (1, 37, 510, 293);
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
);
196 gfx_set_clip_region (1, 1, 510, 383);
202 void draw_laser_sights(void)
207 switch (current_screen
)
210 gfx_display_centre_text (32, "Front View", 120, GFX_COL_WHITE
);
211 laser
= cmdr
.front_laser
;
215 gfx_display_centre_text (32, "Rear View", 120, GFX_COL_WHITE
);
216 laser
= cmdr
.rear_laser
;
220 gfx_display_centre_text (32, "Left View", 120, GFX_COL_WHITE
);
221 laser
= cmdr
.left_laser
;
225 gfx_display_centre_text (32, "Right View", 120, GFX_COL_WHITE
);
226 laser
= cmdr
.right_laser
;
233 x1
= 128 * GFX_SCALE
;
234 y1
= (96-8) * GFX_SCALE
;
235 y2
= (96-16) * GFX_SCALE
;
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
);
241 y1
= (96+8) * GFX_SCALE
;
242 y2
= (96+16) * GFX_SCALE
;
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
);
248 x1
= (128-8) * GFX_SCALE
;
250 x2
= (128-16) * GFX_SCALE
;
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
);
256 x1
= (128+8) * GFX_SCALE
;
257 x2
= (128+16) * GFX_SCALE
;
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
);
266 static void roll_left(void)
272 increase_flight_roll();
273 increase_flight_roll();
278 static void roll_right(void)
284 decrease_flight_roll();
285 decrease_flight_roll();
290 static void climb(void)
292 if (flight_climb
< 0)
296 increase_flight_climb();
301 static void dive(void)
303 if (flight_climb
> 0)
307 decrease_flight_climb();
312 void arrow_right (void)
314 switch (current_screen
)
316 case SCR_MARKET_PRICES
:
321 select_right_setting();
324 case SCR_SHORT_RANGE
:
325 case SCR_GALACTIC_CHART
:
333 if (remap_keys
) roll_left(); else roll_right();
336 if (remap_keys
) climb(); else roll_right();
339 if (remap_keys
) dive(); else roll_right();
345 void arrow_left (void)
347 switch (current_screen
)
349 case SCR_MARKET_PRICES
:
354 select_left_setting();
357 case SCR_SHORT_RANGE
:
358 case SCR_GALACTIC_CHART
:
366 if (remap_keys
) roll_right(); else roll_left();
369 if (remap_keys
) dive(); else roll_left();
372 if (remap_keys
) climb(); else roll_left();
380 switch (current_screen
)
382 case SCR_MARKET_PRICES
:
383 select_previous_stock();
387 select_previous_equip();
391 select_previous_option();
398 case SCR_SHORT_RANGE
:
399 case SCR_GALACTIC_CHART
:
407 if (remap_keys
) climb(); else dive();
410 if (remap_keys
) roll_right(); else dive();
413 if (remap_keys
) roll_left(); else dive();
420 void arrow_down (void)
422 switch (current_screen
)
424 case SCR_MARKET_PRICES
:
433 select_next_option();
437 select_down_setting();
440 case SCR_SHORT_RANGE
:
441 case SCR_GALACTIC_CHART
:
449 if (remap_keys
) dive(); else climb();
452 if (remap_keys
) roll_left(); else climb();
455 if (remap_keys
) roll_right(); else climb();
462 void return_pressed (void)
464 switch (current_screen
)
481 void y_pressed (void)
483 switch (current_screen
)
495 void n_pressed (void)
497 switch (current_screen
)
502 display_commander_status();
504 current_screen
= SCR_FRONT_VIEW
;
510 void d_pressed (void)
512 switch (current_screen
)
514 case SCR_GALACTIC_CHART
:
515 case SCR_SHORT_RANGE
:
516 show_distance_to_planet();
524 disengage_auto_pilot();
530 void f_pressed (void)
532 if ((current_screen
== SCR_GALACTIC_CHART
) ||
533 (current_screen
== SCR_SHORT_RANGE
))
537 gfx_clear_text_area();
538 gfx_display_text (16, 340, "Planet Name?");
543 void add_find_char (int letter
)
547 if (strlen (find_name
) == 16)
550 str
[0] = toupper (letter
);
552 strcat (find_name
, str
);
554 sprintf (str
, "Planet Name? %s", find_name
);
555 gfx_clear_text_area ();
556 gfx_display_text(16, 340, str
);
560 void delete_find_char (void)
565 len
= strlen (find_name
);
569 find_name
[len
- 1] = '\0';
571 sprintf (str
, "Planet Name? %s", find_name
);
572 gfx_clear_text_area();
573 gfx_display_text(16, 340, str
);
578 switch (current_screen
)
580 case SCR_GALACTIC_CHART
:
581 case SCR_SHORT_RANGE
:
582 move_cursor_to_origin();
588 void auto_dock (void)
590 struct univ_object ship
;
596 set_init_matrix (ship
.rotmat
);
597 ship
.rotmat
[2].z
= 1;
598 ship
.rotmat
[0].x
= -1;
600 ship
.velocity
= flight_speed
;
601 ship
.acceleration
= 0;
606 auto_pilot_ship (&ship
);
608 if (ship
.velocity
> 22)
611 flight_speed
= ship
.velocity
;
613 if (ship
.acceleration
> 0)
616 if (flight_speed
> 22)
620 if (ship
.acceleration
< 0)
623 if (flight_speed
< 1)
632 increase_flight_climb();
635 increase_flight_climb();
640 decrease_flight_climb();
643 decrease_flight_climb();
646 if (ship
.rotz
== 127)
655 increase_flight_roll();
658 increase_flight_roll();
663 decrease_flight_roll();
666 decrease_flight_roll();
672 void run_escape_sequence (void)
678 current_screen
= SCR_ESCAPE_POD
;
684 set_init_matrix (rotmat
);
687 newship
= add_new_ship (SHIP_COBRA3
, 0, 0, 200, rotmat
, -127, -127);
688 universe
[newship
].velocity
= 7;
689 snd_play_sample (SND_LAUNCH
);
691 for (i
= 0; i
< 90; i
++)
695 universe
[newship
].flags
|= FLG_DEAD
;
696 snd_play_sample (SND_EXPLODE
);
699 gfx_set_clip_region (1, 1, 510, 383);
704 universe
[newship
].location
.x
= 0;
705 universe
[newship
].location
.y
= 0;
706 universe
[newship
].location
.z
+= 2;
708 gfx_display_centre_text (358, "Escape pod launched - Ship auto-destuct initiated.", 120, GFX_COL_WHITE
);
715 while ((ship_count
[SHIP_CORIOLIS
] == 0) &&
716 (ship_count
[SHIP_DODEC
] == 0))
720 if ((abs(flight_roll
) < 3) && (abs(flight_climb
) < 3))
722 for (i
= 0; i
< MAX_UNIV_OBJECTS
; i
++)
724 if (universe
[i
].type
!= 0)
725 universe
[i
].location
.z
-= 1500;
731 gfx_set_clip_region (1, 1, 510, 383);
742 static int cheat_arg
= 0;
743 static void check_cheat_keys(void)
747 if (!kbd_ctrl_pressed
)
750 for (i
= 0; i
< 10; i
++) {
751 if (old_key
[KEY_0
+ i
] == 1) {
752 cheat_arg
= cheat_arg
* 10 + i
;
757 if (old_key
[KEY_C
] == 1)
763 if (old_key
[KEY_S
] == 1) {
764 if (cheat_arg
< NO_OF_SHIPS
) {
765 int un
= create_other_ship(cheat_arg
);
767 universe
[un
].flags
|= FLG_TARGET
;
772 if (old_key
[KEY_D
] == 1) {
774 snd_play_sample (SND_DOCK
);
776 current_screen
= SCR_BREAK_PATTERN
;
784 snd_play_sample(SND_BEEP
);
788 void handle_flight_keys (void)
793 ((current_screen
== SCR_MARKET_PRICES
) ||
794 (current_screen
== SCR_OPTIONS
) ||
795 (current_screen
== SCR_SETTINGS
) ||
796 (current_screen
== SCR_EQUIP_SHIP
)))
805 if (joy
[0].stick
[0].axis
[1].d1
)
808 if (joy
[0].stick
[0].axis
[1].d2
)
811 if (joy
[0].stick
[0].axis
[0].d1
)
814 if (joy
[0].stick
[0].axis
[0].d2
)
817 if (joy
[0].button
[0].b
)
818 kbd_fire_pressed
= 1;
820 if (joy
[0].button
[1].b
)
821 kbd_inc_speed_pressed
= 1;
823 if (joy
[0].button
[2].b
)
824 kbd_dec_speed_pressed
= 1;
830 if (kbd_resume_pressed
)
845 if (current_screen
!= SCR_FRONT_VIEW
)
847 current_screen
= SCR_FRONT_VIEW
;
859 if (current_screen
!= SCR_REAR_VIEW
)
861 current_screen
= SCR_REAR_VIEW
;
873 if (current_screen
!= SCR_LEFT_VIEW
)
875 current_screen
= SCR_LEFT_VIEW
;
889 if (current_screen
!= SCR_RIGHT_VIEW
)
891 current_screen
= SCR_RIGHT_VIEW
;
902 display_galactic_chart();
909 display_short_range_chart();
915 display_data_on_planet();
918 if (kbd_F8_pressed
&& (!witchspace
))
921 display_market_prices();
927 display_commander_status();
944 keyasc
= kbd_read_key();
946 if (kbd_enter_pressed
)
949 find_planet_by_name (find_name
);
953 if (kbd_backspace_pressed
)
960 add_find_char (keyasc
);
972 if (kbd_i_pressed
== 1)
973 identify
= !identify
;
975 if (kbd_zoom_pressed
== 1)
978 if (kbd_fire_pressed
)
980 if ((!docked
) && (draw_lasers
== 0))
981 draw_lasers
= fire_laser();
984 if (kbd_dock_pressed
)
986 if (!docked
&& cmdr
.docking_computer
)
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();
1002 if (kbd_ecm_pressed
)
1004 if (!docked
&& cmdr
.ecm
)
1008 if (kbd_find_pressed
)
1011 if (kbd_hyperspace_pressed
&& (!docked
))
1013 if (kbd_ctrl_pressed
)
1014 start_galactic_hyperspace();
1019 if (kbd_jump_pressed
&& (!docked
) && (!witchspace
))
1024 if (kbd_fire_missile_pressed
)
1030 if (kbd_origin_pressed
)
1033 if (kbd_pause_pressed
) {
1038 if (kbd_target_missile_pressed
)
1044 if (kbd_unarm_missile_pressed
)
1050 if (kbd_inc_speed_pressed
)
1054 if (flight_speed
< myship
.max_speed
)
1059 if (kbd_dec_speed_pressed
)
1063 if (flight_speed
> 1)
1071 if (kbd_down_pressed
)
1074 if (kbd_left_pressed
)
1077 if (kbd_right_pressed
)
1080 if (kbd_enter_pressed
)
1083 if (kbd_energy_bomb_pressed
&& kbd_ctrl_pressed
)
1085 if ((!docked
) && (cmdr
.energy_bomb
))
1088 cmdr
.energy_bomb
= 0;
1092 if (kbd_escape_pressed
&& kbd_ctrl_pressed
)
1094 if ((!docked
) && (cmdr
.escape_pod
) && (!witchspace
))
1095 run_escape_sequence();
1101 void set_commander_name (char *path
)
1103 char *fname
, *cname
;
1106 fname
= get_filename (path
);
1109 for (i
= 0; i
< 31; i
++)
1111 if (!isalnum(*fname
))
1114 *cname
++ = toupper(*fname
++);
1121 void save_commander_screen (void)
1127 current_screen
= SCR_SAVE_CMDR
;
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();
1134 strcpy (path
, cmdr
.name
);
1135 strcat (path
, ".nkc");
1137 okay
= gfx_request_file ("Save Commander", path
, "nkc");
1145 rv
= save_commander_file (path
);
1149 gfx_display_centre_text (175, "Error Saving Commander!", 140, GFX_COL_GOLD
);
1153 gfx_display_centre_text (175, "Commander Saved.", 140, GFX_COL_GOLD
);
1155 set_commander_name (path
);
1157 saved_cmdr
.ship_x
= docked_planet
.d
;
1158 saved_cmdr
.ship_y
= docked_planet
.b
;
1162 void load_commander_screen (void)
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();
1173 strcpy (path
, "jameson.nkc");
1175 rv
= gfx_request_file ("Load Commander", path
, "nkc");
1180 rv
= load_commander_file (path
);
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();
1192 restore_saved_commander();
1193 set_commander_name (path
);
1200 void run_first_intro_screen (void)
1202 current_screen
= SCR_INTRO_ONE
;
1204 snd_play_midi (SND_ELITE_THEME
, TRUE
);
1206 initialise_intro1();
1215 gfx_update_screen();
1217 kbd_poll_keyboard();
1222 load_commander_screen();
1237 void run_second_intro_screen (void)
1239 current_screen
= SCR_INTRO_TWO
;
1241 snd_play_midi (SND_BLUE_DANUBE
, TRUE
);
1246 initialise_intro2();
1256 gfx_update_screen();
1258 kbd_poll_keyboard();
1260 if (kbd_space_pressed
)
1270 * Draw the game over sequence.
1273 void run_game_over_screen()
1280 current_screen
= SCR_GAME_OVER
;
1281 gfx_set_clip_region (1, 1, 510, 383);
1291 set_init_matrix (rotmat
);
1293 newship
= add_new_ship (SHIP_COBRA3
, 0, 0, -400, rotmat
, 0, 0);
1294 universe
[newship
].flags
|= FLG_DEAD
;
1296 for (i
= 0; i
< 5; i
++)
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;
1307 for (i
= 0; i
< 100; i
++)
1309 gfx_clear_display();
1312 gfx_display_centre_text (190, "GAME OVER", 140, GFX_COL_GOLD
);
1313 gfx_update_screen();
1321 * Draw a break pattern (for launching, docking and hyperspacing).
1322 * Just draw a very simple one for the moment.
1325 void display_break_pattern (void)
1329 gfx_set_clip_region (1, 1, 510, 383);
1330 gfx_clear_display();
1332 for (i
= 0; i
< 20; i
++)
1334 gfx_draw_circle (256, 192, 30 + i
* 15, GFX_COL_WHITE
);
1335 gfx_update_screen();
1341 check_mission_brief();
1342 display_commander_status();
1346 current_screen
= SCR_FRONT_VIEW
;
1350 void info_message (char *message
)
1352 strcpy (message_string
, message
);
1354 // snd_play_sample (SND_BEEP);
1362 void initialise_allegro (void)
1371 if (install_joystick(JOY_TYPE_AUTODETECT
) == 0)
1373 have_joystick
= (num_joysticks
> 0);
1381 initialise_allegro();
1384 if (gfx_graphics_startup() == 1)
1389 /* Start the sound system... */
1390 snd_sound_startup();
1392 /* Do any setup necessary for the keyboard... */
1393 kbd_keyboard_startup();
1406 current_screen
= SCR_FRONT_VIEW
;
1407 run_first_intro_screen();
1408 run_second_intro_screen();
1414 display_commander_status ();
1419 gfx_update_screen();
1420 gfx_set_clip_region (1, 1, 510, 383);
1425 handle_flight_keys ();
1430 if (message_count
> 0)
1435 if (flight_roll
> 0)
1436 decrease_flight_roll();
1438 if (flight_roll
< 0)
1439 increase_flight_roll();
1444 if (flight_climb
> 0)
1445 decrease_flight_climb();
1447 if (flight_climb
< 0)
1448 increase_flight_climb();
1454 gfx_acquire_screen();
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
))
1461 gfx_clear_display();
1468 if ((mcount
& 127) == 0)
1469 info_message ("Docking Computers On");
1477 gfx_release_screen();
1481 if ((current_screen
== SCR_FRONT_VIEW
) || (current_screen
== SCR_REAR_VIEW
) ||
1482 (current_screen
== SCR_LEFT_VIEW
) || (current_screen
== SCR_RIGHT_VIEW
))
1490 draw_laser_sights();
1493 if (message_count
> 0)
1494 gfx_display_centre_text (358, message_string
, 120, GFX_COL_WHITE
);
1498 display_hyper_status();
1499 if ((mcount
& 3) == 0)
1501 countdown_hyperspace();
1505 gfx_release_screen();
1511 if ((mcount
& 7) == 0)
1512 regenerate_shields();
1514 if ((mcount
& 31) == 10)
1518 info_message ("ENERGY LOW");
1519 snd_play_sample (SND_BEEP
);
1525 if ((mcount
& 31) == 20)
1526 update_cabin_temp();
1528 if ((mcount
== 0) && (!witchspace
))
1537 if (current_screen
== SCR_BREAK_PATTERN
)
1538 display_break_pattern();
1540 if (cross_timer
> 0)
1543 if (cross_timer
== 0)
1545 show_distance_to_planet();
1549 if ((cross_x
!= old_cross_x
) ||
1550 (cross_y
!= old_cross_y
))
1552 if (old_cross_x
!= -1)
1553 draw_cross (old_cross_x
, old_cross_y
);
1555 old_cross_x
= cross_x
;
1556 old_cross_y
= cross_y
;
1558 draw_cross (old_cross_x
, old_cross_y
);
1563 run_game_over_screen();
1566 snd_sound_shutdown();
1568 gfx_graphics_shutdown ();