windows-nt/Source/XPSP1/NT/multimedia/directx/dxg/ref8/common/rdutil.cpp
2020-09-26 16:20:57 +08:00

402 lines
12 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Copyright (C) Microsoft Corporation, 1998.
//
// rdutil.cpp
//
// Direct3D Reference Device - Utilities
//
//
//
//
///////////////////////////////////////////////////////////////////////////////
#include "pch.cpp"
#pragma hdrstop
//////////////////////////////////////////////////////////////////////////////////
// //
// DPF support //
// //
//////////////////////////////////////////////////////////////////////////////////
// control globals
int g_iDPFLevel = 0;
unsigned long g_uDPFMask = 0x0;
//-----------------------------------------------------------------------------
//
// RDDebugPrintf(L) - Utilities to print varargs-formatted strings of debugging
// info. The 'L' version takes a level into account in deciding to print or
// not.
//
//-----------------------------------------------------------------------------
void
RDErrorPrintf( const char* pszFormat, ... )
{
char tmp[1024];
_snprintf( (LPSTR) tmp, 1024, "D3DRefDev:ERROR: ");
va_list marker;
va_start(marker, pszFormat);
_vsnprintf(tmp+lstrlen(tmp), 1024-lstrlen(tmp), pszFormat, marker);
_snprintf( (LPSTR) tmp, 1024, "%s\n", tmp );
OutputDebugString(tmp);
printf(tmp);
}
void
RDDebugPrintf( const char* pszFormat, ... )
{
char tmp[1024];
_snprintf( (LPSTR) tmp, 1024, "D3DRefDev: ");
va_list marker;
va_start(marker, pszFormat);
_vsnprintf(tmp+lstrlen(tmp), 1024-lstrlen(tmp), pszFormat, marker);
_snprintf( (LPSTR) tmp, 1024, "%s\n", tmp );
OutputDebugString(tmp);
printf(tmp);
}
void
RDDebugPrintfL( int iLevel, const char* pszFormat, ... )
{
if ( (iLevel <= g_iDPFLevel) )
{
char tmp[1024];
_snprintf( (LPSTR) tmp, 1024, "D3DRefDev: ");
va_list marker;
va_start(marker, pszFormat);
_vsnprintf(tmp+lstrlen(tmp), 1024-lstrlen(tmp), pszFormat, marker);
_snprintf( (LPSTR) tmp, 1024, "%s\n", tmp );
OutputDebugString(tmp);
printf(tmp);
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Assert Reporting
//
///////////////////////////////////////////////////////////////////////////////
// little-bit-o-state to track file and line number reporting - this is makes
// this code non-reentrant and non-threadsafe... oh well...
static const char* _pszLastReportFile = NULL;
static int _iLastReportLine = -1;
//-----------------------------------------------------------------------------
void
RDAssertReport( const char* pszString, const char* pszFile, int iLine )
{
char szTmp[1024];
_snprintf( szTmp, 1024, "D3DRR ASSERT: <%d,%s> %s\n",
iLine, pszFile, pszString );
OutputDebugString( szTmp );
#if DBG
DebugBreak();
#endif
}
//-----------------------------------------------------------------------------
void
RDAssertReportPrefix( const char* pszFile, int iLine )
{
_pszLastReportFile = pszFile;
_iLastReportLine = iLine;
}
//-----------------------------------------------------------------------------
void
RDAssertReportMessage( const char* pszFormat, ... )
{
char szTmp[1024];
va_list marker;
va_start( marker, pszFormat );
_vsnprintf( szTmp, 1024, pszFormat, marker );
RDAssertReport( szTmp, _pszLastReportFile, _iLastReportLine );
}
///////////////////////////////////////////////////////////////////////////////
// //
// Generic bit twiddling utilities //
// //
///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// CountSetBits - Returns number of set bits in a multibit value (up to
// 32 bits).
//
//-----------------------------------------------------------------------------
INT32
CountSetBits( UINT32 uVal, INT32 nBits )
{
INT32 iRet = 0;
for (INT32 i=0; i<nBits; i++) {
if (uVal & (0x1<<i)) { iRet++; }
}
return iRet;
}
//-----------------------------------------------------------------------------
//
// FindFirstSetBit - Returns index of first set bit in a multibit value
// (up to 32 bits) or -1 if no bits are set.
//
//-----------------------------------------------------------------------------
INT32
FindFirstSetBit( UINT32 uVal, INT32 nBits )
{
for (INT32 i=0; i<nBits; i++) {
if (uVal & (0x1<<i)) { return i; }
}
return -1;
}
//-----------------------------------------------------------------------------
//
// FindMostSignificantSetBit - Returns index of first set bit in a
// multibit value (up to 32 bits) or 0 if no bits are set.
//
//-----------------------------------------------------------------------------
INT32
FindMostSignificantSetBit( UINT32 uVal, INT32 nBits )
{
for (INT32 i=nBits; i>=0; i--) {
if (uVal & (0x1<<i)) { return i+1; }
}
return 0;
}
//-----------------------------------------------------------------------------
//
// FindLastSetBit - Returns index of last set bit in a multibit value
// (up to 32 bits) or -1 if no bits are set.
//
//-----------------------------------------------------------------------------
INT32
FindLastSetBit( UINT32 uVal, INT32 nBits )
{
for (INT32 i=0; i<nBits; i++) {
if (uVal & (0x1<<(nBits-i-1))) { return (nBits-i-1); }
}
return -1;
}
///////////////////////////////////////////////////////////////////////////////
// //
// Arithmetic utilities //
// //
///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// LerpColor - Performs a linear interpolation between two RDColors
//
// uT is in 1.5 format (1<<5 represents a unit value)
//
//-----------------------------------------------------------------------------
void
LerpColor(
RDColor& Color,
const RDColor& Color0, const RDColor& Color1, UINT8 uT )
{
FLOAT fT = (1./(FLOAT)(1<<5))*(FLOAT)uT;
Color.A = Color0.A + (Color1.A - Color0.A)*fT;
Color.R = Color0.R + (Color1.R - Color0.R)*fT;
Color.G = Color0.G + (Color1.G - Color0.G)*fT;
Color.B = Color0.B + (Color1.B - Color0.B)*fT;
}
//-----------------------------------------------------------------------------
//
// Bilerp - Performs bilinear interpolation of 4 RDColors returning one RDColor.
//
//-----------------------------------------------------------------------------
void
BiLerpColor(
RDColor& OutColor,
const RDColor& Color00, const RDColor& Color01,
const RDColor& Color10, const RDColor& Color11,
UINT8 uA, UINT8 uB )
{
RDColor Color0, Color1;
LerpColor( Color0, Color00, Color01, uA);
LerpColor( Color1, Color10, Color11, uA);
LerpColor( OutColor, Color0, Color1, uB);
}
void
BiLerpColor3D(
RDColor& OutColor,
const RDColor& Color000, const RDColor& Color010,
const RDColor& Color100, const RDColor& Color110,
const RDColor& Color001, const RDColor& Color011,
const RDColor& Color101, const RDColor& Color111,
UINT8 uA, UINT8 uB, UINT8 uC)
{
RDColor Color0, Color1, OutColor0, OutColor1;
LerpColor( Color0, Color000, Color010, uA);
LerpColor( Color1, Color100, Color110, uA);
LerpColor( OutColor0, Color0, Color1, uB);
LerpColor( Color0, Color001, Color011, uA);
LerpColor( Color1, Color101, Color111, uA);
LerpColor( OutColor1, Color0, Color1, uB);
LerpColor( OutColor, OutColor0, OutColor1, uC);
}
///////////////////////////////////////////////////////////////////////////////
//
// DDGetAttachedSurfaceLcl implementation
//
///////////////////////////////////////////////////////////////////////////////
HRESULT
DDGetAttachedSurfaceLcl(
LPDDRAWI_DDRAWSURFACE_LCL this_lcl,
LPDDSCAPS2 lpDDSCaps,
LPDDRAWI_DDRAWSURFACE_LCL *lplpDDAttachedSurfaceLcl)
{
LPDDRAWI_DIRECTDRAW_GBL pdrv;
LPDDRAWI_DDRAWSURFACE_GBL pgbl;
LPATTACHLIST pal;
DWORD caps;
DWORD testcaps;
DWORD ucaps;
DWORD caps2;
DWORD testcaps2;
DWORD ucaps2;
DWORD caps3;
DWORD testcaps3;
DWORD ucaps3;
DWORD caps4;
DWORD testcaps4;
DWORD ucaps4;
BOOL ok;
pgbl = this_lcl->lpGbl;
*lplpDDAttachedSurfaceLcl = NULL;
pdrv = pgbl->lpDD;
/*
* look for the surface
*/
pal = this_lcl->lpAttachList;
testcaps = lpDDSCaps->dwCaps;
testcaps2 = lpDDSCaps->dwCaps2;
testcaps3 = lpDDSCaps->dwCaps3;
testcaps4 = lpDDSCaps->dwCaps4;
while( pal != NULL )
{
ok = TRUE;
caps = pal->lpAttached->ddsCaps.dwCaps;
caps2 = pal->lpAttached->lpSurfMore->ddsCapsEx.dwCaps2;
caps3 = pal->lpAttached->lpSurfMore->ddsCapsEx.dwCaps3;
caps4 = pal->lpAttached->lpSurfMore->ddsCapsEx.dwCaps4;
ucaps = caps & testcaps;
ucaps2 = caps2 & testcaps2;
ucaps3 = caps3 & testcaps3;
ucaps4 = caps4 & testcaps4;
if( ucaps | ucaps2 | ucaps3 | ucaps4 )
{
/*
* there are caps in common, make sure that the caps to test
* were all there
*/
if( (ucaps & testcaps) == testcaps &&
(ucaps2 & testcaps2) == testcaps2 &&
(ucaps3 & testcaps3) == testcaps3 &&
(ucaps4 & testcaps4) == testcaps4 )
{
}
else
{
ok = FALSE;
}
}
else
{
ok = FALSE;
}
if( ok )
{
*lplpDDAttachedSurfaceLcl = pal->lpAttached;
return DD_OK;
}
pal = pal->lpLink;
}
return DDERR_NOTFOUND;
}
//---------------------------------------------------------------------
// Gets the value from DIRECT3D registry key
// Returns TRUE if success
// If fails value is not changed
//---------------------------------------------------------------------
BOOL
GetD3DRegValue(DWORD type, char *valueName, LPVOID value, DWORD dwSize)
{
HKEY hKey = (HKEY) NULL;
if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, RESPATH_D3D, &hKey))
{
DWORD dwType;
LONG result;
result = RegQueryValueEx(hKey, valueName, NULL, &dwType,
(LPBYTE)value, &dwSize);
RegCloseKey(hKey);
return result == ERROR_SUCCESS && dwType == type;
}
else
return FALSE;
}
//---------------------------------------------------------------------
// Gets the value from DIRECT3D Reference device registry key
// Returns TRUE if success
// If fails value is not changed
//---------------------------------------------------------------------
BOOL
GetD3DRefRegValue(DWORD type, char *valueName, LPVOID value, DWORD dwSize)
{
HKEY hKey = (HKEY) NULL;
if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, RESPATH_D3DREF, &hKey))
{
DWORD dwType;
LONG result;
result = RegQueryValueEx(hKey, valueName, NULL, &dwType,
(LPBYTE)value, &dwSize);
RegCloseKey(hKey);
return result == ERROR_SUCCESS && dwType == type;
}
else
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// RefAlignedBuffer32
///////////////////////////////////////////////////////////////////////////////
HRESULT
RefAlignedBuffer32::Grow(DWORD growSize)
{
if (m_allocatedBuf)
free(m_allocatedBuf);
m_size = growSize;
if ((m_allocatedBuf = malloc(m_size + 31)) == NULL)
{
m_allocatedBuf = 0;
m_alignedBuf = 0;
m_size = 0;
return DDERR_OUTOFMEMORY;
}
m_alignedBuf = (LPVOID)(((ULONG_PTR)m_allocatedBuf + 31 ) & ~31);
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////////
// end