forked from teamnwah/openmw-tes3coop
4b70fd9a06
git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@99 ea6a568a-9f4f-0410-981a-c910a81bb256
214 lines
6 KiB
C++
214 lines
6 KiB
C++
/*
|
|
OpenMW - The completely unofficial reimplementation of Morrowind
|
|
Copyright (C) 2008 Nicolay Korslund
|
|
Email: < korslund@gmail.com >
|
|
WWW: http://openmw.snaptoad.com/
|
|
|
|
This file (cpp_framelistener.cpp) is part of the OpenMW package.
|
|
|
|
OpenMW is distributed as free software: you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License
|
|
version 3, as published by the Free Software Foundation.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
version 3 along with this program. If not, see
|
|
http://www.gnu.org/licenses/ .
|
|
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
|
|
// Callbacks to D code.
|
|
|
|
// Called once each frame
|
|
extern "C" int32_t d_frameStarted(float time, int guiMode);
|
|
|
|
// Handle events
|
|
extern "C" void d_handleKey(int keycode, uint32_t text);
|
|
extern "C" void d_handleMouseMove(const OIS::MouseState *state);
|
|
extern "C" void d_handleMouseButton(const OIS::MouseState *state,
|
|
int32_t button);
|
|
|
|
// Frame listener, passed to Ogre. The only thing we use this for is
|
|
// to capture input and pass control to D code.
|
|
class MorroFrameListener: public FrameListener
|
|
{
|
|
|
|
public:
|
|
// Start of frame
|
|
bool frameStarted(const FrameEvent& evt)
|
|
{
|
|
if(mWindow->isClosed())
|
|
return false;
|
|
|
|
// Capture keyboard and mouse events
|
|
mKeyboard->capture();
|
|
mMouse->capture();
|
|
|
|
// Notify the GUI
|
|
mGUI->injectFrameEntered(evt.timeSinceLastFrame);
|
|
|
|
// Turn over control to the D code
|
|
return d_frameStarted(evt.timeSinceLastFrame, guiMode);
|
|
}
|
|
};
|
|
|
|
// Recieves input events and sends them to the D event handler.
|
|
class InputListener : public OIS::KeyListener, public OIS::MouseListener
|
|
{
|
|
public:
|
|
bool keyPressed( const OIS::KeyEvent &arg )
|
|
{
|
|
/*
|
|
std::cout << "KeyPressed {" << arg.key
|
|
<< ", " << ((OIS::Keyboard*)(arg.device))->getAsString(arg.key)
|
|
<< "} || Character (" << (char)arg.text << ")\n";
|
|
//*/
|
|
d_handleKey(arg.key, arg.text);
|
|
return true;
|
|
}
|
|
|
|
bool mouseMoved( const OIS::MouseEvent &arg )
|
|
{
|
|
/*
|
|
const OIS::MouseState& s = arg.state;
|
|
std::cout << "MouseMoved: Abs("
|
|
<< s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
|
|
<< s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")\n";
|
|
*/
|
|
// TODO: this should be handled elsewhere later on, most likely in
|
|
// Monster script.
|
|
if(guiMode)
|
|
mGUI->injectMouseMove(arg);
|
|
else
|
|
d_handleMouseMove(&arg.state);
|
|
return true;
|
|
}
|
|
|
|
bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
|
|
{
|
|
/*
|
|
const OIS::MouseState& s = arg.state;
|
|
std::cout << "Mouse button #" << id << " pressed. Abs("
|
|
<< s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
|
|
<< s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")\n";
|
|
*/
|
|
if(guiMode)
|
|
mGUI->injectMousePress(arg, id);
|
|
|
|
d_handleMouseButton(&arg.state, id);
|
|
return true;
|
|
}
|
|
|
|
bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
|
|
{
|
|
if(guiMode)
|
|
mGUI->injectMouseRelease(arg, id);
|
|
return true;
|
|
}
|
|
|
|
// Unused
|
|
bool keyReleased( const OIS::KeyEvent &arg ) { return true; }
|
|
};
|
|
|
|
MorroFrameListener mFrameListener;
|
|
InputListener mInput;
|
|
|
|
// Functions called from D during event handling
|
|
|
|
extern "C" int32_t ois_isPressed(int32_t keysym)
|
|
{
|
|
return mKeyboard->isKeyDown((OIS::KeyCode)keysym);
|
|
}
|
|
|
|
// Dump screen contents to file
|
|
extern "C" void ogre_screenshot(char* filename)
|
|
{
|
|
mWindow->writeContentsToFile(filename);
|
|
|
|
//This doesn't work, I think I have to set up an overlay or
|
|
//something first and display the text manually.
|
|
//mWindow->setDebugText(String("Wrote ") + filename);
|
|
}
|
|
|
|
// Rotate camera as result of mouse movement
|
|
extern "C" void ogre_rotateCamera(float x, float y)
|
|
{
|
|
mCamera->yaw(Degree(-x));
|
|
|
|
Quaternion nopitch = mCamera->getOrientation();
|
|
|
|
mCamera->pitch(Degree(-y));
|
|
|
|
// Is the camera close to being upside down?
|
|
if(mCamera->getUp()[1] <= 0.1)
|
|
// If so, undo the last pitch
|
|
mCamera->setOrientation(nopitch);
|
|
}
|
|
|
|
// Get current camera position
|
|
extern "C" void ogre_getCameraPos(float *x, float *y, float *z)
|
|
{
|
|
Vector3 pos = mCamera->getPosition();
|
|
*x = pos[0];
|
|
*y = -pos[2];
|
|
*z = pos[1];
|
|
}
|
|
|
|
// Get current camera orientation, in the form of 'front' and 'up'
|
|
// vectors.
|
|
extern "C" void ogre_getCameraOrientation(float *fx, float *fy, float *fz,
|
|
float *ux, float *uy, float *uz)
|
|
{
|
|
Vector3 front = mCamera->getDirection();
|
|
Vector3 up = mCamera->getUp();
|
|
*fx = front[0];
|
|
*fy = -front[2];
|
|
*fz = front[1];
|
|
*ux = up[0];
|
|
*uy = -up[2];
|
|
*uz = up[1];
|
|
}
|
|
|
|
// Move camera
|
|
extern "C" void ogre_moveCamera(float x, float y, float z)
|
|
{
|
|
// Transforms Morrowind coordinates to OGRE coordinates. The camera
|
|
// is not affected by the rotation of the root node, so we must
|
|
// transform this manually.
|
|
mCamera->setPosition(Vector3(x,z+90,-y));
|
|
|
|
//g_light->setPosition(mCamera->getPosition());
|
|
}
|
|
|
|
// Rotate camera using Morrowind rotation specifiers
|
|
extern "C" void ogre_setCameraRotation(float r1, float r2, float r3)
|
|
{
|
|
// TODO: This translation is probably not correct, but for now I
|
|
// have no reference point. Fix it later when we teleport from one
|
|
// cell to another, so we have something to compare against.
|
|
|
|
// Rotate around X axis
|
|
Quaternion xr(Radian(-r1), Vector3::UNIT_X);
|
|
// Rotate around Y axis
|
|
Quaternion yr(Radian(r3+3.14), Vector3::UNIT_Y);
|
|
// Rotate around Z axis
|
|
Quaternion zr(Radian(-r2), Vector3::UNIT_Z);
|
|
|
|
// Rotates first around z, then y, then x
|
|
mCamera->setOrientation(xr*yr*zr);
|
|
}
|
|
|
|
// Move camera relative to its own axis set.
|
|
extern "C" void ogre_moveCameraRel(float x, float y, float z)
|
|
{
|
|
mCamera->moveRelative(Vector3(x,0,z));
|
|
|
|
// up/down movement is always done relative the world axis
|
|
mCamera->move(Vector3(0,y,0));
|
|
}
|