All 5 phases of the open-source Decal rebuild: Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil) Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters - Decal.Core, DecalControls, DecalRender, D3DService Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL Phase 4: DenAgent WinForms tray application Phase 5: WiX installer and build script 25 C# projects building with 0 errors. Native C++ projects require VS 2022 + Windows SDK (x86). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
215 lines
4.5 KiB
C++
215 lines
4.5 KiB
C++
// Pager.cpp : Implementation of cPager
|
|
#include "stdafx.h"
|
|
#include "Inject.h"
|
|
#include "Pager.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// cPager
|
|
|
|
// The velocity of the scroll in pixels/sec
|
|
#define VELOCITY 500
|
|
|
|
void cPager::setupScroll( long nCommand, LPPOINT pptDest )
|
|
{
|
|
_ASSERTE( pptDest != NULL );
|
|
|
|
m_ptScrollFrom = m_ptCurrent;
|
|
m_dwTimeStart = ::timeGetTime();
|
|
|
|
m_ptScrollTo = *pptDest;
|
|
|
|
// Figure out the time to completion
|
|
int dx = m_ptScrollTo.x - m_ptScrollFrom.x,
|
|
dy = m_ptScrollTo.y - m_ptScrollFrom.y;
|
|
|
|
m_dwTimeEnd = m_dwTimeStart + static_cast< DWORD >( sqrt( static_cast< double >( dx * dx + dy * dy ) ) ) * 1000 / VELOCITY;
|
|
|
|
// Clear command options
|
|
m_nCommand = nCommand;
|
|
m_bContinue = ( nCommand == 0 ) ? VARIANT_FALSE : VARIANT_TRUE;
|
|
|
|
m_bScrolling = VARIANT_TRUE;
|
|
}
|
|
|
|
void cPager::updatePosition()
|
|
{
|
|
long nID;
|
|
m_pSite->get_ID( &nID );
|
|
Fire_Change( nID, m_nCommand, m_ptCurrent.x, m_ptCurrent.y );
|
|
|
|
m_pSite->Invalidate();
|
|
}
|
|
|
|
void cPager::endScroll()
|
|
{
|
|
if( m_bScrolling )
|
|
{
|
|
m_bScrolling = VARIANT_FALSE;
|
|
m_ptCurrent = m_ptScrollTo;
|
|
}
|
|
|
|
updatePosition();
|
|
m_nCommand = 0;
|
|
}
|
|
|
|
void cPager::onCreate()
|
|
{
|
|
m_ptCurrent.x = 0;
|
|
m_ptCurrent.y = 0;
|
|
|
|
m_dwTimeStart = 0;
|
|
m_dwTimeEnd = 0;
|
|
|
|
m_bScrolling = VARIANT_FALSE;
|
|
m_bContinue = VARIANT_FALSE;
|
|
m_nCommand = 0;
|
|
}
|
|
|
|
STDMETHODIMP cPager::ScrollTo(LPPOINT pVal)
|
|
{
|
|
setupScroll( 0, pVal );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP cPager::get_Command(long *pVal)
|
|
{
|
|
_ASSERTE( pVal != NULL );
|
|
*pVal = m_nCommand;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP cPager::put_Command(long nCommand)
|
|
{
|
|
// ::MessageBox( NULL, _T( "cPager::SetCommand" ), _T( "Inject.dll" ), MB_OK );
|
|
m_bContinue = VARIANT_TRUE;
|
|
|
|
if( nCommand != m_nCommand )
|
|
{
|
|
// Prompt the callback to get a destination
|
|
long nID;
|
|
m_pSite->get_ID( &nID );
|
|
|
|
POINT ptDest;
|
|
VARIANT_BOOL bContinue;
|
|
|
|
bContinue = Fire_GetNextPosition( nID, nCommand, &ptDest.x, &ptDest.y );
|
|
|
|
if( !bContinue )
|
|
endScroll();
|
|
else
|
|
setupScroll( nCommand, &ptDest );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP cPager::FinishCommand()
|
|
{
|
|
m_bContinue = VARIANT_FALSE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP cPager::PreRender()
|
|
{
|
|
if( !m_bScrolling )
|
|
// No scrolling means no drawing
|
|
return S_OK;
|
|
|
|
// Calculate the new position
|
|
DWORD dwTime = ::timeGetTime();
|
|
|
|
// We loop until we've used up our animation time
|
|
// so animations with short steps - a single frame
|
|
// may exceed a small step.
|
|
while( dwTime >= m_dwTimeEnd )
|
|
{
|
|
long nCommand = m_nCommand;
|
|
endScroll();
|
|
|
|
// This section of the scroll is complete
|
|
if( !m_bContinue )
|
|
{
|
|
_ASSERTMEM( _CrtCheckMemory( ) );
|
|
return S_OK;
|
|
}
|
|
|
|
// Check for a next destination
|
|
POINT ptDest;
|
|
|
|
long nID;
|
|
m_pSite->get_ID( &nID );
|
|
|
|
VARIANT_BOOL bContinue = VARIANT_FALSE;
|
|
|
|
bContinue = Fire_GetNextPosition( nID, nCommand, &ptDest.x, &ptDest.y );
|
|
|
|
if( bContinue )
|
|
{
|
|
DWORD dwLastEnd = m_dwTimeEnd;
|
|
|
|
// ::MessageBox( NULL, _T( "cPager::Render" ), _T( "Inject.dll" ), MB_OK );
|
|
setupScroll( nCommand, &ptDest );
|
|
|
|
DWORD dwOver = m_dwTimeStart - dwLastEnd;
|
|
|
|
// Adjust the time to eliminate the stutter for the next section
|
|
m_dwTimeStart -= dwOver;
|
|
m_dwTimeEnd -= dwOver;
|
|
}
|
|
else
|
|
{
|
|
_ASSERTMEM( _CrtCheckMemory( ) );
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
// Do a time linear interpolation to figure out the current position
|
|
long nTotalTime = m_dwTimeEnd - m_dwTimeStart,
|
|
nCurrentTime = dwTime - m_dwTimeStart;
|
|
|
|
m_ptCurrent.x = m_ptScrollFrom.x + ( m_ptScrollTo.x - m_ptScrollFrom.x ) * nCurrentTime / nTotalTime;
|
|
m_ptCurrent.y = m_ptScrollFrom.y + ( m_ptScrollTo.y - m_ptScrollFrom.y ) * nCurrentTime / nTotalTime;
|
|
|
|
updatePosition();
|
|
|
|
_ASSERTMEM( _CrtCheckMemory( ) );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP cPager::AdjustRenderArea( ICanvas *pCanvas, VARIANT_BOOL *pbDrawChildren )
|
|
{
|
|
pCanvas->OffsetOrg( &m_ptCurrent, pbDrawChildren );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP cPager::get_Offset(LPPOINT pVal)
|
|
{
|
|
_ASSERTE( pVal != NULL );
|
|
*pVal = m_ptCurrent;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP cPager::put_Offset(LPPOINT newVal)
|
|
{
|
|
// Terminate scrolling
|
|
endScroll();
|
|
m_ptCurrent = *newVal;
|
|
|
|
// Dispatch changes
|
|
updatePosition();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP cPager::CreateClient(ILayer *pLayer)
|
|
{
|
|
// TODO: Add your implementation code here
|
|
|
|
return S_OK;
|
|
}
|