home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / in_dos.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  12.8 KB  |  616 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // in_mouse.c -- dos mouse code
  21.  
  22. #include "quakedef.h"
  23. #include "dosisms.h"
  24.  
  25. #define AUX_FLAG_FREELOOK 0x00000001
  26.  
  27. typedef struct
  28. {
  29.   long    interruptVector;
  30.   char    deviceName[16];
  31.   long    numAxes;
  32.   long  numButtons;
  33.   long  flags;
  34.   
  35.   vec3_t  viewangles;
  36.  
  37. // intended velocities
  38.   float   forwardmove;
  39.   float   sidemove;
  40.   float   upmove;
  41.  
  42.   long  buttons;
  43. } externControl_t;
  44.  
  45. /*
  46. #define AUX_FLAG_FORCEFREELOOK  0x00000001  // r/o
  47. #define AUX_FLAG_EXTENDED   0x00000002  // r/o
  48. #define AUX_FLAG_RUN      0x00000004  // w/o
  49. #define AUX_FLAG_STRAFE     0x00000008  // w/o
  50. #define AUX_FLAG_FREELOOK   0x00000010  // w/o
  51.  
  52. #define AUX_MAP_UNDEFINED 0
  53. #define AUX_MAP_PITCH   1
  54. #define AUX_MAP_YAW     2
  55. #define AUX_MAP_ROLL    3
  56. #define AUX_MAP_FORWARD   4
  57. #define AUX_MAP_SIDE    5
  58. #define AUX_MAP_UP      6
  59.  
  60. typedef struct
  61. {
  62.   long    interruptVector;
  63.   // r/o
  64.   char    deviceName[16];
  65.   // r/o
  66.   long    numAxes;
  67.       // r/o  1-6
  68.   long  numButtons;     // r/o  0-32
  69.   long  flags;        // see above
  70.   byte  axisMapping[6];   // w/o  default = p,y,r,f,s,u
  71.   float axisValue[6];   // r/w
  72.   float sensitivity[6];   // w/o  default = 1.0
  73.   long  buttons;      // r/o
  74.   float last_frame_time;  // w/o
  75. } externControl_t;
  76. */
  77.  
  78. cvar_t  m_filter = {"m_filter","1"};
  79.  
  80. qboolean  mouse_avail;
  81. int   mouse_buttons;
  82. int   mouse_oldbuttonstate;
  83. int   mouse_buttonstate;
  84. float mouse_x, mouse_y;
  85. float old_mouse_x, old_mouse_y;
  86.  
  87.  
  88. cvar_t  in_joystick = {"joystick","1"};
  89. cvar_t  joy_numbuttons = {"joybuttons","4", true};
  90.  
  91. qboolean  joy_avail;
  92. int   joy_oldbuttonstate;
  93. int   joy_buttonstate;
  94.  
  95. int     joyxl, joyxh, joyyl, joyyh; 
  96. int   joystickx, joysticky;
  97.  
  98. qboolean    need_center;
  99.  
  100. qboolean    extern_avail;
  101. int       extern_buttons;
  102. int       extern_oldbuttonstate;
  103. int       extern_buttonstate;
  104. cvar_t  aux_look = {"auxlook","1", true};
  105. externControl_t *extern_control;
  106. void IN_StartupExternal (void);
  107. void IN_ExternalMove (usercmd_t *cmd);
  108.  
  109. void IN_StartupJoystick (void);
  110. qboolean IN_ReadJoystick (void);
  111.  
  112.  
  113. void Toggle_AuxLook_f (void)
  114. {
  115.   if (aux_look.value)
  116.     Cvar_Set ("auxlook","0");
  117.   else
  118.     Cvar_Set ("auxlook","1");
  119. }
  120.  
  121.  
  122. void Force_CenterView_f (void)
  123. {
  124.   cl.viewangles[PITCH] = 0;
  125. }
  126.  
  127.  
  128. /*
  129. ===========
  130. IN_StartupMouse
  131. ===========
  132. */
  133. void IN_StartupMouse (void)
  134. {
  135.   if ( COM_CheckParm ("-nomouse") ) 
  136.     return; 
  137.  
  138. // check for mouse
  139.   regs.x.ax = 0;
  140.   dos_int86(0x33);
  141.   mouse_avail = regs.x.ax;
  142.   if (!mouse_avail)
  143.   {
  144.     Con_Printf ("No mouse found\n");
  145.     return;
  146.   }
  147.   
  148.   mouse_buttons = regs.x.bx;
  149.   if (mouse_buttons > 3)
  150.     mouse_buttons = 3;
  151.   Con_Printf("%d-button mouse available\n", mouse_buttons);
  152. }
  153.  
  154. /*
  155. ===========
  156. IN_Init
  157. ===========
  158. */
  159. void IN_Init (void)
  160. {
  161.   int i;
  162.  
  163.   Cvar_RegisterVariable (&m_filter);
  164.   Cvar_RegisterVariable (&in_joystick);
  165.   Cvar_RegisterVariable (&joy_numbuttons);
  166.   Cvar_RegisterVariable (&aux_look);
  167.   Cmd_AddCommand ("toggle_auxlook", Toggle_AuxLook_f);
  168.   Cmd_AddCommand ("force_centerview", Force_CenterView_f);
  169.  
  170.   IN_StartupMouse ();
  171.   IN_StartupJoystick ();
  172.  
  173.   i = COM_CheckParm ("-control");
  174.   if (i)
  175.   {
  176.     extern_control = real2ptr(Q_atoi (com_argv[i+1]));
  177.     IN_StartupExternal ();
  178.   }
  179. }
  180.  
  181. /*
  182. ===========
  183. IN_Shutdown
  184. ===========
  185. */
  186. void IN_Shutdown (void)
  187. {
  188.  
  189. }
  190.  
  191.  
  192. /*
  193. ===========
  194. IN_Commands
  195. ===========
  196. */
  197. void IN_Commands (void)
  198. {
  199.   int   i;
  200.  
  201.   if (mouse_avail)
  202.   {
  203.     regs.x.ax = 3;    // read buttons
  204.     dos_int86(0x33);
  205.     mouse_buttonstate = regs.x.bx;
  206.   
  207.   // perform button actions
  208.     for (i=0 ; i<mouse_buttons ; i++)
  209.     {
  210.       if ( (mouse_buttonstate & (1<<i)) &&
  211.       !(mouse_oldbuttonstate & (1<<i)) )
  212.       {
  213.         Key_Event (K_MOUSE1 + i, true);
  214.       }
  215.       if ( !(mouse_buttonstate & (1<<i)) &&
  216.       (mouse_oldbuttonstate & (1<<i)) )
  217.       {
  218.         Key_Event (K_MOUSE1 + i, false);
  219.       }
  220.     } 
  221.     
  222.     mouse_oldbuttonstate = mouse_buttonstate;
  223.   }
  224.   
  225.   if (joy_avail)
  226.   {
  227.     joy_buttonstate = ((dos_inportb(0x201) >> 4)&15)^15;
  228.   // perform button actions
  229.     for (i=0 ; i<joy_numbuttons.value ; i++)
  230.     {
  231.       if ( (joy_buttonstate & (1<<i)) &&
  232.       !(joy_oldbuttonstate & (1<<i)) )
  233.       {
  234.         Key_Event (K_JOY1 + i, true);
  235.       }
  236.       if ( !(joy_buttonstate & (1<<i)) &&
  237.       (joy_oldbuttonstate & (1<<i)) )
  238.       {
  239.         Key_Event (K_JOY1 + i, false);
  240.       }
  241.     }
  242.     
  243.     joy_oldbuttonstate = joy_buttonstate;
  244.   }
  245.  
  246.   if (extern_avail)
  247.   {
  248.     extern_buttonstate = extern_control->buttons;
  249.   
  250.   // perform button actions
  251.     for (i=0 ; i<extern_buttons ; i++)
  252.     {
  253.       if ( (extern_buttonstate & (1<<i)) &&
  254.       !(extern_oldbuttonstate & (1<<i)) )
  255.       {
  256.         Key_Event (K_AUX1 + i, true);
  257.       }
  258.       if ( !(extern_buttonstate & (1<<i)) &&
  259.       (extern_oldbuttonstate & (1<<i)) )
  260.       {
  261.         Key_Event (K_AUX1 + i, false);
  262.       }
  263.     } 
  264.     
  265.     extern_oldbuttonstate = extern_buttonstate;
  266.   }
  267.   
  268. }
  269.  
  270.  
  271. /*
  272. ===========
  273. IN_Move
  274. ===========
  275. */
  276. void IN_MouseMove (usercmd_t *cmd)
  277. {
  278.   int   mx, my;
  279.  
  280.   if (!mouse_avail)
  281.     return;
  282.  
  283.   regs.x.ax = 11;   // read move
  284.   dos_int86(0x33);
  285.   mx = (short)regs.x.cx;
  286.   my = (short)regs.x.dx;
  287.   
  288.   if (m_filter.value)
  289.   {
  290.     mouse_x = (mx + old_mouse_x) * 0.5;
  291.     mouse_y = (my + old_mouse_y) * 0.5;
  292.   }
  293.   else
  294.   {
  295.     mouse_x = mx;
  296.     mouse_y = my;
  297.   }
  298.   old_mouse_x = mx;
  299.   old_mouse_y = my;
  300.  
  301.   mouse_x *= sensitivity.value;
  302.   mouse_y *= sensitivity.value;
  303.  
  304. // add mouse X/Y movement to cmd
  305.   if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
  306.     cmd->sidemove += m_side.value * mouse_x;
  307.   else
  308.     cl.viewangles[YAW] -= m_yaw.value * mouse_x;
  309.   
  310.   if (in_mlook.state & 1)
  311.     V_StopPitchDrift ();
  312.     
  313.   if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
  314.   {
  315.     cl.viewangles[PITCH] += m_pitch.value * mouse_y;
  316.     if (cl.viewangles[PITCH] > 80)
  317.       cl.viewangles[PITCH] = 80;
  318.     if (cl.viewangles[PITCH] < -70)
  319.       cl.viewangles[PITCH] = -70;
  320.   }
  321.   else
  322.   {
  323.     if ((in_strafe.state & 1) && noclip_anglehack)
  324.       cmd->upmove -= m_forward.value * mouse_y;
  325.     else
  326.       cmd->forwardmove -= m_forward.value * mouse_y;
  327.   }
  328. }
  329.  
  330. /*
  331. ===========
  332. IN_JoyMove
  333. ===========
  334. */
  335. void IN_JoyMove (usercmd_t *cmd)
  336. {
  337.   float speed, aspeed;
  338.  
  339.   if (!joy_avail || !in_joystick.value) 
  340.     return; 
  341.  
  342.   IN_ReadJoystick (); 
  343.   if (joysticky > joyyh*2 || joystickx > joyxh*2)
  344.     return;   // assume something jumped in and messed up the joystick
  345.           // reading time (win 95)
  346.  
  347.   if (in_speed.state & 1)
  348.     speed = cl_movespeedkey.value;
  349.   else
  350.     speed = 1;
  351.   aspeed = speed*host_frametime;
  352.  
  353.   if (in_strafe.state & 1)
  354.   {
  355.     if (joystickx < joyxl)
  356.       cmd->sidemove -= speed*cl_sidespeed.value; 
  357.     else if (joystickx > joyxh) 
  358.       cmd->sidemove += speed*cl_sidespeed.value; 
  359.   }
  360.   else
  361.   {
  362.     if (joystickx < joyxl)
  363.       cl.viewangles[YAW] += aspeed*cl_yawspeed.value;
  364.     else if (joystickx > joyxh) 
  365.       cl.viewangles[YAW] -= aspeed*cl_yawspeed.value;
  366.     cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]);
  367.   }
  368.  
  369.   if (in_mlook.state & 1)
  370.   {
  371.     if (m_pitch.value < 0)
  372.       speed *= -1;
  373.     
  374.     if (joysticky < joyyl) 
  375.       cl.viewangles[PITCH] += aspeed*cl_pitchspeed.value;
  376.     else if (joysticky > joyyh) 
  377.       cl.viewangles[PITCH] -= aspeed*cl_pitchspeed.value;
  378.   }
  379.   else
  380.   {
  381.     if (joysticky < joyyl) 
  382.       cmd->forwardmove += speed*cl_forwardspeed.value; 
  383.     else if (joysticky > joyyh) 
  384.       cmd->forwardmove -= speed*cl_backspeed.value;  
  385.   }
  386. }
  387.  
  388. /*
  389. ===========
  390. IN_Move
  391. ===========
  392. */
  393. void IN_Move (usercmd_t *cmd)
  394. {
  395.   IN_MouseMove (cmd);
  396.   IN_JoyMove (cmd);
  397.   IN_ExternalMove (cmd);
  398. }
  399.  
  400. /* 
  401. ============================================================================ 
  402.  
  403.           JOYSTICK 
  404.  
  405. ============================================================================ 
  406. */
  407.  
  408.  
  409.  
  410. qboolean IN_ReadJoystick (void)
  411. {
  412.   int   b;
  413.   int   count;
  414.  
  415.   joystickx = 0;
  416.   joysticky = 0;
  417.  
  418.   count = 0;
  419.  
  420.   b = dos_inportb(0x201);
  421.   dos_outportb(0x201, b);
  422.  
  423. // clear counters
  424.   while (++count < 10000)
  425.   {
  426.     b = dos_inportb(0x201);
  427.  
  428.     joystickx += b&1;
  429.     joysticky += (b&2)>>1;
  430.     if ( !(b&3) )
  431.       return true;
  432.   }
  433.   
  434.   Con_Printf ("IN_ReadJoystick: no response\n");
  435.   joy_avail = false;
  436.   return false;
  437. }
  438.  
  439. /*
  440. =============
  441. WaitJoyButton
  442. =============
  443. */
  444. qboolean WaitJoyButton (void) 
  445.   int             oldbuttons, buttons; 
  446.  
  447.   oldbuttons = 0; 
  448.   do 
  449.   {
  450.     key_count = -1;
  451.     Sys_SendKeyEvents ();
  452.     key_count = 0;
  453.     if (key_lastpress == K_ESCAPE)
  454.     {
  455.       Con_Printf ("aborted.\n");
  456.       return false;
  457.     }
  458.     key_lastpress = 0;
  459.     SCR_UpdateScreen ();
  460.     buttons =  ((dos_inportb(0x201) >> 4)&1)^1; 
  461.     if (buttons != oldbuttons) 
  462.     { 
  463.       oldbuttons = buttons; 
  464.       continue; 
  465.     }
  466.   } while ( !buttons); 
  467.  
  468.   do 
  469.   { 
  470.     key_count = -1;
  471.     Sys_SendKeyEvents ();
  472.     key_count = 0;
  473.     if (key_lastpress == K_ESCAPE)
  474.     {
  475.       Con_Printf ("aborted.\n");
  476.       return false;
  477.     }
  478.     key_lastpress = 0;
  479.     SCR_UpdateScreen ();
  480.     buttons =  ((dos_inportb(0x201) >> 4)&1)^1; 
  481.     if (buttons != oldbuttons) 
  482.     { 
  483.       oldbuttons = buttons; 
  484.       continue; 
  485.     } 
  486.   } while ( buttons); 
  487.  
  488.   return true; 
  489.  
  490.  
  491.  
  492. /* 
  493. =============== 
  494. IN_StartupJoystick 
  495. =============== 
  496. */  
  497. void IN_StartupJoystick (void) 
  498.   int     centerx, centery; 
  499.  
  500.   Con_Printf ("\n");
  501.  
  502.   joy_avail = false; 
  503.   if ( COM_CheckParm ("-nojoy") ) 
  504.     return; 
  505.  
  506.   if (!IN_ReadJoystick ()) 
  507.   { 
  508.     joy_avail = false; 
  509.     Con_Printf ("joystick not found\n"); 
  510.     return; 
  511.   } 
  512.  
  513.   Con_Printf ("joystick found\n"); 
  514.  
  515.   Con_Printf ("CENTER the joystick\nand press button 1 (ESC to skip):\n"); 
  516.   if (!WaitJoyButton ()) 
  517.     return; 
  518.   IN_ReadJoystick (); 
  519.   centerx = joystickx; 
  520.   centery = joysticky; 
  521.  
  522.   Con_Printf ("Push the joystick to the UPPER LEFT\nand press button 1 (ESC to skip):\n"); 
  523.   if (!WaitJoyButton ()) 
  524.     return; 
  525.   IN_ReadJoystick (); 
  526.   joyxl = (centerx + joystickx)/2; 
  527.   joyyl = (centerx + joysticky)/2; 
  528.  
  529.   Con_Printf ("Push the joystick to the LOWER RIGHT\nand press button 1 (ESC to skip):\n"); 
  530.   if (!WaitJoyButton ()) 
  531.     return; 
  532.   IN_ReadJoystick (); 
  533.   joyxh = (centerx + joystickx)/2; 
  534.   joyyh = (centery + joysticky)/2; 
  535.  
  536.   joy_avail = true; 
  537.   Con_Printf ("joystick configured.\n"); 
  538.  
  539.   Con_Printf ("\n");
  540.  
  541.  
  542. /* 
  543. ============================================================================ 
  544.  
  545.           EXTERNAL 
  546.  
  547. ============================================================================ 
  548. */
  549.  
  550.  
  551. /* 
  552. =============== 
  553. IN_StartupExternal 
  554. =============== 
  555. */  
  556. void IN_StartupExternal (void) 
  557.   if (extern_control->numButtons > 32)
  558.     extern_control->numButtons = 32;
  559.  
  560.   Con_Printf("%s Initialized\n", extern_control->deviceName);
  561.   Con_Printf("  %u axes  %u buttons\n", extern_control->numAxes, extern_control->numButtons);
  562.  
  563.   extern_avail = true;
  564.   extern_buttons = extern_control->numButtons;
  565. }
  566.  
  567.  
  568. /*
  569. ===========
  570. IN_ExternalMove
  571. ===========
  572. */
  573. void IN_ExternalMove (usercmd_t *cmd)
  574. {
  575.   qboolean freelook;
  576.  
  577.   if (! extern_avail)
  578.     return;
  579.  
  580.   extern_control->viewangles[YAW] = cl.viewangles[YAW];
  581.   extern_control->viewangles[PITCH] = cl.viewangles[PITCH];
  582.   extern_control->viewangles[ROLL] = cl.viewangles[ROLL];
  583.   extern_control->forwardmove = cmd->forwardmove;
  584.   extern_control->sidemove = cmd->sidemove;
  585.   extern_control->upmove = cmd->upmove;
  586.  
  587. Con_DPrintf("IN:  y:%f p:%f r:%f f:%f s:%f u:%f\n", extern_control->viewangles[YAW], extern_control->viewangles[PITCH], extern_control->viewangles[ROLL], extern_control->forwardmove, extern_control->sidemove, extern_control->upmove);
  588.  
  589.   dos_int86(extern_control->interruptVector);
  590.  
  591. Con_DPrintf("OUT: y:%f p:%f r:%f f:%f s:%f u:%f\n", extern_control->viewangles[YAW], extern_control->viewangles[PITCH], extern_control->viewangles[ROLL], extern_control->forwardmove, extern_control->sidemove, extern_control->upmove);
  592.  
  593.   cl.viewangles[YAW] = extern_control->viewangles[YAW];
  594.   cl.viewangles[PITCH] = extern_control->viewangles[PITCH];
  595.   cl.viewangles[ROLL] = extern_control->viewangles[ROLL];
  596.   cmd->forwardmove = extern_control->forwardmove;
  597.   cmd->sidemove = extern_control->sidemove;
  598.   cmd->upmove = extern_control->upmove;
  599.  
  600.   if (cl.viewangles[PITCH] > 80)
  601.     cl.viewangles[PITCH] = 80;
  602.   if (cl.viewangles[PITCH] < -70)
  603.     cl.viewangles[PITCH] = -70;
  604.  
  605.   freelook = (extern_control->flags & AUX_FLAG_FREELOOK || aux_look.value || in_mlook.state & 1);
  606.  
  607.   if (freelook)
  608.     V_StopPitchDrift ();
  609. }
  610.  
  611.