home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / init.c < prev    next >
C/C++ Source or Header  |  1996-03-19  |  11KB  |  413 lines

  1. // Initialization routines for VR-386 demo program.
  2. // You may want to simplify these for your own code,
  3. // especially if you're not supporting all devices
  4.  
  5. // For VR-386 by Dave Stampe, 9/1/94
  6.  
  7.  
  8. /*
  9.  This code is part of the VR-386 project, created by Dave Stampe.
  10.  VR-386 is a desendent of REND386, created by Dave Stampe and
  11.  Bernie Roehl.  Almost all the code has been rewritten by Dave
  12.  Stampre for VR-386.
  13.  
  14.  Copyright (c) 1994 by Dave Stampe:
  15.  May be freely used to write software for release into the public domain
  16.  or for educational use; all commercial endeavours MUST contact Dave Stampe
  17.  (dstampe@psych.toronto.edu) for permission to incorporate any part of
  18.  this software or source code into their products!  Usually there is no
  19.  charge for under 50-100 items for low-cost or shareware products, and terms
  20.  are reasonable.  Any royalties are used for development, so equipment is
  21.  often acceptable payment.
  22.  
  23.  ATTRIBUTION:  If you use any part of this source code or the libraries
  24.  in your projects, you must give attribution to VR-386 and Dave Stampe,
  25.  and any other authors in your documentation, source code, and at startup
  26.  of your program.  Let's keep the freeware ball rolling!
  27.  
  28.  DEVELOPMENT: VR-386 is a effort to develop the process started by
  29.  REND386, improving programmer access by rewriting the code and supplying
  30.  a standard API.  If you write improvements, add new functions rather
  31.  than rewriting current functions.  This will make it possible to
  32.  include you improved code in the next API release.  YOU can help advance
  33.  VR-386.  Comments on the API are welcome.
  34.  
  35.  CONTACT: dstampe@psych.toronto.edu
  36. */
  37.  
  38.  
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <math.h>
  42. #include <ctype.h>   /* toupper() */
  43. #include <string.h>
  44. #include <mem.h>     /* memmove() */
  45. #include <dos.h>
  46. #include <alloc.h>   /* coreleft */
  47.  
  48. #include "config.h"
  49. #include "pointer.h"
  50. #include "vr_api.h"
  51. #include "intmath.h"
  52. #include "pcdevice.h"
  53. #include "splits.h"
  54. #include "renderer.h"   // setup_render()
  55. #include "xmem.h"
  56.  
  57. #include "f3dkitd.h"  /* for load_dac_colors() */
  58.  
  59.  
  60. extern unsigned _stklen = 10000; /* need lots of stack for recursion */
  61.  
  62.  
  63. /************ SYSTEM DATA **************/
  64.  
  65. WORD position_changed = 0;   // reasons to refresh screen
  66. WORD display_changed = 1;
  67. WORD world_changed = 1;
  68.  
  69.  
  70. /************* DRIVER INFORMATION **************/
  71.  
  72. char swdname[40] = "sega";
  73. char mdname[40] = "mouse";
  74.  
  75. PDRIVER *cursor_device = NULL; /* primary mouse device   */
  76. PDRIVER *menu_device = NULL; /* secondary mouse device */
  77.  
  78. int manip_2D_avail = 0; /* can do mouse manipulation */
  79.  
  80. char gpdname[40] = "pglove";
  81. char gpcursor[40] = "hand.fig";
  82.  
  83. POSE ptr_scale = { 65536L,65536L,3*65536L,65536L,65536L,65536L};
  84.  
  85. int have_glove = 0;
  86. int have_ptr = 0;
  87.  
  88. char hdname[40] = "none";
  89. POSE hd_offset = ZERO_POSE;
  90. int use_ht = 0;
  91.  
  92. int use_keyjoy = 0;    // use keys as joystick
  93.  
  94. /************* STEREOSCOPIC DATA ***************/
  95.  
  96. extern STEREO default_stereo;
  97. extern WORD stereo_type;
  98.  
  99. /************ OPTIONS FLAGS ***************/
  100.  
  101. int use_BW = 0;
  102. int swap_eyes = 0;
  103. int use_glove = 0;
  104.  
  105. /************ MISC. COMMUNICTION *************/
  106.  
  107. long emmrequest = 0;    // nonzero if EMM request: number of K
  108.  
  109. long originalmem,aftervideomem,afterloadmem;
  110.  
  111. void *temp_mem = NULL; /* points to area to be used for temp storage */
  112. long temp_size = 0;
  113.  
  114.  
  115. FILE *log_file = NULL;
  116.  
  117.  
  118. /************** VIDEO DRIVER *************/
  119.  
  120.  
  121. int npalette = 0; /* non-zero if we have a palette loaded */
  122. unsigned char palette[256*3];
  123.  
  124. extern struct Screeninfo *screeninfo;
  125.  
  126. char vdname[40] = "vd256.rvd";
  127. int vdmode = 0x14;
  128. int vd_loaded = 0;
  129.  
  130. void *v_driver_pointer = NULL;
  131.  
  132. void load_video_driver(char *dfile)
  133. {
  134.   v_driver_pointer = load_driver(dfile);
  135.   if (v_driver_pointer == NULL)
  136.    {
  137.       errprintf("Cannot read video driver %s\n", dfile);
  138.       exit(0);
  139.     }
  140.   screeninfo = screen_data();
  141. }
  142.  
  143.  
  144. /************ OPTIONS SCAN **********/
  145.  
  146. static int file_arg_index[10] = {0,0,0,0,0,0,0,0,0,0};
  147.  
  148.     // get cmd line options, loads cfg file
  149.     // also marks files on cmd line for loading
  150. void read_configuration(int argc, char *argv[])
  151. {
  152.   int i;
  153.   int fp = 0;
  154.   FILE *in;
  155.   char *fname;
  156.   char *config_file_name = "vr386.cfg";
  157.  
  158.   if(argc>0)    // any args?
  159.     {
  160.       for (i=1; i < argc; i++)
  161.     {
  162.       if (argv[i][0] == '/' || argv[i][0] == '-')
  163.         {
  164.           switch(toupper(argv[i][1]))
  165.         {
  166.           case 'L':    /* log file */
  167.             {
  168.               char *lf;
  169.               if (argv[i][2]) lf = &argv[i][2];
  170.               else lf = argv[++i];
  171.               log_file = fopen(lf, "w");
  172.               if (log_file == NULL)
  173.             {
  174.               errprintf("Could not open log file '%s'\n", lf);
  175.               exit(2);
  176.             }
  177.             } break;
  178.  
  179.           case 'M':    /* disable MS mouse */
  180.             mdname[0] = 0;
  181.             break;
  182.  
  183.           case 'R':/* swap eyes on Sega driver */
  184.             swap_eyes = 1;
  185.             break;
  186.  
  187.           case 'E':    /* set eye spacing OR EMM on */
  188.             if(toupper(argv[i][2])=='M')
  189.               {
  190.             if(isdigit(argv[i+1][0]))
  191.             emmrequest = atol(argv[++i]);
  192.             else emmrequest = 4000;
  193.             atexit(resetEMMalloc);
  194.             if(!initEMMalloc(emmrequest>>4))
  195.                emmrequest = 0;    // clear flag if failure
  196.             break;
  197.               }
  198.             break;
  199.  
  200.           case 'X':/* turn on stereo */
  201.             stereo_type = SWITCHED;
  202.             break;
  203.  
  204.           case '1':/* com 1 for SEGA */
  205.             select_sega_port(0x3FC);
  206.             break;
  207.  
  208.           case '2':/* com 2 for SEGA */
  209.             select_sega_port(0x2FC);
  210.             break;
  211.  
  212.           case 'G':/* enable glove */
  213.             use_glove = 1;
  214.             if (!have_ptr) have_glove = 1;
  215.             break;
  216.  
  217.           case 'H':/* enable head tracker */
  218.             use_ht = 1;
  219.             break;
  220.  
  221.           case 'B':/* force all colors to monochrome */
  222.             use_BW = 1;
  223.             break;
  224.  
  225.           case 'K':/* turn on key monitor for joy-keys */
  226.             use_keyjoy++;
  227.             init_key_monitor();
  228.             break;
  229.  
  230.           case 'C':    // config file name
  231.             config_file_name = &(argv[++i][0]);
  232.             break;
  233.         }
  234.         }
  235.       else file_arg_index[fp++] = i;    // record for later loading
  236.     }
  237.     }
  238.  
  239.   if ((in = fopen(config_file_name, "r")) == NULL)
  240.     errprintf("Note -- config file '%s' not found; using defaults.\n", config_file_name);
  241.   else
  242.     {
  243.       read_config_file(in);
  244.       fclose(in);
  245.     }
  246. }
  247.  
  248.  
  249. void read_input_files(int argc, char *argv[])
  250. {
  251.   int i;
  252.   FILE *in;
  253.   char *fname;
  254.   OBJECT *obj;
  255.  
  256.   i = 0;
  257.   while(file_arg_index[i])
  258.     {
  259.       fname = fix_fname(argv[file_arg_index[i]]);
  260.       if ((in = fopen(fname, "r")) == NULL)
  261.      errprintf("Could not open '%s'\n", fname);
  262.       else if (strstr(fname,".plg")) /* check if plg or fig file */
  263.     {
  264.       POSE p = ZERO_POSE;
  265.  
  266.       while ((obj = load_plg_object(in, &p, 1, 1, 1, 0)) != NULL)
  267.         {
  268.           if (make_fixed_object_moveable(obj,NULL) == NULL)
  269.          errprintf("Warning: out of memory while loading an object\n");
  270.           else update_object(obj);    // adds to world if not in it
  271.         }
  272.       if (plg_error(NULL))
  273.         {
  274.           errprintf("%s in file %s\n", plg_error(NULL), fname);
  275.           getkey();
  276.         }
  277.     }
  278.       else if (strstr(fname,".fig")) /* check if plg or fig file */
  279.     {
  280.       obj = load_figure_as_object(in, default_objlist, NULL, 0, 1, 1, 1);
  281.       if (obj)
  282.         {
  283.           add_objlist_to_world(default_objlist);
  284.           update_object(obj);
  285.          }
  286.       if (seg_error(NULL))
  287.        {
  288.          errprintf("%s in file %s\n", seg_error(NULL), fname);
  289.        }
  290.     }
  291.      else
  292.        {
  293.      read_world(in);
  294.        }
  295.      fclose(in);
  296.      i++;
  297.    }
  298.  dump_lists(); /* get rid of temps used by world loader */
  299. }
  300.  
  301.  
  302. /********** CLOSE PROGRAM ***********/
  303.  
  304. void exit_handler(void) /* end program */
  305. {
  306.   int i;
  307.  
  308.   if (in_graphics) exit_graphics();
  309.   in_graphics = 0;
  310.   reset_render();
  311.   if (log_file) fclose(log_file);
  312. }
  313.  
  314.  
  315. /************** MAIN PROGRAM ***************/
  316.  
  317. extern void move_rep(OBJECT *o);   // the default renderer object update handler
  318.  
  319. void preload_initialize(int argc, char *argv[])
  320. {
  321.   originalmem = farcoreleft();        // initialize RENDERER
  322.   temp_mem = setup_render(63,1500);      /* # of K, # of polys */
  323.   temp_size = 63000L;
  324.  
  325.   set_renderer_update_handler(move_rep);  // MOTION HANDLERS
  326.   set_move_handler(split_move_handler);
  327.  
  328.   read_configuration(argc, argv);       // configure system
  329.  
  330.         /* preload video driver to set defaults */
  331. #ifdef LOAD_VIDEO_DRIVER
  332.   load_video_driver(vdname);
  333. #endif
  334.   aftervideomem = farcoreleft();
  335.  
  336.   screeninfo = screen_data();        // pre-world-load setup data
  337.   preset_default_colors();              // set up colors for
  338.  
  339.   create_default_world();
  340.  
  341.   init_body_links();            // create cameras, body
  342. }
  343.  
  344.  
  345.  
  346. void load_memory_report()
  347. {
  348.   afterloadmem = farcoreleft();     // memory report
  349.   if(emmrequest)
  350.     {
  351.       extern long alloccount;
  352.       fprintf(stderr,"EMM used: %ld in %ld allocs,  EMM available: %ld  \n",
  353.                 EMMheapused(), alloccount, EMMheapsize() );
  354.     }
  355.  
  356.   fprintf(stderr,"DOS memory:\n\t Renderer = %ld,\n\t World = %ld,\n\t Total = %ld;  %ld free\n",
  357.             originalmem - aftervideomem,
  358.             aftervideomem - afterloadmem,
  359.             originalmem - afterloadmem , afterloadmem   );
  360. }
  361.  
  362.  
  363. void video_initialize()
  364. {
  365.   enter_graphics(vdmode, use_BW);    // GRAPHICS INIT
  366.   in_graphics++;
  367.   compute_camera_factors(default_camera);
  368.   if (npalette)
  369.     load_DAC_colors(palette, screeninfo->colors, use_BW,0);
  370.   reset_screens();
  371. }
  372.  
  373.  
  374. void device_initialize()
  375. {
  376.   PDRIVER *dm;
  377.  
  378.  
  379.             // system timer startup
  380.   init_timer(0,NULL);    // uses default or driver speeds
  381.  
  382.  
  383.             // alternate-frame stero driver start
  384.             // may take over timer
  385.   if(stereo_type==SWITCHED) init_switch_driver(swdname);
  386.  
  387.   add_joy_device("joystick");       // navigation devices
  388.   add_joy_device("keys");
  389.   add_joy_device("mjoy");
  390.   if(use_keyjoy)
  391.      add_joy_device("keymon");
  392.                      // head tracker startup
  393.   if (stricmp(hdname,"none") && use_ht)
  394.       if(!init_head_device(hdname, &hd_offset)) use_ht = 0;
  395.  
  396.   if ((dm=mouseptr_init(mdname))!=NULL)  // mouse/cursor initialize
  397.     {
  398.       cursor_enable(TRUE);    // cursor available
  399.       cursor_show();
  400.       manip_2D_avail++;         // and can be used for manipulation
  401.     }
  402.   cursor_device = dm;        // mouse for object selection
  403.   menu_device = dm;             // mouse for menu interface
  404.  
  405.                 // initialize glove or 3D pointer
  406.   if (use_glove && (!have_ptr))
  407.        if(!(glove_initialize(gpdname, fix_fname(gpcursor), &ptr_scale))) use_glove=0;
  408.  
  409.   if (use_glove && have_ptr)
  410.        if(!pointer_initialize(gpdname, fix_fname(gpcursor), &ptr_scale)) use_glove=0;
  411. }
  412.  
  413.