X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=vid_wgl.c;h=24bcdabc943ffabf7bf63e877ae3e96108f716b4;hb=6fb644eee19956bee121e1f2430d2b84067dc056;hp=960c14c085c8bfac0ceca0b82c7248e28793d2e0;hpb=8c215d5236b730b87168ff735e47a2d61f88976c;p=xonotic%2Fdarkplaces.git diff --git a/vid_wgl.c b/vid_wgl.c index 960c14c0..24bcdabc 100644 --- a/vid_wgl.c +++ b/vid_wgl.c @@ -126,6 +126,7 @@ static dllfunction_t wglpixelformatfuncs[] = }; static DEVMODE gdevmode, initialdevmode; +static vid_mode_t desktop_mode; static qboolean vid_initialized = false; static qboolean vid_wassuspended = false; static qboolean vid_usingmouse = false; @@ -152,10 +153,11 @@ static qboolean vid_isfullscreen; //void VID_MenuDraw (void); //void VID_MenuKey (int key); -//LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -//void AppActivate(BOOL fActive, BOOL minimize); -//void ClearAllStates (void); -//void VID_UpdateWindowStatus (void); +LONG WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void AppActivate(BOOL fActive, BOOL minimize); +static void ClearAllStates(void); +qboolean VID_InitModeGL(viddef_mode_t *mode); +qboolean VID_InitModeSOFT(viddef_mode_t *mode); //==================================== @@ -204,92 +206,17 @@ static qboolean dinput_acquired; static unsigned int mstate_di; #endif -// 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 - -// joystick axes state -typedef struct -{ - float oldmove; - float move; - float mdelta; - double keytime; -}joy_axiscache_t; -static joy_axiscache_t joy_axescache[JOY_MAX_AXES]; - -enum _ControlList -{ - AxisNada = 0, AxisForward, AxisLook, AxisSide, AxisTurn -}; - -static DWORD dwAxisFlags[JOY_MAX_AXES] = -{ - JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, JOY_RETURNR, JOY_RETURNU, JOY_RETURNV -}; - -static DWORD dwAxisMap[JOY_MAX_AXES]; -static DWORD dwControlMap[JOY_MAX_AXES]; -static 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. -static cvar_t in_joystick = {CVAR_SAVE, "joystick","0", "enables joysticks"}; -static cvar_t joy_name = {0, "joyname", "joystick", "name of joystick to use (informational only, used only by joyadvanced 1 mode)"}; -static cvar_t joy_advanced = {0, "joyadvanced", "0", "use more than 2 axis joysticks (configuring this is very technical)"}; -static cvar_t joy_advaxisx = {0, "joyadvaxisx", "0", "axis mapping for joyadvanced 1 mode"}; -static cvar_t joy_advaxisy = {0, "joyadvaxisy", "0", "axis mapping for joyadvanced 1 mode"}; -static cvar_t joy_advaxisz = {0, "joyadvaxisz", "0", "axis mapping for joyadvanced 1 mode"}; -static cvar_t joy_advaxisr = {0, "joyadvaxisr", "0", "axis mapping for joyadvanced 1 mode"}; -static cvar_t joy_advaxisu = {0, "joyadvaxisu", "0", "axis mapping for joyadvanced 1 mode"}; -static cvar_t joy_advaxisv = {0, "joyadvaxisv", "0", "axis mapping for joyadvanced 1 mode"}; -static cvar_t joy_forwardthreshold = {0, "joyforwardthreshold", "0.15", "minimum joystick movement necessary to move forward"}; -static cvar_t joy_sidethreshold = {0, "joysidethreshold", "0.15", "minimum joystick movement necessary to move sideways (strafing)"}; -static cvar_t joy_pitchthreshold = {0, "joypitchthreshold", "0.15", "minimum joystick movement necessary to look up/down"}; -static cvar_t joy_yawthreshold = {0, "joyyawthreshold", "0.15", "minimum joystick movement necessary to turn left/right"}; -static cvar_t joy_forwardsensitivity = {0, "joyforwardsensitivity", "-1.0", "how fast the joystick moves forward"}; -static cvar_t joy_sidesensitivity = {0, "joysidesensitivity", "-1.0", "how fast the joystick moves sideways (strafing)"}; -static cvar_t joy_pitchsensitivity = {0, "joypitchsensitivity", "1.0", "how fast the joystick looks up/down"}; -static cvar_t joy_yawsensitivity = {0, "joyyawsensitivity", "-1.0", "how fast the joystick turns left/right"}; -static cvar_t joy_wwhack1 = {0, "joywwhack1", "0.0", "special hack for wingman warrior"}; -static cvar_t joy_wwhack2 = {0, "joywwhack2", "0.0", "special hack for wingman warrior"}; -static cvar_t joy_axiskeyevents = {CVAR_SAVE, "joy_axiskeyevents", "0", "generate uparrow/leftarrow etc. keyevents for joystick axes, use if your joystick driver is not generating them"}; -static cvar_t joy_axiskeyevents_deadzone = {CVAR_SAVE, "joy_axiskeyevents_deadzone", "0.5", "deadzone value for axes"}; - static cvar_t vid_forcerefreshrate = {0, "vid_forcerefreshrate", "0", "try to set the given vid_refreshrate even if Windows doesn't list it as valid video mode"}; -static qboolean joy_avail, joy_advancedinit, joy_haspov; -static DWORD joy_oldbuttonstate, joy_oldpovstate; - -static int joy_id; -static DWORD joy_flags; -static DWORD joy_numbuttons; - #ifdef SUPPORTDIRECTX static LPDIRECTINPUT g_pdi; static LPDIRECTINPUTDEVICE g_pMouse; static HINSTANCE hInstDI; #endif -static JOYINFOEX ji; - // forward-referenced functions -static void IN_StartupJoystick (void); -static void Joy_AdvancedUpdate_f (void); -static void IN_JoyMove (void); static void IN_StartupMouse (void); - +static void AdjustWindowBounds(int fullscreen, int *width, int *height, viddef_mode_t *mode, DWORD WindowStyle, RECT *rect); //==================================== @@ -400,19 +327,17 @@ void VID_Finish (void) //========================================================================== - - static unsigned char scantokey[128] = { -// 0 1 2 3 4 5 6 7 8 9 A B C D E F - 0 ,27 ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,'0' ,'-' ,'=' ,K_BACKSPACE,9 ,//0 - 'q' ,'w' ,'e' ,'r' ,'t' ,'y' ,'u' ,'i' ,'o' ,'p' ,'[' ,']' ,13 ,K_CTRL ,'a' ,'s' ,//1 - 'd' ,'f' ,'g' ,'h' ,'j' ,'k' ,'l' ,';' ,'\'' ,'`' ,K_SHIFT ,'\\' ,'z' ,'x' ,'c' ,'v' ,//2 - 'b' ,'n' ,'m' ,',' ,'.' ,'/' ,K_SHIFT,'*' ,K_ALT ,' ' ,0 ,K_F1 ,K_F2 ,K_F3 ,K_F4 ,K_F5 ,//3 - K_F6 ,K_F7 ,K_F8 ,K_F9 ,K_F10,K_PAUSE,0 ,K_HOME,K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5,K_RIGHTARROW,K_KP_PLUS ,K_END,//4 - K_DOWNARROW,K_PGDN,K_INS,K_DEL,0 ,0 ,0 ,K_F11 ,K_F12 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,//5 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,//6 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 //7 +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0 ,K_ESCAPE,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,'0' ,'-' ,'=' ,K_BACKSPACE,K_TAB,//0 + 'q' ,'w' ,'e' ,'r' ,'t' ,'y' ,'u' ,'i' ,'o' ,'p' ,'[' ,']' ,K_ENTER,K_CTRL ,'a' ,'s' ,//1 + 'd' ,'f' ,'g' ,'h' ,'j' ,'k' ,'l' ,';' ,'\'' ,'`' ,K_SHIFT ,'\\' ,'z' ,'x' ,'c' ,'v' ,//2 + 'b' ,'n' ,'m' ,',' ,'.' ,'/' ,K_SHIFT ,'*' ,K_ALT ,' ' ,K_CAPSLOCK,K_F1 ,K_F2 ,K_F3 ,K_F4 ,K_F5 ,//3 + K_F6 ,K_F7 ,K_F8 ,K_F9 ,K_F10,K_PAUSE,K_SCROLLOCK,K_HOME,K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5 ,K_RIGHTARROW,K_KP_PLUS ,K_END,//4 + K_DOWNARROW,K_PGDN ,K_INS,K_DEL,0 ,0 ,0 ,K_F11 ,K_F12 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,//5 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,//6 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 //7 }; @@ -442,6 +367,9 @@ static int MapKey (int key, int virtualkey) if ( !is_extended ) { + if(((GetKeyState(VK_NUMLOCK)) & 0xffff) == 0) + return result; + switch ( result ) { case K_HOME: @@ -470,6 +398,9 @@ static int MapKey (int key, int virtualkey) } else { + if(virtualkey == VK_NUMLOCK) + return K_NUMLOCK; + switch ( result ) { case 0x0D: @@ -564,7 +495,7 @@ void AppActivate(BOOL fActive, BOOL minimize) if (vid_isfullscreen) { if (gldll) - ChangeDisplaySettings (NULL, 0); + ChangeDisplaySettings (NULL, CDS_FULLSCREEN); vid_wassuspended = true; } VID_RestoreSystemGamma(); @@ -586,7 +517,9 @@ void Sys_SendKeyEvents (void) } } +#ifdef CONFIG_CD LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +#endif static keynum_t buttonremap[16] = { @@ -609,13 +542,13 @@ static keynum_t buttonremap[16] = }; /* main window procedure */ -static qboolean IN_JoystickBlockDoubledKeyEvents(int keycode); LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LONG lRet = 1; int fActive, fMinimized, temp; unsigned char state[256]; - unsigned char asciichar[4]; + const unsigned int UNICODE_BUFFER_LENGTH = 4; + WCHAR unicode[UNICODE_BUFFER_LENGTH]; int vkey; int charlength; qboolean down = false; @@ -648,14 +581,13 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) GetKeyboardState (state); // alt/ctrl/shift tend to produce funky ToAscii values, // and if it's not a single character we don't know care about it - charlength = ToAscii (wParam, lParam >> 16, state, (LPWORD)asciichar, 0); - if (vkey == K_ALT || vkey == K_CTRL || vkey == K_SHIFT || charlength == 0) - asciichar[0] = 0; - else if( charlength == 2 ) { - asciichar[0] = asciichar[1]; - } - if (!IN_JoystickBlockDoubledKeyEvents(vkey)) - Key_Event (vkey, asciichar[0], down); + charlength = ToUnicode(wParam, lParam >> 16, state, unicode, UNICODE_BUFFER_LENGTH, 0); + if(vkey == K_ALT || vkey == K_CTRL || vkey == K_SHIFT || charlength == 0) + unicode[0] = 0; + else if(charlength == 2) + unicode[0] = unicode[1]; + if (!VID_JoyBlockEmulatedKeys(vkey)) + Key_Event(vkey, unicode[0], down); break; case WM_SYSCHAR: @@ -764,7 +696,9 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // break; case MM_MCINOTIFY: +#ifdef CONFIG_CD lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); +#endif break; default: @@ -938,6 +872,13 @@ void VID_Init(void) memset(&initialdevmode, 0, sizeof(initialdevmode)); EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &initialdevmode); + desktop_mode.width = initialdevmode.dmPelsWidth; + desktop_mode.height = initialdevmode.dmPelsHeight; + desktop_mode.bpp = initialdevmode.dmBitsPerPel; + desktop_mode.refreshrate = initialdevmode.dmDisplayFrequency; + desktop_mode.pixelheight_num = 1; + desktop_mode.pixelheight_denom = 1; // Win32 apparently does not provide this (FIXME) + IN_Init(); } @@ -972,7 +913,6 @@ qboolean VID_InitModeGL(viddef_mode_t *mode) int pixelformat, newpixelformat; UINT numpixelformats; DWORD WindowStyle, ExWindowStyle; - int CenterX, CenterY; const char *gldrivername; int depth; DEVMODE thismode; @@ -1084,7 +1024,15 @@ qboolean VID_InitModeGL(viddef_mode_t *mode) vid_isfullscreen = false; if (fullscreen) { - if(vid_forcerefreshrate.integer) + if(vid_desktopfullscreen.integer) + { + foundmode = true; + gdevmode = initialdevmode; + width = mode->width = gdevmode.dmPelsWidth; + height = mode->height = gdevmode.dmPelsHeight; + bpp = mode->bitsperpixel = gdevmode.dmBitsPerPel; + } + else if(vid_forcerefreshrate.integer) { foundmode = true; gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; @@ -1218,32 +1166,7 @@ qboolean VID_InitModeGL(viddef_mode_t *mode) ExWindowStyle = 0; } - rect.top = 0; - rect.left = 0; - rect.right = width; - rect.bottom = height; - AdjustWindowRectEx(&rect, WindowStyle, false, 0); - - if (fullscreen) - { - CenterX = 0; - CenterY = 0; - } - else - { - CenterX = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2; - CenterY = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2; - } - CenterX = max(0, CenterX); - CenterY = max(0, CenterY); - - // x and y may be changed by WM_MOVE messages - window_x = CenterX; - window_y = CenterY; - rect.left += CenterX; - rect.right += CenterX; - rect.top += CenterY; - rect.bottom += CenterY; + AdjustWindowBounds(fullscreen, &width, &height, mode, WindowStyle, &rect); pixelformat = 0; newpixelformat = 0; @@ -1390,7 +1313,6 @@ qboolean VID_InitModeGL(viddef_mode_t *mode) vid_initialized = true; IN_StartupMouse (); - IN_StartupJoystick (); if (qwglSwapIntervalEXT) { @@ -1402,6 +1324,56 @@ qboolean VID_InitModeGL(viddef_mode_t *mode) return true; } +static void AdjustWindowBounds(int fullscreen, int *width, int *height, viddef_mode_t *mode, DWORD WindowStyle, RECT *rect) +{ + int CenterX, CenterY; + + rect->top = 0; + rect->left = 0; + rect->right = *width; + rect->bottom = *height; + AdjustWindowRectEx(rect, WindowStyle, false, 0); + + if (fullscreen) + { + CenterX = 0; + CenterY = 0; + } + else + { + RECT workArea; + SystemParametersInfo(SPI_GETWORKAREA, NULL, &workArea, 0); + int workWidth = workArea.right - workArea.left; + int workHeight = workArea.bottom - workArea.top; + + // if height/width matches physical screen height/width, adjust it to available desktop size + // and allow 2 pixels on top for the title bar so the window can be moved + const int titleBarPixels = 2; + if (*width == GetSystemMetrics(SM_CXSCREEN) && (*height == GetSystemMetrics(SM_CYSCREEN) || *height == workHeight - titleBarPixels)) + { + rect->right -= *width - workWidth; + *width = mode->width = workWidth; + rect->bottom -= *height - (workHeight - titleBarPixels); + *height = mode->height = workHeight - titleBarPixels; + CenterX = 0; + CenterY = titleBarPixels; + } + else + { + CenterX = max(0, (workWidth - *width) / 2); + CenterY = max(0, (workHeight - *height) / 2); + } + } + + // x and y may be changed by WM_MOVE messages + window_x = CenterX; + window_y = CenterY; + rect->left += CenterX; + rect->right += CenterX; + rect->top += CenterY; + rect->bottom += CenterY; +} + #ifdef SUPPORTD3D static D3DADAPTER_IDENTIFIER9 d3d9adapteridentifier; @@ -1417,7 +1389,6 @@ qboolean VID_InitModeDX(viddef_mode_t *mode, int version) RECT rect; MSG msg; DWORD WindowStyle, ExWindowStyle; - int CenterX, CenterY; int bpp = mode->bitsperpixel; int width = mode->width; int height = mode->height; @@ -1442,32 +1413,7 @@ qboolean VID_InitModeDX(viddef_mode_t *mode, int version) ExWindowStyle = 0; } - rect.top = 0; - rect.left = 0; - rect.right = width; - rect.bottom = height; - AdjustWindowRectEx(&rect, WindowStyle, false, 0); - - if (fullscreen) - { - CenterX = 0; - CenterY = 0; - } - else - { - CenterX = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2; - CenterY = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2; - } - CenterX = max(0, CenterX); - CenterY = max(0, CenterY); - - // x and y may be changed by WM_MOVE messages - window_x = CenterX; - window_y = CenterY; - rect.left += CenterX; - rect.right += CenterX; - rect.top += CenterY; - rect.bottom += CenterY; + AdjustWindowBounds(fullscreen, &width, &height, mode, WindowStyle, &rect); gl_extensions = ""; gl_platformextensions = ""; @@ -1577,6 +1523,7 @@ qboolean VID_InitModeDX(viddef_mode_t *mode, int version) vid.support.arb_depth_texture = true; vid.support.arb_draw_buffers = vid_d3d9caps.NumSimultaneousRTs > 1; vid.support.arb_occlusion_query = true; // can't find a cap for this + vid.support.arb_query_buffer_object = true; vid.support.arb_shadow = true; vid.support.arb_texture_compression = true; vid.support.arb_texture_cube_map = true; @@ -1585,6 +1532,7 @@ qboolean VID_InitModeDX(viddef_mode_t *mode, int version) vid.support.ext_blend_subtract = true; vid.support.ext_draw_range_elements = true; vid.support.ext_framebuffer_object = true; + vid.support.ext_texture_3d = true; vid.support.ext_texture_compression_s3tc = true; vid.support.ext_texture_filter_anisotropic = true; @@ -1605,6 +1553,8 @@ qboolean VID_InitModeDX(viddef_mode_t *mode, int version) vid.texarrayunits = bound(8, vid.texarrayunits, MAX_TEXTUREUNITS); Con_DPrintf("Using D3D9.0 rendering path - %i texture matrix, %i texture images, %i texcoords, shadowmapping supported%s\n", vid.texunits, vid.teximageunits, vid.texarrayunits, vid.maxdrawbuffers > 1 ? ", MRT detected (allows prepass deferred lighting)" : ""); vid.renderpath = RENDERPATH_D3D9; + vid.sRGBcapable2D = false; + vid.sRGBcapable3D = true; vid.useinterleavedarrays = true; Cvar_SetQuick(&gl_info_vendor, gl_vendor); @@ -1634,7 +1584,6 @@ qboolean VID_InitModeDX(viddef_mode_t *mode, int version) vid_initialized = true; IN_StartupMouse (); - IN_StartupJoystick (); return true; } @@ -1648,7 +1597,6 @@ qboolean VID_InitModeSOFT(viddef_mode_t *mode) MSG msg; int pixelformat, newpixelformat; DWORD WindowStyle, ExWindowStyle; - int CenterX, CenterY; int depth; DEVMODE thismode; qboolean foundmode, foundgoodmode; @@ -1800,32 +1748,7 @@ qboolean VID_InitModeSOFT(viddef_mode_t *mode) ExWindowStyle = 0; } - rect.top = 0; - rect.left = 0; - rect.right = width; - rect.bottom = height; - AdjustWindowRectEx(&rect, WindowStyle, false, 0); - - if (fullscreen) - { - CenterX = 0; - CenterY = 0; - } - else - { - CenterX = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2; - CenterY = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2; - } - CenterX = max(0, CenterX); - CenterY = max(0, CenterY); - - // x and y may be changed by WM_MOVE messages - window_x = CenterX; - window_y = CenterY; - rect.left += CenterX; - rect.right += CenterX; - rect.top += CenterY; - rect.bottom += CenterY; + AdjustWindowBounds(fullscreen, &width, &height, mode, WindowStyle, &rect); pixelformat = 0; newpixelformat = 0; @@ -1916,7 +1839,6 @@ qboolean VID_InitModeSOFT(viddef_mode_t *mode) vid_initialized = true; IN_StartupMouse (); - IN_StartupJoystick (); return true; } @@ -1946,6 +1868,7 @@ void VID_Shutdown (void) if(vid_initialized == false) return; + VID_EnableJoystick(false); VID_SetMouse(false, false, false); VID_RestoreSystemGamma(); @@ -1976,8 +1899,8 @@ void VID_Shutdown (void) if (vid_begunscene) IDirect3DDevice9_EndScene(vid_d3d9dev); vid_begunscene = false; -// Cmd_ExecuteString("r_texturestats", src_command); -// Cmd_ExecuteString("memlist", src_command); +// Cmd_ExecuteString("r_texturestats", src_command, true); +// Cmd_ExecuteString("memlist", src_command, true); IDirect3DDevice9_Release(vid_d3d9dev); } vid_d3d9dev = NULL; @@ -2001,7 +1924,7 @@ void VID_Shutdown (void) DestroyWindow(mainwindow); mainwindow = 0; if (vid_isfullscreen && isgl) - ChangeDisplaySettings (NULL, 0); + ChangeDisplaySettings (NULL, CDS_FULLSCREEN); vid_isfullscreen = false; } @@ -2085,6 +2008,28 @@ void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecurso } } +void VID_BuildJoyState(vid_joystate_t *joystate) +{ + VID_Shared_BuildJoyState_Begin(joystate); + VID_Shared_BuildJoyState_Finish(joystate); +} + +void VID_EnableJoystick(qboolean enable) +{ + int index = joy_enable.integer > 0 ? joy_index.integer : -1; + qboolean success = false; + int sharedcount = 0; + sharedcount = VID_Shared_SetJoystick(index); + if (index >= 0 && index < sharedcount) + success = true; + + // update cvar containing count of XInput joysticks + if (joy_detected.integer != sharedcount) + Cvar_SetValueQuick(&joy_detected, sharedcount); + + if (joy_active.integer != (success ? 1 : 0)) + Cvar_SetValueQuick(&joy_active, success ? 1 : 0); +} #ifdef SUPPORTDIRECTX /* @@ -2196,7 +2141,7 @@ static void IN_StartupMouse (void) mouseinitialized = true; #ifdef SUPPORTDIRECTX -// COMMANDLINEOPTION: Windows Input: -dinput enables DirectInput for mouse/joystick input +// COMMANDLINEOPTION: Windows Input: -dinput enables DirectInput for mouse input if (COM_CheckParm ("-dinput")) dinput = IN_InitDInput (); @@ -2306,580 +2251,19 @@ IN_Move */ void IN_Move (void) { + vid_joystate_t joystate; if (vid_activewindow && !vid_reallyhidden) - { IN_MouseMove (); - IN_JoyMove (); - } + VID_EnableJoystick(true); + VID_BuildJoyState(&joystate); + VID_ApplyJoyState(&joystate); } -/* -=============== -IN_StartupJoystick -=============== -*/ -static void IN_StartupJoystick (void) -{ - int numdevs; - JOYCAPS jc; - MMRESULT mmr; - mmr = 0; - - // assume no joystick - joy_avail = false; - - // abort startup if user requests no joystick -// COMMANDLINEOPTION: Windows Input: -nojoy disables joystick support, may be a small speed increase - if (COM_CheckParm ("-nojoy")) - return; - - // verify joystick driver is present - if ((numdevs = joyGetNumDevs ()) == 0) - { - Con_Print("\njoystick not found -- driver not present\n\n"); - return; - } - - // cycle through the joystick ids for the first valid one - for (joy_id=0 ; joy_id= JOY_MAX_AXES) - return 0; // no such axis on this joystick - - // get the floating point zero-centered, potentially-inverted data for the current axis - fAxisValue = (float) *pdwRawValue[axis]; - - // move centerpoint to zero - fAxisValue -= 32768.0; - - if (joy_wwhack2.integer != 0.0) - { - if (dwAxisMap[axis] == AxisTurn) - { - // this is a special formula for the Logitech WingMan Warrior - // y=ax^b; where a = 300 and b = 1.3 - // also x values are in increments of 800 (so this is factored out) - // then bounds check result to level out excessively high spin rates - fTemp = 300.0 * pow(abs(fAxisValue) / 800.0, 1.3); - if (fTemp > 14000.0) - fTemp = 14000.0; - // restore direction information - fAxisValue = (fAxisValue > 0.0) ? fTemp : -fTemp; - } - } - - // convert range from -32768..32767 to -1..1 - fAxisValue /= 32768.0; - - // deadzone around center - if (fabs(fAxisValue) < deadzone) - return 0; - - // apply sensitivity - return fAxisValue * sensitivity; -} - -/* -=========== - IN_JoystickKeyeventForAxis -=========== -*/ - -static void IN_JoystickKeyeventForAxis(int axis, int key_pos, int key_neg) -{ - double joytime; - - if (axis < 0 || axis >= JOY_MAX_AXES) - return; // no such axis on this joystick - - joytime = Sys_DoubleTime(); - // no key event, continuous keydown event - if (joy_axescache[axis].move == joy_axescache[axis].oldmove) - { - if (joy_axescache[axis].move != 0 && joytime > joy_axescache[axis].keytime) - { - //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].move > 0) ? key_pos : key_neg), 1, cl.time); - Key_Event((joy_axescache[axis].move > 0) ? key_pos : key_neg, 0, 1); - joy_axescache[axis].keytime = joytime + 0.5 / 20; - } - return; - } - // generate key up event - if (joy_axescache[axis].oldmove) - { - //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].oldmove > 0) ? key_pos : key_neg), 1, cl.time); - Key_Event((joy_axescache[axis].oldmove > 0) ? key_pos : key_neg, 0, 0); - } - // generate key down event - if (joy_axescache[axis].move) - { - //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].move > 0) ? key_pos : key_neg), 1, cl.time); - Key_Event((joy_axescache[axis].move > 0) ? key_pos : key_neg, 0, 1); - joy_axescache[axis].keytime = joytime + 0.5; - } -} - -/* -=========== - IN_JoystickBlockDoubledKeyEvents -=========== -*/ - -static qboolean IN_ReadJoystick (void); -static qboolean IN_JoystickBlockDoubledKeyEvents(int keycode) -{ - int axis; - - if (!joy_axiskeyevents.integer) - return false; - - // block keyevent if it's going to be provided by joystick keyevent system - if (joy_avail) - { - // collect the joystick data, if possible - if (IN_ReadJoystick() != true) - return false; - axis = IN_JoystickGetAxisNum(AxisForward); - if (keycode == K_UPARROW || keycode == K_DOWNARROW) - if (IN_JoystickGetAxis(axis, 1, joy_axiskeyevents_deadzone.value) || joy_axescache[axis].move || joy_axescache[axis].oldmove) - return true; - axis = IN_JoystickGetAxisNum(AxisSide); - if (keycode == K_RIGHTARROW || keycode == K_LEFTARROW) - if (IN_JoystickGetAxis(axis, 1, joy_axiskeyevents_deadzone.value) || joy_axescache[axis].move || joy_axescache[axis].oldmove) - return true; - } - - return false; -} - -/* -=========== - IN_JoyMove -=========== -*/ -static void IN_JoyMove (void) -{ - float speed, aspeed; - float fAxisValue; - int i, mouselook = (in_mlook.state & 1) || freelook.integer, AxisForwardIndex = -1, AxisSideIndex = -1; - - // complete initialization if first time in - // this is needed as cvars are not available at initialization time - if( joy_advancedinit != true ) - { - Joy_AdvancedUpdate_f(); - joy_advancedinit = true; - } - - if (joy_avail) - { - int i, key_index; - DWORD buttonstate, povstate; - - // loop through the joystick buttons - // key a joystick event or auxillary event for higher number buttons for each state change - buttonstate = ji.dwButtons; - for (i=0 ; i < (int) joy_numbuttons ; i++) - { - if ( (buttonstate & (1<