// This is eng.h CVS version: $Id: eng.h,v 1.2 2000/02/28 17:55:26 andreaha Exp $
#ifndef eng_h_included
#define eng_h_included

#include <iostream.h>
#include <fstream.h>
#include <new.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <unistd.h>

#include "defines.h"

/*-----------------------------------------------------------------*/
/* Debugclass                                                      */
/*-----------------------------------------------------------------*/
class DEbug {
  public:
  
  DEbug *next;
  DEbug *prev;

  int   pushsignature;                                        /* stack signature */
  char  funcname[256];                                        /* name of pushed function */
  
  DEbug(char *);
  ~DEbug();
};

/*-----------------------------------------------------------------*/
/* Linked list library. Uses templates.                            */
/*-----------------------------------------------------------------*/
template <class ElemType>
class List {
  
  class Element {
  public:
    Element *next;                               /* Ptr to next element */
    Element *prev;                               /* Ptr to previous element */
    ElemType *data;                              /* Ptr to this element */

    /**/                                         /* Element constructor */
    Element(ElemType *e) {
      dpush1("World::List::Element()");
      next = NULL;
      data = e;
      dpop();
    }
    
    /**/                                         /* Element destructor */
    ~Element() {
      dpush1("World::List::~Element()");	
      dpop();
    }
  };
  
  /* Data */
  
  Element *first;                                /* Ptr to first element */
  Element *last;                                 /* Ptr to last element */
  Element *current;                              /* Ptr to current element */
  
 public:
  /* Methods */
    
  /**/                                           /* get ptr to first element */
  ElemType *getFirst() {
    dpush1("World::List::getFirst()");
    current = first;
    dpop();
    return current ? current->data : NULL;
  }

  /**/                                           /* get ptr to first element */
  ElemType *getNext() {
    dpush1("World::List::getNext()");

    current = current->next;
    dpop();

    return current ? current->data : NULL;
  }
  
  /**/                                           /* get ptr to last element */
  ElemType *getLast() {
    dpush1("World::List::getLast()");
    dpop();
    return last ? last->data : NULL;
  }
  
  /**/                                           /* Add element */
  void addel(ElemType *e) {
    dpush2("World::List::addel(%#010x)", (int)e);

    Element *el;
    
    if (first == NULL) {
      first = last = new Element(e);
    } else {
      last->next = new Element(e);
      last->next->prev = last;
      el = last;
      last = last->next;
      last->prev = el;
    }
    
    dpop();
  }
  
  /**/                                           /* Remove element */
  void remel(ElemType *e) {
    dpush2("World::List::remel(%#010x)", (int)e);

    Element *el;
    
    if (first == NULL) {
      dpop();
      return;
    }
    
    if (first->data == e) {
      el = first;
      first = first->next;
      if (first == NULL)
	last = NULL;
      else
	first->prev = NULL;

      delete el;
      delete e;
    } else {
      Element *step = first;
      
      while ((step->data != e)&&(step != NULL))
	step = step->next;
      
      if (step == NULL)
	return;
      
      step->prev->next = step->next;
      
      if (step == last) {
	last = step->prev;
	last->prev = step->prev->prev;
      } else
	step->next->prev = step->prev;
      
      delete step;
      delete e;
    }
    
    dpop();
  }
  
  /**/                                           /* Kill list */
  void kill() {
    dpush1("World::List::kill()");
    
    Element *e = first;
    
    while (e != NULL) {
      remel(e->data);
      e = first;
    }
    
    first = last = NULL;
    
    dpop();
  }
  
  /* Constructor, destructor */
  
  /**/                                           /* List Constructor */
  List() {
    dpush1("World::List::List()");
    first = last = NULL;
    dpop();
  }
  
  /**/                                           /* List Destructor */
  ~List() {
    dpush1("World::List::~List()");
    kill();
    dpop();
  }
};

/*-----------------------------------------------------------------*/
/* World / Scene object                                            */
/*-----------------------------------------------------------------*/
class World {
  public:

  class Normal;      /* Vector normal */
  class Object;      /* Mesh structure */
  class Vector;      /* x, y, z */
  class Yvalc;       /* Scanline values */
  class Node;        /* Common node data */
  class Trigon;      /* Trigon / Poly structure */
  class Material;    /* Material / texture */
  class Camera;      /* Camera (Node) */
  class Light;       /* Light (Node) */
  class Vertex;      /* Vertex (Vectors, Normals) */

  /*-----------------------------------------------------------------*/
  /* Mathematical, arithmetical constants.                           */
  /*-----------------------------------------------------------------*/

  static const int BIG    = 1;
  static const int LITTLE = 0;

  static const int OK     = 1;
  static const int ERROR  = 0;

  static const int TRUE   = 1;  
  static const int FALSE  = 0;

  static inline float DEG2RAD(float deg) {
    static float pi = 3.1415927;
    return (deg * pi) / 180.0;
  }

  static inline float FOV2FOC(float width, float angle) {
    return (width * cos(angle / 2.0)) / (sin(angle / 2.0) * 2.0);
  }

  static inline int float2fixed(float d) {
    return (int)(d * 65536.0);
  }

  static inline int CEIL(float f) {
    register int i, j;
    
    i = (int )(f * 65536.0);
    j = i >> 16;
    if ((i & 0xffff) != 0) j += 1;
    
    return j;
  }

  /*-----------------------------------------------------------------*/
  /* Y - values                                                      */
  /*-----------------------------------------------------------------*/
  class Yvalc {
    public:
    
    int xl, xr;                                    /* Left & right edges of scanline */
    int u, v;                                      /* Left texture offset */
    int ul, vl;                                    /* ? */
    int zl;                                        /* Left z-buffer value */
    int r;                                         /* Left red value */
    int g;                                         /* Left green value */
    int b;                                         /* Left blue value */
    float zfr;                                     /* Floating z-buffer fraction */
  };

  /*-----------------------------------------------------------------*/
  /* Color                                                           */
  /*-----------------------------------------------------------------*/
  class Color {
    public:
    
    float r,g,b,a;                               /* color values red, green, blue, alpha */

    void set(float, float, float);               /* set values */
    void set(Color *);
  };

  /*-----------------------------------------------------------------*/
  /* MemChunk                                                        */
  /*-----------------------------------------------------------------*/
  class MemChunk {
    public:

    World *myworld;                              /* ptr to this world */

    size_t size;                                 /* size of memory chunk */
    int *memsize;
    void *memptr;                                /* memory handle */

    MemChunk(World *, size_t);                   /* constructor */
    ~MemChunk();                                 /* destructor */
  };

  /*-----------------------------------------------------------------*/
  /* Quaternion                                                      */
  /*-----------------------------------------------------------------*/
  class Quaternion {
   public:

    float s, x, y, z;                            /* s is real, (x,y,z) imaginary */

    void mulWith(Quaternion *);

    void genIdentity();                          /* generate quaternion identity */
    void genInverseTo(Quaternion *);             /* generate quaternion inverse */

    void printOut();                             /* print all info */
    void reset();                                /* set all == 0 */

    Quaternion();                                /* quat. constructor */
    Quaternion(float, float, float, float);      /* quat. constructor(s, x, y, z) */
    ~Quaternion();                               /* destructor */
  };

  /*-----------------------------------------------------------------*/
  /* Matrix                                                          */
  /*-----------------------------------------------------------------*/
  class Matrix {
    public:

    float m[16];                                 /* matrix represented */

    void reset();                                /* clear matrix content */

    void mulWith(Matrix *);                      /* matrix multiply */
    Matrix operator *(const Matrix &) const;     /* operator override */

    void genIdentity();                          /* create identity */
    void genInverseTo(Matrix *);                 /* generate inverse */
    void genTranslationWith(float,float,float);  /* generate translation */

    void printOut();                             /* print matrix */

    Matrix();                                    /* constructor, do-nothing */
    Matrix(float *);                             /* constructor, transfer */
  };

  /*-----------------------------------------------------------------*/
  /* Material / Texture                                              */
  /*-----------------------------------------------------------------*/
  class Material {
   public:
    static const int PCXFILE = 1;
    static const int GIFFILE = 2;
    static const int UNKNOWN = 42;

    static const int PCXHEADERSIZE = 128;
    static const int GIFHEADERSIZE = 13;

    static const int COUNTER        = 64 + 128;
    static const int STRIPBYTES     = 63;
    static const int IMAGESEPERATOR = 0x2c;

    static inline int WORD(unsigned char *a) {
      return a[0] + (a[1] * 256);
    }

    static inline int WORD(char *a) {
      return a[0] + (a[1] * 256);
    }

    static inline int GCTFLAG(int a) {
      return a & 1;
    }

    static inline int COLORRES(int a) {
      return (a & (1 + 2 + 4)) >> 1; 
    }

    static inline int GCTSORTFLAG(int a) {
      return (a & 16) >> 4;
    }

    static inline int GCTSIZE(int a) {
      return a >> 7;
    }

    static inline int LCTFLAG(int a) {
      return a & 1;
    }

    static inline int INTERLACEFLAG(int a) {
      return (a & 2) >> 1;
    }

    static inline int LCTSORTFLAG(int a) {
      return (a & 4) >> 2;
    }

    class GifHeader {
     public:
      byte signature[3];
      byte version[3];
      
      byte width[2];
      byte height[2];
      
      byte packed;
      byte bgColorIndex;
      byte pixelAspect;      
    };
    
    class PcxHeader {
    public:      
      byte manufacturer;
      byte version;
      byte encoding;
      byte bitsPerPixel;
      
      byte xamin[2], yamin[2];
      byte xamax[2], yamax[2];
      
      byte res[4];
      
      byte colormap[16*3];
      
      byte reserved;
      byte nOfPlanes;
      byte bpla[2];
      byte p1, p2;
      
      byte filler[58];
      
      word xmin, ymin;
      word xmax, ymax;
      word bytesPerLine;
    };
    
    class PixFile {
      int memAlloc;
      int isSignature(char *);
      
    public:
      
      World *myworld;
      
      int loaded;
      int offsetPtr;
      int fileSize;
      
      byte *output;
      char *fileDump;
      
      byte palette[768];
      
      int imageSize;
      
      int xSize, ySize;
      
      void dumpIt(char *);
      
      char *strapp(char *, char *);
      byte getNextByte();
      int getNextWord();
      void skipBytes(int);
      
      int identified();
      
      int loadPcx();
      int loadGif();
      
      int load(char *);
      int load(char *, int);
      
      void transferPalTo(byte *);
      
      byte *sizeTo(int, int);
      
      PixFile(World *, char *);
      PixFile(World *, char *, int);
      ~PixFile();      
    };

    public:

    World *myworld;                              /* ptr to this world */
    Material *next;                              /* ptr to next material */

    PixFile *p;                                  /* pointer to pixfile element */
    
    char name[32];                               /* material name */
    char filename[32];                           /* file name */
    
    int txt  [256 * 256];                        /* texture + alpha values */
    int txtm1[128 * 128];                        /* texture + alpha values */
    int txtm2[ 64 *  64];                        /* texture + alpha values */
    int txtm3[ 32 *  32];                        /* texture + alpha values */
    int txtm4[ 16 *  16];                        /* texture + alpha values */
    int txtm5[  8 *   8];                        /* texture + alpha values */
    int txtm6[  4 *   4];                        /* texture + alpha values */
    int txtm7[  2 *   2];                        /* texture + alpha values */
    int txtm8[  1 *   1];                        /* texture + alpha values */

    Color ambient;                               /* ambient coloring */
    Color specular;                              /* specular */
    Color diffuse;                               /* diffuse */

    float shininess;                             /* from 3ds */
    float transparency;
    char twosided;
    char wire;                                   /* wireframe */
    char shading;
    
    void printOut();
    int importFile(char *);                      /* load PCX file */

    Material(World *);                           /* constructor */
    ~Material();                                 /* recursive destructor */
  };


  /*-----------------------------------------------------------------*/
  /* Vector, set of x,y,z                                            */
  /*-----------------------------------------------------------------*/
  class Vector {
    public:

    float x, y, z;
    byte dummy[4];                               /* round up to 2^n */

    void reset();                                /* set all = 0 */

    void set(float, float, float);               /* set x,y,z */
    void set(Vector *);

    void add(float, float, float);               /* add to x,y,z */
    void add(Vector *);
    void sub(float, float, float);               /* subtract from x,y,z */
    void sub(Vector *);

    void mult(int);                              /* multiply all */
    void mult(float);
    void div(int);                               /* divide all */
    void div(float);

    void crossWith(float, float, float);         /* cross product */
    void crossWith(Vector *);

    float dotWith(float, float, float);          /* dot product */
    float dotWith(Vector *);

    void genTransVect(Vector *, Matrix *);       /* generate translation*/
    void genTransform(Matrix *);                 /* generate transformation */

    void normalize();                            /* set length = 1.0 */

    void printOut();                             /* print vector value */

    float length();                              /* length of vector*/

    Vector();                                    /* constructors */
    Vector(float, float, float);                 /*              */

    Vector operator +(const Vector &) const;     /* operator overloads */
    Vector operator -(const Vector &) const;     /* operator overloads */
    /*    int    operator dot(const Vector &) const;*/ /* operator overloads */
    /*Vector operator cross(const Vector &) const;*/ /* operator overloads */
    Vector operator *(float) const;              /* operator overloads */
    Vector operator /(float) const;              /* operator overloads */

  };

  /*-----------------------------------------------------------------*/
  /* Node                                                            */
  /*-----------------------------------------------------------------*/
  class Node {
   public:
    Matrix matrix;                               /* Node matrix */

    char name[64];                               /* Node name */
    Node *parent;                                /* Parent node */

    World *myworld;                              /* Node's world */

    Vector pos;                                  /* Node's position */
    Vector posr;                                 /* Node's translated position */
    Vector rot;                                  /* Node's rotation */

    int parint;                                  /* index of parent object */
    int hierarchnr;                              /* hierarchy nr */

    int donematrix;                              /* Matrix calculated 1|0 */
    int on;                                      /* Node of/off */
    int visible;                                 /* Node visible/not */

    virtual void createMatrix() {}
    virtual ~Node() {}
  };

  /*-----------------------------------------------------------------*/
  /* Normal                                                          */
  /*-----------------------------------------------------------------*/
  class Normal {
    public:

    Vector *pos;                                 /* untouched position */
    Vector *posr;                                /* Translated position */
  };

  /*-----------------------------------------------------------------*/
  /* Vertex, one of three in a trigon                                */
  /*-----------------------------------------------------------------*/
  class Vertex {
    public:

    Color gouraud;                               /* gouraud color vals */
    float alpha;                                 /* alpha value */
    float u, v;                                  /* texture u,v */
    float phong_u, phong_v;                      /* phong u,v values */

    int cyr;                                     /* CEILed y vertex */

    Vector *pos;                                 /* Untouched position */
    Vector *posr;                                /* Translated position */
    Normal normal;                               /* Vertex normal */

    byte dummy[8];                               /* sizeof -> 2^n */

    void set(float, float, float, float, float); /* set x,y,z,u,v */
  };

  /*-----------------------------------------------------------------*/
  /* Light, omnilight (spot?)                                        */
  /*-----------------------------------------------------------------*/
  class Light : public Node {
    public:

    Color color;                                 /* light color */

    float range;                                 /* light range */

    byte dummy[80];                              /* size -> 2^n */

    void createMatrix();
    void set(float,float,float);                 /* set color */
    void printOut();                             /* print light info */

    Light(float,float,float,float);              /* constructor */
    ~Light();                                    /* destructor */
  };

  /*-----------------------------------------------------------------*/
  /* Camera                                                          */
  /*-----------------------------------------------------------------*/
  class Camera : public Node {
    public:

    unsigned int *addbuffer;                     /* sum table */
    Camera **focuscam;                           /* assisting cameras */
    char *divtable;                              /* division table */

    float roll;                                  /* camera roll */
    float fov;                                   /* fieldofview angle */
    float rad;                                   /* Radius for focalcamera */
    float focusscale;

    int focus;                                   /* focus? */

    byte dummy[96];                              /* size -> 2^n */

    Vector *pivot;                               /* pivot */
    Vector offset;                               /* Camera relative position */
    Vector target;                               /* Target */

    void createMatrix();
    void render(void *);                         /* render scene */
    void setRoll(float);                         /* set camera roll */
    void setFocus(int, float);                   /* focus rendering camera? */
    void printOut();

    Camera();                                    /* constructor */
    ~Camera();                                   /* destructor */
  };

  /*-----------------------------------------------------------------*/
  /* Trigon / Polygon                                                */
  /*-----------------------------------------------------------------*/
  class Trigon {
    public:

    World *myworld;                              /* ptr to this world */

    int na, nb, nc;                              /* indexes of corners */
    int ab, bc, ca;                              /* wireframe vals */
    float ua, ub, uc;                            /* u,v at all corners */
    float va, vb, vc;

    int _y1, _y2;                                /* top, bottom y values */
    int z;                                       /* (a+b+c).z / 4 */
    char filltype;                               /* plain, gouraud */

    char visible;                                /* visibility boolean */
    char twosided;                               /* no/yes */
    int flags;                                   /* wrapping flags */
    int mip;                                    

    char clipped;                                /* poly is / is not clipped */

    Vertex *ap, *bp, *cp;                        /* Pointers to ^^ */
    Normal  normal;                              /* Trigon normal */

    Material *txt;                               /* Ptr to 32bit texture */
    Material *shademap;                          /* Ptr to 32bit shademap */

    byte dummy[32];                              /* size -> 2^n */

    void drawIt(int *);                          /* drawfunction */
    void (Trigon::*draw)(int *);                 /* ptr to draw function */
    void (Trigon::*noclip)(int *);               /* no clip draw */

    void setDraw(int);                           /* set poly filltype */
    void printOut();

    /* fill */

    void fillPlain(int *);                       /* plain shading */
    void fillTexture(int *);                     /* texture mapping */
    void fillTextureMip(int *);                  /* texture mapping */
    void fillGouraud(int *);                     /* gouraud shading */
    void fillPhong(int *);                       /* envmap phong */
    void fillTexP(int *);                        /* perspective texture */
    void fillPTex(int *);                        /* phong | texture */
    void fillGTexture(int *);                    /* gouraud | texture */
    void fillGTextureTrans(int *);               /* gouraud | texture | transparent */
    void fillGTextureMip(int *);                 /* gouraud | texture | mip */
    void fillGouraudTransparent(int *);          /* gouraud shading */

    /* fill, no clipping */

    void fillPlainNoClip(int *);                 /* plain shading, unclipped */
    void fillTextureNoClip(int *);               /* texture mapping, unclipped */
    void fillTextureMipNoClip(int *);            /* texture mapping */
    void fillGouraudNoClip(int *);               /* gouraud shading, unclipped */
    void fillPhongNoClip(int *);                 /* envmap phong, unclipped */
    void fillTexPNoClip(int *);                  /* perspective texture, unclipped */
    void fillPTexNoClip(int *);                  /* phong | texture, unclipped */
    void fillGTextureNoClip(int *);              /* gouraud | texture, unclipped */
    void fillGTextureTransNoClip(int *);         /* gouraud | texture | transparent */
    void fillGTextureMipNoClip(int *);           /* gouraud | texture | mip, unclipped */
    void fillGouraudTransparentNoClip(int *);    /* gouraud shading */

    /* scan */

    void phongScanLeft(Vertex *, Vertex *);      /* scan one left texture */
    void texScanLeft(Vertex *, Vertex *);        /* scan one left texture */
    void gTexScanLeft(Vertex *, Vertex *);       /* scan one left texture */
    void gouraudScanLeft(Vertex *, Vertex *);    /* scan one left gouraud */
    void plainScanLeft(Vertex *, Vertex *);      /* scan one left plain */

    void scanRight(Vertex *, Vertex *);          /* scan right */

    /* innerloops */

    int lostPoly();                              /* is poly totally lost? */
  };

  /*-----------------------------------------------------------------*/
  /* 3d mesh object, polys, vertices                                 */
  /*-----------------------------------------------------------------*/
  class Object : public Node {
   public:

    static const int FILEASC = 0;
    static const int FILE3DS = 1;

    Matrix matrix3ds;

    float uvmul;                                 /* uv multiplier */
    float vtxmul;                                /* vertex multiplier */

    int numofverts;                              /* Vertex count */
    int numoftrigons;                            /* Polygon count */
    int numofnorms;                              /* Number of normals */

    Vertex *vertices;                            /* Vertex array */
    Vector *vertvectors;                         /* Vector array */
    Vector *vertvectorsr;                        /* Vector array, translated */
    Vector *normals;                             /* Normal array */
    Vector *normalsr;                            /* Normal array, translated */

    int normstart, normend;                      /* indexes in array */

    float txtscale;                              /* texture scale */

    int filltype;                                /* plain, gouraud */
    int mapped;                                  /* is object mapped? */
    int loadtype;                                /* asc / 3ds */

    Vector pivot;                                /* pivot position */

    /* Bounding sphere */

    float bsrad;                                 /* bounding sphere rad */
    float bsradr;                                /* ...translated */
    Vector bsphere;                              /* bounding sphere center */
    Vector bspherer;                             /* ...translated */
    Vector *transBsph();                         /* transform b-sphere */
    void makeBsphere();                          /* create bounding sphere */

    List<Trigon> trigonlist;                     /* list of trigons */

    byte dummy[143];                             /* size -> 2^n */

    void setMaterial(Material *);                /* set object material */
    void setMaterial(Material *, Material *);    /* set material & shademap */

    void checkForClip();                         /* check poly clip */

    void createMatrix();

    void calcNormals();                          /* calculate normals */

    void scaleTo(float);                         /* set size = float */
    void setFillType(int);                       /* set plain, gouraud etc */
    void redefMapping(float);                    /* give mapping coords */
    void setParent(Object *);                    /* set parent object */

    void printOut();                             /* print object info */
    void calcGouraudValues();                    /* calculate lights */
    void flipNormals();                          /* all normals *= -1 */

    void setMip();                               /* set all MIP maps */

    void reset();                                /* reset object */

    void loadAsc(char *);                        /* load ASC file */
    void load3ds(char *);                        /* load 3DS file */

    Trigon *addpoly(int,int,int,int);            /* add poly to object */
    Trigon *addpoly(int,int,int,int,Object *);   /* add poly to object */

    Material *txt;                               /* ptr to object material */
    Material *shademap;                          /* ptr to shademap */

    Object(World *,char *,float,float);          /* Object contructor */
    ~Object();                                   /* recursive destructor */
  };

  /*-----------------------------------------------------------------*/
  /* Internal utilities.  */
  /*-----------------------------------------------------------------*/
  class Utils {
   public:
    char text[256];

    char *fillstr(int);
    char *bytes(int);
    char *charptr(const char *);

    void saveBufAsPPM24(void *, int, int, char *);

    char *ucase(char *);
    char *lcase(char *);
    
    double getValue(char *, char *);
    void getString(char *, char *, char *);
  };

  /*-----------------------------------------------------------------*/
  /*-----------------------------------------------------------------*/
  /*-----------------------------------------------------------------*/

  /****/ /* data declarations */ /****/

  Color ambient;                                 /* ambient coloring */

  /* rendering */

  int viewx;                                     /* view x */
  int viewy;                                     /* view y */
  int maxx;                                      /* rendx - 1 */ 
  int maxy;                                      /* rendy - 1 */
  int midx;                                      /* center of screen */
  int midy;

  int rendx;                                     /* render horizontal size */
  int rendy;                                     /* render vectical size */

  int rendbpp;                                   /* render bits per pixel */

  float vmul;                                    /* vertical multiplier */
  float hmul;                                    /* horizontal multiplier */

  unsigned int rendbuffersize;                   /* size of rendering buffer */

  unsigned int vrtscrsize;                       /* vrtscr size */
  unsigned int screensize;                       /* rendx * rendy */

  int visibleobjects;                            /* number of visible objects */
  int rendernum;                                 /* number of polys to render */

  int *rendbuffer;                               /* standard 32bit output */
  void *vrtscr;                                  /* restructured output */

  float viewdistancex;
  float viewdistancey;
  
  int antialias;
  int setantialias;

  int upperscanline;
  int lowerscanline;

  int endian;

  /* timers */

  int frame;
  int starttime;

  /* memory */

  int memused;                                   /* all getmem'ed memory */
  int memtotal;                                  /* total memory usage */
  int objectmem;
  int trigonmem;
  int materialmem;
  int lightmem;
  int cameramem;

  /* system booleans */

  char initcalled;                               /* initcalled boolen */

  /* element counters */

  int numoftrigons;                              /* number of trigon objects */
  int numoflights;
  int numofobjects;
  int numofcameras;
  int numofmaterials;

  /* linked lists */

  List<MemChunk> memlist;
  List<Material> matlist;
  List<Object>   objlist;
  List<Light>    lightlist;
  List<Camera>   camlist;

  /* array lists */

  Trigon **trigonlist;                           /* list of all world polys */
  Trigon **sortedlist;                           /* all sorted polys */
  Trigon **renderlist;                           /* renderable polys */

  /* misc */

  int *precy;                                    /* precalculated Y values */
  Yvalc *yval;                                   /* trigon y values */
  unsigned char precc[193];                      /* precalculated x*1.33 table */

  Material *defaultmat;                          /* default texture */
  Camera *activecamera;                          /* active camera */

  int lookup[256 * 256];                         /* color lookup table */

  /* function declarations */
  void genDefaultMaterial();                     /* generate default txt */
  void *getMem(size_t);                          /* rewritten malloc */
  void freeMem(void *);                          /* delete memory  */

  /* Utility object */

  Utils util;                                    /* Used to access non-static funcs */

 public:

  void blitTo(void *);                           /* Blit to this screen */
  void saveBufAsPPM24(char *);                   /* Save as PPM */

  void dumpSizes();                              /* Dump structure sizes */

  void printOut();

  void genLookUp();                              /* generate lookup table */

  void setActiveCamera(Camera *);                /* active camera */
  void init();                                   /* prepare for render */

  void setRend(int, int, int);                   /* set render info */

  void *getVrtScr();                             /* return ptr to vrtscr */

  void setAntiAlias(int);                        /* switch on / off antialias */
  void render();                                 /* render world */
  void render(void *);                           /* render to external buffer */
  void (World::*blit)(void *);                   /* ptr to member function */

  void antiFlip(void *, void *, int, int);       /* scale down 2x2 bytes */

  /* internal blit translations */
 private:

  void setConstants();                           /* set all "constants'" values */
  void reset();                                  /* reset world */
  void rotate();                                 /* rotate and translate all vertices */
  void cullBackFaces();                          /* cull backfaces */
  void makeRenderList();                         /* find which polys to render */
  void sort();                                   /* radix sort polys */
  void eliminateLostObjects();                   /* remove objects outside FOV */
  void wrappingCorrection();                     /* corrigate wrapping error */

  void floydSteinbergDither();                   /* error dithering */

  void (World::*preProcess)(void *, void *, int, int);

 public:

  void blit32_to_32(void *);                     /* 32bit -> 32bit */
  void blit32_to_24(void *);                     /* 32bit -> 24bit */
  void blit32_to_16(void *);                     /* 32bit -> 16bit */
  void blit32_to_15(void *);                     /* 32bit -> 15bit */
  void blit32_to_8c(void *);                     /* 32bit -> 8bit color */
  void blit32_to_8g(void *);                     /* 32bit -> 8bit greyscale */

  void doNothing(void *, void *, int, int);      /* does nothing */

 public:
  /***/ /* Add elements to world, manually */ /***/

  Object *newObject(char *);                     /* add object */
  Object *newObject(char *,float,float);         

  Material *newMaterial(char *);                 /* add Material */

  Light *newLight();                             /* add white omnilight */
  Light *newLight(float,float,float,float);

  Camera *newCamera();                           /* add standard camera */
  
  /***/ /* World construction */ /***/

  World();                                       /* constructor */
  ~World();                                      /* destructor */
};

/****/ /* GLOBALS */ /****/

extern void trapCtrlBreak(int);
extern void trapSegFault(int);

/****/ /* INLINES */  /****/

/**
  Since list.cc is a templates list, we need to
  include it here. it is *not* linked as a
  seperate obj.
  **/





































/*
long long float2fixed( float d ) {
  static float __S          = 65536.0;
  static float __MAGIC      = ((__S * __S * 16) + (__S * 0.5)) * __S;
  static float __MAGICfixed = __MAGIC / __S;

 double dtemp = __MAGICfixed+d;
 return (*(long long *)&dtemp)-0x80000000;
}


int CEIL(float f) {
 int i,j;
 double dtemp = __MAGICfixed+f;

 i = (*(long long *)&dtemp)-0x80000000;
 j = i >> 16;
 if ((i&0xffff) != 0) j += 1;

 return j;
}
*/

#endif

