diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /public/pixelwriter.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'public/pixelwriter.h')
| -rw-r--r-- | public/pixelwriter.h | 883 |
1 files changed, 883 insertions, 0 deletions
diff --git a/public/pixelwriter.h b/public/pixelwriter.h new file mode 100644 index 0000000..5c51055 --- /dev/null +++ b/public/pixelwriter.h @@ -0,0 +1,883 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef PIXELWRITER_H +#define PIXELWRITER_H + +#ifdef _WIN32 +#pragma once +#endif + +#ifdef _WIN32 +#define FORCEINLINE_PIXEL FORCEINLINE +#elif POSIX +#define FORCEINLINE_PIXEL inline +#else +#error "implement me" +#endif + +#include "bitmap/imageformat.h" +#include "tier0/dbg.h" +#include "mathlib/compressed_vector.h" +#include "mathlib/ssemath.h" + +//----------------------------------------------------------------------------- +// Color writing class +//----------------------------------------------------------------------------- + +class CPixelWriter +{ +public: + FORCEINLINE void SetPixelMemory( ImageFormat format, void* pMemory, int stride ); + FORCEINLINE void *GetPixelMemory() { return m_pBase; } + + // this is no longer used: +#if 0 // defined( _X360 ) + // set after SetPixelMemory() + FORCEINLINE void ActivateByteSwapping( bool bSwap ); +#endif + + FORCEINLINE void Seek( int x, int y ); + FORCEINLINE void* SkipBytes( int n ); + FORCEINLINE void SkipPixels( int n ); + FORCEINLINE void WritePixel( int r, int g, int b, int a = 255 ); + FORCEINLINE void WritePixelNoAdvance( int r, int g, int b, int a = 255 ); + FORCEINLINE void WritePixelSigned( int r, int g, int b, int a = 255 ); + FORCEINLINE void WritePixelNoAdvanceSigned( int r, int g, int b, int a = 255 ); + FORCEINLINE void ReadPixelNoAdvance( int &r, int &g, int &b, int &a ); + + // Floating point formats + FORCEINLINE void WritePixelNoAdvanceF( float r, float g, float b, float a = 1.0f ); + FORCEINLINE void WritePixelF( float r, float g, float b, float a = 1.0f ); + + // SIMD formats + FORCEINLINE void WritePixel( FLTX4 rgba ); + FORCEINLINE void WritePixelNoAdvance( FLTX4 rgba ); +#ifdef _X360 + // here are some explicit formats so we can avoid the switch: + FORCEINLINE void WritePixelNoAdvance_RGBA8888( FLTX4 rgba ); + FORCEINLINE void WritePixelNoAdvance_BGRA8888( FLTX4 rgba ); + // as above, but with m_pBits passed in to avoid a LHS + FORCEINLINE void WritePixelNoAdvance_BGRA8888( FLTX4 rgba, void *pBits ); + // for writing entire SIMD registers at once when they have + // already been packed, and when m_pBits is vector-aligned + // (which is a requirement for write-combined memory) + // offset is added to m_pBits (saving you from the obligatory + // LHS of a SkipBytes) + FORCEINLINE void WriteFourPixelsExplicitLocation_BGRA8888( FLTX4 rgba, int offset ); +#endif + + + FORCEINLINE unsigned char GetPixelSize() { return m_Size; } + + FORCEINLINE bool IsUsingFloatFormat() const; + FORCEINLINE unsigned char *GetCurrentPixel() { return m_pBits; } + +private: + enum + { + PIXELWRITER_USING_FLOAT_FORMAT = 0x01, + PIXELWRITER_USING_16BIT_FLOAT_FORMAT = 0x02, + PIXELWRITER_SWAPBYTES = 0x04, + }; + + unsigned char* m_pBase; + unsigned char* m_pBits; + unsigned short m_BytesPerRow; + unsigned char m_Size; + unsigned char m_nFlags; + signed short m_RShift; + signed short m_GShift; + signed short m_BShift; + signed short m_AShift; + unsigned int m_RMask; + unsigned int m_GMask; + unsigned int m_BMask; + unsigned int m_AMask; + +#ifdef _X360 + ImageFormat m_Format; +public: + inline const ImageFormat &GetFormat() { return m_Format; } +private: +#endif +}; + +FORCEINLINE_PIXEL bool CPixelWriter::IsUsingFloatFormat() const +{ + return (m_nFlags & PIXELWRITER_USING_FLOAT_FORMAT) != 0; +} + +FORCEINLINE_PIXEL void CPixelWriter::SetPixelMemory( ImageFormat format, void* pMemory, int stride ) +{ + m_pBits = (unsigned char*)pMemory; + m_pBase = m_pBits; + m_BytesPerRow = (unsigned short)stride; + m_nFlags = 0; +#ifdef _X360 + m_Format = format; +#endif + + switch ( format ) + { + case IMAGE_FORMAT_R32F: // NOTE! : the low order bits are first in this naming convention. + m_Size = 4; + m_RShift = 0; + m_GShift = 0; + m_BShift = 0; + m_AShift = 0; + m_RMask = 0xFFFFFFFF; + m_GMask = 0x0; + m_BMask = 0x0; + m_AMask = 0x0; + m_nFlags |= PIXELWRITER_USING_FLOAT_FORMAT; + break; + + case IMAGE_FORMAT_RGBA32323232F: + m_Size = 16; + m_RShift = 0; + m_GShift = 32; + m_BShift = 64; + m_AShift = 96; + m_RMask = 0xFFFFFFFF; + m_GMask = 0xFFFFFFFF; + m_BMask = 0xFFFFFFFF; + m_AMask = 0xFFFFFFFF; + m_nFlags |= PIXELWRITER_USING_FLOAT_FORMAT; + break; + + case IMAGE_FORMAT_RGBA16161616F: + m_Size = 8; + m_RShift = 0; + m_GShift = 16; + m_BShift = 32; + m_AShift = 48; + m_RMask = 0xFFFF; + m_GMask = 0xFFFF; + m_BMask = 0xFFFF; + m_AMask = 0xFFFF; + m_nFlags |= PIXELWRITER_USING_FLOAT_FORMAT | PIXELWRITER_USING_16BIT_FLOAT_FORMAT; + break; + + case IMAGE_FORMAT_RGBA8888: +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_RGBA8888: +#endif + m_Size = 4; + m_RShift = 0; + m_GShift = 8; + m_BShift = 16; + m_AShift = 24; + m_RMask = 0xFF; + m_GMask = 0xFF; + m_BMask = 0xFF; + m_AMask = 0xFF; + break; + + case IMAGE_FORMAT_BGRA8888: // NOTE! : the low order bits are first in this naming convention. +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_BGRA8888: +#endif + m_Size = 4; + m_RShift = 16; + m_GShift = 8; + m_BShift = 0; + m_AShift = 24; + m_RMask = 0xFF; + m_GMask = 0xFF; + m_BMask = 0xFF; + m_AMask = 0xFF; + break; + + case IMAGE_FORMAT_BGRX8888: +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_BGRX8888: +#endif + m_Size = 4; + m_RShift = 16; + m_GShift = 8; + m_BShift = 0; + m_AShift = 24; + m_RMask = 0xFF; + m_GMask = 0xFF; + m_BMask = 0xFF; + m_AMask = 0x00; + break; + + case IMAGE_FORMAT_BGRA4444: + m_Size = 2; + m_RShift = 4; + m_GShift = 0; + m_BShift = -4; + m_AShift = 8; + m_RMask = 0xF0; + m_GMask = 0xF0; + m_BMask = 0xF0; + m_AMask = 0xF0; + break; + + case IMAGE_FORMAT_BGR888: + m_Size = 3; + m_RShift = 16; + m_GShift = 8; + m_BShift = 0; + m_AShift = 0; + m_RMask = 0xFF; + m_GMask = 0xFF; + m_BMask = 0xFF; + m_AMask = 0x00; + break; + + case IMAGE_FORMAT_BGR565: + m_Size = 2; + m_RShift = 8; + m_GShift = 3; + m_BShift = -3; + m_AShift = 0; + m_RMask = 0xF8; + m_GMask = 0xFC; + m_BMask = 0xF8; + m_AMask = 0x00; + break; + + case IMAGE_FORMAT_BGRA5551: + case IMAGE_FORMAT_BGRX5551: + m_Size = 2; + m_RShift = 7; + m_GShift = 2; + m_BShift = -3; + m_AShift = 8; + m_RMask = 0xF8; + m_GMask = 0xF8; + m_BMask = 0xF8; + m_AMask = 0x80; + break; + + // GR - alpha format for HDR support + case IMAGE_FORMAT_A8: + m_Size = 1; + m_RShift = 0; + m_GShift = 0; + m_BShift = 0; + m_AShift = 0; + m_RMask = 0x00; + m_GMask = 0x00; + m_BMask = 0x00; + m_AMask = 0xFF; + break; + + case IMAGE_FORMAT_UVWQ8888: + m_Size = 4; + m_RShift = 0; + m_GShift = 8; + m_BShift = 16; + m_AShift = 24; + m_RMask = 0xFF; + m_GMask = 0xFF; + m_BMask = 0xFF; + m_AMask = 0xFF; + break; + + case IMAGE_FORMAT_RGBA16161616: +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_RGBA16161616: +#endif + m_Size = 8; + if ( !IsX360() ) + { + m_RShift = 0; + m_GShift = 16; + m_BShift = 32; + m_AShift = 48; + } + else + { + m_RShift = 48; + m_GShift = 32; + m_BShift = 16; + m_AShift = 0; + } + m_RMask = 0xFFFF; + m_GMask = 0xFFFF; + m_BMask = 0xFFFF; + m_AMask = 0xFFFF; + break; + + case IMAGE_FORMAT_I8: + // whatever goes into R is considered the intensity. + m_Size = 1; + m_RShift = 0; + m_GShift = 0; + m_BShift = 0; + m_AShift = 0; + m_RMask = 0xFF; + m_GMask = 0x00; + m_BMask = 0x00; + m_AMask = 0x00; + break; + // FIXME: Add more color formats as need arises + default: + { + static bool format_error_printed[NUM_IMAGE_FORMATS]; + if ( !format_error_printed[format] ) + { + Assert( 0 ); + Msg( "CPixelWriter::SetPixelMemory: Unsupported image format %i\n", format ); + format_error_printed[format] = true; + } + m_Size = 0; // set to zero so that we don't stomp memory for formats that we don't understand. + m_RShift = 0; + m_GShift = 0; + m_BShift = 0; + m_AShift = 0; + m_RMask = 0x00; + m_GMask = 0x00; + m_BMask = 0x00; + m_AMask = 0x00; + } + break; + } +} + +#if 0 // defined( _X360 ) +FORCEINLINE void CPixelWriter::ActivateByteSwapping( bool bSwap ) +{ + // X360TBD: Who is trying to use this? + // Purposely not hooked up because PixelWriter has been ported to read/write native pixels only + Assert( 0 ); + + if ( bSwap && !(m_nFlags & PIXELWRITER_SWAPBYTES ) ) + { + m_nFlags |= PIXELWRITER_SWAPBYTES; + + // only tested with 4 byte formats + Assert( m_Size == 4 ); + } + else if ( !bSwap && (m_nFlags & PIXELWRITER_SWAPBYTES ) ) + { + m_nFlags &= ~PIXELWRITER_SWAPBYTES; + } + else + { + // same state + return; + } + + // swap the shifts + m_RShift = 24-m_RShift; + m_GShift = 24-m_GShift; + m_BShift = 24-m_BShift; + m_AShift = 24-m_AShift; +} +#endif + +//----------------------------------------------------------------------------- +// Sets where we're writing to +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::Seek( int x, int y ) +{ + m_pBits = m_pBase + y * m_BytesPerRow + x * m_Size; +} + + +//----------------------------------------------------------------------------- +// Skips n bytes: +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void* CPixelWriter::SkipBytes( int n ) RESTRICT +{ + m_pBits += n; + return m_pBits; +} + + +//----------------------------------------------------------------------------- +// Skips n pixels: +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::SkipPixels( int n ) +{ + SkipBytes( n * m_Size ); +} + + +//----------------------------------------------------------------------------- +// Writes a pixel without advancing the index PC ONLY +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixelNoAdvanceF( float r, float g, float b, float a ) +{ + Assert( IsUsingFloatFormat() ); + + // X360TBD: Not ported + Assert( IsPC() ); + + if (PIXELWRITER_USING_16BIT_FLOAT_FORMAT & m_nFlags) + { + float16 fp16[4]; + fp16[0].SetFloat( r ); + fp16[1].SetFloat( g ); + fp16[2].SetFloat( b ); + fp16[3].SetFloat( a ); + // fp16 + unsigned short pBuf[4] = { 0, 0, 0, 0 }; + pBuf[ m_RShift >> 4 ] |= (fp16[0].GetBits() & m_RMask) << ( m_RShift & 0xF ); + pBuf[ m_GShift >> 4 ] |= (fp16[1].GetBits() & m_GMask) << ( m_GShift & 0xF ); + pBuf[ m_BShift >> 4 ] |= (fp16[2].GetBits() & m_BMask) << ( m_BShift & 0xF ); + pBuf[ m_AShift >> 4 ] |= (fp16[3].GetBits() & m_AMask) << ( m_AShift & 0xF ); + memcpy( m_pBits, pBuf, m_Size ); + } + else + { + // fp32 + int pBuf[4] = { 0, 0, 0, 0 }; + pBuf[ m_RShift >> 5 ] |= (FloatBits(r) & m_RMask) << ( m_RShift & 0x1F ); + pBuf[ m_GShift >> 5 ] |= (FloatBits(g) & m_GMask) << ( m_GShift & 0x1F ); + pBuf[ m_BShift >> 5 ] |= (FloatBits(b) & m_BMask) << ( m_BShift & 0x1F ); + pBuf[ m_AShift >> 5 ] |= (FloatBits(a) & m_AMask) << ( m_AShift & 0x1F ); + memcpy( m_pBits, pBuf, m_Size ); + } +} + +//----------------------------------------------------------------------------- +// Writes a pixel, advances the write index +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixelF( float r, float g, float b, float a ) +{ + WritePixelNoAdvanceF(r, g, b, a); + m_pBits += m_Size; +} + + +//----------------------------------------------------------------------------- +// Writes a pixel, advances the write index +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixel( int r, int g, int b, int a ) +{ + WritePixelNoAdvance(r,g,b,a); + m_pBits += m_Size; +} + +//----------------------------------------------------------------------------- +// Writes a pixel, advances the write index +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixelSigned( int r, int g, int b, int a ) +{ + WritePixelNoAdvanceSigned(r,g,b,a); + m_pBits += m_Size; +} + + +//----------------------------------------------------------------------------- +// Writes a pixel without advancing the index +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixelNoAdvance( int r, int g, int b, int a ) +{ + Assert( !IsUsingFloatFormat() ); + + if ( m_Size <= 0 ) + { + return; + } + if ( m_Size < 5 ) + { + unsigned int val = (r & m_RMask) << m_RShift; + val |= (g & m_GMask) << m_GShift; + val |= (m_BShift > 0) ? ((b & m_BMask) << m_BShift) : ((b & m_BMask) >> -m_BShift); + val |= (a & m_AMask) << m_AShift; + + switch( m_Size ) + { + default: + Assert( 0 ); + return; + case 1: + { + m_pBits[0] = (unsigned char)((val & 0xff)); + return; + } + case 2: + { + ((unsigned short *)m_pBits)[0] = (unsigned short)((val & 0xffff)); + return; + } + case 3: + { + if ( IsPC() || !IsX360() ) + { + ((unsigned short *)m_pBits)[0] = (unsigned short)((val & 0xffff)); + m_pBits[2] = (unsigned char)((val >> 16) & 0xff); + } + else + { + m_pBits[0] = (unsigned char)(((val >> 16) & 0xff)); + m_pBits[1] = (unsigned char)(((val >> 8 ) & 0xff)); + m_pBits[2] = (unsigned char)(val & 0xff); + } + return; + } + case 4: + { + ((unsigned int *)m_pBits)[0] = val; + return; + } + } + } + else // RGBA32323232 or RGBA16161616 -- PC only. + { + AssertMsg(!IsX360(), "Unsupported lightmap format used in WritePixelNoAdvance(). This is a severe performance fault.\n"); + + int64 val = ( ( int64 )(r & m_RMask) ) << m_RShift; + val |= ( ( int64 )(g & m_GMask) ) << m_GShift; + val |= (m_BShift > 0) ? ((( int64 )( b & m_BMask)) << m_BShift) : (((int64)( b & m_BMask)) >> -m_BShift); + val |= ( ( int64 )(a & m_AMask) ) << m_AShift; + + switch( m_Size ) + { + case 6: + { + if ( IsPC() || !IsX360() ) + { + ((unsigned int *)m_pBits)[0] = val & 0xffffffff; + ((unsigned short *)m_pBits)[2] = (unsigned short)( ( val >> 32 ) & 0xffff ); + } + else + { + ((unsigned int *)m_pBits)[0] = (val >> 16) & 0xffffffff; + ((unsigned short *)m_pBits)[2] = (unsigned short)( val & 0xffff ); + } + return; + } + case 8: + { + if ( IsPC() || !IsX360() ) + { + ((unsigned int *)m_pBits)[0] = val & 0xffffffff; + ((unsigned int *)m_pBits)[1] = ( val >> 32 ) & 0xffffffff; + } + else + { + ((unsigned int *)m_pBits)[0] = ( val >> 32 ) & 0xffffffff; + ((unsigned int *)m_pBits)[1] = val & 0xffffffff; + } + return; + } + default: + Assert( 0 ); + return; + } + } +} + +#ifdef _X360 +// There isn't a PC port of these because of the many varied +// pixel formats the PC deals with. If you write SSE versions +// of all the various necessary packers, then this can be made +// to work on PC. + +//----------------------------------------------------------------------------- +// Writes a pixel, advances the write index +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixel( FLTX4 rgba ) RESTRICT +{ + WritePixelNoAdvance(rgba); + m_pBits += m_Size; +} + +//----------------------------------------------------------------------------- +// Writes a pixel without advancing the index +// rgba are four float values, each on the range 0..255 (though they may leak +// fractionally over 255 due to numerical errors earlier) +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixelNoAdvance( FLTX4 rgba ) RESTRICT +{ + Assert( !IsUsingFloatFormat() ); + + switch (m_Size) + { + case 0: + return; + case 4: + { + AssertMsg((reinterpret_cast<unsigned int>(m_pBits) & 0x03) == 0,"Unaligned m_pBits in WritePixelNoAdvance!"); + switch ( m_Format ) + { + // note: format names are low-order-byte first. + case IMAGE_FORMAT_RGBA8888: + case IMAGE_FORMAT_LINEAR_RGBA8888: + WritePixelNoAdvance_RGBA8888(rgba); + break; + + case IMAGE_FORMAT_BGRA8888: // NOTE! : the low order bits are first in this naming convention. + case IMAGE_FORMAT_LINEAR_BGRA8888: + WritePixelNoAdvance_BGRA8888(rgba); + break; + + + default: + AssertMsg1(false, "Unknown four-byte pixel format %d in lightmap write.\n", m_Format); + } + break; + } + + default: + AssertMsg1(false, "WritePixelNoAdvance on unsupported 360 %d-byte format\n", m_Size); + break; + } + +} + + +// here are some explicit formats so we can avoid the switch: +FORCEINLINE void CPixelWriter::WritePixelNoAdvance_RGBA8888( FLTX4 rgba ) +{ + // it's easier to do tiered convert-saturates here + // than the d3d color convertor op + + // first permute + const static fltx4 permReverse = XMVectorPermuteControl(3,2,1,0); + fltx4 N = XMVectorPermute(rgba, rgba, permReverse); + + N = __vctuxs(N, 0); // convert to unsigned fixed point 0 w/ saturate + N = __vpkuwus(N, N); // convert to halfword saturate + N = __vpkuhus(N, N); // convert to byte saturate + N = __vspltw(N, 0); // splat w-word to all four + + __stvewx(N, m_pBits, 0); // store whatever word happens to be aligned with m_pBits to that word +} + +FORCEINLINE void CPixelWriter::WritePixelNoAdvance_BGRA8888( FLTX4 rgba ) +{ + WritePixelNoAdvance_BGRA8888( rgba, m_pBits ); +} + +FORCEINLINE void CPixelWriter::WritePixelNoAdvance_BGRA8888( FLTX4 rgba, void * RESTRICT pBits ) RESTRICT +{ + // this happens to be in an order such that we can use the handy builtin packing op + // clamp to 0..255 (coz it might have leaked over) + static const fltx4 vTwoFiftyFive = {255.0f, 255.0f, 255.0f, 255.0f}; + fltx4 N = MinSIMD(vTwoFiftyFive, rgba); + + // the magic number such that when mul-accummulated against rbga, + // gets us a representation 3.0 + (r)*2^-22 -- puts the bits at + // the bottom of the float + static CONST XMVECTOR PackScale = { (1.0f / (FLOAT)(1 << 22)), (1.0f / (FLOAT)(1 << 22)), (1.0f / (FLOAT)(1 << 22)), (1.0f / (FLOAT)(1 << 22))}; // 255.0f / (FLOAT)(1 << 22) + static const XMVECTOR Three = {3.0f, 3.0f, 3.0f, 3.0f}; + + N = __vmaddfp(N, PackScale, Three); + N = __vpkd3d(N, N, VPACK_D3DCOLOR, VPACK_32, 3); // pack to X word + N = __vspltw(N, 0); // splat X + + // this is a nasty thing to work around the April XDK bug in __stvewx + { + void * RESTRICT copyOfPBits = pBits; + __stvewx(N, copyOfPBits, 0); + } + +} + +// for writing entire SIMD registers at once +FORCEINLINE void CPixelWriter::WriteFourPixelsExplicitLocation_BGRA8888 ( FLTX4 rgba, int offset ) +{ + Assert( (reinterpret_cast<unsigned int>(m_pBits) & 15) == 0 ); // assert alignment + XMStoreVector4A( m_pBits + offset , rgba ); +} + + +#endif + +//----------------------------------------------------------------------------- +// Writes a signed pixel without advancing the index +//----------------------------------------------------------------------------- + +FORCEINLINE_PIXEL void CPixelWriter::WritePixelNoAdvanceSigned( int r, int g, int b, int a ) +{ + Assert( !IsUsingFloatFormat() ); + + if ( m_Size <= 0 ) + { + return; + } + + if ( m_Size < 5 ) + { + int val = (r & m_RMask) << m_RShift; + val |= (g & m_GMask) << m_GShift; + val |= (m_BShift > 0) ? ((b & m_BMask) << m_BShift) : ((b & m_BMask) >> -m_BShift); + val |= (a & m_AMask) << m_AShift; + signed char *pSignedBits = (signed char *)m_pBits; + + if ( IsPC() || !IsX360() ) + { + switch ( m_Size ) + { + case 4: + pSignedBits[3] = (signed char)((val >> 24) & 0xff); + // fall through intentionally. + case 3: + pSignedBits[2] = (signed char)((val >> 16) & 0xff); + // fall through intentionally. + case 2: + pSignedBits[1] = (signed char)((val >> 8) & 0xff); + // fall through intentionally. + case 1: + pSignedBits[0] = (signed char)((val & 0xff)); + // fall through intentionally. + return; + } + } + else + { + switch ( m_Size ) + { + case 4: + pSignedBits[0] = (signed char)((val >> 24) & 0xff); + pSignedBits[1] = (signed char)((val >> 16) & 0xff); + pSignedBits[2] = (signed char)((val >> 8) & 0xff); + pSignedBits[3] = (signed char)(val & 0xff); + break; + case 3: + pSignedBits[0] = (signed char)((val >> 16) & 0xff); + pSignedBits[1] = (signed char)((val >> 8) & 0xff); + pSignedBits[2] = (signed char)(val & 0xff); + break; + case 2: + pSignedBits[0] = (signed char)((val >> 8) & 0xff); + pSignedBits[1] = (signed char)(val & 0xff); + break; + case 1: + pSignedBits[0] = (signed char)(val & 0xff); + break; + } + } + } + else + { + int64 val = ( ( int64 )(r & m_RMask) ) << m_RShift; + val |= ( ( int64 )(g & m_GMask) ) << m_GShift; + val |= (m_BShift > 0) ? ((( int64 )( b & m_BMask)) << m_BShift) : (((int64)( b & m_BMask)) >> -m_BShift); + val |= ( ( int64 )(a & m_AMask) ) << m_AShift; + signed char *pSignedBits = ( signed char * )m_pBits; + + if ( IsPC() || !IsX360() ) + { + switch( m_Size ) + { + case 8: + pSignedBits[7] = (signed char)((val >> 56) & 0xff); + pSignedBits[6] = (signed char)((val >> 48) & 0xff); + // fall through intentionally. + case 6: + pSignedBits[5] = (signed char)((val >> 40) & 0xff); + pSignedBits[4] = (signed char)((val >> 32) & 0xff); + // fall through intentionally. + case 4: + pSignedBits[3] = (signed char)((val >> 24) & 0xff); + // fall through intentionally. + case 3: + pSignedBits[2] = (signed char)((val >> 16) & 0xff); + // fall through intentionally. + case 2: + pSignedBits[1] = (signed char)((val >> 8) & 0xff); + // fall through intentionally. + case 1: + pSignedBits[0] = (signed char)((val & 0xff)); + break; + default: + Assert( 0 ); + return; + } + } + else + { + switch( m_Size ) + { + case 8: + pSignedBits[0] = (signed char)((val >> 56) & 0xff); + pSignedBits[1] = (signed char)((val >> 48) & 0xff); + pSignedBits[2] = (signed char)((val >> 40) & 0xff); + pSignedBits[3] = (signed char)((val >> 32) & 0xff); + pSignedBits[4] = (signed char)((val >> 24) & 0xff); + pSignedBits[5] = (signed char)((val >> 16) & 0xff); + pSignedBits[6] = (signed char)((val >> 8) & 0xff); + pSignedBits[7] = (signed char)(val & 0xff); + break; + case 6: + pSignedBits[0] = (signed char)((val >> 40) & 0xff); + pSignedBits[1] = (signed char)((val >> 32) & 0xff); + pSignedBits[2] = (signed char)((val >> 24) & 0xff); + pSignedBits[3] = (signed char)((val >> 16) & 0xff); + pSignedBits[4] = (signed char)((val >> 8) & 0xff); + pSignedBits[5] = (signed char)(val & 0xff); + break; + case 4: + pSignedBits[0] = (signed char)((val >> 24) & 0xff); + pSignedBits[1] = (signed char)((val >> 16) & 0xff); + pSignedBits[2] = (signed char)((val >> 8) & 0xff); + pSignedBits[3] = (signed char)(val & 0xff); + break; + case 3: + pSignedBits[0] = (signed char)((val >> 16) & 0xff); + pSignedBits[1] = (signed char)((val >> 8) & 0xff); + pSignedBits[2] = (signed char)(val & 0xff); + break; + case 2: + pSignedBits[0] = (signed char)((val >> 8) & 0xff); + pSignedBits[1] = (signed char)(val & 0xff); + break; + case 1: + pSignedBits[0] = (signed char)(val & 0xff); + break; + default: + Assert( 0 ); + return; + } + } + } +} + +FORCEINLINE_PIXEL void CPixelWriter::ReadPixelNoAdvance( int &r, int &g, int &b, int &a ) +{ + Assert( !IsUsingFloatFormat() ); + + int val = m_pBits[0]; + if ( m_Size > 1 ) + { + if ( IsPC() || !IsX360() ) + { + val |= (int)m_pBits[1] << 8; + if ( m_Size > 2 ) + { + val |= (int)m_pBits[2] << 16; + if ( m_Size > 3 ) + { + val |= (int)m_pBits[3] << 24; + } + } + } + else + { + val <<= 8; + val |= (int)m_pBits[1]; + if ( m_Size > 2 ) + { + val <<= 8; + val |= (int)m_pBits[2]; + if ( m_Size > 3 ) + { + val <<= 8; + val |= (int)m_pBits[3]; + } + } + } + } + + r = (val>>m_RShift) & m_RMask; + g = (val>>m_GShift) & m_GMask; + b = (val>>m_BShift) & m_BMask; + a = (val>>m_AShift) & m_AMask; +} + +#endif // PIXELWRITER_H; |