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:
commit
d1442e3747
1382 changed files with 170725 additions and 0 deletions
291
Native/Inject/IconCache.cpp
Normal file
291
Native/Inject/IconCache.cpp
Normal file
|
|
@ -0,0 +1,291 @@
|
|||
// IconCache.cpp : Implementation of cIconCache
|
||||
#include "stdafx.h"
|
||||
#include "Inject.h"
|
||||
#include "IconCache.h"
|
||||
|
||||
#include "Manager.h"
|
||||
//Moputu - 05172002: Added long lColor to make icons with different colored borders unique.
|
||||
bool cIconCache::findIcon( HMODULE hMod, DWORD dwFile, cIconCache::cIconBuffer *&pBuffer, int &nIndex, long lColor )
|
||||
{
|
||||
for( cIconBufferList::iterator i = m_icons.begin(); i != m_icons.end(); )
|
||||
{
|
||||
VARIANT_BOOL bLost;
|
||||
i->m_pSurface->get_WasLost( &bLost );
|
||||
if( bLost )
|
||||
{
|
||||
i = m_icons.erase( i );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Search inside this buffer
|
||||
for( cIDList::iterator j = i->m_icons.begin(); j != i->m_icons.end(); ++ j )
|
||||
{
|
||||
//if( j->m_hMod == hMod && j->m_dwID == dwFile ) // Original Code
|
||||
if( j->m_hMod == hMod && j->m_dwID == dwFile && j->m_lBColor == lColor )
|
||||
{
|
||||
// We found the icon, return happy
|
||||
pBuffer = &( *i );
|
||||
nIndex = j - i->m_icons.begin();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
++ i;
|
||||
}
|
||||
|
||||
// Icon not found
|
||||
return false;
|
||||
}
|
||||
|
||||
void cIconCache::findFreeSlot( cIconBuffer *&pBuffer, int &nIndex )
|
||||
{
|
||||
// First find a buffer with an unused icon slot, note that we test
|
||||
// the buffers
|
||||
for( cIconBufferList::iterator i = m_icons.begin(); i != m_icons.end(); )
|
||||
{
|
||||
VARIANT_BOOL bLost;
|
||||
i->m_pSurface->get_WasLost( &bLost );
|
||||
if( bLost )
|
||||
{
|
||||
i = m_icons.erase( i );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( i->m_icons.size() < ( m_nEdge * m_nEdge ) )
|
||||
break;
|
||||
|
||||
++ i;
|
||||
}
|
||||
|
||||
if( i == m_icons.end() )
|
||||
{
|
||||
// There were no surfaces with free slots, make a new one
|
||||
cIconBuffer buf;
|
||||
buf.m_icons.reserve( m_nEdge * m_nEdge );
|
||||
|
||||
SIZE sz = { m_szIcon.cx * m_nEdge, m_szIcon.cy * m_nEdge };
|
||||
|
||||
cManager::_p->CreateCanvas( &sz, &buf.m_pSurface );
|
||||
m_icons.push_back( buf );
|
||||
|
||||
// Reset to last entry
|
||||
i = -- m_icons.end();
|
||||
}
|
||||
|
||||
pBuffer = &( *i );
|
||||
nIndex = i->m_icons.size();
|
||||
}
|
||||
|
||||
//Modified by Moputu 05/12/2002 to allow the replacement of icon border colors.
|
||||
bool cIconCache::loadIcon( DWORD dwFile, cIconCache::cIconBuffer *&pBuffer, int &nIndex, long lColor )
|
||||
{
|
||||
findFreeSlot( pBuffer, nIndex );
|
||||
|
||||
struct cColorImage
|
||||
{
|
||||
DWORD m_dwID,
|
||||
m_dwX,
|
||||
m_dwY;
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
cDatFile::cFile icon = cManager::_p->m_portal.getFile( dwFile );
|
||||
cColorImage header;
|
||||
|
||||
icon.read( reinterpret_cast< BYTE * >( &header ), sizeof( cColorImage ) );
|
||||
|
||||
int nXScale, nYScale;
|
||||
|
||||
if( header.m_dwX % m_szIcon.cx != 0 )
|
||||
{
|
||||
// Bad size - only linear filtering here
|
||||
_ASSERT( FALSE );
|
||||
return false;
|
||||
}
|
||||
|
||||
nXScale = header.m_dwX / m_szIcon.cx;
|
||||
|
||||
if( header.m_dwY % m_szIcon.cy != 0 )
|
||||
{
|
||||
// Bad size - only linear filtering here
|
||||
_ASSERT( FALSE );
|
||||
return false;
|
||||
}
|
||||
|
||||
nYScale = header.m_dwY / m_szIcon.cy;
|
||||
|
||||
// Can't fail now, transfering bits to the buffer
|
||||
POINT ptIconOrg = { ( nIndex % m_nEdge ) * m_szIcon.cx, ( nIndex / m_nEdge ) * m_szIcon.cy };
|
||||
RECT rcSrc = { ptIconOrg.x, ptIconOrg.y, ptIconOrg.x + m_szIcon.cx, ptIconOrg.y + m_szIcon.cy };
|
||||
|
||||
DDSURFACEDESC2 desc;
|
||||
desc.dwSize = sizeof( DDSURFACEDESC2 );
|
||||
|
||||
CComPtr< IDirectDrawSurface4 > pSurface;
|
||||
pBuffer->m_pSurface->GetSurface( IID_IDirectDrawSurface4, reinterpret_cast< void ** >( &pSurface ) );
|
||||
|
||||
pSurface->Lock( &rcSrc, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL );
|
||||
|
||||
BYTE srcLine[ 3 * 64 ],
|
||||
*pEndLine = srcLine + 3 * header.m_dwX;
|
||||
|
||||
{
|
||||
for( int i = 0; i < m_szIcon.cy; ++ i )
|
||||
{
|
||||
// Read in a line
|
||||
icon.read( srcLine, 3 * header.m_dwX );
|
||||
icon.skip( 3 * header.m_dwX * ( nYScale - 1 ) );
|
||||
WORD *pwDest = reinterpret_cast< WORD * >( reinterpret_cast< BYTE * >( desc.lpSurface ) + desc.lPitch * i );
|
||||
|
||||
for( BYTE *pbSrc = srcLine; pbSrc != pEndLine; pbSrc += 3 * nXScale, ++ pwDest )
|
||||
{
|
||||
// Check for black (transparent)
|
||||
if( ( pbSrc[ 0 ] == 0 && pbSrc[ 1 ] == 0 && pbSrc[ 2 ] == 0 ) ||
|
||||
( pbSrc[ 0 ] == 255 && pbSrc[ 1 ] == 255 && pbSrc[ 2 ] == 255 ) )
|
||||
// *pwDest = 0x07FF; // Original code
|
||||
if( pbSrc[ 0 ] == 255 && pbSrc[ 1 ] == 255 && pbSrc[ 2 ] == 255 ) //Check for White (border)
|
||||
{
|
||||
if ( lColor == -1 ) // No argument was passed, treat it like the original code would have.
|
||||
{
|
||||
*pwDest = 0x07FF;
|
||||
}
|
||||
else //Replace with specified color.
|
||||
{
|
||||
pBuffer->m_pSurface->DownMixRGB((BYTE)lColor, (BYTE)(lColor >> 8), (BYTE)(lColor >> 16), pwDest);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pwDest = 0x07FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBuffer->m_pSurface->DownMixRGB(pbSrc[0], pbSrc[1], pbSrc[2], pwDest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pSurface->Unlock( &rcSrc );
|
||||
cIconID iid = { NULL, dwFile, lColor }; //Moputu - 05172002: Added lColor to make icons with different colored borders unique.
|
||||
pBuffer->m_icons.push_back( iid );
|
||||
|
||||
// Survived the encounter
|
||||
return true;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Failure, return false at end
|
||||
}
|
||||
|
||||
// File not found, fail
|
||||
_ASSERT( FALSE );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cIconCache::loadIconResource( HMODULE hMod, DWORD dwResourceID, cIconBuffer *&pBuffer, int &nIndex, long lColor )
|
||||
{
|
||||
HICON hIcon = reinterpret_cast< HICON >( ::LoadImage( hMod, MAKEINTRESOURCE( dwResourceID ), IMAGE_ICON, m_szIcon.cx, m_szIcon.cy, LR_DEFAULTCOLOR ) );
|
||||
if( hIcon == NULL )
|
||||
return false;
|
||||
|
||||
findFreeSlot( pBuffer, nIndex );
|
||||
|
||||
// TODO: Write a fast version of this function, use GDI for now
|
||||
|
||||
HDC hdc;
|
||||
pBuffer->m_pSurface->GetDC( &hdc );
|
||||
|
||||
HBRUSH br = ::CreateSolidBrush( RGB( 0, 255, 255 ) );
|
||||
POINT ptIconOrg = { ( nIndex % m_nEdge ) * m_szIcon.cx, ( nIndex / m_nEdge ) * m_szIcon.cy };
|
||||
RECT rcSrc = { ptIconOrg.x, ptIconOrg.y, ptIconOrg.x + m_szIcon.cx, ptIconOrg.y + m_szIcon.cy };
|
||||
|
||||
::FillRect( hdc, &rcSrc, br );
|
||||
::DrawIconEx( hdc, ptIconOrg.x, ptIconOrg.y, hIcon, m_szIcon.cx, m_szIcon.cy, 0, NULL, DI_NORMAL );
|
||||
|
||||
::DeleteObject( br );
|
||||
|
||||
pBuffer->m_pSurface->ReleaseDC();
|
||||
|
||||
::DestroyIcon( hIcon );
|
||||
|
||||
cIconID iid = { hMod, dwResourceID, lColor }; //Moputu - 05172002: Added long lColor to make icons with different colored borders unique.
|
||||
pBuffer->m_icons.push_back( iid );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cIconCache::drawIcon( LPPOINT pPos, ICanvas *pDest, cIconBuffer *pBuffer, int nIndex )
|
||||
{
|
||||
_ASSERTE( pPos != NULL );
|
||||
_ASSERTE( pDest != NULL );
|
||||
_ASSERTE( pBuffer != NULL );
|
||||
_ASSERTE( nIndex >= 0 && nIndex < ( m_nEdge * m_nEdge ) );
|
||||
|
||||
POINT ptIconOrg = { ( nIndex % m_nEdge ) * m_szIcon.cx, ( nIndex / m_nEdge ) * m_szIcon.cy };
|
||||
RECT rcSrc = { ptIconOrg.x, ptIconOrg.y, ptIconOrg.x + m_szIcon.cx, ptIconOrg.y + m_szIcon.cy };
|
||||
|
||||
pDest->Blt( &rcSrc, pBuffer->m_pSurface, pPos );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// cIconCache
|
||||
|
||||
|
||||
STDMETHODIMP cIconCache::DrawIcon( LPPOINT ppt, long nFile, long nModule, ICanvas *pCanvas )
|
||||
{
|
||||
_ASSERTE( ppt != NULL );
|
||||
_ASSERTE( pCanvas != NULL );
|
||||
|
||||
cIconBuffer *pBuffer;
|
||||
int nIndex;
|
||||
|
||||
// GKusnick: Handle no-icon case without asserting.
|
||||
if (nModule == 0 && nFile == 0) return S_OK;
|
||||
|
||||
if( !findIcon( reinterpret_cast< HMODULE >( nModule ), *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex ) )
|
||||
{
|
||||
if( nModule == 0 )
|
||||
{
|
||||
if( !loadIcon( *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !loadIconResource( reinterpret_cast< HMODULE >( nModule ), *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
drawIcon( ppt, pCanvas, pBuffer, nIndex );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cIconCache::DrawIconEx( LPPOINT ppt, long nFile, long nModule, ICanvas *pCanvas, long lColor )
|
||||
{
|
||||
_ASSERTE( ppt != NULL );
|
||||
_ASSERTE( pCanvas != NULL );
|
||||
|
||||
cIconBuffer *pBuffer;
|
||||
int nIndex;
|
||||
|
||||
if( !findIcon( reinterpret_cast< HMODULE >( nModule ), *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex, lColor ) ) //Moputu - 05172002: Added long lColor to make icons with different colored borders unique.
|
||||
{
|
||||
if( nModule == 0 )
|
||||
{
|
||||
if( !loadIcon( *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex, lColor ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !loadIconResource( reinterpret_cast< HMODULE >( nModule ), *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex, lColor ) ) //Moputu - 05172002: Added long lColor to make icons with different colored borders unique.
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
drawIcon( ppt, pCanvas, pBuffer, nIndex );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue