home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / SRC / DEMO4B / MDEMO4.CPP < prev    next >
C/C++ Source or Header  |  1993-05-11  |  25KB  |  1,064 lines

  1. /* A simple user-interface demo -- Version 4 */
  2.  
  3. /* Written by Bernie Roehl, February 1992 */
  4.  
  5. /* Latest version (re)written June 1992 */
  6.  
  7. /* Contact: broehl@sunee.waterloo.edu */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. #include <ctype.h>
  13. #include <string.h>
  14. #include <mem.h>
  15. #include <dos.h>
  16. #include <bios.h>
  17. #include <iostream.h>
  18. #include <strstream.h>
  19. #include <conio.h>
  20.  
  21. #include "rend386.hpp"
  22. #include "intmath.h"
  23. #include "plg.h"
  24. #include "segio.hpp"
  25. #include "segasupp.hpp"
  26. #include "splits.hpp"
  27. #include "pointer.hpp"
  28. #include "tasks.hpp"
  29. #include "cursor.hpp"
  30. #include "userint.hpp"
  31. #include "world.hpp"
  32. #include "colormap.hpp"
  33. #include "hdmanip.hpp"
  34. #include "keyboard.hpp"
  35. #include "render.hpp"
  36. #include "vd2.hpp"
  37.  
  38. #include "isr.hpp"
  39. #include "inputptr.hpp"
  40. #include "shamless.hpp"
  41.  
  42. extern void *screen_data();
  43.  
  44. extern unsigned _stklen = 10000;
  45.  
  46. #define XFSC 536870912   /* 2**29 for shifting xform coeffs to long */
  47.  
  48. #define sub_exit        atexit
  49.  
  50. /* default screen data setup */
  51.  
  52. STEREO default_stereo = {
  53.     600 , 240, 320, 50, 600, 1*65536L };
  54.  
  55. VIEW default_view = {
  56.     0,0,-8000, /* ex,ey,ez */
  57.     0,0,0, /* pan,tilt,roll */
  58.     4*65536L, /* zoom */
  59.     1000,15000,-5000, /* lx,ly,lz */
  60.     0,63, /* point, ambient */
  61.     0,319,0,200, /* left,right,top,bottom */
  62.     1,100000, /* hither, yon */
  63.     1/1.25*65536L, /* aspect ratio */
  64.     0, /* flags */
  65.     0,0, /* no offset */
  66.     0 /* no flip */
  67. }; /* don't init. matrix */
  68.  
  69. VIEW *current_view = &default_view;
  70.  
  71. VIEW orig_view; /* used for '*' key */
  72.  
  73. int v_page = 0; /* screen page swap variable */
  74.  
  75. OBJLIST *objlist; /* the linked list of objects in the scene */
  76.  
  77. int running = 1; /* non-zero until we're ready to exit */
  78. int redraw = 1; /* non-zero if we need a redraw */
  79. int review = 1; /* non-zero if we need to recompute current view */
  80. int reframe = 1; /* non-zero if we need to copy our frame back on-screen */
  81.  
  82. int do_horizon = 1;
  83.  
  84. int stereo_type = MONOSCOPIC;
  85.  
  86. extern int use_old_keys; /* NEED TO SET DISTANCE AS WELL ! */
  87.  
  88. int have_joystick = 0; /* non-zero if we have one or more joysticks */
  89. joystick_data joy;
  90.  
  91. long spacestep = 10L; /* "granularity" of motion */
  92.  
  93. unsigned lastkey = 0, nextolastkey = 0;
  94.  
  95. char *progname = "demo";
  96.  
  97. char vdname[40] = "vd256.rvd";
  98. int vdmode = 0x14;
  99.  
  100. char swdname[40] = "sega";
  101.  
  102. char mdname[40] = "mouse";
  103. PDRIVER *cursor_device = NULL; // primary mouse device
  104. PDRIVER *menu_device = NULL; // secondary mouse device
  105. int manip_2D_avail = 0; // can do mouse manipulation
  106.  
  107. char gpdname[40] = "pglove";
  108. char gpcursor[80] = "handsm.fig";
  109. char lgpcursor[80] = "lhandsm.fig";
  110. float gpdo_x = 1, gpdo_y = 1, gpdo_z = 2, gpdo_rx = 1, gpdo_ry = 1, gpdo_rz = 1;
  111. int have_glove = 0;
  112. int have_ptr = 0;
  113. PDRIVER *manip_device[2] = {NULL, NULL}; // extended manip. device (glove or pointer)
  114.  
  115. char hdname[40] = "none";
  116. float hdo_x = 0, hdo_y = 0, hdo_z = 0; // relative pos'n to neck
  117. float hdo_rx = 0, hdo_ry = 0, hdo_rz = 0;
  118. PDRIVER *head_device = NULL; // head tracking device
  119.  
  120.  
  121. MATRIX head_tracker_map = { 
  122.     XFSC, 0, 0, 0, XFSC, 0, 0, 0, XFSC, 0, 0, 0 };
  123.  
  124. int sl_xflip = 0, sl_xoff = 0;
  125. long sl_left = -1, sl_top, sl_right, sl_bottom;
  126. int sr_xflip = 0, sr_xoff = 0;
  127. long sr_left = -1, sr_top, sr_right, sr_bottom;
  128. float sl_xrot = 0, sr_xrot = 0;
  129.  
  130. int use_glove = 0;
  131. int use_ht = 0;
  132. int use_wide = 0;
  133. int use_BW = 0;
  134. int swap_eyes = 0;
  135. int vd_loaded = 0;
  136.  
  137. int fancy_background = 0; // if set, we display a fancy background
  138. int reflection_pool = 0; // if set, draw a "reflecting pool" at the bottom of the screen
  139. int have_logo = 0; // if set, we have a logo
  140. int show_logo = 0; // if set, show the logo (if we have one)
  141. int show_location = 1; // if set, we display the current location on-screen
  142. int show_compass = 1; // if set, we display the 3-D compass on-screen
  143. int show_framerate = 1; // if set, we display the frames/second rate
  144. int show_gestures = 1; // display the name of the gestures.
  145. int do_screen_clear = 1; // by default, we clear the screen on each frame
  146. int use_frame = 0; // if set, draw a "frame"
  147. int frame_x = 0, frame_y = 0, frame_w = 320, frame_h = 200; // frame location
  148.  
  149. TASK *tasklist = NULL;
  150.  
  151. SPLIT *split_tree = NULL;
  152.  
  153. int npalette = 0; /* non-zero if we have a palette loaded */
  154. unsigned char palette[256*3];
  155.  
  156. extern unsigned getkey();
  157.  
  158. char framefname[100];
  159.  
  160. extern struct Screeninfo *screeninfo;
  161. extern highest_color;
  162.  
  163. char loadpath[100] = "";
  164. char cursorloadpath[100] = "";
  165.  
  166. segaISR* switcherISR;
  167.  
  168. static char buff[100];          // for temporary output
  169.  
  170. Boolean want_mouse = True;
  171.  
  172. char *fix_fname(char *name)
  173. {
  174.     static char tempname[100];
  175.  
  176.     if (loadpath[0] && !strchr(name, '\\') && !strchr(name, '/')) {
  177.         strcpy(tempname, loadpath);
  178.         strcat(tempname, "\\");
  179.         strcat(tempname, name);
  180.         // sprintf(tempname, "%s\\%s", loadpath, name);
  181.     }
  182.     else
  183.         strcpy(tempname, name);
  184.     strlwr(tempname);
  185.     return tempname;
  186. }
  187.  
  188. void *v_driver_pointer = NULL;
  189.  
  190. Boolean load_video_driver(char *dfile)
  191. {
  192.     if (vd_loaded) return True;
  193.     v_driver_pointer = load_driver(dfile);
  194.     if (v_driver_pointer == NULL)
  195.     {
  196.         cerr << "Cannot read video driver " <<  dfile << endl;
  197.         return False;
  198.     }
  199.     return True;
  200. }
  201.  
  202. void read_file_arg(char * name)
  203. {
  204.     FILE *in;
  205.     long x, y, z;
  206.     OBJECT *obj;
  207.     char *in_filename;
  208.     in_filename = fix_fname(name);
  209.     if (strstr(in_filename,".plg")) // check if plg or fig file
  210.     {
  211.         if ((in = fopen(in_filename, "r")) == NULL) {
  212.             cerr << "Could not open '" << in_filename << "'" << endl;
  213.             fclose(in);
  214.             return;
  215.         }
  216.  
  217.         set_loadplg_offset(0,0,0);
  218.         set_loadplg_scale(1,1,1);
  219.         while ((obj = load_plg(in)) != NULL)
  220.         {
  221.             SEGMENT *s;
  222.             add_to_objlist(objlist, obj);
  223.             if ((s = new_seg(NULL)) == NULL)
  224.                 cerr << "Warning: out of memory while loading an object" << endl;
  225.             else
  226.             {
  227.                 seg_set_object(s, obj);
  228.                 set_object_owner(obj, s);
  229.                 update_segment(s);
  230.             }
  231.             if (spacestep < get_object_bounds(obj, &x, &y, &z)/5L)
  232.                 spacestep = get_object_bounds(obj, &x, &y, &z)/5L;
  233.         }
  234.         if (load_err)
  235.         {
  236.             cerr << "Load error: " << load_err << endl;
  237.             getkey();
  238.         }
  239.     }
  240.     else if (strstr(in_filename,".fig")) /* check if plg or fig file */
  241.     {
  242.         SEGMENT *s;
  243.         int c;
  244.         if ((in = fopen(in_filename, "r")) == NULL) {
  245.             cerr << "Could not open '" << in_filename << "'" << endl;
  246.             fclose(in);
  247.             return;
  248.         }
  249.         set_readseg_objlist(objlist);
  250.         if ((s = readseg(in, NULL)) == NULL)
  251.             cerr << "Could not read '" << name << "'" << endl;
  252.         else
  253.             update_segment(s);
  254.     }
  255.     else {
  256.         FILE * fptr = fopen(fix_fname(in_filename), "r");
  257.         if (fptr) {
  258.             if (!read_world(fptr))
  259.                 cerr << "Error reading world file" << endl;
  260.             fclose(fptr);
  261.         }
  262.         // defaults should not be written to file.
  263.         // (since this is not a "config" file.)
  264.     }
  265. }
  266.  
  267. void parse_args(char *argv[])
  268. {
  269.     int i = 0;
  270.     for (; argv[i]; ++i)
  271.     {
  272.         if (argv[i][0] == '/' || argv[i][0] == '-')
  273.         {
  274.             switch(toupper(argv[i][1]))
  275.             {
  276.             case 'M':/* mirror stereo */
  277.                 stereo_type = SPLITLR;
  278.                 /* possibly problem here: assumes 320x200 mode before checking */
  279.                 default_stereo.phys_screen_dist = 200;
  280.                 default_stereo.phys_convergence = 700;
  281.                 default_stereo.phys_screen_width = 120;
  282.                 default_stereo.pixel_width = 160;
  283.                 default_view.right = 159;
  284.                 compute_stereo_data(&default_stereo, 0, 0, 0, 0, 0, 0, 159, 100);
  285.                 compute_stereo_data(&default_stereo, 1, 1, 0, 0, 160, 0, 319, 100);
  286.                 break;
  287.             case 'R':/* swap eyes on Sega driver */
  288.                 swap_eyes = 1;
  289.                 break;
  290.             case 'C':/* set conv. distance */
  291.                 default_stereo.phys_screen_dist = atol(argv[++i]);
  292.                 break;
  293.             case 'S':/* set world scale */
  294.                 default_stereo.world_scaling = 65536.0*atof(argv[++i]);
  295.                 break;
  296.             case 'E':/* set eye spacing */
  297.                 default_stereo.phys_eye_spacing = atol(argv[++i]);
  298.                 break;
  299.             case 'X':/* turn on stereo */
  300.                 stereo_type = SWITCHED;
  301.                 break;
  302.             case 'J':/* sort by object (default is polys) */
  303.                 set_default_depth_sort(get_default_depth_sort() | BYOBJECT);
  304.                 break;
  305.             case 'P':/* depth sort-- deepest */
  306.                 set_default_depth_sort(get_default_depth_sort() & (~(BYOBJECT|AVERAGE|ATBACK)));
  307.                 break;
  308.             case 'A':/* depth sort-- middle */
  309.                 set_default_depth_sort(get_default_depth_sort() | AVERAGE);
  310.                 break;
  311.             case '1':/* com 1 for SEGA */
  312.                 select_sega_port(0x3FC);
  313.                 break;
  314.             case '2':/* com 2 for SEGA */
  315.                 select_sega_port(0x2FC);
  316.                 break;
  317.             case 'G':/* enable glove */
  318.                 use_glove = 1;
  319.                 if(!have_ptr) have_glove = 1;
  320.                 break;
  321.             case 'H':/* enable head tracker */
  322.                 use_ht = 1;
  323.                 break;
  324.             case 'W':/* enable wide-angle dual-VGA displays */
  325.                 use_wide = 1;
  326.                 stereo_type = SEPARATE;
  327.                 default_stereo.phys_screen_dist = 50;
  328.                 default_stereo.phys_convergence = 1200;
  329.                 default_stereo.phys_screen_width = 115;
  330.                 default_stereo.pixel_width = 320; /* hmm... may vary */
  331.                 break;
  332.             case 'B':/* force all colors to monochrome */
  333.                 use_BW = 1;
  334.                 break;
  335.             }
  336.         }
  337.         else
  338.             read_file_arg(argv[i]);
  339.     }
  340. }
  341.  
  342. void parse_all_argv(char *argv[])
  343. {
  344.     char * fname;
  345.     int i = 1;
  346.  
  347.     if(!stricmp(&(argv[i][0]), "/C"))
  348.     {
  349.         i = 2;
  350.         fname = &(argv[i][0]);
  351.     }
  352.     else fname = "rend386.cfg";
  353.  
  354. //      InitFile ini(fname);
  355.     FILE * fptr = fopen(fix_fname(fname), "r");
  356.     if (fptr) {
  357.         if (!read_world(fptr))
  358.             cerr << "Error reading config file '" << fname << "'" << endl;
  359.         fclose(fptr);
  360.     }
  361.     // Save defaults if necessary.
  362. //      ini.write();
  363.     parse_args(&argv[i]);
  364. }
  365.  
  366. void main_entry(char * name)
  367. {
  368.     void wrap(); /* wrap-up function, shuts everything down */
  369.  
  370.     if ((progname = strrchr(name, '.')) != NULL) *progname = '\0';
  371.     progname = name;
  372.  
  373.     if (getenv("REND386"))
  374.         strcpy(loadpath, getenv("REND386"));
  375.  
  376.     setup_render(50,800); /* # of K, # of polys */
  377.     sub_exit(wrap);
  378.     set_global_split_root(&split_tree);
  379.     initial_world_split(&split_tree);
  380.     set_move_handler(split_move_handler);
  381.     objlist = new_objlist();
  382. }
  383.  
  384.  
  385. void main_body()
  386. {
  387.     void joystick_calibration(joystick_data *joy) , refresh_display();
  388.  
  389.     unsigned getkey();
  390.     PDRIVER *dm;
  391.  
  392.     have_joystick = joystick_check();
  393.  
  394. //      if (!load_video_driver(vdname)) return;
  395.     screeninfo = (Screeninfo *)screen_data();
  396.     highest_color = screeninfo->colors-1;
  397.     preset_default_colors();
  398.  
  399.     frame_x = screeninfo->xmin;
  400.     frame_y = screeninfo->ymin;
  401.     frame_w = screeninfo->xmax - screeninfo->xmin + 1;
  402.     frame_h = screeninfo->ymax - screeninfo->ymin + 1;
  403.  
  404.     /* Default view is full-screen: */
  405.     default_view.left = screeninfo->xmin;
  406.     default_view.top = screeninfo->ymin;
  407.     default_view.right = screeninfo->xmax;
  408.     default_view.bottom = screeninfo->ymax;
  409.     default_view.aspect = screeninfo->aspect;
  410.  
  411.     orig_view = default_view;
  412.  
  413.     PDRIVER *gd1, *gd2;
  414.     if(use_glove && (!have_ptr))
  415.     {
  416.         cout << "Looking for glove #1..." << endl;
  417.         cout << "(press any key to proceed without glove)" << endl;
  418.         gd1 = gloveptr_init(gpdname, 0);
  419.         if (!pointer_check(gd1, 0)) {
  420.             gd1 = gd2 = NULL;
  421.             use_glove = 0;
  422.         }
  423.  
  424.         manip_device[0] = menu_device = gd1;
  425.  
  426.         if (gd1) {
  427.             cout << "Looking for glove #2..." << endl;
  428.             cout << "(press any key to proceed with just 1 glove)" << endl;
  429.             gd2 = gloveptr_init(gpdname, 1);
  430.             if (!pointer_check(gd2, 1)) gd2 = NULL;
  431.             manip_device[1] = gd2;
  432.             glove_Start();
  433.         }
  434.     }
  435.     if (enter_graphics())
  436.     {
  437.         cerr << "Could not enter graphics mode" << endl;
  438.         return;
  439.         // exit(1);
  440.     }
  441.     vd_loaded++;
  442.  
  443.     initialize_screen_factors(current_view);
  444.     fast_view_factors(current_view);
  445.  
  446.     if (npalette)
  447.         load_DAC_colors(palette, highest_color+1, use_BW);
  448.  
  449.     if (use_frame)
  450.     {
  451.         FILE *in;
  452.         use_frame = 0; /* we only set it back to 1 if we're successful */
  453.         if(stereo_type == MONOSCOPIC)
  454.             if ((in = fopen(fix_fname(framefname), "rb")) != NULL)
  455.             {
  456.                 if (load_pcx(in, 3) == 0) use_frame = 1;
  457.                 copy_block(3, 0, 0, 0, frame_x, frame_y, frame_w, frame_h);
  458.                 copy_block(3, 0, 0, 1, frame_x, frame_y, frame_w, frame_h);
  459.                 copy_block(3, 0, 0, 2, frame_x, frame_y, frame_w, frame_h);
  460.                 fclose(in);
  461.             }
  462.     }
  463.  
  464.     init_body_links();
  465.  
  466.     if(stereo_type != MONOSCOPIC)
  467.     {
  468.         if (!init_switch_driver(swdname)) return;
  469.  
  470.         if(sl_left<0)
  471.         {
  472.             sl_left = default_view.left;
  473.             sl_right = default_view.right;
  474.             sl_top = default_view.top;
  475.             sl_bottom = default_view.bottom;
  476.         }
  477.         compute_stereo_data(&default_stereo, 0, sl_xflip, sl_xoff, 65536.0*sl_xrot,
  478.         sl_left, sl_top, sl_right, sl_bottom);
  479.  
  480.         if(sr_left<0)
  481.         {
  482.             sr_left = default_view.left;
  483.             sr_right = default_view.right;
  484.             sr_top = default_view.top;
  485.             sr_bottom = default_view.bottom;
  486.         }
  487.         compute_stereo_data(&default_stereo, 1, sr_xflip, sr_xoff, 65536.0*sr_xrot,
  488.         sr_left, sr_top, sr_right, sr_bottom);
  489.     }
  490.  
  491.     if (want_mouse) {
  492.         if ((dm=mouseptr_init(mdname))!=NULL) {
  493.             cursor_show(v_page);
  494.             manip_2D_avail++;
  495.         }
  496.     }
  497.     else {
  498.         dm = NULL;
  499.     }
  500.     cursor_device = dm;
  501.     menu_device = dm;
  502.  
  503.     if(stricmp(hdname,"none") && use_ht)
  504.     {
  505.         extern PDRIVER *init_head_device(char *name, long x, long y, long z, long rx, long ry, long rz);
  506.         head_device = init_head_device(hdname, hdo_x, hdo_y, hdo_z,
  507.         hdo_rx*65536.0, hdo_ry*65536.0, hdo_rz*65536.0);
  508.     }
  509.  
  510.     // not going to be using powerglove
  511.     if ((!use_glove) || have_ptr || stricmp(gpdname,"pglove"))
  512.     {
  513.         switcherISR = new segaISR;
  514.         if(stereo_type==SWITCHED) {
  515.             switcherISR->Init(switch_sega);
  516.             switcherISR->run();
  517.             // init_SG_interrupt(switch_sega,NULL,6500);
  518.         }
  519.         else {
  520.             switcherISR->Init();
  521.             switcherISR->run();
  522.             // init_timer();
  523.         }
  524.     }
  525.  
  526.     if(use_glove && (!have_ptr))
  527.     {
  528.  
  529.         extern SEGMENT *body_seg;
  530.         if(gd1 || gd2) {
  531.             if(gd1) gloveptr_setup(gd1, gpdo_x*65536.0, gpdo_y*65536.0, gpdo_z*65536.0,
  532.                 gpdo_rx*65536.0, gpdo_ry*65536.0, gpdo_rz*65536.0);
  533.             if(gd2) gloveptr_setup(gd2, gpdo_x*65536.0, gpdo_y*65536.0, gpdo_z*65536.0,
  534.                 gpdo_rx*65536.0, gpdo_ry*65536.0, gpdo_rz*65536.0);
  535.         }
  536.         refresh_display();
  537.  
  538.         if(gd1 || gd2) {
  539.             if(gd1)
  540.                 load_glove_cursor(body_seg, manip_device[0], gpcursor, 0);
  541.             if(gd2) {
  542.                 if (glove_Polarity(1))
  543.                     load_glove_cursor(body_seg, manip_device[1], gpcursor, 1);
  544.                 else
  545.                     load_glove_cursor(body_seg, manip_device[1], lgpcursor, 1);
  546.             }
  547.         }
  548.         else have_glove = use_glove = 0;
  549.     }
  550.  
  551.     if(use_glove && have_ptr)
  552.     {
  553.         extern SEGMENT *body_seg;
  554.         PDRIVER *gd;
  555. //              extern PDRIVER *gloveptr_init(char *gname, long sx, long sy, long sz, long srx, long sry, long srz, int which);
  556.  
  557.         gd = gloveptr_init(gpdname, 0);
  558.         gloveptr_setup(gd, gpdo_x*65536.0, gpdo_y*65536.0, gpdo_z*65536.0,
  559.             gpdo_rx*65536.0, gpdo_ry*65536.0, gpdo_rz*65536.0);
  560.         manip_device[0] = menu_device = gd;
  561.         if(gd)
  562.         {
  563.             set_loadplg_offset(0, 0, 0);
  564.             set_loadplg_scale(1, 1, 1);
  565.             load_3D_cursor(body_seg, manip_device[0], gpcursor);
  566.         }
  567.         else have_ptr = use_glove = 0;
  568.     }
  569.  
  570.     if ((have_joystick) != 0)
  571.     {
  572. #ifdef ASKUSER
  573.         popmsg("Joystick found -- use it?");
  574.         reframe = 1;
  575.         joystick_read(&joy);
  576.         while(!kbhit() && (joy.buttons==0)) joystick_read(&joy);
  577.         if(joy.buttons || toupper(getkey()) == 'Y')
  578.         {
  579.             refresh_display();
  580.             joystick_calibration(&joy);
  581.         }
  582.         else
  583.             have_joystick = 0;
  584.         refresh_display();
  585. #else
  586.         joystick_calibration(&joy);
  587. #endif
  588.     }
  589.  
  590.     while (running)
  591.     {
  592.         int x, y;
  593.         unsigned buttons;
  594.  
  595.         if (cursor_device) move_and_select_2D(cursor_device);
  596.  
  597.         if (have_joystick)
  598.             if (joystick_read(&joy))
  599.                 do_joy(&joy);
  600.         if (bioskey(1))
  601.         {
  602.             do_key(nextolastkey = getkey());
  603.             lastkey = nextolastkey;
  604.         }
  605.  
  606.         if(head_device && use_ht) head_update(0);
  607.  
  608.         if (use_glove)
  609.         {
  610.             POINTER gp, gp2;
  611.             int g;
  612.  
  613. // FIRST GLOVE
  614.             if((!have_ptr) && gd1)
  615.             {
  616.                 glove_update(manip_device[0], &gp, 0);
  617.                 gp.gesture = perform_gestset(0);
  618.                 switch(gp.gesture)
  619.                 {
  620.                 case G_FIST :
  621.                     g = GRASP_DO;
  622.                     break;
  623.                 case G_PINCH:
  624.                     g = ROTATE_DO;
  625.                     break;
  626.                 case G_POINT:
  627.                     g = SELECT_DO;
  628.                     break;
  629.                 default:
  630.                     g = FREE_DO;
  631.                     break;
  632.                 }
  633.             }
  634. /***
  635.             else
  636.                 {
  637.                 cursor_update3D(manip_device[0], &gp);
  638.                 switch(gp.buttons)
  639.                 {
  640.                 case 2:
  641.                     g = GRASP_DO;
  642.                     break;
  643.                 case 3:
  644.                     g = ROTATE_DO;
  645.                     break;
  646.                 case 1:
  647.                     g = SELECT_DO;
  648.                     break;
  649.                 default:
  650.                     g = FREE_DO;
  651.                     break;
  652.                 }
  653.             }
  654. ****/
  655.  
  656.             if (gd1) manip_do(manip_device[0],g, 0);
  657. // SECOND GLOVE
  658.             if((!have_ptr) && gd2)
  659.             {
  660.                 glove_update(manip_device[1], &gp2, 1);
  661.                 gp2.gesture = perform_gestset(1);
  662.                 switch(gp2.gesture)
  663.                 {
  664.                 case G_FIST :
  665.                     g = GRASP_DO;
  666.                     break;
  667.                 case G_PINCH:
  668.                     g = ROTATE_DO;
  669.                     break;
  670.                 case G_POINT:
  671.                     g = SELECT_DO;
  672.                     break;
  673.                 default:
  674.                     g = FREE_DO;
  675.                     break;
  676.                 }
  677.             }
  678.             if (gd2) manip_do(manip_device[1],g, 1);
  679.         }
  680.  
  681.         run_tasks(tasklist);
  682.  
  683.         if (redraw) refresh_display();
  684.     }
  685. }
  686.  
  687. unsigned __ovrbuffer = 0x1000;
  688.  
  689. #ifdef CMD_LINE
  690. #pragma argsused
  691. void main(int argc, char *argv[])
  692. {
  693.     main_entry(argv[0]);
  694.     parse_all_argv(argv);
  695.     main_body();
  696.     sub_exit_funcs();
  697.     //exit(0);
  698. }
  699.  
  700. #else
  701.  
  702. void internal_demo(char * exe_name, char *file_selected)
  703. {
  704.     running = 1;
  705.     reset_sub_exits();
  706.     main_entry(exe_name);
  707.     InitFile ini("rend386.cfg");
  708.     if (!read_world(ini))
  709.         cerr << "Error reading config file 'rend386.cfg'" << endl;
  710.     // Save defaults if necessary.
  711.     ini.write();
  712.     read_file_arg(file_selected);
  713.     main_body();
  714.     sub_exit_funcs();
  715. }
  716. #endif
  717.  
  718. void wrap() /* end program */
  719. {
  720.     int i;
  721.  
  722.     if (have_joystick) joystick_quit();
  723.     if(vd_loaded) exit_graphics();
  724.     reset_render();
  725.     cout << endl << "The libraries used in this package are available on the Internet," << endl;
  726.     cout << "via anonymous ftp to sunee.uwaterloo.ca in pub/rend386." << endl << endl;
  727.     cout << "For more information, send e-mail to:" << endl;
  728.     cout << "    Bernie Roehl  (broehl@sunee.uwaterloo.ca)" << endl;
  729.     cout << "    Dave Stampe   (dstampe@sunee.uwaterloo.ca)" << endl << endl;
  730.     shamelessFunc();
  731.     //sub_exit_funcs();
  732. }
  733.  
  734.  
  735. static l_x = 1000, l_y = 15000, l_z = -5000; /* light source */
  736.  
  737. long center_d = 10000;
  738. long center_x = 0;
  739. long center_y = 0;
  740. long center_z = 0;
  741. long latitude = 0;
  742. long longitude = 0;
  743. long center_roll = 0;
  744.  
  745. static long light_d = 1000000;
  746.  
  747. void polar_compute()
  748. {
  749.     MATRIX m,n;
  750.  
  751.     long x = 0;
  752.     long y = 0;
  753.     long z = -center_d;
  754.  
  755.     std_matrix(n,longitude,latitude,center_roll,0,0,0);
  756.  
  757.     matrix_point(n,&x,&y,&z);
  758.     current_view->ex = x + center_x;
  759.     current_view->ey = y + center_y;
  760.     current_view->ez = z + center_z;
  761.  
  762.     x = l_x;
  763.     y = l_y; 
  764.     z = l_z;
  765.     matrix_point(n,&x,&y,&z);
  766.     current_view->lx = x;
  767.     current_view->ly = y;
  768.     current_view->lz = z;
  769.     current_view->pan = latitude;
  770.     current_view->tilt = longitude;
  771.     current_view->roll = center_roll;
  772. }
  773.  
  774. void refresh_display()
  775. {
  776.     VIEW v;
  777.  
  778.     if (use_old_keys) polar_compute();
  779.     initialize_screen_factors(current_view);
  780.  
  781.     if (!(use_glove || head_device)) {
  782.         fast_view_factors(current_view);
  783.         screen_refresh(current_view);
  784.     }
  785.     else {
  786.         body_centric_map(current_view, &v);
  787.         screen_refresh(&v);
  788.     }
  789.  
  790.     redraw = 0;
  791. }
  792.  
  793. load_logo(char *filename)
  794. {
  795.     char far *buffer;
  796.     FILE *in;
  797.     if ((in = fopen(fix_fname(filename), "rb")) == NULL) return 0;
  798.     if (load_pcx(in, 3)) { /* some sort of problem loading it in */
  799.         fclose(in);
  800.         return 0;
  801.     }
  802.     fclose(in);
  803.     return 1; /* all is well... we have a logo */
  804. }
  805.  
  806. resize_viewport()
  807. {
  808.     int top, left, bottom, right;
  809.     unsigned buttons;
  810.     cursor_hide();
  811.     clear_display(v_page);
  812.     cursor_show(v_page);
  813.     popmsg("Click top-left and drag");
  814.     do {
  815.         move_2D(cursor_device, &left, &top, &buttons);
  816.     }
  817.     while (buttons == 0);
  818.     while (buttons) {
  819.         while (!move_2D(cursor_device, &right, &bottom, &buttons));
  820.         clear_display(v_page);
  821.         vgabox(left, top, right, bottom, 15);
  822.     }
  823.     if (right - left > 10) {
  824.         current_view->left = left & (~0x0007); /* always on a 16-pixel boundary */
  825.         current_view->right = (right & (~0x0007)) + 7;
  826.     }
  827.     if (bottom - top > 10) {
  828.         current_view->top = top;
  829.         current_view->bottom = bottom;
  830.     }
  831.  
  832.  if(stereo_type == SWITCHED)  /* makes sense for Sega only (no shift) */
  833.     {
  834.         compute_stereo_data(&default_stereo, 0, sl_xflip, sl_xoff, 65536.0*sl_xrot,
  835.         current_view->left, current_view->top, current_view->right, current_view->bottom);
  836.         compute_stereo_data(&default_stereo, 1, sr_xflip, sr_xoff, 65536.0*sr_xrot,
  837.         current_view->left, current_view->top, current_view->right, current_view->bottom);
  838.     }
  839.  
  840.     /* Make sure all pages are refreshed: */
  841.     reset_screens();
  842.     refresh_display();
  843.     return 0;
  844. }
  845.  
  846. save_pcx_file()
  847. {
  848.     char far *buffer;
  849.     FILE *out;
  850.     refresh_display();
  851.     askfor("File to save to? ", buff, 15);
  852.     reframe = 1;
  853.     if (buff[0] == '\0') return 1;
  854.     refresh_display();
  855.     if ((out = fopen(buff, "wb")) == NULL) {
  856.         popmsg("Could not open file");
  857.         reframe = 1;
  858.         getkey();
  859.         return 3;
  860.     }
  861.     cursor_hide();
  862.     save_pcx(out, v_page);
  863.     cursor_show(v_page);
  864.     fclose(out);
  865.     return 0;
  866. }
  867.  
  868. /* Some support routines */
  869.  
  870. char * center(char *s, int w)
  871. {
  872.     //if (!s) return;
  873.     int slen = strlen(s);
  874.     if (slen == 0) return s;
  875.     int n = (w - slen) / 2;
  876.     if (n < 0) return s;
  877.     char * retval = new char[n + slen + 2];
  878.     for (int i = 0; i < n; i ++) retval[i] = ' ';
  879.     retval[n] = '\0';
  880.     strcat(retval, s);
  881.     return retval;
  882. }
  883.  
  884. disp_status(VIEW *v)
  885. {
  886.     char *text[9];
  887.     int w, i;
  888.  
  889.     text[0] = "STATUS";
  890.     text[1] = "";
  891.  
  892.     ostrstream xyz;
  893.     xyz << "X = " << v->ex << "  Y = " << v->ey << "  Z = " << v->ez << '\0';
  894.     text[2] = xyz.str();
  895.     w = strlen(text[2]);
  896.  
  897.     ostrstream ptr;
  898.     ptr << "Pan = " << v->pan/65536L << "   Tilt = "
  899.         << v->tilt/65536L << "   Roll = "
  900.         << v->roll/65536L << '\0';
  901.     text[3] = ptr.str();
  902.     w = max(w, strlen(text[3]));
  903.  
  904.     ostrstream zm;
  905.     zm << "Zoom = " << v->zoom/65536L << '\0';
  906.     text[4] = zm.str();
  907.     w = max(w, strlen(text[4]));
  908.  
  909.     ostrstream hy;
  910.     hy << "Hither = " << v->hither << "  Yon = " << v->yon << '\0';
  911.     text[5] = hy.str();
  912.     w = max(w, strlen(text[5]));
  913.  
  914.     if (have_joystick) {
  915.         joystick_read(&joy);
  916.         ostrstream js;
  917.         js << "Joystick = " << joy.x << "," << joy.y << '\0';
  918.         text[6] = js.str();
  919.         w = max(w, strlen(text[6]));
  920.         text[7] = NULL;
  921.     }
  922.     else text[6] = NULL;
  923.  
  924.     char * temp;
  925.     w += 2;
  926.  
  927.     for (i = 0; text[i]; ++i) {
  928.         temp = text[i];
  929.         text[i] = center(text[i], w);
  930.         if (i > 1) free(temp);
  931.     }
  932.     poptext(text);
  933.     reframe = 1;
  934.     getkey();
  935.     for (i = 2; text[i]; ++i) delete text[i];
  936.     return 0;
  937. }
  938.  
  939.  
  940. void joystick_calibration(joystick_data *joy)
  941. {
  942.     if (have_joystick == 0) return;
  943.     if (have_joystick & 1) joystick_init(joy, 0);
  944.     else if (have_joystick & 2) joystick_init(joy, 1);
  945.  
  946.     joystick_setscale(joy, 100);
  947.     reframe = 1;
  948. }
  949.  
  950. static int nobjs, nverts, npolys;
  951.  
  952. void gather_data(OBJECT *obj)
  953. {
  954.     int nv = 0, np = 0;
  955.     get_obj_info(obj, &nv, &np);
  956.     ++nobjs;
  957.     nverts += nv;
  958.     npolys += np;
  959. }
  960.  
  961. disp_info()
  962. {
  963.     OBJECT *obj;
  964.     nobjs = 0, nverts = 0, npolys = 0;
  965.     char * text[9];
  966.  
  967.     walk_split_tree(split_tree, gather_data);
  968.     ostrstream objs;
  969.     objs << nobjs << " object" << ((nobjs == 1) ? "" : "s") << '\0';
  970.     text[0] = objs.str();
  971.  
  972.     ostrstream vrt;
  973.     vrt << nverts << " vert" << ((nverts == 1) ? "ex" : "ices") << '\0';
  974.     text[1] = vrt.str();
  975.  
  976.     ostrstream plg;
  977.     plg << npolys << " polygon" << ((npolys == 1) ? "" : "s") << '\0';
  978.     text[2] = plg.str();
  979.  
  980.     text[3] = NULL;
  981.  
  982.     int w = max(strlen(text[0]), strlen(text[1]));
  983.     w = max(w, strlen(text[2]));
  984.     char * temp;
  985.     for (int i = 0; text[i]; ++i) {
  986.         temp = text[i];
  987.         text[i] = center(text[i], w);
  988.         delete temp;
  989.     }
  990.  
  991.     poptext(text);
  992.     reframe = 1;
  993.     getkey();
  994.     for (i = 0; text[i]; ++i) delete text[i];
  995.     return 0;
  996. }
  997.  
  998. extern AREA *areas;
  999.  
  1000. extern POINTER gloveptr;
  1001.  
  1002. char *gest[] = {
  1003.     "FLAT", "THUMB_IN", "INDEX_IN", "MIDDLE_IN",
  1004.     "RING_IN", "PINCH", "FIST", "THUMB_OUT", "POINT",
  1005.     "BADFINGER", "RING_OUT", "??????" };
  1006.  
  1007. void prprint(int x,int y, int color, char *t)
  1008. {
  1009.     int bk = (color>8) ? 0 : 15;
  1010.  
  1011.     printxyr(x,y,bk,t,0);
  1012.     printxyr(x+1,y+1,color,t,0);
  1013. }
  1014.  
  1015. status_on_screen()
  1016. {
  1017.     AREA *a;
  1018.     long floor_at(), ceiling_at();
  1019.  
  1020.     if (show_location) {
  1021.         strcpy(buff, "Pos(x,z): ");
  1022.         ltoa(current_view->ex, buff + 10, 10);
  1023.         strcat(buff, ",");
  1024.         ltoa(current_view->ez, buff + strlen(buff), 10);
  1025.         prprint(2, 3, 15, buff);
  1026.  
  1027.         strcpy(buff, "Not in any area");
  1028.         a = what_area(split_tree, current_view->ex, current_view->ey, current_view->ez);
  1029.         if (a)
  1030.         {
  1031.             char *p = find_value((NAMEREF *)areas, a);
  1032.             if (p) {
  1033.                 strcpy(buff, "Area: ");
  1034.                 strcat(buff, p);
  1035.                 // sprintf(buff, "Area: %s", p);
  1036.             }
  1037.         }
  1038.         prprint(2,15,15,buff);
  1039.     }
  1040.     if (show_gestures && use_glove)
  1041.     {
  1042.         int sl;
  1043.         POINTER p;
  1044.  
  1045.         last_pointer(manip_device[0], &p);
  1046.         strcpy(buff, "Glove 1: ");
  1047.         strcat(buff, gest[p.gesture]);
  1048.         //sprintf(buff,"Glove: %s",gest[p.gesture]);
  1049.         sl = strlen(buff)<<3;
  1050.         prprint(300-sl,3,15,buff);
  1051.         if (manip_device[1]) {
  1052.             last_pointer(manip_device[1], &p);
  1053.             strcpy(buff, "Glove 2: ");
  1054.             strcat(buff, gest[p.gesture]);
  1055.             //sprintf(buff,"Glove: %s",gest[p.gesture]);
  1056.             sl = strlen(buff)<<3;
  1057.             prprint(300-sl,15,15,buff);
  1058.         }
  1059.     }
  1060.     return 0;
  1061.  
  1062. }
  1063.  
  1064.