Jump to content
  • Advertisement
Sign in to follow this  
TheBroodian

Button Assignments

This topic is 2544 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Trying to work on some sort of a button assignment system to change key bindings for controllers and keyboards. I have some sort of foggy idea about how I would do this, but I reach a point where the idea escapes me a little bit. Both direct input and Xinput's buttons correspond to an int, so it would seem simple enough to be able to attach that int to a string to symbolize the function the button has in the game (as the player prefers). But I'm a little unsure of how I would set this up.

In case I'm explaining this poorly, this is sort of how I would like it to work:

A menu queries the player to press the button he wants to use to Jump.

Player presses the button he wants to use for Jumping.

That button returns its int value corresponding to that button, and the game stores that int somewhere and correlates it to the action/function.

Anytime the button is pressed with that value, the game will relate it to the "Jump" button.

And if at a later time the player would like to do so, he can reassign the button to another function, and use a different button for Jump.

Share this post


Link to post
Share on other sites
Advertisement
What language are you using? In C++ you can create a map from a button id to a function pointer. In C# you could create a dictionary from a button id to a delegate.

Share this post


Link to post
Share on other sites
I am doing something like that, except the user defines the keys he wants to use in an xml file, like this:


<Left>a</Left>
<Right>d</Right>
<Up>w</Up>
<Down>s</Down>
<Fire>MouseLButton</Fire>
<SpecialFire>MouseRButton</SpecialFire>


And, it allows the user to map a typical key action to a keyboard or a mouse button.

And, in my source file, i have these structures:


typedef enum
{
GAME_KEY_FIRST = 0,
GAME_KEY_LEFT = GAME_KEY_FIRST,
GAME_KEY_RIGHT,
GAME_KEY_UP,
GAME_KEY_DOWN,
GAME_KEY_FIRE,
GAME_KEY_SPECIAL_FIRE,
GAME_KEY_MAX

} etGameKeys;


std::string gpCfgStrings[MAX_CONFIG_OPTIONS] =
{
"Left",
"Right",
"Up",
"Down",
"Fire",
"SpecialFire",
"MouseSensitivity",
"ScreenWidth",
"ScreenHeight",
"FullScreen"
};


typedef struct
{
BOOL bMouseKey;
sf::Key::Code SfKey;
sf::Mouse::Button SFButton;

} tKeyHash;

typedef struct
{
std::string ConfigName;
tKeyHash KeyHash;

} tInputConfigNames;

// Available names for config file setting
tInputConfigNames gInputConfigNames[] =
{
{ "MouseLButton", {TRUE, sf::Key::A, sf::Mouse::Left} },
{ "MouseRButton", {TRUE, sf::Key::A, sf::Mouse::Right} },
{ "RCtrl", {FALSE, sf::Key::RControl, sf::Mouse::Left} },
{ "LCtrl", {FALSE, sf::Key::LControl, sf::Mouse::Left} },
{ "RShift", {FALSE, sf::Key::RShift, sf::Mouse::Left} },
{ "LShift", {FALSE, sf::Key::LShift, sf::Mouse::Left} },
{ "RAlt", {FALSE, sf::Key::RAlt, sf::Mouse::Left} },
{ "LAlt", {FALSE, sf::Key::LAlt, sf::Mouse::Left} },
{ "Space", {FALSE, sf::Key::Space, sf::Mouse::Left} },
{ "Return", {FALSE, sf::Key::Return, sf::Mouse::Left} },
{ "CursorRight", {FALSE, sf::Key::Right, sf::Mouse::Left} },
{ "CursorLeft", {FALSE, sf::Key::Left, sf::Mouse::Left} },
{ "CursorUp", {FALSE, sf::Key::Up, sf::Mouse::Left} },
{ "CursorDown", {FALSE, sf::Key::Down, sf::Mouse::Left} },
{ ",", {FALSE, sf::Key::Comma, sf::Mouse::Left} },
{ ".", {FALSE, sf::Key::Period, sf::Mouse::Left} },
{ "/", {FALSE, sf::Key::Slash, sf::Mouse::Left} },
{ ";", {FALSE, sf::Key::SemiColon, sf::Mouse::Left} },
{ "\'", {FALSE, sf::Key::Quote, sf::Mouse::Left} },
{ "[", {FALSE, sf::Key::LBracket, sf::Mouse::Left} },
{ "]", {FALSE, sf::Key::RBracket, sf::Mouse::Left} },
{ "\\", {FALSE, sf::Key::BackSlash, sf::Mouse::Left} }
};


/* strings for certain array locations */

tKeyHash gKeyHash[GAME_KEY_MAX] =
{
{FALSE, sf::Key::A, sf::Mouse::Left},
{FALSE, sf::Key::D, sf::Mouse::Left},
{FALSE, sf::Key::W, sf::Mouse::Left},
{FALSE, sf::Key::S, sf::Mouse::Left},
{TRUE, sf::Key::RControl, sf::Mouse::Left},
{TRUE, sf::Key::RControl, sf::Mouse::Right},
};


I then loop through the xml file, and look for items in the gpCfgStrings array, and when they match, I call UpdateSettings():



static void UpdateSettings(C8 *pcSetting, U32 u32Option)
{
U32 u32Value;
std::string SettingStr(pcSetting);
BOOL bFoundName = FALSE;

if (u32Option >= GAME_KEY_MAX)
{
u32Value = atoi(pcSetting);
//printf("Setting option %d value %d\n", u32Option, u32Value);

if (u32Option == MOUSE_SENSITIVITY_LOC)
{
gu32MouseSens = u32Value;
}
else if (u32Option == SCREEN_WIDTH_LOC)
{
gu32ScreenWidth = u32Value;
}
else if (u32Option == SCREEN_HEIGHT_LOC)
{
gu32ScreenHeight = u32Value;
}
else
{
gbFullScreen = FALSE;

/* it's Full Screen, get Yes or No */
if (strcmp(pcSetting, "Yes") == 0)
{
printf("It's Fullscreen!\n");
gbFullScreen = TRUE;
}
}

return;
}

for(uint32_t i = 0; i < sizeof(gInputConfigNames)/sizeof(tInputConfigNames); i++)
{
if (SettingStr == gInputConfigNames.ConfigName)
{
gKeyHash[u32Option] = gInputConfigNames.KeyHash;
bFoundName = TRUE;
break;
}
}

if (!bFoundName)
{
/* it should be a single character */
C8 c8Key = pcSetting[0];

if ((c8Key >= 'a') && (c8Key <= 'z'))
{
gKeyHash[u32Option].SfKey = (sf::Key::Code)c8Key;
}
}
}


Finally, the user checks if a key is down by passing in a etGameKeys enumeration, and gets a boolen IsDown back:


BOOL Utilities::KeyIsDown(const sf::Input& Input, etGameKeys eQKey)
{
BOOL bDown = FALSE;

if (eQKey < GAME_KEY_MAX)
{
if (gKeyHash[eQKey].bMouseKey)
{
if (Input.IsMouseButtonDown(gKeyHash[eQKey].SFButton))
{
bDown = TRUE;
}
}
else
{
if (Input.IsKeyDown(gKeyHash[eQKey].SfKey))
{
bDown = TRUE;
}
}
}

return bDown;

}


So, that's how I do it in C++. Maybe you'll get an idea of how you can do this in C#/XNA.

Good Luck!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!