home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / PCVRJET / JET.C < prev    next >
C/C++ Source or Header  |  1992-12-11  |  33KB  |  1,191 lines

  1. /* This program requires Release 4.01 of Rend386 to compile */
  2. /* This program is COPYRIGHTED by Gradecki Publishing and PCVR */
  3. /* ANY commercial distribution must be authorized by said companies */
  4.  
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <dos.h>
  9. #include <math.h>
  10. #include "rend386.h"
  11. #include "userint.h"
  12. #include "plg.h"
  13. #include "splits.h"
  14. #include "tasks.h"
  15. #include "pointer.h"
  16. #include "cursor.h"
  17. #include "segasupp.h"
  18. #include "segio.h"
  19. #include "intmath.h"
  20.  
  21. #define to_rad(a) ((a) * 3.14159262 / 180.0)
  22. #define sine(x)   sin(to_rad(x/65536L))
  23. #define cosine(x) cos(to_rad(x/65536L))
  24.  
  25.  
  26. /* Global variables */
  27. /* This is our main object list.
  28.    Files used:  keyboard, world, cursors
  29. */
  30. OBJLIST      *objlist;
  31.  
  32. /* This is the default values for stereo viewing.
  33.    Files used:  keyboard, world, render
  34. */
  35. STEREO         default_stereo = {600,240,320,50,600, 1*65536L};
  36.  
  37. /* This variable indicates the type of viewing.
  38.    Declared in file: render.c
  39.    Files used: keyboard, gloveptr, world, render
  40. */
  41. int         stereo_type = MONOSCOPIC;
  42.  
  43. /* This variable declares the default startup view of the program.
  44.    Files used: keyboard, world
  45. */
  46. VIEW         default_view =  {
  47.                 0,0,0,
  48.                 0,0,0,
  49.                 9*65536L,
  50.                 1000,15000,-5000,
  51.                 0,319,0,199,
  52.                 1,100000,
  53.                 1/1.25*65535L,
  54.                 0
  55.                 };
  56.  
  57. /* This pointer points to the location of the default view
  58.    Files used: keyboard, world, render
  59. */
  60. VIEW         *current_view = &default_view;
  61.  
  62. /* This pointer in the beginning of the split tree for the program.  We
  63.    will only one however, that is not a requirement.
  64.    Files used: keyboard, world, render, cursors, hdmanip
  65. */
  66. SPLIT           *split_tree = NULL;
  67.  
  68. /* This variable holds a palette.
  69.    Files used: world
  70. */
  71. unsigned char     palette[256*3];
  72.  
  73. /* This pointer is the start of a set of tasks.
  74.    Files used: world
  75. */
  76. TASK         *tasklist = NULL;
  77.  
  78. /* This pointer holds a handle to the current video driver installed.
  79.    Files used: main program
  80. */
  81. void        *v_driver_pointer = NULL;
  82.  
  83. /* This variable holds a loadpath specified in the configuration file or
  84.    in a world file.
  85.    Files used: world
  86. */
  87. char         loadpath[100] = "";
  88.  
  89. /* This variable holds a temporary filename including a loadpath.
  90.    Files used: main program
  91. */
  92. static char     tempname[100];
  93.  
  94.  
  95. char         framefname[100];
  96.  
  97. /* Delcares an extern function. */
  98. extern void     *screen_data();
  99.  
  100. /* This variable is used to hold information about the current screen setup.
  101.    File used: gloveptr, mouseptr, render, userint
  102. */
  103. extern struct     Screeninfo *screeninfo;
  104.  
  105. /* This variable is used in the userint file.  Purpose ?
  106. */
  107. PDRIVER     *menu_device = NULL;
  108. PDRIVER        *manip_device = NULL;
  109.  
  110. /* These variable are used as the configuration settings for the glove
  111.    pointer device, translation and rotation.
  112.    Files used: world
  113. */
  114. float         gpdo_x = 0.1, gpdo_y = 0.1, gpdo_z = 0.1,
  115.         gpdo_rx = 1, gpdo_ry = 1, gpdo_rz = 1;
  116.  
  117. /* These varaiables are used as the configuration settings for the head
  118.    tracker device, relative position to neck, and rotation. */
  119. float         hdo_x = 0, hdo_y = 0, hdo_z = 0; /* relative pos'n to neck */
  120. float         hdo_rx = 0, hdo_ry = 0, hdo_rz = 0;
  121.  
  122. /* These variables are used as the configuration settings for the STEREOLEFT
  123.    command in a world file.  Check world.doc for description.
  124.    Files used: world keyboard
  125. */
  126. int         sl_xflip = 0, sl_xoff = 0;
  127. long         sl_left = -1, sl_top, sl_right, sl_bottom;
  128.  
  129. /* These variables are used as the configuration settings for the
  130.    STEREORIGHT command in a world file.  Check world.doc for description.
  131.    Files used: world keyboard
  132. */
  133. int         sr_xflip = 0, sr_xoff = 0;
  134. long         sr_left = -1, sr_top, sr_right, sr_bottom;
  135.  
  136. /* These variables are used as the configuration settings for the rotation
  137.    of the STEREORIGHT and STEREOLEFT commands in the world file.  Check
  138.    world.doc for description.
  139.    Files used: world keyboard.
  140. */
  141. float         sl_xrot = 0, sr_xrot = 0;
  142.  
  143. /* This variable indicates whether or not a glove is being used.
  144.    0 = false.
  145.    Files used: cursors hdmanip
  146. */
  147. int         use_glove = 1;
  148.  
  149. /* This variable indicates whether or not a head tracker is being used.
  150.    0 = false.
  151.    Files used: render
  152. */
  153. int         use_ht = 0;
  154.  
  155. /* This variable indicates whether or not a wide-angle dual VGA
  156.    head mounted display system is being used.
  157.    0 = false.
  158.    Files used: render
  159. */
  160. int         use_wide = 0;
  161.  
  162. /* This variable indicates whether or not a monochrome system is being used.
  163.    0 = false.
  164.    Files used: render
  165. */
  166. int         use_BW = 0;
  167.  
  168. /* This variable is set to 1 if the eyes are to be switched when using
  169.    the Sega 3D glasses.
  170.    Files used: render
  171. */
  172. int         swap_eyes = 0;
  173.  
  174. /* This variable is set to display a fancy background
  175.    Files used: keyboard render
  176. */
  177. int         fancy_background = 0;
  178.  
  179. /* This variable is set to draw a reflection pool at the bottom of the
  180.    screen.
  181.    Files used: keybaord render
  182. */
  183. int         reflection_pool = 0;
  184.  
  185. /* This variable is set to indicate we have a logo to display.
  186.    Files used: render
  187. */
  188. int         have_logo = 0;
  189.  
  190. /* This variable is set to show our logo, if we have one.
  191.    Files used: render keyboard
  192. */
  193. int         show_logo = 0;
  194.  
  195. /* This variable is set to show the current location on-screen.
  196.    Files used: render keyboard
  197. */
  198. int         show_location = 0;
  199.  
  200. /* This variable is set to show the 3D compass on-screen.
  201.    Files used: render keyboard
  202. */
  203. int         show_compass = 0;
  204.  
  205. /* This variable is set to display the frames/second rate on-screen.
  206.    Files used: render keyboard
  207. */
  208. int         show_framerate = 0;
  209.  
  210. /* This variable is set to clear the screen on each frame.
  211.    Files used: render world keyboard
  212. */
  213. int         do_screen_clear = 1;
  214.  
  215. /* This variable is set to draw a "frame".
  216.    Files used: world render
  217. */
  218. int         use_frame = 0;
  219.  
  220. /* These variabels define the location of a "frame".
  221.    Files used: world render
  222. */
  223. int         frame_x = 0, frame_y = 0, frame_w = 320, frame_h = 200;
  224.  
  225. /* This variable is set to the current display mode to use.
  226.    Files used: render world
  227. */
  228. int        vdmode = 0x14;
  229.  
  230. /* This variable is set to 1 if we need to recompute the current view.
  231.    Files used: world keyboard
  232. */
  233. int         review = 1;
  234.  
  235. /* This variable is set to 1 if we need to copy our gram back on-screen.
  236.    Files used: keyboard world colormap render rendrep
  237. */
  238. int         reframe = 0;
  239.  
  240.  
  241. /* This variable is set if the shift key is used by the user.
  242.    Files used: main program keyboard
  243. */
  244. int         shifted = 0;
  245.  
  246. /* This variable is used to hold the current visual page being used.
  247.    Files used: render userint
  248. */
  249. int        v_page = 0;
  250.  
  251. /* This variable is set if a glove is available.
  252.    Files used: world cursors
  253. */
  254. int         have_glove = 1;
  255.  
  256. /* This variable is set if a pointer device is available.
  257.    Files used: world cursors
  258. */
  259. int         have_ptr = 0;
  260.  
  261. /* This variable is set if we can do mouse manipulations.
  262.    Files used: keyboard
  263. */
  264. int         manip_2D_avail = 0;
  265.  
  266. /* This variable is set to run the main execution loop.
  267.    Files used: main
  268. */
  269. int             execution = 1;
  270.  
  271. /* This variable is set to indicate a screen redraw is necessary.
  272.    Files used: keyboard anim world cursors render hdmanip
  273. */
  274. int        redraw = 1;
  275.  
  276. /* This variable is set if a horizon should be drawn.
  277.    Files used: keyboard render colormap
  278. */
  279. int        do_horizon = 1;
  280.  
  281. /* This variable is not necessary because it is define elsewhere and can
  282.    be set with a world file.  It is the color the system paints the top
  283.    half of the screen after it is cleared; if the do_horizon variable is
  284.    set to 1.
  285.    Files used: world render colormap
  286. */
  287. extern         sky_color;
  288.  
  289. /* This variable is not necessary because it is define elsewhere and can
  290.    be set with a world file.  It is the color the system paints the bottom
  291.    half of the screen after it is cleared; if the do_horizon variable is
  292.    set to 1.
  293.    Files used: world render colormap
  294. */
  295. extern        ground_color;
  296.  
  297. /* This variable is not necessary because it is define elsewhere and can
  298.    be set with a world file.  It is the color the system paints the screen
  299.    after it is cleared; if the do_horizon variable is set to 0.
  300.    Files used: world render colormap
  301. */
  302. extern int      screen_clear_color;
  303.  
  304.  
  305. /* This variable holds the highest possible color value.
  306.    Files used: render colormap
  307. */
  308. extern         highest_color;
  309.  
  310. /* This variable is set to 0 if no palette is loaded and
  311.    non-zero if a palette is loaded
  312.    Files used: world
  313. */
  314. int         npalette = 0;
  315.  
  316. /* This variable holds the name of the current switcher driver.
  317.    Files used: world
  318. */
  319. char         swdname[40] = "sega";
  320.  
  321. /* This variable holds the name of the current glove pointer driver.
  322.    Files used: world
  323. */
  324. char         gpdname[40] = "pglove";
  325.  
  326. /* This variable holds the name of the current head tracker driver.
  327.    Files used: world
  328. */
  329. char         hdname[40] = "none";
  330.  
  331. /* This variable holds the name of the glove pointer driver cursor figure.
  332.    Files used: world
  333. */
  334. char         gpcursor[40] = "handsm.fig";
  335.  
  336. /* This variable holds the name of the current video driver.
  337.    Files used: main program and world
  338. */
  339. char            vdname[40] = "vd256.rvd";
  340.  
  341. /* This variable holds the name of the current mouse driver.
  342.    Files used: world
  343. */
  344. char            mdname[40] = "none";
  345.  
  346. int head_device = 0;
  347. extern SEGMENT *body_seg;
  348. joystick_data joy_data;
  349. int joy_return = 0;
  350. int jet_speed = 5;
  351. int fire_distance = 100;
  352. OBJECT *finger_tip, *palm, *but1, *but2, *but3, *yoke_obj;
  353. SEGMENT *yoke;
  354.  
  355. /**************************************************************************
  356.    This function is used by the file render.c to display various things
  357.    on the screen to the user.  This is not needed by any program just
  358.    an option.  However, render.c needs access to this function
  359. ***************************************************************************/
  360. void status_on_screen()
  361. {
  362. }
  363.  
  364.  
  365. /**************************************************************************
  366.    This function concatenates the loadpath to the string name IF
  367.    name is not "\\" and not "/" and loadpath is not empty.  It is used by
  368.    the files: world.c.
  369. **************************************************************************/
  370. char *fix_fname(char *name)
  371. {
  372.  
  373.     if (loadpath[0] && !strchr(name, '\\') && !strchr(name, '/'))
  374.         sprintf(tempname, "%s\\%s", loadpath, name);
  375.     else
  376.         strcpy(tempname, name);
  377.     return tempname;
  378. }
  379.  
  380.  
  381. /**************************************************************************
  382.   This function is called when the user ends the graphics program.  It
  383.   shuts done the graphics system and exits the renders and finally exits
  384.   the progam.
  385. **************************************************************************/
  386. void closeall(){
  387.   exit_graphics();
  388.   reset_render();
  389.   exit(0);
  390. }
  391.  
  392. /**************************************************************************
  393.   This function performs the updating of the screen after any object or
  394.   perspective movements.  The majority of the work is done in the
  395.   function screen_refresh in the file render.c
  396. **************************************************************************/
  397. void refresh_display(){
  398.  
  399.   initialize_screen_factors ( current_view );
  400.   fast_view_factors ( current_view );
  401.   screen_refresh ( current_view );
  402.  
  403. }
  404.  
  405.  
  406. /**************************************************************************
  407.    This function is from Rend386 demo2.c program and is used to get
  408.    keyboard input from the user.
  409. ***************************************************************************/
  410. unsigned getkey(){
  411.   unsigned c;
  412.   union REGS regs;
  413.  
  414.   regs.h.ah = 2;
  415.   int86(0x16, ®s,®s );
  416.   shifted = (regs.h.al & 3);
  417.   if ((c=bioskey(0)) & 0xff) c &= 0xff;
  418.   else if ( shifted ) c |= 1;
  419.   return c;
  420. }
  421.  
  422.  
  423.  
  424. void prprint(int x,int y, int color, char *t)
  425. {
  426.     int bk = (color>8) ? 0 : 15;
  427.  
  428.     printxyr(x,y,bk,t,0);
  429.     printxyr(x+1,y+1,color,t,0);
  430. }
  431.  
  432.  
  433.  
  434.  
  435. long test_x, test_y, test_z;
  436. void test_object ( OBJECT *obj )
  437. {
  438.   long x, y, z;
  439.  
  440.   if (sphere_pretest ( obj, test_x, test_y, test_z) < 100 )
  441.     remove_from_objlist ( obj );
  442. }
  443.  
  444. OBJECT *exp1, *exp2, *exp3, *exp4, *exp5, *exp6;
  445. SEGMENT *exp1s, *exp2s, *exp3s, *exp4s, *exp5s, *exp6s, *jet;
  446. /**************************************************************************
  447. **************************************************************************/
  448. void do_explosion( long x, long y, long z )
  449. {
  450.  
  451.   abs_move_segment ( exp1s, x, y, z );
  452.   update_segment ( exp1s );
  453.   get_object_bounds ( seg_get_object ( exp1s ), &test_x, &test_y, &test_z );
  454.   walk_split_tree ( &split_tree, test_object );
  455.  
  456.   refresh_display();
  457.   delay (100);
  458.  
  459.   abs_move_segment ( exp2s, x, y, z );
  460.   update_segment ( exp2s );
  461.   refresh_display();
  462.   delay (100);
  463.  
  464.   abs_move_segment ( exp3s, x, y, z );
  465.   update_segment ( exp3s );
  466.   refresh_display();
  467.   delay (100);
  468.  
  469.   abs_move_segment ( exp4s, x, y, z );
  470.   update_segment ( exp4s );
  471.   refresh_display();
  472.   delay (100);
  473.  
  474.   abs_move_segment ( exp5s, x, y, z );
  475.   update_segment ( exp5s );
  476.   refresh_display();
  477.   delay (100);
  478.  
  479.   abs_move_segment ( exp6s, x, y, z );
  480.   update_segment ( exp6s );
  481.   refresh_display();
  482.   delay (100);
  483.  
  484.   remove_from_objlist ( exp1 );
  485.   remove_from_objlist ( exp2 );
  486.   remove_from_objlist ( exp3 );
  487.   remove_from_objlist ( exp4 );
  488.   remove_from_objlist ( exp5 );
  489.   remove_from_objlist ( exp6 );
  490.   refresh_display ();
  491.  
  492. }
  493.  
  494.  
  495.  
  496.  
  497.  
  498. /**************************************************************************
  499.    This function handles keys pressed by the user.Handle any user keys.
  500. **************************************************************************/
  501. void handle_key ( unsigned int c ){
  502. FILE *infile;
  503.  
  504.   switch ( c ) {
  505.     case 'q':
  506.     case 'Q':popmsg ( "Do you wish to quit? (y/n)" );
  507.          if ( toupper(getkey())== 'Y' ) execution = 0;
  508.          else redraw = 1;
  509.          break;
  510.  
  511.     /* Look up. Step by 1 angle value */
  512.     case 0x4800: current_view->ex += 50 + 5L * sine(current_view->roll);
  513.          current_view->ez += 50+ 5L * cosine(current_view->roll);
  514.  
  515.          rel_move_segment ( jet,
  516.                          50+5L*sine(current_view->roll),
  517.                          0,
  518.                          50+5L*cosine(current_view->roll));
  519.          update_segment ( jet );
  520.          redraw = 1;
  521.          break;
  522.  
  523.     /* Look down. Step by 1 angle value */
  524.     case 0x5000: current_view->ex -= 50 + 5L * sine(current_view->roll);
  525.          current_view->ez -= 50 + 5L * cosine(current_view->roll);
  526.          rel_move_segment ( jet,
  527.                       -(50 + 5L*sine(current_view->roll)),
  528.                       0,
  529.                       -( 50 + 5L*cosine(current_view->roll)));
  530.          update_segment ( jet );
  531.          redraw = 1;
  532.          break;
  533.  
  534.     case 0x4B00: current_view->roll -= 65536L;
  535.          current_view->pan  -= 65536L;
  536.          redraw = 1;
  537.          break;
  538.  
  539.     case 0x4D00: current_view->roll += 65536L;
  540.          current_view->pan  += 65536L;
  541.          redraw = 1;
  542.          break;
  543.  
  544.     case 'b': do_explosion ( current_view->ex,
  545.                  current_view->ey,
  546.                  current_view->ez+fire_distance );
  547.           break;
  548.   }
  549. }
  550.  
  551.  
  552. SEGMENT *but1_menu_seg, *but2_menu_seg, *but3_menu_seg;
  553. POINTER gp;
  554. void do_button1()
  555. {
  556.   long button1x, button1y, button1z;
  557.   long button2x, button2y, button2z;
  558.   long button3x, button3y, button3z;
  559.   int key_pressed = 0;
  560.   char buf[40];
  561.  
  562.   abs_move_segment ( but1_menu_seg, current_view->ex-25,
  563.                     current_view->ey-10,
  564.                     current_view->ez+55);
  565.   update_segment ( but1_menu_seg );
  566.   get_object_bounds ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "m1button1" ) ), &button1x, &button1y, &button1z );
  567.   get_object_bounds ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "m1button2" ) ), &button2x, &button2y, &button2z );
  568.   get_object_bounds ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "m1button3" ) ), &button3x, &button3y, &button3z );
  569.  
  570.  
  571.  
  572.   while (!key_pressed)
  573.   {
  574.  
  575.     refresh_display();
  576.     glove_update( manip_device, &gp );
  577.     update_segment ( body_seg );
  578.  
  579.     sprintf ( buf, "Jet Speed = %d", jet_speed );
  580.     prprint(102,40,15, buf );
  581.  
  582.     sprintf(buf, "Increase 10" );
  583.     prprint(90,62,15,buf);
  584.  
  585.     sprintf(buf, "Decrease 10" );
  586.     prprint(90,84,15,buf);
  587.  
  588.     sprintf(buf, "Finished" );
  589.     prprint(90,105,15,buf);
  590.  
  591.  
  592.     if (sphere_pretest(finger_tip, button1x, button1y, button1z) < 100)
  593.       jet_speed += 10;
  594.  
  595.     if (sphere_pretest(finger_tip, button2x, button2y, button2z) < 100)
  596.       jet_speed -= 10;
  597.  
  598.     if (sphere_pretest(finger_tip, button3x, button3y, button3z) < 100)
  599.       key_pressed = 1;
  600.  
  601.   }
  602.  
  603.   refresh_display();
  604.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "menu1")));
  605.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "m1button1")));
  606.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "m1button2")));
  607.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "m1button3")));
  608.   refresh_display();
  609.  
  610. }
  611.  
  612.  
  613. void do_button2()
  614. {
  615.   long button1x, button1y, button1z;
  616.   long button2x, button2y, button2z;
  617.   long button3x, button3y, button3z;
  618.   int key_pressed = 0;
  619.   char buf[40];
  620.  
  621.   abs_move_segment ( but2_menu_seg, current_view->ex-25,
  622.                     current_view->ey-10,
  623.                     current_view->ez+55);
  624.   update_segment ( but2_menu_seg );
  625.   get_object_bounds ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "m2button1" ) ), &button1x, &button1y, &button1z );
  626.   get_object_bounds ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "m2button2" ) ), &button2x, &button2y, &button2z );
  627.   get_object_bounds ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "m2button3" ) ), &button3x, &button3y, &button3z );
  628.  
  629.  
  630.  
  631.   while (!key_pressed)
  632.   {
  633.  
  634.     refresh_display();
  635.     glove_update( manip_device, &gp );
  636.     update_segment ( body_seg );
  637.  
  638.     sprintf ( buf, "Fire Distance = %d", fire_distance );
  639.     prprint(90,40,15, buf );
  640.  
  641.     sprintf(buf, "Increase 10" );
  642.     prprint(90,62,15,buf);
  643.  
  644.     sprintf(buf, "Decrease 10" );
  645.     prprint(90,84,15,buf);
  646.  
  647.     sprintf(buf, "Finished" );
  648.     prprint(90,105,15,buf);
  649.  
  650.  
  651.     if (sphere_pretest(finger_tip, button1x, button1y, button1z) < 100)
  652.       fire_distance += 10;
  653.  
  654.     if (sphere_pretest(finger_tip, button2x, button2y, button2z) < 100)
  655.       fire_distance -= 10;
  656.  
  657.     if (sphere_pretest(finger_tip, button3x, button3y, button3z) < 100)
  658.       key_pressed = 1;
  659.  
  660.   }
  661.  
  662.   refresh_display();
  663.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "menu2")));
  664.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "m2button1")));
  665.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "m2button2")));
  666.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "m2button3")));
  667.   refresh_display();
  668.  
  669. }
  670.  
  671. void read_menus()
  672. {
  673.   FILE *in;
  674.  
  675.   if ((in = fopen("menu1.fig", "r")) == NULL)
  676.   {
  677.     popmsg("Could not load figure file");
  678.   }
  679.   else
  680.   {
  681.     set_readseg_objlist(objlist);
  682.     if ((but1_menu_seg = readseg(in, NULL)) == NULL)
  683.     {
  684.     popmsg("Error reading menu1 figure file");
  685.     }
  686.     else
  687.     update_segment(but1_menu_seg);
  688.   }
  689.   fclose ( in );
  690.  
  691.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "menu1")));
  692.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "m1button1")));
  693.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "m1button2")));
  694.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but1_menu_seg, "m1button3")));
  695.  
  696.   if ((in = fopen("menu2.fig", "r")) == NULL)
  697.   {
  698.     popmsg("Could not load figure file");
  699.   }
  700.   else
  701.   {
  702.     set_readseg_objlist(objlist);
  703.     if ((but2_menu_seg = readseg(in, NULL)) == NULL)
  704.     {
  705.     popmsg("Error reading menu2 figure file");
  706.     }
  707.     else
  708.     update_segment(but2_menu_seg);
  709.   }
  710.   fclose ( in );
  711.  
  712.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "menu2")));
  713.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "m2button1")));
  714.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "m2button2")));
  715.   remove_from_objlist ( seg_get_object ( find_segment_by_name ( but2_menu_seg, "m2button3")));
  716.  
  717.  
  718. }
  719.  
  720.  
  721.  
  722.  
  723. /**************************************************************************
  724.   This function performs the functions of the program.  The loop terminates
  725.   when execution = 1.
  726. **************************************************************************/
  727. void main_loop(){
  728.   char buf[100];
  729.   long button1x, button1y, button1z;
  730.   long button2x, button2y, button2z;
  731.   long button3x, button3y, button3z;
  732.   long yokex, yokey, yokez;
  733.   long dist;
  734.   int on_yoke = 0;
  735.  
  736.  
  737.   finger_tip = seg_get_object ( find_segment_by_name ( body_seg, "indextip" ));
  738.   palm = seg_get_object ( find_segment_by_name ( body_seg, "palm" ));
  739.   yoke = find_segment_by_name ( jet, "yoke_stick" );
  740.   yoke_obj = seg_get_object ( yoke );
  741.   but1 = seg_get_object ( find_segment_by_name ( jet, "button1" ));
  742.   but2 = seg_get_object ( find_segment_by_name ( jet, "button2" ));
  743.   but3 = seg_get_object ( find_segment_by_name ( jet, "button3" ));
  744.   while ( execution )
  745.     {
  746.       if (bioskey(1))     handle_key (getkey());
  747.       if (redraw)     refresh_display();
  748.  
  749.       get_object_bounds ( yoke_obj, &yokex, &yokey, &yokez );
  750.       yokey += 20;
  751.  
  752.       get_object_bounds ( but1, &button1x, &button1y, &button1z );
  753.       get_object_bounds ( but2, &button2x, &button2y, &button2z );
  754.       get_object_bounds ( but3, &button3x, &button3y, &button3z );
  755.  
  756.       glove_update( manip_device, &gp );
  757.       update_segment ( body_seg );
  758.  
  759.       if (((dist = sphere_pretest ( palm, yokex, yokey, yokez)) < 300 ) && ((gp.gesture== G_FIST) || (gp.gesture==G_THUMB_OUT) ))
  760.       on_yoke = 1;
  761.       else if (!((gp.gesture==G_THUMB_OUT)||(gp.gesture == G_FIST)))
  762.     on_yoke = 0;
  763.  
  764.  
  765.       if (! on_yoke )
  766.       {
  767.     if ((dist = sphere_pretest (finger_tip,button1x,button1y,button1z)) < 100 )
  768.       do_button1();
  769.     else if ((dist = sphere_pretest (finger_tip,button2x,button2y,button2z)) < 100 )
  770.       do_button2();
  771.     else if ((dist = sphere_pretest (finger_tip,button3x,button3y,button3z)) < 100 )
  772.       execution = 0;
  773.       }
  774.  
  775.       if (( gp.gesture == G_FIST ) && (on_yoke))
  776.       {
  777.     if ( gp.dz > 0 )
  778.     {
  779.       current_view->ex += jet_speed * sine(current_view->pan);
  780.       current_view->ez += jet_speed * cosine(current_view->pan);
  781.  
  782.       rel_move_segment ( jet,
  783.                  jet_speed*sine(current_view->pan),
  784.                  0,
  785.                  jet_speed*cosine(current_view->pan));
  786.       update_segment ( jet );
  787.       rel_move_segment ( body_seg,
  788.                  jet_speed*sine(current_view->pan),
  789.                  0,
  790.                  jet_speed*cosine(current_view->pan));
  791.       update_segment ( body_seg );
  792.  
  793.       redraw = 1;
  794.     }
  795.     else if ( gp.dz < 0 )
  796.     {
  797.       current_view->ex -= jet_speed * sine(current_view->pan);
  798.       current_view->ez -= jet_speed * cosine(current_view->pan);
  799.       rel_move_segment ( jet,
  800.                   -(jet_speed*sine(current_view->pan)),
  801.                   0,
  802.                   -(jet_speed*cosine(current_view->pan)));
  803.       update_segment ( jet );
  804.       rel_move_segment ( body_seg,
  805.                  -(jet_speed*sine(current_view->pan)),
  806.                  0,
  807.                  -(jet_speed*cosine(current_view->pan)));
  808.       update_segment ( body_seg );
  809.       redraw = 1;
  810.     }
  811.     else if ( gp.dx > 0 )
  812.     {
  813.           current_view->ex += jet_speed * cosine(current_view->pan);
  814.           current_view->ez -= jet_speed * sine(current_view->pan);
  815.           rel_move_segment ( body_seg, +jet_speed*cosine(current_view->pan),
  816.                        0,
  817.                        -jet_speed*sine(current_view->pan));
  818.           update_segment ( body_seg );
  819.           rel_move_segment ( jet, +jet_speed*cosine(current_view->pan),
  820.                        0,
  821.                        -jet_speed*sine(current_view->pan));
  822.           update_segment ( jet );
  823.           redraw = 1;
  824.     }
  825.     else if ( gp.dx < 0 )
  826.     {
  827.           current_view->ex -= jet_speed * cosine(current_view->pan);
  828.           current_view->ez += jet_speed * sine(current_view->pan);
  829.           rel_move_segment ( body_seg, -jet_speed*cosine(current_view->pan),
  830.                        0,
  831.                        +jet_speed*sine(current_view->pan));
  832.           update_segment ( body_seg );
  833.           rel_move_segment ( jet, -jet_speed*cosine(current_view->pan),
  834.                        0,
  835.                        +jet_speed*sine(current_view->pan));
  836.           update_segment ( jet );
  837.           redraw = 1;
  838.  
  839.     }
  840.       }
  841.     }
  842. }
  843.  
  844.  
  845.  
  846. /**************************************************************************
  847.   This function is called to load video drivers.  The pointer
  848.   v_driver_pointer is set to a handle representing the video driver.
  849.   The variable v_driver_pointer is used by the files: main only.
  850. **************************************************************************/
  851. void load_video_driver ( char *dfile )
  852. {
  853.   v_driver_pointer = load_driver ( dfile );
  854.   if ( v_driver_pointer == NULL )
  855.   {
  856.     fprintf ( stderr, "Bad video driver/n" );
  857.     exit ( 1 );
  858.   }
  859. }
  860.  
  861.  
  862. /**************************************************************************
  863. **************************************************************************/
  864. void get_jet()
  865. {
  866.   FILE *in;
  867.  
  868.   if ((in = fopen("jet.fig", "r")) == NULL)
  869.   {
  870.     popmsg("Could not load figure file");
  871.   }
  872.   else
  873.   {
  874.     set_readseg_objlist(objlist);
  875.     if ((jet = readseg(in, NULL)) == NULL)
  876.     {
  877.     popmsg("Error reading jet figure file");
  878.     }
  879.     else
  880.     update_segment(jet);
  881.   }
  882.   fclose ( in );
  883. }
  884.  
  885. /**************************************************************************
  886. **************************************************************************/
  887. void get_explosions()
  888. {
  889.  
  890.   FILE *in;
  891.  
  892.   set_loadplg_offset ( 0,0,0 );
  893.   set_loadplg_scale ( 1,1,1 );
  894.  
  895.  
  896.   if ((in = fopen ( "exp1.plg", "r" )) == NULL )
  897.     {
  898.       fprintf ( stderr, "Unable to open exp1 file.\n" );
  899.       exit(1);
  900.     }
  901.  
  902.   exp1 = load_plg ( in );
  903.   if ( load_err != 0 )
  904.     {
  905.       fprintf ( stderr, "Error loading exp1.plg file.\n" );
  906.       exit(1);
  907.     }
  908.   fclose ( in );
  909.  
  910.   if ((in = fopen ( "exp2.plg", "r" )) == NULL )
  911.     {
  912.       fprintf ( stderr, "Unable to open exp2 file.\n" );
  913.       exit(1);
  914.     }
  915.  
  916.   exp2 = load_plg ( in );
  917.   if ( load_err != 0 )
  918.     {
  919.       fprintf ( stderr, "Error loading exp2.plg file.\n" );
  920.       exit(1);
  921.     }
  922.   fclose ( in );
  923.  
  924.   if ((in = fopen ( "exp3.plg", "r" )) == NULL )
  925.     {
  926.       fprintf ( stderr, "Unable to open exp3 file.\n" );
  927.       exit(1);
  928.     }
  929.  
  930.   exp3 = load_plg ( in );
  931.   if ( load_err != 0 )
  932.     {
  933.       fprintf ( stderr, "Error loading exp3.plg file.\n" );
  934.       exit(1);
  935.     }
  936.   fclose ( in );
  937.  
  938.   if ((in = fopen ( "exp4.plg", "r" )) == NULL )
  939.     {
  940.       fprintf ( stderr, "Unable to open exp4 file.\n" );
  941.       exit(1);
  942.     }
  943.  
  944.   exp4 = load_plg ( in );
  945.   if ( load_err != 0 )
  946.     {
  947.       fprintf ( stderr, "Error loading exp4.plg file.\n" );
  948.       exit(1);
  949.     }
  950.   fclose (in);
  951.  
  952.   if ((in = fopen ( "exp5.plg", "r" )) == NULL )
  953.     {
  954.       fprintf ( stderr, "Unable to open exp5 file.\n" );
  955.       exit(1);
  956.     }
  957.  
  958.   exp5 = load_plg ( in );
  959.   if ( load_err != 0 )
  960.     {
  961.       fprintf ( stderr, "Error loading exp5.plg file.\n" );
  962.       exit(1);
  963.     }
  964.   fclose( in );
  965.  
  966.   if ((in = fopen ( "exp6.plg", "r" )) == NULL )
  967.     {
  968.       fprintf ( stderr, "Unable to open exp6 file.\n" );
  969.       exit(1);
  970.     }
  971.  
  972.   exp6 = load_plg ( in );
  973.   if ( load_err != 0 )
  974.     {
  975.       fprintf ( stderr, "Error loading exp6.plg file.\n" );
  976.       exit(1);
  977.     }
  978.   fclose ( in );
  979.  
  980.  
  981.   add_obj_to_split ( &split_tree, exp1 );
  982.   exp1s = new_seg ( NULL );
  983.   seg_set_object ( exp1s, exp1 );
  984.   set_object_owner ( exp1, exp1s );
  985.   abs_rot_segment ( exp1s, 90*65536L, 0, 0, RXYZ );
  986.   update_segment ( exp1s );
  987.   remove_from_objlist ( exp1 );
  988.  
  989.   add_obj_to_split ( &split_tree, exp2 );
  990.   exp2s = new_seg ( NULL );
  991.   seg_set_object ( exp2s, exp2 );
  992.   set_object_owner ( exp2, exp2s );
  993.   abs_rot_segment ( exp2s, 90*65536L, 0, 0, RXYZ );
  994.   update_segment ( exp2s );
  995.   remove_from_objlist ( exp2 );
  996.  
  997.   add_obj_to_split ( &split_tree, exp3 );
  998.   exp3s = new_seg ( NULL );
  999.   seg_set_object ( exp3s, exp3 );
  1000.   set_object_owner ( exp3, exp3s );
  1001.   abs_rot_segment ( exp3s, 90*65536L, 0, 0, RXYZ );
  1002.   update_segment ( exp3s );
  1003.   remove_from_objlist ( exp3 );
  1004.  
  1005.   add_obj_to_split ( &split_tree, exp4 );
  1006.   exp4s = new_seg ( NULL );
  1007.   seg_set_object ( exp4s, exp4 );
  1008.   set_object_owner ( exp4, exp4s );
  1009.   abs_rot_segment ( exp4s, 90*65536L, 0, 0, RXYZ );
  1010.   update_segment ( exp4s );
  1011.   remove_from_objlist ( exp4 );
  1012.  
  1013.  
  1014.   add_obj_to_split ( &split_tree, exp5 );
  1015.   exp5s = new_seg ( NULL );
  1016.   seg_set_object ( exp5s, exp5 );
  1017.   set_object_owner ( exp5, exp5s );
  1018.   abs_rot_segment ( exp5s, 90*65536L, 0, 0, RXYZ );
  1019.   update_segment ( exp5s );
  1020.   remove_from_objlist ( exp5 );
  1021.  
  1022.   add_obj_to_split ( &split_tree, exp6 );
  1023.   exp6s = new_seg ( NULL );
  1024.   seg_set_object ( exp6s, exp6 );
  1025.   set_object_owner ( exp6, exp6s );
  1026.   abs_rot_segment ( exp6s, 90*65536L, 0, 0, RXYZ );
  1027.   update_segment ( exp6s );
  1028.   remove_from_objlist ( exp6 );
  1029.  
  1030. }
  1031.  
  1032.  
  1033. /**************************************************************************
  1034. **************************************************************************/
  1035. void get_x29_jet()
  1036. {
  1037. }
  1038.  
  1039.  
  1040.  
  1041. /**************************************************************************
  1042. **************************************************************************/
  1043. void get_1701_ship()
  1044. {
  1045. }
  1046.  
  1047. /**************************************************************************
  1048. **************************************************************************/
  1049. void set_1701_ship_flight_plan()
  1050. {
  1051. }
  1052.  
  1053. /**************************************************************************
  1054. **************************************************************************/
  1055. void set_x29_jet_flight_plan()
  1056. {
  1057. }
  1058.  
  1059. /**************************************************************************
  1060. **************************************************************************/
  1061. void get_glove()
  1062. {
  1063.   PDRIVER *gd;
  1064.   extern PDRIVER *gloveptr_init(char *gname, long sx, long sy,
  1065.          long sz, long srx, long sry, long srz );
  1066.  
  1067.   gd = gloveptr_init ( gpdname, gpdo_x*65536.0, gpdo_y*65536.0, gpdo_z*65536.0,
  1068.                gpdo_rx*65536.0, gpdo_ry*65536.0, gpdo_rz*65536.0 );
  1069.  
  1070.   manip_device = menu_device = gd;
  1071.   if(gd)
  1072.     load_glove_cursor ( body_seg, manip_device, gpcursor );
  1073. }
  1074.  
  1075.  
  1076.  
  1077.  
  1078. void main(int argc, char *argv[]){
  1079.   char *fname, *in_filename;
  1080.   FILE *in;
  1081.  
  1082.   setup_render(40,800);
  1083.   atexit(closeall);
  1084.   set_global_split_root ( &split_tree );
  1085.   initial_world_split ( &split_tree );
  1086.   set_move_handler ( split_move_handler );
  1087.   objlist = new_objlist();
  1088.  
  1089.  
  1090.   fname = "rend386.cfg";
  1091.   if ((in = fopen ( fname, "r" )) == NULL )
  1092.     {
  1093.       fprintf ( stderr, "Configuration file not found!" );
  1094.       exit(1);
  1095.     }
  1096.   else
  1097.     {
  1098.       if ( read_world(in))
  1099.     {
  1100.         fprintf ( stderr, "Error reading configuration file!" );
  1101.         exit(1);
  1102.     }
  1103.       fclose ( in );
  1104.     }
  1105.  
  1106.   in_filename = fix_fname(argv[1] );
  1107.   if ( strstr (in_filename, ".wld"))
  1108.     {
  1109.       if ((in = fopen ( in_filename, "r" )) == NULL )
  1110.     {
  1111.       fprintf ( stderr, "Error opening world file.\n" );
  1112.       exit(1);
  1113.     }
  1114.       if (read_world(in))
  1115.     {
  1116.       fprintf ( stderr, "Error reading world file.\n");
  1117.       exit(1);
  1118.     }
  1119.       fclose(in);
  1120.     }
  1121.  
  1122.  
  1123.   load_video_driver ( vdname );
  1124.   screeninfo = screen_data();
  1125.   highest_color = screeninfo->colors-1;
  1126.   preset_default_colors();
  1127.  
  1128.   frame_x = screeninfo->xmin;
  1129.   frame_y = screeninfo->ymin;
  1130.   frame_w = screeninfo->xmax - screeninfo->xmin+1;
  1131.   frame_h = screeninfo->ymax - screeninfo->ymin+1;
  1132.  
  1133.   default_view.left = screeninfo->xmin;
  1134.   default_view.top = screeninfo->ymin;
  1135.   default_view.right = screeninfo->xmax;
  1136.   default_view.bottom = screeninfo->ymax;
  1137.   default_view.aspect = screeninfo->aspect;
  1138.  
  1139.  
  1140.   if (enter_graphics()) {
  1141.     fprintf ( stderr, "could not enter graphics mode\n\n");
  1142.     exit(1);
  1143.     }
  1144.  
  1145.   screen_clear_color = 0;
  1146.  
  1147.   sky_color  = 1; ground_color = 2;
  1148.  
  1149.   initialize_screen_factors ( current_view );
  1150.   fast_view_factors ( current_view );
  1151.  
  1152.  
  1153.   if(stereo_type != MONOSCOPIC)
  1154.   {
  1155.    init_switch_driver(swdname);
  1156.    if(sl_left<0)
  1157.    {
  1158.     sl_left = default_view.left;
  1159.     sl_right = default_view.right;
  1160.     sl_top = default_view.top;
  1161.     sl_bottom = default_view.bottom;
  1162.    }
  1163.      compute_stereo_data(&default_stereo, 0, sl_xflip, sl_xoff, 65536.0*sl_xrot,
  1164.              sl_left, sl_top, sl_right, sl_bottom);
  1165.    if(sr_left<0)
  1166.    {
  1167.     sr_left = default_view.left;
  1168.     sr_right = default_view.right;
  1169.     sr_top = default_view.top;
  1170.     sr_bottom = default_view.bottom;
  1171.    }
  1172.      compute_stereo_data(&default_stereo, 1, sr_xflip, sr_xoff, 65536.0*sr_xrot,
  1173.              sr_left, sr_top, sr_right, sr_bottom);
  1174.   }
  1175.  
  1176.  
  1177.   set_readseg_scale ( 1,1,1 ); /* Must do or will get previous readseg scale */
  1178.   get_jet();
  1179.  
  1180.   body_seg = new_seg(NULL);
  1181.   set_readseg_scale ( 0.15, 0.15, 0.15 );
  1182.   get_glove();
  1183.   abs_move_segment ( body_seg, 0, 0, -1075 );
  1184.   update_segment ( body_seg );
  1185.  
  1186.   get_explosions();
  1187.   read_menus();
  1188.  
  1189.   main_loop();   /* start us off */
  1190. }
  1191.