Blame |
Last modification |
View Log
| RSS feed
#include "DDImage.h"
#include <Math.h>
#include "DDInterface.h"
#include "D3DInterface.h"
#include "Rect.h"
#include "Graphics.h"
#include "SexyAppBase.h"
#include "Debug.h"
#include "PerfTimer.h"
#pragma warning(disable:4005) // macro redefinition
#pragma warning(disable:4244) // conversion possible loss of data
using namespace Sexy;
extern bool gOptimizeSoftwareDrawing;
DDImage::DDImage(DDInterface* theDDInterface) :
MemoryImage(theDDInterface->mApp)
{
mDDInterface = theDDInterface;
Init();
}
DDImage::DDImage() :
MemoryImage(gSexyAppBase)
{
mDDInterface = gSexyAppBase->mDDInterface;
Init();
}
DDImage::~DDImage()
{
if (mSurface != NULL)
mSurface->Release();
mDDInterface->RemoveDDImage(this);
DBG_ASSERTE(mLockCount == 0);
}
void DDImage::Init()
{
mSurface = NULL;
mDDInterface->AddDDImage(this);
mNoLock = false;
mVideoMemory = false;
mFirstPixelTrans = false;
mWantDDSurface = false;
mDrawToBits = false;
mSurfaceSet = false;
mLockCount = 0;
}
bool DDImage::Check3D(Image *theImage)
{
DDImage *anImage = dynamic_cast<DDImage*>(theImage);
if (anImage!=NULL)
return Check3D(anImage);
else
return false;
}
bool DDImage::Check3D(DDImage *theImage)
{
return theImage->mDDInterface->mIs3D && theImage->mSurface==theImage->mDDInterface->mDrawSurface;
}
bool DDImage::LockSurface()
{
if (Check3D(this))
return false;
if (mLockCount == 0)
{
memset(&mLockedSurfaceDesc, 0, sizeof(mLockedSurfaceDesc));
mLockedSurfaceDesc.dwSize = sizeof(mLockedSurfaceDesc);
int aResult = GetSurface()->Lock(NULL, &mLockedSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
if (aResult != DD_OK)
return false;
}
mLockCount++;
DBG_ASSERTE(mLockCount < 8);
return true;
}
bool DDImage::UnlockSurface()
{
if (Check3D(this))
return false;
--mLockCount;
if (mLockCount == 0)
{
mSurface->Unlock(NULL);
}
DBG_ASSERTE(mLockCount >= 0);
return true;
}
void DDImage::SetSurface(LPDIRECTDRAWSURFACE theSurface)
{
mSurfaceSet = true;
mSurface = theSurface;
mSurface->AddRef();
// TDDSurfaceDesc aDesc;
DDSURFACEDESC aDesc;
ZeroMemory(&aDesc, sizeof(aDesc));
aDesc.dwSize = sizeof(aDesc);
aDesc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
HRESULT aResult = mSurface->GetSurfaceDesc(&aDesc);
mWidth = aDesc.dwWidth;
mHeight = aDesc.dwHeight;
mNoLock = false;
}
bool DDImage::GenerateDDSurface()
{
if (mSurface != NULL)
return true;
CommitBits();
if (mHasAlpha)
return false;
mWantDDSurface = true;
// Force into non-palletized mode for this
if (mColorTable != NULL)
GetBits();
HRESULT aResult;
// TDDSurfaceDesc aDesc;
DDSURFACEDESC2 aDesc;
ZeroMemory(&aDesc, sizeof(aDesc));
aDesc.dwSize = sizeof(aDesc);
aDesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
aDesc.ddsCaps.dwCaps = mVideoMemory ? DDSCAPS_VIDEOMEMORY : DDSCAPS_SYSTEMMEMORY;
aDesc.dwWidth = mWidth;
aDesc.dwHeight = mHeight;
AutoCrit aCrit(mDDInterface->mCritSect); // prevent mSurface from being released while we're in this code
aResult = mDDInterface->CreateSurface(&aDesc, &mSurface, NULL);
if (aResult != DD_OK)
return false;
if (!LockSurface())
return false;
const int rRightShift = 16 + (8-mDDInterface->mRedBits);
const int gRightShift = 8 + (8-mDDInterface->mGreenBits);
const int bRightShift = 0 + (8-mDDInterface->mBlueBits);
const int rLeftShift = mDDInterface->mRedShift;
const int gLeftShift = mDDInterface->mGreenShift;
const int bLeftShift = mDDInterface->mBlueShift;
const int rMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
const int gMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
const int bMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
int aNumBits = mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
if (aNumBits == 16)
{
ushort* mSurfaceBits = (ushort*) mLockedSurfaceDesc.lpSurface;
if (mSurfaceBits != NULL)
{
int i;
bool firstTrans = true;
ushort* a16Bits = NULL;
ushort aTransColor = 0;
if (mBits != NULL)
{
a16Bits = new ushort[mWidth*mHeight];
ulong* aSrcPtr = mBits;
ushort* a16SrcPtr = a16Bits;
for (i = 0; i < mWidth*mHeight; i++)
{
ulong val = *(aSrcPtr++);
*a16SrcPtr = (((val>>rRightShift)<<rLeftShift)&rMask) |
(((val>>gRightShift)<<gLeftShift)&gMask) |
(((val>>bRightShift)<<bLeftShift)&bMask);
int anAlpha = val >> 24;
if ((firstTrans) && (anAlpha < 255))
{
firstTrans = false;
aTransColor = *a16SrcPtr;
}
++a16SrcPtr;
}
}
if ((mHasTrans) && (mBits != NULL))
{
if (mFirstPixelTrans)
{
aTransColor = *a16Bits;
if (a16Bits != NULL)
{
ushort* aDestPtr = mSurfaceBits;
ushort* a16SrcPtr = a16Bits;
for (int aRow = 0; aRow < mHeight; aRow++)
{
for (int aCol = 0; aCol < mWidth; aCol++)
{
*(aDestPtr++) = *a16SrcPtr;
++a16SrcPtr;
}
aDestPtr += mLockedSurfaceDesc.lPitch/2 - mWidth;
}
}
}
else
{
bool needNewColor = false;
ulong* aSrcPtr = mBits;
ushort* a16SrcPtr = a16Bits;
for (i = 0; i < mWidth*mHeight; i++)
{
ulong val = *(aSrcPtr++);
ushort a16Val = *(a16SrcPtr++);
int anAlpha = val >> 24;
if ((anAlpha == 255) && (aTransColor == a16Val))
{
needNewColor = true;
break;
}
}
if (needNewColor)
{
int* aUsedColorArray = new int[2048];
ZeroMemory(aUsedColorArray, 2048*sizeof(int));
aSrcPtr = mBits;
a16SrcPtr = a16Bits;
for (i = 0; i < mWidth*mHeight; i++)
{
ulong val = *(aSrcPtr++);
ushort a16Val = *(a16SrcPtr++);
int anAlpha = val >> 24;
if (anAlpha > 0)
aUsedColorArray[a16Val/32] |= (1<<(a16Val%32));
}
bool done = false;
for (int i = 0; i < 2048; i++)
{
if (aUsedColorArray[i] != 0xFFFF)
{
for (int aBit = 0; aBit < 32; aBit++)
{
if ((aUsedColorArray[i] & (1<<aBit)) == 0)
{
aTransColor = i*32+aBit;
break;
}
}
}
if (done)
break;
}
delete aUsedColorArray;
}
if (mBits != NULL)
{
ushort* aDestPtr = mSurfaceBits;
ulong* aSrcPtr = mBits;
ushort* a16SrcPtr = a16Bits;
for (int aRow = 0; aRow < mHeight; aRow++)
{
for (int aCol = 0; aCol < mWidth; aCol++)
{
ulong val = *(aSrcPtr++);
//*(aDestPtr++) = 0xFF000000 | ((val >> 24) & 0xFF);
int anAlpha = val >> 24;
if (anAlpha < 255)
*(aDestPtr++) = aTransColor;
else
*(aDestPtr++) = *a16SrcPtr;
++a16SrcPtr;
}
aDestPtr += mLockedSurfaceDesc.lPitch/2 - mWidth;
}
}
}
}
else
{
if (a16Bits != NULL)
{
ushort* aDestPtr = mSurfaceBits;
ushort* a16SrcPtr = a16Bits;
for (int aRow = 0; aRow < mHeight; aRow++)
{
for (int aCol = 0; aCol < mWidth; aCol++)
{
*(aDestPtr++) = *a16SrcPtr;
++a16SrcPtr;
}
aDestPtr += mLockedSurfaceDesc.lPitch/2 - mWidth;
}
}
}
delete a16Bits;
if (mHasTrans)
{
DDCOLORKEY aColorKey = {aTransColor, aTransColor};
mSurface->SetColorKey(DDCKEY_SRCBLT, &aColorKey);
}
}
}
else if (aNumBits == 32)
{
ulong* mSurfaceBits = (ulong*) mLockedSurfaceDesc.lpSurface;
if (mSurfaceBits != NULL)
{
int i;
bool firstTrans = true;
ulong aTransColor = 0;
if ((mHasTrans) && (mBits != NULL))
{
if (mFirstPixelTrans)
{
ulong val = *mBits;
aTransColor = (((val>>rRightShift)<<rLeftShift)&rMask) |
(((val>>gRightShift)<<gLeftShift)&gMask) |
(((val>>bRightShift)<<bLeftShift)&bMask);
if (mBits != NULL)
{
ulong* aDestPtr = mSurfaceBits;
ulong* aSrcPtr = mBits;
for (int aRow = 0; aRow < mHeight; aRow++)
{
for (int aCol = 0; aCol < mWidth; aCol++)
{
ulong val = *(aSrcPtr++);
*(aDestPtr++) =
(((val>>rRightShift)<<rLeftShift)&rMask) |
(((val>>gRightShift)<<gLeftShift)&gMask) |
(((val>>bRightShift)<<bLeftShift)&bMask);
}
aDestPtr += mLockedSurfaceDesc.lPitch/4 - mWidth;
}
}
}
else
{
ulong* aSrcPtr = mBits;
for (i = 0; i < mWidth*mHeight; i++)
{
ulong val = *(aSrcPtr++);
int anAlpha = val >> 24;
if ((firstTrans) && (anAlpha < 255))
{
firstTrans = false;
aTransColor = val;
}
}
bool needNewColor = false;
aSrcPtr = mBits;
for (i = 0; i < mWidth*mHeight; i++)
{
ulong val = *(aSrcPtr++);
int anAlpha = val >> 24;
if ((anAlpha == 255) && (aTransColor == (val & 0x00FFFFFF)))
{
needNewColor = true;
break;
}
}
if (needNewColor)
{
int* aUsedColorArray = new int[0x80000];
ZeroMemory(aUsedColorArray, 0x80000*sizeof(int));
aSrcPtr = mBits;
for (i = 0; i < mWidth*mHeight; i++)
{
ulong val = *(aSrcPtr++);
int anAlpha = val >> 24;
if (anAlpha > 0)
aUsedColorArray[(val & 0xFFFFFF)/32] |= (1<<(val%32));
}
bool done = false;
for (int i = 0; i < 0x80000; i++)
{
if (aUsedColorArray[i] != 0xFFFF)
{
for (int aBit = 0; aBit < 32; aBit++)
{
if ((aUsedColorArray[i] & (1<<aBit)) == 0)
{
aTransColor = i*32+aBit;
done = true;
break;
}
}
}
if (done)
break;
}
delete aUsedColorArray;
}
if (mBits != NULL)
{
ulong* aDestPtr = mSurfaceBits;
ulong* aSrcPtr = mBits;
for (int aRow = 0; aRow < mHeight; aRow++)
{
for (int aCol = 0; aCol < mWidth; aCol++)
{
ulong val = *(aSrcPtr++);
//*(aDestPtr++) = 0xFF000000 | ((val >> 24) & 0xFF);
int anAlpha = val >> 24;
if (anAlpha < 255)
*(aDestPtr++) = aTransColor;
else
{
*(aDestPtr++) =
(((val>>rRightShift)<<rLeftShift)&rMask) |
(((val>>gRightShift)<<gLeftShift)&gMask) |
(((val>>bRightShift)<<bLeftShift)&bMask);
}
}
aDestPtr += mLockedSurfaceDesc.lPitch/4 - mWidth;
}
}
}
DDCOLORKEY aColorKey = {aTransColor, aTransColor};
mSurface->SetColorKey(DDCKEY_SRCBLT, &aColorKey);
}
else
{
if (mBits != NULL)
{
ulong* aDestPtr = mSurfaceBits;
ulong* aSrcPtr = mBits;
for (int aRow = 0; aRow < mHeight; aRow++)
{
for (int aCol = 0; aCol < mWidth; aCol++)
{
ulong val = *(aSrcPtr++);
*(aDestPtr++) =
(((val>>rRightShift)<<rLeftShift)&rMask) |
(((val>>gRightShift)<<gLeftShift)&gMask) |
(((val>>bRightShift)<<bLeftShift)&bMask);
}
aDestPtr += mLockedSurfaceDesc.lPitch/4 - mWidth;
}
}
}
}
}
else
{
return false;
}
UnlockSurface();
return true;
}
void DDImage::DeleteDDSurface()
{
if (mSurface != NULL)
{
if ((mColorTable == NULL) && (mBits == NULL) && (mD3DData == NULL))
GetBits();
mSurface->Release();
mSurface = NULL;
}
}
void DDImage::ReInit()
{
MemoryImage::ReInit();
if (mWantDDSurface)
GenerateDDSurface();
}
void DDImage::PurgeBits()
{
if (mSurfaceSet)
return;
mPurgeBits = true;
CommitBits();
if (!mApp->Is3DAccelerated())
{
if ((mWantDDSurface) && (GenerateDDSurface()))
{
delete [] mBits;
mBits = NULL;
delete [] mColorIndices;
mColorIndices = NULL;
delete [] mColorTable;
mColorTable = NULL;
return;
}
}
else // Accelerated
{
if (mSurface != NULL)
{
GetBits();
DeleteDDSurface();
}
}
MemoryImage::PurgeBits();
}
void DDImage::DeleteAllNonSurfaceData()
{
delete [] mBits;
mBits = NULL;
delete [] mNativeAlphaData;
mNativeAlphaData = NULL;
delete [] mRLAdditiveData;
mRLAdditiveData = NULL;
delete [] mRLAlphaData;
mRLAlphaData = NULL;
delete [] mColorTable;
mColorTable = NULL;
delete [] mColorIndices;
mColorIndices = NULL;
}
void DDImage::DeleteNativeData()
{
if (mSurfaceSet)
return;
MemoryImage::DeleteNativeData();
DeleteDDSurface();
}
void DDImage::DeleteExtraBuffers()
{
if (mSurfaceSet)
return;
MemoryImage::DeleteExtraBuffers();
DeleteDDSurface();
}
void DDImage::SetVideoMemory(bool wantVideoMemory)
{
if (wantVideoMemory != mVideoMemory)
{
mVideoMemory = wantVideoMemory;
// Make sure that we have the bits
GetBits();
DeleteDDSurface();
}
}
void DDImage::RehupFirstPixelTrans()
{
if (!GenerateDDSurface())
return;
if ((mNoLock) || (!mHasTrans) || (!mFirstPixelTrans))
return;
// TDDSurfaceDesc aDesc;
DDSURFACEDESC aDesc;
ZeroMemory(&aDesc, sizeof(aDesc));
aDesc.dwSize = sizeof(aDesc);
aDesc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
HRESULT aResult = mDDInterface->mPrimarySurface->GetSurfaceDesc(&aDesc);
if (FAILED(aResult))
return;
int aNumBits = aDesc.ddpfPixelFormat.dwRGBBitCount;
if (aNumBits == 16)
{
if (!LockSurface())
return;
ushort* aSurfaceBits = (ushort*) mLockedSurfaceDesc.lpSurface;
ushort aTransColor = *aSurfaceBits;
DDCOLORKEY aColorKey = {aTransColor, aTransColor};
mSurface->SetColorKey(DDCKEY_SRCBLT, &aColorKey);
UnlockSurface();
}
else if ((aNumBits == 24) || (aNumBits == 32))
{
if (!LockSurface())
return;
ulong* aSurfaceBits = (ulong*) mLockedSurfaceDesc.lpSurface;
ulong aTransColor = *aSurfaceBits;
DDCOLORKEY aColorKey = {aTransColor, aTransColor};
mSurface->SetColorKey(DDCKEY_SRCBLT, &aColorKey);
UnlockSurface();
}
}
LPDIRECTDRAWSURFACE DDImage::GetSurface()
{
//TODO: Log if generate surface fails
if (mSurface == NULL)
GenerateDDSurface();
return mSurface;
}
bool DDImage::PolyFill3D(const Point theVertices[], int theNumVertices, const Rect *theClipRect, const Color &theColor, int theDrawMode, int tx, int ty, bool convex)
{
if (Check3D(this))
{
mDDInterface->mD3DInterface->FillPoly(theVertices,theNumVertices,theClipRect,theColor,theDrawMode,tx,ty);
return true;
}
else
return false;
}
void DDImage::FillRect(const Rect& theRect, const Color& theColor, int theDrawMode)
{
if (Check3D(this))
{
mDDInterface->mD3DInterface->FillRect(theRect,theColor,theDrawMode);
return;
}
CommitBits();
if ((mDrawToBits) || (mHasAlpha) || ((mHasTrans) && (!mFirstPixelTrans)) || (mDDInterface->mIs3D))
{
MemoryImage::FillRect(theRect, theColor, theDrawMode);
return;
}
switch (theDrawMode)
{
case Graphics::DRAWMODE_NORMAL:
NormalFillRect(theRect, theColor);
break;
case Graphics::DRAWMODE_ADDITIVE:
AdditiveFillRect(theRect, theColor);
break;
}
DeleteAllNonSurfaceData();
}
void DDImage::NormalDrawLine(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor)
{
if (mNoLock)
return;
double aMinX = min(theStartX, theEndX);
double aMinY = min(theStartY, theEndY);
double aMaxX = max(theStartX, theEndX);
double aMaxY = max(theStartY, theEndY);
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
ulong aRRoundAdd = aRMask >> 1;
ulong aGRoundAdd = aGMask >> 1;
ulong aBRoundAdd = aBMask >> 1;
if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
{
if (theColor.mAlpha == 255)
{
ushort aColor = (ushort)
(((((theColor.mRed * aRMask) + aRRoundAdd) >> 8) & aRMask) |
((((theColor.mGreen * aGMask) + aGRoundAdd) >> 8) & aGMask) |
((((theColor.mBlue * aBMask) + aBRoundAdd) >> 8) & aBMask));
double dv = theEndY - theStartY;
double dh = theEndX - theStartX;
int minG, maxG, G, DeltaG1, DeltaG2;
double swap;
int inc = 1;
int aCurX;
int aCurY;
int aRowWidth = mLockedSurfaceDesc.lPitch/2;
int aRowAdd = aRowWidth;
if (fabs(dv) < fabs(dh))
{
// Mostly horizontal
if (dh < 0)
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dv < 0)
{
dv = -dv;
inc = -1;
aRowAdd = -aRowAdd;
}
ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
*aDestPixels = aColor;
aDestPixels++;
aCurY = (int) theStartY;
aCurX = (int) theStartX + 1;
G = 2 * dv - dh;
DeltaG1 = 2 * (dv - dh);
DeltaG2 = 2 * dv;
G += DeltaG2 * (theStartY - (int) theStartY);
while (aCurX <= theEndX)
{
if (G > 0)
{
G += DeltaG1;
aCurY += inc;
aDestPixels += aRowAdd;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
*aDestPixels = aColor;
aCurX++;
aDestPixels++;
}
}
else
{
// Mostly vertical
if ( dv < 0 )
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dh < 0)
{
dh = -dh;
inc = -1;
}
ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * mLockedSurfaceDesc.lPitch/2) + (int) theStartX;
*aDestPixels = aColor;
aDestPixels += aRowAdd;
aCurX = theStartX;
aCurY = theStartY + 1;
G = 2 * dh - dv;
minG = maxG = G;
DeltaG1 = 2 * ( dh - dv );
DeltaG2 = 2 * dh;
G += DeltaG2 * (theStartX - (int) theStartX);
while (aCurY <= theEndY)
{
if ( G > 0 )
{
G += DeltaG1;
aCurX += inc;
aDestPixels += inc;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
*aDestPixels = aColor;
aCurY++;
aDestPixels += aRowAdd;
}
}
}
else
{
ushort src =
((((((theColor.mRed * theColor.mAlpha + 0x80) >> 8) * aRMask) + aRRoundAdd) >> 8) & aRMask) +
((((((theColor.mGreen * theColor.mAlpha + 0x80) >> 8) * aGMask) + aGRoundAdd) >> 8) & aGMask) +
((((((theColor.mBlue * theColor.mAlpha + 0x80) >> 8) * aBMask) + aBRoundAdd) >> 8) & aBMask);
int oma = 256 - theColor.mAlpha;
double dv = theEndY - theStartY;
double dh = theEndX - theStartX;
int minG, maxG, G, DeltaG1, DeltaG2;
double swap;
int inc = 1;
int aCurX;
int aCurY;
int aRowWidth = mLockedSurfaceDesc.lPitch/2;
int aRowAdd = aRowWidth;
if (abs(dv) < abs(dh))
{
// Mostly horizontal
if (dh < 0)
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dv < 0)
{
dv = -dv;
inc = -1;
aRowAdd = -aRowAdd;
}
ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
ushort dest = *aDestPixels;
*(aDestPixels++) = src +
(((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
(((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
(((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
aCurY = theStartY;
aCurX = theStartX + 1;
G = 2 * dv - dh;
DeltaG1 = 2 * (dv - dh);
DeltaG2 = 2 * dv;
G += DeltaG2 * (theStartY - (int) theStartY);
while (aCurX <= theEndX)
{
if (G > 0)
{
G += DeltaG1;
aCurY += inc;
aDestPixels += aRowAdd;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
dest = *aDestPixels;
*(aDestPixels++) = src +
(((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
(((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
(((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
aCurX++;
}
}
else
{
// Mostly vertical
if ( dv < 0 )
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dh < 0)
{
dh = -dh;
inc = -1;
}
ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * mLockedSurfaceDesc.lPitch/2) + (int) theStartX;
ushort dest = *aDestPixels;
*aDestPixels = src +
(((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
(((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
(((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
aDestPixels += aRowAdd;
aCurX = theStartX;
aCurY = theStartY + 1;
G = 2 * dh - dv;
minG = maxG = G;
DeltaG1 = 2 * ( dh - dv );
DeltaG2 = 2 * dh;
G += DeltaG2 * (theStartX - (int) theStartX);
while (aCurY <= theEndY)
{
if ( G > 0 )
{
G += DeltaG1;
aCurX += inc;
aDestPixels += inc;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
dest = *aDestPixels;
*aDestPixels = src +
(((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
(((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
(((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
aCurY++;
aDestPixels += aRowAdd;
}
}
}
}
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
{
if (theColor.mAlpha == 255)
{
ulong aColor =
((((theColor.mRed * aRMask) + aRRoundAdd) >> 8) & aRMask) |
((((theColor.mGreen * aGMask) + aGRoundAdd) >> 8) & aGMask) |
((((theColor.mBlue * aBMask) + aBRoundAdd) >> 8) & aBMask);
double dv = theEndY - theStartY;
double dh = theEndX - theStartX;
int minG, maxG, G, DeltaG1, DeltaG2;
double swap;
int inc = 1;
int aCurX;
int aCurY;
int aRowWidth = mLockedSurfaceDesc.lPitch/4;
int aRowAdd = aRowWidth;;
if (abs(dv) < abs(dh))
{
// Mostly horizontal
if (dh < 0)
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dv < 0)
{
dv = -dv;
inc = -1;
aRowAdd = -aRowAdd;
}
ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
*aDestPixels = aColor;
aDestPixels++;
aCurY = theStartY;
aCurX = theStartX + 1;
G = 2 * dv - dh;
DeltaG1 = 2 * (dv - dh);
DeltaG2 = 2 * dv;
G += DeltaG2 * (theStartY - (int) theStartY);
while (aCurX <= theEndX)
{
if (G > 0)
{
G += DeltaG1;
aCurY += inc;
aDestPixels += aRowAdd;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
*aDestPixels = aColor;
aCurX++;
aDestPixels++;
}
}
else
{
// Mostly vertical
if ( dv < 0 )
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dh < 0)
{
dh = -dh;
inc = -1;
}
ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
*aDestPixels = aColor;
aDestPixels += aRowAdd;
aCurX = theStartX;
aCurY = theStartY + 1;
G = 2 * dh - dv;
minG = maxG = G;
DeltaG1 = 2 * ( dh - dv );
DeltaG2 = 2 * dh;
G += DeltaG2 * (theStartX - (int) theStartX);
while (aCurY <= theEndY)
{
if ( G > 0 )
{
G += DeltaG1;
aCurX += inc;
aDestPixels += inc;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
*aDestPixels = aColor;
aCurY++;
aDestPixels += aRowAdd;
}
}
}
else
{
ulong src =
((((((theColor.mRed * theColor.mAlpha + 0x80) >> 8) * aRMask) + aRRoundAdd) >> 8) & aRMask) +
((((((theColor.mGreen * theColor.mAlpha + 0x80) >> 8) * aGMask) + aGRoundAdd) >> 8) & aGMask) +
((((((theColor.mBlue * theColor.mAlpha + 0x80) >> 8) * aBMask) + aBRoundAdd) >> 8) & aBMask);
int oma = 256 - theColor.mAlpha;
double dv = theEndY - theStartY;
double dh = theEndX - theStartX;
int minG, maxG, G, DeltaG1, DeltaG2;
double swap;
int inc = 1;
int aCurX;
int aCurY;
int aRowWidth = mLockedSurfaceDesc.lPitch/4;
int aRowAdd = aRowWidth;
if (abs(dv) < abs(dh))
{
// Mostly horizontal
if (dh < 0)
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dv < 0)
{
dv = -dv;
inc = -1;
aRowAdd = -aRowAdd;
}
ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
ulong dest = *aDestPixels;
*(aDestPixels++) = src +
(((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
(((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
(((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
aCurY = theStartY;
aCurX = theStartX + 1;
G = 2 * dv - dh;
DeltaG1 = 2 * (dv - dh);
DeltaG2 = 2 * dv;
G += DeltaG2 * (theStartX - (int) theStartX);
while (aCurX <= theEndX)
{
if (G > 0)
{
G += DeltaG1;
aCurY += inc;
aDestPixels += aRowAdd;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
dest = *aDestPixels;
*(aDestPixels++) = src +
(((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
(((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
(((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
aCurX++;
}
}
else
{
// Mostly vertical
if ( dv < 0 )
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dh < 0)
{
dh = -dh;
inc = -1;
}
ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
ulong dest = *aDestPixels;
*aDestPixels = src +
(((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
(((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
(((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
aDestPixels += aRowAdd;
aCurX = theStartX;
aCurY = theStartY + 1;
G = 2 * dh - dv;
minG = maxG = G;
DeltaG1 = 2 * ( dh - dv );
DeltaG2 = 2 * dh;
G += DeltaG2 * (theStartX - (int) theStartX);
while (aCurY <= theEndY)
{
if ( G > 0 )
{
G += DeltaG1;
aCurX += inc;
aDestPixels += inc;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
dest = *aDestPixels;
*aDestPixels = src +
(((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
(((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
(((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
aCurY++;
aDestPixels += aRowAdd;
}
}
}
}
UnlockSurface();
}
void DDImage::AdditiveDrawLine(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor)
{
if (mNoLock)
return;
double aMinX = min(theStartX, theEndX);
double aMinY = min(theStartY, theEndY);
double aMaxX = max(theStartX, theEndX);
double aMaxY = max(theStartY, theEndY);
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
ulong aRRoundAdd = aRMask >> 1;
ulong aGRoundAdd = aGMask >> 1;
ulong aBRoundAdd = aBMask >> 1;
int aRedShift = mDDInterface->mRedShift;
int aGreenShift = mDDInterface->mGreenShift;
int aBlueShift = mDDInterface->mBlueShift;
int* aMaxRedTable = mDDInterface->mRedAddTable;
int* aMaxGreenTable = mDDInterface->mGreenAddTable;
int* aMaxBlueTable = mDDInterface->mBlueAddTable;
if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
{
ushort rc = ((theColor.mRed * theColor.mAlpha) / 255) >> (8-mDDInterface->mRedBits);
ushort gc = ((theColor.mGreen * theColor.mAlpha) / 255) >> (8-mDDInterface->mGreenBits);
ushort bc = ((theColor.mBlue * theColor.mAlpha) / 255) >> (8-mDDInterface->mBlueBits);
double dv = theEndY - theStartY;
double dh = theEndX - theStartX;
int minG, maxG, G, DeltaG1, DeltaG2;
double swap;
int inc = 1;
int aCurX;
int aCurY;
int aRowWidth = mLockedSurfaceDesc.lPitch/2;
int aRowAdd = aRowWidth;
if (abs(dv) < abs(dh))
{
// Mostly horizontal
if (dh < 0)
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dv < 0)
{
dv = -dv;
inc = -1;
aRowAdd = -aRowAdd;
}
ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
ushort dest = *aDestPixels;
int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
*(aDestPixels++) =
(r << aRedShift) |
(g << aGreenShift) |
(b << aBlueShift);
aCurY = theStartY;
aCurX = theStartX + 1;
G = 2 * dv - dh;
DeltaG1 = 2 * (dv - dh);
DeltaG2 = 2 * dv;
G += DeltaG2 * (theStartY - (int) theStartY);
while (aCurX <= theEndX)
{
if (G > 0)
{
G += DeltaG1;
aCurY += inc;
aDestPixels += aRowAdd;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
dest = *aDestPixels;
r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
*(aDestPixels++) =
(r << aRedShift) |
(g << aGreenShift) |
(b << aBlueShift);
aCurX++;
}
}
else
{
// Mostly vertical
if ( dv < 0 )
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dh < 0)
{
dh = -dh;
inc = -1;
}
ushort* aDestPixels = ((ushort*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * mLockedSurfaceDesc.lPitch/2) + (int) theStartX;
ushort dest = *aDestPixels;
int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
*aDestPixels =
(r << aRedShift) |
(g << aGreenShift) |
(b << aBlueShift);
aDestPixels += aRowAdd;
aCurX = theStartX;
aCurY = theStartY + 1;
G = 2 * dh - dv;
minG = maxG = G;
DeltaG1 = 2 * ( dh - dv );
DeltaG2 = 2 * dh;
G += DeltaG2 * (theStartX - (int) theStartX);
while (aCurY <= theEndY)
{
if ( G > 0 )
{
G += DeltaG1;
aCurX += inc;
aDestPixels += inc;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
dest = *aDestPixels;
r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
*aDestPixels =
(r << aRedShift) |
(g << aGreenShift) |
(b << aBlueShift);
aCurY++;
aDestPixels += aRowAdd;
}
}
}
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
{
ulong rc = ((theColor.mRed * theColor.mAlpha) / 255) >> (8-mDDInterface->mRedBits);
ulong gc = ((theColor.mGreen * theColor.mAlpha) / 255) >> (8-mDDInterface->mGreenBits);
ulong bc = ((theColor.mBlue * theColor.mAlpha) / 255) >> (8-mDDInterface->mBlueBits);
double dv = theEndY - theStartY;
double dh = theEndX - theStartX;
int minG, maxG, G, DeltaG1, DeltaG2;
double swap;
int inc = 1;
int aCurX;
int aCurY;
int aRowWidth = mLockedSurfaceDesc.lPitch/4;
int aRowAdd = aRowWidth;
if (abs(dv) < abs(dh))
{
// Mostly horizontal
if (dh < 0)
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dv < 0)
{
dv = -dv;
inc = -1;
aRowAdd = -aRowAdd;
}
ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * aRowWidth) + (int) theStartX;
ulong dest = *aDestPixels;
int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
*(aDestPixels++) =
(r << aRedShift) |
(g << aGreenShift) |
(b << aBlueShift);
aCurY = theStartY;
aCurX = theStartX + 1;
G = 2 * dv - dh;
DeltaG1 = 2 * (dv - dh);
DeltaG2 = 2 * dv;
while (aCurX <= theEndX)
{
if (G > 0)
{
G += DeltaG1;
aCurY += inc;
aDestPixels += aRowAdd;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
dest = *aDestPixels;
r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
*(aDestPixels++) =
(r << aRedShift) |
(g << aGreenShift) |
(b << aBlueShift);
aCurX++;
}
}
else
{
// Mostly vertical
if ( dv < 0 )
{
dh = -dh;
dv = -dv;
swap = theEndY;
theEndY = theStartY;
theStartY = swap;
swap = theEndX;
theEndX = theStartX;
theStartX = swap;
}
if (dh < 0)
{
dh = -dh;
inc = -1;
}
ulong* aDestPixels = ((ulong*) mLockedSurfaceDesc.lpSurface) + ((int) theStartY * mLockedSurfaceDesc.lPitch/4) + (int) theStartX;
ulong dest = *aDestPixels;
int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
*aDestPixels =
(r << aRedShift) |
(g << aGreenShift) |
(b << aBlueShift);
aDestPixels += aRowAdd;
aCurX = theStartX;
aCurY = theStartY + 1;
G = 2 * dh - dv;
minG = maxG = G;
DeltaG1 = 2 * ( dh - dv );
DeltaG2 = 2 * dh;
while (aCurY <= theEndY)
{
if ( G > 0 )
{
G += DeltaG1;
aCurX += inc;
aDestPixels += inc;
if (aCurX<aMinX || aCurY<aMinY || aCurX>aMaxX || aCurY>aMaxY)
break;
}
else
G += DeltaG2;
dest = *aDestPixels;
r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
*aDestPixels =
(r << aRedShift) |
(g << aGreenShift) |
(b << aBlueShift);
aCurY++;
aDestPixels += aRowAdd;
}
}
}
UnlockSurface();
}
void DDImage::DrawLine(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor, int theDrawMode)
{
if (Check3D(this))
{
mDDInterface->mD3DInterface->DrawLine(theStartX,theStartY,theEndX,theEndY,theColor,theDrawMode);
return;
}
if ((mDrawToBits) || (mHasAlpha) || (mHasTrans) || (mDDInterface->mIs3D))
{
MemoryImage::DrawLine(theStartX, theStartY, theEndX, theEndY, theColor, theDrawMode);
return;
}
if (theStartY == theEndY)
{
int aStartX = min(theStartX, theEndX);
int aEndX = max(theStartX, theEndX);
FillRect(Rect(aStartX, theStartY, aEndX-aStartX+1, theEndY-theStartY+1), theColor, theDrawMode);
return;
}
else if (theStartX == theEndX)
{
int aStartY = min(theStartY, theEndY);
int aEndY = max(theStartY, theEndY);
FillRect(Rect(theStartX, aStartY, theEndX-theStartX+1, aEndY-aStartY+1), theColor, theDrawMode);
return;
}
CommitBits();
switch (theDrawMode)
{
case Graphics::DRAWMODE_NORMAL:
NormalDrawLine(theStartX, theStartY, theEndX, theEndY, theColor);
break;
case Graphics::DRAWMODE_ADDITIVE:
AdditiveDrawLine(theStartX, theStartY, theEndX, theEndY, theColor);
break;
}
DeleteAllNonSurfaceData();
}
void DDImage::NormalDrawLineAA(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor)
{
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
ulong color = (((theColor.mRed * aRMask) >> 8) & aRMask) |
(((theColor.mGreen * aGMask) >> 8) & aGMask) |
(((theColor.mBlue * aBMask) >> 8) & aBMask);
int aX0 = (int)theStartX, aX1 = (int)theEndX;
int aY0 = (int)theStartY, aY1 = (int)theEndY;
int aXinc = 1;
if (aY0 > aY1)
{
int aTempX = aX0, aTempY = aY0;
aX0 = aX1; aY0 = aY1;
aX1 = aTempX; aY1 = aTempY;
double aTempXd = theStartX, aTempYd = theStartY;
theStartX = theEndX; theStartY = theEndY;
theEndX = aTempXd; theEndY = aTempYd;
}
int dx = aX1 - aX0;
int dy = aY1 - aY0;
double dxd = theEndX - theStartX;
double dyd = theEndY - theStartY;
if (dx < 0)
{
dx = -dx;
aXinc = -1;
dxd = -dxd;
}
if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
{
ulong* aBits = (ulong*)mLockedSurfaceDesc.lpSurface;
#ifdef OPTIMIZE_SOFTWARE_DRAWING
if (theColor.mAlpha != 255)
{
#define PIXEL_TYPE ulong
#define CALC_WEIGHT_A(w) (((w) * (theColor.mAlpha+1)) >> 8)
#define BLEND_PIXEL(p) \
*(p) = \
((((color & 0xFF00FF) * a + (dest & 0xFF00FF) * oma) >> 8) & 0xFF00FF) |\
((((color & 0x00FF00) * a + (dest & 0x00FF00) * oma) >> 8) & 0x00FF00);
const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
#include "GENERIC_DrawLineAA.inc"
#undef PIXEL_TYPE
#undef CALC_WEIGHT_A
#undef BLEND_PIXEL
}
else
{
#define PIXEL_TYPE ulong
#define CALC_WEIGHT_A(w) (w)
#define BLEND_PIXEL(p) \
*(p) = \
((((color & 0xFF00FF) * a + (dest & 0xFF00FF) * oma) >> 8) & 0xFF00FF) |\
((((color & 0x00FF00) * a + (dest & 0x00FF00) * oma) >> 8) & 0x00FF00);
const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
#include "GENERIC_DrawLineAA.inc"
#undef PIXEL_TYPE
#undef CALC_WEIGHT_A
#undef BLEND_PIXEL
}
#else
if (theColor.mAlpha != 255)
{
#define PIXEL_TYPE ulong
#define CALC_WEIGHT_A(w) (((w) * (theColor.mAlpha+1)) >> 8)
#define BLEND_PIXEL(p) \
*(p) = \
((((color & aRMask) * a + (dest & aRMask) * oma) >> 8) & aRMask) |\
((((color & aGMask) * a + (dest & aGMask) * oma) >> 8) & aGMask) |\
((((color & aBMask) * a + (dest & aBMask) * oma) >> 8) & aBMask);
const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
#include "GENERIC_DrawLineAA.inc"
#undef PIXEL_TYPE
#undef CALC_WEIGHT_A
#undef BLEND_PIXEL
}
else
{
#define PIXEL_TYPE ulong
#define CALC_WEIGHT_A(w) (w)
#define BLEND_PIXEL(p) \
*(p) = \
((((color & aRMask) * a + (dest & aRMask) * oma) >> 8) & aRMask) |\
((((color & aGMask) * a + (dest & aGMask) * oma) >> 8) & aGMask) |\
((((color & aBMask) * a + (dest & aBMask) * oma) >> 8) & aBMask);
const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
#include "GENERIC_DrawLineAA.inc"
#undef PIXEL_TYPE
#undef CALC_WEIGHT_A
#undef BLEND_PIXEL
}
#endif
}
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
{
ushort* aBits = (ushort*)mLockedSurfaceDesc.lpSurface;
#ifdef OPTIMIZE_SOFTWARE_DRAWING
if (aGMask == 0x3E0) // 5-5-5
{
#define PIXEL_TYPE ushort
#define BLEND_PIXEL(p) \
{\
a >>= 3;\
oma >>= 3;\
ulong _src = (((color | (color << 16)) & 0x3E07C1F) * a >> 5) & 0x3E07C1F;\
ulong _dest = (((dest | (dest << 16)) & 0x3E07C1F) * oma >> 5) & 0x3E07C1F;\
*(p) = (_src | (_src>>16)) + (_dest | (_dest>>16));\
}
const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
if (theColor.mAlpha != 255)
{
#define CALC_WEIGHT_A(w) (((w) * (theColor.mAlpha+1)) >> 8)
#include "GENERIC_DrawLineAA.inc"
#undef CALC_WEIGHT_A
}
else
{
#define CALC_WEIGHT_A(w) (w)
#include "GENERIC_DrawLineAA.inc"
#undef CALC_WEIGHT_A
}
#undef PIXEL_TYPE
#undef BLEND_PIXEL
}
else if (aGMask == 0x7E0) // 5-6-5
{
#define PIXEL_TYPE ushort
#define BLEND_PIXEL(p) \
{\
a >>= 3;\
oma >>= 3;\
ulong _src = (((color | (color << 16)) & 0x7E0F81F) * a >> 5) & 0x7E0F81F;\
ulong _dest = (((dest | (dest << 16)) & 0x7E0F81F) * oma >> 5) & 0x7E0F81F;\
*(p) = (_src | (_src>>16)) + (_dest | (_dest>>16));\
}
const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
if (theColor.mAlpha != 255)
{
#define CALC_WEIGHT_A(w) (((w) * (theColor.mAlpha+1)) >> 8)
#include "GENERIC_DrawLineAA.inc"
#undef CALC_WEIGHT_A
}
else
{
#define CALC_WEIGHT_A(w) (w)
#include "GENERIC_DrawLineAA.inc"
#undef CALC_WEIGHT_A
}
#undef PIXEL_TYPE
#undef BLEND_PIXEL
}
else
{
#endif
if (theColor.mAlpha != 255)
{
#define PIXEL_TYPE ushort
#define CALC_WEIGHT_A(w) (((w) * (theColor.mAlpha+1)) >> 8)
#define BLEND_PIXEL(p) \
*(p) = \
((((color & aRMask) * a + (dest & aRMask) * oma) >> 8) & aRMask) |\
((((color & aGMask) * a + (dest & aGMask) * oma) >> 8) & aGMask) |\
((((color & aBMask) * a + (dest & aBMask) * oma) >> 8) & aBMask);
const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
#include "GENERIC_DrawLineAA.inc"
#undef PIXEL_TYPE
#undef CALC_WEIGHT_A
#undef BLEND_PIXEL
}
else
{
#define PIXEL_TYPE ushort
#define CALC_WEIGHT_A(w) (w)
#define BLEND_PIXEL(p) \
*(p) = \
((((color & aRMask) * a + (dest & aRMask) * oma) >> 8) & aRMask) |\
((((color & aGMask) * a + (dest & aGMask) * oma) >> 8) & aGMask) |\
((((color & aBMask) * a + (dest & aBMask) * oma) >> 8) & aBMask);
const int STRIDE = mLockedSurfaceDesc.lPitch / sizeof(PIXEL_TYPE);
#include "GENERIC_DrawLineAA.inc"
#undef PIXEL_TYPE
#undef CALC_WEIGHT_A
#undef BLEND_PIXEL
}
#ifdef OPTIMIZE_SOFTWARE_DRAWING
}
#endif
}
UnlockSurface();
}
void DDImage::AdditiveDrawLineAA(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor)
{
}
void DDImage::DrawLineAA(double theStartX, double theStartY, double theEndX, double theEndY, const Color& theColor, int theDrawMode)
{
if (Check3D(this))
{
mDDInterface->mD3DInterface->DrawLine(theStartX,theStartY,theEndX,theEndY,theColor,theDrawMode);
return;
}
if ((mDrawToBits) || (mHasAlpha) || (mHasTrans) || (mDDInterface->mIs3D))
{
MemoryImage::DrawLine(theStartX, theStartY, theEndX, theEndY, theColor, theDrawMode);
return;
}
if (theStartY == theEndY)
{
int aStartX = min(theStartX, theEndX);
int aEndX = max(theStartX, theEndX);
FillRect(Rect(aStartX, theStartY, aEndX-aStartX+1, theEndY-theStartY+1), theColor, theDrawMode);
return;
}
else if (theStartX == theEndX)
{
int aStartY = min(theStartY, theEndY);
int aEndY = max(theStartY, theEndY);
FillRect(Rect(theStartX, aStartY, theEndX-theStartX+1, aEndY-aStartY+1), theColor, theDrawMode);
return;
}
CommitBits();
switch (theDrawMode)
{
case Graphics::DRAWMODE_NORMAL:
NormalDrawLineAA(theStartX, theStartY, theEndX, theEndY, theColor);
break;
case Graphics::DRAWMODE_ADDITIVE:
AdditiveDrawLineAA(theStartX, theStartY, theEndX, theEndY, theColor);
break;
}
DeleteAllNonSurfaceData();
}
void DDImage::CommitBits()
{
if (mSurface == NULL)
{
MemoryImage::CommitBits();
return;
}
}
void DDImage::Create(int theWidth, int theHeight)
{
delete [] mBits;
mWidth = theWidth;
mHeight = theHeight;
mBits = NULL;
BitsChanged();
}
void DDImage::BitsChanged()
{
MemoryImage::BitsChanged();
if (mSurface != NULL)
mSurface->Release();
mSurface = NULL;
}
ulong* DDImage::GetBits()
{
if (mBits == NULL)
{
if (mSurface == NULL)
return MemoryImage::GetBits();
if (mNoLock)
return NULL;
LPDIRECTDRAWSURFACE aSurface = mSurface;
if (!LockSurface())
return NULL;
mBits = new ulong[mWidth*mHeight + 1];
mBits[mWidth*mHeight] = MEMORYCHECK_ID;
int aRRound = (1 << (7 - mDDInterface->mRedBits));
int aGRound = (1 << (7 - mDDInterface->mGreenBits));
int aBRound = (1 << (7 - mDDInterface->mBlueBits));
if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
{
ushort* aSrcPixelsRow = (ushort*) mLockedSurfaceDesc.lpSurface;
ulong* aDest = mBits;
for (int y = 0; y < mHeight; y++)
{
ushort* aSrcPixels = aSrcPixelsRow;
for (int x = 0; x < mWidth; x++)
{
ulong src = *(aSrcPixels++);
int r = ((src >> mDDInterface->mRedShift << (8 - mDDInterface->mRedBits)) & 0xFF);
int g = ((src >> mDDInterface->mGreenShift << (8 - mDDInterface->mGreenBits)) & 0xFF);
int b = ((src >> mDDInterface->mBlueShift << (8 - mDDInterface->mBlueBits)) & 0xFF);
*aDest++ = 0xFF000000 | (r << 16) | (g << 8) | (b);
}
aSrcPixelsRow += mLockedSurfaceDesc.lPitch/2;
}
}
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
{
ulong* aSrcPixelsRow = (ulong*) mLockedSurfaceDesc.lpSurface;
ulong* aDest = mBits;
for (int y = 0; y < mHeight; y++)
{
ulong* aSrcPixels = aSrcPixelsRow;
for (int x = 0; x < mWidth; x++)
{
ulong src = *(aSrcPixels++);
int r = (src >> mDDInterface->mRedShift << (8 - mDDInterface->mRedBits)) & 0xFF;
int g = (src >> mDDInterface->mGreenShift << (8 - mDDInterface->mGreenBits)) & 0xFF;
int b = (src >> mDDInterface->mBlueShift << (8 - mDDInterface->mBlueBits)) & 0xFF;
*aDest++ = 0xFF000000 | (r << 16) | (g << 8) | (b);
}
aSrcPixelsRow += mLockedSurfaceDesc.lPitch/4;
}
}
UnlockSurface();
}
return mBits;
}
void DDImage::NormalFillRect(const Rect& theRect, const Color& theColor)
{
if (mNoLock)
return;
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
ulong aRRoundAdd = aRMask;
ulong aGRoundAdd = aGMask;
ulong aBRoundAdd = aBMask;
if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
{
if (theColor.mAlpha == 255)
{
ushort aColor =
((((theColor.mRed * aRMask) + aRRoundAdd) >> 8) & aRMask) |
((((theColor.mGreen * aGMask) + aGRoundAdd) >> 8) & aGMask) |
((((theColor.mBlue * aBMask) + aBRoundAdd) >> 8) & aBMask);
ushort* aDestPixelsRow = ((ushort*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/2) + theRect.mX;
for (int y = 0; y < theRect.mHeight; y++)
{
ushort* aDestPixels = aDestPixelsRow;
for (int x = 0; x < theRect.mWidth; x++)
*(aDestPixels++) = aColor;
aDestPixelsRow += mLockedSurfaceDesc.lPitch/2;
}
}
else
{
ushort src =
((((((theColor.mRed * theColor.mAlpha + 0x80) >> 8) * aRMask) + aRRoundAdd) >> 8) & aRMask) +
((((((theColor.mGreen * theColor.mAlpha + 0x80) >> 8) * aGMask) + aGRoundAdd) >> 8) & aGMask) +
((((((theColor.mBlue * theColor.mAlpha + 0x80) >> 8) * aBMask) + aBRoundAdd) >> 8) & aBMask);
int oma = 256 - theColor.mAlpha;
ushort* aDestPixelsRow = ((ushort*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/2) + theRect.mX;
for (int y = 0; y < theRect.mHeight; y++)
{
ushort* aDestPixels = aDestPixelsRow;
for (int x = 0; x < theRect.mWidth; x++)
{
ushort dest = *aDestPixels;
*(aDestPixels++) = src +
(((((dest & aRMask) * oma) + aRRoundAdd) >> 8) & aRMask) +
(((((dest & aGMask) * oma) + aGRoundAdd) >> 8) & aGMask) +
(((((dest & aBMask) * oma) + aBRoundAdd) >> 8) & aBMask);
}
aDestPixelsRow += mLockedSurfaceDesc.lPitch/2;
}
}
}
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
{
if (theColor.mAlpha == 255)
{
ulong aColor =
((((theColor.mRed * aRMask)) >> 8) & aRMask) |
((((theColor.mGreen * aGMask)) >> 8) & aGMask) |
((((theColor.mBlue * aBMask)) >> 8) & aBMask);
ulong* aDestPixelsRow = ((ulong*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/4) + theRect.mX;
for (int y = 0; y < theRect.mHeight; y++)
{
ulong* aDestPixels = aDestPixelsRow;
for (int x = 0; x < theRect.mWidth; x++)
*(aDestPixels++) = aColor;
aDestPixelsRow += mLockedSurfaceDesc.lPitch/4;
}
}
else
{
ulong src =
((((((theColor.mRed * theColor.mAlpha + 0x7F) >> 8) * aRMask) + aRRoundAdd) >> 8) & aRMask) +
((((((theColor.mGreen * theColor.mAlpha + 0x7F) >> 8) * aGMask) + aGRoundAdd) >> 8) & aGMask) +
((((((theColor.mBlue * theColor.mAlpha + 0x7F) >> 8) * aBMask) + aBRoundAdd) >> 8) & aBMask);
int oma = 256 - theColor.mAlpha;
ulong* aDestPixelsRow = ((ulong*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/4) + theRect.mX;
for (int y = 0; y < theRect.mHeight; y++)
{
ulong* aDestPixels = aDestPixelsRow;
for (int x = 0; x < theRect.mWidth; x++)
{
ulong dest = *aDestPixels;
*(aDestPixels++) = src +
(((((dest & aRMask) * oma)) >> 8) & aRMask) +
(((((dest & aGMask) * oma)) >> 8) & aGMask) +
(((((dest & aBMask) * oma)) >> 8) & aBMask);
}
aDestPixelsRow += mLockedSurfaceDesc.lPitch/4;
}
}
}
UnlockSurface();
}
void DDImage::AdditiveFillRect(const Rect& theRect, const Color& theColor)
{
if (mNoLock)
return;
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
ulong aRRoundAdd = aRMask >> 1;
ulong aGRoundAdd = aGMask >> 1;
ulong aBRoundAdd = aBMask >> 1;
int aRedShift = mDDInterface->mRedShift;
int aGreenShift = mDDInterface->mGreenShift;
int aBlueShift = mDDInterface->mBlueShift;
int* aMaxRedTable = mDDInterface->mRedAddTable;
int* aMaxGreenTable = mDDInterface->mGreenAddTable;
int* aMaxBlueTable = mDDInterface->mBlueAddTable;
if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
{
ushort rc = ((theColor.mRed * theColor.mAlpha) / 255) >> (8-mDDInterface->mRedBits);
ushort gc = ((theColor.mGreen * theColor.mAlpha) / 255) >> (8-mDDInterface->mGreenBits);
ushort bc = ((theColor.mBlue * theColor.mAlpha) / 255) >> (8-mDDInterface->mBlueBits);
ushort* aDestPixelsRow = ((ushort*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/2) + theRect.mX;
for (int y = 0; y < theRect.mHeight; y++)
{
ushort* aDestPixels = aDestPixelsRow;
for (int x = 0; x < theRect.mWidth; x++)
{
ushort dest = *aDestPixels;
int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
*(aDestPixels++) =
(r << aRedShift) |
(g << aGreenShift) |
(b << aBlueShift);
}
aDestPixelsRow += mLockedSurfaceDesc.lPitch/2;
}
}
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
{
ulong rc = ((theColor.mRed * theColor.mAlpha) / 255) >> (8-mDDInterface->mRedBits);
ulong gc = ((theColor.mGreen * theColor.mAlpha) / 255) >> (8-mDDInterface->mGreenBits);
ulong bc = ((theColor.mBlue * theColor.mAlpha) / 255) >> (8-mDDInterface->mBlueBits);
ulong* aDestPixelsRow = ((ulong*) mLockedSurfaceDesc.lpSurface) + (theRect.mY * mLockedSurfaceDesc.lPitch/4) + theRect.mX;
for (int y = 0; y < theRect.mHeight; y++)
{
ulong* aDestPixels = aDestPixelsRow;
for (int x = 0; x < theRect.mWidth; x++)
{
ulong dest = *aDestPixels;
int r = aMaxRedTable[((dest & aRMask) >> aRedShift) + rc];
int g = aMaxGreenTable[((dest & aGMask) >> aGreenShift) + gc];
int b = aMaxBlueTable[((dest & aBMask) >> aBlueShift) + bc];
*(aDestPixels++) =
(r << aRedShift) |
(g << aGreenShift) |
(b << aBlueShift);
}
aDestPixelsRow += mLockedSurfaceDesc.lPitch/4;
}
}
UnlockSurface();
}
void DDImage::NormalBlt(Image* theImage, int theX, int theY, const Rect& theSrcRect, const Color& theColor)
{
theImage->mDrawn = true;
MemoryImage* aMemoryImage = dynamic_cast<MemoryImage*>(theImage);
DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);
if (aMemoryImage != NULL)
{
aMemoryImage->CommitBits();
RECT aDestRect = {theX, theY, theX + theSrcRect.mWidth, theY + theSrcRect.mHeight};
RECT aSrcRect = {theSrcRect.mX, theSrcRect.mY, theSrcRect.mX + theSrcRect.mWidth, theSrcRect.mY + theSrcRect.mHeight};
//TODO:
if ((aMemoryImage->mIsVolatile) && ((aDDImage == NULL) || (aDDImage->mSurface == NULL)) &&
(!mNoLock) && (theColor == Color::White))
{
if (aMemoryImage->mColorTable == NULL)
{
ulong* aSrcBits = aMemoryImage->GetBits();
#define SRC_TYPE ulong
#define NEXT_SRC_COLOR (*(aSrcPixels++))
#include "DDI_NormalBlt_Volatile.inc"
#undef SRC_TYPE
#undef NEXT_SRC_COLOR
}
else
{
ulong* aColorTable = aMemoryImage->mColorTable;
uchar* aSrcBits = aMemoryImage->mColorIndices;
#define SRC_TYPE uchar
#define NEXT_SRC_COLOR (aColorTable[*(aSrcPixels++)])
#include "DDI_NormalBlt_Volatile.inc"
#undef SRC_TYPE
#undef NEXT_SRC_COLOR
}
}
else if ((aMemoryImage->mHasAlpha) || (theColor != Color::White))
{
if (mNoLock)
return;
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
// Ensure NativeAlphaData is calculated
void *aNativeData = aMemoryImage->GetNativeAlphaData(mDDInterface);
// Ensure RunLength data is calculated
uchar* aSrcRLAlphaData = aMemoryImage->GetRLAlphaData();
#define _PLUSPLUS ++
#define _PLUSEQUALS +=
if (aMemoryImage->mColorTable == NULL)
{
ulong* aSrcPixelsRow = ((ulong*) aNativeData) + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
ulong* aSrcPixels;
#define NEXT_SRC_COLOR (*(aSrcPixels++))
#define PEEK_SRC_COLOR (*aSrcPixels)
#include "DDI_AlphaBlt.inc"
#undef NEXT_SRC_COLOR
#undef PEEK_SRC_COLOR
}
else
{
ulong* aNativeColorTable = (ulong*) aNativeData;
uchar* aSrcPixelsRow = aMemoryImage->mColorIndices + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
uchar* aSrcPixels;
#define NEXT_SRC_COLOR (aNativeColorTable[*(aSrcPixels++)])
#define PEEK_SRC_COLOR (aNativeColorTable[*aSrcPixels])
#include "DDI_AlphaBlt.inc"
#undef NEXT_SRC_COLOR
#undef PEEK_SRC_COLOR
}
#undef _PLUSPLUS
#undef _PLUSEQUALS
UnlockSurface();
}
else if ((aDDImage == NULL) || (aDDImage->mSurface == NULL) || ((!mVideoMemory) && (aDDImage->mVideoMemory)))
{
if (mNoLock)
return;
//TODO: Have some sort of cool thing here
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
void* aNativeAlphaData = aMemoryImage->GetNativeAlphaData(mDDInterface);
if (aMemoryImage->mColorTable == NULL)
{
ulong* aSrcPixelsRow = ((ulong*) aNativeAlphaData) + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
ulong* aSrcPixels;
#define NEXT_SRC_COLOR (*(aSrcPixels++))
#define PEEK_SRC_COLOR (*aSrcPixels)
#include "DDI_FastBlt_NoAlpha.inc"
#undef NEXT_SRC_COLOR
#undef PEEK_SRC_COLOR
}
else
{
ulong* aNativeAlphaColorTable = (ulong*) aNativeAlphaData;
uchar* aSrcPixelsRow = aMemoryImage->mColorIndices + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
uchar* aSrcPixels;
#define NEXT_SRC_COLOR (aNativeAlphaColorTable[*(aSrcPixels++)])
#define PEEK_SRC_COLOR (aNativeAlphaColorTable[*aSrcPixels])
#include "DDI_FastBlt_NoAlpha.inc"
#undef NEXT_SRC_COLOR
#undef PEEK_SRC_COLOR
}
}
else
{
if (mLockCount > 0)
mSurface->Unlock(NULL);
DDBLTFX aBltFX;
ZeroMemory(&aBltFX, sizeof(aBltFX));
aBltFX.dwSize = sizeof(aBltFX);
DWORD aFlags = DDBLT_WAIT;
if (aDDImage->mHasTrans)
aFlags |= DDBLT_KEYSRC;
HRESULT aResult = GetSurface()->Blt(&aDestRect, aDDImage->GetSurface(), &aSrcRect, aFlags, &aBltFX);
if (mLockCount > 0)
{
if (mSurface->Lock(NULL, &mLockedSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL) != DD_OK)
return;
}
}
}
}
void DDImage::NormalBltMirror(Image* theImage, int theX, int theY, const Rect& theSrcRectOrig, const Color& theColor)
{
theImage->mDrawn = true;
Rect theSrcRect = theSrcRectOrig;
// theSrcRect.mX = (theSrcRect.mX+theSrcRect.mWidth)*-1 + theImage->mWidth;
theX += theSrcRect.mWidth-1;
MemoryImage* aMemoryImage = dynamic_cast<MemoryImage*>(theImage);
DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);
if (aMemoryImage != NULL)
{
aMemoryImage->CommitBits();
if (mNoLock)
return;
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
// Ensure NativeAlphaData is calculated
void *aNativeData = aMemoryImage->GetNativeAlphaData(mDDInterface);
// Ensure RunLength data is calculated
uchar* aSrcRLAlphaData = aMemoryImage->GetRLAlphaData();
#define _PLUSPLUS --
#define _PLUSEQUALS -=
if (aMemoryImage->mColorTable == NULL)
{
ulong* aSrcPixelsRow = ((ulong*) aNativeData) + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
ulong* aSrcPixels;
#define NEXT_SRC_COLOR (*(aSrcPixels++))
#define PEEK_SRC_COLOR (*aSrcPixels)
#include "DDI_AlphaBlt.inc"
#undef NEXT_SRC_COLOR
#undef PEEK_SRC_COLOR
}
else
{
ulong* aNativeColorTable = (ulong*) aNativeData;
uchar* aSrcPixelsRow = aMemoryImage->mColorIndices + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
uchar* aSrcPixels;
#define NEXT_SRC_COLOR (aNativeColorTable[*(aSrcPixels++)])
#define PEEK_SRC_COLOR (aNativeColorTable[*aSrcPixels])
#include "DDI_AlphaBlt.inc"
#undef NEXT_SRC_COLOR
#undef PEEK_SRC_COLOR
}
#undef _PLUSPLUS
#undef _PLUSEQUALS
UnlockSurface();
}
}
void DDImage::AdditiveBlt(Image* theImage, int theX, int theY, const Rect& theSrcRect, const Color& theColor)
{
theImage->mDrawn = true;
if (mNoLock)
return;
MemoryImage* aMemoryImage = dynamic_cast<MemoryImage*>(theImage);
DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);
if (aMemoryImage != NULL)
{
if (!LockSurface())
return;
// Ensure NativeAlphaData is calculated
void* aNativeAlphaData = aMemoryImage->GetNativeAlphaData(mDDInterface);
#define _PLUSPLUS ++
#define _PLUSEQUALS +=
if (aMemoryImage->mColorTable == NULL)
{
ulong* aSrcPixelsRow = ((ulong*) aNativeAlphaData) + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
ulong* aSrcPixels;
#define NEXT_SRC_COLOR (*(aSrcPixels++))
#define PEEK_SRC_COLOR (*aSrcPixels)
#include "DDI_Additive.inc"
#undef NEXT_SRC_COLOR
#undef PEEK_SRC_COLOR
}
else
{
ulong* aNativeAlphaColorTable = (ulong*) aNativeAlphaData;
uchar* aSrcPixelsRow = aMemoryImage->mColorIndices + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
uchar* aSrcPixels;
#define NEXT_SRC_COLOR (aNativeAlphaColorTable[*(aSrcPixels++)])
#define PEEK_SRC_COLOR (aNativeAlphaColorTable[*aSrcPixels])
#include "DDI_Additive.inc"
#undef NEXT_SRC_COLOR
#undef PEEK_SRC_COLOR
}
#undef _PLUSPLUS
#undef _PLUSEQUALS
UnlockSurface();
}
}
void DDImage::AdditiveBltMirror(Image* theImage, int theX, int theY, const Rect& theSrcRectOrig, const Color& theColor)
{
theImage->mDrawn = true;
if (mNoLock)
return;
Rect theSrcRect = theSrcRectOrig;
// theSrcRect.mX = (theSrcRect.mX+theSrcRect.mWidth)*-1 + theImage->mWidth;
theX += theSrcRect.mWidth-1;
MemoryImage* aMemoryImage = dynamic_cast<MemoryImage*>(theImage);
DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);
if (aMemoryImage != NULL)
{
if (!LockSurface())
return;
// Ensure NativeAlphaData is calculated
void* aNativeAlphaData = aMemoryImage->GetNativeAlphaData(mDDInterface);
#define _PLUSPLUS --
#define _PLUSEQUALS -=
if (aMemoryImage->mColorTable == NULL)
{
ulong* aSrcPixelsRow = ((ulong*) aNativeAlphaData) + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
ulong* aSrcPixels;
#define NEXT_SRC_COLOR (*(aSrcPixels++))
#define PEEK_SRC_COLOR (*aSrcPixels)
#include "DDI_Additive.inc"
#undef NEXT_SRC_COLOR
#undef PEEK_SRC_COLOR
}
else
{
ulong* aNativeAlphaColorTable = (ulong*) aNativeAlphaData;
uchar* aSrcPixelsRow = aMemoryImage->mColorIndices + (theSrcRect.mY * theImage->mWidth) + theSrcRect.mX;
uchar* aSrcPixels;
#define NEXT_SRC_COLOR (aNativeAlphaColorTable[*(aSrcPixels++)])
#define PEEK_SRC_COLOR (aNativeAlphaColorTable[*aSrcPixels])
#include "DDI_Additive.inc"
#undef NEXT_SRC_COLOR
#undef PEEK_SRC_COLOR
}
#undef _PLUSPLUS
#undef _PLUSEQUALS
UnlockSurface();
}
}
void DDImage::Blt(Image* theImage, int theX, int theY, const Rect& theSrcRect, const Color& theColor, int theDrawMode)
{
theImage->mDrawn = true;
//if (gDebug)
// mApp->CopyToClipboard("+DDImage::Blt");
DBG_ASSERTE((theColor.mRed >= 0) && (theColor.mRed <= 255));
DBG_ASSERTE((theColor.mGreen >= 0) && (theColor.mGreen <= 255));
DBG_ASSERTE((theColor.mBlue >= 0) && (theColor.mBlue <= 255));
DBG_ASSERTE((theColor.mAlpha >= 0) && (theColor.mAlpha <= 255));
CommitBits();
if (Check3D(this))
{
DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);
// Special short-circuit
if ((aDDImage != NULL) && (aDDImage->mSurface != NULL) &&
(mDDInterface->mD3DInterface->mTransformStack.empty()) &&
(theDrawMode == Graphics::DRAWMODE_NORMAL) &&
(theColor == Color::White) && (!aDDImage->mHasAlpha))
{
if (mLockCount > 0)
mSurface->Unlock(NULL);
DDBLTFX aBltFX;
ZeroMemory(&aBltFX, sizeof(aBltFX));
aBltFX.dwSize = sizeof(aBltFX);
DWORD aFlags = DDBLT_WAIT;
if (aDDImage->mHasTrans)
aFlags |= DDBLT_KEYSRC;
RECT aDestRect = {theX, theY, theX + theSrcRect.mWidth, theY + theSrcRect.mHeight};
RECT aSrcRect = {theSrcRect.mX, theSrcRect.mY, theSrcRect.mX + theSrcRect.mWidth, theSrcRect.mY + theSrcRect.mHeight};
HRESULT aResult = GetSurface()->Blt(&aDestRect, aDDImage->GetSurface(), &aSrcRect, aFlags, &aBltFX);
if (mLockCount > 0)
{
if (mSurface->Lock(NULL, &mLockedSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL) != DD_OK)
return;
}
return;
}
mDDInterface->mD3DInterface->Blt(theImage,theX,theY,theSrcRect,theColor,theDrawMode);
return;
}
if ((mDrawToBits) || (mHasAlpha) || ((mHasTrans) && (!mFirstPixelTrans)) || (mDDInterface->mIs3D && this!=mDDInterface->mNewCursorAreaImage && this!=mDDInterface->mOldCursorAreaImage))
{
MemoryImage::Blt(theImage, theX, theY, theSrcRect, theColor, theDrawMode);
return;
}
switch (theDrawMode)
{
case Graphics::DRAWMODE_NORMAL:
NormalBlt(theImage, theX, theY, theSrcRect, theColor);
break;
case Graphics::DRAWMODE_ADDITIVE:
AdditiveBlt(theImage, theX, theY, theSrcRect, theColor);
break;
}
DeleteAllNonSurfaceData();
}
void DDImage::BltMirror(Image* theImage, int theX, int theY, const Rect& theSrcRect, const Color& theColor, int theDrawMode)
{
DBG_ASSERTE((theColor.mRed >= 0) && (theColor.mRed <= 255));
DBG_ASSERTE((theColor.mGreen >= 0) && (theColor.mGreen <= 255));
DBG_ASSERTE((theColor.mBlue >= 0) && (theColor.mBlue <= 255));
DBG_ASSERTE((theColor.mAlpha >= 0) && (theColor.mAlpha <= 255));
CommitBits();
if (Check3D(this))
{
mDDInterface->mD3DInterface->BltMirror(theImage,theX,theY,theSrcRect,theColor,theDrawMode);
return;
}
switch (theDrawMode)
{
case Graphics::DRAWMODE_NORMAL:
NormalBltMirror(theImage, theX, theY, theSrcRect, theColor);
break;
case Graphics::DRAWMODE_ADDITIVE:
AdditiveBltMirror(theImage, theX, theY, theSrcRect, theColor);
break;
}
DeleteAllNonSurfaceData();
}
void DDImage::BltF(Image* theImage, float theX, float theY, const Rect& theSrcRect, const Rect &theClipRect, const Color& theColor, int theDrawMode)
{
theImage->mDrawn = true;
if (Check3D(this))
{
FRect aClipRect(theClipRect.mX,theClipRect.mY,theClipRect.mWidth,theClipRect.mHeight);
FRect aDestRect(theX,theY,theSrcRect.mWidth,theSrcRect.mHeight);
FRect anIntersect = aDestRect.Intersection(aClipRect);
if (anIntersect.mWidth!=aDestRect.mWidth || anIntersect.mHeight!=aDestRect.mHeight)
{
if (anIntersect.mWidth!=0 && anIntersect.mHeight!=0)
mDDInterface->mD3DInterface->BltClipF(theImage,theX,theY,theSrcRect,&theClipRect,theColor,theDrawMode);
}
else
mDDInterface->mD3DInterface->Blt(theImage,theX,theY,theSrcRect,theColor,theDrawMode,true);
return;
}
else
BltRotated(theImage,theX,theY,theSrcRect,theClipRect,theColor,theDrawMode,0,0,0);
}
void DDImage::BltRotated(Image* theImage, float theX, float theY, const Rect &theSrcRect, const Rect& theClipRect, const Color& theColor, int theDrawMode, double theRot, float theRotCenterX, float theRotCenterY)
{
theImage->mDrawn = true;
if (mNoLock)
return;
CommitBits();
if (Check3D(this))
{
mDDInterface->mD3DInterface->BltRotated(theImage,theX,theY,&theClipRect,theColor,theDrawMode,theRot,theRotCenterX,theRotCenterY,theSrcRect);
return;
}
if ((mDrawToBits) || (mHasAlpha) || ((mHasTrans) && (!mFirstPixelTrans)) || (mDDInterface->mIs3D))
{
MemoryImage::BltRotated(theImage, theX, theY, theSrcRect, theClipRect, theColor, theDrawMode, theRot, theRotCenterX, theRotCenterY);
return;
}
// This BltRotatedClipHelper clipping used to happen in Graphics::DrawImageRotated
FRect aDestRect;
if (!BltRotatedClipHelper(theX, theY, theSrcRect, theClipRect, theRot, aDestRect,theRotCenterX,theRotCenterY))
return;
MemoryImage* aMemoryImage = dynamic_cast<MemoryImage*>(theImage);
DDImage* aDDImage = dynamic_cast<DDImage*>(theImage);
if (aMemoryImage != NULL)
{
aMemoryImage->CommitBits();
if (theDrawMode == Graphics::DRAWMODE_NORMAL)
{
if (aMemoryImage->mColorTable == NULL)
{
ulong* aSrcBits = aMemoryImage->GetBits() + theSrcRect.mX + theSrcRect.mY*aMemoryImage->GetWidth();
#define SRC_TYPE ulong
#define READ_COLOR(ptr) (*(ptr))
#include "DDI_BltRotated.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
else
{
ulong* aColorTable = aMemoryImage->mColorTable;
uchar* aSrcBits = aMemoryImage->mColorIndices + theSrcRect.mX + theSrcRect.mY*aMemoryImage->GetWidth();
#define SRC_TYPE uchar
#define READ_COLOR(ptr) (aColorTable[*(ptr)])
#include "DDI_BltRotated.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
}
else
{
if (aMemoryImage->mColorTable == NULL)
{
ulong* aSrcBits = aMemoryImage->GetBits() + theSrcRect.mX + theSrcRect.mY*aMemoryImage->GetWidth();
#define SRC_TYPE ulong
#define READ_COLOR(ptr) (*(ptr))
#include "DDI_BltRotated_Additive.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
else
{
ulong* aColorTable = aMemoryImage->mColorTable;
uchar* aSrcBits = aMemoryImage->mColorIndices + theSrcRect.mX + theSrcRect.mY*aMemoryImage->GetWidth();
#define SRC_TYPE uchar
#define READ_COLOR(ptr) (aColorTable[*(ptr)])
#include "DDI_BltRotated_Additive.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
}
}
DeleteAllNonSurfaceData();
}
void DDImage::StretchBlt(Image* theImage, const Rect& theDestRectOrig, const Rect& theSrcRectOrig, const Rect& theClipRect, const Color& theColor, int theDrawMode, bool fastStretch)
{
theImage->mDrawn = true;
DDImage* aSrcDDImage = dynamic_cast<DDImage*>(theImage);
MemoryImage* aSrcMemoryImage = dynamic_cast<MemoryImage*>(theImage);
CommitBits();
if (Check3D(this))
{
mDDInterface->mD3DInterface->StretchBlt(theImage,theDestRectOrig,theSrcRectOrig,&theClipRect,theColor,theDrawMode,fastStretch);
return;
}
Rect theDestRect;
FRect theSrcRect;
if (!StretchBltClipHelper(theSrcRectOrig,theClipRect,theDestRectOrig,theSrcRect,theDestRect))
return;
if (fastStretch)
{
if ((aSrcDDImage != NULL) && (theColor == Color::White) && (theDrawMode == Graphics::DRAWMODE_NORMAL) &&
(!aSrcDDImage->mHasAlpha) && (aSrcDDImage->GetSurface() != NULL))
{
LPDIRECTDRAWSURFACE aSrcSurface = aSrcDDImage->GetSurface();
LPDIRECTDRAWSURFACE aDestSurface = GetSurface();
DDBLTFX aBltFX;
ZeroMemory(&aBltFX, sizeof(aBltFX));
aBltFX.dwSize = sizeof(aBltFX);
DWORD aFlags = DDBLT_WAIT;
if (aSrcDDImage->mHasTrans)
aFlags |= DDBLT_KEYSRC;
RECT aDestRect = {theDestRect.mX, theDestRect.mY, theDestRect.mX + theDestRect.mWidth, theDestRect.mY + theDestRect.mHeight};
RECT aSrcRect = {theSrcRect.mX, theSrcRect.mY, theSrcRect.mX + theSrcRect.mWidth, theSrcRect.mY + theSrcRect.mHeight};
if (mLockCount > 0)
{
mSurface->Unlock(NULL);
}
HRESULT aResult = GetSurface()->Blt(&aDestRect, aSrcDDImage->GetSurface(), &aSrcRect, aFlags, &aBltFX);
if (mLockCount > 0)
{
if (mSurface->Lock(NULL, &mLockedSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL) != DD_OK)
return;
}
}
else
{
if (aSrcMemoryImage != NULL)
{
aSrcMemoryImage->CommitBits();
// Ensure NativeAlphaData is calculated
void *aNativeAlphaData = aSrcMemoryImage->GetNativeAlphaData(mDDInterface);
#define _PLUSPLUS ++
if (theDrawMode == Graphics::DRAWMODE_NORMAL)
{
if (aSrcMemoryImage->mColorTable == NULL)
{
//ulong* aSrcBits = aSrcMemoryImage->GetBits();
ulong* aSrcBits = ((ulong*) aNativeAlphaData);
#define SRC_TYPE ulong
#define READ_COLOR(ptr) (*(ptr))
#include "DDI_FastStretch.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
else
{
ulong* aColorTable = (ulong*) aNativeAlphaData;
uchar* aSrcBits = aSrcMemoryImage->mColorIndices;
#define SRC_TYPE uchar
#define READ_COLOR(ptr) (aColorTable[*(ptr)])
#include "DDI_FastStretch.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
}
else
{
if (aSrcMemoryImage->mColorTable == NULL)
{
//ulong* aSrcBits = aSrcMemoryImage->GetBits();
ulong* aSrcBits = ((ulong*) aNativeAlphaData);
#define SRC_TYPE ulong
#define READ_COLOR(ptr) (*(ptr))
#include "DDI_FastStretch_Additive.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
else
{
ulong* aColorTable = (ulong*) aNativeAlphaData;
uchar* aSrcBits = aSrcMemoryImage->mColorIndices;
#define SRC_TYPE uchar
#define READ_COLOR(ptr) (aColorTable[*(ptr)])
#include "DDI_FastStretch_Additive.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
}
#undef _PLUSPLUS
}
}
}
else
{
if ((mDrawToBits) || (mHasAlpha) || (mHasTrans) || (mDDInterface->mIs3D))
{
MemoryImage::StretchBlt(theImage, theDestRectOrig, theSrcRectOrig, theClipRect, theColor, theDrawMode, fastStretch);
return;
}
// Stretch it to a temporary image
MemoryImage aTempImage(mApp);
Rect aTempRect(0, 0, theDestRect.mWidth, theDestRect.mHeight);
aTempImage.Create(theDestRect.mWidth, theDestRect.mHeight);
if (fastStretch)
aTempImage.FastStretchBlt(theImage, aTempRect, theSrcRect, theColor, 0);
else
aTempImage.SlowStretchBlt(theImage, aTempRect, theSrcRect, theColor, 0);
Blt(&aTempImage, theDestRect.mX, theDestRect.mY, aTempRect, theColor, theDrawMode);
}
DeleteAllNonSurfaceData();
}
void DDImage::StretchBltMirror(Image* theImage, const Rect& theDestRectOrig, const Rect& theSrcRectOrig, const Rect& theClipRect, const Color& theColor, int theDrawMode, bool fastStretch)
{
theImage->mDrawn = true;
DDImage* aSrcDDImage = dynamic_cast<DDImage*>(theImage);
MemoryImage* aSrcMemoryImage = dynamic_cast<MemoryImage*>(theImage);
CommitBits();
if (Check3D(this))
{
mDDInterface->mD3DInterface->StretchBlt(theImage,theDestRectOrig,theSrcRectOrig,&theClipRect,theColor,theDrawMode,fastStretch,true);
return;
}
FRect theSrcRect;
Rect theDestRect;
if (!StretchBltMirrorClipHelper(theSrcRectOrig,theClipRect,theDestRectOrig,theSrcRect,theDestRect))
return;
theDestRect.mX += theDestRect.mWidth-1;
if (aSrcMemoryImage != NULL)
{
aSrcMemoryImage->CommitBits();
// Ensure NativeAlphaData is calculated
void *aNativeAlphaData = aSrcMemoryImage->GetNativeAlphaData(mDDInterface);
#define _PLUSPLUS --
if (theDrawMode == Graphics::DRAWMODE_NORMAL)
{
if (aSrcMemoryImage->mColorTable == NULL)
{
//ulong* aSrcBits = aSrcMemoryImage->GetBits();
ulong* aSrcBits = ((ulong*) aNativeAlphaData);
#define SRC_TYPE ulong
#define READ_COLOR(ptr) (*(ptr))
#include "DDI_FastStretch.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
else
{
ulong* aColorTable = (ulong*) aNativeAlphaData;
uchar* aSrcBits = aSrcMemoryImage->mColorIndices;
#define SRC_TYPE uchar
#define READ_COLOR(ptr) (aColorTable[*(ptr)])
#include "DDI_FastStretch.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
}
else
{
if (aSrcMemoryImage->mColorTable == NULL)
{
//ulong* aSrcBits = aSrcMemoryImage->GetBits();
ulong* aSrcBits = ((ulong*) aNativeAlphaData);
#define SRC_TYPE ulong
#define READ_COLOR(ptr) (*(ptr))
#include "DDI_FastStretch_Additive.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
else
{
ulong* aColorTable = (ulong*) aNativeAlphaData;
uchar* aSrcBits = aSrcMemoryImage->mColorIndices;
#define SRC_TYPE uchar
#define READ_COLOR(ptr) (aColorTable[*(ptr)])
#include "DDI_FastStretch_Additive.inc"
#undef SRC_TYPE
#undef READ_COLOR
}
}
#undef _PLUSPLUS
}
DeleteAllNonSurfaceData();
}
void DDImage::BltMatrix(Image* theImage, float x, float y, const SexyMatrix3 &theMatrix, const Rect& theClipRect, const Color& theColor, int theDrawMode, const Rect &theSrcRect, bool blend)
{
theImage->mDrawn = true;
if (Check3D(this))
{
mDDInterface->mD3DInterface->BltTransformed(theImage,&theClipRect,theColor,theDrawMode,theSrcRect,theMatrix,blend,x,y,true);
return;
}
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
int aPixelFormat;
if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
aPixelFormat = 0x888;
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask == 0xf800 && mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask == 0x07e0 && mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask == 0x001f)
aPixelFormat = 0x565;
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask == 0x7c00 && mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask == 0x03e0 && mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask == 0x001f)
aPixelFormat = 0x555;
else
DBG_ASSERTE(FALSE);
BltMatrixHelper(theImage,x,y,theMatrix,theClipRect,theColor,theDrawMode,theSrcRect,mLockedSurfaceDesc.lpSurface,mLockedSurfaceDesc.lPitch,aPixelFormat,blend);
UnlockSurface();
DeleteAllNonSurfaceData();
}
void DDImage::BltTrianglesTex(Image *theTexture, const TriVertex theVertices[][3], int theNumTriangles, const Rect& theClipRect, const Color &theColor, int theDrawMode, float tx, float ty, bool blend)
{
theTexture->mDrawn = true;
if (Check3D(this))
{
mDDInterface->mD3DInterface->DrawTrianglesTex(theVertices,theNumTriangles,theColor,theDrawMode,theTexture,tx,ty,blend);
return;
}
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
int aPixelFormat;
if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
aPixelFormat = 0x888;
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask == 0xf800 && mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask == 0x07e0 && mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask == 0x001f)
aPixelFormat = 0x565;
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask == 0x7c00 && mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask == 0x03e0 && mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask == 0x001f)
aPixelFormat = 0x555;
else
DBG_ASSERTE(FALSE);
BltTrianglesTexHelper(theTexture,theVertices,theNumTriangles,theClipRect,theColor,theDrawMode,mLockedSurfaceDesc.lpSurface,mLockedSurfaceDesc.lPitch,aPixelFormat,tx,ty,blend);
UnlockSurface();
DeleteAllNonSurfaceData();
}
bool DDImage::Palletize()
{
if (MemoryImage::Palletize())
{
// Don't keep around the DDSurface if we palletize the image, that
// would be a waste of memory
DeleteDDSurface();
return true;
}
else
{
return false;
}
}
void DDImage::FillScanLinesWithCoverage(Span* theSpans, int theSpanCount, const Color& theColor, int theDrawMode, const BYTE* theCoverage, int theCoverX, int theCoverY, int theCoverWidth, int theCoverHeight)
{
if (theSpanCount == 0) return;
if (Check3D(this))
{ // ugh!#@$
int l = theSpans[0].mX, t = theSpans[0].mY;
int r = l + theSpans[0].mWidth, b = t;
for (int i = 1; i < theSpanCount; ++i)
{
l = min(theSpans[i].mX, l);
r = max(theSpans[i].mX + theSpans[i].mWidth - 1, r);
t = min(theSpans[i].mY, t);
b = max(theSpans[i].mY, b);
}
for (int i = 0; i < theSpanCount; ++i)
{
theSpans[i].mX -= l;
theSpans[i].mY -= t;
}
MemoryImage aTempImage;
aTempImage.Create(r-l+1, b-t+1);
aTempImage.FillScanLinesWithCoverage(theSpans, theSpanCount, theColor, theDrawMode, theCoverage, theCoverX - l, theCoverY - t, theCoverWidth, theCoverHeight);
Blt(&aTempImage, l, t, Rect(0, 0, r-l+1, b-t+1), Color::White, theDrawMode);
return;
}
LPDIRECTDRAWSURFACE aSurface = GetSurface();
if (!LockSurface())
return;
ulong aRMask = mLockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
ulong aGMask = mLockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
ulong aBMask = mLockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
ulong aRRoundAdd = aRMask >> 1;
ulong aGRoundAdd = aGMask >> 1;
ulong aBRoundAdd = aBMask >> 1;
if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16)
{
//ushort src_red = (((theColor.mRed * (theColor.mAlpha+1)) >> 8) * aRMask) & aRMask;
//ushort src_green = (((theColor.mGreen * (theColor.mAlpha+1)) >> 8) * aGMask) & aGMask;
//ushort src_blue = (((theColor.mBlue * (theColor.mAlpha+1)) >> 8) * aBMask) & aBMask;
ushort src =
(((theColor.mRed * aRMask) >> 8) & aRMask) |
(((theColor.mGreen * aGMask) >> 8) & aGMask) |
(((theColor.mBlue * aBMask) >> 8) & aBMask);
ushort* theBits = (ushort*)mLockedSurfaceDesc.lpSurface;
for (int i = 0; i < theSpanCount; ++i)
{
Span* aSpan = &theSpans[i];
int x = aSpan->mX - theCoverX;
int y = aSpan->mY - theCoverY;
ushort* aDestPixels = &theBits[aSpan->mY*mWidth + aSpan->mX];
const BYTE* aCoverBits = &theCoverage[y*theCoverWidth+x];
for (int w = 0; w < aSpan->mWidth; ++w)
{
int cover = *aCoverBits++;
int a = ((cover+1) * theColor.mAlpha) >> 8;
int oma = 256 - a;
ushort dest = *aDestPixels;
*(aDestPixels++) =
((((dest & aRMask) * oma + (src & aRMask) * a) >> 8) & aRMask) |
((((dest & aGMask) * oma + (src & aGMask) * a) >> 8) & aGMask) |
((((dest & aBMask) * oma + (src & aBMask) * a) >> 8) & aBMask);
}
}
}
else if (mLockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32)
{
//ulong src_red = (((theColor.mRed * (theColor.mAlpha+1)) >> 8) * aRMask) & aRMask;
//ulong src_green = (((theColor.mGreen * (theColor.mAlpha+1)) >> 8) * aGMask) & aGMask;
//ulong src_blue = (((theColor.mBlue * (theColor.mAlpha+1)) >> 8) * aBMask) & aBMask;
ulong src =
(((theColor.mRed * aRMask) >> 8) & aRMask) |
(((theColor.mGreen * aGMask) >> 8) & aGMask) |
(((theColor.mBlue * aBMask) >> 8) & aBMask);
ulong* theBits = (ulong*)mLockedSurfaceDesc.lpSurface;
for (int i = 0; i < theSpanCount; ++i)
{
Span* aSpan = &theSpans[i];
int x = aSpan->mX - theCoverX;
int y = aSpan->mY - theCoverY;
ulong* aDestPixels = &theBits[aSpan->mY*mWidth + aSpan->mX];
const BYTE* aCoverBits = &theCoverage[y*theCoverWidth+x];
for (int w = 0; w < aSpan->mWidth; ++w)
{
int cover = *aCoverBits++;
int a = ((cover+1) * theColor.mAlpha) >> 8;
int oma = 256 - a;
ulong dest = *aDestPixels;
*(aDestPixels++) =
((((dest & aRMask) * oma + (src & aRMask) * a) >> 8) & aRMask) |
((((dest & aGMask) * oma + (src & aGMask) * a) >> 8) & aGMask) |
((((dest & aBMask) * oma + (src & aBMask) * a) >> 8) & aBMask);
}
}
}
UnlockSurface();
DeleteAllNonSurfaceData();
}