/* * input.cc - keyboard input handlers for Bombermaze * written by Sydney Tang * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * For more details see the file COPYING. */ #include #include "map.hh" #include "game.hh" #include "input.hh" #include "preferences.hh" #include #include #include #include ////////////////////////////////////////////////////////////////////////////// static KeyMap *Key_Map; static bool PlayerEnableAutoFire[Player::MAX_NUMBER_OF_LOCAL_PLAYERS]; static PlayerActionKeyBinding *get_keybinding_from_keyval(int keyval); ////////////////////////////////////////////////////////////////////////////// void handle_keypress( GtkWidget *widget, GdkEventKey *event, gpointer data ) { game_get_current_state()->handle_keypress(event->keyval); return; } void handle_keyrelease( GtkWidget *widget, GdkEventKey *event, gpointer data ) { game_get_current_state()->handle_keyrelease(event->keyval); return; } PlayerActionKeyBinding *get_keybinding_from_keyval(int keyval) { PlayerActionKeyBinding *action; action = (PlayerActionKeyBinding *)g_hash_table_lookup (Key_Map->LookupTable, &keyval); if ((preferences_case_sensitive() == false) && (action == NULL)) { if (isalpha(keyval) && isupper(keyval)) keyval = tolower(keyval); else keyval = toupper(keyval); action=(PlayerActionKeyBinding *)g_hash_table_lookup(Key_Map->LookupTable, &keyval); } return action; } void GameState::handle_keypress(guint keyval) { handle_new_game_keypress(keyval); } bool GameState::handle_new_game_keypress(guint keyval) { int i; int NumPlayers = 0; for (i = 0; i < Player::MAX_NUMBER_OF_PLAYERS; i++) { if (keyval == Key_Map->StartNPlayerGame[i]) { NumPlayers = i+1; break; } } if (NumPlayers != 0) { owner->start_game(NumPlayers); return true; } return false; } void GameState::handle_keyrelease(guint keyval) { return; } void TitleScreenState::handle_keypress(guint keyval) { if (GameState::handle_new_game_keypress(keyval) == true) { return; } if (keyval == Key_Map->Quit) { ui_quit_game(); return; } } void TitleScreenState::handle_keyrelease(guint keyval) { return; } void InGameState::handle_keypress(guint keyval) { PlayerActionKeyBinding *action; action = get_keybinding_from_keyval(keyval); if (action != NULL) { if ((int)(action->ActionType) < (int)NUMBER_OF_DIRECTIONS) { SustainedPlayerAction[SUSTAINED_MOVEMENT][action->PlayerIndex] = action->ActionType; } else if (((int)(action->ActionType) == (int)Player::PLAYER_DROP_BOMB) && (PlayerEnableAutoFire[action->PlayerIndex] == true)) { SustainedPlayerAction[SUSTAINED_BOMBDROP][action->PlayerIndex] = action->ActionType; } if (paused == true) { return; } perform_player_action(action); return; } if (GameState::handle_new_game_keypress(keyval) == true) { return; } if (keyval == Key_Map->Pause) { toggle_pause(); } if (keyval == Key_Map->Quit) { undraw_maze(); owner->change_state(GameStateMachine::STATE_TITLESCREEN, 0); return; } return; } void InGameState::handle_keyrelease(guint keyval) { PlayerActionKeyBinding *action; action = get_keybinding_from_keyval(keyval); if (action != NULL) { for (int j = 0; j < MAX_ALLOWED_SUSTAINED_ACTIONS; j++) { if ((int)(action->ActionType) == SustainedPlayerAction[j][action->PlayerIndex]) { SustainedPlayerAction[j][action->PlayerIndex] = -1; } } } return; } void InGameState::match_status_keypress(guint keyval) { int i; bool start_new_game = false; for (i = 0; i < Player::MAX_NUMBER_OF_PLAYERS; i++) { if (keyval == Key_Map->StartNPlayerGame[i]) { start_new_game = true; break; } } if ((start_new_game == true) || (keyval == Key_Map->Quit) || (keyval == Key_Map->Continue)) { hide_match_status(); return; } } void InGameState::match_status_continue(void) { match_status_keypress(Key_Map->Continue); game_get_current_state()->handle_keypress(Key_Map->Continue); } void GameOverState::handle_keypress(guint keyval) { if (keyval == Key_Map->Continue) { if (winner == RESUME_MATCH) { owner->change_state(GameStateMachine::STATE_MULTIPLAYER, RESUME_MATCH); return; } else { owner->change_state(GameStateMachine::STATE_TITLESCREEN, 0); /* if (GameOver == false) { GameOver = true; draw_game_over_screen(winner); } else { GameOver = false; hide_game_over_screen(); owner->change_state(GameStateMachine::STATE_TITLESCREEN, 0); } */ return; } } if (GameState::handle_new_game_keypress(keyval) == true) { return; } if (keyval == Key_Map->Quit) { owner->change_state(GameStateMachine::STATE_TITLESCREEN, 0); return; } return; } void GameOverState::handle_keyrelease(guint keyval) { return; } ////////////////////////////////////////////////////////////////////////////// int input_set_keymap(KeyMap *key_map) { Key_Map = key_map; return 0; } void input_set_autofire(int PlayerIndex, bool setting) { if ((PlayerIndex >= 0) && (PlayerIndex < Player::MAX_NUMBER_OF_LOCAL_PLAYERS)) { PlayerEnableAutoFire[PlayerIndex] = setting; } } ////////////////////////////////////////////////////////////////////////////// KeyMap::KeyMap() { int p, a; LookupTable = NULL; for (p = 0; p < Player::MAX_NUMBER_OF_LOCAL_PLAYERS; p++) { for (a = 0; a < Player::NUMBER_OF_PLAYER_ACTIONS; a++) { PlayerAction[p][a].PlayerIndex = -1; PlayerAction[p][a].keyval = 0; PlayerAction[p][a].ActionType = Player::PLAYER_SPECIAL; } } for (p = 0; p < Player::MAX_NUMBER_OF_PLAYERS; p++) { StartNPlayerGame[p] = 0; } Pause = 0; Quit = 0; } KeyMap::~KeyMap() { } KeyMap KeyMap::operator=(KeyMap op2) { int p, a; LookupTable = op2.LookupTable; for (p = 0; p < Player::MAX_NUMBER_OF_LOCAL_PLAYERS; p++) { for (a = 0; a < Player::NUMBER_OF_PLAYER_ACTIONS; a++) { PlayerAction[p][a].PlayerIndex = op2.PlayerAction[p][a].PlayerIndex; PlayerAction[p][a].keyval = op2.PlayerAction[p][a].keyval; PlayerAction[p][a].ActionType = op2.PlayerAction[p][a].ActionType; } } for (p = 0; p < Player::MAX_NUMBER_OF_PLAYERS; p++) { StartNPlayerGame[p] = op2.StartNPlayerGame[p]; } Pause = op2.Pause; Quit = op2.Quit; Continue = op2.Continue; return *this; } void KeyMap::rehash(void) { if (LookupTable != NULL) { g_hash_table_destroy (LookupTable); } LookupTable = g_hash_table_new (g_int_hash, g_int_equal); for (int p = 0; p < Player::MAX_NUMBER_OF_LOCAL_PLAYERS; p++) { for (int a = 0; a < Player::NUMBER_OF_PLAYER_ACTIONS; a++) { g_hash_table_insert (LookupTable, (gpointer)&(PlayerAction[p][a].keyval), (gpointer)&(PlayerAction[p][a])); } } } //////////////////////////////////////////////////////////////////////////////