Wrecked Games

Please login or register.

Login with username, password and session length
Advanced search  

News:

We're just that awesome.

Author Topic: [patch proposal] Input binding system  (Read 1470 times)

Kulik

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 8
    • View Profile
[patch proposal] Input binding system
« on: August 29, 2010, 03:32:43 PM »

Hi,
let me start by saying that I really like OIS, it hides all the dirty aspects of input handling :-) But I think it's a bit too low level for most games/applications so I created a big wrapper around it.

I now have an insanely ambitious idea :-D Decoupling that wrapper from my engine and releasing it separately. I think it would be even better to rework it a bit and include it with the OIS.

It's all cross platform stuff, only uses OIS itself, no new dependencies except for boost::signal but I can get rid of that or allow optional inclusion of it.

Now what it does :-) It allows bindings of input states to actions, it groups these bindings in schemes so you can switch from menu mode to ingame mode, etc... I have to rework some details first but this is the grand idea...

Basically you have Devices (OIS::Object), these devices have States (analog or digital, basically an axis for analog and pressed/released for digital - like a key). You can bind States to Actions, Actions provide further abstraction to allow binding of digital input state to analog action (emulating analog for car steering on keyboard for example) and vice versa (not really usable but it's there). You can basically work the same with Actions as with current States. I have yet to decide whether I want multiple input states (like CTRL+A) bound to one action but one action can be triggered by two different input states.

I am open to suggestions about it, the plan is to make powerful binding system that will allow to implement game controls settings with ease (every decent game needs one IMO). If there are any existing implementations please tell me, I haven't found any.

So my question is if you are interested in this thing getting into OIS or if it should be separate... The idea is that if somebody chooses not to use this, low level OIS can be used without touching high level stuff.

Martin Preisler
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 2652
    • View Profile
    • http://www.wreckedgames.com
Re: [patch proposal] Input binding system
« Reply #1 on: August 29, 2010, 05:48:27 PM »

I would welcome such a project into OIS main project. However, it would have to be a static/dynamic dll extension type of thing and not part of the main libOIS. That way it would be completely optional.

Some nice things of such a system:
* Input mapping (don't think boost is a good requirement, something like fast delegates or events like OIS implements would reduce external dependencies)
* Gestures - Mouse, multi-touch
* Combination - like you mention CTRL+A, etc
* And history based combinations, like for example, the konami code (Up Up Down Down Left, etc etc)

Logged

Kulik

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 8
    • View Profile
Re: [patch proposal] Input binding system
« Reply #2 on: August 30, 2010, 01:29:42 AM »

Damn, that means I have to come up with a name for it ;D But having this as part of OIS project is great, means more ppl will use it. I will try to come up with some design ideas and get back there.

Input mapping without boost is a done deal, I had boost as a dependency because I already use it elsewhere.
Gestures will need some more thinking, do you think Action should be triggered when certain gesture is "drawn"? I had just 1D axes in mind (mouse would be 2 analog input states), this will probably need some refactoring to include 2D axes.
Combinations is a done deal
Konami history thing will need some refactoring. Doing this inefficiently is easy but I want a clean fast solution.

The only thing that bugs me is the fact that OIS::Object derived classes are too concrete. That means I have to write a thin wrapper aroud OIS::Object. But this is probably the only reasonable way because I need a class that will expose all it's states and the states must have string names.

If anyone has any related ideas, please share them.
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 2652
    • View Profile
    • http://www.wreckedgames.com
Re: [patch proposal] Input binding system
« Reply #3 on: August 31, 2010, 07:07:03 PM »

What do you think the Object classes need exactly? I designed them towards Action Mapping, not really gestures. They can be added to if you think more information could be passed along.

I'm planning on pushing out a release shortly. I had planned to add a few more features, but I don't think I will get those in. After I put out the release, I can branch that out and make head a testing ground for this - and also give you SVN access. Will plan for this weekend on getting that done - 3-day weekend coming up :)
Logged

Kulik

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 8
    • View Profile
Re: [patch proposal] Input binding system
« Reply #4 on: September 01, 2010, 07:57:14 AM »

My initial idea was to have a Device that will contain States. The states can be analog or digital and they have string understandable names. OIS::Object itself doesn't allow me to do that, because Mouse and Keyboard are handled differently. There is Keyboard::isKeyPressed whilst Mouse has MouseState. Same with Events.

The wrapper will be really thin and it will just hide this aspect.

I will probably wrap events and buffer them but allow something like ActionListener at the same time. I have some ideas rattling in my head, I will post how I want the API to look soon :-)

Still don't have any ideas about the name though ;D
Logged

Kulik

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 8
    • View Profile
Re: [patch proposal] Input binding system
« Reply #5 on: September 14, 2010, 02:33:35 PM »

Sorry I haven't replied for so long, I have been busy (and I still am). But I definitely want this to get done eventually, it just might take time.

Ideas:
Code: [Select]
void Game::defineActions()
{
    Scheme* ingame = SchemeManager::getSingleton().createScheme("Ingame");
    // defining actions
    Action* shoot = ingame->createAction("Shoot", AT_DIGITAL);
    Action* nextW = ingame->createAction("Next weapon", AT_DIGITAL);
    Action* prevW = ingame->createAction("Previous weapon", AT_DIGITAL);
    Action* mouseLookX = ingame->createAction("Mouse Look X", AT_ANALOG_AXIS);
    Action* mouseLookY = ingame->createAction("Mouse Look Y", AT_ANALOG_AXIS);
    // binding them
    Keyboard* keyboard = DeviceManager::getSingleton().getDevice("Keyboard");
    shoot->bind(keyboard->getState("CTRL")); // doom 1 style!
    nextW->bind("Keyboard/R"); // allow absolute string state names (this eases loading/saving of bindings)
    prevW->bind("Keyboard/T");
    mouseLookX->bind("Mouse/X Axis");
    mouseLookY->bind("Mouse/Y Axis");
    // will also allow this to make things extra easy for scripts/loading/saving
    ingame->bind("Shoot", "Keyboard/CTRL");
    ingame->bind("Shoot", "Keyboard/CTRL + Keyboard/A"); // combination binding
    // I want "," to delimit alternative bindings (ie any of those states activated means that action is activated)
    // and "+" to delimit combination bindings (all of those states need to be activated for the action to be activated)
    // I am not sure yet how I will implement this in the raw API
    // maybe this?
    Binding b;
    b.add("Keyboard/CTRL");
    b.add("Keyboard/A");
    shoot->bind(b);
    // I don't like this yet so I will give it some more thought   
   
    Scheme* ingameCar = SchemeManager::getSingleton().createScheme("Ingame (Car)");
    AnalogAxisAction* steer = static_cast<AnalogAxisAction*>(ingameCar->createAction("Steer", AT_ANALOG_AXIS));
    // change properties of analog axis action
    steer->setAllowAnalogEmulation(true);
    steer->setMinimum(-1.0);
    // also allow properties for easier save/load and scripting
    steer->setProperty("Minimum", "-1.0");
    steer->setProperty("Maximum", "1.0");
    steer->setProperty("Sensitivity", "2.0");
    // for analog, you can normally bind analog stuff
    steer->bind("Joystick/Axis");
    // or you can bind digital stuff and the analog action will emulate analog input state
    steer->bindDigital("Keyboard/Left", "Keyboard/Right");
    // I might allow some other ways to do this to ease scripting
    // perhaps this?:
    steer->bind("Keyboard/Left, Keyboard/Right");
       
    Scheme* menu = SchemeManager::getSingleton().createScheme("Menu");
    Action* mouseX = menu->createAction("Mouse X", AT_ANALOG_AXIS);
    Action* mouseY = menu->createAction("Mouse Y", AT_ANALOG_AXIS);
    Action* click = menu->createAction("Mouse Click", AT_DIGITAL);
    // ...

    // KONAMI SEQUENCE STUFF
    SequenceAction* iddqd = static_cast<SequenceAction*>(ingame->createAction("Godmode", AT_SEQUENCE));
    // I don't like this, it doesn't really decouple actions and input states
    // and it disallows 2 or more possible sequences
    iddqd->bind("Keyboard/I, Keyboard/D, Keyboard/D, Keyboard/Q, Keyboard/D");
    iddqd->setTimeout(0.5); // allow half a second between sequence keys

    // I have no idea yet about gestures, but I guess gestures are pretty much just Action's that
    // will need 2 analog axes bound to them and they can recognize something based on that
    // I have to do more research in this area
   
    ingame->activate();
    menu->deactivate();
   
    // now
   
}
 
void Game::setupIngame()
{
    SchemeManager::getSingleton().deactivateAll();
    ingame->activate();
}
 
// HOW TO USE THE ACTIONS IN BUFFERED MODE:
 
if (shoot->isActive())
{
    // perform shooting
}
//...

// OR VIA LISTENERS
via shoot->setListener(ActionListener*)
 
 
// BUFFERED ANALOG ACTION
if (steer->isActive()) // this means it was activated == changed
{
    // steer our ingame car
    //steer->getAbsolute();
    //steer->getRelative();
}

This is just a mockup, but most of this is already possible with my code with some differences. I want to clean it up a lot (right now I only support buffered actions).

I want to make it easy to create generic ingame controls UI. So I will add ways to listen to all states at once, etc...
Logged

Kulik

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 8
    • View Profile
Re: [patch proposal] Input binding system
« Reply #6 on: September 28, 2010, 04:26:03 AM »

OK I have ported the code over and renamed the project to OISB. I still have some boost dependencies that are quite easy to get rid of (lexical_cast mostly). I want to redo the Actions now a bit to allow SequenceActions (IDDQD), AnalogAxisAction (steering for example), AnalogPlaneAction (this will allow gestures in future), CombinationAction (CTRL + A). Right now I have binding manager holding bindings, I want to get rid of this singleton and let actions manage their bindings. I am still not sure how to allow alternatives generically so I don't have to reimplement them for all the different Actions but I will figure it out soon hopefully.

If you don't mind me polluting the svn, I would like to commit so I can keep history. Otherwise I will just set up a local repo.

The project is for now called OISB (OIS Binding System?). If anyone has a better idea for a name I am all for it ;D
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 2652
    • View Profile
    • http://www.wreckedgames.com
Re: [patch proposal] Input binding system
« Reply #7 on: September 28, 2010, 06:58:34 PM »

I can setup a branch of SVN head for you to work with. If you can, please email/PM me your sourceforge user name and I'll get that set up.
Logged

Kulik

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 8
    • View Profile
Re: [patch proposal] Input binding system
« Reply #8 on: September 30, 2010, 05:16:51 AM »

Hi, thanks for the svn access. I can see the branch.

I wanted to ask where do you want the code to go? I originaly thought this would go to the root, folder "oisb" next to ois but I can see now that this would need a new svn layout there. The branch is aready from svnroot/ois folder, so do I just add the oisb folder there? Doesn't look OK to me ???

The OISB has a separate namespace "OISB", separate include and src files, separate project files. Right now it's basically a DLL, static linking is also allowed. I kept it completely separate from ois to avoid forcing it onto people.

I have put the current WIP version to this url http://harcov.czenet.com/kulik/oisb.zip for now before you decide where it should go.

Lil' todo list:
  • Allow sequences to be bound to states and actions, so that you can define combos (ATTACK + LEFT + ATTACK for example).
  • Add ActionListeners and StateListeners.
  • Doing a console demo (ois demo won't start for me unfortunately so I can't grab it's code, it complains about not being able to CreateDialog :-( )
  • Cleaning up and documenting

PS: Do you go on IRC somewhere so I can annoy you in realtime reducing the forum lag? ;)
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 2652
    • View Profile
    • http://www.wreckedgames.com
Re: [patch proposal] Input binding system
« Reply #9 on: September 30, 2010, 06:09:16 PM »

I don't think placing it in the main solution file as an additional project will force people to have to use it. So, I suggest just adding:

branches\mpreisler\extras\inputbinding\src
branches\mpreisler\extras\inputbinding\include

And place the project files in the win32 directory.

I'm unfortunately not online enough to use IRC. Forum is probably the best way to ask questions. Though, it would be possible to talk via Y! Msg or Msn Msg occasionally.
Logged

Kulik

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 8
    • View Profile
Re: [patch proposal] Input binding system
« Reply #10 on: October 01, 2010, 03:17:35 PM »

OK, I've committed some initial code. it's in branches/mpreisler/oisb
I only have MSVC 2010 so I only provided vc10 project files for now.

The API isn't clean and ready yet, but the main concepts are there. I still want to rename and reorganize some of it (I hate the name "Bindable" for example).

SequenceAction isn't much tested yet but Trigger and AnalogAxis work fine for me.
Logged

Kulik

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 8
    • View Profile
Re: [patch proposal] Input binding system
« Reply #11 on: October 08, 2010, 10:14:42 AM »

I posted some more stuff on Ogre forum, including initial demo.

Here's the thread:
http://www.ogre3d.org/forums/viewtopic.php?f=1&t=60635
Logged

reptor

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 6
    • View Profile
Re: [patch proposal] Input binding system
« Reply #12 on: March 01, 2011, 04:35:46 PM »

I tried to compile the latest OISB code from svn on Linux and g++ (Debian 4.3.2-1.1) 4.3.2 gives this:

Quote
In file included from src/oisb/OISBPropertySet.cpp:24:
include/oisb/OISBPropertySet.h:57: error: explicit specialization in non-namespace scope ‘class OISB::PropertySet’
include/oisb/OISBPropertySet.h:67: error: expected nested-name-specifier before ‘T’
include/oisb/OISBPropertySet.h:67: error: too many template-parameter-lists
include/oisb/OISBPropertySet.h:73: error: explicit specialization in non-namespace scope ‘class OISB::PropertySet’
include/oisb/OISBPropertySet.h:81: error: too many template-parameter-lists
include/oisb/OISBPropertySet.h:91: error: too many template-parameter-lists

It looks like some template code in there isn't g++ compatible? Perhaps someone else can try to compile it on Linux - I don't understand how to fix that.
« Last Edit: March 01, 2011, 04:38:31 PM by reptor »
Logged