|
|
/*==========================================================================;
* * Copyright (C) 1997, 1998 Microsoft Corporation. All Rights Reserved. * * File: haldrv.cpp * Content: Direct3D HAL Driver * ***************************************************************************/
#include "pch.cpp"
#pragma hdrstop
#include "commdrv.hpp"
#include "d3dfei.h"
#include "tlhal.h"
#ifndef WIN95
#include <ntgdistr.h>
#endif
void Destroy(LPDIRECT3DDEVICEI lpDevI); //---------------------------------------------------------------------
int GenGetExtraVerticesNumber( LPDIRECT3DDEVICEI lpDevI ) { LPD3DHAL_GLOBALDRIVERDATA lpGlob = lpDevI->lpD3DHALGlobalDriverData;
return (int)(lpGlob->dwNumVertices ? lpGlob->dwNumVertices : D3DHAL_DEFAULT_TL_NUM);
} //---------------------------------------------------------------------
HRESULT CalcDDSurfInfo(LPDIRECT3DDEVICEI lpDevI, BOOL bUpdateZBufferFields) { DDSURFACEDESC ddsd; HRESULT ddrval; DWORD dwWidth, dwHeight; unsigned long m; int s;
// Get info from the surface
memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC); ddrval = lpDevI->lpDDSTarget->GetSurfaceDesc(&ddsd); if (ddrval != DD_OK) { return ddrval; }
dwWidth = ddsd.dwWidth; dwHeight = ddsd.dwHeight; if ((ddsd.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8)) == 0) { // palettized pixfmts will not have valid RGB Bitmasks, so avoid computing this for them
lpDevI->red_mask = ddsd.ddpfPixelFormat.dwRBitMask; lpDevI->green_mask = ddsd.ddpfPixelFormat.dwGBitMask; lpDevI->blue_mask = ddsd.ddpfPixelFormat.dwBBitMask; if ((lpDevI->red_mask == 0x0) || (lpDevI->green_mask == 0x0) || (lpDevI->blue_mask == 0x0)) { D3D_ERR("All the color masks in the Render target's pixel-format must be non-zero"); return DDERR_INVALIDPIXELFORMAT; }
// these are used by Clear
for (s = 0, m = lpDevI->red_mask; !(m & 1); s++, m >>= 1) ; lpDevI->red_shift = s; lpDevI->red_scale = 255 / (lpDevI->red_mask >> s); for (s = 0, m = lpDevI->green_mask; !(m & 1); s++, m >>= 1) ; lpDevI->green_shift = s; lpDevI->green_scale = 255 / (lpDevI->green_mask >> s); for (s = 0, m = lpDevI->blue_mask; !(m & 1); s++, m >>= 1) ; lpDevI->blue_shift = s; lpDevI->blue_scale = 255 / (lpDevI->blue_mask >> s);
if ( (lpDevI->red_scale==0) || (lpDevI->green_scale==0) || (lpDevI->blue_scale==0) ) return DDERR_INVALIDPIXELFORMAT;
// If there is Alpha in this format
if (ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) { lpDevI->alpha_mask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; for (s = 0, m = lpDevI->alpha_mask; !(m & 1); s++, m >>= 1) ; lpDevI->alpha_shift = s; lpDevI->alpha_scale = 255 / (lpDevI->alpha_mask >> s); } else { lpDevI->alpha_shift = lpDevI->alpha_scale = lpDevI->alpha_mask = 0; } lpDevI->bDDSTargetIsPalettized=FALSE; } else lpDevI->bDDSTargetIsPalettized=TRUE;
if (lpDevI->lpDDSZBuffer_DDS7 && bUpdateZBufferFields) { // Get info from the surface
DDSURFACEDESC2 ddsd2;
memset(&ddsd2, 0, sizeof(ddsd2)); ddsd2.dwSize = sizeof(ddsd2); ddrval = lpDevI->lpDDSZBuffer_DDS7->GetSurfaceDesc(&ddsd2); if (ddrval != DD_OK) { return ddrval; }
if( ddsd2.ddpfPixelFormat.dwZBitMask!=0x0) { for (s = 0, m = ddsd2.ddpfPixelFormat.dwZBitMask; !(m & 0x1); s++, m >>= 1) ; lpDevI->zmask_shift=s; } else { lpDevI->zmask_shift=0; // if ZBitMask isn't being set, then Clear2 will never be used,
// so zbuf_shift/stencil_shift wont be needed anyway
}
if( ddsd2.ddpfPixelFormat.dwStencilBitMask!=0x0) { for (s = 0, m = ddsd2.ddpfPixelFormat.dwStencilBitMask; !(m & 0x1); s++, m >>= 1) ; lpDevI->stencilmask_shift=s; } else { lpDevI->stencilmask_shift=0; } }
return D3D_OK; }
// called by DDRAW
extern "C" HRESULT __stdcall Direct3D_HALCleanUp(LPD3DHAL_CALLBACKS lpD3DHALCallbacks, DWORD dwPID) { D3DHAL_CONTEXTDESTROYALLDATA data; HRESULT ret;
DDASSERT(lpD3DHALCallbacks!=NULL); if (lpD3DHALCallbacks->ContextDestroyAll==NULL) { // no cleanup necessary (running on d3d hel)
return D3D_OK; }
memset(&data, 0, sizeof(D3DHAL_CONTEXTDESTROYALLDATA)); data.dwPID = dwPID;
// I'd prefer to use CALL_HALONLY() to do the locking (to avoid doing it for the SW rasterizers),
// but that requires a pDevI which I can't get to from the caller, which is a ddraw cleanup routine
#ifdef WIN95
_EnterSysLevel(lpWin16Lock); #endif
ret = (*lpD3DHALCallbacks->ContextDestroyAll)(&data);
#ifdef WIN95
_LeaveSysLevel(lpWin16Lock); #endif
return ret; }
// ATTENTION - These two functions should be combined into one as soon
// as ContextCreate has the new private data mechanism built in.
#ifdef WIN95
HRESULT DIRECT3DDEVICEI::halCreateContext() { D3DHAL_CONTEXTCREATEDATA data; HRESULT ret;
D3D_INFO(6, "in halCreateContext. Creating Context for driver = %08lx", this);
memset(&data, 0, sizeof(D3DHAL_CONTEXTCREATEDATA)); //
// From DX7 onwards, drivers should be accepting
// Surface Locals instead of the Surface interfaces
// this future-proofs the drivers
//
if (IS_DX7HAL_DEVICE(this)) { if (this->lpDD) data.lpDDLcl = ((LPDDRAWI_DIRECTDRAW_INT)(this->lpDD))->lpLcl; else data.lpDDLcl = NULL;
if (lpDDSTarget) data.lpDDSLcl = ((LPDDRAWI_DDRAWSURFACE_INT)lpDDSTarget)->lpLcl; else data.lpDDSLcl = NULL;
if (lpDDSZBuffer) data.lpDDSZLcl = ((LPDDRAWI_DDRAWSURFACE_INT)lpDDSZBuffer)->lpLcl; else data.lpDDSZLcl = NULL;
} else { data.lpDDGbl = this->lpDDGbl; data.lpDDS = this->lpDDSTarget; data.lpDDSZ = this->lpDDSZBuffer; }
// Hack Alert!! dwhContext is used to inform the driver which version
// of the D3D interface is calling it.
data.dwhContext = 3; data.dwPID = GetCurrentProcessId(); // Hack Alert!! ddrval is used to inform the driver which driver type
// the runtime thinks it is (DriverStyle registry setting)
data.ddrval = this->deviceType;
if (!IS_HW_DEVICE(this)) { // The new software rasterizers want to share IM's state vector so
// we need to pass them the rstates pointer. They don't
// care about dwPID so stick the pointer in there.
data.dwPID = (DWORD)this->rstates; }
/* 0 for pre-DX5 devices.
* 1 for DX5 devices. * 2 for DX6 devices. * 3 for DX7 devices. */
CALL_HALONLY(ret, this, ContextCreate, &data); if (ret != DDHAL_DRIVER_HANDLED || data.ddrval != DD_OK) { D3D_ERR( "Driver did not handle ContextCreate" ); return (DDERR_GENERIC); } this->dwhContext = data.dwhContext;
if (D3DMalloc ((void**)&this->lpwDPBufferAlloced, max(dwD3DTriBatchSize*4*sizeof(WORD), dwHWBufferSize) +32) != DD_OK) { D3D_ERR( "Out of memory in DeviceCreate" ); return (DDERR_OUTOFMEMORY); } this->lpwDPBuffer = (LPWORD) (((DWORD) this->lpwDPBufferAlloced+31) & (~31));
// save the surface handle for later checks
this->hSurfaceTarget = ((LPDDRAWI_DDRAWSURFACE_INT)this->lpDDSTarget)->lpLcl->lpSurfMore->dwSurfaceHandle;
D3D_INFO(6, "in halCreateContext. Succeeded. dwhContext = %d", data.dwhContext);
return (D3D_OK); } #else
/*
* On NT the kernel code creates the buffer to be used * for DrawPrim batching and returns it as extra data * in the ContextCreate request. */ HRESULT DIRECT3DDEVICEI::halCreateContext() { D3DNTHAL_CONTEXTCREATEI ntData; D3DHAL_CONTEXTCREATEDATA *lpData = (D3DHAL_CONTEXTCREATEDATA *)&ntData; HRESULT ret;
D3D_INFO(6, "in halCreateContext. Creating Context for driver = %08lx", this);
/*
* AnanKan: Assert here that the D3DNTHAL_CONTEXTCREATEI structure is * 2 DWORDS bigger than D3DHAL_CONTEXTCREATEDATA. This will be a good * consistency check for NT kernel updates. */ memset(&ntData, 0, sizeof(ntData)); if (IS_DX7HAL_DEVICE(this) || (dwFEFlags & D3DFE_REALHAL)) { if (this->lpDD) lpData->lpDDLcl = ((LPDDRAWI_DIRECTDRAW_INT)(this->lpDD))->lpLcl; else lpData->lpDDLcl = NULL;
if (lpDDSTarget) lpData->lpDDSLcl = ((LPDDRAWI_DDRAWSURFACE_INT)lpDDSTarget)->lpLcl; else lpData->lpDDSLcl = NULL;
if (lpDDSZBuffer) lpData->lpDDSZLcl = ((LPDDRAWI_DDRAWSURFACE_INT)lpDDSZBuffer)->lpLcl; else lpData->lpDDSZLcl = NULL;
} else { lpData->lpDDGbl = lpDDGbl; lpData->lpDDS = lpDDSTarget; lpData->lpDDSZ = lpDDSZBuffer; }
// Hack Alert!! dwhContext is used to inform the driver which version
// of the D3D interface is calling it.
lpData->dwhContext = 3; lpData->dwPID = GetCurrentProcessId(); // Hack Alert!! ddrval is used to inform the driver which driver type
// the runtime thinks it is (DriverStyle registry setting)
lpData->ddrval = this->deviceType;
if (IS_HW_DEVICE(this)) { // The new software rasterizers want to share IM's state vector so
// we need to pass them the rstates pointer. They don't
// care about dwPID so stick the pointer in there.
lpData->dwPID = (DWORD)((ULONG_PTR)this->rstates); }
/* 0 for pre-DX5 devices.
* 1 for DX5 devices. * 2 for DX6 devices. * 3 for DX7 devices. */ ntData.cjBuffer = this->dwDPBufferSize; ntData.pvBuffer = NULL;
CALL_HALONLY(ret, this, ContextCreate, lpData); if (ret != DDHAL_DRIVER_HANDLED || lpData->ddrval != DD_OK) { D3D_ERR( "Driver did not handle ContextCreate" ); return (DDERR_GENERIC); } this->dwhContext = (DWORD)((ULONG_PTR)lpData->dwhContext);
// If the this chose not to allocate a DrawPrim buffer do
// it for them.
if (ntData.pvBuffer == NULL) { this->dwDPBufferSize = dwD3DTriBatchSize * 4 * sizeof(WORD); if (this->dwDPBufferSize < dwHWBufferSize) { this->dwDPBufferSize = dwHWBufferSize; }
ret = D3DMalloc((void**)&this->lpwDPBufferAlloced, this->dwDPBufferSize + 32); if (ret != DD_OK) { return ret; }
ntData.pvBuffer = (LPVOID) (((ULONG_PTR)this->lpwDPBufferAlloced + 31) & ~31); ntData.cjBuffer = this->dwDPBufferSize + 32 - (DWORD)((ULONG_PTR)ntData.pvBuffer - (ULONG_PTR)this->lpwDPBufferAlloced); } else if( (this->dwDPBufferSize && ntData.cjBuffer < this->dwDPBufferSize) || ntData.cjBuffer < sizeof(D3DHAL_DRAWPRIMCOUNTS) ) { D3D_ERR( "Driver did not correctly allocate DrawPrim buffer"); return (DDERR_GENERIC); }
// Need to save the buffer space provided and its size
this->lpwDPBuffer = (LPWORD)ntData.pvBuffer;
// save the surface handle for later checks
this->hSurfaceTarget = (DWORD)(((LPDDRAWI_DDRAWSURFACE_INT)this->lpDDSTarget)->lpLcl->hDDSurface);
D3D_INFO(6, "in halCreateContext. Succeeded. dwhContext = %d", lpData->dwhContext);
return (D3D_OK); } #endif //WIN95
void halDestroyContext(LPDIRECT3DDEVICEI lpDevI) { D3DHAL_CONTEXTDESTROYDATA data; HRESULT ret;
D3D_INFO(6, "in halCreateDestroy. Destroying Context for driver = %08lx", lpDevI); D3D_INFO(6, " dwhContext = %d", lpDevI->dwhContext);
if(lpDevI->dwhContext!=NULL) { memset(&data, 0, sizeof(D3DHAL_CONTEXTDESTROYDATA)); data.dwhContext = lpDevI->dwhContext;
CALL_HALONLY(ret, lpDevI, ContextDestroy, &data); if (ret != DDHAL_DRIVER_HANDLED || data.ddrval != DD_OK) { D3D_WARN(0,"Failed ContextDestroy HAL call in halDestroyContext"); return; } } } //---------------------------------------------------------------------
HRESULT D3DFE_Create(LPDIRECT3DDEVICEI lpDevI, LPDIRECTDRAW lpDD, LPDIRECTDRAW7 lpDD7, LPDIRECTDRAWSURFACE lpDDS, LPDIRECTDRAWSURFACE lpZ, LPDIRECTDRAWPALETTE lpPal) { DDSURFACEDESC ddsd; HRESULT hr; LPD3DHAL_GLOBALDRIVERDATA lpGlob;
/*
* Allocate and check validity of DirectDraw surfaces */
lpDevI->lpDD = lpDD; lpDevI->lpDDGbl = ((LPDDRAWI_DIRECTDRAW_INT)lpDD)->lpLcl->lpGbl; lpDevI->lpDDSTarget = lpDDS;
// Get DDS7 Interfaces for RenderTarget/ZBuffer
HRESULT ret = lpDDS->QueryInterface(IID_IDirectDrawSurface7, (LPVOID*)&lpDevI->lpDDSTarget_DDS7);
if(FAILED(ret)) { D3D_ERR("QI for RenderTarget DDS7 Interface failed "); return ret; }
if(lpZ!=NULL) { ret = lpZ->QueryInterface(IID_IDirectDrawSurface7, (LPVOID*)&lpDevI->lpDDSZBuffer_DDS7);
if(FAILED(ret)) { D3D_ERR("QI for ZBuffer DDS7 Interface failed ");
return ret; } lpDevI->lpDDSZBuffer_DDS7->Release(); }
LPD3DHAL_D3DEXTENDEDCAPS lpCaps = lpDevI->lpD3DExtendedCaps; if (NULL == lpCaps || 0.0f == lpCaps->dvExtentsAdjust) { lpDevI->dvExtentsAdjust = 1.0f; } else { lpDevI->dvExtentsAdjust = lpCaps->dvExtentsAdjust; } lpDevI->dwClipMaskOffScreen = 0xFFFFFFFF; if (lpCaps != NULL) { if (lpCaps->dvGuardBandLeft != 0.0f || lpCaps->dvGuardBandRight != 0.0f || lpCaps->dvGuardBandTop != 0.0f || lpCaps->dvGuardBandBottom != 0.0f) { lpDevI->dwDeviceFlags |= D3DDEV_GUARDBAND; lpDevI->dwClipMaskOffScreen = ~__D3DCLIP_INGUARDBAND; DWORD v; if (GetD3DRegValue(REG_DWORD, "DisableGB", &v, 4) && v != 0) { lpDevI->dwDeviceFlags &= ~D3DDEV_GUARDBAND; lpDevI->dwClipMaskOffScreen = 0xFFFFFFFF; } #if DBG
// Try to get test values for the guard band
char value[80]; if (GetD3DRegValue(REG_SZ, "GuardBandLeft", &value, 80) && value[0] != 0) sscanf(value, "%f", &lpCaps->dvGuardBandLeft); if (GetD3DRegValue(REG_SZ, "GuardBandRight", &value, 80) && value[0] != 0) sscanf(value, "%f", &lpCaps->dvGuardBandRight); if (GetD3DRegValue(REG_SZ, "GuardBandTop", &value, 80) && value[0] != 0) sscanf(value, "%f", &lpCaps->dvGuardBandTop); if (GetD3DRegValue(REG_SZ, "GuardBandBottom", &value, 80) && value[0] != 0) sscanf(value, "%f", &lpCaps->dvGuardBandBottom); #endif // DBG
} }
if (!lpDevI->lpD3DHALCallbacks || ! lpDevI->lpD3DHALGlobalDriverData) { return DDERR_INVALIDOBJECT; }
if (IS_HW_DEVICE(lpDevI)) { // We do texture management (and hence clipped Blts) only for a real HAL.
hr = lpDD7->CreateClipper(0, &lpDevI->lpClipper, NULL); if(hr != DD_OK) { D3D_ERR("Failed to create a clipper"); return hr; } } else { lpDevI->lpClipper = 0; }
lpGlob = lpDevI->lpD3DHALGlobalDriverData;
memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC); if (lpZ) { if ((hr = lpZ->GetSurfaceDesc(&ddsd)) != DD_OK) { D3D_ERR("Failed to getsurfacedesc on z"); return hr; } if (ddsd.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) { D3D_INFO(1, "Z buffer is in system memory."); } else if (ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) { D3D_INFO(1, "Z buffer is in video memory."); } else { D3D_ERR("Z buffer not in video or system?"); } } memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC); if (lpDDS) { if ((hr = lpDDS->GetSurfaceDesc(&ddsd)) != DD_OK) { D3D_ERR("Failed to getsurfacedesc on back buffer"); return hr; } if (ddsd.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) { D3D_INFO(1, "back buffer is in system memory."); } else if (ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) { D3D_INFO(1, "back buffer is in video memory."); } else { D3D_ERR("back buffer not in video or system?"); } if (!(lpGlob->hwCaps.dwDeviceRenderBitDepth & BitDepthToDDBD(ddsd.ddpfPixelFormat.dwRGBBitCount))) { D3D_ERR("Rendering surface's RGB bit count not supported " "by hardware device"); return DDERR_INVALIDOBJECT; } }
if (lpGlob->dwNumVertices && lpGlob->dwNumClipVertices < D3DHAL_NUMCLIPVERTICES) { D3D_ERR("In global driver data, dwNumClipVertices " "< D3DHAL_NUMCLIPVERTICES"); lpGlob->dwNumClipVertices = D3DHAL_NUMCLIPVERTICES; }
if ((hr = CalcDDSurfInfo(lpDevI,TRUE)) != DD_OK) { return hr; }
RESET_HAL_CALLS(lpDevI);
/*
* Create our context in the HAL driver */ if ((hr = lpDevI->halCreateContext()) != D3D_OK) { return hr; } // Initialize the transform and lighting state
D3DMATRIXI m; setIdentity(&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_VIEW, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_WORLD1, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_WORLD2, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_WORLD3, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_TEXTURE0, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_TEXTURE1, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_TEXTURE2, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_TEXTURE3, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_TEXTURE4, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_TEXTURE5, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_TEXTURE6, (D3DMATRIX*)&m); lpDevI->SetTransformI(D3DTRANSFORMSTATE_TEXTURE7, (D3DMATRIX*)&m);
LIST_INITIALIZE(&lpDevI->specular_tables); lpDevI->specular_table = NULL;
lpDevI->lightVertexFuncTable = &lightVertexTable; lpDevI->lighting.activeLights = NULL;
lpDevI->iClipStatus = D3DSTATUS_DEFAULT; lpDevI->rExtents.x1 = D3DVAL(2048); lpDevI->rExtents.x2 = D3DVAL(0); lpDevI->rExtents.y1 = D3DVAL(2048); lpDevI->rExtents.y2 = D3DVAL(0);
return S_OK; }
void D3DFE_Destroy(LPDIRECT3DDEVICEI lpDevI) { // Destroy lighting data
SpecularTable *spec; SpecularTable *spec_next;
for (spec = LIST_FIRST(&lpDevI->specular_tables); spec; spec = spec_next) { spec_next = LIST_NEXT(spec,list); D3DFree(spec); }
if(lpDevI->lpClipper) { lpDevI->lpClipper->Release(); }
delete [] lpDevI->m_pLights;
if (lpDevI->lpD3DHALCallbacks) { halDestroyContext(lpDevI); }
#ifdef TRACK_HAL_CALLS
D3D_INFO(0, "Made %d HAL calls", lpDevI->hal_calls); #endif
}
void BltFillRects(LPDIRECT3DDEVICEI lpDevI, DWORD count, LPD3DRECT rect, D3DCOLOR dwFillColor) { LPDIRECTDRAWSURFACE lpDDS = lpDevI->lpDDSTarget; HRESULT ddrval; DDBLTFX bltfx; RECT tr; DWORD i; DWORD r, g, b, a;
// Fill with background color
memset(&bltfx, 0, sizeof(bltfx)); bltfx.dwSize = sizeof(bltfx);
// unlike clear callback, which just takes pure 32-bit ARGB word and forces the driver to scale it for
// the pixelformat, here we need to compute the exact fill word, depending on surface's R,G,B bitmasks
if(lpDevI->bDDSTargetIsPalettized) { // map 24-bit color to 8-bit index used by 8bit RGB rasterizer
CallRastService(lpDevI, RAST_SERVICE_RGB8COLORTOPIXEL, dwFillColor, &bltfx.dwFillColor); } else { DDASSERT((lpDevI->red_scale!=0)&&(lpDevI->green_scale!=0)&&(lpDevI->blue_scale!=0)); r = RGB_GETRED(dwFillColor) / lpDevI->red_scale; g = RGB_GETGREEN(dwFillColor) / lpDevI->green_scale; b = RGB_GETBLUE(dwFillColor) / lpDevI->blue_scale; bltfx.dwFillColor = (r << lpDevI->red_shift) | (g << lpDevI->green_shift) | (b << lpDevI->blue_shift); if( lpDevI->alpha_scale!=0 ) { a = RGBA_GETALPHA(dwFillColor) / lpDevI->alpha_scale; bltfx.dwFillColor |= (a << lpDevI->alpha_shift); } }
for (i = 0; i < count; i++,rect++) { tr.left = rect->x1; tr.right = rect->x2; tr.top = rect->y1; tr.bottom = rect->y2; do { ddrval = lpDDS->Blt(&tr, NULL, NULL, DDBLT_COLORFILL, &bltfx); } while (ddrval == DDERR_WASSTILLDRAWING); } }
void BltFillZRects(LPDIRECT3DDEVICEI lpDevI, unsigned long Zpixel, DWORD count, LPD3DRECT rect, DWORD dwWriteMask) { HRESULT ddrval; DDBLTFX bltfx; DWORD i; RECT tr; DWORD dwExtraFlags=0;
#if DBG
if (lpDevI->lpDDSZBuffer == NULL) // should be checked prior to call
return; #endif
memset(&bltfx, 0, sizeof(DDBLTFX)); bltfx.dwSize = sizeof(DDBLTFX); bltfx.dwFillDepth = Zpixel;
// hack to pass DepthBlt WriteMask through ddraw/ddhel to blitlib
if(dwWriteMask!=0) { bltfx.dwZDestConstBitDepth=dwWriteMask; dwExtraFlags = DDBLT_DEPTHFILLWRITEMASK; }
for(i=0;i<count;i++,rect++) { D3D_INFO(4, "Z Clearing x1 = %d, y1 = %d, x2 = %d, y2 = %d, WriteMask %X", rect->x1, rect->y1, rect->x2, rect->y2, bltfx.dwReserved); tr.left = rect->x1; tr.right = rect->x2; tr.top = rect->y1; tr.bottom = rect->y2; do { ddrval = lpDevI->lpDDSZBuffer->Blt(&tr, NULL, NULL, DDBLT_DEPTHFILL | dwExtraFlags, &bltfx); } while (ddrval == DDERR_WASSTILLDRAWING); } }
//---------------------------------------------------------------------
struct CHandle { DWORD m_Next; // Used to make list of free handles
#if DBG
DWORD m_Tag; // 1 - empty; 2 = taken
#endif
};
CHandleFactory::~CHandleFactory() { if (m_Handles) delete m_Handles; }
HRESULT CHandleFactory::Init(DWORD dwInitialSize, DWORD dwGrowSize) { m_Handles = CreateHandleArray(dwInitialSize); if (m_Handles == NULL) return DDERR_OUTOFMEMORY; m_dwArraySize = dwInitialSize; m_dwGrowSize = dwGrowSize; m_Free = 0; return D3D_OK; }
DWORD CHandleFactory::CreateNewHandle() { DWORD handle = m_Free; if (m_Free != __INVALIDHANDLE) { m_Free = m_Handles[m_Free].m_Next; } else { handle = m_dwArraySize; m_Free = m_dwArraySize + 1; m_dwArraySize += m_dwGrowSize; CHandle * newHandles = CreateHandleArray(m_dwArraySize); #if DBG
memcpy(newHandles, m_Handles, (m_dwArraySize - m_dwGrowSize)*sizeof(CHandle)); #endif
delete m_Handles; m_Handles = newHandles; } DDASSERT(m_Handles[handle].m_Tag == 1); #if DBG
m_Handles[handle].m_Tag = 2; // Mark as taken
#endif
return handle; }
void CHandleFactory::ReleaseHandle(DWORD handle) { DDASSERT(handle < m_dwArraySize); DDASSERT(m_Handles[handle].m_Tag == 2); #if DBG
m_Handles[handle].m_Tag = 1; // Mark as empty
#endif
m_Handles[handle].m_Next = m_Free; m_Free = handle; }
CHandle* CHandleFactory::CreateHandleArray(DWORD dwSize) { CHandle *handles = new CHandle[dwSize]; DDASSERT(handles != NULL); if ( NULL == handles ) return NULL; for (DWORD i=0; i < dwSize; i++) { handles[i].m_Next = i+1; #if DBG
handles[i].m_Tag = 1; // Mark as empty
#endif
} handles[dwSize-1].m_Next = __INVALIDHANDLE; return handles; }
|