forked from teamnwah/openmw-tes3coop
Finished basic key binding system. Minor other cleanups.
This commit is contained in:
parent
4fbada8605
commit
f3d7f2e25a
23 changed files with 144 additions and 220 deletions
|
@ -28,13 +28,16 @@ set(OGRE ogre/renderer.cpp)
|
|||
set(OGRE_HEADER ogre/renderer.hpp)
|
||||
|
||||
set(INPUT input/oismanager.cpp)
|
||||
set(INPUT_HEADER input/oismanager.hpp input/listener.hpp)
|
||||
set(INPUT_HEADER input/oismanager.hpp input/listener.hpp input/func_binder.hpp input/dispatch_map.hpp input/dispatcher.hpp)
|
||||
|
||||
set(GAME game/main.cpp game/esm_store/store.cpp game/cell_store.cpp)
|
||||
set(GAME_HEADER game/cell_store.hpp game/esm_store/reclists.hpp game/esm_store/store.hpp)
|
||||
set(GAME game/main.cpp)
|
||||
set(GAME_HEADER game/mwinput/inputmanager.hpp)
|
||||
|
||||
set(GAMEREND game/render/mwscene.cpp game/render/cell.cpp)
|
||||
set(GAMEREND_HEADER game/render/cell.hpp game/render/mwscene.hpp)
|
||||
set(ESM_STORE esm_store/store.cpp esm_store/cell_store.cpp)
|
||||
set(ESM_STORE_HEADER esm_store/cell_store.hpp esm_store/reclists.hpp esm_store/store.hpp)
|
||||
|
||||
set(GAMEREND game/mwrender/mwscene.cpp game/mwrender/cell.cpp)
|
||||
set(GAMEREND_HEADER game/mwrender/cell.hpp game/mwrender/mwscene.hpp)
|
||||
|
||||
set(ESM_HEADER esm/defs.hpp esm/loadcell.hpp esm/loadfact.hpp esm/loadltex.hpp
|
||||
esm/loadskil.hpp
|
||||
|
@ -87,7 +90,8 @@ add_executable(openmw
|
|||
${NIF} ${NIF_HEADER}
|
||||
${NIFOGRE} ${NIFOGRE_HEADER}
|
||||
${MANGLE_VFS}
|
||||
${GAME} ${GAME_HEADER}
|
||||
${GAME}
|
||||
${ESM_STORE} ${ESM_STORE_HEADER}
|
||||
${GAMEREND} ${GAMEREND_HEADER}
|
||||
${ESM_HEADER})
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
NOTE: This README is for ardekantur's Mac branch of OpenMW. A README
|
||||
for the main branch has yet to be written. If you want to submit one,
|
||||
please send me a message!
|
||||
|
||||
OpenMW
|
||||
======
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
(looking up references.) Neither of these modules depend on us.
|
||||
*/
|
||||
|
||||
#include "esm_store/store.hpp"
|
||||
#include "store.hpp"
|
||||
#include "esm/records.hpp"
|
||||
#include "mangle/tools/str_exception.hpp"
|
||||
#include <list>
|
|
@ -1,13 +1,13 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "cell_store.hpp"
|
||||
#include "render/cell.hpp"
|
||||
#include "render/mwscene.hpp"
|
||||
#include "esm_store/cell_store.hpp"
|
||||
#include "bsa/bsa_archive.hpp"
|
||||
#include "ogre/renderer.hpp"
|
||||
#include "tools/fileops.hpp"
|
||||
#include "input/oismanager.hpp"
|
||||
#include "input/listener.hpp"
|
||||
|
||||
#include "mwrender/cell.hpp"
|
||||
#include "mwrender/mwscene.hpp"
|
||||
#include "mwinput/inputmanager.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -44,10 +44,10 @@ void maintest()
|
|||
cout << "\nSetting up cell rendering\n";
|
||||
|
||||
// Sets up camera, scene manager etc
|
||||
Render::MWScene scene(ogre);
|
||||
MWRender::MWScene scene(ogre);
|
||||
|
||||
// This connects the cell data with the rendering scene.
|
||||
Render::CellRender rend(cell, scene);
|
||||
MWRender::CellRender rend(cell, scene);
|
||||
|
||||
// Load the cell and insert it into the renderer
|
||||
rend.show();
|
||||
|
@ -55,10 +55,7 @@ void maintest()
|
|||
cout << "Setting up input system\n";
|
||||
|
||||
// Sets up the input system
|
||||
Input::OISManager input(ogre);
|
||||
|
||||
// Add the frame and input listener
|
||||
Input::ExitListener frame(ogre, input);
|
||||
MWInput::MWInputManager input(ogre);
|
||||
|
||||
cout << "\nStart! Press Q/ESC or close window to exit.\n";
|
||||
|
||||
|
|
44
game/mwinput/inputmanager.hpp
Normal file
44
game/mwinput/inputmanager.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef _INPUT_MWINPUTMANAGER_H
|
||||
#define _INPUT_MWINPUTMANAGER_H
|
||||
|
||||
#include "input/listener.hpp"
|
||||
#include "input/dispatcher.hpp"
|
||||
#include "boost/bind.hpp"
|
||||
|
||||
namespace MWInput
|
||||
{
|
||||
enum Actions
|
||||
{
|
||||
A_Quit, // Exit the program
|
||||
|
||||
A_LAST // Marker for the last item
|
||||
};
|
||||
|
||||
// Class that handles all input and key bindings for OpenMW
|
||||
class MWInputManager
|
||||
{
|
||||
Input::Dispatcher disp;
|
||||
Input::OISManager input;
|
||||
Input::InputListener listener;
|
||||
|
||||
public:
|
||||
MWInputManager(Render::OgreRenderer &ogre)
|
||||
: disp(A_LAST),
|
||||
input(ogre),
|
||||
listener(ogre, input, disp)
|
||||
{
|
||||
using namespace Input;
|
||||
using namespace OIS;
|
||||
|
||||
// Bind MW-specific functions
|
||||
disp.funcs.bind(A_Quit,
|
||||
boost::bind(&InputListener::exitNow, &listener),
|
||||
"Quit program");
|
||||
|
||||
// Key bindings
|
||||
disp.bind(KC_Q, A_Quit);
|
||||
disp.bind(KC_ESCAPE, A_Quit);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "nifogre/ogre_nif_loader.hpp"
|
||||
|
||||
using namespace Render;
|
||||
using namespace MWRender;
|
||||
using namespace Ogre;
|
||||
using namespace ESMS;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef _GAME_RENDER_CELL_H
|
||||
#define _GAME_RENDER_CELL_H
|
||||
|
||||
#include "../cell_store.hpp"
|
||||
#include "esm_store/cell_store.hpp"
|
||||
#include "mwscene.hpp"
|
||||
|
||||
namespace Render
|
||||
namespace MWRender
|
||||
{
|
||||
/**
|
||||
This class is responsible for inserting meshes and other
|
|
@ -9,10 +9,10 @@
|
|||
#include "OgreCamera.h"
|
||||
#include "OgreTextureManager.h"
|
||||
|
||||
using namespace Render;
|
||||
using namespace MWRender;
|
||||
using namespace Ogre;
|
||||
|
||||
MWScene::MWScene(OgreRenderer &_rend)
|
||||
MWScene::MWScene(Render::OgreRenderer &_rend)
|
||||
: rend(_rend)
|
||||
{
|
||||
Root *root = rend.getRoot();
|
|
@ -11,7 +11,7 @@ namespace Ogre
|
|||
class SceneNode;
|
||||
}
|
||||
|
||||
namespace Render
|
||||
namespace MWRender
|
||||
{
|
||||
/** Class responsible for Morrowind-specific interfaces to OGRE.
|
||||
|
||||
|
@ -20,7 +20,7 @@ namespace Render
|
|||
*/
|
||||
class MWScene
|
||||
{
|
||||
OgreRenderer &rend;
|
||||
Render::OgreRenderer &rend;
|
||||
Ogre::SceneManager *sceneMgr;
|
||||
Ogre::Camera *camera;
|
||||
Ogre::Viewport *vp;
|
||||
|
@ -31,7 +31,7 @@ namespace Render
|
|||
Ogre::SceneNode *mwRoot;
|
||||
|
||||
public:
|
||||
MWScene(OgreRenderer &_rend);
|
||||
MWScene(Render::OgreRenderer &_rend);
|
||||
|
||||
Ogre::SceneNode *getRoot() { return mwRoot; }
|
||||
Ogre::SceneManager *getMgr() { return sceneMgr; }
|
|
@ -48,7 +48,7 @@ struct DispatchMap
|
|||
}
|
||||
|
||||
/// Check if a given input is bound to anything
|
||||
bool isBound(int in)
|
||||
bool isBound(int in) const
|
||||
{
|
||||
return map.find(in) != map.end();
|
||||
}
|
||||
|
@ -60,10 +60,12 @@ struct DispatchMap
|
|||
The returned set is only intended for immediate iteration. Do not
|
||||
store references to it.
|
||||
*/
|
||||
const OutList &getList(int in)
|
||||
const OutList &getList(int in) const
|
||||
{
|
||||
assert(isBound(in));
|
||||
const OutList &out = map[in];
|
||||
InMap::const_iterator it = map.find(in);
|
||||
assert(it != map.end());
|
||||
const OutList &out = it->second;
|
||||
assert(!out.empty());
|
||||
return out;
|
||||
}
|
||||
|
|
44
input/dispatcher.hpp
Normal file
44
input/dispatcher.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef _INPUT_DISPATCHER_H
|
||||
#define _INPUT_DISPATCHER_H
|
||||
|
||||
#include "dispatch_map.hpp"
|
||||
#include "func_binder.hpp"
|
||||
|
||||
namespace Input {
|
||||
|
||||
struct Dispatcher
|
||||
{
|
||||
DispatchMap map;
|
||||
FuncBinder funcs;
|
||||
|
||||
/**
|
||||
Constructor. Takes the number of actions and passes it to
|
||||
FuncBinder.
|
||||
*/
|
||||
Dispatcher(int actions) : funcs(actions) {}
|
||||
|
||||
void bind(int in, int out) { map.bind(in, out); }
|
||||
void unbind(int in, int out) { map.unbind(in, out); }
|
||||
bool isBound(int in) const { return map.isBound(in); }
|
||||
|
||||
/**
|
||||
Instigate an event. It is translated through the dispatch map and
|
||||
sent to the function bindings.
|
||||
*/
|
||||
typedef DispatchMap::OutList _O;
|
||||
void event(int index, const void* p=NULL) const
|
||||
{
|
||||
// No bindings, nothing happens
|
||||
if(!isBound(index))
|
||||
return;
|
||||
|
||||
// Get the mapped actions and execute them
|
||||
const _O &list = map.getList(index);
|
||||
_O::const_iterator it;
|
||||
for(it = list.begin(); it != list.end(); it++)
|
||||
funcs.call(*it, p);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -1,78 +0,0 @@
|
|||
#ifndef _INPUT_EVENT_DISPATCHER_H
|
||||
#define _INPUT_EVENT_DISPATCHER_H
|
||||
|
||||
#include "dispatch_map.hpp"
|
||||
#include <boost/function.hpp>
|
||||
|
||||
namespace Input {
|
||||
|
||||
/**
|
||||
The EventDispatcher translates an input event (as given by an
|
||||
identifying index and an optional void pointer) into an output
|
||||
event function call.
|
||||
*/
|
||||
class EventDispatcher
|
||||
{
|
||||
DispatchMap map;
|
||||
|
||||
/*
|
||||
The event callback function that is called for all events. The
|
||||
first parameter is the input event. The second parameter is the
|
||||
resolved output event. The third is an optional user-defined
|
||||
parameter passed to call().
|
||||
*/
|
||||
typedef boost::function<void(int,int,void*)> EventCallback;
|
||||
|
||||
EventCallback callback;
|
||||
|
||||
// Carpal-tunnel prevention
|
||||
typedef DispatchMap::OutList _OL;
|
||||
|
||||
public:
|
||||
|
||||
/// Create an event binding connection
|
||||
void bind(int in, int out)
|
||||
{ map.bind(in,out); }
|
||||
|
||||
/// Dissolve an event binding connection
|
||||
void unbind(int in, int out)
|
||||
{ map.unbind(in, out); }
|
||||
|
||||
/// Check if a given input is bound to anything
|
||||
bool isBound(int in)
|
||||
{ return map.isBound(in); }
|
||||
|
||||
/// Register the callback you want to use to handle events.
|
||||
void setCallback(EventCallback cb)
|
||||
{ callback = cb; }
|
||||
|
||||
/**
|
||||
Instigate an event.
|
||||
|
||||
This will look up the input event number (first parameter), and
|
||||
call the event callback for each output number associated with
|
||||
(bound to) that input.
|
||||
|
||||
The optional second paramter is also passed to the callback.
|
||||
|
||||
If no output is bound to the given event number, the callback
|
||||
is never called.
|
||||
*/
|
||||
void call(int event, void *p = NULL)
|
||||
{
|
||||
// You have to set the callback before using call().
|
||||
assert(!callback.empty());
|
||||
|
||||
// Not bound? Exit.
|
||||
if(!isBound(event)) return;
|
||||
|
||||
// Dispatch to all events.
|
||||
const _OL &list = map.getList(event);
|
||||
for(_OL::const_iterator it = list.begin();
|
||||
it != list.end(); it++)
|
||||
callback(event, *it, p);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -22,7 +22,7 @@ namespace Input {
|
|||
permanent references to it unless you've planning for this on the
|
||||
calling side as well.
|
||||
*/
|
||||
typedef boost::function<void(int,void*)> Action;
|
||||
typedef boost::function<void(int,const void*)> Action;
|
||||
|
||||
/**
|
||||
The FuncBinder is a simple struct that binds user-defined indices
|
||||
|
@ -73,22 +73,22 @@ public:
|
|||
Call a specific action. Takes an optional parameter that is
|
||||
passed to the action.
|
||||
*/
|
||||
void call(int index, void *p=NULL)
|
||||
void call(int index, const void *p=NULL) const
|
||||
{
|
||||
assert(index >= 0 && index < bindings.size());
|
||||
FuncBinding &fb = bindings[index];
|
||||
const FuncBinding &fb = bindings[index];
|
||||
if(fb.action) fb.action(index, p);
|
||||
}
|
||||
|
||||
/// Check if a given index is bound to anything
|
||||
bool isBound(int index)
|
||||
bool isBound(int index) const
|
||||
{
|
||||
assert(index >= 0 && index < bindings.size());
|
||||
return !bindings[index].action.empty();
|
||||
}
|
||||
|
||||
/// Return the name associated with an action (empty if not bound)
|
||||
const std::string &getName(int index)
|
||||
const std::string &getName(int index) const
|
||||
{
|
||||
assert(index >= 0 && index < bindings.size());
|
||||
return bindings[index].name;
|
||||
|
|
|
@ -3,19 +3,21 @@
|
|||
|
||||
#include "oismanager.hpp"
|
||||
#include "ogre/renderer.hpp"
|
||||
#include "dispatcher.hpp"
|
||||
|
||||
#include <OgreFrameListener.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
|
||||
namespace Input
|
||||
{
|
||||
struct ExitListener : Ogre::FrameListener,
|
||||
OIS::KeyListener,
|
||||
OIS::MouseListener
|
||||
struct InputListener : Ogre::FrameListener,
|
||||
OIS::KeyListener,
|
||||
OIS::MouseListener
|
||||
{
|
||||
ExitListener(Render::OgreRenderer &rend,
|
||||
Input::OISManager &input)
|
||||
: doExit(false)
|
||||
InputListener(Render::OgreRenderer &rend,
|
||||
Input::OISManager &input,
|
||||
const Input::Dispatcher &_disp)
|
||||
: doExit(false), disp(_disp)
|
||||
{
|
||||
// Set up component pointers
|
||||
mWindow = rend.getWindow();
|
||||
|
@ -45,17 +47,8 @@ namespace Input
|
|||
|
||||
bool keyPressed( const OIS::KeyEvent &arg )
|
||||
{
|
||||
/*
|
||||
std::cout << "KeyPressed {" << arg.key
|
||||
<< ", " << ((OIS::Keyboard*)(arg.device))->getAsString(arg.key)
|
||||
<< "} || Character (" << (char)arg.text << ")\n";
|
||||
*/
|
||||
using namespace OIS;
|
||||
|
||||
if(arg.key == KC_Q ||
|
||||
arg.key == KC_ESCAPE)
|
||||
exitNow();
|
||||
|
||||
// Pass the event to the dispatcher
|
||||
disp.event(arg.key, &arg);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -81,6 +74,7 @@ namespace Input
|
|||
|
||||
private:
|
||||
|
||||
const Dispatcher &disp;
|
||||
Ogre::RenderWindow *mWindow;
|
||||
OIS::Mouse *mMouse;
|
||||
OIS::Keyboard *mKeyboard;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
GCC=g++
|
||||
|
||||
all: funcbind_test dispatch_map_test event_dispatcher_test
|
||||
all: funcbind_test dispatch_map_test
|
||||
|
||||
funcbind_test: funcbind_test.cpp ../func_binder.hpp
|
||||
$(GCC) $< -o $@
|
||||
|
@ -8,8 +8,5 @@ funcbind_test: funcbind_test.cpp ../func_binder.hpp
|
|||
dispatch_map_test: dispatch_map_test.cpp ../dispatch_map.hpp
|
||||
$(GCC) $< -o $@
|
||||
|
||||
event_dispatcher_test: event_dispatcher_test.cpp ../event_dispatcher.hpp
|
||||
$(GCC) $< -o $@
|
||||
|
||||
clean:
|
||||
rm *_test
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#include "../event_dispatcher.hpp"
|
||||
|
||||
using namespace Input;
|
||||
|
||||
void callback(int in, int out, void *p)
|
||||
{
|
||||
cout << " Got event: in=" << in << " out=" << out << endl;
|
||||
}
|
||||
|
||||
EventDispatcher dsp;
|
||||
|
||||
void callAll()
|
||||
{
|
||||
cout << "\nDuty calls:\n";
|
||||
for(int i=1; i<5; i++)
|
||||
{
|
||||
cout << " Calling event " << i << ":\n";
|
||||
dsp.call(i);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "Testing the event dispatcher\n";
|
||||
|
||||
dsp.setCallback(&callback);
|
||||
|
||||
callAll();
|
||||
|
||||
dsp.bind(2,1);
|
||||
dsp.bind(1,10);
|
||||
dsp.bind(14,-12);
|
||||
dsp.bind(2,-137);
|
||||
|
||||
callAll();
|
||||
|
||||
dsp.unbind(1,8);
|
||||
dsp.unbind(1,10);
|
||||
dsp.unbind(2,-137);
|
||||
dsp.unbind(2,1);
|
||||
|
||||
callAll();
|
||||
|
||||
dsp.bind(3, 19);
|
||||
dsp.bind(4, 18);
|
||||
dsp.bind(4, 18);
|
||||
|
||||
callAll();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -3,16 +3,16 @@ using namespace std;
|
|||
|
||||
#include "../func_binder.hpp"
|
||||
|
||||
void f1(int i, void *p)
|
||||
void f1(int i, const void *p)
|
||||
{
|
||||
cout << " F1 i=" << i << endl;
|
||||
|
||||
if(p)
|
||||
cout << " Got a nice gift: "
|
||||
<< *((float*)p) << endl;
|
||||
<< *((const float*)p) << endl;
|
||||
}
|
||||
|
||||
void f2(int i, void *p)
|
||||
void f2(int i, const void *p)
|
||||
{
|
||||
cout << " F2 i=" << i << endl;
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
Testing the event dispatcher
|
||||
|
||||
Duty calls:
|
||||
Calling event 1:
|
||||
Calling event 2:
|
||||
Calling event 3:
|
||||
Calling event 4:
|
||||
|
||||
Duty calls:
|
||||
Calling event 1:
|
||||
Got event: in=1 out=10
|
||||
Calling event 2:
|
||||
Got event: in=2 out=-137
|
||||
Got event: in=2 out=1
|
||||
Calling event 3:
|
||||
Calling event 4:
|
||||
|
||||
Duty calls:
|
||||
Calling event 1:
|
||||
Calling event 2:
|
||||
Calling event 3:
|
||||
Calling event 4:
|
||||
|
||||
Duty calls:
|
||||
Calling event 1:
|
||||
Calling event 2:
|
||||
Calling event 3:
|
||||
Got event: in=3 out=19
|
||||
Calling event 4:
|
||||
Got event: in=4 out=18
|
Loading…
Reference in a new issue