"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSEngine/Src/Input/LSEMouse.h

00001 
00016 #ifndef __LSE_MOUSE_H__
00017 #define __LSE_MOUSE_H__
00018 
00019 #include "../LSEEngine.h"
00020 #include "Vector/LSMVector2.h"
00021 
00022 
00023 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00024 // MACROS
00025 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00026 // Number of buttons on a mouse.  Change it to support as many as you want (but you will
00027 //      also have to make a way to send clicks to the extra slots).
00028 #define __LSE_MOUSE_BUTTONS__                   3
00029 // Number of history items in the mouse-smoothening array.
00030 #define __LSE_MOUSE_SMOOTH_HISTORY__    50
00031 
00032 namespace lse {
00033 
00039         class CMouse {
00040         public :
00041                 // == Various constructors.
00042                 LSE_INLINE LSE_CALL                             CMouse();
00043 
00044 
00045                 // == Functions.
00051                 const CVector2 & LSE_CALL               GetPos() const;
00052 
00058                 const CVector2 & LSE_CALL               GetLastPos() const;
00059 
00065                 CVector2 LSE_CALL                               GetDelta() const;
00066 
00072                 LSREAL LSE_CALL                                 GetXDelta() const;
00073 
00079                 LSREAL LSE_CALL                                 GetYDelta() const;
00080 
00086                 const CVector2 & LSE_CALL               GetInterpPos() const;
00087 
00093                 const CVector2 & LSE_CALL               GetInterpLastPos() const;
00094 
00100                 CVector2 LSE_CALL                               GetInterpDelta() const;
00101 
00107                 LSREAL LSE_CALL                                 GetInterpXDelta() const;
00108 
00114                 LSREAL LSE_CALL                                 GetInterpYDelta() const;
00115 
00116 
00124                 LSVOID LSE_CALL                                 SetPos( LSREAL _fX, LSREAL _fY );
00125 
00133                 LSVOID LSE_CALL                                 AddPos( LSREAL _fX, LSREAL _fY );
00134 
00141                 LSVOID LSE_CALL                                 ApplyChanges( LSUINT64 _ui64TimeStamp );
00142 
00150                 LSVOID LSE_CALL                                 SetStartPos( LSREAL _fX, LSREAL _fY );
00151 
00160                 LSVOID LSE_CALL                                 Snap( LSREAL _fX, LSREAL _fY, LSREAL _fRight, LSREAL _fBottom );
00161 
00167                 LSVOID LSE_CALL                                 Click( LSUINT32 _ui32Index );
00168 
00174                 LSVOID LSE_CALL                                 UnClick( LSUINT32 _ui32Index );
00175 
00182                 LSBOOL LSE_CALL                                 IsMouseButtonDown( LSUINT32 _ui32Index ) const;
00183 
00190                 LSBOOL LSE_CALL                                 MouseButtonJustPressed( LSUINT32 _ui32Index ) const;
00191 
00198                 LSBOOL LSE_CALL                                 MouseButtonJustReleased( LSUINT32 _ui32Index ) const;
00199 
00204                 LSVOID LSE_CALL                                 ResetClicks();
00205 
00211                 const LSINT16 * LSE_CALL                GetIndexMap() const;
00212 
00213 
00214         protected :
00215                 // == Types.
00221                 struct LSE_MOUSE_MOVE_POS {
00225                         CVector2                                        vPos;
00226 
00230                         LSUINT64                                        ui64Time;
00231                 };
00232 
00233 
00234                 // == Members.
00238                 CVector2                                                m_vPos;
00239 
00243                 CVector2                                                m_vTempPos;
00244 
00248                 CVector2                                                m_vLastPos;
00249 
00253                 CVector2                                                m_vInterpPos;
00254 
00258                 CVector2                                                m_vLastInterpPos;
00259 
00263                 LSE_MOUSE_MOVE_POS                              m_mmpHistory[__LSE_MOUSE_SMOOTH_HISTORY__];
00264 
00268                 LSUINT32                                                m_ui32HistorySize               : 30;
00269 
00273                 LSUINT32                                                m_ui32UpdateMoveBuffer  : 2;
00274 
00291                 LSUINT32                                                m_ui32InterpTime;
00292 
00296                 LSUINT64                                                m_ui64TimeNow;
00297 
00308                 LSINT32                                                 m_i32ClickCountBuffer[__LSE_MOUSE_BUTTONS__];
00309                 LSINT32                                                 m_i32ClickCount[__LSE_MOUSE_BUTTONS__];
00310 
00317                 LSINT32                                                 m_i32UnClickCount[__LSE_MOUSE_BUTTONS__];
00318 
00319                 // States of each button at the last update.
00320                 LSINT32                                                 m_i32LastClickState[__LSE_MOUSE_BUTTONS__];
00321 
00322                 // Input mapping.  The source index is the index into this array.
00323                 //      the destination index is the value at that index.  Defaults
00324                 //      to a one-to-one mapping where the source and destination
00325                 //      values are the same.
00326                 LSINT16                                                 m_i16IndexMap[__LSE_MOUSE_BUTTONS__];
00327 
00328 
00329                 // == Functions.
00335                 LSUINT64 LSE_CALL                               GetMostRecentHistoryTime() const;
00336 
00345                 LSUINT32 LSE_CALL                               FindTimeStampByTime( LSUINT64 _ui64Time ) const;
00346 
00353                 CVector2 LSE_CALL                               GetInterpolatedPos() const;
00354         };
00355 
00356 
00357         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00358         // DEFINITIONS
00359         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00360         // == Various constructors.
00361         LSE_INLINE LSE_CALL CMouse::CMouse() :
00362                 m_ui32HistorySize( 0 ),
00363                 m_ui32UpdateMoveBuffer( 0 ),
00364                 m_ui32InterpTime( 8000 ),
00365                 m_ui64TimeNow( 0ULL ) {
00366                 for ( LSUINT32 I = 0; I < LSE_ELEMENTS( m_i32ClickCount ); ++I ) {
00367                         m_i32ClickCountBuffer[I] = m_i32ClickCount[I] = m_i32UnClickCount[I] = m_i32LastClickState[I] = 0;
00368                         m_i16IndexMap[I] = static_cast<LSINT16>(I);
00369                 }
00370         }
00371 
00372         // == Functions.
00378         LSE_INLINE const CVector2 & LSE_CALL CMouse::GetPos() const {
00379                 return m_vPos;
00380         }
00381 
00387         LSE_INLINE const CVector2 & LSE_CALL CMouse::GetLastPos() const {
00388                 return m_vLastPos;
00389         }
00390 
00396         LSE_INLINE CVector2 LSE_CALL CMouse::GetDelta() const {
00397                 return CVector2( m_vPos.x - m_vLastPos.x, m_vPos.y - m_vLastPos.y );
00398         }
00399 
00405         LSE_INLINE LSREAL LSE_CALL CMouse::GetXDelta() const {
00406                 return m_vPos.x - m_vLastPos.x;
00407         }
00408 
00414         LSE_INLINE LSREAL LSE_CALL CMouse::GetYDelta() const {
00415                 return m_vPos.y - m_vLastPos.y;
00416         }
00417 
00423         LSE_INLINE const CVector2 & LSE_CALL CMouse::GetInterpPos() const {
00424                 return m_vInterpPos;
00425         }
00426 
00432         LSE_INLINE const CVector2 & LSE_CALL CMouse::GetInterpLastPos() const {
00433                 return m_vLastInterpPos;
00434         }
00435 
00441         LSE_INLINE CVector2 LSE_CALL CMouse::GetInterpDelta() const {
00442                 return m_vInterpPos - m_vLastInterpPos;
00443         }
00444 
00450         LSE_INLINE LSREAL LSE_CALL CMouse::GetInterpXDelta() const {
00451                 return m_vInterpPos.x - m_vLastInterpPos.x;
00452         }
00453 
00459         LSE_INLINE LSREAL LSE_CALL CMouse::GetInterpYDelta() const {
00460                 return m_vInterpPos.y - m_vLastInterpPos.y;
00461         }
00462 
00469         LSE_INLINE LSBOOL LSE_CALL CMouse::IsMouseButtonDown( LSUINT32 _ui32Index ) const {
00470                 assert( _ui32Index < __LSE_MOUSE_BUTTONS__ );
00471                 return m_i32ClickCount[_ui32Index] != 0;
00472         }
00473 
00480         LSE_INLINE LSBOOL LSE_CALL CMouse::MouseButtonJustPressed( LSUINT32 _ui32Index ) const {
00481                 assert( _ui32Index < __LSE_MOUSE_BUTTONS__ );
00482                 return m_i32ClickCount[_ui32Index] > m_i32LastClickState[_ui32Index];
00483         }
00484 
00491         LSE_INLINE LSBOOL LSE_CALL CMouse::MouseButtonJustReleased( LSUINT32 _ui32Index ) const {
00492                 assert( _ui32Index < __LSE_MOUSE_BUTTONS__ );
00493                 return m_i32ClickCount[_ui32Index] < m_i32LastClickState[_ui32Index];
00494         }
00495 
00500         LSE_INLINE LSVOID LSE_CALL CMouse::ResetClicks() {
00501                 // Actually we set the unclick count to a number absurdly high so that the mouse buttons
00502                 //      are guaranteed to be unclicked fully on the next update.
00503                 // We cannot set it too high, however, as we would risk overflow if another unclick
00504                 //      event occurred before the next update.
00505                 // This is why we clip both the click and unclick values to 0x0FFFFFFF.
00506                 for ( LSUINT32 I = 0; I < LSE_ELEMENTS( m_i32ClickCount ); ++I ) {
00507                         m_i32UnClickCount[I] = 0x0FFFFFFF;
00508                 }
00509         }
00510 
00516         LSE_INLINE const LSINT16 * LSE_CALL CMouse::GetIndexMap() const { return m_i16IndexMap; }
00517 
00523         LSE_INLINE LSUINT64 LSE_CALL CMouse::GetMostRecentHistoryTime() const {
00524                 if ( m_ui32HistorySize == 0 ) {
00525                         // No history.
00526                         return 0ULL;
00527                 }
00528                 return m_mmpHistory[m_ui32HistorySize-1].ui64Time;
00529         }
00530 
00539         LSE_INLINE LSUINT32 LSE_CALL CMouse::FindTimeStampByTime( LSUINT64 _ui64Time ) const {
00540                 for ( LSUINT32 I = 0; I < m_ui32HistorySize; ++I ) {
00541                         if ( m_mmpHistory[I].ui64Time >= _ui64Time ) {
00542                                 return I;
00543                         }
00544                 }
00545                 return __LSE_MOUSE_SMOOTH_HISTORY__;
00546         }
00547 
00554         LSE_INLINE CVector2 LSE_CALL CMouse::GetInterpolatedPos() const {
00555                 if ( m_ui32HistorySize == 0 ) {
00556                         // No history.
00557                         return m_vPos;
00558                 }
00559 
00560                 LSUINT32 ui32Index = FindTimeStampByTime( m_ui64TimeNow - m_ui32InterpTime );
00561                 // If none found, we are at the end of the history.
00562                 if ( ui32Index == __LSE_MOUSE_SMOOTH_HISTORY__ ) {
00563                         return m_vPos;
00564                 }
00565                 if ( ui32Index == 0 ) {
00566                         // No history item prior to this for interpolating between.
00567                         return m_mmpHistory[ui32Index].vPos;
00568                 }
00569 
00570                 // Now we have positions on both sides of our delayed timestamp, so
00571                 //      we can interpolate between them.
00572                 LSUINT32 ui32DistanceBetweenPos = static_cast<LSUINT32>(m_mmpHistory[ui32Index].ui64Time - m_mmpHistory[ui32Index-1].ui64Time);
00573                 LSUINT32 ui32DistanceBetweenCurTime = static_cast<LSUINT32>((m_ui64TimeNow - m_ui32InterpTime) - m_mmpHistory[ui32Index-1].ui64Time);
00574                 LSREAL fFrac = static_cast<LSREAL>(ui32DistanceBetweenCurTime >> 2UL) / static_cast<LSREAL>(ui32DistanceBetweenPos >> 2UL);
00575 
00576                 CVector2 vInterp = m_mmpHistory[ui32Index].vPos - m_mmpHistory[ui32Index-1].vPos;
00577                 return m_mmpHistory[ui32Index-1].vPos + (vInterp * fFrac);
00578         }
00579 
00580 }       // namespace lse
00581 
00582 #endif  // __LSE_MOUSE_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator