Alibek Omarov
7 years ago
14 changed files with 848 additions and 95 deletions
@ -0,0 +1,676 @@ |
|||||||
|
/*
|
||||||
|
events.c - SDL event system handlers |
||||||
|
Copyright (C) 2015-2017 a1batross |
||||||
|
|
||||||
|
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 3 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef XASH_SDL |
||||||
|
#include <SDL.h> |
||||||
|
|
||||||
|
#include "common.h" |
||||||
|
#include "keydefs.h" |
||||||
|
#include "input.h" |
||||||
|
#include "client.h" |
||||||
|
#include "vgui_draw.h" |
||||||
|
#include "events.h" |
||||||
|
#include "sound.h" |
||||||
|
#include "vid_common.h" |
||||||
|
#include "gl_local.h" |
||||||
|
|
||||||
|
extern convar_t *vid_fullscreen; |
||||||
|
extern convar_t *snd_mute_losefocus; |
||||||
|
static int wheelbutton; |
||||||
|
static SDL_Joystick *joy; |
||||||
|
static SDL_GameController *gamecontroller; |
||||||
|
|
||||||
|
void R_ChangeDisplaySettingsFast( int w, int h ); |
||||||
|
|
||||||
|
/*
|
||||||
|
============= |
||||||
|
SDLash_KeyEvent |
||||||
|
|
||||||
|
============= |
||||||
|
*/ |
||||||
|
static void SDLash_KeyEvent( SDL_KeyboardEvent key, int down ) |
||||||
|
{ |
||||||
|
int keynum = key.keysym.scancode; |
||||||
|
qboolean numLock = SDL_GetModState() & KMOD_NUM; |
||||||
|
|
||||||
|
if( SDL_IsTextInputActive() && down ) |
||||||
|
{ |
||||||
|
if( SDL_GetModState() & KMOD_CTRL ) |
||||||
|
{ |
||||||
|
if( keynum >= SDL_SCANCODE_A && keynum <= SDL_SCANCODE_Z ) |
||||||
|
{ |
||||||
|
keynum = keynum - SDL_SCANCODE_A + 1; |
||||||
|
CL_CharEvent( keynum ); |
||||||
|
} |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#define DECLARE_KEY_RANGE( min, max, repl ) \ |
||||||
|
if( keynum >= (min) && keynum <= (max) ) \ |
||||||
|
{ \ |
||||||
|
keynum = keynum - (min) + (repl); \ |
||||||
|
} |
||||||
|
|
||||||
|
DECLARE_KEY_RANGE( SDL_SCANCODE_A, SDL_SCANCODE_Z, 'a' ) |
||||||
|
else DECLARE_KEY_RANGE( SDL_SCANCODE_1, SDL_SCANCODE_9, '1' ) |
||||||
|
else DECLARE_KEY_RANGE( SDL_SCANCODE_F1, SDL_SCANCODE_F12, K_F1 ) |
||||||
|
#undef DECLARE_KEY_RANGE |
||||||
|
else |
||||||
|
{ |
||||||
|
switch( keynum ) |
||||||
|
{ |
||||||
|
case SDL_SCANCODE_GRAVE: keynum = '`'; break; |
||||||
|
case SDL_SCANCODE_0: keynum = '0'; break; |
||||||
|
case SDL_SCANCODE_BACKSLASH: keynum = '\\'; break; |
||||||
|
case SDL_SCANCODE_LEFTBRACKET: keynum = '['; break; |
||||||
|
case SDL_SCANCODE_RIGHTBRACKET: keynum = ']'; break; |
||||||
|
case SDL_SCANCODE_EQUALS: keynum = '='; break; |
||||||
|
case SDL_SCANCODE_MINUS: keynum = '-'; break; |
||||||
|
case SDL_SCANCODE_TAB: keynum = K_TAB; break; |
||||||
|
case SDL_SCANCODE_RETURN: keynum = K_ENTER; break; |
||||||
|
case SDL_SCANCODE_ESCAPE: keynum = K_ESCAPE; break; |
||||||
|
case SDL_SCANCODE_SPACE: keynum = K_SPACE; break; |
||||||
|
case SDL_SCANCODE_BACKSPACE: keynum = K_BACKSPACE; break; |
||||||
|
case SDL_SCANCODE_UP: keynum = K_UPARROW; break; |
||||||
|
case SDL_SCANCODE_LEFT: keynum = K_LEFTARROW; break; |
||||||
|
case SDL_SCANCODE_DOWN: keynum = K_DOWNARROW; break; |
||||||
|
case SDL_SCANCODE_RIGHT: keynum = K_RIGHTARROW; break; |
||||||
|
case SDL_SCANCODE_LALT: |
||||||
|
case SDL_SCANCODE_RALT: keynum = K_ALT; break; |
||||||
|
case SDL_SCANCODE_LCTRL: |
||||||
|
case SDL_SCANCODE_RCTRL: keynum = K_CTRL; break; |
||||||
|
case SDL_SCANCODE_LSHIFT: |
||||||
|
case SDL_SCANCODE_RSHIFT: keynum = K_SHIFT; break; |
||||||
|
case SDL_SCANCODE_LGUI: |
||||||
|
case SDL_SCANCODE_RGUI: keynum = K_WIN; break; |
||||||
|
case SDL_SCANCODE_INSERT: keynum = K_INS; break; |
||||||
|
case SDL_SCANCODE_DELETE: keynum = K_DEL; break; |
||||||
|
case SDL_SCANCODE_PAGEDOWN: keynum = K_PGDN; break; |
||||||
|
case SDL_SCANCODE_PAGEUP: keynum = K_PGUP; break; |
||||||
|
case SDL_SCANCODE_HOME: keynum = K_HOME; break; |
||||||
|
case SDL_SCANCODE_END: keynum = K_END; break; |
||||||
|
case SDL_SCANCODE_KP_1: keynum = numLock ? '1' : K_KP_END; break; |
||||||
|
case SDL_SCANCODE_KP_2: keynum = numLock ? '2' : K_KP_DOWNARROW; break; |
||||||
|
case SDL_SCANCODE_KP_3: keynum = numLock ? '3' : K_KP_PGDN; break; |
||||||
|
case SDL_SCANCODE_KP_4: keynum = numLock ? '4' : K_KP_LEFTARROW; break; |
||||||
|
case SDL_SCANCODE_KP_5: keynum = numLock ? '5' : K_KP_5; break; |
||||||
|
case SDL_SCANCODE_KP_6: keynum = numLock ? '6' : K_KP_RIGHTARROW; break; |
||||||
|
case SDL_SCANCODE_KP_7: keynum = numLock ? '7' : K_KP_HOME; break; |
||||||
|
case SDL_SCANCODE_KP_8: keynum = numLock ? '8' : K_KP_UPARROW; break; |
||||||
|
case SDL_SCANCODE_KP_9: keynum = numLock ? '9' : K_KP_PGUP; break; |
||||||
|
case SDL_SCANCODE_KP_0: keynum = numLock ? '0' : K_KP_INS; break; |
||||||
|
case SDL_SCANCODE_KP_PERIOD: keynum = K_KP_DEL; break; |
||||||
|
case SDL_SCANCODE_KP_ENTER: keynum = K_KP_ENTER; break; |
||||||
|
case SDL_SCANCODE_KP_PLUS: keynum = K_KP_PLUS; break; |
||||||
|
case SDL_SCANCODE_KP_MINUS: keynum = K_KP_MINUS; break; |
||||||
|
case SDL_SCANCODE_KP_DIVIDE: keynum = K_KP_SLASH; break; |
||||||
|
case SDL_SCANCODE_KP_MULTIPLY: keynum = '*'; break; |
||||||
|
case SDL_SCANCODE_NUMLOCKCLEAR: keynum = K_KP_NUMLOCK; break; |
||||||
|
case SDL_SCANCODE_CAPSLOCK: keynum = K_CAPSLOCK; break; |
||||||
|
case SDL_SCANCODE_APPLICATION: keynum = K_WIN; break; // (compose key) ???
|
||||||
|
case SDL_SCANCODE_SLASH: keynum = '/'; break; |
||||||
|
case SDL_SCANCODE_PERIOD: keynum = '.'; break; |
||||||
|
case SDL_SCANCODE_SEMICOLON: keynum = ';'; break; |
||||||
|
case SDL_SCANCODE_APOSTROPHE: keynum = '\''; break; |
||||||
|
case SDL_SCANCODE_COMMA: keynum = ','; break; |
||||||
|
case SDL_SCANCODE_PRINTSCREEN: |
||||||
|
{ |
||||||
|
host.force_draw_version = true; |
||||||
|
host.force_draw_version_time = host.realtime + FORCE_DRAW_VERSION_TIME; |
||||||
|
break; |
||||||
|
} |
||||||
|
// don't console spam on known functional buttons, but not used in engine
|
||||||
|
case SDL_SCANCODE_MUTE: |
||||||
|
case SDL_SCANCODE_VOLUMEUP: |
||||||
|
case SDL_SCANCODE_VOLUMEDOWN: |
||||||
|
case SDL_SCANCODE_BRIGHTNESSDOWN: |
||||||
|
case SDL_SCANCODE_BRIGHTNESSUP: |
||||||
|
return; |
||||||
|
case SDL_SCANCODE_UNKNOWN: |
||||||
|
{ |
||||||
|
if( down ) MsgDev( D_INFO, "SDLash_KeyEvent: Unknown scancode\n" ); |
||||||
|
return; |
||||||
|
} |
||||||
|
default: |
||||||
|
if( down ) MsgDev( D_INFO, "SDLash_KeyEvent: Unknown key: %s = %i\n", SDL_GetScancodeName( keynum ), keynum ); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Key_Event( keynum, down ); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
============= |
||||||
|
SDLash_MouseEvent |
||||||
|
|
||||||
|
============= |
||||||
|
*/ |
||||||
|
static void SDLash_MouseEvent( SDL_MouseButtonEvent button ) |
||||||
|
{ |
||||||
|
int down = button.type == SDL_MOUSEBUTTONDOWN ? 1 : 0; |
||||||
|
if( in_mouseinitialized && !m_ignore->value && button.which != SDL_TOUCH_MOUSEID ) |
||||||
|
{ |
||||||
|
Key_Event( K_MOUSE1 - 1 + button.button, down ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
============= |
||||||
|
SDLash_InputEvent |
||||||
|
|
||||||
|
============= |
||||||
|
*/ |
||||||
|
static void SDLash_InputEvent( SDL_TextInputEvent input ) |
||||||
|
{ |
||||||
|
int i; |
||||||
|
|
||||||
|
// Pass characters one by one to Con_CharEvent
|
||||||
|
for(i = 0; input.text[i]; ++i) |
||||||
|
{ |
||||||
|
int ch; |
||||||
|
|
||||||
|
if( !Q_stricmp( cl_charset->string, "utf-8" ) ) |
||||||
|
ch = (unsigned char)input.text[i]; |
||||||
|
else |
||||||
|
ch = Con_UtfProcessCharForce( (unsigned char)input.text[i] ); |
||||||
|
|
||||||
|
if( !ch ) |
||||||
|
continue; |
||||||
|
|
||||||
|
CL_CharEvent( ch ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
============= |
||||||
|
SDLash_EnableTextInput |
||||||
|
|
||||||
|
============= |
||||||
|
*/ |
||||||
|
void SDLash_EnableTextInput( int enable, qboolean force ) |
||||||
|
{ |
||||||
|
if( force ) |
||||||
|
{ |
||||||
|
if( enable ) |
||||||
|
SDL_StartTextInput(); |
||||||
|
else |
||||||
|
SDL_StopTextInput(); |
||||||
|
} |
||||||
|
else if( enable ) |
||||||
|
{ |
||||||
|
if( !host.textmode ) |
||||||
|
{ |
||||||
|
SDL_StartTextInput(); |
||||||
|
} |
||||||
|
host.textmode = true; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
SDL_StopTextInput(); |
||||||
|
host.textmode = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
============= |
||||||
|
SDLash_EventFilter |
||||||
|
|
||||||
|
============= |
||||||
|
*/ |
||||||
|
static void SDLash_EventFilter( SDL_Event *event ) |
||||||
|
{ |
||||||
|
static int mdown; |
||||||
|
|
||||||
|
if( wheelbutton ) |
||||||
|
{ |
||||||
|
Key_Event( wheelbutton, false ); |
||||||
|
wheelbutton = 0; |
||||||
|
} |
||||||
|
|
||||||
|
switch ( event->type ) |
||||||
|
{ |
||||||
|
/* Mouse events */ |
||||||
|
case SDL_MOUSEMOTION: |
||||||
|
if( !host.mouse_visible && event->motion.which != SDL_TOUCH_MOUSEID ) |
||||||
|
IN_MouseEvent(); |
||||||
|
#ifdef TOUCHEMU |
||||||
|
if( mdown ) |
||||||
|
IN_TouchEvent( event_motion, 0, |
||||||
|
event->motion.x/scr_width->value, |
||||||
|
event->motion.y/scr_height->value, |
||||||
|
event->motion.xrel/scr_width->value, |
||||||
|
event->motion.yrel/scr_height->value ); |
||||||
|
SDL_ShowCursor( true ); |
||||||
|
#endif |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_MOUSEBUTTONUP: |
||||||
|
#ifdef TOUCHEMU |
||||||
|
mdown = 0; |
||||||
|
IN_TouchEvent( event_up, 0, |
||||||
|
event->button.x/scr_width->value, |
||||||
|
event->button.y/scr_height->value, 0, 0); |
||||||
|
#else |
||||||
|
SDLash_MouseEvent( event->button ); |
||||||
|
#endif |
||||||
|
break; |
||||||
|
case SDL_MOUSEBUTTONDOWN: |
||||||
|
#ifdef TOUCHEMU |
||||||
|
mdown = 1; |
||||||
|
IN_TouchEvent( event_down, 0, |
||||||
|
event->button.x/scr_width->value, |
||||||
|
event->button.y/scr_height->value, 0, 0); |
||||||
|
#else |
||||||
|
SDLash_MouseEvent( event->button ); |
||||||
|
#endif |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_MOUSEWHEEL: |
||||||
|
wheelbutton = event->wheel.y < 0 ? K_MWHEELDOWN : K_MWHEELUP; |
||||||
|
Key_Event( wheelbutton, true ); |
||||||
|
break; |
||||||
|
|
||||||
|
/* Keyboard events */ |
||||||
|
case SDL_KEYDOWN: |
||||||
|
SDLash_KeyEvent( event->key, 1 ); |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_KEYUP: |
||||||
|
SDLash_KeyEvent( event->key, 0 ); |
||||||
|
break; |
||||||
|
|
||||||
|
|
||||||
|
/* Touch events */ |
||||||
|
case SDL_FINGERDOWN: |
||||||
|
case SDL_FINGERUP: |
||||||
|
case SDL_FINGERMOTION: |
||||||
|
{ |
||||||
|
touchEventType type; |
||||||
|
static int scale = 0; |
||||||
|
float x, y, dx, dy; |
||||||
|
|
||||||
|
if( event->type == SDL_FINGERDOWN ) |
||||||
|
type = event_down; |
||||||
|
else if( event->type == SDL_FINGERUP ) |
||||||
|
type = event_up ; |
||||||
|
else if(event->type == SDL_FINGERMOTION ) |
||||||
|
type = event_motion; |
||||||
|
else break; |
||||||
|
|
||||||
|
/*
|
||||||
|
SDL sends coordinates in [0..width],[0..height] values |
||||||
|
on some devices |
||||||
|
*/ |
||||||
|
if( !scale ) |
||||||
|
{ |
||||||
|
if( ( event->tfinger.x > 0 ) && ( event->tfinger.y > 0 ) ) |
||||||
|
{ |
||||||
|
if( ( event->tfinger.x > 2 ) && ( event->tfinger.y > 2 ) ) |
||||||
|
{ |
||||||
|
scale = 2; |
||||||
|
MsgDev( D_INFO, "SDL reports screen coordinates, workaround enabled!\n"); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
scale = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
x = event->tfinger.x; |
||||||
|
y = event->tfinger.y; |
||||||
|
dx = event->tfinger.dx; |
||||||
|
dy = event->tfinger.dy; |
||||||
|
|
||||||
|
if( scale == 2 ) |
||||||
|
{ |
||||||
|
x /= (float)glState.width; |
||||||
|
y /= (float)glState.height; |
||||||
|
dx /= (float)glState.width; |
||||||
|
dy /= (float)glState.height; |
||||||
|
} |
||||||
|
|
||||||
|
IN_TouchEvent( type, event->tfinger.fingerId, x, y, dx, dy ); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* IME */ |
||||||
|
case SDL_TEXTINPUT: |
||||||
|
SDLash_InputEvent( event->text ); |
||||||
|
break; |
||||||
|
|
||||||
|
/* Joystick events */ |
||||||
|
case SDL_JOYAXISMOTION: |
||||||
|
Joy_AxisMotionEvent( event->jaxis.which, event->jaxis.axis, event->jaxis.value ); |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_JOYBALLMOTION: |
||||||
|
Joy_BallMotionEvent( event->jball.which, event->jball.ball, event->jball.xrel, event->jball.yrel ); |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_JOYHATMOTION: |
||||||
|
Joy_HatMotionEvent( event->jhat.which, event->jhat.hat, event->jhat.value ); |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_JOYBUTTONDOWN: |
||||||
|
case SDL_JOYBUTTONUP: |
||||||
|
Joy_ButtonEvent( event->jbutton.which, event->jbutton.button, event->jbutton.state ); |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_JOYDEVICEADDED: |
||||||
|
Joy_AddEvent( event->jdevice.which ); |
||||||
|
break; |
||||||
|
case SDL_JOYDEVICEREMOVED: |
||||||
|
Joy_RemoveEvent( event->jdevice.which ); |
||||||
|
break; |
||||||
|
|
||||||
|
/* GameController API */ |
||||||
|
case SDL_CONTROLLERAXISMOTION: |
||||||
|
if( event->caxis.axis == (Uint8)SDL_CONTROLLER_AXIS_INVALID ) |
||||||
|
break; |
||||||
|
|
||||||
|
// Swap axis to follow default axis binding:
|
||||||
|
// LeftX, LeftY, RightX, RightY, TriggerRight, TriggerLeft
|
||||||
|
if( event->caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT ) |
||||||
|
event->caxis.axis = SDL_CONTROLLER_AXIS_TRIGGERRIGHT; |
||||||
|
else if( event->caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT ) |
||||||
|
event->caxis.axis = SDL_CONTROLLER_AXIS_TRIGGERLEFT; |
||||||
|
|
||||||
|
Joy_AxisMotionEvent( event->caxis.which, event->caxis.axis, event->caxis.value ); |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_CONTROLLERBUTTONDOWN: |
||||||
|
case SDL_CONTROLLERBUTTONUP: |
||||||
|
{ |
||||||
|
static int sdlControllerButtonToEngine[] = |
||||||
|
{ |
||||||
|
K_AUX16, // invalid
|
||||||
|
K_A_BUTTON, K_B_BUTTON, K_X_BUTTON, K_Y_BUTTON, |
||||||
|
K_BACK_BUTTON, K_MODE_BUTTON, K_START_BUTTON, |
||||||
|
K_LSTICK, K_RSTICK, |
||||||
|
K_L1_BUTTON, K_R1_BUTTON, |
||||||
|
K_UPARROW, K_DOWNARROW, K_LEFTARROW, K_RIGHTARROW |
||||||
|
}; |
||||||
|
|
||||||
|
// TODO: Use joyinput funcs, for future multiple gamepads support
|
||||||
|
if( Joy_IsActive() ) |
||||||
|
Key_Event( sdlControllerButtonToEngine[event->cbutton.button], event->cbutton.state ); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
case SDL_CONTROLLERDEVICEADDED: |
||||||
|
Joy_AddEvent( event->cdevice.which ); |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_CONTROLLERDEVICEREMOVED: |
||||||
|
Joy_RemoveEvent( event->cdevice.which ); |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_QUIT: |
||||||
|
Sys_Quit(); |
||||||
|
break; |
||||||
|
|
||||||
|
case SDL_WINDOWEVENT: |
||||||
|
if( event->window.windowID != SDL_GetWindowID( host.hWnd ) ) |
||||||
|
return; |
||||||
|
|
||||||
|
if( ( host.status == HOST_SHUTDOWN ) || |
||||||
|
( host.type == HOST_DEDICATED ) ) |
||||||
|
break; // no need to activate
|
||||||
|
switch( event->window.event ) |
||||||
|
{ |
||||||
|
case SDL_WINDOWEVENT_MOVED: |
||||||
|
if( !vid_fullscreen->value ) |
||||||
|
{ |
||||||
|
Cvar_SetValue( "_window_xpos", (float)event->window.data1 ); |
||||||
|
Cvar_SetValue( "_window_ypos", (float)event->window.data1 ); |
||||||
|
} |
||||||
|
break; |
||||||
|
case SDL_WINDOWEVENT_RESTORED: |
||||||
|
host.status = HOST_FRAME; |
||||||
|
host.force_draw_version = true; |
||||||
|
host.force_draw_version_time = host.realtime + 2; |
||||||
|
if( vid_fullscreen->value ) |
||||||
|
VID_SetMode(); |
||||||
|
break; |
||||||
|
case SDL_WINDOWEVENT_FOCUS_GAINED: |
||||||
|
host.status = HOST_FRAME; |
||||||
|
IN_ActivateMouse(true); |
||||||
|
if( snd_mute_losefocus->value ) |
||||||
|
{ |
||||||
|
S_Activate( true ); |
||||||
|
} |
||||||
|
host.force_draw_version = true; |
||||||
|
host.force_draw_version_time = host.realtime + 2; |
||||||
|
if( vid_fullscreen->value ) |
||||||
|
VID_SetMode(); |
||||||
|
break; |
||||||
|
case SDL_WINDOWEVENT_MINIMIZED: |
||||||
|
host.status = HOST_SLEEP; |
||||||
|
VID_RestoreScreenResolution(); |
||||||
|
break; |
||||||
|
case SDL_WINDOWEVENT_FOCUS_LOST: |
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE |
||||||
|
{ |
||||||
|
// Keep running if ftp server enabled
|
||||||
|
void IOS_StartBackgroundTask( void ); |
||||||
|
IOS_StartBackgroundTask(); |
||||||
|
} |
||||||
|
#endif |
||||||
|
host.status = HOST_NOFOCUS; |
||||||
|
IN_DeactivateMouse(); |
||||||
|
if( snd_mute_losefocus->value ) |
||||||
|
{ |
||||||
|
S_Activate( false ); |
||||||
|
} |
||||||
|
host.force_draw_version = true; |
||||||
|
host.force_draw_version_time = host.realtime + 1; |
||||||
|
VID_RestoreScreenResolution(); |
||||||
|
break; |
||||||
|
case SDL_WINDOWEVENT_CLOSE: |
||||||
|
Sys_Quit(); |
||||||
|
break; |
||||||
|
case SDL_WINDOWEVENT_RESIZED: |
||||||
|
if( vid_fullscreen->value ) break; |
||||||
|
Cvar_SetValue( "vid_mode", VID_NOMODE ); // no mode
|
||||||
|
R_ChangeDisplaySettingsFast( event->window.data1, |
||||||
|
event->window.data2 ); |
||||||
|
break; |
||||||
|
case SDL_WINDOWEVENT_MAXIMIZED: |
||||||
|
{ |
||||||
|
int w, h; |
||||||
|
if( vid_fullscreen->value ) break; |
||||||
|
Cvar_SetValue( "vid_mode", VID_NOMODE ); // no mode
|
||||||
|
|
||||||
|
SDL_GL_GetDrawableSize( host.hWnd, &w, &h ); |
||||||
|
R_ChangeDisplaySettingsFast( w, h ); |
||||||
|
break; |
||||||
|
} |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
============= |
||||||
|
SDLash_RunEvents |
||||||
|
|
||||||
|
============= |
||||||
|
*/ |
||||||
|
void SDLash_RunEvents( void ) |
||||||
|
{ |
||||||
|
SDL_Event event; |
||||||
|
|
||||||
|
while( !host.crashed && !host.shutdown_issued && SDL_PollEvent( &event ) ) |
||||||
|
SDLash_EventFilter( &event ); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
============= |
||||||
|
SDLash_JoyInit_Old |
||||||
|
|
||||||
|
============= |
||||||
|
*/ |
||||||
|
static int SDLash_JoyInit_Old( int numjoy ) |
||||||
|
{ |
||||||
|
int num; |
||||||
|
int i; |
||||||
|
|
||||||
|
MsgDev( D_INFO, "Joystick: SDL\n" ); |
||||||
|
|
||||||
|
if( SDL_WasInit( SDL_INIT_JOYSTICK ) != SDL_INIT_JOYSTICK && |
||||||
|
SDL_InitSubSystem( SDL_INIT_JOYSTICK ) ) |
||||||
|
{ |
||||||
|
MsgDev( D_INFO, "Failed to initialize SDL Joysitck: %s\n", SDL_GetError() ); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
if( joy ) |
||||||
|
{ |
||||||
|
SDL_JoystickClose( joy ); |
||||||
|
} |
||||||
|
|
||||||
|
num = SDL_NumJoysticks(); |
||||||
|
|
||||||
|
if( num > 0 ) |
||||||
|
MsgDev( D_INFO, "%i joysticks found:\n", num ); |
||||||
|
else |
||||||
|
{ |
||||||
|
MsgDev( D_INFO, "No joystick found.\n" ); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
for( i = 0; i < num; i++ ) |
||||||
|
MsgDev( D_INFO, "%i\t: %s\n", i, SDL_JoystickNameForIndex( i ) ); |
||||||
|
|
||||||
|
MsgDev( D_INFO, "Pass +set joy_index N to command line, where N is number, to select active joystick\n" ); |
||||||
|
|
||||||
|
joy = SDL_JoystickOpen( numjoy ); |
||||||
|
|
||||||
|
if( !joy ) |
||||||
|
{ |
||||||
|
MsgDev( D_INFO, "Failed to select joystick: %s\n", SDL_GetError( ) ); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
MsgDev( D_INFO, "Selected joystick: %s\n" |
||||||
|
"\tAxes: %i\n" |
||||||
|
"\tHats: %i\n" |
||||||
|
"\tButtons: %i\n" |
||||||
|
"\tBalls: %i\n", |
||||||
|
SDL_JoystickName( joy ), SDL_JoystickNumAxes( joy ), SDL_JoystickNumHats( joy ), |
||||||
|
SDL_JoystickNumButtons( joy ), SDL_JoystickNumBalls( joy ) ); |
||||||
|
|
||||||
|
SDL_GameControllerEventState( SDL_DISABLE ); |
||||||
|
SDL_JoystickEventState( SDL_ENABLE ); |
||||||
|
|
||||||
|
return num; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
============= |
||||||
|
SDLash_JoyInit_New |
||||||
|
|
||||||
|
============= |
||||||
|
*/ |
||||||
|
static int SDLash_JoyInit_New( int numjoy ) |
||||||
|
{ |
||||||
|
int temp, num; |
||||||
|
int i; |
||||||
|
|
||||||
|
MsgDev( D_INFO, "Joystick: SDL GameController API\n" ); |
||||||
|
|
||||||
|
if( SDL_WasInit( SDL_INIT_GAMECONTROLLER ) != SDL_INIT_GAMECONTROLLER && |
||||||
|
SDL_InitSubSystem( SDL_INIT_GAMECONTROLLER ) ) |
||||||
|
{ |
||||||
|
MsgDev( D_INFO, "Failed to initialize SDL GameController API: %s\n", SDL_GetError() ); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
// chance to add mappings from file
|
||||||
|
SDL_GameControllerAddMappingsFromFile( "controllermappings.txt" ); |
||||||
|
|
||||||
|
if( gamecontroller ) |
||||||
|
{ |
||||||
|
SDL_GameControllerClose( gamecontroller ); |
||||||
|
} |
||||||
|
|
||||||
|
temp = SDL_NumJoysticks(); |
||||||
|
num = 0; |
||||||
|
|
||||||
|
for( i = 0; i < temp; i++ ) |
||||||
|
{ |
||||||
|
if( SDL_IsGameController( i )) |
||||||
|
num++; |
||||||
|
} |
||||||
|
|
||||||
|
if( num > 0 ) |
||||||
|
MsgDev( D_INFO, "%i joysticks found:\n", num ); |
||||||
|
else |
||||||
|
{ |
||||||
|
MsgDev( D_INFO, "No joystick found.\n" ); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
for( i = 0; i < num; i++ ) |
||||||
|
MsgDev( D_INFO, "%i\t: %s\n", i, SDL_GameControllerNameForIndex( i ) ); |
||||||
|
|
||||||
|
MsgDev( D_INFO, "Pass +set joy_index N to command line, where N is number, to select active joystick\n" ); |
||||||
|
|
||||||
|
gamecontroller = SDL_GameControllerOpen( numjoy ); |
||||||
|
|
||||||
|
if( !gamecontroller ) |
||||||
|
{ |
||||||
|
MsgDev( D_INFO, "Failed to select joystick: %s\n", SDL_GetError( ) ); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
// was added in SDL2-2.0.6, allow build with earlier versions just in case
|
||||||
|
#if SDL_MAJOR_VERSION > 2 || SDL_MINOR_VERSION > 0 || SDL_PATCHLEVEL >= 6 |
||||||
|
MsgDev( D_INFO, "Selected joystick: %s (%i:%i:%i)\n", |
||||||
|
SDL_GameControllerName( gamecontroller ), |
||||||
|
SDL_GameControllerGetVendor( gamecontroller ), |
||||||
|
SDL_GameControllerGetProduct( gamecontroller ), |
||||||
|
SDL_GameControllerGetProductVersion( gamecontroller )); |
||||||
|
#endif |
||||||
|
SDL_GameControllerEventState( SDL_ENABLE ); |
||||||
|
SDL_JoystickEventState( SDL_DISABLE ); |
||||||
|
|
||||||
|
return num; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
============= |
||||||
|
SDLash_JoyInit |
||||||
|
|
||||||
|
============= |
||||||
|
*/ |
||||||
|
int SDLash_JoyInit( int numjoy ) |
||||||
|
{ |
||||||
|
// SDL_Joystick is now an old API
|
||||||
|
// SDL_GameController is preferred
|
||||||
|
if( Sys_CheckParm( "-sdl_joy_old_api" ) ) |
||||||
|
return SDLash_JoyInit_Old(numjoy); |
||||||
|
|
||||||
|
return SDLash_JoyInit_New(numjoy); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
#endif // XASH_SDL
|
@ -0,0 +1,27 @@ |
|||||||
|
/*
|
||||||
|
events.h - SDL event system handlers |
||||||
|
Copyright (C) 2015-2017 a1batross |
||||||
|
|
||||||
|
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 3 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#pragma once |
||||||
|
#ifndef KEYWRAPPER_H |
||||||
|
#define KEYWRAPPER_H |
||||||
|
|
||||||
|
#ifdef XASH_SDL |
||||||
|
|
||||||
|
void SDLash_RunEvents( void ); |
||||||
|
void SDLash_EnableTextInput( int enable, qboolean force ); |
||||||
|
int SDLash_JoyInit( int numjoy ); // pass -1 to init every joystick
|
||||||
|
|
||||||
|
#endif // XASH_SDL
|
||||||
|
#endif // KEYWRAPPER_H
|
Loading…
Reference in new issue