Initial commit: Complete open-source Decal rebuild

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>
This commit is contained in:
erik 2026-02-08 18:27:56 +01:00
commit d1442e3747
1382 changed files with 170725 additions and 0 deletions

215
Native/Inject/Pager.cpp Normal file
View file

@ -0,0 +1,215 @@
// 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;
}