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];
76 * Initialise the game parameters.
79 void initialise_game(void)
81 set_rand_seed (time(NULL
));
82 current_screen
= SCR_INTRO_ONE
;
84 restore_saved_commander();
110 myship
.max_speed
= 40; /* 0.27 Light Mach */
111 myship
.max_roll
= 31;
112 myship
.max_climb
= 8; /* CF 8 */
113 myship
.max_fuel
= 70; /* 7.0 Light Years */
117 void finish_game (void)
130 * Move the planet chart cross hairs to specified position.
134 void move_cross (int dx
, int dy
)
138 if (kbd_ctrl_pressed
) {
143 if (current_screen
== SCR_SHORT_RANGE
)
150 if (current_screen
== SCR_GALACTIC_CHART
)
171 * Draw the cross hairs at the specified position.
174 void draw_cross (int cx
, int cy
)
176 if (current_screen
== SCR_SHORT_RANGE
)
178 gfx_set_clip_region (1, 37, 510, 339);
180 gfx_draw_colour_line (cx
- 16, cy
, cx
+ 16, cy
, GFX_COL_RED
);
181 gfx_draw_colour_line (cx
, cy
- 16, cx
, cy
+ 16, GFX_COL_RED
);
183 gfx_set_clip_region (1, 1, 510, 383);
187 if (current_screen
== SCR_GALACTIC_CHART
)
189 gfx_set_clip_region (1, 37, 510, 293);
191 gfx_draw_colour_line (cx
- 8, cy
, cx
+ 8, cy
, GFX_COL_RED
);
192 gfx_draw_colour_line (cx
, cy
- 8, cx
, cy
+ 8, GFX_COL_RED
);
194 gfx_set_clip_region (1, 1, 510, 383);
200 void draw_laser_sights(void)
205 switch (current_screen
)
208 gfx_display_centre_text (32, "Front View", 120, GFX_COL_WHITE
);
209 laser
= cmdr
.front_laser
;
213 gfx_display_centre_text (32, "Rear View", 120, GFX_COL_WHITE
);
214 laser
= cmdr
.rear_laser
;
218 gfx_display_centre_text (32, "Left View", 120, GFX_COL_WHITE
);
219 laser
= cmdr
.left_laser
;
223 gfx_display_centre_text (32, "Right View", 120, GFX_COL_WHITE
);
224 laser
= cmdr
.right_laser
;
231 x1
= 128 * GFX_SCALE
;
232 y1
= (96-8) * GFX_SCALE
;
233 y2
= (96-16) * GFX_SCALE
;
235 gfx_draw_colour_line (x1
-1, y1
, x1
-1, y2
, GFX_COL_GREY_1
);
236 gfx_draw_colour_line (x1
, y1
, x1
, y2
, GFX_COL_WHITE
);
237 gfx_draw_colour_line (x1
+1, y1
, x1
+1, y2
, GFX_COL_GREY_1
);
239 y1
= (96+8) * GFX_SCALE
;
240 y2
= (96+16) * GFX_SCALE
;
242 gfx_draw_colour_line (x1
-1, y1
, x1
-1, y2
, GFX_COL_GREY_1
);
243 gfx_draw_colour_line (x1
, y1
, x1
, y2
, GFX_COL_WHITE
);
244 gfx_draw_colour_line (x1
+1, y1
, x1
+1, y2
, GFX_COL_GREY_1
);
246 x1
= (128-8) * GFX_SCALE
;
248 x2
= (128-16) * GFX_SCALE
;
250 gfx_draw_colour_line (x1
, y1
-1, x2
, y1
-1, GFX_COL_GREY_1
);
251 gfx_draw_colour_line (x1
, y1
, x2
, y1
, GFX_COL_WHITE
);
252 gfx_draw_colour_line (x1
, y1
+1, x2
, y1
+1, GFX_COL_GREY_1
);
254 x1
= (128+8) * GFX_SCALE
;
255 x2
= (128+16) * GFX_SCALE
;
257 gfx_draw_colour_line (x1
, y1
-1, x2
, y1
-1, GFX_COL_GREY_1
);
258 gfx_draw_colour_line (x1
, y1
, x2
, y1
, GFX_COL_WHITE
);
259 gfx_draw_colour_line (x1
, y1
+1, x2
, y1
+1, GFX_COL_GREY_1
);
264 static void roll_left(void)
270 increase_flight_roll();
271 increase_flight_roll();
276 static void roll_right(void)
282 decrease_flight_roll();
283 decrease_flight_roll();
288 static void climb(void)
290 if (flight_climb
< 0)
294 increase_flight_climb();
299 static void dive(void)
301 if (flight_climb
> 0)
305 decrease_flight_climb();
310 void arrow_right (void)
312 switch (current_screen
)
314 case SCR_MARKET_PRICES
:
319 select_right_setting();
322 case SCR_SHORT_RANGE
:
323 case SCR_GALACTIC_CHART
:
331 if (remap_keys
) roll_left(); else roll_right();
334 if (remap_keys
) climb(); else roll_right();
337 if (remap_keys
) dive(); else roll_right();
343 void arrow_left (void)
345 switch (current_screen
)
347 case SCR_MARKET_PRICES
:
352 select_left_setting();
355 case SCR_SHORT_RANGE
:
356 case SCR_GALACTIC_CHART
:
364 if (remap_keys
) roll_right(); else roll_left();
367 if (remap_keys
) dive(); else roll_left();
370 if (remap_keys
) climb(); else roll_left();
378 switch (current_screen
)
380 case SCR_MARKET_PRICES
:
381 select_previous_stock();
385 select_previous_equip();
389 select_previous_option();
396 case SCR_SHORT_RANGE
:
397 case SCR_GALACTIC_CHART
:
405 if (remap_keys
) climb(); else dive();
408 if (remap_keys
) roll_right(); else dive();
411 if (remap_keys
) roll_left(); else dive();
418 void arrow_down (void)
420 switch (current_screen
)
422 case SCR_MARKET_PRICES
:
431 select_next_option();
435 select_down_setting();
438 case SCR_SHORT_RANGE
:
439 case SCR_GALACTIC_CHART
:
447 if (remap_keys
) dive(); else climb();
450 if (remap_keys
) roll_left(); else climb();
453 if (remap_keys
) roll_right(); else climb();
460 void return_pressed (void)
462 switch (current_screen
)
479 void y_pressed (void)
481 switch (current_screen
)
493 void n_pressed (void)
495 switch (current_screen
)
500 display_commander_status();
502 current_screen
= SCR_FRONT_VIEW
;
508 void d_pressed (void)
510 switch (current_screen
)
512 case SCR_GALACTIC_CHART
:
513 case SCR_SHORT_RANGE
:
514 show_distance_to_planet();
522 disengage_auto_pilot();
528 void f_pressed (void)
530 if ((current_screen
== SCR_GALACTIC_CHART
) ||
531 (current_screen
== SCR_SHORT_RANGE
))
535 gfx_clear_text_area();
536 gfx_display_text (16, 340, "Planet Name?");
541 void add_find_char (int letter
)
545 if (strlen (find_name
) == 16)
548 str
[0] = toupper (letter
);
550 strcat (find_name
, str
);
552 sprintf (str
, "Planet Name? %s", find_name
);
553 gfx_clear_text_area ();
554 gfx_display_text(16, 340, str
);
558 void delete_find_char (void)
563 len
= strlen (find_name
);
567 find_name
[len
- 1] = '\0';
569 sprintf (str
, "Planet Name? %s", find_name
);
570 gfx_clear_text_area();
571 gfx_display_text(16, 340, str
);
576 switch (current_screen
)
578 case SCR_GALACTIC_CHART
:
579 case SCR_SHORT_RANGE
:
580 move_cursor_to_origin();
586 void auto_dock (void)
588 struct univ_object ship
;
594 set_init_matrix (ship
.rotmat
);
595 ship
.rotmat
[2].z
= 1;
596 ship
.rotmat
[0].x
= -1;
598 ship
.velocity
= flight_speed
;
599 ship
.acceleration
= 0;
604 auto_pilot_ship (&ship
);
606 if (ship
.velocity
> 22)
609 flight_speed
= ship
.velocity
;
611 if (ship
.acceleration
> 0)
614 if (flight_speed
> 22)
618 if (ship
.acceleration
< 0)
621 if (flight_speed
< 1)
630 increase_flight_climb();
633 increase_flight_climb();
638 decrease_flight_climb();
641 decrease_flight_climb();
644 if (ship
.rotz
== 127)
653 increase_flight_roll();
656 increase_flight_roll();
661 decrease_flight_roll();
664 decrease_flight_roll();
670 void run_escape_sequence (void)
676 current_screen
= SCR_ESCAPE_POD
;
682 set_init_matrix (rotmat
);
685 newship
= add_new_ship (SHIP_COBRA3
, 0, 0, 200, rotmat
, -127, -127);
686 universe
[newship
].velocity
= 7;
687 snd_play_sample (SND_LAUNCH
);
689 for (i
= 0; i
< 90; i
++)
693 universe
[newship
].flags
|= FLG_DEAD
;
694 snd_play_sample (SND_EXPLODE
);
697 gfx_set_clip_region (1, 1, 510, 383);
702 universe
[newship
].location
.x
= 0;
703 universe
[newship
].location
.y
= 0;
704 universe
[newship
].location
.z
+= 2;
706 gfx_display_centre_text (358, "Escape pod launched - Ship auto-destuct initiated.", 120, GFX_COL_WHITE
);
713 while ((ship_count
[SHIP_CORIOLIS
] == 0) &&
714 (ship_count
[SHIP_DODEC
] == 0))
718 if ((abs(flight_roll
) < 3) && (abs(flight_climb
) < 3))
720 for (i
= 0; i
< MAX_UNIV_OBJECTS
; i
++)
722 if (universe
[i
].type
!= 0)
723 universe
[i
].location
.z
-= 1500;
729 gfx_set_clip_region (1, 1, 510, 383);
740 static int cheat_arg
= 0;
741 static void check_cheat_keys(void)
745 if (!kbd_ctrl_pressed
)
748 for (i
= 0; i
< 10; i
++) {
749 if (old_key
[KEY_0
+ i
] == 1) {
750 cheat_arg
= cheat_arg
* 10 + i
;
755 if (old_key
[KEY_C
] == 1)
761 if (old_key
[KEY_S
] == 1) {
762 if (cheat_arg
< NO_OF_SHIPS
) {
763 int un
= create_other_ship(cheat_arg
);
765 universe
[un
].flags
|= FLG_TARGET
;
770 if (old_key
[KEY_D
] == 1) {
772 snd_play_sample (SND_DOCK
);
774 current_screen
= SCR_BREAK_PATTERN
;
782 snd_play_sample(SND_BEEP
);
786 void handle_flight_keys (void)
791 ((current_screen
== SCR_MARKET_PRICES
) ||
792 (current_screen
== SCR_OPTIONS
) ||
793 (current_screen
== SCR_SETTINGS
) ||
794 (current_screen
== SCR_EQUIP_SHIP
)))
803 if (joy
[0].stick
[0].axis
[1].d1
)
806 if (joy
[0].stick
[0].axis
[1].d2
)
809 if (joy
[0].stick
[0].axis
[0].d1
)
812 if (joy
[0].stick
[0].axis
[0].d2
)
815 if (joy
[0].button
[0].b
)
816 kbd_fire_pressed
= 1;
818 if (joy
[0].button
[1].b
)
819 kbd_inc_speed_pressed
= 1;
821 if (joy
[0].button
[2].b
)
822 kbd_dec_speed_pressed
= 1;
828 if (kbd_resume_pressed
)
843 if (current_screen
!= SCR_FRONT_VIEW
)
845 current_screen
= SCR_FRONT_VIEW
;
857 if (current_screen
!= SCR_REAR_VIEW
)
859 current_screen
= SCR_REAR_VIEW
;
871 if (current_screen
!= SCR_LEFT_VIEW
)
873 current_screen
= SCR_LEFT_VIEW
;
887 if (current_screen
!= SCR_RIGHT_VIEW
)
889 current_screen
= SCR_RIGHT_VIEW
;
900 display_galactic_chart();
907 display_short_range_chart();
913 display_data_on_planet();
916 if (kbd_F8_pressed
&& (!witchspace
))
919 display_market_prices();
925 display_commander_status();
942 keyasc
= kbd_read_key();
944 if (kbd_enter_pressed
)
947 find_planet_by_name (find_name
);
951 if (kbd_backspace_pressed
)
958 add_find_char (keyasc
);
969 if (kbd_i_pressed
== 1)
970 identify
= !identify
;
971 if (kbd_zoom_pressed
== 1)
974 if (kbd_fire_pressed
)
976 if ((!docked
) && (draw_lasers
== 0))
977 draw_lasers
= fire_laser();
980 if (kbd_dock_pressed
)
982 if (!docked
&& cmdr
.docking_computer
)
984 if ((universe
[1].type
== SHIP_CORIOLIS
||
985 universe
[1].type
== SHIP_DODEC
) &&
986 (universe
[1].flags
& FLG_ANGRY
))
987 info_message("Docking permission refused");
988 else if (instant_dock
)
989 engage_docking_computer();
1000 if (!docked
&& cmdr
.ecm
)
1004 if (kbd_find_pressed
)
1007 if (kbd_hyperspace_pressed
&& (!docked
))
1009 if (kbd_ctrl_pressed
)
1010 start_galactic_hyperspace();
1015 if (kbd_jump_pressed
&& (!docked
) && (!witchspace
))
1020 if (kbd_fire_missile_pressed
)
1026 if (kbd_origin_pressed
)
1029 if (kbd_pause_pressed
) {
1034 if (kbd_target_missile_pressed
)
1040 if (kbd_unarm_missile_pressed
)
1046 if (kbd_inc_speed_pressed
)
1050 if (flight_speed
< myship
.max_speed
)
1055 if (kbd_dec_speed_pressed
)
1059 if (flight_speed
> 1)
1067 if (kbd_down_pressed
)
1070 if (kbd_left_pressed
)
1073 if (kbd_right_pressed
)
1076 if (kbd_enter_pressed
)
1079 if (kbd_energy_bomb_pressed
&& kbd_ctrl_pressed
)
1081 if ((!docked
) && (cmdr
.energy_bomb
))
1084 cmdr
.energy_bomb
= 0;
1088 if (kbd_escape_pressed
&& kbd_ctrl_pressed
)
1090 if ((!docked
) && (cmdr
.escape_pod
) && (!witchspace
))
1091 run_escape_sequence();
1097 void set_commander_name (char *path
)
1099 char *fname
, *cname
;
1102 fname
= get_filename (path
);
1105 for (i
= 0; i
< 31; i
++)
1107 if (!isalnum(*fname
))
1110 *cname
++ = toupper(*fname
++);
1117 void save_commander_screen (void)
1123 current_screen
= SCR_SAVE_CMDR
;
1125 gfx_clear_display();
1126 gfx_display_centre_text (10, "SAVE COMMANDER", 140, GFX_COL_GOLD
);
1127 gfx_draw_line (0, 36, 511, 36);
1128 gfx_update_screen();
1130 strcpy (path
, cmdr
.name
);
1131 strcat (path
, ".nkc");
1133 okay
= gfx_request_file ("Save Commander", path
, "nkc");
1141 rv
= save_commander_file (path
);
1145 gfx_display_centre_text (175, "Error Saving Commander!", 140, GFX_COL_GOLD
);
1149 gfx_display_centre_text (175, "Commander Saved.", 140, GFX_COL_GOLD
);
1151 set_commander_name (path
);
1153 saved_cmdr
.ship_x
= docked_planet
.d
;
1154 saved_cmdr
.ship_y
= docked_planet
.b
;
1158 void load_commander_screen (void)
1163 gfx_clear_display();
1164 gfx_display_centre_text (10, "LOAD COMMANDER", 140, GFX_COL_GOLD
);
1165 gfx_draw_line (0, 36, 511, 36);
1166 gfx_update_screen();
1169 strcpy (path
, "jameson.nkc");
1171 rv
= gfx_request_file ("Load Commander", path
, "nkc");
1176 rv
= load_commander_file (path
);
1181 gfx_display_centre_text (175, "Error Loading Commander!", 140, GFX_COL_GOLD
);
1182 gfx_display_centre_text (200, "Press any key to continue.", 140, GFX_COL_GOLD
);
1183 gfx_update_screen();
1188 restore_saved_commander();
1189 set_commander_name (path
);
1196 void run_first_intro_screen (void)
1198 current_screen
= SCR_INTRO_ONE
;
1200 snd_play_midi (SND_ELITE_THEME
, TRUE
);
1202 initialise_intro1();
1209 gfx_update_screen();
1211 kbd_poll_keyboard();
1216 load_commander_screen();
1231 void run_second_intro_screen (void)
1233 current_screen
= SCR_INTRO_TWO
;
1235 snd_play_midi (SND_BLUE_DANUBE
, TRUE
);
1238 initialise_intro2();
1248 gfx_update_screen();
1250 kbd_poll_keyboard();
1252 if (kbd_space_pressed
)
1262 * Draw the game over sequence.
1265 void run_game_over_screen()
1272 current_screen
= SCR_GAME_OVER
;
1273 gfx_set_clip_region (1, 1, 510, 383);
1281 set_init_matrix (rotmat
);
1283 newship
= add_new_ship (SHIP_COBRA3
, 0, 0, -400, rotmat
, 0, 0);
1284 universe
[newship
].flags
|= FLG_DEAD
;
1286 for (i
= 0; i
< 5; i
++)
1288 type
= (rand255() & 1) ? SHIP_CARGO
: SHIP_ALLOY
;
1289 newship
= add_new_ship (type
, (rand255() & 63) - 32,
1290 (rand255() & 63) - 32, -400, rotmat
, 0, 0);
1291 universe
[newship
].rotz
= ((rand255() * 2) & 255) - 128;
1292 universe
[newship
].rotx
= ((rand255() * 2) & 255) - 128;
1293 universe
[newship
].velocity
= rand255() & 15;
1297 for (i
= 0; i
< 100; i
++)
1299 gfx_clear_display();
1302 gfx_display_centre_text (190, "GAME OVER", 140, GFX_COL_GOLD
);
1303 gfx_update_screen();
1311 * Draw a break pattern (for launching, docking and hyperspacing).
1312 * Just draw a very simple one for the moment.
1315 void display_break_pattern (void)
1319 gfx_set_clip_region (1, 1, 510, 383);
1320 gfx_clear_display();
1322 for (i
= 0; i
< 20; i
++)
1324 gfx_draw_circle (256, 192, 30 + i
* 15, GFX_COL_WHITE
);
1325 gfx_update_screen();
1331 check_mission_brief();
1332 display_commander_status();
1336 current_screen
= SCR_FRONT_VIEW
;
1340 void info_message (char *message
)
1342 strcpy (message_string
, message
);
1344 // snd_play_sample (SND_BEEP);
1352 void initialise_allegro (void)
1361 if (install_joystick(JOY_TYPE_AUTODETECT
) == 0)
1363 have_joystick
= (num_joysticks
> 0);
1371 initialise_allegro();
1374 if (gfx_graphics_startup() == 1)
1379 /* Start the sound system... */
1380 snd_sound_startup();
1382 /* Do any setup necessary for the keyboard... */
1383 kbd_keyboard_startup();
1396 current_screen
= SCR_FRONT_VIEW
;
1397 run_first_intro_screen();
1398 run_second_intro_screen();
1404 display_commander_status ();
1409 gfx_update_screen();
1410 gfx_set_clip_region (1, 1, 510, 383);
1415 handle_flight_keys ();
1420 if (message_count
> 0)
1425 if (flight_roll
> 0)
1426 decrease_flight_roll();
1428 if (flight_roll
< 0)
1429 increase_flight_roll();
1434 if (flight_climb
> 0)
1435 decrease_flight_climb();
1437 if (flight_climb
< 0)
1438 increase_flight_climb();
1444 gfx_acquire_screen();
1446 if ((current_screen
== SCR_FRONT_VIEW
) || (current_screen
== SCR_REAR_VIEW
) ||
1447 (current_screen
== SCR_LEFT_VIEW
) || (current_screen
== SCR_RIGHT_VIEW
) ||
1448 (current_screen
== SCR_INTRO_ONE
) || (current_screen
== SCR_INTRO_TWO
) ||
1449 (current_screen
== SCR_GAME_OVER
))
1451 gfx_clear_display();
1458 if ((mcount
& 127) == 0)
1459 info_message ("Docking Computers On");
1467 gfx_release_screen();
1471 if ((current_screen
== SCR_FRONT_VIEW
) || (current_screen
== SCR_REAR_VIEW
) ||
1472 (current_screen
== SCR_LEFT_VIEW
) || (current_screen
== SCR_RIGHT_VIEW
))
1480 draw_laser_sights();
1483 if (message_count
> 0)
1484 gfx_display_centre_text (358, message_string
, 120, GFX_COL_WHITE
);
1488 display_hyper_status();
1489 if ((mcount
& 3) == 0)
1491 countdown_hyperspace();
1495 gfx_release_screen();
1501 if ((mcount
& 7) == 0)
1502 regenerate_shields();
1504 if ((mcount
& 31) == 10)
1508 info_message ("ENERGY LOW");
1509 snd_play_sample (SND_BEEP
);
1515 if ((mcount
& 31) == 20)
1516 update_cabin_temp();
1518 if ((mcount
== 0) && (!witchspace
))
1527 if (current_screen
== SCR_BREAK_PATTERN
)
1528 display_break_pattern();
1530 if (cross_timer
> 0)
1533 if (cross_timer
== 0)
1535 show_distance_to_planet();
1539 if ((cross_x
!= old_cross_x
) ||
1540 (cross_y
!= old_cross_y
))
1542 if (old_cross_x
!= -1)
1543 draw_cross (old_cross_x
, old_cross_y
);
1545 old_cross_x
= cross_x
;
1546 old_cross_y
= cross_y
;
1548 draw_cross (old_cross_x
, old_cross_y
);
1553 run_game_over_screen();
1556 snd_sound_shutdown();
1558 gfx_graphics_shutdown ();