/////////////////////////////////////////////////////////////////////////////// // // primfns.cpp // // Copyright (C) Microsoft Corporation, 1998. // ////////////////////////////////////////////////////////////////////////////// #include "pch.cpp" #pragma hdrstop //---------------------------------------------------------------------------- // // Wrap functions // //---------------------------------------------------------------------------- HRESULT WrapDp2SetViewport( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetViewport(pCmd); } HRESULT WrapDp2SetWRange ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetWRange(pCmd); } HRESULT WrapDp2SetZRange ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetZRange(pCmd); } HRESULT WrapDp2SetRenderStates( RefDev *pRefDev, DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates ) { return pRefDev->Dp2SetRenderStates(dwFvf, pCmd, lpdwRuntimeRStates); } HRESULT WrapDp2SetTextureStageState( RefDev *pRefDev, DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetTextureStageState(dwFvf, pCmd); } HRESULT WrapDp2SetMaterial ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetMaterial(pCmd); } HRESULT WrapDp2SetLight( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd, LPDWORD pdwStride ) { return pRefDev->Dp2SetLight(pCmd, pdwStride); } HRESULT WrapDp2CreateLight ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2CreateLight(pCmd); } HRESULT WrapDp2SetTransform( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetTransform(pCmd); } HRESULT WrapDp2MultiplyTransform( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2MultiplyTransform(pCmd); } HRESULT WrapDp2SetExtention( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetExtention(pCmd); } HRESULT WrapDp2SetClipPlane( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetClipPlane(pCmd); } HRESULT WrapDp2SetVertexShader( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetVertexShader( pCmd ); } HRESULT WrapDp2SetVertexShaderConsts( RefDev *pRefDev, DWORD StartReg, DWORD dwCount, LPDWORD pData ) { return pRefDev->Dp2SetVertexShaderConsts( StartReg, dwCount, pData ); } HRESULT WrapDp2SetPixelShader( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetPixelShader( pCmd ); } HRESULT WrapDp2SetPixelShaderConsts( RefDev *pRefDev, DWORD StartReg, DWORD dwCount, LPDWORD pData ) { return pRefDev->Dp2SetPixelShaderConsts( StartReg, dwCount, pData ); } HRESULT WrapDp2SetStreamSource( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetStreamSource( pCmd ); } HRESULT WrapDp2SetIndices( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetIndices( pCmd ); } HRESULT WrapDp2RecViewport( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecViewport(pCmd); } HRESULT WrapDp2RecWRange ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecWRange(pCmd); } HRESULT WrapDp2RecZRange ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecZRange(pCmd); } HRESULT WrapDp2RecRenderStates( RefDev *pRefDev, DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates ) { return pRefDev->Dp2RecRenderStates(dwFvf, pCmd, lpdwRuntimeRStates); } HRESULT WrapDp2RecTextureStageState( RefDev *pRefDev, DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecTextureStageState(dwFvf, pCmd); } HRESULT WrapDp2RecMaterial ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecMaterial(pCmd); } HRESULT WrapDp2RecSetLight ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd, LPDWORD pdwStride) { return pRefDev->Dp2RecSetLight(pCmd, pdwStride); } HRESULT WrapDp2RecCreateLight( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecCreateLight(pCmd); } HRESULT WrapDp2RecTransform( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecTransform(pCmd); } HRESULT WrapDp2RecExtention( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecExtention(pCmd); } HRESULT WrapDp2RecClipPlane( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecClipPlane(pCmd); } HRESULT WrapDp2RecSetVertexShader( RefDev* pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecSetVertexShader( pCmd ); } HRESULT WrapDp2RecSetVertexShaderConsts( RefDev* pRefDev, DWORD StartReg, DWORD dwCount, LPDWORD pData ) { return pRefDev->Dp2RecSetVertexShaderConsts( StartReg, dwCount, pData ); } HRESULT WrapDp2RecSetPixelShader( RefDev* pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecSetPixelShader( pCmd ); } HRESULT WrapDp2RecSetPixelShaderConsts( RefDev* pRefDev, DWORD StartReg, DWORD dwCount, LPDWORD pData ) { return pRefDev->Dp2RecSetPixelShaderConsts( StartReg, dwCount, pData ); } HRESULT WrapDp2RecSetStreamSource( RefDev* pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecSetStreamSource( pCmd ); } HRESULT WrapDp2RecSetIndices( RefDev* pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecSetIndices( pCmd ); } static RD_STATESETFUNCTIONTBL StateRecFunctions = { sizeof(RD_STATESETFUNCTIONTBL), WrapDp2RecRenderStates, WrapDp2RecTextureStageState, WrapDp2RecViewport, WrapDp2RecWRange, WrapDp2RecMaterial, WrapDp2RecZRange, WrapDp2RecSetLight, WrapDp2RecCreateLight, WrapDp2RecTransform, WrapDp2RecExtention, WrapDp2RecClipPlane, WrapDp2RecSetVertexShader, WrapDp2RecSetVertexShaderConsts, WrapDp2RecSetPixelShader, WrapDp2RecSetPixelShaderConsts, WrapDp2RecSetStreamSource, WrapDp2RecSetIndices }; static RD_STATESETFUNCTIONTBL StateSetFunctions = { sizeof(RD_STATESETFUNCTIONTBL), WrapDp2SetRenderStates, WrapDp2SetTextureStageState, WrapDp2SetViewport, WrapDp2SetWRange, WrapDp2SetMaterial, WrapDp2SetZRange, WrapDp2SetLight, WrapDp2CreateLight, WrapDp2SetTransform, WrapDp2SetExtention, WrapDp2SetClipPlane, WrapDp2SetVertexShader, WrapDp2SetVertexShaderConsts, WrapDp2SetPixelShader, WrapDp2SetPixelShaderConsts, WrapDp2SetStreamSource, WrapDp2SetIndices, WrapDp2MultiplyTransform }; //---------------------------------------------------------------------------- // // RefDev methods // //---------------------------------------------------------------------------- void RefDev::StoreLastPixelState(BOOL bStore) { if( bStore ) { m_LastState = GetRS()[D3DRENDERSTATE_LASTPIXEL]; SetRenderState(D3DRENDERSTATE_LASTPIXEL, 0); } else { SetRenderState(D3DRENDERSTATE_LASTPIXEL, m_LastState); } } void RefDev::SetRecStateFunctions(void) { pStateSetFuncTbl = &StateRecFunctions; } void RefDev::SetSetStateFunctions(void) { pStateSetFuncTbl = &StateSetFunctions; } HRESULT RefDev::Dp2SetRenderStates(DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates ) { WORD wStateCount = pCmd->wStateCount; INT i; HRESULT hr = D3D_OK; D3DHAL_DP2RENDERSTATE *pRenderState = (D3DHAL_DP2RENDERSTATE *)(pCmd + 1); for (i = 0; i < (INT)wStateCount; i++, pRenderState++) { UINT32 type = (UINT32) pRenderState->RenderState; // Check for overrides if( IS_OVERRIDE(type) ) { UINT32 override = GET_OVERRIDE(type); if( pRenderState->dwState ) STATESET_SET(m_renderstate_override, override); else STATESET_CLEAR(m_renderstate_override, override); continue; } if( STATESET_ISSET(m_renderstate_override, type) ) continue; // Set the runtime copy (if necessary) if( NULL != lpdwRuntimeRStates ) { lpdwRuntimeRStates[pRenderState->RenderState] = pRenderState->dwState; } // Set the state SetRenderState(pRenderState->RenderState, pRenderState->dwState); } return hr; } HRESULT RefDev::Dp2SetTextureStageState( DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd ) { WORD wStateCount = pCmd->wStateCount; INT i; HRESULT hr = D3D_OK; D3DHAL_DP2TEXTURESTAGESTATE *pTexStageState = (D3DHAL_DP2TEXTURESTAGESTATE *)(pCmd + 1); for (i = 0; i < (INT)wStateCount; i++, pTexStageState++) { SetTextureStageState( pTexStageState->wStage, pTexStageState->TSState, pTexStageState->dwValue ); } return hr; } HRESULT RefDev::Dp2SetViewport(LPD3DHAL_DP2COMMAND pCmd) { LPD3DHAL_DP2VIEWPORTINFO pVpt; // Keep only the last viewport notification pVpt = (D3DHAL_DP2VIEWPORTINFO *)(pCmd + 1) + (pCmd->wStateCount - 1); // Update T&L viewport state D3DVIEWPORT7& vp = m_Clipper.m_Viewport; vp.dwX = pVpt->dwX; vp.dwY = pVpt->dwY; vp.dwWidth = pVpt->dwWidth; vp.dwHeight = pVpt->dwHeight; m_Clipper.m_dwFlags |= RefClipper::RCLIP_DIRTY_VIEWRECT; // get render target; update it; put it back RDRenderTarget *pRendTgt = this->GetRenderTarget(); pRendTgt->m_Clip.left = pVpt->dwX; pRendTgt->m_Clip.top = pVpt->dwY; pRendTgt->m_Clip.right = pVpt->dwX + pVpt->dwWidth - 1; pRendTgt->m_Clip.bottom = pVpt->dwY + pVpt->dwHeight - 1; SetRenderTarget( pRendTgt ); return D3D_OK; } HRESULT RefDev::Dp2SetWRange(LPD3DHAL_DP2COMMAND pCmd) { LPD3DHAL_DP2WINFO pWInfo; // Keep only the last viewport notification pWInfo = (D3DHAL_DP2WINFO *)(pCmd + 1) + (pCmd->wStateCount - 1); // get render target; update it; put it back RDRenderTarget *pRendTgt = this->GetRenderTarget(); pRendTgt->m_fWRange[0] = pWInfo->dvWNear; pRendTgt->m_fWRange[1] = pWInfo->dvWFar; this->SetRenderTarget( pRendTgt ); return D3D_OK; } HRESULT RefDev::Dp2SetZRange(LPD3DHAL_DP2COMMAND pCmd) { LPD3DHAL_DP2ZRANGE pZRange; // Keep only the last viewport notification pZRange = (D3DHAL_DP2ZRANGE *)(pCmd + 1) + (pCmd->wStateCount - 1); // Update T&L viewport state D3DVIEWPORT7& vp = m_Clipper.m_Viewport; vp.dvMinZ = pZRange->dvMinZ; vp.dvMaxZ = pZRange->dvMaxZ; m_Clipper.m_dwFlags |= RefClipper::RCLIP_DIRTY_ZRANGE; return D3D_OK; } HRESULT RefDev::Dp2SetMaterial(LPD3DHAL_DP2COMMAND pCmd) { LPD3DHAL_DP2SETMATERIAL pSetMat; // Keep only the last material notification pSetMat = (D3DHAL_DP2SETMATERIAL *)(pCmd + 1) + (pCmd->wStateCount - 1); m_RefVP.m_Material = *(D3DMATERIAL7 *)pSetMat; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_MATERIAL; return D3D_OK; } HRESULT RefDev::Dp2CreateLight(LPD3DHAL_DP2COMMAND pCmd) { WORD wNumCreateLight = pCmd->wStateCount; LPD3DHAL_DP2CREATELIGHT pCreateLight = (LPD3DHAL_DP2CREATELIGHT)(pCmd + 1); HRESULT hr = D3D_OK; for (int i = 0; i < wNumCreateLight; i++, pCreateLight++) { HR_RET(m_RefVP.GrowLightArray( pCreateLight->dwIndex ) ); } return hr; } HRESULT RefDev::Dp2SetLight(LPD3DHAL_DP2COMMAND pCmd, LPDWORD pdwStride) { HRESULT hr = D3D_OK; WORD wNumSetLight = pCmd->wStateCount; _ASSERT( pdwStride != NULL, "pdwStride is Null" ); *pdwStride = sizeof(D3DHAL_DP2COMMAND); LPD3DHAL_DP2SETLIGHT pSetLight = (LPD3DHAL_DP2SETLIGHT)(pCmd + 1); D3DLIGHT7 *pLightData = NULL; for (int i = 0; i < wNumSetLight; i++) { DWORD dwStride = sizeof(D3DHAL_DP2SETLIGHT); DWORD dwIndex = pSetLight->dwIndex; // Assert that create was not called here _ASSERTf( m_RefVP.m_LightArray.IsValidIndex( dwIndex ), ( "Create was not called prior to the SetLight for light %d", dwIndex )); switch (pSetLight->dwDataType) { case D3DHAL_SETLIGHT_ENABLE: m_RefVP.LightEnable( dwIndex, TRUE ); break; case D3DHAL_SETLIGHT_DISABLE: m_RefVP.LightEnable( dwIndex, FALSE ); break; case D3DHAL_SETLIGHT_DATA: pLightData = (D3DLIGHT7 *)((LPBYTE)pSetLight + dwStride); dwStride += sizeof(D3DLIGHT7); HR_RET(m_RefVP.SetLightData( pSetLight->dwIndex, pLightData)); break; default: DPFERR( "Unknown SetLight command" ); hr = DDERR_INVALIDPARAMS; } *pdwStride += dwStride; // Update the command buffer pointer pSetLight = (D3DHAL_DP2SETLIGHT *)((LPBYTE)pSetLight + dwStride); } return hr; } static D3DMATRIX matIdent = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; HRESULT RefDev::Dp2SetTransform(LPD3DHAL_DP2COMMAND pCmd) { WORD wNumXfrms = pCmd->wStateCount; D3DHAL_DP2SETTRANSFORM *pSetXfrm = (D3DHAL_DP2SETTRANSFORM*)(pCmd + 1); for (int i = 0; i < (int) wNumXfrms; i++, pSetXfrm++) { D3DMATRIX* pMat = &pSetXfrm->matrix; DWORD xfrmType = (DWORD)pSetXfrm->xfrmType; if ((DWORD)xfrmType >= RD_WORLDMATRIXBASE && (DWORD)xfrmType < (RD_WORLDMATRIXBASE + RD_MAX_WORLD_MATRICES)) { // World matrix is set UINT index = (DWORD)xfrmType - RD_WORLDMATRIXBASE; memcpy(&(m_RefVP.m_xfmWorld[index]), pMat, sizeof(D3DMATRIX)); switch (index) { case 0: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDXFM; break; case 1: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD1XFM; break; case 2: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD2XFM; break; case 3: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD3XFM; break; default: // m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDNXFM; break; } } else { switch( xfrmType ) { case D3DTRANSFORMSTATE_WORLD_DX7: memcpy(&(m_RefVP.m_xfmWorld[0]), pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDXFM; break; case D3DTRANSFORMSTATE_VIEW: memcpy(&m_RefVP.m_xfmView, pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_VIEWXFM; break; case D3DTRANSFORMSTATE_PROJECTION: memcpy(&m_RefVP.m_xfmProj, pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_PROJXFM; break; case D3DTRANSFORMSTATE_WORLD1_DX7: memcpy(&(m_RefVP.m_xfmWorld[1]), pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD1XFM; break; case D3DTRANSFORMSTATE_WORLD2_DX7: memcpy(&(m_RefVP.m_xfmWorld[2]), pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD2XFM; break; case D3DTRANSFORMSTATE_WORLD3_DX7: memcpy(&(m_RefVP.m_xfmWorld[3]), pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD3XFM; break; case D3DTRANSFORMSTATE_TEXTURE0: case D3DTRANSFORMSTATE_TEXTURE1: case D3DTRANSFORMSTATE_TEXTURE2: case D3DTRANSFORMSTATE_TEXTURE3: case D3DTRANSFORMSTATE_TEXTURE4: case D3DTRANSFORMSTATE_TEXTURE5: case D3DTRANSFORMSTATE_TEXTURE6: case D3DTRANSFORMSTATE_TEXTURE7: memcpy( &(m_RefVP.m_xfmTex[xfrmType - D3DTRANSFORMSTATE_TEXTURE0]), pMat, sizeof(D3DMATRIX) ); break; default: DPFERR( "Ignoring unknown transform type" ); } } } return D3D_OK; } extern void MatrixProduct(D3DMATRIX *result, D3DMATRIX *a, D3DMATRIX *b); HRESULT RefDev::Dp2MultiplyTransform(LPD3DHAL_DP2COMMAND pCmd) { WORD wNumXfrms = pCmd->wStateCount; D3DHAL_DP2MULTIPLYTRANSFORM *pSetXfrm = (D3DHAL_DP2MULTIPLYTRANSFORM*)(pCmd + 1); for (int i = 0; i < (int) wNumXfrms; i++, pSetXfrm++) { D3DMATRIX* pMat = &pSetXfrm->matrix; DWORD xfrmType = (DWORD)pSetXfrm->xfrmType; if ((DWORD)xfrmType >= RD_WORLDMATRIXBASE && (DWORD)xfrmType < (RD_WORLDMATRIXBASE + RD_MAX_WORLD_MATRICES)) { // World matrix is set UINT index = (DWORD)xfrmType - RD_WORLDMATRIXBASE; MatrixProduct(&(m_RefVP.m_xfmWorld[index]), pMat, &(m_RefVP.m_xfmWorld[index])); switch (index) { case 0: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDXFM; break; case 1: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD1XFM; break; case 2: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD2XFM; break; case 3: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD3XFM; break; default: // m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDNXFM; break; } } else { switch( xfrmType ) { case D3DTRANSFORMSTATE_WORLD_DX7: MatrixProduct(&(m_RefVP.m_xfmWorld[0]), pMat, &(m_RefVP.m_xfmWorld[0])); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDXFM; break; case D3DTRANSFORMSTATE_VIEW: MatrixProduct(&m_RefVP.m_xfmView, pMat, &m_RefVP.m_xfmView); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_VIEWXFM; break; case D3DTRANSFORMSTATE_PROJECTION: MatrixProduct(&m_RefVP.m_xfmProj, pMat, &m_RefVP.m_xfmProj); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_PROJXFM; break; case D3DTRANSFORMSTATE_WORLD1_DX7: MatrixProduct(&(m_RefVP.m_xfmWorld[1]), pMat, &(m_RefVP.m_xfmWorld[1])); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD1XFM; break; case D3DTRANSFORMSTATE_WORLD2_DX7: MatrixProduct(&(m_RefVP.m_xfmWorld[2]), pMat, &(m_RefVP.m_xfmWorld[2])); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD2XFM; break; case D3DTRANSFORMSTATE_WORLD3_DX7: MatrixProduct(&(m_RefVP.m_xfmWorld[3]), pMat, &(m_RefVP.m_xfmWorld[3])); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD3XFM; break; case D3DTRANSFORMSTATE_TEXTURE0: case D3DTRANSFORMSTATE_TEXTURE1: case D3DTRANSFORMSTATE_TEXTURE2: case D3DTRANSFORMSTATE_TEXTURE3: case D3DTRANSFORMSTATE_TEXTURE4: case D3DTRANSFORMSTATE_TEXTURE5: case D3DTRANSFORMSTATE_TEXTURE6: case D3DTRANSFORMSTATE_TEXTURE7: MatrixProduct( &(m_RefVP.m_xfmTex[xfrmType - D3DTRANSFORMSTATE_TEXTURE0]), pMat, &(m_RefVP.m_xfmTex[xfrmType - D3DTRANSFORMSTATE_TEXTURE0]) ); break; default: DPFERR( "Ignoring unknown transform type" ); } } } return D3D_OK; } HRESULT RefDev::Dp2SetClipPlane(LPD3DHAL_DP2COMMAND pCmd) { WORD wNumClipPlanes = pCmd->wStateCount; LPD3DHAL_DP2SETCLIPPLANE pSetClipPlane = (LPD3DHAL_DP2SETCLIPPLANE)(pCmd + 1); for (int i = 0; i < (int) wNumClipPlanes; i++, pSetClipPlane++) { _ASSERTf( pSetClipPlane->dwIndex < RD_MAX_USER_CLIPPLANES, ("Refrast does not support %d clip planes", pSetClipPlane->dwIndex ) ); memcpy( &(m_Clipper.m_userClipPlanes[pSetClipPlane->dwIndex]), pSetClipPlane->plane, sizeof(RDVECTOR4) ); } return D3D_OK; } HRESULT RefDev::Dp2SetExtention(LPD3DHAL_DP2COMMAND pCmd) { return D3D_OK; } HRESULT RefDev::Dp2RecRenderStates(DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates ) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2RENDERSTATE); return RecordStates((PUINT8)pCmd, dwSize); } HRESULT RefDev::Dp2RecTextureStageState(DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd ) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2TEXTURESTAGESTATE); return RecordStates((PUINT8)pCmd, dwSize); } HRESULT RefDev::Dp2RecViewport(LPD3DHAL_DP2COMMAND pCmd) { return RecordLastState(pCmd, sizeof(D3DHAL_DP2VIEWPORTINFO)); } HRESULT RefDev::Dp2RecWRange(LPD3DHAL_DP2COMMAND pCmd) { return RecordLastState(pCmd, sizeof(D3DHAL_DP2WINFO)); } HRESULT RefDev::Dp2RecZRange(LPD3DHAL_DP2COMMAND pCmd) { return RecordLastState(pCmd, sizeof(D3DHAL_DP2ZRANGE)); } HRESULT RefDev::Dp2RecMaterial(LPD3DHAL_DP2COMMAND pCmd) { return RecordLastState(pCmd, sizeof(D3DHAL_DP2SETMATERIAL)); } HRESULT RefDev::Dp2RecCreateLight(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2CREATELIGHT); return RecordStates((PUINT8)pCmd, dwSize); } HRESULT RefDev::Dp2RecSetLight(LPD3DHAL_DP2COMMAND pCmd, LPDWORD pdwStride) { WORD wNumSetLight = pCmd->wStateCount; _ASSERT(pdwStride != NULL, "pdwStride is NULL" ); *pdwStride = sizeof(D3DHAL_DP2COMMAND); LPD3DHAL_DP2SETLIGHT pSetLight = (LPD3DHAL_DP2SETLIGHT)(pCmd + 1); for (int i = 0; i < wNumSetLight; i++) { DWORD dwStride = sizeof(D3DHAL_DP2SETLIGHT); switch (pSetLight->dwDataType) { case D3DHAL_SETLIGHT_ENABLE: break; case D3DHAL_SETLIGHT_DISABLE: break; case D3DHAL_SETLIGHT_DATA: dwStride += sizeof(D3DLIGHT7); break; } *pdwStride += dwStride; // Update the command buffer pointer pSetLight = (D3DHAL_DP2SETLIGHT *)((LPBYTE)pSetLight + dwStride); } return RecordStates((PUINT8)pCmd, *pdwStride); } HRESULT RefDev::Dp2RecTransform(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2SETTRANSFORM); return RecordStates((PUINT8)pCmd, dwSize); } HRESULT RefDev::Dp2RecExtention(LPD3DHAL_DP2COMMAND pCmd) { return D3D_OK; } HRESULT RefDev::Dp2RecClipPlane(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2SETCLIPPLANE); return RecordStates((PUINT8)pCmd, dwSize); } HRESULT RefDev::Dp2RecSetVertexShader(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2VERTEXSHADER); return RecordStates((PUINT8)pCmd, dwSize); } HRESULT RefDev::Dp2RecSetVertexShaderConsts( DWORD StartReg, DWORD dwCount, LPDWORD pData ) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + dwCount*4*sizeof(float); LPBYTE pBytes = new BYTE[dwSize]; if( pBytes == NULL ) return DDERR_OUTOFMEMORY; LPD3DHAL_DP2COMMAND pCmd = (LPD3DHAL_DP2COMMAND)pBytes; LPD3DHAL_DP2SETVERTEXSHADERCONST pSVC = (LPD3DHAL_DP2SETVERTEXSHADERCONST)(pCmd + 1); LPDWORD pStuff = (LPDWORD)(pSVC + 1); // Set up pCmd pCmd->bCommand = D3DDP2OP_SETVERTEXSHADERCONST; pCmd->wStateCount = 1; // Set up pSVC pSVC->dwRegister = StartReg; pSVC->dwCount = dwCount; // Copy the data memcpy( pStuff, pData, dwCount*4*sizeof(float)); HRESULT hr = RecordStates(pBytes, dwSize); delete [] pBytes; return hr; } HRESULT RefDev::Dp2RecSetPixelShader(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2PIXELSHADER); return RecordStates((PUINT8)pCmd, dwSize); } HRESULT RefDev::Dp2RecSetPixelShaderConsts( DWORD StartReg, DWORD dwCount, LPDWORD pData ) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + dwCount*4*sizeof(float); LPBYTE pBytes = new BYTE[dwSize]; if( pBytes == NULL ) return DDERR_OUTOFMEMORY; LPD3DHAL_DP2COMMAND pCmd = (LPD3DHAL_DP2COMMAND)pBytes; LPD3DHAL_DP2SETPIXELSHADERCONST pSVC = (LPD3DHAL_DP2SETPIXELSHADERCONST)(pCmd + 1); LPDWORD pStuff = (LPDWORD)(pSVC + 1); // Set up pCmd pCmd->bCommand = D3DDP2OP_SETPIXELSHADERCONST; pCmd->wStateCount = 1; // Set up pSVC pSVC->dwRegister = StartReg; pSVC->dwCount = dwCount; // Copy the data memcpy( pStuff, pData, dwCount*4*sizeof(float)); HRESULT hr = RecordStates(pBytes, dwSize); delete [] pBytes; return hr; } HRESULT RefDev::Dp2RecSetStreamSource(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2SETSTREAMSOURCE); return RecordStates((PUINT8)pCmd, dwSize); } HRESULT RefDev::Dp2RecSetIndices(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2SETINDICES); return RecordStates((PUINT8)pCmd, dwSize); } //----------------------------------------------------------------------------- // // RecordStates - This function copies the state data into the internal stateset // buffer. It assumes that the current state set has already been properly set // up in BeginStateSet(). // //----------------------------------------------------------------------------- HRESULT RefDev::RecordStates(PUINT8 pData, DWORD dwSize) { HRESULT ret; LPStateSetData pCurStateSets = m_pStateSets.CurrentItem(); DWORD dwCurIdx = pCurStateSets->CurrentIndex(); // Check if the buffer has enough space if( (ret = pCurStateSets->CheckAndGrow(dwCurIdx + dwSize, RD_STATESET_GROWDELTA)) != D3D_OK ) { return ret; } // Copy the data and update the ptr. PUINT8 pDest = (PUINT8)&((*pCurStateSets)[dwCurIdx]); memcpy(pDest, pData, dwSize); pCurStateSets->SetCurrentIndex(dwCurIdx + dwSize); return D3D_OK; } HRESULT RefDev::RecordLastState(LPD3DHAL_DP2COMMAND pCmd, DWORD dwUnitSize) { _ASSERT(pCmd->wStateCount != 0, "Number of states to record is zero" ); if( pCmd->wStateCount == 1 ) { return RecordStates((PUINT8)pCmd, sizeof(D3DHAL_DP2COMMAND) + dwUnitSize); } else { HRESULT ret; WORD wCount = pCmd->wStateCount; pCmd->wStateCount = 1; ret = RecordStates((PUINT8)pCmd, sizeof(D3DHAL_DP2COMMAND)); if( ret != D3D_OK ) { return ret; } ret = RecordStates((PUINT8)(pCmd + 1) + dwUnitSize * (wCount - 1), dwUnitSize); if( ret != D3D_OK ) { return ret; } pCmd->wStateCount = wCount; return D3D_OK; } } HRESULT RefDev::BeginStateSet(DWORD dwHandle) { HRESULT ret; // Grow the array if no more space left if( (ret = m_pStateSets.CheckAndGrow(dwHandle)) != D3D_OK ) { return ret; } _ASSERT(m_pStateSets[dwHandle] == NULL, "pStateSets array is NULL" ); // Create the new StateSet LPStateSetData pNewStateSet = new StateSetData; if( pNewStateSet == NULL ) { return DDERR_OUTOFMEMORY; } m_pStateSets.SetCurrentIndex(dwHandle); m_pStateSets.SetCurrentItem(pNewStateSet); // Switch to record mode SetRecStateFunctions(); return D3D_OK; } HRESULT RefDev::EndStateSet(void) { // Switch to execute mode SetSetStateFunctions(); return D3D_OK; } HRESULT RefDev::ExecuteStateSet(DWORD dwHandle) { HRESULT ret; if( (ret = m_pStateSets.CheckRange(dwHandle)) != D3D_OK ) { return ret; } LPStateSetData pStateSet = m_pStateSets[dwHandle]; if( pStateSet == NULL ) { return DDERR_INVALIDPARAMS; } LPD3DHAL_DP2COMMAND pCmd = (LPD3DHAL_DP2COMMAND)&((*pStateSet)[0]); UINT_PTR CmdBoundary = (UINT_PTR)pCmd + pStateSet->CurrentIndex(); // Loop through the data, update render states for (;;) { ret = DrawPrimitives2( NULL, (UINT16)0, (DWORD)0, 0, &pCmd, NULL ); if( ret != D3D_OK ) { return ret; } if( (UINT_PTR)pCmd >= CmdBoundary ) break; } return D3D_OK; } HRESULT RefDev::DeleteStateSet(DWORD dwHandle) { HRESULT ret; if( (ret = m_pStateSets.CheckRange(dwHandle)) != D3D_OK ) { return ret; } if( m_pStateSets[dwHandle] != NULL ) { delete m_pStateSets[dwHandle]; m_pStateSets[dwHandle] = NULL; } return D3D_OK; } HRESULT RefDev::CaptureStateSet(DWORD dwHandle) { HRESULT ret; if( (ret = m_pStateSets.CheckRange(dwHandle)) != D3D_OK ) { return ret; } LPStateSetData pStateSet = m_pStateSets[dwHandle]; if( pStateSet == NULL ) { return DDERR_INVALIDPARAMS; } BYTE *p = &((*pStateSet)[0]); UINT_PTR pEnd = (UINT_PTR)(p + pStateSet->CurrentIndex()); while((UINT_PTR)p < pEnd) { LPD3DHAL_DP2COMMAND pCmd = (LPD3DHAL_DP2COMMAND)p; p += sizeof(D3DHAL_DP2COMMAND); switch(pCmd->bCommand) { case D3DDP2OP_RENDERSTATE: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2RENDERSTATE pData = (LPD3DHAL_DP2RENDERSTATE)p; pData->dwState = GetRS()[pData->RenderState]; p += sizeof(D3DHAL_DP2RENDERSTATE); } break; } case D3DDP2OP_SETLIGHT: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETLIGHT pData = (LPD3DHAL_DP2SETLIGHT)p; p += sizeof(D3DHAL_DP2SETLIGHT); if( !m_RefVP.m_LightArray.IsValidIndex( pData->dwIndex ) ) { DPFERR( "The light index in capture is invalid\n" ); return D3DERR_INVALIDCALL; } switch (pData->dwDataType) { case D3DHAL_SETLIGHT_ENABLE: if(!m_RefVP.m_LightArray[pData->dwIndex].IsEnabled()) pData->dwDataType = D3DHAL_SETLIGHT_DISABLE; break; case D3DHAL_SETLIGHT_DISABLE: if(m_RefVP.m_LightArray[pData->dwIndex].IsEnabled()) pData->dwDataType = D3DHAL_SETLIGHT_ENABLE; break; case D3DHAL_SETLIGHT_DATA: m_RefVP.m_LightArray[pData->dwIndex].GetLight((LPD3DLIGHT7)p); p += sizeof(D3DLIGHT7); break; } } break; } case D3DDP2OP_SETMATERIAL: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETMATERIAL pData = (LPD3DHAL_DP2SETMATERIAL)p; *pData = m_RefVP.m_Material; p += sizeof(D3DHAL_DP2SETMATERIAL); } break; } case D3DDP2OP_SETTRANSFORM: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETTRANSFORM pData = (LPD3DHAL_DP2SETTRANSFORM)p; switch(pData->xfrmType) { case D3DTRANSFORMSTATE_WORLD: pData->matrix = m_RefVP.m_xfmWorld[0]; break; case D3DTRANSFORMSTATE_WORLD1: pData->matrix = m_RefVP.m_xfmWorld[1]; break; case D3DTRANSFORMSTATE_WORLD2: pData->matrix = m_RefVP.m_xfmWorld[2]; break; case D3DTRANSFORMSTATE_WORLD3: pData->matrix = m_RefVP.m_xfmWorld[3]; break; case D3DTRANSFORMSTATE_VIEW: pData->matrix = m_RefVP.m_xfmView; break; case D3DTRANSFORMSTATE_PROJECTION: pData->matrix = m_RefVP.m_xfmProj; break; case D3DTRANSFORMSTATE_TEXTURE0: case D3DTRANSFORMSTATE_TEXTURE1: case D3DTRANSFORMSTATE_TEXTURE2: case D3DTRANSFORMSTATE_TEXTURE3: case D3DTRANSFORMSTATE_TEXTURE4: case D3DTRANSFORMSTATE_TEXTURE5: case D3DTRANSFORMSTATE_TEXTURE6: case D3DTRANSFORMSTATE_TEXTURE7: pData->matrix = m_RefVP.m_xfmTex[pData->xfrmType - D3DTRANSFORMSTATE_TEXTURE0]; break; default: if( ((DWORD)pData->xfrmType >= RD_WORLDMATRIXBASE) && ((DWORD)pData->xfrmType < (RD_WORLDMATRIXBASE + RD_MAX_WORLD_MATRICES)) ) { pData->matrix = m_RefVP.m_xfmWorld[ (DWORD)pData->xfrmType - RD_WORLDMATRIXBASE]; } else { DPFERR( "Ignoring unknown transform type" ); return D3DERR_INVALIDCALL; } break; } p += sizeof(D3DHAL_DP2SETTRANSFORM); } break; } case D3DDP2OP_TEXTURESTAGESTATE: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p; pData->dwValue = m_TextureStageState[pData->wStage].m_dwVal[pData->TSState]; p += sizeof(D3DHAL_DP2TEXTURESTAGESTATE); } break; } case D3DDP2OP_VIEWPORTINFO: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { D3DVIEWPORT7 viewport; LPD3DHAL_DP2VIEWPORTINFO lpVwpData = (LPD3DHAL_DP2VIEWPORTINFO)p; D3DVIEWPORT7& vp = m_Clipper.m_Viewport; lpVwpData->dwX = vp.dwX; lpVwpData->dwY = vp.dwY; lpVwpData->dwWidth = vp.dwWidth; lpVwpData->dwHeight = vp.dwHeight; p += sizeof(D3DHAL_DP2VIEWPORTINFO); } break; } case D3DDP2OP_ZRANGE: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2ZRANGE pData = (LPD3DHAL_DP2ZRANGE)p; D3DVIEWPORT7& vp = m_Clipper.m_Viewport; pData->dvMinZ = vp.dvMinZ; pData->dvMaxZ = vp.dvMaxZ; p += sizeof(D3DHAL_DP2ZRANGE); } break; } case D3DDP2OP_SETCLIPPLANE: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETCLIPPLANE pData = (LPD3DHAL_DP2SETCLIPPLANE)p; *((RDVECTOR4 *)pData->plane) = m_Clipper.m_userClipPlanes[pData->dwIndex]; p += sizeof(D3DHAL_DP2SETCLIPPLANE); } break; } case D3DDP2OP_SETVERTEXSHADER: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2VERTEXSHADER pData = (LPD3DHAL_DP2VERTEXSHADER)p; pData->dwHandle = m_CurrentVShaderHandle; p += sizeof(D3DHAL_DP2VERTEXSHADER); } break; } case D3DDP2OP_SETVERTEXSHADERCONST: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETVERTEXSHADERCONST pData = (LPD3DHAL_DP2SETVERTEXSHADERCONST)p; m_RefVM.GetData( D3DSPR_CONST, pData->dwRegister, pData->dwCount, (LPVOID)(pData+1) ); p += (sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + (pData->dwCount<<4)); } break; } case D3DDP2OP_SETSTREAMSOURCE: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETSTREAMSOURCE pData = (LPD3DHAL_DP2SETSTREAMSOURCE)p; pData->dwVBHandle = m_VStream[pData->dwStream].m_dwHandle; pData->dwStride = m_VStream[pData->dwStream].m_dwStride; p += sizeof(D3DHAL_DP2SETSTREAMSOURCE); } break; } case D3DDP2OP_SETINDICES: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETINDICES pData = (LPD3DHAL_DP2SETINDICES)p; pData->dwVBHandle = m_IndexStream.m_dwHandle; pData->dwStride = m_IndexStream.m_dwStride; p += sizeof(D3DHAL_DP2SETINDICES); } break; } case D3DDP2OP_SETPIXELSHADER: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2PIXELSHADER pData = (LPD3DHAL_DP2PIXELSHADER)p; pData->dwHandle = m_CurrentPShaderHandle; p += sizeof(D3DHAL_DP2PIXELSHADER); } break; } case D3DDP2OP_SETPIXELSHADERCONST: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETPIXELSHADERCONST pData = (LPD3DHAL_DP2SETPIXELSHADERCONST)p; FLOAT* pfData = (FLOAT*)(pData+1); for (UINT iR=pData->dwRegister; iRdwCount; iR++) { *(pfData+0) = m_Rast.m_ConstReg[iR][0][0]; *(pfData+1) = m_Rast.m_ConstReg[iR][0][1]; *(pfData+2) = m_Rast.m_ConstReg[iR][0][2]; *(pfData+3) = m_Rast.m_ConstReg[iR][0][3]; pfData += 4; } p += (sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + (pData->dwCount<<4)); } break; } default: _ASSERT(FALSE, "Ununderstood DP2 command in Capture"); } } return D3D_OK; } HRESULT RefDev::CreateStateSet(DWORD dwHandle, D3DSTATEBLOCKTYPE sbType) { HRESULT hr = S_OK; // This DDI should be called only for drivers > DX7 // and only for those which support TLHals. // It is called only when the device created is a pure-device // We need to add filtering code in DX9 to make the DDI emulation // work. _ASSERT( m_dwDDIType > RDDDI_DX8HAL, "This DDI should be called only" " for DX8TL\n" ); // Begin a new stateset if( FAILED( hr = BeginStateSet( dwHandle ) ) ) { DPFERR( "CreateStateSet: Begin failed\n" ); return hr; } switch( sbType ) { case D3DSBT_VERTEXSTATE: hr = RecordVertexState( dwHandle ); if( FAILED( hr ) ) { DPFERR( "RecordVertexState failed\n" ); } break; case D3DSBT_PIXELSTATE: hr = RecordPixelState( dwHandle ); if( FAILED( hr ) ) { DPFERR( "RecordPixelState failed\n" ); } break; case D3DSBT_ALL: hr = RecordAllState( dwHandle ); if( FAILED( hr ) ) { DPFERR( "RecordAllState failed\n" ); } break; default: DPFERR( "Unknown StateBlock type for Creation\n" ); hr = D3DERR_INVALIDCALL; } EndStateSet(); return hr; } HRESULT RefDev::RecordAllState( DWORD dwHandle ) { DWORD data_size = 0; DWORD i = 0; DWORD j = 0; GArrayT data; LPD3DHAL_DP2COMMAND pCmd = NULL; HRESULT hr = S_OK; static D3DRENDERSTATETYPE rstates[] = { D3DRENDERSTATE_SPECULARENABLE, D3DRENDERSTATE_ZENABLE, D3DRENDERSTATE_FILLMODE, D3DRENDERSTATE_SHADEMODE, D3DRENDERSTATE_LINEPATTERN, D3DRENDERSTATE_ZWRITEENABLE, D3DRENDERSTATE_ALPHATESTENABLE, D3DRENDERSTATE_LASTPIXEL, D3DRENDERSTATE_SRCBLEND, D3DRENDERSTATE_DESTBLEND, D3DRENDERSTATE_CULLMODE, D3DRENDERSTATE_ZFUNC, D3DRENDERSTATE_ALPHAREF, D3DRENDERSTATE_ALPHAFUNC, D3DRENDERSTATE_DITHERENABLE, D3DRENDERSTATE_FOGENABLE, D3DRENDERSTATE_STIPPLEDALPHA, D3DRENDERSTATE_FOGCOLOR, D3DRENDERSTATE_FOGTABLEMODE, D3DRENDERSTATE_FOGSTART, D3DRENDERSTATE_FOGEND, D3DRENDERSTATE_FOGDENSITY, D3DRENDERSTATE_EDGEANTIALIAS, D3DRENDERSTATE_ALPHABLENDENABLE, D3DRENDERSTATE_ZBIAS, D3DRENDERSTATE_RANGEFOGENABLE, D3DRENDERSTATE_STENCILENABLE, D3DRENDERSTATE_STENCILFAIL, D3DRENDERSTATE_STENCILZFAIL, D3DRENDERSTATE_STENCILPASS, D3DRENDERSTATE_STENCILFUNC, D3DRENDERSTATE_STENCILREF, D3DRENDERSTATE_STENCILMASK, D3DRENDERSTATE_STENCILWRITEMASK, D3DRENDERSTATE_TEXTUREFACTOR, D3DRENDERSTATE_WRAP0, D3DRENDERSTATE_WRAP1, D3DRENDERSTATE_WRAP2, D3DRENDERSTATE_WRAP3, D3DRENDERSTATE_WRAP4, D3DRENDERSTATE_WRAP5, D3DRENDERSTATE_WRAP6, D3DRENDERSTATE_WRAP7, D3DRENDERSTATE_AMBIENT, D3DRENDERSTATE_COLORVERTEX, D3DRENDERSTATE_FOGVERTEXMODE, D3DRENDERSTATE_CLIPPING, D3DRENDERSTATE_LIGHTING, D3DRENDERSTATE_NORMALIZENORMALS, D3DRENDERSTATE_LOCALVIEWER, D3DRENDERSTATE_EMISSIVEMATERIALSOURCE, D3DRENDERSTATE_AMBIENTMATERIALSOURCE, D3DRENDERSTATE_DIFFUSEMATERIALSOURCE, D3DRENDERSTATE_SPECULARMATERIALSOURCE, D3DRENDERSTATE_VERTEXBLEND, D3DRENDERSTATE_CLIPPLANEENABLE, D3DRS_SOFTWAREVERTEXPROCESSING, D3DRS_POINTSIZE, D3DRS_POINTSIZE_MIN, D3DRS_POINTSPRITEENABLE, D3DRS_POINTSCALEENABLE, D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, D3DRS_POINTSCALE_C, D3DRS_MULTISAMPLEANTIALIAS, D3DRS_MULTISAMPLEMASK, D3DRS_PATCHEDGESTYLE, D3DRS_PATCHSEGMENTS, D3DRS_POINTSIZE_MAX, D3DRS_INDEXEDVERTEXBLENDENABLE, D3DRS_COLORWRITEENABLE, D3DRS_TWEENFACTOR, D3DRS_BLENDOP, }; static D3DTEXTURESTAGESTATETYPE tsstates[] = { D3DTSS_COLOROP, D3DTSS_COLORARG1, D3DTSS_COLORARG2, D3DTSS_ALPHAOP, D3DTSS_ALPHAARG1, D3DTSS_ALPHAARG2, D3DTSS_BUMPENVMAT00, D3DTSS_BUMPENVMAT01, D3DTSS_BUMPENVMAT10, D3DTSS_BUMPENVMAT11, D3DTSS_TEXCOORDINDEX, D3DTSS_ADDRESSU, D3DTSS_ADDRESSV, D3DTSS_BORDERCOLOR, D3DTSS_MAGFILTER, D3DTSS_MINFILTER, D3DTSS_MIPFILTER, D3DTSS_MIPMAPLODBIAS, D3DTSS_MAXMIPLEVEL, D3DTSS_MAXANISOTROPY, D3DTSS_BUMPENVLSCALE, D3DTSS_BUMPENVLOFFSET, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTSS_ADDRESSW, D3DTSS_COLORARG0, D3DTSS_ALPHAARG0, D3DTSS_RESULTARG, }; // // !!! Dont Capture vertex streams !!! // !!! Dont Capture index streams !!! // !!! Dont Capture textures !!! // // // Capture render-states // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2RENDERSTATE) * sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); pCmd->bCommand = D3DDP2OP_RENDERSTATE; D3DHAL_DP2RENDERSTATE* pRS = (D3DHAL_DP2RENDERSTATE*)(pCmd + 1); for( i = 0; i < sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); ++i) { pRS->RenderState = rstates[i]; pRS->dwState = GetRS()[rstates[i]]; pRS++; } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture texture-stage-states // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2TEXTURESTAGESTATE) * sizeof(tsstates)/sizeof(D3DTEXTURESTAGESTATETYPE) * D3DHAL_TSS_MAXSTAGES; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = sizeof(tsstates)/sizeof(D3DTEXTURESTAGESTATETYPE) * D3DHAL_TSS_MAXSTAGES; pCmd->bCommand = D3DDP2OP_TEXTURESTAGESTATE; D3DHAL_DP2TEXTURESTAGESTATE* pTSS = (D3DHAL_DP2TEXTURESTAGESTATE*)(pCmd+1); for ( i = 0; i < D3DHAL_TSS_MAXSTAGES; i++ ) { for( DWORD j = 0; j < sizeof(tsstates)/ sizeof(D3DTEXTURESTAGESTATETYPE); ++j) { pTSS->wStage = i; pTSS->TSState = tsstates[j]; pTSS->dwValue = GetTSS( i )[tsstates[j]]; pTSS++; } } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture viewport // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2VIEWPORTINFO); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_VIEWPORTINFO; D3DHAL_DP2VIEWPORTINFO* pVP = (D3DHAL_DP2VIEWPORTINFO*)(pCmd+1); pVP->dwX = m_Clipper.m_Viewport.dwX; pVP->dwY = m_Clipper.m_Viewport.dwY; pVP->dwWidth = m_Clipper.m_Viewport.dwWidth; pVP->dwHeight = m_Clipper.m_Viewport.dwHeight; HR_RET(RecordStates( (PUINT8)pCmd, data_size )); data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2ZRANGE); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_ZRANGE; D3DHAL_DP2ZRANGE* pZR = (D3DHAL_DP2ZRANGE*)(pCmd+1); D3DVIEWPORT7& vp = m_Clipper.m_Viewport; pZR->dvMinZ = m_Clipper.m_Viewport.dvMinZ; pZR->dvMaxZ = m_Clipper.m_Viewport.dvMaxZ; HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture transforms // // All the world-matrices, view, projection and the texture matrices // (one per stage) data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETTRANSFORM) * (RD_MAX_WORLD_MATRICES + D3DHAL_TSS_MAXSTAGES + 2); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = RD_MAX_WORLD_MATRICES + D3DHAL_TSS_MAXSTAGES + 2; pCmd->bCommand = D3DDP2OP_SETTRANSFORM; D3DHAL_DP2SETTRANSFORM* pST = (D3DHAL_DP2SETTRANSFORM*)(pCmd+1); for( i = 0; i < RD_MAX_WORLD_MATRICES; i++ ) { pST->xfrmType = (D3DTRANSFORMSTATETYPE)(RD_WORLDMATRIXBASE + i); pST->matrix = m_RefVP.m_xfmWorld[i]; pST++; } // View Matrix pST->xfrmType = D3DTRANSFORMSTATE_VIEW; pST->matrix = m_RefVP.m_xfmView; pST++; // Projection Matrix pST->xfrmType = D3DTRANSFORMSTATE_PROJECTION; pST->matrix = m_RefVP.m_xfmProj; pST++; // Texture Matrices for( i = 0; i < D3DHAL_TSS_MAXSTAGES; i++ ) { pST->xfrmType = (D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0 + i); pST->matrix = m_RefVP.m_xfmTex[i]; pST++; } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture clip-planes // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETCLIPPLANE) * RD_MAX_USER_CLIPPLANES; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = RD_MAX_USER_CLIPPLANES; pCmd->bCommand = D3DDP2OP_SETCLIPPLANE; D3DHAL_DP2SETCLIPPLANE* pSCP = (D3DHAL_DP2SETCLIPPLANE*)(pCmd+1); for( i = 0; i < RD_MAX_USER_CLIPPLANES; i++ ) { pSCP->dwIndex = i; for( j=0; j<4; j++ ) pSCP->plane[j] = m_Clipper.m_userClipPlanes[i].v[j]; pSCP++; } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture material // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETMATERIAL); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETMATERIAL; D3DHAL_DP2SETMATERIAL* pSM = (D3DHAL_DP2SETMATERIAL*)(pCmd+1); *pSM = m_RefVP.m_Material; HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture lights // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DLIGHT7) + sizeof(D3DHAL_DP2SETLIGHT)*2; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 2; pCmd->bCommand = D3DDP2OP_SETLIGHT; D3DHAL_DP2SETLIGHT* pSL = (D3DHAL_DP2SETLIGHT *)(pCmd + 1); D3DHAL_DP2SETLIGHT* pSL2 = pSL + 1; pSL2->dwDataType = D3DHAL_SETLIGHT_DATA; for( i = 0; i < m_RefVP.m_LightArray.GetSize(); i++ ) { if( m_RefVP.m_LightArray[i].IsRefered() ) { pSL2->dwIndex = pSL->dwIndex = i; if( m_RefVP.m_LightArray[i].IsEnabled() ) { pSL->dwDataType = D3DHAL_SETLIGHT_ENABLE; } else { pSL->dwDataType = D3DHAL_SETLIGHT_DISABLE; } m_RefVP.m_LightArray[i].GetLight((D3DLIGHT7*)(pSL2 + 1)); HR_RET(RecordStates( (PUINT8)pCmd, data_size )); } } // // Capture current vertex shader // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2VERTEXSHADER); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETVERTEXSHADER; D3DHAL_DP2VERTEXSHADER* pVS = (D3DHAL_DP2VERTEXSHADER*)(pCmd+1); pVS->dwHandle = m_CurrentVShaderHandle; HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture current pixel shader // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2PIXELSHADER); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETPIXELSHADER; D3DHAL_DP2PIXELSHADER* pPS = (D3DHAL_DP2PIXELSHADER*)(pCmd+1); pPS->dwHandle = m_CurrentPShaderHandle; HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture vertex shader constants // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + (RD_MAX_NUMCONSTREG << 4); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETVERTEXSHADERCONST; D3DHAL_DP2SETVERTEXSHADERCONST* pVSC = (D3DHAL_DP2SETVERTEXSHADERCONST*)(pCmd+1); pVSC->dwRegister = 0; pVSC->dwCount = RD_MAX_NUMCONSTREG; m_RefVM.GetData( D3DSPR_CONST, pVSC->dwRegister, pVSC->dwCount, (LPVOID)(pVSC+1) ); HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture pixel shader constants // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + (RDPS_MAX_NUMCONSTREG << 4); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETPIXELSHADERCONST; D3DHAL_DP2SETPIXELSHADERCONST* pPSC = (D3DHAL_DP2SETPIXELSHADERCONST*)(pCmd+1); pPSC->dwRegister = 0; pPSC->dwCount = RDPS_MAX_NUMCONSTREG; FLOAT* pfData = (FLOAT*)(pPSC+1); for (UINT iR=pPSC->dwRegister; iRdwCount; iR++) { *(pfData+0) = m_Rast.m_ConstReg[iR][0][0]; *(pfData+1) = m_Rast.m_ConstReg[iR][0][1]; *(pfData+2) = m_Rast.m_ConstReg[iR][0][2]; *(pfData+3) = m_Rast.m_ConstReg[iR][0][3]; pfData += 4; } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); return hr; } HRESULT RefDev::RecordVertexState( DWORD dwHandle ) { DWORD data_size = 0; DWORD i = 0; DWORD j = 0; GArrayT data; LPD3DHAL_DP2COMMAND pCmd = NULL; HRESULT hr = S_OK; static D3DRENDERSTATETYPE rstates[] = { D3DRENDERSTATE_SHADEMODE, D3DRENDERSTATE_SPECULARENABLE, D3DRENDERSTATE_CULLMODE, D3DRENDERSTATE_FOGENABLE, D3DRENDERSTATE_FOGCOLOR, D3DRENDERSTATE_FOGTABLEMODE, D3DRENDERSTATE_FOGSTART, D3DRENDERSTATE_FOGEND, D3DRENDERSTATE_FOGDENSITY, D3DRENDERSTATE_RANGEFOGENABLE, D3DRENDERSTATE_AMBIENT, D3DRENDERSTATE_COLORVERTEX, D3DRENDERSTATE_FOGVERTEXMODE, D3DRENDERSTATE_CLIPPING, D3DRENDERSTATE_LIGHTING, D3DRENDERSTATE_NORMALIZENORMALS, D3DRENDERSTATE_LOCALVIEWER, D3DRENDERSTATE_EMISSIVEMATERIALSOURCE, D3DRENDERSTATE_AMBIENTMATERIALSOURCE, D3DRENDERSTATE_DIFFUSEMATERIALSOURCE, D3DRENDERSTATE_SPECULARMATERIALSOURCE, D3DRENDERSTATE_VERTEXBLEND, D3DRENDERSTATE_CLIPPLANEENABLE, D3DRS_SOFTWAREVERTEXPROCESSING, D3DRS_POINTSIZE, D3DRS_POINTSIZE_MIN, D3DRS_POINTSPRITEENABLE, D3DRS_POINTSCALEENABLE, D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, D3DRS_POINTSCALE_C, D3DRS_MULTISAMPLEANTIALIAS, D3DRS_MULTISAMPLEMASK, D3DRS_PATCHEDGESTYLE, D3DRS_PATCHSEGMENTS, D3DRS_POINTSIZE_MAX, D3DRS_INDEXEDVERTEXBLENDENABLE, D3DRS_TWEENFACTOR, }; static D3DTEXTURESTAGESTATETYPE tsstates[] = { D3DTSS_TEXCOORDINDEX, D3DTSS_TEXTURETRANSFORMFLAGS }; // // Capture render-states // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2RENDERSTATE) * sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); pCmd->bCommand = D3DDP2OP_RENDERSTATE; D3DHAL_DP2RENDERSTATE* pRS = (D3DHAL_DP2RENDERSTATE*)(pCmd + 1); for( i = 0; i < sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); ++i) { pRS->RenderState = rstates[i]; pRS->dwState = GetRS()[rstates[i]]; pRS++; } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture texture-stage-states // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2TEXTURESTAGESTATE) * sizeof(tsstates)/sizeof(D3DTEXTURESTAGESTATETYPE) * D3DHAL_TSS_MAXSTAGES; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = sizeof(tsstates)/sizeof(D3DTEXTURESTAGESTATETYPE) * D3DHAL_TSS_MAXSTAGES; pCmd->bCommand = D3DDP2OP_TEXTURESTAGESTATE; D3DHAL_DP2TEXTURESTAGESTATE* pTSS = (D3DHAL_DP2TEXTURESTAGESTATE*)(pCmd+1); for ( i = 0; i < D3DHAL_TSS_MAXSTAGES; i++ ) { for( DWORD j = 0; j < sizeof(tsstates)/ sizeof(D3DTEXTURESTAGESTATETYPE); ++j) { pTSS->wStage = i; pTSS->TSState = tsstates[j]; pTSS->dwValue = GetTSS( i )[tsstates[j]]; pTSS++; } } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture lights // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DLIGHT7) + sizeof(D3DHAL_DP2SETLIGHT)*2; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 2; pCmd->bCommand = D3DDP2OP_SETLIGHT; D3DHAL_DP2SETLIGHT* pSL = (D3DHAL_DP2SETLIGHT *)(pCmd + 1); D3DHAL_DP2SETLIGHT* pSL2 = pSL + 1; pSL2->dwDataType = D3DHAL_SETLIGHT_DATA; for( i = 0; i < m_RefVP.m_LightArray.GetSize(); i++ ) { if( m_RefVP.m_LightArray[i].IsRefered() ) { pSL2->dwIndex = pSL->dwIndex = i; if( m_RefVP.m_LightArray[i].IsEnabled() ) { pSL->dwDataType = D3DHAL_SETLIGHT_ENABLE; } else { pSL->dwDataType = D3DHAL_SETLIGHT_DISABLE; } m_RefVP.m_LightArray[i].GetLight((D3DLIGHT7*)(pSL2 + 1)); HR_RET(RecordStates( (PUINT8)pCmd, data_size )); } } // // Capture vertex shader constants // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + (RD_MAX_NUMCONSTREG << 4); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETVERTEXSHADERCONST; D3DHAL_DP2SETVERTEXSHADERCONST* pVSC = (D3DHAL_DP2SETVERTEXSHADERCONST*)(pCmd+1); pVSC->dwRegister = 0; pVSC->dwCount = RD_MAX_NUMCONSTREG; m_RefVM.GetData( D3DSPR_CONST, pVSC->dwRegister, pVSC->dwCount, (LPVOID)(pVSC+1) ); HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture current vertex shader // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2VERTEXSHADER); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETVERTEXSHADER; D3DHAL_DP2VERTEXSHADER* pVS = (D3DHAL_DP2VERTEXSHADER*)(pCmd+1); pVS->dwHandle = m_CurrentVShaderHandle; HR_RET(RecordStates( (PUINT8)pCmd, data_size )); return hr; } HRESULT RefDev::RecordPixelState( DWORD dwHandle ) { DWORD data_size = 0; DWORD i = 0; DWORD j = 0; GArrayT data; LPD3DHAL_DP2COMMAND pCmd = NULL; HRESULT hr = S_OK; static D3DRENDERSTATETYPE rstates[] = { D3DRENDERSTATE_ZENABLE, D3DRENDERSTATE_FILLMODE, D3DRENDERSTATE_SHADEMODE, D3DRENDERSTATE_LINEPATTERN, D3DRENDERSTATE_ZWRITEENABLE, D3DRENDERSTATE_ALPHATESTENABLE, D3DRENDERSTATE_LASTPIXEL, D3DRENDERSTATE_SRCBLEND, D3DRENDERSTATE_DESTBLEND, D3DRENDERSTATE_ZFUNC, D3DRENDERSTATE_ALPHAREF, D3DRENDERSTATE_ALPHAFUNC, D3DRENDERSTATE_DITHERENABLE, D3DRENDERSTATE_STIPPLEDALPHA, D3DRENDERSTATE_FOGSTART, D3DRENDERSTATE_FOGEND, D3DRENDERSTATE_FOGDENSITY, D3DRENDERSTATE_EDGEANTIALIAS, D3DRENDERSTATE_ALPHABLENDENABLE, D3DRENDERSTATE_ZBIAS, D3DRENDERSTATE_STENCILENABLE, D3DRENDERSTATE_STENCILFAIL, D3DRENDERSTATE_STENCILZFAIL, D3DRENDERSTATE_STENCILPASS, D3DRENDERSTATE_STENCILFUNC, D3DRENDERSTATE_STENCILREF, D3DRENDERSTATE_STENCILMASK, D3DRENDERSTATE_STENCILWRITEMASK, D3DRENDERSTATE_TEXTUREFACTOR, D3DRENDERSTATE_WRAP0, D3DRENDERSTATE_WRAP1, D3DRENDERSTATE_WRAP2, D3DRENDERSTATE_WRAP3, D3DRENDERSTATE_WRAP4, D3DRENDERSTATE_WRAP5, D3DRENDERSTATE_WRAP6, D3DRENDERSTATE_WRAP7, D3DRS_COLORWRITEENABLE, D3DRS_BLENDOP, }; static D3DTEXTURESTAGESTATETYPE tsstates[] = { D3DTSS_COLOROP, D3DTSS_COLORARG1, D3DTSS_COLORARG2, D3DTSS_ALPHAOP, D3DTSS_ALPHAARG1, D3DTSS_ALPHAARG2, D3DTSS_BUMPENVMAT00, D3DTSS_BUMPENVMAT01, D3DTSS_BUMPENVMAT10, D3DTSS_BUMPENVMAT11, D3DTSS_TEXCOORDINDEX, D3DTSS_ADDRESSU, D3DTSS_ADDRESSV, D3DTSS_BORDERCOLOR, D3DTSS_MAGFILTER, D3DTSS_MINFILTER, D3DTSS_MIPFILTER, D3DTSS_MIPMAPLODBIAS, D3DTSS_MAXMIPLEVEL, D3DTSS_MAXANISOTROPY, D3DTSS_BUMPENVLSCALE, D3DTSS_BUMPENVLOFFSET, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTSS_ADDRESSW, D3DTSS_COLORARG0, D3DTSS_ALPHAARG0, D3DTSS_RESULTARG, }; // // Capture render-states // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2RENDERSTATE) * sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); pCmd->bCommand = D3DDP2OP_RENDERSTATE; D3DHAL_DP2RENDERSTATE* pRS = (D3DHAL_DP2RENDERSTATE*)(pCmd + 1); for( i = 0; i < sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); ++i) { pRS->RenderState = rstates[i]; pRS->dwState = GetRS()[rstates[i]]; pRS++; } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture texture-stage-states // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2TEXTURESTAGESTATE) * sizeof(tsstates)/sizeof(D3DTEXTURESTAGESTATETYPE) * D3DHAL_TSS_MAXSTAGES; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = sizeof(tsstates)/sizeof(D3DTEXTURESTAGESTATETYPE) * D3DHAL_TSS_MAXSTAGES; pCmd->bCommand = D3DDP2OP_TEXTURESTAGESTATE; D3DHAL_DP2TEXTURESTAGESTATE* pTSS = (D3DHAL_DP2TEXTURESTAGESTATE*)(pCmd+1); for ( i = 0; i < D3DHAL_TSS_MAXSTAGES; i++ ) { for( DWORD j = 0; j < sizeof(tsstates)/ sizeof(D3DTEXTURESTAGESTATETYPE); ++j) { pTSS->wStage = i; pTSS->TSState = tsstates[j]; pTSS->dwValue = GetTSS( i )[tsstates[j]]; pTSS++; } } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture pixel shader constants // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + (RDPS_MAX_NUMCONSTREG << 4); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETPIXELSHADERCONST; D3DHAL_DP2SETPIXELSHADERCONST* pPSC = (D3DHAL_DP2SETPIXELSHADERCONST*)(pCmd+1); pPSC->dwRegister = 0; pPSC->dwCount = RDPS_MAX_NUMCONSTREG; FLOAT* pfData = (FLOAT*)(pPSC+1); for (UINT iR=pPSC->dwRegister; iRdwCount; iR++) { *(pfData+0) = m_Rast.m_ConstReg[iR][0][0]; *(pfData+1) = m_Rast.m_ConstReg[iR][0][1]; *(pfData+2) = m_Rast.m_ConstReg[iR][0][2]; *(pfData+3) = m_Rast.m_ConstReg[iR][0][3]; pfData += 4; } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); // // Capture current pixel shader // data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2PIXELSHADER); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETPIXELSHADER; D3DHAL_DP2PIXELSHADER* pPS = (D3DHAL_DP2PIXELSHADER*)(pCmd+1); pPS->dwHandle = m_CurrentPShaderHandle; HR_RET(RecordStates( (PUINT8)pCmd, data_size )); return hr; } //----------------------------------------------------------------------------- // // SetRenderState - // //----------------------------------------------------------------------------- void RefDev::SetRenderState( DWORD dwState, DWORD dwValue ) { // check for range before continuing if( dwState >= D3DHAL_MAX_RSTATES ) { return; } // set value in internal object m_dwRenderState[dwState] = dwValue; if( m_pDbgMon ) m_pDbgMon->StateChanged( D3DDM_SC_DEVICESTATE ); // do special validation work for some render states switch ( dwState ) { case D3DRS_DEBUGMONITORTOKEN: if( m_pDbgMon ) m_pDbgMon->NextEvent( D3DDM_EVENT_RSTOKEN ); break; case D3DRENDERSTATE_ZENABLE: if( dwValue ) m_Clipper.m_dwFlags |= RefClipper::RCLIP_Z_ENABLE; else m_Clipper.m_dwFlags &= ~RefClipper::RCLIP_Z_ENABLE; break; case D3DRENDERSTATE_LIGHTING: if( dwValue ) m_RefVP.m_dwTLState |= RDPV_DOLIGHTING; else m_RefVP.m_dwTLState &= ~RDPV_DOLIGHTING; break; case D3DRS_INDEXEDVERTEXBLENDENABLE: if( dwValue ) m_RefVP.m_dwTLState |= RDPV_DOINDEXEDVERTEXBLEND; else m_RefVP.m_dwTLState &= ~RDPV_DOINDEXEDVERTEXBLEND; break; case D3DRENDERSTATE_CLIPPING: if( dwValue ) m_RefVP.m_dwTLState |= RDPV_DOCLIPPING; else m_RefVP.m_dwTLState &= ~RDPV_DOCLIPPING; break; case D3DRENDERSTATE_SHADEMODE: { if( dwValue == D3DSHADE_FLAT ) m_Clipper.m_dwFlags |= RefClipper::RCLIP_DO_FLATSHADING; else m_Clipper.m_dwFlags &= ~RefClipper::RCLIP_DO_FLATSHADING; } break; case D3DRENDERSTATE_FILLMODE: { if( dwValue == D3DFILL_WIREFRAME ) m_Clipper.m_dwFlags |= RefClipper::RCLIP_DO_WIREFRAME; else m_Clipper.m_dwFlags &= ~RefClipper::RCLIP_DO_WIREFRAME; } break; case D3DRENDERSTATE_NORMALIZENORMALS: { if( dwValue ) m_RefVP.m_dwTLState |= RDPV_NORMALIZENORMALS; else m_RefVP.m_dwTLState &= ~RDPV_NORMALIZENORMALS; } break; case D3DRENDERSTATE_LOCALVIEWER: { if( dwValue ) m_RefVP.m_dwTLState |= RDPV_LOCALVIEWER; else m_RefVP.m_dwTLState &= ~RDPV_LOCALVIEWER; } break; case D3DRENDERSTATE_SPECULARENABLE: { if( dwValue ) m_RefVP.m_dwTLState |= RDPV_DOSPECULAR; else m_RefVP.m_dwTLState &= ~RDPV_DOSPECULAR; } break; case D3DRENDERSTATE_COLORVERTEX: case D3DRENDERSTATE_AMBIENTMATERIALSOURCE: case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE: case D3DRENDERSTATE_SPECULARMATERIALSOURCE: case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_COLORVTX; break; case D3DRENDERSTATE_FOGCOLOR: { m_RefVP.m_lighting.fog_color = (D3DCOLOR) dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_FOG; } break; case D3DRENDERSTATE_FOGTABLESTART: { m_RefVP.m_lighting.fog_start = *(D3DVALUE*)&dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_FOG; } break; case D3DRENDERSTATE_FOGTABLEEND: { m_RefVP.m_lighting.fog_end = *(D3DVALUE*)&dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_FOG; } break; case D3DRENDERSTATE_FOGTABLEDENSITY: { m_RefVP.m_lighting.fog_density = *(D3DVALUE*)&dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_FOG; } break; case D3DRENDERSTATE_FOGVERTEXMODE: { m_RefVP.m_lighting.fog_mode = (int) dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_FOG; } break; case D3DRENDERSTATE_AMBIENT: { m_RefVP.m_lighting.ambient_red = D3DVAL(RGBA_GETRED(dwValue))/D3DVALUE(255); m_RefVP.m_lighting.ambient_green = D3DVAL(RGBA_GETGREEN(dwValue))/D3DVALUE(255); m_RefVP.m_lighting.ambient_blue = D3DVAL(RGBA_GETBLUE(dwValue))/D3DVALUE(255); m_RefVP.m_lighting.ambient_save = dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_MATERIAL; } break; // // map legacy texture to multi-texture stage 0 // case D3DRENDERSTATE_TEXTUREMAPBLEND: // map legacy blending state to texture stage 0 MapLegacyTextureBlend(); break; // map legacy modes with one-to-one mappings to texture stage 0 case D3DRENDERSTATE_TEXTUREADDRESS: // not available in DX8 headers // m_TextureStageState[0].m_dwVal[D3DTSS_ADDRESS] = m_TextureStageState[0].m_dwVal[D3DTSS_ADDRESSU] = m_TextureStageState[0].m_dwVal[D3DTSS_ADDRESSV] = dwValue; break; case D3DRENDERSTATE_TEXTUREADDRESSU: m_TextureStageState[0].m_dwVal[D3DTSS_ADDRESSU] = dwValue; break; case D3DRENDERSTATE_TEXTUREADDRESSV: m_TextureStageState[0].m_dwVal[D3DTSS_ADDRESSV] = dwValue; break; case D3DRENDERSTATE_MIPMAPLODBIAS: m_TextureStageState[0].m_dwVal[D3DTSS_MIPMAPLODBIAS] = dwValue; break; case D3DRENDERSTATE_BORDERCOLOR: m_TextureStageState[0].m_dwVal[D3DTSS_BORDERCOLOR] = dwValue; break; case D3DRENDERSTATE_ANISOTROPY: m_TextureStageState[0].m_dwVal[D3DTSS_MAXANISOTROPY] = dwValue; // fall thru to update filter state case D3DRENDERSTATE_TEXTUREMAG: case D3DRENDERSTATE_TEXTUREMIN: // map legacy filtering/sampling state to texture stage 0 MapLegacyTextureFilter(); break; case D3DRENDERSTATE_TEXTUREHANDLE: // map thru to set handle for first stage SetTextureStageState( 0, D3DTSS_TEXTUREMAP, dwValue ); break; // // map legacy WRAPU/V state through to controls for tex coord 0 // case D3DRENDERSTATE_WRAPU: m_dwRenderState[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_U; m_dwRenderState[D3DRENDERSTATE_WRAP0] |= ((dwValue) ? D3DWRAP_U : 0); break; case D3DRENDERSTATE_WRAPV: m_dwRenderState[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_V; m_dwRenderState[D3DRENDERSTATE_WRAP0] |= ((dwValue) ? D3DWRAP_V : 0); break; case D3DRS_MULTISAMPLEANTIALIAS: case D3DRS_MULTISAMPLEMASK: m_dwRastFlags |= RDRF_MULTISAMPLE_CHANGED; break; // // Scene Capture // case D3DRENDERSTATE_SCENECAPTURE: if( dwValue ) SceneCapture(D3DHAL_SCENE_CAPTURE_START); else SceneCapture(D3DHAL_SCENE_CAPTURE_END); break; case D3DRS_POINTSIZE: m_RefVP.m_fPointSize = m_fRenderState[dwState]; break; case D3DRS_POINTSCALE_A: m_RefVP.m_fPointAttA = m_fRenderState[dwState]; break; case D3DRS_POINTSCALE_B: m_RefVP.m_fPointAttB = m_fRenderState[dwState]; break; case D3DRS_POINTSCALE_C: m_RefVP.m_fPointAttC = m_fRenderState[dwState]; break; case D3DRS_POINTSIZE_MIN: m_RefVP.m_fPointSizeMin = m_fRenderState[dwState]; break; case D3DRS_POINTSIZE_MAX: m_RefVP.m_fPointSizeMax = min(RD_MAX_POINT_SIZE, m_fRenderState[dwState]); break; case D3DRS_TWEENFACTOR: m_RefVP.m_fTweenFactor = m_fRenderState[dwState]; break; // // HOSurface DDI only renderstate // case D3DRS_DELETERTPATCH: if(dwValue < m_HOSCoeffs.GetSize()) { RDHOCoeffs &coeffs = m_HOSCoeffs[dwValue]; delete[] coeffs.m_pNumSegs; coeffs.m_pNumSegs = 0; for(unsigned i = 0; i < RD_MAX_NUMSTREAMS; ++i) { delete[] coeffs.m_pData[i]; coeffs.m_pData[i] = 0; } } } } HRESULT RefDev::Dp2SetRenderTarget(LPD3DHAL_DP2COMMAND pCmd) { LPD3DHAL_DP2SETRENDERTARGET pSRTData; HRESULT hr; // Get new data by ignoring all but the last structure pSRTData = (D3DHAL_DP2SETRENDERTARGET*)(pCmd + 1) + (pCmd->wStateCount - 1); // set 'changed' flags m_dwRastFlags = RDRF_MULTISAMPLE_CHANGED| RDRF_PIXELSHADER_CHANGED| RDRF_LEGACYPIXELSHADER_CHANGED| RDRF_TEXTURESTAGESTATE_CHANGED; return GetRenderTarget()->Initialize( m_pDDLcl, pSRTData->hRenderTarget, pSRTData->hZBuffer ); } HRESULT RefDev::Dp2CreateVertexShader( DWORD handle, DWORD dwDeclSize, LPDWORD pDecl, DWORD dwCodeSize, LPDWORD pCode ) { HRESULT hr = S_OK; HR_RET( m_VShaderHandleArray.Grow( handle ) ); // // Validation sequence // #if DBG _ASSERT( m_VShaderHandleArray[handle].m_tag == 0, "A shader exists with the given handle, tag is non-zero" ); #endif _ASSERT( pDecl, "A declaration should exist" ); _ASSERT( dwDeclSize, "A declaration size should be non-zero" ); _ASSERT( m_VShaderHandleArray[handle].m_pShader == NULL, "A shader exists with the given handle" ); RDVShader* pShader = m_VShaderHandleArray[handle].m_pShader = new RDVShader; if( pShader == NULL ) return E_OUTOFMEMORY; // // Parse the declaration // if( FAILED( hr = pShader->m_Declaration.Parse( pDecl, !(BOOL)dwCodeSize ) ) ) { DPFERR( "Vertex Shader declaration parsing failed" ); goto error_ret; } // // Now compile the shader code if any of it is given // if( dwCodeSize ) { pShader->m_pCode = m_RefVM.CompileCode( dwCodeSize, pCode ); if( pShader->m_pCode == NULL ) { DPFERR( "Vertex Shader Code compilation failed" ); hr = E_FAIL; goto error_ret; } } #if DBG // Everything successful, mark this handle as in use. m_VShaderHandleArray[handle].m_tag = 1; #endif if( m_pDbgMon ) m_pDbgMon->StateChanged( D3DDM_SC_VSMODIFYSHADERS ); return S_OK; error_ret: delete pShader; m_VShaderHandleArray[handle].m_pShader = NULL; #if DBG m_VShaderHandleArray[handle].m_tag = 0; #endif return hr; } HRESULT RefDev::Dp2DeleteVertexShader(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; LPD3DHAL_DP2VERTEXSHADER pVS = (LPD3DHAL_DP2VERTEXSHADER)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { DWORD handle = pVS[i].dwHandle; _ASSERT( m_VShaderHandleArray.IsValidIndex( handle ), "Such a shader does not exist" ); _ASSERT( m_VShaderHandleArray[handle].m_pShader, "Such a shader does not exist" ); delete m_VShaderHandleArray[handle].m_pShader; m_VShaderHandleArray[handle].m_pShader = NULL; #if DBG m_VShaderHandleArray[handle].m_tag = 0; #endif if( handle == m_CurrentVShaderHandle ) { m_CurrentVShaderHandle = 0; m_pCurrentVShader = NULL; } } if( m_pDbgMon ) m_pDbgMon->StateChanged( D3DDM_SC_VSMODIFYSHADERS ); return hr; } HRESULT RefDev::Dp2SetVertexShader(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; LPD3DHAL_DP2VERTEXSHADER pVS = (LPD3DHAL_DP2VERTEXSHADER)(pCmd + 1); // Just set the last Vertex Shader in this array DWORD handle = pVS[pCmd->wStateCount-1].dwHandle; // // Zero is a special handle that tells the driver to // invalidate the currently set shader. // if( handle == 0 ) { m_pCurrentVShader = NULL; m_CurrentVShaderHandle = handle; return hr; } if( RDVSD_ISLEGACY(handle) ) { // Make it parse the FVF and build the VertexElement array hr = m_FVFShader.m_Declaration.MakeVElementArray( handle ); if( FAILED( hr ) ) { DPFERR( "MakeVElementArray failed" ); return hr; } m_pCurrentVShader = &m_FVFShader; } else { if( !m_VShaderHandleArray.IsValidIndex( handle ) || (m_VShaderHandleArray[handle].m_pShader == NULL) ) { DPFERR( "Such a Vertex Shader has not been created" ); return E_INVALIDARG; } m_pCurrentVShader = m_VShaderHandleArray[handle].m_pShader; // Save the tesselator stride computed at parsing time. // This feature is only available when using a Declaration. m_VStream[RDVSD_STREAMTESS].m_dwStride = m_pCurrentVShader->m_Declaration.m_dwStreamTessStride; } if( m_pCurrentVShader->m_pCode ) { hr = m_RefVM.SetActiveShaderCode( m_pCurrentVShader->m_pCode ); if( FAILED( hr ) ) { DPFERR( "SetActiveShaderCode failed" ); return hr; } RDVConstantData* pConst = m_pCurrentVShader->m_Declaration.m_pConstants; while( pConst ) { hr = m_RefVM.SetData( D3DSPR_CONST, pConst->m_dwAddress, pConst->m_dwCount, pConst->m_pData ); if( FAILED( hr ) ) { DPFERR( "SetVMData failed" ); return hr; } pConst = static_cast(pConst->m_pNext); } } m_CurrentVShaderHandle = handle; if( m_pCurrentVShader->m_Declaration.m_qwInputFVF != m_RefVP.m_qwFVFIn ) { m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_COLORVTX; } m_RefVP.m_qwFVFIn = m_pCurrentVShader->m_Declaration.m_qwInputFVF; if( m_pDbgMon ) m_pDbgMon->StateChanged( D3DDM_SC_VSSETSHADER ); return hr; } HRESULT RefDev::Dp2SetVertexShaderConsts( DWORD StartReg, DWORD dwCount, LPDWORD pData ) { HRESULT hr = m_RefVM.SetData( D3DSPR_CONST, StartReg, dwCount, pData ); if( m_pDbgMon ) m_pDbgMon->StateChanged( D3DDM_SC_VSCONSTANTS ); return hr; } HRESULT RefDev::Dp2SetStreamSource(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; LPD3DHAL_DP2SETSTREAMSOURCE pSSS = (LPD3DHAL_DP2SETSTREAMSOURCE)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { RDVStream& Stream = m_VStream[pSSS[i].dwStream]; // NULL handle means that the StreamSource should be unset. if( pSSS[i].dwVBHandle == 0 ) { Stream.m_pData = NULL; Stream.m_dwStride = 0; Stream.m_dwHandle = 0; } else { // Check if the handle has a valid vertexbuffer RDSurface* pSurf = g_SurfMgr.GetSurfFromList(m_pDDLcl, pSSS[i].dwVBHandle); if( (pSurf == NULL) || (pSurf->GetSurfaceType() != RR_ST_VERTEXBUFFER) ) { DPFERR( "Invalid VB Handle passed in SetStreamSource" ); return E_INVALIDARG; } RDVertexBuffer* pVB = static_cast(pSurf); Stream.m_pData = pVB->GetBits(); Stream.m_dwStride = pSSS[i].dwStride; Stream.m_dwHandle = pSSS[i].dwVBHandle; } } return hr; } HRESULT RefDev::Dp2SetStreamSourceUM( LPD3DHAL_DP2COMMAND pCmd, PUINT8 pUMVtx ) { HRESULT hr = S_OK; // Get new data by ignoring all but the last structure D3DHAL_DP2SETSTREAMSOURCEUM* pSSUM = (D3DHAL_DP2SETSTREAMSOURCEUM*)(pCmd + 1) + (pCmd->wStateCount - 1); // Access only the Zero'th stream m_VStream[pSSUM->dwStream].m_pData = pUMVtx; m_VStream[pSSUM->dwStream].m_dwStride = pSSUM->dwStride; m_VStream[pSSUM->dwStream].m_dwHandle = 0; return hr; } HRESULT RefDev::Dp2SetIndices(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; // Get new data by ignoring all but the last structure D3DHAL_DP2SETINDICES* pSI = (D3DHAL_DP2SETINDICES*)(pCmd + 1) + (pCmd->wStateCount - 1); // NULL handle means that the StreamSource should be unset. if( pSI->dwVBHandle == 0 ) { m_IndexStream.m_pData = NULL; m_IndexStream.m_dwStride = 0; m_IndexStream.m_dwHandle = 0; } else { // Check if the handle has a valid vertexbuffer RDSurface* pSurf = g_SurfMgr.GetSurfFromList(m_pDDLcl, pSI->dwVBHandle); if( (pSurf == NULL) || (pSurf->GetSurfaceType() != RR_ST_VERTEXBUFFER) ) { DPFERR( "Invalid VB Handle passed in SetIndices" ); return E_INVALIDARG; } RDVertexBuffer* pVB = static_cast(pSurf); m_IndexStream.m_pData = pVB->GetBits(); m_IndexStream.m_dwStride = pSI->dwStride; m_IndexStream.m_dwHandle = pSI->dwVBHandle; } return hr; } HRESULT RefDev::Dp2DrawPrimitive(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; // // Validation // _ASSERT( m_CurrentVShaderHandle, "No vertex shader currently bound" ); LPD3DHAL_DP2DRAWPRIMITIVE pDP = (LPD3DHAL_DP2DRAWPRIMITIVE)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { if( FAILED( hr = DrawDX8Prim( &(pDP[i]) ) ) ) return hr; } return hr; } HRESULT RefDev::Dp2DrawPrimitive2(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; // // Validation // _ASSERT( m_CurrentVShaderHandle, "No vertex shader currently bound" ); LPD3DHAL_DP2DRAWPRIMITIVE2 pDP = (LPD3DHAL_DP2DRAWPRIMITIVE2)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { if( FAILED( hr = DrawDX8Prim2( &(pDP[i]) ) ) ) return hr; } return hr; } HRESULT RefDev::Dp2DrawIndexedPrimitive(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; // // Validation // _ASSERT( m_CurrentVShaderHandle, "No vertex shader currently bound" ); LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE pDIP = (LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { if( FAILED( hr = DrawDX8IndexedPrim( &(pDIP[i]) ) ) ) return hr; } return hr; } HRESULT RefDev::Dp2DrawIndexedPrimitive2(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; // // Validation // _ASSERT( m_CurrentVShaderHandle, "No vertex shader currently bound" ); LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE2 pDIP = (LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE2)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { if( FAILED( hr = DrawDX8IndexedPrim2( &(pDIP[i]) ) ) ) return hr; } return hr; } HRESULT RefDev::Dp2DrawClippedTriFan(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; // // Validation // _ASSERT( m_CurrentVShaderHandle, "No vertex shader currently bound" ); LPD3DHAL_CLIPPEDTRIANGLEFAN pDIP = (LPD3DHAL_CLIPPEDTRIANGLEFAN)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { if( FAILED( hr = DrawDX8ClippedTriFan( &(pDIP[i]) ) ) ) return hr; } return hr; } HRESULT RefDev::Dp2SetPalette(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; LPD3DHAL_DP2SETPALETTE pSP = (LPD3DHAL_DP2SETPALETTE)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { HR_RET( m_PaletteHandleArray.Grow( pSP->dwPaletteHandle ) ); if( m_PaletteHandleArray[pSP->dwPaletteHandle].m_pPal == NULL ) { m_PaletteHandleArray[pSP->dwPaletteHandle].m_pPal = new RDPalette; } RDPalette* pPal = m_PaletteHandleArray[pSP->dwPaletteHandle].m_pPal; pPal->m_dwFlags = (pSP->dwPaletteFlags & DDRAWIPAL_ALPHA) ? RDPalette::RDPAL_ALPHAINPALETTE : 0; RDSurface2D* pSurf = (RDSurface2D *)g_SurfMgr.GetSurfFromList( m_pDDLcl, pSP->dwSurfaceHandle ); if( pSurf == NULL ) return E_FAIL; if( (pSurf->GetSurfaceType() & RR_ST_TEXTURE) == 0 ) { DPFERR( "Setting palette to a non-texture\n" ); return E_FAIL; } pSurf->SetPalette( pPal ); } return hr; } HRESULT RefDev::Dp2UpdatePalette(LPD3DHAL_DP2UPDATEPALETTE pUP, PALETTEENTRY* pPalData) { HRESULT hr = S_OK; HR_RET( m_PaletteHandleArray.Grow( pUP->dwPaletteHandle ) ); if( m_PaletteHandleArray[pUP->dwPaletteHandle].m_pPal == NULL ) { m_PaletteHandleArray[pUP->dwPaletteHandle].m_pPal = new RDPalette; } RDPalette* pPal = m_PaletteHandleArray[pUP->dwPaletteHandle].m_pPal; HR_RET( pPal->Update( pUP->wStartIndex, pUP->wNumEntries, pPalData ) ); return hr; } HRESULT RefDev::Dp2SetTexLod(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; LPD3DHAL_DP2SETTEXLOD pSTL = (LPD3DHAL_DP2SETTEXLOD)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { RDSurface2D* pSurf = (RDSurface2D *)g_SurfMgr.GetSurfFromList( m_pDDLcl, pSTL->dwDDSurface ); if( pSurf == NULL ) return E_FAIL; if( (pSurf->GetSurfaceType() & RR_ST_TEXTURE) == 0 ) { DPFERR( "Setting LOD to a non-texture\n" ); return E_FAIL; } HR_RET(pSurf->SetLod( pSTL->dwLOD )); } return hr; }