Initial revision
authormdw <mdw>
Sun, 2 Mar 2003 12:15:41 +0000 (12:15 +0000)
committermdw <mdw>
Sun, 2 Mar 2003 12:15:41 +0000 (12:15 +0000)
82 files changed:
alg_data.h [new file with mode: 0644]
alg_gfx.c [new file with mode: 0644]
alg_main.c [new file with mode: 0644]
alg_main.h [new file with mode: 0644]
beep.wav [new file with mode: 0644]
boop.wav [new file with mode: 0644]
config.h [new file with mode: 0644]
crash.wav [new file with mode: 0644]
data/blake.bmp [new file with mode: 0644]
data/danube.mid [new file with mode: 0644]
data/ecm.bmp [new file with mode: 0644]
data/elitetx3.bmp [new file with mode: 0644]
data/greendot.bmp [new file with mode: 0644]
data/missgrn.bmp [new file with mode: 0644]
data/missred.bmp [new file with mode: 0644]
data/missyell.bmp [new file with mode: 0644]
data/reddot.bmp [new file with mode: 0644]
data/safe.bmp [new file with mode: 0644]
data/theme.mid [new file with mode: 0644]
data/verd2.pcx [new file with mode: 0644]
data/verd4.pcx [new file with mode: 0644]
dock.wav [new file with mode: 0644]
docked.c [new file with mode: 0644]
docked.h [new file with mode: 0644]
ecm.wav [new file with mode: 0644]
elite.c [new file with mode: 0644]
elite.dat [new file with mode: 0644]
elite.h [new file with mode: 0644]
explode.wav [new file with mode: 0644]
file.c [new file with mode: 0644]
file.h [new file with mode: 0644]
gameover.wav [new file with mode: 0644]
gfx.h [new file with mode: 0644]
hitem.wav [new file with mode: 0644]
hyper.wav [new file with mode: 0644]
incom1.wav [new file with mode: 0644]
incom2.wav [new file with mode: 0644]
intro.c [new file with mode: 0644]
intro.h [new file with mode: 0644]
keyboard.c [new file with mode: 0644]
keyboard.h [new file with mode: 0644]
launch.wav [new file with mode: 0644]
main.h [new file with mode: 0644]
makefile [new file with mode: 0644]
makefile-linux [new file with mode: 0644]
menu.h [new file with mode: 0644]
missile.wav [new file with mode: 0644]
missions.c [new file with mode: 0644]
missions.h [new file with mode: 0644]
newkind.cfg [new file with mode: 0644]
newkind.ico [new file with mode: 0644]
newscan.cfg [new file with mode: 0644]
nkres.rc [new file with mode: 0644]
options.c [new file with mode: 0644]
options.h [new file with mode: 0644]
pilot.c [new file with mode: 0644]
pilot.h [new file with mode: 0644]
planet.c [new file with mode: 0644]
planet.h [new file with mode: 0644]
pulse.wav [new file with mode: 0644]
random.c [new file with mode: 0644]
random.h [new file with mode: 0644]
readme.txt [new file with mode: 0644]
scanner.bmp [new file with mode: 0644]
shipdata.c [new file with mode: 0644]
shipdata.h [new file with mode: 0644]
shipface.c [new file with mode: 0644]
shipface.h [new file with mode: 0644]
sound.c [new file with mode: 0644]
sound.h [new file with mode: 0644]
space.c [new file with mode: 0644]
space.h [new file with mode: 0644]
stars.c [new file with mode: 0644]
stars.h [new file with mode: 0644]
swat.c [new file with mode: 0644]
swat.h [new file with mode: 0644]
threed.c [new file with mode: 0644]
threed.h [new file with mode: 0644]
trade.c [new file with mode: 0644]
trade.h [new file with mode: 0644]
vector.c [new file with mode: 0644]
vector.h [new file with mode: 0644]

diff --git a/alg_data.h b/alg_data.h
new file mode 100644 (file)
index 0000000..fd24597
--- /dev/null
@@ -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 (file)
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: <christian@newkind.co.uk>
+ *
+ * Routines for drawing anti-aliased lines and circles by T.Harte.
+ *
+ **/
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <ctype.h>
+
+#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 (file)
index 0000000..ef1246e
--- /dev/null
@@ -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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * alg_main.c
+ *
+ * Allegro version of the main game handler.
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h> 
+#include <ctype.h>
+#include <time.h>
+#include <stdlib.h>
+
+#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 (file)
index 0000000..a359d3d
--- /dev/null
@@ -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 (file)
index 0000000..71a3d4b
Binary files /dev/null and b/beep.wav differ
diff --git a/boop.wav b/boop.wav
new file mode 100644 (file)
index 0000000..d130333
Binary files /dev/null and b/boop.wav differ
diff --git a/config.h b/config.h
new file mode 100644 (file)
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: <christian@newkind.co.uk>
+ *
+ **/
+
+/*
+ * 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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
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 (file)
index 0000000..9a6c1df
Binary files /dev/null and b/dock.wav differ
diff --git a/docked.c b/docked.c
new file mode 100644 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <ctype.h>
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+#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 (file)
index 0000000..37f7990
Binary files /dev/null and b/ecm.wav differ
diff --git a/elite.c b/elite.c
new file mode 100644 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+#include <stdlib.h>
+
+#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 (&current_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 (file)
index 0000000..8475074
Binary files /dev/null and b/elite.dat differ
diff --git a/elite.h b/elite.h
new file mode 100644 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+#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 (file)
index 0000000..5a7922b
Binary files /dev/null and b/explode.wav differ
diff --git a/file.c b/file.c
new file mode 100644 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * file.c
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * 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 (file)
index 0000000..300a0a8
Binary files /dev/null and b/gameover.wav differ
diff --git a/gfx.h b/gfx.h
new file mode 100644 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+
+/**
+ *
+ * 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 (file)
index 0000000..1852ea0
Binary files /dev/null and b/hitem.wav differ
diff --git a/hyper.wav b/hyper.wav
new file mode 100644 (file)
index 0000000..ef40800
Binary files /dev/null and b/hyper.wav differ
diff --git a/incom1.wav b/incom1.wav
new file mode 100644 (file)
index 0000000..87abce5
Binary files /dev/null and b/incom1.wav differ
diff --git a/incom2.wav b/incom2.wav
new file mode 100644 (file)
index 0000000..ee1210a
Binary files /dev/null and b/incom2.wav differ
diff --git a/intro.c b/intro.c
new file mode 100644 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+ /*
+  * intro.c
+  *
+  * Run the two intro screens.
+  * First is a rolling Cobra MkIII.
+  * Second is a parade of the various ships.
+  *
+  */
+#include <stdlib.h>
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+#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 (file)
index 0000000..d0dae25
--- /dev/null
@@ -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: <christian@newkind.co.uk>
+ *
+ */
+
+/*
+ * keyboard.c
+ *
+ * Code to handle keyboard input.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#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 (file)
index 0000000..7d0cdd2
--- /dev/null
@@ -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: <christian@newkind.co.uk>
+ *
+ */
+
+/*
+ * 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 (file)
index 0000000..9ea99dc
Binary files /dev/null and b/launch.wav differ
diff --git a/main.h b/main.h
new file mode 100644 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+#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 (file)
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 (file)
index 0000000..ca806aa
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..0d756e6
Binary files /dev/null and b/missile.wav differ
diff --git a/missions.c b/missions.c
new file mode 100644 (file)
index 0000000..ea36df6
--- /dev/null
@@ -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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * missions.c
+ *
+ * Code to handle the special missions.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#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 (file)
index 0000000..ae3bfff
--- /dev/null
@@ -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 (file)
index 0000000..d30c9e6
--- /dev/null
@@ -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 (file)
index 0000000..16338a2
Binary files /dev/null and b/newkind.ico differ
diff --git a/newscan.cfg b/newscan.cfg
new file mode 100644 (file)
index 0000000..c1300be
--- /dev/null
@@ -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 (file)
index 0000000..120b239
--- /dev/null
+++ b/nkres.rc
@@ -0,0 +1 @@
+NKICON ICON "newkind.ico"\r
diff --git a/options.c b/options.c
new file mode 100644 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * Options.c
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * 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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * 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 <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * 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 (file)
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: <christian@newkind.co.uk>
+ *
+ */
+
+/*
+ *
+ * Handle the generation of planet info...
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+#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 (file)
index 0000000..c9c9e8b
Binary files /dev/null and b/pulse.wav differ
diff --git a/random.c b/random.c
new file mode 100644 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * random.c
+ */
+#include <stdlib.h>
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * 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 (file)
index 0000000..0a21095
--- /dev/null
@@ -0,0 +1,300 @@
+Elite - The New Kind   Release 1.0\r
+--------------------   -----------\r
+\r
+Revision date: 22 July 2001\r
+\r
+This is release 1.0 of Elite - The New Kind.\r
+For changes since previous releases see below.\r
+\r
+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.\r
+\r
+newkind.zip contains source code for Elite - The New Kind.\r
+If you want to recompile the game then please note the following...\r
+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.\r
+b. You need the WIP version of Allegro to compile the code.\r
+\r
+The latest versions of the source and executable can always be found on the New Kind website...\r
+http://www.newkind.co.uk\r
+\r
+To run the supplied executable you will need DirectX installed.  Windows 98/ME/2000 and NT 4 (with latest service pack) come with this.\r
+If you are using Windows 95 and you haven't already installed DirectX you will need to do so.\r
+The DirectX runtime can be downloaded from the Microsoft website. (www.microsoft.com/directx).\r
+\r
+Two pieces of music are included in Elite - The New Kind.  The Elite Theme and The Blue Danube.\r
+The Elite Theme was composed by Aidan Bell and the Blue Danube was composed by Strauss.\r
+I spent a long time hunting for the best MIDI versions of these pieces I could find.\r
+To appreciate them properly you will need a decent Soft Synth Midi driver installed and set as you prefered Midi and Sound device.\r
+\r
+Keys you can use...\r
+Press Y or N on the intro screen.\r
+Press Space on the ship parade screen.\r
+\r
+F1  - Launch when docked, Front View when in flight.\r
+F2  - Rear View\r
+F3  - Left View\r
+F4  - Right View when in flight.\r
+       When docked, Buy Equipment for ship.\r
+      Use up and down arrow keys to select item, return/enter key to buy.\r
+F5  - Display Galactic Chart.\r
+F6  - Short Range Chart.\r
+F7  - Show information on selected planet.\r
+F8  - Buy and sell items on the stock market.\r
+      Use up and down arrow keys to select item, right arrow key to buy, left arrow key to sell.\r
+F9  - Commander information.\r
+F10 - Inventory.\r
+F11 - Options screen (Save Game, Load Game, Game Settings, Quit).\r
+      Use up and down arrows keys to select option, return/enter to select.\r
+\r
+ A - Fire.\r
+ S - Dive.\r
+ X - Climb.\r
+ < - Roll Left\r
+ > - Roll Right\r
+ / - Slow Down\r
+Space - Speed up.\r
+\r
+ C  - Activate docking computer, if fitted.\r
+ D  - De-activate docking computer if switched on.\r
+ E  - Active ECM, if fitted.\r
+ H  - Hyperspace.\r
+ J  - Warp Jump.\r
+ M  - Fire missile.\r
+ T  - Target a missile.\r
+ U  - Un-target missile.\r
+TAB - Detonate energy bomb, if fitted.\r
+CTRL+H - Galactic Hyperspace, if fitted.\r
+ESC - Launch escape capsule, if fitted.\r
+ P  - Pause game.\r
+ R  - Resume game when paused.\r
+\r
+On The Chart Screens\r
+--------------------\r
+D - Select a planet and show distance to it.\r
+F - Find planet by name.\r
+O - Return cursor to current planet.\r
+Cursor Keys - Move cross hairs around.\r
+\r
+\r
+On The Game Settings Screen\r
+---------------------------\r
+From the Options Screen (F11) you can enter the Game Settings Screen. From here you can change\r
+a number of settings that control how the game looks and plays.  Use the cursor keys to select an option\r
+and the Enter/Return key to change it. The options can be saved as default for future games by pressing Enter\r
+while on the Save Settings option (NB this is not necessary if you want to change the settings just for\r
+the current game).  Game settings are held in the newkind.cfg file which should be in the same directory\r
+as the newkind.exe file.\r
+\r
+\r
+\r
+Release 1.0 - Changes since Beta 3.0\r
+====================================\r
+\r
+- Rocks, alloys and boulders no longer stop you from engaging the jump drive.\r
+\r
+- Stopped tactics routine from being called while on the intro screens.\r
+\r
+- Ramming ships was causing little damage to player's ship.  Now fixed.\r
+\r
+- Switching views while in space now switches stars around.\r
+\r
+- Moved all Allegro specific graphic functions into alg_gfx.c\r
+\r
+- Moved keyboard handling routines into keyboard.c\r
+\r
+- Moved file handling routines out of alg_main.c into file.c\r
+\r
+- Added screen to allow player to set the game options from within the game.\r
+  This means the player no longer has to hack newkind.cfg directly.\r
+\r
+- Tidied graphics routines and removed all references to HDC.\r
+\r
+- Fixed movement of crosshairs on chart screens so that they are clipped properly.\r
+\r
+- Added explosion, cargo cannisters and alloys to the game over screen.\r
+\r
+- Added escape capsule sequence.\r
+\r
+- Added option for instant dock vs. auto-pilot docking.\r
+\r
+- Fixed bug that allowed an enemy craft to launch multiple escape capsules.\r
+\r
+- Fixed asteroids so that they move slower and don't try to evade attack.\r
+\r
+- Added rock hermits.\r
+\r
+- Tweaked the tactics routine again.\r
+\r
+- Added limited joystick support (digital only at the moment).\r
+\r
+- Added beep sound when missile target is locked.\r
+\r
+- Added low pitch beep sound when missile is unarmed.\r
+\r
+- Added Energy Low message when enegry levels reach critical.\r
+\r
+\r
+\r
+Beta 3.0 - Changes since Beta 2.1\r
+=================================\r
+\r
+- Fixed bug that allowed lasers to fire too rapidly.\r
+\r
+- The console was not being updated (i.e no of missiles) after a saved commander was loaded.  Now fixed.\r
+\r
+- Added planet auto-select on chart screens ala NES.\r
+\r
+- Asteroid mining implemented.\r
+\r
+- Exploding ships now release alloys.\r
+\r
+- Fixed bug that caused enemy ships to only fire when at close range.\r
+\r
+- Thargoids can now appear.\r
+\r
+- Witchspace ambush added.\r
+\r
+- Anacondas now release worms and sidewinders when attacked.\r
+\r
+- Attacked ships can now release escape capsules.\r
+\r
+- Objects other than cargo cannisters can now be scooped.\r
+\r
+- Corrected condition indicator code.  Was previously showing yellow even after danger had passed.\r
+\r
+- Added ability to pause game (P key pauses, R resumes).\r
+\r
+- The Cougar (a cloaked ship) can now appear.\r
+\r
+- The second mission is now playable.\r
+\r
+- Fixed bug that allowed enemy ships to fire from bizare angles.\r
+\r
+- Rewrote tactics routines. New code now based on NES Elite.\r
+\r
+- Docking computers now use full auto-pilot rather than just instant dock.\r
+\r
+- Space station now launches shuttles and transporters bound for the planet.\r
+\r
+\r
+\r
+Beta 2.1 - Changes since Beta 2.0\r
+=================================\r
+\r
+- Added code to set legal status to clean and fuel to maximum after using an escape capsule.\r
+\r
+- Fixed enemy missile targeting so that other ships don't blow themselves up.\r
+\r
+- Fixed speed of enemy ships which were moving too slowly in previous versions.\r
+\r
+- Added game speed control option to newkind.cfg.\r
+\r
+\r
+Beta 2.0 - Changes since Beta 1.1\r
+=================================\r
+\r
+- Fixed bug in enemy tactics which caused ships to run away.\r
+\r
+- Set the max speed of player's ship to 0.30LM.\r
+\r
+- Added code to display version number on options screen.\r
+\r
+- Corrected spelling of "Feudal".\r
+\r
+- Enabled docking computers (instant dock for the moment).\r
+\r
+- Added hyperspace sound.\r
+\r
+- Changed code to display number of credits instead of bounty.\r
+\r
+- Set hyperspace count down to 15.\r
+\r
+- Added Suns, cabin temperature and fuel scooping.\r
+\r
+- Added left and right views when in flight.\r
+\r
+- Enabled use of Energy Bomb, activated with TAB key.\r
+\r
+- Changed scanner slightly, added code to display objects in different colours.\r
+\r
+- Fixed warping of stars in rear view.\r
+\r
+- Enabled Escape Capsule, use ESC key to abandon ship.\r
+\r
+- Enabled Galactic Hyperspace.\r
+\r
+- Added use of 'O' key on chart screens.\r
+\r
+- Added ability to find planets by name.\r
+\r
+- Added Windows icon created by Marcus Buchanan.\r
+\r
+- Added code by Thomas Harte to anti-alias lines and improve hidden surface removal.\r
+\r
+- Added option to newkind.cfg to enable anti-alias code.\r
+\r
+- Added the first secret mission, hunt the Constrictor!\r
+\r
+- Fixed equipment buying so that refund is given on existing lasers.\r
+\r
+- Changed colour of fuel limit circle from white to green.\r
+\r
+- Put some colour on the Local Chart screen.\r
+\r
+- Changed look of ship lollipops on the scanner to look more like the original.\r
+\r
+- Changed incoming laser sounds, one for hitting shields and one for hitting the hull.\r
+\r
+- Fixed asteroids so that they travel in straight lines.\r
+\r
+- Changed creation of ships so that the appear at more random locations.\r
+\r
+- Removed the Constrictor and the Cougar from the ship parade intro.\r
+\r
+\r
+\r
+Beta 1.1 - Changes since Beta 1.0\r
+=================================\r
+\r
+- Fixed bug in load and save routine which caused the player to aways return to Lave.\r
+\r
+- Fixed bug in equipment buying screen.  Buying military lasers for the side or rear view\r
+  would cause mining lasers to be fitted instead.\r
+\r
+- Renamed files to be all lowercase.  This should ease ports to other OSes.\r
+\r
+- Removed #include of windows only allegro files from alg_main.c\r
+\r
+- Added #ifdef around use of GFX_DIRECTX in alg_main.c to allow compilation on non Windows OSes.\r
+\r
+\r
+\r
+Work in progress\r
+================\r
+\r
+The following features have not yet been implemented but are being currently worked on.\r
+\r
+- C64 Elite style scoring.\r
+\r
+- Trumbles (from C64/NES Elite).\r
+\r
+- View of docking bay after docking.\r
+\r
+- Loading of different consoles not yet fully implemented.\r
+\r
+- Enhance joystick support, i.e. use of more buttons and analogue control.\r
+\r
+\r
+Known Problems\r
+==============\r
+\r
+- Bits of hidden surfaces on ships sometimes show through.\r
+\r
+- Buying more than 255gs of Gold/Platinum doesn't work.\r
+  It didn't in the original Elite either.  Broken as designed.\r
+\r
+\r
+Have fun!\r
+\r
+Christian Pinder.\r
+<christian@newkind.co.uk>\r
+http://www.newkind.co.uk\r
diff --git a/scanner.bmp b/scanner.bmp
new file mode 100644 (file)
index 0000000..17428eb
Binary files /dev/null and b/scanner.bmp differ
diff --git a/shipdata.c b/shipdata.c
new file mode 100644 (file)
index 0000000..b88e29a
--- /dev/null
@@ -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 (file)
index 0000000..eae43e8
--- /dev/null
@@ -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: <christian@newkind.co.uk>
+ *
+ */
+
+
+#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 (file)
index 0000000..01ab277
--- /dev/null
@@ -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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * shipface.c
+ *
+ * Face information for the ships.
+ * Adapted from the Elite ship data published by Ian Bell.
+ *
+ * Adapted further for clockwise vertex lists.
+ */ 
+
+#include <stdlib.h>
+
+#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 (file)
index 0000000..5a4555a
--- /dev/null
@@ -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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * sound.c
+ */
+
+#include <stdlib.h>
+#include <allegro.h>
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * 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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * space.c
+ *
+ * This module handles all the flight system and management of the space universe.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+
+#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 (&current_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 (file)
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: <christian@newkind.co.uk>
+ *
+ */
+
+/*
+ * 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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+#include <stdlib.h>
+#include <math.h>
+
+#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 (file)
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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * swat.c
+ *
+ * Special Weapons And Tactics.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <ctype.h>
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ */
+
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * trade.c
+ */
+
+#include <stdlib.h>
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ *
+ */
+
+/*
+ * 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 (file)
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: <christian@newkind.co.uk>
+ *
+ */
+
+
+/*
+ * 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 <stdlib.h>
+#include <math.h>
+
+#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 (file)
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: <christian@newkind.co.uk>
+ *
+ */
+
+
+#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
+