home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / SRC / DEMO4B / WORLD.CPP < prev   
C/C++ Source or Header  |  1993-05-09  |  25KB  |  911 lines

  1. /* Read a World Description File */
  2.  
  3. /* Written by Bernie Roehl, July 1992 */
  4.  
  5. /* Copyright 1992 by Dave Stampe and Bernie Roehl.
  6.    May be freely used to write software for release into the public domain;
  7.    all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
  8.    for permission to incorporate any part of this software into their
  9.    products!
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <ctype.h>
  16. #include "iostream.h"
  17.  
  18. #include "rend386.hpp"
  19. #include "tasks.hpp"
  20. #include "plg.h"
  21. #include "intmath.h"
  22. #include "splits.hpp"
  23. #include "pointer.hpp"
  24. #include "cursor.hpp"
  25. #include "segasupp.hpp"
  26. #include "segio.hpp"
  27. #include "world.hpp"
  28. #include "demo4.hpp"
  29. #include "userint.hpp"
  30. #include "keyboard.hpp"
  31.  
  32. extern SPLIT *split_tree;
  33.  
  34. extern int sl_xflip, sl_xoff;
  35. extern long sl_left, sl_top, sl_right, sl_bottom;
  36. extern int sr_xflip, sr_xoff;
  37. extern long sr_left, sr_top, sr_right, sr_bottom;
  38. extern float sl_xrot, sr_xrot;
  39.  
  40. extern unsigned screen_clear_color,sky_color,ground_color;
  41. extern int use_frame, redraw, review, reframe, do_screen_clear;
  42. extern int frame_x, frame_y, frame_w, frame_h; /* frame location */
  43. extern char framefname[];
  44. extern STEREO default_stereo;
  45. extern VIEW default_view;
  46. extern unsigned char *palette;
  47. extern int npalette;
  48. extern OBJLIST *objlist;
  49. extern TASK *tasklist;
  50. extern VIEW *current_view;
  51.  
  52. extern char *fix_fname(char *fname);
  53.  
  54. char dummy[8192];
  55.  
  56. OBJECT *where_split_screen_pt(int *pol, int *vert, int x, int y)
  57. {
  58.     extern OBJECT *render_check_monitor(int *pol, int *vert);
  59.  
  60.     render_monitor_point(x, y);
  61.     refresh_display();
  62.     return render_check_monitor(pol, vert);
  63. }
  64.  
  65. NAMEREF *add_name(NAMEREF **list, char *name, void *value)
  66. {
  67.     NAMEREF *p;
  68.     if ((p = (NAMEREF *)malloc(sizeof(NAMEREF))) == NULL) return NULL;
  69.     p->name = strdup(name);
  70.     p->value = value;
  71.     p->next = *list;
  72.     *list = p;
  73.     return *list;
  74. }
  75.  
  76. void del_namelist(NAMEREF *list)
  77. {
  78.     while (list) {
  79.         if (list->name)
  80.             free(list->name);
  81.         free(list);
  82.         list = list->next;
  83.     }
  84. }
  85.  
  86. void *find_name(NAMEREF *list, char *name)
  87. {
  88.     while (list) {
  89.         if (!stricmp(list->name, name))
  90.             return list->value;
  91.         list = list->next;
  92.     }
  93.     return NULL;
  94. }
  95.  
  96. char *find_value(NAMEREF *list, void *value)
  97. {
  98.     while (list) {
  99.         if (list->value == value)
  100.             return list->name;
  101.         list = list->next;
  102.     }
  103.     return NULL;
  104. }
  105.  
  106. #pragma argsused
  107. void ticker(int dum1, void * dum2, long dum3, long dum4)
  108. {
  109.     putchar('.');
  110. }
  111.  
  112. typedef struct _key KEY;
  113.  
  114. struct _key {
  115.     unsigned key;
  116.     void (*fn)(int, void *, long, long);
  117.     unsigned param;
  118.     KEY *next;
  119. };
  120.  
  121. KEY *keylist = NULL;
  122.  
  123. typedef struct _control CONTROL;
  124.  
  125. struct _control {
  126.     int x, y, w, h;
  127.     unsigned buttonmask;
  128.     void (*fn)(int, void *, long, long);
  129.     unsigned param;
  130.     CONTROL *next;
  131. };
  132.  
  133. CONTROL *controllist = NULL;
  134.  
  135. #define MAXSPINCOLORS 100
  136.  
  137. typedef struct {
  138.     OBJECT *obj;
  139.     int np; /* number of polys in obj */
  140.     int ncolors;
  141.     unsigned colors[MAXSPINCOLORS];
  142. } SPINDATA;
  143.  
  144. NAMEREF *objectlist = NULL;
  145.  
  146. #define LSCALE 536870912.0
  147.  
  148. void scale3(float a, float b, float c,
  149.     long *ap, long *bp, long *cp)
  150. {
  151.     float maxim; /* integerize normal */
  152.  
  153.     maxim = (a > 0) ? a : -a; /* BUG IN BC 3.0 fabs()! */
  154.     maxim += (b > 0) ? b : -b;
  155.     maxim += (c > 0) ? c : -c;
  156.     if (maxim > 0.0001)
  157.     {
  158.         maxim /= LSCALE;
  159.         *ap = a/maxim;
  160.         *bp = b/maxim; /* normalize to <3.29> */
  161.         *cp = c/maxim;
  162.     }
  163. }
  164.  
  165. void scale4(float a, float b, float c, float d,
  166.     long *ap, long *bp, long *cp, long *dp)
  167. {
  168.     float maxim; /* integerize normal */
  169.  
  170.     maxim = (a > 0) ? a : -a; /* BUG IN BC 3.0 fabs()! */
  171.     maxim += (b > 0) ? b : -b;
  172.     maxim += (c > 0) ? c : -c;
  173.     maxim += (d > 0) ? d : -d;
  174.     if (maxim > 0.0001)
  175.     {
  176.         maxim /= LSCALE;
  177.         *ap = a/maxim;
  178.         *bp = b/maxim; /* normalize to <3.29> */
  179.         *cp = c/maxim;
  180.         *dp = d/maxim;
  181.     }
  182. }
  183.  
  184.  
  185. /* facing normal, points should be in CW sequence */
  186. /* for axis aligned (+) split directions, use:    */
  187. /* x 0 0  x 100 0  x 0 100  for constant x */
  188. /* 0 y 0  0 y 100  100 y 0  for constant y */
  189. /* 0 0 z  100 0 z  0 100 z  for constant z */
  190.  
  191. void points_to_normal(float x1, float y1, float z1,
  192.     float x2, float y2, float z2,
  193.     float x3, float y3, float z3,
  194.     long *ap, long *bp, long *cp)
  195. {
  196.     float v1x, v1y, v1z, v2x, v2y, v2z;
  197.     float a, b, c; /* compute line equation */
  198.  
  199.     v1x = x2 - x1; 
  200.     v1y = y2 - y1; 
  201.     v1z = z2 - z1;
  202.     v2x = x3 - x1; 
  203.     v2y = y3 - y1; 
  204.     v2z = z3 - y1;
  205.     a = (v1y * v2z - v2y * v1z);
  206.     b = (v1x * v2z - v2x * v1z);
  207.     c = (v1x * v2y - v2x * v1y);
  208.  
  209.     scale3(a, b, c, ap, bp, cp);
  210. }
  211.  
  212. void points_to_eqn(float x1, float y1, float z1,
  213.     float x2, float y2, float z2,
  214.     float x3, float y3, float z3,
  215.     long *ap, long *bp, long *cp, long *dp)
  216. {
  217.     float v1x, v1y, v1z, v2x, v2y, v2z;
  218.     float a, b, c, d; /* compute line equation */
  219.  
  220.     v1x = x2 - x1; 
  221.     v1y = y2 - y1; 
  222.     v1z = z2 - z1;
  223.     v2x = x3 - x1; 
  224.     v2y = y3 - y1; 
  225.     v2z = z3 - y1;
  226.     a = (v1y * v2z - v2y * v1z);
  227.     b = (v1x * v2z - v2x * v1z);
  228.     c = (v1x * v2y - v2x * v1y);
  229.     d = -(a*x1 + b*y1 + c*z1); /* normalize to <3.29> */
  230.  
  231.     scale4(a, b, c, d, ap, bp, cp, dp);
  232. }
  233.  
  234. void normal_to_plane(float x, float y, float z,
  235.     float nx, float ny, float nz,
  236.     long *ap, long *bp, long *cp, long *dp)
  237. {
  238.     float a, b, c, d; /* compute line equation  */
  239.     /* given normal and point */
  240.     a = nx; 
  241.     b = -ny; 
  242.     c = nz;
  243.     d = -(a*x + b*y + c*z);
  244.  
  245.     scale4(a, b, c, d, ap, bp, cp, dp);
  246. }
  247.  
  248.  
  249. extern PDRIVER *menu_device;
  250.  
  251. #pragma argsused
  252. void clickfn(int cmd, void *msg, long dum1, long dum2)
  253. {
  254.     char buff[100];
  255.     int x, y;
  256.     unsigned buttons;
  257.     if (cmd == 3) {
  258.         sprintf(buff, "button %u", *((unsigned *)msg));
  259.         popmsg(buff);
  260.         /*        do {
  261.                     mouse_read(&x, &y, &buttons);   NEEDS PTR DEVICE UPDATE
  262.                 }
  263.                 while (buttons & 1);
  264.         */     }
  265.     else if (cmd == 2) {
  266.         sprintf(buff, "key %u", *((unsigned *)(msg)));
  267.         popmsg(buff);
  268.         getkey();
  269.     }
  270.     reframe = redraw = 1;
  271. }
  272.  
  273. check_key(unsigned key)
  274. {
  275.     KEY *p;
  276.     for (p = keylist; p; p = p->next)
  277.         if (key == p->key) {
  278.             p->fn(2, &p->param, 0L, 0L);
  279.             return 1;
  280.         }
  281.     return 0;
  282. }
  283.  
  284. check_controls(int x, int y, unsigned buttons)
  285. {
  286.     CONTROL *p;
  287.     for (p = controllist; p; p = p->next)
  288.         if (x >= p->x && y >= p->y && x < (p->x + p->w) && y < (p->y + p->h) && (buttons & p->buttonmask)) {
  289.             p->fn(3, &p->param, 0L, 0L);
  290.             return 1;
  291.         }
  292.     return 0;
  293. }
  294.  
  295. match(char *a, char *b)
  296. {
  297.     return !strnicmp(a, b, strlen(b));
  298. }
  299.  
  300. extern void spinner(int, void *, long, long), sculspin(int, void *, long, long);
  301.  
  302. struct {
  303.     char *name;
  304.     void (*fn)(int, void *, long, long);
  305. } functions[] = {
  306.     { "ticker", ticker },
  307.     { "spinner", spinner },
  308.     { "sculspin", sculspin },
  309.     { "clickfn", clickfn },
  310.     { NULL, NULL }
  311. };
  312.  
  313. NAMEREF *areas = NULL;
  314. NAMEREF *maps = NULL;
  315. NAMEREF *surfdefs = NULL;
  316.  
  317. typedef struct _surface SURFACE;
  318.  
  319. struct _surface {
  320.     unsigned color;
  321.     char *value;
  322.     SURFACE *next;
  323. };
  324.  
  325. extern char loadpath[];
  326. extern char cursorloadpath[];
  327.  
  328. extern int show_framerate, show_location, show_compass, show_gestures;
  329. extern Boolean want_mouse;
  330.  
  331. // If we're reading in a config file, we want to use defaults.
  332. Boolean read_world(FILE *in)
  333. {
  334.     char inbuff[256], *buff, fname[100];
  335.     char surfacemapname[100];
  336.     SURFACE *current_surface = NULL, *map;
  337.     int i;
  338.     SPLIT *current_split = NULL;
  339.     while (fgets(inbuff, sizeof(inbuff), in)) {
  340.         strip_comment(inbuff);
  341.         for (buff = inbuff; isspace(*buff); ++buff);
  342.  
  343.         if (match(buff, "showframerate "))
  344.             sscanf(buff, "%*s %d", &show_framerate);
  345.         else if (match(buff, "showlocation "))
  346.             sscanf(buff, "%*s %d", &show_location);
  347.         else if (match(buff, "showgestures "))
  348.             sscanf(buff, "%*s %d", &show_gestures);
  349.         else if (match(buff, "showcompass "))
  350.             sscanf(buff, "%*s %d", &show_compass);
  351.  
  352.         if (match(buff, "loadpath "))
  353.             sscanf(buff, "%*s %s", loadpath);
  354.         else if (match(buff, "palette ")) {
  355.             FILE *in;
  356.             sscanf(buff, "%*s %s", fname);
  357.             if ((in = fopen(fix_fname(fname), "rb")) != NULL) {
  358.                 npalette = fread(palette, 3, 256, in);
  359.                 fclose(in);
  360.             }
  361.         }
  362.         if (match(buff, "skycolor ")) /* can have optional r,g,b at end of line */
  363.             sscanf(buff, "%*s %d", &sky_color);
  364.         else if (match(buff, "groundcolor ")) /* can have optional r,g,b at end of line */
  365.             sscanf(buff, "%*s %d", &ground_color);
  366.         else if (match(buff, "screenclearcolor "))
  367.             sscanf(buff, "%*s %d", &screen_clear_color);
  368.         else if (match(buff, "screenclear "))
  369.             sscanf(buff, "%*s %d", &do_screen_clear);
  370.         else if (match(buff, "ambient ")) {
  371.             sscanf(buff, "%*s %d", ¤t_view->ambient);
  372.             /* current_view->ambient = (0.3 * (r%256) + 0.59 * (g%256) + 0.21 * (b%256)) / 3; */
  373.         }
  374.         else if (match(buff, "worldscale ")) {
  375.             float ws;
  376.             sscanf(buff, "%*s %f", &ws);
  377.             default_stereo.world_scaling = 65536.0 * ws;
  378.         }
  379.         else if (match(buff, "light "))
  380.             /* light x,y,z r,g,b dx,dy,dz angle radius sampling sampling */
  381.             sscanf(buff, "%*s %ld,%ld,%ld",
  382.             &default_view.lx, &default_view.ly, &default_view.lz);
  383.         else if (match(buff, "window ")) {
  384.             int x, y, w, h;
  385.             switch (sscanf(buff, "%*s %d,%d,%d,%d", &x, &y, &w, &h)) {
  386.             case 4:
  387.                 default_view.bottom = y + h - 1;
  388.             case 3:
  389.                 default_view.right = x + w - 1;
  390.             case 2:
  391.                 default_view.top = y;
  392.             case 1:
  393.                 default_view.left = x;
  394.             default:
  395.                 break;
  396.             };
  397.         }
  398.         else if (match(buff, "key ")) {
  399.             char fname[100];
  400.             unsigned key, param;
  401.             int i;
  402.             sscanf(buff, "%*s %x %s %u", &key, fname, ¶m);
  403.             for (i = 0; functions[i].name; ++i)
  404.                 if (!stricmp(fname, functions[i].name)) {
  405.                     KEY *k;
  406.                     if ((k = (KEY *)malloc(sizeof(KEY))) != NULL) {
  407.                         k->key = key;
  408.                         k->param = param;
  409.                         k->fn = functions[i].fn;
  410.                         k->next = keylist;
  411.                         keylist = k;
  412.                     }
  413.                     break;
  414.                 }
  415.         }
  416.         else if (match(buff, "control ")) {
  417.             char fname[100];
  418.             int x, y, w, h;
  419.             unsigned mask, param;
  420.             int i;
  421.             sscanf(buff, "%*s %d,%d,%d,%d %u %s %u",
  422.             &x, &y, &w, &h, &mask, fname, ¶m);
  423.             for (i = 0; functions[i].name; ++i)
  424.                 if (!stricmp(fname, functions[i].name)) {
  425.                     CONTROL *c;
  426.                     if ((c = (CONTROL *)malloc(sizeof(CONTROL))) != NULL) {
  427.                         c->x = x; 
  428.                         c->y = y; 
  429.                         c->w = w; 
  430.                         c->h = h;
  431.                         c->buttonmask = mask; 
  432.                         c->fn = functions[i].fn;
  433.                         c->param = param;
  434.                         c->next = controllist; 
  435.                         controllist = c;
  436.                     }
  437.                     break;
  438.                 }
  439.         }
  440.         else if (match(buff, "frame ")) {
  441.             FILE *in;
  442.             sscanf(buff, "%*s %s %d,%d,%d,%d", framefname, &frame_x, &frame_y, &frame_w, &frame_h);
  443.             use_frame = 1;
  444.         }
  445.         else if (match(buff, "start ")) {
  446.             float pan, tilt, roll, zoom;
  447.             sscanf(buff, "%*s %ld,%ld,%ld %f,%f,%f %f",
  448.             &default_view.ex, &default_view.ey, &default_view.ez,
  449.             &pan, &tilt, &roll, &zoom);
  450.             if (zoom == 0) zoom = 3;
  451.             default_view.pan = pan * 65536L; 
  452.             default_view.tilt = tilt * 65536L;
  453.             default_view.roll = roll * 65536L; 
  454.             default_view.zoom = zoom * 65536L;
  455.         }
  456.         else if (match(buff, "hither "))
  457.             sscanf(buff, "%*s %ld", &default_view.hither);
  458.         else if (match(buff, "yon "))
  459.             sscanf(buff, "%*s %ld", &default_view.yon);
  460.         else if (match(buff, "eyespacing "))
  461.             sscanf(buff, "%*s %ld", &default_stereo.phys_eye_spacing);
  462.         else if (match(buff, "screendist "))
  463.             sscanf(buff, "%*s %ld", &default_stereo.phys_screen_dist);
  464.         else if (match(buff, "screenwidth "))
  465.             sscanf(buff, "%*s %ld,%d", &default_stereo.phys_screen_width,
  466.             &default_stereo.pixel_width);
  467.         else if (match(buff, "convergence "))
  468.             sscanf(buff, "%*s %ld", &default_stereo.phys_convergence);
  469.  
  470.         else if (match(buff, "figure "))
  471.         {
  472.             char filename[60], parentname[60], *p;
  473.             float sx = 1, sy = 1, sz = 1, rx = 0, ry = 0, rz = 0;
  474.             long tx = 0, ty = 0, tz = 0;
  475.             FILE *fig;
  476.             parentname[0] = '\0';
  477.             sscanf(buff, "%*s %s %f,%f,%f %f,%f,%f %ld,%ld,%ld %s ",
  478.             filename, &sx, &sy, &sz, &rx, &ry, &rz, &tx, &ty, &tz, parentname);
  479.             strcat(filename, ".fig");
  480.             set_readseg_scale(sx, sy, sz);
  481.             if ((p = strchr(filename, '=')) != NULL)
  482.                 *p++ = '\0';
  483.             else
  484.                 p = filename;
  485.             if ((fig = fopen(fix_fname(p), "r")) != NULL)
  486.             {
  487.                 SEGMENT *this_seg;
  488.                 set_readseg_objlist(objlist);
  489.                 if ((this_seg = readseg(fig, NULL)) != NULL)
  490.                 {
  491.                     abs_move_segment(this_seg, tx, ty, tz);
  492.                     abs_rot_segment(this_seg, rx*65536L, ry*65536L, rz*65536L, RYXZ);
  493.                     update_segment(this_seg);
  494.                 }
  495.                 fclose(fig);
  496.             }
  497.         }
  498.  
  499.         else if (match(buff, "object "))
  500.         {
  501.             char mappings[100], *p, filename[100], *oname, parentname[100];
  502.             float sx = 1, sy = 1, sz = 1, rx = 0, ry = 0, rz = 0;
  503.             long tx = 0, ty = 0, tz = 0;
  504.             int dt = 0;
  505.             MATRIX m;
  506.             FILE *plg;
  507.             OBJECT *obj;
  508.  
  509.             parentname[0] = mappings[0] = '\0';
  510.             sscanf(buff, "%*s %s %f,%f,%f %f,%f,%f %ld,%ld,%ld %d %s %s",
  511.             filename, &sx, &sy, &sz, &rx, &ry, &rz, &tx, &ty, &tz, &dt, mappings, parentname);
  512.             strcat(filename, ".plg");
  513.             set_loadplg_scale(sx, sy, sz);
  514.             set_loadplg_depthsort(dt);
  515.  
  516.             map = (SURFACE *)find_name(maps, mappings);
  517.  
  518.             if ((p = strchr(filename, '=')) != NULL)
  519.             {
  520.                 oname = filename;
  521.                 *p++ = '\0';
  522.             }
  523.             else
  524.             {
  525.                 oname = NULL;
  526.                 p = filename;
  527.             }
  528.             if ((plg = fopen(fix_fname(p), "r")) != NULL)
  529.             {
  530.                 while((obj=load_plg(plg))!=NULL)
  531.                     if (obj)
  532.                     {
  533.                         if (map)
  534.                         {
  535.                             int np;
  536.  
  537.                             get_obj_info(obj, NULL, &np);
  538.                             while (np--)
  539.                             {
  540.                                 SURFACE *p;
  541.                                 unsigned color;
  542.                                 void *v;
  543.  
  544.                                 get_poly_info(obj, np, &color, NULL, NULL, 0);
  545.                                 for (p = map; p; p = p->next)
  546.                                     if (p->color == color)
  547.                                     {
  548.                                         if ((v = find_name(surfdefs, p->value)) != NULL)
  549.                                             set_poly_color(obj, np, (unsigned) v);
  550.                                         break;
  551.                                     }
  552.                             }
  553.                         }
  554.  
  555.                         if (oname) add_name(&objectlist, oname, obj);
  556.                         oname = NULL; /* so it's done once only */
  557.  
  558.                         if (!stricmp(parentname, "fixed"))
  559.                         {
  560.                             std_matrix(m, (long) (rx * 65536L), (long) (ry * 65536L),
  561.                             (long) (rz * 65536L), tx, ty, tz);
  562.                             apply_matrix(obj, m);
  563.                             if (current_split)
  564.                                 add_obj_to_split_center(current_split, obj);
  565.                             else
  566.                                 add_obj_to_split_area(split_tree, obj);
  567.                         }
  568.                         else
  569.                             {
  570.                             SEGMENT *s, *p = NULL;
  571.                             OBJECT *o;
  572.  
  573.                             if ((o = (OBJECT *)find_name(objectlist, parentname)) != NULL)
  574.                                 p = (SEGMENT *)get_object_owner(o);
  575.                             s = new_seg(p);
  576.                             seg_set_object(s, obj);
  577.                             set_object_owner(obj, s);
  578.                             abs_rot_segment(s, rx * 65536L, ry * 65536L, rz * 65536L, RYXZ);
  579.                             abs_move_segment(s, tx, ty, tz);
  580.                             update_segment(s);
  581.                         }
  582.                     }
  583.             }
  584.             fclose(plg);
  585.         }
  586.  
  587.         else if (match(buff, "task ")) {
  588.             char taskname[100], param[100];
  589.             long period;
  590.             int i;
  591.             void *data;
  592.             sscanf(buff, "%*s %s %ld %s", taskname, &period, param);
  593.             for (i = 0; functions[i].name; ++i)
  594.                 if (!stricmp(taskname, functions[i].name)) {
  595.                     add_task(&tasklist, functions[i].fn, period, param);
  596.                     break;
  597.                 }
  598.         }
  599.         else if (match(buff, "position ")) {
  600.             OBJECT *obj;
  601.             SEGMENT *s;
  602.             char oname[100];
  603.             long x, y, z;
  604.             sscanf(buff, "%*s %s %ld,%ld,%ld", oname, &x, &y, &z);
  605.             if ((obj = (OBJECT *)find_name(objectlist, oname)) != NULL)
  606.                 if ((s = (SEGMENT *)get_object_owner(obj)) != NULL) {
  607.                     abs_move_segment(s, x, y, z);
  608.                     update_segment(s);
  609.                     remove_from_objlist(obj);
  610.                     add_obj_to_split_area(split_tree, obj);
  611.                 }
  612.         }
  613.         else if (match(buff, "rotate ")) {
  614.             OBJECT *obj;
  615.             SEGMENT *s;
  616.             char oname[100];
  617.             float rx, ry, rz;
  618.             sscanf(buff, "%*s %s %f,%f,%f", oname, &rx, &ry, &rz);
  619.             if ((obj = (OBJECT *)find_name(objectlist, oname)) != NULL)
  620.                 if ((s = (SEGMENT *)get_object_owner(obj)) != NULL) {
  621.                     abs_rot_segment(s, rx * 65536L, ry * 65536L, rz * 65536L, RYXZ);
  622.                     update_segment(s);
  623.                 }
  624.         }
  625.         else if (match(buff, "camera ")) {
  626.             int n;
  627.             long x = default_view.ex, y = default_view.ey, z = default_view.ez;
  628.             float pan = default_view.pan, tilt = default_view.tilt, roll = default_view.roll;
  629.             float zoom = default_view.zoom;
  630.             float hither = default_view.hither, yon = default_view.yon;
  631.             sscanf(buff, "%*s %d %ld,%ld,%ld %f,%f,%f %f %ld %ld",
  632.             &n, &x, &y, &z, &tilt, &pan, &roll, &zoom, &hither, &yon);
  633.             --n; /* camera 1 is on key 0 ... */
  634.         }
  635.         else if (match(buff, "attrib ")) {
  636.             /* ignore for now */
  637.         }
  638.         else if (match(buff, "include ")) {
  639.             char fname[100];
  640.             FILE *in;
  641.             sscanf(buff, "%*s %s", fname);
  642.             if ((in = fopen(fname, "r")) != NULL) {
  643.                 read_world(in);
  644.                 fclose(in);
  645.             }
  646.         }
  647.         else if (match(buff, "surfacemap ")) {
  648.             /* starts a new map of color numbers to surface names */
  649.             sscanf(buff, "%*s %s", surfacemapname);
  650.             current_surface = NULL;
  651.         }
  652.         else if (match(buff, "surface ")) {
  653.             SURFACE *p;
  654.             /* maps a color number to a surface name */
  655.             if ((p = (SURFACE *)malloc(sizeof(SURFACE))) != NULL) {
  656.                 char buf2[40];
  657.                 if (current_surface == NULL)
  658.                     add_name(&maps, surfacemapname, p);
  659.                 else
  660.                     current_surface->next = p;
  661.                 current_surface = p;
  662.                 p->next = NULL;
  663.                 sscanf(buff, "%*s %u %s %*s", &p->color, buf2);
  664.                 p->value = strdup(buf2);
  665.             }
  666.         }
  667.         else if (match(buff, "surfacedef ")) {
  668.             char sname[100], svalue[20];
  669.             /* maps a surface name to an internal color value */
  670.             sscanf(buff, "%*s %s %s", sname, svalue);
  671.             add_name(&surfdefs, sname, (void *) strtoul(svalue, NULL, 0));
  672.         }
  673.         else if (match(buff, "split ")) {
  674.             float x, y, z, nnx, nny, nnz;
  675.             long nx, ny, nz;
  676.             unsigned flags = 0;
  677.             set_move_handler(split_move_handler);
  678.             set_global_split_root(&split_tree);
  679.             if (sscanf(buff, "%*s %f,%f,%f %f,%f,%f %u", &x, &y, &z,
  680.             &nnx, &nny, &nnz, &flags) > 5)
  681.             {
  682.                 scale3(nnx, nny, nnz, &nx, &ny, &nz);
  683.                 current_split = add_split(&split_tree, x, y, z, nx, ny, nz, flags);
  684.             }
  685.         }
  686.         else if (match(buff, "splitpt ")) {
  687.             float x1, x2, x3, y1, y2, y3, z1, z2, z3;
  688.             long nx, ny, nz;
  689.             unsigned flags = 0;
  690.             set_move_handler(split_move_handler);
  691.             set_global_split_root(&split_tree);
  692.             if (sscanf(buff, "%*s %f,%f,%f %f,%f,%f %f,%f,%f %u", &x1, &y1, &z1,
  693.             &x2, &y2, &z2, &x3, &y3, &z3, &flags) > 8)
  694.             {
  695.                 points_to_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3, &nx, &ny, &nz);
  696.                 current_split = add_split(&split_tree, x1, y1, z1, nx, ny, nz, flags);
  697.             }
  698.         }
  699.         else if (match(buff, "area ")) {
  700.             long x, y, z;
  701.             char areaname[100];
  702.             sscanf(buff, "%*s %ld,%ld,%ld %s", &x, &y, &z, areaname);
  703.             add_name(&areas, areaname, what_area(split_tree, x, y, z));
  704.         }
  705.         else if (match(buff, "floor ")) {
  706.             char aname[100];
  707.             float aa, bb, cc, dd;
  708.             long a,b,c,d;
  709.             sscanf(buff, "%*s %s %f,%f,%f,%f", aname, &aa, &bb, &cc, &dd);
  710.             scale4(aa, bb, cc, dd, &a, &b, &c, &d);
  711.             add_floor((AREA *)find_name(areas, aname), a, b, c, d);
  712.         }
  713.         else if (match(buff, "floorpts ")) {
  714.             char aname[100];
  715.             float x1, y1, z1, x2, y2, z2, x3, y3, z3;
  716.             long a, b, c, d;
  717.             sscanf(buff, "%*s %s %f,%f,%f %f,%f,%f %f,%f,%f",
  718.             aname, &x1, &y1, &z1, &x2, &y2, &z2, &x3, &y3, &z3);
  719.             points_to_eqn(x1, y1, z1, x2, y2, z2, x3, y3, z3, &a, &b, &c, &d);
  720.             add_floor((AREA *)find_name(areas, aname), a, b, c, d);
  721.         }
  722.         else if (match(buff, "ceiling ")) {
  723.             char aname[100];
  724.             float aa, bb, cc, dd;
  725.             long a, b, c, d;
  726.             sscanf(buff, "%*s %s %f,%f,%f,%f", aname, &aa, &bb, &cc, &dd);
  727.             scale4(aa, bb, cc, dd, &a, &b, &c, &d);
  728.             add_ceiling((AREA *)find_name(areas, aname), a, b, c, d);
  729.         }
  730.         else if (match(buff, "ceilingpts ")) {
  731.             char aname[100];
  732.             float x1, y1, z1, x2, y2, z2, x3, y3, z3;
  733.             long a, b, c, d;
  734.             sscanf(buff, "%*s %s %f,%f,%f %f,%f,%f %f,%f,%f",
  735.             aname, &x1, &y1, &z1, &x2, &y2, &z2, &x3, &y3, &z3);
  736.             points_to_eqn(x1, y1, z1, x2, y2, z2, x3, y3, z3, &a, &b, &c, &d);
  737.             add_ceiling((AREA *)find_name(areas, aname), a, b, c, d);
  738.         }
  739.         else if (match(buff, "visfrom ")) {
  740.             char aname[100], alist[1000], *p;
  741.             AREA *a, *b;
  742.             sscanf(buff, "%*s %s %s", aname, alist);
  743.             if ((a = (AREA *)find_name(areas, aname)) != NULL)
  744.                 for (p = strtok(alist, ","); p; p = strtok(NULL, ","))
  745.                     if ((b = (AREA *)find_name(areas, p)) != NULL)
  746.                         add_visfrom(a, b);
  747.         }
  748.         else if (match(buff, "passage ")) {
  749.         }
  750.         else if (match(buff, "endsplits"))
  751.         {
  752.             current_split = NULL;
  753.         }
  754.         else if (match(buff, "polyobj "))
  755.         {
  756.             char map[100];
  757.             OBJECT *obj;
  758.             POLY *poly;
  759.             unsigned color;
  760.             int nv = 0;
  761.             int i;
  762.             long x[8], y[8], z[8];
  763.  
  764.             map[0] = '\0';
  765.             set_loadplg_depthsort(0);
  766.             sscanf(buff, "%*s %d %s %ld,%ld,%ld %ld,%ld,%ld %ld,%ld,%ld   \
  767.                                                             %ld,%ld,%ld %ld,%ld,%ld %ld,%ld,%ld   \
  768.                                                             %ld,%ld,%ld %ld,%ld,%ld ", &nv, map,
  769.             &x[0], &y[0], &z[0], &x[1], &y[1], &z[1],
  770.             &x[2], &y[2], &z[2], &x[3], &y[3], &z[3],
  771.             &x[4], &y[4], &z[4], &x[5], &y[5], &z[5],
  772.             &x[6], &y[6], &z[6], &x[7], &y[7], &z[7]);
  773.             if (nv > 8) nv = 8;
  774.             obj = new_obj(0, nv, 1);
  775.             if (obj)
  776.             {
  777.                 if (map)
  778.                     color = (unsigned) find_name(surfdefs, map);
  779.                 poly = add_poly(obj, color, nv);
  780.                 for (i = 0; i < nv; i++)
  781.                 {
  782.                     add_vertex(obj, x[i], y[i], z[i]);
  783.                     add_point(obj, poly, nv-i-1);
  784.                 }
  785.                 compute_obj(obj);
  786.                 if (current_split)
  787.                     add_obj_to_split_center(current_split, obj);
  788.                 else
  789.                     add_obj_to_split_area(split_tree, obj);
  790.             }
  791.         }
  792.  
  793.         /* CONFIG FILE LOAD STUFF */
  794.  
  795.         /* THESE DONE AFTER LOADING */
  796.  
  797.         else if (match(buff, "videodev"))
  798.         {
  799.             extern char vdname[];
  800.              extern int vdmode;
  801.              sscanf(buff, "%*s %s %x", vdname, &vdmode);
  802.         }
  803.         else if (match(buff, "mousedev"))
  804.         {
  805.             extern char mdname[];
  806.             sscanf(buff, "%*s %s", mdname);
  807.             if (!stricmp(mdname, "NULL")) want_mouse = False;
  808.             else want_mouse = True;
  809.         }
  810.         else if (match(buff, "headdev"))
  811.         {
  812.             extern char hdname[];
  813.             extern float hdo_x, hdo_y, hdo_z, hdo_rx, hdo_ry, hdo_rz;
  814.             sscanf(buff, "%*s %s %f %f %f %f %f %f", hdname, &hdo_x, &hdo_y, &hdo_z, &hdo_rx, &hdo_ry, &hdo_rz);
  815.         }
  816.         else if (match(buff, "glovedev"))
  817.         {
  818.             extern char gpdname[];
  819.             extern int have_glove;
  820.             extern float gpdo_x, gpdo_y, gpdo_z, gpdo_rx, gpdo_ry, gpdo_rz;
  821.             have_glove = 1;
  822.             sscanf(buff, "%*s %s %f %f %f %f %f %f", gpdname, &gpdo_x, &gpdo_y, &gpdo_z, &gpdo_rx, &gpdo_ry, &gpdo_rz);
  823.         }
  824.         else if (match(buff, "ptrdev"))
  825.         {
  826.             extern char gpdname[];
  827.             extern int have_ptr;
  828.             extern float gpdo_x, gpdo_y, gpdo_z, gpdo_rx, gpdo_ry, gpdo_rz;
  829.             have_ptr = 1;
  830.             sscanf(buff, "%*s %s %f %f %f %f %f %f", gpdname, &gpdo_x, &gpdo_y, &gpdo_z, &gpdo_rx, &gpdo_ry, &gpdo_rz);
  831.         }
  832.         else if (match(buff, "switchdev"))
  833.         {
  834.             extern char swdname[];
  835.             sscanf(buff, "%*s %s", swdname);
  836.         }
  837.         else if (match(buff, "glovecursor"))
  838.         {
  839.             extern char gpcursor[];
  840.             sscanf(buff, "%*s %s", gpcursor);
  841.             strcpy(cursorloadpath, loadpath);
  842.         }
  843.         else if (match(buff, "leftglovecursor"))
  844.         {
  845.             extern char lgpcursor[];
  846.             sscanf(buff, "%*s %s", lgpcursor);
  847.             strcpy(cursorloadpath, loadpath);
  848.         }
  849.         else if (match(buff, "ptrcursor"))
  850.         {
  851.             extern char gpcursor[];
  852.             sscanf(buff, "%*s %s", gpcursor);
  853.         }
  854.  
  855.         /* CONFIG: DONE IMMEDIATELY */
  856.  
  857.         else if (match(buff, "segaport"))
  858.         {
  859.             sscanf(buff, "%*s %x %x %x %x %x", &sega_address,
  860.             &sega_mask, &sega_left, &sega_right, &sega_doff, &sega_port_image);
  861.         }
  862. /*********
  863.         else if (match(buff, "pgloveport"))
  864.         {
  865.             sscanf(buff, "%*s %x %x %x %x %x %x %x %x", &glove_in_port, &glove_out_port,
  866.             &glove_write_mask, &glove_none_mask, &glove_latch_mask, &glove_clock_mask,
  867.             &glove_clock_latch, &glove_data_mask, &port_image );
  868.         }
  869.         else if (match(buff, "pglovetime"))
  870.         {
  871.             sscanf(buff, "%*s %d %d", &glove_bit_delay, &glove_byte_delay );
  872.         }
  873. *********/
  874.         else if (match(buff, "stereoset"))
  875.         {
  876.             float ws = 1.0;
  877.             sscanf(buff, "%*s %ld %ld %ld %ld %ld %f", &(default_stereo.phys_screen_dist),
  878.             &(default_stereo.phys_screen_width), &(default_stereo.pixel_width),
  879.             &(default_stereo.phys_eye_spacing), &(default_stereo.phys_convergence), &ws);
  880.             default_stereo.world_scaling = 65536.0 * ws;
  881.         }
  882.         else if (match(buff, "stereotype"))
  883.         {
  884.             char st[80];
  885.             extern int stereo_type;
  886.             sscanf(buff, "%*s %s", st);
  887.             if (match(st, "OFF")) stereo_type = MONOSCOPIC;
  888.             else if (match(st, "SWITCH")) stereo_type = SWITCHED;
  889.             else if (match(st, "SEPARATE")) stereo_type = SEPARATE;
  890.             else if (match(st, "SPLIT")) stereo_type = SPLITLR;
  891.         }
  892.         else if (match(buff,"stereoleft"))
  893.         {
  894.             sl_left = -1;
  895.             sscanf(buff, "%*s %d %d %f %ld %ld %ld %ld %ld", &sl_xoff, &sl_xflip,
  896.             &sl_xrot, &sl_left, &sl_top, &sl_right, &sl_bottom );
  897.         }
  898.         else if (match(buff,"stereoright"))
  899.         {
  900.             sr_left = -1;
  901.             sscanf(buff, "%*s %d %d %f %ld %ld %ld %ld %ld", & sr_xoff, &sr_xflip,
  902.             &sr_xrot, &sr_left, &sr_top, &sr_right, &sr_bottom );
  903.         }
  904.  
  905.  
  906.     }
  907.     fclose(in);
  908.     return True;
  909. }
  910.  
  911.