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.
604 lines
18 KiB
604 lines
18 KiB
//----------------------------------------------------------------------------
|
|
//
|
|
// rasttex.cpp
|
|
//
|
|
// Texture functions.
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.cpp"
|
|
#pragma hdrstop
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// SetSizesSpanTexture
|
|
//
|
|
// Initialize pSpanTex data using current iMaxMipLevel info, Getting the
|
|
// surfaces from pSurf. Assumes InitSpanTexture has been called first.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
D3DContext::SetSizesSpanTexture(PD3DI_SPANTEX pSpanTex)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_LCL pLcl;
|
|
INT iFirstSurf = min(pSpanTex->iMaxMipLevel, pSpanTex->cLODTex);
|
|
LPDIRECTDRAWSURFACE pDDS = pSpanTex->pSurf[iFirstSurf];
|
|
INT i;
|
|
|
|
// Init
|
|
pLcl = ((LPDDRAWI_DDRAWSURFACE_INT)pDDS)->lpLcl;
|
|
|
|
pSpanTex->iSizeU = (INT16)DDSurf_Width(pLcl);
|
|
pSpanTex->iSizeV = (INT16)DDSurf_Height(pLcl);
|
|
pSpanTex->uMaskU = (INT16)(pSpanTex->iSizeU - 1);
|
|
pSpanTex->uMaskV = (INT16)(pSpanTex->iSizeV - 1);
|
|
pSpanTex->iShiftU = (INT16)IntLog2(pSpanTex->iSizeU);
|
|
if (0 != DDSurf_BitDepth(pLcl))
|
|
{
|
|
pSpanTex->iShiftPitch[0] =
|
|
(INT16)IntLog2((UINT32)(DDSurf_Pitch(pLcl) * 8)/DDSurf_BitDepth(pLcl));
|
|
}
|
|
else
|
|
{
|
|
pSpanTex->iShiftPitch[0] =
|
|
(INT16)IntLog2(((UINT32)DDSurf_Width(pLcl) * 8));
|
|
}
|
|
pSpanTex->iShiftV = (INT16)IntLog2(pSpanTex->iSizeV);
|
|
pSpanTex->uMaskV = pSpanTex->uMaskV;
|
|
|
|
// Check if the texture size is power of 2
|
|
if (!ValidTextureSize(pSpanTex->iSizeU, pSpanTex->iShiftU,
|
|
pSpanTex->iSizeV, pSpanTex->iShiftV))
|
|
{
|
|
// this texture can only be used for a ramp fill
|
|
pSpanTex->uFlags |= D3DI_SPANTEX_NON_POWER_OF_2;
|
|
pSpanTex->cLODTex = 0;
|
|
}
|
|
|
|
// Check for mipmap if any.
|
|
// iPreSizeU and iPreSizeV store the size(u and v) of the previous level
|
|
// mipmap. They are init'ed with the first texture size.
|
|
INT16 iPreSizeU = pSpanTex->iSizeU, iPreSizeV = pSpanTex->iSizeV;
|
|
for ( i = iFirstSurf + 1; i <= pSpanTex->cLODTex; i++)
|
|
{
|
|
pDDS = pSpanTex->pSurf[i];
|
|
// Check for invalid mipmap texture size
|
|
pLcl = ((LPDDRAWI_DDRAWSURFACE_INT)pDDS)->lpLcl;
|
|
if (!ValidMipmapSize(iPreSizeU, (INT16)DDSurf_Width(pLcl)) ||
|
|
!ValidMipmapSize(iPreSizeV, (INT16)DDSurf_Height(pLcl)))
|
|
{
|
|
return DDERR_INVALIDPARAMS;
|
|
}
|
|
if (0 != DDSurf_BitDepth(pLcl))
|
|
{
|
|
pSpanTex->iShiftPitch[i - iFirstSurf] =
|
|
(INT16)IntLog2(((UINT32)DDSurf_Pitch(pLcl)*8)/DDSurf_BitDepth(pLcl));
|
|
}
|
|
else
|
|
{
|
|
pSpanTex->iShiftPitch[0] =
|
|
(INT16)IntLog2(((UINT32)DDSurf_Width(pLcl)*8));
|
|
}
|
|
iPreSizeU = (INT16)DDSurf_Width(pLcl);
|
|
iPreSizeV = (INT16)DDSurf_Height(pLcl);
|
|
}
|
|
pSpanTex->iMaxScaledLOD = ((pSpanTex->cLODTex + 1) << LOD_SHIFT) - 1;
|
|
pSpanTex->uFlags &= ~D3DI_SPANTEX_MAXMIPLEVELS_DIRTY;
|
|
|
|
return D3D_OK;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// InitSpanTexture
|
|
//
|
|
// Initializes the entire array of pSurf's (regardless of iMaxMipLevel) pointed
|
|
// to by the root surface of pDDS. Sets all pSpanTex state that will not ever
|
|
// change in SetSizesSpanTexture.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
D3DContext::InitSpanTexture(PD3DI_SPANTEX pSpanTex, LPDIRECTDRAWSURFACE pDDS)
|
|
{
|
|
HRESULT hr;
|
|
LPDDRAWI_DDRAWSURFACE_LCL pLcl;
|
|
DDSCAPS ddscaps;
|
|
static INT32 iGeneration = 0;
|
|
|
|
// Init
|
|
pSpanTex->iGeneration = iGeneration++;
|
|
|
|
// Note that all pSpanTex elements are initialized to 0
|
|
pLcl = ((LPDDRAWI_DDRAWSURFACE_INT)pDDS)->lpLcl;
|
|
|
|
// Set the transparent bit and the transparent color with pSurf[0]
|
|
// initially
|
|
if ((pLcl->dwFlags & DDRAWISURF_HASCKEYSRCBLT) != 0)
|
|
{
|
|
pSpanTex->uFlags |= D3DI_SPANTEX_HAS_TRANSPARENT;
|
|
pSpanTex->TransparentColor =
|
|
pLcl->ddckCKSrcBlt.dwColorSpaceHighValue;
|
|
}
|
|
else
|
|
{
|
|
pSpanTex->uFlags &= ~D3DI_SPANTEX_HAS_TRANSPARENT;
|
|
}
|
|
|
|
HR_RET(FindOutSurfFormat(&(DDSurf_PixFmt(pLcl)), &(pSpanTex->Format)));
|
|
|
|
if (pSpanTex->Format == D3DI_SPTFMT_PALETTE8 ||
|
|
pSpanTex->Format == D3DI_SPTFMT_PALETTE4)
|
|
{
|
|
if (pLcl->lpDDPalette)
|
|
{
|
|
LPDDRAWI_DDRAWPALETTE_GBL pPal = pLcl->lpDDPalette->lpLcl->lpGbl;
|
|
if (pPal->dwFlags & DDRAWIPAL_ALPHA)
|
|
{
|
|
pSpanTex->uFlags |= D3DI_SPANTEX_ALPHAPALETTE;
|
|
}
|
|
pSpanTex->pPalette = (PUINT32)pPal->lpColorTable;
|
|
}
|
|
if (pSpanTex->Format == D3DI_SPTFMT_PALETTE8)
|
|
{
|
|
pSpanTex->iPaletteSize = 256;
|
|
}
|
|
else
|
|
{
|
|
// PALETTE4
|
|
pSpanTex->iPaletteSize = 16;
|
|
}
|
|
}
|
|
pSpanTex->TexAddrU = D3DTADDRESS_WRAP;
|
|
pSpanTex->TexAddrV = D3DTADDRESS_WRAP;
|
|
pSpanTex->BorderColor = RGBA_MAKE(0xff, 0x00, 0xff, 0xff);
|
|
|
|
// assign first pSurf here (mipmap chain gets assigned below)
|
|
pSpanTex->pSurf[0] = pDDS;
|
|
|
|
// Check for mipmap if any.
|
|
LPDIRECTDRAWSURFACE pTmpS;
|
|
// iPreSizeU and iPreSizeV store the size(u and v) of the previous level
|
|
// mipmap. They are init'ed with the first texture size.
|
|
INT16 iPreSizeU = pSpanTex->iSizeU, iPreSizeV = pSpanTex->iSizeV;
|
|
for (;;)
|
|
{
|
|
memset(&ddscaps, 0, sizeof(DDSCAPS));
|
|
ddscaps.dwCaps = DDSCAPS_TEXTURE;
|
|
hr = pDDS->GetAttachedSurface(&ddscaps, &pTmpS); //implicit AddRef
|
|
if (hr == DDERR_NOTFOUND)
|
|
{
|
|
break;
|
|
}
|
|
else if (hr != D3D_OK)
|
|
{
|
|
return hr;
|
|
}
|
|
pDDS = pTmpS;
|
|
|
|
pSpanTex->cLODTex ++;
|
|
pSpanTex->pSurf[pSpanTex->cLODTex] = pTmpS;
|
|
}
|
|
|
|
pSpanTex->dwSize = sizeof(D3DI_SPANTEX);
|
|
|
|
return D3D_OK;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// RemoveTexture
|
|
//
|
|
// Check to see if the to-be-destroyed pSpanTex is currently used by the
|
|
// context. If yes, set the according entry to be NULL to disable texture.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void D3DContext::RemoveTexture(PD3DI_SPANTEX pSpanTex)
|
|
{
|
|
INT i;
|
|
INT cActTex = (INT)m_RastCtx.cActTex;
|
|
|
|
for (i = 0; i < cActTex; i++)
|
|
{
|
|
if (m_RastCtx.pTexture[i] == pSpanTex)
|
|
{
|
|
// NULL out the according texture and set dirty bits
|
|
m_RastCtx.cActTex --;
|
|
StateChanged(D3DRENDERSTATE_TEXTUREHANDLE);
|
|
m_RastCtx.pTexture[i] = NULL;
|
|
for (int j=pSpanTex->cLODTex;j>0;j--) //release attached surfs
|
|
{
|
|
pSpanTex->pSurf[j]->Release();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// RastTextureCreate
|
|
//
|
|
// Creates a RAST texture and initializes it with the info passed in.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
DWORD __stdcall
|
|
RastTextureCreate(LPD3DHAL_TEXTURECREATEDATA pTexData)
|
|
{
|
|
PD3DI_SPANTEX *ppSpanTex;
|
|
PD3DI_SPANTEX pSpanTex;
|
|
D3DContext *pDCtx;
|
|
|
|
VALIDATE_D3DCONTEXT("RastTextureCreate", pTexData);
|
|
|
|
// Create the span texture
|
|
ppSpanTex = new PD3DI_SPANTEX;
|
|
pSpanTex = new D3DI_SPANTEX;
|
|
if (ppSpanTex == NULL || pSpanTex == NULL)
|
|
{
|
|
delete ppSpanTex;
|
|
delete pSpanTex;
|
|
D3D_ERR("(Rast) Out of memory in RastTextureCreate");
|
|
pTexData->ddrval = DDERR_OUTOFMEMORY;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
memset(pSpanTex, 0, sizeof(D3DI_SPANTEX));
|
|
|
|
// Point indirector to this texture initially.
|
|
*ppSpanTex = pSpanTex;
|
|
|
|
// Init the span texture
|
|
if ((pTexData->ddrval = pDCtx->InitSpanTexture(pSpanTex, pTexData->lpDDS))
|
|
!= D3D_OK)
|
|
{
|
|
delete ppSpanTex;
|
|
delete pSpanTex;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
if ((pTexData->ddrval = pDCtx->SetSizesSpanTexture(pSpanTex))
|
|
!= D3D_OK)
|
|
{
|
|
delete ppSpanTex;
|
|
delete pSpanTex;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
// ppSpanTex is used as the texture handle returned to d3dim.
|
|
pTexData->dwHandle = (UINT32)(ULONG_PTR)ppSpanTex;
|
|
|
|
pTexData->ddrval = D3D_OK;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// RastTextureDestroy
|
|
//
|
|
// Destroy a RAST texture.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
DWORD __stdcall
|
|
RastTextureDestroy(LPD3DHAL_TEXTUREDESTROYDATA pTexDestroyData)
|
|
{
|
|
PD3DI_SPANTEX *ppSpanTex;
|
|
PD3DI_SPANTEX pSpanTex;
|
|
D3DContext *pDCtx;
|
|
|
|
VALIDATE_D3DCONTEXT("RastTextureDestroy", pTexDestroyData);
|
|
if (!VALID_D3DI_SPANTEX_PTR_PTR(
|
|
(PD3DI_SPANTEX*)ULongToPtr(pTexDestroyData->dwHandle)))
|
|
{
|
|
D3D_ERR("(Rast) in RastTextureDestroy, invalid texture handle");
|
|
pTexDestroyData->ddrval = DDERR_INVALIDPARAMS;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
// Find the texture
|
|
ppSpanTex = (PD3DI_SPANTEX *)ULongToPtr(pTexDestroyData->dwHandle);
|
|
pSpanTex = *ppSpanTex;
|
|
|
|
pDCtx->RemoveTexture(pSpanTex);
|
|
|
|
// Delete it
|
|
if (pSpanTex)
|
|
{
|
|
delete ppSpanTex;
|
|
delete pSpanTex;
|
|
}
|
|
else
|
|
{
|
|
pTexDestroyData->ddrval = DDERR_INVALIDPARAMS;
|
|
}
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// RastTextureSwap
|
|
//
|
|
// Swaps over the ownership of two texture handles.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
DWORD __stdcall
|
|
RastTextureSwap(LPD3DHAL_TEXTURESWAPDATA pTexSwapData)
|
|
{
|
|
D3DContext *pDCtx;
|
|
|
|
VALIDATE_D3DCONTEXT("RastTextureSwap", pTexSwapData);
|
|
|
|
// Check out the span textures
|
|
PD3DI_SPANTEX pSpanTex1, pSpanTex2;
|
|
pSpanTex1 = HANDLE_TO_SPANTEX(pTexSwapData->dwHandle1);
|
|
pSpanTex2 = HANDLE_TO_SPANTEX(pTexSwapData->dwHandle2);
|
|
|
|
// Swap
|
|
if (pSpanTex1 != NULL && pSpanTex2 != NULL)
|
|
{
|
|
HANDLE_TO_SPANTEX(pTexSwapData->dwHandle1) = pSpanTex2;
|
|
HANDLE_TO_SPANTEX(pTexSwapData->dwHandle2) = pSpanTex1;
|
|
pTexSwapData->ddrval = D3D_OK;
|
|
}
|
|
else
|
|
{
|
|
pTexSwapData->ddrval = DDERR_INVALIDPARAMS;
|
|
}
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// RastTextureGetSurf
|
|
//
|
|
// Returns the surface pointer associate with a texture handle.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
DWORD __stdcall
|
|
RastTextureGetSurf(LPD3DHAL_TEXTUREGETSURFDATA pTexGetSurf)
|
|
{
|
|
D3DContext *pDCtx;
|
|
|
|
VALIDATE_D3DCONTEXT("RastTextureGetSurf", pTexGetSurf);
|
|
|
|
// Check out the span texture
|
|
PD3DI_SPANTEX pSpanTex;
|
|
pSpanTex = HANDLE_TO_SPANTEX(pTexGetSurf->dwHandle);
|
|
|
|
if (pSpanTex)
|
|
{
|
|
pTexGetSurf->lpDDS = (UINT_PTR)pSpanTex->pSurf[0];
|
|
pTexGetSurf->ddrval = D3D_OK;
|
|
}
|
|
else
|
|
{
|
|
pTexGetSurf->ddrval = DDERR_INVALIDPARAMS;
|
|
}
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// RastLockSpanTexture
|
|
//
|
|
// Lock current texture surface before the texture bits are accessed.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
D3DContext::RastLockSpanTexture(void)
|
|
{
|
|
INT i, j;
|
|
PD3DI_SPANTEX pSpanTex;
|
|
HRESULT hr;
|
|
|
|
if (IsTextureOff())
|
|
{
|
|
return D3D_OK;
|
|
}
|
|
|
|
DDASSERT((m_uFlags & D3DCONTEXT_TEXTURE_LOCKED) == 0);
|
|
|
|
for (j = 0;
|
|
j < (INT)m_RastCtx.cActTex;
|
|
j++)
|
|
{
|
|
pSpanTex = m_RastCtx.pTexture[j];
|
|
if (pSpanTex->uFlags & D3DI_SPANTEX_MAXMIPLEVELS_DIRTY)
|
|
{
|
|
hr = SetSizesSpanTexture(pSpanTex);
|
|
if (hr != D3D_OK)
|
|
{
|
|
goto EH_Unlock;
|
|
}
|
|
}
|
|
INT iFirstSurf = min(pSpanTex->iMaxMipLevel, pSpanTex->cLODTex);
|
|
|
|
// Currently recursive locks are not allowed.
|
|
DDASSERT((pSpanTex->uFlags & D3DI_SPANTEX_SURFACES_LOCKED) == 0);
|
|
|
|
for (i = iFirstSurf; i <= pSpanTex->cLODTex; i++)
|
|
{
|
|
hr = LockSurface(pSpanTex->pSurf[i],
|
|
(LPVOID*)&(pSpanTex->pBits[i-iFirstSurf]));
|
|
if (hr != D3D_OK)
|
|
{
|
|
// Unlock any partial mipmap locks we've taken, as
|
|
// RastUnlock can only handle entire textures being
|
|
// locked or unlocked.
|
|
while (--i >= 0)
|
|
{
|
|
UnlockSurface(pSpanTex->pSurf[i]);
|
|
}
|
|
|
|
// Make sure that i is signed and that the above
|
|
// loop exited properly.
|
|
DDASSERT(i < 0);
|
|
|
|
goto EH_Unlock;
|
|
}
|
|
}
|
|
|
|
pSpanTex->uFlags |= D3DI_SPANTEX_SURFACES_LOCKED;
|
|
}
|
|
|
|
m_uFlags |= D3DCONTEXT_TEXTURE_LOCKED;
|
|
|
|
return D3D_OK;
|
|
|
|
EH_Unlock:
|
|
if (j > 0)
|
|
{
|
|
// Unlock complete textures we've already locked.
|
|
// RastUnlock will check the flags to figure
|
|
// out which ones to unlock.
|
|
RastUnlockSpanTexture();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// RastUnlockTexture
|
|
//
|
|
// Unlock texture surface after the texture bits are accessed.
|
|
// The input is a D3DI_SPANTEX. NULL texture needs to be checked before this
|
|
// function gets called.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
D3DContext::RastUnlockSpanTexture(void)
|
|
{
|
|
INT i, j;
|
|
PD3DI_SPANTEX pSpanTex;;
|
|
|
|
if (IsTextureOff())
|
|
{
|
|
return;
|
|
}
|
|
|
|
DDASSERT((m_uFlags & D3DCONTEXT_TEXTURE_LOCKED) != 0);
|
|
|
|
for (j = 0;
|
|
j < (INT)m_RastCtx.cActTex;
|
|
j++)
|
|
{
|
|
pSpanTex = m_RastCtx.pTexture[j];
|
|
|
|
INT iFirstSurf = min(pSpanTex->iMaxMipLevel, pSpanTex->cLODTex);
|
|
// RastUnlock is used for cleanup in RastLock so it needs to
|
|
// be able to handle partially locked mipmap chains.
|
|
if (pSpanTex->uFlags & D3DI_SPANTEX_SURFACES_LOCKED)
|
|
{
|
|
for (i = iFirstSurf; i <= pSpanTex->cLODTex; i++)
|
|
{
|
|
UnlockSurface(pSpanTex->pSurf[i]);
|
|
}
|
|
|
|
pSpanTex->uFlags &= ~D3DI_SPANTEX_SURFACES_LOCKED;
|
|
}
|
|
}
|
|
m_uFlags &= ~D3DCONTEXT_TEXTURE_LOCKED;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// UpdateColorKeyAndPalette
|
|
//
|
|
// Updates the color key value and palette.
|
|
//
|
|
// Also, if the ColorKey enable for the texture has changed, set the texture handle
|
|
// dirty bit so the new mode is recognized in span init.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
D3DContext::UpdateColorKeyAndPalette(void)
|
|
{
|
|
INT j;
|
|
PD3DI_SPANTEX pSpanTex;
|
|
|
|
// Set the transparent bit and the transparent color with pSurf[0]
|
|
LPDDRAWI_DDRAWSURFACE_LCL pLcl;
|
|
for (j = 0;
|
|
j < (INT)m_RastCtx.cActTex;
|
|
j++)
|
|
{
|
|
pSpanTex = m_RastCtx.pTexture[j];
|
|
if ((pSpanTex != NULL) && (pSpanTex->pSurf[0] != NULL))
|
|
{
|
|
pLcl = ((LPDDRAWI_DDRAWSURFACE_INT) pSpanTex->pSurf[0])->lpLcl;
|
|
|
|
// Palette might be changed
|
|
if (pSpanTex->Format == D3DI_SPTFMT_PALETTE8 ||
|
|
pSpanTex->Format == D3DI_SPTFMT_PALETTE4)
|
|
{
|
|
if (pLcl->lpDDPalette)
|
|
{
|
|
LPDDRAWI_DDRAWPALETTE_GBL pPal = pLcl->lpDDPalette->lpLcl->lpGbl;
|
|
if (pPal->dwFlags & DDRAWIPAL_ALPHA)
|
|
{
|
|
pSpanTex->uFlags |= D3DI_SPANTEX_ALPHAPALETTE;
|
|
}
|
|
pSpanTex->pPalette = (PUINT32)pPal->lpColorTable;
|
|
}
|
|
}
|
|
|
|
if ((pLcl->dwFlags & DDRAWISURF_HASCKEYSRCBLT) != 0)
|
|
{
|
|
// texture has a ColorKey value
|
|
pSpanTex->TransparentColor =
|
|
pLcl->ddckCKSrcBlt.dwColorSpaceHighValue;
|
|
if (!(pSpanTex->uFlags & D3DI_SPANTEX_HAS_TRANSPARENT))
|
|
{
|
|
pSpanTex->uFlags |= D3DI_SPANTEX_HAS_TRANSPARENT;
|
|
|
|
// make sure this state change is recognized, and a new
|
|
// texture read function is used
|
|
StateChanged(D3DHAL_TSS_OFFSET(j, D3DTSS_TEXTUREMAP));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// texture does not have a ColorKey value
|
|
if (pSpanTex->uFlags & D3DI_SPANTEX_HAS_TRANSPARENT)
|
|
{
|
|
pSpanTex->uFlags &= ~D3DI_SPANTEX_HAS_TRANSPARENT;
|
|
|
|
// make sure this state change is recognized, and a new
|
|
// texture read function is used
|
|
StateChanged(D3DHAL_TSS_OFFSET(j, D3DTSS_TEXTUREMAP));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Dp2TextureStageState
|
|
//
|
|
// Called by Drawprim2 to set texture stage states..
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
D3DContext::Dp2TextureStageState(LPD3DHAL_DP2COMMAND pCmd, DWORD dwFvf)
|
|
{
|
|
WORD wStateCount = pCmd->wStateCount;
|
|
INT i;
|
|
HRESULT hr;
|
|
LPD3DHAL_DP2TEXTURESTAGESTATE pTexStageState =
|
|
(D3DHAL_DP2TEXTURESTAGESTATE *)(pCmd + 1);
|
|
// Flush the prim proc before any state changs
|
|
HR_RET(End(FALSE));
|
|
|
|
for (i = 0; i < (INT)wStateCount; i++, pTexStageState++)
|
|
{
|
|
HR_RET(SetRenderState(D3DHAL_TSS_OFFSET((DWORD)pTexStageState->wStage,
|
|
(DWORD)pTexStageState->TSState),
|
|
pTexStageState->dwValue));
|
|
}
|
|
|
|
HR_RET(CheckFVF(dwFvf));
|
|
|
|
hr = Begin();
|
|
return hr;
|
|
}
|