From 0a25f2084f15b2bf8613c3f2248b3a74eb87f8cb Mon Sep 17 00:00:00 2001 From: TimeServ Date: Wed, 29 Jun 2005 21:20:34 +0000 Subject: [PATCH] Windows XP raw input support (should fix rid#1217412?) enhanced con_ocranaleds git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1120 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_main.c | 12 +- engine/client/image.c | 20 +- engine/client/in_raw.h | 119 +++++++++++ engine/client/in_win.c | 433 ++++++++++++++++++++++++++++++++++++++- engine/client/winquake.h | 1 + engine/gl/gl_draw.c | 18 +- engine/gl/gl_vidnt.c | 8 + engine/sw/sw_draw.c | 1 + engine/sw/vid_win2.c | 8 + 9 files changed, 592 insertions(+), 28 deletions(-) create mode 100644 engine/client/in_raw.h diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 3571bae4e..95c7a7326 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -401,10 +401,10 @@ void CL_SendConnectPacket ( clients = 1; if (cl_splitscreen.value) { - if (adr.type == NA_LOOPBACK) +// if (adr.type == NA_LOOPBACK) clients = cl_splitscreen.value+1; - else - Con_Printf("Split screens are still under development\n"); +// else +// Con_Printf("Split screens are still under development\n"); } if (clients < 1) @@ -3006,11 +3006,11 @@ void Host_Init (quakeparms_t *parms) idroq_depth = COM_FDepthFile("video/idlogo.roq", true); //q2 ol_depth = COM_FDepthFile("video/openinglogos.roq", true); //jk2 - if (ol_depth <= idroq_depth || ol_depth <= idcin_depth) + if (ol_depth != 0x7fffffff && (ol_depth <= idroq_depth || ol_depth <= idcin_depth)) Media_PlayFilm("video/openinglogos.roq"); - else if (idroq_depth <= idcin_depth) + else if (idroq_depth != 0x7fffffff && idroq_depth <= idcin_depth) Media_PlayFilm("video/idlogo.roq"); - else if (idcin_depth) + else if (idcin_depth != 0x7fffffff) Media_PlayFilm("video/idlog.cin"); } #endif diff --git a/engine/client/image.c b/engine/client/image.c index eb3fcb9e7..582386882 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -1896,9 +1896,12 @@ void AddOcranaLEDsIndexed (qbyte *image, int h, int w) int i, idx, x, y, rs; int r, g, b, rd, gd, bd; + // calc row size, character size rs = w; h /= 16; w /= 16; + + // generate palettes for (i = 0; i < 4; i++) { // get palette @@ -1917,14 +1920,25 @@ void AddOcranaLEDsIndexed (qbyte *image, int h, int w) } // generate LED into image + b = (w * w + h * h) / 16; + if (b < 1) + b = 1; + rd = w + 1; + gd = h + 1; + point = image + (8 * rs * h) + ((6 + i) * w); for (y = 1; y <= h; y++) { for (x = 1; x <= w; x++) { - idx = (8 * x * y) / ((w - 1) * (h - 1)); - idx = bound(0, idx, 7); - *point++ = tridx[idx]; + r = rd - (x*2); r *= r; + g = gd - (y*2); g *= g; + idx = (r + g) / b; + + if (idx > 7) + *point++ = 0; + else + *point++ = tridx[idx]; } point += rs - w; } diff --git a/engine/client/in_raw.h b/engine/client/in_raw.h new file mode 100644 index 000000000..e8862d1fe --- /dev/null +++ b/engine/client/in_raw.h @@ -0,0 +1,119 @@ +// Raw input includes + +#ifndef RIM_TYPEMOUSE +#define WM_INPUT 255 + +#undef QS_INPUT +#define QS_RAWINPUT 1024 +#define QS_INPUT 1031 + +#define RIM_INPUT 0x00000000 +#define RIM_INPUTSINK 0x00000001 +#define RIM_TYPEMOUSE 0x00000000 +#define RIM_TYPEKEYBOARD 0x00000001 +#define RIM_TYPEHID 0x00000002 +#define MOUSE_MOVE_RELATIVE 0x00000000 +#define MOUSE_MOVE_ABSOLUTE 0x00000001 +#define MOUSE_VIRTUAL_DESKTOP 0x00000002 +#define MOUSE_ATTRIBUTES_CHANGED 0x00000004 +#define RI_MOUSE_LEFT_BUTTON_DOWN 0x0001 +#define RI_MOUSE_LEFT_BUTTON_UP 0x0002 +#define RI_MOUSE_RIGHT_BUTTON_DOWN 0x0004 +#define RI_MOUSE_RIGHT_BUTTON_UP 0x0008 +#define RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010 +#define RI_MOUSE_MIDDLE_BUTTON_UP 0x0020 +#define RI_MOUSE_BUTTON_1_DOWN RI_MOUSE_LEFT_BUTTON_DOWN +#define RI_MOUSE_BUTTON_1_UP RI_MOUSE_LEFT_BUTTON_UP +#define RI_MOUSE_BUTTON_2_DOWN RI_MOUSE_RIGHT_BUTTON_DOWN +#define RI_MOUSE_BUTTON_2_UP RI_MOUSE_RIGHT_BUTTON_UP +#define RI_MOUSE_BUTTON_3_DOWN RI_MOUSE_MIDDLE_BUTTON_DOWN +#define RI_MOUSE_BUTTON_3_UP RI_MOUSE_MIDDLE_BUTTON_UP +#define RI_MOUSE_BUTTON_4_DOWN 0x0040 +#define RI_MOUSE_BUTTON_4_UP 0x0080 +#define RI_MOUSE_BUTTON_5_DOWN 0x0100 +#define RI_MOUSE_BUTTON_5_UP 0x0200 +#define RI_MOUSE_WHEEL 0x0400 +#define KEYBOARD_OVERRUN_MAKE_CODE 0x00ff +#define RI_KEY_MAKE 0x0000 +#define RI_KEY_BREAK 0x0001 +#define RI_KEY_E0 0x0002 +#define RI_KEY_E1 0x0004 +#define RI_KEY_TERMSRV_SET_LED 0x0008 +#define RI_KEY_TERMSRV_SHADOW 0x0010 +#define RID_INPUT 0x10000003 +#define RID_HEADER 0x10000005 +#define RIDI_PREPARSEDDATA 0x20000005 +#define RIDI_DEVICENAME 0x20000007 +#define RIDI_DEVICEINFO 0x2000000b +#define RIDEV_REMOVE 0x00000001 +#define RIDEV_EXCLUDE 0x00000010 +#define RIDEV_PAGEONLY 0x00000020 +#define RIDEV_NOLEGACY 0x00000030 +#define RIDEV_INPUTSINK 0x00000100 +#define RIDEV_CAPTUREMOUSE 0x00000200 +#define RIDEV_NOHOTKEYS 0x00000200 +#define RIDEV_APPKEYS 0x00000400 + +DECLARE_HANDLE(HRAWINPUT); +typedef struct tagRAWINPUTHEADER { + DWORD dwType; + DWORD dwSize; + HANDLE hDevice; + WPARAM wParam; +} RAWINPUTHEADER,*PRAWINPUTHEADER; +typedef struct tagRAWMOUSE { + USHORT usFlags; + union { + ULONG ulButtons; + struct { + USHORT usButtonFlags; + USHORT usButtonData; + }; + }; + ULONG ulRawButtons; + LONG lLastX; + LONG lLastY; + ULONG ulExtraInformation; +} RAWMOUSE,*PRAWMOUSE,*LPRAWMOUSE; +typedef struct tagRAWKEYBOARD { + USHORT MakeCode; + USHORT Flags; + USHORT Reserved; + USHORT VKey; + UINT Message; + ULONG ExtraInformation; +} RAWKEYBOARD,*PRAWKEYBOARD,*LPRAWKEYBOARD; +typedef struct tagRAWHID { + DWORD dwSizeHid; + DWORD dwCount; + BYTE bRawData; +} RAWHID,*PRAWHID,*LPRAWHID; +typedef struct tagRAWINPUT { + RAWINPUTHEADER header; + union { + RAWMOUSE mouse; + RAWKEYBOARD keyboard; + RAWHID hid; + } data; +} RAWINPUT,*PRAWINPUT,*LPRAWINPUT; +typedef struct tagRAWINPUTDEVICE { + USHORT usUsagePage; + USHORT usUsage; + DWORD dwFlags; + HWND hwndTarget; +} RAWINPUTDEVICE,*PRAWINPUTDEVICE,*LPRAWINPUTDEVICE; +typedef const RAWINPUTDEVICE *PCRAWINPUTDEVICE; +typedef struct tagRAWINPUTDEVICELIST { + HANDLE hDevice; + DWORD dwType; +} RAWINPUTDEVICELIST,*PRAWINPUTDEVICELIST; + +WINUSERAPI LRESULT WINAPI DefRawInputProc(PRAWINPUT*,INT,UINT); +WINUSERAPI UINT WINAPI GetRawInputBuffer(PRAWINPUT,PUINT,UINT); +WINUSERAPI UINT WINAPI GetRawInputData(HRAWINPUT,UINT,LPVOID,PUINT,UINT); +WINUSERAPI UINT WINAPI GetRawInputDeviceInfoA(HANDLE,UINT,LPVOID,PUINT); +WINUSERAPI UINT WINAPI GetRawInputDeviceInfoW(HANDLE,UINT,LPVOID,PUINT); +WINUSERAPI UINT WINAPI GetRawInputDeviceList(PRAWINPUTDEVICELIST,PUINT,UINT); +WINUSERAPI UINT WINAPI GetRegisteredRawInputDevices(PRAWINPUTDEVICE,PUINT,UINT); +WINUSERAPI BOOL WINAPI RegisterRawInputDevices(PCRAWINPUTDEVICE,UINT,UINT); +#endif \ No newline at end of file diff --git a/engine/client/in_win.c b/engine/client/in_win.c index 375b6dac0..f9f210f9c 100644 --- a/engine/client/in_win.c +++ b/engine/client/in_win.c @@ -24,6 +24,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "winquake.h" //#include "dosisms.h" +#define USINGRAWINPUT + +#ifdef USINGRAWINPUT +#include "in_raw.h" +#endif + #ifndef NODIRECTX #include @@ -51,9 +57,14 @@ cvar_t in_dinput = {"in_dinput","0", NULL, CVAR_ARCHIVE}; cvar_t cl_keypad = {"cl_keypad", "0"}; typedef struct { - HANDLE comhandle; - HANDLE threadhandle; - DWORD threadid; + union { + struct { // serial mouse + HANDLE comhandle; + HANDLE threadhandle; + DWORD threadid; + }; + HANDLE rawinputhandle; // raw input + }; int numbuttons; @@ -220,6 +231,37 @@ static HRESULT (WINAPI *pDirectInputCreateEx)(HINSTANCE hinst, static JOYINFOEX ji; +// raw input specific defines +#ifdef USINGRAWINPUT +// defines +#define MAX_RI_DEVICE_SIZE 128 +#define INIT_RIBUFFER_SIZE (sizeof(RAWINPUTHEADER)+sizeof(RAWMOUSE)) + +#define RI_RAWBUTTON_MASK 0x000003E0 +#define RI_INVALID_POS 0x80000000 + +// raw input dynamic functions +typedef WINUSERAPI INT (WINAPI *pGetRawInputDeviceList)(OUT PRAWINPUTDEVICELIST pRawInputDeviceList, IN OUT PINT puiNumDevices, IN UINT cbSize); +typedef WINUSERAPI INT(WINAPI *pGetRawInputData)(IN HRAWINPUT hRawInput, IN UINT uiCommand, OUT LPVOID pData, IN OUT PINT pcbSize, IN UINT cbSizeHeader); +typedef WINUSERAPI INT(WINAPI *pGetRawInputDeviceInfoA)(IN HANDLE hDevice, IN UINT uiCommand, OUT LPVOID pData, IN OUT PINT pcbSize); +typedef WINUSERAPI BOOL (WINAPI *pRegisterRawInputDevices)(IN PCRAWINPUTDEVICE pRawInputDevices, IN UINT uiNumDevices, IN UINT cbSize); + +pGetRawInputDeviceList _GRIDL; +pGetRawInputData _GRID; +pGetRawInputDeviceInfoA _GRIDIA; +pRegisterRawInputDevices _RRID; + +mouse_t *rawmice; +int rawmicecount; +int usingindividualmice; +RAWINPUT *raw; +int ribuffersize; + +cvar_t in_rawinput = {"in_rawinput", "0"}; +cvar_t in_rawinput_system = {"in_rawinput_combine", "0"}; +cvar_t in_rawinput_rdp = {"in_rawinput_rdp", "0"}; +#endif + // forward-referenced functions void IN_StartupJoystick (void); void Joy_AdvancedUpdate_f (void); @@ -528,9 +570,11 @@ void IN_RestoreOriginalMouseState (void) } #ifndef NODIRECTX -BOOL (FAR PASCAL IN_EnumerateDevices)(LPCDIDEVICEINSTANCE inst, LPVOID parm) +BOOL CALLBACK IN_EnumerateDevices(LPCDIDEVICEINSTANCE inst, LPVOID parm) { - return TRUE; + Con_SafePrintf("Found: %s\n", inst->tszProductName); + + return DIENUM_CONTINUE; } /* =========== @@ -573,7 +617,7 @@ int IN_InitDInput (void) if (FAILED(hr)) return 0; - IDirectInput7_EnumDevices(g_pdi7, 0, &IN_EnumerateDevices, NULL, 0); + IDirectInput7_EnumDevices(g_pdi7, 0, &IN_EnumerateDevices, NULL, DIEDFL_ATTACHEDONLY); // obtain an interface to the system mouse device. hr = IDirectInput7_CreateDeviceEx(g_pdi7, &GUID_SysMouse, &IID_IDirectInputDevice7, &g_pMouse7, NULL); @@ -631,7 +675,7 @@ int IN_InitDInput (void) { return 0; } - IDirectInput_EnumDevices(g_pdi, 0, &IN_EnumerateDevices, NULL, 0); + IDirectInput_EnumDevices(g_pdi, 0, &IN_EnumerateDevices, NULL, DIEDFL_ATTACHEDONLY); // obtain an interface to the system mouse device. hr = IDirectInput_CreateDevice(g_pdi, &GUID_SysMouse, &g_pMouse, NULL); @@ -717,6 +761,29 @@ void IN_CloseDInput (void) } #endif +#ifdef USINGRAWINPUT +void IN_RawInput_DeInit(void) +{ + RAWINPUTDEVICE Rid; + + if (rawmicecount < 1) + return; + + // deregister raw input + Rid.usUsagePage = 0x01; + Rid.usUsage = 0x02; + Rid.dwFlags = RIDEV_REMOVE; + Rid.hwndTarget = NULL; + + (*_RRID)(&Rid, 1, sizeof(Rid)); + + Z_Free(rawmice); + + // dealloc mouse structure + rawmicecount = 0; +} +#endif + void IN_SetSerialBoad(HANDLE port, int boadrate) { DCB dcb; @@ -828,6 +895,194 @@ unsigned long __stdcall IN_SerialMSIntelliRun(void *param) return true; } +#ifdef USINGRAWINPUT +// raw input registration functions +int IN_RawInput_Register(void) +{ + // This function registers to receive the WM_INPUT messages + RAWINPUTDEVICE Rid; // Register only for mouse messages from wm_input. + + //register to get wm_input messages + Rid.usUsagePage = 0x01; + Rid.usUsage = 0x02; + Rid.dwFlags = RIDEV_NOLEGACY; // adds HID mouse and also ignores legacy mouse messages + Rid.hwndTarget = NULL; + + // Register to receive the WM_INPUT message for any change in mouse (buttons, wheel, and movement will all generate the same message) + if (!(*_RRID)(&Rid, 1, sizeof(Rid))) + return 0; + + return 1; +} + +int IN_RawInput_IsRDPMouse(char *cDeviceString) +{ + char cRDPString[] = "\\??\\Root#RDP_MOU#"; + int i; + + if (strlen(cDeviceString) < strlen(cRDPString)) { + return 0; + } + + for (i = strlen(cRDPString) - 1; i >= 0; i--) + { + if (cDeviceString[i] != cRDPString[i]) + return 0; + } + + return 1; // is RDP mouse +} + +void IN_RawInput_Init(void) +{ + // "0" to exclude, "1" to include + PRAWINPUTDEVICELIST pRawInputDeviceList; + int inputdevices, i, j, mtemp; + char dname[MAX_RI_DEVICE_SIZE]; + + // Return 0 if rawinput is not available + HMODULE user32 = LoadLibrary("user32.dll"); + if (!user32) + { + Con_SafePrintf("Raw input: unable to load user32.dll\n"); + return; + } + _RRID = (pRegisterRawInputDevices)GetProcAddress(user32,"RegisterRawInputDevices"); + if (!_RRID) + { + Con_SafePrintf("Raw input: function RegisterRawInputDevices could not be registered\n"); + return; + } + _GRIDL = (pGetRawInputDeviceList)GetProcAddress(user32,"GetRawInputDeviceList"); + if (!_GRIDL) + { + Con_SafePrintf("Raw input: function GetRawInputDeviceList could not be registered\n"); + return; + } + _GRIDIA = (pGetRawInputDeviceInfoA)GetProcAddress(user32,"GetRawInputDeviceInfoA"); + if (!_GRIDIA) + { + Con_SafePrintf("Raw input: function GetRawInputDeviceInfoA could not be registered\n"); + return; + } + _GRID = (pGetRawInputData)GetProcAddress(user32,"GetRawInputData"); + if (!_GRID) + { + Con_SafePrintf("Raw input: function GetRawInputData could not be registered\n"); + return; + } + + rawmicecount = 0; + rawmice = NULL; + usingindividualmice = 1; + raw = NULL; + ribuffersize = 0; + + // 1st call to GetRawInputDeviceList: Pass NULL to get the number of devices. + if ((*_GRIDL)(NULL, &inputdevices, sizeof(RAWINPUTDEVICELIST)) != 0) + { + Con_SafePrintf("Raw input: unable to count raw input devices\n"); + return; + } + + // Allocate the array to hold the DeviceList + pRawInputDeviceList = Z_Malloc(sizeof(RAWINPUTDEVICELIST) * inputdevices); + + // 2nd call to GetRawInputDeviceList: Pass the pointer to our DeviceList and GetRawInputDeviceList() will fill the array + if ((*_GRIDL)(pRawInputDeviceList, &inputdevices, sizeof(RAWINPUTDEVICELIST)) == -1) + { + Con_SafePrintf("Raw input: unable to get raw input device list\n"); + return; + } + + if (in_rawinput_system.value) // use system mouse (cvar) + usingindividualmice = 0; + + // Loop through all devices and count the mice + for (i = 0, mtemp = 0; i < inputdevices; i++) + { + if (pRawInputDeviceList[i].dwType == RIM_TYPEMOUSE) + { + j = MAX_RI_DEVICE_SIZE; + + // Get the device name and use it to determine if it's the RDP Terminal Services virtual device. + if ((*_GRIDIA)(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, dname, &j) < 0) + dname[0] = 0; + + if (!(in_rawinput_rdp.value) && IN_RawInput_IsRDPMouse(dname)) // use rdp mouse (cvar) + continue; + + // advance temp device count + mtemp++; + } + } + + // exit out if no devices found + if (!mtemp) + { + Con_SafePrintf("Raw input: no usable device found\n"); + return; + } + + // Loop again and bind devices + rawmice = Z_Malloc(sizeof(mouse_t) * mtemp); + for (i = 0; i < inputdevices; i++) + { + if (pRawInputDeviceList[i].dwType == RIM_TYPEMOUSE) + { + j = MAX_RI_DEVICE_SIZE; + + // Get the device name and use it to determine if it's the RDP Terminal Services virtual device. + if ((*_GRIDIA)(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, dname, &j) < 0) + dname[0] = 0; + + if (!(in_rawinput_rdp.value) && IN_RawInput_IsRDPMouse(dname)) // use rdp mouse (cvar) + continue; + + // print pretty message about the mouse + dname[MAX_RI_DEVICE_SIZE - 1] = 0; + for (mtemp = strlen(dname); mtemp >= 0; mtemp--) + { + if (dname[mtemp] == '#') + { + dname[mtemp + 1] = 0; + break; + } + } + Con_SafePrintf("Raw input: [%i] %s\n", i, dname); + + // set handle + rawmice[rawmicecount].rawinputhandle = pRawInputDeviceList[i].hDevice; + rawmice[rawmicecount].numbuttons = 10; + rawmice[rawmicecount].pos[0] = RI_INVALID_POS; + rawmicecount++; + } + } + + + // free the RAWINPUTDEVICELIST + Z_Free(pRawInputDeviceList); + + // finally, register to recieve raw input WM_INPUT messages + if (!IN_RawInput_Register()) { + Con_SafePrintf("Raw input: unable to register raw input\n"); + + // quick deinit + rawmicecount = 0; + Z_Free(rawmice); + return; + } + + // alloc raw input buffer + raw = BZ_Malloc(INIT_RIBUFFER_SIZE); + ribuffersize = INIT_RIBUFFER_SIZE; + + Con_SafePrintf("Raw input: initialized with %i mice\n", rawmicecount); + + return; // success +} +#endif + /* =========== IN_StartupMouse @@ -881,6 +1136,13 @@ void IN_StartupMouse (void) newmouseparms[2] = originalmouseparms[2]; } } + +#ifdef USINGRAWINPUT + if (in_rawinput.value) + { + IN_RawInput_Init(); + } +#endif } if (COM_CheckParm("-m_mwhook")) @@ -980,6 +1242,12 @@ void IN_Init (void) Cmd_AddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f); uiWheelMessage = RegisterWindowMessage ( "MSWHEEL_ROLLMSG" ); + +#ifdef USINGRAWINPUT + Cvar_Register (&in_rawinput, "Input stuff"); + Cvar_Register (&in_rawinput_system, "Input stuff"); + Cvar_Register (&in_rawinput_rdp, "Input stuff"); +#endif } else { @@ -1005,6 +1273,9 @@ void IN_Shutdown (void) #ifndef NODIRECTX IN_CloseDInput(); #endif +#ifdef USINGRAWINPUT + IN_RawInput_DeInit(); +#endif } @@ -1339,6 +1610,26 @@ void IN_MouseMove (usercmd_t *cmd, int pnum) sysmouse.buttons = sysmouse.oldbuttons; //don't do it!!! Our buttons are event driven. We don't want to merge em and forget do we now? } +#ifdef USINGRAWINPUT + if (rawmicecount) + { + if (!usingindividualmice && pnum == 0) + { + // not the right way to do this but it'll work for now + int x; + + for (x = 0; x < rawmicecount; x++) + { + ProcessMouse(rawmice + x, cmd, 0); + } + } + else if (pnum < rawmicecount) + { + ProcessMouse(rawmice + pnum, cmd, pnum); + } + } +#endif + if (pnum == 0) ProcessMouse(&sysmouse, cmd, pnum); @@ -1375,18 +1666,138 @@ void IN_Accumulate (void) { if (mouseactive && !dinput) { - POINT current_pos; +#ifdef USINGRAWINPUT + if (rawmicecount) + { + } + else +#endif + { + POINT current_pos; - GetCursorPos (¤t_pos); + GetCursorPos (¤t_pos); - sysmouse.delta[0] += current_pos.x - window_center_x; - sysmouse.delta[1] += current_pos.y - window_center_y; + sysmouse.delta[0] += current_pos.x - window_center_x; + sysmouse.delta[1] += current_pos.y - window_center_y; + } // force the mouse to the center, so there's room to move SetCursorPos (window_center_x, window_center_y); } } +#ifdef USINGRAWINPUT +void IN_RawInput_MouseRead(HANDLE in_device_handle) +{ + int i = 0, tbuttons, j; + int dwSize; + + // get raw input + if ((*_GRID)((HRAWINPUT)in_device_handle, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) == -1) + { + Con_Printf("Raw input: unable to add to get size of raw input header.\n"); + return; + } + + if (dwSize > ribuffersize) + { + ribuffersize = dwSize; + raw = BZ_Realloc(raw, dwSize); + } + + if ((*_GRID)((HRAWINPUT)in_device_handle, RID_INPUT, raw, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize ) { + Con_Printf("Raw input: unable to add to get raw input header.\n"); + return; + } + + // find mouse in our mouse list + for (; i < rawmicecount; i++) + { + if (rawmice[i].rawinputhandle == raw->header.hDevice) + break; + } + + if (i == rawmicecount) // we're not tracking this mouse + return; + + // movement + if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) + { + if (rawmice[i].pos[0] != RI_INVALID_POS) + { + rawmice[i].delta[0] += raw->data.mouse.lLastX - rawmice[i].pos[0]; + rawmice[i].delta[1] += raw->data.mouse.lLastY - rawmice[i].pos[1]; + } + rawmice[i].pos[0] = raw->data.mouse.lLastX; + rawmice[i].pos[1] = raw->data.mouse.lLastY; + } + else // RELATIVE + { + rawmice[i].delta[0] += raw->data.mouse.lLastX; + rawmice[i].delta[1] += raw->data.mouse.lLastY; + rawmice[i].pos[0] = RI_INVALID_POS; + } + + // buttons + if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) + Key_Event(K_MOUSE1, true); + if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) + Key_Event(K_MOUSE1, false); + if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) + Key_Event(K_MOUSE2, true); + if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) + Key_Event(K_MOUSE2, false); + if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) + Key_Event(K_MOUSE3, true); + if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) + Key_Event(K_MOUSE3, false); + if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) + Key_Event(K_MOUSE4, true); + if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) + Key_Event(K_MOUSE4, false); + if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) + Key_Event(K_MOUSE5, true); + if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) + Key_Event(K_MOUSE5, false); + + // mouse wheel + if (raw->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) { // If the current message has a mouse_wheel message + if ((SHORT)raw->data.mouse.usButtonData > 0) { + Key_Event(K_MWHEELUP, true); + Key_Event(K_MWHEELUP, false); + } + if ((SHORT)raw->data.mouse.usButtonData < 0) { + Key_Event(K_MWHEELDOWN, true); + Key_Event(K_MWHEELDOWN, false); + } + } + + // extra buttons + tbuttons = raw->data.mouse.ulRawButtons & RI_RAWBUTTON_MASK; + for (j=6 ; j