Two modes?

hongen

16-01-2008 18:18:31

Hi!

I'm trying make my project switch between QuickGUI's handlers for mouse and keyboard events to the "standard" version in ExampleFrameListener depending on whether my GUI is visible or not.

Since QuickGUIDemo inherits from ExampleFrameListener, I hope there is some easy way to achieve this.

Thanks in advance

kungfoomasta

16-01-2008 18:50:57

I'm not sure I understand. QuickGUI doesn't depend on the example framework, it just outlines a possible scenario for use. It is up to the user to determine when to inject inputs into QuickGUI.

You can use any framework you want, and inject inputs through the GUIManager's "inject" methods.

Can you elaborate what you mean by the "standard" version? Some code?

hongen

17-01-2008 09:46:20

Sorry if I was a bit vague on that. :)

I was referring to processUnbufferedKeyInput() and processUnbufferedMouseInput() in Ogre's own ExampleFrameListener. Currently, I have a project based mainly on QuickGUIDemo, where mouse and keyboard are being processed in mouseMoved() and keyPressed(). What I'm trying to do is something like this:

bool mouseMoved( const OIS::MouseEvent &arg )
{
if (guiVisible)
{
mGUIManager->injectMouseMove( arg.state.X.rel, arg.state.Y.rel );
return true;
}
else
{
//This is where I need to refer to ExampleFrameListener's
//methods
}
}


Hope you understand what I mean. :)

kungfoomasta

17-01-2008 17:27:27

FrameListener inherits from OIS::MouseListener and KeyListener, right?

I don't understand this:


//This is where I need to refer to ExampleFrameListener's
//methods


the "mouseMoved" function is one of the ExampleFrameListener methods.

What you're trying to do is perfectly fine.

hongen

17-01-2008 23:01:19

Hmm.. I guess I have some of the structure backwards then. I thought ExampleFrameListener only processed keyboard and mouse events using processUnbufferedKeyInput and processUnbufferedMouseInput, since I see no mention of mouseMoved, keyPressed nor keyReleased in ExampleFrameListener.

Is there something I'm missing here? I'm using 1.4.4 Eihort and QuickGUI v0.9.7 PreRelease.

From what I understand, defining my own mouseMoved seems to have fully overrided the mouse look behaviour found in ExampleFrameListener (as the inputs are now injected into the GUI instead). Do I need to copy a certain code snippet from ExampleFrameListener and insert it into the if-clause I submitted earlier? My idea is to switch between mouse look (when GUI is hidden) and GUI-mouse (when GUI is toggled on) in my application.

One more question:
In the demo, the up and down arrow keys are used to move the camera forward and backwards. However, the camera does not keep on moving when the key is pressed.. how can I do this?

Sorry if my questions are kinda newbie-level, but I've searched through the forums and wiki without finding answers.


Once again, thanks

kungfoomasta

17-01-2008 23:49:59

I'll try to shed some light. :)

First off, the demo isn't the greatest example to work with, I'm not really a fan of the demo framework, but I don't have time to come up with something better, with the same benefits. (small and simple)

In order to be notified by OIS that keys events have occurred, you need to use the following function:

OIS::Keyboard::setEventCallback

Likewise for the mouse:

OIS::Mouse::setEventCallback

These functions required an OIS::KeyListener object, and an OIS::MouseListener object. These classes define the interface for receiving mouse and key events.

For the demo, we have the framelistener inherit from these classes, and register the framelistener to be notified of mouse and key events:


class GuiFrameListener : public ExampleFrameListener, public OIS::KeyListener, public OIS::MouseListener

....

mMouse->setEventCallback(this);
mKeyboard->setEventCallback(this);


We override the KeyListener and MouseListener events, so we can make use of the notification of events:


bool mouseMoved( const OIS::MouseEvent &arg )
...
bool keyPressed( const OIS::KeyEvent &arg )
...


What you do inside these functions is totally up to you, and in your case, this is where you would put the code to inject QuickGUI with events. More advanced functionality, like injecting GUI events based on a flag (state), can be done as well.

defining my own mouseMoved seems to have fully overrided the mouse look behaviour found in ExampleFrameListener

If you want, you could do something like:


bool mouseMoved( const OIS::MouseEvent &arg )
{
ExampleFrameListener::mouseMoved(arg);
... // do some extra stuff
}


Or you could just take the code from that function and add it in.

chunky

18-01-2008 23:24:38

I'm not sure if this is what you want, but here's most of the salient bits of input.cpp from my current app.

Basically, I keep a boolean variable, mSendEventsToGUI, and if it's false, do one things, if it's true, do another. When the user hits '/', then events start going to the GUI instead of the game, ending when they hit either enter [like an "ok"] or escape [like a "cancel"]. If you've played any regular style MMO [think "warcraft"], you'll understand what I mean.

Other stuff of note:
1) It's the slash keyup event, not the keydown one, that triggers the modeswitch, to avoid a spurious keyup event going to the GUI.
2) When hitting enter while in GUI mode, send a keyup after the keydown. Same sanity stuff as #1.
3) There's two ways out of GUI mode, either esc or enter. Note how they're laid out, and that the enter case falls through to the esc case instead of ending with break. That's not an accident.

State machines 101 :-)

TWInput::TWInput(Ogre::RenderWindow *win, TWInputState *inputstate, TWGUI *twgui) {

mSendEventsToGUI = false;
mTWGUI = twgui;

if(NULL != mTWGUI) {
mGUIManager = mTWGUI->getGUIManager();
mGUIManager->getMouseCursor()->hide();
}
// Do all your normal OIS input creation stuff here
}

bool TWInput::mouseMoved(const OIS::MouseEvent &e) {
if(mTWGUI != NULL && mSendEventsToGUI) {
mGUIManager->injectMouseMove( e.state.X.rel, e.state.Y.rel );
// do stuff
}
return true;
}

bool TWInput::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) {
if(mTWGUI != NULL && mSendEventsToGUI) {
mGUIManager->injectMouseButtonDown(static_cast<QuickGUI::MouseButtonID>(id));
// do stuff
} else {
if(OIS::MB_Right == id) {
mInputState->mBoost = 1.0;
}
}
return true;
}

bool TWInput::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) {
if(NULL != mTWGUI && mSendEventsToGUI) {
mGUIManager->injectMouseButtonUp(static_cast<QuickGUI::MouseButtonID>(id));
// do stuff
} else {
if(OIS::MB_Right == id) {
mInputState->mBoost = 0.0;
}
}
return true;
}

bool TWInput::keyPressed(const OIS::KeyEvent &e) {
if(NULL != mTWGUI && mSendEventsToGUI) {
switch (e.key) {
case OIS::KC_RETURN:
// Assume this means we really want to do whatever we just did
mGUIManager->injectKeyDown(static_cast<QuickGUI::KeyCode>(e.key));
mGUIManager->injectChar(e.text);
mGUIManager->injectKeyUp(static_cast<QuickGUI::KeyCode>(e.key));
case OIS::KC_ESCAPE:
// Assume this means we want to cancel whatever input we started
mGUIManager->getMouseCursor()->hide();
mSendEventsToGUI = false;
break;
default:
mGUIManager->injectKeyDown(static_cast<QuickGUI::KeyCode>(e.key));
mGUIManager->injectChar(e.text);
// Push the event into the GUI
break;
}
} else {
switch (e.key) {
case OIS::KC_ESCAPE:
mContinue = false;
break;
default:
break;
}
}

return true;
}

bool TWInput::keyReleased(const OIS::KeyEvent &e) {
if(mSendEventsToGUI) {
mGUIManager->injectKeyUp(static_cast<QuickGUI::KeyCode>(e.key));
// do stuff
} else {
switch (e.key)
{
case OIS::KC_SLASH:
if(NULL != mTWGUI) {
mGUIManager->getMouseCursor()->show();
mTWGUI->focusChatTB();
mSendEventsToGUI = true;
}
break;
default:
break;
}
}

return true;
}


Hope that's of some use,
Gary (-;

chunky

18-01-2008 23:28:08

Also, I concur with kungfoomasta that life will be easier if you don't run with the example framework. Personally I found it entirely opaque and hard to create a real game around. Most notably, making things framerate-independant really sucks, compared to writing your own main loop.

In the demo, the up and down arrow keys are used to move the camera forward and backwards. However, the camera does not keep on moving when the key is pressed

If you're using the exampleapplication, it'll be *really* hard to make the camera move in a truly framerate-independant manner.

Gary (-;