home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 */
-
- /*
- Data types used in Silver
- */
-
- #define FAST register
- #define CARD unsigned
- #define GLOBAL extern
- #define FRACT long
-
- typedef UBYTE COLOR[3];
-
- typedef struct vectors {
- FRACT X;
- FRACT Y;
- FRACT Z;
- } VECTOR;
-
- /*
- * A "FRACT" number is a 32 bit fixed point number with a 16 bit
- * fractional part. (e.g. 7.25 is represented as 0x00074000)
- *
- * Colors are stored as 3 UBYTE values on a scale of 0 to 255.
- */
-
- /*
- This is the internal structure of Turbo Silver Objects
- */
-
- #define PRP_SURFACE 0
- #define PRP_BRUSH PRP_SURFACE + 1
- #define PRP_STENCIL PRP_BRUSH + 1
- #define PRP_MATTER PRP_STENCIL + 1
- #define PRP_BLEND PRP_MATTER + 1
- #define PRP_SMOOTH PRP_BLEND + 1
- #define PRP_SHINY PRP_SMOOTH + 1
- #define PRP_EXTRA PRP_SHINY + 1
-
- #define NUM_OBJ_PROPS (PRP_EXTRA + 1)
-
- #define ABS_ROT 1
- #define ABS_SCL 2
- #define LOC_ROT 4
- #define LOC_SCL 8
-
- typedef struct story {
- UBYTE Path[18]; /* 18 bytes */
- VECTOR Rotate; /* 12 bytes */
- VECTOR Scale; /* 12 bytes */
- UWORD info; /* 2 bytes */
- } STORY; /* 44 bytes total */
-
- typedef struct barfu {
- UBYTE Shape; /* 1 byte */
- UBYTE Parent [3]; /* 3 bytes */
- ULONG Number; /* 4 bytes */
- VECTOR Position; /* 12 bytes */
- VECTOR A; /* 12 bytes */
- VECTOR B; /* 12 bytes */
- VECTOR C; /* 12 bytes */
- VECTOR S; /* 12 bytes */
- } SUBOBJ, *SUBPTR; /* 68 bytes total */
-
- typedef struct object {
- struct object *Parent; /* 4 bytes */
- struct object *Child; /* 4 bytes */
- struct object *Older; /* 4 bytes */
- struct object *Younger; /* 4 bytes */
- STORY *Story; /* 4 bytes */
- SUBOBJ Object; /* 68 bytes */
- UBYTE Props [NUM_OBJ_PROPS]; /* 8 bytes */
- UBYTE Name [18]; /* 18 bytes */
- UWORD PCount; /* 2 bytes */
- ULONG TCount; /* 4 bytes */
- VECTOR *Points; /* 4 bytes / 12 bytes */
- UWORD *Connects; /* 4 bytes / 6 bytes */
- SUBOBJ *Subjects; /* 4 bytes / 68 bytes */
- VECTOR *Phongs; /* 4 bytes / 12 bytes */
- COLOR *Diffuse; /* 4 bytes / 3 bytes */
- COLOR *Reflect; /* 4 bytes / 3 bytes */
- COLOR *Transmit; /* 4 bytes / 3 bytes */
- } OBJECT, *OBJPTR; /* 152 bytes total */
-
- #define OSIZE (long) sizeof (OBJECT)
- #define SSIZE (long) sizeof (SUBOBJ)
- #define VSIZE (long) sizeof (VECTOR)
-
- #define SPHERE 0L
- #define STENCIL 1L
- #define AXIS 2L
- #define FACETS 3L
- #define SURFACE 4L
-
- /*
- * The 'Object' component of the 'struct object' structure
- * and the 'Props[]' component, contains the necessary info
- * for everything but faceted objects (i.e. spheres, surfaces,
- * stencils and axes). The 'Object.Shape' field is a number
- * (from the #defines above) specifying which type of object
- * is described. The 'Object.Parent' and 'Object.Number' fields
- * don't matter in file data. The 'Object.A', 'B', and 'C' vectors
- * are the unit vectors describing the object coordinate system
- * ('A' is the 'x' axis, 'B' is the 'y' axis, 'C' is the 'z').
- *
- * The 'Props[]' array is:
- *
- * Props[PRP_SURFACE] - bits 0-3 are the "surface type":
- * 0 = Matte, 4 = genlock, 5 = brush
- * - bit 6 is clear for phong shaded, else set
- * Props[PRP_BRUSH ] - the brush number
- * Props[PRP_STENCIL] - the stencil number
- * Props[PRP_MATTER ] - type of matter: 0 = Air, 1 = Water,
- * 2 = Glass, 3 = Crystal, 4 = Custom
- * Props[PRP_BLEND ] - blending factor 0-255
- * Props[PRP_SMOOTH ] - roughness factor 0-255
- * Props[PRP_SHINY ] - non-zero for shiny objects
- * Props[PRP_EXTRA ] - custom index of refraction 0-255
- * (if Props[PRP_MATTER] == 4).
- * 0 correnponds to 1.00, and 255 to 3.55
- *
- * The 'Diffuse', 'Reflect', and 'Transmit' fields should really
- * be unions. If the object is not a "custom" (points/faces) object,
- * they are really a pad byte and 3 color bytes (RGB).
- *
- * If the object is a "custom" - faceted - object, the 'PCount', and
- * 'TCount' parameters give the number of points and faces respectively.
- * The point list is pointed to by 'Points', and the face list is
- * pointed to by 'Connects'. The point list is a list of 'VECTOR's,
- * and the face list is a list of UWORD point number triples. The
- * Colors for each face are stored in 3 COLOR lists pointed to by
- * 'Diffuse', 'Reflect', and 'Transmit'. There is one COLOR
- * structure for each face, in order corresponding to the face list.
- *
- * The routines below indicate what information actually gets read
- * or written to the file, and how.
- */
-
- /*
- * These routines write the Silver object trees to the file:
- *
- * after opening the file ('ofile'):
- *
- * fprintf (ofile, "SILVER II\nOBJT\n");
- * WrtNode (TheObject, ofile);
- * fclose (ofile);
- *
- * - where 'TheObject' points to a 'struct object'.
- */
-
- static ULONG story_header [] = { 0x53545259, (ULONG) sizeof (STORY) };
-
- void write_node (p, fp)
-
- OBJECT *p;
- FILE *fp;
-
- {
- while (p) {
- WrtNode (p, fp);
- p = p->Younger;
- }
- fwrite ("\0", 1, 1, fp);
- }
-
- void WrtNode (p, fp)
-
- OBJECT *p;
- FILE *fp;
-
- {
- FAST ULONG i;
- FAST UWORD *w;
- FAST COLOR *c;
-
- if ((long) p <= 0)
- return;
-
- fwrite ("\001", 1, 1, fp);
-
- fwrite (p->Name, 18, 1, fp);
- fwrite (&p->Object, (int) SSIZE, 1, fp);
- fwrite (p->Props, NUM_OBJ_PROPS, 1, fp);
-
- if (p->Story) {
- fwrite (story_header, 8, 1, fp);
- fwrite (p->Story, sizeof (STORY), 1, fp);
- }
-
- fwrite (&p->PCount, 2, 1, fp);
- fwrite (&p->TCount, 4, 1, fp);
-
- if (p->PCount) {
- fwrite ("PNTS", 4, 1, fp);
- fwrite (p->Points, (int) VSIZE, p->PCount, fp);
- }
-
- if (p->TCount) {
- fwrite ("CNRS", 4, 1, fp);
- i = p->TCount * 3L;
- w = p->Connects;
- while (i--)
- fwrite (w++, 2, 1, fp);
-
- i = p->TCount;
- c = p->Diffuse;
- while (i--)
- fwrite (c++, 3, 1, fp);
-
- i = p->TCount;
- c = p->Reflect;
- while (i--)
- fwrite (c++, 3, 1, fp);
-
- i = p->TCount;
- c = p->Transmit;
- while (i--)
- fwrite (c++, 3, 1, fp);
- } else {
- fwrite (&p->Diffuse, 4, 1, fp);
- fwrite (&p->Reflect, 4, 1, fp);
- fwrite (&p->Transmit, 4, 1, fp);
- }
-
- write_node (p->Child, fp);
- }
-
- /*
- * These read the Silver object trees from the file:
- *
- * After opening the file ('ofile'):
- *
- * char s[256];
- * OBJECT *temp;
- *
- * fgets (s, 256, ofile);
- * if (strncmp (s, "SILVER II", 9))
- * goto oerr;
- *
- * fgets (s, 256, ofile);
- * if (strncmp (s, "OBJT", 4))
- * goto oerr;
- *
- * temp = LodNode (ofile);
- *
- */
-
- OBJECT *load_node (fp)
-
- FILE *fp;
-
- {
- OBJECT *head, *prev, *curr;
-
- head = 0L;
- prev = 0L;
-
- for (;;) {
- curr = LodNode (fp);
- if (!curr)
- break;
-
- if (prev)
- prev->Younger = curr;
- else
- head = curr;
- curr->Older = prev;
- prev = curr;
- }
-
- return head;
- }
-
- OBJECT *LodNode (fp)
-
- FILE *fp;
-
- {
- OBJECT *temp, *curr;
- UBYTE s;
- ULONG id;
- FAST ULONG i;
- FAST UWORD *w;
- FAST COLOR *c;
-
- if (feof (fp) || ferror (fp))
- return NULL;
-
- if (!(s = getc (fp)))
- return NULL;
-
- if (!(temp = add_node ((int) FACETS)))
- return NULL;
-
- fread (temp->Name, 18, 1, fp);
- temp->Name[17] = '\0';
- StringUp (temp->Name);
- fread (&temp->Object, (int) SSIZE, 1, fp);
- fread (temp->Props, NUM_OBJ_PROPS, 1, fp);
-
- fread (&id, 4, 1, fp);
- if (id == 0x53545259) {
- fread (&id, 4, 1, fp);
- if (temp->Story = AllocMem (id, 0L))
- fread (temp->Story, (int) id, 1, fp);
- else
- fseek (fp, id, 1);
- } else
- fseek (fp, -4L, 1);
-
- fread (&temp->PCount, 2, 1, fp);
- fread (&temp->TCount, 4, 1, fp);
-
- if (temp->PCount) {
- fread (&id, 4, 1, fp);
- if (id != 0x504e5453) {
- DelNode (temp);
- return NULL;
- }
-
- if (temp->Points = AllocMem (temp->PCount * VSIZE, 0L))
- fread (temp->Points, (int) VSIZE, temp->PCount, fp);
- else
- fseek (fp, temp->PCount * VSIZE, 1);
- }
-
- if (temp->TCount) {
- fread (&id, 4, 1, fp);
- if (id != 0x434e5253) {
- DelNode (temp);
- return NULL;
- }
- if (temp->Connects = AllocMem (temp->TCount * 6L, 0L)) {
- i = temp->TCount * 3;
- w = temp->Connects;
- while (i--)
- fread (w++, 2, 1, fp);
- } else
- fseek (fp, temp->TCount * 6L, 1);
- }
-
- if (temp->TCount)
- if (temp->Diffuse = AllocMem (temp->TCount * 3L, 0L)) {
- i = temp->TCount;
- c = temp->Diffuse;
- while (i--)
- fread (c++, 3, 1, fp);
- } else
- fseek (fp, temp->TCount * 3L, 1);
- else
- fread (&temp->Diffuse, 4, 1, fp);
-
- if (temp->TCount)
- if (temp->Reflect = AllocMem (temp->TCount * 3L, 0L)) {
- i = temp->TCount;
- c = temp->Reflect;
- while (i--)
- fread (c++, 3, 1, fp);
- } else
- fseek (fp, temp->TCount * 3L, 1);
- else
- fread (&temp->Reflect, 4, 1, fp);
-
- if (temp->TCount)
- if (temp->Transmit = AllocMem (temp->TCount * 3L, 0L)) {
- i = temp->TCount;
- c = temp->Transmit;
- while (i--)
- fread (c++, 3, 1, fp);
- } else
- fseek (fp, temp->TCount * 3L, 1);
- else
- fread (&temp->Transmit, 4, 1, fp);
-
- SetSubParent (temp);
-
- temp->Child = load_node (fp);
-
- curr = temp->Child;
-
- while (curr) {
- curr->Parent = temp;
- curr = curr->Younger;
- }
-
- return temp;
- }
-
-