mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 18:19:55 +00:00
add preliminary hardware cursor support into sdl4ogre and windowmanagerimp, handle alt-tabbing away from fullscreen gracefully
This commit is contained in:
parent
1117105039
commit
f9b064d1bc
8 changed files with 334 additions and 5 deletions
|
@ -55,6 +55,11 @@ namespace MWGui
|
||||||
class DialogueWindow;
|
class DialogueWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace SFO
|
||||||
|
{
|
||||||
|
class CursorChangeClient;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWBase
|
namespace MWBase
|
||||||
{
|
{
|
||||||
/// \brief Interface for widnow manager (implemented in MWGui)
|
/// \brief Interface for widnow manager (implemented in MWGui)
|
||||||
|
@ -238,6 +243,8 @@ namespace MWBase
|
||||||
virtual void startTraining(MWWorld::Ptr actor) = 0;
|
virtual void startTraining(MWWorld::Ptr actor) = 0;
|
||||||
|
|
||||||
virtual const Translation::Storage& getTranslationDataStorage() const = 0;
|
virtual const Translation::Storage& getTranslationDataStorage() const = 0;
|
||||||
|
|
||||||
|
virtual void setCursorChangeClient(SFO::CursorChangeClient* client) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,73 @@
|
||||||
|
|
||||||
#include <OgreResourceGroupManager.h>
|
#include <OgreResourceGroupManager.h>
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
#include <MyGUI.h>
|
||||||
|
|
||||||
using namespace MWGui;
|
using namespace MWGui;
|
||||||
|
|
||||||
|
|
||||||
|
#include "MyGUI_Precompiled.h"
|
||||||
|
#include "MyGUI_ResourceImageSetPointer.h"
|
||||||
|
#include "MyGUI_ImageBox.h"
|
||||||
|
#include "MyGUI_ResourceManager.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ResourceImageSetPointerFix::ResourceImageSetPointerFix() :
|
||||||
|
mImageSet(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceImageSetPointerFix::~ResourceImageSetPointerFix()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceImageSetPointerFix::deserialization(xml::ElementPtr _node, Version _version)
|
||||||
|
{
|
||||||
|
Base::deserialization(_node, _version);
|
||||||
|
|
||||||
|
// берем детей и крутимся, основной цикл
|
||||||
|
xml::ElementEnumerator info = _node->getElementEnumerator();
|
||||||
|
while (info.next("Property"))
|
||||||
|
{
|
||||||
|
const std::string& key = info->findAttribute("key");
|
||||||
|
const std::string& value = info->findAttribute("value");
|
||||||
|
|
||||||
|
if (key == "Point")
|
||||||
|
mPoint = IntPoint::parse(value);
|
||||||
|
else if (key == "Size")
|
||||||
|
mSize = IntSize::parse(value);
|
||||||
|
else if (key == "Resource")
|
||||||
|
mImageSet = ResourceManager::getInstance().getByName(value)->castType<ResourceImageSet>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceImageSetPointerFix::setImage(ImageBox* _image)
|
||||||
|
{
|
||||||
|
if (mImageSet != nullptr)
|
||||||
|
_image->setItemResourceInfo(mImageSet->getIndexInfo(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceImageSetPointerFix::setPosition(ImageBox* _image, const IntPoint& _point)
|
||||||
|
{
|
||||||
|
_image->setCoord(_point.left - mPoint.left, _point.top - mPoint.top, mSize.width, mSize.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceImageSetPtr ResourceImageSetPointerFix:: getImageSet()
|
||||||
|
{
|
||||||
|
return mImageSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPoint ResourceImageSetPointerFix::getHotSpot()
|
||||||
|
{
|
||||||
|
return mPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntSize ResourceImageSetPointerFix::getSize()
|
||||||
|
{
|
||||||
|
return mSize;
|
||||||
|
}
|
||||||
|
|
||||||
CursorReplace::CursorReplace()
|
CursorReplace::CursorReplace()
|
||||||
{
|
{
|
||||||
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_vresize.png", 90);
|
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_vresize.png", 90);
|
||||||
|
|
|
@ -2,9 +2,44 @@
|
||||||
#define GAME_CURSORREPLACE_H
|
#define GAME_CURSORREPLACE_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <MyGUI.h>
|
||||||
|
#include <MyGUI_IPointer.h>
|
||||||
|
|
||||||
|
using namespace MyGUI;
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
/// \brief A simple class that allows us to get the members of
|
||||||
|
/// ResourceImageSetPointer that we need. Use with
|
||||||
|
/// MyGUI
|
||||||
|
/// \example MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
|
||||||
|
/// MyGUI::ResourceManager::getInstance().load("core.xml");
|
||||||
|
class ResourceImageSetPointerFix :
|
||||||
|
public IPointer
|
||||||
|
{
|
||||||
|
MYGUI_RTTI_DERIVED( ResourceImageSetPointerFix )
|
||||||
|
|
||||||
|
public:
|
||||||
|
ResourceImageSetPointerFix();
|
||||||
|
virtual ~ResourceImageSetPointerFix();
|
||||||
|
|
||||||
|
virtual void deserialization(xml::ElementPtr _node, Version _version);
|
||||||
|
|
||||||
|
virtual void setImage(ImageBox* _image);
|
||||||
|
virtual void setPosition(ImageBox* _image, const IntPoint& _point);
|
||||||
|
|
||||||
|
//and now for the whole point of this class, allow us to get
|
||||||
|
//the hot spot, the image and the size of the cursor.
|
||||||
|
virtual ResourceImageSetPtr getImageSet();
|
||||||
|
virtual IntPoint getHotSpot();
|
||||||
|
virtual IntSize getSize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
IntPoint mPoint;
|
||||||
|
IntSize mSize;
|
||||||
|
ResourceImageSetPtr mImageSet;
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief MyGUI does not support rotating cursors, so we have to do it manually
|
/// \brief MyGUI does not support rotating cursors, so we have to do it manually
|
||||||
class CursorReplace
|
class CursorReplace
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,10 +4,15 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
#include "MyGUI_UString.h"
|
#include "MyGUI_UString.h"
|
||||||
|
#include "MYGUI/MyGUI_IPointer.h"
|
||||||
|
#include "MYGUI/MyGUI_ResourceImageSetPointer.h"
|
||||||
|
#include "MyGUI_TextureUtility.h"
|
||||||
|
|
||||||
#include <openengine/ogre/renderer.hpp>
|
#include <openengine/ogre/renderer.hpp>
|
||||||
#include <openengine/gui/manager.hpp>
|
#include <openengine/gui/manager.hpp>
|
||||||
|
|
||||||
|
#include <extern/sdl4ogre/sdlinputwrapper.hpp>
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
#include <components/translation/translation.hpp>
|
#include <components/translation/translation.hpp>
|
||||||
|
|
||||||
|
@ -53,6 +58,8 @@
|
||||||
#include "trainingwindow.hpp"
|
#include "trainingwindow.hpp"
|
||||||
#include "imagebutton.hpp"
|
#include "imagebutton.hpp"
|
||||||
|
|
||||||
|
#include "cursorreplace.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
using namespace MWGui;
|
||||||
|
|
||||||
WindowManager::WindowManager(
|
WindowManager::WindowManager(
|
||||||
|
@ -108,12 +115,17 @@ WindowManager::WindowManager(
|
||||||
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
|
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
|
||||||
, mHudEnabled(true)
|
, mHudEnabled(true)
|
||||||
, mTranslationDataStorage (translationDataStorage)
|
, mTranslationDataStorage (translationDataStorage)
|
||||||
|
, mCursorChangeClient(NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Set up the GUI system
|
// Set up the GUI system
|
||||||
mGuiManager = new OEngine::GUI::MyGUIManager(mOgre->getWindow(), mOgre->getScene(), false, logpath);
|
mGuiManager = new OEngine::GUI::MyGUIManager(mOgre->getWindow(), mOgre->getScene(), false, logpath);
|
||||||
mGui = mGuiManager->getGui();
|
mGui = mGuiManager->getGui();
|
||||||
|
|
||||||
|
//Use our own ResourceImageSetPointer class so we can get the texture and hotspot for a pointer
|
||||||
|
MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
|
||||||
|
MyGUI::ResourceManager::getInstance().load("core.xml");
|
||||||
|
|
||||||
//Register own widgets with MyGUI
|
//Register own widgets with MyGUI
|
||||||
MyGUI::FactoryManager::getInstance().registerFactory<DialogueHistory>("Widget");
|
MyGUI::FactoryManager::getInstance().registerFactory<DialogueHistory>("Widget");
|
||||||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSkill>("Widget");
|
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSkill>("Widget");
|
||||||
|
@ -130,6 +142,7 @@ WindowManager::WindowManager(
|
||||||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ImageButton>("Widget");
|
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ImageButton>("Widget");
|
||||||
|
|
||||||
MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag);
|
MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag);
|
||||||
|
MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &WindowManager::onCursorChange);
|
||||||
|
|
||||||
// Get size info from the Gui object
|
// Get size info from the Gui object
|
||||||
assert(mGui);
|
assert(mGui);
|
||||||
|
@ -758,6 +771,44 @@ void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowManager::setCursorChangeClient(SFO::CursorChangeClient* client)
|
||||||
|
{
|
||||||
|
mCursorChangeClient = client;
|
||||||
|
onCursorChange(PointerManager::getInstance().getDefaultPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::onCursorChange(const std::string &name)
|
||||||
|
{
|
||||||
|
//we have no client, don't care.
|
||||||
|
if(!mCursorChangeClient)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//the client doesn't want any more info about this cursor
|
||||||
|
if(!mCursorChangeClient->cursorChanged(name))
|
||||||
|
return;
|
||||||
|
//See if we can get the information we need out of the cursor resource
|
||||||
|
ResourceImageSetPointerFix* imgSetPtr = dynamic_cast<ResourceImageSetPointerFix*>(MyGUI::PointerManager::getInstance().getByName(name));
|
||||||
|
if(imgSetPtr != NULL)
|
||||||
|
{
|
||||||
|
MyGUI::ResourceImageSet* imgSet = imgSetPtr->getImageSet();
|
||||||
|
|
||||||
|
std::string tex_name = imgSet->getIndexInfo(0,0).texture;
|
||||||
|
|
||||||
|
Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().getByName(tex_name);
|
||||||
|
|
||||||
|
//everything looks good, send it to the client
|
||||||
|
if(!tex.isNull())
|
||||||
|
{
|
||||||
|
Uint8 size_x = imgSetPtr->getSize().width;
|
||||||
|
Uint8 size_y = imgSetPtr->getSize().height;
|
||||||
|
Uint8 hotspot_x = imgSetPtr->getHotSpot().left;
|
||||||
|
Uint8 hotspot_y = imgSetPtr->getHotSpot().top;
|
||||||
|
|
||||||
|
mCursorChangeClient->receiveCursorInfo(name, tex, size_x, size_y, hotspot_x, hotspot_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed)
|
void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed)
|
||||||
{
|
{
|
||||||
mHud->setFpsLevel(Settings::Manager::getInt("fps", "HUD"));
|
mHud->setFpsLevel(Settings::Manager::getInt("fps", "HUD"));
|
||||||
|
|
|
@ -48,6 +48,11 @@ namespace OEngine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace SFO
|
||||||
|
{
|
||||||
|
class CursorChangeClient;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
class WindowBase;
|
class WindowBase;
|
||||||
|
@ -228,6 +233,8 @@ namespace MWGui
|
||||||
|
|
||||||
virtual const Translation::Storage& getTranslationDataStorage() const;
|
virtual const Translation::Storage& getTranslationDataStorage() const;
|
||||||
|
|
||||||
|
virtual void setCursorChangeClient(SFO::CursorChangeClient* client);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OEngine::GUI::MyGUIManager *mGuiManager;
|
OEngine::GUI::MyGUIManager *mGuiManager;
|
||||||
HUD *mHud;
|
HUD *mHud;
|
||||||
|
@ -282,6 +289,8 @@ namespace MWGui
|
||||||
MyGUI::Gui *mGui; // Gui
|
MyGUI::Gui *mGui; // Gui
|
||||||
std::vector<GuiMode> mGuiModes;
|
std::vector<GuiMode> mGuiModes;
|
||||||
|
|
||||||
|
SFO::CursorChangeClient* mCursorChangeClient;
|
||||||
|
|
||||||
std::vector<OEngine::GUI::Layout*> mGarbageDialogs;
|
std::vector<OEngine::GUI::Layout*> mGarbageDialogs;
|
||||||
void cleanupGarbage();
|
void cleanupGarbage();
|
||||||
|
|
||||||
|
@ -310,6 +319,8 @@ namespace MWGui
|
||||||
* so this method will retrieve the GMST with the name \a _tag and place the result in \a _result
|
* so this method will retrieve the GMST with the name \a _tag and place the result in \a _result
|
||||||
*/
|
*/
|
||||||
void onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result);
|
void onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result);
|
||||||
|
|
||||||
|
void onCursorChange(const std::string& name);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,8 @@ namespace MWInput
|
||||||
mInputManager->setKeyboardEventCallback (this);
|
mInputManager->setKeyboardEventCallback (this);
|
||||||
mInputManager->setWindowEventCallback(this);
|
mInputManager->setWindowEventCallback(this);
|
||||||
|
|
||||||
|
mWindows.setCursorChangeClient(mInputManager);
|
||||||
|
|
||||||
std::string file = userFileExists ? userFile : "";
|
std::string file = userFileExists ? userFile : "";
|
||||||
mInputBinder = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
|
mInputBinder = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
|
||||||
|
|
||||||
|
|
134
extern/sdl4ogre/sdlinputwrapper.cpp
vendored
134
extern/sdl4ogre/sdlinputwrapper.cpp
vendored
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <OgrePlatform.h>
|
#include <OgrePlatform.h>
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
#include <OgreHardwarePixelBuffer.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
|
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
|
||||||
# include <X11/Xlib.h>
|
# include <X11/Xlib.h>
|
||||||
|
@ -13,6 +15,8 @@
|
||||||
|
|
||||||
namespace SFO
|
namespace SFO
|
||||||
{
|
{
|
||||||
|
/// \brief General purpose wrapper for OGRE applications around SDL's event
|
||||||
|
/// queue, mostly used for handling input-related events.
|
||||||
InputWrapper::InputWrapper(Ogre::RenderWindow *window) :
|
InputWrapper::InputWrapper(Ogre::RenderWindow *window) :
|
||||||
mWindow(window),
|
mWindow(window),
|
||||||
mSDLWindow(NULL),
|
mSDLWindow(NULL),
|
||||||
|
@ -58,6 +62,11 @@ namespace SFO
|
||||||
if(mSDLWindow == NULL)
|
if(mSDLWindow == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
//without this SDL will take ownership of the window and iconify it when
|
||||||
|
//we alt-tab away.
|
||||||
|
SDL_SetWindowFullscreen(mSDLWindow, 0);
|
||||||
|
|
||||||
|
//translate our keypresses into text
|
||||||
SDL_StartTextInput();
|
SDL_StartTextInput();
|
||||||
|
|
||||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
|
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
|
||||||
|
@ -160,6 +169,7 @@ namespace SFO
|
||||||
return SDL_GetModState() & mod;
|
return SDL_GetModState() & mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Moves the mouse to the specified point within the viewport
|
||||||
void InputWrapper::warpMouse(int x, int y)
|
void InputWrapper::warpMouse(int x, int y)
|
||||||
{
|
{
|
||||||
SDL_WarpMouseInWindow(mSDLWindow, x, y);
|
SDL_WarpMouseInWindow(mSDLWindow, x, y);
|
||||||
|
@ -168,14 +178,15 @@ namespace SFO
|
||||||
mWarpY = y;
|
mWarpY = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Locks the pointer to the window
|
||||||
void InputWrapper::setGrabPointer(bool grab)
|
void InputWrapper::setGrabPointer(bool grab)
|
||||||
{
|
{
|
||||||
SDL_bool sdlGrab = grab ? SDL_TRUE : SDL_FALSE;
|
|
||||||
|
|
||||||
mGrabPointer = grab;
|
mGrabPointer = grab;
|
||||||
SDL_SetWindowGrab(mSDLWindow, sdlGrab);
|
SDL_SetWindowGrab(mSDLWindow, grab ? SDL_TRUE : SDL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Set the mouse to relative positioning. Doesn't move the cursor
|
||||||
|
/// and disables mouse acceleration.
|
||||||
void InputWrapper::setMouseRelative(bool relative)
|
void InputWrapper::setMouseRelative(bool relative)
|
||||||
{
|
{
|
||||||
if(mMouseRelative == relative)
|
if(mMouseRelative == relative)
|
||||||
|
@ -200,6 +211,121 @@ namespace SFO
|
||||||
SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION);
|
SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InputWrapper::cursorChanged(const std::string &name)
|
||||||
|
{
|
||||||
|
CursorMap::const_iterator curs_iter = mCursorMap.find(name);
|
||||||
|
|
||||||
|
//we have this cursor
|
||||||
|
if(curs_iter != mCursorMap.end())
|
||||||
|
{
|
||||||
|
SDL_SetCursor(curs_iter->second);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//they should get back to use with more info
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputWrapper::receiveCursorInfo(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y)
|
||||||
|
{
|
||||||
|
_createCursorFromResource(name, tex, size_x, size_y, hotspot_x, hotspot_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief creates an SDL cursor from an Ogre texture
|
||||||
|
void InputWrapper::_createCursorFromResource(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y)
|
||||||
|
{
|
||||||
|
Ogre::Image::Box box;
|
||||||
|
box.right = size_x;
|
||||||
|
box.bottom = size_y;
|
||||||
|
|
||||||
|
//get the surfaces set up
|
||||||
|
Ogre::HardwarePixelBufferSharedPtr buffer = tex.get()->getBuffer();
|
||||||
|
buffer.get()->lock(box, Ogre::HardwarePixelBuffer::HBL_READ_ONLY);
|
||||||
|
|
||||||
|
std::string tempName = "_" + name + "_processing";
|
||||||
|
|
||||||
|
//we need to copy this to a temporary texture since Ogre doesn't like us using getColourAt
|
||||||
|
Ogre::TexturePtr tempTexture = Ogre::TextureManager::getSingleton().createManual(
|
||||||
|
tempName,
|
||||||
|
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||||
|
Ogre::TEX_TYPE_2D,
|
||||||
|
size_x, size_y,
|
||||||
|
0,
|
||||||
|
Ogre::PF_FLOAT16_RGBA,
|
||||||
|
Ogre::TU_STATIC);
|
||||||
|
|
||||||
|
tempTexture->getBuffer()->blit(buffer);
|
||||||
|
buffer->unlock();
|
||||||
|
|
||||||
|
Ogre::HardwarePixelBufferSharedPtr new_buffer = tempTexture.get()->getBuffer();
|
||||||
|
//FIXME: Casting away constness is almost certainly the wrong thing to do here
|
||||||
|
Ogre::PixelBox& pixels = const_cast<Ogre::PixelBox&>(new_buffer->lock(box, Ogre::HardwarePixelBuffer::HBL_READ_ONLY));
|
||||||
|
|
||||||
|
|
||||||
|
SDL_Surface* surf = SDL_CreateRGBSurface(0,size_x,size_y,32,0,0,0,0);
|
||||||
|
|
||||||
|
|
||||||
|
//copy the Ogre texture to an SDL surface
|
||||||
|
for(size_t x = 0; x < size_x; ++x)
|
||||||
|
{
|
||||||
|
for(size_t y = 0; y < size_y; ++y)
|
||||||
|
{
|
||||||
|
Ogre::ColourValue clr = pixels.getColourAt(x, y, 0);
|
||||||
|
|
||||||
|
//set the pixel on the SDL surface to the same value as the Ogre texture's
|
||||||
|
_putPixel(surf, x, y, SDL_MapRGBA(surf->format, clr.r, clr.g, clr.b, clr.a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//set the cursor and store it for later
|
||||||
|
SDL_Cursor* curs = SDL_CreateColorCursor(surf, hotspot_x, hotspot_y);
|
||||||
|
SDL_SetCursor(curs);
|
||||||
|
mCursorMap.insert(CursorMap::value_type(std::string(name), curs));
|
||||||
|
|
||||||
|
new_buffer->unlock();
|
||||||
|
|
||||||
|
//clean up
|
||||||
|
SDL_FreeSurface(surf);
|
||||||
|
Ogre::TextureManager::getSingleton().remove(tempName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputWrapper::_putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
|
||||||
|
{
|
||||||
|
int bpp = surface->format->BytesPerPixel;
|
||||||
|
/* Here p is the address to the pixel we want to set */
|
||||||
|
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
|
||||||
|
|
||||||
|
switch(bpp) {
|
||||||
|
case 1:
|
||||||
|
*p = pixel;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
*(Uint16 *)p = pixel;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
|
||||||
|
p[0] = (pixel >> 16) & 0xff;
|
||||||
|
p[1] = (pixel >> 8) & 0xff;
|
||||||
|
p[2] = pixel & 0xff;
|
||||||
|
} else {
|
||||||
|
p[0] = pixel & 0xff;
|
||||||
|
p[1] = (pixel >> 8) & 0xff;
|
||||||
|
p[2] = (pixel >> 16) & 0xff;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
*(Uint32 *)p = pixel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Internal method for ignoring relative motions as a side effect
|
||||||
|
/// of warpMouse()
|
||||||
bool InputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt)
|
bool InputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt)
|
||||||
{
|
{
|
||||||
if(!mWarpCompensate)
|
if(!mWarpCompensate)
|
||||||
|
@ -215,6 +341,7 @@ namespace SFO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Wrap the mouse to the viewport
|
||||||
void InputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt)
|
void InputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt)
|
||||||
{
|
{
|
||||||
//don't wrap if we don't want relative movements, support relative
|
//don't wrap if we don't want relative movements, support relative
|
||||||
|
@ -238,6 +365,7 @@ namespace SFO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Package mouse and mousewheel motions into a single event
|
||||||
MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt)
|
MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt)
|
||||||
{
|
{
|
||||||
MouseMotionEvent pack_evt;
|
MouseMotionEvent pack_evt;
|
||||||
|
|
35
extern/sdl4ogre/sdlinputwrapper.hpp
vendored
35
extern/sdl4ogre/sdlinputwrapper.hpp
vendored
|
@ -9,13 +9,33 @@
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Texture;
|
||||||
|
}
|
||||||
|
|
||||||
namespace SFO
|
namespace SFO
|
||||||
{
|
{
|
||||||
class InputWrapper
|
|
||||||
|
|
||||||
|
class CursorChangeClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// \brief Tell the client that the cursor has changed, giving the
|
||||||
|
/// name of the cursor we changed to ("arrow", "ibeam", etc)
|
||||||
|
/// \return Whether the client is interested in more information about the cursor
|
||||||
|
virtual bool cursorChanged(const std::string &name) = 0;
|
||||||
|
|
||||||
|
/// \brief Follow up a cursorChanged() call with enough info to create an SDL cursor.
|
||||||
|
virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InputWrapper :
|
||||||
|
public CursorChangeClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InputWrapper(Ogre::RenderWindow* window);
|
InputWrapper(Ogre::RenderWindow* window);
|
||||||
~InputWrapper();
|
virtual ~InputWrapper();
|
||||||
|
|
||||||
void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; }
|
void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; }
|
||||||
void setKeyboardEventCallback(KeyListener* listen) { mKeyboardListener = listen; }
|
void setKeyboardEventCallback(KeyListener* listen) { mKeyboardListener = listen; }
|
||||||
|
@ -28,9 +48,13 @@ namespace SFO
|
||||||
bool getMouseRelative() { return mMouseRelative; }
|
bool getMouseRelative() { return mMouseRelative; }
|
||||||
void setGrabPointer(bool grab);
|
void setGrabPointer(bool grab);
|
||||||
|
|
||||||
|
virtual bool cursorChanged(const std::string &name);
|
||||||
|
virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y);
|
||||||
|
|
||||||
OIS::KeyCode sdl2OISKeyCode(SDL_Keycode code);
|
OIS::KeyCode sdl2OISKeyCode(SDL_Keycode code);
|
||||||
|
|
||||||
void warpMouse(int x, int y);
|
void warpMouse(int x, int y);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _start();
|
bool _start();
|
||||||
|
|
||||||
|
@ -38,6 +62,9 @@ namespace SFO
|
||||||
void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
|
void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
|
||||||
MouseMotionEvent _packageMouseMotion(const SDL_Event& evt);
|
MouseMotionEvent _packageMouseMotion(const SDL_Event& evt);
|
||||||
|
|
||||||
|
void _createCursorFromResource(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y);
|
||||||
|
void _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
|
||||||
|
|
||||||
void _handleKeyPress(SDL_KeyboardEvent& evt);
|
void _handleKeyPress(SDL_KeyboardEvent& evt);
|
||||||
Uint32 _UTF8ToUTF32(const unsigned char *buf);
|
Uint32 _UTF8ToUTF32(const unsigned char *buf);
|
||||||
void _setupOISKeys();
|
void _setupOISKeys();
|
||||||
|
@ -49,6 +76,9 @@ namespace SFO
|
||||||
typedef boost::unordered_map<SDL_Keycode, OIS::KeyCode> KeyMap;
|
typedef boost::unordered_map<SDL_Keycode, OIS::KeyCode> KeyMap;
|
||||||
KeyMap mKeyMap;
|
KeyMap mKeyMap;
|
||||||
|
|
||||||
|
typedef std::map<std::string, SDL_Cursor*> CursorMap;
|
||||||
|
CursorMap mCursorMap;
|
||||||
|
|
||||||
Uint16 mWarpX;
|
Uint16 mWarpX;
|
||||||
Uint16 mWarpY;
|
Uint16 mWarpY;
|
||||||
bool mWarpCompensate;
|
bool mWarpCompensate;
|
||||||
|
@ -63,6 +93,7 @@ namespace SFO
|
||||||
Ogre::RenderWindow* mWindow;
|
Ogre::RenderWindow* mWindow;
|
||||||
SDL_Window* mSDLWindow;
|
SDL_Window* mSDLWindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue