/* * Biloba * Copyright (C) 2004-2005 Guillaume Demougeot, Colin Leroy * * 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 2 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** * Biloba - Q1 2005 * Game by Guillaume Demougeot * Code by Colin Leroy * * This file contains all the keyboard handling code. * Mainly used by options.c. */ #include #include #include #include #include "keyboard.h" #include "utils.h" #include "logic.h" static SDL_Thread *keyb_thread = NULL; static int running = 0; static LList *event_list = NULL; static SDL_mutex *keyb_mutex = NULL; void keyboard_push_event(int code, int mod) { #ifdef DEBUG printf("pushing event\n"); #endif SDL_LockMutex(keyb_mutex); if ((mod & KMOD_CTRL)) code = -code; event_list = llist_append(event_list, (void *)code); SDL_UnlockMutex(keyb_mutex); #ifdef DEBUG printf("pushed event\n"); #endif } int keyboard_pull_event(void) { int mcode = 0; SDL_LockMutex(keyb_mutex); if (event_list) { LList *next = event_list->next; mcode = (int)event_list->data; free(event_list); event_list = next; #ifdef DEBUG printf("pulled event\n"); #endif } SDL_UnlockMutex(keyb_mutex); return mcode; } int keyboard_handler(void *data) { running = 1; while (running) { int code = 0; int handled = FALSE; code = keyboard_pull_event(); if (code) { #ifdef DEBUG printf("keycode %d\n", code); #endif if (code == -SDLK_q) { stop_game(); handled = TRUE; } if (code == -SDLK_e) { end_game(); handled = TRUE; } if (handled) { SDL_Event user_event; user_event.type=SDL_USEREVENT; user_event.user.code=2; user_event.user.data1=NULL; user_event.user.data2=NULL; SDL_PushEvent(&user_event); } } SDL_Delay(100); } return 0; } void init_keyboard(void) { assert(keyb_thread == NULL); keyb_mutex = SDL_CreateMutex(); keyb_thread = SDL_CreateThread(keyboard_handler, NULL); } void stop_keyboard(void) { assert(keyb_thread != NULL); running = 0; keyb_thread = NULL; } static int get_number(int symbol, int mod) { if (symbol >= SDLK_KP0 && symbol <= SDLK_KP9) return symbol - SDLK_KP0 + '0'; if ((mod & KMOD_SHIFT)) { int fr_translation[] = {224, 38, 233, 34, 39, 40, 45, 232, 95, 231}; int i = 0; for (i = 0; i < 10; i++) if (symbol == fr_translation[i]) return i + '0'; } return 0; } static int translate_keysym(int symbol, int mod) { int res = symbol; if (res >= SDLK_a && res <= SDLK_z) { if ((mod & KMOD_SHIFT)) return res - SDLK_a + 'A'; else return res - SDLK_a + 'a'; } if (res == SDLK_RETURN || res == SDLK_BACKSPACE || res == SDLK_SPACE) return res; if (res < SDLK_a || res > SDLK_z) if (res != SDLK_RETURN && res != SDLK_BACKSPACE) return get_number(res, mod); return 0; } int keyboard_grab(void) { SDL_Event event; int result = 0; do { rescan: SDL_WaitEvent(&event); if (event.type == SDL_KEYDOWN) { SDL_KeyboardEvent *kevent = &event.key; result = translate_keysym(kevent->keysym.sym, kevent->keysym.mod); if (result == 0) goto rescan; return result; } } while (event.type != SDL_KEYDOWN); assert(FALSE); return 0; }