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
231
Native/DecalInput/TypeAction.cpp
Normal file
231
Native/DecalInput/TypeAction.cpp
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
// TypeAction.cpp : Implementation of cTypeAction
|
||||
#include "stdafx.h"
|
||||
#include "DecalInput.h"
|
||||
#include "TypeAction.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// cTypeAction
|
||||
|
||||
HRESULT cTypeAction::extractKey( LPTSTR &szIter, long nShiftState, IInputService *pService )
|
||||
{
|
||||
HRESULT hRes;
|
||||
|
||||
switch( *szIter )
|
||||
{
|
||||
case _T( '\0' ):
|
||||
return E_INVALIDARG;
|
||||
|
||||
case _T( '{' ):
|
||||
// Make sure this is a good key
|
||||
{
|
||||
for( TCHAR *szChar = szIter + 1; *szChar != _T( '\0' ); ++ szChar )
|
||||
{
|
||||
if( *szChar == _T( '}' ) )
|
||||
{
|
||||
// Look up this character in the site table
|
||||
std::string strspecial( szIter + 1, szChar - ( szIter + 1 ) );
|
||||
long nVK;
|
||||
|
||||
hRes = pService->get_KeyByName( _bstr_t( strspecial.c_str() ), &nVK );
|
||||
if( FAILED( hRes ) )
|
||||
{
|
||||
_ASSERTE( FALSE );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
cKey key = { nShiftState, nVK };
|
||||
m_keys.push_back( key );
|
||||
szIter = szChar + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( *szChar == _T( '\0' ) )
|
||||
{
|
||||
// Unterminated constant
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case _T( '<' ):
|
||||
{
|
||||
for( TCHAR *szChar = szIter + 1; *szChar != _T( '\0' ); ++ szChar )
|
||||
{
|
||||
if( *szChar == _T( '>' ) )
|
||||
{
|
||||
// Look up this character in the site table
|
||||
std::string strspecial( szIter + 1, szChar - ( szIter + 1 ) );
|
||||
long nVK;
|
||||
|
||||
hRes = pService->get_CommandKey( _bstr_t( strspecial.c_str() ), &nVK );
|
||||
if( hRes != S_OK )
|
||||
{
|
||||
_ASSERTE( FALSE );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
cKey key = { nShiftState, nVK };
|
||||
m_keys.push_back( key );
|
||||
szIter = szChar + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( *szChar == _T( '\0' ) )
|
||||
{
|
||||
// Unterminated constant
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
// Convert the character
|
||||
WORD wVkScan = VkKeyScan( *szIter );
|
||||
|
||||
cKey key = { nShiftState | ( wVkScan & SHIFT_MASK ),
|
||||
wVkScan & VKEY_MASK };
|
||||
m_keys.push_back( key );
|
||||
|
||||
++ szIter;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT cTypeAction::onLoad( LPTSTR szData )
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
typedef std::stack< long > cShiftStack;
|
||||
cShiftStack shifts;
|
||||
long nCurrentShift = 0;
|
||||
|
||||
CComPtr< IInputService > pService;
|
||||
HRESULT hRes = m_pSite->get_Service( &pService );
|
||||
if( FAILED( hRes ) )
|
||||
return hRes;
|
||||
|
||||
for( TCHAR *szIter = szData; *szIter != _T( '\0' ); )
|
||||
{
|
||||
switch( *szIter )
|
||||
{
|
||||
case _T( '+' ):
|
||||
if( szIter[ 1 ] == _T( '(' ) )
|
||||
{
|
||||
szIter += 2;
|
||||
shifts.push( nCurrentShift );
|
||||
nCurrentShift |= MASK_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
++ szIter;
|
||||
hRes = extractKey( szIter, nCurrentShift | MASK_SHIFT, pService );
|
||||
if( FAILED( hRes ) )
|
||||
return hRes;
|
||||
}
|
||||
break;
|
||||
|
||||
case _T( '^' ):
|
||||
if( szIter[ 1 ] == _T( '(' ) )
|
||||
{
|
||||
szIter += 2;
|
||||
shifts.push( nCurrentShift );
|
||||
nCurrentShift |= MASK_CTRL;
|
||||
}
|
||||
else
|
||||
{
|
||||
++ szIter;
|
||||
hRes = extractKey( szIter, nCurrentShift | MASK_SHIFT, pService );
|
||||
if( FAILED( hRes ) )
|
||||
return hRes;
|
||||
}
|
||||
break;
|
||||
|
||||
case _T( '%' ):
|
||||
if( szIter[ 1 ] == _T( '(' ) )
|
||||
{
|
||||
szIter += 2;
|
||||
shifts.push( nCurrentShift );
|
||||
nCurrentShift |= MASK_ALT;
|
||||
}
|
||||
else
|
||||
{
|
||||
++ szIter;
|
||||
hRes = extractKey( szIter, nCurrentShift | MASK_SHIFT, pService );
|
||||
if( FAILED( hRes ) )
|
||||
return hRes;
|
||||
}
|
||||
break;
|
||||
|
||||
case _T( ')' ):
|
||||
{
|
||||
if( shifts.size() == 0 )
|
||||
{
|
||||
// Misplaced ')'
|
||||
_ASSERT( FALSE );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
nCurrentShift = shifts.top();
|
||||
shifts.pop();
|
||||
|
||||
++ szIter;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
hRes = extractKey( szIter, nCurrentShift, pService );
|
||||
if( FAILED( hRes ) )
|
||||
return hRes;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( shifts.size() > 0 )
|
||||
{
|
||||
// Unterminated shift
|
||||
_ASSERT( FALSE );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Successful parsing WTG!
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cTypeAction::Execute()
|
||||
{
|
||||
long nShift = 0;
|
||||
for( cKeyList::iterator i = m_keys.begin(); i != m_keys.end(); ++ i )
|
||||
{
|
||||
transitionShift( nShift, i->m_nShiftState );
|
||||
pressKey( i->m_nVK, true );
|
||||
pressKey( i->m_nVK, false );
|
||||
|
||||
nShift = i->m_nShiftState;
|
||||
}
|
||||
|
||||
// Make sure all shift keys are released
|
||||
transitionShift( nShift, 0 );
|
||||
flushInput();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cTypeAction::Push()
|
||||
{
|
||||
doInput( m_keys.begin(), m_keys.end(), true );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cTypeAction::Pop()
|
||||
{
|
||||
doInput( m_keys.rbegin(), m_keys.rend(), false );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue