2975 lines
103 KiB
C++
2975 lines
103 KiB
C++
![]() |
#include "advwin32.h"
|
||
|
#ifndef DB_LEVEL
|
||
|
#define DB_LEVEL 4
|
||
|
#endif
|
||
|
#include "db.h"
|
||
|
|
||
|
#ifndef NDEBUG
|
||
|
#define HT_FAIL db_log1
|
||
|
#include "hash_tem.hpp" // for the backup surfaces memory leak checking
|
||
|
#endif
|
||
|
|
||
|
#ifdef _MSC_VER
|
||
|
#include "iff.hpp"
|
||
|
#endif
|
||
|
|
||
|
#include "list_tem.hpp"
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <limits.h>
|
||
|
|
||
|
#include "awTexLd.h"
|
||
|
#pragma warning(disable: 4701)
|
||
|
#include "awTexLd.hpp"
|
||
|
#pragma warning(default: 4701)
|
||
|
|
||
|
#ifdef _CPPRTTI
|
||
|
#include <typeinfo.h>
|
||
|
#endif
|
||
|
|
||
|
/* awTexLd.cpp - Author: Jake Hotson */
|
||
|
|
||
|
/*****************************************/
|
||
|
/* Preprocessor switches for experiments */
|
||
|
/*****************************************/
|
||
|
|
||
|
#define MIPMAPTEST 0 // experiment to create mip map surfaces for textures, but doesn't bother putting any data into them
|
||
|
|
||
|
/*****************************/
|
||
|
/* DB_LEVEL dependent macros */
|
||
|
/*****************************/
|
||
|
|
||
|
#if DB_LEVEL >= 5
|
||
|
#define inline // prevent function inlining at level 5 debugging
|
||
|
#endif
|
||
|
|
||
|
/*****************************************************/
|
||
|
/* ZEROFILL and SETDWSIZE macros ensure that I won't */
|
||
|
/* accidentally get the parameters wrong */
|
||
|
/*****************************************************/
|
||
|
|
||
|
#if 1 // which do you prefer?
|
||
|
|
||
|
// zero mem
|
||
|
template <class X>
|
||
|
static inline void ZEROFILL(X & x)
|
||
|
{
|
||
|
memset(&x,0,sizeof(X));
|
||
|
}
|
||
|
|
||
|
// set dwSize
|
||
|
template <class X>
|
||
|
static inline void SETDWSIZE(X & x)
|
||
|
{
|
||
|
x.dwSize = sizeof(X);
|
||
|
}
|
||
|
|
||
|
template <class X>
|
||
|
static inline void INITDXSTRUCT(X & x)
|
||
|
{
|
||
|
ZEROFILL(x);
|
||
|
SETDWSIZE(x);
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define ZEROFILL(x) (memset(&x,0,sizeof x))
|
||
|
#define SETDWSIZE(x) (x.dwSize = sizeof x)
|
||
|
#define INITDXSTRUCT(x) (ZEROFILL(x),SETDWSIZE(x))
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/*****************************************************************/
|
||
|
/* Put everything I can in a namespace to avoid naming conflicts */
|
||
|
/*****************************************************************/
|
||
|
|
||
|
namespace AwTl
|
||
|
{
|
||
|
/**************************************************/
|
||
|
/* Allow breakpoints to be potentially hard coded */
|
||
|
/* into macros and template functions */
|
||
|
/**************************************************/
|
||
|
|
||
|
db_code5(void BrkPt(){})
|
||
|
#define BREAKPOINT db_code5(::AwTl::BrkPt();)
|
||
|
|
||
|
#if DB_LEVEL > 4
|
||
|
static unsigned GetRefCount(IUnknown * pUnknown)
|
||
|
{
|
||
|
if (!pUnknown) return 0;
|
||
|
pUnknown->AddRef();
|
||
|
return static_cast<unsigned>(pUnknown->Release());
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*********************************/
|
||
|
/* Pixel format global structure */
|
||
|
/*********************************/
|
||
|
|
||
|
PixelFormat pixelFormat;
|
||
|
|
||
|
PixelFormat pfTextureFormat;
|
||
|
PixelFormat pfSurfaceFormat;
|
||
|
|
||
|
static inline void SetBitShifts(unsigned * leftShift,unsigned * rightShift,unsigned mask)
|
||
|
{
|
||
|
if (!mask)
|
||
|
*leftShift = 0;
|
||
|
else
|
||
|
for (*leftShift = 0; !(mask & 1); ++*leftShift, mask>>=1)
|
||
|
;
|
||
|
for (*rightShift = 8; mask; --*rightShift, mask>>=1)
|
||
|
;
|
||
|
}
|
||
|
|
||
|
/************************************/
|
||
|
/* D3D Driver info global structure */
|
||
|
/************************************/
|
||
|
|
||
|
static
|
||
|
struct DriverDesc
|
||
|
{
|
||
|
DriverDesc() : validB(false), ddP(NULL) {}
|
||
|
|
||
|
bool validB : 1;
|
||
|
bool needSquareB : 1;
|
||
|
bool needPow2B : 1;
|
||
|
|
||
|
unsigned minWidth;
|
||
|
unsigned minHeight;
|
||
|
unsigned maxWidth;
|
||
|
unsigned maxHeight;
|
||
|
|
||
|
DWORD memFlag;
|
||
|
|
||
|
DDObject * ddP;
|
||
|
}
|
||
|
driverDesc;
|
||
|
|
||
|
/*************************************************************************/
|
||
|
/* Class used to hold all the parameters for the CreateTexture functions */
|
||
|
/*************************************************************************/
|
||
|
|
||
|
class CreateTextureParms
|
||
|
{
|
||
|
public:
|
||
|
inline CreateTextureParms()
|
||
|
: fileNameS(NULL)
|
||
|
, fileH(INVALID_HANDLE_VALUE)
|
||
|
, dataP(NULL)
|
||
|
, restoreH(NULL)
|
||
|
, maxReadBytes(UINT_MAX)
|
||
|
, bytesReadP(NULL)
|
||
|
, flags(AW_TLF_DEFAULT)
|
||
|
, originalWidthP(NULL)
|
||
|
, originalHeightP(NULL)
|
||
|
, widthP(NULL)
|
||
|
, heightP(NULL)
|
||
|
, backupHP(NULL)
|
||
|
, prevTexP(static_cast<D3DTexture *>(NULL))
|
||
|
, prevTexB(false)
|
||
|
, loadTextureB(false)
|
||
|
, callbackF(NULL)
|
||
|
, rectA(NULL)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
SurfUnion DoCreate() const;
|
||
|
|
||
|
bool loadTextureB;
|
||
|
|
||
|
LPCTSTR fileNameS;
|
||
|
HANDLE fileH;
|
||
|
PtrUnionConst dataP;
|
||
|
AW_BACKUPTEXTUREHANDLE restoreH;
|
||
|
|
||
|
unsigned maxReadBytes;
|
||
|
unsigned * bytesReadP;
|
||
|
|
||
|
unsigned flags;
|
||
|
|
||
|
unsigned * widthP;
|
||
|
unsigned * heightP;
|
||
|
|
||
|
unsigned * originalWidthP;
|
||
|
unsigned * originalHeightP;
|
||
|
|
||
|
AW_BACKUPTEXTUREHANDLE * backupHP;
|
||
|
|
||
|
SurfUnion prevTexP;
|
||
|
bool prevTexB; // used when rectA is non-NULL, otherwise prevTexP is used
|
||
|
|
||
|
AW_TL_PFN_CALLBACK callbackF;
|
||
|
void * callbackParam;
|
||
|
|
||
|
unsigned numRects;
|
||
|
AwCreateGraphicRegion * rectA;
|
||
|
};
|
||
|
|
||
|
|
||
|
/****************************************/
|
||
|
/* Reference Count Object Debug Support */
|
||
|
/****************************************/
|
||
|
|
||
|
#ifndef NDEBUG
|
||
|
|
||
|
static bool g_bAllocListActive = false;
|
||
|
|
||
|
class AllocList : public ::HashTable<RefCntObj *>
|
||
|
{
|
||
|
public:
|
||
|
AllocList()
|
||
|
{
|
||
|
g_bAllocListActive = true;
|
||
|
}
|
||
|
~AllocList()
|
||
|
{
|
||
|
if (Size())
|
||
|
{
|
||
|
db_log1(("AW: Potential Memory Leaks Detected!!!"));
|
||
|
}
|
||
|
#ifdef _CPPRTTI
|
||
|
#pragma message("Run-Time Type Identification (RTTI) is enabled")
|
||
|
for (Iterator itLeak(*this) ; !itLeak.Done() ; itLeak.Next())
|
||
|
{
|
||
|
db_logf1(("\tAW Object not deallocated: Type: %s RefCnt: %u",typeid(*itLeak.Get()).name(),itLeak.Get()->m_nRefCnt));
|
||
|
}
|
||
|
if (Size())
|
||
|
{
|
||
|
db_log1(("AW: Object dump complete"));
|
||
|
}
|
||
|
#else // ! _CPPRTTI
|
||
|
#pragma message("Run-Time Type Identification (RTTI) is not enabled - memory leak checking will not report types")
|
||
|
unsigned nRefs(0);
|
||
|
for (Iterator itLeak(*this) ; !itLeak.Done() ; itLeak.Next())
|
||
|
{
|
||
|
nRefs += itLeak.Get()->m_nRefCnt;
|
||
|
}
|
||
|
if (Size())
|
||
|
{
|
||
|
db_logf1(("AW: Objects not deallocated: Number of Objects: %u Number of References: %u",Size(),nRefs));
|
||
|
}
|
||
|
#endif // ! _CPPRTTI
|
||
|
g_bAllocListActive = false;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
static AllocList g_listAllocated;
|
||
|
|
||
|
void DbRemember(RefCntObj * pObj)
|
||
|
{
|
||
|
g_listAllocated.AddAsserted(pObj);
|
||
|
}
|
||
|
|
||
|
void DbForget(RefCntObj * pObj)
|
||
|
{
|
||
|
if (g_bAllocListActive)
|
||
|
g_listAllocated.RemoveAsserted(pObj);
|
||
|
}
|
||
|
|
||
|
#endif // ! NDEBUG
|
||
|
|
||
|
/********************************************/
|
||
|
/* structure to contain loading information */
|
||
|
/********************************************/
|
||
|
|
||
|
struct LoadInfo
|
||
|
{
|
||
|
DDSurface * surfaceP;
|
||
|
bool surface_lockedB;
|
||
|
DDSurface * dst_surfaceP;
|
||
|
D3DTexture * textureP;
|
||
|
D3DTexture * dst_textureP;
|
||
|
|
||
|
unsigned surface_width;
|
||
|
unsigned surface_height;
|
||
|
PtrUnion surface_dataP;
|
||
|
LONG surface_pitch;
|
||
|
DWORD dwCapsCaps;
|
||
|
|
||
|
unsigned * widthP;
|
||
|
unsigned * heightP;
|
||
|
SurfUnion prevTexP;
|
||
|
SurfUnion resultP;
|
||
|
unsigned top,left,bottom,right;
|
||
|
unsigned width,height; // set to right-left and bottom-top
|
||
|
|
||
|
AwCreateGraphicRegion * rectP;
|
||
|
|
||
|
bool skipB; // used to indicate that a surface/texture was not lost and .`. does not need restoring
|
||
|
|
||
|
LoadInfo()
|
||
|
: surfaceP(NULL)
|
||
|
, surface_lockedB(false)
|
||
|
, dst_surfaceP(NULL)
|
||
|
, textureP(NULL)
|
||
|
, dst_textureP(NULL)
|
||
|
, skipB(false)
|
||
|
{
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/*******************************/
|
||
|
/* additiional texture formats */
|
||
|
/*******************************/
|
||
|
|
||
|
struct AdditionalPixelFormat : PixelFormat
|
||
|
{
|
||
|
bool canDoTranspB;
|
||
|
unsigned maxColours;
|
||
|
|
||
|
// for List
|
||
|
bool operator == (AdditionalPixelFormat const &) const { return false; }
|
||
|
bool operator != (AdditionalPixelFormat const &) const { return true; }
|
||
|
};
|
||
|
|
||
|
static List<AdditionalPixelFormat> listTextureFormats;
|
||
|
|
||
|
} // namespace AwTl
|
||
|
|
||
|
/*******************/
|
||
|
/* Generic Loaders */
|
||
|
/*******************/
|
||
|
|
||
|
#define HANDLE_DXERROR(s) \
|
||
|
if (DD_OK != awTlLastDxErr) { \
|
||
|
awTlLastErr = AW_TLE_DXERROR; \
|
||
|
db_logf3(("AwCreateGraphic() failed whilst %s",s)); \
|
||
|
db_log1("AwCreateGraphic(): ERROR: DirectX SDK call failed"); \
|
||
|
goto EXIT_WITH_ERROR; \
|
||
|
} else { \
|
||
|
db_logf5(("\tsuccessfully completed %s",s)); \
|
||
|
}
|
||
|
|
||
|
#define ON_ERROR_RETURN_NULL(s) \
|
||
|
if (awTlLastErr != AW_TLE_OK) { \
|
||
|
db_logf3(("AwCreateGraphic() failed whilst %s",s)); \
|
||
|
db_logf1(("AwCreateGraphic(): ERROR: %s",AwTlErrorToString())); \
|
||
|
return static_cast<D3DTexture *>(NULL); \
|
||
|
} else { \
|
||
|
db_logf5(("\tsuccessfully completed %s",s)); \
|
||
|
}
|
||
|
|
||
|
#define CHECK_MEDIA_ERRORS(s) \
|
||
|
if (pMedium->m_fError) { \
|
||
|
db_logf3(("AwCreateGraphic(): The following media errors occurred whilst %s",s)); \
|
||
|
if (pMedium->m_fError & MediaMedium::MME_VEOFMET) { \
|
||
|
db_log3("\tA virtual end of file was met"); \
|
||
|
if (awTlLastErr == AW_TLE_OK) awTlLastErr = AW_TLE_EOFMET; \
|
||
|
} \
|
||
|
if (pMedium->m_fError & MediaMedium::MME_EOFMET) { \
|
||
|
db_log3("\tAn actual end of file was met"); \
|
||
|
if (awTlLastErr == AW_TLE_OK) awTlLastErr = AW_TLE_EOFMET; \
|
||
|
} \
|
||
|
if (pMedium->m_fError & MediaMedium::MME_OPENFAIL) { \
|
||
|
db_log3("\tThe file could not be opened"); \
|
||
|
if (awTlLastErr == AW_TLE_OK) { awTlLastErr = AW_TLE_CANTOPENFILE; awTlLastWinErr = GetLastError(); } \
|
||
|
} \
|
||
|
if (pMedium->m_fError & MediaMedium::MME_CLOSEFAIL) { \
|
||
|
db_log3("\tThe file could not be closed"); \
|
||
|
if (awTlLastErr == AW_TLE_OK) { awTlLastErr = AW_TLE_CANTOPENFILE; awTlLastWinErr = GetLastError(); } \
|
||
|
} \
|
||
|
if (pMedium->m_fError & MediaMedium::MME_UNAVAIL) { \
|
||
|
db_log3("\tA requested operation was not available"); \
|
||
|
if (awTlLastErr == AW_TLE_OK) { awTlLastErr = AW_TLE_CANTREADFILE; awTlLastWinErr = GetLastError(); } \
|
||
|
} \
|
||
|
if (pMedium->m_fError & MediaMedium::MME_IOERROR) { \
|
||
|
db_log3("\tA read error occurred"); \
|
||
|
if (awTlLastErr == AW_TLE_OK) { awTlLastErr = AW_TLE_CANTREADFILE; awTlLastWinErr = GetLastError(); } \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
AwTl::SurfUnion AwBackupTexture::Restore(AwTl::CreateTextureParms const & rParams)
|
||
|
{
|
||
|
using namespace AwTl;
|
||
|
|
||
|
ChoosePixelFormat(rParams);
|
||
|
|
||
|
if (!pixelFormat.validB)
|
||
|
db_log3("AwCreateGraphic(): ERROR: pixel format not valid");
|
||
|
if (!driverDesc.ddP || !driverDesc.validB && rParams.loadTextureB)
|
||
|
db_log3("AwCreateGraphic(): ERROR: driver description not valid");
|
||
|
|
||
|
awTlLastErr = pixelFormat.validB && driverDesc.ddP && (driverDesc.validB || !rParams.loadTextureB) ? AW_TLE_OK : AW_TLE_NOINIT;
|
||
|
|
||
|
ON_ERROR_RETURN_NULL("initializing restore")
|
||
|
|
||
|
OnBeginRestoring(pixelFormat.palettizedB ? 1<<pixelFormat.bitsPerPixel : 0);
|
||
|
|
||
|
ON_ERROR_RETURN_NULL("initializing restore")
|
||
|
|
||
|
SurfUnion pTex = CreateTexture(rParams);
|
||
|
|
||
|
OnFinishRestoring(AW_TLE_OK == awTlLastErr ? true : false);
|
||
|
|
||
|
return pTex;
|
||
|
}
|
||
|
|
||
|
bool AwBackupTexture::HasTransparentMask(bool bDefault)
|
||
|
{
|
||
|
return bDefault;
|
||
|
}
|
||
|
|
||
|
DWORD AwBackupTexture::GetTransparentColour()
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void AwBackupTexture::ChoosePixelFormat(AwTl::CreateTextureParms const & _parmsR)
|
||
|
{
|
||
|
using namespace AwTl;
|
||
|
|
||
|
pixelFormat.validB = false; // set invalid first
|
||
|
|
||
|
// which flags to use?
|
||
|
unsigned fMyFlags =
|
||
|
_parmsR.flags & AW_TLF_PREVSRCALL ? db_assert1(_parmsR.restoreH), m_fFlags
|
||
|
: _parmsR.flags & AW_TLF_PREVSRC ? db_assert1(_parmsR.restoreH),
|
||
|
_parmsR.flags & ~AW_TLF_TRANSP | m_fFlags & AW_TLF_TRANSP
|
||
|
: _parmsR.flags;
|
||
|
|
||
|
// transparency?
|
||
|
m_bTranspMask = HasTransparentMask(fMyFlags & AW_TLF_TRANSP ? true : false);
|
||
|
|
||
|
#if 0
|
||
|
if (_parmsR.prevTexP.voidP)
|
||
|
{
|
||
|
// use the previous format
|
||
|
}
|
||
|
else if (_parmsR.prevTexB)
|
||
|
{
|
||
|
// use the previous format from one of the regiouns
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
|
||
|
if (_parmsR.loadTextureB || fMyFlags & AW_TLF_TEXTURE)
|
||
|
{
|
||
|
// use a texture format
|
||
|
unsigned nColours = GetNumColours();
|
||
|
unsigned nMinPalSize = GetMinPaletteSize();
|
||
|
|
||
|
PixelFormat const * pFormat = &pfTextureFormat;
|
||
|
|
||
|
for (LIF<AdditionalPixelFormat> itFormat(&listTextureFormats); !itFormat.done(); itFormat.next())
|
||
|
{
|
||
|
AdditionalPixelFormat const * pThisFormat = &itFormat();
|
||
|
// is this format suitable?
|
||
|
// ignoring alpha for now
|
||
|
if
|
||
|
(
|
||
|
(nMinPalSize <= 1U<<pThisFormat->bitsPerPixel && nMinPalSize || !pThisFormat->palettizedB) // few enough colours for palettized format
|
||
|
&& (nColours <= pThisFormat->maxColours && nColours || !pThisFormat->maxColours) // pass the max colours test
|
||
|
&& (pThisFormat->canDoTranspB || !m_bTranspMask) // pass the transparency test
|
||
|
)
|
||
|
{
|
||
|
pFormat = pThisFormat;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pixelFormat = *pFormat;
|
||
|
|
||
|
#if DB_LEVEL >= 4
|
||
|
if (pixelFormat.palettizedB)
|
||
|
{
|
||
|
db_logf4(("\tchosen %u-bit palettized texture format",pixelFormat.bitsPerPixel));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pixelFormat.alphaB)
|
||
|
{
|
||
|
unsigned alpha_l_shft,alpha_r_shft;
|
||
|
SetBitShifts(&alpha_l_shft,&alpha_r_shft,pixelFormat.ddpf.dwRGBAlphaBitMask);
|
||
|
|
||
|
db_logf4(("\tchosen %u-bit %u%u%u%u texture format",
|
||
|
pixelFormat.bitsPerPixel,
|
||
|
8U-pixelFormat.redRightShift,
|
||
|
8U-pixelFormat.greenRightShift,
|
||
|
8U-pixelFormat.blueRightShift,
|
||
|
8U-alpha_r_shft));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
db_logf4(("\tchosen %u-bit %u%u%u texture format",
|
||
|
pixelFormat.bitsPerPixel,
|
||
|
8U-pixelFormat.redRightShift,
|
||
|
8U-pixelFormat.greenRightShift,
|
||
|
8U-pixelFormat.blueRightShift));
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// use display surface format
|
||
|
pixelFormat = pfSurfaceFormat;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
AwTl::SurfUnion AwBackupTexture::CreateTexture(AwTl::CreateTextureParms const & _parmsR)
|
||
|
{
|
||
|
using namespace AwTl;
|
||
|
|
||
|
// which flags to use?
|
||
|
unsigned fMyFlags =
|
||
|
_parmsR.flags & AW_TLF_PREVSRCALL ? db_assert1(_parmsR.restoreH),
|
||
|
_parmsR.flags & (AW_TLF_CHECKLOST|AW_TLF_SKIPNOTLOST) | m_fFlags & ~(AW_TLF_CHECKLOST|AW_TLF_SKIPNOTLOST)
|
||
|
: _parmsR.flags & AW_TLF_PREVSRC ? db_assert1(_parmsR.restoreH),
|
||
|
_parmsR.flags & ~AW_TLF_TRANSP | m_fFlags & AW_TLF_TRANSP
|
||
|
: _parmsR.flags;
|
||
|
|
||
|
db_code1(ULONG refcnt;)
|
||
|
|
||
|
DDPalette * dd_paletteP = NULL;
|
||
|
LoadInfo * arrLoadInfo = NULL;
|
||
|
unsigned nLoadInfos = 0;
|
||
|
{
|
||
|
// quick error check
|
||
|
if (pixelFormat.palettizedB && (!m_nPaletteSize || 1U<<pixelFormat.bitsPerPixel < m_nPaletteSize))
|
||
|
awTlLastErr = AW_TLE_CANTPALETTIZE;
|
||
|
if (!m_nHeight || !m_nWidth)
|
||
|
awTlLastErr = AW_TLE_BADFILEDATA;
|
||
|
if (AW_TLE_OK != awTlLastErr)
|
||
|
{
|
||
|
db_log1("AwCreateGraphic() failed whilst interpreting the header data or palette");
|
||
|
goto EXIT_WITH_ERROR;
|
||
|
}
|
||
|
|
||
|
if (_parmsR.originalWidthP) *_parmsR.originalWidthP = m_nWidth;
|
||
|
if (_parmsR.originalHeightP) *_parmsR.originalHeightP = m_nHeight;
|
||
|
|
||
|
if (_parmsR.rectA)
|
||
|
{
|
||
|
nLoadInfos = 0;
|
||
|
arrLoadInfo = _parmsR.numRects ? new LoadInfo[_parmsR.numRects] : NULL;
|
||
|
for (unsigned i=0; i<_parmsR.numRects; ++i)
|
||
|
{
|
||
|
_parmsR.rectA[i].width = 0;
|
||
|
_parmsR.rectA[i].height = 0;
|
||
|
if
|
||
|
(
|
||
|
_parmsR.rectA[i].top < m_nHeight
|
||
|
&& _parmsR.rectA[i].left < m_nWidth
|
||
|
&& (!_parmsR.prevTexB || (_parmsR.loadTextureB ? (_parmsR.rectA[i].pTexture != NULL) : (_parmsR.rectA[i].pSurface != NULL)))
|
||
|
&& _parmsR.rectA[i].right > _parmsR.rectA[i].left
|
||
|
&& _parmsR.rectA[i].bottom > _parmsR.rectA[i].top
|
||
|
)
|
||
|
{
|
||
|
// rectangle covers at least some of the image and non-null previous texture
|
||
|
arrLoadInfo[nLoadInfos].widthP = &_parmsR.rectA[i].width;
|
||
|
arrLoadInfo[nLoadInfos].heightP = &_parmsR.rectA[i].height;
|
||
|
if (_parmsR.prevTexB)
|
||
|
{
|
||
|
if (_parmsR.loadTextureB)
|
||
|
arrLoadInfo[nLoadInfos].prevTexP = _parmsR.rectA[i].pTexture;
|
||
|
else
|
||
|
arrLoadInfo[nLoadInfos].prevTexP = _parmsR.rectA[i].pSurface;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
arrLoadInfo[nLoadInfos].prevTexP = static_cast<D3DTexture *>(NULL);
|
||
|
if (_parmsR.loadTextureB)
|
||
|
_parmsR.rectA[i].pTexture = NULL;
|
||
|
else
|
||
|
_parmsR.rectA[i].pSurface = NULL;
|
||
|
}
|
||
|
|
||
|
arrLoadInfo[nLoadInfos].rectP = &_parmsR.rectA[i];
|
||
|
arrLoadInfo[nLoadInfos].top = _parmsR.rectA[i].top;
|
||
|
arrLoadInfo[nLoadInfos].left = _parmsR.rectA[i].left;
|
||
|
arrLoadInfo[nLoadInfos].bottom = _parmsR.rectA[i].bottom;
|
||
|
arrLoadInfo[nLoadInfos].right = _parmsR.rectA[i].right;
|
||
|
|
||
|
if (arrLoadInfo[nLoadInfos].right > m_nWidth) arrLoadInfo[nLoadInfos].right = m_nWidth;
|
||
|
if (arrLoadInfo[nLoadInfos].bottom > m_nHeight) arrLoadInfo[nLoadInfos].bottom = m_nHeight;
|
||
|
|
||
|
arrLoadInfo[nLoadInfos].width = arrLoadInfo[nLoadInfos].right - arrLoadInfo[nLoadInfos].left;
|
||
|
arrLoadInfo[nLoadInfos].height = arrLoadInfo[nLoadInfos].bottom - arrLoadInfo[nLoadInfos].top;
|
||
|
|
||
|
++nLoadInfos;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!_parmsR.prevTexB)
|
||
|
_parmsR.rectA[i].pTexture = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nLoadInfos = 1;
|
||
|
arrLoadInfo = new LoadInfo[1];
|
||
|
arrLoadInfo[0].widthP = _parmsR.widthP;
|
||
|
arrLoadInfo[0].heightP = _parmsR.heightP;
|
||
|
arrLoadInfo[0].prevTexP = _parmsR.prevTexP;
|
||
|
arrLoadInfo[0].rectP = NULL;
|
||
|
arrLoadInfo[0].top = 0;
|
||
|
arrLoadInfo[0].left = 0;
|
||
|
arrLoadInfo[0].bottom = m_nHeight;
|
||
|
arrLoadInfo[0].right = m_nWidth;
|
||
|
arrLoadInfo[0].width = m_nWidth;
|
||
|
arrLoadInfo[0].height = m_nHeight;
|
||
|
}
|
||
|
|
||
|
bool bSkipAll = true;
|
||
|
|
||
|
// loop creating surfaces
|
||
|
{for (unsigned i=0; i<nLoadInfos; ++i)
|
||
|
{
|
||
|
LoadInfo * pLoadInfo = &arrLoadInfo[i];
|
||
|
|
||
|
db_logf4(("\trectangle from image (%u,%u)-(%u,%u)",pLoadInfo->left,pLoadInfo->top,pLoadInfo->right,pLoadInfo->bottom));
|
||
|
db_logf5(("\treference count on input surface %u",_parmsR.loadTextureB ? GetRefCount(pLoadInfo->prevTexP.textureP) : GetRefCount(pLoadInfo->prevTexP.surfaceP)));
|
||
|
|
||
|
// determine what the width and height of the surface will be
|
||
|
|
||
|
if (_parmsR.loadTextureB || fMyFlags & AW_TLF_TEXTURE)
|
||
|
{
|
||
|
awTlLastErr =
|
||
|
AwGetTextureSize
|
||
|
(
|
||
|
&pLoadInfo->surface_width,
|
||
|
&pLoadInfo->surface_height,
|
||
|
fMyFlags & AW_TLF_MINSIZE && pLoadInfo->rectP ? pLoadInfo->rectP->right - pLoadInfo->rectP->left : pLoadInfo->width,
|
||
|
fMyFlags & AW_TLF_MINSIZE && pLoadInfo->rectP ? pLoadInfo->rectP->bottom - pLoadInfo->rectP->top : pLoadInfo->height
|
||
|
);
|
||
|
if (awTlLastErr != AW_TLE_OK)
|
||
|
goto EXIT_WITH_ERROR;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pLoadInfo->surface_width = fMyFlags & AW_TLF_MINSIZE && pLoadInfo->rectP ? pLoadInfo->rectP->right - pLoadInfo->rectP->left : pLoadInfo->width;
|
||
|
pLoadInfo->surface_height = fMyFlags & AW_TLF_MINSIZE && pLoadInfo->rectP ? pLoadInfo->rectP->bottom - pLoadInfo->rectP->top : pLoadInfo->height;
|
||
|
#if 1 // not sure if this is required...
|
||
|
pLoadInfo->surface_width += 3;
|
||
|
pLoadInfo->surface_width &= ~3;
|
||
|
pLoadInfo->surface_height += 3;
|
||
|
pLoadInfo->surface_height &= ~3;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if (pLoadInfo->widthP) *pLoadInfo->widthP = pLoadInfo->surface_width;
|
||
|
if (pLoadInfo->heightP) *pLoadInfo->heightP = pLoadInfo->surface_height;
|
||
|
|
||
|
// Create DD Surface
|
||
|
|
||
|
DD_SURFACE_DESC ddsd;
|
||
|
INITDXSTRUCT(ddsd);
|
||
|
ddsd.ddpfPixelFormat = pixelFormat.ddpf;
|
||
|
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
|
||
|
if (_parmsR.loadTextureB || fMyFlags & AW_TLF_TEXTURE)
|
||
|
pLoadInfo->dwCapsCaps = DDSCAPS_TEXTURE | (fMyFlags & (AW_TLF_COMPRESS|AW_TLF_TEXTURE) ? DDSCAPS_SYSTEMMEMORY : driverDesc.memFlag);
|
||
|
else
|
||
|
pLoadInfo->dwCapsCaps = DDSCAPS_OFFSCREENPLAIN | (fMyFlags & AW_TLF_VIDMEM ? DDSCAPS_VIDEOMEMORY : DDSCAPS_SYSTEMMEMORY);
|
||
|
ddsd.ddsCaps.dwCaps = pLoadInfo->dwCapsCaps;
|
||
|
ddsd.dwHeight = pLoadInfo->surface_height;
|
||
|
ddsd.dwWidth = pLoadInfo->surface_width;
|
||
|
|
||
|
#if MIPMAPTEST
|
||
|
/*
|
||
|
D3DPTEXTURECAPS_POW2
|
||
|
All nonmipmapped textures must have widths and heights specified as powers of two if this flag is set.
|
||
|
(Note that all mipmapped textures must always have dimensions that are powers of two.)
|
||
|
*/
|
||
|
if (128==pLoadInfo->surface_width && 128==pLoadInfo->surface_height)
|
||
|
{
|
||
|
ddsd.ddsCaps.dwCaps |= DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
|
||
|
ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
|
||
|
ddsd.dwMipMapCount = 3;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (pLoadInfo->prevTexP.voidP && (!_parmsR.loadTextureB || !(fMyFlags & AW_TLF_COMPRESS)))
|
||
|
{
|
||
|
if (_parmsR.loadTextureB)
|
||
|
awTlLastDxErr = pLoadInfo->prevTexP.textureP->QueryInterface(GUID_DD_SURFACE,(LPVOID *)&pLoadInfo->surfaceP);
|
||
|
else
|
||
|
awTlLastDxErr = pLoadInfo->prevTexP.surfaceP->QueryInterface(GUID_DD_SURFACE,(LPVOID *)&pLoadInfo->surfaceP);
|
||
|
HANDLE_DXERROR("getting direct draw surface interface")
|
||
|
#if DB_LEVEL >= 5
|
||
|
if (_parmsR.loadTextureB)
|
||
|
db_logf5(("\t\tnow prev tex ref %u new surface i/f ref %u",GetRefCount(pLoadInfo->prevTexP.textureP),GetRefCount(pLoadInfo->surfaceP)));
|
||
|
else
|
||
|
db_logf5(("\t\tnow prev surf ref %u new surface i/f ref %u",GetRefCount(pLoadInfo->prevTexP.surfaceP),GetRefCount(pLoadInfo->surfaceP)));
|
||
|
#endif
|
||
|
|
||
|
// check for lost surfaces
|
||
|
if (fMyFlags & AW_TLF_CHECKLOST)
|
||
|
{
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->IsLost();
|
||
|
|
||
|
if (DDERR_SURFACELOST == awTlLastDxErr)
|
||
|
{
|
||
|
db_log4("\tRestoring Lost Surface");
|
||
|
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->Restore();
|
||
|
}
|
||
|
else if (DD_OK == awTlLastDxErr && (fMyFlags & AW_TLF_SKIPNOTLOST))
|
||
|
{
|
||
|
db_log4("\tSkipping Surface which was not Lost");
|
||
|
|
||
|
pLoadInfo->skipB = true;
|
||
|
}
|
||
|
|
||
|
HANDLE_DXERROR("testing for lost surface and restoring if necessary");
|
||
|
}
|
||
|
|
||
|
if (!pLoadInfo->skipB)
|
||
|
{
|
||
|
// check that the surface desc is OK
|
||
|
// note that SetSurfaceDesc is *only* supported for changing the surface memory pointer
|
||
|
DD_SURFACE_DESC old_ddsd;
|
||
|
INITDXSTRUCT(old_ddsd);
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->GetSurfaceDesc(&old_ddsd);
|
||
|
HANDLE_DXERROR("getting previous surface desc")
|
||
|
// check width, height, RGBBitCount and memory type
|
||
|
if (old_ddsd.dwFlags & DDSD_ALL || (old_ddsd.dwFlags & (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT)) == (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT))
|
||
|
{
|
||
|
if (old_ddsd.dwHeight == pLoadInfo->surface_height && old_ddsd.dwWidth == pLoadInfo->surface_width && (old_ddsd.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY|DDSCAPS_TEXTURE)) == pLoadInfo->dwCapsCaps)
|
||
|
{
|
||
|
unsigned bpp = 0;
|
||
|
if (old_ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
|
||
|
bpp = 8;
|
||
|
else if (old_ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
|
||
|
bpp = 4;
|
||
|
else if (old_ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED2)
|
||
|
bpp = 2;
|
||
|
else if (old_ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED1)
|
||
|
bpp = 1;
|
||
|
else if (old_ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB)
|
||
|
bpp = old_ddsd.ddpfPixelFormat.dwRGBBitCount;
|
||
|
if (pixelFormat.bitsPerPixel != bpp)
|
||
|
awTlLastErr = AW_TLE_CANTRELOAD;
|
||
|
}
|
||
|
else
|
||
|
awTlLastErr = AW_TLE_CANTRELOAD;
|
||
|
}
|
||
|
else
|
||
|
awTlLastErr = AW_TLE_CANTRELOAD;
|
||
|
if (AW_TLE_OK != awTlLastErr)
|
||
|
{
|
||
|
db_log1("AwCreateGraphic() failed because existing surface is incompatible");
|
||
|
goto EXIT_WITH_ERROR;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pLoadInfo->surfaceP->Release();
|
||
|
pLoadInfo->surfaceP = NULL;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pLoadInfo->prevTexP.voidP && (fMyFlags & AW_TLF_CHECKLOST))
|
||
|
{
|
||
|
db_assert1(_parmsR.loadTextureB);
|
||
|
|
||
|
awTlLastDxErr = pLoadInfo->prevTexP.textureP->QueryInterface(GUID_DD_SURFACE,(LPVOID *)&pLoadInfo->surfaceP);
|
||
|
HANDLE_DXERROR("getting direct draw surface interface")
|
||
|
|
||
|
db_logf5(("\t\tnow prev tex ref %u new surface i/f ref %u",GetRefCount(pLoadInfo->prevTexP.textureP),GetRefCount(pLoadInfo->surfaceP)));
|
||
|
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->IsLost();
|
||
|
|
||
|
if (DDERR_SURFACELOST == awTlLastDxErr)
|
||
|
{
|
||
|
db_log4("\tRestoring Lost Surface");
|
||
|
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->Restore();
|
||
|
}
|
||
|
else if (DD_OK == awTlLastDxErr && (fMyFlags & AW_TLF_SKIPNOTLOST))
|
||
|
{
|
||
|
db_log4("\tSkipping Surface which was not Lost");
|
||
|
|
||
|
pLoadInfo->skipB = true;
|
||
|
}
|
||
|
|
||
|
HANDLE_DXERROR("testing for lost surface and restoring if necessary");
|
||
|
|
||
|
pLoadInfo->surfaceP->Release();
|
||
|
pLoadInfo->surfaceP = NULL;
|
||
|
}
|
||
|
|
||
|
if (!pLoadInfo->skipB)
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
awTlLastDxErr = driverDesc.ddP->CreateSurface(&ddsd,&pLoadInfo->surfaceP,NULL);
|
||
|
}
|
||
|
while
|
||
|
(
|
||
|
DDERR_OUTOFVIDEOMEMORY == awTlLastDxErr
|
||
|
&& _parmsR.callbackF
|
||
|
&& _parmsR.callbackF(_parmsR.callbackParam)
|
||
|
);
|
||
|
|
||
|
HANDLE_DXERROR("creating direct draw surface")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pLoadInfo->skipB)
|
||
|
{
|
||
|
db_assert1(pLoadInfo->prevTexP.voidP);
|
||
|
|
||
|
// skipping so result is same as input
|
||
|
pLoadInfo->resultP = pLoadInfo->prevTexP;
|
||
|
|
||
|
if (_parmsR.loadTextureB)
|
||
|
pLoadInfo->prevTexP.textureP->AddRef();
|
||
|
else
|
||
|
pLoadInfo->prevTexP.surfaceP->AddRef();
|
||
|
}
|
||
|
|
||
|
#if MIPMAPTEST
|
||
|
if (128==surface_width && 128==surface_height)
|
||
|
{
|
||
|
// test if we can get attached surfaces...
|
||
|
DDSCAPS ddscaps;
|
||
|
ZEROFILL(ddscaps);
|
||
|
ddscaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
|
||
|
DDSurface * mip2P;
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->GetAttachedSurface(&ddscaps,&mip2P);
|
||
|
HANDLE_DXERROR("getting first mipmap")
|
||
|
DDSurface * mip3P;
|
||
|
awTlLastDxErr = mip2P->GetAttachedSurface(&ddscaps,&mip3P);
|
||
|
HANDLE_DXERROR("getting second mipmap")
|
||
|
db_logf5(("\tabout to release 2nd mip with ref %u",GetRefCount(mip2P)));
|
||
|
db_code1(refcnt =)
|
||
|
mip2P->Release();
|
||
|
db_onlyassert1(1==refcnt);
|
||
|
db_logf5(("\tabout to release 3nd mip with ref %u",GetRefCount(mip3P)));
|
||
|
db_code1(refcnt =)
|
||
|
mip3P->Release();
|
||
|
db_onlyassert1(1==refcnt);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
bSkipAll = bSkipAll && pLoadInfo->skipB;
|
||
|
}}
|
||
|
|
||
|
if (!bSkipAll)
|
||
|
{
|
||
|
Colour * paletteP = m_nPaletteSize ? GetPalette() : NULL;
|
||
|
|
||
|
unsigned y = 0;
|
||
|
bool reversed_rowsB = AreRowsReversed();
|
||
|
if (reversed_rowsB)
|
||
|
{
|
||
|
y = m_nHeight-1;
|
||
|
}
|
||
|
|
||
|
for (unsigned rowcount = m_nHeight; rowcount; --rowcount)
|
||
|
{
|
||
|
PtrUnion src_rowP = GetRowPtr(y);
|
||
|
db_assert1(src_rowP.voidP);
|
||
|
|
||
|
// allow loading of the next row from the file
|
||
|
LoadNextRow(src_rowP);
|
||
|
|
||
|
// loop for copying data to surfaces
|
||
|
for (unsigned i=0; i<nLoadInfos; ++i)
|
||
|
{
|
||
|
LoadInfo * pLoadInfo = &arrLoadInfo[i];
|
||
|
|
||
|
if (!pLoadInfo->skipB)
|
||
|
{
|
||
|
// are we in the vertical range of this surface?
|
||
|
if (y>=pLoadInfo->top && y<pLoadInfo->bottom)
|
||
|
{
|
||
|
if (!pLoadInfo->surface_lockedB)
|
||
|
{
|
||
|
// lock the surfaces
|
||
|
DD_SURFACE_DESC ddsd;
|
||
|
INITDXSTRUCT(ddsd);
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->Lock(NULL,&ddsd,DDLOCK_WRITEONLY|DDLOCK_NOSYSLOCK,NULL);
|
||
|
HANDLE_DXERROR("locking direct draw surface")
|
||
|
pLoadInfo->surface_lockedB = true;
|
||
|
pLoadInfo->surface_dataP.voidP = ddsd.lpSurface;
|
||
|
pLoadInfo->surface_dataP.byteP += ddsd.lPitch * (y-pLoadInfo->top);
|
||
|
pLoadInfo->surface_pitch = ddsd.lPitch;
|
||
|
}
|
||
|
|
||
|
// convert and copy the section of the row to the direct draw surface
|
||
|
ConvertRow(pLoadInfo->surface_dataP,pLoadInfo->surface_width,src_rowP,pLoadInfo->left,pLoadInfo->width,paletteP db_code1(DB_COMMA m_nPaletteSize));
|
||
|
|
||
|
// do the bottom row twice if the dd surface is bigger
|
||
|
if (pLoadInfo->bottom-1 == y && pLoadInfo->surface_height > pLoadInfo->height)
|
||
|
{
|
||
|
PtrUnion next_surface_rowP = pLoadInfo->surface_dataP;
|
||
|
next_surface_rowP.byteP += pLoadInfo->surface_pitch;
|
||
|
ConvertRow(next_surface_rowP,pLoadInfo->surface_width,src_rowP,pLoadInfo->left,pLoadInfo->width,paletteP db_code1(DB_COMMA m_nPaletteSize));
|
||
|
}
|
||
|
|
||
|
// next ddsurface row
|
||
|
if (reversed_rowsB)
|
||
|
pLoadInfo->surface_dataP.byteP -= pLoadInfo->surface_pitch;
|
||
|
else
|
||
|
pLoadInfo->surface_dataP.byteP += pLoadInfo->surface_pitch;
|
||
|
}
|
||
|
else if (pLoadInfo->surface_lockedB)
|
||
|
{
|
||
|
// unlock the surface
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->Unlock(NULL);
|
||
|
HANDLE_DXERROR("unlocking direct draw surface")
|
||
|
pLoadInfo->surface_lockedB = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// next row
|
||
|
if (reversed_rowsB)
|
||
|
--y;
|
||
|
else
|
||
|
++y;
|
||
|
|
||
|
if (AW_TLE_OK != awTlLastErr)
|
||
|
{
|
||
|
db_log1("AwCreateGraphic() failed whilst copying data to direct draw surface");
|
||
|
goto EXIT_WITH_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// create a palette for the surfaces if there is one
|
||
|
DWORD palcreateflags = 0;
|
||
|
PALETTEENTRY colour_tableA[256];
|
||
|
if (pixelFormat.palettizedB)
|
||
|
{
|
||
|
if (!_parmsR.loadTextureB && !(fMyFlags & AW_TLF_TEXTURE))
|
||
|
{
|
||
|
db_log3("AwCreateGraphic(): WARNING: setting a palette on a DD surface may have no effect");
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
if (m_bTranspMask)
|
||
|
{
|
||
|
colour_tableA[0].peRed = 0;
|
||
|
colour_tableA[0].peGreen = 0;
|
||
|
colour_tableA[0].peBlue = 0;
|
||
|
colour_tableA[0].peFlags = 0;
|
||
|
for (unsigned i=1; i<m_nPaletteSize; ++i)
|
||
|
{
|
||
|
colour_tableA[i].peRed = paletteP[i].r;
|
||
|
colour_tableA[i].peGreen = paletteP[i].g;
|
||
|
colour_tableA[i].peBlue = paletteP[i].b;
|
||
|
if (!(paletteP[i].r + paletteP[i].g + paletteP[i].b))
|
||
|
colour_tableA[i].peRed = 1;
|
||
|
colour_tableA[i].peFlags = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
for (unsigned i=0; i<m_nPaletteSize; ++i)
|
||
|
{
|
||
|
colour_tableA[i].peRed = paletteP[i].r;
|
||
|
colour_tableA[i].peGreen = paletteP[i].g;
|
||
|
colour_tableA[i].peBlue = paletteP[i].b;
|
||
|
colour_tableA[i].peFlags = 0;
|
||
|
}
|
||
|
}
|
||
|
for (unsigned i=m_nPaletteSize; i<256; ++i)
|
||
|
colour_tableA[i].peFlags = 0;
|
||
|
switch (pixelFormat.bitsPerPixel)
|
||
|
{
|
||
|
default:
|
||
|
CANT_HAPPEN
|
||
|
case 8:
|
||
|
palcreateflags = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
|
||
|
break;
|
||
|
case 4:
|
||
|
palcreateflags = DDPCAPS_4BIT;
|
||
|
break;
|
||
|
case 2:
|
||
|
palcreateflags = DDPCAPS_2BIT;
|
||
|
break;
|
||
|
case 1:
|
||
|
palcreateflags = DDPCAPS_1BIT;
|
||
|
break;
|
||
|
}
|
||
|
awTlLastDxErr = driverDesc.ddP->CreatePalette(palcreateflags,colour_tableA,&dd_paletteP,NULL);
|
||
|
HANDLE_DXERROR("creating palette for direct draw surface")
|
||
|
}
|
||
|
|
||
|
{for (unsigned i=0; i<nLoadInfos; ++i)
|
||
|
{
|
||
|
LoadInfo * pLoadInfo = &arrLoadInfo[i];
|
||
|
|
||
|
if (!pLoadInfo->skipB)
|
||
|
{
|
||
|
// unlock the surface
|
||
|
if (pLoadInfo->surface_lockedB)
|
||
|
{
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->Unlock(NULL);
|
||
|
HANDLE_DXERROR("unlocking direct draw surface")
|
||
|
pLoadInfo->surface_lockedB = false;
|
||
|
}
|
||
|
|
||
|
if (pixelFormat.palettizedB)
|
||
|
{
|
||
|
// set the palette on the surface
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->SetPalette(dd_paletteP);
|
||
|
HANDLE_DXERROR("setting palette on direct draw surface")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}}
|
||
|
|
||
|
if (pixelFormat.palettizedB)
|
||
|
{
|
||
|
db_logf5(("\tabout to release palette with ref %u",GetRefCount(dd_paletteP)));
|
||
|
dd_paletteP->Release();
|
||
|
dd_paletteP = NULL;
|
||
|
}
|
||
|
|
||
|
DWORD dwColourKey;
|
||
|
DDCOLORKEY invis;
|
||
|
// get colour for chroma keying if required
|
||
|
if (m_bTranspMask && (!pixelFormat.alphaB || fMyFlags & AW_TLF_CHROMAKEY))
|
||
|
{
|
||
|
dwColourKey = GetTransparentColour();
|
||
|
invis.dwColorSpaceLowValue = dwColourKey;
|
||
|
invis.dwColorSpaceHighValue = dwColourKey;
|
||
|
}
|
||
|
|
||
|
{for (unsigned i=0; i<nLoadInfos; ++i)
|
||
|
{
|
||
|
LoadInfo * pLoadInfo = &arrLoadInfo[i];
|
||
|
|
||
|
if (!pLoadInfo->skipB)
|
||
|
{
|
||
|
// do the copying crap and Texture::Load() stuff - see CopyD3DTexture in d3_func.cpp
|
||
|
|
||
|
if (_parmsR.loadTextureB)
|
||
|
{
|
||
|
// get a texture pointer
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->QueryInterface(GUID_D3D_TEXTURE,(LPVOID *)&pLoadInfo->textureP);
|
||
|
HANDLE_DXERROR("getting texture interface on direct draw surface")
|
||
|
db_logf5(("\t\tnow surface ref %u texture ref %u",GetRefCount(pLoadInfo->surfaceP),GetRefCount(pLoadInfo->textureP)));
|
||
|
|
||
|
if (fMyFlags & AW_TLF_COMPRESS) // deal with Texture::Load and ALLOCONLOAD flag
|
||
|
{
|
||
|
if (pLoadInfo->prevTexP.voidP)
|
||
|
{
|
||
|
// load into the existing texture
|
||
|
awTlLastDxErr = pLoadInfo->prevTexP.textureP->QueryInterface(GUID_DD_SURFACE,(LPVOID *)&pLoadInfo->dst_surfaceP);
|
||
|
HANDLE_DXERROR("getting direct draw surface interface")
|
||
|
db_logf5(("\t\tnow prev texture ref %u dst surface ref %u",GetRefCount(pLoadInfo->prevTexP.textureP),GetRefCount(pLoadInfo->dst_surfaceP)));
|
||
|
// check that the surface desc is OK
|
||
|
// note that SetSurfaceDesc is *only* supported for changing the surface memory pointer
|
||
|
DD_SURFACE_DESC old_ddsd;
|
||
|
INITDXSTRUCT(old_ddsd);
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->GetSurfaceDesc(&old_ddsd);
|
||
|
HANDLE_DXERROR("getting previous surface desc")
|
||
|
// check width, height, RGBBitCount and memory type
|
||
|
if (old_ddsd.dwFlags & DDSD_ALL || (old_ddsd.dwFlags & (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT)) == (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT))
|
||
|
{
|
||
|
if (old_ddsd.dwHeight == pLoadInfo->surface_height && old_ddsd.dwWidth == pLoadInfo->surface_width && (old_ddsd.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY|DDSCAPS_TEXTURE)) == pLoadInfo->dwCapsCaps)
|
||
|
{
|
||
|
unsigned bpp = 0;
|
||
|
if (old_ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
|
||
|
bpp = 8;
|
||
|
else if (old_ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
|
||
|
bpp = 4;
|
||
|
else if (old_ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED2)
|
||
|
bpp = 2;
|
||
|
else if (old_ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED1)
|
||
|
bpp = 1;
|
||
|
else if (old_ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB)
|
||
|
bpp = old_ddsd.ddpfPixelFormat.dwRGBBitCount;
|
||
|
if (pixelFormat.bitsPerPixel != bpp)
|
||
|
awTlLastErr = AW_TLE_CANTRELOAD;
|
||
|
}
|
||
|
else
|
||
|
awTlLastErr = AW_TLE_CANTRELOAD;
|
||
|
}
|
||
|
else
|
||
|
awTlLastErr = AW_TLE_CANTRELOAD;
|
||
|
if (AW_TLE_OK != awTlLastErr)
|
||
|
{
|
||
|
db_log1("AwCreateGraphic() failed because existing surface is incompatible");
|
||
|
goto EXIT_WITH_ERROR;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DD_SURFACE_DESC ddsd;
|
||
|
|
||
|
INITDXSTRUCT(ddsd);
|
||
|
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->GetSurfaceDesc(&ddsd);
|
||
|
HANDLE_DXERROR("getting direct draw surface desc")
|
||
|
|
||
|
ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY;
|
||
|
ddsd.ddsCaps.dwCaps |= DDSCAPS_ALLOCONLOAD | driverDesc.memFlag;
|
||
|
do
|
||
|
{
|
||
|
awTlLastDxErr = driverDesc.ddP->CreateSurface(&ddsd,&pLoadInfo->dst_surfaceP,NULL);
|
||
|
}
|
||
|
while
|
||
|
(
|
||
|
DDERR_OUTOFVIDEOMEMORY == awTlLastDxErr
|
||
|
&& _parmsR.callbackF
|
||
|
&& _parmsR.callbackF(_parmsR.callbackParam)
|
||
|
);
|
||
|
HANDLE_DXERROR("creating destination direct draw surface")
|
||
|
}
|
||
|
|
||
|
// create a zero palette if required -> Texture::Load() will copy in correct palette
|
||
|
if (pixelFormat.palettizedB)
|
||
|
{
|
||
|
memset(colour_tableA,0,sizeof colour_tableA);
|
||
|
|
||
|
awTlLastDxErr = driverDesc.ddP->CreatePalette(palcreateflags,colour_tableA,&dd_paletteP,NULL);
|
||
|
HANDLE_DXERROR("creating palette for destination direct draw surface")
|
||
|
awTlLastDxErr = pLoadInfo->dst_surfaceP->SetPalette(dd_paletteP);
|
||
|
HANDLE_DXERROR("setting palette on destination direct draw surface")
|
||
|
db_logf5(("\tabout to release dest palette with ref %u",GetRefCount(dd_paletteP)));
|
||
|
dd_paletteP->Release();
|
||
|
dd_paletteP = NULL;
|
||
|
}
|
||
|
|
||
|
// get a texture pointer on the destination
|
||
|
awTlLastDxErr = pLoadInfo->dst_surfaceP->QueryInterface(GUID_D3D_TEXTURE,(LPVOID *)&pLoadInfo->dst_textureP);
|
||
|
HANDLE_DXERROR("getting texture interface on destination direct draw surface")
|
||
|
db_logf5(("\t\tnow dst surface ref %u dst texture ref %u",GetRefCount(pLoadInfo->dst_surfaceP),GetRefCount(pLoadInfo->dst_textureP)));
|
||
|
|
||
|
do
|
||
|
{
|
||
|
awTlLastDxErr = pLoadInfo->dst_textureP->Load(pLoadInfo->textureP);
|
||
|
}
|
||
|
while
|
||
|
(
|
||
|
DDERR_OUTOFVIDEOMEMORY == awTlLastDxErr
|
||
|
&& _parmsR.callbackF
|
||
|
&& _parmsR.callbackF(_parmsR.callbackParam)
|
||
|
);
|
||
|
HANDLE_DXERROR("loading texture into destination")
|
||
|
|
||
|
// release src texture and surface, and set pointers to point to dst texture and surface
|
||
|
db_logf5(("\tabout to release internal surface with ref %u",GetRefCount(pLoadInfo->surfaceP)));
|
||
|
db_code1(refcnt =)
|
||
|
pLoadInfo->surfaceP->Release();
|
||
|
db_onlyassert1(1==refcnt);
|
||
|
pLoadInfo->surfaceP = pLoadInfo->dst_surfaceP;
|
||
|
pLoadInfo->dst_surfaceP = NULL;
|
||
|
|
||
|
db_logf5(("\tabout to release internal texture i/f with ref %u",GetRefCount(pLoadInfo->textureP)));
|
||
|
db_code1(refcnt =)
|
||
|
pLoadInfo->textureP->Release();
|
||
|
db_onlyassert1(!refcnt);
|
||
|
pLoadInfo->textureP = pLoadInfo->dst_textureP;
|
||
|
pLoadInfo->dst_textureP = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// set chroma keying if required
|
||
|
if (m_bTranspMask && (!pixelFormat.alphaB || fMyFlags & AW_TLF_CHROMAKEY))
|
||
|
{
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->SetColorKey(DDCKEY_SRCBLT,&invis);
|
||
|
HANDLE_DXERROR("setting the colour key")
|
||
|
}
|
||
|
|
||
|
if (_parmsR.loadTextureB)
|
||
|
{
|
||
|
// release the direct draw interface:
|
||
|
// since the textureP was obtained with a call
|
||
|
// to QueryInterface on the surface (increasing
|
||
|
// its referenc count), this wont actually release
|
||
|
// the surface
|
||
|
|
||
|
db_logf5(("\tabout to release surface i/f with ref %u",GetRefCount(pLoadInfo->surfaceP)));
|
||
|
db_code1(refcnt =)
|
||
|
pLoadInfo->surfaceP->Release();
|
||
|
pLoadInfo->surfaceP = NULL;
|
||
|
// if loading into a previous texture, refcnt may be two or more, our ref and the ref passed to us
|
||
|
db_onlyassert1(1==refcnt|| pLoadInfo->prevTexP.voidP);
|
||
|
|
||
|
pLoadInfo->resultP = pLoadInfo->textureP;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
db_assert1(pLoadInfo->surfaceP);
|
||
|
|
||
|
DDSurface * pSurfaceReturn = NULL;
|
||
|
|
||
|
awTlLastDxErr = pLoadInfo->surfaceP->QueryInterface(GUID_DD_SURFACE, (LPVOID *)&pSurfaceReturn);
|
||
|
HANDLE_DXERROR("getting the required DDSurface interface")
|
||
|
db_logf5(("\t\tnow surface ref %u return surface ref %u",GetRefCount(pLoadInfo->surfaceP),GetRefCount(pSurfaceReturn)));
|
||
|
|
||
|
pLoadInfo->resultP = pSurfaceReturn;
|
||
|
}
|
||
|
}
|
||
|
}}
|
||
|
|
||
|
// release the IDirectDrawSurface interfaces if returning DDSurface interfaces
|
||
|
if (!_parmsR.loadTextureB)
|
||
|
{
|
||
|
for (unsigned i=0; i<nLoadInfos; ++i)
|
||
|
{
|
||
|
if (!arrLoadInfo[i].skipB)
|
||
|
{
|
||
|
db_assert1(arrLoadInfo[i].surfaceP);
|
||
|
db_logf5(("\tabout to release internal surface i/f with ref %u",GetRefCount(arrLoadInfo[i].surfaceP)));
|
||
|
arrLoadInfo[i].surfaceP->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// OK
|
||
|
db_log4("AwCreateGraphic() OK");
|
||
|
|
||
|
SurfUnion pRet = static_cast<D3DTexture *>(NULL);
|
||
|
|
||
|
if (!_parmsR.rectA)
|
||
|
{
|
||
|
// if loading the entire graphic as one surface/texture, return pointer to that
|
||
|
pRet = arrLoadInfo[0].resultP;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// return NULL, but fill in the pTexture or pSurface members of the AwCreateGraphicRegion
|
||
|
for (unsigned i=0; i<nLoadInfos; ++i)
|
||
|
{
|
||
|
LoadInfo * pLoadInfo = &arrLoadInfo[i];
|
||
|
|
||
|
db_assert1(pLoadInfo->rectP);
|
||
|
|
||
|
if (_parmsR.loadTextureB)
|
||
|
{
|
||
|
if (pLoadInfo->prevTexP.voidP)
|
||
|
{
|
||
|
db_assert1(pLoadInfo->prevTexP.textureP == pLoadInfo->rectP->pTexture);
|
||
|
db_assert1(pLoadInfo->resultP.textureP == pLoadInfo->rectP->pTexture);
|
||
|
db_logf5(("\tabout to release duplicate texture i/f with ref %u",GetRefCount(pLoadInfo->resultP.textureP)));
|
||
|
pLoadInfo->resultP.textureP->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pLoadInfo->rectP->pTexture = pLoadInfo->resultP.textureP;
|
||
|
}
|
||
|
db_logf5(("\tresultant texture for region with ref count %u",GetRefCount(pLoadInfo->rectP->pTexture)));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pLoadInfo->prevTexP.voidP)
|
||
|
{
|
||
|
db_assert1(pLoadInfo->prevTexP.surfaceP == pLoadInfo->rectP->pSurface);
|
||
|
db_assert1(pLoadInfo->resultP.surfaceP == pLoadInfo->rectP->pSurface);
|
||
|
db_logf5(("\tabout to release duplicate surface i/f with ref %u",GetRefCount(pLoadInfo->resultP.surfaceP)));
|
||
|
pLoadInfo->resultP.surfaceP->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pLoadInfo->rectP->pSurface = pLoadInfo->resultP.surfaceP;
|
||
|
}
|
||
|
db_logf5(("\tresultant texture for surface with ref count %u",GetRefCount(pLoadInfo->rectP->pSurface)));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
delete[] arrLoadInfo;
|
||
|
|
||
|
#if DB_LEVEL >= 5
|
||
|
if (_parmsR.loadTextureB)
|
||
|
db_logf5(("AwCreateGraphic(): returning texture with ref cnt %u",GetRefCount(pRet.textureP)));
|
||
|
else
|
||
|
db_logf5(("AwCreateGraphic(): returning surface with ref cnt %u",GetRefCount(pRet.surfaceP)));
|
||
|
#endif
|
||
|
|
||
|
return pRet;
|
||
|
}
|
||
|
|
||
|
EXIT_WITH_ERROR:
|
||
|
{
|
||
|
|
||
|
db_logf2(("AwCreateGraphic(): ERROR: %s",AwTlErrorToString()));
|
||
|
|
||
|
if (arrLoadInfo)
|
||
|
{
|
||
|
for (unsigned i=0; i<nLoadInfos; ++i)
|
||
|
{
|
||
|
LoadInfo * pLoadInfo = &arrLoadInfo[i];
|
||
|
|
||
|
db_logf5(("\tref counts: dst tex %u dst surf %u int tex %u int surf %u",
|
||
|
GetRefCount(pLoadInfo->dst_textureP),
|
||
|
GetRefCount(pLoadInfo->dst_surfaceP),
|
||
|
GetRefCount(pLoadInfo->textureP),
|
||
|
GetRefCount(pLoadInfo->surfaceP)));
|
||
|
|
||
|
if (pLoadInfo->dst_textureP)
|
||
|
{
|
||
|
pLoadInfo->dst_textureP->Release();
|
||
|
}
|
||
|
if (pLoadInfo->textureP)
|
||
|
{
|
||
|
pLoadInfo->textureP->Release();
|
||
|
}
|
||
|
if (pLoadInfo->dst_surfaceP)
|
||
|
{
|
||
|
pLoadInfo->dst_surfaceP->Release();
|
||
|
}
|
||
|
if (pLoadInfo->surfaceP)
|
||
|
{
|
||
|
if (pLoadInfo->surface_lockedB)
|
||
|
pLoadInfo->surfaceP->Unlock(NULL);
|
||
|
db_code1(refcnt =)
|
||
|
pLoadInfo->surfaceP->Release();
|
||
|
db_onlyassert1(!refcnt);
|
||
|
}
|
||
|
|
||
|
if (pLoadInfo->rectP)
|
||
|
{
|
||
|
pLoadInfo->rectP->width = 0;
|
||
|
pLoadInfo->rectP->height = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delete[] arrLoadInfo;
|
||
|
}
|
||
|
|
||
|
if (dd_paletteP)
|
||
|
{
|
||
|
db_code1(refcnt =)
|
||
|
dd_paletteP->Release();
|
||
|
db_onlyassert1(!refcnt);
|
||
|
}
|
||
|
|
||
|
return static_cast<D3DTexture *>(NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void AwBackupTexture::OnBeginRestoring(unsigned nMaxPaletteSize)
|
||
|
{
|
||
|
if (nMaxPaletteSize && (nMaxPaletteSize < m_nPaletteSize || !m_nPaletteSize))
|
||
|
{
|
||
|
awTlLastErr = AW_TLE_CANTPALETTIZE;
|
||
|
db_logf3(("AwCreateGraphic(): [restoring] ERROR: Palette size is %u, require %u",m_nPaletteSize,nMaxPaletteSize));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool AwBackupTexture::AreRowsReversed()
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void AwBackupTexture::ConvertRow(AwTl::PtrUnion pDest, unsigned nDestWidth, AwTl::PtrUnionConst pSrc, unsigned nSrcOffset, unsigned nSrcWidth, AwTl::Colour * pPalette db_code1(DB_COMMA unsigned nPaletteSize))
|
||
|
{
|
||
|
using namespace AwTl;
|
||
|
|
||
|
if (pPalette)
|
||
|
{
|
||
|
if (pixelFormat.palettizedB)
|
||
|
{
|
||
|
GenericConvertRow<Colour::ConvNull,BYTE>::Do(pDest,nDestWidth,pSrc.byteP+nSrcOffset,nSrcWidth);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m_bTranspMask)
|
||
|
GenericConvertRow<Colour::ConvTransp,BYTE>::Do(pDest,nDestWidth,pSrc.byteP+nSrcOffset,nSrcWidth,pPalette db_code1(DB_COMMA nPaletteSize));
|
||
|
else
|
||
|
GenericConvertRow<Colour::ConvNonTransp,BYTE>::Do(pDest,nDestWidth,pSrc.byteP+nSrcOffset,nSrcWidth,pPalette db_code1(DB_COMMA nPaletteSize));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m_bTranspMask)
|
||
|
GenericConvertRow<Colour::ConvTransp,Colour>::Do(pDest,nDestWidth,pSrc.colourP+nSrcOffset,nSrcWidth);
|
||
|
else
|
||
|
GenericConvertRow<Colour::ConvNonTransp,Colour>::Do(pDest,nDestWidth,pSrc.colourP+nSrcOffset,nSrcWidth);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void AwBackupTexture::OnFinishRestoring(bool)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
namespace AwTl {
|
||
|
|
||
|
Colour * TypicalBackupTexture::GetPalette()
|
||
|
{
|
||
|
return m_pPalette;
|
||
|
}
|
||
|
|
||
|
PtrUnion TypicalBackupTexture::GetRowPtr(unsigned nRow)
|
||
|
{
|
||
|
return m_ppPixMap[nRow];
|
||
|
}
|
||
|
|
||
|
void TypicalBackupTexture::LoadNextRow(PtrUnion)
|
||
|
{
|
||
|
// already loaded
|
||
|
}
|
||
|
|
||
|
unsigned TypicalBackupTexture::GetNumColours()
|
||
|
{
|
||
|
return m_nPaletteSize;
|
||
|
}
|
||
|
|
||
|
unsigned TypicalBackupTexture::GetMinPaletteSize()
|
||
|
{
|
||
|
return m_nPaletteSize;
|
||
|
}
|
||
|
|
||
|
|
||
|
SurfUnion TexFileLoader::Load(MediaMedium * pMedium, CreateTextureParms const & rParams)
|
||
|
{
|
||
|
m_fFlags = rParams.flags;
|
||
|
|
||
|
awTlLastErr = AW_TLE_OK;
|
||
|
|
||
|
LoadHeaderInfo(pMedium);
|
||
|
|
||
|
CHECK_MEDIA_ERRORS("loading file headers")
|
||
|
ON_ERROR_RETURN_NULL("loading file headers")
|
||
|
|
||
|
ChoosePixelFormat(rParams);
|
||
|
|
||
|
if (!pixelFormat.validB)
|
||
|
db_log3("AwCreateGraphic(): ERROR: pixel format not valid");
|
||
|
if (!driverDesc.ddP || !driverDesc.validB && rParams.loadTextureB)
|
||
|
db_log3("AwCreateGraphic(): ERROR: driver description not valid");
|
||
|
|
||
|
awTlLastErr = pixelFormat.validB && driverDesc.ddP && (driverDesc.validB || !rParams.loadTextureB) ? AW_TLE_OK : AW_TLE_NOINIT;
|
||
|
|
||
|
ON_ERROR_RETURN_NULL("initializing load")
|
||
|
|
||
|
AllocateBuffers(rParams.backupHP ? true : false, pixelFormat.palettizedB ? 1<<pixelFormat.bitsPerPixel : 0);
|
||
|
|
||
|
CHECK_MEDIA_ERRORS("allocating buffers")
|
||
|
ON_ERROR_RETURN_NULL("allocating buffers")
|
||
|
|
||
|
db_logf4(("\tThe image in the file is %ux%u with %u %spalette",m_nWidth,m_nHeight,m_nPaletteSize ? m_nPaletteSize : 0,m_nPaletteSize ? "colour " : ""));
|
||
|
|
||
|
SurfUnion pTex = CreateTexture(rParams);
|
||
|
|
||
|
bool bOK = AW_TLE_OK == awTlLastErr;
|
||
|
|
||
|
CHECK_MEDIA_ERRORS("loading image data")
|
||
|
|
||
|
if (bOK && awTlLastErr != AW_TLE_OK)
|
||
|
{
|
||
|
// an error occurred which was not detected in CreateTexture()
|
||
|
if (pTex.voidP)
|
||
|
{
|
||
|
if (rParams.loadTextureB)
|
||
|
pTex.textureP->Release();
|
||
|
else
|
||
|
pTex.surfaceP->Release();
|
||
|
pTex.voidP = NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
db_assert1(rParams.rectA);
|
||
|
|
||
|
for (unsigned i=0; i<rParams.numRects; ++i)
|
||
|
{
|
||
|
AwCreateGraphicRegion * pRect = &rParams.rectA[i];
|
||
|
|
||
|
if (!rParams.prevTexB)
|
||
|
{
|
||
|
// release what was created
|
||
|
if (rParams.loadTextureB)
|
||
|
pRect->pTexture->Release();
|
||
|
else
|
||
|
pRect->pSurface->Release();
|
||
|
}
|
||
|
pRect->width = 0;
|
||
|
pRect->height = 0;
|
||
|
}
|
||
|
}
|
||
|
db_logf1(("AwCreateGraphic(): ERROR: %s",AwTlErrorToString()));
|
||
|
bOK = false;
|
||
|
}
|
||
|
|
||
|
OnFinishLoading(bOK);
|
||
|
|
||
|
if (bOK && rParams.backupHP)
|
||
|
{
|
||
|
*rParams.backupHP = CreateBackupTexture();
|
||
|
}
|
||
|
|
||
|
return pTex;
|
||
|
}
|
||
|
|
||
|
void TexFileLoader::OnFinishLoading(bool)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
TypicalTexFileLoader::~TypicalTexFileLoader()
|
||
|
{
|
||
|
if (m_pPalette)
|
||
|
{
|
||
|
delete[] m_pPalette;
|
||
|
|
||
|
if (m_pRowBuf) delete[] m_pRowBuf.byteP;
|
||
|
if (m_ppPixMap)
|
||
|
{
|
||
|
delete[] m_ppPixMap->byteP;
|
||
|
delete[] m_ppPixMap;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m_pRowBuf) delete[] m_pRowBuf.colourP;
|
||
|
if (m_ppPixMap)
|
||
|
{
|
||
|
delete[] m_ppPixMap->colourP;
|
||
|
delete[] m_ppPixMap;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsigned TypicalTexFileLoader::GetNumColours()
|
||
|
{
|
||
|
return m_nPaletteSize;
|
||
|
}
|
||
|
|
||
|
unsigned TypicalTexFileLoader::GetMinPaletteSize()
|
||
|
{
|
||
|
return m_nPaletteSize;
|
||
|
}
|
||
|
|
||
|
void TypicalTexFileLoader::AllocateBuffers(bool bWantBackup, unsigned /*nMaxPaletteSize*/)
|
||
|
{
|
||
|
if (m_nPaletteSize)
|
||
|
{
|
||
|
m_pPalette = new Colour [ m_nPaletteSize ];
|
||
|
}
|
||
|
|
||
|
if (bWantBackup)
|
||
|
{
|
||
|
m_ppPixMap = new PtrUnion [m_nHeight];
|
||
|
if (m_nPaletteSize)
|
||
|
{
|
||
|
m_ppPixMap->byteP = new BYTE [m_nHeight*m_nWidth];
|
||
|
BYTE * pRow = m_ppPixMap->byteP;
|
||
|
for (unsigned y=1;y<m_nHeight;++y)
|
||
|
{
|
||
|
pRow += m_nWidth;
|
||
|
m_ppPixMap[y].byteP = pRow;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_ppPixMap->colourP = new Colour [m_nHeight*m_nWidth];
|
||
|
Colour * pRow = m_ppPixMap->colourP;
|
||
|
for (unsigned y=1;y<m_nHeight;++y)
|
||
|
{
|
||
|
pRow += m_nWidth;
|
||
|
m_ppPixMap[y].colourP = pRow;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m_nPaletteSize)
|
||
|
m_pRowBuf.byteP = new BYTE [m_nWidth];
|
||
|
else
|
||
|
m_pRowBuf.colourP = new Colour [m_nWidth];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PtrUnion TypicalTexFileLoader::GetRowPtr(unsigned nRow)
|
||
|
{
|
||
|
if (m_ppPixMap)
|
||
|
{
|
||
|
return m_ppPixMap[nRow];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return m_pRowBuf;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
AwBackupTexture * TypicalTexFileLoader::CreateBackupTexture()
|
||
|
{
|
||
|
AwBackupTexture * pBackup = new TypicalBackupTexture(*this,m_ppPixMap,m_pPalette);
|
||
|
m_ppPixMap = NULL;
|
||
|
m_pPalette = NULL;
|
||
|
return pBackup;
|
||
|
}
|
||
|
|
||
|
/****************************************************************************/
|
||
|
/* For determining which loader should be used for the file format detected */
|
||
|
/****************************************************************************/
|
||
|
|
||
|
static
|
||
|
class MagicFileIdTree
|
||
|
{
|
||
|
public:
|
||
|
MagicFileIdTree()
|
||
|
: m_pfnCreate(NULL)
|
||
|
#ifdef _MSC_VER
|
||
|
, hack(0)
|
||
|
#endif
|
||
|
{
|
||
|
for (unsigned i=0; i<256; ++i)
|
||
|
m_arrNextLayer[i]=NULL;
|
||
|
}
|
||
|
|
||
|
~MagicFileIdTree()
|
||
|
{
|
||
|
for (unsigned i=0; i<256; ++i)
|
||
|
if (m_arrNextLayer[i]) delete m_arrNextLayer[i];
|
||
|
}
|
||
|
|
||
|
MagicFileIdTree * m_arrNextLayer [256];
|
||
|
|
||
|
TexFileLoader * (* m_pfnCreate) ();
|
||
|
|
||
|
#ifdef _MSC_VER
|
||
|
unsigned hack;
|
||
|
#endif
|
||
|
}
|
||
|
* g_pMagicFileIdTree = NULL;
|
||
|
|
||
|
void RegisterLoader(char const * pszMagic, TexFileLoader * (* pfnCreate) () )
|
||
|
{
|
||
|
static MagicFileIdTree mfidt;
|
||
|
|
||
|
#ifdef _MSC_VER
|
||
|
// Touch the loaders.
|
||
|
{
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rlcAwBmpLoader_187);
|
||
|
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rlcAwIffLoader_428);
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rlcAwIffLoader_429);
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rlcAwIffLoader_430);
|
||
|
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rlcAwPpmLoader_229);
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rlcAwPgmLoader_230);
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rlcAwPbmLoader_231);
|
||
|
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rccIlbmBmhdChunk_4);
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rccIlbmCmapChunk_5);
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rccIlbmBodyChunk_6);
|
||
|
mfidt.hack += reinterpret_cast<unsigned>(&rccIlbmGrabChunk_7);
|
||
|
}
|
||
|
#endif
|
||
|
g_pMagicFileIdTree = &mfidt;
|
||
|
|
||
|
MagicFileIdTree * pLayer = g_pMagicFileIdTree;
|
||
|
|
||
|
while (*pszMagic)
|
||
|
{
|
||
|
BYTE c = static_cast<BYTE>(*pszMagic++);
|
||
|
|
||
|
if (!pLayer->m_arrNextLayer[c])
|
||
|
pLayer->m_arrNextLayer[c] = new MagicFileIdTree;
|
||
|
|
||
|
pLayer = pLayer->m_arrNextLayer[c];
|
||
|
}
|
||
|
|
||
|
db_assert1(!pLayer->m_pfnCreate);
|
||
|
|
||
|
pLayer->m_pfnCreate = pfnCreate;
|
||
|
}
|
||
|
|
||
|
static
|
||
|
TexFileLoader * CreateLoaderObject(MediaMedium * pMedium)
|
||
|
{
|
||
|
TexFileLoader * (* pfnBest) () = NULL;
|
||
|
|
||
|
signed nMoveBack = 0;
|
||
|
|
||
|
BYTE c;
|
||
|
|
||
|
MagicFileIdTree * pLayer = g_pMagicFileIdTree;
|
||
|
|
||
|
while (pLayer)
|
||
|
{
|
||
|
if (pLayer->m_pfnCreate)
|
||
|
pfnBest = pLayer->m_pfnCreate;
|
||
|
|
||
|
MediaRead(pMedium,&c);
|
||
|
|
||
|
-- nMoveBack;
|
||
|
|
||
|
pLayer = pLayer->m_arrNextLayer[c];
|
||
|
}
|
||
|
|
||
|
pMedium->MovePos(nMoveBack);
|
||
|
|
||
|
if (pfnBest)
|
||
|
return pfnBest();
|
||
|
else
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
/**********************************/
|
||
|
/* These are the loader functions */
|
||
|
/**********************************/
|
||
|
|
||
|
static inline SurfUnion DoLoadTexture(MediaMedium * pMedium, CreateTextureParms const & rParams)
|
||
|
{
|
||
|
TexFileLoader * pLoader = CreateLoaderObject(pMedium);
|
||
|
|
||
|
if (!pLoader)
|
||
|
{
|
||
|
awTlLastErr = AW_TLE_BADFILEFORMAT;
|
||
|
db_log1("AwCreateGraphic(): ERROR: file format not recognized");
|
||
|
return static_cast<D3DTexture *>(NULL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SurfUnion pTex = pLoader->Load(pMedium,rParams);
|
||
|
pLoader->Release();
|
||
|
return pTex;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static inline SurfUnion LoadTexture(MediaMedium * pMedium, CreateTextureParms const & _parmsR)
|
||
|
{
|
||
|
if (_parmsR.bytesReadP||_parmsR.maxReadBytes!=UINT_MAX)
|
||
|
{
|
||
|
MediaSection * pMedSect = new MediaSection;
|
||
|
pMedSect->Open(pMedium,_parmsR.maxReadBytes);
|
||
|
SurfUnion pTex = DoLoadTexture(pMedSect,_parmsR);
|
||
|
pMedSect->Close();
|
||
|
if (_parmsR.bytesReadP) *_parmsR.bytesReadP = pMedSect->GetUsedSize();
|
||
|
delete pMedSect;
|
||
|
return pTex;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return DoLoadTexture(pMedium,_parmsR);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SurfUnion CreateTextureParms::DoCreate() const
|
||
|
{
|
||
|
if (INVALID_HANDLE_VALUE!=fileH)
|
||
|
{
|
||
|
MediaWinFileMedium * pMedium = new MediaWinFileMedium;
|
||
|
pMedium->Attach(fileH);
|
||
|
SurfUnion pTex = LoadTexture(pMedium,*this);
|
||
|
pMedium->Detach();
|
||
|
pMedium->Release();
|
||
|
return pTex;
|
||
|
}
|
||
|
else if (dataP)
|
||
|
{
|
||
|
MediaMemoryReadMedium * pMedium = new MediaMemoryReadMedium;
|
||
|
pMedium->Open(dataP);
|
||
|
SurfUnion pTex = LoadTexture(pMedium,*this);
|
||
|
pMedium->Close();
|
||
|
pMedium->Release();
|
||
|
return pTex;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
db_assert1(restoreH);
|
||
|
return restoreH->Restore(*this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if DB_LEVEL >= 4
|
||
|
static void LogPrimCaps(LPD3DPRIMCAPS _pcP, bool _triB)
|
||
|
{
|
||
|
#define DEVCAP(mask,can_or_does,explanation) \
|
||
|
db_logf4(("\t\t" can_or_does "%s " explanation, _pcP->MEMBER & (mask) ? "" : "not"));
|
||
|
|
||
|
#define MEMBER dwMiscCaps
|
||
|
DEVCAP(D3DPMISCCAPS_CONFORMANT,"Does ","conform to OpenGL standard")
|
||
|
if (_triB)
|
||
|
{
|
||
|
DEVCAP(D3DPMISCCAPS_CULLCCW,"Does ","support counterclockwise culling through the D3DRENDERSTATE_CULLMODE state")
|
||
|
DEVCAP(D3DPMISCCAPS_CULLCW,"Does ","support clockwise triangle culling through the D3DRENDERSTATE_CULLMODE state")
|
||
|
db_logf4(("\t\tDoes %s perform triangle culling", _pcP->dwMiscCaps & (D3DPMISCCAPS_CULLNONE) ? "not" : ""));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DEVCAP(D3DPMISCCAPS_LINEPATTERNREP,"Can","handle values other than 1 in the wRepeatFactor member of the D3DLINEPATTERN structure")
|
||
|
}
|
||
|
DEVCAP(D3DPMISCCAPS_MASKPLANES,"Can","perform a bitmask of color planes")
|
||
|
DEVCAP(D3DPMISCCAPS_MASKZ,"Can","enable and disable modification of the z-buffer on pixel operations")
|
||
|
#undef MEMBER
|
||
|
#define MEMBER dwRasterCaps
|
||
|
DEVCAP(D3DPRASTERCAPS_ANISOTROPY,"Does ","support anisotropic filtering")
|
||
|
DEVCAP(D3DPRASTERCAPS_ANTIALIASEDGES,"Can","antialias lines forming the convex outline of objects")
|
||
|
DEVCAP(D3DPRASTERCAPS_ANTIALIASSORTDEPENDENT,"Does","support antialiasing that is dependent on the sort order of the polygons")
|
||
|
DEVCAP(D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT,"Does","support antialiasing that is not dependent on the sort order of the polygons")
|
||
|
DEVCAP(D3DPRASTERCAPS_DITHER,"Can","dither to improve color resolution")
|
||
|
DEVCAP(D3DPRASTERCAPS_FOGRANGE,"Does ","support range-based fog")
|
||
|
DEVCAP(D3DPRASTERCAPS_FOGTABLE,"Does ","calculate the fog value by referring to a lookup table containing fog values that are indexed to the depth of a given pixel")
|
||
|
DEVCAP(D3DPRASTERCAPS_FOGVERTEX,"Does ","calculate the fog value during the lighting operation")
|
||
|
DEVCAP(D3DPRASTERCAPS_MIPMAPLODBIAS,"Does ","support level-of-detail (LOD) bias adjustments")
|
||
|
DEVCAP(D3DPRASTERCAPS_PAT,"Can","perform patterned drawing for the primitive being queried")
|
||
|
DEVCAP(D3DPRASTERCAPS_ROP2,"Can","support raster operations other than R2_COPYPEN")
|
||
|
DEVCAP(D3DPRASTERCAPS_STIPPLE,"Can","stipple polygons to simulate translucency")
|
||
|
DEVCAP(D3DPRASTERCAPS_SUBPIXEL,"Does ","perform subpixel placement of z, color, and texture data, rather than working with the nearest integer pixel coordinate")
|
||
|
DEVCAP(D3DPRASTERCAPS_SUBPIXELX,"Is ","subpixel accurate along the x-axis only and is clamped to an integer y-axis scan line")
|
||
|
DEVCAP(D3DPRASTERCAPS_XOR,"Can","support XOR operations")
|
||
|
DEVCAP(D3DPRASTERCAPS_ZBIAS,"Does ","support z-bias values")
|
||
|
DEVCAP(D3DPRASTERCAPS_ZBUFFERLESSHSR,"Can","perform hidden-surface removal without requiring the application to sort polygons, and without requiring the allocation of a z-buffer")
|
||
|
DEVCAP(D3DPRASTERCAPS_ZTEST,"Can","perform z-test operations")
|
||
|
#undef MEMBER
|
||
|
#define MEMBER dwZCmpCaps
|
||
|
DEVCAP(D3DPCMPCAPS_ALWAYS,"Can","always pass the z test")
|
||
|
DEVCAP(D3DPCMPCAPS_EQUAL,"Can","pass the z test if the new z equals the current z")
|
||
|
DEVCAP(D3DPCMPCAPS_GREATER,"Can","pass the z test if the new z is greater than the current z")
|
||
|
DEVCAP(D3DPCMPCAPS_GREATEREQUAL,"Can","pass the z test if the new z is greater than or equal to the current z")
|
||
|
DEVCAP(D3DPCMPCAPS_LESS,"Can","pass the z test if the new z is less than the current z")
|
||
|
DEVCAP(D3DPCMPCAPS_LESSEQUAL,"Can","pass the z test if the new z is less than or equal to the current z")
|
||
|
DEVCAP(D3DPCMPCAPS_NEVER,"Can","always fail the z test")
|
||
|
DEVCAP(D3DPCMPCAPS_NOTEQUAL,"Can","pass the z test if the new z does not equal the current z")
|
||
|
#undef MEMBER
|
||
|
#define MEMBER dwSrcBlendCaps
|
||
|
DEVCAP(D3DPBLENDCAPS_BOTHINVSRCALPHA,"Can","source blend with source blend factor of (1-As, 1-As, 1-As, 1-As) and destination blend factor of (As, As, As, As); the destination blend selection is overridden")
|
||
|
DEVCAP(D3DPBLENDCAPS_BOTHSRCALPHA,"Can","source blend with source blend factor of (As, As, As, As) and destination blend factor of (1-As, 1-As, 1-As, 1-As); the destination blend selection is overridden")
|
||
|
DEVCAP(D3DPBLENDCAPS_DESTALPHA,"Can","source blend with blend factor of (Ad, Ad, Ad, Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_DESTCOLOR,"Can","source blend with blend factor of (Rd, Gd, Bd, Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_INVDESTALPHA,"Can","source blend with blend factor of (1-Ad, 1-Ad, 1-Ad, 1-Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_INVDESTCOLOR,"Can","source blend with blend factor of (1-Rd, 1-Gd, 1-Bd, 1-Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_INVSRCALPHA,"Can","source blend with blend factor of (1-As, 1-As, 1-As, 1-As)")
|
||
|
DEVCAP(D3DPBLENDCAPS_INVSRCCOLOR,"Can","source blend with blend factor of (1-Rd, 1-Gd, 1-Bd, 1-Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_ONE,"Can","source blend with blend factor of (1, 1, 1, 1)")
|
||
|
DEVCAP(D3DPBLENDCAPS_SRCALPHA,"Can","source blend with blend factor of (As, As, As, As)")
|
||
|
DEVCAP(D3DPBLENDCAPS_SRCALPHASAT,"Can","source blend with blend factor of (f, f, f, 1); f = min(As, 1-Ad).")
|
||
|
DEVCAP(D3DPBLENDCAPS_SRCCOLOR,"Can","source blend with blend factor of (Rs, Gs, Bs, As)")
|
||
|
DEVCAP(D3DPBLENDCAPS_ZERO,"Can","source blend with blend factor of (0, 0, 0, 0)")
|
||
|
#undef MEMBER
|
||
|
#define MEMBER dwDestBlendCaps
|
||
|
DEVCAP(D3DPBLENDCAPS_BOTHINVSRCALPHA,"Can","destination blend with source blend factor of (1-As, 1-As, 1-As, 1-As) and destination blend factor of (As, As, As, As); the destination blend selection is overridden")
|
||
|
DEVCAP(D3DPBLENDCAPS_BOTHSRCALPHA,"Can","destination blend with source blend factor of (As, As, As, As) and destination blend factor of (1-As, 1-As, 1-As, 1-As); the destination blend selection is overridden")
|
||
|
DEVCAP(D3DPBLENDCAPS_DESTALPHA,"Can","destination blend with blend factor of (Ad, Ad, Ad, Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_DESTCOLOR,"Can","destination blend with blend factor of (Rd, Gd, Bd, Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_INVDESTALPHA,"Can","destination blend with blend factor of (1-Ad, 1-Ad, 1-Ad, 1-Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_INVDESTCOLOR,"Can","destination blend with blend factor of (1-Rd, 1-Gd, 1-Bd, 1-Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_INVSRCALPHA,"Can","destination blend with blend factor of (1-As, 1-As, 1-As, 1-As)")
|
||
|
DEVCAP(D3DPBLENDCAPS_INVSRCCOLOR,"Can","destination blend with blend factor of (1-Rd, 1-Gd, 1-Bd, 1-Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_ONE,"Can","destination blend with blend factor of (1, 1, 1, 1)")
|
||
|
DEVCAP(D3DPBLENDCAPS_SRCALPHA,"Can","destination blend with blend factor of (As, As, As, As)")
|
||
|
DEVCAP(D3DPBLENDCAPS_SRCALPHASAT,"Can","destination blend with blend factor of (f, f, f, 1); f = min(As, 1-Ad)")
|
||
|
DEVCAP(D3DPBLENDCAPS_SRCCOLOR,"Can","destination blend with blend factor of (Rs, Gs, Bs, As)")
|
||
|
DEVCAP(D3DPBLENDCAPS_ZERO,"Can","destination blend with blend factor of (0, 0, 0, 0)")
|
||
|
#undef MEMBER
|
||
|
#define MEMBER dwAlphaCmpCaps
|
||
|
DEVCAP(D3DPCMPCAPS_ALWAYS,"Can","always pass the alpha test")
|
||
|
DEVCAP(D3DPCMPCAPS_EQUAL,"Can","pass the alpha test if the new alpha equals the current alpha")
|
||
|
DEVCAP(D3DPCMPCAPS_GREATER,"Can","pass the alpha test if the new alpha is greater than the current alpha")
|
||
|
DEVCAP(D3DPCMPCAPS_GREATEREQUAL,"Can","pass the alpha test if the new alpha is greater than or equal to the current alpha")
|
||
|
DEVCAP(D3DPCMPCAPS_LESS,"Can","pass the alpha test if the new alpha is less than the current alpha")
|
||
|
DEVCAP(D3DPCMPCAPS_LESSEQUAL,"Can","pass the alpha test if the new alpha is less than or equal to the current alpha")
|
||
|
DEVCAP(D3DPCMPCAPS_NEVER,"Can","always fail the alpha test")
|
||
|
DEVCAP(D3DPCMPCAPS_NOTEQUAL,"Can","pass the alpha test if the new alpha does not equal the current alpha")
|
||
|
#undef MEMBER
|
||
|
#define MEMBER dwShadeCaps
|
||
|
DEVCAP(D3DPSHADECAPS_ALPHAFLATBLEND,"Can","support an alpha component for flat blended transparency")
|
||
|
DEVCAP(D3DPSHADECAPS_ALPHAFLATSTIPPLED,"Can","support an alpha component for flat stippled transparency")
|
||
|
DEVCAP(D3DPSHADECAPS_ALPHAGOURAUDBLEND,"Can","support an alpha component for Gouraud blended transparency")
|
||
|
DEVCAP(D3DPSHADECAPS_ALPHAGOURAUDSTIPPLED,"Can","support an alpha component for Gouraud stippled transparency")
|
||
|
DEVCAP(D3DPSHADECAPS_ALPHAPHONGBLEND,"Can","support an alpha component for Phong blended transparency")
|
||
|
DEVCAP(D3DPSHADECAPS_ALPHAPHONGSTIPPLED,"Can","support an alpha component for Phong stippled transparency")
|
||
|
DEVCAP(D3DPSHADECAPS_COLORFLATMONO,"Can","support colored flat shading in the D3DCOLOR_MONO color model")
|
||
|
DEVCAP(D3DPSHADECAPS_COLORFLATRGB,"Can","support colored flat shading in the D3DCOLOR_RGB color model")
|
||
|
DEVCAP(D3DPSHADECAPS_COLORGOURAUDMONO,"Can","support colored flat shading in the D3DCOLOR_MONO color model")
|
||
|
DEVCAP(D3DPSHADECAPS_COLORGOURAUDRGB,"Can","support colored Gouraud shading in the D3DCOLOR_RGB color model")
|
||
|
DEVCAP(D3DPSHADECAPS_COLORPHONGMONO,"Can","support colored Phong shading in the D3DCOLOR_MONO color model")
|
||
|
DEVCAP(D3DPSHADECAPS_COLORPHONGRGB,"Can","support colored Phong shading in the D3DCOLOR_RGB color model")
|
||
|
DEVCAP(D3DPSHADECAPS_FOGFLAT,"Can","support fog in the flat shading model")
|
||
|
DEVCAP(D3DPSHADECAPS_FOGGOURAUD,"Can","support fog in the Gouraud shading model")
|
||
|
DEVCAP(D3DPSHADECAPS_FOGPHONG,"Can","support fog in the Phong shading model")
|
||
|
DEVCAP(D3DPSHADECAPS_SPECULARFLATMONO,"Can","support specular highlights in flat shading in the D3DCOLOR_MONO color model")
|
||
|
DEVCAP(D3DPSHADECAPS_SPECULARFLATRGB,"Can","support specular highlights in flat shading in the D3DCOLOR_RGB color model")
|
||
|
DEVCAP(D3DPSHADECAPS_SPECULARGOURAUDMONO,"Can","support specular highlights in Gouraud shading in the D3DCOLOR_MONO color model")
|
||
|
DEVCAP(D3DPSHADECAPS_SPECULARGOURAUDRGB,"Can","support specular highlights in Gouraud shading in the D3DCOLOR_RGB color model")
|
||
|
DEVCAP(D3DPSHADECAPS_SPECULARPHONGMONO,"Can","support specular highlights in Phong shading in the D3DCOLOR_MONO color model")
|
||
|
DEVCAP(D3DPSHADECAPS_SPECULARPHONGRGB,"Can","support specular highlights in Phong shading in the D3DCOLOR_RGB color model")
|
||
|
#undef MEMBER
|
||
|
#define MEMBER dwTextureCaps
|
||
|
DEVCAP(D3DPTEXTURECAPS_ALPHA,"Does ","support RGBA textures in the D3DTEX_DECAL and D3DTEX_MODULATE texture filtering modes")
|
||
|
DEVCAP(D3DPTEXTURECAPS_BORDER,"Does ","support texture mapping along borders")
|
||
|
DEVCAP(D3DPTEXTURECAPS_PERSPECTIVE,"Does ","support perspective correction")
|
||
|
DEVCAP(D3DPTEXTURECAPS_POW2,"Does ","require all nonmipmapped textures to have widths and heights specified as powers of two")
|
||
|
DEVCAP(D3DPTEXTURECAPS_SQUAREONLY,"Does ","require all textures to be square")
|
||
|
DEVCAP(D3DPTEXTURECAPS_TRANSPARENCY,"Does ","support texture transparency")
|
||
|
#undef MEMBER
|
||
|
#define MEMBER dwTextureFilterCaps
|
||
|
DEVCAP(D3DPTFILTERCAPS_LINEAR,"Can","use a weighted average of a 2x2 area of texels surrounding the desired pixel")
|
||
|
DEVCAP(D3DPTFILTERCAPS_LINEARMIPLINEAR,"Can","use a weighted average of a 2x2 area of texels, and also interpolate between mipmaps")
|
||
|
DEVCAP(D3DPTFILTERCAPS_LINEARMIPNEAREST,"Can","use a weighted average of a 2x2 area of texels, and also use a mipmap")
|
||
|
DEVCAP(D3DPTFILTERCAPS_MIPLINEAR,"Can","choose two mipmaps whose texels most closely match the size of the pixel to be textured, and interpolate between them")
|
||
|
DEVCAP(D3DPTFILTERCAPS_MIPNEAREST,"Can","use an appropriate mipmap for texel selection")
|
||
|
DEVCAP(D3DPTFILTERCAPS_NEAREST,"Can","use the texel with coordinates nearest to the desired pixel value is used")
|
||
|
#undef MEMBER
|
||
|
#define MEMBER dwTextureBlendCaps
|
||
|
DEVCAP(D3DPTBLENDCAPS_ADD,"Can","use the additive texture-blending mode")
|
||
|
DEVCAP(D3DPTBLENDCAPS_COPY,"Can","use copy mode texture-blending")
|
||
|
DEVCAP(D3DPTBLENDCAPS_DECAL,"Can","use decal texture-blending mode")
|
||
|
DEVCAP(D3DPTBLENDCAPS_DECALALPHA,"Can","use decal-alpha texture-blending mode")
|
||
|
DEVCAP(D3DPTBLENDCAPS_DECALMASK,"Can","use decal-mask texture-blending mode")
|
||
|
DEVCAP(D3DPTBLENDCAPS_MODULATE,"Can","use modulate texture-blending mode")
|
||
|
DEVCAP(D3DPTBLENDCAPS_MODULATEALPHA,"Can","use modulate-alpha texture-blending mode")
|
||
|
DEVCAP(D3DPTBLENDCAPS_MODULATEMASK,"Can","use modulate-mask texture-blending mode")
|
||
|
#undef MEMBER
|
||
|
#define MEMBER dwTextureAddressCaps
|
||
|
DEVCAP(D3DPTADDRESSCAPS_BORDER,"Does ","support setting coordinates outside the range [0.0, 1.0] to the border color")
|
||
|
DEVCAP(D3DPTADDRESSCAPS_CLAMP,"Can","clamp textures to addresses")
|
||
|
DEVCAP(D3DPTADDRESSCAPS_INDEPENDENTUV,"Can","separate the texture-addressing modes of the U and V coordinates of the texture")
|
||
|
DEVCAP(D3DPTADDRESSCAPS_MIRROR,"Can","mirror textures to addresses")
|
||
|
DEVCAP(D3DPTADDRESSCAPS_WRAP,"Can","wrap textures to addresses")
|
||
|
#undef MEMBER
|
||
|
#undef DEVCAP
|
||
|
db_logf4(("\t\tMaximum size of the supported stipple is %u x %u",_pcP->dwStippleWidth,_pcP->dwStippleHeight));
|
||
|
}
|
||
|
static void LogCaps(LPD3DDEVICEDESC _descP)
|
||
|
{
|
||
|
if (_descP->dwFlags & D3DDD_BCLIPPING)
|
||
|
{
|
||
|
db_logf4(("\tCan%s perform 3D clipping",_descP->bClipping ? "" : "not"));
|
||
|
}
|
||
|
else db_log4("\tHas unknown 3D clipping capability");
|
||
|
|
||
|
if (_descP->dwFlags & D3DDD_COLORMODEL)
|
||
|
{
|
||
|
db_logf4(("\tCan%s use mono (ramp) colour model",_descP->dcmColorModel & D3DCOLOR_MONO ? "" : "not"));
|
||
|
db_logf4(("\tCan%s use full RGB colour model",_descP->dcmColorModel & D3DCOLOR_RGB ? "" : "not"));
|
||
|
}
|
||
|
else db_log4("\tHas unknown colour model");
|
||
|
|
||
|
if (_descP->dwFlags & D3DDD_DEVCAPS)
|
||
|
{
|
||
|
#define DEVCAP(mask,can_or_does,explanation) \
|
||
|
db_logf4(("\t" can_or_does "%s " explanation,_descP->dwDevCaps & (mask) ? "" : "not"));
|
||
|
|
||
|
DEVCAP(D3DDEVCAPS_CANRENDERAFTERFLIP,"Can","queue rendering commands after a page flip")
|
||
|
DEVCAP(D3DDEVCAPS_DRAWPRIMTLVERTEX,"Does ","export a DrawPrimitive-aware HAL")
|
||
|
DEVCAP(D3DDEVCAPS_EXECUTESYSTEMMEMORY,"Can","use execute buffers from system memory")
|
||
|
DEVCAP(D3DDEVCAPS_EXECUTEVIDEOMEMORY,"Can","use execute buffer from video memory")
|
||
|
DEVCAP(D3DDEVCAPS_FLOATTLVERTEX,"Does ","accept floating point for post-transform vertex data")
|
||
|
DEVCAP(D3DDEVCAPS_SORTDECREASINGZ,"Does ","need Z data sorted for decreasing depth")
|
||
|
DEVCAP(D3DDEVCAPS_SORTEXACT,"Does ","need data sorted exactly")
|
||
|
DEVCAP(D3DDEVCAPS_SORTINCREASINGZ,"Does ","need data sorted for increasing depth")
|
||
|
DEVCAP(D3DDEVCAPS_TEXTURENONLOCALVIDMEM,"Can","retrieve textures from nonlocal video (AGP) memory")
|
||
|
DEVCAP(D3DDEVCAPS_TEXTURESYSTEMMEMORY,"Can","retrieve textures from system memory")
|
||
|
DEVCAP(D3DDEVCAPS_TEXTUREVIDEOMEMORY,"Can","retrieve textures from device memory")
|
||
|
DEVCAP(D3DDEVCAPS_TLVERTEXSYSTEMMEMORY,"Can","use buffers from system memory for transformed and lit vertices")
|
||
|
DEVCAP(D3DDEVCAPS_TLVERTEXVIDEOMEMORY,"Can","use buffers from video memory for transformed and lit vertices")
|
||
|
|
||
|
#undef DEVCAP
|
||
|
}
|
||
|
else db_log4("\tHas unknown device capabilities");
|
||
|
|
||
|
if (_descP->dwFlags & D3DDD_DEVICERENDERBITDEPTH)
|
||
|
{
|
||
|
#define DEVCAP(mask,explanation) \
|
||
|
db_logf4(("\tCan%s render to "explanation" surface",_descP->dwDeviceRenderBitDepth & (mask) ? "" : "not"));
|
||
|
|
||
|
DEVCAP(DDBD_8,"an 8-bit")
|
||
|
DEVCAP(DDBD_16,"a 16-bit")
|
||
|
DEVCAP(DDBD_24,"a 24-bit")
|
||
|
DEVCAP(DDBD_32,"a 32-bit")
|
||
|
|
||
|
#undef DEVCAP
|
||
|
}
|
||
|
else db_log4("\tHas unknown rendering target bitdepth requirements");
|
||
|
|
||
|
if (_descP->dwFlags & D3DDD_DEVICEZBUFFERBITDEPTH)
|
||
|
{
|
||
|
#define DEVCAP(mask,explanation) \
|
||
|
db_logf4(("\tCan%s use "explanation" Z-buffer",_descP->dwDeviceZBufferBitDepth & (mask) ? "" : "not"));
|
||
|
|
||
|
DEVCAP(DDBD_8,"an 8-bit")
|
||
|
DEVCAP(DDBD_16,"a 16-bit")
|
||
|
DEVCAP(DDBD_24,"a 24-bit")
|
||
|
DEVCAP(DDBD_32,"a 32-bit")
|
||
|
|
||
|
#undef DEVCAP
|
||
|
}
|
||
|
else db_log4("\tHas unknown Z-buffer bitdepth requirements");
|
||
|
|
||
|
if (_descP->dwFlags & D3DDD_TRANSFORMCAPS)
|
||
|
{
|
||
|
db_log4("\tTransform capabilities are known");
|
||
|
}
|
||
|
else db_log4("\tHas unknown transform capabilities");
|
||
|
|
||
|
if (_descP->dwFlags & D3DDD_LIGHTINGCAPS)
|
||
|
{
|
||
|
db_log4("\tLighting capabilities are known");
|
||
|
}
|
||
|
else db_log4("\tHas unknown lighting capabilities");
|
||
|
|
||
|
if (_descP->dwFlags & D3DDD_LINECAPS)
|
||
|
{
|
||
|
db_log4("\tLine drawing capabilities follow");
|
||
|
LogPrimCaps(&_descP->dpcLineCaps,false);
|
||
|
}
|
||
|
else db_log4("\tHas unknown line drawing capabilities");
|
||
|
|
||
|
if (_descP->dwFlags & D3DDD_TRICAPS)
|
||
|
{
|
||
|
db_log4("\tTriangle rendering capabilities follow");
|
||
|
LogPrimCaps(&_descP->dpcTriCaps,true);
|
||
|
}
|
||
|
else db_log4("\tHas unknown triangle rendering capabilities");
|
||
|
|
||
|
if (_descP->dwFlags & D3DDD_MAXBUFFERSIZE)
|
||
|
{
|
||
|
unsigned max_exb = _descP->dwMaxBufferSize;
|
||
|
if (!max_exb) max_exb = UINT_MAX;
|
||
|
db_logf4(("\tMaximum execute buffer size is %u",max_exb));
|
||
|
}
|
||
|
else db_log4("\tHas unknown maximum execute buffer size");
|
||
|
|
||
|
if (_descP->dwFlags & D3DDD_MAXVERTEXCOUNT)
|
||
|
{
|
||
|
db_logf4(("\tMaximum vertex count is %u",_descP->dwMaxVertexCount));
|
||
|
}
|
||
|
else db_log4("\tHas unknown maximum vertex count");
|
||
|
|
||
|
unsigned max_tw = _descP->dwMaxTextureWidth;
|
||
|
unsigned max_th = _descP->dwMaxTextureHeight;
|
||
|
unsigned max_sw = _descP->dwMaxStippleWidth;
|
||
|
unsigned max_sh = _descP->dwMaxStippleHeight;
|
||
|
if (!max_tw) max_tw = UINT_MAX;
|
||
|
if (!max_th) max_th = UINT_MAX;
|
||
|
if (!max_sw) max_sw = UINT_MAX;
|
||
|
if (!max_sh) max_sh = UINT_MAX;
|
||
|
|
||
|
db_logf4(("\tMinimum texture size is %u x %u",_descP->dwMinTextureWidth,_descP->dwMinTextureHeight));
|
||
|
db_logf4(("\tMaximum texture size is %u x %u",max_tw,max_th));
|
||
|
db_logf4(("\tMinimum stipple size is %u x %u",_descP->dwMinStippleWidth,_descP->dwMinStippleHeight));
|
||
|
db_logf4(("\tMaximum stipple size is %u x %u",max_sw,max_sh));
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// Parse the format string and get the parameters
|
||
|
|
||
|
static bool ParseParams(CreateTextureParms * pParams, char const * _argFormatS, va_list ap)
|
||
|
{
|
||
|
bool bad_parmsB = false;
|
||
|
db_code2(unsigned ch_off = 0;)
|
||
|
db_code2(char ch = 0;)
|
||
|
|
||
|
while (*_argFormatS && !bad_parmsB)
|
||
|
{
|
||
|
db_code2(++ch_off;)
|
||
|
db_code2(ch = *_argFormatS;)
|
||
|
switch (*_argFormatS++)
|
||
|
{
|
||
|
case 's':
|
||
|
if (pParams->fileNameS || INVALID_HANDLE_VALUE!=pParams->fileH || pParams->dataP || pParams->restoreH)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->fileNameS = va_arg(ap,LPCTSTR);
|
||
|
db_logf4(("\tFilename = \"%s\"",pParams->fileNameS));
|
||
|
}
|
||
|
break;
|
||
|
case 'h':
|
||
|
if (pParams->fileNameS || INVALID_HANDLE_VALUE!=pParams->fileH || pParams->dataP || pParams->restoreH)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->fileH = va_arg(ap,HANDLE);
|
||
|
db_logf4(("\tFile HANDLE = 0x%08x",pParams->fileH));
|
||
|
}
|
||
|
break;
|
||
|
case 'p':
|
||
|
if (pParams->fileNameS || INVALID_HANDLE_VALUE!=pParams->fileH || pParams->dataP || pParams->restoreH)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->dataP = va_arg(ap,void const *);
|
||
|
db_logf4(("\tData Pointer = %p",pParams->dataP));
|
||
|
}
|
||
|
break;
|
||
|
case 'r':
|
||
|
if (pParams->fileNameS || INVALID_HANDLE_VALUE!=pParams->fileH || pParams->dataP || pParams->restoreH || UINT_MAX!=pParams->maxReadBytes || pParams->bytesReadP || pParams->backupHP)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->restoreH = va_arg(ap,AW_BACKUPTEXTUREHANDLE);
|
||
|
db_logf4(("\tRestore Handle = 0x%08x",pParams->restoreH));
|
||
|
}
|
||
|
break;
|
||
|
case 'x':
|
||
|
if (UINT_MAX!=pParams->maxReadBytes || pParams->restoreH)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->maxReadBytes = va_arg(ap,unsigned);
|
||
|
db_logf4(("\tMax bytes to read = %u",pParams->maxReadBytes));
|
||
|
}
|
||
|
break;
|
||
|
case 'N':
|
||
|
if (pParams->bytesReadP || pParams->restoreH)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->bytesReadP = va_arg(ap,unsigned *);
|
||
|
db_logf4(("\tPtr to bytes read = %p",pParams->bytesReadP));
|
||
|
}
|
||
|
break;
|
||
|
case 'f':
|
||
|
if (AW_TLF_DEFAULT!=pParams->flags)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->flags = va_arg(ap,unsigned);
|
||
|
db_logf4(("\tFlags = 0x%08x",pParams->flags));
|
||
|
}
|
||
|
break;
|
||
|
case 'W':
|
||
|
if (pParams->widthP || pParams->rectA)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->widthP = va_arg(ap,unsigned *);
|
||
|
db_logf4(("\tPtr to width = %p",pParams->widthP));
|
||
|
}
|
||
|
break;
|
||
|
case 'H':
|
||
|
if (pParams->heightP || pParams->rectA)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->heightP = va_arg(ap,unsigned *);
|
||
|
db_logf4(("\tPtr to height = %p",pParams->heightP));
|
||
|
}
|
||
|
break;
|
||
|
case 'X':
|
||
|
if (pParams->originalWidthP)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->originalWidthP = va_arg(ap,unsigned *);
|
||
|
db_logf4(("\tPtr to image width = %p",pParams->originalWidthP));
|
||
|
}
|
||
|
break;
|
||
|
case 'Y':
|
||
|
if (pParams->originalHeightP)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->originalHeightP = va_arg(ap,unsigned *);
|
||
|
db_logf4(("\tPtr to image height = %p",pParams->originalHeightP));
|
||
|
}
|
||
|
break;
|
||
|
case 'B':
|
||
|
if (pParams->backupHP || pParams->restoreH)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->backupHP = va_arg(ap,AW_BACKUPTEXTUREHANDLE *);
|
||
|
db_logf4(("\tPtr to backup handle = %p",pParams->backupHP));
|
||
|
}
|
||
|
break;
|
||
|
case 't':
|
||
|
if (pParams->prevTexP.voidP)
|
||
|
bad_parmsB = true;
|
||
|
else if (pParams->rectA)
|
||
|
{
|
||
|
pParams->prevTexB = true;
|
||
|
db_log4("\tPrevious DDSurface * or D3DTexture * in rectangle array");
|
||
|
}
|
||
|
else if (pParams->loadTextureB)
|
||
|
{
|
||
|
pParams->prevTexP = va_arg(ap,D3DTexture *);
|
||
|
db_logf4(("\tPrevious D3DTexture * = %p",pParams->prevTexP.textureP));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pParams->prevTexP = va_arg(ap,DDSurface *);
|
||
|
db_logf4(("\tPrevious DDSurface * = %p",pParams->prevTexP.surfaceP));
|
||
|
}
|
||
|
break;
|
||
|
case 'c':
|
||
|
if (pParams->callbackF)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->callbackF = va_arg(ap,AW_TL_PFN_CALLBACK);
|
||
|
pParams->callbackParam = va_arg(ap,void *);
|
||
|
db_logf4(("\tCallback function = %p, param = %p",pParams->callbackF,pParams->callbackParam));
|
||
|
}
|
||
|
break;
|
||
|
case 'a':
|
||
|
if (pParams->prevTexP.voidP || pParams->rectA || pParams->widthP || pParams->heightP)
|
||
|
bad_parmsB = true;
|
||
|
else
|
||
|
{
|
||
|
pParams->numRects = va_arg(ap,unsigned);
|
||
|
pParams->rectA = va_arg(ap,AwCreateGraphicRegion *);
|
||
|
db_logf4(("\tRectangle array = %p, size = %u",pParams->rectA,pParams->numRects));
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
bad_parmsB = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!pParams->fileNameS && INVALID_HANDLE_VALUE==pParams->fileH && !pParams->dataP && !pParams->restoreH)
|
||
|
{
|
||
|
awTlLastErr = AW_TLE_BADPARMS;
|
||
|
db_log2("AwCreateGraphic(): ERROR: No data medium is specified");
|
||
|
return false;
|
||
|
}
|
||
|
else if (bad_parmsB)
|
||
|
{
|
||
|
awTlLastErr = AW_TLE_BADPARMS;
|
||
|
db_logf2(("AwCreateGraphic(): ERROR: Unexpected '%c' in format string at character %u",ch,ch_off));
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
db_log5("\tParameters are OK");
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Use the parameters parsed to load the surface or texture
|
||
|
|
||
|
SurfUnion LoadFromParams(CreateTextureParms * pParams)
|
||
|
{
|
||
|
if (pParams->fileNameS)
|
||
|
{
|
||
|
pParams->fileH = CreateFile(pParams->fileNameS,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
|
||
|
|
||
|
if (INVALID_HANDLE_VALUE==pParams->fileH)
|
||
|
{
|
||
|
awTlLastErr = AW_TLE_CANTOPENFILE;
|
||
|
awTlLastWinErr = GetLastError();
|
||
|
db_logf1(("AwCreateGraphic(): ERROR opening file \"%s\"",pParams->fileNameS));
|
||
|
db_log2(AwTlErrorToString());
|
||
|
return static_cast<D3DTexture *>(NULL);
|
||
|
}
|
||
|
|
||
|
SurfUnion textureP = pParams->DoCreate();
|
||
|
|
||
|
CloseHandle(pParams->fileH);
|
||
|
|
||
|
return textureP;
|
||
|
}
|
||
|
else return pParams->DoCreate();
|
||
|
}
|
||
|
|
||
|
} // namespace AwTl
|
||
|
|
||
|
/******************************/
|
||
|
/* PUBLIC: AwSetTextureFormat */
|
||
|
/******************************/
|
||
|
|
||
|
#define IS_VALID_MEMBER(sP,mem) (reinterpret_cast<unsigned>(&(sP)->mem) - reinterpret_cast<unsigned>(sP) < static_cast<unsigned>((sP)->dwSize))
|
||
|
|
||
|
#if defined(__WATCOMC__) && (__WATCOMC__ <= 1100) // currently Watcom compiler crashes when the macro is expanded with the db_logf code in it
|
||
|
#define GET_VALID_MEMBER(sP,mem,deflt) (IS_VALID_MEMBER(sP,mem) ? (sP)->mem : (deflt))
|
||
|
#else
|
||
|
#define GET_VALID_MEMBER(sP,mem,deflt) (IS_VALID_MEMBER(sP,mem) ? (sP)->mem : (db_logf4((FUNCTION_NAME ": WARNING: %s->%s is not valid",#sP ,#mem )),(deflt)))
|
||
|
#endif
|
||
|
|
||
|
#define HANDLE_INITERROR(test,s) \
|
||
|
if (!(test)) { \
|
||
|
db_logf3((FUNCTION_NAME " failed becuse %s",s)); \
|
||
|
db_log1(FUNCTION_NAME ": ERROR: unexpected parameters"); \
|
||
|
return AW_TLE_BADPARMS; \
|
||
|
} else { \
|
||
|
db_logf5(("\t" FUNCTION_NAME " passed check '%s'",#test )); \
|
||
|
}
|
||
|
|
||
|
#define FUNCTION_NAME "AwSetD3DDevice()"
|
||
|
|
||
|
AW_TL_ERC AwSetD3DDevice(D3DDevice * _d3ddeviceP)
|
||
|
{
|
||
|
using AwTl::driverDesc;
|
||
|
|
||
|
driverDesc.validB = false;
|
||
|
|
||
|
db_logf4(("AwSetD3DDevice(%p) called",_d3ddeviceP));
|
||
|
|
||
|
HANDLE_INITERROR(_d3ddeviceP,"D3DDevice * is NULL")
|
||
|
|
||
|
D3DDEVICEDESC hw_desc;
|
||
|
D3DDEVICEDESC hel_desc;
|
||
|
INITDXSTRUCT(hw_desc);
|
||
|
INITDXSTRUCT(hel_desc);
|
||
|
|
||
|
awTlLastDxErr = _d3ddeviceP->GetCaps(&hw_desc,&hel_desc);
|
||
|
if (DD_OK != awTlLastDxErr)
|
||
|
{
|
||
|
db_logf2(("AwSetD3DDevice(): ERROR: %s",AwDxErrorToString()));
|
||
|
return AW_TLE_DXERROR;
|
||
|
}
|
||
|
|
||
|
db_log4("Direct3D Device Hardware Capabilities:");
|
||
|
db_code4(AwTl::LogCaps(&hw_desc);)
|
||
|
db_log4("Direct3D Device Emulation Capabilities:");
|
||
|
db_code4(AwTl::LogCaps(&hel_desc);)
|
||
|
|
||
|
LPD3DDEVICEDESC descP = (GET_VALID_MEMBER(&hw_desc,dwFlags,0) & D3DDD_COLORMODEL && GET_VALID_MEMBER(&hw_desc,dcmColorModel,0) & (D3DCOLOR_RGB|D3DCOLOR_MONO)) ? &hw_desc : &hel_desc;
|
||
|
db_logf4(("Direct3D Device is %s",&hw_desc==descP ? "HAL" : "emulation only"));
|
||
|
|
||
|
HANDLE_INITERROR(GET_VALID_MEMBER(descP,dwFlags,0) & D3DDD_DEVCAPS && IS_VALID_MEMBER(descP,dwDevCaps),"LPD3DDEVICEDESC::dwDevCaps is not valid")
|
||
|
HANDLE_INITERROR(descP->dwDevCaps & (D3DDEVCAPS_TEXTUREVIDEOMEMORY|D3DDEVCAPS_TEXTURENONLOCALVIDMEM|D3DDEVCAPS_TEXTURESYSTEMMEMORY),"Textures cannot be in ANY type of memory")
|
||
|
|
||
|
driverDesc.memFlag = descP->dwDevCaps & D3DDEVCAPS_TEXTURESYSTEMMEMORY ? DDSCAPS_SYSTEMMEMORY : DDSCAPS_VIDEOMEMORY;
|
||
|
driverDesc.minWidth = GET_VALID_MEMBER(descP,dwMinTextureWidth,0);
|
||
|
driverDesc.minHeight = GET_VALID_MEMBER(descP,dwMinTextureHeight,0);
|
||
|
driverDesc.maxWidth = GET_VALID_MEMBER(descP,dwMaxTextureWidth,0);
|
||
|
driverDesc.maxHeight = GET_VALID_MEMBER(descP,dwMaxTextureHeight,0);
|
||
|
driverDesc.needPow2B = GET_VALID_MEMBER(descP,dpcTriCaps.dwTextureCaps,0) & D3DPTEXTURECAPS_POW2 ? true : false;
|
||
|
driverDesc.needSquareB = GET_VALID_MEMBER(descP,dpcTriCaps.dwTextureCaps,0) & D3DPTEXTURECAPS_SQUAREONLY ? true : false;
|
||
|
// if max w and h are 0, make them as large as possible
|
||
|
if (!driverDesc.maxWidth) driverDesc.maxWidth = UINT_MAX;
|
||
|
if (!driverDesc.maxHeight) driverDesc.maxHeight = UINT_MAX;
|
||
|
|
||
|
db_log4("AwSetD3DDevice() OK");
|
||
|
|
||
|
db_log4("Direct 3D Device texture characteristics follow:");
|
||
|
db_logf4(("\tMinimum texture size: %u x %u",driverDesc.minWidth,driverDesc.minHeight));
|
||
|
db_logf4(("\tMaximum texture size: %u x %u",driverDesc.maxWidth,driverDesc.maxHeight));
|
||
|
db_logf4(("\tTextures %s be sqaure",driverDesc.needSquareB ? "must" : "need not"));
|
||
|
db_logf4(("\tTextures %s be a power of two in width and height",driverDesc.needPow2B ? "must" : "need not"));
|
||
|
db_logf4(("\tTextures can%s be in non-local video (AGP) memory",descP->dwDevCaps & D3DDEVCAPS_TEXTURENONLOCALVIDMEM ? "" : "not"));
|
||
|
db_logf4(("\tTextures can%s be in local video (device) memory",descP->dwDevCaps & D3DDEVCAPS_TEXTUREVIDEOMEMORY ? "" : "not"));
|
||
|
db_logf4(("\tTextures can%s be in system memory",descP->dwDevCaps & D3DDEVCAPS_TEXTURESYSTEMMEMORY ? "" : "not"));
|
||
|
db_logf4(("\tTextures will be in %s memory",driverDesc.memFlag & DDSCAPS_SYSTEMMEMORY ? "system" : "video"));
|
||
|
|
||
|
driverDesc.validB = true;
|
||
|
|
||
|
return AW_TLE_OK;
|
||
|
}
|
||
|
|
||
|
AW_TL_ERC AwSetDDObject(DDObject * _ddP)
|
||
|
{
|
||
|
using AwTl::driverDesc;
|
||
|
|
||
|
db_logf4(("AwSetDDObject(%p) called.",_ddP));
|
||
|
#ifdef DIRECTDRAW_VERSION
|
||
|
db_logf4(("\tCompiled with DirectDraw Version %u.%u",DIRECTDRAW_VERSION/0x100U,DIRECTDRAW_VERSION%0x100U));
|
||
|
#else
|
||
|
db_log4("\tCompiled with unknown DirectDraw version");
|
||
|
#endif
|
||
|
|
||
|
|
||
|
HANDLE_INITERROR(_ddP,"DDObject * is NULL")
|
||
|
driverDesc.ddP = _ddP;
|
||
|
|
||
|
return AW_TLE_OK;
|
||
|
}
|
||
|
|
||
|
AW_TL_ERC AwSetD3DDevice(DDObject * _ddP, D3DDevice * _d3ddeviceP)
|
||
|
{
|
||
|
db_logf4(("AwSetD3DDevice(%p,%p) called",_ddP,_d3ddeviceP));
|
||
|
|
||
|
AW_TL_ERC iResult = AwSetDDObject(_ddP);
|
||
|
|
||
|
if (AW_TLE_OK != iResult)
|
||
|
return iResult;
|
||
|
else
|
||
|
return AwSetD3DDevice(_d3ddeviceP);
|
||
|
}
|
||
|
|
||
|
#undef FUNCTION_NAME
|
||
|
#define FUNCTION_NAME "AwSetPixelFormat()"
|
||
|
static AW_TL_ERC AwSetPixelFormat(AwTl::PixelFormat * _pfP, LPDDPIXELFORMAT _ddpfP)
|
||
|
{
|
||
|
using AwTl::SetBitShifts;
|
||
|
|
||
|
_pfP->validB = false;
|
||
|
|
||
|
// parameter check
|
||
|
HANDLE_INITERROR(_ddpfP,"DDPIXELFORMAT is NULL")
|
||
|
HANDLE_INITERROR(IS_VALID_MEMBER(_ddpfP,dwFlags),"DDPIXELFORMAT::dwFlags is an invalid field")
|
||
|
HANDLE_INITERROR(!(_ddpfP->dwFlags & DDPF_ALPHA),"DDPIXELFORMAT describes an alpha only surface")
|
||
|
HANDLE_INITERROR(!(_ddpfP->dwFlags & DDPF_PALETTEINDEXEDTO8),"DDPIXELFORMAT describes a 1- 2- or 4- bit surface indexed to an 8-bit palette. This is not yet supported")
|
||
|
HANDLE_INITERROR(!(_ddpfP->dwFlags & DDPF_ZBUFFER),"DDPIXELFORMAT describes Z buffer")
|
||
|
HANDLE_INITERROR(!(_ddpfP->dwFlags & DDPF_ZPIXELS),"DDPIXELFORMAT describes a RGBZ surface")
|
||
|
HANDLE_INITERROR(!(_ddpfP->dwFlags & DDPF_YUV),"DDPIXELFORMAT describes a YUV surface. This is not yet supported")
|
||
|
HANDLE_INITERROR(!(_ddpfP->dwFlags & DDPF_FOURCC),"DDPIXELFORMAT gives a FourCC code for a non RGB surface. This is not yet supported")
|
||
|
|
||
|
_pfP->palettizedB = true;
|
||
|
switch (_ddpfP->dwFlags & (DDPF_PALETTEINDEXED8|DDPF_PALETTEINDEXED4|DDPF_PALETTEINDEXED2|DDPF_PALETTEINDEXED1))
|
||
|
{
|
||
|
case 0:
|
||
|
_pfP->palettizedB = false;
|
||
|
break;
|
||
|
case DDPF_PALETTEINDEXED1:
|
||
|
_pfP->bitsPerPixel = 1;
|
||
|
break;
|
||
|
case DDPF_PALETTEINDEXED2:
|
||
|
_pfP->bitsPerPixel = 2;
|
||
|
break;
|
||
|
case DDPF_PALETTEINDEXED4:
|
||
|
_pfP->bitsPerPixel = 4;
|
||
|
break;
|
||
|
case DDPF_PALETTEINDEXED8:
|
||
|
_pfP->bitsPerPixel = 8;
|
||
|
break;
|
||
|
default:
|
||
|
db_log1("AwSetPixelFormat(): ERROR: more than one DDPF_PALETTEINDEXED<n> flags is set");
|
||
|
return AW_TLE_BADPARMS;
|
||
|
}
|
||
|
|
||
|
_pfP->alphaB = _ddpfP->dwFlags & DDPF_ALPHAPIXELS ? true : false;
|
||
|
|
||
|
if (_pfP->palettizedB)
|
||
|
{
|
||
|
HANDLE_INITERROR(!_pfP->alphaB,"alpha channel info is on a palettized format. This is not yet supported")
|
||
|
#if DB_LEVEL >= 4
|
||
|
if (_ddpfP->dwFlags & DDPF_RGB)
|
||
|
{
|
||
|
db_log4(FUNCTION_NAME ": WARNING: RGB data supplied for a palettized format is ignored");
|
||
|
db_logf4(("\tRGB bitcount is %u",GET_VALID_MEMBER(_ddpfP,dwRGBBitCount,0)));
|
||
|
db_logf4(("\tRed Mask is 0x%08x",GET_VALID_MEMBER(_ddpfP,dwRBitMask,0)));
|
||
|
db_logf4(("\tGreen Mask is 0x%08x",GET_VALID_MEMBER(_ddpfP,dwGBitMask,0)));
|
||
|
db_logf4(("\tBlue Mask is 0x%08x",GET_VALID_MEMBER(_ddpfP,dwBBitMask,0)));
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HANDLE_INITERROR(IS_VALID_MEMBER(_ddpfP,dwRGBBitCount),"DDPIXELFORMAT::dwRGBBitCount is an invalid field")
|
||
|
switch (_ddpfP->dwRGBBitCount)
|
||
|
{
|
||
|
case 4:
|
||
|
case 8:
|
||
|
case 16:
|
||
|
case 24:
|
||
|
case 32:
|
||
|
break;
|
||
|
default:
|
||
|
db_log1("AwSetPixelFormat(): ERROR: RGB bit count is not 4,8,16,24 or 32");
|
||
|
return AW_TLE_BADPARMS;
|
||
|
}
|
||
|
|
||
|
HANDLE_INITERROR(!_pfP->alphaB || GET_VALID_MEMBER(_ddpfP,dwRGBAlphaBitMask,0),"Pixel format specifies alpha channel info but alpha mask is zero")
|
||
|
HANDLE_INITERROR(IS_VALID_MEMBER(_ddpfP,dwRBitMask),"DDPIXELFORMAT::dwRBitMask is an invalid field")
|
||
|
HANDLE_INITERROR(IS_VALID_MEMBER(_ddpfP,dwGBitMask),"DDPIXELFORMAT::dwGBitMask is an invalid field")
|
||
|
HANDLE_INITERROR(IS_VALID_MEMBER(_ddpfP,dwBBitMask),"DDPIXELFORMAT::dwBBitMask is an invalid field")
|
||
|
|
||
|
_pfP->bitsPerPixel = _ddpfP->dwRGBBitCount;
|
||
|
SetBitShifts(&_pfP->redLeftShift,&_pfP->redRightShift,_ddpfP->dwRBitMask);
|
||
|
SetBitShifts(&_pfP->greenLeftShift,&_pfP->greenRightShift,_ddpfP->dwGBitMask);
|
||
|
SetBitShifts(&_pfP->blueLeftShift,&_pfP->blueRightShift,_ddpfP->dwBBitMask);
|
||
|
}
|
||
|
ZEROFILL(_pfP->ddpf);
|
||
|
memcpy(&_pfP->ddpf,_ddpfP,__min(_ddpfP->dwSize,sizeof(DDPIXELFORMAT)));
|
||
|
if (!_pfP->alphaB)
|
||
|
_pfP->ddpf.dwRGBAlphaBitMask = 0;
|
||
|
|
||
|
db_log4("AwSetPixelFormat() OK");
|
||
|
|
||
|
#if DB_LEVEL >= 4
|
||
|
db_logf4(("Pixel Format is %u-bit %s",_pfP->bitsPerPixel,_pfP->palettizedB ? "palettized" : _pfP->alphaB ? "RGBA" : "RGB"));
|
||
|
if (!_pfP->palettizedB)
|
||
|
{
|
||
|
if (_pfP->alphaB)
|
||
|
{
|
||
|
unsigned alpha_l_shft,alpha_r_shft;
|
||
|
SetBitShifts(&alpha_l_shft,&alpha_r_shft,_pfP->ddpf.dwRGBAlphaBitMask);
|
||
|
db_logf4(("\t%u-%u-%u-%u",8-_pfP->redRightShift,8-_pfP->greenRightShift,8-_pfP->blueRightShift,8-alpha_r_shft));
|
||
|
db_logf4(("\tAlpha->[%u..%u]",alpha_l_shft+7-alpha_r_shft,alpha_l_shft));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
db_logf4(("\t%u-%u-%u",8-_pfP->redRightShift,8-_pfP->greenRightShift,8-_pfP->blueRightShift));
|
||
|
}
|
||
|
db_logf4(("\tRed->[%u..%u]",_pfP->redLeftShift+7-_pfP->redRightShift,_pfP->redLeftShift));
|
||
|
db_logf4(("\tGreen->[%u..%u]",_pfP->greenLeftShift+7-_pfP->greenRightShift,_pfP->greenLeftShift));
|
||
|
db_logf4(("\tBlue->[%u..%u]",_pfP->blueLeftShift+7-_pfP->blueRightShift,_pfP->blueLeftShift));
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
_pfP->validB = true;
|
||
|
return AW_TLE_OK;
|
||
|
}
|
||
|
|
||
|
AW_TL_ERC AwSetTextureFormat2(LPDDPIXELFORMAT _ddpfP)
|
||
|
{
|
||
|
db_logf4(("AwSetTextureFormat(%p) called",_ddpfP));
|
||
|
|
||
|
using namespace AwTl;
|
||
|
|
||
|
while (listTextureFormats.size())
|
||
|
listTextureFormats.delete_first_entry();
|
||
|
|
||
|
return AwSetPixelFormat(&pfTextureFormat, _ddpfP);
|
||
|
}
|
||
|
|
||
|
AW_TL_ERC AwSetAdditionalTextureFormat2(LPDDPIXELFORMAT _ddpfP, unsigned _maxAlphaBits, int _canDoTransp, unsigned _maxColours)
|
||
|
{
|
||
|
db_logf4(("AwSetAdditionalTextureFormat(%p.%u,%d,%u) called",_ddpfP,_maxAlphaBits,_canDoTransp,_maxColours));
|
||
|
|
||
|
using namespace AwTl;
|
||
|
|
||
|
AdditionalPixelFormat pf;
|
||
|
|
||
|
AW_TL_ERC erc = AwSetPixelFormat(&pf, _ddpfP);
|
||
|
|
||
|
if (AW_TLE_OK == erc)
|
||
|
{
|
||
|
pf.canDoTranspB = _canDoTransp ? true : false;
|
||
|
pf.maxColours = _maxColours;
|
||
|
|
||
|
listTextureFormats.add_entry_end(pf);
|
||
|
}
|
||
|
|
||
|
return erc;
|
||
|
}
|
||
|
|
||
|
AW_TL_ERC AwSetSurfaceFormat2(LPDDPIXELFORMAT _ddpfP)
|
||
|
{
|
||
|
db_logf4(("AwSetSurfaceFormat(%p) called",_ddpfP));
|
||
|
|
||
|
using namespace AwTl;
|
||
|
|
||
|
return AwSetPixelFormat(&pfSurfaceFormat, _ddpfP);
|
||
|
}
|
||
|
|
||
|
/****************************/
|
||
|
/* PUBLIC: AwGetTextureSize */
|
||
|
/****************************/
|
||
|
|
||
|
AW_TL_ERC AwGetTextureSize(register unsigned * _widthP, register unsigned * _heightP, unsigned _width, unsigned _height)
|
||
|
{
|
||
|
db_assert1(_widthP);
|
||
|
db_assert1(_heightP);
|
||
|
|
||
|
using AwTl::driverDesc;
|
||
|
|
||
|
if (!driverDesc.validB)
|
||
|
{
|
||
|
db_log3("AwGetTextureSize(): ERROR: driver description not valid");
|
||
|
return AW_TLE_NOINIT;
|
||
|
}
|
||
|
|
||
|
if (_width < driverDesc.minWidth) _width = driverDesc.minWidth;
|
||
|
if (_height < driverDesc.minHeight) _height = driverDesc.minHeight;
|
||
|
|
||
|
if (driverDesc.needPow2B)
|
||
|
{
|
||
|
*_widthP = 1;
|
||
|
while (*_widthP < _width) *_widthP <<= 1;
|
||
|
*_heightP = 1;
|
||
|
while (*_heightP < _height) *_heightP <<= 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*_widthP = _width;
|
||
|
*_heightP = _height;
|
||
|
}
|
||
|
|
||
|
if (driverDesc.needSquareB)
|
||
|
{
|
||
|
if (*_widthP < *_heightP) *_widthP = *_heightP;
|
||
|
else *_heightP = *_widthP;
|
||
|
}
|
||
|
|
||
|
#if 1 // not sure if this is required...
|
||
|
*_widthP += 3;
|
||
|
*_widthP &= ~3;
|
||
|
*_heightP += 3;
|
||
|
*_heightP &= ~3;
|
||
|
#endif
|
||
|
|
||
|
db_logf4(("\tAwGetTextureSize(): d3d texture will be %ux%u",*_widthP,*_heightP));
|
||
|
|
||
|
if (*_widthP > driverDesc.maxWidth || *_heightP > driverDesc.maxHeight)
|
||
|
{
|
||
|
db_log3("AwGetTextureSize(): ERROR: image size too large to be a d3d texture");
|
||
|
return AW_TLE_IMAGETOOLARGE;
|
||
|
}
|
||
|
else return AW_TLE_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
/******************************/
|
||
|
/* PUBLIC: AwCreate functions */
|
||
|
/******************************/
|
||
|
|
||
|
D3DTexture * _AWTL_VARARG AwCreateTexture(char const * _argFormatS, ...)
|
||
|
{
|
||
|
db_logf4(("AwCreateTexture(\"%s\") called",_argFormatS));
|
||
|
|
||
|
using namespace AwTl;
|
||
|
|
||
|
va_list ap;
|
||
|
va_start(ap,_argFormatS);
|
||
|
CreateTextureParms parms;
|
||
|
parms.loadTextureB = true;
|
||
|
bool bParmsOK = ParseParams(&parms, _argFormatS, ap);
|
||
|
va_end(ap);
|
||
|
return bParmsOK ? LoadFromParams(&parms).textureP : NULL;
|
||
|
}
|
||
|
|
||
|
DDSurface * _AWTL_VARARG AwCreateSurface(char const * _argFormatS, ...)
|
||
|
{
|
||
|
db_logf4(("AwCreateSurface(\"%s\") called",_argFormatS));
|
||
|
|
||
|
using namespace AwTl;
|
||
|
|
||
|
va_list ap;
|
||
|
va_start(ap,_argFormatS);
|
||
|
CreateTextureParms parms;
|
||
|
parms.loadTextureB = false;
|
||
|
bool bParmsOK = ParseParams(&parms, _argFormatS, ap);
|
||
|
va_end(ap);
|
||
|
return bParmsOK ? LoadFromParams(&parms).surfaceP : NULL;
|
||
|
}
|
||
|
|
||
|
AW_TL_ERC AwDestroyBackupTexture(AW_BACKUPTEXTUREHANDLE _bH)
|
||
|
{
|
||
|
db_logf4(("AwDestroyBackupTexture(0x%08x) called",_bH));
|
||
|
if (_bH)
|
||
|
{
|
||
|
_bH->Release();
|
||
|
return AW_TLE_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
db_log1("AwDestroyBackupTexture(): ERROR: AW_BACKUPTEXTUREHANDLE==NULL");
|
||
|
return AW_TLE_BADPARMS;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*********************************/
|
||
|
/* PUBLIC DEBUG: LastErr globals */
|
||
|
/*********************************/
|
||
|
|
||
|
AW_TL_ERC awTlLastErr;
|
||
|
HRESULT awTlLastDxErr;
|
||
|
DWORD awTlLastWinErr;
|
||
|
|
||
|
/*******************************************/
|
||
|
/* PUBLIC DEBUG: AwErrorToString functions */
|
||
|
/*******************************************/
|
||
|
|
||
|
#ifndef NDEBUG
|
||
|
char const * AwWinErrorToString(DWORD error)
|
||
|
{
|
||
|
if (NO_ERROR==error) return "No error";
|
||
|
static TCHAR buffer[1024];
|
||
|
if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,error,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),buffer,sizeof buffer/sizeof(TCHAR)-1,NULL))
|
||
|
wsprintf(buffer,TEXT("FormatMessage() failed; previous Windows error code: 0x%08X"),error);
|
||
|
for (TCHAR * bufP = buffer; *bufP; ++bufP)
|
||
|
{
|
||
|
switch (*bufP)
|
||
|
{
|
||
|
case '\n':
|
||
|
case '\r':
|
||
|
*bufP=' ';
|
||
|
}
|
||
|
}
|
||
|
return reinterpret_cast<char *>(buffer);
|
||
|
}
|
||
|
|
||
|
char const * AwTlErrorToString(AwTlErc error)
|
||
|
{
|
||
|
char const * defaultS;
|
||
|
switch (error)
|
||
|
{
|
||
|
case AW_TLE_OK:
|
||
|
return "No error";
|
||
|
case AW_TLE_DXERROR:
|
||
|
if (DD_OK==awTlLastDxErr)
|
||
|
return "Unknown DirectX error";
|
||
|
else
|
||
|
return AwDxErrorToString();
|
||
|
case AW_TLE_BADPARMS:
|
||
|
return "Invalid parameters or functionality not supported";
|
||
|
case AW_TLE_NOINIT:
|
||
|
return "Initialization failed or not performed";
|
||
|
case AW_TLE_CANTOPENFILE:
|
||
|
defaultS = "Unknown error opening file";
|
||
|
goto WIN_ERR;
|
||
|
case AW_TLE_CANTREADFILE:
|
||
|
defaultS = "Unknown error reading file";
|
||
|
WIN_ERR:
|
||
|
if (NO_ERROR==awTlLastWinErr)
|
||
|
return defaultS;
|
||
|
else
|
||
|
return AwWinErrorToString();
|
||
|
case AW_TLE_EOFMET:
|
||
|
return "Unexpected end of file during texture load";
|
||
|
case AW_TLE_BADFILEFORMAT:
|
||
|
return "Texture file format not recognized";
|
||
|
case AW_TLE_BADFILEDATA:
|
||
|
return "Texture file data not consistent";
|
||
|
case AW_TLE_CANTPALETTIZE:
|
||
|
return "Texture file data not palettized";
|
||
|
case AW_TLE_IMAGETOOLARGE:
|
||
|
return "Image is too large for a texture";
|
||
|
case AW_TLE_CANTRELOAD:
|
||
|
return "New image is wrong size or format to load into existing texture";
|
||
|
default:
|
||
|
return "Unknown texture loading error";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
char const * AwDxErrorToString(HRESULT error)
|
||
|
{
|
||
|
switch(error) {
|
||
|
case DD_OK:
|
||
|
return "No error.\0";
|
||
|
case DDERR_ALREADYINITIALIZED:
|
||
|
return "This object is already initialized.\0";
|
||
|
case DDERR_BLTFASTCANTCLIP:
|
||
|
return "Return if a clipper object is attached to the source surface passed into a BltFast call.\0";
|
||
|
case DDERR_CANNOTATTACHSURFACE:
|
||
|
return "This surface can not be attached to the requested surface.\0";
|
||
|
case DDERR_CANNOTDETACHSURFACE:
|
||
|
return "This surface can not be detached from the requested surface.\0";
|
||
|
case DDERR_CANTCREATEDC:
|
||
|
return "Windows can not create any more DCs.\0";
|
||
|
case DDERR_CANTDUPLICATE:
|
||
|
return "Can't duplicate primary & 3D surfaces, or surfaces that are implicitly created.\0";
|
||
|
case DDERR_CLIPPERISUSINGHWND:
|
||
|
return "An attempt was made to set a cliplist for a clipper object that is already monitoring an hwnd.\0";
|
||
|
case DDERR_COLORKEYNOTSET:
|
||
|
return "No src color key specified for this operation.\0";
|
||
|
case DDERR_CURRENTLYNOTAVAIL:
|
||
|
return "Support is currently not available.\0";
|
||
|
case DDERR_DIRECTDRAWALREADYCREATED:
|
||
|
return "A DirectDraw object representing this driver has already been created for this process.\0";
|
||
|
case DDERR_EXCEPTION:
|
||
|
return "An exception was encountered while performing the requested operation.\0";
|
||
|
case DDERR_EXCLUSIVEMODEALREADYSET:
|
||
|
return "An attempt was made to set the cooperative level when it was already set to exclusive.\0";
|
||
|
case DDERR_GENERIC:
|
||
|
return "Generic failure.\0";
|
||
|
case DDERR_HEIGHTALIGN:
|
||
|
return "Height of rectangle provided is not a multiple of reqd alignment.\0";
|
||
|
case DDERR_HWNDALREADYSET:
|
||
|
return "The CooperativeLevel HWND has already been set. It can not be reset while the process has surfaces or palettes created.\0";
|
||
|
case DDERR_HWNDSUBCLASSED:
|
||
|
return "HWND used by DirectDraw CooperativeLevel has been subclassed, this prevents DirectDraw from restoring state.\0";
|
||
|
case DDERR_IMPLICITLYCREATED:
|
||
|
return "This surface can not be restored because it is an implicitly created surface.\0";
|
||
|
case DDERR_INCOMPATIBLEPRIMARY:
|
||
|
return "Unable to match primary surface creation request with existing primary surface.\0";
|
||
|
case DDERR_INVALIDCAPS:
|
||
|
return "One or more of the caps bits passed to the callback are incorrect.\0";
|
||
|
case DDERR_INVALIDCLIPLIST:
|
||
|
return "DirectDraw does not support the provided cliplist.\0";
|
||
|
case DDERR_INVALIDDIRECTDRAWGUID:
|
||
|
return "The GUID passed to DirectDrawCreate is not a valid DirectDraw driver identifier.\0";
|
||
|
case DDERR_INVALIDMODE:
|
||
|
return "DirectDraw does not support the requested mode.\0";
|
||
|
case DDERR_INVALIDOBJECT:
|
||
|
return "DirectDraw received a pointer that was an invalid DIRECTDRAW object.\0";
|
||
|
case DDERR_INVALIDPARAMS:
|
||
|
return "One or more of the parameters passed to the function are incorrect.\0";
|
||
|
case DDERR_INVALIDPIXELFORMAT:
|
||
|
return "The pixel format was invalid as specified.\0";
|
||
|
case DDERR_INVALIDPOSITION:
|
||
|
return "Returned when the position of the overlay on the destination is no longer legal for that destination.\0";
|
||
|
case DDERR_INVALIDRECT:
|
||
|
return "Rectangle provided was invalid.\0";
|
||
|
case DDERR_LOCKEDSURFACES:
|
||
|
return "Operation could not be carried out because one or more surfaces are locked.\0";
|
||
|
case DDERR_NO3D:
|
||
|
return "There is no 3D present.\0";
|
||
|
case DDERR_NOALPHAHW:
|
||
|
return "Operation could not be carried out because there is no alpha accleration hardware present or available.\0";
|
||
|
case DDERR_NOBLTHW:
|
||
|
return "No blitter hardware present.\0";
|
||
|
case DDERR_NOCLIPLIST:
|
||
|
return "No cliplist available.\0";
|
||
|
case DDERR_NOCLIPPERATTACHED:
|
||
|
return "No clipper object attached to surface object.\0";
|
||
|
case DDERR_NOCOLORCONVHW:
|
||
|
return "Operation could not be carried out because there is no color conversion hardware present or available.\0";
|
||
|
case DDERR_NOCOLORKEY:
|
||
|
return "Surface doesn't currently have a color key\0";
|
||
|
case DDERR_NOCOLORKEYHW:
|
||
|
return "Operation could not be carried out because there is no hardware support of the destination color key.\0";
|
||
|
case DDERR_NOCOOPERATIVELEVELSET:
|
||
|
return "Create function called without DirectDraw object method SetCooperativeLevel being called.\0";
|
||
|
case DDERR_NODC:
|
||
|
return "No DC was ever created for this surface.\0";
|
||
|
case DDERR_NODDROPSHW:
|
||
|
return "No DirectDraw ROP hardware.\0";
|
||
|
case DDERR_NODIRECTDRAWHW:
|
||
|
return "A hardware-only DirectDraw object creation was attempted but the driver did not support any hardware.\0";
|
||
|
case DDERR_NOEMULATION:
|
||
|
return "Software emulation not available.\0";
|
||
|
case DDERR_NOEXCLUSIVEMODE:
|
||
|
return "Operation requires the application to have exclusive mode but the application does not have exclusive mode.\0";
|
||
|
case DDERR_NOFLIPHW:
|
||
|
return "Flipping visible surfaces is not supported.\0";
|
||
|
case DDERR_NOGDI:
|
||
|
return "There is no GDI present.\0";
|
||
|
case DDERR_NOHWND:
|
||
|
return "Clipper notification requires an HWND or no HWND has previously been set as the CooperativeLevel HWND.\0";
|
||
|
case DDERR_NOMIRRORHW:
|
||
|
return "Operation could not be carried out because there is no hardware present or available.\0";
|
||
|
case DDERR_NOOVERLAYDEST:
|
||
|
return "Returned when GetOverlayPosition is called on an overlay that UpdateOverlay has never been called on to establish a destination.\0";
|
||
|
case DDERR_NOOVERLAYHW:
|
||
|
return "Operation could not be carried out because there is no overlay hardware present or available.\0";
|
||
|
case DDERR_NOPALETTEATTACHED:
|
||
|
return "No palette object attached to this surface.\0";
|
||
|
case DDERR_NOPALETTEHW:
|
||
|
return "No hardware support for 16 or 256 color palettes.\0";
|
||
|
case DDERR_NORASTEROPHW:
|
||
|
return "Operation could not be carried out because there is no appropriate raster op hardware present or available.\0";
|
||
|
case DDERR_NOROTATIONHW:
|
||
|
return "Operation could not be carried out because there is no rotation hardware present or available.\0";
|
||
|
case DDERR_NOSTRETCHHW:
|
||
|
return "Operation could not be carried out because there is no hardware support for stretching.\0";
|
||
|
case DDERR_NOT4BITCOLOR:
|
||
|
return "DirectDrawSurface is not in 4 bit color palette and the requested operation requires 4 bit color palette.\0";
|
||
|
case DDERR_NOT4BITCOLORINDEX:
|
||
|
return "DirectDrawSurface is not in 4 bit color index palette and the requested operation requires 4 bit color index palette.\0";
|
||
|
case DDERR_NOT8BITCOLOR:
|
||
|
return "DirectDrawSurface is not in 8 bit color mode and the requested operation requires 8 bit color.\0";
|
||
|
case DDERR_NOTAOVERLAYSURFACE:
|
||
|
return "Returned when an overlay member is called for a non-overlay surface.\0";
|
||
|
case DDERR_NOTEXTUREHW:
|
||
|
return "Operation could not be carried out because there is no texture mapping hardware present or available.\0";
|
||
|
case DDERR_NOTFLIPPABLE:
|
||
|
return "An attempt has been made to flip a surface that is not flippable.\0";
|
||
|
case DDERR_NOTFOUND:
|
||
|
return "Requested item was not found.\0";
|
||
|
case DDERR_NOTLOCKED:
|
||
|
return "Surface was not locked. An attempt to unlock a surface that was not locked at all, or by this process, has been attempted.\0";
|
||
|
case DDERR_NOTPALETTIZED:
|
||
|
return "The surface being used is not a palette-based surface.\0";
|
||
|
case DDERR_NOVSYNCHW:
|
||
|
return "Operation could not be carried out because there is no hardware support for vertical blank synchronized operations.\0";
|
||
|
case DDERR_NOZBUFFERHW:
|
||
|
return "Operation could not be carried out because there is no hardware support for zbuffer blitting.\0";
|
||
|
case DDERR_NOZOVERLAYHW:
|
||
|
return "Overlay surfaces could not be z layered based on their BltOrder because the hardware does not support z layering of overlays.\0";
|
||
|
case DDERR_OUTOFCAPS:
|
||
|
return "The hardware needed for the requested operation has already been allocated.\0";
|
||
|
case DDERR_OUTOFMEMORY:
|
||
|
return "DirectDraw does not have enough memory to perform the operation.\0";
|
||
|
case DDERR_OUTOFVIDEOMEMORY:
|
||
|
return "DirectDraw does not have enough video memory to perform the operation.\0";
|
||
|
case DDERR_OVERLAYCANTCLIP:
|
||
|
return "The hardware does not support clipped overlays.\0";
|
||
|
case DDERR_OVERLAYCOLORKEYONLYONEACTIVE:
|
||
|
return "Can only have ony color key active at one time for overlays.\0";
|
||
|
case DDERR_OVERLAYNOTVISIBLE:
|
||
|
return "Returned when GetOverlayPosition is called on a hidden overlay.\0";
|
||
|
case DDERR_PALETTEBUSY:
|
||
|
return "Access to this palette is being refused because the palette is already locked by another thread.\0";
|
||
|
case DDERR_PRIMARYSURFACEALREADYEXISTS:
|
||
|
return "This process already has created a primary surface.\0";
|
||
|
case DDERR_REGIONTOOSMALL:
|
||
|
return "Region passed to Clipper::GetClipList is too small.\0";
|
||
|
case DDERR_SURFACEALREADYATTACHED:
|
||
|
return "This surface is already attached to the surface it is being attached to.\0";
|
||
|
case DDERR_SURFACEALREADYDEPENDENT:
|
||
|
return "This surface is already a dependency of the surface it is being made a dependency of.\0";
|
||
|
case DDERR_SURFACEBUSY:
|
||
|
return "Access to this surface is being refused because the surface is already locked by another thread.\0";
|
||
|
case DDERR_SURFACEISOBSCURED:
|
||
|
return "Access to surface refused because the surface is obscured.\0";
|
||
|
case DDERR_SURFACELOST:
|
||
|
return "Access to this surface is being refused because the surface memory is gone. The DirectDrawSurface object representing this surface should have Restore called on it.\0";
|
||
|
case DDERR_SURFACENOTATTACHED:
|
||
|
return "The requested surface is not attached.\0";
|
||
|
case DDERR_TOOBIGHEIGHT:
|
||
|
return "Height requested by DirectDraw is too large.\0";
|
||
|
case DDERR_TOOBIGSIZE:
|
||
|
return "Size requested by DirectDraw is too large, but the individual height and width are OK.\0";
|
||
|
case DDERR_TOOBIGWIDTH:
|
||
|
return "Width requested by DirectDraw is too large.\0";
|
||
|
case DDERR_UNSUPPORTED:
|
||
|
return "Action not supported.\0";
|
||
|
case DDERR_UNSUPPORTEDFORMAT:
|
||
|
return "FOURCC format requested is unsupported by DirectDraw.\0";
|
||
|
case DDERR_UNSUPPORTEDMASK:
|
||
|
return "Bitmask in the pixel format requested is unsupported by DirectDraw.\0";
|
||
|
case DDERR_VERTICALBLANKINPROGRESS:
|
||
|
return "Vertical blank is in progress.\0";
|
||
|
case DDERR_WASSTILLDRAWING:
|
||
|
return "Informs DirectDraw that the previous Blt which is transfering information to or from this Surface is incomplete.\0";
|
||
|
case DDERR_WRONGMODE:
|
||
|
return "This surface can not be restored because it was created in a different mode.\0";
|
||
|
case DDERR_XALIGN:
|
||
|
return "Rectangle provided was not horizontally aligned on required boundary.\0";
|
||
|
case D3DERR_BADMAJORVERSION:
|
||
|
return "D3DERR_BADMAJORVERSION\0";
|
||
|
case D3DERR_BADMINORVERSION:
|
||
|
return "D3DERR_BADMINORVERSION\0";
|
||
|
case D3DERR_EXECUTE_LOCKED:
|
||
|
return "D3DERR_EXECUTE_LOCKED\0";
|
||
|
case D3DERR_EXECUTE_NOT_LOCKED:
|
||
|
return "D3DERR_EXECUTE_NOT_LOCKED\0";
|
||
|
case D3DERR_EXECUTE_CREATE_FAILED:
|
||
|
return "D3DERR_EXECUTE_CREATE_FAILED\0";
|
||
|
case D3DERR_EXECUTE_DESTROY_FAILED:
|
||
|
return "D3DERR_EXECUTE_DESTROY_FAILED\0";
|
||
|
case D3DERR_EXECUTE_LOCK_FAILED:
|
||
|
return "D3DERR_EXECUTE_LOCK_FAILED\0";
|
||
|
case D3DERR_EXECUTE_UNLOCK_FAILED:
|
||
|
return "D3DERR_EXECUTE_UNLOCK_FAILED\0";
|
||
|
case D3DERR_EXECUTE_FAILED:
|
||
|
return "D3DERR_EXECUTE_FAILED\0";
|
||
|
case D3DERR_EXECUTE_CLIPPED_FAILED:
|
||
|
return "D3DERR_EXECUTE_CLIPPED_FAILED\0";
|
||
|
case D3DERR_TEXTURE_NO_SUPPORT:
|
||
|
return "D3DERR_TEXTURE_NO_SUPPORT\0";
|
||
|
case D3DERR_TEXTURE_NOT_LOCKED:
|
||
|
return "D3DERR_TEXTURE_NOT_LOCKED\0";
|
||
|
case D3DERR_TEXTURE_LOCKED:
|
||
|
return "D3DERR_TEXTURE_LOCKED\0";
|
||
|
case D3DERR_TEXTURE_CREATE_FAILED:
|
||
|
return "D3DERR_TEXTURE_CREATE_FAILED\0";
|
||
|
case D3DERR_TEXTURE_DESTROY_FAILED:
|
||
|
return "D3DERR_TEXTURE_DESTROY_FAILED\0";
|
||
|
case D3DERR_TEXTURE_LOCK_FAILED:
|
||
|
return "D3DERR_TEXTURE_LOCK_FAILED\0";
|
||
|
case D3DERR_TEXTURE_UNLOCK_FAILED:
|
||
|
return "D3DERR_TEXTURE_UNLOCK_FAILED\0";
|
||
|
case D3DERR_TEXTURE_LOAD_FAILED:
|
||
|
return "D3DERR_TEXTURE_LOAD_FAILED\0";
|
||
|
case D3DERR_MATRIX_CREATE_FAILED:
|
||
|
return "D3DERR_MATRIX_CREATE_FAILED\0";
|
||
|
case D3DERR_MATRIX_DESTROY_FAILED:
|
||
|
return "D3DERR_MATRIX_DESTROY_FAILED\0";
|
||
|
case D3DERR_MATRIX_SETDATA_FAILED:
|
||
|
return "D3DERR_MATRIX_SETDATA_FAILED\0";
|
||
|
case D3DERR_SETVIEWPORTDATA_FAILED:
|
||
|
return "D3DERR_SETVIEWPORTDATA_FAILED\0";
|
||
|
case D3DERR_MATERIAL_CREATE_FAILED:
|
||
|
return "D3DERR_MATERIAL_CREATE_FAILED\0";
|
||
|
case D3DERR_MATERIAL_DESTROY_FAILED:
|
||
|
return "D3DERR_MATERIAL_DESTROY_FAILED\0";
|
||
|
case D3DERR_MATERIAL_SETDATA_FAILED:
|
||
|
return "D3DERR_MATERIAL_SETDATA_FAILED\0";
|
||
|
case D3DERR_LIGHT_SET_FAILED:
|
||
|
return "D3DERR_LIGHT_SET_FAILED\0";
|
||
|
#if 0 // retained mode error codes
|
||
|
case D3DRMERR_BADOBJECT:
|
||
|
return "D3DRMERR_BADOBJECT\0";
|
||
|
case D3DRMERR_BADTYPE:
|
||
|
return "D3DRMERR_BADTYPE\0";
|
||
|
case D3DRMERR_BADALLOC:
|
||
|
return "D3DRMERR_BADALLOC\0";
|
||
|
case D3DRMERR_FACEUSED:
|
||
|
return "D3DRMERR_FACEUSED\0";
|
||
|
case D3DRMERR_NOTFOUND:
|
||
|
return "D3DRMERR_NOTFOUND\0";
|
||
|
case D3DRMERR_NOTDONEYET:
|
||
|
return "D3DRMERR_NOTDONEYET\0";
|
||
|
case D3DRMERR_FILENOTFOUND:
|
||
|
return "The file was not found.\0";
|
||
|
case D3DRMERR_BADFILE:
|
||
|
return "D3DRMERR_BADFILE\0";
|
||
|
case D3DRMERR_BADDEVICE:
|
||
|
return "D3DRMERR_BADDEVICE\0";
|
||
|
case D3DRMERR_BADVALUE:
|
||
|
return "D3DRMERR_BADVALUE\0";
|
||
|
case D3DRMERR_BADMAJORVERSION:
|
||
|
return "D3DRMERR_BADMAJORVERSION\0";
|
||
|
case D3DRMERR_BADMINORVERSION:
|
||
|
return "D3DRMERR_BADMINORVERSION\0";
|
||
|
case D3DRMERR_UNABLETOEXECUTE:
|
||
|
return "D3DRMERR_UNABLETOEXECUTE\0";
|
||
|
#endif
|
||
|
default:
|
||
|
return "Unrecognized error value.\0";
|
||
|
}
|
||
|
}
|
||
|
#endif
|