📄 halblit.c
字号:
/******************************************************************************
<module>
* Name : halblit.c
* Title : DDraw blit functionality
* Author(s) : Imagination Technologies
* Created : 26 May 2004
*
* Copyright : 2004 by Imagination Technologies Limited.
* All rights reserved. No part of this software, either
* material or conceptual may be copied or distributed,
* transmitted, transcribed, stored in a retrieval system
* or translated into any human or computer language in any
* form by any means, electronic, mechanical, manual or
* other-wise, or disclosed to third parties without the
* express written permission of Imagination Technologies
* Limited, Unit 8, HomePark Industrial Estate,
* King's Langley, Hertfordshire, WD4 8LZ, U.K.
*
* Description : ddraw blit functionality
*
* Platform : Windows CE
*
$Log: halblit.c $
********************************************************************************/
#include "ddraw_headers.h"
/*****************************************************************************
<function>
FUNCTION : GetTextureCopyOrder
PURPOSE : Calculate texture copy order from source and dest dimensions.
PARAMETERS : PRECTL psSourceRect - Source dimensions
PRECTL psDestRect - Destination dimensions
RETURNS : DWORD dwCopyOrder - Copy order as defined in mbx12ddef.h
<function/>
*****************************************************************************/
DWORD GetTextureCopyOrder(PRECTL psSourceRect, PRECTL psDestRect)
{
// This code can probably be optimised, cached, etc.
// Default to left-down blitting.
DWORD dwCopyOrder = MBX2D_TEXTCOPY_TL2BR;
BOOL ScanXPositive = TRUE;
BOOL ScanYPositive = TRUE;
// Check for an overlap.
if (psSourceRect->bottom > psDestRect->top &&
psSourceRect->top < psDestRect->bottom &&
psSourceRect->right > psDestRect->left &&
psSourceRect->left < psDestRect->right)
{
// Work out ScanX/ScanY flags.
if (psSourceRect->top == psDestRect->top)
{
// Horizontal blt, just set ScanXPositive appropriately.
ScanXPositive = (BOOL)(psSourceRect->left >= psDestRect->left);
}
else
{
// Non horizontal blts, just set ScanYPositive appropriately.
ScanYPositive = (BOOL)(psSourceRect->top >= psDestRect->top);
}
// Work out copy order from ScanX/ScanY flags.
if (ScanXPositive)
{// X+
if (ScanYPositive)
{// Y+
dwCopyOrder = MBX2D_TEXTCOPY_TL2BR;
}
else
{// Y-
dwCopyOrder = MBX2D_TEXTCOPY_BL2TR;
}
}
else
{// X-
if (ScanYPositive)
{// Y+
dwCopyOrder = MBX2D_TEXTCOPY_TR2BL;
}
else
{// Y-
dwCopyOrder = MBX2D_TEXTCOPY_BR2TL;
}
}
}
return dwCopyOrder;
}
/*****************************************************************************
<function>
FUNCTION : WriteStretchBlock
PURPOSE : Calculate stretch from source and dest dimensions and write to
2D hardware.
PARAMETERS : PRECTL psSourceRect - Source dimensions
PRECTL psDestRect - Destination dimensions
RETURNS : BOOL bHandled - False means punt the blit
<function/>
*****************************************************************************/
BOOL WriteStretchBlock(PRECTL psSourceRect, PRECTL psDestRect, ULONG **ppuCmd)
{
ULONG uXFPStretch;
ULONG uYFPStretch;
ULONG uDW = RectWidth ((PRECT) psDestRect);
ULONG uDH = RectHeight((PRECT) psDestRect);
ULONG uSW = RectWidth ((PRECT) psSourceRect);
ULONG uSH = RectHeight((PRECT) psSourceRect);
// Check the scale factor falls within our range by centering
// it and making sure that none overlaps our 10 bit range.
ULONG uXCheck = (uSW << 16) / uDW;
ULONG uYCheck = (uSH << 16) / uDH;
if ((uXCheck & 0xFFE007FF) || (0 == uXCheck) ||
(uYCheck & 0xFFE007FF) || (0 == uYCheck))
{
return FALSE;
}
// Calculate X and Y stretch in 5.5 fixed point format.
uXFPStretch = (uDW == uSW)
? MBX2D_NO_STRETCH
: uXCheck >> (16 - MBX2D_STRETCH_FPSHIFT);
uYFPStretch = (uDH == uSH)
? MBX2D_NO_STRETCH
: uYCheck >> (16 - MBX2D_STRETCH_FPSHIFT);
//// PDUMPSTRING(GetDriverData(NULL)->psPDContext, "-- Stretch setup");
*(*ppuCmd)++ = MBX2D_STRETCH_BH
| (uXFPStretch<<MBX2D_X_STRETCH_SHIFT)
| (uYFPStretch<<MBX2D_Y_STRETCH_SHIFT);
return TRUE;
}
/*****************************************************************************
<function>
FUNCTION : WriteSrcSurf
PURPOSE : Write 2D Source Surface data to the 2D hardware.
PARAMETERS : PSURFDATA psData - Surface data
PRECTL psRect - Surface dimensions
RETURNS : BOOL - TRUE if successful
<function/>
*****************************************************************************/
BOOL WriteSrcSurf(PSURFDATA psData, PRECTL psRect, ULONG **ppuCmd)
{
ULONG uHWFormat;
DWORD dwStrideBytes;
//// PDUMPSTRING(GetDriverData(NULL)->psPDContext, "-- SRC surface attributes");
// Select a hardware format based on the surface format.
switch(psData->dwMBXFormat)
{
case MBXDD_FORMAT_RGB332: uHWFormat = MBX2D_SRC_332RGB; break;
case MBXDD_FORMAT_RGB565: uHWFormat = MBX2D_SRC_565RGB; break;
case MBXDD_FORMAT_RGB555: uHWFormat = MBX2D_SRC_555RGB; break;
case MBXDD_FORMAT_RGB888: uHWFormat = MBX2D_SRC_888RGB; break;
case MBXDD_FORMAT_ARGB1555: uHWFormat = MBX2D_SRC_1555ARGB; break;
case MBXDD_FORMAT_ARGB4444: uHWFormat = MBX2D_SRC_4444ARGB; break;
case MBXDD_FORMAT_ARGB8888: uHWFormat = MBX2D_SRC_8888ARGB; break;
default:
ASSERT(FALSE);
break;
}
// Convert stride from pixels to bytes.
dwStrideBytes = psData->lStride * psData->sPixelFormat.dwRGBBitCount / 8;
// Write block header.
*(*ppuCmd)++ = MBX2D_SRC_CTRL_BH
| MBX2D_SRC_FBMEM
| uHWFormat
| ((dwStrideBytes << MBX2D_SRC_STRIDE_SHIFT) & MBX2D_SRC_STRIDE_MASK);
// Write base address.
*(*ppuCmd)++ = ((psData->psMemInfo->uiDevAddr.uiAddr
>> MBX2D_SRC_ADDR_ALIGNSHIFT)
<< MBX2D_SRC_ADDR_SHIFT)
& MBX2D_SRC_ADDR_MASK;
// Write the starting pixel coordinate.
*(*ppuCmd)++ = MBX2D_SRC_OFF_BH
| ((psRect->left << MBX2D_SRCOFF_XSTART_SHIFT) & MBX2D_SRCOFF_XSTART_MASK)
| ((psRect->top << MBX2D_SRCOFF_YSTART_SHIFT) & MBX2D_SRCOFF_YSTART_MASK);
return TRUE;
}
/*****************************************************************************
<function>
FUNCTION : WriteDstSurf
PURPOSE : Write 2D Destination Surface data to the 2D hardware.
PARAMETERS : PSURFDATA psData - Surface data
RETURNS : BOOL - TRUE if successful
<function/>
*****************************************************************************/
BOOL WriteDstSurf(PSURFDATA psData, ULONG **ppuCmd)
{
ULONG uHWFormat;
DWORD dwStrideBytes;
//// PDUMPSTRING(GetDriverData(NULL)->psPDContext, "-- DST surface attributes");
// Select a hardware format based on the surface format.
switch(psData->dwMBXFormat)
{
case MBXDD_FORMAT_RGB332: uHWFormat = MBX2D_DST_332RGB; break;
case MBXDD_FORMAT_RGB565: uHWFormat = MBX2D_DST_565RGB; break;
case MBXDD_FORMAT_RGB555: uHWFormat = MBX2D_DST_555RGB; break;
case MBXDD_FORMAT_RGB888: uHWFormat = MBX2D_DST_888RGB; break;
case MBXDD_FORMAT_ARGB1555: uHWFormat = MBX2D_DST_1555ARGB; break;
case MBXDD_FORMAT_ARGB4444: uHWFormat = MBX2D_DST_4444ARGB; break;
case MBXDD_FORMAT_ARGB8888: uHWFormat = MBX2D_DST_8888ARGB; break;
default:
ASSERT(FALSE);
break;
}
// Convert stride from pixels to bytes.
dwStrideBytes = psData->lStride * psData->sPixelFormat.dwRGBBitCount / 8;
// Write block header.
*(*ppuCmd)++ = MBX2D_DST_CTRL_BH
| uHWFormat
| ((dwStrideBytes << MBX2D_DST_STRIDE_SHIFT) & MBX2D_DST_STRIDE_MASK);
// Write base address.
*(*ppuCmd)++ = ((psData->psMemInfo->uiDevAddr.uiAddr
>> MBX2D_DST_ADDR_ALIGNSHIFT)
<< MBX2D_DST_ADDR_SHIFT)
& MBX2D_DST_ADDR_MASK;
return TRUE;
}
/*****************************************************************************
<function>
FUNCTION : Write2DControlBlock
PURPOSE : Write 2D Control data to the 2D hardware.
PARAMETERS : DWORD dw2DDataPresent -
DWORD dwSrcCKValue -
DWORD dwDstCKValue -
RETURNS : void
<function/>
*****************************************************************************/
void Write2DControlBlock(DWORD dw2DDataPresent, DWORD dwSrcCKValue, DWORD dwDstCKValue, DWORD dwAlphaConst, ULONG **ppuCmd)
{
DWORD dwAlphaControl = 0;
// Write block header.
*(*ppuCmd)++ = MBX2D_CTRL_BH | dw2DDataPresent;
// Write required data. Note: masks are set to check all bits.
if (dw2DDataPresent & MBX2D_SRCCK_CTRL)
{
*(*ppuCmd)++ = dwSrcCKValue;
*(*ppuCmd)++ = MBX2D_CK_MASK_MASK;
}
if (dw2DDataPresent & MBX2D_DSTCK_CTRL)
{
*(*ppuCmd)++ = dwDstCKValue;
*(*ppuCmd)++ = MBX2D_CK_MASK_MASK;
}
if (dw2DDataPresent & MBX2D_ALPHA_CTRL)
{
DWORD dwDstAlphaOp = MBX2D_DSTALPHA_OP_SRC;
DWORD dwSrcAlphaOp = MBX2D_SRCALPHA_OP_SRC;
if(dwAlphaConst != 0)
{
dwDstAlphaOp = MBX2D_DSTALPHA_OP_GBL;
dwSrcAlphaOp = MBX2D_SRCALPHA_OP_GBL;
}
/* Standard (non-premultiplied) blending formulae.
colour: DstC = SrcC*SrcA + DstC*(1-SrcA)
alpha: DstA = SrcA + DstA*(1-SrcA) */
dwAlphaControl = MBX2D_DSTALPHA_INVERT
| dwDstAlphaOp
| 0
| dwSrcAlphaOp
| ((dwAlphaConst & 0x000000FF) << MBX2D_GBLALPHA_SHIFT);
*(*ppuCmd)++ = dwAlphaControl;
}
}
/*****************************************************************************
<function>
FUNCTION : WriteBlitBlock
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -