mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 19:20:46 +00:00
291 lines
No EOL
8.3 KiB
C++
291 lines
No EOL
8.3 KiB
C++
#include "gamecontrol.h"
|
|
#include "tarray.h"
|
|
#include "zstring.h"
|
|
#include "name.h"
|
|
#include "control.h"
|
|
#include "keyboard.h"
|
|
#include "sc_man.h"
|
|
|
|
struct GameFuncNameDesc
|
|
{
|
|
int index;
|
|
const char *name;
|
|
};
|
|
|
|
static const GameFuncNameDesc gamefuncs[] = {
|
|
{ gamefunc_Move_Forward, "Move_Forward"},
|
|
{ gamefunc_Move_Backward, "Move_Backward"},
|
|
{ gamefunc_Turn_Left, "Turn_Left"},
|
|
{ gamefunc_Turn_Right, "Turn_Right"},
|
|
{ gamefunc_Strafe, "Strafe"},
|
|
{ gamefunc_Fire, "Fire"},
|
|
{ gamefunc_Open, "Open"},
|
|
{ gamefunc_Run, "Run"},
|
|
{ gamefunc_Alt_Fire, "Alt_Fire"},
|
|
{ gamefunc_Jump, "Jump"},
|
|
{ gamefunc_Crouch, "Crouch"},
|
|
{ gamefunc_Look_Up, "Look_Up"},
|
|
{ gamefunc_Look_Down, "Look_Down"},
|
|
{ gamefunc_Look_Left, "Look_Left"},
|
|
{ gamefunc_Look_Right, "Look_Right"},
|
|
{ gamefunc_Strafe_Left, "Strafe_Left"},
|
|
{ gamefunc_Strafe_Right, "Strafe_Right"},
|
|
{ gamefunc_Aim_Up, "Aim_Up"},
|
|
{ gamefunc_Aim_Down, "Aim_Down"},
|
|
{ gamefunc_Weapon_1, "Weapon_1"},
|
|
{ gamefunc_Weapon_2, "Weapon_2"},
|
|
{ gamefunc_Weapon_3, "Weapon_3"},
|
|
{ gamefunc_Weapon_4, "Weapon_4"},
|
|
{ gamefunc_Weapon_5, "Weapon_5"},
|
|
{ gamefunc_Weapon_6, "Weapon_6"},
|
|
{ gamefunc_Weapon_7, "Weapon_7"},
|
|
{ gamefunc_Weapon_8, "Weapon_8"},
|
|
{ gamefunc_Weapon_9, "Weapon_9"},
|
|
{ gamefunc_Weapon_10, "Weapon_10"},
|
|
{ gamefunc_Inventory, "Inventory"},
|
|
{ gamefunc_Inventory_Left, "Inventory_Left"},
|
|
{ gamefunc_Inventory_Right, "Inventory_Right"},
|
|
{ gamefunc_Holo_Duke, "Holo_Duke"},
|
|
{ gamefunc_Jetpack, "Jetpack"},
|
|
{ gamefunc_NightVision, "NightVision"},
|
|
{ gamefunc_MedKit, "MedKit"},
|
|
{ gamefunc_TurnAround, "TurnAround"},
|
|
{ gamefunc_SendMessage, "SendMessage"},
|
|
{ gamefunc_Map, "Map"},
|
|
{ gamefunc_Shrink_Screen, "Shrink_Screen"},
|
|
{ gamefunc_Enlarge_Screen, "Enlarge_Screen"},
|
|
{ gamefunc_Center_View, "Center_View"},
|
|
{ gamefunc_Holster_Weapon, "Holster_Weapon"},
|
|
{ gamefunc_Show_Opponents_Weapon, "Show_Opponents_Weapon"},
|
|
{ gamefunc_Map_Follow_Mode, "Map_Follow_Mode"},
|
|
{ gamefunc_See_Coop_View, "See_Coop_View"},
|
|
{ gamefunc_Mouse_Aiming, "Mouse_Aiming"},
|
|
{ gamefunc_Toggle_Crosshair, "Toggle_Crosshair"},
|
|
{ gamefunc_Steroids, "Steroids"},
|
|
{ gamefunc_Quick_Kick, "Quick_Kick"},
|
|
{ gamefunc_Next_Weapon, "Next_Weapon"},
|
|
{ gamefunc_Previous_Weapon, "Previous_Weapon"},
|
|
{ gamefunc_Show_Console, "Show_Console"},
|
|
{ gamefunc_Show_DukeMatch_Scores, "Show_DukeMatch_Scores"},
|
|
{ gamefunc_Dpad_Select, "Dpad_Select"},
|
|
{ gamefunc_Dpad_Aiming, "Dpad_Aiming"},
|
|
{ gamefunc_AutoRun, "AutoRun"},
|
|
{ gamefunc_Last_Weapon, "Last_Used_Weapon"},
|
|
{ gamefunc_Quick_Save, "Quick_Save"},
|
|
{ gamefunc_Quick_Load, "Quick_Load"},
|
|
{ gamefunc_Alt_Weapon, "Alternate_Weapon"}, // Name in RedNukem
|
|
{ gamefunc_Alt_Weapon, "Alt_Weapon"}, // Name in EDuke32
|
|
{ gamefunc_Third_Person_View, "Third_Person_View"},
|
|
{ gamefunc_Toggle_Crouch, "Toggle_Crouch"},
|
|
{ gamefunc_See_Chase_View, "See_Chase_View"}, // the following were added by Blood
|
|
{ gamefunc_Turn_Around, "Turn_Around"},
|
|
{ gamefunc_Weapon_Fire, "Weapon_Fire"},
|
|
{ gamefunc_Weapon_Special_Fire, "Weapon_Special_Fire"},
|
|
{ gamefunc_Aim_Center, "Aim_Center"},
|
|
{ gamefunc_Tilt_Left, "Tilt_Left"},
|
|
{ gamefunc_Tilt_Right, "Tilt_Right"},
|
|
{ gamefunc_Inventory_Use, "Inventory_Use"},
|
|
{ gamefunc_Map_Toggle, "Map_Toggle"},
|
|
{ gamefunc_Send_Message, "Send_Message"},
|
|
{ gamefunc_BeastVision, "BeastVision"},
|
|
{ gamefunc_CrystalBall, "CrystalBall"},
|
|
{ gamefunc_JumpBoots, "JumpBoots"},
|
|
{ gamefunc_ProximityBombs, "ProximityBombs"},
|
|
{ gamefunc_RemoteBombs, "RemoteBombs"},
|
|
};
|
|
|
|
static TMap<FName, int> GF_NameToNum;
|
|
static TArray<FString> GF_NumToName; // This one will preserve the original name for writing to the config (which must be loaded before CON scripts can hack around with the alias array.)
|
|
static TArray<FString> GF_NumToAlias; // This is for CON scripts to hack apart.
|
|
|
|
uint8_t KeyboardKeys[NUMGAMEFUNCTIONS][2];
|
|
|
|
static void InitNameToNum()
|
|
{
|
|
GF_NumToName.Resize(NUMGAMEFUNCTIONS);
|
|
GF_NumToAlias.Resize(NUMGAMEFUNCTIONS);
|
|
for(auto &gf : gamefuncs)
|
|
{
|
|
GF_NameToNum.Insert(gf.name, gf.index);
|
|
GF_NumToAlias[gf.index] = GF_NumToName[gf.index] = gf.name;
|
|
}
|
|
}
|
|
|
|
int32_t CONFIG_FunctionNameToNum(const char *func)
|
|
{
|
|
if (!func) return -1;
|
|
|
|
FName name(func, true);
|
|
if (name == NAME_None) return -1;
|
|
|
|
auto res = GF_NameToNum.CheckKey(name);
|
|
if (!res) return -1;
|
|
|
|
return *res;
|
|
}
|
|
|
|
const char *CONFIG_FunctionNumToName(int32_t func)
|
|
{
|
|
if ((unsigned)func >= (unsigned)NUMGAMEFUNCTIONS)
|
|
return NULL;
|
|
return GF_NumToAlias[func];
|
|
}
|
|
|
|
const char *CONFIG_FunctionNumToRealName(int32_t func)
|
|
{
|
|
if ((unsigned)func >= (unsigned)NUMGAMEFUNCTIONS)
|
|
return NULL;
|
|
return GF_NumToName[func];
|
|
}
|
|
|
|
void CONFIG_ReplaceButtonName(int num, const char *text)
|
|
{
|
|
if ((unsigned)num >= (unsigned)NUMGAMEFUNCTIONS)
|
|
return;
|
|
GF_NumToAlias[num] = text;
|
|
GF_NameToNum.Insert(text, num);
|
|
}
|
|
|
|
void CONFIG_DeleteButtonName(int num)
|
|
{
|
|
if ((unsigned)num >= (unsigned)NUMGAMEFUNCTIONS)
|
|
return;
|
|
GF_NumToAlias[num] = "";
|
|
}
|
|
|
|
// wrapper for CONTROL_MapKey(), generates key bindings to reflect changes to keyboard setup
|
|
void CONFIG_MapKey(int which, kb_scancode key1, kb_scancode oldkey1, kb_scancode key2, kb_scancode oldkey2)
|
|
{
|
|
int const keys[] = { key1, key2, oldkey1, oldkey2 };
|
|
|
|
if (which == gamefunc_Show_Console)
|
|
OSD_CaptureKey(key1);
|
|
|
|
for (int k = 0; (unsigned)k < ARRAY_SIZE(keys); k++)
|
|
{
|
|
if (keys[k] == 0xff || !keys[k])
|
|
continue;
|
|
|
|
int match = 0;
|
|
|
|
for (; sctokeylut[match].key; match++)
|
|
{
|
|
if (keys[k] == sctokeylut[match].sc)
|
|
break;
|
|
}
|
|
|
|
FString tempbuf;
|
|
|
|
for (int i = NUMGAMEFUNCTIONS - 1; i >= 0; i--)
|
|
{
|
|
if (KeyboardKeys[i][0] == keys[k] || KeyboardKeys[i][1] == keys[k])
|
|
{
|
|
tempbuf.AppendFormat("gamefunc_%s; ", CONFIG_FunctionNumToName(i));
|
|
}
|
|
}
|
|
|
|
auto len = tempbuf.Len();
|
|
|
|
if (len >= 2)
|
|
{
|
|
tempbuf.Truncate(len - 2); // cut off the trailing "; "
|
|
CONTROL_BindKey(keys[k], tempbuf, 1, sctokeylut[match].key ? sctokeylut[match].key : "<?>");
|
|
}
|
|
else
|
|
{
|
|
CONTROL_FreeKeyBind(keys[k]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CONFIG_SetDefaultKeys(const char *defbinds, bool lazy/*=false*/)
|
|
{
|
|
FScanner sc;
|
|
|
|
sc.Open(defbinds);
|
|
|
|
if (!lazy)
|
|
{
|
|
memset(KeyboardKeys, 0xff, sizeof(KeyboardKeys));
|
|
CONTROL_ClearAllBinds();
|
|
}
|
|
|
|
while (sc.GetToken())
|
|
{
|
|
sc.TokenMustBe(TK_StringConst);
|
|
int num = CONFIG_FunctionNameToNum(sc.String);
|
|
int default0 = -1;
|
|
int default1 = -1;
|
|
|
|
if (sc.CheckToken(','))
|
|
{
|
|
sc.MustGetToken(TK_StringConst);
|
|
default0 = KB_StringToScanCode(sc.String);
|
|
if (sc.CheckToken(','))
|
|
{
|
|
sc.MustGetToken(TK_StringConst);
|
|
default1 = KB_StringToScanCode(sc.String);
|
|
if (num >= 0 && num < NUMGAMEFUNCTIONS)
|
|
{
|
|
auto& key = KeyboardKeys[num];
|
|
#if 0
|
|
// skip the function if the default key is already used
|
|
// or the function is assigned to another key
|
|
if (lazy && (key[0] != 0xff || (CONTROL_KeyIsBound(default0) && Bstrlen(CONTROL_KeyBinds[default0].cmdstr) > strlen_gamefunc_
|
|
&& CONFIG_FunctionNameToNum(CONTROL_KeyBinds[default0].cmdstr + strlen_gamefunc_) >= 0)))
|
|
{
|
|
continue;
|
|
}
|
|
#endif
|
|
key[0] = default0;
|
|
key[1] = default1;
|
|
|
|
if (key[0]) CONTROL_FreeKeyBind(key[0]);
|
|
if (key[1]) CONTROL_FreeKeyBind(key[1]);
|
|
|
|
if (num == gamefunc_Show_Console)
|
|
OSD_CaptureKey(key[0]);
|
|
else
|
|
CONFIG_MapKey(num, key[0], 0, key[1], 0);
|
|
|
|
CONTROL_DefineFlag(num, false);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
static int osdcmd_button(osdcmdptr_t parm)
|
|
{
|
|
static char const s_gamefunc_[] = "gamefunc_";
|
|
int constexpr strlen_gamefunc_ = ARRAY_SIZE(s_gamefunc_) - 1;
|
|
|
|
char const *p = parm->name + strlen_gamefunc_;
|
|
|
|
//if (gInputMode == kInputGame) // only trigger these if in game (fixme: Ensure it works for all games!)
|
|
CONTROL_ButtonFlags[CONFIG_FunctionNameToNum(p)] = 1; // FIXME
|
|
|
|
return OSDCMD_OK;
|
|
}
|
|
|
|
static FString stringStore[2*NUMGAMEFUNCTIONS]; // toss all persistent strings in here so that they stick around until shutdown.
|
|
void SetupButtonFunctions()
|
|
{
|
|
unsigned index = 0;
|
|
// Note: This must run after the CON scripts had a chance to mess around with the game function name array.
|
|
for (auto & func : GF_NumToAlias)
|
|
{
|
|
if (func[0] == '\0')
|
|
continue;
|
|
|
|
stringStore[index].Format("gamefunc_%s", func);
|
|
stringStore[index].ToLower();
|
|
stringStore[index+1] = stringStore[index];
|
|
stringStore[index+1] += ": game button";
|
|
OSD_RegisterFunction(stringStore[index], stringStore[index+1], osdcmd_button);
|
|
index += 2;
|
|
}
|
|
|
|
} |