From: <axl...@us...> - 2009-05-17 19:16:45
|
Revision: 267 http://hgengine.svn.sourceforge.net/hgengine/?rev=267&view=rev Author: axlecrusher Date: 2009-05-17 19:16:37 +0000 (Sun, 17 May 2009) Log Message: ----------- Input system via messages. Camera movable by mouse Modified Paths: -------------- Mercury2/src/Camera.cpp Mercury2/src/Camera.h Mercury2/src/MercuryMessageManager.cpp Mercury2/src/MercuryMessageManager.h Mercury2/src/MessageHandler.h Mercury2/src/Viewport.cpp Mercury2/src/X11Window.cpp Added Paths: ----------- Mercury2/src/MercuryInput.cpp Mercury2/src/MercuryInput.h Modified: Mercury2/src/Camera.cpp =================================================================== --- Mercury2/src/Camera.cpp 2009-05-17 12:59:54 UTC (rev 266) +++ Mercury2/src/Camera.cpp 2009-05-17 19:16:37 UTC (rev 267) @@ -1,7 +1,15 @@ #include <Camera.h> +#include <MercuryMessageManager.h> +#include <MercuryInput.h> REGISTER_NODE_TYPE(CameraNode); +CameraNode::CameraNode() + :TransformNode() +{ + REGISTER_FOR_MESSAGE( INPUTEVENT_MOUSE ); +} + void CameraNode::ComputeMatrix() { m_tainted = false; @@ -14,6 +22,20 @@ m_globalMatrix = GetParentMatrix() * local; } +void CameraNode::HandleMessage(const MString& message, const MessageData* data) +{ + if (message == INPUTEVENT_MOUSE) + { + MouseInput* m = (MouseInput*)data; + + MercuryVector r = m_rotation; + r[0] += m->dy/30.0f; + r[1] += m->dx/30.0f; + + SetRotation(r); + } +} + /**************************************************************************** * Copyright (C) 2009 by Joshua Allen * * * Modified: Mercury2/src/Camera.h =================================================================== --- Mercury2/src/Camera.h 2009-05-17 12:59:54 UTC (rev 266) +++ Mercury2/src/Camera.h 2009-05-17 19:16:37 UTC (rev 267) @@ -6,10 +6,12 @@ class CameraNode : public TransformNode { public: + CameraNode(); virtual void ComputeMatrix(); + virtual void HandleMessage(const MString& message, const MessageData* data); + GENRTTI(CameraNode); - - + private: }; #endif Added: Mercury2/src/MercuryInput.cpp =================================================================== --- Mercury2/src/MercuryInput.cpp (rev 0) +++ Mercury2/src/MercuryInput.cpp 2009-05-17 19:16:37 UTC (rev 267) @@ -0,0 +1,48 @@ +#include <MercuryInput.h> +#include <MercuryMessageManager.h> + +MouseInput::MouseInput() + :MessageData(), dx(0), dy(0), buttonMasks(0) +{ +} + +void MouseInput::ProcessMouseInput(int dx, int dy) +{ + MouseInput* mi = new MouseInput(); + mi->dx = dx; + mi->dy = dy; + + POST_MESSAGE( INPUTEVENT_MOUSE, mi, 0 ); +} + +/**************************************************************************** + * Copyright (C) 2009 by Joshua Allen * + * * + * * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * Redistributions in binary form must reproduce the above * + * copyright notice, this list of conditions and the following * + * disclaimer in the documentation and/or other materials provided * + * with the distribution. * + * * Neither the name of the Mercury Engine nor the names of its * + * contributors may be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + ***************************************************************************/ Added: Mercury2/src/MercuryInput.h =================================================================== --- Mercury2/src/MercuryInput.h (rev 0) +++ Mercury2/src/MercuryInput.h 2009-05-17 19:16:37 UTC (rev 267) @@ -0,0 +1,54 @@ +#ifndef MERCURYINPUT_H +#define MERCURYINPUT_H + +#include <MessageHandler.h> + +const MString INPUTEVENT_MOUSE = "MouseInputEvent"; + +class MouseInput : public MessageData +{ + public: + static const uint8_t LEFTBUTTON = 1; + static const uint8_t RIGHTBUTTON = 2; + static const uint8_t CENTERBUTTON = 4; + + static void ProcessMouseInput(int x, int y); + + MouseInput(); + int32_t dx, dy; + uint8_t buttonMasks; +}; + +#endif + +/**************************************************************************** + * Copyright (C) 2009 by Joshua Allen * + * * + * * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * Redistributions in binary form must reproduce the above * + * copyright notice, this list of conditions and the following * + * disclaimer in the documentation and/or other materials provided * + * with the distribution. * + * * Neither the name of the Mercury Engine nor the names of its * + * contributors may be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + ***************************************************************************/ Modified: Mercury2/src/MercuryMessageManager.cpp =================================================================== --- Mercury2/src/MercuryMessageManager.cpp 2009-05-17 12:59:54 UTC (rev 266) +++ Mercury2/src/MercuryMessageManager.cpp 2009-05-17 19:16:37 UTC (rev 267) @@ -1,9 +1,17 @@ #include <MercuryMessageManager.h> -void MercuryMessageManager::PostMessage(const MString& message, float delay) +MessageHolder::MessageHolder() + :data(NULL) { +} + +void MercuryMessageManager::PostMessage(const MString& message, MessageData* data, float delay) +{ + MessageHolder m; + m.message = message; + m.data = data; uint64_t fireTime = m_currTime + uint64_t(delay*1000000); - m_messageQueue.Insert(fireTime, message); + m_messageQueue.Insert(fireTime, m); } void MercuryMessageManager::PumpMessages(const uint64_t& currTime) @@ -13,8 +21,9 @@ { if ( m_messageQueue.PeekNextPriority() > m_currTime ) return; - MString& message = m_messageQueue.GetNext(); + MessageHolder& message = m_messageQueue.GetNext(); FireOffMessage( message ); + SAFE_DELETE( message.data ); m_messageQueue.PopNext(); } } @@ -24,15 +33,17 @@ m_messageRecipients[message].push_back(ptr); } -void MercuryMessageManager::FireOffMessage(const MString& message) +void MercuryMessageManager::FireOffMessage(const MessageHolder& message) { - std::map< MString, std::list< MessageHandler* > >::iterator i = m_messageRecipients.find(message); + std::map< MString, std::list< MessageHandler* > >::iterator i = m_messageRecipients.find(message.message); + if ( i != m_messageRecipients.end() ) + { + std::list< MessageHandler* >::iterator recipients = i->second.begin(); - std::list< MessageHandler* >::iterator recipients = i->second.begin(); - - for (; recipients != i->second.end(); ++recipients) - (*recipients)->HandleMessage(message); + for (; recipients != i->second.end(); ++recipients) + (*recipients)->HandleMessage(message.message, message.data); + } } MercuryMessageManager& MercuryMessageManager::GetInstance() Modified: Mercury2/src/MercuryMessageManager.h =================================================================== --- Mercury2/src/MercuryMessageManager.h 2009-05-17 12:59:54 UTC (rev 266) +++ Mercury2/src/MercuryMessageManager.h 2009-05-17 19:16:37 UTC (rev 267) @@ -9,6 +9,14 @@ #include <MercuryUtil.h> #include <Mint.h> +class MessageHolder +{ + public: + MessageHolder(); + MString message; + MessageData* data; +}; + /* This message system uses absolute integer time values to fire off events. This ensures accuarate firing times while eliminating floating point error. Because we use absolute times in the queue we do not need to "count down" the @@ -17,15 +25,15 @@ class MercuryMessageManager { public: - void PostMessage(const MString& message, float delay); + void PostMessage(const MString& message, MessageData* data, float delay); void PumpMessages(const uint64_t& currTime); void RegisterForMessage(const MString& message, MessageHandler* ptr); static MercuryMessageManager& GetInstance(); private: - void FireOffMessage(const MString& message); + void FireOffMessage(const MessageHolder& message); - PriorityQueue<uint64_t, MString> m_messageQueue; + PriorityQueue<uint64_t, MessageHolder> m_messageQueue; uint64_t m_currTime; //microseconds std::map< MString, std::list< MessageHandler* > > m_messageRecipients; @@ -34,8 +42,8 @@ static InstanceCounter<MercuryMessageManager> MMcounter("MessageManager"); #define MESSAGEMAN MercuryMessageManager -#define REGISTER_FOR_MESSAGE(x) MESSAGEMAN::GetInstance().RegisterForMessage(#x, this) -#define POST_MESSAGE(x,delay) MESSAGEMAN::GetInstance().PostMessage(#x, delay) +#define REGISTER_FOR_MESSAGE(x) MESSAGEMAN::GetInstance().RegisterForMessage(x, this) +#define POST_MESSAGE(x,data,delay) MESSAGEMAN::GetInstance().PostMessage(x, data, delay) #endif Modified: Mercury2/src/MessageHandler.h =================================================================== --- Mercury2/src/MessageHandler.h 2009-05-17 12:59:54 UTC (rev 266) +++ Mercury2/src/MessageHandler.h 2009-05-17 19:16:37 UTC (rev 267) @@ -4,11 +4,17 @@ #include <MercuryString.h> #include <global.h> +class MessageData +{ + public: + virtual ~MessageData() {}; +}; + class MessageHandler { public: virtual ~MessageHandler() {}; - virtual void HandleMessage(const MString& message) {}; + virtual void HandleMessage(const MString& message, const MessageData* data) {}; }; #endif Modified: Mercury2/src/Viewport.cpp =================================================================== --- Mercury2/src/Viewport.cpp 2009-05-17 12:59:54 UTC (rev 266) +++ Mercury2/src/Viewport.cpp 2009-05-17 19:16:37 UTC (rev 267) @@ -39,9 +39,9 @@ LOOKAT = (matrix * z).Normalize(); // matrix.Print(); - EYE.Print("Eye"); - LOOKAT.Print("Lookat"); - printf("******\n"); +// EYE.Print("Eye"); +// LOOKAT.Print("Lookat"); +// printf("******\n"); // LOOKAT = (matrix * l).Normalize(); // LOOKAT. // LOOKAT.Print(); Modified: Mercury2/src/X11Window.cpp =================================================================== --- Mercury2/src/X11Window.cpp 2009-05-17 12:59:54 UTC (rev 266) +++ Mercury2/src/X11Window.cpp 2009-05-17 19:16:37 UTC (rev 267) @@ -1,4 +1,6 @@ #include <X11Window.h> +#include <MercuryMessageManager.h> +#include <MercuryInput.h> Callback0R< MercuryWindow* > MercuryWindow::genWindowClbk(X11Window::GenX11Window); //Register window generation callback @@ -34,7 +36,7 @@ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap( m_display, root_window, visinfo->visual, AllocNone); - attr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonPressMask | PointerMotionMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask |KeyPressMask |KeyReleaseMask | SubstructureNotifyMask; + attr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonPressMask | PointerMotionMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask |KeyPressMask |KeyReleaseMask | SubstructureNotifyMask | FocusChangeMask; unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; @@ -97,10 +99,12 @@ bool X11Window::PumpMessages() { + static bool inFocus = false; XEvent event; while ( XPending(m_display) > 0) { XNextEvent(m_display, &event); + switch (event.type) { case ClientMessage: @@ -115,6 +119,27 @@ if (e->window == m_window) return false; break; } + case ConfigureNotify: + { + XConfigureEvent* e = (XConfigureEvent*)&event; + m_width = e->width; + m_height = e->height; + break; + } + case FocusIn: + case FocusOut: + { + XFocusChangeEvent*e = (XFocusChangeEvent*)&event; + inFocus = (event.type == FocusIn); + if (inFocus) XWarpPointer(m_display, None, m_window, 0,0,0,0,m_width/2,m_height/2); + break; + } + } + + //The events below only get processed if window is in focus + if ( !inFocus ) continue; + switch (event.type) + { case ButtonPress: { XButtonEvent* e = (XButtonEvent*)&event; @@ -128,7 +153,8 @@ case KeyPress: { XKeyEvent* e = (XKeyEvent*)&event; - e->keycode; +// unsigned int* keycode = new unsigned int( e->keycode ); +// POST_MESSAGE( "KeyPress", (void*)keycode, 0 ); break; } case KeyRelease: @@ -140,15 +166,16 @@ case MotionNotify: { XMotionEvent* e = (XMotionEvent*)&event; + int x, y; + x = m_width/2 - e->x; + y = m_height/2 - e->y; + if (x!=0 || y!=0) //prevent recursive XWarp + { + MouseInput::ProcessMouseInput(x, y); + XWarpPointer(m_display, None, m_window, 0,0,0,0,m_width/2,m_height/2); + } break; } - case ConfigureNotify: - { - XConfigureEvent* e = (XConfigureEvent*)&event; - m_width = e->width; - m_height = e->height; - break; - } default: break; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |