diff options
Diffstat (limited to 'WinQuake/in_dos.c')
| -rw-r--r-- | WinQuake/in_dos.c | 615 |
1 files changed, 615 insertions, 0 deletions
diff --git a/WinQuake/in_dos.c b/WinQuake/in_dos.c new file mode 100644 index 0000000..fab89f4 --- /dev/null +++ b/WinQuake/in_dos.c @@ -0,0 +1,615 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// in_mouse.c -- dos mouse code + +#include "quakedef.h" +#include "dosisms.h" + +#define AUX_FLAG_FREELOOK 0x00000001 + +typedef struct +{ + long interruptVector; + char deviceName[16]; + long numAxes; + long numButtons; + long flags; + + vec3_t viewangles; + +// intended velocities + float forwardmove; + float sidemove; + float upmove; + + long buttons; +} externControl_t; + +/* +#define AUX_FLAG_FORCEFREELOOK 0x00000001 // r/o +#define AUX_FLAG_EXTENDED 0x00000002 // r/o +#define AUX_FLAG_RUN 0x00000004 // w/o +#define AUX_FLAG_STRAFE 0x00000008 // w/o +#define AUX_FLAG_FREELOOK 0x00000010 // w/o + +#define AUX_MAP_UNDEFINED 0 +#define AUX_MAP_PITCH 1 +#define AUX_MAP_YAW 2 +#define AUX_MAP_ROLL 3 +#define AUX_MAP_FORWARD 4 +#define AUX_MAP_SIDE 5 +#define AUX_MAP_UP 6 + +typedef struct +{ + long interruptVector; + // r/o + char deviceName[16]; + // r/o + long numAxes; + // r/o 1-6 + long numButtons; // r/o 0-32 + long flags; // see above + byte axisMapping[6]; // w/o default = p,y,r,f,s,u + float axisValue[6]; // r/w + float sensitivity[6]; // w/o default = 1.0 + long buttons; // r/o + float last_frame_time; // w/o +} externControl_t; +*/ + +cvar_t m_filter = {"m_filter","1"}; + +qboolean mouse_avail; +int mouse_buttons; +int mouse_oldbuttonstate; +int mouse_buttonstate; +float mouse_x, mouse_y; +float old_mouse_x, old_mouse_y; + + +cvar_t in_joystick = {"joystick","1"}; +cvar_t joy_numbuttons = {"joybuttons","4", true}; + +qboolean joy_avail; +int joy_oldbuttonstate; +int joy_buttonstate; + +int joyxl, joyxh, joyyl, joyyh; +int joystickx, joysticky; + +qboolean need_center; + +qboolean extern_avail; +int extern_buttons; +int extern_oldbuttonstate; +int extern_buttonstate; +cvar_t aux_look = {"auxlook","1", true}; +externControl_t *extern_control; +void IN_StartupExternal (void); +void IN_ExternalMove (usercmd_t *cmd); + +void IN_StartupJoystick (void); +qboolean IN_ReadJoystick (void); + + +void Toggle_AuxLook_f (void) +{ + if (aux_look.value) + Cvar_Set ("auxlook","0"); + else + Cvar_Set ("auxlook","1"); +} + + +void Force_CenterView_f (void) +{ + cl.viewangles[PITCH] = 0; +} + + +/* +=========== +IN_StartupMouse +=========== +*/ +void IN_StartupMouse (void) +{ + if ( COM_CheckParm ("-nomouse") ) + return; + +// check for mouse + regs.x.ax = 0; + dos_int86(0x33); + mouse_avail = regs.x.ax; + if (!mouse_avail) + { + Con_Printf ("No mouse found\n"); + return; + } + + mouse_buttons = regs.x.bx; + if (mouse_buttons > 3) + mouse_buttons = 3; + Con_Printf("%d-button mouse available\n", mouse_buttons); +} + +/* +=========== +IN_Init +=========== +*/ +void IN_Init (void) +{ + int i; + + Cvar_RegisterVariable (&m_filter); + Cvar_RegisterVariable (&in_joystick); + Cvar_RegisterVariable (&joy_numbuttons); + Cvar_RegisterVariable (&aux_look); + Cmd_AddCommand ("toggle_auxlook", Toggle_AuxLook_f); + Cmd_AddCommand ("force_centerview", Force_CenterView_f); + + IN_StartupMouse (); + IN_StartupJoystick (); + + i = COM_CheckParm ("-control"); + if (i) + { + extern_control = real2ptr(Q_atoi (com_argv[i+1])); + IN_StartupExternal (); + } +} + +/* +=========== +IN_Shutdown +=========== +*/ +void IN_Shutdown (void) +{ + +} + + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ + int i; + + if (mouse_avail) + { + regs.x.ax = 3; // read buttons + dos_int86(0x33); + mouse_buttonstate = regs.x.bx; + + // perform button actions + for (i=0 ; i<mouse_buttons ; i++) + { + if ( (mouse_buttonstate & (1<<i)) && + !(mouse_oldbuttonstate & (1<<i)) ) + { + Key_Event (K_MOUSE1 + i, true); + } + if ( !(mouse_buttonstate & (1<<i)) && + (mouse_oldbuttonstate & (1<<i)) ) + { + Key_Event (K_MOUSE1 + i, false); + } + } + + mouse_oldbuttonstate = mouse_buttonstate; + } + + if (joy_avail) + { + joy_buttonstate = ((dos_inportb(0x201) >> 4)&15)^15; + // perform button actions + for (i=0 ; i<joy_numbuttons.value ; i++) + { + if ( (joy_buttonstate & (1<<i)) && + !(joy_oldbuttonstate & (1<<i)) ) + { + Key_Event (K_JOY1 + i, true); + } + if ( !(joy_buttonstate & (1<<i)) && + (joy_oldbuttonstate & (1<<i)) ) + { + Key_Event (K_JOY1 + i, false); + } + } + + joy_oldbuttonstate = joy_buttonstate; + } + + if (extern_avail) + { + extern_buttonstate = extern_control->buttons; + + // perform button actions + for (i=0 ; i<extern_buttons ; i++) + { + if ( (extern_buttonstate & (1<<i)) && + !(extern_oldbuttonstate & (1<<i)) ) + { + Key_Event (K_AUX1 + i, true); + } + if ( !(extern_buttonstate & (1<<i)) && + (extern_oldbuttonstate & (1<<i)) ) + { + Key_Event (K_AUX1 + i, false); + } + } + + extern_oldbuttonstate = extern_buttonstate; + } + +} + + +/* +=========== +IN_Move +=========== +*/ +void IN_MouseMove (usercmd_t *cmd) +{ + int mx, my; + + if (!mouse_avail) + return; + + regs.x.ax = 11; // read move + dos_int86(0x33); + mx = (short)regs.x.cx; + my = (short)regs.x.dx; + + if (m_filter.value) + { + mouse_x = (mx + old_mouse_x) * 0.5; + mouse_y = (my + old_mouse_y) * 0.5; + } + else + { + mouse_x = mx; + mouse_y = my; + } + old_mouse_x = mx; + old_mouse_y = my; + + mouse_x *= sensitivity.value; + mouse_y *= sensitivity.value; + +// add mouse X/Y movement to cmd + if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) + cmd->sidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + cl.viewangles[PITCH] += m_pitch.value * mouse_y; + if (cl.viewangles[PITCH] > 80) + cl.viewangles[PITCH] = 80; + if (cl.viewangles[PITCH] < -70) + cl.viewangles[PITCH] = -70; + } + else + { + if ((in_strafe.state & 1) && noclip_anglehack) + cmd->upmove -= m_forward.value * mouse_y; + else + cmd->forwardmove -= m_forward.value * mouse_y; + } +} + +/* +=========== +IN_JoyMove +=========== +*/ +void IN_JoyMove (usercmd_t *cmd) +{ + float speed, aspeed; + + if (!joy_avail || !in_joystick.value) + return; + + IN_ReadJoystick (); + if (joysticky > joyyh*2 || joystickx > joyxh*2) + return; // assume something jumped in and messed up the joystick + // reading time (win 95) + + if (in_speed.state & 1) + speed = cl_movespeedkey.value; + else + speed = 1; + aspeed = speed*host_frametime; + + if (in_strafe.state & 1) + { + if (joystickx < joyxl) + cmd->sidemove -= speed*cl_sidespeed.value; + else if (joystickx > joyxh) + cmd->sidemove += speed*cl_sidespeed.value; + } + else + { + if (joystickx < joyxl) + cl.viewangles[YAW] += aspeed*cl_yawspeed.value; + else if (joystickx > joyxh) + cl.viewangles[YAW] -= aspeed*cl_yawspeed.value; + cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]); + } + + if (in_mlook.state & 1) + { + if (m_pitch.value < 0) + speed *= -1; + + if (joysticky < joyyl) + cl.viewangles[PITCH] += aspeed*cl_pitchspeed.value; + else if (joysticky > joyyh) + cl.viewangles[PITCH] -= aspeed*cl_pitchspeed.value; + } + else + { + if (joysticky < joyyl) + cmd->forwardmove += speed*cl_forwardspeed.value; + else if (joysticky > joyyh) + cmd->forwardmove -= speed*cl_backspeed.value; + } +} + +/* +=========== +IN_Move +=========== +*/ +void IN_Move (usercmd_t *cmd) +{ + IN_MouseMove (cmd); + IN_JoyMove (cmd); + IN_ExternalMove (cmd); +} + +/* +============================================================================ + + JOYSTICK + +============================================================================ +*/ + + + +qboolean IN_ReadJoystick (void) +{ + int b; + int count; + + joystickx = 0; + joysticky = 0; + + count = 0; + + b = dos_inportb(0x201); + dos_outportb(0x201, b); + +// clear counters + while (++count < 10000) + { + b = dos_inportb(0x201); + + joystickx += b&1; + joysticky += (b&2)>>1; + if ( !(b&3) ) + return true; + } + + Con_Printf ("IN_ReadJoystick: no response\n"); + joy_avail = false; + return false; +} + +/* +============= +WaitJoyButton +============= +*/ +qboolean WaitJoyButton (void) +{ + int oldbuttons, buttons; + + oldbuttons = 0; + do + { + key_count = -1; + Sys_SendKeyEvents (); + key_count = 0; + if (key_lastpress == K_ESCAPE) + { + Con_Printf ("aborted.\n"); + return false; + } + key_lastpress = 0; + SCR_UpdateScreen (); + buttons = ((dos_inportb(0x201) >> 4)&1)^1; + if (buttons != oldbuttons) + { + oldbuttons = buttons; + continue; + } + } while ( !buttons); + + do + { + key_count = -1; + Sys_SendKeyEvents (); + key_count = 0; + if (key_lastpress == K_ESCAPE) + { + Con_Printf ("aborted.\n"); + return false; + } + key_lastpress = 0; + SCR_UpdateScreen (); + buttons = ((dos_inportb(0x201) >> 4)&1)^1; + if (buttons != oldbuttons) + { + oldbuttons = buttons; + continue; + } + } while ( buttons); + + return true; +} + + + +/* +=============== +IN_StartupJoystick +=============== +*/ +void IN_StartupJoystick (void) +{ + int centerx, centery; + + Con_Printf ("\n"); + + joy_avail = false; + if ( COM_CheckParm ("-nojoy") ) + return; + + if (!IN_ReadJoystick ()) + { + joy_avail = false; + Con_Printf ("joystick not found\n"); + return; + } + + Con_Printf ("joystick found\n"); + + Con_Printf ("CENTER the joystick\nand press button 1 (ESC to skip):\n"); + if (!WaitJoyButton ()) + return; + IN_ReadJoystick (); + centerx = joystickx; + centery = joysticky; + + Con_Printf ("Push the joystick to the UPPER LEFT\nand press button 1 (ESC to skip):\n"); + if (!WaitJoyButton ()) + return; + IN_ReadJoystick (); + joyxl = (centerx + joystickx)/2; + joyyl = (centerx + joysticky)/2; + + Con_Printf ("Push the joystick to the LOWER RIGHT\nand press button 1 (ESC to skip):\n"); + if (!WaitJoyButton ()) + return; + IN_ReadJoystick (); + joyxh = (centerx + joystickx)/2; + joyyh = (centery + joysticky)/2; + + joy_avail = true; + Con_Printf ("joystick configured.\n"); + + Con_Printf ("\n"); +} + + +/* +============================================================================ + + EXTERNAL + +============================================================================ +*/ + + +/* +=============== +IN_StartupExternal +=============== +*/ +void IN_StartupExternal (void) +{ + if (extern_control->numButtons > 32) + extern_control->numButtons = 32; + + Con_Printf("%s Initialized\n", extern_control->deviceName); + Con_Printf(" %u axes %u buttons\n", extern_control->numAxes, extern_control->numButtons); + + extern_avail = true; + extern_buttons = extern_control->numButtons; +} + + +/* +=========== +IN_ExternalMove +=========== +*/ +void IN_ExternalMove (usercmd_t *cmd) +{ + qboolean freelook; + + if (! extern_avail) + return; + + extern_control->viewangles[YAW] = cl.viewangles[YAW]; + extern_control->viewangles[PITCH] = cl.viewangles[PITCH]; + extern_control->viewangles[ROLL] = cl.viewangles[ROLL]; + extern_control->forwardmove = cmd->forwardmove; + extern_control->sidemove = cmd->sidemove; + extern_control->upmove = cmd->upmove; + +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); + + dos_int86(extern_control->interruptVector); + +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); + + cl.viewangles[YAW] = extern_control->viewangles[YAW]; + cl.viewangles[PITCH] = extern_control->viewangles[PITCH]; + cl.viewangles[ROLL] = extern_control->viewangles[ROLL]; + cmd->forwardmove = extern_control->forwardmove; + cmd->sidemove = extern_control->sidemove; + cmd->upmove = extern_control->upmove; + + if (cl.viewangles[PITCH] > 80) + cl.viewangles[PITCH] = 80; + if (cl.viewangles[PITCH] < -70) + cl.viewangles[PITCH] = -70; + + freelook = (extern_control->flags & AUX_FLAG_FREELOOK || aux_look.value || in_mlook.state & 1); + + if (freelook) + V_StopPitchDrift (); +} + |
