You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
381 lines
12 KiB
381 lines
12 KiB
namespace RGB_RAST_LIB_NAMESPACE
|
|
{
|
|
void MemFill( UINT32 uiData, void* pData, UINT32 uiBytes) throw();
|
|
void MemMask( UINT32 uiData, UINT32 uiMask, void* pData, UINT32 uiBytes) throw();
|
|
|
|
class IRGBSurface: public IVidMemSurface
|
|
{
|
|
protected:
|
|
LONG m_lPitch;
|
|
WORD m_wWidth;
|
|
WORD m_wHeight;
|
|
unsigned char m_ucBPP;
|
|
|
|
IRGBSurface( DWORD dwHandle, LONG P, WORD W, WORD H, unsigned char BPP)
|
|
throw(): IVidMemSurface( dwHandle), m_lPitch( P), m_wWidth( W),
|
|
m_wHeight( H), m_ucBPP( BPP)
|
|
{ }
|
|
|
|
public:
|
|
LONG GetGBLlPitch( void) const throw()
|
|
{ return m_lPitch; }
|
|
WORD GetGBLwWidth( void) const throw()
|
|
{ return m_wWidth; }
|
|
WORD GetGBLwHeight( void) const throw()
|
|
{ return m_wHeight; }
|
|
unsigned char GetBytesPerPixel( void) const throw()
|
|
{ return m_ucBPP; }
|
|
virtual ~IRGBSurface() throw()
|
|
{ }
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()= 0;
|
|
};
|
|
|
|
class CRGBSurfAllocator
|
|
{
|
|
public: // Types
|
|
typedef IRGBSurface TSurface;
|
|
typedef TSurface* (*TCreateSurfFn)( const DDSURFACEDESC&,
|
|
PORTABLE_DDRAWSURFACE_LCL&);
|
|
|
|
protected: // Types
|
|
typedef vector< std::pair< DDSURFACEDESC, TCreateSurfFn> > TCreateSurfFns;
|
|
TCreateSurfFns m_CreateSurfFns;
|
|
struct SAdaptedMatchFn: public SMatchSDesc
|
|
{
|
|
typedef TCreateSurfFns::value_type argument_type;
|
|
using SMatchSDesc::result_type;
|
|
|
|
SAdaptedMatchFn( const DDSURFACEDESC& SDesc) throw(): SMatchSDesc( SDesc) {}
|
|
|
|
result_type operator()( argument_type Arg) const throw()
|
|
{ return (*static_cast< const SMatchSDesc*>(this))( Arg.first); }
|
|
};
|
|
|
|
public:
|
|
template< class TIter>
|
|
CRGBSurfAllocator( TIter itStart, const TIter itEnd) throw(bad_alloc)
|
|
{
|
|
while( itStart!= itEnd)
|
|
{
|
|
m_CreateSurfFns.push_back(
|
|
TCreateSurfFns::value_type( itStart->GetMatch(), *itStart));
|
|
++itStart;
|
|
}
|
|
}
|
|
|
|
TSurface* CreateSurf( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& Surf) const
|
|
{
|
|
TCreateSurfFns::const_iterator itFound(
|
|
find_if( m_CreateSurfFns.begin(), m_CreateSurfFns.end(),
|
|
SAdaptedMatchFn( SDesc) ) );
|
|
|
|
// Hey, if we don't support a VM of this surface type,
|
|
// but how did we get asked to allocate one, then?
|
|
if( itFound== m_CreateSurfFns.end())
|
|
throw HRESULT( DDERR_UNSUPPORTED);
|
|
|
|
return (itFound->second)( SDesc, Surf);
|
|
}
|
|
};
|
|
|
|
class CRGBSurface: public IRGBSurface
|
|
{
|
|
public: // Types
|
|
typedef unsigned int TLocks;
|
|
|
|
protected: // Variables
|
|
void* m_pData;
|
|
size_t m_uiBytes;
|
|
TLocks m_uiLocks;
|
|
|
|
public: // Functions
|
|
CRGBSurface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf)
|
|
throw(bad_alloc): IRGBSurface( DDSurf.lpSurfMore()->dwSurfaceHandle(),
|
|
0, DDSurf.lpGbl()->wWidth, DDSurf.lpGbl()->wHeight, 0),
|
|
m_pData( NULL), m_uiBytes( 0), m_uiLocks( 0)
|
|
{
|
|
// We must allocate this surface. Since we are specified as a SW driver,
|
|
// DDraw will not allocate for us.
|
|
assert((SDesc.dwFlags& DDSD_PIXELFORMAT)!= 0);
|
|
|
|
m_ucBPP= static_cast< unsigned char>(
|
|
SDesc.ddpfPixelFormat.dwRGBBitCount>> 3);
|
|
|
|
// TODO: Align pitch to 128-bit bit boundary, instead?
|
|
DDSurf.lpGbl()->lPitch= m_lPitch= ((m_ucBPP* m_wWidth+ 7)& ~7);
|
|
|
|
m_uiBytes= m_lPitch* m_wHeight;
|
|
|
|
// It would've been nice to have the initial proctection NOACCESS, but
|
|
// it seems the HAL needs to read to the region, initially.
|
|
m_pData= VirtualAlloc( NULL, m_uiBytes, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
if( m_pData== NULL)
|
|
throw bad_alloc( "Not enough memory to allocate Surface data");
|
|
DDSurf.lpGbl()->fpVidMem= reinterpret_cast<FLATPTR>( m_pData);
|
|
}
|
|
virtual ~CRGBSurface() throw()
|
|
{
|
|
// Warning: m_uiLocks doesn't have to be 0. The run-time will destroy
|
|
// a surface without un-locking it.
|
|
assert( m_pData!= NULL);
|
|
VirtualFree( m_pData, 0, MEM_DECOMMIT| MEM_RELEASE);
|
|
}
|
|
virtual void* Lock( DWORD dwFlags, const RECTL* pRect) throw()
|
|
{
|
|
numeric_limits< TLocks> Dummy;
|
|
assert( Dummy.max()!= m_uiLocks);
|
|
#if 0 // defined(DBG) || defined(_DEBUG)
|
|
// This code can't be enabled. Currently, run-time knows that this is
|
|
// really a system memory surface, and thus doesn't tell us to lock it
|
|
// into memory before using the bits. Known areas that could be fixed:
|
|
// (surface creation needs valid pointer & Present uses pointer).
|
|
if( 0== m_uiLocks)
|
|
{
|
|
DWORD dwProtect( PAGE_EXECUTE_READWRITE);
|
|
if( dwFlags& DDLOCK_READONLY)
|
|
dwProtect= PAGE_READONLY;
|
|
else if( dwFlags& DDLOCK_WRITEONLY)
|
|
dwProtect= PAGE_READWRITE;
|
|
|
|
DWORD dwOldP;
|
|
VirtualProtect( m_pData, m_uiBytes, dwProtect, &dwOldP);
|
|
}
|
|
#endif
|
|
++m_uiLocks;
|
|
|
|
if( pRect!= NULL)
|
|
{
|
|
return static_cast<void*>( reinterpret_cast<UINT8*>(
|
|
m_pData)+ pRect->top* m_lPitch+ pRect->left* m_ucBPP);
|
|
}
|
|
else
|
|
return m_pData;
|
|
}
|
|
virtual void Unlock( void) throw()
|
|
{
|
|
assert( 0!= m_uiLocks);
|
|
#if 0 // defined(DBG) || defined(_DEBUG)
|
|
if( 0== --m_uiLocks)
|
|
{
|
|
DWORD dwOldP;
|
|
VirtualProtect( m_pData, m_uiBytes, PAGE_NOACCESS, &dwOldP);
|
|
}
|
|
#else
|
|
--m_uiLocks;
|
|
#endif
|
|
}
|
|
};
|
|
|
|
class CR5G6B5Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CR5G6B5Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw();
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_B5G6R5; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CR5G6B5Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
class CA8R8G8B8Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CA8R8G8B8Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw();
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_B8G8R8A8; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CA8R8G8B8Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
class CX8R8G8B8Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CX8R8G8B8Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw();
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_B8G8R8X8; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CX8R8G8B8Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
class CD16Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CD16Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw();
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_Z16S0; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CD16Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
class CD24S8Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CD24S8Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw();
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_Z24S8; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CD24S8Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
class CX1R5G5B5Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CX1R5G5B5Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw()
|
|
{
|
|
const bool CX1R5G5B5Surface_being_asked_to_Clear( false);
|
|
assert( CX1R5G5B5Surface_being_asked_to_Clear);
|
|
}
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_B5G5R5; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CX1R5G5B5Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
class CA1R5G5B5Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CA1R5G5B5Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw()
|
|
{
|
|
const bool CA1R5G5B5Surface_being_asked_to_Clear( false);
|
|
assert( CA1R5G5B5Surface_being_asked_to_Clear);
|
|
}
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_B5G5R5A1; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CA1R5G5B5Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
class CP8Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CP8Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw()
|
|
{
|
|
const bool CP8Surface_being_asked_to_Clear( false);
|
|
assert( CP8Surface_being_asked_to_Clear);
|
|
}
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_PALETTE8; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CP8Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
class CA8L8Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CA8L8Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw()
|
|
{
|
|
const bool CA8L8Surface_being_asked_to_Clear( false);
|
|
assert( CA8L8Surface_being_asked_to_Clear);
|
|
}
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_L8A8; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CA8L8Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
class CL8Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CL8Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw()
|
|
{
|
|
const bool CL8Surface_being_asked_to_Clear( false);
|
|
assert( CL8Surface_being_asked_to_Clear);
|
|
}
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_L8; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CL8Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
class CA4R4G4B4Surface: public CRGBSurface
|
|
{
|
|
public:
|
|
CA4R4G4B4Surface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf):
|
|
CRGBSurface( SDesc, DDSurf) { }
|
|
|
|
virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC) throw()
|
|
{
|
|
const bool CA4R4G4B4Surface_being_asked_to_Clear( false);
|
|
assert( CA4R4G4B4Surface_being_asked_to_Clear);
|
|
}
|
|
virtual D3DI_SPANTEX_FORMAT GetSpanTexFormat( void) const throw()
|
|
{ return D3DI_SPTFMT_B4G4R4A4; }
|
|
|
|
static IRGBSurface* Create( const DDSURFACEDESC& SDesc,
|
|
PORTABLE_DDRAWSURFACE_LCL& DDSurf) throw(bad_alloc)
|
|
{
|
|
return new CA4R4G4B4Surface( SDesc, DDSurf);
|
|
}
|
|
};
|
|
|
|
}
|