home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / DOC / DEVEL4.DOC < prev    next >
Text File  |  1992-09-24  |  75KB  |  1,676 lines

  1.  
  2.       REND386 -- A 3-D Polygon Rendering Package for the 386 and 486
  3.                   Written by Dave Stampe and Bernie Roehl
  4.  
  5.                            LIBRARY Documentation
  6.                        Version 4.01 - September 1992
  7.  
  8. This package contains a library of routines (callable from C) that will
  9. render 3 dimensional scenes on 386 and 486 based systems with a VGA display.
  10.  
  11. The package also includes a simple user-interface library with joystick
  12. support, and a demo program to show what it's capable of.
  13.  
  14. The package is designed to be fast.   It accomplishes that goal by making
  15. use of the special instructions that exist only on 386 and 486 processors;
  16. it will not run on 286s, 8086s or 8088s.
  17.  
  18. It also requires Turbo C++ or Borland C to link; Turbo C 2.00 seems to
  19. generate unresolved references.
  20.  
  21. A NOTE ON SPEED:
  22.  
  23. Speed is not a straightforward thing to measure.  There is a relationship
  24. between the speed of the processor, the complexity of the scene, and the
  25. number of frames per second.
  26.  
  27. With this software, a 512-polygon scene can be rendered at speeds up to
  28. 14 frames/second on a 486/25; this corresponds to a speed of over 7000
  29. polys/second.
  30.  
  31. LICENSING:
  32.  
  33. These libraries may be freely used to write software for release into the
  34. public domain.  Permission to use these libraries for the production of
  35. commercial software (including shareware) must be obtained from the authors,
  36. Bernie Roehl (broehl@sunee.uwaterloo.ca) and Dave Stampe
  37. (dstampe@sunee.uwaterloo.ca).
  38.  
  39. Licensing terms will be quite reasonable.
  40.  
  41. SOFTWARE DOCUMENTATION
  42.  
  43. The following sessions describe the various data structures and routines
  44. that comprise the rend386 package.
  45.  
  46. SECTION A -- OBJECTS
  47.  
  48. The following functions deal with OBJECTs.  OBJECTs can have several different
  49. "representations", each at a different level of detail.  The rendering
  50. software will automatically select an appropriate representation based on
  51. the apparent size on-screen of the object.
  52.  
  53. Every object has at least one representation.
  54.  
  55. Each representation has a set of vertices and a set of polygons associated
  56. with it.
  57.  
  58. In addition, objects can have an "owner" field indicating the segment which
  59. tracks the objects movements.  (See below for more information on segments).
  60. Objects also have a set of flags.
  61.  
  62. Each vertex has an x,y,z location in the object's native coordinates, and a
  63. (probably different) x,y,z location in world coordinates.  Each polygon has
  64. a color value and an array of pointers to the vertices that define that
  65. polygon.
  66.  
  67. OBJECT *new_obj(int type, int nv, int np)
  68.          Creates a new object, with a single representation which will have
  69.          room for up to nv vertices and np polygons.
  70.  
  71. REP *add_representation(OBJECT *obj, long size, int nv, int np)
  72.          Adds an additional representation to an object, that should be used
  73.          if the screen size of the object is greater than the "size" field
  74.          of the object.  The object representations are linked in order of
  75.          size, and an object with size 0 is always drawn.
  76.          A call to this function makes the newly-created representation
  77.          the current one for purposes of adding vertices and polygons.  It
  78.          will have room for up to nv vertices and np polys.
  79.  
  80. void delete_rep(OBJECT *obj)
  81.          Deletes the current representation of the given object.
  82.  
  83. void select_representation(OBJECT *obj, long size)
  84.          Find the representation of the given object that would be used
  85.          if the object had the given apparent size, and make it the current
  86.          representation of the object.
  87.  
  88. void first_rep(OBJECT *obj)
  89.          Makes the highest-resolution representation of given object
  90.          the current one.
  91.  
  92. void next_rep(OBJECT *obj)
  93.          Selects the next coarser representation of the given object.
  94.  
  95. long get_rep_size(OBJECT *obj)
  96.          Returns the size value for the current representation of the
  97.          given object.
  98.  
  99. void set_rep_size(OBJECT *obj, long size)
  100.          Sets the size value for the current representation of the given
  101.          object.
  102.  
  103. void add_vertex(OBJECT *obj, long x, long y, long z)
  104.          Adds a vertex to the current representation of the given object,
  105.          with x,y,z as its coordinates in object space.
  106.  
  107. POLY *add_poly(OBJECT *obj, unsigned color, int npoints)
  108.          Adds a polygon to the current representation of the given object,
  109.          with the given color and room for up to npoints vertices.
  110.  
  111. void add_point(OBJECT *obj, POLY *p, int vertnum)
  112.          Adds a point to a polygon.  Vertex number vertnum in object obj is
  113.          added to the given polygon.  The vertices must be added in a
  114.          "clockwise" order as seen from outside the object.
  115.  
  116. void delete_obj(OBJECT *obj)
  117.          Deletes the given object and frees all memory associated with it.
  118.  
  119. long get_object_bounds(OBJECT *obj, long *x, long *y, long *z)
  120.          Obtains the x,y,z extents of the given object.
  121.  
  122. void compute_obj(OBJECT *obj)
  123.          Does internal computation of polygon normals, bounding sphere, and
  124.          so forth.  Must be called once the object is complete (i.e. all the
  125.          vertices and polygons have been added, and the points comprising
  126.          the polys have been defined) and before the object is rendered.
  127.          Note that this routine must be called for each representation,
  128.          since different reps have different polygons and thus different
  129.          normals.  Also note that the object has a single bounding sphere
  130.          (not one per representation), and the bounding sphere is calculated
  131.          based on the current representation of the object (so compute the
  132.          largest representation last for best results).
  133.  
  134. unsigned get_object_sorting(OBJECT *obj)
  135.          Returns the current value of the object's depth-sorting type field.
  136.          Values are:
  137.              DEEPEST - the default; sorts by deepest (i.e. farthest) vertex
  138.              AVERAGE - use average depth rather than maximum
  139.              ATBACK  - sorts the polys as if they were very far away
  140.          You can also depth sort by objects before sorting by poly by OR'ing
  141.          in the BYOBJECT value.
  142.  
  143. void set_object_sorting(OBJECT *obj, unsigned depth_type)
  144.          Sets an object's depth-sorting type field.
  145.  
  146. unsigned get_default_depth_sort()
  147.          Returns the current default value for the depth-sort type.
  148.  
  149. void set_default_depth_sort(unsigned value)
  150.          Sets the current default value for the depth-sort type.  This
  151.          value becomes the default setting for all new objects.
  152.  
  153. void set_obj_flags(OBJECT *obj, unsigned char value)
  154.          Sets the object's flags.
  155.  
  156. unsigned get_obj_flags(OBJECT *obj)
  157.          Gets the object flags.
  158.  
  159. The bottom 14 bits of the flags are user-accessible; the top two bits are
  160. used internally by the rendering software.  The bits defined in rend386.h
  161. are OBJ_NONSEL (which indicates the object should be non-selectable, for
  162. example a 3D representation of a pointer device), OBJ_INVIS (which indicates
  163. the object is invisible, and should not be drawn), and OBJ_HIGHLIGHTED
  164. (indicating that the object should be drawn highlighted).
  165.  
  166. void get_obj_info(OBJECT *obj, int *nv, int *np)
  167.         Extracts the number of vertices in obj and stores it in *nv, and
  168.         similarly stores the number of polys in obj in *np.
  169.  
  170. void get_vertex_info(OBJECT *obj, int vertnum, long *x, long *y, long *z)
  171.         Extracts the x, y and z values of vertex number vertnum in obj.
  172.         This function obtains the coordinates in the object coordinate system.
  173.  
  174. void get_vertex_world_info(OBJECT *obj, int vertnum, long *x, long *y, long *z)
  175.         Extracts the x, y and z values of vertex number vertnum in obj.
  176.         This function obtains the coordinates in the world coordinate system.
  177.  
  178. void get_poly_info(OBJECT *obj, int polynum, unsigned *color, int *nverts,
  179.          int *verts, int maxverts)
  180.       Extracts information from polygon number polynum in obj.  The color
  181.       parameter is set to the polygon color (see colors.doc for details).
  182.       If maxverts is non-zero, then the array of integers verts is filled
  183.       in with the index numbers of the vertices comprising the polygon.
  184.       No more than maxverts vertices will be stored; if there are more
  185.       than that number of vertices in the object, the rest will be ignored.
  186.  
  187. void set_poly_color(OBJECT *obj, int polynum, unsigned color)
  188.       Sets the color of polygon number polynum in obj to the given color.
  189.       See colors.doc for details of how the color parameter is interpreted.
  190.  
  191. void *get_object_owner(OBJECT *obj)
  192.       Returns the owner field of the given object.  The owner field is
  193.       used by the renderer to hold a pointer to the owning segment, but
  194.       can be used by the application programmer if the object is fixed.
  195.  
  196. void set_object_owner(OBJECT *obj, void *owner)
  197.       Sets the object's owner field.
  198.  
  199. void copy_world_to_object(OBJECT *obj)
  200.       Copies the world coordinates of the object into its object coordinates,
  201.       effectively making the object's coordinate system the same as the
  202.       world coordinate system.  Rarely used.
  203.  
  204. void highlight_obj(OBJECT *obj)
  205.       Turns on the HIGHLIGHT bit in the color field of all the polys in the
  206.       given object.
  207.  
  208. void unhighlight_obj(OBJECT *obj)
  209.       Turns off the HIGHLIGHT bit in the color field of all the polys in the
  210.       given object.
  211.  
  212. SECTION B -- OBJLISTS
  213.  
  214. The following functions deal with object lists, or OBJLISTs.  An OBJLIST is
  215. what you pass to the renderer (i.e. you tell it to render a given list of
  216. objects).
  217.  
  218. OBJLIST *new_objlist()
  219.       Creates a new object list and returns a pointer to it.
  220.  
  221. void add_to_objlist(OBJLIST *list, OBJECT *obj)
  222.       Adds an object to an object list. WARNING: be sure object is NOT
  223.       on another objlist first!  If on_objlist(obj) does not return NULL,
  224.       remove it from the old list first.
  225.  
  226. OBJLIST *void remove_from_objlist(OBJECT *obj)
  227.       Removes an object from its object list.
  228.  
  229. void del_objlist(OBJLIST *list)
  230.       Deletes an object list.
  231.  
  232. OBJLIST *on_objlist(OBJECT *obj)
  233.       Returns the objlist that the given object is on, or NULL if it's
  234.       not on any objlist.
  235.  
  236. OBJECT *first_in_objlist(OBJECT **objlist)
  237.       Returns a pointer to the first object in a list.
  238.  
  239. OBJECT *next_in_objlist(OBJECT *obj)
  240.       Returns a pointer to the next object (after obj) in its list.
  241.  
  242. OBJECT *prev_in_objlist(OBJECT *obj)
  243.       Returns a pointer to the previous object (before obj) in its list.
  244.  
  245. int is_first_in_objlist(OBJECT *obj)
  246.       Returns non-zero if obj is the first entry in its list.
  247.  
  248. int is_last_in_objlist(OBJECT *obj)
  249.       Returns non-zero if obj is the last entry in its list.
  250.  
  251. void walk_objlist(OBJLIST *objlist, void (*fn)())
  252.       Walks down the given objlist, calling the given function on each
  253.       object in turn (i.e. fn is called as fn(obj)).
  254.  
  255. SECTION C -- VIEWS
  256.  
  257. In addition to an OBJLIST, the rendering routines need to know about your
  258. current viewpoint; the VIEW structure contains this information.  It has
  259. three fields (ex, ey, ez) that define the current location of your "eye"
  260. or "camera" in world coordinates, and another three (pan, tilt and roll)
  261. that define the "camera's" rotation about the Y (vertical) axis, X
  262. (horizontal) axis, and Z (forward) axis respectively.
  263.  
  264. The VIEW also has near/far clipping information in the hither and yon
  265. fields (in world coordinates). Keep hither >10, yon >1000000 for best results.
  266.  
  267. (A note about coordinates: X is positive to the right, Y is positive up and
  268. Z is positive away from you).
  269.  
  270. There is also a zoom factor, which works like the zoom on a camera.  It
  271. is equal to 65536/(tan(FOV/2)) where FOV is the horizontal field of view.
  272.  
  273. The angles and zoom factor are all stored as 32-bit (long) integers, but
  274. are best thought of as floating point numbers multiplied by 65536L.  This
  275. is referred to in this document as "16.16" format (16 bits of integer,
  276. 16 bits of fraction).
  277.  
  278. A VIEW also has information about what area on the screen should be used to
  279. present the scene; these left, right, top and bottom values are in absolute
  280. screen coordinates.  There is also an "aspect ratio" which determines the
  281. relative size of a non-square pixel.  (See the default_view structure in the
  282. demo for defaults).
  283.  
  284. The world-space coordinates of a single light source are stored in the lx,ly
  285. an lz fields.  In addition there's a flag that indicates whether the light
  286. is a point source or a directional source, and a measure of the amount of
  287. ambient light in the environment.
  288.  
  289. There is also a "flags" field whose bottom bit is set if the objects should
  290. all be drawn in wire-frame mode rather than as filled polygons.  Because no
  291. explicit edge information is stored in the OBJECT data structures, wireframing
  292. is actually slower than filled-polys since each edge winds up getting drawn
  293. twice.
  294.  
  295. The next two bits (called HIDE_HIGHLIGHTED and HIDE_UNHIGHLIGHTED) determine
  296. whether highlighted (and/or unhighlighted) objects should be invisible.
  297.  
  298. There is now a pair of values (x_offset and y_offset) that effectively shift
  299. the screen center by a given amount (number of pixels), and an orientation
  300. field.  The orientation field can have the OR of the values NOFLIP,
  301. XFLIP or YFLIP to determine which axis or axes to flip the image over in this
  302. view. Use it with some HMDs or mirror stereo. There's also a viewpoint
  303. transform matrix which should only be accessed by the provided routines,
  304. and can be wiped by a number of routines such as fast_view_factors() or
  305. compute_view_factors().
  306.  
  307. Finally, there's a 200 byte "work area" associated with each VIEW, used by the
  308. renderer for precomputed values.
  309.  
  310. void compute_view_factors(VIEW *v)
  311.    This function has been replaced by initialize_screen_factors()
  312.    and fast_view_factors(), but can still be used since it just calls
  313.    those two routines.
  314.  
  315. void initialize_screen_factors(VIEW *v)
  316.    Computes the screen factors and sets them into the given VIEW struct.
  317.    Should be called once initially, and again whenever the zoom,
  318.    x_offsets, y_offset or orientation have changed.
  319.  
  320. void fast_view_factors(VIEW *v)
  321.    Should be called whenever the viewpoint changes. Just recomputes the view
  322.    matrix from the pan, etc.
  323.  
  324. void matrix_view_factors(VIEW *v,MATRIX m)
  325.    Converts the current view matrix to a homogenous matrix.  The view
  326.    matrix may be set from pan, etc. by a call to fast_view_factors()
  327.  
  328. void view_to_matrix(VIEW *v,MATRIX m)
  329.    Sets up the view matrix from a homogenous matrix.  Takes the place
  330.    of fast_view factors().
  331.  
  332. In addition to all this, there's a global struct called Screeninfo that
  333. has the minimum and maximum X and Y values, the number of available colors,
  334. the number of pages, and the screen coordinates of the screen "center".
  335. This is set up by the video driver, and should not be changed.
  336.  
  337. SECTION D -- MATRICES AND INTEGER MATH ROUTINES
  338.  
  339. A matrix is a 4 by 3 array of long (32-bit) integers.  It can best be thought
  340. of as an upper 3x3 matrix representing rotations, and 3-element bottom row
  341. vector representing translation.  A matrix is used to transform a point or
  342. an object.
  343.  
  344. NOTE ON NUMERIC FORMATS:
  345.  
  346. All numbers are fixed point, and are 32 bits long in total.
  347. The decimal point is expressed as <ii.ff>, where ii is the
  348. number of integer bits and ff is the number of fractional bits.
  349. <16.16> is usually used for angles, and is 65536 times the angle
  350. in degrees.  <3.29> is used for sines, cosines, and matrix entries
  351. where a magnitude of one or less is expected.  This is 536870912
  352. times the real value.
  353.  
  354. ALL THESE FUNCTIONS MAY BE USED ONLY AFTER setup_render() has been
  355. called to initialize the math tables.
  356.  
  357. TRIGNOMETRIC FUNCTIONS
  358.  
  359. All these fuctions are very fast: less than 5-10 uS each.
  360. This is about twice as fast as a floating point coprocessor.
  361.  
  362. long isine(long angle)
  363.      Given <16.16> angle (65536L * degrees) returns <3.29> sine
  364.      or sin(angle)<<29.  Uses table with entry every 0.35 degrees,
  365.      with interpolation.
  366.  
  367. long icosine(long angle)
  368.      Given <16.16> angle (65536L * degrees) returns <3.29> cosine
  369.      or cos(angle)<<29.  Uses isine(90*65536L-angle).
  370.  
  371. To compute tangent, use isine(angle)/cosine(angle).
  372.  
  373. long arcsine(long x)
  374.      Given <3.29> sine, computes <16.16> angle.  Accurate to 25 bits.
  375.  
  376. long arccosine(long x)
  377.      Given <3.29> cosine, computes <16.16> angle.  Accurate to 25 bits.
  378.  
  379. long arctan2(long y, long x)
  380.      Equivalent to C atan2, uses the y and x argument's signs and ratio
  381.      to compute full 360 degree angle.  Accurate to 25 bits.
  382.  
  383.  
  384. MATRIX LIBRARY
  385.  
  386. This is a set of routines for multiplying vectors and homogenous matrices,
  387. inverting matrices, and creating rotation matrices from angles.  There is
  388. also a routine to convert a matrix back to rotation angles, but it depends
  389. on the matrix being very close to unit scale (0.999 or so).
  390.  
  391. Homogenous matrices express a rotation followed by a translation, and
  392. may be multiplied to cascade transforms or coordinate shifts.  A
  393. homogenous matrix is 4x4, but since our scale is always 1, we can use a
  394. 3x4 2D array to store the matrix.  All rotation entries are in <3.29>
  395. format, translation entries are <32.0>.
  396.  
  397. This is a storage map of a matrix:
  398.  
  399.    { m[0][0] m[0][1] m[0][2] | m[3][0] }   { rotation | translation }
  400.    { m[1][0] m[1][1] m[1][2] | m[3][1] } = {  matrix  |   vector    }
  401.    { m[2][0] m[2][1] m[2][2] | m[3][2] }   {          |             }
  402.    {   0       0       0         1     }   {  0 0 0         1       }
  403.  
  404.  
  405. Some matrices are rotation only: the translation vector is 0.
  406. Applying a matrix M|t to a vector v does Mv + t.
  407.  
  408. void matrix_mult(MATRIX a, MATRIX b, MATRIX c)
  409.      Multiplies the rotation parts (3x3 submatrices) so C = AB.  Does not
  410.      affect the translational parts.  Any or all of A, B, and C may be
  411.      the same matrix.
  412.  
  413. void matrix_product(MATRIX a, MATRIX b, MATRIX c)
  414.      Full homogenous matrix multiply.  Does C = AB, and computes new
  415.      translational part for C.  Any or all of A, B, and C may be
  416.      the same matrix.
  417.  
  418. void matrix_point(MATRIX m, long *xp, long *yp, long *zp)
  419.      Applies the homogenous matrix M to the given vector.  Also equivalent
  420.      to applying the matrix transformation to the point (x,y,z).
  421.  
  422. void matrix_rotate(MATRIX m, long *xp, long *yp, long *zp)
  423.      Applies rotational part of matrix M to the given vector.  Also
  424.      equivalent to applying the matrix rotation to the point (x,y,z).
  425.  
  426. void matrix_transpose(MATRIX a, MATRIX b)
  427.      Computes the rotational inverse of matrix A and stores it in B.
  428.      The transpose is equivalent to the inverse for orthonormal matrices.
  429.      A and B may be the same matrix.
  430.  
  431. void inverse_matrix(MATRIX a, MATRIX b)
  432.      Computes the inverse for homogenous matrix A, and stores it in B.
  433.      This matrix will perform the reverse transform of matrix A.
  434.      A and B may be the same matrix.
  435.  
  436. void identity_matrix(MATRIX m)
  437.      Fills the matrix M with zero rotate, zero translate data.
  438.  
  439. void matrix_copy(MATRIX s, MATRIX d)
  440.      Copy matrix s to matrix d.
  441.  
  442. void matrix_rot_copy(MATRIX s, MATRIX d)
  443.      Copies upper left 3x3 submatrix, zeros translation part of
  444.      matrix s to matrix d.
  445.  
  446. void multi_matrix(MATRIX m,long rx,long ry,long rz,
  447.           long tx,long ty,long tz,int type)
  448.      Creates a rotation/translation matrix.  The rotations are around the
  449.      X, Y, and Z axes, CCW looking "out" along the axis (left-hand coordinate
  450.      system). Positive X is right, positive Y is up, positive Z is into
  451.      screen.
  452.  
  453.      The order that these rotations are applied is specified by "type", which
  454.      is one of:
  455.  
  456.         #define RXYZ 1      /* matrix rotation types */
  457.         #define RYXZ 0      /* ONLY RYXZ guaranteed to be tested */
  458.         #define RXZY 2
  459.         #define RZYX 5
  460.         #define RZXY 4
  461.         #define RYZX 6
  462.  
  463. void std_matrix(MATRIX m,long rx,long ry,long rz,long tx,long ty,long tz)
  464.       Creates a matrix as above, but with RYXZ (the standard order) implied.
  465.  
  466. void matrix_to_angle(MATRIX m, long *rx, long *ry, long *rz)
  467.       Converts a well-scaled matrix to a set of rotation angles (RYXZ) and
  468.       a translation.  Results will be somewhat erroneous if the matrix is
  469.       badly scaled (i.e after many multiplies).
  470.  
  471. void vector_to_matrix(MATRIX m, long x, long y, long z)
  472.       Makes rotation-only matrix that will xform Z axis to given vector.
  473.       Used by "pinch" glove rotation.
  474.  
  475. long dot_prod_29(long a, long b, long c, long x, long y, long z)
  476.       Computes a 2-vector dot product, using <3.29> values.  This is defined
  477.       as (ax + by+ cz) >> 29.
  478.  
  479. void cross_column(MATRIX m, int col)
  480.       Replaces one column of the rotational part of a matrix with the cross
  481.       product of the other 2 columns.  This can be used to reduce
  482.       calculations, but will square the scaling error of the matrix.
  483.  
  484. long plane_y(long a, long b, long c, long d, long x, long z)
  485.       Computes -(ax + cz + d) / b in order to compute the y coordinate of
  486.       a plane (a,b,c,d) given the x and z coordinates.
  487.  
  488. void fix_matrix_scale(MATRIX m)
  489.       Uses floating point calculations to restore the unit scale of a
  490.       rotational matrix.  This is expensive, but needed every 1000 or
  491.       so matrix self-multiplications to prevent shrinkage and
  492.       distortion of objects.
  493.  
  494. long m_mult(long a, long b)
  495.       Performs (a*b) >> 29.
  496.  
  497. long scale_16(long s, long a, long x)
  498.       Performs s*(x + a) >> 16.  Used for scaling pointer devices.
  499.  
  500. long calc_scale_16(long a, long b, long s)
  501.       Computes a scale factor to center and scale the range of a pointer
  502.       device.
  503.  
  504. void apply_matrix(OBJECT *obj, MATRIX m)
  505.       Completely moves an object (current representation, bounds, etc)
  506.       by translating object coordinates to world coordinates using the
  507.       matrix M.
  508.  
  509. void matmove_osphere(OBJECT *obj, MATRIX m)
  510.       Moves an object's position and bounding volume to world coordinates
  511.       using the matrix M.  The translation of the current representation
  512.       will be performed the first time the object is rendered.
  513.  
  514. void matmove_rep(REP *rep, MATRIX m)
  515.       Moves an object's position to world coordinates using the matrix M.
  516.       This translates the vertices and poly normals of the current representation
  517.       and is performed the first time the object is rendered.
  518.  
  519. long sphere_pretest(OBJECT *obj, long x, long y, long z)
  520.       Bounding sphere pretest for collision detection and selection.
  521.       Returns 0x40000000L if not in bounding sphere, else returns square
  522.       of distance from center of object to the point (x,y,z).
  523.  
  524. long big_dist(long x1,long y1,long z1,long x2,long y2,long z2)
  525.       Returns estimate of distance between points:
  526.           abs(x1-x2) + abs(y1-y2) + abs(z1-z2)
  527.  
  528. int find_normal(long x1,long y1,long z1,long x2,long y2,long z2,
  529.         long x3,long y3,long z3,long *xn,long *yn,long *zn)
  530.       Compute polygon normal, given 3 points on polygon.  Normal is
  531.       scaled to a length of 2^29 (to 8 bits of accuracy) for lighting
  532.       purposes.  This code is quite fast: about 20 uS or so.  It is
  533.       part of a larger polygon normal computation that determines the best
  534.       set of vertex points to use (in 3DSUPP.C).  It returns the
  535.       power of 2 closest to the normal magnitude before unitizing, which
  536.       can be used as a measure of the "goodness" of the normal.
  537.  
  538. SECTION E -- SEGMENTS
  539.  
  540. A segment is a piece of an articulated (multi-jointed) figure.  Each segment
  541. has a parent segment; the parent of the "root" segment is NULL.  Each segment
  542. has a linked list of children, and each segment has a 'sibling' which
  543. is the next segment in the parent's linked list of children.
  544.  
  545. Each segment has a pointer to the object that the segment controls.  Each
  546. segment may also have a name associated with it.
  547.  
  548. Segments keep track of the position of objects by storing transformation
  549. matrices that transform the object into the parent's coordinate system;
  550. you can think of a segmented figure as being a tree of transformation
  551. matrices.  Segments also cache the transformation matrix used to convert
  552. the object to world coordinates (i.e. the product of all the matrices
  553. higher up in the tree).
  554.  
  555. SEGMENT *new_seg(SEGMENT *parent)
  556.       Creates a new segment, with the given segment as its parent.  If the
  557.       'parent' parameter is NULL, this is a root object.
  558.  
  559. void seg_set_object(SEGMENT *s, OBJECT *rep)
  560.       Specifies the object that the given segment should keep track of.  Used
  561.       to be called seg_setrep().
  562.   
  563. OBJECT *seg_get_object(SEGMENT *s)
  564.       Returns a pointer to the object controlled by the given segment.
  565.       Used to be called seg_getrep().
  566.  
  567. WARNING: all the routines that get the angle of a segment call
  568. matrix_to_angles(), which may be expensive (100-1000 uS).
  569.  
  570. void seg_getposang(SEGMENT *s, long *rx, long *ry, long *rz)
  571.       Stores the current orientation of the given segment (relative to the
  572.       world coordinate system) in *rx, *ry and *rz.  The angles are in
  573.       16.16 format.
  574.  
  575. void seg_getjointang(SEGMENT *s, long *rx, long *ry, long *rz)
  576.       Stores the current orientation of the given segment (relative to the
  577.       its parent's coordinate system) in *rx, *ry and *rz.  The angles are in
  578.       16.16 format.  Used to be part of seg_getposition().
  579.  
  580. void seg_getposxyz(SEGMENT *s, long *x, long *y, long *z)
  581.       Stores the current position of the given segment (relative to
  582.       the world coordinate system) in *x, *y and *z.
  583.  
  584. void seg_getjointxyz(SEGMENT *s, long *x, long *y, long *z)
  585.       Stores the current position of the given segment (relative to
  586.       its parent's coordinate system) in *x, *y and *z.  Used to be part of
  587.       seg_getposition().
  588.  
  589. char *seg_getname(SEGMENT *s)
  590.       Returns the name of the given segment.
  591.  
  592. void set_setname(SEGMENT *s, char *name)
  593.       Sets the name of the given segment to the given value; a copy of the
  594.       string is made.
  595.  
  596. void rel_move_segment(SEGMENT *obj, long x, long y, long z)
  597.       Performs a relative move of the given segment; x, y and z are the amounts
  598.       to move the segment along each of the three axes.  After calling this
  599.       routine, you must at some point call update_segment().
  600.  
  601. void abs_move_segment(SEGMENT *obj, long x, long y, long z)
  602.       Performs an absolute move of the given segment; x, y and z are the new
  603.       absolute location of the segment along each of the three axes.  After
  604.       calling this routine, you must at some point call update_segment().
  605.  
  606. WARNING: all relative rotates multiply the segment matrix by another matrix.
  607. After 1000x or so, the matrix (and the objects) will start to shrink.  A
  608. rescaling routine is called at pseudorandom intervals every 1000 or so
  609. multiplies, but this can take up to 3000uS, so be warned!
  610.  
  611. void rel_rot_segment(SEGMENT *seg, long rx, long ry, long rz)
  612.       Performs a relative rotation of the given segment; x, y and z are the
  613.       angles to rotate the segment along each of the three axes (in 16.16
  614.       format).  After calling this routine, you must at some point call
  615.       update_segment().
  616.  
  617. void abs_rot_segment(SEGMENT *seg, long rx, long ry, long rz)
  618.       Performs an absolute rotation of the given segment; x, y and z are the
  619.       angles to rotate the segment to along each of the three axes (in 16.16
  620.       format).  After calling this routine, you must at some point call
  621.       update_segment().
  622.  
  623. void abs_mat_segment(SEGMENT *s, MATRIX m)
  624.       Directly sets the transformation matrix for the given segment.
  625.  
  626. void abs_rotmat_segment(SEGMENT *s, MATRIX m)
  627.       Directly sets the rotation part of the transformation matrix for the
  628.       given segment.  Only the first three rows of the matrix m are used.
  629.  
  630. void rel_mat_segment(SEGMENT *s, MATRIX m)
  631.       Multiplies the given segment's transformation matrix by the given
  632.       matrix, doing a rotation and translation relative to the segment's
  633.       current position.
  634.  
  635. void rel_rotmat_segment(SEGMENT *s, MATRIX m)
  636.       Multiplies the given segment's transformation matrix by the given
  637.       matrix, doing a rotation only relative to the segment's current
  638.       position.  Only the first three rows of the matrix m are used.
  639.  
  640. void update_segment(SEGMENT *s)
  641.       Takes the current position and orientation and uses it (and similar
  642.       information from the parent segment, and its parents, and so on) to
  643.       transform the segment's representation.  Also transforms all the
  644.       segments attached to this one (recursively).  May use lots of stack
  645.       space.  Only recomputes the segments that need it.
  646.  
  647. void full_update_segment(SEGMENT *s)
  648.       Similar to update_segment, but explicitly recomputes the matrices
  649.       at each node even if it's not needed.  You should not need to use
  650.       this function.
  651.  
  652. SEGMENT *find_root_segment(SEGMENT *s)
  653.       Walks up the tree from the given segment and finds the root segment for
  654.       the figure of which the segment is a part.
  655.  
  656. SEGMENT *parent_segment(SEGMENT *s)
  657.       Returns the parent of the given segment.
  658.  
  659. SEGMENT *child_segment(SEGMENT *s)
  660.       Returns the child of the given segment.
  661.  
  662. SEGMENT *sibling_segment(SEGMENT *s)
  663.       Returns the sibling of the given segment.
  664.  
  665. void delete_segment(SEGMENT *s, void (*delrep_fn)())
  666.       Deletes the given segment and frees the memory associated with it; calls
  667.       the given function (if not NULL) to delete any representation associated
  668.       with the given segment.
  669.  
  670. void attach_segment(SEGMENT *s, SEGMENT *to)
  671.       Attaches the given segment to the given parent ('to'), making it a child
  672.       of that segment.
  673.  
  674. void detach_segment(SEGMENT *s)
  675.       Detaches the given segment from its parent, and makes it an independent
  676.       segment with no parent.  Its children remain attached to it, and other
  677.       siblings are unaffected (i.e. they still descend from the same parent
  678.       that has 'disowned' the given segment).
  679.  
  680. SEGMENT *find_segment_by_name(SEGMENT *s, char *name)
  681.       Returns a pointer to the segment (descended from the given segment)
  682.       whose name matches the given name.  If none is found, NULL is returned.
  683.  
  684. SECTION F -- COLORS
  685.  
  686. For background information on the color mapping system used in REND386, be
  687. sure to read the file "colors.doc".
  688.  
  689. The application programmer should supply a module that provides support
  690. for color mapping; a sample has been supplied as "colormap.c".
  691.  
  692. The following function should be defined in the color mapping module:
  693.  
  694. int user_poly_color(POLY *p, int pcolor, long maxz)
  695.       Does the mapping of user-specified color values into whatever format
  696.       gets passed to lower-level drawing routines; this is where cosine
  697.       lighting is done, for example.  The maxz specifies the polygon depth
  698.       (so you can do distance-based shading).  This routine is called by
  699.       the renderer, and might call poly_cosine(p) to determine the cosine of
  700.       the lighting angle for shading purposes.
  701.  
  702. This routines may be changed at will, but bear in mind that this may make
  703. color usage incompatible with data files generated elsewhere.
  704.  
  705. SECTION G -- RENDERING ROUTINES
  706.  
  707. These routines are the main interface to the renderer.
  708.  
  709. void setup_render(unsigned k, int maxp)
  710.       Sets up the internal data structures used by the renderer; should be
  711.       called before doing any other calls to any of the rend386 library
  712.       routines.  The parameter k gives the Kbytes of memory to allocate,
  713.       and maxp is the maximum number of polys that will be rendered in any
  714.       frame. (40, 800 suggested).
  715.  
  716. void reset_render()
  717.       Frees memory allocated for internal data structures used by the renderer;
  718.       should be called before exiting.
  719.  
  720. void subrender(OBJLIST *objlist)
  721.       Renders all the objects in the given objlist, writing to the current
  722.       page (see set_drawpage()).  Call render_set_view() first to set viewport.
  723.       Especially fast if you have a lot of short objlists to draw.
  724.  
  725. void render_set_view(VIEW *view)
  726.       Recalculates view for rendering, and loads renderer with it.
  727.  
  728. void render(OBJLIST *objlist, VIEW *view)
  729.       Calls render_set_view(view) then subrender(objlist).  Use this if
  730.       you're rendering 1 or 2 big objlists.
  731.  
  732. These next three routines support "monitoring" of a point on the screen, to
  733. find the frontmost polygon that is under that point.
  734.  
  735. On the next rendering of the screen, the system will watch the point in
  736. question and see which polys cover it.
  737.  
  738. void set_screen_monitor(int x, int y)
  739.      Specifies the point to monitor.  The x and y values are in screen
  740.      coordinates.
  741.  
  742. void clear_screen_monitor()
  743.      Disables monitoring.
  744.  
  745. POLY *read_screen_monitor()
  746.       Returns a pointer to the nearest polygon that covers the monitor point.
  747.  
  748. This next routine can be called by the user part of the renderer code.
  749.  
  750. int poly_cosine(void *poly)
  751.       Given a pointer to a polygon, returns the cosine of the angle between
  752.       the current light source and the polygon's surface normal; the value
  753.       returned is actually the cosine times 128.  VERY fast (5-10 uS).
  754.  
  755. SECTION H -- ROUTINES CALLED BY THE RENDERER
  756.  
  757. These routines are provided by the user (sample source in render.c); you can
  758. implement your own "back end" to the renderer just by rewriting these
  759. routines.  BE VERY CAREFUL-- the new video driver makes most of these
  760. obsolete, and you could make your code incompatible if you screw around too
  761. much with them.
  762.  
  763. <see also user_poly_color()>
  764.  
  765. void user_setup_blitter()
  766.       Sets up the polygon blitter.
  767.  
  768. void user_reset_blitter()
  769.       Resets the polygon blitter.
  770.  
  771. void user_box(int x1, int y1, int x2, int y2, int color)
  772.       Draws a box with top left corner (x1,y1) and bottom right corner (x2,y2)
  773.       filled in the given color.
  774.  
  775. void user_text(int x, int y, int color, char *string)
  776.       Displays a string at (x,y) in the given color.
  777.  
  778. void vgabox(int left, int top, int right, int bottom, int color)
  779.        Draw a box on the display at the given location in the given color.
  780.        No clipping is done!
  781.  
  782. void user_render_poly(int number, int *coords, int color, long MAXZ)
  783.       Called by the renderer to actually draw polys.
  784.       See render.c for details.  The maxz values species the
  785.       polygon depth, so you can make distance-based polygon rendering
  786.       decisions.
  787.  
  788. There is also a global flag, an integer called 'wireframe', which, if non-zero,
  789. will cause all objects to be rendered in wireframe mode.  Note that this is
  790. in general slower than actual filled-polygon rendering, since the absence of
  791. explicit edge information forces each edge to be drawn twice.
  792.  
  793. SECTION I -- MISCELLANEOUS ROUTINES
  794.  
  795. OBJECT *where_screen_pt(int *pol, int *vert, int x, int y)
  796.       Given the x, y location of a point on the screen, this routine returns a
  797.       pointer to the object that point is on; if pol is not NULL, it is
  798.       set to be the index in the object of the polygon the cursor is on.
  799.       The vert pointer is currently not used.  THIS FUNCTION MAY REDRAW THE
  800.       SCREEN.
  801.  
  802. long where_pt(OBJLIST objlist, long x, long y, long z, OBJECT **obj, int *vert)
  803.       Finds which object (if any) the point (x,y,z) is contained within, and
  804.       sets *obj to point to that object.  Also sets *vert to be the index of
  805.       the vertex on that object which is closest to (x,y,z) and returns the
  806.       distance from (x,y,z) to that vertex.   THIS ROUTINE HAS NOT BEEN
  807.       EXTENSIVELY TESTED!  Caveat programmer.
  808.  
  809. SECTION J -- LOWER-LEVEL GRAPHICS ROUTINES
  810.  
  811. As of version 4.00, REND386 supports loadable graphics drivers.  To load
  812. a driver, use the following call:
  813.  
  814. void *load_driver(char *filename)
  815.      Loads a device driver from the given file into memory, and returns a
  816.      handle for it (pointer to segment-aligned start, which is after the 16-byte
  817.      pad at the file start).
  818.  
  819. These routines are loaded from the external device driver file, and provide
  820. low-level access to the display hardware.  All display access should go
  821. through these routines, in order to maintain compatibility with new hardware.
  822.  
  823. void far VGA_select(int card)
  824.      Selects which of several VGA cards should be the one written to;
  825.      useful for stereoscopic systems that use one display per eye.  The
  826.      parameter 'card' is the OR of MAIN_VGA, LEFT_VGA, and RIGHT_VGA.  You
  827.      can use ALL_VGA to refer to all three. (Of course, your video device
  828.      driver must support switching multiple VGA cards!).  This is supported
  829.      with the SEPARATE stereo type only.
  830.  
  831. void *far screen_data()
  832.      Returns a pointer to a screen_info struct that holds the information
  833.      for the current display.
  834.  
  835. void far clipline(int x1, int y1, int x2, int y2, int color)
  836.      Does Cohen-Sutherland clipping and draws the line in the given color.
  837.  
  838. void far set_clip_rect(int l, int t, int r, int b)
  839.      Sets the on-screen clipping rectangle.  ONLY used for clipline().
  840.  
  841. void far vsync()
  842.      Pauses until the next vertical retrace.
  843.  
  844. void far set_vpage(int page)
  845.      Sets the current video page through the BIOS.
  846.  
  847. void far setup_hdwe(int mode)
  848.      Sets up the VGA card for a series of line or poly draws.  The mode
  849.      is one of PUT, AND, OR, or XOR; you should usually use PUT.
  850.  
  851. void far reset_hdwe()
  852.      Resets the VGA to BIOS state after drawing.
  853.  
  854. int far clr_page(int page, int color)
  855.      Clears the video page to a solid color.  Returns -1 if the page number
  856.      is invalid.  The Mode Y driver does this in 10 ms per call.
  857.  
  858. int far copy_page(int source, int dest)
  859.      Copies one complete page to another for use as a background.  Returns -1
  860.      if either page number is invalid.  The Mode Y driver does this in 21 mS
  861.      per call.
  862.  
  863. void far vgaline(int x1, int y1, int x2, int y2, int color)
  864.      Fast VGA line draw ; the Mode Y driver does about 15600 24-pixel
  865.      vectors/sec (much faster for horizontal lines (y1 == y2)).
  866.  
  867. void far vgapoint(int x, int y, int color)
  868.      Sets a point on the screen; no clipping is done.
  869.  
  870. void far set_gmode()
  871.      Enters graphics mode and clears the screen.
  872.  
  873. void far exit_gmode()
  874.      Leaves graphics mode.
  875.  
  876. int far set_drawpage(int page)
  877.      Sets the page to draw into.  The Mode Y driver supports pages 0 through 3.
  878.  
  879. void far fastpoly(int count, int far *pcoords, int color)
  880.      Fast multi-sided polygon draw routine.  Draws convex polygons with up to
  881.      20 sides.  The pcoords are a series of X, Y coordinate pairs (x,y,x,y...)
  882.      in counter-clockwise order.
  883.  
  884. void far m_fastpoly(int count, int far *pcoords, int color,
  885.           int gmask, int toggle)
  886.      Same as fastpoly(), but does color cycling for pseudo-metallic effects
  887.      and masking (alternate bits on/off for pseudo-transparency).
  888.      The color cycles through the lower 4 bits (0-3), up then down then up
  889.      then down.  The next 4 bits (4-7) give the hue.  Bit 8 is a "sign" bit
  890.      for determining the initial cycle direction.  The gmask is XOR'd with
  891.      the toggle every line to generate a halftone pattern.
  892.  
  893. void far printxyr(int x, int y, int color, char far *pstring, int reversed)
  894.      Prints text on the screen at a given location and in a given color.
  895.      If reversed is non-zero, the text is written right-to-left with x now
  896.      being the right-hand (rather than left-hand) edge of the text.
  897.  
  898. void far draw_cursor(int x, int y, int color, int savebuff)
  899.      Draws a crosshair cursor on the screen at the given location, saving
  900.      what was there before into the given buffer.
  901.  
  902. void far erase_cursor(int savebuff)
  903.      Restores an 8x8 area that was saved by draw_cursor().
  904.  
  905. int far copy_block(int spage, int sx, int sy,
  906.             int dpage, int dx, int dy, int xs, int ys)
  907.      Copies a rectangle of pixels from the given location (sx,sy) on the
  908.      given source page (spage) to a given location (dx,dy) in a given
  909.      destination page.  The size of the array to copy is given by (xs,ys).
  910.      The left boundary must be a multiple of 8, and the size also.
  911.  
  912. int far clr_block(int left, int top, int right, int bottom,
  913.             int page, int color)
  914.      Clears a block defined by (left,top,right,bottom) on the given page
  915.      to the specified color.  The left side must be a multiple of 8,
  916.      and the right side a multiple of 8, minus 1.  May be a bit slower than
  917.      clear_page().
  918.  
  919. void far load_DAC_colors(char far *pal, int n, int bw)
  920.      The given palette should have n entries of 3 bytes each, whose values
  921.      can be between 0 and 63 inclusive.  The first of each triple is the Red
  922.      value, the second is the Green value, and the third is the Blue value.
  923.      If pal is NULL, the default palette is used (but specify n anyway!).
  924.      If bw is 1, the palette will be mapped into greyscales.
  925.  
  926. void far read_DAC_colors(char far *pal, int n)
  927.      Read n entries from the palette into the provided buffer.
  928.  
  929. SECTION K -- CURSOR ROUTINES
  930.  
  931. There is a set of routines for manipulating both 2D and 3D cursors.
  932.  
  933. The 2D cursor is a simple crosshair, and has support routines are as follows:
  934.  
  935. void cursor_move(int x, int y)
  936.      If the cursor is visible, it is moved to the given screen location.
  937.  
  938. int cursor_hide()
  939.      Hide the cursor if it's visible (an internal counter is decremented;
  940.      the cursor is considered visible if the counter is greater than or
  941.      equal to zero).  The number of the currently displayed page is returned.
  942.  
  943. void cursor_show(page)
  944.      Increment the internal counter, and if it's greater than or equal to
  945.      zero the cursor is displayed.  The currently displayed page should be
  946.      passed as a parameter.
  947.  
  948. int cursor_forget()
  949.      Simply decrements the internal counter, and does not bother hiding the
  950.      cursor (since this page will be overwritten soon anyway).  Returns the
  951.      number of the currently displayed page.
  952.  
  953. int move_2D(PDRIVER *drvr, int *x, int *y, unsigned *b)
  954.      Reads the 2D pointing device associated with drvr; if the position
  955.      or button status has changed, the cursor is automatically moved on-screen.
  956.      The variables pointed to by *x and *y are filled with the x and y
  957.      position of the cursor on-screen, and b is filled with the status of the
  958.      pointing device's buttons.  A non-zero value is returned if the pointing
  959.      device has moved or a button been pushed on it since the last call to
  960.      this routine.
  961.      
  962. int move_till_click(PDRIVER *drvr, unsigned buttmask, int *x, int *y)
  963.      Tracks the pointing device specified by the given drvr, until the button
  964.      status on that device (AND'ed with the given buttmask) yields a non-zero
  965.      value.  The *x and *y variables are filled in with the on-screen position
  966.      of the pointing device.
  967.  
  968. The following routines handle 3D pointing device cursors:
  969.  
  970. void pointer_to_world(POINTER *p, VIEW *v, long *x, long *y, long *z)
  971.      Updates the world coordinates of the pointer information in the given
  972.      POINTER structure (see the section on POINTERS).  The x, y, and z
  973.      variables are filled in with the view-relative coordinates of the
  974.      pointing device.
  975.  
  976. void rotate_to_view( VIEW *v, long *x, long *y, long *z)
  977.      Rotates the given x, y, z values using the viewing transform.
  978.  
  979. int glove_update(PDRIVER *drvr, POINTER *p)
  980.      Reads the glove device specified by drvr, and updates the position and
  981.      orientation information in the given POINTER struct.  See the section
  982.      on POINTERS for more details.
  983.  
  984. int cursor_update3D(PDRIVER *d, POINTER *p) /* read pointer, update positions */
  985.      Reads the 3D pointer device specified by drvr, and updates the position
  986.      and orientation information in the given POINTER struct.  See the section
  987.      on POINTERS for more details.
  988.  
  989. SEGMENT *manip_data(PDRIVER *d, long *x, long *y, long *z)
  990.      Sets *x, *y and *z to be the location in world coordinates of the
  991.      pointing device, and returns a pointer to the segment corresponding
  992.      to the pointing device.
  993.  
  994. SECTION L -- JOYSTICK ROUTINES
  995.  
  996. The package provides support for reading a joystick.  The following struct
  997. describes the information associated with a joystick port:
  998.  
  999. typedef struct { 
  1000.     int x, y, buttons;
  1001.     int cenx, ceny;
  1002.     int xrange, yrange;
  1003.     long scale;
  1004.     int port;  /* port number, 0 or 1; -1 means 'unused' */
  1005.     } joystick_data;
  1006.  
  1007. The x, y and buttons fields are the values read from the joystick.  The
  1008. cenx and ceny values are the values of x and y that are read when the joystick
  1009. is centered; the values the application program sees are relative to these
  1010. center values, so (0,0) is a centered stick.
  1011.  
  1012. The xrange and yrange values are the maximum values for x and y; the scale
  1013. factor is the ratio of movement on the screen to movement of the joystick.
  1014.  
  1015. The value the user sees after a call to joystick_read() is, in the case of
  1016. x, ((x_as_read - cenx) * scale)/xrange.
  1017.  
  1018. The port value specifies which of the two possible joysticks this structure
  1019. corresponds to.
  1020.  
  1021. int joystick_check()
  1022.        Checks for the presence of one or two joysticks; the returned value has
  1023.        the low-order bit set if joystick 1 is present, and the next higher bit
  1024.        set if joystick 2 is present.
  1025.  
  1026. void joystick_init(joystick_data *joy, int port)
  1027.        Initializes the joystick on the given port (0 or 1)
  1028.  
  1029. void joystick_setscale(joystick_data *joy, int value)
  1030.        Sets the scale factor for the given joystick
  1031.  
  1032. void joystick_scale(joystick_data *joy, int dir)
  1033.        Used for joystick calibration; should be called with dir = 0 and joystick
  1034.        forward and to the left, then again with dir = 1 and joystick backward and
  1035.        to the right.  This sets the xrange and yrange values for you.
  1036.  
  1037. int joystick_read(joystick_data *joystick)
  1038.        Reads the current values of the specified joystick.
  1039.  
  1040. void joystick_quit()
  1041.        De-initializes joystick processing (currently does nothing)
  1042.  
  1043. SECTION M -- POINTER ROUTINES
  1044.  
  1045. Support is provided for 3-dimensional pointing devices. These are supported
  1046. by pointer drivers and by the .cfg files.  Not all the possible manipulation
  1047. methods are implemented, but 2D, 2D plus mapping to Z axis, 3D, and 6D
  1048. are supported with cursors, as well as gloves.
  1049.  
  1050. The routines documented here are the low-level pointer driver interface.
  1051. There are others, but there hasn't been time to document them yet.
  1052.  
  1053. The following structure is used to return information about the current
  1054. location, orientation, and control-status information about a 3D pointer:
  1055.  
  1056. typedef struct {
  1057.       long x, y, z;          /* location in scaled coordinates     */
  1058.       long dx, dy, dz;       /* position change from last read     */
  1059.       long rx, ry, rz;       /* scaled orientation around x, y, z  */
  1060.       long drx, dry, drz;    /* orientation change from last read  */
  1061.       unsigned buttons;      /* 16 bits: raw mouse buttons         */
  1062.       unsigned gesture;      /* glove gesture ID, or a mapping     */
  1063.       unsigned keys;         /* keypad return value                */
  1064.       int flex[16];          /* 16 words of flexion (i.e. fingers) */
  1065.       int changed;
  1066.       int wpos_valid;        /* set if world pos'n is valid        */
  1067.       MATRIX wpos;           /* world position/rotation            */
  1068.       } POINTER;
  1069.  
  1070. The x, y and z values are the location of the pointer in 0-centered coordinates.
  1071. The rx, ry and rz are the rotation of the pointer in 16.16 format.  Every
  1072. time you call pointer_read(), it compares the current values to the ones
  1073. it last read, and stores the differences in dx, dy, dz and drx, dry, drz.
  1074. These will not be updated if the databits field of the pconfig structure
  1075. indicates they are not available.
  1076.  
  1077. The buttons represent up to 3 buttons, each of which is down or up;
  1078. Again, there is a mask field in databits in pconfig.
  1079.  
  1080. The flexion information is only meaningful for glove-type devices.
  1081. For gloves, it is 10 entries from 0 (straight) to 255 (fully bent) in the
  1082. order (T, I, M, R, P) for fingers, and (base, distal) bend joint.
  1083.  
  1084. The keys field indicates any keys that may be on the device (e.g. the keypad
  1085. on the Nintendo PowerGlove).  The nullkey field in pconfig gives the
  1086. "no-key" code (see pdriver.doc for details).
  1087.  
  1088. The changed flag is set if the data has changed since the last read.  It
  1089. is set by pointer_read() (see this function for the codes).
  1090.  
  1091. The routine pointer_to_world() (see section on CURSOR ROUTINES for details)
  1092. will update the world transform matrix and set the wpos_valid flag; this flag
  1093. is cleared when fresh data is read in.
  1094.  
  1095. The gesture field is provided for those systems that support gesture
  1096. recognition.  Some codes are identified in the pointer.h file.  The glove
  1097. driver must do the recognition.
  1098.  
  1099. The following routines provided support for pointer devices:
  1100.  
  1101. PDRIVER *pointer_init(int type, char *driverfile)
  1102.       Initializes a driver, and returns a handle for reading data from it.
  1103.       The type field is a subset of the bits in the type field of pconfig,
  1104.       and can configure some pointer drivers.
  1105.       The given driverfile name is the name of a device driver file that
  1106.       gets loaded in ("mouse", "sega", and "pglove" are built-in). If the
  1107.       device cannot be initialized, NULL is returned.
  1108.  
  1109. PCONFIG *pointer_check(PDRIVER *drvr)
  1110.       Checks the current status of the given device, and returns a pointer
  1111.       to the pconfig struct that describes the characteristics of the device.
  1112.  
  1113. unsigned pointer_read(PDRIVER *drvr, POINTER *pointerdata)
  1114.       Reads the pointing device associated with drvr, and updates the fields
  1115.       in the given pointer data struct.  Returns a "changed" mask that's the
  1116.       bitwise OR of the following:
  1117.  
  1118.            PNEW_POS    position in 3-space has changed
  1119.            PNEW_ROT    orientation has changed
  1120.            PNEW_BUT    button status has changed
  1121.            PNEW_GEST   gesture state has changed
  1122.            PNEW_KEY    a key has been pressed/released
  1123.            PNEW_FLEX   the flexion information has changed
  1124.  
  1125. int last_pointer(PDRIVER *drvr, POINTER *p)
  1126.       Similar to pointer_read(), but returns the previously read value (i.e.
  1127.       does not re-read the pointer device.
  1128.  
  1129. void pointer_reset(PDRIVER *drvr)
  1130.       Resets the specified pointer driver to a known state.
  1131.  
  1132. void pointer_quit(PDRIVER *drvr)
  1133.       Shuts down the specified driver.
  1134.  
  1135. PCONFIG *device_command(PDRIVER *drvr, int command)
  1136.       Sends a command to the pointer device (sort of like an ioctl() call).
  1137.       Possible commands are bits of the commands field of pconfig.
  1138.  
  1139. void pointer_tscale(PDRIVER *drvr, long x, long y, long z)
  1140.       Sets the amounts by which translation should be scaled in x, y and z.
  1141.       The range will be set to +/- the given value.
  1142.  
  1143. void pointer_rscale(PDRIVER *drvr, long rx, long ry, long rz)
  1144.       Sets the amounts by which rotation about the x, y and z axes.
  1145.       The range will be set to +/- the given value in (16.16) format.
  1146.  
  1147. void pointer_abscale(PDRIVER *drvr, long xs, long ys, long zs,
  1148.           long rxs, long rys, long rzs)
  1149.       Sets the absolute scale values for translation and rotation.
  1150.       This means that the xres etc. values are used to compute a scale
  1151.       so that the returned positions are in 1 mm per unit, and the
  1152.       rotation in <16.16> degrees (real world measures).
  1153.  
  1154. int mouse_read(PDRIVER *drvr, int *x, int *y, unsigned *b)
  1155.       Emulates a mouse driver with a pointer device; sets *x and *y to
  1156.       screen position, and *b to button status.  Returns non-zero if the
  1157.       values have changed.
  1158.  
  1159. int mouse_last(PDRIVER *drvr, int *x, int *y, unsigned *b)
  1160.       Similar to mouse_read(), but returns the previously read position
  1161.       (i.e. does not read the pointer device).
  1162.  
  1163. int set_mouse_limits(PDRIVER *drvr, int maxx, int maxy)
  1164.       Sets the maximum X and Y limits for the mouse device.
  1165.  
  1166. SECTION N -- USER-INTERFACE ROUTINES
  1167.  
  1168. These routines allow you to provide a simple user interface.
  1169.  
  1170. void neatbox(int w, int h, int *x, int *y)
  1171.         Displays a neat-looking box of height h and width w, centered on the
  1172.         screen.  The *x and *y values are set to the computed top-left corner
  1173.         of the box.
  1174.  
  1175. void poptext(char *text[])
  1176.         Pops up text box on the screen; the 'text' parameter is an array of
  1177.         strings, the last of which is NULL.
  1178.  
  1179. void popmsg(char *msg)
  1180.         Pops up a one-line message in a box centered on the screen.
  1181.         Especially useful for debugging.
  1182.  
  1183. unsigned askfor(char *prompt, char *buff, int n)
  1184.         Prompts the user to enter a string; buff must contain room for up to n
  1185.         characters plus a null byte to terminate the string.
  1186.  
  1187. int menu(char *text[])
  1188.         Pops up a menu of text strings, and returns the index of the one
  1189.         the user selects (either with a pointing device or by hitting the
  1190.         first letter of any entry)
  1191.  
  1192. SECTION O -- PLG FILE I/O ROUTINES
  1193.  
  1194. The ".plg" file format is described in plg.doc; it is not tightly coupled to
  1195. the rest of the renderer software.
  1196.  
  1197. OBJECT *load_plg(FILE *in)
  1198.       Loads a .plg file and returns a pointer to the newly-created OBJECT.
  1199.       The global variable load_err will be set to a non-zero value if there
  1200.       was a problem loading the file.  As the file is loaded, it is first
  1201.       scaled by the current scaling factor and then shifted by the current
  1202.       x,y,z offset.
  1203.  
  1204. OBJECT *load_multi_plg(FILE *in)
  1205.       Works just like load_plg(), but loads a series of representations
  1206.       from the plg file and stores them all into the object it creates.
  1207.       See plg.doc for details on multi-rep .plg files.
  1208.  
  1209. void set_loadplg_offset(long x, long y, long z)
  1210.       Specifies the x,y,z offset to use; see figure.doc for details.
  1211.     
  1212. void set_loadplg_scale(float x, float y, float z)
  1213.       Specifies the x,y,z scaling to use; see figure.doc for details.
  1214.  
  1215. save_plg(OBJECT *obj, FILE *out)
  1216.       Saves the given object as a .plg file.
  1217.  
  1218. void set_loadplg_depthsort(type)
  1219.       Sets the depth-sorting type to a particular value (see description of
  1220.       depth sorting earlier in this document for details).
  1221.  
  1222. void set_loadplg_colormap(unsigned *map, int msize)
  1223.       If the top bit of a color value in a .plg file is set, the bottom
  1224.       15 bits are taken to be an index into a "map" that specifies the
  1225.       actual color value to be used.  The map consists of msize values,
  1226.       each of which is an unsigned 16-bit number.
  1227.  
  1228. void strip_comment(char *buff)
  1229.       A utility routine (used outside of .plg file parsing) that strips
  1230.       off everything after the first '#' character in the given buffer.
  1231.  
  1232. In addition, a global int variable called load_err is set to a non-zero
  1233. value if an error was encountered while loading a .plg file; see the code in
  1234. plg.c for details.
  1235.  
  1236. SECTION P -- FIG FILE I/O ROUTINES
  1237.  
  1238. A figure file consists of a set of segments.  See figure.doc for details.
  1239. The format of a figure file is not tightly coupled to the rest of the
  1240. renderer.
  1241.  
  1242. SEGMENT *readseg(FILE *in, SEGMENT *parent)
  1243.      Allocates a new segment, with the given parent, and reads a segment
  1244.      description into that segment.  If the file contains nested segments,
  1245.      readseg will recursively call itself to load them.  See figure.doc for
  1246.      more information.  The global integer variable readseg_err will be set
  1247.      to a non-zero value if an error was encountered during loading.
  1248.  
  1249. void set_readseg_scale(float x, float y, float z)
  1250.      Specifies a set of values that get used to "pre-scale" loaded plg files.
  1251.      Note that this is used in addition to the plg scaling; i.e. the two
  1252.      scale factors are multiplied together to give the actual factor.
  1253.  
  1254. void set_readseg_objlist(OBJLIST *objlist)
  1255.      Sets the given object list as the one to add newly-loaded representations
  1256.      to.
  1257.  
  1258. void set_readseg_seglist(SEGMENT **seglist, int maxsegs)
  1259.      Segments in .FIG files now have an optional "segnum" attribute that
  1260.      associates a simple integer with a the segment.  This allows you to
  1261.      subsequently refer to segments by number.  The given seglist is an
  1262.      array of pointers to segments that you supply, which will get filled
  1263.      in as segments get loaded.  The value maxsegs specifies the number of
  1264.      slots in the seglist.  Note that you can have as many seglists as you
  1265.      like, possibly even one for each figure.
  1266.  
  1267. writeseg(FILE *out, SEGMENT *s, int level)
  1268.      Writes the given segment out to a file; 'level' is used to provide
  1269.      levels of indentation, since writeseg calls itself recursively.  In
  1270.      general, root segments should be written out with level = 0.
  1271.  
  1272. In addition, a global int variable called readseg_err is set to a non-zero
  1273. value if an error was encountered while loading a .fig file; see the code in
  1274. segio.c for details.
  1275.  
  1276. SECTION Q -- PCX FILE I/O ROUTINES
  1277.  
  1278. These routines are only available in Mode Y.  They allow you to read
  1279. and write .PCX files (PC-Paintbrush format).  THESE ARE NOT SUPPORTED
  1280. BY THE VIDEO DRIVERS, so use at your own risk!
  1281.  
  1282. load_pcx(FILE *in, int page)
  1283.        Load a 320x200x256 .PCX image from the given file onto the given
  1284.        display page.
  1285.  
  1286. int save_pcx(FILE *out, int page)
  1287.        Save a 320x200x256 .PCX image into the given file from the given
  1288.        display page.
  1289.  
  1290. SECTION R -- STEREOSCOPIC RENDERING
  1291.  
  1292. The rend386 package supports stereoscopic rendering.  The structure
  1293. STEREO is used to store information about the stereo environment.
  1294.  
  1295. The fields in this structure are:
  1296.     phys_screen_dist  - the distance in mm from the eye to the screen
  1297.     phys_screen_width - the viewport width on the screen in mm
  1298.     pixel_width       - the viewport width in pixels
  1299.     phys_eye_spacing  - the physical spacing between the eyes, in mm
  1300.     world_scaling     - world units per physical mm
  1301.     phys_convergence  - the convergence distance in mm (usually the same
  1302.                         as phys_screen_dist)
  1303.  
  1304. All units are stored as long integers.
  1305.  
  1306. The stereo_type variable is set to one of:
  1307.  
  1308. #define MONOSCOPIC 0 /* monoscopic */
  1309. #define SWITCHED   1 /* time-multiplexed (like Sega glasses) */
  1310. #define SPLITLR    3 /* seperate left, right windows on screen */
  1311. #define SEPERATE   5 /* seperate VGA cards for left, right */
  1312.  
  1313. The following routines support stereoscopic rendering:
  1314.  
  1315. void compute_stereo_data(STEREO *stereo, int eye, int xflip, int xdist,
  1316.           long yr, long left, long top, long right, long bottom );
  1317.    Computes stereo parameters and caches them for use with make_stereo_view().
  1318.    Eye is 0 (left) or 1 (right). xflip will flip left to right on this eye
  1319.    (mirror).  xdist is a pixel offset of the center of the window used mostly for
  1320.    HMDs or split-screen displays.  yr is a <16.16> angle to "tilt" the image plane
  1321.    about the Y axis (for HMDs, etc).  The left, top, bottom, and right are
  1322.    the viewport for this eye (useful mostly for split screens)-- use the
  1323.    viewport clipping if not needed.
  1324.  
  1325. void make_stereo_view(VIEW *root, VIEW *nview, int eye);
  1326.    Given a view (the center or cyclopean view) will fill in nview with
  1327.    the view for that eye.  Calls initialize_view_factors() so is a bit
  1328.    expensive.
  1329.  
  1330. void update_stereo_view(VIEW *v, STEREO *s, int eye);
  1331.    Sufficient if only view point has changed and no twist or offset.
  1332.    CAUTION.
  1333.  
  1334. void default_stereo_setup(VIEW *v, STEREO *s);
  1335.    Sets up a Sega time-multiplexed view.
  1336.  
  1337. See the routine refresh_display() in demo4.c for an example of how all this
  1338. works.
  1339.  
  1340. SECTION S -- SUPPORT FOR THE SEGA 3D GLASSES AND NINTENDO POWERGLOVE
  1341.  
  1342. The Sega 3D glasses are now supported by rend386.  See the file sega.txt for
  1343. details on how to build an interface for the Sega glasses that allows them to
  1344. be connected to a serial port; the sega.txt file is in demo4.zip.
  1345.  
  1346. The Nintendo Powerglove is now supported by rend386.  See the article in the
  1347. July 1990 Byte magazine for details on constructing a cable that allows the
  1348. glove to be connected to a parallel port.
  1349.  
  1350. SOME OF THE FOLLOWING IS OBSOLETE IF YOU ARE USING DRIVERS,
  1351. but may be useful otherwise:
  1352.  
  1353. In order to use the Sega glasses or the Nintendo Powerglove, you must call
  1354. the following routine:
  1355.  
  1356. void init_SG_interrupt(void (*sega_switcher), void (*glove_handler), int tc)
  1357.     Installs interrupt support for the Sega glasses and the Nintendo glove.
  1358.     The sega_switcher() routine will be called just before the vertical
  1359.     retrace triggers, and the glove_handler() routine will be called at
  1360.     least once per screen refresh.  If either routine is NULL, then that
  1361.     routine will not be called.  The tc value indicates the interval (in
  1362.     units of 1.19 microseconds) for polling the glove; 6500 is a good
  1363.     value to use if the sega_switcher is also being used.
  1364.  
  1365. If you do not use this, call init_timer() to start the timing
  1366. for animation and speed control.  See demo4.c for more information.
  1367.  
  1368. Two routines are provided which may be passed as parameters to the
  1369. init_SG_interrupt() routine: switch_sega() and glove_int_handler().
  1370.  
  1371. Starting with version 4 of REND386, it is possible to load a driver for
  1372. doing the left/right switching.
  1373.  
  1374. init_switch_driver(char *filename)
  1375.      Loads a switching driver from the given file.
  1376.  
  1377. void switch_sega(to_go)
  1378.      Switches the sega glasses from left eye to right eye or vice-versa, and
  1379.      swaps the screen as well.  To_go will be 0 for switching, 1 for the
  1380.      video page switch.
  1381.  
  1382. int left_page;
  1383. int right_page;
  1384.      The global variables left_page is the number of the screen page that
  1385.      contains the left-eye image, and right_page is the number of the screen
  1386.      page that contains the right-eye image.  In Mode X, four pages are
  1387.      available altogether, so you can have an "active" left-right pair and a
  1388.      "visual" left-right pair.
  1389.  
  1390. void sega_off()
  1391.      The routine sega_off() can be used to make both lenses on the Sega
  1392.      glasses transparent; it should be called before exiting to avoid
  1393.      damaging the glasses.
  1394.  
  1395. void select_sega_port(int port)
  1396.      Specifies the i/o port address at which the Sega controller is found.
  1397.  
  1398. int sega_port_image, sega_mask, sega_left, sega_right, sega_doff;
  1399.      The meaning of these global variables is defined in the SEGAPORT
  1400.      description in the world.doc file.
  1401.  
  1402. The following struct contains data from the Powerglove:
  1403.  
  1404. typedef struct {
  1405.       signed char x, y, z, rot, fingers, keys, gstat1, gstat2, rxflags;
  1406.       unsigned int nmissed;
  1407.       } glove_data;
  1408.  
  1409. The x, y, and z values are the location of the glove in three-space; the
  1410. rot value is the rotation position (0 to 12).  The fingers are a one-byte
  1411. bitmap, two bits for each of the thumb and three fingers (pinky not included).
  1412. The keys value indicates which keys are down on the wrist control panel.
  1413.  
  1414. The following routines can be used to interface to the Powerglove:
  1415. (but use of the "pglove" driver is recommended).
  1416.  
  1417. void glove_init(int gdeg)
  1418.    Sets up the glove and enters hi-res mode.  If gdeg is non-zero, deglitching
  1419.    is enabled.
  1420.  
  1421. int glove_ready()
  1422.    Returns 0 if the glove is not ready, 1 if data is ready, 2 if data is ready
  1423.    and the rxflags are valid.
  1424.  
  1425. int glove_read(glove_data *gdata)
  1426.    Reads the glove data into the given struct, and returns non-zero if the
  1427.    data has changed since the last time the routine was called.
  1428.  
  1429. long gesture_time;
  1430.    This global variable counts the number of glove-reads for which the
  1431.    current gesture has been seen.
  1432.  
  1433. unsigned char gesture_type;
  1434.    The current gesture, after mapping.  See segasupp.h for definitions of
  1435.    possible values.
  1436.  
  1437. In order to allow greater configurability, the following global variables
  1438. are available and may be set by the user:
  1439.  
  1440.     glove_in_port, glove_out_port, glove_write_mask, glove_none_mask,
  1441.     glove_latch_mask, glove_clock_mask, glove_clock_latch, port_image
  1442.  
  1443. All are ints and are describe in the PGLOVEPORT entry in the world.doc file.
  1444.  
  1445. The timing may also be configured by altering the glove_bit_delay and
  1446. glove_byte_delay values; again, both are ints.
  1447.  
  1448. Note that there is still considerable inherent glitching in the glove due
  1449. to noise, reflections and so forth.
  1450.  
  1451. See the demo file for other details.
  1452.  
  1453.  
  1454. SECTION T -- SPLITTING PLANES
  1455.  
  1456. Before reading this section, be sure you've read "splits.doc" (which
  1457. describes the basic ideas behind splitting planes).
  1458.  
  1459. A splitting plane divides space into two parts, each of which can be
  1460. further subdivided into two parts by another plane, and so on.  The
  1461. resulting is a binary 'splitting tree' which partitions space into
  1462. areas.
  1463.  
  1464. SPLIT *add_split(SPLIT **tree, long x, long y, long z,
  1465.           long nx, long ny, long nz, unsigned flags)
  1466.       This routine creates a splitting plane that passes through the given
  1467.       point [x,y,z] and has a normal pointing in the [nx,ny,nz] direction.
  1468.       The 'tree' parameter is a pointer to a pointer to a splitting tree,
  1469.       and the function returns a pointer to the newly-created split.
  1470.  
  1471. AREA *what_area(SPLIT *tree, long x, long y, long z)
  1472.       Returns a pointer to the area containing the point [x,y,z].
  1473.  
  1474. void add_obj_to_area(AREA *a, OBJECT *obj)
  1475.       Adds an object to the list of objects contained in the given area.
  1476.  
  1477. void add_obj_to_split(SPLIT *tree, OBJECT *obj)
  1478.       Adds an object to the list of objects.  Finds the correct split, then
  1479.       adds object to list on split side (area) or on the split plane
  1480.       itself (not recommended).
  1481.  
  1482. void split_move_handler(OBJECT *obj)
  1483.       When an object moves around, it may wind up in a different place
  1484.       in the splitting tree; this function gets called to move an
  1485.       object in the tree as needed.
  1486.  
  1487. void initial_world_split(SPLIT **split_ptr)
  1488.       Creates an initial split to define the "world", and stores it in the
  1489.       given pointer.  Typical usage would be:
  1490.             SPLIT *world;
  1491.             initial_world_split(&world);
  1492.  
  1493. void set_global_split_root(SPLIT **split_tree)
  1494.       Causes the given split tree to become the root of the splitting tree
  1495.       describing the world.  Note that it is entirely possibly to have
  1496.       multiple worlds, all independent and all having their own splitting
  1497.       trees.
  1498.  
  1499. OBJLIST *which_area_objlist(SPLIT *tree, long x, long y, long z)
  1500.       Returns the objlist for the area containing the given point [x,y,z].
  1501.  
  1502. OBJLIST *which_objlist(SPLIT *tree, long x, long y, long z)
  1503.       Returns the objlist for the splitting tree that divides the area
  1504.       containing the point [x,y,z].
  1505.  
  1506. void add_obj_to_split_area(SPLIT *tree, OBJECT *obj)
  1507.       Adds an object to the objlist for the appropriate area within the
  1508.       given split tree.  Recommended if object is NOT supposed to be
  1509.       a wall or surface to divide areas.
  1510.  
  1511. void add_obj_to_split_center(SPLIT *tree, OBJECT *obj)
  1512.       Adds an object to the objlist for the given split in the tree.
  1513.       Used to place objects on area divisions (e.g. walls).
  1514.  
  1515. void render_monitor_point(int x, int y)
  1516.       Defines a point on the screen for the 'monitor' routines; the next
  1517.       time the scene is rendered, the object and polygon 'under' this point
  1518.       and nearest the user will be noted.  This information may be retrieved
  1519.       using render_check_monitor().
  1520.  
  1521. OBJECT *render_check_monitor(int *poly, int *vert)
  1522.       Return a pointer to the object nearest the user and 'under' the point
  1523.       on the screen specified in the most recent call to the function
  1524.       render_monitor_point().  The poly pointer (if not NULL) is set to
  1525.       the number of the polygon (within the object's polygon list) of the
  1526.       polygon 'under' the screen point, and the vert pointer (if not NULL)
  1527.       is set to the index of vertex (within the object's vertex list) whose
  1528.       projection onto the screen is nearest the screen point.
  1529.  
  1530. void render_objlist(OBJLIST *objlist)
  1531.       Renders the given object list.
  1532.  
  1533. void render_area(AREA *a)
  1534.       Renders the objects contained in the given area.
  1535.  
  1536. void render_split(SPLIT *tree, VIEW *view)
  1537.       Renders the objects contained in the given splitting tree, from the
  1538.       given view.  The tree is walked such that objects on the far side of
  1539.       any given plane (relative to your view) are rendered first, followed
  1540.       by objects "on" the splitting plane, followed by objects on the near
  1541.       side of the plane.  This is done recursively, and eliminates visibility
  1542.       errors between areas.
  1543.  
  1544. void walk_area(AREA *a, void (*fn)())
  1545.       Walks the list of objects in the given area, calling the given function
  1546.       on each object found.
  1547.  
  1548. void walk_split_tree(SPLIT *tree, void (*fn)())
  1549.       Recursively walks down the given splitting tree, calling the given
  1550.       function on each object found.
  1551.  
  1552. void add_floor(AREA *area, long a, long b, long c, long d)
  1553.       Defines a plane (ax + by + cz + d) giving the tilt of the 'floor'
  1554.       in the given area.
  1555.  
  1556. void add_ceiling(AREA *area, long a, long b, long c, long d)
  1557.       Defines a plane (ax + by + cz + d) giving the tilt of the 'ceiling'
  1558.       in the given area.
  1559.  
  1560. long floor_at(AREA *a, long x, long z)
  1561.       Finds the height of the 'floor' at a point [x,z] in the given area.
  1562.  
  1563. long ceiling_at(AREA *a, long x, long z)
  1564.       Finds the height of the 'ceiling' at a point [x,z] in the given area.
  1565.  
  1566. void set_area_function(AREA *a, void (*fn)())
  1567.       Associates a function with the given area; the function can be called
  1568.       when you enter an area, for example.
  1569.  
  1570. void call_area_fn(AREA *a)
  1571.       Calls the function associated with the given area; the function is
  1572.       passed the area as a parameter.
  1573.  
  1574. SECTION U -- HIGH-RESOLUTION TIMER ROUTINES
  1575.  
  1576. REND386 now takes over the timer hardware; it chains to the existing handlers
  1577. at appropriate intervals, but you can do more accurate timekeeping than would
  1578. be possible using the standard 18.2 ticks/second timer.
  1579.  
  1580. void init_timer()
  1581.       Initializes the timer into high-resolution mode.  The timer will be
  1582.       automatically set back to normal when your program exits.
  1583.  
  1584. long current_time()
  1585.       Returns the current time in high-speed ticks.
  1586.  
  1587. void set_current_time(long newtime)
  1588.       Allows you to set the current time value returned by the current_time()
  1589.       function.  The time will, of course, advance from that point onwards.
  1590.  
  1591. long get_ticks_per_second()
  1592.       Returns the number of ticks per second in high-resolution mode.
  1593.  
  1594. volatile interrupts_occurred;
  1595.       This flag can be used to determine whether interrupts have occurred
  1596.       during a given period of time.  To use it, set its value to zero and
  1597.       then perform other activities.  You can check the flag periodically
  1598.       to see if interrupts have occurred.
  1599.  
  1600. The renderer code in render.c updates the variable last_render_time
  1601. which records the time (in ticks) to redraw the screen.  Useful for
  1602. scaling speeds, etc. or computing the drawing speed.
  1603.  
  1604. SECTION V -- TASKING ROUTINES
  1605.  
  1606. A very primitive "multi-tasking" system has been incorporated into REND386.
  1607.  
  1608. TASK *add_task(TASK **tasklist, void (*fn)(), long period, void *param)
  1609.     This will create a 'task', adding it to the given tasklist.  The parameter
  1610.     'fn' is the function defining the tasks, 'period' is the number of ticks
  1611.     that should elapse between calls, and 'param' is an arbitrary parameter
  1612.     to be passed to the 'fn'.
  1613.  
  1614. void del_task(TASK **tasklist, TASK *tsk)
  1615.     Deletes a task, removing it from the given tasklist and releasing its
  1616.     memory.
  1617.  
  1618. void run_tasks(TASK *tasklist)
  1619.      Should be called regularly in polling loops, etc to run the tasks in
  1620.      the given task list.
  1621.  
  1622. TASK *get_current_task()
  1623.      Returns the id of the currently-running task; typically called by a
  1624.      task function.
  1625.  
  1626. void *find_task_data(TASK *task)
  1627.      Returns a pointer to the task-specific data.  Typically called by a
  1628.      task function.
  1629.  
  1630.  
  1631. THE FUTURE:
  1632.  
  1633. This documentation is still incomplete, but we're releasing source
  1634. so you can find out other routines' specs as needed.
  1635.  
  1636. This rendering package is intended to be the foundation for a wide range
  1637. of applications.
  1638.  
  1639. It is suggested that radical changes not be made if you want the code to
  1640. be at all portable.  Redefining the standards and ideas in REND386 is
  1641. also discouraged without consultation, as there are many implicit concepts
  1642. in the code for future expansion.  Suggestions are always welcome.
  1643.  
  1644. For further information about the package, feel free to contact us:
  1645.  
  1646.     Bernie Roehl (broehl@sunee.uwaterloo.ca)
  1647.     Dave Stampe (dstampe@sunee.uwaterloo.ca)
  1648.  
  1649. Note that the ".ca" stands for CAnada, not CAlifornia!
  1650.  
  1651. The major contribution others can make to the project at this stage is
  1652. to write converters from other polygon formats to OFF.  In particular,
  1653. a DXF to OFF converter would let us create objects with a CAD package.
  1654.  
  1655. OFF is a reasonably good, open format that encodes author/copyright
  1656. information along with geometry and colors.  While it's a bit of a
  1657. nuisance to parse, it's very easy to generate.
  1658.  
  1659. Two of our data files were converted from OFF files using off2plg: the bishop
  1660. and the banana.  Below is the author/copyright information from their .aoff
  1661. files:
  1662.  
  1663. name           bishop8
  1664. description    chess piece - bishop
  1665. author         Randy Brown, brown@cs.unc.edu
  1666. copyright      (c) Randy Brown, OK to distribute if copyright/author appears
  1667.  
  1668. name           banana
  1669. description    Banana made on Frank Crow's U. Utah surface design system
  1670. copyright      (c) Ohio State Univ. - ok to distribute if copyright appears
  1671.  
  1672. That's it.  Please direct any questions to broehl@sunee.uwaterloo.ca or
  1673. dstampe@sunee.uwaterloo.ca, or join the mailing list.  To join the list,
  1674. send mail to rend386-request@sunee.uwaterloo.ca (the list itself is just
  1675. rend386@sunee.uwaterloo.ca).
  1676.