diff options
Diffstat (limited to 'source/ui_keys.c')
-rw-r--r-- | source/ui_keys.c | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/source/ui_keys.c b/source/ui_keys.c new file mode 100644 index 0000000..06b16ec --- /dev/null +++ b/source/ui_keys.c @@ -0,0 +1,208 @@ +/* +Copyright (C) 2003-2006 Andrey Nazarov + +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. + +*/ + +#include "ui_local.h" + +#define MAX_KEYBINDS 32 + +static const char *keybinds[][2] = { + { "+attack", "attack" }, + { "weapnext", "next weapon" }, + { "+forward", "walk forward" }, + { "+back", "backpedal" }, + { "+left", "turn left" }, + { "+right", "turn right" }, + { "+speed", "run" }, + { "+moveleft", "step left" }, + { "+moveright", "step right" }, + { "+strafe", "sidestep" }, + { "+lookup", "look up" }, + { "+lookdown", "look down" }, + { "centerview", "center view" }, + { "+mlook", "mouse look" }, + { "+klook", "keyboard look" }, + { "+moveup", "up / jump" }, + { "+movedown", "down / crouch" }, + + { "inven", "inventory" }, + { "invuse", "use item" }, + { "invdrop", "drop item" }, + { "invprev", "prev item" }, + { "invnext", "next item" }, + + { "help", "help computer" } +}; + +static const int numKeyBinds = sizeof( keybinds ) / sizeof( keybinds[0] ); + +static const char *weapbinds[][2] = { + { "use Blaster", "blaster" }, + { "use Shotgun", "shotgun" }, + { "use Super Shotgun", "super shotgun" }, + { "use Machinegun", "machinegun" }, + { "use Chaingun", "chaingun" }, + { "use Grenade Launcher", "grenade launcher" }, + { "use Rocket Launcher", "rocket launcher" }, + { "use HyperBlaster", "hyperblaster" }, + { "use Railgun", "railgun" }, + { "use BFG10K", "bfg10k" } +}; + +static const int numWeapBinds = sizeof( weapbinds ) / sizeof( weapbinds[0] ); + + +typedef struct keysMenu_s { + menuFrameWork_t menu; + menuKeybind_t actions[MAX_KEYBINDS]; + menuStatic_t banner; + const char *binds[MAX_KEYBINDS]; + int current; + int total; +} keysMenu_t; + +static keysMenu_t m_keys; + +static void KeysMenu_Update( void ) { + menuKeybind_t *k; + int i, key; + + for( i = 0, k = m_keys.actions; i < m_keys.total; i++, k++ ) { + key = keys.EnumBindings( 0, m_keys.binds[i] ); + k->altbinding[0] = 0; + if( key == -1 ) { + strcpy( k->binding, "???" ); + } else { + strcpy( k->binding, keys.KeyNumToString( key ) ); + key = keys.EnumBindings( key + 1, m_keys.binds[i] ); + if( key != -1 ) { + strcpy( k->altbinding, keys.KeyNumToString( key ) ); + } + } + } +} + +static void KeysMenu_Remove( const char *binding ) { + int key; + + for( key = 0; ; key++ ) { + key = keys.EnumBindings( key, binding ); + if( key == -1 ) { + break; + } + keys.SetBinding( key, NULL ); + } +} + + +static int KeysMenu_Callback( int id, int msg, int param ) { + menuKeybind_t *k; + + + switch( msg ) { + case QM_ACTIVATE: + if( id >= 0 && id < m_keys.total ) { + m_keys.menu.keywait = qtrue; + m_keys.menu.statusbar = "Press the desired key, Escape to cancel"; + } + return QMS_IN; + case QM_GOTFOCUS: + m_keys.current = id; + break; + case QM_KEY: + if( id == ID_MENU && m_keys.menu.keywait ) { + if( param != K_ESCAPE && m_keys.current >= 0 && m_keys.current < m_keys.total ) { + k = &m_keys.actions[m_keys.current]; + if( k->altbinding[0] ) { + KeysMenu_Remove( m_keys.binds[m_keys.current] ); + } + keys.SetBinding( param, m_keys.binds[m_keys.current] ); + } + KeysMenu_Update(); + m_keys.menu.keywait = qfalse; + m_keys.menu.statusbar = "Press Enter to change, Backspace to clear"; + return QMS_OUT; + } else if( param == K_BACKSPACE || param == K_DEL ) { + if( id >= 0 && id < m_keys.total ) { + KeysMenu_Remove( m_keys.binds[id] ); + KeysMenu_Update(); + return QMS_IN; + } + } + break; + default: + break; + } + + return QMS_NOTHANDLED; +} + +static void KeysMenu_Init( const char **names, int total, const char *banner ) { + menuKeybind_t *k; + int i, x, y; + + x = uis.glconfig.vidWidth / 2; + y = ( uis.glconfig.vidHeight - MENU_SPACING * total ) / 2; + + memset( &m_keys, 0, sizeof( m_keys ) ); + + m_keys.menu.callback = KeysMenu_Callback; + m_keys.total = total; + + for( i = 0, k = m_keys.actions; i < total; i++, k++ ) { + m_keys.binds[i] = names[0]; + k->generic.type = MTYPE_KEYBIND; + k->generic.id = i; + k->generic.name = names[1]; + k->generic.x = x; + k->generic.y = y; + k->generic.uiFlags = UI_CENTER; + + names += 2; + + y += MENU_SPACING; + + Menu_AddItem( &m_keys.menu, ( void * )&m_keys.actions[i] ); + } + + KeysMenu_Update(); + + m_keys.menu.statusbar = "Press Enter to change, Backspace to clear"; + + m_keys.actions[0].generic.flags = QMF_HASFOCUS; + + UI_SetupDefaultBanner( &m_keys.banner, banner ); + + Menu_AddItem( &m_keys.menu, ( void * )&m_keys.banner ); + +} + + +void M_Menu_Keys_f( void ) { + KeysMenu_Init( ( const char ** )keybinds, numKeyBinds, "Key Bindings" ); + UI_PushMenu( &m_keys.menu ); +} + +void M_Menu_Weapons_f( void ) { + KeysMenu_Init( ( const char ** )weapbinds, numWeapBinds, "Weapon Bindings" ); + UI_PushMenu( &m_keys.menu ); +} + + + |