From 29610f5d518dfc0c803a2e1861b5d53c8cac9eae Mon Sep 17 00:00:00 2001 From: bitplane Date: Sat, 9 Jun 2007 03:01:58 +0000 Subject: [PATCH] added reference rect to linux and osx devices (untested) git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@700 dfc29bdd-3216-0410-991c-e03cc46cb475 --- source/Irrlicht/CIrrDeviceLinux.h | 59 +++++++++++++++++++---- source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h | 28 ++++++++++- 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/source/Irrlicht/CIrrDeviceLinux.h b/source/Irrlicht/CIrrDeviceLinux.h index cbec9586..4a38739e 100644 --- a/source/Irrlicht/CIrrDeviceLinux.h +++ b/source/Irrlicht/CIrrDeviceLinux.h @@ -96,9 +96,8 @@ namespace irr public: CCursorControl(CIrrDeviceLinux* dev, bool null) - : Device(dev), IsVisible(true), Null(null) + : Device(dev), IsVisible(true), Null(null), UseReferenceRect(false) { - Device->grab(); #ifdef _IRR_COMPILE_WITH_X11_ if (!null) { @@ -136,7 +135,6 @@ namespace irr #ifdef _IRR_COMPILE_WITH_X11_ XFreeGC(Device->display, gc); #endif - Device->drop(); } //! Changes the visible state of the mouse cursor. @@ -182,16 +180,33 @@ namespace irr virtual void setPosition(s32 x, s32 y) { #ifdef _IRR_COMPILE_WITH_X11_ + if (!Null) { - XWarpPointer(Device->display, - None, - Device->window, 0, 0, - Device->Width, - Device->Height, x, y); + if (UseReferenceRect) + { + XWarpPointer(Device->display, + None, + Device->window, 0, 0, + Device->Width, + Device->Height, + ReferenceRect.UpperLeftCorner.X + x, + ReferenceRect.UpperLeftCorner.Y + y); + + } + else + { + XWarpPointer(Device->display, + None, + Device->window, 0, 0, + Device->Width, + Device->Height, x, y); + } XFlush(Device->display); } #endif + CursorPos.X = x; + CursorPos.Y = y; } //! Returns the current position of the mouse cursor. @@ -205,12 +220,34 @@ namespace irr virtual core::position2d getRelativePosition() { updateCursorPos(); - return core::position2d(CursorPos.X / (f32)Device->Width, - CursorPos.Y / (f32)Device->Height); + + if (!UseReferenceRect) + { + return core::position2d(CursorPos.X / (f32)Device->Width, + CursorPos.Y / (f32)Device->Height); + } + + return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), + CursorPos.Y / (f32)ReferenceRect.getHeight()); } virtual void setReferenceRect(core::rect* rect=0) { + if (rect) + { + ReferenceRect = *rect; + UseReferenceRect = true; + + // prevent division through zero and uneven sizes + + if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) + ReferenceRect.LowerRightCorner.Y += 1; + + if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) + ReferenceRect.LowerRightCorner.X += 1; + } + else + UseReferenceRect = false; } private: @@ -244,6 +281,8 @@ namespace irr CIrrDeviceLinux* Device; bool IsVisible; bool Null; + bool UseReferenceRect; + core::rect ReferenceRect; #ifdef _IRR_COMPILE_WITH_X11_ GC gc; Cursor invisCursor; diff --git a/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h b/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h index 19221102..4a3a6aa1 100644 --- a/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h +++ b/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h @@ -1,2 +1,26 @@ -// Copyright (C) 2005 Etienne Petitjean // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in Irrlicht.h #ifndef __C_IRR_DEVICE_MACOSX_H_INCLUDED__ #define __C_IRR_DEVICE_MACOSX_H_INCLUDED__ #include "IrrCompileConfig.h" #ifdef MACOSX #include "CIrrDeviceStub.h" #include "IrrlichtDevice.h" #include "IImagePresenter.h" #include "IGUIEnvironment.h" #include "ICursorControl.h" #include #include namespace irr { class CIrrDeviceMacOSX : public CIrrDeviceStub, video::IImagePresenter { public: //! constructor CIrrDeviceMacOSX(video::E_DRIVER_TYPE driverType, const core::dimension2d& windowSize, u32 bits, bool fullscreen, bool sbuffer, bool vsync, bool antiAlias, IEventReceiver* receiver, const char* version); //! destructor virtual ~CIrrDeviceMacOSX(); //! runs the device. Returns false if device wants to be deleted virtual bool run(); //! Cause the device to temporarily pause execution and let other processes to run // This should bring down processor usage without major performance loss for Irrlicht virtual void yield(); //! Pause execution and let other processes to run for a specified amount of time. - virtual void sleep(u32 timeMs, bool pauseTimer); //! sets the caption of the window virtual void setWindowCaption(const wchar_t* text); //! returns if window is active. if not, nothing need to be drawn virtual bool isWindowActive(); //! presents a surface in the client area virtual void present(video::IImage* surface, s32 windowId = 0, core::rect* src=0 ); //! notifies the device that it should close itself virtual void closeDevice(); void flush(); void setMouseLocation(int x,int y); void setResize(int width,int height); void setCursorVisible(bool visible); private: //! create the driver void createDriver(video::E_DRIVER_TYPE driverType, const core::dimension2d& windowSize, u32 bits, bool fullscreen, bool stencilbuffer, bool vsync, bool antiAlias); //! Implementation of the macos x cursor control class CCursorControl : public gui::ICursorControl { public: CCursorControl(const core::dimension2d& wsize, CIrrDeviceMacOSX *device) : WindowSize(wsize), IsVisible(true), InvWindowSize(0.0f, 0.0f), _device(device) { CursorPos.X = CursorPos.Y = 0; if (WindowSize.Width!=0) InvWindowSize.Width = 1.0f / WindowSize.Width; if (WindowSize.Height!=0) InvWindowSize.Height = 1.0f / WindowSize.Height; } //! Changes the visible state of the mouse cursor. virtual void setVisible(bool visible) { IsVisible = visible; _device->setCursorVisible(visible); } //! Returns if the cursor is currently visible. virtual bool isVisible() { return IsVisible; } //! Sets the new position of the cursor. virtual void setPosition(const core::position2d &pos) { setPosition(pos.X, pos.Y); } //! Sets the new position of the cursor. virtual void setPosition(f32 x, f32 y) { setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height)); } //! Sets the new position of the cursor. virtual void setPosition(const core::position2d &pos) { if (CursorPos.X != pos.X || CursorPos.Y != pos.Y) setPosition(pos.X, pos.Y); } //! Sets the new position of the cursor. virtual void setPosition(s32 x, s32 y) { _device->setMouseLocation(x,y); } //! Returns the current position of the mouse cursor. virtual core::position2d getPosition() { return CursorPos; } //! Returns the current position of the mouse cursor. virtual core::position2d getRelativePosition() { return core::position2d(CursorPos.X * InvWindowSize.Width,CursorPos.Y * InvWindowSize.Height); } //! Updates the internal cursor position void updateInternalCursorPosition(int x,int y) { CursorPos.X = x; CursorPos.Y = y; } private: core::position2d CursorPos; core::dimension2d WindowSize; core::dimension2d InvWindowSize; CIrrDeviceMacOSX *_device; bool IsVisible; }; bool createWindow(const irr::core::dimension2d& windowSize, irr::u32 bits, bool fullscreen, bool vsync, bool stencilBuffer); void initKeycodes(); void storeMouseLocation(); void postMouseEvent(void *event,irr::SEvent &ievent); void postKeyEvent(void *event,irr::SEvent &ievent,bool pressed); video::E_DRIVER_TYPE DriverType; bool stencilbuffer; void *_window; CGLContextObj _cglcontext; void *_oglcontext; int _width; int _height; std::map _keycodes; int _screenWidth; int _screenHeight; bool _active; }; } // end namespace irr #endif // MACOSX #endif // __C_IRR_DEVICE_MACOSX_H_INCLUDED__ \ No newline at end of file +// Copyright (C) 2005 Etienne Petitjean // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in Irrlicht.h #ifndef __C_IRR_DEVICE_MACOSX_H_INCLUDED__ #define __C_IRR_DEVICE_MACOSX_H_INCLUDED__ #include "IrrCompileConfig.h" #ifdef MACOSX #include "CIrrDeviceStub.h" #include "IrrlichtDevice.h" #include "IImagePresenter.h" #include "IGUIEnvironment.h" #include "ICursorControl.h" #include #include namespace irr { class CIrrDeviceMacOSX : public CIrrDeviceStub, video::IImagePresenter { public: //! constructor CIrrDeviceMacOSX(video::E_DRIVER_TYPE driverType, const core::dimension2d& windowSize, u32 bits, bool fullscreen, bool sbuffer, bool vsync, bool antiAlias, IEventReceiver* receiver, const char* version); //! destructor virtual ~CIrrDeviceMacOSX(); //! runs the device. Returns false if device wants to be deleted virtual bool run(); //! Cause the device to temporarily pause execution and let other processes to run // This should bring down processor usage without major performance loss for Irrlicht virtual void yield(); //! Pause execution and let other processes to run for a specified amount of time. virtual void sleep(u32 timeMs, bool pauseTimer); //! sets the caption of the window virtual void setWindowCaption(const wchar_t* text); //! returns if window is active. if not, nothing need to be drawn virtual bool isWindowActive(); //! presents a surface in the client area virtual void present(video::IImage* surface, s32 windowId = 0, core::rect* src=0 ); //! notifies the device that it should close itself virtual void closeDevice(); void flush(); void setMouseLocation(int x,int y); void setResize(int width,int height); void setCursorVisible(bool visible); private: //! create the driver void createDriver(video::E_DRIVER_TYPE driverType, const core::dimension2d& windowSize, u32 bits, bool fullscreen, bool stencilbuffer, bool vsync, bool antiAlias); //! Implementation of the macos x cursor control class CCursorControl : public gui::ICursorControl { public: CCursorControl(const core::dimension2d& wsize, CIrrDeviceMacOSX *device) : WindowSize(wsize), IsVisible(true), InvWindowSize(0.0f, 0.0f), _device(device), UseReferenceRect(false) { CursorPos.X = CursorPos.Y = 0; if (WindowSize.Width!=0) InvWindowSize.Width = 1.0f / WindowSize.Width; if (WindowSize.Height!=0) InvWindowSize.Height = 1.0f / WindowSize.Height; } //! Changes the visible state of the mouse cursor. virtual void setVisible(bool visible) { IsVisible = visible; _device->setCursorVisible(visible); } //! Returns if the cursor is currently visible. virtual bool isVisible() { return IsVisible; } //! Sets the new position of the cursor. virtual void setPosition(const core::position2d &pos) { setPosition(pos.X, pos.Y); } //! Sets the new position of the cursor. virtual void setPosition(f32 x, f32 y) { setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height)); } //! Sets the new position of the cursor. virtual void setPosition(const core::position2d &pos) { if (CursorPos.X != pos.X || CursorPos.Y != pos.Y) setPosition(pos.X, pos.Y); } //! Sets the new position of the cursor. virtual void setPosition(s32 x, s32 y) { if (UseReferenceRect) { _device->setMouseLocation(ReferenceRect.UpperLeftCorner.X + x, ReferenceRect.UpperLeftCorner.Y + y); } else { _device->setMouseLocation(x,y); } } //! Returns the current position of the mouse cursor. virtual core::position2d getPosition() { return CursorPos; } //! Returns the current position of the mouse cursor. virtual core::position2d getRelativePosition() { if (!UseReferenceRect) + { + return core::position2d(CursorPos.X * InvWindowSize.Width, + CursorPos.Y * InvWindowSize.Height); + } + + return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), + CursorPos.Y / (f32)ReferenceRect.getHeight()); } //! Sets an absolute reference rect for calculating the cursor position. + virtual void setReferenceRect(core::rect* rect=0) + { + if (rect) + { + ReferenceRect = *rect; + UseReferenceRect = true; + + // prevent division through zero and uneven sizes + + if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) + ReferenceRect.LowerRightCorner.Y += 1; + + if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) + ReferenceRect.LowerRightCorner.X += 1; + } + else + UseReferenceRect = false; + } //! Updates the internal cursor position void updateInternalCursorPosition(int x,int y) { CursorPos.X = x; CursorPos.Y = y; } private: core::position2d CursorPos; core::dimension2d WindowSize; core::dimension2d InvWindowSize; CIrrDeviceMacOSX *_device; bool IsVisible; bool UseReferenceRect; core::rect ReferenceRect; }; bool createWindow(const irr::core::dimension2d& windowSize, irr::u32 bits, bool fullscreen, bool vsync, bool stencilBuffer); void initKeycodes(); void storeMouseLocation(); void postMouseEvent(void *event,irr::SEvent &ievent); void postKeyEvent(void *event,irr::SEvent &ievent,bool pressed); video::E_DRIVER_TYPE DriverType; bool stencilbuffer; void *_window; CGLContextObj _cglcontext; void *_oglcontext; int _width; int _height; std::map _keycodes; int _screenWidth; int _screenHeight; bool _active; }; } // end namespace irr #endif // MACOSX #endif // __C_IRR_DEVICE_MACOSX_H_INCLUDED__ \ No newline at end of file