Game Development Community

Working with OptionsDlg for keybinding?

by Jon Mitchell · in Torque Game Builder · 04/25/2007 (12:04 pm) · 25 replies

I have started to work a little with the OptionsDlg gui. Video and sound work pretty well as it although there seems to be a bit of an issue in full screen, the resolution really does not change as I would have expected.

Anyhow the question I wanted to ask is if anyone has edited OptionsDlg binding menu?
I am curious where the keybinding menu that is currently there gets its data to display, and when bindings are updated and saved where it is stored?

With my project I had been working on, I re-invented the keybinding system and it is horrible! I erally would like to work with what Garage games has already provided in T2D.
Page «Previous 1 2
#1
04/25/2007 (6:26 pm)
Jon, check out the OptionsDlg.cs file ... you might need to do some backwards tracking to find all the things you need, but thats a good starting point.

I've used this to disable things from optionsdlg, such as removing the keybinding tab, and changing other things (removing/adding/changing defaults, etc)... pretty easy once you get the hang of where your going ... :)


#2
04/27/2007 (1:06 pm)
I have worked on this a bit, and I have the whole menu working but the keybinding still.

It all relates back to 'KeysTextList' This is referenced in the Gui and also in keybindings.cs

I am not sure what it is though, Is it a function, a file, I just do not know? And I seem unable to find a default key mapping file as well.
#3
04/27/2007 (1:27 pm)
Search for the KeysTextList and find it in the Gui ... sounds like it'd be a GuiList control instance ... and it probably stores all the bindings in the list when it generates them ... but, I would assume that the key-bindings are read from the $Pref:: variables, check your prefs.cs and defaults.cs ... if you don't see anything in prefs.cs it could be in defaults.cs ... for the standard bindings ... and chances are ... the code is dynamic ...in the sense that ... it looks for all $Pref::Bindings::???? variables and lists them ... and then you can also read those values as well ... so if you toss some extras onto the end ... they might show up ... but I haven't look, this is a 'best guess' ...
#4
04/28/2007 (10:55 am)
Hi David,
After searching through the .gui files in the /games/common/gui folder I did go into the Gui editor and check if it was an instance, if it is a control instance it eludes me so far. Also to note that is that text menu's internal name as well KeysTextList and its alt command calls the ChangeBinding(); which is in keybinds.cs around line 129 which the very first line again refers to KeysTextList
%index = KeysTextList.getSelectedId();



DefaultPrefs.cs contains a lot of information for video, audio, input, networking but no key binding info. Prefs.cs looks to contain the modified values of defaultPrefs, but no key binding info there either, the way the configs are written out are pretty standard, I am not so certain that anything would happen after I turned up this up in the /common/gamescripts directory, in common.cs there is this function around line 101, it looks like a custom bind would create its own pref file.

//---------------------------------------------------------------------------------------------
// dumpKeybindings
// Saves of all keybindings.
//---------------------------------------------------------------------------------------------
function dumpKeybindings()
{
   // Loop through all the binds.
   for (%i = 0; %i < $keybindCount; %i++)
   {
      // If we haven't dealt with this map yet...
      if (isObject($keybindMap[%i]))
      {
         // Save and delete.
         $keybindMap[%i].save("~/preferences/bind.cs", %i == 0 ? false : true);
         $keybindMap[%i].delete();
      }
   }
}



I feel like I am missing something obvious, but am really close to the answer like it is under my nose. Unless of course that little nagging voice in the back of my head is right and it is something in the /engine directory because it is a default thing.

I am going to poke at the Adventure kit since they use custom keybindings too and maybe that might help.
#5
04/28/2007 (11:14 am)
So I though if I fired up the Adventure kit and modified the controls and I though I could then could do a search and look for all files modified at that time, but all the files with a modified time stamp that work contained no binding info??

Also to add to my confusion, the Adventure kit options menu looks like it calls the default optionsDlg and their bind menu is customized and it too calls KeysTextList. >_<
#6
04/28/2007 (1:43 pm)
K -- I just did a quick trace, and everything leads back to the game\main.cs setupKeybinds() function:

function setupKeybinds()
{
  new ActionMap(moveMap);
  moveMap.bind("keyboard", "a", "DoAction", "Description that shows up in Keybindings List");
}

So ... looks like all you gotta do to add items to the list, is add them here ...

Now ... to save the items, you have to call the dumpKeybindings() function, which writes out to common/preferences/bind.cs ...

Now, if you uncomment the default demo line in your games setupKeybinds() ... exec your game ... then load the optionsdlg ... and look inside, you'll see your new key binding is at the top ... the next time your game is loaded, it will load this new binding ...

So ... seems it's quite simple ...

The levelEditorMap.bind(....) calls found in the bind.cs are a level builder thing ... so when your game is shipped ... it won't have these ... you can test this by creating a new project in TGB and simply telling it load and display the optionsdlg ... then analyze and build it ... then run the newly built game and check the keybindings ... there should be none ...

now, if you go back to this new projects main.cs ... and add a few moveMap.bind values into it ... re-build and try again... your bindings will appear ...

now ... here's the kicker ... all the tutorials tell you to put the keybindings in places like gameStart() or Player::onLevelLoaded() ... why? I'm not sure ... if the Keybindings package is not activated, then the moveMap.bind() command does not add the key to the OptionsDlg ... and this package is only activated for a very short period of time ... you can see this in common.cs ...

activatePackage(keyBindings); 
setupKeybinds(); 
deactivatePackage(keyBindings);

now ... it's being activated, it's calling the code to init the bindings, then it's being deactivated ... only while this package is activated does it have the custom override that adds your bindings to the 'list' ... so, you'll have to change up some of your logic to use this ...

and this seems an interesting topic, since all the tutorials don't mention it and they bind in other contexts ... haha ...

#7
04/28/2007 (2:07 pm)
Jon, for future reference, I just tossed this up on TDN real quick -- as your sifting through it yourself, please feel free to update the TDN reference to make it more accurate ... I've not actually done anything short of rapid prototyping with this so I'm not really sure how nested into the system things are ... and how simply they are to modify overall ... I'm not 100% positive if the OptionsDlg saves your keybindings for you or not ... so I added a comment about adding 'dumpKeybindings()' to the Options Dialog OK ... but it might be in there ...

TGB -> Standard Tutorials -> Basics -> Options Dialog
#8
04/28/2007 (4:17 pm)
I just did some testing on your findings, and what I am looking at now makes lots of sense. it is pretty straight forward once you know how it works.
I will use the adventure kit as an example again. They have their key binds in a file, so I followed in their foot steps after I read your previous response. In the main.cs I put this in as they did for the setting up of the key binds, it just seems cleaner.

function setupKeybinds()
{
exec("./gameScripts/inputkeys.cs");
setupInputs();
}


And the input keys simply hold the binding information like this:

moveMap.bind( keyboard, up, "moveUp" );
moveMap.bind( keyboard, down, "moveDown" );
moveMap.bind( keyboard, left, "moveLeft" );
moveMap.bind( keyboard, right, "moveRight" );


The bit about adding the dump bind command is right on the money, a person will need to add the dumpKeybindings() to their script because by default optionsDlg does not save them. I made that modification and it did exactly what I expected, it made a bind.cs file in /preferences.


The only change I would recommend that people set up their bindings in a separate file that is called and add this as a default entry in the file to start with so you can access the menu from in game:

GlobalActionMap.bindCmd(keyboard, "Ctrl m", "", "Canvas.PushDialog(optionsDlg);");
Or whatever key or key combo that someone would want to use to open a menu.

But that is just me I like keeping the main.cs and game.cs as clean as I can if possible :-p
Once it is laid out it is really just crazy at how simple it is. I did compile it as a test and indeed the finished product does not have the editor information.
Thank you again David, you have been a huge help for me, and I sure hope other people who come along find the information you have come up with as useful as I have!
#9
04/28/2007 (5:32 pm)
Jon, your welcome -- it's all a learning experience for me as well ... as people ask questions, I wonder myself what the answer is ... and in helping them out, I learn along the way ...

Glad it's appreciated :)

#10
04/29/2007 (11:00 pm)
Jon ... you might have some input this ... ;)

garagegames.com/mg/forums/result.thread.php?qt=61459
#11
05/06/2007 (8:59 pm)
Well, I just ran into an error. I had run into something like this before and was the result of malformed input moveMap.bind for the menu, however I do not think this is the case this time.
What happens if you open the keybinding menu and make a change, then save it your controls are disabled. If you open the bind menu again all the inputs are blank, even if you reset them they will be blank when you load the menu again. If you quit TGB and reload it the controls are re-enabled and you are free to move about again in the game and the bind menu has the bindings displayed again, but if you try to change them the same thing will happen.

Here is the output from the console, these errors seem to say that they are unable to fetch the binding. I did clear the binding.cs file and the .dso and tried again with the same luck. I am at a bit of a loss at the moment.




common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'moveMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
common/gameScripts/keybindings.cs (39): Unable to find object: 'levelEditorMap' attempting to call function 'getBinding'
Loading compiled script Retrotank/gameScripts/input.cs.
Retrotank/gameScripts/game.cs (30): Unable to find object: 'moveMap' attempting to call function 'pop'
tools/leveleditor/main.cs (253): Unable to find object: 'levelEditorMap' attempting to call function 'push'
Set::getObject index out of range.
Retrotank/gameScripts/game.cs (30): Unable to find object: 'moveMap' attempting to call function 'pop'
#12
05/07/2007 (6:54 am)
Sounds like a bug with level builder possibly ...
#13
05/07/2007 (11:58 am)
I had a chance to test the game on another computer today and it did not have the same problem, so I am guessing you are quite correct, I guess it would not hurt for a reinstall now anyhow :)
#14
05/07/2007 (5:22 pm)
I spoke a little too soon, it seems pretty normal until you use the reset to defaults button, if you use that none of the inputs work until you load a new level and there is no console error reported.
I am checking into why that would happen, for all controls to not work until next level loaded seems a little funny, since all the reload default button does is clear the bindings, and that is the funny part, the bindings should not need to be reloaded should they?
#15
05/07/2007 (5:44 pm)
Did you modify the keybindings.cs to support bindCmd ... ? or make any changes to the default behaviour of the keybinding system?
#16
05/08/2007 (8:07 am)
IThe only change I made was to the option.gui to add the dump bind command, I just discovered on the test computer I had not made that change which explains the new behavior. If I add the dumpKeybindings(); back into the line near 389 I see the original problem resurface, if I remove it I end up with the issue when I revert to defaults I have to load a new level for them to take effect, but new manual bindings work fine.

In my Main.cs this is how I call my key mappings:
function setupKeybinds()
{
exec("./gameScripts/input.cs");
setupInputs();
}



then the input.cs looks like this:
//*********************Set up input controls and bindings********************************
function setupInputs()
{
   $enableDirectInput = "1";
   activateDirectInput();
   enableJoystick();
   
   if ( isObject( moveMap ) )
      moveMap.delete();
   new ActionMap(moveMap);

//Player 1 default bindings
   moveMap.bind( keyboard, "w", "moveUp1", "Player 1 - Forward" );
   moveMap.bind( keyboard, "s", "moveDown1", "Player 1 - Reverse" );
//Player 2 default bindings
   moveMap.bind( keyboard, "numpad8", "moveUp2", "Player 2 - Forward" );
   moveMap.bind( keyboard, "numpad5", "moveDown2", "Player 2 - Reverse" );
//The menu key can not be rebound and so it does not show up in the menu.
   GlobalActionMap.bindCmd(keyboard, "ctrl delete", "", "Canvas.PushDialog(optionsDlg);");
}



//*********************Input control and function calls********************************
//Player 1 controls
function moveUp1( %val )
{
  if ( %moveUp1 = %val )
   {
   $P1Tank.gasPedal = true;
   } else {
   $P1Tank.gasPedal = false;
   }
}

and so on



Just to note, it is only the movemap keys that will fail, the ctrl + delete option still will pop the menu open.
#17
05/08/2007 (6:22 pm)
//---------------------------------------------------------------------------------------------
// setupKeybinds
// Bind keys to actions here..
//---------------------------------------------------------------------------------------------
function setupKeybinds()
{
   new ActionMap(moveMap);
   //moveMap.bind("keyboard", "a", "doAction", "Action Description");
}

That's the original setupKeybinds() ... so ... hrm ...

What does "dumpKeybindings()" generate as a resulting file in common/preferences/bind.cs?
#18
05/08/2007 (7:46 pm)
Here is the long of it below, I had cut short the original input.cs file but included the whole dump from bind.cs:


// Torque Input Map File
if (isObject(moveMap)) moveMap.delete();
new ActionMap(moveMap);
moveMap.bind(keyboard, "a", moveCCW1);
moveMap.bind(keyboard, "d", moveCW1);
moveMap.bind(keyboard, "q", moveTurretCCW1);
moveMap.bind(keyboard, "e", moveTurretCW1);
moveMap.bind(keyboard, "space", Fire1);
moveMap.bind(keyboard, "numpad8", moveDown2);
moveMap.bind(keyboard, "numpad5", moveUp2);
moveMap.bind(keyboard, "numpad4", moveCCW2);
moveMap.bind(keyboard, "numpad6", moveCW2);
moveMap.bind(keyboard, "numpad7", moveTurretCCW2);
moveMap.bind(keyboard, "numpad9", moveTurretCW2);
moveMap.bind(keyboard, "numpad0", Fire2);
moveMap.bind(keyboard, "x", moveDown1);
moveMap.bind(keyboard, "s", moveUp1);
if (isObject(levelEditorMap)) levelEditorMap.delete();
new ActionMap(levelEditorMap);
levelEditorMap.bind(keyboard, "[", layerSelectionDown);
levelEditorMap.bind(keyboard, "]", layerSelectionUp);
levelEditorMap.bind(keyboard, "escape", levelBuilderSetSelectionTool);
levelEditorMap.bind(keyboard, "e", levelBuilderSetEditPanel);
levelEditorMap.bind(keyboard, "c", levelBuilderSetCreatePanel);
levelEditorMap.bind(keyboard, "p", levelBuilderSetProjectPanel);
levelEditorMap.bind(keyboard, "home", levelBuilderHomeView);
levelEditorMap.bind(keyboard, "end", levelBuilderZoomToFit);
levelEditorMap.bind(keyboard, "=", levelBuilderZoomViewIn);
levelEditorMap.bind(keyboard, "minus", levelBuilderZoomViewOut);
levelEditorMap.bind(keyboard, "left", levelBuilderViewLeft);
levelEditorMap.bind(keyboard, "right", levelBuilderViewRight);
levelEditorMap.bind(keyboard, "up", levelBuilderViewUp);
levelEditorMap.bind(keyboard, "down", levelBuilderViewDown);
levelEditorMap.bindCmd(keyboard, "f5", "runGame();", "");
levelEditorMap.bind(keyboard, "ctrl z", levelBuilderUndo);
levelEditorMap.bind(keyboard, "ctrl y", levelBuilderRedo);
levelEditorMap.bind(keyboard, "ctrl c", levelBuilderCopy);
levelEditorMap.bind(keyboard, "ctrl x", levelBuilderCut);
levelEditorMap.bind(keyboard, "ctrl v", levelBuilderPaste);
#19
05/08/2007 (7:48 pm)
Is bind.cs being re-executed at any point after the optionsdlg wipes the keybindings? :)
#20
05/09/2007 (7:15 am)
No I guess not, I was under the impression when you hit OK it would re-run bind.cs after you make your manual changes.
Page «Previous 1 2