in_win.c

来自「quake1 dos源代码最新版本」· C语言 代码 · 共 1,284 行 · 第 1/2 页

C
1,284
字号
/*
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_win.c -- windows 95 mouse and joystick code
// 02/21/97 JCB Added extended DirectInput code to support external controllers.

#include <dinput.h>
#include "quakedef.h"
#include "winquake.h"
#include "dosisms.h"

#define DINPUT_BUFFERSIZE	16
#define iDirectInputCreate(a,b,c,d)	pDirectInputCreate(a,b,c,d)

HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion,
	LPDIRECTINPUT * lplpDirectInput, LPUNKNOWN punkOuter);

// mouse variables
cvar_t	*m_filter;

int			mouse_buttons;
int			mouse_oldbuttonstate;
POINT		current_pos;
int			mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum;

static qboolean	restore_spi;
static int		originalmouseparms[3], newmouseparms[3] = {0, 0, 1};

unsigned int uiWheelMessage;
qboolean	mouseactive;
qboolean		mouseinitialized;
static qboolean	mouseparmsvalid, mouseactivatetoggle;
static qboolean	mouseshowtoggle = 1;
static qboolean	dinput_acquired;

static unsigned int		mstate_di;

// joystick defines and variables
// where should defines be moved?
#define JOY_ABSOLUTE_AXIS	0x00000000		// control like a joystick
#define JOY_RELATIVE_AXIS	0x00000010		// control like a mouse, spinner, trackball
#define	JOY_MAX_AXES		6				// X, Y, Z, R, U, V
#define JOY_AXIS_X			0
#define JOY_AXIS_Y			1
#define JOY_AXIS_Z			2
#define JOY_AXIS_R			3
#define JOY_AXIS_U			4
#define JOY_AXIS_V			5

enum _ControlList
{
	AxisNada = 0, AxisForward, AxisLook, AxisSide, AxisTurn
};

DWORD	dwAxisFlags[JOY_MAX_AXES] =
{
	JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, JOY_RETURNR, JOY_RETURNU, JOY_RETURNV
};

DWORD	dwAxisMap[JOY_MAX_AXES];
DWORD	dwControlMap[JOY_MAX_AXES];
PDWORD	pdwRawValue[JOY_MAX_AXES];

// none of these cvars are saved over a session
// this means that advanced controller configuration needs to be executed
// each time.  this avoids any problems with getting back to a default usage
// or when changing from one controller to another.  this way at least something
// works.
cvar_t	*in_joystick;
cvar_t	*joy_name;
cvar_t	*joy_advanced;
cvar_t	*joy_advaxisx;
cvar_t	*joy_advaxisy;
cvar_t	*joy_advaxisz;
cvar_t	*joy_advaxisr;
cvar_t	*joy_advaxisu;
cvar_t	*joy_advaxisv;
cvar_t	*joy_forwardthreshold;
cvar_t	*joy_sidethreshold;
cvar_t	*joy_pitchthreshold;
cvar_t	*joy_yawthreshold;
cvar_t	*joy_forwardsensitivity;
cvar_t	*joy_sidesensitivity;
cvar_t	*joy_pitchsensitivity;
cvar_t	*joy_yawsensitivity;
cvar_t	*joy_wwhack1;
cvar_t	*joy_wwhack2;

qboolean	joy_avail, joy_advancedinit, joy_haspov;
DWORD		joy_oldbuttonstate, joy_oldpovstate;

int			joy_id;
DWORD		joy_flags;
DWORD		joy_numbuttons;

static LPDIRECTINPUT		g_pdi;
static LPDIRECTINPUTDEVICE	g_pMouse;

static JOYINFOEX	ji;

static HINSTANCE hInstDI;

static qboolean	dinput;

typedef struct MYDATA {
	LONG	lX;			// X axis goes here
	LONG	lY;			// Y axis goes here
	LONG	lZ;			// Z axis goes here
	BYTE	bButtonA;	// One button goes here
	BYTE	bButtonB;	// Another button goes here
	BYTE	bButtonC;	// Another button goes here
	BYTE	bButtonD;	// Another button goes here
} MYDATA;

static DIOBJECTDATAFORMAT rgodf[] = {
	{ &GUID_XAxis,    FIELD_OFFSET(MYDATA, lX),       DIDFT_AXIS | DIDFT_ANYINSTANCE,   0,},
	{ &GUID_YAxis,    FIELD_OFFSET(MYDATA, lY),       DIDFT_AXIS | DIDFT_ANYINSTANCE,   0,},
	{ &GUID_ZAxis,    FIELD_OFFSET(MYDATA, lZ),       0x80000000 | DIDFT_AXIS | DIDFT_ANYINSTANCE,   0,},
	{ 0,              FIELD_OFFSET(MYDATA, bButtonA), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
	{ 0,              FIELD_OFFSET(MYDATA, bButtonB), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
	{ 0,              FIELD_OFFSET(MYDATA, bButtonC), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
	{ 0,              FIELD_OFFSET(MYDATA, bButtonD), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
};

#define NUM_OBJECTS (sizeof(rgodf) / sizeof(rgodf[0]))

static DIDATAFORMAT	df = {
	sizeof(DIDATAFORMAT),		// this structure
	sizeof(DIOBJECTDATAFORMAT),	// size of object data format
	DIDF_RELAXIS,				// absolute axis coordinates
	sizeof(MYDATA),				// device data size
	NUM_OBJECTS,				// number of objects
	rgodf,						// and here they are
};

// forward-referenced functions
void IN_StartupJoystick (void);
void Joy_AdvancedUpdate_f (void);
void IN_JoyMove (usercmd_t *cmd);


/*
===========
Force_CenterView_f
===========
*/
void Force_CenterView_f (void)
{
	cl.viewangles[PITCH] = 0;
}


/*
===========
IN_UpdateClipCursor
===========
*/
void IN_UpdateClipCursor (void)
{

	if (mouseinitialized && mouseactive && !dinput)
	{
		ClipCursor (&window_rect);
	}
}


/*
===========
IN_ShowMouse
===========
*/
void IN_ShowMouse (void)
{

	if (!mouseshowtoggle)
	{
		ShowCursor (TRUE);
		mouseshowtoggle = 1;
	}
}


/*
===========
IN_HideMouse
===========
*/
void IN_HideMouse (void)
{

	if (mouseshowtoggle)
	{
		ShowCursor (FALSE);
		mouseshowtoggle = 0;
	}
}


/*
===========
IN_ActivateMouse
===========
*/
void IN_ActivateMouse (void)
{

	mouseactivatetoggle = true;

	if (mouseinitialized)
	{
		if (dinput)
		{
			if (g_pMouse)
			{
				if (!dinput_acquired)
				{
					IDirectInputDevice_Acquire(g_pMouse);
					dinput_acquired = true;
				}
			}
			else
			{
				return;
			}
		}
		else
		{
			if (mouseparmsvalid)
				restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0);

			SetCursorPos (window_center_x, window_center_y);
			SetCapture (mainwindow);
			ClipCursor (&window_rect);
		}

		mouseactive = true;
	}
}


/*
===========
IN_SetQuakeMouseState
===========
*/
void IN_SetQuakeMouseState (void)
{
	if (mouseactivatetoggle)
		IN_ActivateMouse ();
}


/*
===========
IN_DeactivateMouse
===========
*/
void IN_DeactivateMouse (void)
{

	mouseactivatetoggle = false;

	if (mouseinitialized)
	{
		if (dinput)
		{
			if (g_pMouse)
			{
				if (dinput_acquired)
				{
					IDirectInputDevice_Unacquire(g_pMouse);
					dinput_acquired = false;
				}
			}
		}
		else
		{
			if (restore_spi)
				SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0);

			ClipCursor (NULL);
			ReleaseCapture ();
		}

		mouseactive = false;
	}
}


/*
===========
IN_RestoreOriginalMouseState
===========
*/
void IN_RestoreOriginalMouseState (void)
{
	if (mouseactivatetoggle)
	{
		IN_DeactivateMouse ();
		mouseactivatetoggle = true;
	}

// try to redraw the cursor so it gets reinitialized, because sometimes it
// has garbage after the mode switch
	ShowCursor (TRUE);
	ShowCursor (FALSE);
}


/*
===========
IN_InitDInput
===========
*/
qboolean IN_InitDInput (void)
{
	HRESULT	hr;
	DIPROPDWORD	dipdw = {
		{
			sizeof(DIPROPDWORD),	// diph.dwSize
			sizeof(DIPROPHEADER),	// diph.dwHeaderSize
			0,						// diph.dwObj
			DIPH_DEVICE,			// diph.dwHow
		},
		DINPUT_BUFFERSIZE,			// dwData
	};

	if (!hInstDI)
	{
		hInstDI = LoadLibrary("dinput.dll");

		if (hInstDI == NULL)
		{
			Con_SafePrintf ("Couldn't load dinput.dll\n");
			return false;
		}
	}

	if (!pDirectInputCreate)
	{
		pDirectInputCreate = (void *)GetProcAddress(hInstDI,"DirectInputCreateA");

		if (!pDirectInputCreate)
		{
			Con_SafePrintf ("Couldn't get DI proc addr\n");
			return false;
		}
	}

// register with DirectInput and get an IDirectInput to play with.
	hr = iDirectInputCreate(global_hInstance, DIRECTINPUT_VERSION, &g_pdi, NULL);

	if (FAILED(hr))
	{
		return false;
	}

// obtain an interface to the system mouse device.
	hr = IDirectInput_CreateDevice(g_pdi, &GUID_SysMouse, &g_pMouse, NULL);

	if (FAILED(hr))
	{
		Con_SafePrintf ("Couldn't open DI mouse device\n");
		return false;
	}

// set the data format to "mouse format".
	hr = IDirectInputDevice_SetDataFormat(g_pMouse, &df);

	if (FAILED(hr))
	{
		Con_SafePrintf ("Couldn't set DI mouse format\n");
		return false;
	}

// set the cooperativity level.
	hr = IDirectInputDevice_SetCooperativeLevel(g_pMouse, mainwindow,
			DISCL_EXCLUSIVE | DISCL_FOREGROUND);

	if (FAILED(hr))
	{
		Con_SafePrintf ("Couldn't set DI coop level\n");
		return false;
	}


// set the buffer size to DINPUT_BUFFERSIZE elements.
// the buffer size is a DWORD property associated with the device
	hr = IDirectInputDevice_SetProperty(g_pMouse, DIPROP_BUFFERSIZE, &dipdw.diph);

	if (FAILED(hr))
	{
		Con_SafePrintf ("Couldn't set DI buffersize\n");
		return false;
	}

	return true;
}


/*
===========
IN_StartupMouse
===========
*/
void IN_StartupMouse (void)
{
	HDC			hdc;

	if ( COM_CheckParm ("-nomouse") )
		return;

	mouseinitialized = true;

	if (COM_CheckParm ("-dinput"))
	{
		dinput = IN_InitDInput ();

		if (dinput)
		{
			Con_SafePrintf ("DirectInput initialized\n");
		}
		else
		{
			Con_SafePrintf ("DirectInput not initialized\n");
		}
	}

	if (!dinput)
	{
		mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0);

		if (mouseparmsvalid)
		{
			if ( COM_CheckParm ("-noforcemspd") )
				newmouseparms[2] = originalmouseparms[2];

			if ( COM_CheckParm ("-noforcemaccel") )
			{
				newmouseparms[0] = originalmouseparms[0];
				newmouseparms[1] = originalmouseparms[1];
			}

			if ( COM_CheckParm ("-noforcemparms") )
			{
				newmouseparms[0] = originalmouseparms[0];
				newmouseparms[1] = originalmouseparms[1];
				newmouseparms[2] = originalmouseparms[2];
			}
		}
	}

	mouse_buttons = 3;

// if a fullscreen video mode was set before the mouse was initialized,
// set the mouse state appropriately
	if (mouseactivatetoggle)
		IN_ActivateMouse ();
}

// 2001-09-18 New cvar system by Maddes (Init)  start
/*
===========
IN_Init_Cvars
===========
*/
void IN_Init_Cvars (void)
{
	// mouse variables
	m_filter = Cvar_Get ("m_filter", "0", CVAR_ORIGINAL);

	// joystick variables
	in_joystick = Cvar_Get ("joystick", "0", CVAR_ARCHIVE|CVAR_ORIGINAL);
	joy_name = Cvar_Get ("joyname", "joystick", CVAR_ORIGINAL);
	joy_advanced = Cvar_Get ("joyadvanced", "0", CVAR_ORIGINAL);
	joy_advaxisx = Cvar_Get ("joyadvaxisx", "0", CVAR_ORIGINAL);
	joy_advaxisy = Cvar_Get ("joyadvaxisy", "0", CVAR_ORIGINAL);
	joy_advaxisz = Cvar_Get ("joyadvaxisz", "0", CVAR_ORIGINAL);
	joy_advaxisr = Cvar_Get ("joyadvaxisr", "0", CVAR_ORIGINAL);
	joy_advaxisu = Cvar_Get ("joyadvaxisu", "0", CVAR_ORIGINAL);
	joy_advaxisv = Cvar_Get ("joyadvaxisv", "0", CVAR_ORIGINAL);
	joy_forwardthreshold = Cvar_Get ("joyforwardthreshold", "0.15", CVAR_ORIGINAL);
	joy_sidethreshold = Cvar_Get ("joysidethreshold", "0.15", CVAR_ORIGINAL);
	joy_pitchthreshold = Cvar_Get ("joypitchthreshold", "0.15", CVAR_ORIGINAL);
	joy_yawthreshold = Cvar_Get ("joyyawthreshold", "0.15", CVAR_ORIGINAL);
	joy_forwardsensitivity = Cvar_Get ("joyforwardsensitivity", "-1", CVAR_ORIGINAL);
	joy_sidesensitivity = Cvar_Get ("joysidesensitivity", "-1", CVAR_ORIGINAL);
	joy_pitchsensitivity = Cvar_Get ("joypitchsensitivity", "1", CVAR_ORIGINAL);
	joy_yawsensitivity = Cvar_Get ("joyyawsensitivity", "-1", CVAR_ORIGINAL);
	joy_wwhack1 = Cvar_Get ("joywwhack1", "0", CVAR_ORIGINAL);
	joy_wwhack2 = Cvar_Get ("joywwhack2", "0", CVAR_ORIGINAL);
}
// 2001-09-18 New cvar system by Maddes (Init)  end

/*
===========
IN_Init
===========
*/
void IN_Init (void)
{
// 2001-09-18 New cvar system by Maddes (Init)  start
/*
	// mouse variables
	m_filter = Cvar_Get ("m_filter", "0", CVAR_ORIGINAL);

	// joystick variables
	in_joystick = Cvar_Get ("joystick", "0", CVAR_ARCHIVE|CVAR_ORIGINAL);
	joy_name = Cvar_Get ("joyname", "joystick", CVAR_ORIGINAL);
	joy_advanced = Cvar_Get ("joyadvanced", "0", CVAR_ORIGINAL);
	joy_advaxisx = Cvar_Get ("joyadvaxisx", "0", CVAR_ORIGINAL);
	joy_advaxisy = Cvar_Get ("joyadvaxisy", "0", CVAR_ORIGINAL);
	joy_advaxisz = Cvar_Get ("joyadvaxisz", "0", CVAR_ORIGINAL);
	joy_advaxisr = Cvar_Get ("joyadvaxisr", "0", CVAR_ORIGINAL);
	joy_advaxisu = Cvar_Get ("joyadvaxisu", "0", CVAR_ORIGINAL);
	joy_advaxisv = Cvar_Get ("joyadvaxisv", "0", CVAR_ORIGINAL);
	joy_forwardthreshold = Cvar_Get ("joyforwardthreshold", "0.15", CVAR_ORIGINAL);
	joy_sidethreshold = Cvar_Get ("joysidethreshold", "0.15", CVAR_ORIGINAL);
	joy_pitchthreshold = Cvar_Get ("joypitchthreshold", "0.15", CVAR_ORIGINAL);
	joy_yawthreshold = Cvar_Get ("joyyawthreshold", "0.15", CVAR_ORIGINAL);
	joy_forwardsensitivity = Cvar_Get ("joyforwardsensitivity", "-1", CVAR_ORIGINAL);
	joy_sidesensitivity = Cvar_Get ("joysidesensitivity", "-1", CVAR_ORIGINAL);
	joy_pitchsensitivity = Cvar_Get ("joypitchsensitivity", "1", CVAR_ORIGINAL);
	joy_yawsensitivity = Cvar_Get ("joyyawsensitivity", "-1", CVAR_ORIGINAL);
	joy_wwhack1 = Cvar_Get ("joywwhack1", "0", CVAR_ORIGINAL);
	joy_wwhack2 = Cvar_Get ("joywwhack2", "0", CVAR_ORIGINAL);
*/
// 2001-09-18 New cvar system by Maddes (Init)  end

	Cmd_AddCommand ("force_centerview", Force_CenterView_f);
	Cmd_AddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f);

	uiWheelMessage = RegisterWindowMessage ( "MSWHEEL_ROLLMSG" );

	IN_StartupMouse ();
	IN_StartupJoystick ();
}

/*
===========
IN_Shutdown
===========
*/
void IN_Shutdown (void)
{

	IN_DeactivateMouse ();
	IN_ShowMouse ();

	if (g_pMouse)
	{
		IDirectInputDevice_Release(g_pMouse);
		g_pMouse = NULL;
	}

	if (g_pdi)
	{
		IDirectInput_Release(g_pdi);
		g_pdi = NULL;
	}
}


/*
===========
IN_MouseEvent
===========
*/
void IN_MouseEvent (int mstate)
{
	int	i;

	if (mouseactive && !dinput)
	{
	// perform button actions
		for (i=0 ; i<mouse_buttons ; i++)
		{
			if ( (mstate & (1<<i)) &&
				!(mouse_oldbuttonstate & (1<<i)) )
			{
				Key_Event (K_MOUSE1 + i, true);
			}

			if ( !(mstate & (1<<i)) &&
				(mouse_oldbuttonstate & (1<<i)) )
			{
				Key_Event (K_MOUSE1 + i, false);
			}
		}

		mouse_oldbuttonstate = mstate;
	}
}


/*
===========
IN_MouseMove
===========
*/
void IN_MouseMove (usercmd_t *cmd)
{
	int					mx, my;
	HDC					hdc;
	int					i;
	DIDEVICEOBJECTDATA	od;
	DWORD				dwElements;
	HRESULT				hr;

	if (!mouseactive)
		return;

	if (dinput)
	{
		mx = 0;
		my = 0;

		for (;;)
		{
			dwElements = 1;

			hr = IDirectInputDevice_GetDeviceData(g_pMouse,
					sizeof(DIDEVICEOBJECTDATA), &od, &dwElements, 0);

			if ((hr == DIERR_INPUTLOST) || (hr == DIERR_NOTACQUIRED))

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?