/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ #include #include "SDL.h" #include #include #include 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; static int input_grabbed = 0; static unsigned int last_release = 0; static unsigned int release_delta = -1; void inp_mouse_relative(int *x, int *y) { int nx = 0, ny = 0; float sens = config.inp_mousesens/100.0f; if(config.inp_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; } } *x = nx*sens; *y = ny*sens; } enum { INPUT_BUFFER_SIZE=32 }; static INPUT_EVENT input_events[INPUT_BUFFER_SIZE]; static int num_events = 0; static void add_event(int unicode, int key, int flags) { if(num_events != INPUT_BUFFER_SIZE) { input_events[num_events].unicode = unicode; input_events[num_events].key = key; input_events[num_events].flags = flags; num_events++; } } int inp_num_events() { return num_events; } void inp_clear_events() { num_events = 0; } INPUT_EVENT inp_get_event(int index) { if(index < 0 || index >= num_events) { INPUT_EVENT e = {0,0}; return e; } return input_events[index]; } void inp_init() { SDL_EnableUNICODE(1); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); } void inp_mouse_mode_absolute() { SDL_ShowCursor(1); input_grabbed = 0; if(config.inp_grab) SDL_WM_GrabInput(SDL_GRAB_OFF); } void inp_mouse_mode_relative() { SDL_ShowCursor(0); input_grabbed = 1; if(config.inp_grab) SDL_WM_GrabInput(SDL_GRAB_ON); } int inp_mouse_doubleclick() { return release_delta < (time_freq() >> 2); } void inp_clear_key_states() { mem_zero(input_state, sizeof(input_state)); mem_zero(input_count, sizeof(input_count)); } 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]; } int inp_key_pressed(int key) { return input_state[input_current][key]; } int inp_key_was_pressed(int key) { return input_state[input_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 input_state[input_current][button]; } void inp_update() { int i; if(input_grabbed && !gfx_window_active()) inp_mouse_mode_absolute(); /*if(!input_grabbed && gfx_window_active()) inp_mouse_mode_relative();*/ /* clear and begin count on the other one */ input_current^=1; mem_zero(&input_count[input_current], sizeof(input_count[input_current])); mem_zero(&input_state[input_current], sizeof(input_state[input_current])); { Uint8 *state = SDL_GetKeyState(&i); if(i >= KEY_LAST) i = KEY_LAST-1; mem_copy(input_state[input_current], state, i); } /* these states must always be updated manually because they are not in the GetKeyState from SDL */ i = SDL_GetMouseState(NULL, NULL); if(i&SDL_BUTTON(1)) input_state[input_current][KEY_MOUSE_1] = 1; /* 1 is left */ if(i&SDL_BUTTON(3)) input_state[input_current][KEY_MOUSE_2] = 1; /* 3 is right */ if(i&SDL_BUTTON(2)) input_state[input_current][KEY_MOUSE_3] = 1; /* 2 is middle */ if(i&SDL_BUTTON(4)) input_state[input_current][KEY_MOUSE_4] = 1; if(i&SDL_BUTTON(5)) input_state[input_current][KEY_MOUSE_5] = 1; if(i&SDL_BUTTON(6)) input_state[input_current][KEY_MOUSE_6] = 1; if(i&SDL_BUTTON(7)) input_state[input_current][KEY_MOUSE_7] = 1; if(i&SDL_BUTTON(8)) input_state[input_current][KEY_MOUSE_8] = 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; if(event.button.button == 1) { release_delta = time_get() - last_release; last_release = time_get(); } /* fall through */ case SDL_MOUSEBUTTONDOWN: if(event.button.button == SDL_BUTTON_LEFT) key = KEY_MOUSE_1; if(event.button.button == SDL_BUTTON_RIGHT) key = KEY_MOUSE_2; if(event.button.button == SDL_BUTTON_MIDDLE) key = KEY_MOUSE_3; if(event.button.button == SDL_BUTTON_WHEELUP) key = KEY_MOUSE_WHEEL_UP; if(event.button.button == SDL_BUTTON_WHEELDOWN) key = KEY_MOUSE_WHEEL_DOWN; if(event.button.button == 6) key = KEY_MOUSE_6; if(event.button.button == 7) key = KEY_MOUSE_7; if(event.button.button == 8) key = KEY_MOUSE_8; break; /* other messages */ case SDL_QUIT: /* TODO: cleaner exit */ exit(0); break; } /* */ if(key != -1) { input_count[input_current][key].presses++; if(action == INPFLAG_PRESS) input_state[input_current][key] = 1; add_event(0, key, action); } } } }