mirror of
https://github.com/blendogames/quadrilateralcowboy.git
synced 2024-11-23 20:43:05 +00:00
904 lines
19 KiB
C++
904 lines
19 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 GPL Source Code
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
|
|
|
Doom 3 Source Code 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.
|
|
|
|
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#ifdef USE_SDL
|
|
|
|
#include "../idlib/precompiled.h"
|
|
|
|
#include "../idlib/containers/List.h"
|
|
#include "../idlib/Heap.h"
|
|
#include "../framework/Common.h"
|
|
#include "../framework/KeyInput.h"
|
|
#include "../renderer/RenderSystem.h"
|
|
#include "../renderer/tr_local.h"
|
|
|
|
#include "../sys/sys_public.h"
|
|
|
|
#ifdef __WINDOWS__
|
|
#include "win32/win_local.h"
|
|
|
|
#include <SDL_syswm.h>
|
|
#endif
|
|
|
|
extern bool g_inputGrabbed;
|
|
|
|
const char *kbdNames[] = {
|
|
"english", "french", "german", "italian", "spanish", "turkish", "norwegian", NULL
|
|
};
|
|
|
|
idCVar in_kbd("in_kbd", "english", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_NOCHEAT, "keyboard layout", kbdNames, idCmdSystem::ArgCompletion_String<kbdNames> );
|
|
|
|
struct kbd_poll_t {
|
|
int key;
|
|
bool state;
|
|
|
|
kbd_poll_t() {
|
|
}
|
|
|
|
kbd_poll_t(int k, bool s) {
|
|
key = k;
|
|
state = s;
|
|
}
|
|
};
|
|
|
|
struct mouse_poll_t {
|
|
int action;
|
|
int value;
|
|
|
|
mouse_poll_t() {
|
|
}
|
|
|
|
mouse_poll_t(int a, int v) {
|
|
action = a;
|
|
value = v;
|
|
}
|
|
};
|
|
|
|
struct joystick_poll_t {
|
|
int action;
|
|
int value;
|
|
|
|
joystick_poll_t() {
|
|
}
|
|
|
|
joystick_poll_t(int a, int v) {
|
|
action = a;
|
|
value = v;
|
|
}
|
|
};
|
|
|
|
static idList<kbd_poll_t> kbd_polls;
|
|
static idList<mouse_poll_t> mouse_polls;
|
|
static idList<joystick_poll_t> joystick_polls;
|
|
|
|
static bool buttonStates[K_LAST_KEY];
|
|
static int joyAxis[MAX_JOYSTICK_AXIS];
|
|
|
|
static idList<sysEvent_t> event_overflow;
|
|
|
|
static byte mapkey(SDL_Keycode key) {
|
|
switch (key) {
|
|
case SDLK_BACKSPACE:
|
|
return K_BACKSPACE;
|
|
case SDLK_PAUSE:
|
|
return K_PAUSE;
|
|
}
|
|
|
|
if (key <= SDLK_z)
|
|
return key & 0xff;
|
|
|
|
switch (key) {
|
|
case SDLK_APPLICATION:
|
|
return K_COMMAND;
|
|
case SDLK_CAPSLOCK:
|
|
return K_CAPSLOCK;
|
|
case SDLK_SCROLLLOCK:
|
|
return K_SCROLL;
|
|
case SDLK_POWER:
|
|
return K_POWER;
|
|
|
|
case SDLK_UP:
|
|
return K_UPARROW;
|
|
case SDLK_DOWN:
|
|
return K_DOWNARROW;
|
|
case SDLK_LEFT:
|
|
return K_LEFTARROW;
|
|
case SDLK_RIGHT:
|
|
return K_RIGHTARROW;
|
|
|
|
case SDLK_LGUI:
|
|
return K_LWIN;
|
|
case SDLK_RGUI:
|
|
return K_RWIN;
|
|
case SDLK_MENU:
|
|
return K_MENU;
|
|
|
|
case SDLK_LALT:
|
|
case SDLK_RALT:
|
|
return K_ALT;
|
|
case SDLK_RCTRL:
|
|
case SDLK_LCTRL:
|
|
return K_CTRL;
|
|
case SDLK_RSHIFT:
|
|
case SDLK_LSHIFT:
|
|
return K_SHIFT;
|
|
case SDLK_INSERT:
|
|
return K_INS;
|
|
case SDLK_DELETE:
|
|
return K_DEL;
|
|
case SDLK_PAGEDOWN:
|
|
return K_PGDN;
|
|
case SDLK_PAGEUP:
|
|
return K_PGUP;
|
|
case SDLK_HOME:
|
|
return K_HOME;
|
|
case SDLK_END:
|
|
return K_END;
|
|
|
|
case SDLK_F1:
|
|
return K_F1;
|
|
case SDLK_F2:
|
|
return K_F2;
|
|
case SDLK_F3:
|
|
return K_F3;
|
|
case SDLK_F4:
|
|
return K_F4;
|
|
case SDLK_F5:
|
|
return K_F5;
|
|
case SDLK_F6:
|
|
return K_F6;
|
|
case SDLK_F7:
|
|
return K_F7;
|
|
case SDLK_F8:
|
|
return K_F8;
|
|
case SDLK_F9:
|
|
return K_F9;
|
|
case SDLK_F10:
|
|
return K_F10;
|
|
case SDLK_F11:
|
|
return K_F11;
|
|
case SDLK_F12:
|
|
return K_F12;
|
|
// K_INVERTED_EXCLAMATION;
|
|
case SDLK_F13:
|
|
return K_F13;
|
|
case SDLK_F14:
|
|
return K_F14;
|
|
case SDLK_F15:
|
|
return K_F15;
|
|
|
|
case SDLK_KP_7:
|
|
return K_KP_HOME;
|
|
case SDLK_KP_8:
|
|
return K_KP_UPARROW;
|
|
case SDLK_KP_9:
|
|
return K_KP_PGUP;
|
|
case SDLK_KP_4:
|
|
return K_KP_LEFTARROW;
|
|
case SDLK_KP_5:
|
|
return K_KP_5;
|
|
case SDLK_KP_6:
|
|
return K_KP_RIGHTARROW;
|
|
case SDLK_KP_1:
|
|
return K_KP_END;
|
|
case SDLK_KP_2:
|
|
return K_KP_DOWNARROW;
|
|
case SDLK_KP_3:
|
|
return K_KP_PGDN;
|
|
case SDLK_KP_ENTER:
|
|
return K_KP_ENTER;
|
|
case SDLK_KP_0:
|
|
return K_KP_INS;
|
|
case SDLK_KP_PERIOD:
|
|
return K_KP_DEL;
|
|
case SDLK_KP_DIVIDE:
|
|
return K_KP_SLASH;
|
|
// K_SUPERSCRIPT_TWO;
|
|
case SDLK_KP_MINUS:
|
|
return K_KP_MINUS;
|
|
// K_ACUTE_ACCENT;
|
|
case SDLK_KP_PLUS:
|
|
return K_KP_PLUS;
|
|
case SDLK_NUMLOCKCLEAR:
|
|
return K_KP_NUMLOCK;
|
|
case SDLK_KP_MULTIPLY:
|
|
return K_KP_STAR;
|
|
case SDLK_KP_EQUALS:
|
|
return K_KP_EQUALS;
|
|
|
|
// K_MASCULINE_ORDINATOR;
|
|
// K_GRAVE_A;
|
|
// K_AUX1;
|
|
// K_CEDILLA_C;
|
|
// K_GRAVE_E;
|
|
// K_AUX2;
|
|
// K_AUX3;
|
|
// K_AUX4;
|
|
// K_GRAVE_I;
|
|
// K_AUX5;
|
|
// K_AUX6;
|
|
// K_AUX7;
|
|
// K_AUX8;
|
|
// K_TILDE_N;
|
|
// K_GRAVE_O;
|
|
// K_AUX9;
|
|
// K_AUX10;
|
|
// K_AUX11;
|
|
// K_AUX12;
|
|
// K_AUX13;
|
|
// K_AUX14;
|
|
// K_GRAVE_U;
|
|
// K_AUX15;
|
|
// K_AUX16;
|
|
|
|
case SDLK_PRINTSCREEN:
|
|
return K_PRINT_SCR;
|
|
case SDLK_MODE:
|
|
return K_RIGHT_ALT;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static sys_jEvents mapjoybutton(SDL_GameControllerButton button) {
|
|
|
|
switch (button)
|
|
{
|
|
case SDL_CONTROLLER_BUTTON_A:
|
|
return J_ACTION1;
|
|
case SDL_CONTROLLER_BUTTON_B:
|
|
return J_ACTION2;
|
|
case SDL_CONTROLLER_BUTTON_X:
|
|
return J_ACTION3;
|
|
case SDL_CONTROLLER_BUTTON_Y:
|
|
return J_ACTION4;
|
|
case SDL_CONTROLLER_BUTTON_BACK:
|
|
return J_ACTION10;
|
|
case SDL_CONTROLLER_BUTTON_GUIDE:
|
|
// TODO:
|
|
break;
|
|
case SDL_CONTROLLER_BUTTON_START:
|
|
return J_ACTION9;
|
|
case SDL_CONTROLLER_BUTTON_LEFTSTICK:
|
|
return J_ACTION7;
|
|
case SDL_CONTROLLER_BUTTON_RIGHTSTICK:
|
|
return J_ACTION8;
|
|
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
|
|
return J_ACTION5;
|
|
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
|
|
return J_ACTION6;
|
|
case SDL_CONTROLLER_BUTTON_DPAD_UP:
|
|
return J_DPAD_UP;
|
|
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
|
|
return J_DPAD_DOWN;
|
|
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
|
|
return J_DPAD_LEFT;
|
|
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
|
|
return J_DPAD_RIGHT;
|
|
default:
|
|
common->Warning("unknown game controller button %u", button);
|
|
break;
|
|
}
|
|
|
|
return MAX_JOY_EVENT;
|
|
}
|
|
|
|
static sys_jEvents mapjoyaxis(SDL_GameControllerAxis axis) {
|
|
|
|
switch (axis)
|
|
{
|
|
case SDL_CONTROLLER_AXIS_LEFTX:
|
|
return J_AXIS_LEFT_X;
|
|
case SDL_CONTROLLER_AXIS_LEFTY:
|
|
return J_AXIS_LEFT_Y;
|
|
case SDL_CONTROLLER_AXIS_RIGHTX:
|
|
return J_AXIS_RIGHT_X;
|
|
case SDL_CONTROLLER_AXIS_RIGHTY:
|
|
return J_AXIS_RIGHT_Y;
|
|
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
|
return J_AXIS_LEFT_TRIG;
|
|
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
|
return J_AXIS_RIGHT_TRIG;
|
|
default:
|
|
common->Warning("unknown game controller axis %u", axis);
|
|
break;
|
|
}
|
|
|
|
return J_AXIS_MAX;
|
|
}
|
|
|
|
static void PushConsoleEvent(const char *s) {
|
|
char *b;
|
|
size_t len;
|
|
|
|
len = strlen(s) + 1;
|
|
b = (char *)Mem_Alloc(len);
|
|
strcpy(b, s);
|
|
|
|
SDL_Event event;
|
|
|
|
event.type = SDL_USEREVENT;
|
|
event.user.code = SE_CONSOLE;
|
|
event.user.data1 = (void *)len;
|
|
event.user.data2 = b;
|
|
|
|
SDL_PushEvent(&event);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Sys_InitInput
|
|
=================
|
|
*/
|
|
void Sys_InitInput() {
|
|
kbd_polls.SetGranularity(64);
|
|
mouse_polls.SetGranularity(64);
|
|
joystick_polls.SetGranularity(64);
|
|
|
|
event_overflow.SetGranularity(64);
|
|
|
|
memset( buttonStates, 0, sizeof( buttonStates ) );
|
|
memset( joyAxis, 0, sizeof( joyAxis ) );
|
|
|
|
in_kbd.SetModified();
|
|
|
|
const int NumJoysticks = SDL_NumJoysticks();
|
|
for( int i = 0; i < NumJoysticks; ++i )
|
|
{
|
|
SDL_GameControllerOpen( i );
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Sys_ShutdownInput
|
|
=================
|
|
*/
|
|
void Sys_ShutdownInput() {
|
|
kbd_polls.Clear();
|
|
mouse_polls.Clear();
|
|
joystick_polls.Clear();
|
|
event_overflow.Clear();
|
|
}
|
|
|
|
/*
|
|
===========
|
|
Sys_InitScanTable
|
|
===========
|
|
*/
|
|
// Windows has its own version due to the tools
|
|
#ifndef _WIN32
|
|
void Sys_InitScanTable() {
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
===============
|
|
Sys_GetConsoleKey
|
|
===============
|
|
*/
|
|
unsigned char Sys_GetConsoleKey(bool shifted) {
|
|
static unsigned char keys[2] = { '`', '~' };
|
|
|
|
if (in_kbd.IsModified()) {
|
|
idStr lang = in_kbd.GetString();
|
|
|
|
if (lang.Length()) {
|
|
if (!lang.Icmp("french")) {
|
|
keys[0] = '<';
|
|
keys[1] = '>';
|
|
} else if (!lang.Icmp("german")) {
|
|
keys[0] = '^';
|
|
keys[1] = 176; // °
|
|
} else if (!lang.Icmp("italian")) {
|
|
keys[0] = '\\';
|
|
keys[1] = '|';
|
|
} else if (!lang.Icmp("spanish")) {
|
|
keys[0] = 186; // º
|
|
keys[1] = 170; // ª
|
|
} else if (!lang.Icmp("turkish")) {
|
|
keys[0] = '"';
|
|
keys[1] = 233; // é
|
|
} else if (!lang.Icmp("norwegian")) {
|
|
keys[0] = 124; // |
|
|
keys[1] = 167; // §
|
|
}
|
|
}
|
|
|
|
in_kbd.ClearModified();
|
|
}
|
|
|
|
return shifted ? keys[1] : keys[0];
|
|
}
|
|
|
|
/*
|
|
===============
|
|
Sys_MapCharForKey
|
|
===============
|
|
*/
|
|
unsigned char Sys_MapCharForKey(int key) {
|
|
return key & 0xff;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
Sys_GrabMouseCursor
|
|
===============
|
|
*/
|
|
void Sys_GrabMouseCursor(bool grabIt) {
|
|
int flags;
|
|
|
|
if (grabIt)
|
|
flags = GRAB_ENABLE | GRAB_HIDECURSOR;
|
|
else
|
|
flags = 0;
|
|
|
|
GLimp_GrabInput(flags);
|
|
}
|
|
|
|
|
|
void PushButton( int key, bool value ) {
|
|
// So we don't keep sending the same SE_KEY message over and over again
|
|
if ( buttonStates[key] != value ) {
|
|
buttonStates[key] = value;
|
|
sysEvent_t res = { SE_KEY, key, value ? 1 : 0, 0, NULL };
|
|
event_overflow.Append(res);
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_GetEvent
|
|
================
|
|
*/
|
|
sysEvent_t Sys_GetEvent() {
|
|
SDL_Event ev;
|
|
sysEvent_t res = { };
|
|
byte key;
|
|
|
|
static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL };
|
|
|
|
// process any overflow.
|
|
if (event_overflow.Num() > 0)
|
|
{
|
|
res = event_overflow[0];
|
|
event_overflow.RemoveIndex(0);
|
|
return res;
|
|
}
|
|
|
|
// overflow text input.
|
|
static char *s = NULL;
|
|
static size_t s_pos = 0;
|
|
|
|
if (s) {
|
|
res.evType = SE_CHAR;
|
|
res.evValue = s[s_pos];
|
|
|
|
s_pos++;
|
|
if (!s[s_pos]) {
|
|
free(s);
|
|
s = NULL;
|
|
s_pos = 0;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static byte c = 0;
|
|
|
|
if (c) {
|
|
res.evType = SE_CHAR;
|
|
res.evValue = c;
|
|
|
|
c = 0;
|
|
|
|
return res;
|
|
}
|
|
|
|
bool getNext = true;
|
|
while (SDL_PollEvent(&ev) && getNext) {
|
|
getNext = false;
|
|
switch (ev.type) {
|
|
#ifdef __WINDOWS__ // on windows we need to grab the hwnd.
|
|
case SDL_SYSWMEVENT:
|
|
if (win32.hWnd == NULL)
|
|
{
|
|
win32.hWnd = ev.syswm.msg->msg.win.hwnd;
|
|
}
|
|
getNext = true; // try to get a decent event.
|
|
break;
|
|
#endif
|
|
case SDL_WINDOWEVENT:
|
|
switch (ev.window.event) {
|
|
case SDL_WINDOWEVENT_FOCUS_GAINED: {
|
|
// unset modifier, in case alt-tab was used to leave window and ALT is still set
|
|
// as that can cause fullscreen-toggling when pressing enter...
|
|
SDL_Keymod currentmod = SDL_GetModState();
|
|
|
|
int newmod = KMOD_NONE;
|
|
if (currentmod & KMOD_CAPS) // preserve capslock
|
|
newmod |= KMOD_CAPS;
|
|
|
|
SDL_SetModState((SDL_Keymod)newmod);
|
|
} // new context because visual studio complains about newmod and currentmod not initialized because of the case SDL_WINDOWEVENT_FOCUS_LOST
|
|
|
|
GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR);
|
|
break;
|
|
case SDL_WINDOWEVENT_FOCUS_LOST:
|
|
GLimp_GrabInput(0);
|
|
break;
|
|
}
|
|
|
|
return res_none;
|
|
|
|
case SDL_KEYDOWN:
|
|
if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) {
|
|
cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen());
|
|
PushConsoleEvent("vid_restart");
|
|
return res_none;
|
|
}
|
|
|
|
// fall through
|
|
case SDL_KEYUP:
|
|
key = mapkey(ev.key.keysym.sym);
|
|
if(!key) {
|
|
if (ev.key.keysym.scancode == SDL_SCANCODE_GRAVE) {
|
|
key = Sys_GetConsoleKey(true);
|
|
} else {
|
|
if (ev.type == SDL_KEYDOWN) {
|
|
common->Warning("unmapped SDL key %d", ev.key.keysym.sym);
|
|
getNext = true; // try to get a decent event.
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
res.evType = SE_KEY;
|
|
res.evValue = key;
|
|
res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0;
|
|
|
|
kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED));
|
|
|
|
if ( (key == K_BACKSPACE && ev.key.state == SDL_PRESSED)
|
|
|| SDL_GetEventState(SDL_TEXTINPUT) == SDL_DISABLE)
|
|
c = key;
|
|
|
|
return res;
|
|
|
|
case SDL_TEXTINPUT:
|
|
if (ev.text.text && *ev.text.text) {
|
|
|
|
res.evType = SE_CHAR;
|
|
res.evValue = *ev.text.text;
|
|
|
|
// if there are more characters hold onto them for later events.
|
|
if (ev.text.text[1] != 0)
|
|
s = strdup(ev.text.text+1);
|
|
|
|
return res;
|
|
}
|
|
|
|
getNext = true; // try to get a decent event.
|
|
break;
|
|
|
|
case SDL_MOUSEMOTION:
|
|
if (g_inputGrabbed)
|
|
{
|
|
res.evType = SE_MOUSE;
|
|
|
|
res.evValue = ev.motion.xrel;
|
|
res.evValue2 = ev.motion.yrel;
|
|
|
|
mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel));
|
|
mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel));
|
|
|
|
return res;
|
|
}
|
|
|
|
getNext = true;
|
|
break;
|
|
|
|
case SDL_MOUSEWHEEL:
|
|
if (g_inputGrabbed)
|
|
{
|
|
res.evType = SE_KEY;
|
|
|
|
if (ev.wheel.y > 0) {
|
|
res.evValue = K_MWHEELUP;
|
|
mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1));
|
|
} else {
|
|
res.evValue = K_MWHEELDOWN;
|
|
mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1));
|
|
}
|
|
|
|
res.evValue2 = 1;
|
|
|
|
return res;
|
|
}
|
|
|
|
getNext = true;
|
|
break;
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
case SDL_MOUSEBUTTONUP:
|
|
if (g_inputGrabbed)
|
|
{
|
|
res.evType = SE_KEY;
|
|
|
|
switch (ev.button.button) {
|
|
case SDL_BUTTON_LEFT:
|
|
res.evValue = K_MOUSE1;
|
|
mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0));
|
|
break;
|
|
case SDL_BUTTON_MIDDLE:
|
|
res.evValue = K_MOUSE3;
|
|
mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0));
|
|
break;
|
|
case SDL_BUTTON_RIGHT:
|
|
res.evValue = K_MOUSE2;
|
|
mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0));
|
|
break;
|
|
}
|
|
|
|
res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0;
|
|
|
|
return res;
|
|
}
|
|
|
|
getNext = true;
|
|
break;
|
|
|
|
case SDL_CONTROLLERBUTTONDOWN:
|
|
case SDL_CONTROLLERBUTTONUP:
|
|
{
|
|
sys_jEvents jEvent = mapjoybutton( (SDL_GameControllerButton)ev.cbutton.button);
|
|
joystick_polls.Append(joystick_poll_t( jEvent,
|
|
ev.cbutton.state == SDL_PRESSED ? 1 : 0) );
|
|
|
|
res.evType = SE_KEY;
|
|
res.evValue2 = ev.cbutton.state == SDL_PRESSED ? 1 : 0;
|
|
if ( ( jEvent >= J_ACTION1 ) && ( jEvent <= J_ACTION_MAX ) ) {
|
|
res.evValue = K_JOY1 + ( jEvent - J_ACTION1 );
|
|
return res;
|
|
} else if ( ( jEvent >= J_DPAD_UP ) && ( jEvent <= J_DPAD_RIGHT ) ) {
|
|
res.evValue = K_JOY_DPAD_UP + ( jEvent - J_DPAD_UP );
|
|
return res;
|
|
}
|
|
|
|
getNext = true; // try to get a decent event.
|
|
}
|
|
break;
|
|
|
|
case SDL_CONTROLLERAXISMOTION:
|
|
{
|
|
const int range = 16384;
|
|
|
|
sys_jEvents jEvent = mapjoyaxis( (SDL_GameControllerAxis)ev.caxis.axis);
|
|
joystick_polls.Append(joystick_poll_t( jEvent, ev.caxis.value) );
|
|
|
|
if ( jEvent == J_AXIS_LEFT_X ) {
|
|
PushButton( K_JOY_STICK1_LEFT, ( ev.caxis.value < -range ) );
|
|
PushButton( K_JOY_STICK1_RIGHT, ( ev.caxis.value > range ) );
|
|
} else if ( jEvent == J_AXIS_LEFT_Y ) {
|
|
PushButton( K_JOY_STICK1_UP, ( ev.caxis.value < -range ) );
|
|
PushButton( K_JOY_STICK1_DOWN, ( ev.caxis.value > range ) );
|
|
} else if ( jEvent == J_AXIS_RIGHT_X ) {
|
|
PushButton( K_JOY_STICK2_LEFT, ( ev.caxis.value < -range ) );
|
|
PushButton( K_JOY_STICK2_RIGHT, ( ev.caxis.value > range ) );
|
|
} else if ( jEvent == J_AXIS_RIGHT_Y ) {
|
|
PushButton( K_JOY_STICK2_UP, ( ev.caxis.value < -range ) );
|
|
PushButton( K_JOY_STICK2_DOWN, ( ev.caxis.value > range ) );
|
|
} else if ( jEvent == J_AXIS_LEFT_TRIG ) {
|
|
PushButton( K_JOY_TRIGGER1, ( ev.caxis.value > range ) );
|
|
} else if ( jEvent == J_AXIS_RIGHT_TRIG ) {
|
|
PushButton( K_JOY_TRIGGER2, ( ev.caxis.value > range ) );
|
|
}
|
|
if ( jEvent >= J_AXIS_MIN && jEvent <= J_AXIS_MAX ) {
|
|
int axis = jEvent - J_AXIS_MIN;
|
|
int percent = ( ev.caxis.value * 16 ) / range;
|
|
if ( joyAxis[axis] != percent ) {
|
|
joyAxis[axis] = percent;
|
|
res.evType = SE_JOYSTICK;
|
|
res.evValue = axis;
|
|
res.evValue2 = percent;
|
|
return res;
|
|
}
|
|
}
|
|
|
|
getNext = true; // try to get a decent event.
|
|
}
|
|
break;
|
|
|
|
case SDL_JOYDEVICEADDED:
|
|
SDL_GameControllerOpen( ev.jdevice.which );
|
|
// TODO: hot swapping maybe.
|
|
//lbOnControllerPlugIn(event.jdevice.which);
|
|
break;
|
|
|
|
case SDL_JOYDEVICEREMOVED:
|
|
// TODO: hot swapping maybe.
|
|
//lbOnControllerUnPlug(event.jdevice.which);
|
|
break;
|
|
|
|
case SDL_QUIT:
|
|
PushConsoleEvent("quit");
|
|
return res_none;
|
|
|
|
case SDL_USEREVENT:
|
|
switch (ev.user.code) {
|
|
case SE_CONSOLE:
|
|
res.evType = SE_CONSOLE;
|
|
res.evPtrLength = (intptr_t)ev.user.data1;
|
|
res.evPtr = ev.user.data2;
|
|
return res;
|
|
default:
|
|
common->Warning("unknown user event %u", ev.user.code);
|
|
getNext = true; // try to get a decent event.
|
|
break;
|
|
}
|
|
default:
|
|
getNext = true; // try to get a decent event.
|
|
break;
|
|
}
|
|
}
|
|
|
|
return res_none;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_ClearEvents
|
|
================
|
|
*/
|
|
void Sys_ClearEvents() {
|
|
SDL_Event ev;
|
|
|
|
while (SDL_PollEvent(&ev))
|
|
;
|
|
|
|
kbd_polls.SetNum(0, false);
|
|
mouse_polls.SetNum(0, false);
|
|
joystick_polls.SetNum(0, false);
|
|
|
|
memset( buttonStates, 0, sizeof( buttonStates ) );
|
|
memset( joyAxis, 0, sizeof( joyAxis ) );
|
|
|
|
event_overflow.SetNum(0, false);
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_GenerateEvents
|
|
================
|
|
*/
|
|
void Sys_GenerateEvents() {
|
|
char *s = Sys_ConsoleInput();
|
|
|
|
if (s)
|
|
PushConsoleEvent(s);
|
|
|
|
SDL_PumpEvents();
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_PollKeyboardInputEvents
|
|
================
|
|
*/
|
|
int Sys_PollKeyboardInputEvents() {
|
|
return kbd_polls.Num();
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_ReturnKeyboardInputEvent
|
|
================
|
|
*/
|
|
int Sys_ReturnKeyboardInputEvent(const int n, int &key, bool &state) {
|
|
if (n >= kbd_polls.Num())
|
|
return 0;
|
|
|
|
key = kbd_polls[n].key;
|
|
state = kbd_polls[n].state;
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_EndKeyboardInputEvents
|
|
================
|
|
*/
|
|
void Sys_EndKeyboardInputEvents() {
|
|
kbd_polls.SetNum(0, false);
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_PollMouseInputEvents
|
|
================
|
|
*/
|
|
int Sys_PollMouseInputEvents() {
|
|
return mouse_polls.Num();
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_ReturnMouseInputEvent
|
|
================
|
|
*/
|
|
int Sys_ReturnMouseInputEvent(const int n, int &action, int &value) {
|
|
if (n >= mouse_polls.Num())
|
|
return 0;
|
|
|
|
action = mouse_polls[n].action;
|
|
value = mouse_polls[n].value;
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_EndMouseInputEvents
|
|
================
|
|
*/
|
|
void Sys_EndMouseInputEvents() {
|
|
mouse_polls.SetNum(0, false);
|
|
}
|
|
|
|
/*
|
|
================
|
|
Joystick Input Methods
|
|
================
|
|
*/
|
|
void Sys_SetRumble( int device, int low, int hi ) {
|
|
// TODO: support multiple controllers.
|
|
assert(device == 0);
|
|
// TODO: support rumble maybe.
|
|
assert(0);
|
|
}
|
|
|
|
int Sys_PollJoystickInputEvents( int deviceNum ) {
|
|
// TODO: support multiple controllers.
|
|
assert(deviceNum == 0);
|
|
return joystick_polls.Num();
|
|
}
|
|
|
|
int Sys_ReturnJoystickInputEvent( const int n, int &action, int &value ) {
|
|
if (n >= joystick_polls.Num())
|
|
return 0;
|
|
|
|
action = joystick_polls[n].action;
|
|
value = joystick_polls[n].value;
|
|
return 1;
|
|
}
|
|
|
|
void Sys_EndJoystickInputEvents() {
|
|
joystick_polls.SetNum(0, false);
|
|
}
|
|
|
|
#endif
|