Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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. {
  446.         int             oldbuttons, buttons;
  447.  
  448.         oldbuttons = 0;
  449.         do
  450.         {
  451.                 key_count = -1;
  452.                 Sys_SendKeyEvents ();
  453.                 key_count = 0;
  454.                 if (key_lastpress == K_ESCAPE)
  455.                 {
  456.                         Con_Printf ("aborted.\n");
  457.                         return false;
  458.                 }
  459.                 key_lastpress = 0;
  460.                 SCR_UpdateScreen ();
  461.                 buttons =  ((dos_inportb(0x201) >> 4)&1)^1;
  462.                 if (buttons != oldbuttons)
  463.                 {
  464.                         oldbuttons = buttons;
  465.                         continue;
  466.                 }
  467.         } while ( !buttons);
  468.  
  469.         do
  470.         {
  471.                 key_count = -1;
  472.                 Sys_SendKeyEvents ();
  473.                 key_count = 0;
  474.                 if (key_lastpress == K_ESCAPE)
  475.                 {
  476.                         Con_Printf ("aborted.\n");
  477.                         return false;
  478.                 }
  479.                 key_lastpress = 0;
  480.                 SCR_UpdateScreen ();
  481.                 buttons =  ((dos_inportb(0x201) >> 4)&1)^1;
  482.                 if (buttons != oldbuttons)
  483.                 {
  484.                         oldbuttons = buttons;
  485.                         continue;
  486.                 }
  487.         } while ( buttons);
  488.  
  489.         return true;
  490. }
  491.  
  492.  
  493.  
  494. /*
  495. ===============
  496. IN_StartupJoystick
  497. ===============
  498. */  
  499. void IN_StartupJoystick (void)
  500. {
  501.         int     centerx, centery;
  502.  
  503.         Con_Printf ("\n");
  504.  
  505.         joy_avail = false;
  506.         if ( COM_CheckParm ("-nojoy") )
  507.                 return;
  508.  
  509.         if (!IN_ReadJoystick ())
  510.         {
  511.                 joy_avail = false;
  512.                 Con_Printf ("joystick not found\n");
  513.                 return;
  514.         }
  515.  
  516.         Con_Printf ("joystick found\n");
  517.  
  518.         Con_Printf ("CENTER the joystick\nand press button 1 (ESC to skip):\n");
  519.         if (!WaitJoyButton ())
  520.                 return;
  521.         IN_ReadJoystick ();
  522.         centerx = joystickx;
  523.         centery = joysticky;
  524.  
  525.         Con_Printf ("Push the joystick to the UPPER LEFT\nand press button 1 (ESC to skip):\n");
  526.         if (!WaitJoyButton ())
  527.                 return;
  528.         IN_ReadJoystick ();
  529.         joyxl = (centerx + joystickx)/2;
  530.         joyyl = (centerx + joysticky)/2;
  531.  
  532.         Con_Printf ("Push the joystick to the LOWER RIGHT\nand press button 1 (ESC to skip):\n");
  533.         if (!WaitJoyButton ())
  534.                 return;
  535.         IN_ReadJoystick ();
  536.         joyxh = (centerx + joystickx)/2;
  537.         joyyh = (centery + joysticky)/2;
  538.  
  539.         joy_avail = true;
  540.         Con_Printf ("joystick configured.\n");
  541.  
  542.         Con_Printf ("\n");
  543. }
  544.  
  545.  
  546. /*
  547. ============================================================================
  548.  
  549.                                         EXTERNAL
  550.  
  551. ============================================================================
  552. */
  553.  
  554.  
  555. /*
  556. ===============
  557. IN_StartupExternal
  558. ===============
  559. */  
  560. void IN_StartupExternal (void)
  561. {
  562.         if (extern_control->numButtons > 32)
  563.                 extern_control->numButtons = 32;
  564.  
  565.         Con_Printf("%s Initialized\n", extern_control->deviceName);
  566.         Con_Printf("  %u axes  %u buttons\n", extern_control->numAxes, extern_control->numButtons);
  567.  
  568.         extern_avail = true;
  569.         extern_buttons = extern_control->numButtons;
  570. }
  571.  
  572.  
  573. /*
  574. ===========
  575. IN_ExternalMove
  576. ===========
  577. */
  578. void IN_ExternalMove (usercmd_t *cmd)
  579. {
  580.         qboolean freelook;
  581.  
  582.         if (! extern_avail)
  583.                 return;
  584.  
  585.         extern_control->viewangles[YAW] = cl.viewangles[YAW];
  586.         extern_control->viewangles[PITCH] = cl.viewangles[PITCH];
  587.         extern_control->viewangles[ROLL] = cl.viewangles[ROLL];
  588.         extern_control->forwardmove = cmd->forwardmove;
  589.         extern_control->sidemove = cmd->sidemove;
  590.         extern_control->upmove = cmd->upmove;
  591.  
  592. 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);
  593.  
  594.         dos_int86(extern_control->interruptVector);
  595.  
  596. 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);
  597.  
  598.         cl.viewangles[YAW] = extern_control->viewangles[YAW];
  599.         cl.viewangles[PITCH] = extern_control->viewangles[PITCH];
  600.         cl.viewangles[ROLL] = extern_control->viewangles[ROLL];
  601.         cmd->forwardmove = extern_control->forwardmove;
  602.         cmd->sidemove = extern_control->sidemove;
  603.         cmd->upmove = extern_control->upmove;
  604.  
  605.         if (cl.viewangles[PITCH] > 80)
  606.                 cl.viewangles[PITCH] = 80;
  607.         if (cl.viewangles[PITCH] < -70)
  608.                 cl.viewangles[PITCH] = -70;
  609.  
  610.         freelook = (extern_control->flags & AUX_FLAG_FREELOOK || aux_look.value || in_mlook.state & 1);
  611.  
  612.         if (freelook)
  613.                 V_StopPitchDrift ();
  614. }
  615.  
  616.