quakeforge/libs/video/targets/pr_keys.c
Bill Currie ace8d9ebc5 Implement dynamic IMTs.
Now the user can create and destroy IMTs at will, though currently
destroying IMTs is currently all or nothing (imt_drop_all).

An IMT is created via imt_create which takes the keydest name (key_game
etc), the name of the IMT (must be unique for all IMTs) and optionally the
name of the IMT to which the key binding search will fall back if there is
no binding in the current IMT, but must be already defined and on the same
keydest. This means that IMTs now have user determined fallback paths. The
requirements for the fallback IMT prevent loops and other weird behaviour.

Actual key binding via in_bind is unaffected. This is why the IMT name must
be unique across all IMTs.

The "imt" command works with the key_game keydest, but imt_keydest is
provided for specifying the active IMT for a specific keydest.

At startup, default IMTs are setup to emulate the previous static IMTs so
old configs will continue to work (mostly). New config files will be
written with commands to drop all of the current IMTs and build new ones,
with the bindings and active IMT set as well.
2013-01-16 19:48:54 +09:00

159 lines
3.1 KiB
C

/*
bi_keys.c
CSQC key-api builtins
Copyright (C) 1996-1997 Id Software, Inc.
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/csqc.h"
#include "QF/keys.h"
#include "QF/progs.h"
#include "QF/zone.h"
/*
bi_Key_SetBinding
QC-Function for set a binding
*/
static void
bi_Key_SetBinding (progs_t *pr)
{
const char *imt_name = P_GSTRING (pr, 0);
int keynum = P_INT (pr, 1);
const char *binding = P_GSTRING (pr, 2);
imt_t *imt;
if (binding && !binding[0]) {
binding = NULL; /* unbind a binding */
}
imt = Key_FindIMT (imt_name);
if (imt) {
Key_SetBinding (imt, keynum, binding);
}
}
/*
bi_Key_LookupBinding
Perform a reverse-binding-lookup
*/
static void
bi_Key_LookupBinding (progs_t *pr)
{
const char *imt_name = P_GSTRING (pr, 0);
int bindnum = P_INT (pr, 1);
const char *binding = P_GSTRING (pr, 2);
imt_t *imt;
int i;
knum_t keynum = -1;
const char *keybind = NULL;
imt = Key_FindIMT (imt_name);
if (imt) {
for (i = 0; i < QFK_LAST; i++) {
keybind = imt->bindings[i].str;
if (keybind == NULL) {
continue;
}
if (strcmp (keybind, binding) == 0) {
bindnum--;
if (bindnum == 0) {
keynum = i;
break;
}
}
}
}
R_INT (pr) = keynum;
};
/*
bi_Key_CountBinding
Counts how often a binding is assigned to a key
*/
static void
bi_Key_CountBinding (progs_t *pr)
{
const char *imt_name = P_GSTRING (pr, 0);
const char *binding = P_GSTRING (pr, 1);
int i, res = 0;
const char *keybind = NULL;
imt_t *imt;
imt = Key_FindIMT (imt_name);
if (imt) {
for (i = 0; i < QFK_LAST; i++) {
keybind = imt->bindings[i].str;
if (keybind == NULL) {
continue;
}
if (strcmp (keybind, binding) == 0) {
res++;
}
}
}
R_INT (pr) = res;
};
/*
bi_Key_LookupBinding
Convertes a keynum to a string
*/
static void
bi_Key_KeynumToString (progs_t *pr)
{
int keynum = P_INT (pr, 0);
RETURN_STRING (pr, Key_KeynumToString (keynum));
};
static builtin_t builtins[] = {
{"Key_SetBinding", bi_Key_SetBinding, -1},
{"Key_LookupBinding", bi_Key_LookupBinding, -1},
{"Key_CountBinding", bi_Key_CountBinding, -1},
{"Key_KeynumToString", bi_Key_KeynumToString, -1},
// NEED THIS ?// {"Key_StringToKeynum", bi_Key_KeynumToString, -1},
{0}
};
void
Key_Progs_Init (progs_t *pr)
{
PR_RegisterBuiltins (pr, builtins);
}