You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
679 lines
24 KiB
679 lines
24 KiB
/******************************Module*Header**********************************\
|
|
*
|
|
* *********************
|
|
* * DDraw SAMPLE CODE *
|
|
* *********************
|
|
*
|
|
* Module Name: ddcpyblt.c
|
|
*
|
|
* Content: several copy and clear blits for Permedia 2
|
|
*
|
|
* Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
|
|
* Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
|
|
\*****************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#include "directx.h"
|
|
#include "dd.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// PermediaPackedCopyBlt
|
|
//
|
|
// Does a packed blit, allowing for different source and destination
|
|
// partial products.
|
|
//
|
|
// ppdev----------- the ppdev
|
|
// dwDestPitch----- pitch of destination surface
|
|
// dwSourcePitch--- pitch of source surface
|
|
// pDest----------- pointer to private data structure of dest. surface
|
|
// pSource--------- pointer to private data structure of source surface
|
|
// *rDest---------- dest. rectangle of blit
|
|
// *rSrc----------- source rectangle of blit
|
|
// dwWindowBase---- offset of dest. window in frame buffer
|
|
// lWindowOffset--- offset of source window in frame buffer
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
PermediaPackedCopyBlt( PPDev ppdev, // ppdev
|
|
DWORD dwDestPitch, // pitch of dest
|
|
DWORD dwSourcePitch,
|
|
PermediaSurfaceData* pDest,
|
|
PermediaSurfaceData* pSource,
|
|
RECTL *rDest,
|
|
RECTL *rSrc,
|
|
DWORD dwWindowBase,
|
|
LONG lWindowOffset
|
|
)
|
|
{
|
|
PERMEDIA_DEFS(ppdev);
|
|
|
|
LONG lOffset;
|
|
LONG lSourceOffset;
|
|
|
|
LONG lPixelSize=pDest->SurfaceFormat.PixelSize;
|
|
LONG lPixelMask=3>>pDest->SurfaceFormat.PixelShift;
|
|
LONG lPixelShift=2-pDest->SurfaceFormat.PixelShift;
|
|
|
|
DBG_DD(( 5, "DDraw:PermediaPackedCopyBlt "
|
|
"From %08lx %08lx %08lx %08lx %08lx %08lx %08lx "
|
|
"To %08lx %08lx %08lx %08lx %08lx %08lx %08lx",
|
|
dwSourcePitch,pSource,rSrc->bottom,rSrc->left,
|
|
rSrc->right,rSrc->top,lWindowOffset,
|
|
dwDestPitch,pDest,rDest->bottom,rDest->left,
|
|
rDest->right,rDest->top,dwWindowBase));
|
|
|
|
ASSERTDD(!(rSrc->top<0) && !(rSrc->left<0),
|
|
"PermediaPackedCopyBlt: cannot handle neg. src coordinates");
|
|
ASSERTDD(!(rDest->top<0) && !(rDest->left<0),
|
|
"PermediaPackedCopyBlt: cannot handle neg. src coordinates");
|
|
|
|
lOffset = (((rDest->left & lPixelMask)-(rSrc->left & lPixelMask)) & 7);
|
|
lSourceOffset = lWindowOffset +
|
|
RECTS_PIXEL_OFFSET(rSrc, rDest,
|
|
dwSourcePitch, dwDestPitch,
|
|
lPixelMask ) +
|
|
LINEAR_FUDGE(dwSourcePitch, dwDestPitch, rDest);
|
|
|
|
RESERVEDMAPTR(14);
|
|
|
|
SEND_PERMEDIA_DATA( FBPixelOffset, 0x0);
|
|
SEND_PERMEDIA_DATA( FBReadPixel, pDest->SurfaceFormat.FBReadPixel);
|
|
|
|
// set packed with offset
|
|
SEND_PERMEDIA_DATA( FBWindowBase, dwWindowBase);
|
|
|
|
SEND_PERMEDIA_DATA( FBReadMode,
|
|
PM_FBREADMODE_PARTIAL(pSource->ulPackedPP) |
|
|
PM_FBREADMODE_READSOURCE(__PERMEDIA_ENABLE) |
|
|
PM_FBREADMODE_PACKEDDATA(__PERMEDIA_ENABLE) |
|
|
PM_FBREADMODE_RELATIVEOFFSET(lOffset));
|
|
|
|
SEND_PERMEDIA_DATA( FBWriteConfig,
|
|
PM_FBREADMODE_PARTIAL(pDest->ulPackedPP) |
|
|
PM_FBREADMODE_READSOURCE(__PERMEDIA_ENABLE) |
|
|
PM_FBREADMODE_PACKEDDATA(__PERMEDIA_ENABLE) |
|
|
PM_FBREADMODE_RELATIVEOFFSET(lOffset));
|
|
|
|
SEND_PERMEDIA_DATA( LogicalOpMode, __PERMEDIA_DISABLE);
|
|
SEND_PERMEDIA_DATA( FBSourceOffset, lSourceOffset);
|
|
|
|
// Render the rectangle
|
|
|
|
if (lSourceOffset >= 0) {
|
|
// Use left to right and top to bottom
|
|
SEND_PERMEDIA_DATA( StartXDom,
|
|
INTtoFIXED(rDest->left >> lPixelShift));
|
|
SEND_PERMEDIA_DATA( StartXSub,
|
|
INTtoFIXED((rDest->right >> lPixelShift) + lPixelMask));
|
|
SEND_PERMEDIA_DATA( PackedDataLimits,
|
|
PM_PACKEDDATALIMITS_OFFSET(lOffset) |
|
|
PM_PACKEDDATALIMITS_XSTART(rDest->left) |
|
|
PM_PACKEDDATALIMITS_XEND(rDest->right));
|
|
SEND_PERMEDIA_DATA( StartY, INTtoFIXED(rDest->top));
|
|
SEND_PERMEDIA_DATA( dY, INTtoFIXED(1));
|
|
}
|
|
else {
|
|
// Use right to left and bottom to top
|
|
SEND_PERMEDIA_DATA( StartXDom,
|
|
INTtoFIXED(((rDest->right) >> lPixelShift) + lPixelMask));
|
|
SEND_PERMEDIA_DATA( StartXSub,
|
|
INTtoFIXED(rDest->left >> lPixelShift));
|
|
SEND_PERMEDIA_DATA( PackedDataLimits,
|
|
PM_PACKEDDATALIMITS_OFFSET(lOffset) |
|
|
PM_PACKEDDATALIMITS_XSTART(rDest->right) |
|
|
PM_PACKEDDATALIMITS_XEND(rDest->left));
|
|
SEND_PERMEDIA_DATA( StartY, INTtoFIXED(rDest->bottom - 1));
|
|
SEND_PERMEDIA_DATA( dY, (DWORD)INTtoFIXED(-1));
|
|
}
|
|
|
|
SEND_PERMEDIA_DATA( Count, rDest->bottom - rDest->top);
|
|
SEND_PERMEDIA_DATA( Render, __RENDER_TRAPEZOID_PRIMITIVE);
|
|
COMMITDMAPTR();
|
|
FLUSHDMA();
|
|
|
|
} // PermediaPackedCopyBlt
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// PermediaPatchedCopyBlt
|
|
//
|
|
// Does a patched blit, i.e. blits from source to destination and
|
|
// turns on patching. Note that this method cannot use packed blits.
|
|
//
|
|
// ppdev----------- the ppdev
|
|
// dwDestPitch----- pitch of destination surface
|
|
// dwSourcePitch--- pitch of source surface
|
|
// pDest----------- pointer to private data structure of dest. surface
|
|
// pSource--------- pointer to private data structure of source surface
|
|
// *rDest---------- dest. rectangle of blit
|
|
// *rSrc----------- source rectangle of blit
|
|
// dwWindowBase---- offset of dest. window in frame buffer
|
|
// lWindowOffset--- offset of source window in frame buffer
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
PermediaPatchedCopyBlt( PPDev ppdev,
|
|
DWORD dwDestPitch,
|
|
DWORD dwSourcePitch,
|
|
PermediaSurfaceData* pDest,
|
|
PermediaSurfaceData* pSource,
|
|
RECTL *rDest,
|
|
RECTL *rSrc,
|
|
DWORD dwWindowBase,
|
|
LONG lWindowOffset
|
|
)
|
|
{
|
|
PERMEDIA_DEFS(ppdev);
|
|
|
|
LONG lSourceOffset;
|
|
LONG lPixelSize=pDest->SurfaceFormat.PixelSize;
|
|
LONG lPixelMask=pDest->SurfaceFormat.PixelMask;
|
|
LONG lPixelShift=pDest->SurfaceFormat.PixelShift;
|
|
|
|
ASSERTDD(!(rSrc->top<0) && !(rSrc->left<0),
|
|
"PermediaPackedCopyBlt: cannot handle neg. src coordinates");
|
|
ASSERTDD(!(rDest->top<0) && !(rDest->left<0),
|
|
"PermediaPackedCopyBlt: cannot handle neg. src coordinates");
|
|
|
|
DBG_DD(( 5, "DDraw:PermediaPatchedCopyBlt"));
|
|
|
|
lSourceOffset = lWindowOffset +
|
|
RECTS_PIXEL_OFFSET(rSrc, rDest,
|
|
dwSourcePitch, dwDestPitch, lPixelMask) +
|
|
LINEAR_FUDGE(dwSourcePitch, dwDestPitch, rDest);
|
|
|
|
RESERVEDMAPTR(13);
|
|
|
|
SEND_PERMEDIA_DATA( FBPixelOffset, 0x0);
|
|
SEND_PERMEDIA_DATA( FBReadPixel, pDest->SurfaceFormat.FBReadPixel);
|
|
|
|
// Patching isn't symetric, so we need to reverse the patch code depending
|
|
// on the direction of the patch
|
|
|
|
SEND_PERMEDIA_DATA( FBWindowBase, dwWindowBase);
|
|
|
|
if (pDest->dwFlags & P2_CANPATCH)
|
|
{
|
|
pDest->dwFlags |= P2_ISPATCHED;
|
|
SEND_PERMEDIA_DATA( FBReadMode,
|
|
pSource->ulPackedPP |
|
|
__FB_READ_SOURCE);
|
|
SEND_PERMEDIA_DATA( FBWriteConfig,
|
|
pDest->ulPackedPP |
|
|
PM_FBREADMODE_PATCHENABLE(__PERMEDIA_ENABLE) |
|
|
PM_FBREADMODE_PATCHMODE(__PERMEDIA_SUBPATCH));
|
|
} else
|
|
{
|
|
pDest->dwFlags &= ~P2_ISPATCHED;
|
|
SEND_PERMEDIA_DATA( FBReadMode,
|
|
pSource->ulPackedPP |
|
|
__FB_READ_SOURCE |
|
|
PM_FBREADMODE_PATCHENABLE(__PERMEDIA_ENABLE) |
|
|
PM_FBREADMODE_PATCHMODE(__PERMEDIA_SUBPATCH) );
|
|
SEND_PERMEDIA_DATA(FBWriteConfig, (pDest->ulPackedPP ));
|
|
}
|
|
|
|
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
|
|
SEND_PERMEDIA_DATA(FBSourceOffset, lSourceOffset);
|
|
|
|
// Render the rectangle
|
|
|
|
if (lSourceOffset >= 0)
|
|
{
|
|
// Use left to right and top to bottom
|
|
SEND_PERMEDIA_DATA(StartXDom, INTtoFIXED(rDest->left));
|
|
SEND_PERMEDIA_DATA(StartXSub, INTtoFIXED(rDest->right));
|
|
SEND_PERMEDIA_DATA(StartY, INTtoFIXED(rDest->top));
|
|
SEND_PERMEDIA_DATA(dY, INTtoFIXED(1));
|
|
} else
|
|
{
|
|
// Use right to left and bottom to top
|
|
SEND_PERMEDIA_DATA(StartXDom, INTtoFIXED(rDest->right));
|
|
SEND_PERMEDIA_DATA(StartXSub, INTtoFIXED(rDest->left));
|
|
SEND_PERMEDIA_DATA(StartY, INTtoFIXED(rDest->bottom - 1));
|
|
SEND_PERMEDIA_DATA(dY, (DWORD)INTtoFIXED(-1));
|
|
}
|
|
|
|
SEND_PERMEDIA_DATA(Count, rDest->bottom - rDest->top);
|
|
SEND_PERMEDIA_DATA(Render, __RENDER_TRAPEZOID_PRIMITIVE);
|
|
COMMITDMAPTR();
|
|
FLUSHDMA();
|
|
|
|
} // PermediaPatchedCopyBlt
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// PermediaFastClear
|
|
//
|
|
// Does a fast clear of a surface. Supports all color depths
|
|
// Can clear depth or Frame buffer.
|
|
//
|
|
// ppdev---------the ppdev
|
|
// pPrivateData--pointer to private data structure of dest. surface
|
|
// rDest---------rectangle for colorfill in dest. surface
|
|
// dwWindowBase--offset of dest. surface in frame buffer
|
|
// dwColor-------color for fill
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
PermediaFastClear(PPDev ppdev,
|
|
PermediaSurfaceData* pPrivateData,
|
|
RECTL *rDest,
|
|
DWORD dwWindowBase,
|
|
DWORD dwColor)
|
|
{
|
|
PERMEDIA_DEFS(ppdev);
|
|
|
|
ULONG ulRenderBits;
|
|
BOOL bFastFill=TRUE;
|
|
LONG lPixelSize=pPrivateData->SurfaceFormat.PixelSize;
|
|
|
|
|
|
DBG_DD(( 5, "DDraw:PermediaFastClear"));
|
|
|
|
ASSERTDD(CHECK_P2_SURFACEDATA_VALIDITY(pPrivateData),
|
|
"Private Surface data not valid in clear");
|
|
|
|
ASSERTDD((pPrivateData->dwFlags & P2_PPVALID),
|
|
"PermediaFastClear called with invalid PP codes");
|
|
|
|
ulRenderBits = __RENDER_FAST_FILL_ENABLE
|
|
| __RENDER_TRAPEZOID_PRIMITIVE;
|
|
|
|
// Clear depending on depth
|
|
switch (lPixelSize)
|
|
{
|
|
case __PERMEDIA_4BITPIXEL:
|
|
dwColor &= 0xF;
|
|
dwColor |= dwColor << 4;
|
|
// fall through...
|
|
case __PERMEDIA_8BITPIXEL:
|
|
dwColor &= 0xFF;
|
|
dwColor |= dwColor << 8;
|
|
// fall through
|
|
case __PERMEDIA_16BITPIXEL:
|
|
dwColor &= 0xFFFF;
|
|
dwColor |= (dwColor << 16);
|
|
break;
|
|
|
|
case __PERMEDIA_24BITPIXEL:
|
|
dwColor &= 0xFFFFFF;
|
|
dwColor |= ((dwColor & 0xFF) << 24);
|
|
// Can't use SGRAM fast block fills on any color, only on grey.
|
|
if (((dwColor & 0xFF) == ((dwColor & 0xFF00) >> 8)) &&
|
|
((dwColor & 0xFF) == ((dwColor & 0xFF0000) >> 16))) {
|
|
bFastFill = TRUE;
|
|
} else {
|
|
bFastFill = FALSE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
|
|
RESERVEDMAPTR(15);
|
|
SEND_PERMEDIA_DATA( dXDom, 0x0);
|
|
SEND_PERMEDIA_DATA( dXSub, 0x0);
|
|
SEND_PERMEDIA_DATA( FBPixelOffset, 0);
|
|
SEND_PERMEDIA_DATA( FBReadPixel,
|
|
pPrivateData->SurfaceFormat.FBReadPixel);
|
|
|
|
if (bFastFill)
|
|
{
|
|
SEND_PERMEDIA_DATA(FBBlockColor, dwColor);
|
|
} else
|
|
{
|
|
ulRenderBits &= ~__RENDER_FAST_FILL_ENABLE;
|
|
SEND_PERMEDIA_DATA(FBWriteData, dwColor);
|
|
}
|
|
|
|
SEND_PERMEDIA_DATA(FBReadMode,
|
|
PM_FBREADMODE_PARTIAL(pPrivateData->ulPackedPP)|
|
|
PM_FBREADMODE_PACKEDDATA(__PERMEDIA_DISABLE));
|
|
|
|
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_CONSTANT_FB_WRITE);
|
|
SEND_PERMEDIA_DATA(FBWindowBase, dwWindowBase);
|
|
|
|
// Render the rectangle
|
|
|
|
SEND_PERMEDIA_DATA(StartXDom, INTtoFIXED(rDest->left));
|
|
SEND_PERMEDIA_DATA(StartXSub, INTtoFIXED(rDest->right));
|
|
SEND_PERMEDIA_DATA(StartY, INTtoFIXED(rDest->top));
|
|
SEND_PERMEDIA_DATA(dY, INTtoFIXED(1));
|
|
SEND_PERMEDIA_DATA(Count, rDest->bottom - rDest->top);
|
|
|
|
SEND_PERMEDIA_DATA(Render, ulRenderBits);
|
|
|
|
// Reset our pixel values.
|
|
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
|
|
COMMITDMAPTR();
|
|
FLUSHDMA();
|
|
|
|
} //PermediaFastClear
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// PermediaClearManagedSurface
|
|
//
|
|
// Does a clear of a managed surface. Supports all color depths
|
|
//
|
|
// PixelSize-----surface color depth
|
|
// rDest---------rectangle for colorfill in dest. surface
|
|
// fpVidMem------pointer to fill
|
|
// lPitch--------Surface Pitch
|
|
// dwColor-------color for fill
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
PermediaClearManagedSurface(DWORD PixelSize,
|
|
RECTL *rDest,
|
|
FLATPTR fpVidMem,
|
|
LONG lPitch,
|
|
DWORD dwColor)
|
|
{
|
|
BYTE* pDestStart;
|
|
LONG i;
|
|
DBG_DD(( 5, "DDraw:PermediaClearManagedSurface"));
|
|
|
|
LONG lByteWidth = rDest->right - rDest->left;
|
|
LONG lHeight = rDest->bottom - rDest->top;
|
|
|
|
// Calculate the start pointer for the dest
|
|
pDestStart = (BYTE*)(fpVidMem + (rDest->top * lPitch));
|
|
// Clear depending on depth
|
|
switch (PixelSize)
|
|
{
|
|
case __PERMEDIA_4BITPIXEL:
|
|
{
|
|
DWORD right=rDest->right,left=rDest->left;
|
|
dwColor &= 0x0F;
|
|
dwColor |= dwColor << 4;
|
|
if (right & 1)
|
|
{
|
|
pDestStart = (BYTE*)(fpVidMem + (rDest->top * lPitch));
|
|
pDestStart += right/2;
|
|
for (i=0;i<lHeight;i++)
|
|
{
|
|
pDestStart[i*lPitch] = (pDestStart[i*lPitch] & 0xF0) |
|
|
(BYTE)(dwColor & 0x0F);
|
|
}
|
|
right--;
|
|
}
|
|
|
|
if (left & 1)
|
|
{
|
|
pDestStart = (BYTE*)(fpVidMem + (rDest->top * lPitch));
|
|
pDestStart += left/2;
|
|
for (i=0;i<lHeight;i++)
|
|
{
|
|
pDestStart[i*lPitch] = (pDestStart[i*lPitch] & 0x0F) |
|
|
(BYTE)(dwColor << 4);
|
|
}
|
|
left++;
|
|
}
|
|
pDestStart = (BYTE*)(fpVidMem + (rDest->top * lPitch));
|
|
while (--lHeight >= 0)
|
|
{
|
|
while (left<right)
|
|
{
|
|
pDestStart[left/2]=(BYTE)dwColor;
|
|
left +=2;
|
|
}
|
|
pDestStart += lPitch;
|
|
}
|
|
}
|
|
break;
|
|
case __PERMEDIA_8BITPIXEL:
|
|
pDestStart += rDest->left;
|
|
while (--lHeight >= 0)
|
|
{
|
|
for (i=0;i<lByteWidth;i++)
|
|
pDestStart[i]=(BYTE)dwColor;
|
|
pDestStart += lPitch;
|
|
}
|
|
break;
|
|
// fall through
|
|
case __PERMEDIA_16BITPIXEL:
|
|
pDestStart += rDest->left*2;
|
|
while (--lHeight >= 0)
|
|
{
|
|
LPWORD lpWord=(LPWORD)pDestStart;
|
|
for (i=0;i<lByteWidth;i++)
|
|
lpWord[i]=(WORD)dwColor;
|
|
pDestStart += lPitch;
|
|
}
|
|
break;
|
|
|
|
case __PERMEDIA_24BITPIXEL:
|
|
dwColor &= 0xFFFFFF;
|
|
dwColor |= ((dwColor & 0xFF) << 24);
|
|
default:
|
|
pDestStart += rDest->left*4;
|
|
while (--lHeight >= 0)
|
|
{
|
|
LPDWORD lpDWord=(LPDWORD)pDestStart;
|
|
for (i=0;i<lByteWidth;i++)
|
|
lpDWord[i]=(WORD)dwColor;
|
|
pDestStart += lPitch;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// PermediaFastLBClear
|
|
//
|
|
// Does a fast clear of the Permedia Z (local) Buffer. The Permedia Z Buffer
|
|
// is always 16 bit wide...
|
|
//
|
|
// ppdev---------the ppdev
|
|
// pPrivateData--pointer to private data structure of dest. surface
|
|
// rDest---------rectangle for colorfill in dest. surface
|
|
// dwWindowBase--offset of dest. surface in frame buffer
|
|
// dwColor-------color for fill
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
PermediaFastLBClear(PPDev ppdev,
|
|
PermediaSurfaceData* pPrivateData,
|
|
RECTL *rDest,
|
|
DWORD dwWindowBase,
|
|
DWORD dwColor)
|
|
{
|
|
PERMEDIA_DEFS(ppdev);
|
|
|
|
DBG_DD(( 5, "DDraw:PermediaFastLBClear"));
|
|
|
|
ASSERTDD(CHECK_P2_SURFACEDATA_VALIDITY(pPrivateData),
|
|
"Private Surface data not valid in clear");
|
|
ASSERTDD((pPrivateData->dwFlags & P2_PPVALID),
|
|
"PermediaFastClear called with invalid PP codes");
|
|
|
|
// Clear according to Z-Buffer depth
|
|
dwColor &= 0xFFFF;
|
|
dwColor |= dwColor << 16;
|
|
|
|
RESERVEDMAPTR(15);
|
|
SEND_PERMEDIA_DATA( dXDom, 0x0);
|
|
SEND_PERMEDIA_DATA( dXSub, 0x0);
|
|
SEND_PERMEDIA_DATA( FBPixelOffset, 0);
|
|
SEND_PERMEDIA_DATA( FBReadPixel, __PERMEDIA_16BITPIXEL);
|
|
SEND_PERMEDIA_DATA( FBBlockColor, dwColor);
|
|
SEND_PERMEDIA_DATA( FBReadMode,
|
|
PM_FBREADMODE_PARTIAL(pPrivateData->ulPackedPP) |
|
|
PM_FBREADMODE_PACKEDDATA(__PERMEDIA_DISABLE));
|
|
SEND_PERMEDIA_DATA( LogicalOpMode, __PERMEDIA_CONSTANT_FB_WRITE);
|
|
SEND_PERMEDIA_DATA( FBWindowBase, dwWindowBase);
|
|
SEND_PERMEDIA_DATA( StartXDom, INTtoFIXED(rDest->left));
|
|
SEND_PERMEDIA_DATA( StartXSub, INTtoFIXED(rDest->right));
|
|
SEND_PERMEDIA_DATA( StartY, INTtoFIXED(rDest->top));
|
|
SEND_PERMEDIA_DATA( dY, INTtoFIXED(1));
|
|
SEND_PERMEDIA_DATA( Count, rDest->bottom - rDest->top);
|
|
SEND_PERMEDIA_DATA( Render, __RENDER_FAST_FILL_ENABLE
|
|
|__RENDER_TRAPEZOID_PRIMITIVE);
|
|
|
|
// Reset our pixel values.
|
|
SEND_PERMEDIA_DATA( LogicalOpMode, __PERMEDIA_DISABLE);
|
|
|
|
COMMITDMAPTR();
|
|
FLUSHDMA();
|
|
|
|
} // PermediaFastLBClear
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// SysMemToSysMemSurfaceCopy
|
|
//
|
|
// Does a copy from System memory to System memory (either from or to an
|
|
// AGP surface, or any other system memory surface)
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
SysMemToSysMemSurfaceCopy(FLATPTR fpSrcVidMem,
|
|
LONG lSrcPitch,
|
|
DWORD dwSrcBitCount,
|
|
FLATPTR fpDstVidMem,
|
|
LONG lDstPitch,
|
|
DWORD dwDstBitCount,
|
|
RECTL* rSource,
|
|
RECTL* rDest)
|
|
{
|
|
BYTE* pSourceStart;
|
|
BYTE* pDestStart;
|
|
BYTE pixSource;
|
|
BYTE* pNewDest;
|
|
BYTE* pNewSource;
|
|
|
|
DBG_DD(( 5, "DDraw:SysMemToSysMemSurfaceCopy"));
|
|
|
|
LONG lByteWidth = rSource->right - rSource->left;
|
|
LONG lHeight = rSource->bottom - rSource->top;
|
|
if (NULL == fpSrcVidMem || NULL == fpDstVidMem)
|
|
{
|
|
DBG_DD(( 0, "DDraw:SysMemToSysMemSurfaceCopy unexpected 0 fpVidMem"));
|
|
return;
|
|
}
|
|
// Calculate the start pointer for the source and the dest
|
|
pSourceStart = (BYTE*)(fpSrcVidMem + (rSource->top * lSrcPitch));
|
|
pDestStart = (BYTE*)(fpDstVidMem + (rDest->top * lDstPitch));
|
|
|
|
// Be careful if the source is 4 bits deep.
|
|
if(4 == dwSrcBitCount)
|
|
{
|
|
// May have to handle horrible single pixel edges. Check if we need to
|
|
if (!((1 & (rSource->left ^ rDest->left)) == 1))
|
|
{
|
|
pSourceStart += rSource->left / 2;
|
|
pDestStart += rDest->left / 2;
|
|
lByteWidth /= 2;
|
|
|
|
// Do we have to account for the odd pixel at the start?
|
|
if (rSource->left & 0x1)
|
|
{
|
|
lByteWidth--;
|
|
}
|
|
|
|
// If the end is odd then miss of the last nibble (do it later).
|
|
if (rSource->right & 0x1)
|
|
{
|
|
lByteWidth--;
|
|
}
|
|
|
|
while (--lHeight >= 0)
|
|
{
|
|
// Potentially copy the left hand pixel
|
|
if (rSource->left & 0x1) {
|
|
*pDestStart &= 0x0F;
|
|
*pDestStart |= (*pSourceStart & 0xF0);
|
|
|
|
pNewDest = pDestStart + 1;
|
|
pNewSource = pSourceStart + 1;
|
|
} else {
|
|
pNewDest = pDestStart;
|
|
pNewSource = pSourceStart;
|
|
}
|
|
|
|
// Byte copy the rest of the field
|
|
memcpy(pNewDest, pNewSource, lByteWidth);
|
|
|
|
// Potentially copy the right hand pixel
|
|
if (rSource->right & 0x1) {
|
|
*(pNewDest + lByteWidth) &= 0xF0;
|
|
*(pNewDest + lByteWidth) |=
|
|
(*(pNewSource + lByteWidth) & 0xF);
|
|
}
|
|
|
|
pDestStart += lDstPitch;
|
|
pSourceStart += lSrcPitch;
|
|
}
|
|
|
|
} else
|
|
{
|
|
// Do it the hard way - copy single pixels one at a time
|
|
|
|
pSourceStart += rSource->left / 2;
|
|
pDestStart += rDest->left / 2;
|
|
|
|
while (--lHeight >= 0)
|
|
{
|
|
BOOL bOddSource = rSource->left & 0x1;
|
|
BOOL bOddDest = rDest->left & 0x1;
|
|
|
|
pNewDest = pDestStart;
|
|
pNewSource = pSourceStart;
|
|
|
|
for (INT i = 0; i < lByteWidth; i++)
|
|
{
|
|
if (bOddSource) {
|
|
pixSource = (*pNewSource & 0xF0) >> 4;
|
|
pNewSource++;
|
|
} else {
|
|
pixSource = (*pNewSource & 0x0F);
|
|
}
|
|
|
|
if (bOddDest) {
|
|
*pNewDest &= 0x0F;
|
|
*pNewDest |= pixSource << 4;
|
|
pNewDest++;
|
|
} else {
|
|
*pNewDest &= 0xF0;
|
|
*pNewDest |= pixSource;
|
|
}
|
|
|
|
bOddSource = !bOddSource;
|
|
bOddDest = !bOddDest;
|
|
}
|
|
|
|
// Step onto the next line
|
|
pDestStart += lDstPitch;
|
|
pSourceStart += lSrcPitch;
|
|
}
|
|
}
|
|
}
|
|
else // The simple 8, 16 or 24 bit copy
|
|
{
|
|
pSourceStart += rSource->left * (dwSrcBitCount >> 3);
|
|
pDestStart += rDest->left * (dwDstBitCount >> 3);
|
|
lByteWidth *= (dwSrcBitCount >> 3);
|
|
|
|
while (--lHeight >= 0)
|
|
{
|
|
memcpy(pDestStart, pSourceStart, lByteWidth);
|
|
pDestStart += lDstPitch;
|
|
pSourceStart += lSrcPitch;
|
|
};
|
|
}
|
|
|
|
} // SysMemToSysMemSurfaceCopy
|
|
|
|
|
|
|