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.
817 lines
28 KiB
817 lines
28 KiB
/******************************Module*Header**********************************\
|
|
*
|
|
* *********************
|
|
* * DDraw SAMPLE CODE *
|
|
* *********************
|
|
*
|
|
* Module Name: ddstrblt.c
|
|
*
|
|
* Content:
|
|
*
|
|
* 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"
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// ConvertColorKeys
|
|
//
|
|
// converts a color key to the Permedia internal format according to
|
|
// the given Permedia surface format
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
VOID
|
|
ConvertColorKeys(PermediaSurfaceData *pSurface,
|
|
DWORD &dwLowerBound,
|
|
DWORD &dwUpperBound)
|
|
{
|
|
switch (pSurface->SurfaceFormat.Format)
|
|
{
|
|
case PERMEDIA_444_RGB:
|
|
dwLowerBound = CHROMA_LOWER_ALPHA(
|
|
FORMAT_4444_32BIT_BGR(dwLowerBound));
|
|
dwUpperBound = CHROMA_UPPER_ALPHA(
|
|
FORMAT_4444_32BIT_BGR(dwUpperBound));
|
|
break;
|
|
case PERMEDIA_332_RGB:
|
|
dwLowerBound = CHROMA_LOWER_ALPHA(
|
|
FORMAT_332_32BIT_BGR(dwLowerBound));
|
|
dwUpperBound = CHROMA_UPPER_ALPHA(
|
|
FORMAT_332_32BIT_BGR(dwUpperBound));
|
|
break;
|
|
case PERMEDIA_2321_RGB:
|
|
dwLowerBound = CHROMA_LOWER_ALPHA(
|
|
FORMAT_2321_32BIT_BGR(dwLowerBound));
|
|
dwUpperBound = CHROMA_UPPER_ALPHA(
|
|
FORMAT_2321_32BIT_BGR(dwUpperBound));
|
|
break;
|
|
case PERMEDIA_4BIT_PALETTEINDEX:
|
|
case PERMEDIA_8BIT_PALETTEINDEX:
|
|
dwLowerBound = CHROMA_LOWER_ALPHA(
|
|
FORMAT_PALETTE_32BIT(dwLowerBound));
|
|
dwUpperBound = CHROMA_UPPER_ALPHA(
|
|
FORMAT_PALETTE_32BIT(dwUpperBound));
|
|
break;
|
|
case PERMEDIA_5551_RGB:
|
|
dwLowerBound = CHROMA_LOWER_ALPHA(
|
|
FORMAT_5551_32BIT_BGR(dwLowerBound));
|
|
dwUpperBound = CHROMA_UPPER_ALPHA(
|
|
FORMAT_5551_32BIT_BGR(dwUpperBound));
|
|
dwLowerBound = dwLowerBound & 0xF8F8F8F8;
|
|
dwUpperBound = dwUpperBound | 0x07070707;
|
|
break;
|
|
case PERMEDIA_8888_RGB:
|
|
// The permedia 565 mode is an extension, so don't confuse it with
|
|
// the 8888 mode which has the same number
|
|
if (pSurface->SurfaceFormat.FormatExtension ==
|
|
PERMEDIA_565_RGB_EXTENSION)
|
|
{
|
|
dwLowerBound = CHROMA_LOWER_ALPHA(
|
|
FORMAT_565_32BIT_BGR(dwLowerBound));
|
|
dwUpperBound = CHROMA_UPPER_ALPHA(
|
|
FORMAT_565_32BIT_BGR(dwUpperBound));
|
|
dwLowerBound = dwLowerBound & 0xF8F8FcF8;
|
|
dwUpperBound = dwUpperBound | 0x07070307;
|
|
}
|
|
else
|
|
{
|
|
dwLowerBound = CHROMA_LOWER_ALPHA(
|
|
FORMAT_8888_32BIT_BGR(dwLowerBound));
|
|
dwUpperBound = CHROMA_UPPER_ALPHA(
|
|
FORMAT_8888_32BIT_BGR(dwUpperBound));
|
|
}
|
|
break;
|
|
case PERMEDIA_888_RGB:
|
|
dwLowerBound = CHROMA_LOWER_ALPHA(
|
|
FORMAT_8888_32BIT_BGR(dwLowerBound));
|
|
dwUpperBound = CHROMA_UPPER_ALPHA(
|
|
FORMAT_8888_32BIT_BGR(dwUpperBound));
|
|
break;
|
|
}
|
|
|
|
// swap blue and red if we have a RGB surface
|
|
if (!pSurface->SurfaceFormat.ColorOrder)
|
|
{
|
|
dwLowerBound = SWAP_BR(dwLowerBound);
|
|
dwUpperBound = SWAP_BR(dwUpperBound);
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// PermediaStretchCopyBlt
|
|
//
|
|
// stretched blt through texture unit. no keying.
|
|
// handle mirroring if the stretched image requires it.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
VOID
|
|
PermediaStretchCopyBlt( PPDev ppdev,
|
|
LPDDHAL_BLTDATA lpBlt,
|
|
PermediaSurfaceData* pDest,
|
|
PermediaSurfaceData* pSource,
|
|
RECTL *rDest,
|
|
RECTL *rSrc,
|
|
DWORD dwWindowBase,
|
|
DWORD dwSourceOffset
|
|
)
|
|
{
|
|
LONG lXScale;
|
|
LONG lYScale;
|
|
BOOL bYMirror=FALSE;
|
|
BOOL bXMirror=FALSE;
|
|
LONG lPixelSize=pDest->SurfaceFormat.PixelSize;
|
|
|
|
DWORD dwDestWidth = rDest->right - rDest->left;
|
|
DWORD dwDestHeight = rDest->bottom - rDest->top;
|
|
DWORD dwSourceWidth = rSrc->right - rSrc->left;
|
|
DWORD dwSourceHeight = rSrc->bottom - rSrc->top;
|
|
|
|
DWORD dwTexSStart, dwTexTStart;
|
|
DWORD dwRenderDirection;
|
|
|
|
PERMEDIA_DEFS(ppdev);
|
|
|
|
DBG_DD(( 5, "DDraw:PermediaStretchCopyBlt dwWindowBase=%08lx "
|
|
"dwSourceOffset=%08lx", dwWindowBase, dwSourceOffset));
|
|
|
|
ASSERTDD(pDest, "Not valid private surface in destination");
|
|
ASSERTDD(pSource, "Not valid private surface in source");
|
|
|
|
lXScale = (dwSourceWidth << 20) / dwDestWidth;
|
|
lYScale = (dwSourceHeight << 20) / dwDestHeight;
|
|
|
|
// Changes pixel depth to Dest buffer pixel depth if neccessary.
|
|
RESERVEDMAPTR(28);
|
|
|
|
SEND_PERMEDIA_DATA( FBPixelOffset, 0x0);
|
|
SEND_PERMEDIA_DATA( FBReadPixel, pDest->SurfaceFormat.FBReadPixel);
|
|
|
|
if (lPixelSize != 0)
|
|
{
|
|
// set writeback to dest surface...
|
|
SEND_PERMEDIA_DATA( DitherMode,
|
|
(pDest->SurfaceFormat.ColorOrder <<
|
|
PM_DITHERMODE_COLORORDER) |
|
|
(pDest->SurfaceFormat.Format <<
|
|
PM_DITHERMODE_COLORFORMAT) |
|
|
(pDest->SurfaceFormat.FormatExtension <<
|
|
PM_DITHERMODE_COLORFORMATEXTENSION) |
|
|
(__PERMEDIA_ENABLE << PM_DITHERMODE_ENABLE));
|
|
|
|
}
|
|
|
|
SEND_PERMEDIA_DATA(FBWindowBase, dwWindowBase);
|
|
|
|
// set no read of dest.
|
|
SEND_PERMEDIA_DATA(FBReadMode, pDest->ulPackedPP);
|
|
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
|
|
|
|
// set base of source
|
|
SEND_PERMEDIA_DATA(TextureBaseAddress, dwSourceOffset);
|
|
SEND_PERMEDIA_DATA(TextureAddressMode,(1 << PM_TEXADDRESSMODE_ENABLE));
|
|
SEND_PERMEDIA_DATA(TextureColorMode, (1 << PM_TEXCOLORMODE_ENABLE) |
|
|
(_P2_TEXTURE_COPY <<
|
|
PM_TEXCOLORMODE_APPLICATION));
|
|
|
|
SEND_PERMEDIA_DATA(TextureReadMode,
|
|
PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE)|
|
|
PM_TEXREADMODE_FILTER(__PERMEDIA_DISABLE)|
|
|
PM_TEXREADMODE_WIDTH(11) |
|
|
PM_TEXREADMODE_HEIGHT(11) );
|
|
|
|
// set source bitmap format
|
|
SEND_PERMEDIA_DATA(TextureDataFormat,
|
|
(pSource->SurfaceFormat.Format <<
|
|
PM_TEXDATAFORMAT_FORMAT) |
|
|
(pSource->SurfaceFormat.FormatExtension <<
|
|
PM_TEXDATAFORMAT_FORMATEXTENSION) |
|
|
(pSource->SurfaceFormat.ColorOrder <<
|
|
PM_TEXDATAFORMAT_COLORORDER));
|
|
SEND_PERMEDIA_DATA(TextureMapFormat, (pSource->ulPackedPP) |
|
|
(pSource->SurfaceFormat.PixelSize <<
|
|
PM_TEXMAPFORMAT_TEXELSIZE) );
|
|
|
|
// If we are doing special effects, and we are mirroring,
|
|
// we need to fix up the rectangles and change the sense of
|
|
// the render operation - we need to be carefull with overlapping
|
|
// rectangles
|
|
if (dwWindowBase != dwSourceOffset)
|
|
{
|
|
dwRenderDirection = 1;
|
|
}
|
|
else
|
|
{
|
|
if(rSrc->top < rDest->top)
|
|
{
|
|
dwRenderDirection = 0;
|
|
}
|
|
else if(rSrc->top > rDest->top)
|
|
{
|
|
dwRenderDirection = 1;
|
|
}
|
|
else if(rSrc->left < rDest->left)
|
|
{
|
|
dwRenderDirection = 0;
|
|
}
|
|
else dwRenderDirection = 1;
|
|
}
|
|
|
|
if(NULL != lpBlt && lpBlt->dwFlags & DDBLT_DDFX)
|
|
{
|
|
bYMirror = lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORUPDOWN;
|
|
bXMirror = lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORLEFTRIGHT;
|
|
|
|
} else
|
|
{
|
|
if (dwRenderDirection==0)
|
|
{
|
|
bXMirror = TRUE;
|
|
bYMirror = TRUE;
|
|
}
|
|
}
|
|
|
|
if (bXMirror)
|
|
{
|
|
dwTexSStart = rSrc->right - 1;
|
|
lXScale = -lXScale;
|
|
}
|
|
else
|
|
{
|
|
dwTexSStart = rSrc->left;
|
|
}
|
|
|
|
if (bYMirror)
|
|
{
|
|
dwTexTStart = rSrc->bottom - 1;
|
|
lYScale = -lYScale;
|
|
}
|
|
else
|
|
{
|
|
dwTexTStart = rSrc->top;
|
|
}
|
|
|
|
SEND_PERMEDIA_DATA(SStart, dwTexSStart << 20);
|
|
SEND_PERMEDIA_DATA(TStart, dwTexTStart << 20);
|
|
SEND_PERMEDIA_DATA(dSdx, lXScale);
|
|
SEND_PERMEDIA_DATA(dSdyDom, 0);
|
|
SEND_PERMEDIA_DATA(dTdx, 0);
|
|
SEND_PERMEDIA_DATA(dTdyDom, lYScale);
|
|
|
|
// Render the rectangle
|
|
|
|
if (dwRenderDirection)
|
|
{
|
|
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_TRAPEZOID_PRIMITIVE |
|
|
__RENDER_TEXTURED_PRIMITIVE);
|
|
}
|
|
else
|
|
{
|
|
// Render right to left, 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 |
|
|
__RENDER_TEXTURED_PRIMITIVE);
|
|
}
|
|
|
|
SEND_PERMEDIA_DATA(DitherMode, __PERMEDIA_DISABLE);
|
|
SEND_PERMEDIA_DATA(TextureAddressMode, __PERMEDIA_DISABLE);
|
|
SEND_PERMEDIA_DATA(TextureColorMode, __PERMEDIA_DISABLE);
|
|
SEND_PERMEDIA_DATA(TextureReadMode, __PERMEDIA_DISABLE);
|
|
|
|
COMMITDMAPTR();
|
|
FLUSHDMA();
|
|
|
|
} // PermediaStretchCopyBlt
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// PermediaSourceChromaBlt
|
|
//
|
|
// Does a blit through the texture unit to allow chroma keying.
|
|
// Note the unpacking of the colour key to fit into the Permedia format.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
VOID
|
|
PermediaSourceChromaBlt( PPDev ppdev,
|
|
LPDDHAL_BLTDATA lpBlt,
|
|
PermediaSurfaceData* pDest,
|
|
PermediaSurfaceData* pSource,
|
|
RECTL *rDest,
|
|
RECTL *rSrc,
|
|
DWORD dwWindowBase,
|
|
DWORD dwSourceOffset
|
|
)
|
|
{
|
|
DWORD dwLowerBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue;
|
|
DWORD dwUpperBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue;
|
|
DWORD dwRenderDirection;
|
|
LONG lPixelSize=pDest->SurfaceFormat.PixelSize;
|
|
|
|
PERMEDIA_DEFS(ppdev);
|
|
|
|
DBG_DD(( 5, "DDraw:PermediaSourceChromaBlt"));
|
|
|
|
ASSERTDD(pDest, "Not valid private surface in destination");
|
|
ASSERTDD(pSource, "Not valid private surface in source");
|
|
|
|
// Changes pixel depth to Frame buffer pixel depth if neccessary.
|
|
|
|
ConvertColorKeys( pSource, dwLowerBound, dwUpperBound);
|
|
|
|
RESERVEDMAPTR(31);
|
|
|
|
SEND_PERMEDIA_DATA(FBReadPixel, pDest->SurfaceFormat.FBReadPixel);
|
|
|
|
if (lPixelSize != 0)
|
|
{
|
|
|
|
// set writeback to dest surface...
|
|
SEND_PERMEDIA_DATA( DitherMode,
|
|
(pDest->SurfaceFormat.ColorOrder <<
|
|
PM_DITHERMODE_COLORORDER) |
|
|
(pDest->SurfaceFormat.Format <<
|
|
PM_DITHERMODE_COLORFORMAT) |
|
|
(pDest->SurfaceFormat.FormatExtension <<
|
|
PM_DITHERMODE_COLORFORMATEXTENSION) |
|
|
(1 << PM_DITHERMODE_ENABLE));
|
|
|
|
}
|
|
|
|
|
|
// Reject range
|
|
SEND_PERMEDIA_DATA(YUVMode, PM_YUVMODE_CHROMATEST_FAILWITHIN << 1);
|
|
SEND_PERMEDIA_DATA(FBWindowBase, dwWindowBase);
|
|
|
|
// set no read of source.
|
|
// add read src/dest enable
|
|
SEND_PERMEDIA_DATA(FBReadMode,pDest->ulPackedPP);
|
|
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
|
|
|
|
// set base of source
|
|
SEND_PERMEDIA_DATA(TextureBaseAddress, dwSourceOffset);
|
|
SEND_PERMEDIA_DATA(TextureAddressMode,(1 << PM_TEXADDRESSMODE_ENABLE));
|
|
//
|
|
// modulate & ramp??
|
|
SEND_PERMEDIA_DATA(TextureColorMode, (1 << PM_TEXCOLORMODE_ENABLE) |
|
|
(_P2_TEXTURE_COPY <<
|
|
PM_TEXCOLORMODE_APPLICATION));
|
|
|
|
SEND_PERMEDIA_DATA(TextureReadMode,
|
|
PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
|
|
PM_TEXREADMODE_FILTER(__PERMEDIA_DISABLE) |
|
|
PM_TEXREADMODE_WIDTH(11) |
|
|
PM_TEXREADMODE_HEIGHT(11) );
|
|
|
|
SEND_PERMEDIA_DATA(TextureDataFormat,
|
|
(pSource->SurfaceFormat.Format <<
|
|
PM_TEXDATAFORMAT_FORMAT) |
|
|
(pSource->SurfaceFormat.FormatExtension <<
|
|
PM_TEXDATAFORMAT_FORMATEXTENSION) |
|
|
(pSource->SurfaceFormat.ColorOrder <<
|
|
PM_TEXDATAFORMAT_COLORORDER));
|
|
|
|
SEND_PERMEDIA_DATA( TextureMapFormat,
|
|
(pSource->ulPackedPP) |
|
|
(pSource->SurfaceFormat.PixelSize <<
|
|
PM_TEXMAPFORMAT_TEXELSIZE) );
|
|
|
|
|
|
SEND_PERMEDIA_DATA(ChromaLowerBound, dwLowerBound);
|
|
SEND_PERMEDIA_DATA(ChromaUpperBound, dwUpperBound);
|
|
|
|
if ((lpBlt->lpDDDestSurface->lpGbl->fpVidMem) !=
|
|
(lpBlt->lpDDSrcSurface->lpGbl->fpVidMem))
|
|
{
|
|
dwRenderDirection = 1;
|
|
}
|
|
else
|
|
{
|
|
if(rSrc->top < rDest->top)
|
|
{
|
|
dwRenderDirection = 0;
|
|
}
|
|
else if(rSrc->top > rDest->top)
|
|
{
|
|
dwRenderDirection = 1;
|
|
}
|
|
else if(rSrc->left < rDest->left)
|
|
{
|
|
dwRenderDirection = 0;
|
|
}
|
|
else dwRenderDirection = 1;
|
|
}
|
|
|
|
/*
|
|
* Render the rectangle
|
|
*/
|
|
|
|
// Left -> right, top->bottom
|
|
if (dwRenderDirection)
|
|
{
|
|
// set offset of source
|
|
SEND_PERMEDIA_DATA(SStart, rSrc->left<<20);
|
|
SEND_PERMEDIA_DATA(TStart, rSrc->top<<20);
|
|
SEND_PERMEDIA_DATA(dSdx, 1 << 20);
|
|
SEND_PERMEDIA_DATA(dSdyDom, 0);
|
|
SEND_PERMEDIA_DATA(dTdx, 0);
|
|
SEND_PERMEDIA_DATA(dTdyDom, 1 << 20);
|
|
|
|
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_TRAPEZOID_PRIMITIVE |
|
|
__RENDER_TEXTURED_PRIMITIVE);
|
|
}
|
|
else
|
|
// right->left, bottom->top
|
|
{
|
|
// set offset of source
|
|
SEND_PERMEDIA_DATA(SStart, rSrc->right << 20);
|
|
SEND_PERMEDIA_DATA(TStart, (rSrc->bottom - 1) << 20);
|
|
SEND_PERMEDIA_DATA(dSdx, (DWORD)(-1 << 20));
|
|
SEND_PERMEDIA_DATA(dSdyDom, 0);
|
|
SEND_PERMEDIA_DATA(dTdx, 0);
|
|
SEND_PERMEDIA_DATA(dTdyDom, (DWORD)(-1 << 20));
|
|
|
|
// Render right to left, 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 |
|
|
__RENDER_TEXTURED_PRIMITIVE);
|
|
}
|
|
|
|
|
|
// Turn off chroma key
|
|
SEND_PERMEDIA_DATA(YUVMode, 0x0);
|
|
|
|
SEND_PERMEDIA_DATA(TextureAddressMode, __PERMEDIA_DISABLE);
|
|
SEND_PERMEDIA_DATA(TextureColorMode, __PERMEDIA_DISABLE);
|
|
SEND_PERMEDIA_DATA(TextureReadMode, __PERMEDIA_DISABLE);
|
|
|
|
if (pSource->SurfaceFormat.PixelSize != 0)
|
|
{
|
|
SEND_PERMEDIA_DATA(DitherMode, 0);
|
|
}
|
|
|
|
COMMITDMAPTR();
|
|
FLUSHDMA();
|
|
|
|
} // PermediaSourceChromaBlt
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// PermediaStretchCopyChromaBlt
|
|
//
|
|
// Does a blit through the texture unit to allow stretching. Also
|
|
// handle mirroring and chroma keying if the stretched image requires it.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
VOID
|
|
PermediaStretchCopyChromaBlt( PPDev ppdev,
|
|
LPDDHAL_BLTDATA lpBlt,
|
|
PermediaSurfaceData* pDest,
|
|
PermediaSurfaceData* pSource,
|
|
RECTL *rDest,
|
|
RECTL *rSrc,
|
|
DWORD dwWindowBase,
|
|
DWORD dwSourceOffset
|
|
)
|
|
{
|
|
LONG lXScale;
|
|
LONG lYScale;
|
|
BOOL bYMirror;
|
|
BOOL bXMirror;
|
|
DWORD dwDestWidth = rDest->right - rDest->left;
|
|
DWORD dwDestHeight = rDest->bottom - rDest->top;
|
|
DWORD dwSourceWidth = rSrc->right - rSrc->left;
|
|
DWORD dwSourceHeight = rSrc->bottom - rSrc->top;
|
|
DWORD dwTexSStart, dwTexTStart;
|
|
DWORD dwRenderDirection;
|
|
LONG lPixelSize=pDest->SurfaceFormat.PixelSize;
|
|
|
|
DWORD dwLowerBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue;
|
|
DWORD dwUpperBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue;
|
|
PERMEDIA_DEFS(ppdev);
|
|
|
|
DBG_DD(( 5, "DDraw:PermediaStretchCopyChromaBlt"));
|
|
|
|
ASSERTDD(pDest, "Not valid private surface in destination");
|
|
ASSERTDD(pSource, "Not valid private surface in source");
|
|
|
|
// Changes pixel depth to Frame buffer pixel depth if neccessary.
|
|
|
|
ConvertColorKeys( pSource, dwLowerBound, dwUpperBound);
|
|
|
|
RESERVEDMAPTR(31);
|
|
|
|
SEND_PERMEDIA_DATA(FBReadPixel, pDest->SurfaceFormat.FBReadPixel);
|
|
|
|
if (lPixelSize != 0)
|
|
{
|
|
|
|
// set writeback to dest surface...
|
|
SEND_PERMEDIA_DATA( DitherMode,
|
|
(pDest->SurfaceFormat.ColorOrder <<
|
|
PM_DITHERMODE_COLORORDER) |
|
|
(pDest->SurfaceFormat.Format <<
|
|
PM_DITHERMODE_COLORFORMAT) |
|
|
(pDest->SurfaceFormat.FormatExtension <<
|
|
PM_DITHERMODE_COLORFORMATEXTENSION) |
|
|
(1 << PM_DITHERMODE_ENABLE));
|
|
|
|
}
|
|
|
|
// Reject range
|
|
SEND_PERMEDIA_DATA(YUVMode, PM_YUVMODE_CHROMATEST_FAILWITHIN <<1);
|
|
SEND_PERMEDIA_DATA(FBWindowBase, dwWindowBase);
|
|
|
|
// set no read of source.
|
|
SEND_PERMEDIA_DATA(FBReadMode, pDest->ulPackedPP);
|
|
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
|
|
|
|
// set base of source
|
|
SEND_PERMEDIA_DATA(TextureBaseAddress, dwSourceOffset);
|
|
SEND_PERMEDIA_DATA(TextureAddressMode,(1 << PM_TEXADDRESSMODE_ENABLE));
|
|
|
|
SEND_PERMEDIA_DATA( TextureColorMode,
|
|
(1 << PM_TEXCOLORMODE_ENABLE) |
|
|
(_P2_TEXTURE_COPY << PM_TEXCOLORMODE_APPLICATION));
|
|
|
|
SEND_PERMEDIA_DATA( TextureReadMode,
|
|
PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
|
|
PM_TEXREADMODE_FILTER(__PERMEDIA_DISABLE) |
|
|
PM_TEXREADMODE_WIDTH(11) |
|
|
PM_TEXREADMODE_HEIGHT(11));
|
|
|
|
lXScale = (dwSourceWidth << 20) / (dwDestWidth);
|
|
lYScale = (dwSourceHeight << 20) / (dwDestHeight);
|
|
|
|
SEND_PERMEDIA_DATA( TextureDataFormat,
|
|
(pSource->SurfaceFormat.Format <<
|
|
PM_TEXDATAFORMAT_FORMAT) |
|
|
(pSource->SurfaceFormat.FormatExtension <<
|
|
PM_TEXDATAFORMAT_FORMATEXTENSION) |
|
|
(pSource->SurfaceFormat.ColorOrder <<
|
|
PM_TEXDATAFORMAT_COLORORDER));
|
|
|
|
SEND_PERMEDIA_DATA( TextureMapFormat,
|
|
(pSource->ulPackedPP) |
|
|
(pSource->SurfaceFormat.PixelSize <<
|
|
PM_TEXMAPFORMAT_TEXELSIZE) );
|
|
|
|
bYMirror = FALSE;
|
|
bXMirror = FALSE;
|
|
|
|
if ((lpBlt->lpDDDestSurface->lpGbl->fpVidMem) !=
|
|
(lpBlt->lpDDSrcSurface->lpGbl->fpVidMem))
|
|
{
|
|
dwRenderDirection = 1;
|
|
}
|
|
else
|
|
{
|
|
if(rSrc->top < rDest->top)
|
|
{
|
|
dwRenderDirection = 0;
|
|
}
|
|
else if(rSrc->top > rDest->top)
|
|
{
|
|
dwRenderDirection = 1;
|
|
}
|
|
else if(rSrc->left < rDest->left)
|
|
{
|
|
dwRenderDirection = 0;
|
|
}
|
|
else dwRenderDirection = 1;
|
|
}
|
|
|
|
if(lpBlt->dwFlags & DDBLT_DDFX)
|
|
{
|
|
bYMirror = lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORUPDOWN;
|
|
bXMirror = lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORLEFTRIGHT;
|
|
|
|
} else
|
|
{
|
|
if (dwRenderDirection==0)
|
|
{
|
|
bXMirror = TRUE;
|
|
bYMirror = TRUE;
|
|
}
|
|
}
|
|
|
|
if (bXMirror)
|
|
{
|
|
dwTexSStart = rSrc->right - 1;
|
|
lXScale = -lXScale;
|
|
}
|
|
else
|
|
{
|
|
dwTexSStart = rSrc->left;
|
|
}
|
|
|
|
if (bYMirror)
|
|
{
|
|
dwTexTStart = rSrc->bottom - 1;
|
|
lYScale = -lYScale;
|
|
}
|
|
else
|
|
{
|
|
dwTexTStart = rSrc->top;
|
|
}
|
|
|
|
SEND_PERMEDIA_DATA(dTdyDom, lYScale);
|
|
SEND_PERMEDIA_DATA(ChromaLowerBound, dwLowerBound);
|
|
SEND_PERMEDIA_DATA(ChromaUpperBound, dwUpperBound);
|
|
|
|
// set texture coordinates
|
|
SEND_PERMEDIA_DATA(SStart, dwTexSStart << 20);
|
|
SEND_PERMEDIA_DATA(TStart, dwTexTStart << 20);
|
|
SEND_PERMEDIA_DATA(dSdx, lXScale);
|
|
SEND_PERMEDIA_DATA(dSdyDom, 0);
|
|
SEND_PERMEDIA_DATA(dTdx, 0);
|
|
|
|
//
|
|
// Render the rectangle
|
|
//
|
|
|
|
if (dwRenderDirection)
|
|
{
|
|
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
|
|
{
|
|
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 |
|
|
__RENDER_TEXTURED_PRIMITIVE);
|
|
|
|
|
|
// Turn off units
|
|
SEND_PERMEDIA_DATA(YUVMode, __PERMEDIA_DISABLE);
|
|
SEND_PERMEDIA_DATA(TextureAddressMode, __PERMEDIA_DISABLE);
|
|
SEND_PERMEDIA_DATA(TextureColorMode, __PERMEDIA_DISABLE);
|
|
SEND_PERMEDIA_DATA(TextureReadMode, __PERMEDIA_DISABLE);
|
|
|
|
if (pSource->SurfaceFormat.PixelSize != 0)
|
|
{
|
|
SEND_PERMEDIA_DATA(DitherMode, 0);
|
|
}
|
|
|
|
COMMITDMAPTR();
|
|
FLUSHDMA();
|
|
|
|
} // PermediaStretchCopyChromaBlt
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// PermediaYUVtoRGB
|
|
//
|
|
// Permedia2 YUV to RGB conversion blt
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
VOID
|
|
PermediaYUVtoRGB( PPDev ppdev,
|
|
DDBLTFX* lpBltFX,
|
|
PermediaSurfaceData* pDest,
|
|
PermediaSurfaceData* pSource,
|
|
RECTL *rDest,
|
|
RECTL *rSrc,
|
|
DWORD dwWindowBase,
|
|
DWORD dwSourceOffset)
|
|
{
|
|
DWORD lXScale;
|
|
DWORD lYScale;
|
|
DWORD dwDestWidth = rDest->right - rDest->left;
|
|
DWORD dwDestHeight = rDest->bottom - rDest->top;
|
|
DWORD dwSourceWidth = rSrc->right - rSrc->left;
|
|
DWORD dwSourceHeight = rSrc->bottom - rSrc->top;
|
|
PERMEDIA_DEFS(ppdev);
|
|
|
|
ASSERTDD(pDest, "Not valid private surface in destination");
|
|
ASSERTDD(pSource, "Not valid private surface in source");
|
|
|
|
lXScale = (dwSourceWidth << 20) / dwDestWidth;
|
|
lYScale = (dwSourceHeight << 20) / dwDestHeight;
|
|
|
|
// Changes pixel depth to Frame buffer pixel depth if neccessary.
|
|
|
|
RESERVEDMAPTR(29);
|
|
|
|
SEND_PERMEDIA_DATA(FBReadPixel,ppdev->bPixShift);
|
|
|
|
if (pDest->SurfaceFormat.PixelSize != __PERMEDIA_8BITPIXEL)
|
|
{
|
|
SEND_PERMEDIA_DATA(DitherMode,
|
|
(COLOR_MODE << PM_DITHERMODE_COLORORDER) |
|
|
(pDest->SurfaceFormat.Format << PM_DITHERMODE_COLORFORMAT) |
|
|
(pDest->SurfaceFormat.FormatExtension <<
|
|
PM_DITHERMODE_COLORFORMATEXTENSION) |
|
|
(1 << PM_DITHERMODE_ENABLE) |
|
|
(1 << PM_DITHERMODE_DITHERENABLE));
|
|
}
|
|
|
|
SEND_PERMEDIA_DATA(FBWindowBase, dwWindowBase);
|
|
|
|
// set no read of source.
|
|
SEND_PERMEDIA_DATA(FBReadMode, pDest->ulPackedPP);
|
|
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
|
|
|
|
// set base of source
|
|
SEND_PERMEDIA_DATA(TextureBaseAddress, dwSourceOffset);
|
|
SEND_PERMEDIA_DATA(TextureAddressMode,(1 << PM_TEXADDRESSMODE_ENABLE));
|
|
|
|
SEND_PERMEDIA_DATA( TextureColorMode,
|
|
(1 << PM_TEXCOLORMODE_ENABLE) |
|
|
(_P2_TEXTURE_COPY << PM_TEXCOLORMODE_APPLICATION));
|
|
|
|
SEND_PERMEDIA_DATA( TextureReadMode,
|
|
PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
|
|
PM_TEXREADMODE_FILTER(__PERMEDIA_ENABLE) |
|
|
PM_TEXREADMODE_WIDTH(11) |
|
|
PM_TEXREADMODE_HEIGHT(11) );
|
|
|
|
SEND_PERMEDIA_DATA( TextureDataFormat,
|
|
(pSource->SurfaceFormat.Format <<
|
|
PM_TEXDATAFORMAT_FORMAT) |
|
|
(pSource->SurfaceFormat.FormatExtension <<
|
|
PM_TEXDATAFORMAT_FORMATEXTENSION) |
|
|
(INV_COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER));
|
|
|
|
SEND_PERMEDIA_DATA( TextureMapFormat,
|
|
(pSource->ulPackedPP) |
|
|
(pSource->SurfaceFormat.PixelSize <<
|
|
PM_TEXMAPFORMAT_TEXELSIZE) );
|
|
|
|
// Turn on the YUV unit
|
|
SEND_PERMEDIA_DATA(YUVMode, 0x1);
|
|
|
|
SEND_PERMEDIA_DATA(LogicalOpMode, 0);
|
|
|
|
// set offset of source
|
|
SEND_PERMEDIA_DATA(SStart, rSrc->left << 20);
|
|
SEND_PERMEDIA_DATA(TStart, rSrc->top << 20);
|
|
SEND_PERMEDIA_DATA(dSdx, lXScale);
|
|
SEND_PERMEDIA_DATA(dSdyDom, 0);
|
|
SEND_PERMEDIA_DATA(dTdx, 0);
|
|
SEND_PERMEDIA_DATA(dTdyDom, lYScale);
|
|
|
|
|
|
// 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, __RENDER_TRAPEZOID_PRIMITIVE |
|
|
__RENDER_TEXTURED_PRIMITIVE);
|
|
|
|
if (pSource->SurfaceFormat.PixelSize != __PERMEDIA_8BITPIXEL)
|
|
{
|
|
SEND_PERMEDIA_DATA(DitherMode, 0);
|
|
}
|
|
|
|
// Turn off units
|
|
SEND_PERMEDIA_DATA(YUVMode, 0x0);
|
|
SEND_PERMEDIA_DATA( TextureAddressMode,
|
|
(0 << PM_TEXADDRESSMODE_ENABLE));
|
|
SEND_PERMEDIA_DATA( TextureColorMode,
|
|
(0 << PM_TEXCOLORMODE_ENABLE));
|
|
COMMITDMAPTR();
|
|
FLUSHDMA();
|
|
}
|
|
|