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
515
Native/DecalControls/Slider.cpp
Normal file
515
Native/DecalControls/Slider.cpp
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
#include "stdafx.h"// Slider.cpp : Implementation of cSlider
|
||||
#include <stdio.h>
|
||||
#include "DecalControls.h"
|
||||
#include "Slider.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// cSlider
|
||||
|
||||
cSlider::cSlider() : m_nTextColor(RGB(0, 0, 0)),
|
||||
m_bMouseIn(VARIANT_FALSE),
|
||||
m_bGrappled(VARIANT_FALSE),
|
||||
m_nMinimum(0),
|
||||
m_nMaximum(100),
|
||||
m_nMinSliderColor( RGB(200,0,0) ),
|
||||
m_nMaxSliderColor( RGB(0,200,0) ),
|
||||
m_nSliderPos(0),
|
||||
m_strTextLeft(NULL),
|
||||
m_strTextRight(NULL),
|
||||
m_bVertical(VARIANT_FALSE) {
|
||||
}
|
||||
|
||||
cSlider::~cSlider() {
|
||||
if (m_strTextLeft)
|
||||
free(m_strTextLeft);
|
||||
|
||||
if (m_strTextRight)
|
||||
free(m_strTextRight);
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::get_Font(IFontCacheDisp **pVal) {
|
||||
_ASSERTE(pVal != NULL);
|
||||
|
||||
if (m_pFont.p == NULL)
|
||||
*pVal = NULL;
|
||||
else
|
||||
m_pFont->QueryInterface(pVal);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::putref_Font(IFontCacheDisp *newVal) {
|
||||
_ASSERTE(newVal != NULL);
|
||||
|
||||
if (m_pFont.p)
|
||||
m_pFont.Release();
|
||||
|
||||
HRESULT hRes = newVal->QueryInterface(&m_pFont);
|
||||
|
||||
_ASSERTE(SUCCEEDED(hRes));
|
||||
m_pSite->Reformat();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::get_TextColor(long *pVal) {
|
||||
_ASSERTE(pVal != NULL);
|
||||
|
||||
*pVal = m_nTextColor;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::put_TextColor(long newVal) {
|
||||
_ASSERTE((newVal & 0xFF000000L) == 0);
|
||||
|
||||
m_nTextColor = newVal;
|
||||
m_pSite->Invalidate();
|
||||
Reformat();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP cSlider::get_SliderPosition(long *pVal) {
|
||||
_ASSERTE(pVal != NULL);
|
||||
|
||||
*pVal = m_nSliderPos;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::put_SliderPosition(long newVal) {
|
||||
if (m_nSliderPos == newVal)
|
||||
return S_OK;
|
||||
|
||||
if (newVal < m_nMinimum || newVal > m_nMaximum)
|
||||
return S_FALSE;
|
||||
|
||||
m_nSliderPos = newVal;
|
||||
Reformat();
|
||||
m_pSite->Invalidate();
|
||||
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::get_Minimum(long *pVal) {
|
||||
_ASSERTE(pVal != NULL);
|
||||
|
||||
*pVal = m_nMinimum;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::put_Minimum(long newVal) {
|
||||
if (m_nMinimum == newVal)
|
||||
return S_OK;
|
||||
|
||||
m_nMinimum = newVal;
|
||||
Reformat();
|
||||
m_pSite->Invalidate();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::get_Maximum(long *pVal) {
|
||||
_ASSERTE(pVal != NULL);
|
||||
|
||||
*pVal = m_nMaximum;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::put_Maximum(long newVal) {
|
||||
if (m_nMaximum == newVal)
|
||||
return S_OK;
|
||||
|
||||
m_nMaximum = newVal;
|
||||
Reformat();
|
||||
m_pSite->Invalidate();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::SchemaLoad(IView *pView, IUnknown *pSchema)
|
||||
{
|
||||
// First attempt to load the font
|
||||
CComPtr< IPluginSite > pPlugin;
|
||||
m_pSite->get_PluginSite( &pPlugin );
|
||||
|
||||
pPlugin->CreateFontSchema(14, 0, pSchema, &m_pFont);
|
||||
|
||||
MSXML::IXMLDOMElementPtr pElement = pSchema;
|
||||
|
||||
_variant_t vTextColor = pElement->getAttribute(_T("textcolor")),
|
||||
vMinSliderColor = pElement->getAttribute(_T("mincolor")),
|
||||
vMaxSliderColor = pElement->getAttribute(_T("maxcolor")),
|
||||
vVertical = pElement->getAttribute(_T("vertical")),
|
||||
vDefault = pElement->getAttribute(_T("default")),
|
||||
vMaximum = pElement->getAttribute(_T("maximum")),
|
||||
vMinimum = pElement->getAttribute(_T("minimum")),
|
||||
vName = pElement->getAttribute(_T("name"));
|
||||
|
||||
// Maximum must exist
|
||||
_ASSERTE(vMaximum.vt == VT_INT);
|
||||
|
||||
if (vTextColor.vt != VT_NULL) {
|
||||
try {
|
||||
m_nTextColor = static_cast<long>(vTextColor);
|
||||
} catch(...) {
|
||||
// Type conversion error
|
||||
_ASSERTE(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (vMinSliderColor.vt != VT_NULL) {
|
||||
try {
|
||||
_bstr_t szWhat = vMinSliderColor.bstrVal;
|
||||
m_nMinSliderColor = wcstoul( szWhat, 0, 16 );
|
||||
} catch( ... ) {
|
||||
// Type conversion error
|
||||
_ASSERTE(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (vMaxSliderColor.vt != VT_NULL) {
|
||||
try {
|
||||
_bstr_t szWhat = vMaxSliderColor.bstrVal;
|
||||
m_nMaxSliderColor = wcstoul( szWhat, 0, 16 );
|
||||
} catch( ... ) {
|
||||
// Type conversion error
|
||||
_ASSERTE(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (vVertical.vt != VT_NULL) {
|
||||
try {
|
||||
m_bVertical = (static_cast<bool>(vVertical)) ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
} catch( ... ) {
|
||||
// Type conversion error
|
||||
_ASSERTE(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (vMaximum.vt != VT_NULL) {
|
||||
try {
|
||||
m_nMaximum = static_cast<long>(vMaximum);
|
||||
} catch( ... ) {
|
||||
// Type conversion error
|
||||
_ASSERTE(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (vMinimum.vt != VT_NULL) {
|
||||
try {
|
||||
m_nMinimum = static_cast<long>(vMinimum);
|
||||
} catch( ... ) {
|
||||
// Type conversion error
|
||||
_ASSERTE(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (vDefault.vt != VT_NULL) {
|
||||
try {
|
||||
m_nSliderPos = static_cast<long>(vDefault);
|
||||
} catch( ... ) {
|
||||
m_nSliderPos = m_nMinimum;
|
||||
}
|
||||
}
|
||||
|
||||
/* fprintf( f, "name - %s\n", OLE2A(vName.bstrVal) );
|
||||
fprintf( f, "textcolor - %08X\n", m_nTextColor );
|
||||
fprintf( f, "mincolor - %08X\n", m_nMinSliderColor );
|
||||
fprintf( f, "maxcolor - %08X\n", m_nMaxSliderColor );
|
||||
fprintf( f, "vertical - %X\n", m_bVertical );
|
||||
fprintf( f, "maximum - %08X\n", m_nMaximum );
|
||||
fprintf( f, "minimum - %08X\n\n", m_nMinimum ); */
|
||||
|
||||
/* // it's a pain in the ass that we need set the min and max for them to work, aye? let's fix it
|
||||
RECT rc;
|
||||
m_pSite->get_Position(&rc);
|
||||
|
||||
long siteHHalf = (rc.bottom - rc.top) / 2;
|
||||
|
||||
// The background bar
|
||||
m_rcBackground.left = 0;
|
||||
m_rcBackground.top = siteHHalf - 4;
|
||||
m_rcBackground.bottom = siteHHalf + 6;
|
||||
m_rcBackground.right = rc.right - rc.left;
|
||||
|
||||
// The middle bar
|
||||
m_rcBar.top = siteHHalf;
|
||||
m_rcBar.left = 0;
|
||||
m_rcBar.bottom = siteHHalf + 3;
|
||||
m_rcBar.right = rc.right - rc.left;
|
||||
|
||||
// Ensure sane slider position
|
||||
if (m_nSliderPos < m_nMinimum)
|
||||
m_nSliderPos = m_nMinimum;
|
||||
|
||||
if (m_nSliderPos > m_nMaximum)
|
||||
m_nSliderPos = m_nMaximum;
|
||||
|
||||
long siteDiff = abs(m_rcBar.right - m_rcBar.left);
|
||||
long extentDiff = abs(m_nMaximum - m_nMinimum);
|
||||
long valDiff = m_nSliderPos - m_nMinimum;
|
||||
|
||||
if (valDiff == 0) {
|
||||
m_ptSlider.x = m_rcBar.left;
|
||||
|
||||
} else {
|
||||
long diff = (long)(((float)valDiff / (float)extentDiff) * (float)siteDiff);
|
||||
|
||||
m_ptSlider.x = m_rcBar.left + diff;
|
||||
|
||||
if (m_ptSlider.x >= m_rcBar.right - 6)
|
||||
m_ptSlider.x = m_rcBar.right - 6;
|
||||
}
|
||||
|
||||
m_ptSlider.y = siteHHalf - 5;
|
||||
*/
|
||||
|
||||
// fclose( f );
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::Reformat() {
|
||||
USES_CONVERSION;
|
||||
|
||||
char strTemp[16];
|
||||
|
||||
if (m_strTextLeft)
|
||||
free(m_strTextLeft);
|
||||
|
||||
if (m_strTextRight)
|
||||
free(m_strTextRight);
|
||||
|
||||
_snprintf(strTemp, 15, "%i", m_nMinimum);
|
||||
m_strTextLeft = strdup(strTemp);
|
||||
|
||||
_snprintf(strTemp, 15, "%i", m_nMaximum);
|
||||
m_strTextRight = strdup(strTemp);
|
||||
|
||||
if (m_pFont.p == NULL) {
|
||||
// No font was specified, create the default font
|
||||
CComPtr<IPluginSite> pPlugin;
|
||||
m_pSite->get_PluginSite(&pPlugin);
|
||||
|
||||
BSTR bstrFontName;
|
||||
pPlugin->get_FontName(&bstrFontName);
|
||||
pPlugin->CreateFont(bstrFontName /*_bstr_t(_T("Times New Roman"))*/, 14, 0, &m_pFont);
|
||||
}
|
||||
|
||||
RECT rc;
|
||||
m_pSite->get_Position(&rc);
|
||||
|
||||
SIZE textRight;
|
||||
|
||||
m_pFont->MeasureText(_bstr_t(m_strTextRight), &textRight);
|
||||
|
||||
long siteHHalf = (rc.bottom - rc.top) / 2;
|
||||
|
||||
// The background bar
|
||||
m_rcBackground.left = 0;
|
||||
m_rcBackground.top = siteHHalf - 4;
|
||||
m_rcBackground.bottom = siteHHalf + 6;
|
||||
m_rcBackground.right = rc.right - rc.left;
|
||||
|
||||
// The middle bar
|
||||
m_rcBar.top = siteHHalf;
|
||||
m_rcBar.left = 0;
|
||||
m_rcBar.bottom = siteHHalf + 3;
|
||||
m_rcBar.right = rc.right - rc.left;
|
||||
|
||||
m_ptLeftText.x = m_rcBackground.left + 1;
|
||||
m_ptLeftText.y = m_rcBackground.bottom + 1;
|
||||
m_ptRightText.x = m_rcBackground.right - (textRight.cx + 1);
|
||||
m_ptRightText.y = m_rcBackground.bottom + 1;
|
||||
|
||||
// Ensure sane slider position
|
||||
if (m_nSliderPos < m_nMinimum)
|
||||
m_nSliderPos = m_nMinimum;
|
||||
|
||||
if (m_nSliderPos > m_nMaximum)
|
||||
m_nSliderPos = m_nMaximum;
|
||||
|
||||
long siteDiff = abs(m_rcBar.right - m_rcBar.left);
|
||||
long extentDiff = abs(m_nMaximum - m_nMinimum);
|
||||
long valDiff = m_nSliderPos - m_nMinimum;
|
||||
|
||||
if (valDiff == 0) {
|
||||
m_ptSlider.x = m_rcBar.left;
|
||||
|
||||
} else {
|
||||
long diff = (long)(((float)valDiff / (float)extentDiff) * (float)siteDiff);
|
||||
|
||||
m_ptSlider.x = m_rcBar.left + diff;
|
||||
|
||||
if (m_ptSlider.x >= m_rcBar.right - 6)
|
||||
m_ptSlider.x = m_rcBar.right - 6;
|
||||
}
|
||||
|
||||
m_ptSlider.y = siteHHalf - 5;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::Render(ICanvas *pCanvas)
|
||||
{
|
||||
// intensity to lose or gain for 3d effect
|
||||
#define COLOR_BAND 20
|
||||
|
||||
USES_CONVERSION;
|
||||
|
||||
CComPtr<IPluginSite> pPlugin;
|
||||
m_pSite->get_PluginSite(&pPlugin);
|
||||
|
||||
CComPtr<IIconCache> pIcon;
|
||||
SIZE szIcon = {7, 12};
|
||||
pPlugin->GetIconCache(&szIcon, &pIcon);
|
||||
|
||||
// we're averaging color differences w/bias...
|
||||
float fractional = m_nSliderPos / m_nMaximum;
|
||||
float lFraction = (1 - fractional) * 2;
|
||||
float rFraction = fractional * 2;
|
||||
|
||||
long lMinSliderRed = lFraction * (BYTE) m_nMinSliderColor;
|
||||
long lMinSliderGreen = lFraction * (BYTE) (m_nMinSliderColor >> 8);
|
||||
long lMinSliderBlue = lFraction * (BYTE) (m_nMinSliderColor >> 16);
|
||||
|
||||
long lMaxSliderRed = rFraction * (BYTE) m_nMaxSliderColor;
|
||||
long lMaxSliderGreen = rFraction * (BYTE) (m_nMaxSliderColor >> 8);
|
||||
long lMaxSliderBlue = rFraction * (BYTE) (m_nMaxSliderColor >> 16);
|
||||
|
||||
long lFillColorTop, lFillColorMiddle, lFillColorBottom;
|
||||
|
||||
long lFillColorRed = (lMinSliderRed + lMaxSliderRed) / 2,
|
||||
lFillColorGreen = (lMinSliderGreen + lMaxSliderGreen) / 2,
|
||||
lFillColorBlue = (lMinSliderBlue + lMaxSliderBlue) / 2;
|
||||
|
||||
if( m_nMinSliderColor && m_nMaxSliderColor ) // not black .. who would choose all black for both bars anyway? grr.
|
||||
{
|
||||
// find the most intense color channel to maul for our evil purposes (we're using std::max here)
|
||||
long lMax = max( max( lFillColorRed, lFillColorGreen ), lFillColorBlue );
|
||||
|
||||
// if we're dark, don't overflow
|
||||
long lOffset = lMax > (COLOR_BAND - 1) ? COLOR_BAND : 0;
|
||||
long lOffset2 = lMax > (COLOR_BAND - 1) ? 0 : COLOR_BAND;
|
||||
|
||||
// red
|
||||
if( lMax == lFillColorRed )
|
||||
{
|
||||
lFillColorTop = RGB( lFillColorRed - lOffset, lFillColorGreen, lFillColorBlue );
|
||||
lFillColorMiddle = RGB( lFillColorRed + lOffset2, lFillColorGreen, lFillColorBlue );
|
||||
lFillColorBottom = RGB( lFillColorRed - lOffset, lFillColorGreen, lFillColorBlue );
|
||||
}
|
||||
|
||||
// green
|
||||
else if( lMax == lFillColorGreen )
|
||||
{
|
||||
lFillColorTop = RGB( lFillColorRed, lFillColorGreen - lOffset, lFillColorBlue );
|
||||
lFillColorMiddle = RGB( lFillColorRed, lFillColorGreen + lOffset2, lFillColorBlue );
|
||||
lFillColorBottom = RGB( lFillColorRed, lFillColorGreen - lOffset, lFillColorBlue );
|
||||
}
|
||||
|
||||
// has to be blue
|
||||
else
|
||||
{
|
||||
lFillColorTop = RGB( lFillColorRed, lFillColorGreen, lFillColorBlue - lOffset );
|
||||
lFillColorMiddle = RGB( lFillColorRed, lFillColorGreen, lFillColorBlue + lOffset2 );
|
||||
lFillColorBottom = RGB( lFillColorRed, lFillColorGreen, lFillColorBlue - lOffset );
|
||||
}
|
||||
}
|
||||
|
||||
// someone's a GOTH
|
||||
else
|
||||
{
|
||||
lFillColorTop = 0;
|
||||
lFillColorMiddle = 0x00161616;
|
||||
lFillColorBottom = 0;
|
||||
}
|
||||
|
||||
pCanvas->Fill( &m_rcBar, lFillColorMiddle );
|
||||
|
||||
RECT topBar = {m_rcBar.left, m_rcBar.top, m_rcBar.right, m_rcBar.top + 1};
|
||||
pCanvas->Fill( &topBar, lFillColorTop );
|
||||
|
||||
RECT bottomBar = {m_rcBar.left, m_rcBar.bottom - 1, m_rcBar.right, m_rcBar.bottom};
|
||||
pCanvas->Fill( &bottomBar, lFillColorBottom );
|
||||
|
||||
pIcon->DrawIcon(&m_ptSlider, 0x06001286, 0, pCanvas);
|
||||
|
||||
m_pFont->DrawText(&m_ptLeftText, _bstr_t(m_strTextLeft), RGB(0, 0, 0), pCanvas);
|
||||
m_pFont->DrawText(&m_ptRightText, _bstr_t(m_strTextRight), RGB(0, 0, 0), pCanvas);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::MouseDown(struct MouseState *mouseState) {
|
||||
_ASSERTE(m_pSite != NULL);
|
||||
|
||||
POINT pt = mouseState->client;
|
||||
|
||||
if (pt.x >= (m_ptSlider.x) && (pt.x <= m_ptSlider.x + 6) &&
|
||||
pt.y >= (m_ptSlider.y) && (pt.y <= m_ptSlider.y + 12)) {
|
||||
// They hit the grapple point!
|
||||
m_ptLastMouse = mouseState->client;
|
||||
m_bGrappled = VARIANT_TRUE;
|
||||
} else {
|
||||
// The hit the bar - see if that's within the bar rect
|
||||
|
||||
if (pt.x > m_rcBar.left && pt.x < m_rcBar.right &&
|
||||
pt.y > (m_rcBar.top - 3) && pt.y < (m_rcBar.bottom + 3)) {
|
||||
|
||||
// Calcuate the new slider position
|
||||
float pixelValue = (float)((float)(m_nMaximum - m_nMinimum) / (float)(m_rcBar.right - m_rcBar.left));
|
||||
|
||||
m_nSliderPos = (pt.x - m_rcBar.left) * pixelValue;
|
||||
|
||||
Reformat();
|
||||
m_pSite->Invalidate();
|
||||
|
||||
long nID;
|
||||
m_pSite->get_ID(&nID);
|
||||
_ASSERTE(m_pSite.p != NULL);
|
||||
Fire_Change(nID, m_nSliderPos);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::MouseUp(struct MouseState *mouseState) {
|
||||
m_bGrappled = VARIANT_FALSE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cSlider::MouseMove(struct MouseState *mouseState) {
|
||||
if (m_bGrappled) {
|
||||
long dx;
|
||||
POINT pt = mouseState->client;
|
||||
|
||||
dx = m_ptLastMouse.x - pt.x;
|
||||
m_ptLastMouse = pt;
|
||||
|
||||
float pixelValue = (float)((float)(m_nMaximum - m_nMinimum) / (float)(m_rcBar.right - m_rcBar.left));
|
||||
m_nSliderPos -= ((float)dx * pixelValue);
|
||||
|
||||
// I personally like being able to drag the slider
|
||||
// PAST THE EDGE OF THE SLIDE BAR without needing pixel accuracy...
|
||||
if( pt.x >= m_rcBar.right )
|
||||
m_nSliderPos = m_nMaximum;
|
||||
|
||||
Reformat();
|
||||
m_pSite->Invalidate();
|
||||
|
||||
long nID;
|
||||
m_pSite->get_ID(&nID);
|
||||
_ASSERTE(m_pSite.p != NULL);
|
||||
Fire_Change(nID, m_nSliderPos);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue