2007-11-25 19:42:40 +00:00
|
|
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
2007-10-07 23:43:14 +00:00
|
|
|
#include <string.h>
|
2008-10-20 17:47:42 +00:00
|
|
|
#ifdef CONFIG_NO_SDL
|
|
|
|
#include <GL/glfw.h>
|
|
|
|
#else
|
|
|
|
#include <SDL/SDL.h>
|
|
|
|
#endif
|
2007-08-22 07:52:33 +00:00
|
|
|
|
2008-08-14 17:19:13 +00:00
|
|
|
#include <base/system.h>
|
2008-01-19 10:57:25 +00:00
|
|
|
#include <engine/e_client_interface.h>
|
2007-12-15 10:24:49 +00:00
|
|
|
#include <engine/e_config.h>
|
2007-08-22 07:52:33 +00:00
|
|
|
|
2008-10-20 17:47:42 +00:00
|
|
|
#ifdef CONFIG_NO_SDL
|
|
|
|
static int keyboard_state[2][1024] = {{0}}; /* TODO: fix this!! */
|
|
|
|
#else
|
|
|
|
static unsigned char keyboard_state[2][1024] = {{0}}; /* TODO: fix this!! */
|
|
|
|
#endif
|
2007-08-22 07:52:33 +00:00
|
|
|
static int keyboard_current = 0;
|
2008-10-20 17:47:42 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_NO_SDL
|
2007-08-22 07:52:33 +00:00
|
|
|
static int keyboard_first = 1;
|
2008-10-20 17:47:42 +00:00
|
|
|
#endif
|
2007-08-22 07:52:33 +00:00
|
|
|
|
2007-10-07 23:43:14 +00:00
|
|
|
|
|
|
|
static struct
|
|
|
|
{
|
|
|
|
unsigned char presses;
|
|
|
|
unsigned char releases;
|
|
|
|
} input_count[2][1024] = {{{0}}, {{0}}};
|
|
|
|
|
|
|
|
static unsigned char input_state[2][1024] = {{0}, {0}};
|
|
|
|
|
|
|
|
static int input_current = 0;
|
2008-10-20 17:47:42 +00:00
|
|
|
#ifdef CONFIG_NO_SDL
|
2007-12-09 15:43:18 +00:00
|
|
|
static unsigned int last_release = 0;
|
2008-10-21 13:47:06 +00:00
|
|
|
#else
|
|
|
|
static int input_grabbed = 0;
|
|
|
|
static int input_use_grab = 1;
|
2008-10-20 17:47:42 +00:00
|
|
|
#endif
|
2007-12-09 15:43:18 +00:00
|
|
|
static unsigned int release_delta = -1;
|
2007-10-07 23:43:14 +00:00
|
|
|
|
2007-08-22 07:52:33 +00:00
|
|
|
void inp_mouse_relative(int *x, int *y)
|
|
|
|
{
|
|
|
|
static int last_x = 0, last_y = 0;
|
2007-12-09 14:15:57 +00:00
|
|
|
static int last_sens = 100.0f;
|
2008-10-20 17:47:42 +00:00
|
|
|
int nx = 0, ny = 0;
|
2007-12-09 14:15:57 +00:00
|
|
|
float sens = config.inp_mousesens/100.0f;
|
|
|
|
|
|
|
|
if(last_sens != config.inp_mousesens)
|
|
|
|
{
|
|
|
|
last_x = (last_x/(float)last_sens)*(float)config.inp_mousesens;
|
|
|
|
last_y = (last_y/(float)last_sens)*(float)config.inp_mousesens;
|
|
|
|
last_sens = config.inp_mousesens;
|
|
|
|
}
|
|
|
|
|
2008-10-20 17:47:42 +00:00
|
|
|
#ifdef CONFIG_NO_SDL
|
2007-08-22 07:52:33 +00:00
|
|
|
glfwGetMousePos(&nx, &ny);
|
2008-10-20 17:47:42 +00:00
|
|
|
|
2007-12-09 14:15:57 +00:00
|
|
|
nx *= sens;
|
|
|
|
ny *= sens;
|
|
|
|
|
2007-08-22 07:52:33 +00:00
|
|
|
*x = nx-last_x;
|
|
|
|
*y = ny-last_y;
|
|
|
|
last_x = nx;
|
|
|
|
last_y = ny;
|
2008-10-20 17:47:42 +00:00
|
|
|
#else
|
2008-10-21 13:47:06 +00:00
|
|
|
if(input_use_grab)
|
|
|
|
SDL_GetRelativeMouseState(&nx, &ny);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(input_grabbed)
|
|
|
|
{
|
|
|
|
SDL_GetMouseState(&nx,&ny);
|
|
|
|
SDL_WarpMouse(gfx_screenwidth()/2,gfx_screenheight()/2);
|
|
|
|
nx -= gfx_screenwidth()/2; ny -= gfx_screenheight()/2;
|
|
|
|
}
|
|
|
|
}
|
2008-10-20 17:47:42 +00:00
|
|
|
|
|
|
|
*x = nx*sens;
|
|
|
|
*y = ny*sens;
|
|
|
|
#endif
|
2007-08-22 07:52:33 +00:00
|
|
|
}
|
|
|
|
|
2008-01-12 12:08:26 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
INPUT_BUFFER_SIZE=32
|
|
|
|
};
|
|
|
|
|
2008-01-19 10:57:25 +00:00
|
|
|
static INPUT_EVENT input_events[INPUT_BUFFER_SIZE];
|
2008-01-12 12:08:26 +00:00
|
|
|
static int num_events = 0;
|
|
|
|
|
2008-03-01 20:03:04 +00:00
|
|
|
static void add_event(char c, int key, int flags)
|
2008-01-12 12:08:26 +00:00
|
|
|
{
|
|
|
|
if(num_events != INPUT_BUFFER_SIZE)
|
|
|
|
{
|
|
|
|
input_events[num_events].ch = c;
|
|
|
|
input_events[num_events].key = key;
|
2008-03-01 20:03:04 +00:00
|
|
|
input_events[num_events].flags = flags;
|
2008-01-12 12:08:26 +00:00
|
|
|
num_events++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int inp_num_events()
|
|
|
|
{
|
|
|
|
return num_events;
|
|
|
|
}
|
|
|
|
|
|
|
|
void inp_clear_events()
|
|
|
|
{
|
|
|
|
num_events = 0;
|
|
|
|
}
|
|
|
|
|
2008-01-19 10:57:25 +00:00
|
|
|
INPUT_EVENT inp_get_event(int index)
|
2008-01-12 12:08:26 +00:00
|
|
|
{
|
|
|
|
if(index < 0 || index >= num_events)
|
|
|
|
{
|
2008-01-19 10:57:25 +00:00
|
|
|
INPUT_EVENT e = {0,0};
|
2008-01-12 12:08:26 +00:00
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
return input_events[index];
|
|
|
|
}
|
|
|
|
|
2008-10-20 17:47:42 +00:00
|
|
|
#ifdef CONFIG_NO_SDL
|
2007-08-22 07:52:33 +00:00
|
|
|
static void char_callback(int character, int action)
|
|
|
|
{
|
|
|
|
if(action == GLFW_PRESS && character < 256)
|
2008-03-01 20:03:04 +00:00
|
|
|
add_event((char)character, 0, 0);
|
2007-08-22 07:52:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void key_callback(int key, int action)
|
|
|
|
{
|
2007-10-07 23:43:14 +00:00
|
|
|
if(action == GLFW_PRESS)
|
2008-03-01 20:03:04 +00:00
|
|
|
add_event(0, key, INPFLAG_PRESS);
|
|
|
|
else
|
|
|
|
add_event(0, key, INPFLAG_RELEASE);
|
2007-10-07 23:43:14 +00:00
|
|
|
|
|
|
|
if(action == GLFW_PRESS)
|
|
|
|
input_count[input_current^1][key].presses++;
|
|
|
|
if(action == GLFW_RELEASE)
|
|
|
|
input_count[input_current^1][key].releases++;
|
|
|
|
input_state[input_current^1][key] = action;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mousebutton_callback(int button, int action)
|
|
|
|
{
|
2007-12-09 15:52:22 +00:00
|
|
|
if(action == GLFW_PRESS)
|
2008-03-01 20:03:04 +00:00
|
|
|
add_event(0, KEY_MOUSE_FIRST+button, INPFLAG_PRESS);
|
|
|
|
else
|
|
|
|
add_event(0, KEY_MOUSE_FIRST+button, INPFLAG_RELEASE);
|
2007-12-09 15:52:22 +00:00
|
|
|
|
2007-10-07 23:43:14 +00:00
|
|
|
if(action == GLFW_PRESS)
|
|
|
|
input_count[input_current^1][KEY_MOUSE_FIRST+button].presses++;
|
|
|
|
if(action == GLFW_RELEASE)
|
2007-12-09 15:43:18 +00:00
|
|
|
{
|
|
|
|
if(button == 0)
|
|
|
|
{
|
|
|
|
release_delta = time_get() - last_release;
|
|
|
|
last_release = time_get();
|
|
|
|
}
|
2007-10-07 23:43:14 +00:00
|
|
|
input_count[input_current^1][KEY_MOUSE_FIRST+button].releases++;
|
2007-12-09 15:43:18 +00:00
|
|
|
}
|
2007-10-07 23:43:14 +00:00
|
|
|
input_state[input_current^1][KEY_MOUSE_FIRST+button] = action;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void mousewheel_callback(int pos)
|
|
|
|
{
|
|
|
|
if(pos > 0)
|
|
|
|
{
|
|
|
|
while(pos-- != 0)
|
|
|
|
{
|
|
|
|
input_count[input_current^1][KEY_MOUSE_WHEEL_UP].presses++;
|
|
|
|
input_count[input_current^1][KEY_MOUSE_WHEEL_UP].releases++;
|
|
|
|
}
|
2007-12-17 00:16:04 +00:00
|
|
|
|
2008-03-01 20:03:04 +00:00
|
|
|
add_event(0, KEY_MOUSE_WHEEL_UP, INPFLAG_PRESS);
|
|
|
|
add_event(0, KEY_MOUSE_WHEEL_UP, INPFLAG_RELEASE);
|
2007-10-07 23:43:14 +00:00
|
|
|
}
|
|
|
|
else if(pos < 0)
|
|
|
|
{
|
|
|
|
while(pos++ != 0)
|
|
|
|
{
|
|
|
|
input_count[input_current^1][KEY_MOUSE_WHEEL_DOWN].presses++;
|
|
|
|
input_count[input_current^1][KEY_MOUSE_WHEEL_DOWN].releases++;
|
|
|
|
}
|
2007-12-17 00:16:04 +00:00
|
|
|
|
2008-03-01 20:03:04 +00:00
|
|
|
add_event(0, KEY_MOUSE_WHEEL_DOWN, INPFLAG_PRESS);
|
|
|
|
add_event(0, KEY_MOUSE_WHEEL_DOWN, INPFLAG_RELEASE);
|
2007-10-07 23:43:14 +00:00
|
|
|
}
|
|
|
|
glfwSetMouseWheel(0);
|
2007-08-22 07:52:33 +00:00
|
|
|
}
|
|
|
|
|
2007-10-07 23:43:14 +00:00
|
|
|
|
2007-08-22 07:52:33 +00:00
|
|
|
void inp_init()
|
|
|
|
{
|
|
|
|
glfwEnable(GLFW_KEY_REPEAT);
|
|
|
|
glfwSetCharCallback(char_callback);
|
|
|
|
glfwSetKeyCallback(key_callback);
|
2007-10-07 23:43:14 +00:00
|
|
|
glfwSetMouseButtonCallback(mousebutton_callback);
|
|
|
|
glfwSetMouseWheelCallback(mousewheel_callback);
|
2007-08-22 07:52:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void inp_mouse_mode_absolute()
|
|
|
|
{
|
|
|
|
glfwEnable(GLFW_MOUSE_CURSOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
void inp_mouse_mode_relative()
|
|
|
|
{
|
2008-01-12 12:08:26 +00:00
|
|
|
/*if (!config.gfx_debug_resizable)*/
|
|
|
|
glfwDisable(GLFW_MOUSE_CURSOR);
|
2007-08-22 07:52:33 +00:00
|
|
|
}
|
2008-10-20 17:47:42 +00:00
|
|
|
#else
|
|
|
|
|
|
|
|
void inp_init()
|
|
|
|
{
|
|
|
|
SDL_EnableUNICODE(1);
|
2008-10-21 13:47:06 +00:00
|
|
|
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
2008-10-20 17:47:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void inp_mouse_mode_absolute()
|
|
|
|
{
|
|
|
|
SDL_ShowCursor(1);
|
2008-10-21 13:47:06 +00:00
|
|
|
input_grabbed = 0;
|
|
|
|
if(input_use_grab)
|
|
|
|
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
2008-10-20 17:47:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void inp_mouse_mode_relative()
|
|
|
|
{
|
|
|
|
SDL_ShowCursor(0);
|
2008-10-21 13:47:06 +00:00
|
|
|
input_grabbed = 1;
|
|
|
|
if(input_use_grab)
|
|
|
|
SDL_WM_GrabInput(SDL_GRAB_ON);
|
2008-10-20 17:47:42 +00:00
|
|
|
}
|
|
|
|
#endif
|
2007-08-22 07:52:33 +00:00
|
|
|
|
2007-12-09 15:43:18 +00:00
|
|
|
int inp_mouse_doubleclick()
|
|
|
|
{
|
|
|
|
return release_delta < (time_freq() >> 2);
|
|
|
|
}
|
|
|
|
|
2008-01-18 15:55:03 +00:00
|
|
|
void inp_clear_key_states()
|
|
|
|
{
|
|
|
|
mem_zero(keyboard_state, sizeof(keyboard_state));
|
|
|
|
mem_zero(input_count, sizeof(input_count));
|
|
|
|
}
|
|
|
|
|
2007-10-07 23:43:14 +00:00
|
|
|
int inp_key_presses(int key)
|
|
|
|
{
|
|
|
|
return input_count[input_current][key].presses;
|
|
|
|
}
|
|
|
|
|
|
|
|
int inp_key_releases(int key)
|
|
|
|
{
|
|
|
|
return input_count[input_current][key].releases;
|
|
|
|
}
|
|
|
|
|
|
|
|
int inp_key_state(int key)
|
|
|
|
{
|
|
|
|
return input_state[input_current][key];
|
|
|
|
}
|
|
|
|
|
2007-08-22 07:52:33 +00:00
|
|
|
int inp_key_pressed(int key) { return keyboard_state[keyboard_current][key]; }
|
|
|
|
int inp_key_was_pressed(int key) { return keyboard_state[keyboard_current^1][key]; }
|
|
|
|
int inp_key_down(int key) { return inp_key_pressed(key)&&!inp_key_was_pressed(key); }
|
|
|
|
int inp_button_pressed(int button) { return keyboard_state[keyboard_current][button]; }
|
|
|
|
|
|
|
|
void inp_update()
|
|
|
|
{
|
2008-10-20 17:47:42 +00:00
|
|
|
#ifdef CONFIG_NO_SDL
|
2007-10-06 17:01:06 +00:00
|
|
|
int i, v;
|
2008-10-20 17:47:42 +00:00
|
|
|
|
2007-10-07 23:43:14 +00:00
|
|
|
/* clear and begin count on the other one */
|
|
|
|
mem_zero(&input_count[input_current], sizeof(input_count[input_current]));
|
2008-02-11 21:49:26 +00:00
|
|
|
mem_copy(input_state[input_current], input_state[input_current^1], sizeof(input_state[input_current]));
|
2007-10-07 23:43:14 +00:00
|
|
|
input_current^=1;
|
2007-10-06 17:01:06 +00:00
|
|
|
|
2007-08-22 07:52:33 +00:00
|
|
|
if(keyboard_first)
|
|
|
|
{
|
2007-10-06 17:01:06 +00:00
|
|
|
/* make sure to reset */
|
2007-08-22 07:52:33 +00:00
|
|
|
keyboard_first = 0;
|
|
|
|
inp_update();
|
|
|
|
}
|
2007-10-04 22:37:35 +00:00
|
|
|
|
2007-08-22 07:52:33 +00:00
|
|
|
keyboard_current = keyboard_current^1;
|
|
|
|
for(i = 0; i < KEY_LAST; i++)
|
|
|
|
{
|
|
|
|
if (i >= KEY_MOUSE_FIRST)
|
|
|
|
v = glfwGetMouseButton(i-KEY_MOUSE_FIRST) == GLFW_PRESS ? 1 : 0;
|
|
|
|
else
|
|
|
|
v = glfwGetKey(i) == GLFW_PRESS ? 1 : 0;
|
|
|
|
keyboard_state[keyboard_current][i] = v;
|
|
|
|
}
|
2008-10-20 17:47:42 +00:00
|
|
|
#else
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* clear and begin count on the other one */
|
|
|
|
mem_zero(&input_count[input_current], sizeof(input_count[input_current]));
|
|
|
|
mem_copy(input_state[input_current], input_state[input_current^1], sizeof(input_state[input_current]));
|
|
|
|
input_current^=1;
|
|
|
|
|
|
|
|
{
|
|
|
|
Uint8 *state = SDL_GetKeyState(&i);
|
|
|
|
if(i >= KEY_LAST)
|
|
|
|
i = KEY_LAST-1;
|
|
|
|
mem_copy(keyboard_state[keyboard_current], state, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
keyboard_state[keyboard_current][KEY_MOUSE_1] = 0;
|
|
|
|
keyboard_state[keyboard_current][KEY_MOUSE_2] = 0;
|
|
|
|
keyboard_state[keyboard_current][KEY_MOUSE_3] = 0;
|
|
|
|
i = SDL_GetMouseState(NULL, NULL);
|
|
|
|
if(i&SDL_BUTTON(1)) keyboard_state[keyboard_current][KEY_MOUSE_1] = 1;
|
|
|
|
if(i&SDL_BUTTON(2)) keyboard_state[keyboard_current][KEY_MOUSE_2] = 1;
|
|
|
|
if(i&SDL_BUTTON(3)) keyboard_state[keyboard_current][KEY_MOUSE_3] = 1;
|
|
|
|
|
|
|
|
{
|
|
|
|
SDL_Event event;
|
|
|
|
|
|
|
|
while(SDL_PollEvent(&event))
|
|
|
|
{
|
|
|
|
int key = -1;
|
|
|
|
int action = INPFLAG_PRESS;
|
|
|
|
switch (event.type)
|
|
|
|
{
|
|
|
|
/* handle keys */
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
if(event.key.keysym.unicode < 255)
|
|
|
|
add_event(event.key.keysym.unicode, 0, 0);
|
|
|
|
key = event.key.keysym.sym;
|
|
|
|
break;
|
|
|
|
case SDL_KEYUP:
|
|
|
|
action = INPFLAG_RELEASE;
|
|
|
|
key = event.key.keysym.sym;
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* handle mouse buttons */
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
|
action = INPFLAG_RELEASE;
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
key = KEY_MOUSE_1+event.button.button-1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* other messages */
|
|
|
|
case SDL_QUIT:
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* */
|
|
|
|
if(key != -1)
|
|
|
|
{
|
|
|
|
input_count[input_current^1][key].presses++;
|
|
|
|
input_state[input_current^1][key] = 1;
|
|
|
|
add_event(0, key, action);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2007-08-22 07:52:33 +00:00
|
|
|
}
|