From: mdw Date: Sun, 2 Mar 2003 12:15:41 +0000 (+0000) Subject: Initial revision X-Git-Url: https://git.distorted.org.uk/~mdw/newkind/commitdiff_plain/84bbd12316a7ed2130dd1b2f2bc860a11624c3f3 Initial revision --- 84bbd12316a7ed2130dd1b2f2bc860a11624c3f3 diff --git a/alg_data.h b/alg_data.h new file mode 100644 index 0000000..fd24597 --- /dev/null +++ b/alg_data.h @@ -0,0 +1,20 @@ +/* Allegro datafile object indexes, produced by grabber v3.9.32 (WIP), Mingw32 */ +/* Datafile: c:\usr\cprogs\NewKind\elite.dat */ +/* Date: Mon May 07 19:20:00 2001 */ +/* Do not hand edit! */ + +#define BLAKE 0 /* BMP */ +#define DANUBE 1 /* MIDI */ +#define ECM 2 /* BMP */ +#define ELITE_1 3 /* FONT */ +#define ELITE_2 4 /* FONT */ +#define ELITETXT 5 /* BMP */ +#define FRONTV 6 /* BMP */ +#define GRNDOT 7 /* BMP */ +#define MISSILE_G 8 /* BMP */ +#define MISSILE_R 9 /* BMP */ +#define MISSILE_Y 10 /* BMP */ +#define REDDOT 11 /* BMP */ +#define SAFE 12 /* BMP */ +#define THEME 13 /* MIDI */ + diff --git a/alg_gfx.c b/alg_gfx.c new file mode 100644 index 0000000..222b0c0 --- /dev/null +++ b/alg_gfx.c @@ -0,0 +1,771 @@ +/** + * + * Elite - The New Kind. + * + * Allegro version of Graphics routines. + * + * The code in this file has not been derived from the original Elite code. + * Written by C.J.Pinder 1999-2001. + * email: + * + * Routines for drawing anti-aliased lines and circles by T.Harte. + * + **/ + +#include +#include +#include +#include +#include + +#include "allegro.h" + +#include "config.h" +#include "gfx.h" +#include "alg_data.h" +#include "elite.h" + +BITMAP *gfx_screen; +volatile int frame_count; +DATAFILE *datafile; +BITMAP *scanner_image; + +#define MAX_POLYS 100 + +static int start_poly; +static int total_polys; + +struct poly_data +{ + int z; + int no_points; + int face_colour; + int point_list[16]; + int next; +}; + +static struct poly_data poly_chain[MAX_POLYS]; + + + + +void frame_timer (void) +{ + frame_count++; +} +END_OF_FUNCTION(frame_timer); + + + +int gfx_graphics_startup (void) +{ + PALETTE the_palette; + int rv; + +#ifdef ALLEGRO_WINDOWS + +#ifdef RES_512_512 + rv = set_gfx_mode(GFX_DIRECTX_OVL, 512, 512, 0, 0); + + if (rv != 0) + rv = set_gfx_mode(GFX_DIRECTX_WIN, 512, 512, 0, 0); + + if (rv != 0) + rv = set_gfx_mode(GFX_GDI, 512, 512, 0, 0); + + if (rv == 0) + set_display_switch_mode (SWITCH_BACKGROUND); +#else + rv = set_gfx_mode(GFX_DIRECTX, 800, 600, 0, 0); + + if (rv != 0) + rv = set_gfx_mode(GFX_GDI, 800, 600, 0, 0); +#endif + +#else + rv = set_gfx_mode(GFX_AUTODETECT, 800, 600, 0, 0); +#endif + + if (rv != 0) + { + set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); + allegro_message("Unable to set graphics mode."); + return 1; + } + + datafile = load_datafile("elite.dat"); + if (!datafile) + { + set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); + allegro_message("Error loading %s!\n", "elite.dat"); + return 1; + } + + scanner_image = load_bitmap(scanner_filename, the_palette); + if (!scanner_image) + { + set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); + allegro_message("Error reading scanner bitmap file.\n"); + return 1; + } + + /* select the scanner palette */ + set_palette(the_palette); + + /* Create the screen buffer bitmap */ + gfx_screen = create_bitmap (SCREEN_W, SCREEN_H); + + clear (gfx_screen); + + blit (scanner_image, gfx_screen, 0, 0, GFX_X_OFFSET, 385+GFX_Y_OFFSET, scanner_image->w, scanner_image->h); + gfx_draw_line (0, 0, 0, 384); + gfx_draw_line (0, 0, 511, 0); + gfx_draw_line (511, 0, 511, 384); + + /* Install a timer to regulate the speed of the game... */ + + LOCK_VARIABLE(frame_count); + LOCK_FUNCTION(frame_timer); + frame_count = 0; + install_int (frame_timer, speed_cap); + + return 0; +} + + +void gfx_graphics_shutdown (void) +{ + destroy_bitmap(scanner_image); + destroy_bitmap(gfx_screen); + unload_datafile(datafile); +} + + +/* + * Blit the back buffer to the screen. + */ + +void gfx_update_screen (void) +{ + while (frame_count < 1) + rest (10); + frame_count = 0; + + acquire_screen(); + blit (gfx_screen, screen, GFX_X_OFFSET, GFX_Y_OFFSET, GFX_X_OFFSET, GFX_Y_OFFSET, 512, 512); + release_screen(); +} + + +void gfx_acquire_screen (void) +{ + acquire_bitmap (gfx_screen); +} + + +void gfx_release_screen (void) +{ + release_bitmap(gfx_screen); +} + +void gfx_fast_plot_pixel (int x, int y, int col) +{ +// _putpixel(gfx_screen, x, y, col); + gfx_screen->line[y][x] = col; +} + + +void gfx_plot_pixel (int x, int y, int col) +{ + putpixel (gfx_screen, x + GFX_X_OFFSET, y + GFX_Y_OFFSET, col); +} + + +void gfx_draw_filled_circle (int cx, int cy, int radius, int circle_colour) +{ + circlefill (gfx_screen, cx + GFX_X_OFFSET, cy + GFX_Y_OFFSET, radius, circle_colour); +} + + +#define AA_BITS 3 +#define AA_AND 7 +#define AA_BASE 235 + +#define trunc(x) ((x) & ~65535) +#define frac(x) ((x) & 65535) +#define invfrac(x) (65535-frac(x)) +#define plot(x,y,c) putpixel(gfx_screen, (x), (y), (c)+AA_BASE) + +/* + * Draw anti-aliased wireframe circle. + * By T.Harte. + */ + +void gfx_draw_aa_circle(int cx, int cy, int radius) +{ + int x,y; + int s; + int sx, sy; + + cx += GFX_X_OFFSET; + cy += GFX_Y_OFFSET; + + radius >>= (16 - AA_BITS); + + x = radius; + s = -radius; + y = 0; + + while (y <= x) + { + //wide pixels + sx = cx + (x >> AA_BITS); sy = cy + (y >> AA_BITS); + + plot(sx, sy, AA_AND - (x&AA_AND)); + plot(sx + 1, sy, x&AA_AND); + + sy = cy - (y >> AA_BITS); + + plot(sx, sy, AA_AND - (x&AA_AND)); + plot(sx + 1, sy, x&AA_AND); + + sx = cx - (x >> AA_BITS); + + plot(sx, sy, AA_AND - (x&AA_AND)); + plot(sx - 1, sy, x&AA_AND); + + sy = cy + (y >> AA_BITS); + + plot(sx, sy, AA_AND - (x&AA_AND)); + plot(sx - 1, sy, x&AA_AND); + + //tall pixels + sx = cx + (y >> AA_BITS); sy = cy + (x >> AA_BITS); + + plot(sx, sy, AA_AND - (x&AA_AND)); + plot(sx, sy + 1, x&AA_AND); + + sy = cy - (x >> AA_BITS); + + plot(sx, sy, AA_AND - (x&AA_AND)); + plot(sx, sy - 1, x&AA_AND); + + sx = cx - (y >> AA_BITS); + + plot(sx, sy, AA_AND - (x&AA_AND)); + plot(sx, sy - 1, x&AA_AND); + + sy = cy + (x >> AA_BITS); + + plot(sx, sy, AA_AND - (x&AA_AND)); + plot(sx, sy + 1, x&AA_AND); + + s += AA_AND+1 + (y << (AA_BITS+1)) + ((1 << (AA_BITS+2))-2); + y += AA_AND+1; + + while(s >= 0) + { + s -= (x << 1) + 2; + x --; + } + } +} + + +/* + * Draw anti-aliased line. + * By T.Harte. + */ + +void gfx_draw_aa_line (int x1, int y1, int x2, int y2) +{ + fixed grad, xd, yd; + fixed xgap, ygap, xend, yend, xf, yf; + fixed brightness1, brightness2, swap; + + int x, y, ix1, ix2, iy1, iy2; + + x1 += itofix(GFX_X_OFFSET); + x2 += itofix(GFX_X_OFFSET); + y1 += itofix(GFX_Y_OFFSET); + y2 += itofix(GFX_Y_OFFSET); + + xd = x2 - x1; + yd = y2 - y1; + + if (abs(xd) > abs(yd)) + { + if(x1 > x2) + { + swap = x1; x1 = x2; x2 = swap; + swap = y1; y1 = y2; y2 = swap; + xd = -xd; + yd = -yd; + } + + grad = fdiv(yd, xd); + + //end point 1 + + xend = trunc(x1 + 32768); + yend = y1 + fmul(grad, xend-x1); + + xgap = invfrac(x1+32768); + + ix1 = xend >> 16; + iy1 = yend >> 16; + + brightness1 = fmul(invfrac(yend), xgap); + brightness2 = fmul(frac(yend), xgap); + + plot(ix1, iy1, brightness1 >> (16-AA_BITS)); + plot(ix1, iy1+1, brightness2 >> (16-AA_BITS)); + + yf = yend+grad; + + //end point 2; + + xend = trunc(x2 + 32768); + yend = y2 + fmul(grad, xend-x2); + + xgap = invfrac(x2 - 32768); + + ix2 = xend >> 16; + iy2 = yend >> 16; + + brightness1 = fmul(invfrac(yend), xgap); + brightness2 = fmul(frac(yend), xgap); + + plot(ix2, iy2, brightness1 >> (16-AA_BITS)); + plot(ix2, iy2+1, brightness2 >> (16-AA_BITS)); + + for(x = ix1+1; x <= ix2-1; x++) + { + brightness1 = invfrac(yf); + brightness2 = frac(yf); + + plot(x, (yf >> 16), brightness1 >> (16-AA_BITS)); + plot(x, 1+(yf >> 16), brightness2 >> (16-AA_BITS)); + + yf += grad; + } + } + else + { + if(y1 > y2) + { + swap = x1; x1 = x2; x2 = swap; + swap = y1; y1 = y2; y2 = swap; + xd = -xd; + yd = -yd; + } + + grad = fdiv(xd, yd); + + //end point 1 + + yend = trunc(y1 + 32768); + xend = x1 + fmul(grad, yend-y1); + + ygap = invfrac(y1+32768); + + iy1 = yend >> 16; + ix1 = xend >> 16; + + brightness1 = fmul(invfrac(xend), ygap); + brightness2 = fmul(frac(xend), ygap); + + plot(ix1, iy1, brightness1 >> (16-AA_BITS)); + plot(ix1+1, iy1, brightness2 >> (16-AA_BITS)); + + xf = xend+grad; + + //end point 2; + + yend = trunc(y2 + 32768); + xend = x2 + fmul(grad, yend-y2); + + ygap = invfrac(y2 - 32768); + + ix2 = xend >> 16; + iy2 = yend >> 16; + + brightness1 = fmul(invfrac(xend), ygap); + brightness2 = fmul(frac(xend), ygap); + + plot(ix2, iy2, brightness1 >> (16-AA_BITS)); + plot(ix2+1, iy2, brightness2 >> (16-AA_BITS)); + + for(y = iy1+1; y <= iy2-1; y++) + { + brightness1 = invfrac(xf); + brightness2 = frac(xf); + + plot((xf >> 16), y, brightness1 >> (16-AA_BITS)); + plot(1+(xf >> 16), y, brightness2 >> (16-AA_BITS)); + + xf += grad; + } + } +} + +#undef trunc +#undef frac +#undef invfrac +#undef plot + +#undef AA_BITS +#undef AA_AND +#undef AA_BASE + + + +void gfx_draw_circle (int cx, int cy, int radius, int circle_colour) +{ + if (anti_alias_gfx && (circle_colour == GFX_COL_WHITE)) + gfx_draw_aa_circle (cx, cy, itofix(radius)); + else + circle (gfx_screen, cx + GFX_X_OFFSET, cy + GFX_Y_OFFSET, radius, circle_colour); +} + + + +void gfx_draw_line (int x1, int y1, int x2, int y2) +{ + if (y1 == y2) + { + hline (gfx_screen, x1 + GFX_X_OFFSET, y1 + GFX_Y_OFFSET, x2 + GFX_X_OFFSET, GFX_COL_WHITE); + return; + } + + if (x1 == x2) + { + vline (gfx_screen, x1 + GFX_X_OFFSET, y1 + GFX_Y_OFFSET, y2 + GFX_Y_OFFSET, GFX_COL_WHITE); + return; + } + + if (anti_alias_gfx) + gfx_draw_aa_line (itofix(x1), itofix(y1), itofix(x2), itofix(y2)); + else + line (gfx_screen, x1 + GFX_X_OFFSET, y1 + GFX_Y_OFFSET, x2 + GFX_X_OFFSET, y2 + GFX_Y_OFFSET, GFX_COL_WHITE); +} + + + +void gfx_draw_colour_line (int x1, int y1, int x2, int y2, int line_colour) +{ + if (y1 == y2) + { + hline (gfx_screen, x1 + GFX_X_OFFSET, y1 + GFX_Y_OFFSET, x2 + GFX_X_OFFSET, line_colour); + return; + } + + if (x1 == x2) + { + vline (gfx_screen, x1 + GFX_X_OFFSET, y1 + GFX_Y_OFFSET, y2 + GFX_Y_OFFSET, line_colour); + return; + } + + if (anti_alias_gfx && (line_colour == GFX_COL_WHITE)) + gfx_draw_aa_line (itofix(x1), itofix(y1), itofix(x2), itofix(y2)); + else + line (gfx_screen, x1 + GFX_X_OFFSET, y1 + GFX_Y_OFFSET, x2 + GFX_X_OFFSET, y2 + GFX_Y_OFFSET, line_colour); +} + + + +void gfx_draw_triangle (int x1, int y1, int x2, int y2, int x3, int y3, int col) +{ + triangle (gfx_screen, x1 + GFX_X_OFFSET, y1 + GFX_Y_OFFSET, x2 + GFX_X_OFFSET, y2 + GFX_Y_OFFSET, + x3 + GFX_X_OFFSET, y3 + GFX_Y_OFFSET, col); +} + + + +void gfx_display_text (int x, int y, char *txt) +{ + text_mode (-1); + textout (gfx_screen, datafile[ELITE_1].dat, txt, (x / (2 / GFX_SCALE)) + GFX_X_OFFSET, (y / (2 / GFX_SCALE)) + GFX_Y_OFFSET, GFX_COL_WHITE); +} + + +void gfx_display_colour_text (int x, int y, char *txt, int col) +{ + text_mode (-1); + textout (gfx_screen, datafile[ELITE_1].dat, txt, (x / (2 / GFX_SCALE)) + GFX_X_OFFSET, (y / (2 / GFX_SCALE)) + GFX_Y_OFFSET, col); +} + + + +void gfx_display_centre_text (int y, char *str, int psize, int col) +{ + int txt_size; + int txt_colour; + + if (psize == 140) + { + txt_size = ELITE_2; + txt_colour = -1; + } + else + { + txt_size = ELITE_1; + txt_colour = col; + } + + text_mode (-1); + textout_centre (gfx_screen, datafile[txt_size].dat, str, (128 * GFX_SCALE) + GFX_X_OFFSET, (y / (2 / GFX_SCALE)) + GFX_Y_OFFSET, txt_colour); +} + + +void gfx_clear_display (void) +{ + rectfill (gfx_screen, GFX_X_OFFSET + 1, GFX_Y_OFFSET + 1, 510 + GFX_X_OFFSET, 383 + GFX_Y_OFFSET, GFX_COL_BLACK); +} + +void gfx_clear_text_area (void) +{ + rectfill (gfx_screen, GFX_X_OFFSET + 1, GFX_Y_OFFSET + 340, 510 + GFX_X_OFFSET, 383 + GFX_Y_OFFSET, GFX_COL_BLACK); +} + + +void gfx_clear_area (int tx, int ty, int bx, int by) +{ + rectfill (gfx_screen, tx + GFX_X_OFFSET, ty + GFX_Y_OFFSET, + bx + GFX_X_OFFSET, by + GFX_Y_OFFSET, GFX_COL_BLACK); +} + +void gfx_draw_rectangle (int tx, int ty, int bx, int by, int col) +{ + rectfill (gfx_screen, tx + GFX_X_OFFSET, ty + GFX_Y_OFFSET, + bx + GFX_X_OFFSET, by + GFX_Y_OFFSET, col); +} + + +void gfx_display_pretty_text (int tx, int ty, int bx, int by, char *txt) +{ + char strbuf[100]; + char *str; + char *bptr; + int len; + int pos; + int maxlen; + + maxlen = (bx - tx) / 8; + + str = txt; + len = strlen(txt); + + while (len > 0) + { + pos = maxlen; + if (pos > len) + pos = len; + + while ((str[pos] != ' ') && (str[pos] != ',') && + (str[pos] != '.') && (str[pos] != '\0')) + { + pos--; + } + + len = len - pos - 1; + + for (bptr = strbuf; pos >= 0; pos--) + *bptr++ = *str++; + + *bptr = '\0'; + + text_mode (-1); + textout (gfx_screen, datafile[ELITE_1].dat, strbuf, tx + GFX_X_OFFSET, ty + GFX_Y_OFFSET, GFX_COL_WHITE); + ty += (8 * GFX_SCALE); + } +} + + +void gfx_draw_scanner (void) +{ + blit (scanner_image, gfx_screen, 0, 0, GFX_X_OFFSET, 385+GFX_Y_OFFSET, scanner_image->w, scanner_image->h); +} + +void gfx_set_clip_region (int tx, int ty, int bx, int by) +{ + set_clip (gfx_screen, tx + GFX_X_OFFSET, ty + GFX_Y_OFFSET, bx + GFX_X_OFFSET, by + GFX_Y_OFFSET); +} + + +void gfx_start_render (void) +{ + start_poly = 0; + total_polys = 0; +} + + +void gfx_render_polygon (int num_points, int *point_list, int face_colour, int zavg) +{ + int i; + int x; + int nx; + + if (total_polys == MAX_POLYS) + return; + + x = total_polys; + total_polys++; + + poly_chain[x].no_points = num_points; + poly_chain[x].face_colour = face_colour; + poly_chain[x].z = zavg; + poly_chain[x].next = -1; + + for (i = 0; i < 16; i++) + poly_chain[x].point_list[i] = point_list[i]; + + if (x == 0) + return; + + if (zavg > poly_chain[start_poly].z) + { + poly_chain[x].next = start_poly; + start_poly = x; + return; + } + + for (i = start_poly; poly_chain[i].next != -1; i = poly_chain[i].next) + { + nx = poly_chain[i].next; + + if (zavg > poly_chain[nx].z) + { + poly_chain[i].next = x; + poly_chain[x].next = nx; + return; + } + } + + poly_chain[i].next = x; +} + + +void gfx_render_line (int x1, int y1, int x2, int y2, int dist, int col) +{ + int point_list[4]; + + point_list[0] = x1; + point_list[1] = y1; + point_list[2] = x2; + point_list[3] = y2; + + gfx_render_polygon (2, point_list, col, dist); +} + + +void gfx_finish_render (void) +{ + int num_points; + int *pl; + int i; + int col; + + if (total_polys == 0) + return; + + for (i = start_poly; i != -1; i = poly_chain[i].next) + { + num_points = poly_chain[i].no_points; + pl = poly_chain[i].point_list; + col = poly_chain[i].face_colour; + + if (num_points == 2) + { + gfx_draw_colour_line (pl[0], pl[1], pl[2], pl[3], col); + continue; + } + + gfx_polygon (num_points, pl, col); + }; +} + + +void gfx_polygon (int num_points, int *poly_list, int face_colour) +{ + int i; + int x,y; + + x = 0; + y = 1; + for (i = 0; i < num_points; i++) + { + poly_list[x] += GFX_X_OFFSET; + poly_list[y] += GFX_Y_OFFSET; + x += 2; + y += 2; + } + + polygon (gfx_screen, num_points, poly_list, face_colour); +} + + +void gfx_draw_sprite (int sprite_no, int x, int y) +{ + BITMAP *sprite_bmp; + + switch (sprite_no) + { + case IMG_GREEN_DOT: + sprite_bmp = datafile[GRNDOT].dat; + break; + + case IMG_RED_DOT: + sprite_bmp = datafile[REDDOT].dat; + break; + + case IMG_BIG_S: + sprite_bmp = datafile[SAFE].dat; + break; + + case IMG_ELITE_TXT: + sprite_bmp = datafile[ELITETXT].dat; + break; + + case IMG_BIG_E: + sprite_bmp = datafile[ECM].dat; + break; + + case IMG_BLAKE: + sprite_bmp = datafile[BLAKE].dat; + break; + + case IMG_MISSILE_GREEN: + sprite_bmp = datafile[MISSILE_G].dat; + break; + + case IMG_MISSILE_YELLOW: + sprite_bmp = datafile[MISSILE_Y].dat; + break; + + case IMG_MISSILE_RED: + sprite_bmp = datafile[MISSILE_R].dat; + break; + + default: + return; + } + + if (x == -1) + x = ((256 * GFX_SCALE) - sprite_bmp->w) / 2; + + draw_sprite (gfx_screen, sprite_bmp, x + GFX_X_OFFSET, y + GFX_Y_OFFSET); +} + + +int gfx_request_file (char *title, char *path, char *ext) +{ + int okay; + + show_mouse (screen); + okay = file_select (title, path, ext); + show_mouse (NULL); + + return okay; +} + diff --git a/alg_main.c b/alg_main.c new file mode 100644 index 0000000..ef1246e --- /dev/null +++ b/alg_main.c @@ -0,0 +1,1447 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * alg_main.c + * + * Allegro version of the main game handler. + */ + + +#include +#include +#include +#include +#include +#include + +#include "allegro.h" + +#include "config.h" +#include "gfx.h" +#include "main.h" +#include "vector.h" +#include "alg_data.h" +#include "elite.h" +#include "docked.h" +#include "intro.h" +#include "shipdata.h" +#include "shipface.h" +#include "space.h" +#include "sound.h" +#include "threed.h" +#include "swat.h" +#include "random.h" +#include "options.h" +#include "stars.h" +#include "missions.h" +#include "pilot.h" +#include "file.h" +#include "keyboard.h" + + + +int old_cross_x, old_cross_y; +int cross_timer; + +int draw_lasers; +int mcount; +int message_count; +char message_string[80]; +int rolling; +int climbing; +int game_paused; +int have_joystick; + +int find_input; +char find_name[20]; + + + +/* + * Initialise the game parameters. + */ + +void initialise_game(void) +{ + set_rand_seed (time(NULL)); + current_screen = SCR_INTRO_ONE; + + restore_saved_commander(); + + flight_speed = 1; + flight_roll = 0; + flight_climb = 0; + docked = 1; + front_shield = 255; + aft_shield = 255; + energy = 255; + draw_lasers = 0; + mcount = 0; + hyper_ready = 0; + detonate_bomb = 0; + find_input = 0; + witchspace = 0; + game_paused = 0; + auto_pilot = 0; + + create_new_stars(); + clear_universe(); + + cross_x = -1; + cross_y = -1; + cross_timer = 0; + + + myship.max_speed = 40; /* 0.27 Light Mach */ + myship.max_roll = 31; + myship.max_climb = 8; /* CF 8 */ + myship.max_fuel = 70; /* 7.0 Light Years */ +} + + +void finish_game (void) +{ + finish = 1; + game_over = 1; +} + + + + + + + +/* + * Move the planet chart cross hairs to specified position. + */ + + +void move_cross (int dx, int dy) +{ + cross_timer = 5; + + if (current_screen == SCR_SHORT_RANGE) + { + cross_x += (dx * 4); + cross_y += (dy * 4); + return; + } + + if (current_screen == SCR_GALACTIC_CHART) + { + cross_x += (dx * 2); + cross_y += (dy * 2); + + if (cross_x < 1) + cross_x = 1; + + if (cross_x > 510) + cross_x = 510; + + if (cross_y < 37) + cross_y = 37; + + if (cross_y > 293) + cross_y = 293; + } +} + + +/* + * Draw the cross hairs at the specified position. + */ + +void draw_cross (int cx, int cy) +{ + if (current_screen == SCR_SHORT_RANGE) + { + gfx_set_clip_region (1, 37, 510, 339); + xor_mode (TRUE); + gfx_draw_colour_line (cx - 16, cy, cx + 16, cy, GFX_COL_RED); + gfx_draw_colour_line (cx, cy - 16, cx, cy + 16, GFX_COL_RED); + xor_mode (FALSE); + gfx_set_clip_region (1, 1, 510, 383); + return; + } + + if (current_screen == SCR_GALACTIC_CHART) + { + gfx_set_clip_region (1, 37, 510, 293); + xor_mode (TRUE); + gfx_draw_colour_line (cx - 8, cy, cx + 8, cy, GFX_COL_RED); + gfx_draw_colour_line (cx, cy - 8, cx, cy + 8, GFX_COL_RED); + xor_mode (FALSE); + gfx_set_clip_region (1, 1, 510, 383); + } +} + + + +void draw_laser_sights(void) +{ + int laser = 0; + int x1,y1,x2,y2; + + switch (current_screen) + { + case SCR_FRONT_VIEW: + gfx_display_centre_text (32, "Front View", 120, GFX_COL_WHITE); + laser = cmdr.front_laser; + break; + + case SCR_REAR_VIEW: + gfx_display_centre_text (32, "Rear View", 120, GFX_COL_WHITE); + laser = cmdr.rear_laser; + break; + + case SCR_LEFT_VIEW: + gfx_display_centre_text (32, "Left View", 120, GFX_COL_WHITE); + laser = cmdr.left_laser; + break; + + case SCR_RIGHT_VIEW: + gfx_display_centre_text (32, "Right View", 120, GFX_COL_WHITE); + laser = cmdr.right_laser; + break; + } + + + if (laser) + { + x1 = 128 * GFX_SCALE; + y1 = (96-8) * GFX_SCALE; + y2 = (96-16) * GFX_SCALE; + + gfx_draw_colour_line (x1-1, y1, x1-1, y2, GFX_COL_GREY_1); + gfx_draw_colour_line (x1, y1, x1, y2, GFX_COL_WHITE); + gfx_draw_colour_line (x1+1, y1, x1+1, y2, GFX_COL_GREY_1); + + y1 = (96+8) * GFX_SCALE; + y2 = (96+16) * GFX_SCALE; + + gfx_draw_colour_line (x1-1, y1, x1-1, y2, GFX_COL_GREY_1); + gfx_draw_colour_line (x1, y1, x1, y2, GFX_COL_WHITE); + gfx_draw_colour_line (x1+1, y1, x1+1, y2, GFX_COL_GREY_1); + + x1 = (128-8) * GFX_SCALE; + y1 = 96 * GFX_SCALE; + x2 = (128-16) * GFX_SCALE; + + gfx_draw_colour_line (x1, y1-1, x2, y1-1, GFX_COL_GREY_1); + gfx_draw_colour_line (x1, y1, x2, y1, GFX_COL_WHITE); + gfx_draw_colour_line (x1, y1+1, x2, y1+1, GFX_COL_GREY_1); + + x1 = (128+8) * GFX_SCALE; + x2 = (128+16) * GFX_SCALE; + + gfx_draw_colour_line (x1, y1-1, x2, y1-1, GFX_COL_GREY_1); + gfx_draw_colour_line (x1, y1, x2, y1, GFX_COL_WHITE); + gfx_draw_colour_line (x1, y1+1, x2, y1+1, GFX_COL_GREY_1); + } +} + + +void arrow_right (void) +{ + switch (current_screen) + { + case SCR_MARKET_PRICES: + buy_stock(); + break; + + case SCR_SETTINGS: + select_right_setting(); + break; + + case SCR_SHORT_RANGE: + case SCR_GALACTIC_CHART: + move_cross(1, 0); + break; + + case SCR_FRONT_VIEW: + case SCR_REAR_VIEW: + case SCR_RIGHT_VIEW: + case SCR_LEFT_VIEW: + if (flight_roll > 0) + flight_roll = 0; + else + { + decrease_flight_roll(); + decrease_flight_roll(); + rolling = 1; + } + break; + } +} + + +void arrow_left (void) +{ + switch (current_screen) + { + case SCR_MARKET_PRICES: + sell_stock(); + break; + + case SCR_SETTINGS: + select_left_setting(); + break; + + case SCR_SHORT_RANGE: + case SCR_GALACTIC_CHART: + move_cross (-1, 0); + break; + + case SCR_FRONT_VIEW: + case SCR_REAR_VIEW: + case SCR_RIGHT_VIEW: + case SCR_LEFT_VIEW: + if (flight_roll < 0) + flight_roll = 0; + else + { + increase_flight_roll(); + increase_flight_roll(); + rolling = 1; + } + break; + } +} + + +void arrow_up (void) +{ + switch (current_screen) + { + case SCR_MARKET_PRICES: + select_previous_stock(); + break; + + case SCR_EQUIP_SHIP: + select_previous_equip(); + break; + + case SCR_OPTIONS: + select_previous_option(); + break; + + case SCR_SETTINGS: + select_up_setting(); + break; + + case SCR_SHORT_RANGE: + case SCR_GALACTIC_CHART: + move_cross (0, -1); + break; + + case SCR_FRONT_VIEW: + case SCR_REAR_VIEW: + case SCR_RIGHT_VIEW: + case SCR_LEFT_VIEW: + if (flight_climb > 0) + flight_climb = 0; + else + { + decrease_flight_climb(); + } + climbing = 1; + break; + } +} + + + +void arrow_down (void) +{ + switch (current_screen) + { + case SCR_MARKET_PRICES: + select_next_stock(); + break; + + case SCR_EQUIP_SHIP: + select_next_equip(); + break; + + case SCR_OPTIONS: + select_next_option(); + break; + + case SCR_SETTINGS: + select_down_setting(); + break; + + case SCR_SHORT_RANGE: + case SCR_GALACTIC_CHART: + move_cross (0, 1); + break; + + case SCR_FRONT_VIEW: + case SCR_REAR_VIEW: + case SCR_RIGHT_VIEW: + case SCR_LEFT_VIEW: + if (flight_climb < 0) + flight_climb = 0; + else + { + increase_flight_climb(); + } + climbing = 1; + break; + + } +} + + +void return_pressed (void) +{ + switch (current_screen) + { + case SCR_EQUIP_SHIP: + buy_equip(); + break; + + case SCR_OPTIONS: + do_option(); + break; + + case SCR_SETTINGS: + toggle_setting(); + break; + } +} + + +void y_pressed (void) +{ + switch (current_screen) + { + case SCR_QUIT: + finish_game(); + break; + } +} + + +void n_pressed (void) +{ + switch (current_screen) + { + case SCR_QUIT: + if (docked) + display_commander_status(); + else + current_screen = SCR_FRONT_VIEW; + break; + } +} + + +void d_pressed (void) +{ + switch (current_screen) + { + case SCR_GALACTIC_CHART: + case SCR_SHORT_RANGE: + show_distance_to_planet(); + break; + + case SCR_FRONT_VIEW: + case SCR_REAR_VIEW: + case SCR_RIGHT_VIEW: + case SCR_LEFT_VIEW: + if (auto_pilot) + disengage_auto_pilot(); + break; + } +} + + +void f_pressed (void) +{ + if ((current_screen == SCR_GALACTIC_CHART) || + (current_screen == SCR_SHORT_RANGE)) + { + find_input = 1; + *find_name = '\0'; + gfx_clear_text_area(); + gfx_display_text (16, 340, "Planet Name?"); + } +} + + +void add_find_char (int letter) +{ + char str[40]; + + if (strlen (find_name) == 16) + return; + + str[0] = toupper (letter); + str[1] = '\0'; + strcat (find_name, str); + + sprintf (str, "Planet Name? %s", find_name); + gfx_clear_text_area (); + gfx_display_text(16, 340, str); +} + + +void delete_find_char (void) +{ + char str[40]; + int len; + + len = strlen (find_name); + if (len == 0) + return; + + find_name[len - 1] = '\0'; + + sprintf (str, "Planet Name? %s", find_name); + gfx_clear_text_area(); + gfx_display_text(16, 340, str); +} + +void o_pressed() +{ + switch (current_screen) + { + case SCR_GALACTIC_CHART: + case SCR_SHORT_RANGE: + move_cursor_to_origin(); + break; + } +} + + +void auto_dock (void) +{ + struct univ_object ship; + + ship.location.x = 0; + ship.location.y = 0; + ship.location.z = 0; + + set_init_matrix (ship.rotmat); + ship.rotmat[2].z = 1; + ship.rotmat[0].x = -1; + ship.type = -96; + ship.velocity = flight_speed; + ship.acceleration = 0; + ship.bravery = 0; + ship.rotz = 0; + ship.rotx = 0; + + auto_pilot_ship (&ship); + + if (ship.velocity > 22) + flight_speed = 22; + else + flight_speed = ship.velocity; + + if (ship.acceleration > 0) + { + flight_speed++; + if (flight_speed > 22) + flight_speed = 22; + } + + if (ship.acceleration < 0) + { + flight_speed--; + if (flight_speed < 1) + flight_speed = 1; + } + + if (ship.rotx == 0) + flight_climb = 0; + + if (ship.rotx < 0) + { + increase_flight_climb(); + + if (ship.rotx < -1) + increase_flight_climb(); + } + + if (ship.rotx > 0) + { + decrease_flight_climb(); + + if (ship.rotx > 1) + decrease_flight_climb(); + } + + if (ship.rotz == 127) + flight_roll = -14; + else + { + if (ship.rotz == 0) + flight_roll = 0; + + if (ship.rotz > 0) + { + increase_flight_roll(); + + if (ship.rotz > 1) + increase_flight_roll(); + } + + if (ship.rotz < 0) + { + decrease_flight_roll(); + + if (ship.rotz < -1) + decrease_flight_roll(); + } + } +} + + +void run_escape_sequence (void) +{ + int i; + int newship; + Matrix rotmat; + + current_screen = SCR_ESCAPE_POD; + + flight_speed = 1; + flight_roll = 0; + flight_climb = 0; + + set_init_matrix (rotmat); + rotmat[2].z = 1.0; + + newship = add_new_ship (SHIP_COBRA3, 0, 0, 200, rotmat, -127, -127); + universe[newship].velocity = 7; + snd_play_sample (SND_LAUNCH); + + for (i = 0; i < 90; i++) + { + if (i == 40) + { + universe[newship].flags |= FLG_DEAD; + snd_play_sample (SND_EXPLODE); + } + + gfx_set_clip_region (1, 1, 510, 383); + gfx_clear_display(); + update_starfield(); + update_universe(); + + universe[newship].location.x = 0; + universe[newship].location.y = 0; + universe[newship].location.z += 2; + + gfx_display_centre_text (358, "Escape pod launched - Ship auto-destuct initiated.", 120, GFX_COL_WHITE); + + update_console(); + gfx_update_screen(); + } + + + while ((ship_count[SHIP_CORIOLIS] == 0) && + (ship_count[SHIP_DODEC] == 0)) + { + auto_dock(); + + if ((abs(flight_roll) < 3) && (abs(flight_climb) < 3)) + { + for (i = 0; i < MAX_UNIV_OBJECTS; i++) + { + if (universe[i].type != 0) + universe[i].location.z -= 1500; + } + + } + + warp_stars = 1; + gfx_set_clip_region (1, 1, 510, 383); + gfx_clear_display(); + update_starfield(); + update_universe(); + update_console(); + gfx_update_screen(); + } + + abandon_ship(); +} + + +void handle_flight_keys (void) +{ + int keyasc; + + if (docked && + ((current_screen == SCR_MARKET_PRICES) || + (current_screen == SCR_OPTIONS) || + (current_screen == SCR_SETTINGS) || + (current_screen == SCR_EQUIP_SHIP))) + kbd_read_key(); + + kbd_poll_keyboard(); + + if (have_joystick) + { + poll_joystick(); + + if (joy[0].stick[0].axis[1].d1) + arrow_up(); + + if (joy[0].stick[0].axis[1].d2) + arrow_down(); + + if (joy[0].stick[0].axis[0].d1) + arrow_left(); + + if (joy[0].stick[0].axis[0].d2) + arrow_right(); + + if (joy[0].button[0].b) + kbd_fire_pressed = 1; + + if (joy[0].button[1].b) + kbd_inc_speed_pressed = 1; + + if (joy[0].button[2].b) + kbd_dec_speed_pressed = 1; + } + + + if (game_paused) + { + if (kbd_resume_pressed) + game_paused = 0; + return; + } + + if (kbd_F1_pressed) + { + find_input = 0; + + if (docked) + launch_player(); + else + { + if (current_screen != SCR_FRONT_VIEW) + { + current_screen = SCR_FRONT_VIEW; + flip_stars(); + } + } + } + + if (kbd_F2_pressed) + { + find_input = 0; + + if (!docked) + { + if (current_screen != SCR_REAR_VIEW) + { + current_screen = SCR_REAR_VIEW; + flip_stars(); + } + } + } + + if (kbd_F3_pressed) + { + find_input = 0; + + if (!docked) + { + if (current_screen != SCR_LEFT_VIEW) + { + current_screen = SCR_LEFT_VIEW; + flip_stars(); + } + } + } + + if (kbd_F4_pressed) + { + find_input = 0; + + if (docked) + equip_ship(); + else + { + if (current_screen != SCR_RIGHT_VIEW) + { + current_screen = SCR_RIGHT_VIEW; + flip_stars(); + } + } + } + + + if (kbd_F5_pressed) + { + find_input = 0; + old_cross_x = -1; + display_galactic_chart(); + } + + if (kbd_F6_pressed) + { + find_input = 0; + old_cross_x = -1; + display_short_range_chart(); + } + + if (kbd_F7_pressed) + { + find_input = 0; + display_data_on_planet(); + } + + if (kbd_F8_pressed && (!witchspace)) + { + find_input = 0; + display_market_prices(); + } + + if (kbd_F9_pressed) + { + find_input = 0; + display_commander_status(); + } + + if (kbd_F10_pressed) + { + find_input = 0; + display_inventory(); + } + + if (kbd_F11_pressed) + { + find_input = 0; + display_options(); + } + + if (find_input) + { + keyasc = kbd_read_key(); + + if (kbd_enter_pressed) + { + find_input = 0; + find_planet_by_name (find_name); + return; + } + + if (kbd_backspace_pressed) + { + delete_find_char(); + return; + } + + if (isalpha(keyasc)) + add_find_char (keyasc); + + return; + } + + if (kbd_y_pressed) + y_pressed(); + + if (kbd_n_pressed) + n_pressed(); + + + if (kbd_fire_pressed) + { + if ((!docked) && (draw_lasers == 0)) + draw_lasers = fire_laser(); + } + + if (kbd_dock_pressed) + { + if (!docked && cmdr.docking_computer) + { + if (instant_dock) + engage_docking_computer(); + else + engage_auto_pilot(); + } + } + + if (kbd_d_pressed) + d_pressed(); + + if (kbd_ecm_pressed) + { + if (!docked && cmdr.ecm) + activate_ecm(1); + } + + if (kbd_find_pressed) + f_pressed (); + + if (kbd_hyperspace_pressed && (!docked)) + { + if (kbd_ctrl_pressed) + start_galactic_hyperspace(); + else + start_hyperspace(); + } + + if (kbd_jump_pressed && (!docked) && (!witchspace)) + { + jump_warp(); + } + + if (kbd_fire_missile_pressed) + { + if (!docked) + fire_missile(); + } + + if (kbd_origin_pressed) + o_pressed(); + + if (kbd_pause_pressed) + game_paused = 1; + + if (kbd_target_missile_pressed) + { + if (!docked) + arm_missile(); + } + + if (kbd_unarm_missile_pressed) + { + if (!docked) + unarm_missile(); + } + + if (kbd_inc_speed_pressed) + { + if (!docked) + { + if (flight_speed < myship.max_speed) + flight_speed++; + } + } + + if (kbd_dec_speed_pressed) + { + if (!docked) + { + if (flight_speed > 1) + flight_speed--; + } + } + + if (kbd_up_pressed) + arrow_up(); + + if (kbd_down_pressed) + arrow_down(); + + if (kbd_left_pressed) + arrow_left(); + + if (kbd_right_pressed) + arrow_right(); + + if (kbd_enter_pressed) + return_pressed(); + + if (kbd_energy_bomb_pressed) + { + if ((!docked) && (cmdr.energy_bomb)) + { + detonate_bomb = 1; + cmdr.energy_bomb = 0; + } + } + + if (kbd_escape_pressed) + { + if ((!docked) && (cmdr.escape_pod) && (!witchspace)) + run_escape_sequence(); + } +} + + + +void set_commander_name (char *path) +{ + char *fname, *cname; + int i; + + fname = get_filename (path); + cname = cmdr.name; + + for (i = 0; i < 31; i++) + { + if (!isalnum(*fname)) + break; + + *cname++ = toupper(*fname++); + } + + *cname = '\0'; +} + + +void save_commander_screen (void) +{ + char path[255]; + int okay; + int rv; + + current_screen = SCR_SAVE_CMDR; + + gfx_clear_display(); + gfx_display_centre_text (10, "SAVE COMMANDER", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + gfx_update_screen(); + + strcpy (path, cmdr.name); + strcat (path, ".nkc"); + + okay = gfx_request_file ("Save Commander", path, "nkc"); + + if (!okay) + { + display_options(); + return; + } + + rv = save_commander_file (path); + + if (rv) + { + gfx_display_centre_text (175, "Error Saving Commander!", 140, GFX_COL_GOLD); + return; + } + + gfx_display_centre_text (175, "Commander Saved.", 140, GFX_COL_GOLD); + + set_commander_name (path); + saved_cmdr = cmdr; + saved_cmdr.ship_x = docked_planet.d; + saved_cmdr.ship_y = docked_planet.b; +} + + +void load_commander_screen (void) +{ + char path[255]; + int rv; + + gfx_clear_display(); + gfx_display_centre_text (10, "LOAD COMMANDER", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + gfx_update_screen(); + + + strcpy (path, "jameson.nkc"); + + rv = gfx_request_file ("Load Commander", path, "nkc"); + + if (rv == 0) + return; + + rv = load_commander_file (path); + + if (rv) + { + saved_cmdr = cmdr; + gfx_display_centre_text (175, "Error Loading Commander!", 140, GFX_COL_GOLD); + gfx_display_centre_text (200, "Press any key to continue.", 140, GFX_COL_GOLD); + gfx_update_screen(); + readkey(); + return; + } + + restore_saved_commander(); + set_commander_name (path); + saved_cmdr = cmdr; + update_console(); +} + + + +void run_first_intro_screen (void) +{ + current_screen = SCR_INTRO_ONE; + + snd_play_midi (SND_ELITE_THEME, TRUE); + + initialise_intro1(); + + for (;;) + { + update_intro1(); + + gfx_update_screen(); + + kbd_poll_keyboard(); + + if (kbd_y_pressed) + { + snd_stop_midi(); + load_commander_screen(); + break; + } + + if (kbd_n_pressed) + { + snd_stop_midi(); + break; + } + } + +} + + + +void run_second_intro_screen (void) +{ + current_screen = SCR_INTRO_TWO; + + snd_play_midi (SND_BLUE_DANUBE, TRUE); + + initialise_intro2(); + + flight_speed = 3; + flight_roll = 0; + flight_climb = 0; + + for (;;) + { + update_intro2(); + + gfx_update_screen(); + + kbd_poll_keyboard(); + + if (kbd_space_pressed) + break; + } + + snd_stop_midi(); +} + + + +/* + * Draw the game over sequence. + */ + +void run_game_over_screen() +{ + int i; + int newship; + Matrix rotmat; + int type; + + current_screen = SCR_GAME_OVER; + gfx_set_clip_region (1, 1, 510, 383); + + flight_speed = 6; + flight_roll = 0; + flight_climb = 0; + clear_universe(); + + set_init_matrix (rotmat); + + newship = add_new_ship (SHIP_COBRA3, 0, 0, -400, rotmat, 0, 0); + universe[newship].flags |= FLG_DEAD; + + for (i = 0; i < 5; i++) + { + type = (rand255() & 1) ? SHIP_CARGO : SHIP_ALLOY; + newship = add_new_ship (type, (rand255() & 63) - 32, + (rand255() & 63) - 32, -400, rotmat, 0, 0); + universe[newship].rotz = ((rand255() * 2) & 255) - 128; + universe[newship].rotx = ((rand255() * 2) & 255) - 128; + universe[newship].velocity = rand255() & 15; + } + + + for (i = 0; i < 100; i++) + { + gfx_clear_display(); + update_starfield(); + update_universe(); + gfx_display_centre_text (190, "GAME OVER", 140, GFX_COL_GOLD); + gfx_update_screen(); + } +} + + + + +/* + * Draw a break pattern (for launching, docking and hyperspacing). + * Just draw a very simple one for the moment. + */ + +void display_break_pattern (void) +{ + int i; + + gfx_set_clip_region (1, 1, 510, 383); + gfx_clear_display(); + + for (i = 0; i < 20; i++) + { + gfx_draw_circle (256, 192, 30 + i * 15, GFX_COL_WHITE); + gfx_update_screen(); + } + + + if (docked) + { + check_mission_brief(); + display_commander_status(); + update_console(); + } + else + current_screen = SCR_FRONT_VIEW; +} + + +void info_message (char *message) +{ + strcpy (message_string, message); + message_count = 37; +// snd_play_sample (SND_BEEP); +} + + + + + + +void initialise_allegro (void) +{ + allegro_init(); + install_keyboard(); + install_timer(); + install_mouse(); + + have_joystick = 0; + + if (install_joystick(JOY_TYPE_AUTODETECT) == 0) + { + have_joystick = (num_joysticks > 0); + } +} + + + +int main() +{ + initialise_allegro(); + read_config_file(); + + if (gfx_graphics_startup() == 1) + { + return 1; + } + + /* Start the sound system... */ + snd_sound_startup(); + + /* Do any setup necessary for the keyboard... */ + kbd_keyboard_startup(); + + finish = 0; + auto_pilot = 0; + + while (!finish) + { + game_over = 0; + initialise_game(); + dock_player(); + + update_console(); + + current_screen = SCR_FRONT_VIEW; + run_first_intro_screen(); + run_second_intro_screen(); + + old_cross_x = -1; + old_cross_y = -1; + + dock_player (); + display_commander_status (); + + while (!game_over) + { + snd_update_sound(); + gfx_update_screen(); + gfx_set_clip_region (1, 1, 510, 383); + + rolling = 0; + climbing = 0; + + handle_flight_keys (); + + if (game_paused) + continue; + + if (message_count > 0) + message_count--; + + if (!rolling) + { + if (flight_roll > 0) + decrease_flight_roll(); + + if (flight_roll < 0) + increase_flight_roll(); + } + + if (!climbing) + { + if (flight_climb > 0) + decrease_flight_climb(); + + if (flight_climb < 0) + increase_flight_climb(); + } + + + if (!docked) + { + gfx_acquire_screen(); + + if ((current_screen == SCR_FRONT_VIEW) || (current_screen == SCR_REAR_VIEW) || + (current_screen == SCR_LEFT_VIEW) || (current_screen == SCR_RIGHT_VIEW) || + (current_screen == SCR_INTRO_ONE) || (current_screen == SCR_INTRO_TWO) || + (current_screen == SCR_GAME_OVER)) + { + gfx_clear_display(); + update_starfield(); + } + + if (auto_pilot) + { + auto_dock(); + if ((mcount & 127) == 0) + info_message ("Docking Computers On"); + } + + update_universe (); + + if (docked) + { + update_console(); + gfx_release_screen(); + continue; + } + + if ((current_screen == SCR_FRONT_VIEW) || (current_screen == SCR_REAR_VIEW) || + (current_screen == SCR_LEFT_VIEW) || (current_screen == SCR_RIGHT_VIEW)) + { + if (draw_lasers) + { + draw_laser_lines(); + draw_lasers--; + } + + draw_laser_sights(); + } + + if (message_count > 0) + gfx_display_centre_text (358, message_string, 120, GFX_COL_WHITE); + + if (hyper_ready) + { + display_hyper_status(); + if ((mcount & 3) == 0) + { + countdown_hyperspace(); + } + } + + gfx_release_screen(); + + mcount--; + if (mcount < 0) + mcount = 255; + + if ((mcount & 7) == 0) + regenerate_shields(); + + if ((mcount & 31) == 10) + { + if (energy < 50) + { + info_message ("ENERGY LOW"); + snd_play_sample (SND_BEEP); + } + + update_altitude(); + } + + if ((mcount & 31) == 20) + update_cabin_temp(); + + if ((mcount == 0) && (!witchspace)) + random_encounter(); + + cool_laser(); + time_ecm(); + + update_console(); + } + + if (current_screen == SCR_BREAK_PATTERN) + display_break_pattern(); + + if (cross_timer > 0) + { + cross_timer--; + if (cross_timer == 0) + { + show_distance_to_planet(); + } + } + + if ((cross_x != old_cross_x) || + (cross_y != old_cross_y)) + { + if (old_cross_x != -1) + draw_cross (old_cross_x, old_cross_y); + + old_cross_x = cross_x; + old_cross_y = cross_y; + + draw_cross (old_cross_x, old_cross_y); + } + } + + if (!finish) + run_game_over_screen(); + } + + snd_sound_shutdown(); + + gfx_graphics_shutdown (); + + return 0; +} + +END_OF_MAIN(); diff --git a/alg_main.h b/alg_main.h new file mode 100644 index 0000000..a359d3d --- /dev/null +++ b/alg_main.h @@ -0,0 +1,7 @@ + +#ifndef MAIN_H +#define MAIN_H + +void info_message (char *message); + +#endif \ No newline at end of file diff --git a/beep.wav b/beep.wav new file mode 100644 index 0000000..71a3d4b Binary files /dev/null and b/beep.wav differ diff --git a/boop.wav b/boop.wav new file mode 100644 index 0000000..d130333 Binary files /dev/null and b/boop.wav differ diff --git a/config.h b/config.h new file mode 100644 index 0000000..8cd91e2 --- /dev/null +++ b/config.h @@ -0,0 +1,51 @@ +/** + * + * Elite - The New Kind. + * + * The code in this file has not been derived from the original Elite code. + * Written by C.J.Pinder 1999-2001. + * + * email: + * + **/ + +/* + * config.h + * + * Define the compile time options. + * Most options are defined at runtime in the newkind.cfg file. + * However some must be done at compile time either because they are + * platform dependant or for playing speed. + */ + + +#ifndef CONFIG_H +#define CONFIG_H + +/* + * Set the graphics platform we are using... + */ + +#define GFX_ALLEGRO + +/* + * #define GFX_WIN32_GDI + * #define GFX_OPENGL + * #defime GFX_X_WINDOWS + * #define GFX_DIRECTX + */ + +/* + * Set the screen resolution... + * (if nothing is defined, assume 256x256). + */ + +#define RES_800_600 +// #define RES_512_512 + +/* + * #define RES_640_480 + * #define RES_320_240 + */ + +#endif diff --git a/crash.wav b/crash.wav new file mode 100644 index 0000000..b9505e7 Binary files /dev/null and b/crash.wav differ diff --git a/data/blake.bmp b/data/blake.bmp new file mode 100644 index 0000000..bf0bddd Binary files /dev/null and b/data/blake.bmp differ diff --git a/data/danube.mid b/data/danube.mid new file mode 100644 index 0000000..d5cfec2 Binary files /dev/null and b/data/danube.mid differ diff --git a/data/ecm.bmp b/data/ecm.bmp new file mode 100644 index 0000000..1fa49fb Binary files /dev/null and b/data/ecm.bmp differ diff --git a/data/elitetx3.bmp b/data/elitetx3.bmp new file mode 100644 index 0000000..41c505d Binary files /dev/null and b/data/elitetx3.bmp differ diff --git a/data/greendot.bmp b/data/greendot.bmp new file mode 100644 index 0000000..e630263 Binary files /dev/null and b/data/greendot.bmp differ diff --git a/data/missgrn.bmp b/data/missgrn.bmp new file mode 100644 index 0000000..2722af0 Binary files /dev/null and b/data/missgrn.bmp differ diff --git a/data/missred.bmp b/data/missred.bmp new file mode 100644 index 0000000..ae15949 Binary files /dev/null and b/data/missred.bmp differ diff --git a/data/missyell.bmp b/data/missyell.bmp new file mode 100644 index 0000000..1be6f0a Binary files /dev/null and b/data/missyell.bmp differ diff --git a/data/reddot.bmp b/data/reddot.bmp new file mode 100644 index 0000000..5247f82 Binary files /dev/null and b/data/reddot.bmp differ diff --git a/data/safe.bmp b/data/safe.bmp new file mode 100644 index 0000000..a2fa561 Binary files /dev/null and b/data/safe.bmp differ diff --git a/data/theme.mid b/data/theme.mid new file mode 100644 index 0000000..7b2de55 Binary files /dev/null and b/data/theme.mid differ diff --git a/data/verd2.pcx b/data/verd2.pcx new file mode 100644 index 0000000..6e31376 Binary files /dev/null and b/data/verd2.pcx differ diff --git a/data/verd4.pcx b/data/verd4.pcx new file mode 100644 index 0000000..3e35d8c Binary files /dev/null and b/data/verd4.pcx differ diff --git a/dock.wav b/dock.wav new file mode 100644 index 0000000..9a6c1df Binary files /dev/null and b/dock.wav differ diff --git a/docked.c b/docked.c new file mode 100644 index 0000000..dc49754 --- /dev/null +++ b/docked.c @@ -0,0 +1,1382 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + + +#include +#include +#include +#include +#include + +#include "config.h" +#include "gfx.h" +#include "elite.h" +#include "planet.h" +#include "shipdata.h" +#include "space.h" + + + + + +char *economy_type[] = {"Rich Industrial", + "Average Industrial", + "Poor Industrial", + "Mainly Industrial", + "Mainly Agricultural", + "Rich Agricultural", + "Average Agricultural", + "Poor Agricultural"}; + +char *government_type[] = { "Anarchy", + "Feudal", + "Multi-Government", + "Dictatorship", + "Communist", + "Confederacy", + "Democracy", + "Corporate State"}; + + + + + + +int cross_x = 0; +int cross_y = 0; + + + + + + + +void draw_fuel_limit_circle (int cx, int cy) +{ + int radius; + int cross_size; + + if (current_screen == SCR_GALACTIC_CHART) + { + radius = cmdr.fuel / 4 * GFX_SCALE; + cross_size = 7 * GFX_SCALE; + } + else + { + radius = cmdr.fuel * GFX_SCALE; + cross_size = 16 * GFX_SCALE; + } + + gfx_draw_circle (cx, cy, radius, GFX_COL_GREEN_1); + + gfx_draw_line (cx, cy - cross_size, cx, cy + cross_size); + gfx_draw_line (cx - cross_size, cy, cx + cross_size, cy); +} + + + + + +int calc_distance_to_planet (struct galaxy_seed from_planet, struct galaxy_seed to_planet) +{ + int dx,dy; + int light_years; + + dx = abs(to_planet.d - from_planet.d); + dy = abs(to_planet.b - from_planet.b); + + dx = dx * dx; + dy = dy / 2; + dy = dy * dy; + + light_years = sqrt(dx + dy); + light_years *= 4; + + return light_years; +} + + +void show_distance (int ypos, struct galaxy_seed from_planet, struct galaxy_seed to_planet) +{ + char str[100]; + int light_years; + + light_years = calc_distance_to_planet (from_planet, to_planet); + + if (light_years > 0) + sprintf (str, "Distance: %2d.%d Light Years ", light_years / 10, light_years % 10); + else + strcpy (str," "); + + gfx_display_text (16, ypos, str); +} + + + +void show_distance_to_planet (void) +{ + int px,py; + char planet_name[16]; + char str[32]; + + if (current_screen == SCR_GALACTIC_CHART) + { + px = cross_x / GFX_SCALE; + py = (cross_y - ((18 * GFX_SCALE) + 1)) * (2 / GFX_SCALE); + } + else + { + px = ((cross_x - GFX_X_CENTRE) / (4 * GFX_SCALE)) + docked_planet.d; + py = ((cross_y - GFX_Y_CENTRE) / (2 * GFX_SCALE)) + docked_planet.b; + } + + hyperspace_planet = find_planet (px, py); + + name_planet (planet_name, hyperspace_planet); + + gfx_clear_text_area(); + sprintf (str, "%-18s", planet_name); + gfx_display_text (16, 340, str); + + show_distance (356, docked_planet, hyperspace_planet); + + if (current_screen == SCR_GALACTIC_CHART) + { + cross_x = hyperspace_planet.d * GFX_SCALE; + cross_y = hyperspace_planet.b / (2 / GFX_SCALE) + (18 * GFX_SCALE) + 1; + } + else + { + cross_x = ((hyperspace_planet.d - docked_planet.d) * (4 * GFX_SCALE)) + GFX_X_CENTRE; + cross_y = ((hyperspace_planet.b - docked_planet.b) * (2 * GFX_SCALE)) + GFX_Y_CENTRE; + } +} + + +void move_cursor_to_origin (void) +{ + if (current_screen == SCR_GALACTIC_CHART) + { + cross_x = docked_planet.d * GFX_SCALE; + cross_y = docked_planet.b / (2 / GFX_SCALE) + (18 * GFX_SCALE) + 1; + } + else + { + cross_x = GFX_X_CENTRE; + cross_y = GFX_Y_CENTRE; + } + + show_distance_to_planet(); +} + + +void find_planet_by_name (char *find_name) +{ + int i; + struct galaxy_seed glx; + char planet_name[16]; + int found; + char str[32]; + + glx = cmdr.galaxy; + found = 0; + + for (i = 0; i < 256; i++) + { + name_planet (planet_name, glx); + + if (strcmp (planet_name, find_name) == 0) + { + found = 1; + break; + } + + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + } + + if (!found) + { + gfx_clear_text_area(); + gfx_display_text (16, 340, "Unknown Planet"); + return; + } + + hyperspace_planet = glx; + + gfx_clear_text_area (); + sprintf (str, "%-18s", planet_name); + gfx_display_text (16, 340, str); + + show_distance (356, docked_planet, hyperspace_planet); + + if (current_screen == SCR_GALACTIC_CHART) + { + cross_x = hyperspace_planet.d * GFX_SCALE; + cross_y = hyperspace_planet.b / (2 / GFX_SCALE) + (18 * GFX_SCALE) + 1; + } + else + { + cross_x = ((hyperspace_planet.d - docked_planet.d) * (4 * GFX_SCALE)) + GFX_X_CENTRE; + cross_y = ((hyperspace_planet.b - docked_planet.b) * (2 * GFX_SCALE)) + GFX_Y_CENTRE; + } +} + + + +void display_short_range_chart (void) +{ + int i; + struct galaxy_seed glx; + int dx,dy; + int px,py; + char planet_name[16]; + int row_used[64]; + int row; + int blob_size; + + current_screen = SCR_SHORT_RANGE; + + gfx_clear_display(); + + gfx_display_centre_text (10, "SHORT RANGE CHART", 140, GFX_COL_GOLD); + + gfx_draw_line (0, 36, 511, 36); + + draw_fuel_limit_circle (GFX_X_CENTRE, GFX_Y_CENTRE); + + for (i = 0; i < 64; i++) + row_used[i] = 0; + + glx = cmdr.galaxy; + + for (i = 0; i < 256; i++) + { + + dx = abs (glx.d - docked_planet.d); + dy = abs (glx.b - docked_planet.b); + + if ((dx >= 20) || (dy >= 38)) + { + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + + continue; + } + + px = (glx.d - docked_planet.d); + px = px * 4 * GFX_SCALE + GFX_X_CENTRE; /* Convert to screen co-ords */ + + py = (glx.b - docked_planet.b); + py = py * 2 * GFX_SCALE + GFX_Y_CENTRE; /* Convert to screen co-ords */ + + row = py / (8 * GFX_SCALE); + + if (row_used[row] == 1) + row++; + + if (row_used[row] == 1) + row -= 2; + + if (row <= 3) + { + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + + continue; + } + + if (row_used[row] == 0) + { + row_used[row] = 1; + + name_planet (planet_name, glx); + capitalise_name (planet_name); + + gfx_display_text (px + (4 * GFX_SCALE), (row * 8 - 5) * GFX_SCALE, planet_name); + } + + + /* The next bit calculates the size of the circle used to represent */ + /* a planet. The carry_flag is left over from the name generation. */ + /* Yes this was how it was done... don't ask :-( */ + + blob_size = (glx.f & 1) + 2 + carry_flag; + blob_size *= GFX_SCALE; + gfx_draw_filled_circle (px, py, blob_size, GFX_COL_GOLD); + + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + } + + cross_x = ((hyperspace_planet.d - docked_planet.d) * 4 * GFX_SCALE) + GFX_X_CENTRE; + cross_y = ((hyperspace_planet.b - docked_planet.b) * 2 * GFX_SCALE) + GFX_Y_CENTRE; +} + + + + +void display_galactic_chart (void) +{ + int i; + struct galaxy_seed glx; + char str[64]; + int px,py; + + + current_screen = SCR_GALACTIC_CHART; + + gfx_clear_display(); + + sprintf (str, "GALACTIC CHART %d", cmdr.galaxy_number + 1); + + gfx_display_centre_text (10, str, 140, GFX_COL_GOLD); + + gfx_draw_line (0, 36, 511, 36); + gfx_draw_line (0, 36+258, 511, 36+258); + + draw_fuel_limit_circle (docked_planet.d * GFX_SCALE, + (docked_planet.b / (2 / GFX_SCALE)) + (18 * GFX_SCALE) + 1); + + glx = cmdr.galaxy; + + for (i = 0; i < 256; i++) + { + px = glx.d * GFX_SCALE; + py = (glx.b / (2 / GFX_SCALE)) + (18 * GFX_SCALE) + 1; + + gfx_plot_pixel (px, py, GFX_COL_WHITE); + + if ((glx.e | 0x50) < 0x90) + gfx_plot_pixel (px + 1, py, GFX_COL_WHITE); + + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + + } + + + cross_x = hyperspace_planet.d * GFX_SCALE; + cross_y = (hyperspace_planet.b / (2 / GFX_SCALE)) + (18 * GFX_SCALE) + 1; +} + + + + + +/* + * Displays data on the currently selected Hyperspace Planet. + */ + +void display_data_on_planet (void) +{ + char planet_name[16]; + char str[100]; + char *description; + struct planet_data hyper_planet_data; + + current_screen = SCR_PLANET_DATA; + + gfx_clear_display(); + + name_planet (planet_name, hyperspace_planet); + sprintf (str, "DATA ON %s", planet_name); + + gfx_display_centre_text (10, str, 140, GFX_COL_GOLD); + + gfx_draw_line (0, 36, 511, 36); + + + generate_planet_data (&hyper_planet_data, hyperspace_planet); + + show_distance (42, docked_planet, hyperspace_planet); + + sprintf (str, "Economy:%s", economy_type[hyper_planet_data.economy]); + gfx_display_text (16, 74, str); + + sprintf (str, "Government:%s", government_type[hyper_planet_data.government]); + gfx_display_text (16, 106, str); + + sprintf (str, "Tech.Level:%3d", hyper_planet_data.techlevel + 1); + gfx_display_text (16, 138, str); + + sprintf (str, "Population:%d.%d Billion", hyper_planet_data.population / 10, hyper_planet_data.population % 10); + gfx_display_text (16, 170, str); + + describe_inhabitants (str, hyperspace_planet); + gfx_display_text (16, 202, str); + + sprintf (str, "Gross Productivity:%5d M CR", hyper_planet_data.productivity); + gfx_display_text (16, 234, str); + + sprintf (str, "Average Radius:%5d km", hyper_planet_data.radius); + gfx_display_text (16, 266, str); + + description = describe_planet (hyperspace_planet); + gfx_display_pretty_text (16, 298, 400, 384, description); +} + + + +struct rank +{ + int score; + char *title; +}; + +#define NO_OF_RANKS 9 + +struct rank rating[NO_OF_RANKS] = +{ + {0x0000, "Harmless"}, + {0x0008, "Mostly Harmless"}, + {0x0010, "Poor"}, + {0x0020, "Average"}, + {0x0040, "Above Average"}, + {0x0080, "Competent"}, + {0x0200, "Dangerous"}, + {0x0A00, "Deadly"}, + {0x1900, "---- E L I T E ---"} +}; + +char *laser_name[5] = {"Pulse", "Beam", "Military", "Mining", "Custom"}; + + + +char *laser_type (int strength) +{ + switch (strength) + { + case PULSE_LASER: + return laser_name[0]; + + case BEAM_LASER: + return laser_name[1]; + + case MILITARY_LASER: + return laser_name[2]; + + case MINING_LASER: + return laser_name[3]; + } + + return laser_name[4]; +} + + +#define EQUIP_START_Y 202 +#define EQUIP_START_X 50 +#define EQUIP_MAX_Y 290 +#define EQUIP_WIDTH 200 +#define Y_INC 16 + + +static char *condition_txt[] = +{ + "Docked", + "Green", + "Yellow", + "Red" +}; + +void display_commander_status (void) +{ + char planet_name[16]; + char str[100]; + int i; + int x,y; + int condition; + int type; + + current_screen = SCR_CMDR_STATUS; + + gfx_clear_display(); + + sprintf (str, "COMMANDER %s", cmdr.name); + + gfx_display_centre_text (10, str, 140, GFX_COL_GOLD); + + gfx_draw_line (0, 36, 511, 36); + + + gfx_display_colour_text (16, 58, "Present System:", GFX_COL_GREEN_1); + + if (!witchspace) + { + name_planet (planet_name, docked_planet); + capitalise_name (planet_name); + sprintf (str, "%s", planet_name); + gfx_display_text (190, 58, str); + } + + gfx_display_colour_text (16, 74, "Hyperspace System:", GFX_COL_GREEN_1); + name_planet (planet_name, hyperspace_planet); + capitalise_name (planet_name); + sprintf (str, "%s", planet_name); + gfx_display_text (190, 74, str); + + if (docked) + condition = 0; + else + { + condition = 1; + + for (i = 0; i < MAX_UNIV_OBJECTS; i++) + { + type = universe[i].type; + + if ((type == SHIP_MISSILE) || + ((type > SHIP_ROCK) && (type < SHIP_DODEC))) + { + condition = 2; + break; + } + } + + if ((condition == 2) && (energy < 128)) + condition = 3; + } + + gfx_display_colour_text (16, 90, "Condition:", GFX_COL_GREEN_1); + gfx_display_text (190, 90, condition_txt[condition]); + + sprintf (str, "%d.%d Light Years", cmdr.fuel / 10, cmdr.fuel % 10); + gfx_display_colour_text (16, 106, "Fuel:", GFX_COL_GREEN_1); + gfx_display_text (70, 106, str); + + sprintf (str, "%d.%d Cr", cmdr.credits / 10, cmdr.credits % 10); + gfx_display_colour_text (16, 122, "Cash:", GFX_COL_GREEN_1); + gfx_display_text (70, 122, str); + + if (cmdr.legal_status == 0) + strcpy (str, "Clean"); + else + strcpy (str, cmdr.legal_status > 50 ? "Fugitive" : "Offender"); + + gfx_display_colour_text (16, 138, "Legal Status:", GFX_COL_GREEN_1); + gfx_display_text (128, 138, str); + + for (i = 0; i < NO_OF_RANKS; i++) + if (cmdr.score >= rating[i].score) + strcpy (str, rating[i].title); + + gfx_display_colour_text (16, 154, "Rating:", GFX_COL_GREEN_1); + gfx_display_text (80, 154, str); + + gfx_display_colour_text (16, 186, "EQUIPMENT:", GFX_COL_GREEN_1); + + x = EQUIP_START_X; + y = EQUIP_START_Y; + + if (cmdr.cargo_capacity > 20) + { + gfx_display_text (x, y, "Large Cargo Bay"); + y += Y_INC; + } + + if (cmdr.escape_pod) + { + gfx_display_text (x, y, "Escape Pod"); + y += Y_INC; + } + + if (cmdr.fuel_scoop) + { + gfx_display_text (x, y, "Fuel Scoops"); + y += Y_INC; + } + + if (cmdr.ecm) + { + gfx_display_text (x, y, "E.C.M. System"); + y += Y_INC; + } + + if (cmdr.energy_bomb) + { + gfx_display_text (x, y, "Energy Bomb"); + y += Y_INC; + } + + if (cmdr.energy_unit) + { + gfx_display_text (x, y, + cmdr.energy_unit == 1 ? "Extra Energy Unit" :"Naval Energy Unit"); + y += Y_INC; + if (y > EQUIP_MAX_Y) + { + y = EQUIP_START_Y; + x += EQUIP_WIDTH; + } + } + + if (cmdr.docking_computer) + { + gfx_display_text (x, y, "Docking Computers"); + y += Y_INC; + if (y > EQUIP_MAX_Y) + { + y = EQUIP_START_Y; + x += EQUIP_WIDTH; + } + } + + + if (cmdr.galactic_hyperdrive) + { + gfx_display_text (x, y, "Galactic Hyperspace"); + y += Y_INC; + if (y > EQUIP_MAX_Y) + { + y = EQUIP_START_Y; + x += EQUIP_WIDTH; + } + } + + if (cmdr.front_laser) + { + sprintf (str, "Front %s Laser", laser_type(cmdr.front_laser)); + gfx_display_text (x, y, str); + y += Y_INC; + if (y > EQUIP_MAX_Y) + { + y = EQUIP_START_Y; + x += EQUIP_WIDTH; + } + } + + if (cmdr.rear_laser) + { + sprintf (str, "Rear %s Laser", laser_type(cmdr.rear_laser)); + gfx_display_text (x, y, str); + y += Y_INC; + if (y > EQUIP_MAX_Y) + { + y = EQUIP_START_Y; + x += EQUIP_WIDTH; + } + } + + if (cmdr.left_laser) + { + sprintf (str, "Left %s Laser", laser_type(cmdr.left_laser)); + gfx_display_text (x, y, str); + y += Y_INC; + if (y > EQUIP_MAX_Y) + { + y = EQUIP_START_Y; + x += EQUIP_WIDTH; + } + } + + if (cmdr.right_laser) + { + sprintf (str, "Right %s Laser", laser_type(cmdr.right_laser)); + gfx_display_text (x, y, str); + } +} + + + +/***********************************************************************************/ + +#define TONNES 0 +#define KILOGRAMS 1 +#define GRAMS 2 + +static int hilite_item; +static char *unit_name[] = {"t", "kg", "g"}; + + +void display_stock_price (int i) +{ + int y; + char str[100]; + + y = i * 15 + 55; + + gfx_display_text (16, y, stock_market[i].name); + + gfx_display_text (180, y, unit_name[stock_market[i].units]); + sprintf (str, "%d.%d", stock_market[i].current_price / 10, + stock_market[i].current_price % 10); + gfx_display_text (256, y, str); + + if (stock_market[i].current_quantity > 0) + sprintf (str, "%d%s", stock_market[i].current_quantity, + unit_name[stock_market[i].units]); + else + strcpy (str, "-"); + + gfx_display_text (338, y, str); + + if (cmdr.current_cargo[i] > 0) + sprintf (str, "%d%s", cmdr.current_cargo[i], + unit_name[stock_market[i].units]); + else + strcpy (str, "-"); + + gfx_display_text (444, y, str); +} + + +void highlight_stock (int i) +{ + int y; + char str[30]; + + if ((hilite_item != -1) && (hilite_item != i)) + { + y = hilite_item * 15 + 55; + gfx_clear_area (2, y, 510, y + 15); + display_stock_price (hilite_item); + } + + y = i * 15 + 55; + + gfx_draw_rectangle (2, y, 510, y + 15, GFX_COL_DARK_RED); + display_stock_price (i); + + hilite_item = i; + + gfx_clear_text_area(); + sprintf (str, "Cash: %d.%d", cmdr.credits / 10, cmdr.credits % 10); + gfx_display_text (16, 340, str); +} + +void select_previous_stock (void) +{ + if ((!docked) || (hilite_item == 0)) + return; + + highlight_stock (hilite_item - 1); +} + +void select_next_stock (void) +{ + if ((!docked) || (hilite_item == 16)) + return; + + highlight_stock (hilite_item + 1); +} + + +void buy_stock (void) +{ + struct stock_item *item; + int cargo_held; + + if (!docked) + return; + + item = &stock_market[hilite_item]; + + if ((item->current_quantity == 0) || + (cmdr.credits < item->current_price)) + return; + + cargo_held = total_cargo(); + + if ((item->units == TONNES) && + (cargo_held == cmdr.cargo_capacity)) + return; + + cmdr.current_cargo[hilite_item]++; + item->current_quantity--; + cmdr.credits -= item->current_price; + + highlight_stock (hilite_item); +} + + +void sell_stock (void) +{ + struct stock_item *item; + + if ((!docked) || (cmdr.current_cargo[hilite_item] == 0)) + return; + + item = &stock_market[hilite_item]; + + cmdr.current_cargo[hilite_item]--; + item->current_quantity++; + cmdr.credits += item->current_price; + + highlight_stock (hilite_item); +} + + + +void display_market_prices (void) +{ + char str[100]; + char planet_name[16]; + int i; + + current_screen = SCR_MARKET_PRICES; + + gfx_clear_display(); + + name_planet (planet_name, docked_planet); + sprintf (str, "%s MARKET PRICES", planet_name); + gfx_display_centre_text (10, str, 140, GFX_COL_GOLD); + + gfx_draw_line (0, 36, 511, 36); + + gfx_display_colour_text (16, 40, "PRODUCT", GFX_COL_GREEN_1); + gfx_display_colour_text (166, 40, "UNIT", GFX_COL_GREEN_1); + gfx_display_colour_text (246, 40, "PRICE", GFX_COL_GREEN_1); + gfx_display_colour_text (314, 40, "FOR SALE", GFX_COL_GREEN_1); + gfx_display_colour_text (420, 40, "IN HOLD", GFX_COL_GREEN_1); + + for (i = 0; i < 17; i++) + { + display_stock_price (i); + } + + if (docked) + { + hilite_item = -1; + highlight_stock (0); + } +} + + +void display_inventory (void) +{ + int i; + int y; + char str[80]; + + current_screen = SCR_INVENTORY; + + gfx_clear_display(); + gfx_display_centre_text (10, "INVENTORY", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + + sprintf (str, "%d.%d Light Years", cmdr.fuel / 10, cmdr.fuel % 10); + gfx_display_colour_text (16, 50, "Fuel:", GFX_COL_GREEN_1); + gfx_display_text (70, 50, str); + + sprintf (str, "%d.%d Cr", cmdr.credits / 10, cmdr.credits % 10); + gfx_display_colour_text (16, 66, "Cash:", GFX_COL_GREEN_1); + gfx_display_text (70, 66, str); + + y = 98; + for (i = 0; i < 17; i++) + { + if (cmdr.current_cargo[i] > 0) + { + gfx_display_text (16, y, stock_market[i].name); + + sprintf (str, "%d%s", cmdr.current_cargo[i], + unit_name[stock_market[i].units]); + + gfx_display_text (180, y, str); + y += 16; + } + } +} + +/***********************************************************************************/ + +enum equip_types +{ + EQ_FUEL, EQ_MISSILE, EQ_CARGO_BAY, EQ_ECM, EQ_FUEL_SCOOPS, + EQ_ESCAPE_POD, EQ_ENERGY_BOMB, EQ_ENERGY_UNIT, EQ_DOCK_COMP, + EQ_GAL_DRIVE, EQ_PULSE_LASER, EQ_FRONT_PULSE, EQ_REAR_PULSE, + EQ_LEFT_PULSE, EQ_RIGHT_PULSE, EQ_BEAM_LASER, EQ_FRONT_BEAM, + EQ_REAR_BEAM, EQ_LEFT_BEAM, EQ_RIGHT_BEAM, EQ_MINING_LASER, + EQ_FRONT_MINING, EQ_REAR_MINING, EQ_LEFT_MINING, EQ_RIGHT_MINING, + EQ_MILITARY_LASER, EQ_FRONT_MILITARY, EQ_REAR_MILITARY, + EQ_LEFT_MILITARY, EQ_RIGHT_MILITARY +}; + + + +#define NO_OF_EQUIP_ITEMS 34 + +struct equip_item +{ + int canbuy; + int y; + int show; + int level; + int price; + char *name; + int type; +}; + +struct equip_item equip_stock[NO_OF_EQUIP_ITEMS] = +{ + {0, 0, 1, 1, 2, " Fuel", EQ_FUEL}, + {0, 0, 1, 1, 300, " Missile", EQ_MISSILE}, + {0, 0, 1, 1, 4000, " Large Cargo Bay", EQ_CARGO_BAY}, + {0, 0, 1, 2, 6000, " E.C.M. System", EQ_ECM}, + {0, 0, 1, 5, 5250, " Fuel Scoops", EQ_FUEL_SCOOPS}, + {0, 0, 1, 6, 10000, " Escape Pod", EQ_ESCAPE_POD}, + {0, 0, 1, 7, 9000, " Energy Bomb", EQ_ENERGY_BOMB}, + {0, 0, 1, 8, 15000, " Extra Energy Unit", EQ_ENERGY_UNIT}, + {0, 0, 1, 9, 15000, " Docking Computers", EQ_DOCK_COMP}, + {0, 0, 1,10, 50000, " Galactic Hyperdrive", EQ_GAL_DRIVE}, + {0, 0, 0, 3, 4000, "+Pulse Laser", EQ_PULSE_LASER}, + {0, 0, 1, 3, 0, "-Pulse Laser", EQ_PULSE_LASER}, + {0, 0, 1, 3, 4000, ">Front", EQ_FRONT_PULSE}, + {0, 0, 1, 3, 4000, ">Rear", EQ_REAR_PULSE}, + {0, 0, 1, 3, 4000, ">Left", EQ_LEFT_PULSE}, + {0, 0, 1, 3, 4000, ">Right", EQ_RIGHT_PULSE}, + {0, 0, 1, 4, 10000, "+Beam Laser", EQ_BEAM_LASER}, + {0, 0, 0, 4, 0, "-Beam Laser", EQ_BEAM_LASER}, + {0, 0, 0, 4, 10000, ">Front", EQ_FRONT_BEAM}, + {0, 0, 0, 4, 10000, ">Rear", EQ_REAR_BEAM}, + {0, 0, 0, 4, 10000, ">Left", EQ_LEFT_BEAM}, + {0, 0, 0, 4, 10000, ">Right", EQ_RIGHT_BEAM}, + {0, 0, 1,10, 8000, "+Mining Laser", EQ_MINING_LASER}, + {0, 0, 0,10, 0, "-Mining Laser", EQ_MINING_LASER}, + {0, 0, 0,10, 8000, ">Front", EQ_FRONT_MINING}, + {0, 0, 0,10, 8000, ">Rear", EQ_REAR_MINING}, + {0, 0, 0,10, 8000, ">Left", EQ_LEFT_MINING}, + {0, 0, 0,10, 8000, ">Right", EQ_RIGHT_MINING}, + {0, 0, 1,10, 60000, "+Military Laser", EQ_MILITARY_LASER}, + {0, 0, 0,10, 0, "-Military Laser", EQ_MILITARY_LASER}, + {0, 0, 0,10, 60000, ">Front", EQ_FRONT_MILITARY}, + {0, 0, 0,10, 60000, ">Rear", EQ_REAR_MILITARY}, + {0, 0, 0,10, 60000, ">Left", EQ_LEFT_MILITARY}, + {0, 0, 0,10, 60000, ">Right", EQ_RIGHT_MILITARY} +}; + + +int equip_present (int type) +{ + switch (type) + { + case EQ_FUEL: + return (cmdr.fuel >= 70); + + case EQ_MISSILE: + return (cmdr.missiles >= 4); + + case EQ_CARGO_BAY: + return (cmdr.cargo_capacity > 20); + + case EQ_ECM: + return cmdr.ecm; + + case EQ_FUEL_SCOOPS: + return cmdr.fuel_scoop; + + case EQ_ESCAPE_POD: + return cmdr.escape_pod; + + case EQ_ENERGY_BOMB: + return cmdr.energy_bomb; + + case EQ_ENERGY_UNIT: + return cmdr.energy_unit; + + case EQ_DOCK_COMP: + return cmdr.docking_computer; + + case EQ_GAL_DRIVE: + return cmdr.galactic_hyperdrive; + + case EQ_FRONT_PULSE: + return (cmdr.front_laser == PULSE_LASER); + + case EQ_REAR_PULSE: + return (cmdr.rear_laser == PULSE_LASER); + + case EQ_LEFT_PULSE: + return (cmdr.left_laser == PULSE_LASER); + + case EQ_RIGHT_PULSE: + return (cmdr.right_laser == PULSE_LASER); + + case EQ_FRONT_BEAM: + return (cmdr.front_laser == BEAM_LASER); + + case EQ_REAR_BEAM: + return (cmdr.rear_laser == BEAM_LASER); + + case EQ_LEFT_BEAM: + return (cmdr.left_laser == BEAM_LASER); + + case EQ_RIGHT_BEAM: + return (cmdr.right_laser == BEAM_LASER); + + case EQ_FRONT_MINING: + return (cmdr.front_laser == MINING_LASER); + + case EQ_REAR_MINING: + return (cmdr.rear_laser == MINING_LASER); + + case EQ_LEFT_MINING: + return (cmdr.left_laser == MINING_LASER); + + case EQ_RIGHT_MINING: + return (cmdr.right_laser == MINING_LASER); + + case EQ_FRONT_MILITARY: + return (cmdr.front_laser == MILITARY_LASER); + + case EQ_REAR_MILITARY: + return (cmdr.rear_laser == MILITARY_LASER); + + case EQ_LEFT_MILITARY: + return (cmdr.left_laser == MILITARY_LASER); + + case EQ_RIGHT_MILITARY: + return (cmdr.right_laser == MILITARY_LASER); + } + + return 0; +} + + +void display_equip_price (int i) +{ + int x, y; + int col; + char str[100]; + + y = equip_stock[i].y; + if (y == 0) + return; + + col = equip_stock[i].canbuy ? GFX_COL_WHITE : GFX_COL_GREY_1; + + x = *(equip_stock[i].name) == '>' ? 50 : 16; + + gfx_display_colour_text (x, y, &equip_stock[i].name[1], col); + + if (equip_stock[i].price != 0) + { + sprintf (str, "%d.%d", equip_stock[i].price / 10, equip_stock[i].price % 10); + gfx_display_colour_text (338, y, str, col); + } +} + + +void highlight_equip (int i) +{ + int y; + char str[30]; + + if ((hilite_item != -1) && (hilite_item != i)) + { + y = equip_stock[hilite_item].y; + gfx_clear_area (2, y+1, 510, y + 15); + display_equip_price (hilite_item); + } + + y = equip_stock[i].y; + + gfx_draw_rectangle (2, y+1, 510, y + 15, GFX_COL_DARK_RED); + display_equip_price (i); + + hilite_item = i; + + gfx_clear_text_area(); + sprintf (str, "Cash: %d.%d", cmdr.credits / 10, cmdr.credits % 10); + gfx_display_text (16, 340, str); +} + + +void select_next_equip (void) +{ + int next; + int i; + + if (hilite_item == (NO_OF_EQUIP_ITEMS - 1)) + return; + + next = hilite_item; + for (i = hilite_item + 1; i < NO_OF_EQUIP_ITEMS; i++) + { + if (equip_stock[i].y != 0) + { + next = i; + break; + } + } + + if (next != hilite_item) + highlight_equip (next); +} + +void select_previous_equip (void) +{ + int i; + int prev; + + if (hilite_item == 0) + return; + + prev = hilite_item; + for (i = hilite_item - 1; i >= 0; i--) + { + if (equip_stock[i].y != 0) + { + prev = i; + break; + } + } + + if (prev != hilite_item) + highlight_equip (prev); +} + + +void list_equip_prices (void) +{ + int i; + int y; + int tech_level; + + gfx_clear_area (2, 55, 510, 380); + + tech_level = current_planet_data.techlevel + 1; + + equip_stock[0].price = (70 - cmdr.fuel) * 2; + + y = 55; + for (i = 0; i < NO_OF_EQUIP_ITEMS; i++) + { + equip_stock[i].canbuy = ((equip_present (equip_stock[i].type) == 0) && + (equip_stock[i].price <= cmdr.credits)); + + if (equip_stock[i].show && (tech_level >= equip_stock[i].level)) + { + equip_stock[i].y = y; + y += 15; + } + else + equip_stock[i].y = 0; + + display_equip_price (i); + } + + i = hilite_item; + hilite_item = -1; + highlight_equip (i); +} + + +void collapse_equip_list (void) +{ + int i; + int ch; + + for (i = 0; i < NO_OF_EQUIP_ITEMS; i++) + { + ch = *(equip_stock[i].name); + equip_stock[i].show = ((ch == ' ') || (ch == '+')); + } +} + + +int laser_refund (int laser_type) +{ + switch (laser_type) + { + case PULSE_LASER: + return 4000; + + case BEAM_LASER: + return 10000; + + case MILITARY_LASER: + return 60000; + + case MINING_LASER: + return 8000; + } + + return 0; +} + + +void buy_equip (void) +{ + int i; + + if (equip_stock[hilite_item].name[0] == '+') + { + collapse_equip_list(); + equip_stock[hilite_item].show = 0; + hilite_item++; + for (i = 0; i < 5; i++) + equip_stock[hilite_item + i].show = 1; + + list_equip_prices(); + return; + } + + if (equip_stock[hilite_item].canbuy == 0) + return; + + switch (equip_stock[hilite_item].type) + { + case EQ_FUEL: + cmdr.fuel = myship.max_fuel; + update_console(); + break; + + case EQ_MISSILE: + cmdr.missiles++; + update_console(); + break; + + case EQ_CARGO_BAY: + cmdr.cargo_capacity = 35; + break; + + case EQ_ECM: + cmdr.ecm = 1; + break; + + case EQ_FUEL_SCOOPS: + cmdr.fuel_scoop = 1; + break; + + case EQ_ESCAPE_POD: + cmdr.escape_pod = 1; + break; + + case EQ_ENERGY_BOMB: + cmdr.energy_bomb = 1; + break; + + case EQ_ENERGY_UNIT: + cmdr.energy_unit = 1; + break; + + case EQ_DOCK_COMP: + cmdr.docking_computer = 1; + break; + + case EQ_GAL_DRIVE: + cmdr.galactic_hyperdrive = 1; + break; + + case EQ_FRONT_PULSE: + cmdr.credits += laser_refund (cmdr.front_laser); + cmdr.front_laser = PULSE_LASER; + break; + + case EQ_REAR_PULSE: + cmdr.credits += laser_refund (cmdr.rear_laser); + cmdr.rear_laser = PULSE_LASER; + break; + + case EQ_LEFT_PULSE: + cmdr.credits += laser_refund (cmdr.left_laser); + cmdr.left_laser = PULSE_LASER; + break; + + case EQ_RIGHT_PULSE: + cmdr.credits += laser_refund (cmdr.right_laser); + cmdr.right_laser = PULSE_LASER; + break; + + case EQ_FRONT_BEAM: + cmdr.credits += laser_refund (cmdr.front_laser); + cmdr.front_laser = BEAM_LASER; + break; + + case EQ_REAR_BEAM: + cmdr.credits += laser_refund (cmdr.rear_laser); + cmdr.rear_laser = BEAM_LASER; + break; + + case EQ_LEFT_BEAM: + cmdr.credits += laser_refund (cmdr.left_laser); + cmdr.left_laser = BEAM_LASER; + break; + + case EQ_RIGHT_BEAM: + cmdr.credits += laser_refund (cmdr.right_laser); + cmdr.right_laser = BEAM_LASER; + break; + + case EQ_FRONT_MINING: + cmdr.credits += laser_refund (cmdr.front_laser); + cmdr.front_laser = MINING_LASER; + break; + + case EQ_REAR_MINING: + cmdr.credits += laser_refund (cmdr.rear_laser); + cmdr.rear_laser = MINING_LASER; + break; + + case EQ_LEFT_MINING: + cmdr.credits += laser_refund (cmdr.left_laser); + cmdr.left_laser = MINING_LASER; + break; + + case EQ_RIGHT_MINING: + cmdr.credits += laser_refund (cmdr.right_laser); + cmdr.right_laser = MINING_LASER; + break; + + case EQ_FRONT_MILITARY: + cmdr.credits += laser_refund (cmdr.front_laser); + cmdr.front_laser = MILITARY_LASER; + break; + + case EQ_REAR_MILITARY: + cmdr.credits += laser_refund (cmdr.rear_laser); + cmdr.rear_laser = MILITARY_LASER; + break; + + case EQ_LEFT_MILITARY: + cmdr.credits += laser_refund (cmdr.left_laser); + cmdr.left_laser = MILITARY_LASER; + break; + + case EQ_RIGHT_MILITARY: + cmdr.credits += laser_refund (cmdr.right_laser); + cmdr.right_laser = MILITARY_LASER; + break; + } + + cmdr.credits -= equip_stock[hilite_item].price; + list_equip_prices(); +} + + +void equip_ship (void) +{ + current_screen = SCR_EQUIP_SHIP; + + gfx_clear_display(); + gfx_display_centre_text (10, "EQUIP SHIP", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + + collapse_equip_list(); + + hilite_item = 0; + + list_equip_prices(); +} diff --git a/docked.h b/docked.h new file mode 100644 index 0000000..0ccc39f --- /dev/null +++ b/docked.h @@ -0,0 +1,43 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +#ifndef DOCKED_H +#define DOCKED_H + +void display_short_range_chart (void); +void display_galactic_chart (void); +void display_data_on_planet (void); +void show_distance_to_planet (void); +void move_cursor_to_origin (void); +void find_planet_by_name (char *find_name); +void display_market_prices (void); +void display_commander_status (void); +int calc_distance_to_planet (struct galaxy_seed from_planet, struct galaxy_seed to_planet); +void highlight_stock (int i); +void select_previous_stock (void); +void select_next_stock (void); +void buy_stock (void); +void sell_stock (void); +void display_inventory (void); +void equip_ship (void); +void select_next_equip (void); +void select_previous_equip (void); +void buy_equip (void); + + +extern int cross_x; +extern int cross_y; + +#endif + diff --git a/ecm.wav b/ecm.wav new file mode 100644 index 0000000..37f7990 Binary files /dev/null and b/ecm.wav differ diff --git a/elite.c b/elite.c new file mode 100644 index 0000000..e416937 --- /dev/null +++ b/elite.c @@ -0,0 +1,156 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +#include + +#include "config.h" +#include "elite.h" +#include "vector.h" +#include "planet.h" +#include "shipdata.h" + + +struct galaxy_seed docked_planet; + +struct galaxy_seed hyperspace_planet; + +struct planet_data current_planet_data; + +int curr_galaxy_num = 1; +int curr_fuel = 70; +int carry_flag = 0; +int current_screen = 0; +int witchspace; + +int wireframe = 0; +int anti_alias_gfx = 0; +int hoopy_casinos = 0; +int speed_cap = 75; +int instant_dock = 0; + + +char scanner_filename[256]; +int scanner_cx; +int scanner_cy; +int compass_centre_x; +int compass_centre_y; + +int planet_render_style = 0; + +int game_over; +int docked; +int finish; +int flight_speed; +int flight_roll; +int flight_climb; +int front_shield; +int aft_shield; +int energy; +int laser_temp; +int detonate_bomb; +int auto_pilot; + + +struct commander saved_cmdr = +{ + "JAMESON", /* Name */ + 0, /* Mission Number */ + 0x14,0xAD, /* Ship X,Y */ + {0x4a, 0x5a, 0x48, 0x02, 0x53, 0xb7}, /* Galaxy Seed */ + 1000, /* Credits * 10 */ + 70, /* Fuel * 10 */ + 0, + 0, /* Galaxy - 1 */ + PULSE_LASER, /* Front Laser */ + 0, /* Rear Laser */ + 0, /* Left Laser */ + 0, /* Right Laser */ + 0, 0, + 20, /* Cargo Capacity */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, /* Current Cargo */ + 0, /* ECM */ + 0, /* Fuel Scoop */ + 0, /* Energy Bomb */ + 0, /* Energy Unit */ + 0, /* Docking Computer */ + 0, /* Galactic H'Drive */ + 0, /* Escape Pod */ + 0,0,0,0, + 3, /* No. of Missiles */ + 0, /* Legal Status */ + {0x10, 0x0F, 0x11, 0x00, 0x03, 0x1C, /* Station Stock */ + 0x0E, 0x00, 0x00, 0x0A, 0x00, 0x11, + 0x3A, 0x07, 0x09, 0x08, 0x00}, + 0, /* Fluctuation */ + 0, /* Score */ + 0x80 /* Saved */ +}; + +struct commander cmdr; + +struct player_ship myship; + + +struct ship_data *ship_list[NO_OF_SHIPS + 1] = +{ + NULL, + &missile_data, + &coriolis_data, + &esccaps_data, + &alloy_data, + &cargo_data, + &boulder_data, + &asteroid_data, + &rock_data, + &orbit_data, + &transp_data, + &cobra3a_data, + &pythona_data, + &boa_data, + &anacnda_data, + &hermit_data, + &viper_data, + &sidewnd_data, + &mamba_data, + &krait_data, + &adder_data, + &gecko_data, + &cobra1_data, + &worm_data, + &cobra3b_data, + &asp2_data, + &pythonb_data, + &ferdlce_data, + &moray_data, + &thargoid_data, + &thargon_data, + &constrct_data, + &cougar_data, + &dodec_data +}; + + + +void restore_saved_commander (void) +{ + cmdr = saved_cmdr; + + docked_planet = find_planet (cmdr.ship_x, cmdr.ship_y); + hyperspace_planet = docked_planet; + + generate_planet_data (¤t_planet_data, docked_planet); + generate_stock_market (); + set_stock_quantities (cmdr.station_stock); +} + diff --git a/elite.dat b/elite.dat new file mode 100644 index 0000000..8475074 Binary files /dev/null and b/elite.dat differ diff --git a/elite.h b/elite.h new file mode 100644 index 0000000..f1396ef --- /dev/null +++ b/elite.h @@ -0,0 +1,167 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +#ifndef ELITE_H +#define ELITE_H + +#include "planet.h" +#include "trade.h" + + +#define SCR_INTRO_ONE 1 +#define SCR_INTRO_TWO 2 +#define SCR_GALACTIC_CHART 3 +#define SCR_SHORT_RANGE 4 +#define SCR_PLANET_DATA 5 +#define SCR_MARKET_PRICES 6 +#define SCR_CMDR_STATUS 7 +#define SCR_FRONT_VIEW 8 +#define SCR_REAR_VIEW 9 +#define SCR_LEFT_VIEW 10 +#define SCR_RIGHT_VIEW 11 +#define SCR_BREAK_PATTERN 12 +#define SCR_INVENTORY 13 +#define SCR_EQUIP_SHIP 14 +#define SCR_OPTIONS 15 +#define SCR_LOAD_CMDR 16 +#define SCR_SAVE_CMDR 17 +#define SCR_QUIT 18 +#define SCR_GAME_OVER 19 +#define SCR_SETTINGS 20 +#define SCR_ESCAPE_POD 21 + + +#define PULSE_LASER 0x0F +#define BEAM_LASER 0x8F +#define MILITARY_LASER 0x97 +#define MINING_LASER 0x32 + + +#define FLG_DEAD (1) +#define FLG_REMOVE (2) +#define FLG_EXPLOSION (4) +#define FLG_ANGRY (8) +#define FLG_FIRING (16) +#define FLG_HAS_ECM (32) +#define FLG_HOSTILE (64) +#define FLG_CLOAKED (128) +#define FLG_FLY_TO_PLANET (256) +#define FLG_FLY_TO_STATION (512) +#define FLG_INACTIVE (1024) +#define FLG_SLOW (2048) +#define FLG_BOLD (4096) +#define FLG_POLICE (8192) + + +#define MAX_UNIV_OBJECTS 20 + + +struct commander +{ + char name[32]; + int mission; + int ship_x; + int ship_y; + struct galaxy_seed galaxy; + int credits; + int fuel; + int unused1; + int galaxy_number; + int front_laser; + int rear_laser; + int left_laser; + int right_laser; + int unused2; + int unused3; + int cargo_capacity; + int current_cargo[NO_OF_STOCK_ITEMS]; + int ecm; + int fuel_scoop; + int energy_bomb; + int energy_unit; + int docking_computer; + int galactic_hyperdrive; + int escape_pod; + int unused4; + int unused5; + int unused6; + int unused7; + int missiles; + int legal_status; + int station_stock[NO_OF_STOCK_ITEMS]; + int market_rnd; + int score; + int saved; +}; + +struct player_ship +{ + int max_speed; + int max_roll; + int max_climb; + int max_fuel; + int altitude; + int cabtemp; +}; + +extern struct player_ship myship; + + +extern struct commander cmdr; +extern struct commander saved_cmdr; + +extern struct galaxy_seed docked_planet; + +extern struct galaxy_seed hyperspace_planet; + +extern struct planet_data current_planet_data; + +extern int carry_flag; +extern int current_screen; + +extern struct ship_data *ship_list[]; + +extern int wireframe; +extern int anti_alias_gfx; +extern char scanner_filename[256]; +extern int hoopy_casinos; +extern int instant_dock; +extern int speed_cap; +extern int scanner_cx; +extern int scanner_cy; +extern int compass_centre_x; +extern int compass_centre_y; + +extern int planet_render_style; + +extern int game_over; +extern int docked; +extern int finish; +extern int flight_speed; +extern int flight_roll; +extern int flight_climb; +extern int front_shield; +extern int aft_shield; +extern int energy; +extern int laser_temp; +extern int mcount; +extern int detonate_bomb; +extern int witchspace; +extern int auto_pilot; + + +void restore_saved_commander (void); + + +#endif diff --git a/explode.wav b/explode.wav new file mode 100644 index 0000000..5a7922b Binary files /dev/null and b/explode.wav differ diff --git a/file.c b/file.c new file mode 100644 index 0000000..f8469b4 --- /dev/null +++ b/file.c @@ -0,0 +1,328 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * file.c + */ + +#include +#include +#include +#include + +#include "elite.h" +#include "config.h" +#include "file.h" + +void write_config_file (void) +{ + FILE *fp; + + fp = fopen ("newkind.cfg", "w"); + if (fp == NULL) + return; + + fprintf (fp, "%d\t\t# Game Speed, the lower the number the faster the game.\n", speed_cap); + + fprintf (fp, "%d\t\t# Graphics: 0 = Solid, 1 = Wireframe\n", wireframe); + + fprintf (fp, "%d\t\t# Anti-Alias Wireframe: 0 = Normal, 1 = Anti-Aliased\n", anti_alias_gfx); + + fprintf (fp, "%d\t\t# Planet style: 0 = Wireframe, 1 = Green, 2 = SNES, 3 = Fractal\n", planet_render_style); + + fprintf (fp, "%d\t\t# Planet Descriptions: 0 = Tree Grubs, 1 = Hoopy Casinos\n", hoopy_casinos); + + fprintf (fp, "%d\t\t# Instant dock: 0 = off, 1 = on\n", instant_dock); + + fprintf (fp, "newscan.cfg\t# Name of scanner config file to use.\n"); + + fclose (fp); +} + + +/* + * Read a line from a .cfg file. + * Ignore blanks, comments and strip white space. + */ + +void read_cfg_line (char *str, int max_size, FILE *fp) +{ + char *s; + + do + { + fgets (str, max_size, fp); + + for (s = str; *s; s++) /* End of line at LF or # */ + { + if ((*s == '\n') || (*s == '#')) + { + *s = '\0'; + break; + } + } + + if (s != str) /* Trim any trailing white space */ + { + s--; + while (isspace(*s)) + { + *s = '\0'; + if (s == str) + break; + s--; + } + } + + } while (*str == '\0'); +} + + +/* + * Read in the scanner .cfg file. + */ + +void read_scanner_config_file (char *filename) +{ + FILE *fp; + char str[256]; + + fp = fopen (filename, "r"); + if (fp == NULL) + return; + + read_cfg_line (str, sizeof(str), fp); + strcpy (scanner_filename, str); + + read_cfg_line (str, sizeof(str), fp); + sscanf (str, "%d,%d", &scanner_cx, &scanner_cy); + scanner_cy += 385; + + read_cfg_line (str, sizeof(str), fp); + sscanf (str, "%d,%d", &compass_centre_x, &compass_centre_y); + compass_centre_y += 385; + + fclose (fp); +} + +/* + * Read in the newkind.cfg file. + */ + +void read_config_file (void) +{ + FILE *fp; + char str[256]; + + fp = fopen ("newkind.cfg", "r"); + if (fp == NULL) + return; + + read_cfg_line (str, sizeof(str), fp); + sscanf (str, "%d", &speed_cap); + + read_cfg_line (str, sizeof(str), fp); + sscanf (str, "%d", &wireframe); + + read_cfg_line (str, sizeof(str), fp); + sscanf (str, "%d", &anti_alias_gfx); + + read_cfg_line (str, sizeof(str), fp); + sscanf (str, "%d", &planet_render_style); + + read_cfg_line (str, sizeof(str), fp); + sscanf (str, "%d", &hoopy_casinos); + + read_cfg_line (str, sizeof(str), fp); + sscanf (str, "%d", &instant_dock); + + read_cfg_line (str, sizeof(str), fp); + read_scanner_config_file (str); + + fclose (fp); +} + +int checksum (unsigned char *block) +{ + int acc,carry; + int i; + + acc = 0x49; + carry = 0; + for (i = 0x49; i > 0; i--) + { + acc += block[i-1] + carry; + carry = acc >> 8; + acc &= 255; + acc ^= block[i]; + } + + return acc; +} + + +int save_commander_file (char *path) +{ + FILE *fp; + unsigned char block[256]; + int i; + int chk; + + fp = fopen (path, "wb"); + if (fp == NULL) + return 1; + + block[0] = cmdr.mission; + block[1] = docked_planet.d; + block[2] = docked_planet.b; + block[3] = cmdr.galaxy.a; + block[4] = cmdr.galaxy.b; + block[5] = cmdr.galaxy.c; + block[6] = cmdr.galaxy.d; + block[7] = cmdr.galaxy.e; + block[8] = cmdr.galaxy.f; + block[9] = (cmdr.credits >> 24) & 255; + block[10] = (cmdr.credits >> 16) & 255; + block[11] = (cmdr.credits >> 8) & 255; + block[12] = cmdr.credits & 255; + block[13] = cmdr.fuel; + block[14] = 4; + block[15] = cmdr.galaxy_number; + block[16] = cmdr.front_laser; + block[17] = cmdr.rear_laser; + block[18] = cmdr.left_laser; + block[19] = cmdr.right_laser; + block[20] = 0; + block[21] = 0; + block[22] = cmdr.cargo_capacity + 2; + + for (i = 0; i < NO_OF_STOCK_ITEMS; i++) + block[23+i] = cmdr.current_cargo[i]; + + block[40] = cmdr.ecm ? 255 : 0; + block[41] = cmdr.fuel_scoop ? 255 : 0; + block[42] = cmdr.energy_bomb ? 0x7F : 0; + block[43] = cmdr.energy_unit; + block[44] = cmdr.docking_computer ? 255 : 0; + block[45] = cmdr.galactic_hyperdrive ? 255 : 0; + block[46] = cmdr.escape_pod ? 255 : 0; + block[47] = 0; + block[48] = 0; + block[49] = 0; + block[50] = 0; + block[51] = cmdr.missiles; + block[52] = cmdr.legal_status; + + for (i = 0; i < NO_OF_STOCK_ITEMS; i++) + block[53+i] = stock_market[i].current_quantity; + + block[70] = cmdr.market_rnd; + block[71] = cmdr.score & 255; + block[72] = cmdr.score >> 8; + block[73] = 0x20; + + chk = checksum (block); + + block[74] = chk ^ 0xA9; + block[75] = chk; + + for (i = 76; i < 256; i++) + block[i] = 0; + + if (fwrite (block, 256, 1, fp) != 1) + return 1; + + if (fclose (fp) == EOF) + return 1; + + return 0; +} + + +int load_commander_file (char *path) +{ + FILE *fp; + unsigned char block[256]; + int i; + int chk; + + fp = fopen (path, "rb"); + if (fp == NULL) + return 1; + + if (fread (block, 256, 1, fp) != 1) + return 1; + + chk = checksum (block); + + if ((block[74] != (chk ^ 0xA9)) || (block[75] != chk)) + return 1; + + saved_cmdr.mission = block[0]; + + saved_cmdr.ship_x = block[1]; + saved_cmdr.ship_y = block[2]; + + saved_cmdr.galaxy.a = block[3]; + saved_cmdr.galaxy.b = block[4]; + saved_cmdr.galaxy.c = block[5]; + saved_cmdr.galaxy.d = block[6]; + saved_cmdr.galaxy.e = block[7]; + saved_cmdr.galaxy.f = block[8];; + + saved_cmdr.credits = block[9] << 24; + saved_cmdr.credits += block[10] << 16; + saved_cmdr.credits += block[11] << 8; + saved_cmdr.credits += block[12]; + + saved_cmdr.fuel = block[13]; + + saved_cmdr.galaxy_number = block[15]; + saved_cmdr.front_laser = block[16]; + saved_cmdr.rear_laser = block[17]; + saved_cmdr.left_laser = block[18]; + saved_cmdr.right_laser = block[19]; + + saved_cmdr.cargo_capacity = block[22] - 2; + + for (i = 0; i < NO_OF_STOCK_ITEMS; i++) + saved_cmdr.current_cargo[i] = block[23+i]; + + saved_cmdr.ecm = block[40]; + saved_cmdr.fuel_scoop = block[41]; + saved_cmdr.energy_bomb = block[42]; + saved_cmdr.energy_unit = block[43]; + saved_cmdr.docking_computer = block[44]; + saved_cmdr.galactic_hyperdrive = block[45]; + saved_cmdr.escape_pod = block[46]; + saved_cmdr.missiles = block[51]; + saved_cmdr.legal_status = block[52]; + + for (i = 0; i < NO_OF_STOCK_ITEMS; i++) + saved_cmdr.station_stock[i] = block[53+i]; + + saved_cmdr.market_rnd = block[70]; + + saved_cmdr.score = block[71]; + saved_cmdr.score += block[72] << 8; + + if (fclose (fp) == EOF) + return 1; + + return 0; +} + + + + diff --git a/file.h b/file.h new file mode 100644 index 0000000..eff30bc --- /dev/null +++ b/file.h @@ -0,0 +1,28 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * file.h + */ + +#ifndef FILE_H +#define FILE_H + +void write_config_file (void); +void read_config_file (void); +int save_commander_file (char *path); +int load_commander_file (char *path); + +#endif + diff --git a/gameover.wav b/gameover.wav new file mode 100644 index 0000000..300a0a8 Binary files /dev/null and b/gameover.wav differ diff --git a/gfx.h b/gfx.h new file mode 100644 index 0000000..c886b5c --- /dev/null +++ b/gfx.h @@ -0,0 +1,156 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + + +/** + * + * Elite - The New Kind. + * + * The code in this file has not been derived from the original Elite code. + * Written by C.J.Pinder 1999/2000. + * + **/ + + +#ifndef GFX_H +#define GFX_H + +#ifdef RES_512_512 + +#define GFX_SCALE (2) +#define GFX_X_OFFSET (0) +#define GFX_Y_OFFSET (0) +#define GFX_X_CENTRE (256) +#define GFX_Y_CENTRE (192) + +#define GFX_VIEW_TX 1 +#define GFX_VIEW_TY 1 +#define GFX_VIEW_BX 509 +#define GFX_VIEW_BY 381 + +#endif + +#ifdef RES_800_600 + +#define GFX_SCALE (2) +#define GFX_X_OFFSET (144) +#define GFX_Y_OFFSET (44) +#define GFX_X_CENTRE (256) +#define GFX_Y_CENTRE (192) + +#define GFX_VIEW_TX 1 +#define GFX_VIEW_TY 1 +#define GFX_VIEW_BX 509 +#define GFX_VIEW_BY 381 + +#endif + +#ifndef GFX_SCALE + +#define GFX_SCALE (1) +#define GFX_X_OFFSET (0) +#define GFX_Y_OFFSET (0) +#define GFX_X_CENTRE (128) +#define GFX_Y_CENTRE (96) + +#define GFX_VIEW_TX 1 +#define GFX_VIEW_TY 1 +#define GFX_VIEW_BX 253 +#define GFX_VIEW_BY 191 + +#endif + + + +#define GFX_COL_BLACK 0 +#define GFX_COL_DARK_RED 28 +#define GFX_COL_WHITE 255 +#define GFX_COL_GOLD 39 +#define GFX_COL_RED 49 +#define GFX_COL_CYAN 11 + +#define GFX_COL_GREY_1 248 +#define GFX_COL_GREY_2 235 +#define GFX_COL_GREY_3 234 +#define GFX_COL_GREY_4 237 + +#define GFX_COL_BLUE_1 45 +#define GFX_COL_BLUE_2 46 +#define GFX_COL_BLUE_3 133 +#define GFX_COL_BLUE_4 4 + +#define GFX_COL_RED_3 1 +#define GFX_COL_RED_4 71 + +#define GFX_COL_WHITE_2 242 + +#define GFX_COL_YELLOW_1 37 +#define GFX_COL_YELLOW_2 39 +#define GFX_COL_YELLOW_3 89 +#define GFX_COL_YELLOW_4 160 +#define GFX_COL_YELLOW_5 251 + +#define GFX_ORANGE_1 76 +#define GFX_ORANGE_2 77 +#define GFX_ORANGE_3 122 + +#define GFX_COL_GREEN_1 2 +#define GFX_COL_GREEN_2 17 +#define GFX_COL_GREEN_3 86 + +#define GFX_COL_PINK_1 183 + +#define IMG_GREEN_DOT 1 +#define IMG_RED_DOT 2 +#define IMG_BIG_S 3 +#define IMG_ELITE_TXT 4 +#define IMG_BIG_E 5 +#define IMG_DICE 6 +#define IMG_MISSILE_GREEN 7 +#define IMG_MISSILE_YELLOW 8 +#define IMG_MISSILE_RED 9 +#define IMG_BLAKE 10 + + +int gfx_graphics_startup (void); +void gfx_graphics_shutdown (void); +void gfx_update_screen (void); +void gfx_acquire_screen (void); +void gfx_release_screen (void); +void gfx_plot_pixel (int x, int y, int col); +void gfx_fast_plot_pixel (int x, int y, int col); +void gfx_draw_filled_circle (int cx, int cy, int radius, int circle_colour); +void gfx_draw_circle (int cx, int cy, int radius, int circle_colour); +void gfx_draw_line (int x1, int y1, int x2, int y2); +void gfx_draw_colour_line (int x1, int y1, int x2, int y2, int line_colour); +void gfx_draw_triangle (int x1, int y1, int x2, int y2, int x3, int y3, int col); +void gfx_draw_rectangle (int tx, int ty, int bx, int by, int col); +void gfx_display_text (int x, int y, char *txt); +void gfx_display_colour_text (int x, int y, char *txt, int col); +void gfx_display_centre_text (int y, char *str, int psize, int col); +void gfx_clear_display (void); +void gfx_clear_text_area (void); +void gfx_clear_area (int tx, int ty, int bx, int by); +void gfx_display_pretty_text (int tx, int ty, int bx, int by, char *txt); +void gfx_draw_scanner (void); +void gfx_set_clip_region (int tx, int ty, int bx, int by); +void gfx_polygon (int num_points, int *poly_list, int face_colour); +void gfx_draw_sprite (int sprite_no, int x, int y); +void gfx_start_render (void); +void gfx_render_polygon (int num_points, int *point_list, int face_colour, int zavg); +void gfx_render_line (int x1, int y1, int x2, int y2, int dist, int col); +void gfx_finish_render (void); +int gfx_request_file (char *title, char *path, char *ext); + +#endif diff --git a/hitem.wav b/hitem.wav new file mode 100644 index 0000000..1852ea0 Binary files /dev/null and b/hitem.wav differ diff --git a/hyper.wav b/hyper.wav new file mode 100644 index 0000000..ef40800 Binary files /dev/null and b/hyper.wav differ diff --git a/incom1.wav b/incom1.wav new file mode 100644 index 0000000..87abce5 Binary files /dev/null and b/incom1.wav differ diff --git a/incom2.wav b/incom2.wav new file mode 100644 index 0000000..ee1210a Binary files /dev/null and b/incom2.wav differ diff --git a/intro.c b/intro.c new file mode 100644 index 0000000..990b2c7 --- /dev/null +++ b/intro.c @@ -0,0 +1,134 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + + /* + * intro.c + * + * Run the two intro screens. + * First is a rolling Cobra MkIII. + * Second is a parade of the various ships. + * + */ + + +#include + +#include "config.h" +#include "elite.h" +#include "gfx.h" +#include "vector.h" +#include "shipdata.h" +#include "shipface.h" +#include "threed.h" +#include "space.h" +#include "stars.h" + +static int ship_no; +static int show_time; +static int direction; + + +static int min_dist[NO_OF_SHIPS+1] = {0, 200, 800, 200, 200, 200, 300, 384, 200, + 200, 200, 420, 900, 500, 800, 384, 384, + 384, 384, 384, 200, 384, 384, 384, 0, + 384, 0, 384, 384, 700, 384, 0, 0, + 900}; + + +static Matrix intro_ship_matrix; + + +void initialise_intro1 (void) +{ + clear_universe(); + set_init_matrix (intro_ship_matrix); + add_new_ship (SHIP_COBRA3, 0, 0, 4500, intro_ship_matrix, -127, -127); +} + + +void initialise_intro2 (void) +{ + ship_no = 0; + show_time = 0; + direction = 100; + + clear_universe(); + create_new_stars(); + set_init_matrix (intro_ship_matrix); + add_new_ship (1, 0, 0, 5000, intro_ship_matrix, -127, -127); +} + + + +void update_intro1 (void) +{ + universe[0].location.z -= 100; + + if (universe[0].location.z < 384) + universe[0].location.z = 384; + + gfx_clear_display(); + + flight_roll = 1; + update_universe(); + + gfx_draw_sprite(IMG_ELITE_TXT, -1, 10); + + gfx_display_centre_text (310, "Original Game (C) I.Bell & D.Braben.", 120, GFX_COL_WHITE); + gfx_display_centre_text (330, "Re-engineered by C.J.Pinder.", 120, GFX_COL_WHITE); + gfx_display_centre_text (360, "Load New Commander (Y/N)?", 140, GFX_COL_GOLD); +} + + +void update_intro2 (void) +{ + show_time++; + + if ((show_time >= 140) && (direction < 0)) + direction = -direction; + + universe[0].location.z += direction; + + if (universe[0].location.z < min_dist[ship_no]) + universe[0].location.z = min_dist[ship_no]; + + if (universe[0].location.z > 4500) + { + do + { + ship_no++; + if (ship_no > NO_OF_SHIPS) + ship_no = 1; + } while (min_dist[ship_no] == 0); + + show_time = 0; + direction = -100; + + ship_count[universe[0].type] = 0; + universe[0].type = 0; + + add_new_ship (ship_no, 0, 0, 4500, intro_ship_matrix, -127, -127); + } + + + gfx_clear_display(); + update_starfield(); + update_universe(); + + gfx_draw_sprite (IMG_ELITE_TXT, -1, 10); + + gfx_display_centre_text (360, "Press Fire or Space, Commander.", 140, GFX_COL_GOLD); + gfx_display_centre_text (330, ship_list[ship_no]->name, 120, GFX_COL_WHITE); +} + diff --git a/intro.h b/intro.h new file mode 100644 index 0000000..20faee1 --- /dev/null +++ b/intro.h @@ -0,0 +1,24 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +#ifndef INTRO_H +#define INTRO_H + +void initialise_intro1 (void); +void initialise_intro2 (void); + +void update_intro1 (void); +void update_intro2 (void); + +#endif diff --git a/keyboard.c b/keyboard.c new file mode 100644 index 0000000..d0dae25 --- /dev/null +++ b/keyboard.c @@ -0,0 +1,166 @@ +/* + * Elite - The New Kind. + * + * Allegro version of the keyboard routines. + * + * The code in this file has not been derived from the original Elite code. + * Written by C.J.Pinder 1999-2001. + * email: + * + */ + +/* + * keyboard.c + * + * Code to handle keyboard input. + */ + +#include +#include + +#include "allegro.h" + +int kbd_F1_pressed; +int kbd_F2_pressed; +int kbd_F3_pressed; +int kbd_F4_pressed; +int kbd_F5_pressed; +int kbd_F6_pressed; +int kbd_F7_pressed; +int kbd_F8_pressed; +int kbd_F9_pressed; +int kbd_F10_pressed; +int kbd_F11_pressed; +int kbd_F12_pressed; +int kbd_y_pressed; +int kbd_n_pressed; +int kbd_fire_pressed; +int kbd_ecm_pressed; +int kbd_energy_bomb_pressed; +int kbd_hyperspace_pressed; +int kbd_ctrl_pressed; +int kbd_jump_pressed; +int kbd_escape_pressed; +int kbd_dock_pressed; +int kbd_d_pressed; +int kbd_origin_pressed; +int kbd_find_pressed; +int kbd_fire_missile_pressed; +int kbd_target_missile_pressed; +int kbd_unarm_missile_pressed; +int kbd_pause_pressed; +int kbd_resume_pressed; +int kbd_inc_speed_pressed; +int kbd_dec_speed_pressed; +int kbd_up_pressed; +int kbd_down_pressed; +int kbd_left_pressed; +int kbd_right_pressed; +int kbd_enter_pressed; +int kbd_backspace_pressed; +int kbd_space_pressed; + + +int kbd_keyboard_startup (void) +{ +// set_keyboard_rate(2000, 2000); + return 0; +} + +int kbd_keyboard_shutdown (void) +{ + return 0; +} + +void kbd_poll_keyboard (void) +{ + poll_keyboard(); + + kbd_F1_pressed = key[KEY_F1]; + kbd_F2_pressed = key[KEY_F2]; + kbd_F3_pressed = key[KEY_F3]; + kbd_F4_pressed = key[KEY_F4]; + kbd_F5_pressed = key[KEY_F5]; + kbd_F6_pressed = key[KEY_F6]; + kbd_F7_pressed = key[KEY_F7]; + kbd_F8_pressed = key[KEY_F8]; + kbd_F9_pressed = key[KEY_F9]; + kbd_F10_pressed = key[KEY_F10]; + kbd_F11_pressed = key[KEY_F11]; + kbd_F12_pressed = key[KEY_F12]; + + kbd_y_pressed = key[KEY_Y]; + kbd_n_pressed = key[KEY_N]; + + kbd_fire_pressed = key[KEY_A]; + kbd_ecm_pressed = key[KEY_E]; + kbd_energy_bomb_pressed = key[KEY_TAB]; + kbd_hyperspace_pressed = key[KEY_H]; + kbd_ctrl_pressed = (key[KEY_LCONTROL]) || (key[KEY_RCONTROL]); + kbd_jump_pressed = key[KEY_J]; + kbd_escape_pressed = key[KEY_ESC]; + + kbd_dock_pressed = key[KEY_C]; + kbd_d_pressed = key[KEY_D]; + kbd_origin_pressed = key[KEY_O]; + kbd_find_pressed = key[KEY_F]; + + kbd_fire_missile_pressed = key[KEY_M]; + kbd_target_missile_pressed = key[KEY_T]; + kbd_unarm_missile_pressed = key[KEY_U]; + + kbd_pause_pressed = key[KEY_P]; + kbd_resume_pressed = key[KEY_R]; + + kbd_inc_speed_pressed = key[KEY_SPACE]; + kbd_dec_speed_pressed = key[KEY_SLASH]; + + kbd_up_pressed = key[KEY_S] || key[KEY_UP]; + kbd_down_pressed = key[KEY_X] || key[KEY_DOWN]; + kbd_left_pressed = key[KEY_COMMA] || key[KEY_LEFT]; + kbd_right_pressed = key[KEY_STOP] || key[KEY_RIGHT]; + + kbd_enter_pressed = key[KEY_ENTER]; + kbd_backspace_pressed = key[KEY_BACKSPACE]; + kbd_space_pressed = key[KEY_SPACE]; + + while (keypressed()) + readkey(); +} + + +int kbd_read_key (void) +{ + int keynum; + int keycode; + int keyasc; + + kbd_enter_pressed = 0; + kbd_backspace_pressed = 0; + + keynum = readkey(); + keycode = keynum >> 8; + keyasc = keynum & 255; + + if (keycode == KEY_ENTER) + { + kbd_enter_pressed = 1; + return 0; + } + + if (keycode == KEY_BACKSPACE) + { + kbd_backspace_pressed = 1; + return 0; + } + + return keyasc; +} + + +void kbd_clear_key_buffer (void) +{ + while (keypressed()) + readkey(); +} + diff --git a/keyboard.h b/keyboard.h new file mode 100644 index 0000000..7d0cdd2 --- /dev/null +++ b/keyboard.h @@ -0,0 +1,69 @@ +/* + * Elite - The New Kind. + * + * Allegro version of the keyboard routines. + * + * The code in this file has not been derived from the original Elite code. + * Written by C.J.Pinder 1999-2001. + * email: + * + */ + +/* + * keyboard.h + * + * Code to handle keyboard input. + */ + +#ifndef KEYBOARD_H +#define KEYBOARD_H + +extern int kbd_F1_pressed; +extern int kbd_F2_pressed; +extern int kbd_F3_pressed; +extern int kbd_F4_pressed; +extern int kbd_F5_pressed; +extern int kbd_F6_pressed; +extern int kbd_F7_pressed; +extern int kbd_F8_pressed; +extern int kbd_F9_pressed; +extern int kbd_F10_pressed; +extern int kbd_F11_pressed; +extern int kbd_F12_pressed; +extern int kbd_y_pressed; +extern int kbd_n_pressed; +extern int kbd_fire_pressed; +extern int kbd_ecm_pressed; +extern int kbd_energy_bomb_pressed; +extern int kbd_hyperspace_pressed; +extern int kbd_ctrl_pressed; +extern int kbd_jump_pressed; +extern int kbd_escape_pressed; +extern int kbd_dock_pressed; +extern int kbd_d_pressed; +extern int kbd_origin_pressed; +extern int kbd_find_pressed; +extern int kbd_fire_missile_pressed; +extern int kbd_target_missile_pressed; +extern int kbd_unarm_missile_pressed; +extern int kbd_pause_pressed; +extern int kbd_resume_pressed; +extern int kbd_inc_speed_pressed; +extern int kbd_dec_speed_pressed; +extern int kbd_up_pressed; +extern int kbd_down_pressed; +extern int kbd_left_pressed; +extern int kbd_right_pressed; +extern int kbd_enter_pressed; +extern int kbd_backspace_pressed; +extern int kbd_space_pressed; + + +int kbd_keyboard_startup (void); +int kbd_keyboard_shutdown (void); +void kbd_poll_keyboard (void); +int kbd_read_key (void); +void kbd_clear_key_buffer (void); + +#endif + diff --git a/launch.wav b/launch.wav new file mode 100644 index 0000000..9ea99dc Binary files /dev/null and b/launch.wav differ diff --git a/main.h b/main.h new file mode 100644 index 0000000..b68cac3 --- /dev/null +++ b/main.h @@ -0,0 +1,24 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +#ifndef MAIN_H +#define MAIN_H + +void info_message (char *message); +void save_commander_screen (void); +void load_commander_screen (void); +void update_screen (void); + + +#endif diff --git a/makefile b/makefile new file mode 100644 index 0000000..b5c2743 --- /dev/null +++ b/makefile @@ -0,0 +1,73 @@ +# +# Makefile for Elite - The New Kind. +# + +CC = gcc +WRES = windres + +LIBS = -s -mwindows -lalleg_s -lkernel32 -lgdi32 -lcomdlg32 -luser32 -lole32 -lddraw -ldxguid -lwinmm -ldsound -ldinput +CFLAGS = -mpentium -O2 -funroll-loops -Wall -DALLEGRO_STATICLINK + +OBJS = alg_gfx.o alg_main.o docked.o elite.o\ + intro.o planet.o shipdata.o shipface.o sound.o space.o\ + swat.o threed.o vector.o random.o trade.o options.o \ + stars.o missions.o nkres.o pilot.o file.o keyboard.o + +.c.o: + $(CC) $(CFLAGS) -c $< + +newkind.exe: $(OBJS) + $(CC) -o newkind.exe $(OBJS) $(LIBS) + +nkres.o: nkres.rc + $(WRES) nkres.rc nkres.o + + +alg_gfx.o: alg_gfx.c alg_data.h config.h elite.h planet.h gfx.h + +alg_main.o: alg_main.c alg_data.h config.h elite.h planet.h gfx.h docked.h\ + intro.h shipdata.h shipface.h space.h main.h pilot.h file.h keyboard.h + +docked.o: docked.c config.h elite.h planet.h gfx.h + +elite.o: elite.c config.h elite.h planet.h vector.h shipdata.h + +intro.o: intro.c space.h config.h elite.h planet.h gfx.h vector.h\ + shipdata.h shipface.h threed.h + +planet.o: planet.c config.h elite.h planet.h + +shipdata.o: shipdata.c shipdata.h vector.h + +shipface.o: shipface.c config.h elite.h planet.h shipface.h gfx.h + +threed.o: threed.c space.h config.h elite.h planet.h gfx.h vector.h shipdata.h\ + shipface.h threed.h + +vector.o: vector.c config.h vector.h + +sound.o: sound.c sound.h + +space.o: space.c space.h vector.h alg_data.h config.h elite.h planet.h\ + gfx.h docked.h intro.h shipdata.h shipface.h main.h random.h + +swat.o: swat.c swat.h elite.h config.h main.h gfx.h alg_data.h shipdata.h\ + random.h pilot.h + +random.o: random.c random.h + +trade.o: trade.c trade.h elite.h config.h + +options.o: options.c options.h elite.h config.h gfx.h file.h + +stars.o: stars.c stars.h elite.h config.h gfx.h random.h + +missions.o: missions.c missions.h config.h elite.h gfx.h planet.h main.h\ + vector.h space.h + +pilot.o: pilot.c pilot.h config.h elite.h gfx.h vector.h space.h main.h + +file.o: file.c file.h config.h elite.h + +keyboard.o: keyboard.c keyboard.h + diff --git a/makefile-linux b/makefile-linux new file mode 100644 index 0000000..ca806aa --- /dev/null +++ b/makefile-linux @@ -0,0 +1,92 @@ +# +# Makefile for Elite - The New Kind, source release 1.0. +# +# +# Instructions for use: +# +# Copy this file to the source directory. +# +# Enter "make -f makefile-linux". +# +# Unzip the Windows distribution from the E:TNK website. +# +# Copy the file "newkind" from the source directory into the same directory as +# the Windows newkind.exe file that you just unzipped. +# +# "cd" to that directory and enter "./newkind &". +# +# Select wisely in battle, and be strong. =) +# + +CC = gcc +LIBS = `allegro-config --libs` +CFLAGS = -O -Wall +OBJS = alg_gfx.o alg_main.o docked.o elite.o \ +intro.o planet.o shipdata.o shipface.o sound.o space.o \ +swat.o threed.o vector.o random.o trade.o options.o \ +stars.o missions.o pilot.o file.o keyboard.o +EXEC = newkind + +all: $(EXEC) + +clean: + rm *.o $(EXEC) + +.SUFFIXES : .c .o + +.c.o: + $(CC) $(CFLAGS) -c $< + +$(EXEC): $(OBJS) + $(CC) -o $(EXEC) $(OBJS) $(LIBS) + + +alg_gfx.o: alg_gfx.c alg_data.h config.h elite.h planet.h gfx.h + +alg_main.o: alg_main.c alg_data.h config.h elite.h planet.h gfx.h docked.h\ + intro.h shipdata.h shipface.h space.h main.h pilot.h file.h keyboard.h + +docked.o: docked.c config.h elite.h planet.h gfx.h + +elite.o: elite.c config.h elite.h planet.h vector.h shipdata.h + +intro.o: intro.c space.h config.h elite.h planet.h gfx.h vector.h\ + shipdata.h shipface.h threed.h + +planet.o: planet.c config.h elite.h planet.h + +shipdata.o: shipdata.c shipdata.h vector.h + +shipface.o: shipface.c config.h elite.h planet.h shipface.h gfx.h + +threed.o: threed.c space.h config.h elite.h planet.h gfx.h vector.h shipdata.h\ + shipface.h threed.h + +vector.o: vector.c config.h vector.h + +sound.o: sound.c sound.h + +space.o: space.c space.h vector.h alg_data.h config.h elite.h planet.h\ + gfx.h docked.h intro.h shipdata.h shipface.h main.h random.h + +swat.o: swat.c swat.h elite.h config.h main.h gfx.h alg_data.h shipdata.h\ + random.h pilot.h + +random.o: random.c random.h + +trade.o: trade.c trade.h elite.h config.h + +options.o: options.c options.h elite.h config.h gfx.h file.h + +stars.o: stars.c stars.h elite.h config.h gfx.h random.h + +missions.o: missions.c missions.h config.h elite.h gfx.h planet.h main.h\ + vector.h space.h + +pilot.o: pilot.c pilot.h config.h elite.h gfx.h vector.h space.h main.h + +file.o: file.c file.h config.h elite.h + +keyboard.o: keyboard.c keyboard.h + + diff --git a/menu.h b/menu.h new file mode 100644 index 0000000..0b03418 --- /dev/null +++ b/menu.h @@ -0,0 +1,5 @@ +#define MENU_FILE 0 +#define MENU_HELP 1 + +#define IDM_EXIT 1 +#define IDM_ABOUT 2 diff --git a/missile.wav b/missile.wav new file mode 100644 index 0000000..0d756e6 Binary files /dev/null and b/missile.wav differ diff --git a/missions.c b/missions.c new file mode 100644 index 0000000..ea36df6 --- /dev/null +++ b/missions.c @@ -0,0 +1,353 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * missions.c + * + * Code to handle the special missions. + */ + +#include +#include + +#include "config.h" +#include "elite.h" +#include "gfx.h" +#include "vector.h" +#include "space.h" +#include "planet.h" +#include "main.h" +#include "missions.h" +#include "keyboard.h" + + +char *mission1_brief_a = + "Greetings Commander, I am Captain Curruthers of " + "Her Majesty's Space Navy and I beg a moment of your " + "valuable time. We would like you to do a little job " + "for us. The ship you see here is a new model, the " + "Constrictor, equiped with a top secret new shield " + "generator. Unfortunately it's been stolen."; + +char *mission1_brief_b = + "It went missing from our ship yard on Xeer five months ago " + "and was last seen at Reesdice. Your mission should you decide " + "to accept it, is to seek and destroy this ship. You are " + "cautioned that only Military Lasers will get through the new " + "shields and that the Constrictor is fitted with an E.C.M. " + "System. Good Luck, Commander. ---MESSAGE ENDS."; + +char *mission1_brief_c = + "It went missing from our ship yard on Xeer five months ago " + "and is believed to have jumped to this galaxy. " + "Your mission should you decide to accept it, is to seek and " + "destroy this ship. You are cautioned that only Military Lasers " + "will get through the new shields and that the Constrictor is " + "fitted with an E.C.M. System. Good Luck, Commander. ---MESSAGE ENDS."; + +char *mission1_debrief = + "There will always be a place for you in Her Majesty's Space Navy. " + "And maybe sooner than you think... ---MESSAGE ENDS."; + +char *mission1_pdesc[] = +{ + "THE CONSTRICTOR WAS LAST SEEN AT REESDICE, COMMANDER.", + "A STRANGE LOOKING SHIP LEFT HERE A WHILE BACK. LOOKED BOUND FOR AREXE.", + "YEP, AN UNUSUAL NEW SHIP HAD A GALACTIC HYPERDRIVE FITTED HERE, USED IT TOO.", + "I HEAR A WEIRD LOOKING SHIP WAS SEEN AT ERRIUS.", + "THIS STRANGE SHIP DEHYPED HERE FROM NOWHERE, SUN SKIMMED AND JUMPED. I HEAR IT WENT TO INBIBE.", + "ROGUE SHIP WENT FOR ME AT AUSAR. MY LASERS DIDN'T EVEN SCRATCH ITS HULL.", + "OH DEAR ME YES. A FRIGHTFUL ROGUE WITH WHAT I BELIEVE YOU PEOPLE CALL A LEAD " + "POSTERIOR SHOT UP LOTS OF THOSE BEASTLY PIRATES AND WENT TO USLERI.", + "YOU CAN TACKLE THE VICIOUS SCOUNDREL IF YOU LIKE. HE'S AT ORARRA.", + "THERE'S A REAL DEADLY PIRATE OUT THERE.", + "BOY ARE YOU IN THE WRONG GALAXY!", + "COMING SOON: ELITE - DARKNESS FALLS.", +}; + +char *mission2_brief_a = + "Attention Commander, I am Captain Fortesque of Her Majesty's Space Navy. " + "We have need of your services again. If you would be so good as to go to " + "Ceerdi you will be briefed.If succesful, you will be rewarded." + "---MESSAGE ENDS."; + +char *mission2_brief_b = + "Good Day Commander. I am Agent Blake of Naval Intelligence. As you know, " + "the Navy have been keeping the Thargoids off your ass out in deep space " + "for many years now. Well the situation has changed. Our boys are ready " + "for a push right to the home system of those murderers."; + +char *mission2_brief_c = + "I have obtained the defence plans for their Hive Worlds. The beetles " + "know we've got something but not what. If I transmit the plans to our " + "base on Birera they'll intercept the transmission. I need a ship to " + "make the run. You're elected. The plans are unipulse coded within " + "this transmission. You will be paid. Good luck Commander. ---MESSAGE ENDS."; + +char *mission2_debrief = + "You have served us well and we shall remember. " + "We did not expect the Thargoids to find out about you." + "For the moment please accept this Navy Extra Energy Unit as payment. " + "---MESSAGE ENDS."; + + + +char *mission_planet_desc (struct galaxy_seed planet) +{ + int pnum; + + if (!docked) + return NULL; + + if ((planet.a != docked_planet.a) || + (planet.b != docked_planet.b) || + (planet.c != docked_planet.c) || + (planet.d != docked_planet.d) || + (planet.e != docked_planet.e) || + (planet.f != docked_planet.f)) + return NULL; + + pnum = find_planet_number (planet); + + if (cmdr.galaxy_number == 0) + { + switch (pnum) + { + case 150: + return mission1_pdesc[0]; + + case 36: + return mission1_pdesc[1]; + + case 28: + return mission1_pdesc[2]; + } + } + + if (cmdr.galaxy_number == 1) + { + switch (pnum) + { + case 32: + case 68: + case 164: + case 220: + case 106: + case 16: + case 162: + case 3: + case 107: + case 26: + case 192: + case 184: + case 5: + return mission1_pdesc[3]; + + case 253: + return mission1_pdesc[4]; + + case 79: + return mission1_pdesc[5]; + + case 53: + return mission1_pdesc[6]; + + case 118: + return mission1_pdesc[7]; + + case 193: + return mission1_pdesc[8]; + } + } + + if ((cmdr.galaxy_number == 2) && (pnum == 101)) + return mission1_pdesc[9]; + + return NULL; +} + + +void constrictor_mission_brief (void) +{ + Matrix rotmat; + + cmdr.mission = 1; + + current_screen = SCR_FRONT_VIEW; + + gfx_clear_display(); + gfx_display_centre_text (10, "INCOMING MESSAGE", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + + gfx_display_pretty_text (16, 50, 300, 384, mission1_brief_a); + gfx_display_pretty_text (16, 200, 470, 384, + (cmdr.galaxy_number == 0) ? mission1_brief_b : mission1_brief_c); + + gfx_display_centre_text (330, "Press space to continue.", 140, GFX_COL_GOLD); + + clear_universe(); + set_init_matrix (rotmat); + add_new_ship (SHIP_CONSTRICTOR, 200, 90, 600, rotmat, -127, -127); + flight_roll = 0; + flight_climb = 0; + flight_speed = 0; + + do + { + gfx_clear_area (310, 50, 510, 180); + update_universe (); + universe[0].location.z = 600; + gfx_update_screen(); + kbd_poll_keyboard(); + } while (!kbd_space_pressed); +} + + +void constrictor_mission_debrief (void) +{ + int keyasc; + + cmdr.mission = 3; + cmdr.score += 256; + cmdr.credits += 50000; + + gfx_clear_display(); + gfx_display_centre_text (10, "INCOMING MESSAGE", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + + gfx_display_centre_text (100, "Congratulations Commander!", 140, GFX_COL_GOLD); + + gfx_display_pretty_text (116, 132, 400, 384, mission1_debrief); + + gfx_display_centre_text (330, "Press space to continue.", 140, GFX_COL_GOLD); + + gfx_update_screen(); + + do + { + keyasc = kbd_read_key(); + } while (keyasc != ' '); +} + + +void thargoid_mission_first_brief (void) +{ + int keyasc; + + cmdr.mission = 4; + + gfx_clear_display(); + gfx_display_centre_text (10, "INCOMING MESSAGE", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + + gfx_display_pretty_text (116, 132, 400, 384, mission2_brief_a); + + gfx_display_centre_text (330, "Press space to continue.", 140, GFX_COL_GOLD); + + gfx_update_screen(); + + do + { + keyasc = kbd_read_key(); + } while (keyasc != ' '); +} + + +void thargoid_mission_second_brief (void) +{ + int keyasc; + + cmdr.mission = 5; + + gfx_clear_display(); + gfx_display_centre_text (10, "INCOMING MESSAGE", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + + gfx_display_pretty_text (16, 50, 300, 384, mission2_brief_b); + gfx_display_pretty_text (16, 200, 470, 384, mission2_brief_c); + + gfx_draw_sprite (IMG_BLAKE, 352, 46); + + gfx_display_centre_text (330, "Press space to continue.", 140, GFX_COL_GOLD); + + gfx_update_screen(); + + do + { + keyasc = kbd_read_key(); + } while (keyasc != ' '); +} + + +void thargoid_mission_debrief (void) +{ + int keyasc; + + cmdr.mission = 6; + cmdr.score += 256; + cmdr.energy_unit = 2; + + gfx_clear_display (); + gfx_display_centre_text (10, "INCOMING MESSAGE", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + + gfx_display_centre_text (100, "Well done Commander.", 140, GFX_COL_GOLD); + + gfx_display_pretty_text (116, 132, 400, 384, mission2_debrief); + + gfx_display_centre_text (330, "Press space to continue.", 140, GFX_COL_GOLD); + + gfx_update_screen(); + + do + { + keyasc = kbd_read_key(); + } while (keyasc != ' '); +} + + + +void check_mission_brief (void) +{ + if ((cmdr.mission == 0) && (cmdr.score >= 256) && (cmdr.galaxy_number < 2)) + { + constrictor_mission_brief(); + return; + } + + if (cmdr.mission == 2) + { + constrictor_mission_debrief(); + return; + } + + if ((cmdr.mission == 3) && (cmdr.score >= 1280) && (cmdr.galaxy_number == 2)) + { + thargoid_mission_first_brief(); + return; + } + + if ((cmdr.mission == 4) && (docked_planet.d == 215) && (docked_planet.b == 84)) + { + thargoid_mission_second_brief(); + return; + } + + if ((cmdr.mission == 5) && (docked_planet.d == 63) && (docked_planet.b == 72)) + { + thargoid_mission_debrief(); + return; + } +} + diff --git a/missions.h b/missions.h new file mode 100644 index 0000000..ae3bfff --- /dev/null +++ b/missions.h @@ -0,0 +1,7 @@ +#ifndef MISSIONS_H +#define MISSIONS_H + +char *mission_planet_desc (struct galaxy_seed planet); +void check_mission_brief (void); + +#endif \ No newline at end of file diff --git a/newkind.cfg b/newkind.cfg new file mode 100644 index 0000000..d30c9e6 --- /dev/null +++ b/newkind.cfg @@ -0,0 +1,7 @@ +75 # Game Speed, the lower the number the faster the game. +0 # Graphics: 0 = Solid, 1 = Wireframe +1 # Anti-Alias Wireframe: 0 = Normal, 1 = Anti-Aliased +3 # Planet style: 0 = Wireframe, 1 = Green, 2 = SNES, 3 = Fractal +0 # Planet Descriptions: 0 = Tree Grubs, 1 = Hoopy Casinos +0 # Instant dock: 0 = off, 1 = on +newscan.cfg # Name of scanner config file to use. diff --git a/newkind.ico b/newkind.ico new file mode 100644 index 0000000..16338a2 Binary files /dev/null and b/newkind.ico differ diff --git a/newscan.cfg b/newscan.cfg new file mode 100644 index 0000000..c1300be --- /dev/null +++ b/newscan.cfg @@ -0,0 +1,12 @@ +############################################################ +# # +# Elite - The New Kind # +# # +# Scanner Config file. # +# # +############################################################ + +scanner.bmp # Scanner bitmap filename. +253,63 # Scanner centre X,Y +382,22 # Compass centre X,Y + diff --git a/nkres.rc b/nkres.rc new file mode 100644 index 0000000..120b239 --- /dev/null +++ b/nkres.rc @@ -0,0 +1 @@ +NKICON ICON "newkind.ico" diff --git a/options.c b/options.c new file mode 100644 index 0000000..3a9fac3 --- /dev/null +++ b/options.c @@ -0,0 +1,366 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * Options.c + */ + +#include +#include + +#include "elite.h" +#include "config.h" +#include "gfx.h" +#include "options.h" +#include "main.h" +#include "docked.h" +#include "file.h" + +static int hilite_item; + +#define NUM_OPTIONS 4 +#define NUM_SETTINGS 6 + +#define OPTION_BAR_WIDTH (400) +#define OPTION_BAR_HEIGHT (15) + +struct option +{ + char *text; + int docked_only; +}; + +static struct option option_list[NUM_OPTIONS] = +{ + {"Save Commander", 1}, + {"Load Commander", 1}, + {"Game Settings", 0}, + {"Quit", 0} +}; + +struct setting +{ + char *name; + char *value[5]; +}; + +static struct setting setting_list[NUM_SETTINGS] = +{ + {"Graphics:", {"Solid", "Wireframe", "", "", ""}}, + {"Anti Alias:", {"Off", "On", "", "", ""}}, + {"Planet Style:", {"Wireframe", "Green", "SNES", "Fractal", ""}}, + {"Planet Desc.:", {"BBC", "MSX", "", "", ""}}, + {"Instant Dock:", {"Off", "On", "", "", ""}}, + {"Save Settings", {"", "", "", "", ""}} +}; + + +void quit_screen (void) +{ + current_screen = SCR_QUIT; + + gfx_clear_display(); + gfx_display_centre_text (10, "GAME OPTIONS", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + + gfx_display_centre_text (175, "QUIT GAME (Y/N)?", 140, GFX_COL_GOLD); +} + + + + + +void display_setting_item (int item) +{ + int x,y; + int v; + + if (item == (NUM_SETTINGS - 1)) + { + y = ((NUM_SETTINGS + 1) / 2) * 30 + 96 + 32; + gfx_display_centre_text (y, setting_list[item].name, 120, GFX_COL_WHITE); + return; + } + + switch (item) + { + case 0: + v = wireframe; + break; + + case 1: + v = anti_alias_gfx; + break; + + case 2: + v = planet_render_style; + break; + + case 3: + v = hoopy_casinos; + break; + + case 4: + v = instant_dock; + break; + + default: + v = 0; + break; + } + + x = (item & 1) * 250 + 32; + y = (item / 2) * 30 + 96; + + gfx_display_colour_text (x, y, setting_list[item].name, GFX_COL_WHITE); + gfx_display_colour_text (x + 120, y, setting_list[item].value[v], GFX_COL_WHITE); +} + + +void highlight_setting (int item) +{ + int x,y; + int width; + + if ((hilite_item != -1) && (hilite_item != item)) + { + if (hilite_item == (NUM_SETTINGS - 1)) + { + x = GFX_X_CENTRE - (OPTION_BAR_WIDTH / 2); + y = ((NUM_SETTINGS + 1) / 2) * 30 + 96 + 32; + width = OPTION_BAR_WIDTH; + } + else + { + x = (hilite_item & 1) * 250 + 32 + 120; + y = (hilite_item / 2) * 30 + 96; + width = 100; + } + + gfx_clear_area (x, y, x + width, y + OPTION_BAR_HEIGHT); + display_setting_item (hilite_item); + } + + if (item == (NUM_SETTINGS - 1)) + { + x = GFX_X_CENTRE - (OPTION_BAR_WIDTH / 2); + y = ((NUM_SETTINGS + 1) / 2) * 30 + 96 + 32; + width = OPTION_BAR_WIDTH; + } + else + { + x = (item & 1) * 250 + 32 + 120; + y = (item / 2) * 30 + 96; + width = 100; + } + + gfx_draw_rectangle (x, y, x + width, y + OPTION_BAR_HEIGHT, GFX_COL_DARK_RED); + display_setting_item (item); + hilite_item = item; +} + + + +void select_left_setting (void) +{ + if ((hilite_item & 1) != 0) + highlight_setting (hilite_item - 1); +} + +void select_right_setting (void) +{ + if (((hilite_item & 1) == 0) && (hilite_item < (NUM_SETTINGS - 1))) + highlight_setting (hilite_item + 1); +} + + +void select_up_setting (void) +{ + if (hilite_item == (NUM_SETTINGS - 1)) + { + highlight_setting (NUM_SETTINGS - 2); + return; + } + + if (hilite_item > 1) + highlight_setting (hilite_item - 2); +} + + +void select_down_setting (void) +{ + if (hilite_item == (NUM_SETTINGS - 2)) + { + highlight_setting (NUM_SETTINGS - 1); + return; + } + + if (hilite_item < (NUM_SETTINGS - 2)) + highlight_setting (hilite_item + 2); +} + +void toggle_setting (void) +{ + if (hilite_item == (NUM_SETTINGS - 1)) + { + write_config_file(); + display_options(); + return; + } + + switch (hilite_item) + { + case 0: + wireframe ^= 1; + break; + + case 1: + anti_alias_gfx ^= 1; + break; + + case 2: + planet_render_style = (planet_render_style + 1) % 4; + break; + + case 3: + hoopy_casinos ^= 1; + break; + + case 4: + instant_dock ^= 1; + break; + } + + highlight_setting (hilite_item); +} + + +void game_settings_screen (void) +{ + int i; + + current_screen = SCR_SETTINGS; + + gfx_clear_display(); + gfx_display_centre_text (10, "GAME SETTINGS", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + + for (i = 0; i < NUM_SETTINGS; i++) + { + display_setting_item (i); + } + + hilite_item = -1; + highlight_setting (0); +} + + +void display_option_item (int i) +{ + int y; + int col; + + y = (384 - (30 * NUM_OPTIONS)) / 2; + y += i * 30; + col = ((!docked) && option_list[i].docked_only) ? GFX_COL_GREY_1 : GFX_COL_WHITE; + + gfx_display_centre_text (y, option_list[i].text, 120, col); +} + + +void highlight_option (int i) +{ + int y; + int x; + + if ((hilite_item != -1) && (hilite_item != i)) + { + x = GFX_X_CENTRE - (OPTION_BAR_WIDTH / 2); + y = (384 - (30 * NUM_OPTIONS)) / 2; + y += hilite_item * 30; + gfx_clear_area (x, y, x + OPTION_BAR_WIDTH, y + OPTION_BAR_HEIGHT); + display_option_item (hilite_item); + } + + x = GFX_X_CENTRE - (OPTION_BAR_WIDTH / 2); + y = (384 - (30 * NUM_OPTIONS)) / 2; + y += i * 30; + + gfx_draw_rectangle (x, y, x + OPTION_BAR_WIDTH, y + OPTION_BAR_HEIGHT, + GFX_COL_DARK_RED); + display_option_item (i); + + hilite_item = i; +} + +void select_previous_option (void) +{ + if (hilite_item > 0) + highlight_option (hilite_item - 1); +} + +void select_next_option (void) +{ + if (hilite_item < (NUM_OPTIONS - 1)) + highlight_option (hilite_item + 1); +} + + +void do_option (void) +{ + if ((!docked) && option_list[hilite_item].docked_only) + return; + + switch (hilite_item) + { + case 0: + save_commander_screen(); + break; + + case 1: + load_commander_screen(); + display_commander_status(); + break; + + case 2: + game_settings_screen(); + break; + + case 3: + quit_screen(); + break; + } +} + + +void display_options (void) +{ + int i; + + current_screen = SCR_OPTIONS; + + gfx_clear_display(); + gfx_display_centre_text (10, "GAME OPTIONS", 140, GFX_COL_GOLD); + gfx_draw_line (0, 36, 511, 36); + gfx_display_centre_text (300, "Version: Release 1.0", 120, GFX_COL_WHITE); + gfx_display_centre_text (320, "www.newkind.co.uk", 120, GFX_COL_WHITE); + gfx_display_centre_text (340, "Written by Christian Pinder 1999-2001", 120, GFX_COL_WHITE); + gfx_display_centre_text (360, "Based on original code by Ian Bell & David Braben", 120, GFX_COL_WHITE); + + for (i = 0; i < NUM_OPTIONS; i++) + display_option_item (i); + + hilite_item = -1; + highlight_option (0); +} diff --git a/options.h b/options.h new file mode 100644 index 0000000..7fdc407 --- /dev/null +++ b/options.h @@ -0,0 +1,33 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * options.h + */ + +#ifndef OPTIONS_H +#define OPTIONS_H + +void display_options (void); +void select_previous_option (void); +void select_next_option (void); +void do_option (void); + +void select_left_setting (void); +void select_right_setting (void); +void select_up_setting (void); +void select_down_setting (void); +void toggle_setting (void); + +#endif diff --git a/pilot.c b/pilot.c new file mode 100644 index 0000000..9c54d42 --- /dev/null +++ b/pilot.c @@ -0,0 +1,294 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * pilot.c + * + * The auto-pilot code. Used for docking computers and for + * flying other ships to and from the space station. + */ + +/* + * In the original Elite this code was mixed in with the tactics routines. + * I have split it out to make it more understandable and easier to maintain. + */ + + +#include +#include +#include + +#include "config.h" +#include "gfx.h" +#include "elite.h" +#include "vector.h" +#include "main.h" +#include "space.h" +#include "sound.h" + + +/* + * Fly to a given point in space. + */ + +void fly_to_vector (struct univ_object *ship, Vector vec) +{ + Vector nvec; + double direction; + double dir; + int rat; + double rat2; + double cnt2; + + rat = 3; + rat2 = 0.1666; + cnt2 = 0.8055; + + nvec = unit_vector(&vec); + direction = vector_dot_product (&nvec, &ship->rotmat[2]); + + if (direction < -0.6666) + rat2 = 0; + + dir = vector_dot_product (&nvec, &ship->rotmat[1]); + + if (direction < -0.861) + { + ship->rotx = (dir < 0) ? 7 : -7; + ship->rotz = 0; + return; + } + + ship->rotx = 0; + + if ((fabs(dir) * 2) >= rat2) + { + ship->rotx = (dir < 0) ? rat : -rat; + } + + if (abs(ship->rotz) < 16) + { + dir = vector_dot_product (&nvec, &ship->rotmat[0]); + + ship->rotz = 0; + + if ((fabs(dir) * 2) >= rat2) + { + ship->rotz = (dir < 0) ? rat : -rat; + + if (ship->rotx < 0) + ship->rotz = -ship->rotz; + } + } + + if (direction <= -0.167) + { + ship->acceleration = -1; + return; + } + + if (direction >= cnt2) + { + ship->acceleration = 3; + return; + } +} + + + +/* + * Fly towards the planet. + */ + +void fly_to_planet (struct univ_object *ship) +{ + Vector vec; + + vec.x = universe[0].location.x - ship->location.x; + vec.y = universe[0].location.y - ship->location.y; + vec.z = universe[0].location.z - ship->location.z; + + fly_to_vector (ship, vec); +} + + +/* + * Fly to a point in front of the station docking bay. + * Done prior to the final stage of docking. + */ + + +void fly_to_station_front (struct univ_object *ship) +{ + Vector vec; + + vec.x = universe[1].location.x - ship->location.x; + vec.y = universe[1].location.y - ship->location.y; + vec.z = universe[1].location.z - ship->location.z; + + vec.x += universe[1].rotmat[2].x * 768; + vec.y += universe[1].rotmat[2].y * 768; + vec.z += universe[1].rotmat[2].z * 768; + + fly_to_vector (ship, vec); +} + + +/* + * Fly towards the space station. + */ + +void fly_to_station (struct univ_object *ship) +{ + Vector vec; + + vec.x = universe[1].location.x - ship->location.x; + vec.y = universe[1].location.y - ship->location.y; + vec.z = universe[1].location.z - ship->location.z; + + fly_to_vector (ship, vec); +} + + +/* + * Final stage of docking. + * Fly into the docking bay. + */ + +void fly_to_docking_bay (struct univ_object *ship) +{ + Vector diff; + Vector vec; + double dir; + + diff.x = ship->location.x - universe[1].location.x; + diff.y = ship->location.y - universe[1].location.y; + diff.z = ship->location.z - universe[1].location.z; + + vec = unit_vector (&diff); + + ship->rotx = 0; + + if (ship->type < 0) + { + ship->rotz = 1; + if (((vec.x >= 0) && (vec.y >= 0)) || + ((vec.x < 0) && (vec.y < 0))) + { + ship->rotz = -ship->rotz; + } + + if (fabs(vec.x) >= 0.0625) + { + ship->acceleration = 0; + ship->velocity = 1; + return; + } + + if (fabs(vec.y) > 0.002436) + ship->rotx = (vec.y < 0) ? -1 : 1; + + if (fabs(vec.y) >= 0.0625) + { + ship->acceleration = 0; + ship->velocity = 1; + return; + } + } + + ship->rotz = 0; + + dir = vector_dot_product (&ship->rotmat[0], &universe[1].rotmat[1]); + + if (fabs(dir) >= 0.9166) + { + ship->acceleration++; + ship->rotz = 127; + return; + } + + ship->acceleration = 0; + ship->rotz = 0; +} + + +/* + * Fly a ship to the planet or to the space station and dock it. + */ + +void auto_pilot_ship (struct univ_object *ship) +{ + Vector diff; + Vector vec; + double dist; + double dir; + + if ((ship->flags & FLG_FLY_TO_PLANET) || + ((ship_count[SHIP_CORIOLIS] == 0) && (ship_count[SHIP_DODEC] == 0))) + { + fly_to_planet (ship); + return; + } + + diff.x = ship->location.x - universe[1].location.x; + diff.y = ship->location.y - universe[1].location.y; + diff.z = ship->location.z - universe[1].location.z; + + dist = sqrt (diff.x * diff.x + diff.y * diff.y + diff.z * diff.z); + + if (dist < 160) + { + ship->flags |= FLG_REMOVE; // Ship has docked. + return; + } + + vec = unit_vector (&diff); + dir = vector_dot_product (&universe[1].rotmat[2], &vec); + + if (dir < 0.9722) + { + fly_to_station_front (ship); + return; + } + + dir = vector_dot_product (&ship->rotmat[2], &vec); + + if (dir < -0.9444) + { + fly_to_docking_bay (ship); + return; + } + + fly_to_station (ship); +} + + +void engage_auto_pilot (void) +{ + if (auto_pilot || witchspace || hyper_ready) + return; + + auto_pilot = 1; + snd_play_midi (SND_BLUE_DANUBE, 1); +} + + +void disengage_auto_pilot (void) +{ + if (auto_pilot) + { + auto_pilot = 0; + snd_stop_midi(); + } +} diff --git a/pilot.h b/pilot.h new file mode 100644 index 0000000..6635e10 --- /dev/null +++ b/pilot.h @@ -0,0 +1,28 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * pilot.h + */ + +#ifndef PILOT_H +#define PILOT_H + +void fly_to_vector (struct univ_object *ship, Vector vec); +void auto_pilot_ship (struct univ_object *ship); +void engage_auto_pilot (void); +void disengage_auto_pilot (void); + +#endif + diff --git a/planet.c b/planet.c new file mode 100644 index 0000000..464e8d1 --- /dev/null +++ b/planet.c @@ -0,0 +1,510 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + */ + +/* + * + * Handle the generation of planet info... + */ + +#include +#include +#include +#include + +#include "config.h" +#include "gfx.h" +#include "elite.h" +#include "planet.h" +#include "missions.h" + + +extern struct galaxy_seed hyperspace_planet; + +struct random_seed +{ + int a; + int b; + int c; + int d; +}; + + +static struct random_seed rnd_seed; + +static char *digrams="ABOUSEITILETSTONLONUTHNOALLEXEGEZACEBISOUSESARMAINDIREA?ERATENBERALAVETIEDORQUANTEISRION"; + +static char *inhabitant_desc1[] = {"Large ", "Fierce ", "Small "}; + +static char *inhabitant_desc2[] = {"Green ", "Red ", "Yellow ", "Blue ", "Black ", "Harmless "}; + +static char *inhabitant_desc3[] = {"Slimy ", "Bug-Eyed ", "Horned ", "Bony ", "Fat ", "Furry "}; + +static char *inhabitant_desc4[] = {"Rodent", "Frog", "Lizard", "Lobster", "Bird", "Humanoid", "Feline", "Insect"}; + + +static char planet_description[300]; +static char *desc_ptr; + + + + +static char *desc_list[36][5] = +{ +/* 0 */ {"fabled", "notable", "well known", "famous", "noted"}, +/* 1 */ {"very", "mildly", "most", "reasonably", ""}, +/* 2 */ {"ancient", "<20>", "great", "vast", "pink"}, +/* 3 */ {"<29> <28> plantations", "mountains", "<27>", "<19> forests", "oceans"}, +/* 4 */ {"shyness", "silliness", "mating traditions", "loathing of <5>", "love for <5>"}, +/* 5 */ {"food blenders", "tourists", "poetry", "discos", "<13>"}, +/* 6 */ {"talking tree", "crab", "bat", "lobst", "%R"}, +/* 7 */ {"beset", "plagued", "ravaged", "cursed", "scourged"}, +/* 8 */ {"<21> civil war", "<26> <23> <24>s", "a <26> disease", "<21> earthquakes", "<21> solar activity"}, +/* 9 */ {"its <2> <3>", "the %I <23> <24>","its inhabitants' <25> <4>", "<32>", "its <12> <13>"}, +/* 10 */ {"juice", "brandy", "water", "brew", "gargle blasters"}, +/* 11 */ {"%R", "%I <24>", "%I %R", "%I <26>", "<26> %R"}, +/* 12 */ {"fabulous", "exotic", "hoopy", "unusual", "exciting"}, +/* 13 */ {"cuisine", "night life", "casinos", "sit coms", " <32> "}, +/* 14 */ {"%H", "The planet %H", "The world %H", "This planet", "This world"}, +/* 15 */ {"n unremarkable", " boring", " dull", " tedious", " revolting"}, +/* 16 */ {"planet", "world", "place", "little planet", "dump"}, +/* 17 */ {"wasp", "moth", "grub", "ant", "%R"}, +/* 18 */ {"poet", "arts graduate", "yak", "snail", "slug"}, +/* 19 */ {"tropical", "dense", "rain", "impenetrable", "exuberant"}, +/* 20 */ {"funny", "wierd", "unusual", "strange", "peculiar"}, +/* 21 */ {"frequent", "occasional", "unpredictable", "dreadful", "deadly"}, +/* 22 */ {"<1> <0> for <9>", "<1> <0> for <9> and <9>", "<7> by <8>", "<1> <0> for <9> but <7> by <8>"," a<15> <16>"}, +/* 23 */ {"<26>", "mountain", "edible", "tree", "spotted"}, +/* 24 */ {"<30>", "<31>", "<6>oid", "<18>", "<17>"}, +/* 25 */ {"ancient", "exceptional", "eccentric", "ingrained", "<20>"}, +/* 26 */ {"killer", "deadly", "evil", "lethal", "vicious"}, +/* 27 */ {"parking meters", "dust clouds", "ice bergs", "rock formations", "volcanoes"}, +/* 28 */ {"plant", "tulip", "banana", "corn", "%Rweed"}, +/* 29 */ {"%R", "%I %R", "%I <26>", "inhabitant", "%I %R"}, +/* 30 */ {"shrew", "beast", "bison", "snake", "wolf"}, +/* 31 */ {"leopard", "cat", "monkey", "goat", "fish"}, +/* 32 */ {"<11> <10>", "%I <30> <33>","its <12> <31> <33>", "<34> <35>", "<11> <10>"}, +/* 33 */ {"meat", "cutlet", "steak", "burgers", "soup"}, +/* 34 */ {"ice", "mud", "Zero-G", "vacuum", "%I ultra"}, +/* 35 */ {"hockey", "cricket", "karate", "polo", "tennis"} +}; + + + + + + + + +/* + * Generate a random number between 0 and 255. + * This is the version used in the 6502 Elites. + */ + +int gen_rnd_number (void) +{ + int a,x; + + x = (rnd_seed.a * 2) & 0xFF; + a = x + rnd_seed.c; + if (rnd_seed.a > 127) + a++; + rnd_seed.a = a & 0xFF; + rnd_seed.c = x; + + a = a / 256; /* a = any carry left from above */ + x = rnd_seed.b; + a = (a + x + rnd_seed.d) & 0xFF; + rnd_seed.b = a; + rnd_seed.d = x; + return a; +} + + +/* + * Generate a random number between 0 and 255. + * This is the version used in the MSX and 16bit Elites. + */ + + +int gen_msx_rnd_number (void) +{ + int a,b; + + a = rnd_seed.a; + b = rnd_seed.b; + + rnd_seed.a = rnd_seed.c; + rnd_seed.b = rnd_seed.d; + + a += rnd_seed.c; + b = (b + rnd_seed.d) & 255; + if (a > 255) + { + a &= 255; + b++; + } + + rnd_seed.c = a; + rnd_seed.d = b; + + return rnd_seed.c / 0x34; +} + + +void waggle_galaxy (struct galaxy_seed *glx_ptr) +{ + unsigned int x; + unsigned int y; + extern int carry_flag; + + x = glx_ptr->a + glx_ptr->c; + y = glx_ptr->b + glx_ptr->d; + + + if (x > 0xFF) + y++; + + x &= 0xFF; + y &= 0xFF; + + glx_ptr->a = glx_ptr->c; + glx_ptr->b = glx_ptr->d; + glx_ptr->c = glx_ptr->e; + glx_ptr->d = glx_ptr->f; + + x += glx_ptr->c; + y += glx_ptr->d; + + + if (x > 0xFF) + y++; + + if (y > 0xFF) + carry_flag = 1; + else + carry_flag = 0; + + x &= 0xFF; + y &= 0xFF; + + glx_ptr->e = x; + glx_ptr->f = y; +} + + + + +struct galaxy_seed find_planet (int cx, int cy) +{ + int min_dist = 10000; + struct galaxy_seed glx; + struct galaxy_seed planet; + int distance; + int dx, dy; + int i; + + glx = cmdr.galaxy; + + for (i = 0; i < 256; i++) + { + + dx = abs(cx - glx.d); + dy = abs(cy - glx.b); + + if (dx > dy) + distance = (dx + dx + dy) / 2; + else + distance = (dx + dy + dy) / 2; + + if (distance < min_dist) + { + min_dist = distance; + planet = glx; + } + + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + } + + return planet; +} + + +int find_planet_number (struct galaxy_seed planet) +{ + struct galaxy_seed glx; + int i; + + glx = cmdr.galaxy; + + for (i = 0; i < 256; i++) + { + + if ((planet.a == glx.a) && + (planet.b == glx.b) && + (planet.c == glx.c) && + (planet.d == glx.d) && + (planet.e == glx.e) && + (planet.f == glx.f)) + return i; + + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + waggle_galaxy (&glx); + } + + return -1; +} + + + +void name_planet (char *gname, struct galaxy_seed glx) +{ + int size; + int i; + char *gp; + unsigned int x; + + + gp = gname; + + if ((glx.a & 0x40) == 0) + size = 3; + else + size = 4; + + for (i = 0; i < size; i++) + { + x = glx.f & 0x1F; + if (x != 0) + { + x += 12; + x *= 2; + *gp++ = digrams[x]; + if (digrams[x+1] != '?') + *gp++ = digrams[x+1]; + } + + waggle_galaxy (&glx); + } + + *gp = '\0'; +} + + +void capitalise_name (char *name) +{ + char *ptr = name; + + if (*ptr == '\0') + return; + + *ptr = toupper(*ptr); + ptr++; + + while (*ptr != '\0') + { + *ptr = tolower(*ptr); + ptr++; + } +} + + +void describe_inhabitants (char *str, struct galaxy_seed planet) +{ + int inhab; + + strcpy (str, "("); + + if (planet.e < 128) + { + strcat (str, "Human Colonial"); + } + else + { + inhab = (planet.f / 4) & 7; + if (inhab < 3) + strcat (str, inhabitant_desc1[inhab]); + + inhab = planet.f / 32; + if (inhab < 6) + strcat (str, inhabitant_desc2[inhab]); + + inhab = (planet.d ^ planet.b) & 7; + if (inhab < 6) + strcat (str, inhabitant_desc3[inhab]); + + inhab = (inhab + (planet.f & 3)) & 7; + strcat (str, inhabitant_desc4[inhab]); + } + + strcat (str, "s)"); +} + + + +void expand_description (char *source) +{ + char str[32]; + char *ptr; + int num; + int rnd; + int option; + int i, len, x; + + while (*source != '\0') + { + if (*source == '<') + { + source++; + ptr = str; + while (*source != '>') + *ptr++ = *source++; + *ptr = '\0'; + source++; + num = atoi(str); + + if (hoopy_casinos) + { + option = gen_msx_rnd_number(); + } + else + { + rnd = gen_rnd_number(); + option = 0; + if (rnd >= 0x33) option++; + if (rnd >= 0x66) option++; + if (rnd >= 0x99) option++; + if (rnd >= 0xCC) option++; + } + + expand_description (desc_list[num][option]); + continue; + } + + if (*source == '%') + { + source++; + switch (*source) + { + case 'H': + name_planet (str, hyperspace_planet); + capitalise_name (str); + for (ptr = str; *ptr != '\0';) + *desc_ptr++ = *ptr++; + break; + + case 'I': + name_planet (str, hyperspace_planet); + capitalise_name (str); + for (ptr = str; *ptr != '\0';) + *desc_ptr++ = *ptr++; + desc_ptr--; + strcpy (desc_ptr, "ian"); + desc_ptr += 3; + break; + + case 'R': + len = gen_rnd_number() & 3; + for (i = 0; i <= len; i++) + { + x = gen_rnd_number() & 0x3e; + if (i == 0) + *desc_ptr++ = digrams[x]; + else + *desc_ptr++ = tolower(digrams[x]); + *desc_ptr++ = tolower(digrams[x+1]); + } + + } + + source++; + continue; + } + + *desc_ptr++ = *source++; + } + + + + *desc_ptr = '\0'; +} + + + +char *describe_planet (struct galaxy_seed planet) +{ + char *mission_text; + + if (cmdr.mission == 1) + { + mission_text = mission_planet_desc (planet); + if (mission_text != NULL) + return mission_text; + } + + rnd_seed.a = planet.c; + rnd_seed.b = planet.d; + rnd_seed.c = planet.e; + rnd_seed.d = planet.f; + + if (hoopy_casinos) + { + rnd_seed.a ^= planet.a; + rnd_seed.b ^= planet.b; + rnd_seed.c ^= rnd_seed.a; + rnd_seed.d ^= rnd_seed.b; + } + + desc_ptr = planet_description; + + expand_description ("<14> is <22>."); + + return planet_description; +} + + + +void generate_planet_data (struct planet_data *pl, struct galaxy_seed planet_seed) +{ + + pl->government = (planet_seed.c / 8) & 7; + + pl->economy = planet_seed.b & 7; + + if (pl->government < 2) + pl->economy = pl->economy | 2; + + pl->techlevel = pl->economy ^ 7; + pl->techlevel += planet_seed.d & 3; + pl->techlevel += (pl->government / 2) + (pl->government & 1); + + + pl->population = pl->techlevel * 4; + pl->population += pl->government; + pl->population += pl->economy; + pl->population++; + + pl->productivity = (pl->economy ^ 7) + 3; + pl->productivity *= pl->government + 4; + pl->productivity *= pl->population; + pl->productivity *= 8; + + pl->radius = (((planet_seed.f & 15) + 11) * 256) + planet_seed.d; +} + + + diff --git a/planet.h b/planet.h new file mode 100644 index 0000000..f112fa0 --- /dev/null +++ b/planet.h @@ -0,0 +1,55 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +#ifndef PLANET_H +#define PLANET_H + + +struct galaxy_seed +{ + unsigned char a; /* 6c */ + unsigned char b; /* 6d */ + unsigned char c; /* 6e */ + unsigned char d; /* 6f */ + unsigned char e; /* 70 */ + unsigned char f; /* 71 */ +}; + + +struct planet_data +{ + int government; + int economy; + int techlevel; + int population; + int productivity; + int radius; +}; + + + + + +char *describe_planet (struct galaxy_seed); +void capitalise_name (char *name); +void name_planet (char *gname, struct galaxy_seed glx); +struct galaxy_seed find_planet (int cx, int cy); +int find_planet_number (struct galaxy_seed planet); +void waggle_galaxy (struct galaxy_seed *glx_ptr); +void describe_inhabitants (char *str, struct galaxy_seed planet); +void generate_planet_data (struct planet_data *pl, struct galaxy_seed planet_seed); +void set_current_planet (struct galaxy_seed new_planet); + +#endif + diff --git a/pulse.wav b/pulse.wav new file mode 100644 index 0000000..c9c9e8b Binary files /dev/null and b/pulse.wav differ diff --git a/random.c b/random.c new file mode 100644 index 0000000..cdd3945 --- /dev/null +++ b/random.c @@ -0,0 +1,64 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * random.c + */ + + +#include +#include "allegro.h" + +#include "random.h" + +static int rand_seed; + +/* + * Portable random number generator implementing the recursion: + * IX = 16807 * IX MOD (2**(31) - 1) + * Using only 32 bits, including sign. + * + * Taken from "A Guide to Simulation" by Bratley, Fox and Schrage. + */ + +int randint (void) +{ + int k1; + int ix = rand_seed; + + k1 = ix / 127773; + ix = 16807 * (ix - k1 * 127773) - k1 * 2836; + if (ix < 0) + ix += 2147483647; + rand_seed = ix; + + return ix; +} + + +void set_rand_seed (int seed) +{ + rand_seed = seed; +} + + +int get_rand_seed (void) +{ + return rand_seed; +} + +int rand255 (void) +{ + return (randint() & 255); +} diff --git a/random.h b/random.h new file mode 100644 index 0000000..0a07139 --- /dev/null +++ b/random.h @@ -0,0 +1,28 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * random.h + */ + +#ifndef RANDOM_H +#define RANDOM_H + +int randint (void); +void set_rand_seed (int seed); +int get_rand_seed (void); +int rand255 (void); + +#endif + diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..0a21095 --- /dev/null +++ b/readme.txt @@ -0,0 +1,300 @@ +Elite - The New Kind Release 1.0 +-------------------- ----------- + +Revision date: 22 July 2001 + +This is release 1.0 of Elite - The New Kind. +For changes since previous releases see below. + +newkindb.zip contains a compiled version of the code designed to run under MS Windows 95/98/NT using the Allegro graphics library and DirectX. + +newkind.zip contains source code for Elite - The New Kind. +If you want to recompile the game then please note the following... +a. The .wav and .dat files are not included in the source distribution to keep the size down, they can be found in newkindb.zip. +b. You need the WIP version of Allegro to compile the code. + +The latest versions of the source and executable can always be found on the New Kind website... +http://www.newkind.co.uk + +To run the supplied executable you will need DirectX installed. Windows 98/ME/2000 and NT 4 (with latest service pack) come with this. +If you are using Windows 95 and you haven't already installed DirectX you will need to do so. +The DirectX runtime can be downloaded from the Microsoft website. (www.microsoft.com/directx). + +Two pieces of music are included in Elite - The New Kind. The Elite Theme and The Blue Danube. +The Elite Theme was composed by Aidan Bell and the Blue Danube was composed by Strauss. +I spent a long time hunting for the best MIDI versions of these pieces I could find. +To appreciate them properly you will need a decent Soft Synth Midi driver installed and set as you prefered Midi and Sound device. + +Keys you can use... +Press Y or N on the intro screen. +Press Space on the ship parade screen. + +F1 - Launch when docked, Front View when in flight. +F2 - Rear View +F3 - Left View +F4 - Right View when in flight. + When docked, Buy Equipment for ship. + Use up and down arrow keys to select item, return/enter key to buy. +F5 - Display Galactic Chart. +F6 - Short Range Chart. +F7 - Show information on selected planet. +F8 - Buy and sell items on the stock market. + Use up and down arrow keys to select item, right arrow key to buy, left arrow key to sell. +F9 - Commander information. +F10 - Inventory. +F11 - Options screen (Save Game, Load Game, Game Settings, Quit). + Use up and down arrows keys to select option, return/enter to select. + + A - Fire. + S - Dive. + X - Climb. + < - Roll Left + > - Roll Right + / - Slow Down +Space - Speed up. + + C - Activate docking computer, if fitted. + D - De-activate docking computer if switched on. + E - Active ECM, if fitted. + H - Hyperspace. + J - Warp Jump. + M - Fire missile. + T - Target a missile. + U - Un-target missile. +TAB - Detonate energy bomb, if fitted. +CTRL+H - Galactic Hyperspace, if fitted. +ESC - Launch escape capsule, if fitted. + P - Pause game. + R - Resume game when paused. + +On The Chart Screens +-------------------- +D - Select a planet and show distance to it. +F - Find planet by name. +O - Return cursor to current planet. +Cursor Keys - Move cross hairs around. + + +On The Game Settings Screen +--------------------------- +From the Options Screen (F11) you can enter the Game Settings Screen. From here you can change +a number of settings that control how the game looks and plays. Use the cursor keys to select an option +and the Enter/Return key to change it. The options can be saved as default for future games by pressing Enter +while on the Save Settings option (NB this is not necessary if you want to change the settings just for +the current game). Game settings are held in the newkind.cfg file which should be in the same directory +as the newkind.exe file. + + + +Release 1.0 - Changes since Beta 3.0 +==================================== + +- Rocks, alloys and boulders no longer stop you from engaging the jump drive. + +- Stopped tactics routine from being called while on the intro screens. + +- Ramming ships was causing little damage to player's ship. Now fixed. + +- Switching views while in space now switches stars around. + +- Moved all Allegro specific graphic functions into alg_gfx.c + +- Moved keyboard handling routines into keyboard.c + +- Moved file handling routines out of alg_main.c into file.c + +- Added screen to allow player to set the game options from within the game. + This means the player no longer has to hack newkind.cfg directly. + +- Tidied graphics routines and removed all references to HDC. + +- Fixed movement of crosshairs on chart screens so that they are clipped properly. + +- Added explosion, cargo cannisters and alloys to the game over screen. + +- Added escape capsule sequence. + +- Added option for instant dock vs. auto-pilot docking. + +- Fixed bug that allowed an enemy craft to launch multiple escape capsules. + +- Fixed asteroids so that they move slower and don't try to evade attack. + +- Added rock hermits. + +- Tweaked the tactics routine again. + +- Added limited joystick support (digital only at the moment). + +- Added beep sound when missile target is locked. + +- Added low pitch beep sound when missile is unarmed. + +- Added Energy Low message when enegry levels reach critical. + + + +Beta 3.0 - Changes since Beta 2.1 +================================= + +- Fixed bug that allowed lasers to fire too rapidly. + +- The console was not being updated (i.e no of missiles) after a saved commander was loaded. Now fixed. + +- Added planet auto-select on chart screens ala NES. + +- Asteroid mining implemented. + +- Exploding ships now release alloys. + +- Fixed bug that caused enemy ships to only fire when at close range. + +- Thargoids can now appear. + +- Witchspace ambush added. + +- Anacondas now release worms and sidewinders when attacked. + +- Attacked ships can now release escape capsules. + +- Objects other than cargo cannisters can now be scooped. + +- Corrected condition indicator code. Was previously showing yellow even after danger had passed. + +- Added ability to pause game (P key pauses, R resumes). + +- The Cougar (a cloaked ship) can now appear. + +- The second mission is now playable. + +- Fixed bug that allowed enemy ships to fire from bizare angles. + +- Rewrote tactics routines. New code now based on NES Elite. + +- Docking computers now use full auto-pilot rather than just instant dock. + +- Space station now launches shuttles and transporters bound for the planet. + + + +Beta 2.1 - Changes since Beta 2.0 +================================= + +- Added code to set legal status to clean and fuel to maximum after using an escape capsule. + +- Fixed enemy missile targeting so that other ships don't blow themselves up. + +- Fixed speed of enemy ships which were moving too slowly in previous versions. + +- Added game speed control option to newkind.cfg. + + +Beta 2.0 - Changes since Beta 1.1 +================================= + +- Fixed bug in enemy tactics which caused ships to run away. + +- Set the max speed of player's ship to 0.30LM. + +- Added code to display version number on options screen. + +- Corrected spelling of "Feudal". + +- Enabled docking computers (instant dock for the moment). + +- Added hyperspace sound. + +- Changed code to display number of credits instead of bounty. + +- Set hyperspace count down to 15. + +- Added Suns, cabin temperature and fuel scooping. + +- Added left and right views when in flight. + +- Enabled use of Energy Bomb, activated with TAB key. + +- Changed scanner slightly, added code to display objects in different colours. + +- Fixed warping of stars in rear view. + +- Enabled Escape Capsule, use ESC key to abandon ship. + +- Enabled Galactic Hyperspace. + +- Added use of 'O' key on chart screens. + +- Added ability to find planets by name. + +- Added Windows icon created by Marcus Buchanan. + +- Added code by Thomas Harte to anti-alias lines and improve hidden surface removal. + +- Added option to newkind.cfg to enable anti-alias code. + +- Added the first secret mission, hunt the Constrictor! + +- Fixed equipment buying so that refund is given on existing lasers. + +- Changed colour of fuel limit circle from white to green. + +- Put some colour on the Local Chart screen. + +- Changed look of ship lollipops on the scanner to look more like the original. + +- Changed incoming laser sounds, one for hitting shields and one for hitting the hull. + +- Fixed asteroids so that they travel in straight lines. + +- Changed creation of ships so that the appear at more random locations. + +- Removed the Constrictor and the Cougar from the ship parade intro. + + + +Beta 1.1 - Changes since Beta 1.0 +================================= + +- Fixed bug in load and save routine which caused the player to aways return to Lave. + +- Fixed bug in equipment buying screen. Buying military lasers for the side or rear view + would cause mining lasers to be fitted instead. + +- Renamed files to be all lowercase. This should ease ports to other OSes. + +- Removed #include of windows only allegro files from alg_main.c + +- Added #ifdef around use of GFX_DIRECTX in alg_main.c to allow compilation on non Windows OSes. + + + +Work in progress +================ + +The following features have not yet been implemented but are being currently worked on. + +- C64 Elite style scoring. + +- Trumbles (from C64/NES Elite). + +- View of docking bay after docking. + +- Loading of different consoles not yet fully implemented. + +- Enhance joystick support, i.e. use of more buttons and analogue control. + + +Known Problems +============== + +- Bits of hidden surfaces on ships sometimes show through. + +- Buying more than 255gs of Gold/Platinum doesn't work. + It didn't in the original Elite either. Broken as designed. + + +Have fun! + +Christian Pinder. + +http://www.newkind.co.uk diff --git a/scanner.bmp b/scanner.bmp new file mode 100644 index 0000000..17428eb Binary files /dev/null and b/scanner.bmp differ diff --git a/shipdata.c b/shipdata.c new file mode 100644 index 0000000..b88e29a --- /dev/null +++ b/shipdata.c @@ -0,0 +1,2671 @@ +#include "shipdata.h" + + + +struct ship_point missile_point[17] = +{ + { 0, 0, 68, 31, 1, 0, 3, 2}, + { 8, -8, 36, 31, 2, 1, 5, 4}, + { 8, 8, 36, 31, 3, 2, 7, 4}, + { -8, 8, 36, 31, 3, 0, 7, 6}, + { -8, -8, 36, 31, 1, 0, 6, 5}, + { 8, 8, -44, 31, 7, 4, 8, 8}, + { 8, -8, -44, 31, 5, 4, 8, 8}, + { -8, -8, -44, 31, 6, 5, 8, 8}, + { -8, 8, -44, 31, 7, 6, 8, 8}, + { 12, 12, -44, 8, 7, 4, 8, 8}, + { 12, -12, -44, 8, 5, 4, 8, 8}, + { -12, -12, -44, 8, 6, 5, 8, 8}, + { -12, 12, -44, 8, 7, 6, 8, 8}, + { -8, 8, -12, 8, 7, 6, 7, 7}, + { -8, -8, -12, 8, 6, 5, 6, 6}, + { 8, 8, -12, 8, 7, 4, 7, 7}, + { 8, -8, -12, 8, 5, 4, 5, 5}, +}; + +struct ship_line missile_line[24] = +{ + {31, 2, 1, 0, 1}, + {31, 3, 2, 0, 2}, + {31, 3, 0, 0, 3}, + {31, 1, 0, 0, 4}, + {31, 2, 4, 1, 2}, + {31, 5, 1, 1, 4}, + {31, 6, 0, 3, 4}, + {31, 7, 3, 2, 3}, + {31, 7, 4, 2, 5}, + {31, 5, 4, 1, 6}, + {31, 6, 5, 4, 7}, + {31, 7, 6, 3, 8}, + {31, 8, 6, 7, 8}, + {31, 8, 7, 5, 8}, + {31, 8, 4, 5, 6}, + {31, 8, 5, 6, 7}, + { 8, 8, 5, 6, 10}, + { 8, 8, 7, 5, 9}, + { 8, 8, 7, 8, 12}, + { 8, 8, 5, 7, 11}, + { 8, 7, 4, 9, 15}, + { 8, 5, 4, 10, 16}, + { 8, 7, 6, 12, 13}, + { 8, 6, 5, 11, 14}, +}; + +struct ship_face_normal missile_face_normal[9] = +{ + {31, -64, 0, 16}, + {31, 0, -64, 16}, + {31, 64, 0, 16}, + {31, 0, 64, 16}, + {31, 32, 0, 0}, + {31, 0, -32, 0}, + {31, -32, 0, 0}, + {31, 0, 32, 0}, + {31, 0, 0, -176}, +}; + +struct ship_data missile_data = +{ + "Missile", + 17, 24, 9, + 0, + 0, + 1600, + 0, + 0, + 14, + 2, + 44, + 0, + 0, + missile_point, + missile_line, + missile_face_normal +}; + + + +struct ship_point coriolis_point[16] = +{ + { 160, 0, 160, 31, 1, 0, 6, 2}, + { 0, 160, 160, 31, 2, 0, 8, 3}, + {-160, 0, 160, 31, 3, 0, 7, 4}, + { 0, -160, 160, 31, 1, 0, 5, 4}, + { 160, -160, 0, 31, 5, 1, 10, 6}, + { 160, 160, 0, 31, 6, 2, 11, 8}, + {-160, 160, 0, 31, 7, 3, 12, 8}, + {-160, -160, 0, 31, 5, 4, 9, 7}, + { 160, 0, -160, 31, 10, 6, 13, 11}, + { 0, 160, -160, 31, 11, 8, 13, 12}, + {-160, 0, -160, 31, 9, 7, 13, 12}, + { 0, -160, -160, 31, 9, 5, 13, 10}, + { 10, -30, 160, 30, 0, 0, 0, 0}, + { 10, 30, 160, 30, 0, 0, 0, 0}, + { -10, 30, 160, 30, 0, 0, 0, 0}, + { -10, -30, 160, 30, 0, 0, 0, 0}, +}; + +struct ship_line coriolis_line[28] = +{ + {31, 1, 0, 0, 3}, + {31, 2, 0, 0, 1}, + {31, 3, 0, 1, 2}, + {31, 4, 0, 2, 3}, + {31, 5, 1, 3, 4}, + {31, 6, 1, 0, 4}, + {31, 6, 2, 0, 5}, + {31, 8, 2, 5, 1}, + {31, 8, 3, 1, 6}, + {31, 7, 3, 2, 6}, + {31, 7, 4, 2, 7}, + {31, 5, 4, 3, 7}, + {31, 13, 10, 8, 11}, + {31, 13, 11, 8, 9}, + {31, 13, 12, 9, 10}, + {31, 13, 9, 10, 11}, + {31, 10, 5, 4, 11}, + {31, 10, 6, 4, 8}, + {31, 11, 6, 5, 8}, + {31, 11, 8, 5, 9}, + {31, 12, 8, 6, 9}, + {31, 12, 7, 6, 10}, + {31, 9, 7, 7, 10}, + {31, 9, 5, 7, 11}, + {30, 0, 0, 12, 13}, + {30, 0, 0, 13, 14}, + {30, 0, 0, 14, 15}, + {30, 0, 0, 15, 12}, +}; + +struct ship_face_normal coriolis_face_normal[14] = +{ + {31, 0, 0, 160}, + {31, 107, -107, 107}, + {31, 107, 107, 107}, + {31, -107, 107, 107}, + {31, -107, -107, 107}, + {31, 0, -160, 0}, + {31, 160, 0, 0}, + {31, -160, 0, 0}, + {31, 0, 160, 0}, + {31, -107, -107, -107}, + {31, 107, -107, -107}, + {31, 107, 107, -107}, + {31, -107, 107, -107}, + {31, 0, 0, -160}, +}; + +struct ship_data coriolis_data = +{ + "Coriolis Space Station", + 16, 28, 14, + 0, + 0, + 25600, + 0, + 0, + 120, + 240, + 0, + 6, + 3, + coriolis_point, + coriolis_line, + coriolis_face_normal +}; + + + +struct ship_point esccaps_point[4] = +{ + { -7, 0, 36, 31, 1, 2, 3, 3}, + { -7, -14, -12, 31, 0, 2, 3, 3}, + { -7, 14, -12, 31, 0, 1, 3, 3}, + { 21, 0, 0, 31, 0, 1, 2, 2}, +}; + +struct ship_line esccaps_line[6] = +{ + {31, 2, 3, 0, 1}, + {31, 0, 3, 1, 2}, + {31, 0, 1, 2, 3}, + {31, 1, 2, 3, 0}, + {31, 1, 3, 0, 2}, + {31, 0, 2, 3, 1}, +}; + +struct ship_face_normal esccaps_face_normal[4] = +{ + {31, 52, 0, -122}, + {31, 39, 103, 30}, + {31, 39, -103, 30}, + {31, -112, 0, 0}, +}; + +struct ship_data esccaps_data = +{ + "Escape Capsule", + 4, 6, 4, + 0, + 2, + 256, + 0, + 0, + 8, + 17, + 8, + 0, + 0, + esccaps_point, + esccaps_line, + esccaps_face_normal +}; + + + +struct ship_point alloy_point[4] = +{ + { -15, -22, -9, 31, 15, 15, 15, 15}, + { -15, 38, -9, 31, 15, 15, 15, 15}, + { 19, 32, 11, 20, 15, 15, 15, 15}, + { 10, -46, 6, 20, 15, 15, 15, 15}, +}; + +struct ship_line alloy_line[4] = +{ + {31, 15, 15, 0, 1}, + {16, 15, 15, 1, 2}, + {20, 15, 15, 2, 3}, + {16, 15, 15, 3, 0}, +}; + +struct ship_face_normal alloy_face_normal[1] = +{ + { 0, 0, 0, 0}, +}; + +struct ship_data alloy_data = +{ + "Alloy", + 4, 4, 1, + 0, + 8, + 100, + 0, + 0, + 5, + 16, + 16, + 0, + 0, + alloy_point, + alloy_line, + alloy_face_normal +}; + + + +struct ship_point cargo_point[10] = +{ + { 24, 16, 0, 31, 1, 0, 5, 5}, + { 24, 5, 15, 31, 1, 0, 2, 2}, + { 24, -13, 9, 31, 2, 0, 3, 3}, + { 24, -13, -9, 31, 3, 0, 4, 4}, + { 24, 5, -15, 31, 4, 0, 5, 5}, + { -24, 16, 0, 31, 5, 1, 6, 6}, + { -24, 5, 15, 31, 2, 1, 6, 6}, + { -24, -13, 9, 31, 3, 2, 6, 6}, + { -24, -13, -9, 31, 4, 3, 6, 6}, + { -24, 5, -15, 31, 5, 4, 6, 6}, +}; + +struct ship_line cargo_line[15] = +{ + {31, 1, 0, 0, 1}, + {31, 2, 0, 1, 2}, + {31, 3, 0, 2, 3}, + {31, 4, 0, 3, 4}, + {31, 5, 0, 0, 4}, + {31, 5, 1, 0, 5}, + {31, 2, 1, 1, 6}, + {31, 3, 2, 2, 7}, + {31, 4, 3, 3, 8}, + {31, 5, 4, 4, 9}, + {31, 6, 1, 5, 6}, + {31, 6, 2, 6, 7}, + {31, 6, 3, 7, 8}, + {31, 6, 4, 8, 9}, + {31, 6, 5, 9, 5}, +}; + +struct ship_face_normal cargo_face_normal[7] = +{ + {31, 96, 0, 0}, + {31, 0, 41, 30}, + {31, 0, -18, 48}, + {31, 0, -51, 0}, + {31, 0, -18, -48}, + {31, 0, 41, -30}, + {31, -96, 0, 0}, +}; + +struct ship_data cargo_data = +{ + "Cargo Canister", + 10, 15, 7, + 0, + 0, + 400, + 0, + 0, + 12, + 17, + 15, + 0, + 0, + cargo_point, + cargo_line, + cargo_face_normal +}; + + + +struct ship_point boulder_point[7] = +{ + { -18, 37, -11, 31, 0, 1, 5, 9}, + { 30, 7, 12, 31, 1, 2, 5, 6}, + { 28, -7, -12, 31, 2, 3, 6, 7}, + { 2, 0, -39, 31, 3, 4, 7, 8}, + { -28, 34, -30, 31, 0, 4, 8, 9}, + { 5, -10, 13, 31, 15, 15, 15, 15}, + { 20, 17, -30, 31, 15, 15, 15, 15}, +}; + +struct ship_line boulder_line[15] = +{ + {31, 1, 5, 0, 1}, + {31, 2, 6, 1, 2}, + {31, 3, 7, 2, 3}, + {31, 4, 8, 3, 4}, + {31, 0, 9, 4, 0}, + {31, 0, 1, 0, 5}, + {31, 1, 2, 1, 5}, + {31, 2, 3, 2, 5}, + {31, 3, 4, 3, 5}, + {31, 0, 4, 4, 5}, + {31, 5, 9, 0, 6}, + {31, 5, 6, 1, 6}, + {31, 6, 7, 2, 6}, + {31, 7, 8, 3, 6}, + {31, 8, 9, 4, 6}, +}; + +struct ship_face_normal boulder_face_normal[10] = +{ + {31, -15, -3, 8}, + {31, -7, 12, 30}, + {31, 32, -47, 24}, + {31, -3, -39, -7}, + {31, -5, -4, -1}, + {31, 49, 84, 8}, + {31, 112, 21, -21}, + {31, 76, -35, -82}, + {31, 22, 56, -137}, + {31, 40, 110, -38}, +}; + +struct ship_data boulder_data = +{ + "Boulder", + 7, 15, 10, + 0, + 0, + 900, + 0, + 1, + 20, + 20, + 30, + 0, + 0, + boulder_point, + boulder_line, + boulder_face_normal +}; + + + +struct ship_point asteroid_point[9] = +{ + { 0, 80, 0, 31, 15, 15, 15, 15}, + { -80, -10, 0, 31, 15, 15, 15, 15}, + { 0, -80, 0, 31, 15, 15, 15, 15}, + { 70, -40, 0, 31, 15, 15, 15, 15}, + { 60, 50, 0, 31, 6, 5, 13, 12}, + { 50, 0, 60, 31, 15, 15, 15, 15}, + { -40, 0, 70, 31, 1, 0, 3, 2}, + { 0, 30, -75, 31, 15, 15, 15, 15}, + { 0, -50, -60, 31, 9, 8, 11, 10}, +}; + +struct ship_line asteroid_line[21] = +{ + {31, 7, 2, 0, 1}, + {31, 13, 6, 0, 4}, + {31, 12, 5, 3, 4}, + {31, 11, 4, 2, 3}, + {31, 10, 3, 1, 2}, + {31, 3, 2, 1, 6}, + {31, 3, 1, 2, 6}, + {31, 4, 1, 2, 5}, + {31, 1, 0, 5, 6}, + {31, 6, 0, 0, 5}, + {31, 5, 4, 3, 5}, + {31, 2, 0, 0, 6}, + {31, 6, 5, 4, 5}, + {31, 10, 8, 1, 8}, + {31, 8, 7, 1, 7}, + {31, 13, 7, 0, 7}, + {31, 13, 12, 4, 7}, + {31, 12, 9, 3, 7}, + {31, 11, 9, 3, 8}, + {31, 11, 10, 2, 8}, + {31, 9, 8, 7, 8}, +}; + +struct ship_face_normal asteroid_face_normal[14] = +{ + {31, 9, 66, 81}, + {31, 9, -66, 81}, + {31, -72, 64, 31}, + {31, -64, -73, 47}, + {31, 45, -79, 65}, + {31, 135, 15, 35}, + {31, 38, 76, 70}, + {31, -66, 59, -39}, + {31, -67, -15, -80}, + {31, 66, -14, -75}, + {31, -70, -80, -40}, + {31, 58, -102, -51}, + {31, 81, 9, -67}, + {31, 47, 94, -63}, +}; + +struct ship_data asteroid_data = +{ + "Asteroid", + 9, 21, 14, + 0, + 0, + 6400, + 0, + 5, + 50, + 60, + 30, + 0, + 0, + asteroid_point, + asteroid_line, + asteroid_face_normal +}; + + + +struct ship_point rock_point[4] = +{ + { -24, -25, 16, 31, 1, 2, 3, 3}, + { 0, 12, -10, 31, 0, 2, 3, 3}, + { 11, -6, 2, 31, 0, 1, 3, 3}, + { 12, 42, 7, 31, 0, 1, 2, 2}, +}; + +struct ship_line rock_line[6] = +{ + {31, 2, 3, 0, 1}, + {31, 0, 3, 1, 2}, + {31, 0, 1, 2, 3}, + {31, 1, 2, 3, 0}, + {31, 1, 3, 0, 2}, + {31, 0, 2, 3, 1}, +}; + +struct ship_face_normal rock_face_normal[4] = +{ + {18, 30, 0, 0}, + {20, 22, 32, -8}, + { 0, 0, 2, 0}, + { 0, 17, 23, 95}, +}; + +struct ship_data rock_data = +{ + "Rock", + 4, 6, 4, + 0, + 11, + 256, + 0, + 0, + 8, + 20, + 10, + 0, + 0, + rock_point, + rock_line, + rock_face_normal +}; + + + +struct ship_point orbit_point[19] = +{ + { 0, -17, 23, 31, 15, 15, 15, 15}, + { -17, 0, 23, 31, 15, 15, 15, 15}, + { 0, 18, 23, 31, 15, 15, 15, 15}, + { 18, 0, 23, 31, 15, 15, 15, 15}, + { -20, -20, -27, 31, 1, 2, 3, 9}, + { -20, 20, -27, 31, 3, 4, 5, 9}, + { 20, 20, -27, 31, 5, 6, 7, 9}, + { 20, -20, -27, 31, 1, 7, 8, 9}, + { 5, 0, -27, 16, 9, 9, 9, 9}, + { 0, -2, -27, 16, 9, 9, 9, 9}, + { -5, 0, -27, 9, 9, 9, 9, 9}, + { 0, 3, -27, 9, 9, 9, 9, 9}, + { 0, -9, 35, 16, 0, 10, 11, 12}, + { 3, -1, 31, 7, 15, 15, 0, 2}, + { 4, 11, 25, 8, 0, 1, 15, 4}, + { 11, 4, 25, 8, 10, 1, 3, 15}, + { -3, -1, 31, 7, 6, 11, 2, 3}, + { -3, 11, 25, 8, 15, 8, 12, 0}, + { -10, 4, 25, 8, 4, 15, 1, 8}, +}; + +struct ship_line orbit_line[30] = +{ + {31, 0, 2, 0, 1}, + {31, 4, 10, 1, 2}, + {31, 6, 11, 2, 3}, + {31, 8, 12, 0, 3}, + {31, 1, 8, 0, 7}, + {24, 1, 2, 0, 4}, + {31, 2, 3, 1, 4}, + {24, 3, 4, 1, 5}, + {31, 4, 5, 2, 5}, + {12, 5, 6, 2, 6}, + {31, 6, 7, 3, 6}, + {24, 7, 8, 3, 7}, + {31, 3, 9, 4, 5}, + {31, 5, 9, 5, 6}, + {31, 7, 9, 6, 7}, + {31, 1, 9, 4, 7}, + {16, 0, 12, 0, 12}, + {16, 0, 10, 1, 12}, + {16, 10, 11, 2, 12}, + {16, 11, 12, 3, 12}, + {16, 9, 9, 8, 9}, + { 7, 9, 9, 9, 10}, + { 9, 9, 9, 10, 11}, + { 7, 9, 9, 8, 11}, + { 5, 11, 11, 13, 14}, + { 8, 11, 11, 14, 15}, + { 7, 11, 11, 13, 15}, + { 5, 10, 10, 16, 17}, + { 8, 10, 10, 17, 18}, + { 7, 10, 10, 16, 18}, +}; + +struct ship_face_normal orbit_face_normal[13] = +{ + {31, -55, -55, 40}, + {31, 0, -74, 4}, + {31, -51, -51, 23}, + {31, -74, 0, 4}, + {31, -51, 51, 23}, + {31, 0, 74, 4}, + {31, 51, 51, 23}, + {31, 74, 0, 4}, + {31, 51, -51, 23}, + {31, 0, 0, -107}, + {31, -41, 41, 90}, + {31, 41, 41, 90}, + {31, 55, -55, 40}, +}; + +struct ship_data orbit_data = +{ + "Orbit Shuttle", + 19, 30, 13, + 15, + 0, + 2500, + 0, + 0, + 22, + 32, + 8, + 0, + 0, + orbit_point, + orbit_line, + orbit_face_normal +}; + + + +struct ship_point transp_point[37] = +{ + { 0, 10, -26, 31, 0, 6, 7, 7}, + { -25, 4, -26, 31, 0, 1, 7, 7}, + { -28, -3, -26, 31, 0, 1, 2, 2}, + { -25, -8, -26, 31, 0, 2, 3, 3}, + { 26, -8, -26, 31, 0, 3, 4, 4}, + { 29, -3, -26, 31, 0, 4, 5, 5}, + { 26, 4, -26, 31, 0, 5, 6, 6}, + { 0, 6, 12, 19, 15, 15, 15, 15}, + { -30, -1, 12, 31, 1, 7, 8, 9}, + { -33, -8, 12, 31, 1, 2, 3, 9}, + { 33, -8, 12, 31, 3, 4, 5, 10}, + { 30, -1, 12, 31, 5, 6, 10, 11}, + { -11, -2, 30, 31, 8, 9, 12, 13}, + { -13, -8, 30, 31, 3, 9, 13, 13}, + { 14, -8, 30, 31, 3, 10, 13, 13}, + { 11, -2, 30, 31, 10, 11, 12, 13}, + { -5, 6, 2, 7, 7, 7, 7, 7}, + { -18, 3, 2, 7, 7, 7, 7, 7}, + { -5, 7, -7, 7, 7, 7, 7, 7}, + { -18, 4, -7, 7, 7, 7, 7, 7}, + { -11, 6, -14, 7, 7, 7, 7, 7}, + { -11, 5, -7, 7, 7, 7, 7, 7}, + { 5, 7, -14, 7, 6, 6, 6, 6}, + { 18, 4, -14, 7, 6, 6, 6, 6}, + { 11, 5, -7, 7, 6, 6, 6, 6}, + { 5, 6, -3, 7, 6, 6, 6, 6}, + { 18, 3, -3, 7, 6, 6, 6, 6}, + { 11, 4, 8, 7, 6, 6, 6, 6}, + { 11, 5, -3, 7, 6, 6, 6, 6}, + { -16, -8, -13, 6, 3, 3, 3, 3}, + { -16, -8, 16, 6, 3, 3, 3, 3}, + { 17, -8, -13, 6, 3, 3, 3, 3}, + { 17, -8, 16, 6, 3, 3, 3, 3}, + { -13, -3, -26, 8, 0, 0, 0, 0}, + { 13, -3, -26, 8, 0, 0, 0, 0}, + { 9, 3, -26, 5, 0, 0, 0, 0}, + { -8, 3, -26, 5, 0, 0, 0, 0}, +}; + +struct ship_line transp_line[46] = +{ + {31, 0, 7, 0, 1}, + {31, 0, 1, 1, 2}, + {31, 0, 2, 2, 3}, + {31, 0, 3, 3, 4}, + {31, 0, 4, 4, 5}, + {31, 0, 5, 5, 6}, + {31, 0, 6, 0, 6}, + {16, 6, 7, 0, 7}, + {31, 1, 7, 1, 8}, + {11, 1, 2, 2, 9}, + {31, 2, 3, 3, 9}, + {31, 3, 4, 4, 10}, + {11, 4, 5, 5, 10}, + {31, 5, 6, 6, 11}, + {17, 7, 8, 7, 8}, + {17, 1, 9, 8, 9}, + {17, 5, 10, 10, 11}, + {17, 6, 11, 7, 11}, + {19, 11, 12, 7, 15}, + {19, 8, 12, 7, 12}, + {16, 8, 9, 8, 12}, + {31, 3, 9, 9, 13}, + {31, 3, 10, 10, 14}, + {16, 10, 11, 11, 15}, + {31, 9, 13, 12, 13}, + {31, 3, 13, 13, 14}, + {31, 10, 13, 14, 15}, + {31, 12, 13, 12, 15}, + { 7, 7, 7, 16, 17}, + { 7, 7, 7, 18, 19}, + { 7, 7, 7, 19, 20}, + { 7, 7, 7, 18, 20}, + { 7, 7, 7, 20, 21}, + { 7, 6, 6, 22, 23}, + { 7, 6, 6, 23, 24}, + { 7, 6, 6, 24, 22}, + { 7, 6, 6, 25, 26}, + { 7, 6, 6, 26, 27}, + { 7, 6, 6, 25, 27}, + { 7, 6, 6, 27, 28}, + { 6, 3, 3, 29, 30}, + { 6, 3, 3, 31, 32}, + { 8, 0, 0, 33, 34}, + { 5, 0, 0, 34, 35}, + { 5, 0, 0, 35, 36}, + { 5, 0, 0, 36, 33}, +}; + +struct ship_face_normal transp_face_normal[14] = +{ + {31, 0, 0, -103}, + {31, -111, 48, -7}, + {31, -105, -63, -21}, + {31, 0, -34, 0}, + {31, 105, -63, -21}, + {31, 111, 48, -7}, + {31, 8, 32, 3}, + {31, -8, 32, 3}, + {19, -8, 34, 11}, + {31, -75, 32, 79}, + {31, 75, 32, 79}, + {19, 8, 34, 11}, + {31, 0, 38, 17}, + {31, 0, 0, 121}, +}; + +struct ship_data transp_data = +{ + "Transporter", + 37, 46, 14, + 0, + 0, + 2500, + 12, + 0, + 16, + 32, + 10, + 0, + 0, + transp_point, + transp_line, + transp_face_normal +}; + + + +struct ship_point cobra3a_point[28] = +{ + { 32, 0, 76, 31, 15, 15, 15, 15}, + { -32, 0, 76, 31, 15, 15, 15, 15}, + { 0, 26, 24, 31, 15, 15, 15, 15}, + {-120, -3, -8, 31, 7, 3, 10, 10}, + { 120, -3, -8, 31, 8, 4, 12, 12}, + { -88, 16, -40, 31, 15, 15, 15, 15}, + { 88, 16, -40, 31, 15, 15, 15, 15}, + { 128, -8, -40, 31, 9, 8, 12, 12}, + {-128, -8, -40, 31, 9, 7, 10, 10}, + { 0, 26, -40, 31, 6, 5, 9, 9}, + { -32, -24, -40, 31, 10, 9, 11, 11}, + { 32, -24, -40, 31, 11, 9, 12, 12}, + { -36, 8, -40, 20, 9, 9, 9, 9}, + { -8, 12, -40, 20, 9, 9, 9, 9}, + { 8, 12, -40, 20, 9, 9, 9, 9}, + { 36, 8, -40, 20, 9, 9, 9, 9}, + { 36, -12, -40, 20, 9, 9, 9, 9}, + { 8, -16, -40, 20, 9, 9, 9, 9}, + { -8, -16, -40, 20, 9, 9, 9, 9}, + { -36, -12, -40, 20, 9, 9, 9, 9}, + { 0, 0, 76, 6, 11, 0, 11, 11}, + { 0, 0, 90, 31, 11, 0, 11, 11}, + { -80, -6, -40, 8, 9, 9, 9, 9}, + { -80, 6, -40, 8, 9, 9, 9, 9}, + { -88, 0, -40, 6, 9, 9, 9, 9}, + { 80, 6, -40, 8, 9, 9, 9, 9}, + { 88, 0, -40, 6, 9, 9, 9, 9}, + { 80, -6, -40, 8, 9, 9, 9, 9}, +}; + +struct ship_line cobra3a_line[38] = +{ + {31, 11, 0, 0, 1}, + {31, 12, 4, 0, 4}, + {31, 10, 3, 1, 3}, + {31, 10, 7, 3, 8}, + {31, 12, 8, 4, 7}, + {31, 9, 8, 6, 7}, + {31, 9, 6, 6, 9}, + {31, 9, 5, 5, 9}, + {31, 9, 7, 5, 8}, + {31, 5, 1, 2, 5}, + {31, 6, 2, 2, 6}, + {31, 7, 3, 3, 5}, + {31, 8, 4, 4, 6}, + {31, 1, 0, 1, 2}, + {31, 2, 0, 0, 2}, + {31, 10, 9, 8, 10}, + {31, 11, 9, 10, 11}, + {31, 12, 9, 7, 11}, + {31, 11, 10, 1, 10}, + {31, 12, 11, 0, 11}, + {29, 3, 1, 1, 5}, + {29, 4, 2, 0, 6}, + { 6, 11, 0, 20, 21}, + {20, 9, 9, 12, 13}, + {20, 9, 9, 18, 19}, + {20, 9, 9, 14, 15}, + {20, 9, 9, 16, 17}, + {19, 9, 9, 15, 16}, + {17, 9, 9, 14, 17}, + {19, 9, 9, 13, 18}, + {19, 9, 9, 12, 19}, + {30, 6, 5, 2, 9}, + { 6, 9, 9, 22, 24}, + { 6, 9, 9, 23, 24}, + { 8, 9, 9, 22, 23}, + { 6, 9, 9, 25, 26}, + { 6, 9, 9, 26, 27}, + { 8, 9, 9, 25, 27}, +}; + +struct ship_face_normal cobra3a_face_normal[13] = +{ + {31, 0, 62, 31}, + {31, -18, 55, 16}, + {31, 18, 55, 16}, + {31, -16, 52, 14}, + {31, 16, 52, 14}, + {31, -14, 47, 0}, + {31, 14, 47, 0}, + {31, -61, 102, 0}, + {31, 61, 102, 0}, + {31, 0, 0, -80}, + {31, -7, -42, 9}, + {31, 0, -30, 6}, + {31, 7, -42, 9}, +}; + +struct ship_data cobra3a_data = +{ + "Cobra MkIII", + 28, 38, 13, + 3, + 0, + 9025, + 21, + 0, + 50, + 150, + 28, + 3, + 9, + cobra3a_point, + cobra3a_line, + cobra3a_face_normal +}; + + + +struct ship_point pythona_point[11] = +{ + { 0, 0, 224, 31, 1, 0, 3, 2}, + { 0, 48, 48, 31, 1, 0, 5, 4}, + { 96, 0, -16, 31, 15, 15, 15, 15}, + { -96, 0, -16, 31, 15, 15, 15, 15}, + { 0, 48, -32, 31, 5, 4, 9, 8}, + { 0, 24, -112, 31, 8, 9, 12, 12}, + { -48, 0, -112, 31, 11, 8, 12, 12}, + { 48, 0, -112, 31, 10, 9, 12, 12}, + { 0, -48, 48, 31, 3, 2, 7, 6}, + { 0, -48, -32, 31, 7, 6, 11, 10}, + { 0, -24, -112, 31, 11, 10, 12, 12}, +}; + +struct ship_line pythona_line[26] = +{ + {31, 3, 2, 0, 8}, + {31, 2, 0, 0, 3}, + {31, 3, 1, 0, 2}, + {31, 1, 0, 0, 1}, + {31, 5, 9, 2, 4}, + {31, 5, 1, 1, 2}, + {31, 3, 7, 2, 8}, + {31, 4, 0, 1, 3}, + {31, 6, 2, 3, 8}, + {31, 10, 7, 2, 9}, + {31, 8, 4, 3, 4}, + {31, 11, 6, 3, 9}, + { 7, 8, 8, 3, 5}, + { 7, 11, 11, 3, 10}, + { 7, 9, 9, 2, 5}, + { 7, 10, 10, 2, 10}, + {31, 10, 9, 2, 7}, + {31, 11, 8, 3, 6}, + {31, 12, 8, 5, 6}, + {31, 12, 9, 5, 7}, + {31, 10, 12, 7, 10}, + {31, 12, 11, 6, 10}, + {31, 9, 8, 4, 5}, + {31, 11, 10, 9, 10}, + {31, 5, 4, 1, 4}, + {31, 7, 6, 8, 9}, +}; + +struct ship_face_normal pythona_face_normal[13] = +{ + {31, -27, 40, 11}, + {31, 27, 40, 11}, + {31, -27, -40, 11}, + {31, 27, -40, 11}, + {31, -19, 38, 0}, + {31, 19, 38, 0}, + {31, -19, -38, 0}, + {31, 19, -38, 0}, + {31, -25, 37, -11}, + {31, 25, 37, -11}, + {31, 25, -37, -11}, + {31, -25, -37, -11}, + {31, 0, 0, -112}, +}; + +struct ship_data pythona_data = +{ + "Python", + 11, 26, 13, + 5, + 0, + 6400, + 0, + 0, + 40, + 250, + 20, + 3, + 13, + pythona_point, + pythona_line, + pythona_face_normal +}; + + + +struct ship_point boa_point[13] = +{ + { 0, 0, 93, 31, 15, 15, 15, 15}, + { 0, 40, -87, 24, 0, 2, 3, 3}, + { 38, -25, -99, 24, 0, 1, 4, 4}, + { -38, -25, -99, 24, 1, 2, 5, 5}, + { -38, 40, -59, 31, 2, 3, 6, 9}, + { 38, 40, -59, 31, 0, 3, 6, 11}, + { 62, 0, -67, 31, 0, 4, 8, 11}, + { 24, -65, -79, 31, 1, 4, 8, 10}, + { -24, -65, -79, 31, 1, 5, 7, 10}, + { -62, 0, -67, 31, 2, 5, 7, 9}, + { 0, 7, -107, 22, 0, 2, 10, 10}, + { 13, -9, -107, 22, 0, 1, 10, 10}, + { -13, -9, -107, 22, 1, 2, 12, 12}, +}; + +struct ship_line boa_line[24] = +{ + {31, 6, 11, 0, 5}, + {31, 8, 10, 0, 7}, + {31, 7, 9, 0, 9}, + {29, 6, 9, 0, 4}, + {29, 8, 11, 0, 6}, + {29, 7, 10, 0, 8}, + {31, 3, 6, 4, 5}, + {31, 0, 11, 5, 6}, + {31, 4, 8, 6, 7}, + {31, 1, 10, 7, 8}, + {31, 5, 7, 8, 9}, + {31, 2, 9, 4, 9}, + {24, 2, 3, 1, 4}, + {24, 0, 3, 1, 5}, + {24, 2, 5, 3, 9}, + {24, 1, 5, 3, 8}, + {24, 0, 4, 2, 6}, + {24, 1, 4, 2, 7}, + {22, 0, 2, 1, 10}, + {22, 0, 1, 2, 11}, + {22, 1, 2, 3, 12}, + {14, 0, 12, 10, 11}, + {14, 1, 12, 11, 12}, + {14, 2, 12, 12, 10}, +}; + +struct ship_face_normal boa_face_normal[13] = +{ + {31, 43, 37, -60}, + {31, 0, -45, -89}, + {31, -43, 37, -60}, + {31, 0, 40, 0}, + {31, 62, -32, -20}, + {31, -62, -32, -20}, + {31, 0, 23, 6}, + {31, -23, -15, 9}, + {31, 23, -15, 9}, + {31, -26, 13, 10}, + {31, 0, -31, 12}, + {31, 26, 13, 10}, + {14, 0, 0, -107}, +}; + +struct ship_data boa_data = +{ + "Boa", + 13, 24, 13, + 5, + 0, + 4900, + 0, + 0, + 40, + 250, + 24, + 4, + 14, + boa_point, + boa_line, + boa_face_normal +}; + + + +struct ship_point anacnda_point[15] = +{ + { 0, 7, -58, 30, 0, 1, 5, 5}, + { -43, -13, -37, 30, 0, 1, 2, 2}, + { -26, -47, -3, 30, 0, 2, 3, 3}, + { 26, -47, -3, 30, 0, 3, 4, 4}, + { 43, -13, -37, 30, 0, 4, 5, 5}, + { 0, 48, -49, 30, 1, 5, 6, 6}, + { -69, 15, -15, 30, 1, 2, 7, 7}, + { -43, -39, 40, 31, 2, 3, 8, 8}, + { 43, -39, 40, 31, 3, 4, 9, 9}, + { 69, 15, -15, 30, 4, 5, 10, 10}, + { -43, 53, -23, 31, 15, 15, 15, 15}, + { -69, -1, 32, 31, 2, 7, 8, 8}, + { 0, 0, 254, 31, 15, 15, 15, 15}, + { 69, -1, 32, 31, 4, 9, 10, 10}, + { 43, 53, -23, 31, 15, 15, 15, 15}, +}; + +struct ship_line anacnda_line[25] = +{ + {30, 0, 1, 0, 1}, + {30, 0, 2, 1, 2}, + {30, 0, 3, 2, 3}, + {30, 0, 4, 3, 4}, + {30, 0, 5, 0, 4}, + {29, 1, 5, 0, 5}, + {29, 1, 2, 1, 6}, + {29, 2, 3, 2, 7}, + {29, 3, 4, 3, 8}, + {29, 4, 5, 4, 9}, + {30, 1, 6, 5, 10}, + {30, 1, 7, 6, 10}, + {30, 2, 7, 6, 11}, + {30, 2, 8, 7, 11}, + {31, 3, 8, 7, 12}, + {31, 3, 9, 8, 12}, + {30, 4, 9, 8, 13}, + {30, 4, 10, 9, 13}, + {30, 5, 10, 9, 14}, + {30, 5, 6, 5, 14}, + {30, 6, 11, 10, 14}, + {31, 7, 11, 10, 12}, + {31, 7, 8, 11, 12}, + {31, 9, 10, 12, 13}, + {31, 10, 11, 12, 14}, +}; + +struct ship_face_normal anacnda_face_normal[12] = +{ + {30, 0, -51, -49}, + {30, -51, 18, -87}, + {30, -77, -57, -19}, + {31, 0, -90, 16}, + {30, 77, -57, -19}, + {30, 51, 18, -87}, + {30, 0, 111, -20}, + {31, -97, 72, 24}, + {31, -108, -68, 34}, + {31, 108, -68, 34}, + {31, 97, 72, 24}, + {31, 0, 94, 18}, +}; + +struct ship_data anacnda_data = +{ + "Anaconda", + 15, 25, 12, + 7, + 0, + 10000, + 12, + 0, + 36, + 252, + 14, + 7, + 31, + anacnda_point, + anacnda_line, + anacnda_face_normal +}; + + + +struct ship_point hermit_point[9] = +{ + { 0, 80, 0, 31, 15, 15, 15, 15}, + { -80, -10, 0, 31, 15, 15, 15, 15}, + { 0, -80, 0, 31, 15, 15, 15, 15}, + { 70, -40, 0, 31, 15, 15, 15, 15}, + { 60, 50, 0, 31, 6, 5, 13, 12}, + { 50, 0, 60, 31, 15, 15, 15, 15}, + { -40, 0, 70, 31, 1, 0, 3, 2}, + { 0, 30, -75, 31, 15, 15, 15, 15}, + { 0, -50, -60, 31, 9, 8, 11, 10}, +}; + +struct ship_line hermit_line[21] = +{ + {31, 7, 2, 0, 1}, + {31, 13, 6, 0, 4}, + {31, 12, 5, 3, 4}, + {31, 11, 4, 2, 3}, + {31, 10, 3, 1, 2}, + {31, 3, 2, 1, 6}, + {31, 3, 1, 2, 6}, + {31, 4, 1, 2, 5}, + {31, 1, 0, 5, 6}, + {31, 6, 0, 0, 5}, + {31, 5, 4, 3, 5}, + {31, 2, 0, 0, 6}, + {31, 6, 5, 4, 5}, + {31, 10, 8, 1, 8}, + {31, 8, 7, 1, 7}, + {31, 13, 7, 0, 7}, + {31, 13, 12, 4, 7}, + {31, 12, 9, 3, 7}, + {31, 11, 9, 3, 8}, + {31, 11, 10, 2, 8}, + {31, 9, 8, 7, 8}, +}; + +struct ship_face_normal hermit_face_normal[14] = +{ + {31, 9, 66, 81}, + {31, 9, -66, 81}, + {31, -72, 64, 31}, + {31, -64, -73, 47}, + {31, 45, -79, 65}, + {31, 135, 15, 35}, + {31, 38, 76, 70}, + {31, -66, 59, -39}, + {31, -67, -15, -80}, + {31, 66, -14, -75}, + {31, -70, -80, -40}, + {31, 58, -102, -51}, + {31, 81, 9, -67}, + {31, 47, 94, -63}, +}; + +struct ship_data hermit_data = +{ + "Rock Hermit", + 9, 21, 14, + 7, + 0, + 6400, + 0, + 0, + 50, + 180, + 30, + 2, + 1, + hermit_point, + hermit_line, + hermit_face_normal +}; + + + +struct ship_point viper_point[15] = +{ + { 0, 0, 72, 31, 2, 1, 4, 3}, + { 0, 16, 24, 30, 1, 0, 2, 2}, + { 0, -16, 24, 30, 4, 3, 5, 5}, + { 48, 0, -24, 31, 4, 2, 6, 6}, + { -48, 0, -24, 31, 3, 1, 6, 6}, + { 24, -16, -24, 30, 5, 4, 6, 6}, + { -24, -16, -24, 30, 3, 5, 6, 6}, + { 24, 16, -24, 31, 2, 0, 6, 6}, + { -24, 16, -24, 31, 1, 0, 6, 6}, + { -32, 0, -24, 19, 6, 6, 6, 6}, + { 32, 0, -24, 19, 6, 6, 6, 6}, + { 8, 8, -24, 19, 6, 6, 6, 6}, + { -8, 8, -24, 19, 6, 6, 6, 6}, + { -8, -8, -24, 18, 6, 6, 6, 6}, + { 8, -8, -24, 18, 6, 6, 6, 6}, +}; + +struct ship_line viper_line[20] = +{ + {31, 4, 2, 0, 3}, + {30, 2, 1, 0, 1}, + {30, 4, 3, 0, 2}, + {31, 3, 1, 0, 4}, + {30, 2, 0, 1, 7}, + {30, 1, 0, 1, 8}, + {30, 5, 4, 2, 5}, + {30, 5, 3, 2, 6}, + {31, 6, 0, 7, 8}, + {30, 6, 5, 5, 6}, + {31, 6, 1, 4, 8}, + {30, 6, 3, 4, 6}, + {31, 6, 2, 3, 7}, + {30, 4, 6, 3, 5}, + {19, 6, 6, 9, 12}, + {18, 6, 6, 9, 13}, + {19, 6, 6, 10, 11}, + {18, 6, 6, 10, 14}, + {16, 6, 6, 11, 14}, + {16, 6, 6, 12, 13}, +}; + +struct ship_face_normal viper_face_normal[7] = +{ + {31, 0, 32, 0}, + {31, -22, 33, 11}, + {31, 22, 33, 11}, + {31, -22, -33, 11}, + {31, 22, -33, 11}, + {31, 0, -32, 0}, + {31, 0, 0, -48}, +}; + +struct ship_data viper_data = +{ + "Viper", + 15, 20, 7, + 0, + 0, + 5625, + 0, + 0, + 23, + 140, + 32, + 1, + 8, + viper_point, + viper_line, + viper_face_normal +}; + + + +struct ship_point sidewnd_point[10] = +{ + { -32, 0, 36, 31, 1, 0, 5, 4}, + { 32, 0, 36, 31, 2, 0, 6, 5}, + { 64, 0, -28, 31, 3, 2, 6, 6}, + { -64, 0, -28, 31, 3, 1, 4, 4}, + { 0, 16, -28, 31, 1, 0, 3, 2}, + { 0, -16, -28, 31, 4, 3, 6, 5}, + { -12, 6, -28, 15, 3, 3, 3, 3}, + { 12, 6, -28, 15, 3, 3, 3, 3}, + { 12, -6, -28, 12, 3, 3, 3, 3}, + { -12, -6, -28, 12, 3, 3, 3, 3}, +}; + +struct ship_line sidewnd_line[15] = +{ + {31, 5, 0, 0, 1}, + {31, 6, 2, 1, 2}, + {31, 2, 0, 1, 4}, + {31, 1, 0, 0, 4}, + {31, 4, 1, 0, 3}, + {31, 3, 1, 3, 4}, + {31, 3, 2, 2, 4}, + {31, 4, 3, 3, 5}, + {31, 6, 3, 2, 5}, + {31, 6, 5, 1, 5}, + {31, 5, 4, 0, 5}, + {15, 3, 3, 6, 7}, + {12, 3, 3, 7, 8}, + {12, 3, 3, 6, 9}, + {12, 3, 3, 8, 9}, +}; + +struct ship_face_normal sidewnd_face_normal[7] = +{ + {31, 0, 32, 8}, + {31, -12, 47, 6}, + {31, 12, 47, 6}, + {31, 0, 0, -112}, + {31, -12, -47, 6}, + {31, 0, -32, 8}, + {31, 12, -47, 6}, +}; + +struct ship_data sidewnd_data = +{ + "Sidewinder", + 10, 15, 7, + 0, + 0, + 4225, + 0, + 50, + 20, + 70, + 37, + 0, + 8, + sidewnd_point, + sidewnd_line, + sidewnd_face_normal +}; + + + +struct ship_point mamba_point[25] = +{ + { 0, 0, 64, 31, 1, 0, 3, 2}, + { -64, -8, -32, 31, 2, 0, 4, 4}, + { -32, 8, -32, 30, 2, 1, 4, 4}, + { 32, 8, -32, 30, 3, 1, 4, 4}, + { 64, -8, -32, 31, 3, 0, 4, 4}, + { -4, 4, 16, 14, 1, 1, 1, 1}, + { 4, 4, 16, 14, 1, 1, 1, 1}, + { 8, 3, 28, 13, 1, 1, 1, 1}, + { -8, 3, 28, 13, 1, 1, 1, 1}, + { -20, -4, 16, 20, 0, 0, 0, 0}, + { 20, -4, 16, 20, 0, 0, 0, 0}, + { -24, -7, -20, 20, 0, 0, 0, 0}, + { -16, -7, -20, 16, 0, 0, 0, 0}, + { 16, -7, -20, 16, 0, 0, 0, 0}, + { 24, -7, -20, 20, 0, 0, 0, 0}, + { -8, 4, -32, 13, 4, 4, 4, 4}, + { 8, 4, -32, 13, 4, 4, 4, 4}, + { 8, -4, -32, 14, 4, 4, 4, 4}, + { -8, -4, -32, 14, 4, 4, 4, 4}, + { -32, 4, -32, 7, 4, 4, 4, 4}, + { 32, 4, -32, 7, 4, 4, 4, 4}, + { 36, -4, -32, 7, 4, 4, 4, 4}, + { -36, -4, -32, 7, 4, 4, 4, 4}, + { -38, 0, -32, 5, 4, 4, 4, 4}, + { 38, 0, -32, 5, 4, 4, 4, 4}, +}; + +struct ship_line mamba_line[28] = +{ + {31, 2, 0, 0, 1}, + {31, 3, 0, 0, 4}, + {31, 4, 0, 1, 4}, + {30, 4, 2, 1, 2}, + {30, 4, 1, 2, 3}, + {30, 4, 3, 3, 4}, + {14, 1, 1, 5, 6}, + {12, 1, 1, 6, 7}, + {13, 1, 1, 7, 8}, + {12, 1, 1, 5, 8}, + {20, 0, 0, 9, 11}, + {16, 0, 0, 9, 12}, + {16, 0, 0, 10, 13}, + {20, 0, 0, 10, 14}, + {14, 0, 0, 13, 14}, + {14, 0, 0, 11, 12}, + {13, 4, 4, 15, 16}, + {14, 4, 4, 17, 18}, + {12, 4, 4, 15, 18}, + {12, 4, 4, 16, 17}, + { 7, 4, 4, 20, 21}, + { 5, 4, 4, 20, 24}, + { 5, 4, 4, 21, 24}, + { 7, 4, 4, 19, 22}, + { 5, 4, 4, 19, 23}, + { 5, 4, 4, 22, 23}, + {30, 2, 1, 0, 2}, + {30, 3, 1, 0, 3}, +}; + +struct ship_face_normal mamba_face_normal[5] = +{ + {30, 0, -24, 2}, + {30, 0, 24, 2}, + {30, -32, 64, 16}, + {30, 32, 64, 16}, + {30, 0, 0, -127}, +}; + +struct ship_data mamba_data = +{ + "Mamba", + 25, 28, 5, + 1, + 0, + 4900, + 0, + 150, + 25, + 90, + 30, + 2, + 9, + mamba_point, + mamba_line, + mamba_face_normal +}; + + + +struct ship_point krait_point[17] = +{ + { 0, 0, 96, 31, 0, 1, 2, 3}, + { 0, 18, -48, 31, 0, 3, 4, 5}, + { 0, -18, -48, 31, 1, 2, 4, 5}, + { 90, 0, -3, 31, 0, 1, 4, 4}, + { -90, 0, -3, 31, 2, 3, 5, 5}, + { 90, 0, 87, 30, 0, 1, 1, 1}, + { -90, 0, 87, 30, 2, 3, 3, 3}, + { 0, 5, 53, 9, 0, 0, 3, 3}, + { 0, 7, 38, 6, 0, 0, 3, 3}, + { -18, 7, 19, 9, 3, 3, 3, 3}, + { 18, 7, 19, 9, 0, 0, 0, 0}, + { 18, 11, -39, 8, 4, 4, 4, 4}, + { 18, -11, -39, 8, 4, 4, 4, 4}, + { 36, 0, -30, 8, 4, 4, 4, 4}, + { -18, 11, -39, 8, 5, 5, 5, 5}, + { -18, -11, -39, 8, 5, 5, 5, 5}, + { -36, 0, -30, 8, 5, 5, 5, 5}, +}; + +struct ship_line krait_line[21] = +{ + {31, 0, 3, 0, 1}, + {31, 1, 2, 0, 2}, + {31, 0, 1, 0, 3}, + {31, 2, 3, 0, 4}, + {31, 3, 5, 1, 4}, + {31, 2, 5, 4, 2}, + {31, 1, 4, 2, 3}, + {31, 0, 4, 3, 1}, + {30, 0, 1, 3, 5}, + {30, 2, 3, 4, 6}, + { 8, 4, 5, 1, 2}, + { 9, 0, 0, 7, 10}, + { 6, 0, 0, 8, 10}, + { 9, 3, 3, 7, 9}, + { 6, 3, 3, 8, 9}, + { 8, 4, 4, 11, 13}, + { 8, 4, 4, 13, 12}, + { 7, 4, 4, 12, 11}, + { 7, 5, 5, 14, 15}, + { 8, 5, 5, 15, 16}, + { 8, 5, 5, 16, 14}, +}; + +struct ship_face_normal krait_face_normal[6] = +{ + {31, 3, 24, 3}, + {31, 3, -24, 3}, + {31, -3, -24, 3}, + {31, -3, 24, 3}, + {31, 38, 0, -77}, + {31, -38, 0, -77}, +}; + +struct ship_data krait_data = +{ + "Krait", + 17, 21, 6, + 1, + 0, + 3600, + 0, + 100, + 20, + 80, + 30, + 0, + 8, + krait_point, + krait_line, + krait_face_normal +}; + + + +struct ship_point adder_point[18] = +{ + { -18, 0, 40, 31, 0, 1, 11, 12}, + { 18, 0, 40, 31, 0, 1, 2, 3}, + { 30, 0, -24, 31, 2, 3, 4, 5}, + { 30, 0, -40, 31, 4, 5, 6, 6}, + { 18, -7, -40, 31, 5, 6, 7, 14}, + { -18, -7, -40, 31, 7, 8, 10, 14}, + { -30, 0, -40, 31, 8, 9, 10, 10}, + { -30, 0, -24, 31, 9, 10, 11, 12}, + { -18, 7, -40, 31, 7, 8, 9, 13}, + { 18, 7, -40, 31, 4, 6, 7, 13}, + { -18, 7, 13, 31, 0, 9, 11, 13}, + { 18, 7, 13, 31, 0, 2, 4, 13}, + { -18, -7, 13, 31, 1, 10, 12, 14}, + { 18, -7, 13, 31, 1, 3, 5, 14}, + { -11, 3, 29, 5, 0, 0, 0, 0}, + { 11, 3, 29, 5, 0, 0, 0, 0}, + { 11, 4, 24, 4, 0, 0, 0, 0}, + { -11, 4, 24, 4, 0, 0, 0, 0}, +}; + +struct ship_line adder_line[29] = +{ + {31, 0, 1, 0, 1}, + { 7, 2, 3, 1, 2}, + {31, 4, 5, 2, 3}, + {31, 5, 6, 3, 4}, + {31, 7, 14, 4, 5}, + {31, 8, 10, 5, 6}, + {31, 9, 10, 6, 7}, + { 7, 11, 12, 7, 0}, + {31, 4, 6, 3, 9}, + {31, 7, 13, 9, 8}, + {31, 8, 9, 8, 6}, + {31, 0, 11, 0, 10}, + {31, 9, 11, 7, 10}, + {31, 0, 2, 1, 11}, + {31, 2, 4, 2, 11}, + {31, 1, 12, 0, 12}, + {31, 10, 12, 7, 12}, + {31, 1, 3, 1, 13}, + {31, 3, 5, 2, 13}, + {31, 0, 13, 10, 11}, + {31, 1, 14, 12, 13}, + {31, 9, 13, 8, 10}, + {31, 4, 13, 9, 11}, + {31, 10, 14, 5, 12}, + {31, 5, 14, 4, 13}, + { 5, 0, 0, 14, 15}, + { 3, 0, 0, 15, 16}, + { 4, 0, 0, 16, 17}, + { 3, 0, 0, 17, 14}, +}; + +struct ship_face_normal adder_face_normal[15] = +{ + {31, 0, 39, 10}, + {31, 0, -39, 10}, + {31, 69, 50, 13}, + {31, 69, -50, 13}, + {31, 30, 52, 0}, + {31, 30, -52, 0}, + {31, 0, 0, -160}, + {31, 0, 0, -160}, + {31, 0, 0, -160}, + {31, -30, 52, 0}, + {31, -30, -52, 0}, + {31, -69, 50, 13}, + {31, -69, -50, 13}, + {31, 0, 28, 0}, + {31, 0, -28, 0}, +}; + +struct ship_data adder_data = +{ + "Adder", + 18, 29, 15, + 0, + 0, + 2500, + 0, + 40, + 20, + 85, + 24, + 0, + 8, + adder_point, + adder_line, + adder_face_normal +}; + + + +struct ship_point gecko_point[12] = +{ + { -10, -4, 47, 31, 0, 3, 4, 5}, + { 10, -4, 47, 31, 0, 1, 2, 3}, + { -16, 8, -23, 31, 0, 5, 6, 7}, + { 16, 8, -23, 31, 0, 1, 7, 8}, + { -66, 0, -3, 31, 4, 5, 6, 6}, + { 66, 0, -3, 31, 1, 2, 8, 8}, + { -20, -14, -23, 31, 3, 4, 6, 7}, + { 20, -14, -23, 31, 2, 3, 7, 8}, + { -8, -6, 33, 16, 3, 3, 3, 3}, + { 8, -6, 33, 17, 3, 3, 3, 3}, + { -8, -13, -16, 16, 3, 3, 3, 3}, + { 8, -13, -16, 17, 3, 3, 3, 3}, +}; + +struct ship_line gecko_line[17] = +{ + {31, 0, 3, 0, 1}, + {31, 1, 2, 1, 5}, + {31, 1, 8, 5, 3}, + {31, 0, 7, 3, 2}, + {31, 5, 6, 2, 4}, + {31, 4, 5, 4, 0}, + {31, 2, 8, 5, 7}, + {31, 3, 7, 7, 6}, + {31, 4, 6, 6, 4}, + {29, 0, 5, 0, 2}, + {30, 0, 1, 1, 3}, + {29, 3, 4, 0, 6}, + {30, 2, 3, 1, 7}, + {20, 6, 7, 2, 6}, + {20, 7, 8, 3, 7}, + {16, 3, 3, 8, 10}, + {17, 3, 3, 9, 11}, +}; + +struct ship_face_normal gecko_face_normal[9] = +{ + {31, 0, 31, 5}, + {31, 4, 45, 8}, + {31, 25, -108, 19}, + {31, 0, -84, 12}, + {31, -25, -108, 19}, + {31, -4, 45, 8}, + {31, -88, 16, -214}, + {31, 0, 0, -187}, + {31, 88, 16, -214}, +}; + +struct ship_data gecko_data = +{ + "Gecko", + 12, 17, 9, + 0, + 0, + 9801, + 0, + 55, + 18, + 70, + 30, + 0, + 8, + gecko_point, + gecko_line, + gecko_face_normal +}; + + + +struct ship_point cobra1_point[11] = +{ + { -18, -1, 50, 31, 0, 1, 2, 3}, + { 18, -1, 50, 31, 0, 1, 4, 5}, + { -66, 0, 7, 31, 2, 3, 8, 8}, + { 66, 0, 7, 31, 4, 5, 9, 9}, + { -32, 12, -38, 31, 2, 6, 7, 8}, + { 32, 12, -38, 31, 4, 6, 7, 9}, + { -54, -12, -38, 31, 1, 3, 7, 8}, + { 54, -12, -38, 31, 1, 5, 7, 9}, + { 0, 12, -6, 20, 0, 2, 4, 6}, + { 0, -1, 50, 2, 0, 1, 1, 1}, + { 0, -1, 60, 31, 0, 1, 1, 1}, +}; + +struct ship_line cobra1_line[18] = +{ + {31, 0, 1, 1, 0}, + {31, 2, 3, 0, 2}, + {31, 3, 8, 2, 6}, + {31, 1, 7, 6, 7}, + {31, 5, 9, 7, 3}, + {31, 4, 5, 3, 1}, + {31, 2, 8, 2, 4}, + {31, 6, 7, 4, 5}, + {31, 4, 9, 5, 3}, + {20, 0, 2, 0, 8}, + {20, 0, 4, 8, 1}, + {16, 2, 6, 4, 8}, + {16, 4, 6, 8, 5}, + {31, 7, 8, 4, 6}, + {31, 7, 9, 5, 7}, + {20, 1, 3, 0, 6}, + {20, 1, 5, 1, 7}, + { 2, 0, 1, 10, 9}, +}; + +struct ship_face_normal cobra1_face_normal[10] = +{ + {31, 0, 41, 10}, + {31, 0, -27, 3}, + {31, -8, 46, 8}, + {31, -12, -57, 12}, + {31, 8, 46, 8}, + {31, 12, -57, 12}, + {31, 0, 49, 0}, + {31, 0, 0, -154}, + {31, -121, 111, -62}, + {31, 121, 111, -62}, +}; + +struct ship_data cobra1_data = +{ + "Cobra MkI", + 11, 18, 10, + 3, + 0, + 9801, + 10, + 75, + 19, + 90, + 26, + 2, + 9, + cobra1_point, + cobra1_line, + cobra1_face_normal +}; + + + +struct ship_point worm_point[10] = +{ + { 10, -10, 35, 31, 0, 2, 7, 7}, + { -10, -10, 35, 31, 0, 3, 7, 7}, + { 5, 6, 15, 31, 0, 1, 2, 4}, + { -5, 6, 15, 31, 0, 1, 3, 5}, + { 15, -10, 25, 31, 2, 4, 7, 7}, + { -15, -10, 25, 31, 3, 5, 7, 7}, + { 26, -10, -25, 31, 4, 6, 7, 7}, + { -26, -10, -25, 31, 5, 6, 7, 7}, + { 8, 14, -25, 31, 1, 4, 6, 6}, + { -8, 14, -25, 31, 1, 5, 6, 6}, +}; + +struct ship_line worm_line[16] = +{ + {31, 0, 7, 0, 1}, + {31, 3, 7, 1, 5}, + {31, 5, 7, 5, 7}, + {31, 6, 7, 7, 6}, + {31, 4, 7, 6, 4}, + {31, 2, 7, 4, 0}, + {31, 0, 2, 0, 2}, + {31, 0, 3, 1, 3}, + {31, 2, 4, 4, 2}, + {31, 3, 5, 5, 3}, + {31, 1, 4, 2, 8}, + {31, 4, 6, 8, 6}, + {31, 1, 5, 3, 9}, + {31, 5, 6, 9, 7}, + {31, 0, 1, 2, 3}, + {31, 1, 6, 8, 9}, +}; + +struct ship_face_normal worm_face_normal[8] = +{ + {31, 0, 88, 70}, + {31, 0, 69, 14}, + {31, 70, 66, 35}, + {31, -70, 66, 35}, + {31, 64, 49, 14}, + {31, -64, 49, 14}, + {31, 0, 0, -200}, + {31, 0, -80, 0}, +}; + +struct ship_data worm_data = +{ + "Worm", + 10, 16, 8, + 0, + 0, + 9801, + 0, + 0, + 19, + 30, + 23, + 0, + 4, + worm_point, + worm_line, + worm_face_normal +}; + + + +struct ship_point cobra3b_point[28] = +{ + { 32, 0, 76, 31, 15, 15, 15, 15}, + { -32, 0, 76, 31, 15, 15, 15, 15}, + { 0, 26, 24, 31, 15, 15, 15, 15}, + {-120, -3, -8, 31, 7, 3, 10, 10}, + { 120, -3, -8, 31, 8, 4, 12, 12}, + { -88, 16, -40, 31, 15, 15, 15, 15}, + { 88, 16, -40, 31, 15, 15, 15, 15}, + { 128, -8, -40, 31, 9, 8, 12, 12}, + {-128, -8, -40, 31, 9, 7, 10, 10}, + { 0, 26, -40, 31, 6, 5, 9, 9}, + { -32, -24, -40, 31, 10, 9, 11, 11}, + { 32, -24, -40, 31, 11, 9, 12, 12}, + { -36, 8, -40, 20, 9, 9, 9, 9}, + { -8, 12, -40, 20, 9, 9, 9, 9}, + { 8, 12, -40, 20, 9, 9, 9, 9}, + { 36, 8, -40, 20, 9, 9, 9, 9}, + { 36, -12, -40, 20, 9, 9, 9, 9}, + { 8, -16, -40, 20, 9, 9, 9, 9}, + { -8, -16, -40, 20, 9, 9, 9, 9}, + { -36, -12, -40, 20, 9, 9, 9, 9}, + { 0, 0, 76, 6, 11, 0, 11, 11}, + { 0, 0, 90, 31, 11, 0, 11, 11}, + { -80, -6, -40, 8, 9, 9, 9, 9}, + { -80, 6, -40, 8, 9, 9, 9, 9}, + { -88, 0, -40, 6, 9, 9, 9, 9}, + { 80, 6, -40, 8, 9, 9, 9, 9}, + { 88, 0, -40, 6, 9, 9, 9, 9}, + { 80, -6, -40, 8, 9, 9, 9, 9}, +}; + +struct ship_line cobra3b_line[38] = +{ + {31, 11, 0, 0, 1}, + {31, 12, 4, 0, 4}, + {31, 10, 3, 1, 3}, + {31, 10, 7, 3, 8}, + {31, 12, 8, 4, 7}, + {31, 9, 8, 6, 7}, + {31, 9, 6, 6, 9}, + {31, 9, 5, 5, 9}, + {31, 9, 7, 5, 8}, + {31, 5, 1, 2, 5}, + {31, 6, 2, 2, 6}, + {31, 7, 3, 3, 5}, + {31, 8, 4, 4, 6}, + {31, 1, 0, 1, 2}, + {31, 2, 0, 0, 2}, + {31, 10, 9, 8, 10}, + {31, 11, 9, 10, 11}, + {31, 12, 9, 7, 11}, + {31, 11, 10, 1, 10}, + {31, 12, 11, 0, 11}, + {29, 3, 1, 1, 5}, + {29, 4, 2, 0, 6}, + { 6, 11, 0, 20, 21}, + {20, 9, 9, 12, 13}, + {20, 9, 9, 18, 19}, + {20, 9, 9, 14, 15}, + {20, 9, 9, 16, 17}, + {19, 9, 9, 15, 16}, + {17, 9, 9, 14, 17}, + {19, 9, 9, 13, 18}, + {19, 9, 9, 12, 19}, + {30, 6, 5, 2, 9}, + { 6, 9, 9, 22, 24}, + { 6, 9, 9, 23, 24}, + { 8, 9, 9, 22, 23}, + { 6, 9, 9, 25, 26}, + { 6, 9, 9, 26, 27}, + { 8, 9, 9, 25, 27}, +}; + +struct ship_face_normal cobra3b_face_normal[13] = +{ + {31, 0, 62, 31}, + {31, -18, 55, 16}, + {31, 18, 55, 16}, + {31, -16, 52, 14}, + {31, 16, 52, 14}, + {31, -14, 47, 0}, + {31, 14, 47, 0}, + {31, -61, 102, 0}, + {31, 61, 102, 0}, + {31, 0, 0, -80}, + {31, -7, -42, 9}, + {31, 0, -30, 6}, + {31, 7, -42, 9}, +}; + +struct ship_data cobra3b_data = +{ + "Cobra MkIII", + 28, 38, 13, + 1, + 0, + 9025, + 21, + 175, + 50, + 150, + 28, + 2, + 9, + cobra3b_point, + cobra3b_line, + cobra3b_face_normal +}; + + + +struct ship_point asp2_point[19] = +{ + { 0, -18, 0, 22, 0, 1, 2, 2}, + { 0, -9, -45, 31, 1, 2, 11, 11}, + { 43, 0, -45, 31, 1, 6, 11, 11}, + { 69, -3, 0, 31, 1, 6, 7, 9}, + { 43, -14, 28, 31, 0, 1, 7, 7}, + { -43, 0, -45, 31, 2, 5, 11, 11}, + { -69, -3, 0, 31, 2, 5, 8, 10}, + { -43, -14, 28, 31, 0, 2, 8, 8}, + { 26, -7, 73, 31, 0, 4, 7, 9}, + { -26, -7, 73, 31, 0, 4, 8, 10}, + { 43, 14, 28, 31, 3, 4, 6, 9}, + { -43, 14, 28, 31, 3, 4, 5, 10}, + { 0, 9, -45, 31, 3, 5, 6, 11}, + { -17, 0, -45, 10, 11, 11, 11, 11}, + { 17, 0, -45, 9, 11, 11, 11, 11}, + { 0, -4, -45, 10, 11, 11, 11, 11}, + { 0, 4, -45, 8, 11, 11, 11, 11}, + { 0, -7, 73, 10, 0, 4, 0, 4}, + { 0, -7, 83, 10, 0, 4, 0, 4}, +}; + +struct ship_line asp2_line[28] = +{ + {22, 1, 2, 0, 1}, + {22, 0, 1, 0, 4}, + {22, 0, 2, 0, 7}, + {31, 1, 11, 1, 2}, + {31, 1, 6, 2, 3}, + {16, 7, 9, 3, 8}, + {31, 0, 4, 8, 9}, + {16, 8, 10, 6, 9}, + {31, 2, 5, 5, 6}, + {31, 2, 11, 1, 5}, + {31, 1, 7, 3, 4}, + {31, 0, 7, 4, 8}, + {31, 2, 8, 6, 7}, + {31, 0, 8, 7, 9}, + {31, 6, 11, 2, 12}, + {31, 5, 11, 5, 12}, + {22, 3, 6, 10, 12}, + {22, 3, 5, 11, 12}, + {22, 3, 4, 10, 11}, + {31, 5, 10, 6, 11}, + {31, 4, 10, 9, 11}, + {31, 6, 9, 3, 10}, + {31, 4, 9, 8, 10}, + {10, 11, 11, 13, 15}, + { 9, 11, 11, 15, 14}, + { 8, 11, 11, 14, 16}, + { 8, 11, 11, 16, 13}, + {10, 0, 4, 18, 17}, +}; + +struct ship_face_normal asp2_face_normal[12] = +{ + {31, 0, -35, 5}, + {31, 8, -38, -7}, + {31, -8, -38, -7}, + {22, 0, 24, -1}, + {31, 0, 43, 19}, + {31, -6, 28, -2}, + {31, 6, 28, -2}, + {31, 59, -64, 31}, + {31, -59, -64, 31}, + {31, 80, 46, 50}, + {31, -80, 46, 50}, + {31, 0, 0, -90}, +}; + +struct ship_data asp2_data = +{ + "Asp MkII", + 19, 28, 12, + 0, + 0, + 3600, + 8, + 200, + 40, + 150, + 40, + 1, + 20, + asp2_point, + asp2_line, + asp2_face_normal +}; + + + +struct ship_point pythonb_point[11] = +{ + { 0, 0, 224, 31, 1, 0, 3, 2}, + { 0, 48, 48, 31, 1, 0, 5, 4}, + { 96, 0, -16, 31, 15, 15, 15, 15}, + { -96, 0, -16, 31, 15, 15, 15, 15}, + { 0, 48, -32, 31, 5, 4, 9, 8}, + { 0, 24, -112, 31, 8, 9, 12, 12}, + { -48, 0, -112, 31, 11, 8, 12, 12}, + { 48, 0, -112, 31, 10, 9, 12, 12}, + { 0, -48, 48, 31, 3, 2, 7, 6}, + { 0, -48, -32, 31, 7, 6, 11, 10}, + { 0, -24, -112, 31, 11, 10, 12, 12}, +}; + +struct ship_line pythonb_line[26] = +{ + {31, 3, 2, 0, 8}, + {31, 2, 0, 0, 3}, + {31, 3, 1, 0, 2}, + {31, 1, 0, 0, 1}, + {31, 5, 9, 2, 4}, + {31, 5, 1, 1, 2}, + {31, 3, 7, 2, 8}, + {31, 4, 0, 1, 3}, + {31, 6, 2, 3, 8}, + {31, 10, 7, 2, 9}, + {31, 8, 4, 3, 4}, + {31, 11, 6, 3, 9}, + { 7, 8, 8, 3, 5}, + { 7, 11, 11, 3, 10}, + { 7, 9, 9, 2, 5}, + { 7, 10, 10, 2, 10}, + {31, 10, 9, 2, 7}, + {31, 11, 8, 3, 6}, + {31, 12, 8, 5, 6}, + {31, 12, 9, 5, 7}, + {31, 10, 12, 7, 10}, + {31, 12, 11, 6, 10}, + {31, 9, 8, 4, 5}, + {31, 11, 10, 9, 10}, + {31, 5, 4, 1, 4}, + {31, 7, 6, 8, 9}, +}; + +struct ship_face_normal pythonb_face_normal[13] = +{ + {31, -27, 40, 11}, + {31, 27, 40, 11}, + {31, -27, -40, 11}, + {31, 27, -40, 11}, + {31, -19, 38, 0}, + {31, 19, 38, 0}, + {31, -19, -38, 0}, + {31, 19, -38, 0}, + {31, -25, 37, -11}, + {31, 25, 37, -11}, + {31, 25, -37, -11}, + {31, -25, -37, -11}, + {31, 0, 0, -112}, +}; + +struct ship_data pythonb_data = +{ + "Python", + 11, 26, 13, + 2, + 0, + 6400, + 0, + 200, + 40, + 250, + 20, + 3, + 13, + pythonb_point, + pythonb_line, + pythonb_face_normal +}; + + + +struct ship_point ferdlce_point[19] = +{ + { 0, -14, 108, 31, 0, 1, 5, 9}, + { -40, -14, -4, 31, 1, 2, 9, 9}, + { -12, -14, -52, 31, 2, 3, 9, 9}, + { 12, -14, -52, 31, 3, 4, 9, 9}, + { 40, -14, -4, 31, 4, 5, 9, 9}, + { -40, 14, -4, 28, 0, 1, 2, 6}, + { -12, 2, -52, 28, 2, 3, 6, 7}, + { 12, 2, -52, 28, 3, 4, 7, 8}, + { 40, 14, -4, 28, 0, 4, 5, 8}, + { 0, 18, -20, 15, 0, 6, 7, 8}, + { -3, -11, 97, 11, 0, 0, 0, 0}, + { -26, 8, 18, 9, 0, 0, 0, 0}, + { -16, 14, -4, 11, 0, 0, 0, 0}, + { 3, -11, 97, 11, 0, 0, 0, 0}, + { 26, 8, 18, 9, 0, 0, 0, 0}, + { 16, 14, -4, 11, 0, 0, 0, 0}, + { 0, -14, -20, 12, 9, 9, 9, 9}, + { -14, -14, 44, 12, 9, 9, 9, 9}, + { 14, -14, 44, 12, 9, 9, 9, 9}, +}; + +struct ship_line ferdlce_line[27] = +{ + {31, 1, 9, 0, 1}, + {31, 2, 9, 1, 2}, + {31, 3, 9, 2, 3}, + {31, 4, 9, 3, 4}, + {31, 5, 9, 0, 4}, + {28, 0, 1, 0, 5}, + {28, 2, 6, 5, 6}, + {28, 3, 7, 6, 7}, + {28, 4, 8, 7, 8}, + {28, 0, 5, 0, 8}, + {15, 0, 6, 5, 9}, + {11, 6, 7, 6, 9}, + {11, 7, 8, 7, 9}, + {15, 0, 8, 8, 9}, + {14, 1, 2, 1, 5}, + {14, 2, 3, 2, 6}, + {14, 3, 4, 3, 7}, + {14, 4, 5, 4, 8}, + { 8, 0, 0, 10, 11}, + { 9, 0, 0, 11, 12}, + {11, 0, 0, 10, 12}, + { 8, 0, 0, 13, 14}, + { 9, 0, 0, 14, 15}, + {11, 0, 0, 13, 15}, + {12, 9, 9, 16, 17}, + {12, 9, 9, 16, 18}, + { 8, 9, 9, 17, 18}, +}; + +struct ship_face_normal ferdlce_face_normal[10] = +{ + {28, 0, 24, 6}, + {31, -68, 0, 24}, + {31, -63, 0, -37}, + {31, 0, 0, -104}, + {31, 63, 0, -37}, + {31, 68, 0, 24}, + {28, -12, 46, -19}, + {28, 0, 45, -22}, + {28, 12, 46, -19}, + {31, 0, -28, 0}, +}; + +struct ship_data ferdlce_data = +{ + "Fer-de-Lance", + 19, 27, 10, + 0, + 0, + 1600, + 0, + 0, + 40, + 160, + 30, + 2, + 9, + ferdlce_point, + ferdlce_line, + ferdlce_face_normal +}; + + + +struct ship_point moray_point[14] = +{ + { 15, 0, 65, 31, 0, 2, 7, 8}, + { -15, 0, 65, 31, 0, 1, 6, 7}, + { 0, 18, -40, 17, 15, 15, 15, 15}, + { -60, 0, 0, 31, 1, 3, 6, 6}, + { 60, 0, 0, 31, 2, 5, 8, 8}, + { 30, -27, -10, 24, 4, 5, 7, 8}, + { -30, -27, -10, 24, 3, 4, 6, 7}, + { -9, -4, -25, 7, 4, 4, 4, 4}, + { 9, -4, -25, 7, 4, 4, 4, 4}, + { 0, -18, -16, 7, 4, 4, 4, 4}, + { 13, 3, 49, 5, 0, 0, 0, 0}, + { 6, 0, 65, 5, 0, 0, 0, 0}, + { -13, 3, 49, 5, 0, 0, 0, 0}, + { -6, 0, 65, 5, 0, 0, 0, 0}, +}; + +struct ship_line moray_line[19] = +{ + {31, 0, 7, 0, 1}, + {31, 1, 6, 1, 3}, + {24, 3, 6, 3, 6}, + {24, 4, 7, 5, 6}, + {24, 5, 8, 4, 5}, + {31, 2, 8, 0, 4}, + {15, 6, 7, 1, 6}, + {15, 7, 8, 0, 5}, + {15, 0, 2, 0, 2}, + {15, 0, 1, 1, 2}, + {17, 1, 3, 2, 3}, + {17, 2, 5, 2, 4}, + {13, 4, 5, 2, 5}, + {13, 3, 4, 2, 6}, + { 5, 4, 4, 7, 8}, + { 7, 4, 4, 7, 9}, + { 7, 4, 4, 8, 9}, + { 5, 0, 0, 10, 11}, + { 5, 0, 0, 12, 13}, +}; + +struct ship_face_normal moray_face_normal[9] = +{ + {31, 0, 43, 7}, + {31, -10, 49, 7}, + {31, 10, 49, 7}, + {24, -59, -28, -101}, + {24, 0, -52, -78}, + {24, 59, -28, -101}, + {31, -72, -99, 50}, + {31, 0, -83, 30}, + {31, 72, -99, 50}, +}; + +struct ship_data moray_data = +{ + "Moray Star Boat", + 14, 19, 9, + 1, + 0, + 900, + 0, + 50, + 40, + 100, + 25, + 0, + 8, + moray_point, + moray_line, + moray_face_normal +}; + + + +struct ship_point thargoid_point[20] = +{ + { 32, -48, 48, 31, 4, 0, 8, 8}, + { 32, -68, 0, 31, 1, 0, 4, 4}, + { 32, -48, -48, 31, 2, 1, 4, 4}, + { 32, 0, -68, 31, 3, 2, 4, 4}, + { 32, 48, -48, 31, 4, 3, 5, 5}, + { 32, 68, 0, 31, 5, 4, 6, 6}, + { 32, 48, 48, 31, 6, 4, 7, 7}, + { 32, 0, 68, 31, 7, 4, 8, 8}, + { -24, -116, 116, 31, 8, 0, 9, 9}, + { -24, -164, 0, 31, 1, 0, 9, 9}, + { -24, -116, -116, 31, 2, 1, 9, 9}, + { -24, 0, -164, 31, 3, 2, 9, 9}, + { -24, 116, -116, 31, 5, 3, 9, 9}, + { -24, 164, 0, 31, 6, 5, 9, 9}, + { -24, 116, 116, 31, 7, 6, 9, 9}, + { -24, 0, 164, 31, 8, 7, 9, 9}, + { -24, 64, 80, 30, 9, 9, 9, 9}, + { -24, 64, -80, 30, 9, 9, 9, 9}, + { -24, -64, -80, 30, 9, 9, 9, 9}, + { -24, -64, 80, 30, 9, 9, 9, 9}, +}; + +struct ship_line thargoid_line[26] = +{ + {31, 8, 4, 0, 7}, + {31, 4, 0, 0, 1}, + {31, 4, 1, 1, 2}, + {31, 4, 2, 2, 3}, + {31, 4, 3, 3, 4}, + {31, 5, 4, 4, 5}, + {31, 6, 4, 5, 6}, + {31, 7, 4, 6, 7}, + {31, 8, 0, 0, 8}, + {31, 1, 0, 1, 9}, + {31, 2, 1, 2, 10}, + {31, 3, 2, 3, 11}, + {31, 5, 3, 4, 12}, + {31, 6, 5, 5, 13}, + {31, 7, 6, 6, 14}, + {31, 8, 7, 7, 15}, + {31, 9, 8, 8, 15}, + {31, 9, 0, 8, 9}, + {31, 9, 1, 9, 10}, + {31, 9, 2, 10, 11}, + {31, 9, 3, 11, 12}, + {31, 9, 5, 12, 13}, + {31, 9, 6, 13, 14}, + {31, 9, 7, 14, 15}, + {30, 9, 9, 16, 17}, + {30, 9, 9, 18, 19}, +}; + +struct ship_face_normal thargoid_face_normal[10] = +{ + {31, 103, -60, 25}, + {31, 103, -60, -25}, + {31, 103, -25, -60}, + {31, 103, 25, -60}, + {31, 64, 0, 0}, + {31, 103, 60, -25}, + {31, 103, 60, 25}, + {31, 103, 25, 60}, + {31, 103, -25, 60}, + {31, -48, 0, 0}, +}; + +struct ship_data thargoid_data = +{ + "Thargoid", + 20, 26, 10, + 0, + 0, + 9801, + 15, + 500, + 55, + 240, + 39, + 6, + 11, + thargoid_point, + thargoid_line, + thargoid_face_normal +}; + + + +struct ship_point thargon_point[10] = +{ + { -9, 0, 40, 31, 0, 1, 5, 5}, + { -9, -38, 12, 31, 0, 1, 2, 2}, + { -9, -24, -32, 31, 0, 2, 3, 3}, + { -9, 24, -32, 31, 0, 3, 4, 4}, + { -9, 38, 12, 31, 0, 4, 5, 5}, + { 9, 0, -8, 31, 1, 5, 6, 6}, + { 9, -10, -15, 31, 1, 2, 6, 6}, + { 9, -6, -26, 31, 2, 3, 6, 6}, + { 9, 6, -26, 31, 3, 4, 6, 6}, + { 9, 10, -15, 31, 4, 5, 6, 6}, +}; + +struct ship_line thargon_line[15] = +{ + {31, 1, 0, 0, 1}, + {31, 2, 0, 1, 2}, + {31, 3, 0, 2, 3}, + {31, 4, 0, 3, 4}, + {31, 5, 0, 0, 4}, + {31, 5, 1, 0, 5}, + {31, 2, 1, 1, 6}, + {31, 3, 2, 2, 7}, + {31, 4, 3, 3, 8}, + {31, 5, 4, 4, 9}, + {31, 6, 1, 5, 6}, + {31, 6, 2, 6, 7}, + {31, 6, 3, 7, 8}, + {31, 6, 4, 8, 9}, + {31, 6, 5, 9, 5}, +}; + +struct ship_face_normal thargon_face_normal[7] = +{ + {31, -36, 0, 0}, + {31, 20, -5, 7}, + {31, 46, -42, -14}, + {31, 36, 0, -104}, + {31, 46, 42, -14}, + {31, 20, 5, 7}, + {31, 36, 0, 0}, +}; + +struct ship_data thargon_data = +{ + "Thargon", + 10, 15, 7, + 0, + 15, + 1600, + 0, + 50, + 20, + 20, + 30, + 0, + 8, + thargon_point, + thargon_line, + thargon_face_normal +}; + + + +struct ship_point constrct_point[17] = +{ + { 20, -7, 80, 31, 0, 2, 9, 9}, + { -20, -7, 80, 31, 0, 1, 9, 9}, + { -54, -7, 40, 31, 1, 4, 9, 9}, + { -54, -7, -40, 31, 4, 5, 8, 9}, + { -20, 13, -40, 31, 5, 6, 8, 8}, + { 20, 13, -40, 31, 6, 7, 8, 8}, + { 54, -7, -40, 31, 3, 7, 8, 9}, + { 54, -7, 40, 31, 2, 3, 9, 9}, + { 20, 13, 5, 31, 15, 15, 15, 15}, + { -20, 13, 5, 31, 15, 15, 15, 15}, + { 20, -7, 62, 18, 9, 9, 9, 9}, + { -20, -7, 62, 18, 9, 9, 9, 9}, + { 25, -7, -25, 18, 9, 9, 9, 9}, + { -25, -7, -25, 18, 9, 9, 9, 9}, + { 15, -7, -15, 10, 9, 9, 9, 9}, + { -15, -7, -15, 10, 9, 9, 9, 9}, + { 0, -7, 0, 0, 9, 15, 0, 1}, +}; + +struct ship_line constrct_line[24] = +{ + {31, 0, 9, 0, 1}, + {31, 1, 9, 1, 2}, + {31, 0, 1, 1, 9}, + {31, 0, 2, 0, 8}, + {31, 2, 9, 0, 7}, + {31, 2, 3, 7, 8}, + {31, 1, 4, 2, 9}, + {31, 4, 9, 2, 3}, + {31, 3, 9, 6, 7}, + {31, 3, 7, 6, 8}, + {31, 6, 7, 5, 8}, + {31, 5, 6, 4, 9}, + {31, 4, 5, 3, 9}, + {31, 5, 8, 3, 4}, + {31, 6, 8, 4, 5}, + {31, 7, 8, 5, 6}, + {31, 8, 9, 3, 6}, + {31, 0, 6, 8, 9}, + {18, 9, 9, 10, 12}, + { 5, 9, 9, 12, 14}, + {10, 9, 9, 14, 10}, + {10, 9, 9, 11, 15}, + { 5, 9, 9, 13, 15}, + {18, 9, 9, 11, 13}, +}; + +struct ship_face_normal constrct_face_normal[10] = +{ + {31, 0, 55, 15}, + {31, -24, 75, 20}, + {31, 24, 75, 20}, + {31, 44, 75, 0}, + {31, -44, 75, 0}, + {31, -44, 75, 0}, + {31, 0, 53, 0}, + {31, 44, 75, 0}, + {31, 0, 0, -160}, + {31, 0, -27, 0}, +}; + +struct ship_data constrct_data = +{ + "Constrictor", + 17, 24, 10, + 3, + 0, + 4225, + 0, + 0, + 45, + 252, + 36, + 4, + 26, + constrct_point, + constrct_line, + constrct_face_normal +}; + + + +struct ship_point cougar_point[19] = +{ + { 0, 5, 67, 31, 0, 2, 4, 4}, + { -20, 0, 40, 31, 0, 1, 2, 2}, + { -40, 0, -40, 31, 0, 1, 5, 5}, + { 0, 14, -40, 30, 0, 4, 5, 5}, + { 0, -14, -40, 30, 1, 2, 3, 5}, + { 20, 0, 40, 31, 2, 3, 4, 4}, + { 40, 0, -40, 31, 3, 4, 5, 5}, + { -36, 0, 56, 31, 0, 1, 1, 1}, + { -60, 0, -20, 31, 0, 1, 1, 1}, + { 36, 0, 56, 31, 3, 4, 4, 4}, + { 60, 0, -20, 31, 3, 4, 4, 4}, + { 0, 7, 35, 18, 0, 0, 4, 4}, + { 0, 8, 25, 20, 0, 0, 4, 4}, + { -12, 2, 45, 20, 0, 0, 0, 0}, + { 12, 2, 45, 20, 4, 4, 4, 4}, + { -10, 6, -40, 20, 5, 5, 5, 5}, + { -10, -6, -40, 20, 5, 5, 5, 5}, + { 10, -6, -40, 20, 5, 5, 5, 5}, + { 10, 6, -40, 20, 5, 5, 5, 5}, +}; + +struct ship_line cougar_line[25] = +{ + {31, 0, 2, 0, 1}, + {31, 0, 1, 1, 7}, + {31, 0, 1, 7, 8}, + {31, 0, 1, 8, 2}, + {30, 0, 5, 2, 3}, + {30, 4, 5, 3, 6}, + {30, 1, 5, 2, 4}, + {30, 3, 5, 4, 6}, + {31, 3, 4, 6, 10}, + {31, 3, 4, 10, 9}, + {31, 3, 4, 9, 5}, + {31, 2, 4, 5, 0}, + {27, 0, 4, 0, 3}, + {27, 1, 2, 1, 4}, + {27, 2, 3, 5, 4}, + {26, 0, 1, 1, 2}, + {26, 3, 4, 5, 6}, + {20, 0, 0, 12, 13}, + {18, 0, 0, 13, 11}, + {18, 4, 4, 11, 14}, + {20, 4, 4, 14, 12}, + {18, 5, 5, 15, 16}, + {20, 5, 5, 16, 18}, + {18, 5, 5, 18, 17}, + {20, 5, 5, 17, 15}, +}; + +struct ship_face_normal cougar_face_normal[6] = +{ + {31, -16, 46, 4}, + {31, -16, -46, 4}, + {31, 0, -27, 5}, + {31, 16, -46, 4}, + {31, 16, 46, 4}, + {30, 0, 0, -160}, +}; + +struct ship_data cougar_data = +{ + "Cougar", + 19, 25, 6, + 3, + 0, + 4900, + 0, + 0, + 34, + 252, + 40, + 4, + 26, + cougar_point, + cougar_line, + cougar_face_normal +}; + + + +struct ship_point dodec_point[24] = +{ + { 0, 150, 196, 31, 0, 1, 5, 5}, + { 143, 46, 196, 31, 0, 1, 2, 2}, + { 88, -121, 196, 31, 0, 2, 3, 3}, + { -88, -121, 196, 31, 0, 3, 4, 4}, + {-143, 46, 196, 31, 0, 4, 5, 5}, + { 0, 243, 46, 31, 1, 5, 6, 6}, + { 231, 75, 46, 31, 1, 2, 7, 7}, + { 143, -196, 46, 31, 2, 3, 8, 8}, + {-143, -196, 46, 31, 3, 4, 9, 9}, + {-231, 75, 46, 31, 4, 5, 10, 10}, + { 143, 196, -46, 31, 1, 6, 7, 7}, + { 231, -75, -46, 31, 2, 7, 8, 8}, + { 0, -243, -46, 31, 3, 8, 9, 9}, + {-231, -75, -46, 31, 4, 9, 10, 10}, + {-143, 196, -46, 31, 5, 6, 10, 10}, + { 88, 121, -196, 31, 6, 7, 11, 11}, + { 143, -46, -196, 31, 7, 8, 11, 11}, + { 0, -150, -196, 31, 8, 9, 11, 11}, + {-143, -46, -196, 31, 9, 10, 11, 11}, + { -88, 121, -196, 31, 6, 10, 11, 11}, + { -16, 32, 196, 30, 0, 0, 0, 0}, + { -16, -32, 196, 30, 0, 0, 0, 0}, + { 16, 32, 196, 23, 0, 0, 0, 0}, + { 16, -32, 196, 23, 0, 0, 0, 0}, +}; + +struct ship_line dodec_line[34] = +{ + {31, 0, 1, 0, 1}, + {31, 0, 2, 1, 2}, + {31, 0, 3, 2, 3}, + {31, 0, 4, 3, 4}, + {31, 0, 5, 4, 0}, + {31, 1, 6, 5, 10}, + {31, 1, 7, 10, 6}, + {31, 2, 7, 6, 11}, + {31, 2, 8, 11, 7}, + {31, 3, 8, 7, 12}, + {31, 3, 9, 12, 8}, + {31, 4, 9, 8, 13}, + {31, 4, 10, 13, 9}, + {31, 5, 10, 9, 14}, + {31, 5, 6, 14, 5}, + {31, 7, 11, 15, 16}, + {31, 8, 11, 16, 17}, + {31, 9, 11, 17, 18}, + {31, 10, 11, 18, 19}, + {31, 6, 11, 19, 15}, + {31, 1, 5, 0, 5}, + {31, 1, 2, 1, 6}, + {31, 2, 3, 2, 7}, + {31, 3, 4, 3, 8}, + {31, 4, 5, 4, 9}, + {31, 6, 7, 10, 15}, + {31, 7, 8, 11, 16}, + {31, 8, 9, 12, 17}, + {31, 9, 10, 13, 18}, + {31, 6, 10, 14, 19}, + {30, 0, 0, 20, 21}, + {20, 0, 0, 21, 23}, + {23, 0, 0, 23, 22}, + {20, 0, 0, 22, 20}, +}; + +struct ship_face_normal dodec_face_normal[12] = +{ + {31, 0, 0, 196}, + {31, 103, 142, 88}, + {31, 169, -55, 89}, + {31, 0, -176, 88}, + {31, -169, -55, 89}, + {31, -103, 142, 88}, + {31, 0, 176, -88}, + {31, 169, 55, -89}, + {31, 103, -142, -88}, + {31, -103, -142, -88}, + {31, -169, 55, -89}, + {31, 0, 0, -196}, +}; + +struct ship_data dodec_data = +{ + "Dodec Space Station", + 24, 34, 12, + 0, + 0, + 32400, + 0, + 0, + 125, + 240, + 0, + 0, + 0, + dodec_point, + dodec_line, + dodec_face_normal +}; diff --git a/shipdata.h b/shipdata.h new file mode 100644 index 0000000..eae43e8 --- /dev/null +++ b/shipdata.h @@ -0,0 +1,151 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + */ + + +#ifndef SHIPDATA_H +#define SHIPDATA_H + +#include "vector.h" + +#define NO_OF_SHIPS 33 + + + +struct ship_point +{ + int x; + int y; + int z; + int dist; + int face1; + int face2; + int face3; + int face4; +}; + + +struct ship_line +{ + int dist; + int face1; + int face2; + int start_point; + int end_point; +}; + + +struct ship_face_normal +{ + int dist; + int x; + int y; + int z; +}; + + + +struct ship_data +{ + char name[32]; + int num_points; + int num_lines; + int num_faces; + int max_loot; + int scoop_type; + double size; + int front_laser; + int bounty; + int vanish_point; + int energy; + int velocity; + int missiles; + int laser_strength; + struct ship_point *points; + struct ship_line *lines; + struct ship_face_normal *normals; +}; + + +#define SHIP_SUN -2 +#define SHIP_PLANET -1 +#define SHIP_MISSILE 1 +#define SHIP_CORIOLIS 2 +#define SHIP_ESCAPE_CAPSULE 3 +#define SHIP_ALLOY 4 +#define SHIP_CARGO 5 +#define SHIP_BOULDER 6 +#define SHIP_ASTEROID 7 +#define SHIP_ROCK 8 +#define SHIP_SHUTTLE 9 +#define SHIP_TRANSPORTER 10 +#define SHIP_COBRA3 11 +#define SHIP_PYTHON 12 +#define SHIP_BOA 13 +#define SHIP_ANACONDA 14 +#define SHIP_HERMIT 15 +#define SHIP_VIPER 16 +#define SHIP_SIDEWINDER 17 +#define SHIP_MAMBA 18 +#define SHIP_KRAIT 19 +#define SHIP_ADDER 20 +#define SHIP_GECKO 21 +#define SHIP_COBRA1 22 +#define SHIP_WORM 23 +#define SHIP_COBRA3_LONE 24 +#define SHIP_ASP2 25 +#define SHIP_PYTHON_LONE 26 +#define SHIP_FER_DE_LANCE 27 +#define SHIP_MORAY 28 +#define SHIP_THARGOID 29 +#define SHIP_THARGLET 30 +#define SHIP_CONSTRICTOR 31 +#define SHIP_COUGAR 32 +#define SHIP_DODEC 33 + +extern struct ship_data missile_data; +extern struct ship_data coriolis_data; +extern struct ship_data esccaps_data; +extern struct ship_data alloy_data; +extern struct ship_data cargo_data; +extern struct ship_data boulder_data; +extern struct ship_data asteroid_data; +extern struct ship_data rock_data; +extern struct ship_data orbit_data; +extern struct ship_data transp_data; +extern struct ship_data cobra3a_data; +extern struct ship_data pythona_data; +extern struct ship_data boa_data; +extern struct ship_data anacnda_data; +extern struct ship_data hermit_data; +extern struct ship_data viper_data; +extern struct ship_data sidewnd_data; +extern struct ship_data mamba_data; +extern struct ship_data krait_data; +extern struct ship_data adder_data; +extern struct ship_data gecko_data; +extern struct ship_data cobra1_data; +extern struct ship_data worm_data; +extern struct ship_data cobra3b_data; +extern struct ship_data asp2_data; +extern struct ship_data pythonb_data; +extern struct ship_data ferdlce_data; +extern struct ship_data moray_data; +extern struct ship_data thargoid_data; +extern struct ship_data thargon_data; +extern struct ship_data constrct_data; +extern struct ship_data cougar_data; +extern struct ship_data dodec_data; + + +#endif + diff --git a/shipface.c b/shipface.c new file mode 100644 index 0000000..01ab277 --- /dev/null +++ b/shipface.c @@ -0,0 +1,707 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * Alterations to vertex ordering by Thomas Harte. + * (T.Harte@excite.com) + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * shipface.c + * + * Face information for the ships. + * Adapted from the Elite ship data published by Ian Bell. + * + * Adapted further for clockwise vertex lists. + */ + +#include + +#include "config.h" +#include "elite.h" +#include "shipface.h" +#include "gfx.h" + + + + +struct ship_face missile_face[] = +{ + //fins + {GFX_COL_RED, 0x20, 0x00, 0x00, 3, 5, 9, 15, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x20, 0x00, 3, 15, 9, 5, 0, 0, 0, 0, 0}, + + {GFX_COL_RED, -0x20, 0x00, 0x00, 3, 8, 12, 13, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x20, 0x00, 3, 13, 12, 8, 0, 0, 0, 0, 0}, + + {GFX_COL_RED, -0x20, 0x00, 0x00, 3, 7, 11, 14, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00,-0x20, 0x00, 3, 14, 11, 7, 0, 0, 0, 0, 0}, + + {GFX_COL_RED, 0x20, 0x00, 0x00, 3, 6, 10, 16, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00,-0x20, 0x00, 3, 16, 10, 6, 0, 0, 0, 0, 0}, + + //nose cone + {GFX_COL_DARK_RED, -0x40, 0x00, 0x10, 3, 0, 3, 4, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00,-0x40, 0x10, 3, 0, 4, 1, 0, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x40, 0x00, 0x10, 3, 0, 1, 2, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x40, 0x10, 3, 0, 2, 3, 0, 0, 0, 0, 0}, + + //main body + {GFX_COL_GREY_3, 0x20, 0x00, 0x00, 4, 6, 5, 2, 1, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00, 0x20, 0x00, 4, 5, 8, 3, 2, 0, 0, 0, 0}, + {GFX_COL_GREY_3, -0x20, 0x00, 0x00, 4, 8, 7, 4, 3, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00,-0x20, 0x00, 4, 7, 6, 1, 4, 0, 0, 0, 0}, + + //bottom + {GFX_COL_GREY_2, 0x00, 0x00,-0xB0, 4, 5, 6, 7, 8, 0, 0, 0, 0}, +}; + + +struct ship_face coriolis_face[] = +{ + {GFX_COL_GREY_3, 0x6B,-0x6B, 0x6B, 3, 4, 0, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x6B, 0x6B, 0x6B, 3, 0, 5, 1, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, -0x6B, 0x6B, 0x6B, 3, 1, 6, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, -0x6B,-0x6B, 0x6B, 3, 2, 7, 3, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_2, 0x00,-0xA0, 0x00, 4, 4, 3, 7, 11, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0xA0, 0x00, 0x00, 4, 8, 5, 0, 4, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0xA0, 0x00, 0x00, 4, 10, 7, 2, 6, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x00, 0xA0, 0x00, 4, 1, 5, 9, 6, 0, 0, 0, 0}, + + {GFX_COL_GREY_3, -0x6B,-0x6B,-0x6B, 3, 11, 7, 10, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x6B,-0x6B,-0x6B, 3, 11, 8, 4, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x6B, 0x6B,-0x6B, 3, 9, 5, 8, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, -0x6B, 0x6B,-0x6B, 3, 10, 6, 9, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_1, 0x00, 0x00,-0xA0, 4, 11, 10, 9, 8, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00, 0x00, 0xA0, 4, 0, 1, 2, 3, 0, 0, 0, 0}, + + {GFX_COL_BLACK, 0x00, 0x00, 0xA0, 4, 15, 12, 13, 14, 0, 0, 0, 0}, +}; + + +struct ship_face escape_face[] = +{ + {GFX_COL_RED, 0x34, 0x00,-0x7A, 3, 3, 1, 2, 0, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x27, 0x67, 0x1E, 3, 0, 3, 2, 0, 0, 0, 0, 0}, + {GFX_COL_RED_3, 0x27,-0x67, 0x1E, 3, 0, 1, 3, 0, 0, 0, 0, 0}, + {GFX_COL_RED_4, -0x70, 0x00, 0x00, 3, 0, 2, 1, 0, 0, 0, 0, 0}, +}; + + +struct ship_face alloy_face[] = +{ + {GFX_COL_GREY_1, 0x00, 0x00, 0x00, 4, 0, 1, 2, 3, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x00, 0x00, 0x00, 4, 3, 2, 1, 0, 0, 0, 0, 0}, +}; + +struct ship_face cargo_face[] = +{ + {GFX_COL_GREY_4, 0x60, 0x00, 0x00, 5, 4, 0, 1, 2, 3, 0, 0, 0}, + + {GFX_COL_GREY_2, 0x00, 0x29, 0x1E, 4, 5, 6, 1, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00,-0x12, 0x30, 4, 6, 7, 2, 1, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x00,-0x33, 0x00, 4, 7, 8, 3, 2, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00,-0x12,-0x30, 4, 8, 9, 4, 3, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x00, 0x29,-0x1E, 4, 9, 5, 0, 4, 0, 0, 0, 0}, + + {GFX_COL_GREY_4, -0x60, 0x00, 0x00, 5, 8, 7, 6, 5, 9, 0, 0, 0}, +}; + + +struct ship_face boulder_face[] = +{ + {GFX_COL_GREY_3, -0x0F,-0x03, 0x08, 3, 0, 4, 5, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x07, 0x0C, 0x1E, 3, 0, 5, 1, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x20,-0x2F, 0x18, 3, 1, 5, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, -0x03,-0x27,-0x07, 3, 2, 5, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x05,-0x04,-0x01, 3, 3, 5, 4, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_2, 0x31, 0x54, 0x08, 3, 1, 6, 0, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x70, 0x15,-0x15, 3, 2, 6, 1, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x4C,-0x23,-0x52, 3, 3, 6, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x16, 0x38,-0x89, 3, 4, 6, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x28, 0x6E,-0x26, 3, 6, 4, 0, 0, 0, 0, 0, 0}, +}; + + +struct ship_face asteroid_face[] = +{ + {GFX_COL_GREY_3, 0x09, 0x42, 0x51, 3, 5, 0, 6, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x09,-0x42, 0x51, 3, 2, 5, 6, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x48, 0x40, 0x1F, 3, 6, 0, 1, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_3, -0x40,-0x49, 0x2F, 3, 2, 6, 1, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x2D,-0x4F, 0x41, 3, 3, 5, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x87, 0x0F, 0x23, 3, 4, 5, 3, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_2, 0x26, 0x4C, 0x46, 3, 0, 5, 4, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, -0x42, 0x3B,-0x27, 3, 1, 0, 7, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x43,-0x0F,-0x50, 3, 1, 7, 8, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_2, 0x42,-0x0E,-0x4B, 3, 3, 8, 7, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x46,-0x50,-0x28, 3, 1, 8, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x3A,-0x66,-0x33, 3, 3, 2, 8, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x51, 0x09,-0x43, 3, 4, 3, 7, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x2F, 0x5E,-0x3F, 3, 4, 7, 0, 0, 0, 0, 0, 0}, +}; + + +struct ship_face rock_face[] = +{ + {GFX_COL_GREY_1, 0x00, 0x00, 0x00, 3, 3, 2, 1, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x00, 0x00, 0x00, 3, 0, 2, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x00, 0x00, 0x00, 3, 3, 1, 0, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_4, 0x00, 0x00, 0x00, 3, 0, 1, 2, 0, 0, 0, 0, 0}, +}; + + + +struct ship_face shuttle_face[] = +{ + {GFX_COL_GREY_1, 0x00,-0x4A, 0x04, 3, 0, 4, 7, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x33,-0x33, 0x17, 3, 1, 4, 0, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x4A, 0x00, 0x04, 3, 1, 5, 4, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x33, 0x33, 0x17, 3, 2, 5, 1, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00, 0x4A, 0x04, 3, 2, 6, 5, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x33, 0x33, 0x17, 3, 3, 6, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x4A, 0x00, 0x04, 3, 3, 7, 6, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x33,-0x33, 0x17, 3, 0, 7, 3, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_3, 0x00, 0x00,-0x6B, 4, 7, 4, 5, 6, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x00,-0x6B, 4, 11, 8, 9, 10, 0, 0, 0, 0}, + + {GFX_COL_GREY_4, -0x37, -0x37, 0x28, 3, 0, 12, 1, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x29, 0x29, 0x5A, 3, 1, 12, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_4, 0x29, 0x29, 0x5A, 3, 2, 12, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x37, -0x37, 0x28, 3, 3, 12, 0, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_1, 0x29, 0x29, 0x5A, 3, 14, 13, 15, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_1, -0x29, 0x29, 0x5A, 3, 18, 16, 17, 0, 0, 0, 0, 0}, +}; + + + +/* Two lines on base & detail of IB DB initials added back in :-) */ + +struct ship_face transporter_face[] = +{ + {GFX_COL_GREY_3, 0x00, 0x00,-0x67, 7, 5, 4, 3, 2, 1 ,0, 6, 0}, + + {GFX_COL_BLUE_1, -0x6F, 0x30,-0x07, 4, 9, 8, 1, 2, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, -0x69,-0x3F,-0x15, 3, 3, 9, 2, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_4, 0x00,-0x22, 0x00, 6, 14, 13, 9, 3, 4, 10, 0, 0}, + {GFX_COL_BLUE_2, 0x69,-0x3F,-0x15, 3, 5, 10, 4, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_1, 0x6F, 0x30,-0x07, 4, 11, 10, 5, 6, 0, 0, 0, 0}, + + {GFX_COL_GREY_1, 0x08, 0x20, 0x03, 4, 6, 0, 7, 11, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x08, 0x20, 0x03, 4, 8, 7, 0, 1, 0, 0, 0, 0}, + + {GFX_COL_BLUE_1, -0x4B, 0x20, 0x4F, 4, 13, 12, 8, 9, 0, 0, 0, 0}, + {GFX_COL_BLUE_1, 0x4B, 0x20, 0x4F, 4, 15, 14, 10, 11, 0, 0, 0, 0}, + + {GFX_COL_GREY_1, -0x08, 0x22, 0x0B, 3, 8, 12, 7, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x08, 0x22, 0x0B, 3, 7, 15, 11, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_4, 0x00, 0x26, 0x11, 3, 7, 12, 15, 0, 0, 0, 0, 0}, + + {GFX_COL_WHITE_2, 0x00, 0x00, 0x79, 4, 15, 12, 13, 14, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x00, 0x00,-0x67, 4, 35, 34, 33, 36, 0, 0, 0, 0}, + + {GFX_COL_WHITE, 0x00,-0x22, 0x00, 2, 30, 29, 31, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x00,-0x22, 0x00, 2, 31, 32, 29, 0, 0, 0, 0, 0}, + + {GFX_COL_WHITE, -0x08, 0x20, 0x03, 2, 17, 16, 18, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, -0x08, 0x20, 0x03, 2, 18, 19, 16, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, -0x08, 0x20, 0x03, 2, 18, 20, 19, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, -0x08, 0x20, 0x03, 2, 20, 21, 18, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, -0x08, 0x20, 0x03, 2, 20, 19, 21, 0, 0, 0, 0, 0}, + + {GFX_COL_WHITE, 0x08, 0x20, 0x03, 2, 23, 22, 26, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x08, 0x20, 0x03, 2, 25, 26, 23, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x08, 0x20, 0x03, 2, 24, 22, 25, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x08, 0x20, 0x03, 2, 24, 23, 22, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x08, 0x20, 0x03, 2, 28, 27, 23, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x08, 0x20, 0x03, 2, 25, 27, 22, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x08, 0x20, 0x03, 2, 27, 26, 22, 0, 0, 0, 0, 0}, +}; + + +struct ship_face cobra3_face[] = +{ + {GFX_COL_GREY_2, 0x00, 0x3E, 0x1F, 3, 1, 0, 2, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_1, -0x12, 0x37, 0x10, 3, 5, 1, 2, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_1, 0x12, 0x37, 0x10, 3, 2, 0, 6, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_3, -0x10, 0x34, 0x0E, 3, 3, 1, 5, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_3, 0x10, 0x34, 0x0E, 3, 6, 0, 4, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_1, -0x0E, 0x2F, 0x00, 3, 5, 2, 9, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x0E, 0x2F, 0x00, 3, 9, 2, 6, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_2, -0x3D, 0x66, 0x00, 3, 8, 3, 5, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, 0x3D, 0x66, 0x00, 3, 6, 4, 7, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_2, 0x00, 0x00,-0x50, 7, 6, 7, 11, 10, 8, 5, 9, 0}, + + {GFX_COL_GREY_3, -0x07,-0x2A, 0x09, 4, 10, 1, 3, 8, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x00,-0x1E, 0x06, 4, 10, 11, 0, 1, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x07,-0x2A, 0x09, 4, 7, 4, 0, 11, 0, 0, 0, 0}, + + {GFX_COL_RED, 0x00, 0x00,-0x50, 4, 17, 14, 15, 16, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x00,-0x50, 4, 19, 12, 13, 18, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x00, 0x00,-0x50, 3, 23, 22, 24, 0, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x00, 0x00,-0x50, 3, 27, 25, 26, 0, 0, 0, 0, 0}, + + {GFX_COL_WHITE, 0x00, 0x3E, 0x1F, 2, 20, 21, 0, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x00,-0x1E, 0x06, 2, 21, 20, 0, 0, 0, 0, 0, 0}, +}; + + +struct ship_face python_face[] = +{ + {GFX_COL_GREY_2, -0x1B, 0x28, 0x0B, 3, 0, 1, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x1B, 0x28, 0x0B, 3, 2, 1, 0, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x1B,-0x28, 0x0B, 3, 0, 3, 8, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x1B,-0x28, 0x0B, 3, 8, 2, 0, 0, 0, 0, 0, 0}, + + {GFX_COL_YELLOW_1, -0x13, 0x26, 0x00, 3, 3, 1, 4, 0, 0, 0, 0, 0}, + {GFX_COL_YELLOW_2, 0x13, 0x26, 0x00, 3, 4, 1, 2, 0, 0, 0, 0, 0}, + {GFX_COL_YELLOW_2, -0x13,-0x26, 0x00, 3, 3, 9, 8, 0, 0, 0, 0, 0}, + {GFX_COL_YELLOW_1, 0x13,-0x26, 0x00, 3, 8, 9, 2, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_2, -0x19, 0x25,-0x0B, 4, 3, 4, 5, 6, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x19, 0x25,-0x0B, 4, 2, 7, 5, 4, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x19,-0x25,-0x0B, 4, 2, 9, 10, 7, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x19,-0x25,-0x0B, 4, 3, 6, 10, 9, 0, 0, 0, 0}, + + {GFX_COL_GREY_3, 0x00, 0x00,-0x70, 4, 10, 6 , 5, 7, 0, 0, 0, 0}, +}; + + +struct ship_face boa_face[] = +{ + {GFX_COL_BLUE_4, 0x2B, 0x25,-0x3C, 6, 11, 10, 1, 5, 6, 2, 0, 0}, + {GFX_COL_BLUE_2, 0x00,-0x2D,-0x59, 6, 12, 11, 2, 7, 8, 3, 0, 0}, + {GFX_COL_BLUE_3, -0x2B, 0x25,-0x3C, 6, 3, 9, 4, 1, 10, 12, 0, 0}, + + {GFX_COL_BLUE_4, 0x00, 0x28, 0x00, 3, 5, 1, 4, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, 0x3E,-0x20,-0x14, 3, 7, 2, 6, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_3, -0x3E,-0x20,-0x14, 3, 3, 8, 9, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_1, 0x00, 0x17, 0x06, 3, 5, 4, 0, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x17,-0x0F, 0x09, 3, 9, 8, 0, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x17,-0x0F, 0x09, 3, 7, 6, 0, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x1A, 0x0D, 0x0A, 3, 0, 4, 9, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x00,-0x1F, 0x0C, 3, 0, 8, 7, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x1A, 0x0D, 0x0A, 3, 0, 6, 5, 0, 0, 0, 0, 0}, + + {GFX_COL_DARK_RED, 0x00, 0x00,-0x6B, 3, 12, 10, 11, 0, 0, 0, 0, 0}, +}; + + +struct ship_face anaconda_face[] = +{ + {GFX_COL_GREEN_1, 0x00,-0x33,-0x31, 5, 3, 2, 1, 0, 4, 0, 0, 0}, + {GFX_COL_GREEN_2, -0x33, 0x12,-0x57, 5, 6, 10, 5, 0, 1, 0, 0, 0}, + {GFX_COL_GREEN_3, -0x4D,-0x39,-0x13, 5, 7, 11, 6, 1, 2, 0, 0, 0}, + + {GFX_COL_GREY_2, 0x00,-0x5A, 0x10, 5, 8, 12, 7, 2, 3, 0, 0, 0}, + + {GFX_COL_GREEN_2, 0x4D,-0x39,-0x13, 5, 9, 13, 8, 3, 4, 0, 0, 0}, + {GFX_COL_GREEN_3, 0x33, 0x12,-0x57, 5, 9, 4, 0, 5, 14, 0, 0, 0}, + {GFX_COL_GREEN_1, 0x00, 0x6F,-0x14, 3, 10, 14, 5, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_2, -0x61, 0x48, 0x18, 4, 10, 6, 11, 12, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x6C,-0x44, 0x22, 3, 7, 12, 11, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x6C,-0x44, 0x22, 3, 8, 13, 12, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x61, 0x48, 0x18, 4, 9, 14, 12, 13, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00, 0x5E, 0x12, 3, 10, 12, 14, 0, 0, 0, 0, 0}, +}; + + +struct ship_face hermit_face[] = +{ + {GFX_COL_PINK_1, 0x09, 0x42, 0x51, 3, 5, 0, 6, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x09,-0x42, 0x51, 3, 2, 5, 6, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x48, 0x40, 0x1F, 3, 6, 0, 1, 0, 0, 0, 0, 0}, + {GFX_COL_PINK_1, -0x40,-0x49, 0x2F, 3, 2, 6, 1, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x2D,-0x4F, 0x41, 3, 3, 5, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x87, 0x0F, 0x23, 3, 4, 5, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x26, 0x4C, 0x46, 3, 0, 5, 4, 0, 0, 0, 0, 0}, + {GFX_COL_PINK_1, -0x42, 0x3B,-0x27, 3, 1, 0, 7, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x43,-0x0F,-0x50, 3, 1, 7, 8, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x42,-0x0E,-0x4B, 3, 3, 8, 7, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x46,-0x50,-0x28, 3, 1, 8, 2, 0, 0, 0, 0, 0}, + {GFX_COL_PINK_1, 0x3A,-0x66,-0x33, 3, 3, 2, 8, 0, 0, 0, 0, 0}, + {GFX_COL_PINK_1, 0x51, 0x09,-0x43, 3, 4, 3, 7, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x2F, 0x5E,-0x3F, 3, 4, 7, 0, 0, 0, 0, 0, 0}, +}; + + +struct ship_face viper_face[] = +{ + {GFX_COL_GREY_2, 0x00, 0x20, 0x00, 3, 7, 8, 1, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_3, -0x16, 0x21, 0x0B, 4, 8, 4, 0, 1, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, 0x16, 0x21, 0x0B, 4, 3, 7, 1, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_2, -0x16,-0x21, 0x0B, 4, 2, 0, 4, 6, 0, 0, 0, 0}, + {GFX_COL_BLUE_3, 0x16,-0x21, 0x0B, 4, 0, 2, 5, 3, 0, 0, 0, 0}, + + {GFX_COL_GREY_2, 0x00,-0x20, 0x00, 3, 2, 6, 5, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00, 0x00,-0x30, 6, 4, 8, 7, 3, 5, 6, 0, 0}, + {GFX_COL_RED, 0x00, 0x00,-0x30, 3, 12, 13, 9, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x00,-0x30, 3, 10, 14, 11, 0, 0, 0, 0, 0}, +}; + + + +struct ship_face sidewinder_face[] = +{ + {GFX_COL_YELLOW_1, 0x00, 0x20, 0x08, 3, 4, 0, 1, 0, 0, 0, 0, 0}, + {GFX_COL_YELLOW_2, -0x0C, 0x2F, 0x06, 3, 4, 3, 0, 0, 0, 0, 0, 0}, + {GFX_COL_YELLOW_2, 0x0C, 0x2F, 0x06, 3, 2, 4, 1, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_1, 0x00, 0x00,-0x70, 4, 2, 5, 3, 4, 0, 0, 0, 0}, + + {GFX_COL_YELLOW_1, -0x0C,-0x2F, 0x06, 3, 5, 0, 3, 0, 0, 0, 0, 0}, + {GFX_COL_YELLOW_2, 0x00,-0x20, 0x08, 3, 1, 0, 5, 0, 0, 0, 0, 0}, + {GFX_COL_YELLOW_1, 0x0C,-0x2F, 0x06, 3, 2, 1, 5, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x00,-0x70, 4, 8, 9, 6, 7, 0, 0, 0, 0}, +}; + + +struct ship_face mamba_face[] = +{ + {GFX_COL_GREEN_1, 0x00,-0x18, 0x02, 3, 1, 4, 0, 0, 0, 0, 0, 0}, + {GFX_COL_GREEN_3, 0x00, 0x18, 0x02, 3, 2, 0, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREEN_2, -0x20, 0x40, 0x10, 3, 1, 0, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREEN_2, 0x20, 0x40, 0x10, 3, 3, 0, 4, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_1, 0x00, 0x00,-0x7F, 4, 1, 2, 3, 4, 0, 0, 0, 0}, + {GFX_COL_BLUE_1, 0x00,-0x18, 0x02, 3, 11, 12, 9, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x00,-0x7F, 4, 17, 18, 15, 16, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, 0x00, 0x18, 0x02, 4, 7, 6, 5, 8, 0, 0, 0, 0}, + {GFX_COL_BLUE_1, 0x00,-0x18, 0x02, 3, 13, 14, 10, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x00,-0x7F, 3, 20, 24, 21, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x00,-0x7F, 3, 22, 23, 19, 0, 0, 0, 0, 0}, +}; + + +struct ship_face krait_face[] = +{ + {GFX_COL_BLUE_3, 0x03, 0x18, 0x03, 3, 0, 3, 1, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, 0x03,-0x18, 0x03, 3, 2, 3, 0, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_3, -0x03,-0x18, 0x03, 3, 0, 4, 2, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, -0x03, 0x18, 0x03, 3, 1, 4, 0, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_3, 0x26, 0x00,-0x4D, 3, 3, 2, 1, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x26, 0x00,-0x4D, 3, 4, 1, 2, 0, 0, 0, 0, 0}, + + {GFX_COL_WHITE, 0x03,-0x18, 0x03, 2, 3, 5, 0, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x03, 0x18, 0x03, 2, 5, 3, 0, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, -0x03, 0x18, 0x03, 2, 4, 6, 0, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, -0x03,-0x18, 0x03, 2, 6, 4, 0, 0, 0, 0, 0, 0}, + + {GFX_COL_RED, 0x26, 0x00,-0x4D, 3, 12, 11, 13, 0, 0, 0, 0, 0}, + {GFX_COL_RED, -0x26, 0x00,-0x4D, 3, 16, 14, 15, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x03, 0x18, 0x03, 3, 7, 10, 8, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, -0x03, 0x18, 0x03, 3, 8, 9, 7, 0, 0, 0, 0, 0}, +}; + + +struct ship_face adder_face[] = +{ + {GFX_COL_GREY_1, 0x00, 0x27, 0x0A, 4, 0, 1, 11, 10, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00,-0x27, 0x0A, 4, 1, 0, 12, 13, 0, 0, 0, 0}, + + {GFX_COL_RED_4, 0x45, 0x32, 0x0D, 3, 2, 11, 1, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x45,-0x32, 0x0D, 3, 1, 13, 2, 0, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x1E, 0x34, 0x00, 4, 9, 11, 2, 3, 0, 0, 0, 0}, + {GFX_COL_RED_3, 0x1E,-0x34, 0x00, 4, 3, 2, 13, 4, 0, 0, 0, 0}, + + {GFX_COL_DARK_RED, -0x1E, 0x34, 0x00, 4, 10, 8, 6, 7, 0, 0, 0, 0}, + {GFX_COL_RED_3, -0x1E,-0x34, 0x00, 4, 7, 6, 5, 12, 0, 0, 0, 0}, + {GFX_COL_RED_4, -0x45, 0x32, 0x0D, 3, 10, 7, 0, 0, 0, 0, 0, 0}, + {GFX_COL_RED, -0x45,-0x32, 0x0D, 3, 0, 7, 12, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_3, 0x00, 0x00,-0xA0, 6, 3, 4, 5, 6, 8, 9, 0, 0}, + {GFX_COL_GREY_2, 0x00, 0x1C, 0x00, 4, 10, 11, 9, 8, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x00,-0x1C, 0x00, 4, 5, 4, 13, 12, 0, 0, 0, 0}, + {GFX_COL_BLUE_1, 0x00, 0x27, 0x0A, 4, 17, 14, 15, 16, 0, 0, 0, 0}, +}; + + +struct ship_face gecko_face[] = +{ + {GFX_COL_GREY_2, 0x00, 0x1F, 0x05, 4, 3, 2, 0, 1, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x04, 0x2D, 0x08, 3, 3, 1, 5, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x19,-0x6C, 0x13, 3, 5, 1, 7, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_1, 0x00,-0x54, 0x0C, 4, 1, 0, 6, 7, 0, 0, 0, 0}, + {GFX_COL_GREY_3, -0x19,-0x6C, 0x13, 3, 4, 6, 0, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x04, 0x2D, 0x08, 3, 0, 2, 4, 0, 0, 0, 0, 0}, + + {GFX_COL_DARK_RED, -0x58, 0x10,-0xD6, 3, 4, 2, 6, 0, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x00,-0xBB, 4, 2, 3, 7, 6, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x58, 0x10,-0xD6, 3, 5, 7, 3, 0, 0, 0, 0, 0}, + + {GFX_COL_WHITE, 0x00,-0x54, 0x0C, 2, 8, 10, 9, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x00,-0x54, 0x0C, 2, 11, 9, 8, 0, 0, 0, 0, 0}, +}; + + + +struct ship_face cobra1_face[] = +{ + {GFX_COL_BLUE_2, 0x00, 0x29, 0x0A, 3, 0, 1, 8, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, 0x00,-0x1B, 0x03, 4, 6, 7, 1, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_3, -0x08, 0x2E, 0x08, 4, 2, 0, 8, 4, 0, 0, 0, 0}, + {GFX_COL_BLUE_4, -0x0C,-0x39, 0x0C, 3, 6, 0, 2, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_3, 0x08, 0x2E, 0x08, 4, 1, 3, 5, 8, 0, 0, 0, 0}, + {GFX_COL_BLUE_4, 0x0C,-0x39, 0x0C, 3, 1, 7, 3, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_2, 0x00, 0x31, 0x00, 3, 4, 8, 5, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_4, 0x00, 0x00,-0x9A, 4, 7, 6, 4, 5, 0, 0, 0, 0}, + + {GFX_COL_BLUE_2, -0x79, 0x6F,-0x3E, 3, 2, 4, 6, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, 0x79, 0x6F,-0x3E, 3, 3, 7, 5, 0, 0, 0, 0, 0}, + + {GFX_COL_WHITE, 0x00, 0x29, 0x0A, 2, 9, 10, 0, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x00,-0x1B, 0x03, 2, 10, 9, 0, 0, 0, 0, 0, 0}, +}; + + +struct ship_face worm_face[] = +{ + {GFX_COL_GREY_4, 0x00, 0x58, 0x46, 4, 1, 0, 2, 3, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x46, 0x42, 0x23, 3, 0, 4, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x46, 0x42, 0x23, 3, 1, 3, 5, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_2, 0x40, 0x31, 0x0E, 4, 2, 4, 6, 8, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x40, 0x31, 0x0E, 4, 5, 3, 9, 7, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00, 0x00,-0xC8, 4, 6, 7, 9, 8, 0, 0, 0, 0}, + + {GFX_COL_GREY_3, 0x00,-0x50, 0x00, 6, 4, 0, 1, 5, 7, 6, 0, 0}, + {GFX_COL_GREY_1, 0x00, 0x45, 0x0E, 4, 9, 3, 2, 8, 0, 0, 0, 0}, +}; + + +struct ship_face asp2_face[] = +{ + {GFX_COL_GREY_4, 0x00,-0x23, 0x05, 5, 8, 9, 7, 0, 4, 0, 0, 0}, + {GFX_COL_GREY_2, 0x08,-0x26,-0x07, 5, 3, 4, 0, 1, 2, 0, 0, 0}, + {GFX_COL_GREY_1, -0x08,-0x26,-0x07, 5, 1, 0, 7, 6, 5, 0, 0, 0}, + {GFX_COL_GREY_3, 0x3B,-0x40, 0x1F, 3, 8, 4, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, -0x3B,-0x40, 0x1F, 3, 6, 7, 9, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_2, 0x00, 0x18,-0x01, 3, 11, 10, 12, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_1, 0x00, 0x2B, 0x13, 4, 9, 8, 10, 11, 0, 0, 0, 0}, + {GFX_COL_BLUE_4, -0x06, 0x1C,-0x02, 4, 6, 11, 12, 5, 0, 0, 0, 0}, + {GFX_COL_BLUE_4, 0x06, 0x1C,-0x02, 4, 2, 12, 10, 3, 0, 0, 0, 0}, + {GFX_COL_BLUE_3, 0x50, 0x2E, 0x32, 3, 3, 10, 8, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_3, -0x50, 0x2E, 0x32, 3, 9, 11, 6, 0, 0, 0, 0, 0}, + + {GFX_COL_DARK_RED, 0x00, 0x00,-0x5A, 4, 2, 1, 5, 12, 0, 0, 0, 0}, + {GFX_COL_RED, 0x00, 0x00,-0x5A, 4, 14, 15, 13, 16, 0, 0, 0, 0}, + + {GFX_COL_WHITE, 0x00, 0x2B, 0x13, 2, 18, 17, 0, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x00,-0x23, 0x05, 2, 17, 18, 0, 0, 0, 0, 0, 0}, +}; + + +struct ship_face fer_de_lance_face[] = +{ + {GFX_COL_GREY_1, 0x00, 0x18, 0x06, 4, 5, 0, 8, 9, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x44, 0x00, 0x18, 3, 0, 5, 1, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_2, -0x3F, 0x00,-0x25, 4, 2, 1, 5, 6, 0, 0, 0, 0}, + + {GFX_COL_RED, 0x00, 0x00,-0x68, 4, 3, 2, 6, 7, 0, 0, 0, 0}, + + {GFX_COL_BLUE_2, 0x3F, 0x00,-0x25, 4, 4, 3, 7, 8, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x44, 0x00, 0x18, 3, 4, 8, 0, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_3, -0x0C, 0x2E,-0x13, 3, 5, 9, 6, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, 0x00, 0x2D,-0x16, 3, 6, 9, 7, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_3, 0x0C, 0x2E,-0x13, 3, 7, 9, 8, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x00,-0x1C, 0x00, 5, 4, 0, 1, 2, 3, 0, 0, 0}, + + {GFX_COL_DARK_RED, 0x00,-0x1C, 0x00, 3, 16, 18, 17, 0, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x00, 0x18, 0x06, 3, 11, 10, 12, 0, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x00, 0x18, 0x06, 3, 15, 13, 14, 0, 0, 0, 0, 0}, +}; + + +struct ship_face moray_face[] = +{ + {GFX_COL_BLUE_4, 0x00, 0x2B, 0x07, 3, 0, 2, 1, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_3, -0x0A, 0x31, 0x07, 3, 1, 2, 3, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_3, 0x0A, 0x31, 0x07, 3, 4, 2, 0, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_1,-0x3B,-0x1C,-0x65, 3, 3, 2, 6, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x00,-0x34,-0x4E, 3, 6, 2, 5, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x3B,-0x1C,-0x65, 3, 5, 2, 4, 0, 0, 0, 0, 0}, + + {GFX_COL_BLUE_1, -0x48,-0x63, 0x32, 3, 6, 1, 3, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, 0x00,-0x53, 0x1E, 4, 6, 5, 0, 1, 0, 0, 0, 0}, + {GFX_COL_BLUE_1, 0x48,-0x63, 0x32, 3, 4, 0, 5, 0, 0, 0, 0, 0}, + + {GFX_COL_DARK_RED, 0x00,-0x34,-0x4E, 3, 8, 9, 7, 0, 0, 0, 0, 0}, + + {GFX_COL_WHITE, 0x00, 0x2B, 0x07, 2, 11, 10, 12, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, 0x00, 0x2B, 0x07, 2, 12, 13, 10, 0, 0, 0, 0, 0}, +}; + + +struct ship_face thargoid_face[] = +{ + {GFX_COL_DARK_RED, 0x67,-0x3C, 0x19, 4, 1, 0, 8, 9, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x67,-0x3C,-0x19, 4, 2, 1, 9, 10, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x67,-0x19,-0x3C, 4, 3, 2, 10, 11, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x67, 0x19,-0x3C, 4, 4, 3, 11, 12, 0, 0, 0, 0}, +/* + {GFX_COL_GREY_3, 0x40, 0x00, 0x00, 8, 7, 6, 5, 4, 3, 2, 1, 0}, +*/ + {GFX_COL_GREY_3, 0x40, 0x00, 0x00, 4, 0, 1, 2, 7, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x40, 0x00, 0x00, 4, 2, 3, 6, 7, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x40, 0x00, 0x00, 4, 3, 4, 5, 6, 0, 0, 0, 0}, + + {GFX_COL_DARK_RED, 0x67, 0x3C,-0x19, 4, 5, 4, 12, 13, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x67, 0x3C, 0x19, 4, 6, 5, 13, 14, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x67, 0x19, 0x3C, 4, 7, 6, 14, 15, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x67,-0x19, 0x3C, 4, 0, 7, 15, 8, 0, 0, 0, 0}, +/* + {GFX_COL_GREY_3, -0x30, 0x00, 0x00, 8, 15, 14, 13, 12, 11, 10, 9, 8}, +*/ + {GFX_COL_GREY_3, -0x30, 0x00, 0x00, 4, 9, 8, 15, 10, 0, 0, 0, 0}, + {GFX_COL_GREY_3, -0x30, 0x00, 0x00, 4, 11, 10, 15, 14, 0, 0, 0, 0}, + {GFX_COL_GREY_3, -0x30, 0x00, 0x00, 4, 12, 11, 14, 13, 0, 0, 0, 0}, + + {GFX_COL_WHITE, -0x30, 0x00, 0x00, 2, 16, 17, 19, 0, 0, 0, 0, 0}, + {GFX_COL_WHITE, -0x30, 0x00, 0x00, 2, 18, 19, 16, 0, 0, 0, 0, 0}, +}; + + +struct ship_face thargon_face[] = +{ + {GFX_COL_DARK_RED, -0x24, 0x00, 0x00, 5, 3, 2, 1, 0, 4, 0, 0, 0}, + + {GFX_COL_GREY_1, 0x14,-0x05, 0x07, 4, 6, 5, 0, 1, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x2E,-0x2A,-0x0E, 4, 7, 6, 1, 2, 0, 0, 0, 0}, + {GFX_COL_GREY_4, 0x24, 0x00,-0x68, 4, 8, 7, 2, 3, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x2E, 0x2A,-0x0E, 4, 9, 8, 3, 4, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x14, 0x05, 0x07, 4, 4, 0, 5, 9, 0, 0, 0, 0}, + + {GFX_COL_DARK_RED, 0x24, 0x00, 0x00, 5, 9, 5, 6, 7, 8, 0, 0, 0}, +}; + + +struct ship_face constrictor_face[]= +{ + {GFX_COL_GREY_4, 0x00, 0x37, 0x0F, 4, 1, 0, 8, 9, 0, 0, 0, 0}, + {GFX_COL_GREY_1, -0x18, 0x4B, 0x14, 3, 1, 9, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x18, 0x4B, 0x14, 3, 0, 7, 8, 0, 0, 0, 0, 0}, + + {GFX_COL_YELLOW_2, 0x2C, 0x4B, 0x00, 3, 7, 6, 8, 0, 0, 0, 0, 0}, + {GFX_COL_YELLOW_2, -0x2C, 0x4B, 0x00, 3, 9, 3, 2, 0, 0, 0, 0, 0}, + + {GFX_COL_YELLOW_1, -0x2C, 0x4B, 0x00, 3, 9, 4, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00, 0x35, 0x00, 4, 8, 5, 4, 9, 0, 0, 0, 0}, + {GFX_COL_YELLOW_1, 0x2C, 0x4B, 0x00, 3, 8, 6, 5, 0, 0, 0, 0, 0}, + + {GFX_COL_GREY_2, 0x00, 0x00, -0xA0, 4, 6, 3, 4, 5, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x00, -0x1B, 0x00, 6, 3, 6, 7, 0, 1, 2, 0, 0}, + {GFX_COL_DARK_RED, 0x00, -0x1B, 0x00, 3, 12, 10, 14, 0, 0, 0, 0, 0}, + {GFX_COL_DARK_RED, 0x00, -0x1B, 0x00, 3, 15, 11, 13, 0, 0, 0, 0, 0}, +}; + +struct ship_face cougar_face[]= +{ + {GFX_COL_GREY_1, -0x10, 0x2E, 0x04, 4, 2, 1, 0, 3, 0, 0, 0, 0}, + {GFX_COL_GREY_2, -0x10, -0x2E, 0x04, 3, 4, 1, 2, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_4, 0x00, -0x1B, 0x05, 4, 4, 5, 0, 1, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x10, -0x2E, 0x04, 3, 6, 5, 4, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_2, 0x10, 0x2E, 0x04, 4, 5, 6, 3, 0, 0, 0, 0, 0}, + {GFX_COL_GREY_3, 0x00, 0x00, -0xA0, 4, 6, 4, 2, 3, 0, 0, 0, 0}, + + {GFX_COL_YELLOW_1, -0x10, -0x2E, 0x04, 4, 1, 2, 8, 7, 0, 0, 0, 0}, + {GFX_COL_YELLOW_1, -0x10, 0x2E, 0x04, 4, 7, 8, 2, 1, 0, 0, 0, 0}, + {GFX_COL_YELLOW_1, 0x10, 0x2E, 0x04, 4, 5, 6, 10, 9, 0, 0, 0, 0}, + {GFX_COL_YELLOW_1, 0x10, -0x2E, 0x04, 4, 9, 10, 6, 5, 0, 0, 0, 0}, + + {GFX_COL_BLUE_3, -0x10, 0x2E, 0x04, 3, 12, 13, 11, 0, 0, 0, 0, 0}, + {GFX_COL_BLUE_2, 0x10, 0x2E, 0x04, 3, 11, 14, 12, 0, 0, 0, 0, 0}, +/* + {8, 0x00, 0x00, -0xA0, 3, 15, 16, 19, 0, 0, 0, 0, 0}, + {8, 0x00, 0x00, -0xA0, 3, 19, 18, 17, 0, 0, 0, 0, 0}, +*/ +}; + +struct ship_face dodec_face[]= +{ + {GFX_COL_GREY_4, 0x00, 0x00, 0xC4, 5, 3, 2, 1, 0, 4, 0, 0, 0}, + {GFX_COL_GREY_1, 0x67, 0x8E, 0x58, 5, 6, 10, 5, 0, 1, 0, 0, 0}, + {GFX_COL_GREY_2, 0xA9, -0x37, 0x59, 5, 7, 11, 6, 1, 2, 0, 0, 0}, + {GFX_COL_GREY_3, 0x00, -0xB0, 0x58, 5, 8, 12, 7, 2, 3, 0, 0, 0}, + {GFX_COL_GREY_1, -0xA9, -0x37, 0x59, 5, 9, 13, 8, 3, 4, 0, 0, 0}, + {GFX_COL_GREY_3, -0x67, 0x8E, 0x58, 5, 5, 14, 9, 4, 0, 0, 0, 0}, + {GFX_COL_GREY_1, 0x00, 0xB0, -0x58, 5, 15, 19, 14, 5, 10, 0, 0, 0}, + {GFX_COL_GREY_2, 0xA9, 0x37, -0x59, 5, 16, 15, 10, 6, 11, 0, 0, 0}, + {GFX_COL_GREY_1, 0x67, -0x8E, -0x58, 5, 17, 16, 11, 7, 12, 0, 0, 0}, + {GFX_COL_GREY_3, -0x67, -0x8E, -0x58, 5, 18, 17, 12, 8, 13, 0, 0, 0}, + {GFX_COL_GREY_2, -0xA9, 0x37, -0x59, 5, 19, 18, 13, 9, 14, 0, 0, 0}, + {GFX_COL_GREY_4, 0x00, 0x00, -0xC4, 5, 19, 15, 16, 17, 18, 0, 0, 0}, + {GFX_COL_BLACK, 0x00, 0x00, 0xC4, 4, 22, 20, 21, 23, 0, 0, 0, 0}, +}; + + +struct ship_solid ship_solids[] = +{ + { 0, NULL}, + {17, missile_face}, + {15, coriolis_face}, + { 4, escape_face}, + { 2, alloy_face}, + { 7, cargo_face}, + {10, boulder_face}, + {14, asteroid_face}, + { 4, rock_face}, + {16, shuttle_face}, + {29, transporter_face}, + {19, cobra3_face}, + {13, python_face}, + {13, boa_face}, + {12, anaconda_face}, + {14, hermit_face}, + { 9, viper_face}, + { 8, sidewinder_face}, + {11, mamba_face}, + {14, krait_face}, + {14, adder_face}, + {11, gecko_face}, + {12, cobra1_face}, + { 8, worm_face}, + {19, cobra3_face}, + {15, asp2_face}, + {13, python_face}, + {13, fer_de_lance_face}, + {12, moray_face}, + {16, thargoid_face}, + { 7, thargon_face}, + {12, constrictor_face}, + {12, cougar_face}, + {13, dodec_face}, +}; + diff --git a/shipface.h b/shipface.h new file mode 100644 index 0000000..5a4555a --- /dev/null +++ b/shipface.h @@ -0,0 +1,44 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +#ifndef SHIPFACE_H +#define SHIPFACE_H + +struct ship_face +{ + int colour; + int norm_x; + int norm_y; + int norm_z; + int points; + int p1; + int p2; + int p3; + int p4; + int p5; + int p6; + int p7; + int p8; +}; + + +struct ship_solid +{ + int num_faces; + struct ship_face *face_data; +}; + +extern struct ship_solid ship_solids[]; + +#endif diff --git a/sound.c b/sound.c new file mode 100644 index 0000000..b49496c --- /dev/null +++ b/sound.c @@ -0,0 +1,145 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * sound.c + */ + +#include +#include +#include "sound.h" +#include "alg_data.h" + +#define NUM_SAMPLES 14 + +extern DATAFILE *datafile; + +static int sound_on; + +struct sound_sample +{ + SAMPLE *sample; + char filename[256]; + int runtime; + int timeleft; +}; + +struct sound_sample sample_list[NUM_SAMPLES] = +{ + {NULL, "launch.wav", 32, 0}, + {NULL, "crash.wav", 7, 0}, + {NULL, "dock.wav", 36, 0}, + {NULL, "gameover.wav", 24, 0}, + {NULL, "pulse.wav", 4, 0}, + {NULL, "hitem.wav", 4, 0}, + {NULL, "explode.wav", 23, 0}, + {NULL, "ecm.wav", 23, 0}, + {NULL, "missile.wav", 25, 0}, + {NULL, "hyper.wav", 37, 0}, + {NULL, "incom1.wav", 4, 0}, + {NULL, "incom2.wav", 5, 0}, + {NULL, "beep.wav", 2, 0}, + {NULL, "boop.wav", 7, 0}, +}; + + +void snd_sound_startup (void) +{ + int i; + + /* Install a sound driver.. */ + sound_on = 1; + + if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, ".") != 0) + { + sound_on = 0; + return; + } + + /* Load the sound samples... */ + + for (i = 0; i < NUM_SAMPLES; i++) + { + sample_list[i].sample = load_sample(sample_list[i].filename); + } +} + + +void snd_sound_shutdown (void) +{ + int i; + + if (!sound_on) + return; + + for (i = 0; i < NUM_SAMPLES; i++) + { + if (sample_list[i].sample != NULL) + { + destroy_sample (sample_list[i].sample); + sample_list[i].sample = NULL; + } + } +} + + +void snd_play_sample (int sample_no) +{ + if (!sound_on) + return; + + if (sample_list[sample_no].timeleft != 0) + return; + + sample_list[sample_no].timeleft = sample_list[sample_no].runtime; + + play_sample (sample_list[sample_no].sample, 255, 128, 1000, FALSE); +} + + +void snd_update_sound (void) +{ + int i; + + for (i = 0; i < NUM_SAMPLES; i++) + { + if (sample_list[i].timeleft > 0) + sample_list[i].timeleft--; + } +} + + +void snd_play_midi (int midi_no, int repeat) +{ + if (!sound_on) + return; + + switch (midi_no) + { + case SND_ELITE_THEME: + play_midi (datafile[THEME].dat, repeat); + break; + + case SND_BLUE_DANUBE: + play_midi (datafile[DANUBE].dat, repeat); + break; + } +} + + +void snd_stop_midi (void) +{ + if (sound_on); + play_midi (NULL, TRUE); +} \ No newline at end of file diff --git a/sound.h b/sound.h new file mode 100644 index 0000000..8a93b2d --- /dev/null +++ b/sound.h @@ -0,0 +1,47 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * sound.h + */ + +#ifndef SOUND_H +#define SOUND_H + +#define SND_LAUNCH 0 +#define SND_CRASH 1 +#define SND_DOCK 2 +#define SND_GAMEOVER 3 +#define SND_PULSE 4 +#define SND_HIT_ENEMY 5 +#define SND_EXPLODE 6 +#define SND_ECM 7 +#define SND_MISSILE 8 +#define SND_HYPERSPACE 9 +#define SND_INCOMMING_FIRE_1 10 +#define SND_INCOMMING_FIRE_2 11 +#define SND_BEEP 12 +#define SND_BOOP 13 + +#define SND_ELITE_THEME 0 +#define SND_BLUE_DANUBE 1 + +void snd_sound_startup (void); +void snd_sound_shutdown (void); +void snd_play_sample (int sample_no); +void snd_play_midi (int midi_no, int repeat); +void snd_update_sound (void); +void snd_stop_midi (void); + +#endif diff --git a/space.c b/space.c new file mode 100644 index 0000000..25129df --- /dev/null +++ b/space.c @@ -0,0 +1,1303 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * space.c + * + * This module handles all the flight system and management of the space universe. + */ + +#include +#include +#include +#include + +#include "vector.h" + +#include "alg_data.h" + +#include "config.h" +#include "elite.h" +#include "gfx.h" +#include "docked.h" +#include "intro.h" +#include "shipdata.h" +#include "shipface.h" +#include "space.h" +#include "threed.h" +#include "sound.h" +#include "main.h" +#include "swat.h" +#include "random.h" +#include "trade.h" +#include "stars.h" +#include "pilot.h" + +extern int flight_climb; +extern int flight_roll; +extern int flight_speed; + +struct galaxy_seed destination_planet; +int hyper_ready; +int hyper_countdown; +char hyper_name[16]; +int hyper_distance; +int hyper_galactic; + + + + + + +void rotate_x_first (double *a, double *b, int direction) +{ + double fx,ux; + + fx = *a; + ux = *b; + + if (direction < 0) + { + *a = fx - (fx / 512) + (ux / 19); + *b = ux - (ux / 512) - (fx / 19); + } + else + { + *a = fx - (fx / 512) - (ux / 19); + *b = ux - (ux / 512) + (fx / 19); + } +} + + +void rotate_vec (struct vector *vec, double alpha, double beta) +{ + double x,y,z; + + x = vec->x; + y = vec->y; + z = vec->z; + + y = y - alpha * x; + x = x + alpha * y; + y = y - beta * z; + z = z + beta * y; + + vec->x = x; + vec->y = y; + vec->z = z; +} + + +/* + * Update an objects location in the universe. + */ + +void move_univ_object (struct univ_object *obj) +{ + double x,y,z; + double k2; + double alpha; + double beta; + int rotx,rotz; + double speed; + + alpha = flight_roll / 256.0; + beta = flight_climb / 256.0; + + x = obj->location.x; + y = obj->location.y; + z = obj->location.z; + + if (!(obj->flags & FLG_DEAD)) + { + if (obj->velocity != 0) + { + speed = obj->velocity; + speed *= 1.5; + x += obj->rotmat[2].x * speed; + y += obj->rotmat[2].y * speed; + z += obj->rotmat[2].z * speed; + } + + if (obj->acceleration != 0) + { + obj->velocity += obj->acceleration; + obj->acceleration = 0; + if (obj->velocity > ship_list[obj->type]->velocity) + obj->velocity = ship_list[obj->type]->velocity; + + if (obj->velocity <= 0) + obj->velocity = 1; + } + } + + k2 = y - alpha * x; + z = z + beta * k2; + y = k2 - z * beta; + x = x + alpha * y; + + z = z - flight_speed; + + obj->location.x = x; + obj->location.y = y; + obj->location.z = z; + + obj->distance = sqrt (x*x + y*y + z*z); + + if (obj->type == SHIP_PLANET) + beta = 0.0; + + rotate_vec (&obj->rotmat[2], alpha, beta); + rotate_vec (&obj->rotmat[1], alpha, beta); + rotate_vec (&obj->rotmat[0], alpha, beta); + + if (obj->flags & FLG_DEAD) + return; + + + rotx = obj->rotx; + rotz = obj->rotz; + + /* If necessary rotate the object around the X axis... */ + + if (rotx != 0) + { + rotate_x_first (&obj->rotmat[2].x, &obj->rotmat[1].x, rotx); + rotate_x_first (&obj->rotmat[2].y, &obj->rotmat[1].y, rotx); + rotate_x_first (&obj->rotmat[2].z, &obj->rotmat[1].z, rotx); + + if ((rotx != 127) && (rotx != -127)) + obj->rotx -= (rotx < 0) ? -1 : 1; + } + + + /* If necessary rotate the object around the Z axis... */ + + if (rotz != 0) + { + rotate_x_first (&obj->rotmat[0].x, &obj->rotmat[1].x, rotz); + rotate_x_first (&obj->rotmat[0].y, &obj->rotmat[1].y, rotz); + rotate_x_first (&obj->rotmat[0].z, &obj->rotmat[1].z, rotz); + + if ((rotz != 127) && (rotz != -127)) + obj->rotz -= (rotz < 0) ? -1 : 1; + } + + + /* Orthonormalize the rotation matrix... */ + + tidy_matrix (obj->rotmat); +} + + +/* + * Dock the player into the space station. + */ + +void dock_player (void) +{ + disengage_auto_pilot(); + docked = 1; + flight_speed = 0; + flight_roll = 0; + flight_climb = 0; + front_shield = 255; + aft_shield = 255; + energy = 255; + myship.altitude = 255; + myship.cabtemp = 30; + reset_weapons(); +} + + +/* + * Check if we are correctly aligned to dock. + */ + +int is_docking (int sn) +{ + struct vector vec; + double fz; + double ux; + + if (auto_pilot) // Don't want it to kill anyone! + return 1; + + fz = universe[sn].rotmat[2].z; + + if (fz > -0.90) + return 0; + + vec = unit_vector (&universe[sn].location); + + if (vec.z < 0.927) + return 0; + + ux = universe[sn].rotmat[1].x; + if (ux < 0) + ux = -ux; + + if (ux < 0.84) + return 0; + + return 1; +} + + +/* + * Game Over... + */ + +void do_game_over (void) +{ + snd_play_sample (SND_GAMEOVER); + game_over = 1; +} + + +void update_altitude (void) +{ + double x,y,z; + double dist; + + myship.altitude = 255; + + if (witchspace) + return; + + x = fabs(universe[0].location.x); + y = fabs(universe[0].location.y); + z = fabs(universe[0].location.z); + + if ((x > 65535) || (y > 65535) || (z > 65535)) + return; + + x /= 256; + y /= 256; + z /= 256; + + dist = (x * x) + (y * y) + (z * z); + + if (dist > 65535) + return; + + dist -= 9472; + if (dist < 1) + { + myship.altitude = 0; + do_game_over (); + return; + } + + dist = sqrt (dist); + if (dist < 1) + { + myship.altitude = 0; + do_game_over (); + return; + } + + myship.altitude = dist; +} + + +void update_cabin_temp (void) +{ + int x,y,z; + int dist; + + myship.cabtemp = 30; + + if (witchspace) + return; + + if (ship_count[SHIP_CORIOLIS] || ship_count[SHIP_DODEC]) + return; + + x = abs((int)universe[1].location.x); + y = abs((int)universe[1].location.y); + z = abs((int)universe[1].location.z); + + if ((x > 65535) || (y > 65535) || (z > 65535)) + return; + + x /= 256; + y /= 256; + z /= 256; + + dist = ((x * x) + (y * y) + (z * z)) / 256; + + if (dist > 255) + return; + + dist ^= 255; + + myship.cabtemp = dist + 30; + + if (myship.cabtemp > 255) + { + myship.cabtemp = 255; + do_game_over (); + return; + } + + if ((myship.cabtemp < 224) || (cmdr.fuel_scoop == 0)) + return; + + cmdr.fuel += flight_speed / 2; + if (cmdr.fuel > myship.max_fuel) + cmdr.fuel = myship.max_fuel; + + info_message ("Fuel Scoop On"); +} + + + +/* + * Regenerate the shields and the energy banks. + */ + +void regenerate_shields (void) +{ + if (energy > 127) + { + if (front_shield < 255) + { + front_shield++; + energy--; + } + + if (aft_shield < 255) + { + aft_shield++; + energy--; + } + } + + energy++; + energy += cmdr.energy_unit; + if (energy > 255) + energy = 255; +} + + +void decrease_energy (int amount) +{ + energy += amount; + + if (energy <= 0) + do_game_over(); +} + + +/* + * Deplete the shields. Drain the energy banks if the shields fail. + */ + +void damage_ship (int damage, int front) +{ + int shield; + + if (damage <= 0) /* sanity check */ + return; + + shield = front ? front_shield : aft_shield; + + shield -= damage; + if (shield < 0) + { + decrease_energy (shield); + shield = 0; + } + + if (front) + front_shield = shield; + else + aft_shield = shield; +} + + + + +void make_station_appear (void) +{ + double px,py,pz; + double sx,sy,sz; + Vector vec; + Matrix rotmat; + + px = universe[0].location.x; + py = universe[0].location.y; + pz = universe[0].location.z; + + vec.x = (rand() & 32767) - 16384; + vec.y = (rand() & 32767) - 16384; + vec.z = rand() & 32767; + + vec = unit_vector (&vec); + + sx = px - vec.x * 65792; + sy = py - vec.y * 65792; + sz = pz - vec.z * 65792; + +// set_init_matrix (rotmat); + + rotmat[0].x = 1.0; + rotmat[0].y = 0.0; + rotmat[0].z = 0.0; + + rotmat[1].x = vec.x; + rotmat[1].y = vec.z; + rotmat[1].z = -vec.y; + + rotmat[2].x = vec.x; + rotmat[2].y = vec.y; + rotmat[2].z = vec.z; + + tidy_matrix (rotmat); + + add_new_station (sx, sy, sz, rotmat); +} + + + +void check_docking (int i) +{ + if (is_docking(i)) + { + snd_play_sample (SND_DOCK); + dock_player(); + current_screen = SCR_BREAK_PATTERN; + return; + } + + if (flight_speed >= 5) + { + do_game_over(); + return; + } + + flight_speed = 1; + damage_ship (5, universe[i].location.z > 0); + snd_play_sample (SND_CRASH); +} + + +void switch_to_view (struct univ_object *flip) +{ + double tmp; + + if ((current_screen == SCR_REAR_VIEW) || + (current_screen == SCR_GAME_OVER)) + { + flip->location.x = -flip->location.x; + flip->location.z = -flip->location.z; + + flip->rotmat[0].x = -flip->rotmat[0].x; + flip->rotmat[0].z = -flip->rotmat[0].z; + + flip->rotmat[1].x = -flip->rotmat[1].x; + flip->rotmat[1].z = -flip->rotmat[1].z; + + flip->rotmat[2].x = -flip->rotmat[2].x; + flip->rotmat[2].z = -flip->rotmat[2].z; + return; + } + + + if (current_screen == SCR_LEFT_VIEW) + { + tmp = flip->location.x; + flip->location.x = flip->location.z; + flip->location.z = -tmp; + + if (flip->type < 0) + return; + + tmp = flip->rotmat[0].x; + flip->rotmat[0].x = flip->rotmat[0].z; + flip->rotmat[0].z = -tmp; + + tmp = flip->rotmat[1].x; + flip->rotmat[1].x = flip->rotmat[1].z; + flip->rotmat[1].z = -tmp; + + tmp = flip->rotmat[2].x; + flip->rotmat[2].x = flip->rotmat[2].z; + flip->rotmat[2].z = -tmp; + return; + } + + if (current_screen == SCR_RIGHT_VIEW) + { + tmp = flip->location.x; + flip->location.x = -flip->location.z; + flip->location.z = tmp; + + if (flip->type < 0) + return; + + tmp = flip->rotmat[0].x; + flip->rotmat[0].x = -flip->rotmat[0].z; + flip->rotmat[0].z = tmp; + + tmp = flip->rotmat[1].x; + flip->rotmat[1].x = -flip->rotmat[1].z; + flip->rotmat[1].z = tmp; + + tmp = flip->rotmat[2].x; + flip->rotmat[2].x = -flip->rotmat[2].z; + flip->rotmat[2].z = tmp; + + } +} + + +/* + * Update all the objects in the universe and render them. + */ + +void update_universe (void) +{ + int i; + int type; + int bounty; + char str[80]; + struct univ_object flip; + + + gfx_start_render(); + + for (i = 0; i < MAX_UNIV_OBJECTS; i++) + { + type = universe[i].type; + + if (type != 0) + { + if (universe[i].flags & FLG_REMOVE) + { + if (type == SHIP_VIPER) + cmdr.legal_status |= 64; + + bounty = ship_list[type]->bounty; + + if ((bounty != 0) && (!witchspace)) + { + cmdr.credits += bounty; + sprintf (str, "%d.%d CR", cmdr.credits / 10, cmdr.credits % 10); + info_message (str); + } + + remove_ship (i); + continue; + } + + if ((detonate_bomb) && ((universe[i].flags & FLG_DEAD) == 0) && + (type != SHIP_PLANET) && (type != SHIP_SUN) && + (type != SHIP_CONSTRICTOR) && (type != SHIP_COUGAR) && + (type != SHIP_CORIOLIS) && (type != SHIP_DODEC)) + { + snd_play_sample (SND_EXPLODE); + universe[i].flags |= FLG_DEAD; + } + + if ((current_screen != SCR_INTRO_ONE) && + (current_screen != SCR_INTRO_TWO) && + (current_screen != SCR_GAME_OVER) && + (current_screen != SCR_ESCAPE_POD)) + { + tactics (i); + } + + move_univ_object (&universe[i]); + + flip = universe[i]; + switch_to_view (&flip); + + if (type == SHIP_PLANET) + { + if ((ship_count[SHIP_CORIOLIS] == 0) && + (ship_count[SHIP_DODEC] == 0) && + (universe[i].distance < 65792)) // was 49152 + { + make_station_appear(); + } + + draw_ship (&flip); + continue; + } + + if (type == SHIP_SUN) + { + draw_ship (&flip); + continue; + } + + + if (universe[i].distance < 170) + { + if ((type == SHIP_CORIOLIS) || (type == SHIP_DODEC)) + check_docking (i); + else + scoop_item(i); + + continue; + } + + if (universe[i].distance > 57344) + { + remove_ship (i); + continue; + } + + draw_ship (&flip); + + universe[i].flags = flip.flags; + universe[i].exp_seed = flip.exp_seed; + universe[i].exp_delta = flip.exp_delta; + + universe[i].flags &= ~FLG_FIRING; + + if (universe[i].flags & FLG_DEAD) + continue; + + check_target (i, &flip); + } + } + + gfx_finish_render(); + detonate_bomb = 0; +} + + + + +/* + * Update the scanner and draw all the lollipops. + */ + +void update_scanner (void) +{ + int i; + int x,y,z; + int x1,y1,y2; + int colour; + + for (i = 0; i < MAX_UNIV_OBJECTS; i++) + { + if ((universe[i].type <= 0) || + (universe[i].flags & FLG_DEAD) || + (universe[i].flags & FLG_CLOAKED)) + continue; + + x = universe[i].location.x / 256; + y = universe[i].location.y / 256; + z = universe[i].location.z / 256; + + x1 = x; + y1 = -z / 4; + y2 = y1 - y / 2; + + if ((y2 < -28) || (y2 > 28) || + (x1 < -50) || (x1 > 50)) + continue; + + x1 += scanner_cx; + y1 += scanner_cy; + y2 += scanner_cy; + + colour = (universe[i].flags & FLG_HOSTILE) ? GFX_COL_YELLOW_5 : GFX_COL_WHITE; + + switch (universe[i].type) + { + case SHIP_MISSILE: + colour = 137; + break; + + case SHIP_DODEC: + case SHIP_CORIOLIS: + colour = GFX_COL_GREEN_1; + break; + + case SHIP_VIPER: + colour = 252; + break; + } + + gfx_draw_colour_line (x1+2, y2, x1-3, y2, colour); + gfx_draw_colour_line (x1+2, y2+1, x1-3, y2+1, colour); + gfx_draw_colour_line (x1+2, y2+2, x1-3, y2+2, colour); + gfx_draw_colour_line (x1+2, y2+3, x1-3, y2+3, colour); + + + gfx_draw_colour_line (x1, y1, x1, y2, colour); + gfx_draw_colour_line (x1+1, y1, x1+1, y2, colour); + gfx_draw_colour_line (x1+2, y1, x1+2, y2, colour); + } +} + + +/* + * Update the compass which tracks the space station / planet. + */ + +void update_compass (void) +{ + struct vector dest; + int compass_x; + int compass_y; + int un = 0; + + if (witchspace) + return; + + if (ship_count[SHIP_CORIOLIS] || ship_count[SHIP_DODEC]) + un = 1; + + dest = unit_vector (&universe[un].location); + + compass_x = compass_centre_x + (dest.x * 16); + compass_y = compass_centre_y + (dest.y * -16); + + if (dest.z < 0) + { + gfx_draw_sprite (IMG_RED_DOT, compass_x, compass_y); + } + else + { + gfx_draw_sprite (IMG_GREEN_DOT, compass_x, compass_y); + } + +} + + +/* + * Display the speed bar. + */ + +void display_speed (void) +{ + int sx,sy; + int i; + int len; + int colour; + + sx = 417; + sy = 384 + 9; + + len = ((flight_speed * 64) / myship.max_speed) - 1; + + colour = (flight_speed > (myship.max_speed * 2 / 3)) ? GFX_COL_DARK_RED : GFX_COL_GOLD; + + for (i = 0; i < 6; i++) + { + gfx_draw_colour_line (sx, sy + i, sx + len, sy + i, colour); + } +} + + +/* + * Draw an indicator bar. + * Used for shields and energy banks. + */ + +void display_dial_bar (int len, int x, int y) +{ + int i = 0; + + gfx_draw_colour_line (x, y + 384, x + len, y + 384, GFX_COL_GOLD); + i++; + gfx_draw_colour_line (x, y + i + 384, x + len, y + i + 384, GFX_COL_GOLD); + + for (i = 2; i < 7; i++) + gfx_draw_colour_line (x, y + i + 384, x + len, y + i + 384, GFX_COL_YELLOW_1); + + gfx_draw_colour_line (x, y + i + 384, x + len, y + i + 384, GFX_COL_DARK_RED); +} + + +/* + * Display the current shield strengths. + */ + +void display_shields (void) +{ + if (front_shield > 3) + display_dial_bar (front_shield / 4, 31, 7); + + if (aft_shield > 3) + display_dial_bar (aft_shield / 4, 31, 23); +} + + +void display_altitude (void) +{ + if (myship.altitude > 3) + display_dial_bar (myship.altitude / 4, 31, 92); +} + +void display_cabin_temp (void) +{ + if (myship.cabtemp > 3) + display_dial_bar (myship.cabtemp / 4, 31, 60); +} + + +void display_laser_temp (void) +{ + if (laser_temp > 0) + display_dial_bar (laser_temp / 4, 31, 76); +} + + +/* + * Display the energy banks. + */ + +void display_energy (void) +{ + int e1,e2,e3,e4; + + e1 = energy > 64 ? 64 : energy; + e2 = energy > 128 ? 64 : energy - 64; + e3 = energy > 192 ? 64 : energy - 128; + e4 = energy - 192; + + if (e4 > 0) + display_dial_bar (e4, 416, 61); + + if (e3 > 0) + display_dial_bar (e3, 416, 79); + + if (e2 > 0) + display_dial_bar (e2, 416, 97); + + if (e1 > 0) + display_dial_bar (e1, 416, 115); +} + + + +void display_flight_roll (void) +{ + int sx,sy; + int i; + int pos; + + sx = 416; + sy = 384 + 9 + 14; + + pos = sx - ((flight_roll * 28) / myship.max_roll); + pos += 32; + + for (i = 0; i < 4; i++) + { + gfx_draw_colour_line (pos + i, sy, pos + i, sy + 7, GFX_COL_GOLD); + } +} + +void display_flight_climb (void) +{ + int sx,sy; + int i; + int pos; + + sx = 416; + sy = 384 + 9 + 14 + 16; + + pos = sx + ((flight_climb * 28) / myship.max_climb); + pos += 32; + + for (i = 0; i < 4; i++) + { + gfx_draw_colour_line (pos + i, sy, pos + i, sy + 7, GFX_COL_GOLD); + } +} + + +void display_fuel (void) +{ + if (cmdr.fuel > 0) + display_dial_bar ((cmdr.fuel * 64) / myship.max_fuel, 31, 44); +} + + +void display_missiles (void) +{ + int nomiss; + int x,y; + + if (cmdr.missiles == 0) + return; + + nomiss = cmdr.missiles > 4 ? 4 : cmdr.missiles; + + x = (4 - nomiss) * 16 + 35; + y = 113 + 385; + + if (missile_target != MISSILE_UNARMED) + { + gfx_draw_sprite ((missile_target < 0) ? IMG_MISSILE_YELLOW : + IMG_MISSILE_RED, x, y); + x += 16; + nomiss--; + } + + for (; nomiss > 0; nomiss--) + { + gfx_draw_sprite (IMG_MISSILE_GREEN, x, y); + x += 16; + } +} + + +void update_console (void) +{ + gfx_set_clip_region (0, 0, 512, 512); + gfx_draw_scanner(); + + display_speed(); + display_flight_climb(); + display_flight_roll(); + display_shields(); + display_altitude(); + display_energy(); + display_cabin_temp(); + display_laser_temp(); + display_fuel(); + display_missiles(); + + if (docked) + return; + + update_scanner(); + update_compass(); + + if (ship_count[SHIP_CORIOLIS] || ship_count[SHIP_DODEC]) + gfx_draw_sprite (IMG_BIG_S, 387, 490); + + if (ecm_active) + gfx_draw_sprite (IMG_BIG_E, 115, 490); +} + +void increase_flight_roll (void) +{ + if (flight_roll < myship.max_roll) + flight_roll++; +} + + +void decrease_flight_roll (void) +{ + if (flight_roll > -myship.max_roll) + flight_roll--; +} + + +void increase_flight_climb (void) +{ + if (flight_climb < myship.max_climb) + flight_climb++; +} + +void decrease_flight_climb (void) +{ + if (flight_climb > -myship.max_climb) + flight_climb--; +} + + +void start_hyperspace (void) +{ + if (hyper_ready) + return; + + hyper_distance = calc_distance_to_planet (docked_planet, hyperspace_planet); + + if ((hyper_distance == 0) || (hyper_distance > cmdr.fuel)) + return; + + destination_planet = hyperspace_planet; + name_planet (hyper_name, destination_planet); + capitalise_name (hyper_name); + + hyper_ready = 1; + hyper_countdown = 15; + hyper_galactic = 0; + + disengage_auto_pilot(); +} + +void start_galactic_hyperspace (void) +{ + if (hyper_ready) + return; + + if (cmdr.galactic_hyperdrive == 0) + return; + + hyper_ready = 1; + hyper_countdown = 2; + hyper_galactic = 1; + disengage_auto_pilot(); +} + + + +void display_hyper_status (void) +{ + char str[80]; + + sprintf (str, "%d", hyper_countdown); + + if ((current_screen == SCR_FRONT_VIEW) || (current_screen == SCR_REAR_VIEW) || + (current_screen == SCR_LEFT_VIEW) || (current_screen == SCR_RIGHT_VIEW)) + { + gfx_display_text (5, 5, str); + if (hyper_galactic) + { + gfx_display_centre_text (358, "Galactic Hyperspace", 120, GFX_COL_WHITE); + } + else + { + sprintf (str, "Hyperspace - %s", hyper_name); + gfx_display_centre_text (358, str, 120, GFX_COL_WHITE); + } + } + else + { + gfx_clear_area (5, 5, 25, 34); + gfx_display_text (5, 5, str); + } +} + + +int rotate_byte_left (int x) +{ + return ((x << 1) | (x >> 7)) & 255; +} + +void enter_next_galaxy (void) +{ + cmdr.galaxy_number++; + cmdr.galaxy_number &= 7; + + cmdr.galaxy.a = rotate_byte_left (cmdr.galaxy.a); + cmdr.galaxy.b = rotate_byte_left (cmdr.galaxy.b); + cmdr.galaxy.c = rotate_byte_left (cmdr.galaxy.c); + cmdr.galaxy.d = rotate_byte_left (cmdr.galaxy.d); + cmdr.galaxy.e = rotate_byte_left (cmdr.galaxy.e); + cmdr.galaxy.f = rotate_byte_left (cmdr.galaxy.f); + + docked_planet = find_planet (0x60, 0x60); + hyperspace_planet = docked_planet; +} + + + + + +void enter_witchspace (void) +{ + int i; + int nthg; + + witchspace = 1; + docked_planet.b ^= 31; + in_battle = 1; + + flight_speed = 12; + flight_roll = 0; + flight_climb = 0; + create_new_stars(); + clear_universe(); + + nthg = (randint() & 3) + 1; + + for (i = 0; i < nthg; i++) + create_thargoid(); + + current_screen = SCR_BREAK_PATTERN; + snd_play_sample (SND_HYPERSPACE); +} + + +void complete_hyperspace (void) +{ + Matrix rotmat; + int px,py,pz; + + hyper_ready = 0; + witchspace = 0; + + if (hyper_galactic) + { + cmdr.galactic_hyperdrive = 0; + enter_next_galaxy(); + cmdr.legal_status = 0; + } + else + { + cmdr.fuel -= hyper_distance; + cmdr.legal_status /= 2; + + if ((rand255() > 253) || (flight_climb == myship.max_climb)) + { + enter_witchspace(); + return; + } + + docked_planet = destination_planet; + } + + cmdr.market_rnd = rand255(); + generate_planet_data (¤t_planet_data, docked_planet); + generate_stock_market (); + + flight_speed = 12; + flight_roll = 0; + flight_climb = 0; + create_new_stars(); + clear_universe(); + + generate_landscape(docked_planet.a * 251 + docked_planet.b); + set_init_matrix (rotmat); + + pz = (((docked_planet.b) & 7) + 7) / 2; + px = pz / 2; + py = px; + + px <<= 16; + py <<= 16; + pz <<= 16; + + if ((docked_planet.b & 1) == 0) + { + px = -px; + py = -py; + } + + add_new_ship (SHIP_PLANET, px, py, pz, rotmat, 0, 0); + + + pz = -(((docked_planet.d & 7) | 1) << 16); + px = ((docked_planet.f & 3) << 16) | ((docked_planet.f & 3) << 8); + + add_new_ship (SHIP_SUN, px, py, pz, rotmat, 0, 0); + + current_screen = SCR_BREAK_PATTERN; + snd_play_sample (SND_HYPERSPACE); +} + + +void countdown_hyperspace (void) +{ + if (hyper_countdown == 0) + { + complete_hyperspace(); + return; + } + + hyper_countdown--; +} + + + +void jump_warp (void) +{ + int i; + int type; + int jump; + + for (i = 0; i < MAX_UNIV_OBJECTS; i++) + { + type = universe[i].type; + + if ((type > 0) && (type != SHIP_ASTEROID) && (type != SHIP_CARGO) && + (type != SHIP_ALLOY) && (type != SHIP_ROCK) && + (type != SHIP_BOULDER) && (type != SHIP_ESCAPE_CAPSULE)) + { + info_message ("Mass Locked"); + return; + } + } + + if ((universe[0].distance < 75001) || (universe[1].distance < 75001)) + { + info_message ("Mass Locked"); + return; + } + + + if (universe[0].distance < universe[1].distance) + jump = universe[0].distance - 75000; + else + jump = universe[1].distance - 75000; + + if (jump > 1024) + jump = 1024; + + for (i = 0; i < MAX_UNIV_OBJECTS; i++) + { + if (universe[i].type != 0) + universe[i].location.z -= jump; + } + + warp_stars = 1; + mcount &= 63; + in_battle = 0; +} + + +void launch_player (void) +{ + Matrix rotmat; + + docked = 0; + flight_speed = 12; + flight_roll = -15; + flight_climb = 0; + cmdr.legal_status |= carrying_contraband(); + create_new_stars(); + clear_universe(); + generate_landscape(docked_planet.a * 251 + docked_planet.b); + set_init_matrix (rotmat); + add_new_ship (SHIP_PLANET, 0, 0, 65536, rotmat, 0, 0); + + rotmat[2].x = -rotmat[2].x; + rotmat[2].y = -rotmat[2].y; + rotmat[2].z = -rotmat[2].z; + add_new_station (0, 0, -256, rotmat); + + current_screen = SCR_BREAK_PATTERN; + snd_play_sample (SND_LAUNCH); +} + + + +/* + * Engage the docking computer. + * For the moment we just do an instant dock if we are in the safe zone. + */ + +void engage_docking_computer (void) +{ + if (ship_count[SHIP_CORIOLIS] || ship_count[SHIP_DODEC]) + { + snd_play_sample (SND_DOCK); + dock_player(); + current_screen = SCR_BREAK_PATTERN; + } +} + diff --git a/space.h b/space.h new file mode 100644 index 0000000..1fa72b1 --- /dev/null +++ b/space.h @@ -0,0 +1,92 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + */ + +/* + * space.h + */ + +#ifndef SPACE_H +#define SPACE_H + +#include "vector.h" +#include "shipdata.h" + +struct point +{ + int x; + int y; + int z; +}; + + +struct univ_object +{ + int type; + Vector location; + Matrix rotmat; + int rotx; + int rotz; + int flags; + int energy; + int velocity; + int acceleration; + int missiles; + int target; + int bravery; + int exp_delta; + int exp_seed; + int distance; +}; + +#define MAX_UNIV_OBJECTS 20 + +extern struct univ_object universe[MAX_UNIV_OBJECTS]; +extern int ship_count[NO_OF_SHIPS + 1]; /* many */ + + + +void clear_universe (void); +int add_new_ship (int ship_type, int x, int y, int z, struct vector *rotmat, int rotx, int rotz); +void add_new_station (double sx, double sy, double sz, Matrix rotmat); +void remove_ship (int un); +void move_univ_object (struct univ_object *obj); +void update_universe (void); + +void update_console (void); + +void update_altitude (void); +void update_cabin_temp (void); +void regenerate_shields (void); + +void increase_flight_roll (void); +void decrease_flight_roll (void); +void increase_flight_climb (void); +void decrease_flight_climb (void); +void dock_player (void); + +void damage_ship (int damage, int front); +void decrease_energy (int amount); + +extern int hyper_ready; + +void start_hyperspace (void); +void start_galactic_hyperspace (void); +void display_hyper_status (void); +void countdown_hyperspace (void); +void jump_warp (void); +void launch_player (void); + +void engage_docking_computer (void); + +#endif + diff --git a/stars.c b/stars.c new file mode 100644 index 0000000..48b3e76 --- /dev/null +++ b/stars.c @@ -0,0 +1,397 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +#include +#include + +#include "config.h" +#include "elite.h" +#include "gfx.h" +#include "vector.h" +#include "stars.h" +#include "random.h" + +int warp_stars; + +struct star +{ + double x; + double y; + double z; +}; + +struct star stars[20]; + + +void create_new_stars (void) +{ + int i; + int nstars; + + nstars = witchspace ? 3 : 12; + + for (i = 0; i < nstars; i++) + { + stars[i].x = (rand255() - 128) | 8; + stars[i].y = (rand255() - 128) | 4; + stars[i].z = rand255() | 0x90; + } + + warp_stars = 0; +} + + +void front_starfield (void) +{ + int i; + double Q; + double delta; + double alpha = 0; + double beta = 0; + double xx,yy,zz; + int sx; + int sy; + int nstars; + + nstars = witchspace ? 3 : 12; + + delta = warp_stars ? 50 : flight_speed; + alpha = (double)flight_roll; + beta = (double)flight_climb; + + alpha /= 256.0; + delta /= 2.0; + + for (i = 0; i < nstars; i++) + { + /* Plot the stars in their current locations... */ + + sy = stars[i].y; + sx = stars[i].x; + zz = stars[i].z; + + sx += 128; + sy += 96; + + sx *= GFX_SCALE; + sy *= GFX_SCALE; + + if ((!warp_stars) && + (sx >= GFX_VIEW_TX) && (sx <= GFX_VIEW_BX) && + (sy >= GFX_VIEW_TY) && (sy <= GFX_VIEW_BY)) + { + gfx_plot_pixel (sx, sy, GFX_COL_WHITE); + + if (zz < 0xC0) + gfx_plot_pixel (sx+1, sy, GFX_COL_WHITE); + + if (zz < 0x90) + { + gfx_plot_pixel (sx, sy+1, GFX_COL_WHITE); + gfx_plot_pixel (sx+1, sy+1, GFX_COL_WHITE); + } + } + + + /* Move the stars to their new locations...*/ + + Q = delta / stars[i].z; + + stars[i].z -= delta; + yy = stars[i].y + (stars[i].y * Q); + xx = stars[i].x + (stars[i].x * Q); + zz = stars[i].z; + + yy = yy + (xx * alpha); + xx = xx - (yy * alpha); + +/* + tx = yy * beta; + xx = xx + (tx * tx * 2); +*/ + yy = yy + beta; + + stars[i].y = yy; + stars[i].x = xx; + + + if (warp_stars) + gfx_draw_line (sx, sy, (xx + 128) * GFX_SCALE, (yy + 96) * GFX_SCALE); + + sx = xx; + sy = yy; + + if ((sx > 120) || (sx < -120) || + (sy > 120) || (sy < -120) || (zz < 16)) + { + stars[i].x = (rand255() - 128) | 8; + stars[i].y = (rand255() - 128) | 4; + stars[i].z = rand255() | 0x90; + continue; + } + + } + + warp_stars = 0; +} + + + +void rear_starfield (void) +{ + int i; + double Q; + double delta; + double alpha = 0; + double beta = 0; + double xx,yy,zz; + int sx,sy; + int ex,ey; + int nstars; + + nstars = witchspace ? 3 : 12; + + delta = warp_stars ? 50 : flight_speed; + alpha = -flight_roll; + beta = -flight_climb; + + alpha /= 256.0; + delta /= 2.0; + + for (i = 0; i < nstars; i++) + { + /* Plot the stars in their current locations... */ + + sy = stars[i].y; + sx = stars[i].x; + zz = stars[i].z; + + sx += 128; + sy += 96; + + sx *= GFX_SCALE; + sy *= GFX_SCALE; + + if ((!warp_stars) && + (sx >= GFX_VIEW_TX) && (sx <= GFX_VIEW_BX) && + (sy >= GFX_VIEW_TY) && (sy <= GFX_VIEW_BY)) + { + gfx_plot_pixel (sx, sy, GFX_COL_WHITE); + + if (zz < 0xC0) + gfx_plot_pixel (sx+1, sy, GFX_COL_WHITE); + + if (zz < 0x90) + { + gfx_plot_pixel (sx, sy+1, GFX_COL_WHITE); + gfx_plot_pixel (sx+1, sy+1, GFX_COL_WHITE); + } + } + + + /* Move the stars to their new locations...*/ + + Q = delta / stars[i].z; + + stars[i].z += delta; + yy = stars[i].y - (stars[i].y * Q); + xx = stars[i].x - (stars[i].x * Q); + zz = stars[i].z; + + yy = yy + (xx * alpha); + xx = xx - (yy * alpha); + +/* + tx = yy * beta; + xx = xx + (tx * tx * 2); +*/ + yy = yy + beta; + + if (warp_stars) + { + ey = yy; + ex = xx; + ex = (ex + 128) * GFX_SCALE; + ey = (ey + 96) * GFX_SCALE; + + if ((sx >= GFX_VIEW_TX) && (sx <= GFX_VIEW_BX) && + (sy >= GFX_VIEW_TY) && (sy <= GFX_VIEW_BY) && + (ex >= GFX_VIEW_TX) && (ex <= GFX_VIEW_BX) && + (ey >= GFX_VIEW_TY) && (ey <= GFX_VIEW_BY)) + gfx_draw_line (sx, sy, (xx + 128) * GFX_SCALE, (yy + 96) * GFX_SCALE); + } + + stars[i].y = yy; + stars[i].x = xx; + + if ((zz >= 300) || (abs(yy) >= 110)) + { + stars[i].z = (rand255() & 127) + 51; + + if (rand255() & 1) + { + stars[i].x = rand255() - 128; + stars[i].y = (rand255() & 1) ? -115 : 115; + } + else + { + stars[i].x = (rand255() & 1) ? -126 : 126; + stars[i].y = rand255() - 128; + } + } + + } + + warp_stars = 0; +} + + +void side_starfield (void) +{ + int i; + double delta; + double alpha; + double beta; + double xx,yy,zz; + int sx; + int sy; + double delt8; + int nstars; + + nstars = witchspace ? 3 : 12; + + delta = warp_stars ? 50 : flight_speed; + alpha = flight_roll; + beta = flight_climb; + + if (current_screen == SCR_LEFT_VIEW) + { + delta = -delta; + alpha = -alpha; + beta = -beta; + } + + for (i = 0; i < nstars; i++) + { + sy = stars[i].y; + sx = stars[i].x; + zz = stars[i].z; + + sx += 128; + sy += 96; + + sx *= GFX_SCALE; + sy *= GFX_SCALE; + + if ((!warp_stars) && + (sx >= GFX_VIEW_TX) && (sx <= GFX_VIEW_BX) && + (sy >= GFX_VIEW_TY) && (sy <= GFX_VIEW_BY)) + { + gfx_plot_pixel (sx, sy, GFX_COL_WHITE); + + if (zz < 0xC0) + gfx_plot_pixel (sx+1, sy, GFX_COL_WHITE); + + if (zz < 0x90) + { + gfx_plot_pixel (sx, sy+1, GFX_COL_WHITE); + gfx_plot_pixel (sx+1, sy+1, GFX_COL_WHITE); + } + } + + yy = stars[i].y; + xx = stars[i].x; + zz = stars[i].z; + + delt8 = delta / (zz / 32); + xx = xx + delt8; + + xx += (yy * (beta / 256)); + yy -= (xx * (beta / 256)); + + xx += ((yy / 256) * (alpha / 256)) * (-xx); + yy += ((yy / 256) * (alpha / 256)) * (yy); + + yy += alpha; + + stars[i].y = yy; + stars[i].x = xx; + + if (warp_stars) + gfx_draw_line (sx, sy, (xx + 128) * GFX_SCALE, (yy + 96) * GFX_SCALE); + + + if (abs(stars[i].x) >= 116) + { + stars[i].y = rand255() - 128; + stars[i].x = (current_screen == SCR_LEFT_VIEW) ? 115 : -115; + stars[i].z = rand255() | 8; + } + else if (abs(stars[i].y) >= 116) + { + stars[i].x = rand255() - 128; + stars[i].y = (alpha > 0) ? -110 : 110; + stars[i].z = rand255() | 8; + } + + } + + warp_stars = 0; +} + + +/* + * When we change view, flip the stars over so they look like other stars. + */ + +void flip_stars (void) +{ + int i; + int nstars; + int sx; + int sy; + + nstars = witchspace ? 3 : 12; + for (i = 0; i < nstars; i++) + { + sy = stars[i].y; + sx = stars[i].x; + stars[i].x = sy; + stars[i].y = sx; + } +} + + +void update_starfield (void) +{ + switch (current_screen) + { + case SCR_FRONT_VIEW: + case SCR_INTRO_ONE: + case SCR_INTRO_TWO: + case SCR_ESCAPE_POD: + front_starfield(); + break; + + case SCR_REAR_VIEW: + case SCR_GAME_OVER: + rear_starfield(); + break; + + case SCR_LEFT_VIEW: + case SCR_RIGHT_VIEW: + side_starfield(); + break; + } +} diff --git a/stars.h b/stars.h new file mode 100644 index 0000000..cb72017 --- /dev/null +++ b/stars.h @@ -0,0 +1,11 @@ +#ifndef STARS_H +#define STARS_H + +extern int warp_stars; + +void create_new_stars (void); +void update_starfield (void); +void flip_stars (void); + +#endif + diff --git a/swat.c b/swat.c new file mode 100644 index 0000000..e687021 --- /dev/null +++ b/swat.c @@ -0,0 +1,1241 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * swat.c + * + * Special Weapons And Tactics. + */ + +#include +#include +#include + +#include "config.h" +#include "gfx.h" +#include "elite.h" +#include "vector.h" +#include "swat.h" +#include "shipdata.h" +#include "space.h" +#include "main.h" +#include "sound.h" +#include "random.h" +#include "trade.h" +#include "pilot.h" + +int laser_counter; +int laser; +int laser2; +int laser_x; +int laser_y; + +int ecm_active; +int missile_target; +int ecm_ours; +int in_battle; + +struct univ_object universe[MAX_UNIV_OBJECTS]; +int ship_count[NO_OF_SHIPS + 1]; /* many */ + + +int initial_flags[NO_OF_SHIPS + 1] = +{ + 0, // NULL, + 0, // missile + 0, // coriolis + FLG_SLOW | FLG_FLY_TO_PLANET, // escape + FLG_INACTIVE, // alloy + FLG_INACTIVE, // cargo + FLG_INACTIVE, // boulder + FLG_INACTIVE, // asteroid + FLG_INACTIVE, // rock + FLG_FLY_TO_PLANET | FLG_SLOW, // shuttle + FLG_FLY_TO_PLANET | FLG_SLOW, // transporter + 0, // cobra3 + 0, // python + 0, // boa + FLG_SLOW, // anaconda + FLG_SLOW, // hermit + FLG_BOLD | FLG_POLICE, // viper + FLG_BOLD | FLG_ANGRY, // sidewinder + FLG_BOLD | FLG_ANGRY, // mamba + FLG_BOLD | FLG_ANGRY, // krait + FLG_BOLD | FLG_ANGRY, // adder + FLG_BOLD | FLG_ANGRY, // gecko + FLG_BOLD | FLG_ANGRY, // cobra1 + FLG_SLOW | FLG_ANGRY, // worm + FLG_BOLD | FLG_ANGRY, // cobra3 + FLG_BOLD | FLG_ANGRY, // asp2 + FLG_BOLD | FLG_ANGRY, // python + FLG_POLICE, // fer_de_lance + FLG_BOLD | FLG_ANGRY, // moray + FLG_BOLD | FLG_ANGRY, // thargoid + FLG_ANGRY, // thargon + FLG_ANGRY, // constrictor + FLG_POLICE | FLG_CLOAKED, // cougar + 0 // dodec +}; + + + + +void clear_universe (void) +{ + int i; + + for (i = 0; i < MAX_UNIV_OBJECTS; i++) + universe[i].type = 0; + + for (i = 0; i <= NO_OF_SHIPS; i++) + ship_count[i] = 0; + + in_battle = 0; +} + + +int add_new_ship (int ship_type, int x, int y, int z, struct vector *rotmat, int rotx, int rotz) +{ + int i; + + for (i = 0; i < MAX_UNIV_OBJECTS; i++) + { + if (universe[i].type == 0) + { + universe[i].type = ship_type; + universe[i].location.x = x; + universe[i].location.y = y; + universe[i].location.z = z; + + universe[i].distance = sqrt(x*x + y*y + z*z); + + universe[i].rotmat[0] = rotmat[0]; + universe[i].rotmat[1] = rotmat[1]; + universe[i].rotmat[2] = rotmat[2]; + + universe[i].rotx = rotx; + universe[i].rotz = rotz; + + universe[i].velocity = 0; + universe[i].acceleration = 0; + universe[i].bravery = 0; + universe[i].target = 0; + + universe[i].flags = initial_flags[ship_type]; + + if ((ship_type != SHIP_PLANET) && (ship_type != SHIP_SUN)) + { + universe[i].energy = ship_list[ship_type]->energy; + universe[i].missiles = ship_list[ship_type]->missiles; + ship_count[ship_type]++; + } + + return i; + } + } + + return -1; +} + + + + +void check_missiles (int un) +{ + int i; + + if (missile_target == un) + { + missile_target = MISSILE_UNARMED; + info_message ("Target Lost"); + } + + for (i = 0; i < MAX_UNIV_OBJECTS; i++) + { + if ((universe[i].type == SHIP_MISSILE) && (universe[i].target == un)) + universe[i].flags |= FLG_DEAD; + } +} + + +void remove_ship (int un) +{ + int type; + Matrix rotmat; + int px,py,pz; + + type = universe[un].type; + + if (type == 0) + return; + + if (type > 0) + ship_count[type]--; + + universe[un].type = 0; + + check_missiles (un); + + if ((type == SHIP_CORIOLIS) || (type == SHIP_DODEC)) + { + set_init_matrix (rotmat); + px = universe[un].location.x; + py = universe[un].location.y; + pz = universe[un].location.z; + + py &= 0xFFFF; + py |= 0x60000; + + add_new_ship (SHIP_SUN, px, py, pz, rotmat, 0, 0); + } +} + + +void add_new_station (double sx, double sy, double sz, Matrix rotmat) +{ + int station; + + station = (current_planet_data.techlevel >= 10) ? SHIP_DODEC : SHIP_CORIOLIS; + universe[1].type = 0; + add_new_ship (station, sx, sy, sz, rotmat, 0, -127); +} + + + + +void reset_weapons (void) +{ + laser_temp = 0; + laser_counter = 0; + laser = 0; + ecm_active = 0; + missile_target = MISSILE_UNARMED; +} + + +void launch_enemy (int un, int type, int flags, int bravery) +{ + int newship; + struct univ_object *ns; + + newship = add_new_ship (type, universe[un].location.x, universe[un].location.y, + universe[un].location.z, universe[un].rotmat, + universe[un].rotx, universe[un].rotz); + + if (newship == -1) + { + return; + } + + ns = &universe[newship]; + + if ((universe[un].type == SHIP_CORIOLIS) || (universe[un].type == SHIP_DODEC)) + { + ns->velocity = 32; + ns->location.x += ns->rotmat[2].x * 2; + ns->location.y += ns->rotmat[2].y * 2; + ns->location.z += ns->rotmat[2].z * 2; + } + + ns->flags |= flags; + ns->rotz /= 2; + ns->rotz *= 2; + ns->bravery = bravery; + + if ((type == SHIP_CARGO) || (type == SHIP_ALLOY) || (type == SHIP_ROCK)) + { + ns->rotz = ((rand255() * 2) & 255) - 128; + ns->rotx = ((rand255() * 2) & 255) - 128; + ns->velocity = rand255() & 15; + } +} + + +void launch_loot (int un, int loot) +{ + int i,cnt; + + if (loot == SHIP_ROCK) + { + cnt = rand255() & 3; + } + else + { + cnt = rand255(); + if (cnt >= 128) + return; + + cnt &= ship_list[universe[un].type]->max_loot; + cnt &= 15; + } + + for (i = 0; i < cnt; i++) + { + launch_enemy (un, loot, 0,0); + } +} + + + + +int in_target (int type, double x, double y, double z) +{ + double size; + + if (z < 0) + return 0; + + size = ship_list[type]->size; + + return ((x*x + y*y) <= size); +} + + + +void make_angry (int un) +{ + int type; + int flags; + + type = universe[un].type; + flags = universe[un].flags; + + if (flags & FLG_INACTIVE) + return; + + if ((type == SHIP_CORIOLIS) || (type == SHIP_DODEC)) + { + universe[un].flags |= FLG_ANGRY; + return; + } + + if (type > SHIP_ROCK) + { + universe[un].rotx = 4; + universe[un].acceleration = 2; + universe[un].flags |= FLG_ANGRY; + } +} + + +void explode_object (int un) +{ + + cmdr.score++; + + if ((cmdr.score & 255) == 0) + info_message ("Right On Commander!"); + + snd_play_sample (SND_EXPLODE); + universe[un].flags |= FLG_DEAD; + + if (universe[un].type == SHIP_CONSTRICTOR) + cmdr.mission = 2; +} + + +void check_target (int un, struct univ_object *flip) +{ + struct univ_object *univ; + + univ = &universe[un]; + + if (in_target (univ->type, flip->location.x, flip->location.y, flip->location.z)) + { + if ((missile_target == MISSILE_ARMED) && (univ->type >= 0)) + { + missile_target = un; + info_message ("Target Locked"); + snd_play_sample (SND_BEEP); + } + + if (laser) + { + snd_play_sample (SND_HIT_ENEMY); + + if ((univ->type != SHIP_CORIOLIS) && (univ->type != SHIP_DODEC)) + { + if ((univ->type == SHIP_CONSTRICTOR) || (univ->type == SHIP_COUGAR)) + { + if (laser == (MILITARY_LASER & 127)) + univ->energy -= laser / 4; + } + else + { + univ->energy -= laser; + } + } + + if (univ->energy <= 0) + { + explode_object (un); + + if (univ->type == SHIP_ASTEROID) + { + if (laser == (MINING_LASER & 127)) + launch_loot (un, SHIP_ROCK); + } + else + { + launch_loot (un, SHIP_ALLOY); + launch_loot (un, SHIP_CARGO); + } + } + + make_angry (un); + } + } +} + + + +void activate_ecm (int ours) +{ + if (ecm_active == 0) + { + ecm_active = 32; + ecm_ours = ours; + snd_play_sample (SND_ECM); + } +} + + +void time_ecm (void) +{ + if (ecm_active != 0) + { + ecm_active--; + if (ecm_ours) + decrease_energy (-1); + } +} + + +void arm_missile (void) +{ + if ((cmdr.missiles != 0) && (missile_target == MISSILE_UNARMED)) + missile_target = MISSILE_ARMED; +} + + +void unarm_missile (void) +{ + missile_target = MISSILE_UNARMED; + snd_play_sample (SND_BOOP); +} + +void fire_missile (void) +{ + int newship; + struct univ_object *ns; + Matrix rotmat; + + if (missile_target < 0) + return; + + set_init_matrix (rotmat); + rotmat[2].z = 1.0; + rotmat[0].x = -1.0; + + newship = add_new_ship (SHIP_MISSILE, 0, -28, 14, rotmat, 0, 0); + + if (newship == -1) + { + info_message ("Missile Jammed"); + return; + } + + ns = &universe[newship]; + + ns->velocity = flight_speed * 2; + ns->flags = FLG_ANGRY; + ns->target = missile_target; + + if (universe[missile_target].type > SHIP_ROCK) + universe[missile_target].flags |= FLG_ANGRY; + + cmdr.missiles--; + missile_target = MISSILE_UNARMED; + + snd_play_sample (SND_MISSILE); +} + + + +void track_object (struct univ_object *ship, double direction, Vector nvec) +{ + double dir; + int rat; + double rat2; + + rat = 3; + rat2 = 0.111; + + dir = vector_dot_product (&nvec, &ship->rotmat[1]); + + if (direction < -0.861) + { + ship->rotx = (dir < 0) ? 7 : -7; + ship->rotz = 0; + return; + } + + ship->rotx = 0; + + if ((fabs(dir) * 2) >= rat2) + { + ship->rotx = (dir < 0) ? rat : -rat; + } + + if (abs(ship->rotz) < 16) + { + dir = vector_dot_product (&nvec, &ship->rotmat[0]); + + ship->rotz = 0; + + if ((fabs(dir) * 2) > rat2) + { + ship->rotz = (dir < 0) ? rat : -rat; + + if (ship->rotx < 0) + ship->rotz = -ship->rotz; + } + } +} + + + +void missile_tactics (int un) +{ + struct univ_object *missile; + struct univ_object *target; + Vector vec; + Vector nvec; + double direction; + double cnt2 = 0.223; + + missile = &universe[un]; + + if (ecm_active) + { + snd_play_sample (SND_EXPLODE); + missile->flags |= FLG_DEAD; + return; + } + + if (missile->target == 0) + { + if (missile->distance < 256) + { + missile->flags |= FLG_DEAD; + snd_play_sample (SND_EXPLODE); + damage_ship (250, missile->location.z >= 0.0); + return; + } + + vec.x = missile->location.x; + vec.y = missile->location.y; + vec.z = missile->location.z; + } + else + { + target = &universe[missile->target]; + + vec.x = missile->location.x - target->location.x; + vec.y = missile->location.y - target->location.y; + vec.z = missile->location.z - target->location.z; + + if ((fabs(vec.x) < 256) && (fabs(vec.y) < 256) && (fabs(vec.z) < 256)) + { + missile->flags |= FLG_DEAD; + + if ((target->type != SHIP_CORIOLIS) && (target->type != SHIP_DODEC)) + explode_object (missile->target); + else + snd_play_sample (SND_EXPLODE); + + return; + } + + if ((rand255() < 16) && (target->flags & FLG_HAS_ECM)) + { + activate_ecm (0); + return; + } + } + + nvec = unit_vector(&vec); + direction = vector_dot_product (&nvec, &missile->rotmat[2]); + nvec.x = -nvec.x; + nvec.y = -nvec.y; + nvec.z = -nvec.z; + direction = -direction; + + track_object (missile, direction, nvec); + + if (direction <= -0.167) + { + missile->acceleration = -2; + return; + } + + if (direction >= cnt2) + { + missile->acceleration = 3; + return; + } + + if (missile->velocity < 6) + missile->acceleration = 3; + else + if (rand255() >= 200) + missile->acceleration = -2; + return; +} + + + +void launch_shuttle (void) +{ + int type; + + if ((ship_count[SHIP_TRANSPORTER] != 0) || + (ship_count[SHIP_SHUTTLE] != 0) || + (rand255() < 253) || (auto_pilot)) + return; + + type = rand255() & 1 ? SHIP_SHUTTLE : SHIP_TRANSPORTER; + launch_enemy (1, type, FLG_HAS_ECM | FLG_FLY_TO_PLANET, 113); +} + + +void tactics (int un) +{ + int type; + int energy; + int maxeng; + int flags; + struct univ_object *ship; + Vector nvec; + double cnt2 = 0.223; + double direction; + int attacking; + + ship = &universe[un]; + type = ship->type; + flags = ship->flags; + + if ((type == SHIP_PLANET) || (type == SHIP_SUN)) + return; + + if (flags & FLG_DEAD) + return; + + if (flags & FLG_INACTIVE) + return; + + if (type == SHIP_MISSILE) + { + if (flags & FLG_ANGRY) + missile_tactics (un); + return; + } + + if (((un ^ mcount) & 7) != 0) + return; + + if ((type == SHIP_CORIOLIS) || (type == SHIP_DODEC)) + { + if (flags & FLG_ANGRY) + { + if ((rand() & 255) < 240) + return; + + if (ship_count[SHIP_VIPER] >= 4) + return; + + launch_enemy (un, SHIP_VIPER, FLG_ANGRY | FLG_HAS_ECM, 113); + return; + } + + launch_shuttle (); + return; + } + + if (type == SHIP_HERMIT) + { + if (rand255() > 200) + { + launch_enemy (un, SHIP_SIDEWINDER + (rand255() & 3), FLG_ANGRY | FLG_HAS_ECM, 113); + ship->flags |= FLG_INACTIVE; + } + + return; + } + + + if (ship->energy < ship_list[type]->energy) + ship->energy++; + + if ((type == SHIP_THARGLET) && (ship_count[SHIP_THARGOID] == 0)) + { + ship->flags = 0; + ship->velocity /= 2; + return; + } + + if (flags & FLG_SLOW) + { + if (rand255() > 50) + return; + } + + if (flags & FLG_POLICE) + { + if (cmdr.legal_status >= 64) + { + flags |= FLG_ANGRY; + ship->flags = flags; + } + } + + if ((flags & FLG_ANGRY) == 0) + { + if ((flags & FLG_FLY_TO_PLANET) || (flags & FLG_FLY_TO_STATION)) + { + auto_pilot_ship (&universe[un]); + } + + return; + } + + + /* If we get to here then the ship is angry so start attacking... */ + + if (ship_count[SHIP_CORIOLIS] || ship_count[SHIP_DODEC]) + { + if ((flags & FLG_BOLD) == 0) + ship->bravery = 0; + } + + + if (type == SHIP_ANACONDA) + { + if (rand255() > 200) + { + launch_enemy (un, rand255() > 100 ? SHIP_WORM : SHIP_SIDEWINDER, + FLG_ANGRY | FLG_HAS_ECM, 113); + return; + } + } + + + if (rand255() >= 250) + { + ship->rotz = rand255() | 0x68; + if (ship->rotz > 127) + ship->rotz = -(ship->rotz & 127); + } + + maxeng = ship_list[type]->energy; + energy = ship->energy; + + if (energy < (maxeng / 2)) + { + if ((energy < (maxeng / 8)) && (rand255() > 230) && (type != SHIP_THARGOID)) + { + ship->flags &= ~FLG_ANGRY; + ship->flags |= FLG_INACTIVE; + launch_enemy (un, SHIP_ESCAPE_CAPSULE, 0, 126); + return; + } + + if ((ship->missiles != 0) && (ecm_active == 0) && + (ship->missiles >= (rand255() & 31))) + { + ship->missiles--; + if (type == SHIP_THARGOID) + launch_enemy (un, SHIP_THARGLET, FLG_ANGRY, ship->bravery); + else + { + launch_enemy (un, SHIP_MISSILE, FLG_ANGRY, 126); + info_message ("INCOMING MISSILE"); + } + return; + } + } + + nvec = unit_vector(&universe[un].location); + direction = vector_dot_product (&nvec, &ship->rotmat[2]); + + if ((ship->distance < 8192) && (direction <= -0.833) && + (ship_list[type]->laser_strength != 0)) + { + if (direction <= -0.917) + ship->flags |= FLG_FIRING | FLG_HOSTILE; + + if (direction <= -0.972) + { + damage_ship (ship_list[type]->laser_strength, ship->location.z >= 0.0); + ship->acceleration--; + if (((ship->location.z >= 0.0) && (front_shield == 0)) || + ((ship->location.z < 0.0) && (aft_shield == 0))) + snd_play_sample (SND_INCOMMING_FIRE_2); + else + snd_play_sample (SND_INCOMMING_FIRE_1); + } + else + { + nvec.x = -nvec.x; + nvec.y = -nvec.y; + nvec.z = -nvec.z; + direction = -direction; + track_object (&universe[un], direction, nvec); + } + +// if ((fabs(ship->location.z) < 768) && (ship->bravery <= ((rand255() & 127) | 64))) + if (fabs(ship->location.z) < 768) + { + ship->rotx = rand255() & 0x87; + if (ship->rotx > 127) + ship->rotx = -(ship->rotx & 127); + + ship->acceleration = 3; + return; + } + + if (ship->distance < 8192) + ship->acceleration = -1; + else + ship->acceleration = 3; + return; + } + + attacking = 0; + + if ((fabs(ship->location.z) >= 768) || + (fabs(ship->location.x) >= 512) || + (fabs(ship->location.y) >= 512)) + { + if (ship->bravery > (rand255() & 127)) + { + attacking = 1; + nvec.x = -nvec.x; + nvec.y = -nvec.y; + nvec.z = -nvec.z; + direction = -direction; + } + } + + track_object (&universe[un], direction, nvec); + + if ((attacking == 1) && (ship->distance < 2048)) + { + if (direction >= cnt2) + { + ship->acceleration = -1; + return; + } + + if (ship->velocity < 6) + ship->acceleration = 3; + else + if (rand255() >= 200) + ship->acceleration = -1; + return; + } + + if (direction <= -0.167) + { + ship->acceleration = -1; + return; + } + + if (direction >= cnt2) + { + ship->acceleration = 3; + return; + } + + if (ship->velocity < 6) + ship->acceleration = 3; + else + if (rand255() >= 200) + ship->acceleration = -1; +} + + +void draw_laser_lines (void) +{ + if (wireframe) + { + gfx_draw_colour_line (32 * GFX_SCALE, GFX_VIEW_BY, laser_x, laser_y, GFX_COL_WHITE); + gfx_draw_colour_line (48 * GFX_SCALE, GFX_VIEW_BY, laser_x, laser_y, GFX_COL_WHITE); + gfx_draw_colour_line (208 * GFX_SCALE, GFX_VIEW_BY, laser_x, laser_y, GFX_COL_WHITE); + gfx_draw_colour_line (224 * GFX_SCALE, GFX_VIEW_BY, laser_x, laser_y, GFX_COL_WHITE); + } + else + { + gfx_draw_triangle (32 * GFX_SCALE, GFX_VIEW_BY, laser_x, laser_y, 48 * GFX_SCALE, GFX_VIEW_BY, GFX_COL_RED); + gfx_draw_triangle (208 * GFX_SCALE, GFX_VIEW_BY, laser_x, laser_y, 224 * GFX_SCALE, GFX_VIEW_BY, GFX_COL_RED); + } +} + + +int fire_laser (void) +{ + if ((laser_counter == 0) && (laser_temp < 242)) + { + switch (current_screen) + { + case SCR_FRONT_VIEW: + laser = cmdr.front_laser; + break; + + case SCR_REAR_VIEW: + laser = cmdr.rear_laser; + break; + + case SCR_RIGHT_VIEW: + laser = cmdr.right_laser; + break; + + case SCR_LEFT_VIEW: + laser = cmdr.left_laser; + break; + + default: + laser = 0; + } + + if (laser != 0) + { + laser_counter = (laser > 127) ? 0 : (laser & 0xFA); + laser &= 127; + laser2 = laser; + + snd_play_sample (SND_PULSE); + laser_temp += 8; + if (energy > 1) + energy--; + + laser_x = ((rand() & 3) + 128 - 2) * GFX_SCALE; + laser_y = ((rand() & 3) + 96 - 2) * GFX_SCALE; + + return 2; + } + } + + return 0; +} + + +void cool_laser (void) +{ + laser = 0; + + if (laser_temp > 0) + laser_temp--; + + if (laser_counter > 0) + laser_counter--; + + if (laser_counter > 0) + laser_counter--; +} + + +int create_other_ship (int type) +{ + Matrix rotmat; + int x,y,z; + int newship; + + set_init_matrix (rotmat); + + z = 12000; + x = 1000 + (randint() & 8191); + y = 1000 + (randint() & 8191); + + if (rand255() > 127) + x = -x; + if (rand255() > 127) + y = -y; + + newship = add_new_ship (type, x, y, z, rotmat, 0, 0); + + return newship; +} + + +void create_thargoid (void) +{ + int newship; + + newship = create_other_ship (SHIP_THARGOID); + if (newship != -1) + { + universe[newship].flags = FLG_ANGRY | FLG_HAS_ECM; + universe[newship].bravery = 113; + + if (rand255() > 64) + launch_enemy (newship, SHIP_THARGLET, FLG_ANGRY | FLG_HAS_ECM, 96); + } +} + + + +void create_cougar (void) +{ + int newship; + + if (ship_count[SHIP_COUGAR] != 0) + return; + + newship = create_other_ship (SHIP_COUGAR); + if (newship != -1) + { + universe[newship].flags = FLG_HAS_ECM; // | FLG_CLOAKED; + universe[newship].bravery = 121; + universe[newship].velocity = 18; + } +} + + + +void create_trader (void) +{ + int newship; + int rnd; + int type; + + type = SHIP_COBRA3 + (rand255() & 3); + + newship = create_other_ship (type); + + if (newship != -1) + { + universe[newship].rotmat[2].z = -1.0; + universe[newship].rotz = rand255() & 7; + + rnd = rand255(); + universe[newship].velocity = (rnd & 31) | 16; + universe[newship].bravery = rnd / 2; + + if (rnd & 1) + universe[newship].flags |= FLG_HAS_ECM; + +// if (rnd & 2) +// universe[newship].flags |= FLG_ANGRY; + } +} + + +void create_lone_hunter (void) +{ + int rnd; + int type; + int newship; + + if ((cmdr.mission == 1) && (cmdr.galaxy_number == 1) && + (docked_planet.d == 144) && (docked_planet.b == 33) && + (ship_count[SHIP_CONSTRICTOR] == 0)) + { + type = SHIP_CONSTRICTOR; + } + else + { + rnd = rand255(); + type = SHIP_COBRA3_LONE + (rnd & 3) + (rnd > 127); + } + + newship = create_other_ship (type); + + if (newship != -1) + { + universe[newship].flags = FLG_ANGRY; + if ((rand255() > 200) || (type == SHIP_CONSTRICTOR)) + universe[newship].flags |= FLG_HAS_ECM; + + universe[newship].bravery = ((rand255() * 2) | 64) & 127; + in_battle = 1; + } +} + + + +/* Check for a random asteroid encounter... */ + +void check_for_asteroids (void) +{ + int newship; + int type; + + if ((rand255() >= 35) || (ship_count[SHIP_ASTEROID] >= 3)) + return; + + if (rand255() > 253) + type = SHIP_HERMIT; + else + type = SHIP_ASTEROID; + + newship = create_other_ship (type); + + if (newship != -1) + { +// universe[newship].velocity = (rand255() & 31) | 16; + universe[newship].velocity = 8; + universe[newship].rotz = rand255() > 127 ? -127 : 127; + universe[newship].rotx = 16; + } +} + + + +/* If we've been a bad boy then send the cops after us... */ + +void check_for_cops (void) +{ + int newship; + int offense; + + offense = carrying_contraband() * 2; + if (ship_count[SHIP_VIPER] == 0) + offense |= cmdr.legal_status; + + if (rand255() >= offense) + return; + + newship = create_other_ship (SHIP_VIPER); + + if (newship != -1) + { + universe[newship].flags = FLG_ANGRY; + if (rand255() > 245) + universe[newship].flags |= FLG_HAS_ECM; + + universe[newship].bravery = ((rand255() * 2) | 64) & 127; + } +} + + +void check_for_others (void) +{ + int x,y,z; + int newship; + Matrix rotmat; + int gov; + int rnd; + int type; + int i; + + gov = current_planet_data.government; + rnd = rand255(); + + if ((gov != 0) && ((rnd >= 90) || ((rnd & 7) < gov))) + return; + + if (rand255() < 100) + { + create_lone_hunter(); + return; + } + + /* Pack hunters... */ + + set_init_matrix (rotmat); + + z = 12000; + x = 1000 + (randint() & 8191); + y = 1000 + (randint() & 8191); + + if (rand255() > 127) + x = -x; + if (rand255() > 127) + y = -y; + + rnd = rand255() & 3; + + for (i = 0; i <= rnd; i++) + { + type = SHIP_SIDEWINDER + (rand255() & rand255() & 7); + newship = add_new_ship (type, x, y, z, rotmat, 0, 0); + if (newship != -1) + { + universe[newship].flags = FLG_ANGRY; + if (rand255() > 245) + universe[newship].flags |= FLG_HAS_ECM; + + universe[newship].bravery = ((rand255() * 2) | 64) & 127; + in_battle++; + } + } + +} + + +void random_encounter (void) +{ + if ((ship_count[SHIP_CORIOLIS] != 0) || (ship_count[SHIP_DODEC] != 0)) + return; + + if (rand255() == 136) + { + if (((int)(universe[0].location.z) & 0x3e) != 0) + create_thargoid (); + else + create_cougar(); + + return; + } + + if ((rand255() & 7) == 0) + { + create_trader(); + return; + } + + check_for_asteroids(); + + check_for_cops(); + + if (ship_count[SHIP_VIPER] != 0) + return; + + if (in_battle) + return; + + if ((cmdr.mission == 5) && (rand255() >= 200)) + create_thargoid (); + + check_for_others(); +} + + +void abandon_ship (void) +{ + int i; + + cmdr.escape_pod = 0; + cmdr.legal_status = 0; + cmdr.fuel = myship.max_fuel; + + for (i = 0; i < NO_OF_STOCK_ITEMS; i++) + cmdr.current_cargo[i] = 0; + + snd_play_sample (SND_DOCK); + dock_player(); + current_screen = SCR_BREAK_PATTERN; +} + diff --git a/swat.h b/swat.h new file mode 100644 index 0000000..731af98 --- /dev/null +++ b/swat.h @@ -0,0 +1,48 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +#ifndef SWAT_H +#define SWAT_H + +#include "space.h" + +#define MISSILE_UNARMED -2 +#define MISSILE_ARMED -1 + +extern int ecm_active; +extern int missile_target; +extern int in_battle; + +void reset_weapons (void); +void tactics (int un); +int in_target (int type, double x, double y, double z); +void check_target (int un, struct univ_object *flip); +void check_missiles (int un); +void draw_laser_lines (void); +int fire_laser (void); +void cool_laser (void); +void arm_missile (void); +void unarm_missile (void); +void fire_missile (void); +void activate_ecm (int ours); +void time_ecm (void); +void random_encounter (void); +void explode_object (int un); +void abandon_ship (void); +void create_thargoid (void); +void dock_it (struct univ_object *ship); + + + +#endif diff --git a/threed.c b/threed.c new file mode 100644 index 0000000..1ea06a3 --- /dev/null +++ b/threed.c @@ -0,0 +1,1013 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + */ + +#include +#include +#include +#include +#include + +#include "config.h" +#include "elite.h" +#include "gfx.h" +#include "planet.h" +#include "vector.h" +#include "shipdata.h" +#include "shipface.h" +#include "threed.h" +#include "space.h" +#include "random.h" + +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) + + +#define LAND_X_MAX 128 +#define LAND_Y_MAX 128 + +static unsigned char landscape[LAND_X_MAX+1][LAND_Y_MAX+1]; + +static struct point point_list[100]; + + +/* + * The following routine is used to draw a wireframe represtation of a ship. + * + * caveat: it is a work in progress. + * A number of features (such as not showing detail at distance) have not yet been implemented. + * + */ + +void draw_wireframe_ship (struct univ_object *univ) +{ + Matrix trans_mat; + int i; + int sx,sy,ex,ey; + double rx,ry,rz; + int visible[32]; + Vector vec; + Vector camera_vec; + double cos_angle; + double tmp; + struct ship_face_normal *ship_norm; + int num_faces; + struct ship_data *ship; + int lasv; + + ship = ship_list[univ->type]; + + for (i = 0; i < 3; i++) + trans_mat[i] = univ->rotmat[i]; + + camera_vec = univ->location; + mult_vector (&camera_vec, trans_mat); + camera_vec = unit_vector (&camera_vec); + + num_faces = ship->num_faces; + + for (i = 0; i < num_faces; i++) + { + ship_norm = ship->normals; + + vec.x = ship_norm[i].x; + vec.y = ship_norm[i].y; + vec.z = ship_norm[i].z; + + if ((vec.x == 0) && (vec.y == 0) && (vec.z == 0)) + visible[i] = 1; + else + { + vec = unit_vector (&vec); + cos_angle = vector_dot_product (&vec, &camera_vec); + visible[i] = (cos_angle < -0.2); + } + } + + tmp = trans_mat[0].y; + trans_mat[0].y = trans_mat[1].x; + trans_mat[1].x = tmp; + + tmp = trans_mat[0].z; + trans_mat[0].z = trans_mat[2].x; + trans_mat[2].x = tmp; + + tmp = trans_mat[1].z; + trans_mat[1].z = trans_mat[2].y; + trans_mat[2].y = tmp; + + for (i = 0; i < ship->num_points; i++) + { + vec.x = ship->points[i].x; + vec.y = ship->points[i].y; + vec.z = ship->points[i].z; + + mult_vector (&vec, trans_mat); + + rx = vec.x + univ->location.x; + ry = vec.y + univ->location.y; + rz = vec.z + univ->location.z; + + sx = (rx * 256) / rz; + sy = (ry * 256) / rz; + + sy = -sy; + + sx += 128; + sy += 96; + + sx *= GFX_SCALE; + sy *= GFX_SCALE; + + point_list[i].x = sx; + point_list[i].y = sy; + + } + + for (i = 0; i < ship->num_lines; i++) + { + if (visible[ship->lines[i].face1] || + visible[ship->lines[i].face2]) + { + sx = point_list[ship->lines[i].start_point].x; + sy = point_list[ship->lines[i].start_point].y; + + ex = point_list[ship->lines[i].end_point].x; + ey = point_list[ship->lines[i].end_point].y; + + gfx_draw_line (sx, sy, ex, ey); + } + } + + + if (univ->flags & FLG_FIRING) + { + lasv = ship_list[univ->type]->front_laser; + gfx_draw_line (point_list[lasv].x, point_list[lasv].y, + univ->location.x > 0 ? 0 : 511, rand255() * 2); + } +} + + + + +/* + * Hacked version of the draw ship routine to display solid ships... + * This needs a lot of tidying... + * + * Check for hidden surface supplied by T.Harte. + */ + +void draw_solid_ship (struct univ_object *univ) +{ + int i; + int sx,sy; + double rx,ry,rz; + struct vector vec; + struct vector camera_vec; + double tmp; + struct ship_face *face_data; + int num_faces; + int num_points; + int poly_list[16]; + int zavg; + struct ship_solid *solid_data; + struct ship_data *ship; + Matrix trans_mat; + int lasv; + int col; + + solid_data = &ship_solids[univ->type]; + ship = ship_list[univ->type]; + + for (i = 0; i < 3; i++) + trans_mat[i] = univ->rotmat[i]; + + camera_vec = univ->location; + mult_vector (&camera_vec, trans_mat); + camera_vec = unit_vector (&camera_vec); + + num_faces = solid_data->num_faces; + face_data = solid_data->face_data; + +/* + for (i = 0; i < num_faces; i++) + { + vec.x = face_data[i].norm_x; + vec.y = face_data[i].norm_y; + vec.z = face_data[i].norm_z; + + vec = unit_vector (&vec); + cos_angle = vector_dot_product (&vec, &camera_vec); + + visible[i] = (cos_angle < -0.13); + } +*/ + + tmp = trans_mat[0].y; + trans_mat[0].y = trans_mat[1].x; + trans_mat[1].x = tmp; + + tmp = trans_mat[0].z; + trans_mat[0].z = trans_mat[2].x; + trans_mat[2].x = tmp; + + tmp = trans_mat[1].z; + trans_mat[1].z = trans_mat[2].y; + trans_mat[2].y = tmp; + + + for (i = 0; i < ship->num_points; i++) + { + vec.x = ship->points[i].x; + vec.y = ship->points[i].y; + vec.z = ship->points[i].z; + + mult_vector (&vec, trans_mat); + + rx = vec.x + univ->location.x; + ry = vec.y + univ->location.y; + rz = vec.z + univ->location.z; + + if (rz <= 0) + rz = 1; + + sx = (rx * 256) / rz; + sy = (ry * 256) / rz; + + sy = -sy; + + sx += 128; + sy += 96; + + sx *= GFX_SCALE; + sy *= GFX_SCALE; + + point_list[i].x = sx; + point_list[i].y = sy; + point_list[i].z = rz; + + } + + for (i = 0; i < num_faces; i++) + { + if (((point_list[face_data[i].p1].x - point_list[face_data[i].p2].x) * + (point_list[face_data[i].p3].y - point_list[face_data[i].p2].y) - + (point_list[face_data[i].p1].y - point_list[face_data[i].p2].y) * + (point_list[face_data[i].p3].x - point_list[face_data[i].p2].x)) <= 0) + { + num_points = face_data[i].points; + + poly_list[0] = point_list[face_data[i].p1].x; + poly_list[1] = point_list[face_data[i].p1].y; + zavg = point_list[face_data[i].p1].z; + + poly_list[2] = point_list[face_data[i].p2].x; + poly_list[3] = point_list[face_data[i].p2].y; + zavg = MAX(zavg,point_list[face_data[i].p2].z); + + if (num_points > 2) + { + poly_list[4] = point_list[face_data[i].p3].x; + poly_list[5] = point_list[face_data[i].p3].y; + zavg = MAX(zavg,point_list[face_data[i].p3].z); + } + + if (num_points > 3) + { + poly_list[6] = point_list[face_data[i].p4].x; + poly_list[7] = point_list[face_data[i].p4].y; + zavg = MAX(zavg,point_list[face_data[i].p4].z); + } + + if (num_points > 4) + { + poly_list[8] = point_list[face_data[i].p5].x; + poly_list[9] = point_list[face_data[i].p5].y; + zavg = MAX(zavg,point_list[face_data[i].p5].z); + } + + if (num_points > 5) + { + poly_list[10] = point_list[face_data[i].p6].x; + poly_list[11] = point_list[face_data[i].p6].y; + zavg = MAX(zavg,point_list[face_data[i].p6].z); + } + + if (num_points > 6) + { + poly_list[12] = point_list[face_data[i].p7].x; + poly_list[13] = point_list[face_data[i].p7].y; + zavg = MAX(zavg,point_list[face_data[i].p7].z); + } + + if (num_points > 7) + { + poly_list[14] = point_list[face_data[i].p8].x; + poly_list[15] = point_list[face_data[i].p8].y; + zavg = MAX(zavg,point_list[face_data[i].p8].z); + } + + + gfx_render_polygon (face_data[i].points, poly_list, face_data[i].colour, zavg); + + } + } + + if (univ->flags & FLG_FIRING) + { + lasv = ship_list[univ->type]->front_laser; + col = (univ->type == SHIP_VIPER) ? GFX_COL_CYAN : GFX_COL_WHITE; + + gfx_render_line (point_list[lasv].x, point_list[lasv].y, + univ->location.x > 0 ? 0 : 511, rand255() * 2, + point_list[lasv].z, col); + } +} + + + + + +/* + * Colour map used to generate a SNES Elite style planet. + * This is a quick hack and needs tidying up. + */ + +int snes_planet_colour[] = +{ + 102, 102, + 134, 134, 134, 134, + 167, 167, 167, 167, + 213, 213, + 255, + 83,83,83,83, + 122, + 83,83, + 249,249,249,249, + 83, + 122, + 249,249,249,249,249,249, + 83, 83, + 122, + 83,83, 83, 83, + 255, + 213, 213, + 167,167, 167, 167, + 134,134, 134, 134, + 102, 102 +}; + + +/* + * Generate a landscape map for a SNES Elite style planet. + */ + +void generate_snes_landscape (void) +{ + int x,y; + int colour; + + for (y = 0; y <= LAND_Y_MAX; y++) + { + colour = snes_planet_colour[y * (sizeof(snes_planet_colour)/sizeof(int)) / LAND_Y_MAX]; + for (x = 0; x <= LAND_X_MAX; x++) + { + landscape[x][y] = colour; + } + } +} + + + + +/* + * Guassian random number generator. + * Returns a number between -7 and +8 with Gaussian distribution. + */ + +int grand (void) +{ + int i; + int r; + + r = 0; + for (i = 0; i < 12; i++) + r += randint() & 15; + + r /= 12; + r -= 7; + + return r; +} + + +/* + * Calculate the midpoint between two given points. + */ + +int calc_midpoint (int sx, int sy, int ex, int ey) +{ + int a,b,n; + + a = landscape[sx][sy]; + b = landscape[ex][ey]; + + n = ((a + b) / 2) + grand(); + if (n < 0) + n = 0; + if (n > 255) + n = 255; + + return n; +} + + +/* + * Calculate a square on the midpoint map. + */ + +void midpoint_square (int tx, int ty, int w) +{ + int mx,my; + int bx,by; + int d; + + d = w / 2; + mx = tx + d; + my = ty + d; + bx = tx + w; + by = ty + w; + + landscape[mx][ty] = calc_midpoint(tx,ty,bx,ty); + landscape[mx][by] = calc_midpoint(tx,by,bx,by); + landscape[tx][my] = calc_midpoint(tx,ty,tx,by); + landscape[bx][my] = calc_midpoint(bx,ty,bx,by); + landscape[mx][my] = calc_midpoint(tx,my,bx,my); + + if (d == 1) + return; + + midpoint_square (tx,ty,d); + midpoint_square (mx,ty,d); + midpoint_square (tx,my,d); + midpoint_square (mx,my,d); +} + + +/* + * Generate a fractal landscape. + * Uses midpoint displacement method. + */ + +void generate_fractal_landscape (int rnd_seed) +{ + int x,y,d,h; + double dist; + int dark; + int old_seed; + + old_seed = get_rand_seed(); + set_rand_seed(rnd_seed); + + d = LAND_X_MAX / 8; + + for (y = 0; y <= LAND_Y_MAX; y += d) + for (x = 0; x <= LAND_X_MAX; x += d) + landscape[x][y] = randint() & 255; + + for (y = 0; y < LAND_Y_MAX; y += d) + for (x = 0; x < LAND_X_MAX; x += d) + midpoint_square (x,y,d); + + for (y = 0; y <= LAND_Y_MAX; y++) + { + for (x = 0; x <= LAND_X_MAX; x++) + { + dist = x*x + y*y; + dark = dist > 10000; + h = landscape[x][y]; + if (h > 166) + landscape[x][y] = dark ? GFX_COL_GREEN_1 : GFX_COL_GREEN_2; + else + landscape[x][y] = dark ? GFX_COL_BLUE_2 : GFX_COL_BLUE_1; + + } + } + + set_rand_seed (old_seed); +} + + +void generate_landscape (int rnd_seed) +{ + switch (planet_render_style) + { + case 0: /* Wireframe... do nothing for now... */ + break; + + case 1: + /* generate_green_landscape (); */ + break; + + case 2: + generate_snes_landscape(); + break; + + case 3: + generate_fractal_landscape (rnd_seed); + break; + } +} + + + +/* + * Draw a line of the planet with appropriate rotation. + */ + + +void render_planet_line (int xo, int yo, int x, int y, int radius, int vx, int vy) +{ + int lx, ly; + int rx, ry; + int colour; + int sx,sy; + int ex; + int div; + + sy = y + yo; + + if ((sy < GFX_VIEW_TY + GFX_Y_OFFSET) || + (sy > GFX_VIEW_BY + GFX_Y_OFFSET)) + return; + + sx = xo - x; + ex = xo + x; + + rx = -x * vx - y * vy; + ry = -x * vy + y * vx; + rx += radius << 16; + ry += radius << 16; + div = radius << 10; /* radius * 2 * LAND_X_MAX >> 16 */ + + + for (; sx <= ex; sx++) + { + if ((sx >= (GFX_VIEW_TX + GFX_X_OFFSET)) && (sx <= (GFX_VIEW_BX + GFX_X_OFFSET))) + { + lx = rx / div; + ly = ry / div; + colour = landscape[lx][ly]; + + gfx_fast_plot_pixel (sx, sy, colour); + } + rx += vx; + ry += vy; + } +} + + +/* + * Draw a solid planet. Based on Doros circle drawing alogorithm. + */ + +void render_planet (int xo, int yo, int radius, struct vector *vec) +{ + int x,y; + int s; + int vx,vy; + + xo += GFX_X_OFFSET; + yo += GFX_Y_OFFSET; + + vx = vec[1].x * 65536; + vy = vec[1].y * 65536; + + s = radius; + x = radius; + y = 0; + + s -= x + x; + while (y <= x) + { + render_planet_line (xo, yo, x, y, radius, vx, vy); + render_planet_line (xo, yo, x,-y, radius, vx, vy); + render_planet_line (xo, yo, y, x, radius, vx, vy); + render_planet_line (xo, yo, y,-x, radius, vx, vy); + + s += y + y + 1; + y++; + if (s >= 0) + { + s -= x + x + 2; + x--; + } + } +} + + +/* + * Draw a wireframe planet. + * At the moment we just draw a circle. + * Need to add in the two arcs that the original Elite had. + */ + +void draw_wireframe_planet (int xo, int yo, int radius, struct vector *vec) +{ + gfx_draw_circle (xo, yo, radius, GFX_COL_WHITE); +} + + +/* + * Draw a planet. + * We can currently do three different types of planet... + * - Wireframe. + * - Fractal landscape. + * - SNES Elite style. + */ + +void draw_planet (struct univ_object *planet) +{ + int x,y; + int radius; + + x = (planet->location.x * 256) / planet->location.z; + y = (planet->location.y * 256) / planet->location.z; + + y = -y; + + x += 128; + y += 96; + + x *= GFX_SCALE; + y *= GFX_SCALE; + + radius = 6291456 / planet->distance; +// radius = 6291456 / ship_vec.z; /* Planets are BIG! */ + + radius *= GFX_SCALE; + + if ((x + radius < 0) || + (x - radius > 511) || + (y + radius < 0) || + (y - radius > 383)) + return; + + switch (planet_render_style) + { + case 0: + draw_wireframe_planet (x, y, radius, planet->rotmat); + break; + + case 1: + gfx_draw_filled_circle (x, y, radius, GFX_COL_GREEN_1); + break; + + case 2: + case 3: + render_planet (x, y, radius, planet->rotmat); + break; + } +} + + +void render_sun_line (int xo, int yo, int x, int y, int radius) +{ + int sy = yo + y; + int sx,ex; + int colour; + int dx,dy; + int distance; + int inner,outer; + int inner2; + int mix; + + if ((sy < GFX_VIEW_TY + GFX_Y_OFFSET) || + (sy > GFX_VIEW_BY + GFX_Y_OFFSET)) + return; + + sx = xo - x; + ex = xo + x; + + sx -= (radius * (2 + (randint() & 7))) >> 8; + ex += (radius * (2 + (randint() & 7))) >> 8; + + if ((sx > GFX_VIEW_BX + GFX_X_OFFSET) || + (ex < GFX_VIEW_TX + GFX_X_OFFSET)) + return; + + if (sx < GFX_VIEW_TX + GFX_X_OFFSET) + sx = GFX_VIEW_TX + GFX_X_OFFSET; + + if (ex > GFX_VIEW_BX + GFX_X_OFFSET) + ex = GFX_VIEW_BX + GFX_X_OFFSET; + + inner = (radius * (200 + (randint() & 7))) >> 8; + inner *= inner; + + inner2 = (radius * (220 + (randint() & 7))) >> 8; + inner2 *= inner2; + + outer = (radius * (239 + (randint() & 7))) >> 8; + outer *= outer; + + dy = y * y; + dx = sx - xo; + + for (; sx <= ex; sx++,dx++) + { + mix = (sx ^ y) & 1; + distance = dx * dx + dy; + + if (distance < inner) + colour = GFX_COL_WHITE; + else if (distance < inner2) + colour = GFX_COL_YELLOW_4; + else if (distance < outer) + colour = GFX_ORANGE_3; + else + colour = mix ? GFX_ORANGE_1 : GFX_ORANGE_2; + + gfx_fast_plot_pixel (sx, sy, colour); + } +} + + +void render_sun (int xo, int yo, int radius) +{ + int x,y; + int s; + + xo += GFX_X_OFFSET; + yo += GFX_Y_OFFSET; + + s = -radius; + x = radius; + y = 0; + + // s -= x + x; + while (y <= x) + { + render_sun_line (xo, yo, x, y, radius); + render_sun_line (xo, yo, x,-y, radius); + render_sun_line (xo, yo, y, x, radius); + render_sun_line (xo, yo, y,-x, radius); + + s += y + y + 1; + y++; + if (s >= 0) + { + s -= x + x + 2; + x--; + } + } +} + + + +void draw_sun (struct univ_object *planet) +{ + int x,y; + int radius; + + x = (planet->location.x * 256) / planet->location.z; + y = (planet->location.y * 256) / planet->location.z; + + y = -y; + + x += 128; + y += 96; + + x *= GFX_SCALE; + y *= GFX_SCALE; + + radius = 6291456 / planet->distance; + + radius *= GFX_SCALE; + + if ((x + radius < 0) || + (x - radius > 511) || + (y + radius < 0) || + (y - radius > 383)) + return; + + render_sun (x, y, radius); +} + + + +void draw_explosion (struct univ_object *univ) +{ + int i; + int z; + int q; + int pr; + int px,py; + int cnt; + int sizex,sizey,psx,psy; + Matrix trans_mat; + int sx,sy; + double rx,ry,rz; + int visible[32]; + struct vector vec; + struct vector camera_vec; + double cos_angle; + double tmp; + struct ship_face_normal *ship_norm; + struct ship_point *sp; + struct ship_data *ship; + int np; + int old_seed; + + + if (univ->exp_delta > 251) + { + univ->flags |= FLG_REMOVE; + return; + } + + univ->exp_delta += 4; + + if (univ->location.z <= 0) + return; + + ship = ship_list[univ->type]; + + for (i = 0; i < 3; i++) + trans_mat[i] = univ->rotmat[i]; + + camera_vec = univ->location; + mult_vector (&camera_vec, trans_mat); + camera_vec = unit_vector (&camera_vec); + + ship_norm = ship->normals; + + for (i = 0; i < ship->num_faces; i++) + { + vec.x = ship_norm[i].x; + vec.y = ship_norm[i].y; + vec.z = ship_norm[i].z; + + vec = unit_vector (&vec); + cos_angle = vector_dot_product (&vec, &camera_vec); + + visible[i] = (cos_angle < -0.13); + } + + tmp = trans_mat[0].y; + trans_mat[0].y = trans_mat[1].x; + trans_mat[1].x = tmp; + + tmp = trans_mat[0].z; + trans_mat[0].z = trans_mat[2].x; + trans_mat[2].x = tmp; + + tmp = trans_mat[1].z; + trans_mat[1].z = trans_mat[2].y; + trans_mat[2].y = tmp; + + sp = ship->points; + np = 0; + + for (i = 0; i < ship->num_points; i++) + { + if (visible[sp[i].face1] || visible[sp[i].face2] || + visible[sp[i].face3] || visible[sp[i].face4]) + { + vec.x = sp[i].x; + vec.y = sp[i].y; + vec.z = sp[i].z; + + mult_vector (&vec, trans_mat); + + rx = vec.x + univ->location.x; + ry = vec.y + univ->location.y; + rz = vec.z + univ->location.z; + + sx = (rx * 256) / rz; + sy = (ry * 256) / rz; + + sy = -sy; + + sx += 128; + sy += 96; + + sx *= GFX_SCALE; + sy *= GFX_SCALE; + + point_list[np].x = sx; + point_list[np].y = sy; + np++; + } + } + + + z = (int)univ->location.z; + + if (z >= 0x2000) + q = 254; + else + q = (z / 32) | 1; + + pr = (univ->exp_delta * 256) / q; + +// if (pr > 0x1C00) +// q = 254; +// else + + q = pr / 32; + + old_seed = get_rand_seed(); + set_rand_seed (univ->exp_seed); + + for (cnt = 0; cnt < np; cnt++) + { + sx = point_list[cnt].x; + sy = point_list[cnt].y; + + for (i = 0; i < 16; i++) + { + px = rand255() - 128; + py = rand255() - 128; + + px = (px * q) / 256; + py = (py * q) / 256; + + px = px + px + sx; + py = py + py + sy; + + sizex = (randint() & 1) + 1; + sizey = (randint() & 1) + 1; + + for (psy = 0; psy < sizey; psy++) + for (psx = 0; psx < sizex; psx++) + gfx_plot_pixel (px+psx, py+psy, GFX_COL_WHITE); + } + } + + set_rand_seed (old_seed); +} + + + +/* + * Draws an object in the universe. + * (Ship, Planet, Sun etc). + */ + +void draw_ship (struct univ_object *ship) +{ + + if ((current_screen != SCR_FRONT_VIEW) && (current_screen != SCR_REAR_VIEW) && + (current_screen != SCR_LEFT_VIEW) && (current_screen != SCR_RIGHT_VIEW) && + (current_screen != SCR_INTRO_ONE) && (current_screen != SCR_INTRO_TWO) && + (current_screen != SCR_GAME_OVER) && (current_screen != SCR_ESCAPE_POD)) + return; + + if ((ship->flags & FLG_DEAD) && !(ship->flags & FLG_EXPLOSION)) + { + ship->flags |= FLG_EXPLOSION; + ship->exp_seed = randint(); + ship->exp_delta = 18; + } + + if (ship->flags & FLG_EXPLOSION) + { + draw_explosion (ship); + return; + } + + if (ship->location.z <= 0) /* Only display ships in front of us. */ + return; + + if (ship->type == SHIP_PLANET) + { + draw_planet (ship); + return; + } + + if (ship->type == SHIP_SUN) + { + draw_sun (ship); + return; + } + + if ((fabs(ship->location.x) > ship->location.z) || /* Check for field of vision. */ + (fabs(ship->location.y) > ship->location.z)) + return; + + if (wireframe) + draw_wireframe_ship (ship); + else + draw_solid_ship (ship); +} + diff --git a/threed.h b/threed.h new file mode 100644 index 0000000..ef7f1db --- /dev/null +++ b/threed.h @@ -0,0 +1,24 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + */ + + +#ifndef THREED_H +#define THREED_H + +#include "space.h" + +void draw_ship (struct univ_object *ship); +void generate_landscape (int rnd_seed); + +#endif + diff --git a/trade.c b/trade.c new file mode 100644 index 0000000..86c6863 --- /dev/null +++ b/trade.c @@ -0,0 +1,191 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * trade.c + */ + +#include + +#include "config.h" +#include "gfx.h" +#include "elite.h" +#include "trade.h" +#include "docked.h" +#include "planet.h" +#include "space.h" +#include "sound.h" +#include "random.h" +#include "main.h" +#include "swat.h" + +#define SLAVES 3 +#define NARCOTICS 6 +#define FIREARMS 10 + +/* + * The following holds the Elite Planet Stock Market. + */ + +#define TONNES 0 +#define KILOGRAMS 1 +#define GRAMS 2 + +struct stock_item stock_market[NO_OF_STOCK_ITEMS]= +{ + {"Food", 0, 0, 19, -2, 6, 0x01, TONNES}, + {"Textiles", 0, 0, 20, -1, 10, 0x03, TONNES}, + {"Radioactives", 0, 0, 65, -3, 2, 0x07, TONNES}, + {"Slaves", 0, 0, 40, -5, 226, 0x1F, TONNES}, + {"Liquor/Wines", 0, 0, 83, -5, 251, 0x0F, TONNES}, + {"Luxuries", 0, 0, 196, 8, 54, 0x03, TONNES}, + {"Narcotics", 0, 0, 235, 29, 8, 0x78, TONNES}, + {"Computers", 0, 0, 154, 14, 56, 0x03, TONNES}, + {"Machinery", 0, 0, 117, 6, 40, 0x07, TONNES}, + {"Alloys", 0, 0, 78, 1, 17, 0x1F, TONNES}, + {"Firearms", 0, 0, 124, 13, 29, 0x07, TONNES}, + {"Furs", 0, 0, 176, -9, 220, 0x3F, TONNES}, + {"Minerals", 0, 0, 32, -1, 53, 0x03, TONNES}, + {"Gold", 0, 0, 97, -1, 66, 0x07, KILOGRAMS}, + {"Platinum", 0, 0, 171, -2, 55, 0x1F, KILOGRAMS}, + {"Gem-Stones", 0, 0, 45, -1, 250, 0x0F, GRAMS}, + {"Alien Items", 0, 0, 53, 15, 192, 0x07, TONNES}, +}; + + + + +/* + * Generate the Elite stock market. + * The prices and quantities are affected by the planet's economy. + * There is also a slight amount of randomness added in. + * The random value is changed each time we hyperspace. + */ + + +void generate_stock_market (void) +{ + int quant; + int price; + int i; + + for (i = 0; i < NO_OF_STOCK_ITEMS; i++) + { + price = stock_market[i].base_price; /* Start with the base price */ + price += cmdr.market_rnd & stock_market[i].mask; /* Add in a random amount */ + price += current_planet_data.economy * stock_market[i].eco_adjust; /* Adjust for planet economy */ + price &= 255; /* Only need bottom 8 bits */ + + quant = stock_market[i].base_quantity; /* Start with the base quantity */ + quant += cmdr.market_rnd & stock_market[i].mask; /* Add in a random amount */ + quant -= current_planet_data.economy * stock_market[i].eco_adjust; /* Adjust for planet economy */ + quant &= 255; /* Only need bottom 8 bits */ + + if (quant > 127) /* In an 8-bit environment '>127' would be negative */ + quant = 0; /* So we set it to a minimum of zero. */ + + quant &= 63; /* Quantities range from 0..63 */ + + stock_market[i].current_price = price * 4; + stock_market[i].current_quantity = quant; + } + + + /* Alien Items are never available for purchase... */ + + stock_market[ALIEN_ITEMS_IDX].current_quantity = 0; +} + + + +void set_stock_quantities(int *quant) +{ + int i; + + for (i = 0; i < NO_OF_STOCK_ITEMS; i++) + stock_market[i].current_quantity = quant[i]; + + stock_market[ALIEN_ITEMS_IDX].current_quantity = 0; +} + + +int carrying_contraband (void) +{ + return (cmdr.current_cargo[SLAVES] + cmdr.current_cargo[NARCOTICS]) * 2 + + cmdr.current_cargo[FIREARMS]; +} + + +int total_cargo (void) +{ + int i; + int cargo_held; + + cargo_held = 0; + for (i = 0; i < 17; i++) + { + if ((cmdr.current_cargo[i] > 0) && + (stock_market[i].units == TONNES)) + { + cargo_held += cmdr.current_cargo[i]; + } + } + + return cargo_held; +} + + +void scoop_item (int un) +{ + int type; + int trade; + + if (universe[un].flags & FLG_DEAD) + return; + + type = universe[un].type; + + if (type == SHIP_MISSILE) + return; + + if ((cmdr.fuel_scoop == 0) || (universe[un].location.y >= 0) || + (total_cargo() == cmdr.cargo_capacity)) + { + explode_object (un); + damage_ship (128 + (universe[un].energy / 2), universe[un].location.z > 0); + return; + } + + if (type == SHIP_CARGO) + { + trade = rand255() & 7; + cmdr.current_cargo[trade]++; + info_message (stock_market[trade].name); + remove_ship (un); + return; + } + + if (ship_list[type]->scoop_type != 0) + { + trade = ship_list[type]->scoop_type + 1; + cmdr.current_cargo[trade]++; + info_message (stock_market[trade].name); + remove_ship (un); + return; + } + + explode_object (un); + damage_ship (universe[un].energy / 2, universe[un].location.z > 0); +} + diff --git a/trade.h b/trade.h new file mode 100644 index 0000000..6a70c87 --- /dev/null +++ b/trade.h @@ -0,0 +1,47 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + * + */ + +/* + * trade.h + */ + +#ifndef TRADE_H +#define TRADE_H + +struct stock_item +{ + char name[16]; + int current_quantity; + int current_price; + int base_price; + int eco_adjust; + int base_quantity; + int mask; + int units; +}; + + +#define NO_OF_STOCK_ITEMS 17 +#define ALIEN_ITEMS_IDX 16 + +extern struct stock_item stock_market[NO_OF_STOCK_ITEMS]; + +void generate_stock_market (void); +void set_stock_quantities(int *quant); +int carrying_contraband (void); +int total_cargo (void); +void scoop_item (int un); + +#endif + diff --git a/vector.c b/vector.c new file mode 100644 index 0000000..95f824b --- /dev/null +++ b/vector.c @@ -0,0 +1,176 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + */ + + +/* + * The original Elite code did all the vector calculations using 8-bit integers. + * + * Writing all the routines in C to use 8 bit ints would have been fairly pointless. + * I have, therefore, written a new set of routines which use floating point math. + */ + +#include +#include + +#include "config.h" +#include "vector.h" + + + +static Matrix start_matrix = +{ + {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0,-1.0} +}; + + + +/* + * Multiply first matrix by second matrix. + * Put result into first matrix. + */ + + +void mult_matrix (struct vector *first, struct vector *second) +{ + int i; + Matrix rv; + + for (i = 0; i < 3; i++) + { + + rv[i].x = (first[0].x * second[i].x) + + (first[1].x * second[i].y) + + (first[2].x * second[i].z); + + rv[i].y = (first[0].y * second[i].x) + + (first[1].y * second[i].y) + + (first[2].y * second[i].z); + + rv[i].z = (first[0].z * second[i].x) + + (first[1].z * second[i].y) + + (first[2].z * second[i].z); + } + + for (i = 0; i < 3; i++) + first[i] = rv[i]; +} + + + + +void mult_vector (struct vector *vec, struct vector *mat) +{ + double x; + double y; + double z; + + x = (vec->x * mat[0].x) + + (vec->y * mat[0].y) + + (vec->z * mat[0].z); + + y = (vec->x * mat[1].x) + + (vec->y * mat[1].y) + + (vec->z * mat[1].z); + + z = (vec->x * mat[2].x) + + (vec->y * mat[2].y) + + (vec->z * mat[2].z); + + vec->x = x; + vec->y = y; + vec->z = z; +} + + +/* + * Calculate the dot product of two vectors sharing a common point. + * Returns the cosine of the angle between the two vectors. + */ + + +double vector_dot_product (struct vector *first, struct vector *second) +{ + return (first->x * second->x) + (first->y * second->y) + (first->z * second->z); +} + + + +/* + * Convert a vector into a vector of unit (1) length. + */ + +struct vector unit_vector (struct vector *vec) +{ + double lx,ly,lz; + double uni; + struct vector res; + + lx = vec->x; + ly = vec->y; + lz = vec->z; + + uni = sqrt (lx * lx + ly * ly + lz * lz); + + res.x = lx / uni; + res.y = ly / uni; + res.z = lz / uni; + + return res; +} + + + + + +void set_init_matrix (struct vector *mat) +{ + int i; + + for (i = 0; i < 3; i++) + mat[i] = start_matrix[i]; +} + + + +void tidy_matrix (struct vector *mat) +{ + mat[2] = unit_vector (&mat[2]); + + if ((mat[2].x > -1) && (mat[2].x < 1)) + { + if ((mat[2].y > -1) && (mat[2].y < 1)) + { + mat[1].z = -(mat[2].x * mat[1].x + mat[2].y * mat[1].y) / mat[2].z; + } + else + { + mat[1].y = -(mat[2].x * mat[1].x + mat[2].z * mat[1].z) / mat[2].y; + } + } + else + { + mat[1].x = -(mat[2].y * mat[1].y + mat[2].z * mat[1].z) / mat[2].x; + } + + mat[1] = unit_vector (&mat[1]); + + + /* xyzzy... nothing happens. :-)*/ + + mat[0].x = mat[1].y * mat[2].z - mat[1].z * mat[2].y; + mat[0].y = mat[1].z * mat[2].x - mat[1].x * mat[2].z; + mat[0].z = mat[1].x * mat[2].y - mat[1].y * mat[2].x; +} + diff --git a/vector.h b/vector.h new file mode 100644 index 0000000..e1b5a69 --- /dev/null +++ b/vector.h @@ -0,0 +1,36 @@ +/* + * Elite - The New Kind. + * + * Reverse engineered from the BBC disk version of Elite. + * Additional material by C.J.Pinder. + * + * The original Elite code is (C) I.Bell & D.Braben 1984. + * This version re-engineered in C by C.J.Pinder 1999-2001. + * + * email: + * + */ + + +#ifndef VECTOR_H +#define VECTOR_H + +struct vector +{ + double x; + double y; + double z; +}; + +typedef struct vector Matrix[3]; +typedef struct vector Vector; + +void mult_matrix (struct vector *first, struct vector *second); +void mult_vector (struct vector *vec, struct vector *mat); +double vector_dot_product (struct vector *first, struct vector *second); +struct vector unit_vector (struct vector *vec); +void set_init_matrix (struct vector *mat); +void tidy_matrix (struct vector *mat); + +#endif +