/*===========================================================================*/ | |
/* */ | |
/* Mesa-3.0 DirectX 6 Driver */ | |
/* */ | |
/* By Leigh McRae */ | |
/* */ | |
/* http://www.altsoftware.com/ */ | |
/* */ | |
/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ | |
/*===========================================================================*/ | |
#include "D3DHAL.h" | |
/*===========================================================================*/ | |
/* Local only functions. */ | |
/*===========================================================================*/ | |
static int CountTrailingZeros( DWORD dwMask ); | |
/*===========================================================================*/ | |
/* This function is used to get the pointer to the surface and the pitch for*/ | |
/* the scanline rendering functions. */ | |
/*===========================================================================*/ | |
/* RETURN: */ | |
/*===========================================================================*/ | |
extern "C" DDSURFACEDESC2 *LockHAL( PMESAD3DSHARED pShared, BOOL bBack ) | |
{ | |
PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; | |
static DDSURFACEDESC2 ddsd2; | |
HRESULT rc; | |
DPF(( DBG_FUNC, "LockHAL();" )); | |
/* Set the request structure up first. */ | |
memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); | |
ddsd2.dwSize = sizeof(DDSURFACEDESC2); | |
/* Make sure we have enough info. */ | |
if ( pHAL ) | |
{ | |
rc = pHAL->lpDDSRender->Lock( NULL, &ddsd2, DDLOCK_WAIT, NULL ); | |
if ( FAILED(rc) ) | |
{ | |
RIP( pHAL, "Lock (RENDER) ->", ErrorStringD3D(rc) ); | |
} | |
} | |
return &ddsd2; | |
} | |
/*===========================================================================*/ | |
/* This is just a simple wrapper. I probably don't need to do any error */ | |
/* checking as the Lock must have worked inorder to get here... */ | |
/*===========================================================================*/ | |
/* RETURN: */ | |
/*===========================================================================*/ | |
extern "C" void UnlockHAL( PMESAD3DSHARED pShared, BOOL bBack ) | |
{ | |
PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; | |
HRESULT rc; | |
DPF(( DBG_FUNC, "UnlockHAL();" )); | |
/* Make sure we have enough info. */ | |
if ( pHAL ) | |
{ | |
rc = pHAL->lpDDSRender->Unlock( NULL ); | |
if ( FAILED(rc) ) | |
{ | |
RIP( pHAL, "Unlock (RENDER) ->", ErrorStringD3D(rc) ); | |
} | |
} | |
} | |
/*===========================================================================*/ | |
/* This function will track the main/Primary window that will be used as the*/ | |
/* target for the Blt in SwapBuffers. As a side effect the call will check */ | |
/* to see if the primary surface is the same size and position as the screen.*/ | |
/* If they are the same size we will call it fullscreen... */ | |
/*===========================================================================*/ | |
/* RETURN: */ | |
/*===========================================================================*/ | |
extern "C" void UpdateScreenPosHAL( PMESAD3DSHARED pShared ) | |
{ | |
PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; | |
POINT pt; | |
DWORD dwWidth, dwHeight; | |
DPF(( DBG_FUNC, "UpdateScreenPosHAL();" )); | |
/* Make sure we have enough info. */ | |
if ( pHAL != NULL ) | |
{ | |
/* Update the windows screen position. */ | |
GetClientRect( pShared->hwnd, &pShared->rectW ); | |
pt.x = pt.y = 0; | |
ClientToScreen( pShared->hwnd, &pt ); | |
OffsetRect( &pShared->rectW, pt.x, pt.y); | |
/* Compare the primary to the screen. */ | |
dwWidth = GetSystemMetrics( SM_CXSCREEN ); | |
dwHeight = GetSystemMetrics( SM_CYSCREEN ); | |
if ( (pShared->rectW.left > 0) || (pShared->rectW.top > 0) || | |
(pShared->rectW.right > dwWidth) || (pShared->rectW.bottom > dwHeight) ) | |
pShared->bWindow = TRUE; | |
else | |
pShared->bWindow = FALSE; | |
} | |
} | |
/*===========================================================================*/ | |
/* This function will fill in the pixel info structure defined in D3Dshared.*/ | |
/* Basicly it will take a DirectDraw pixelformat structure and make scaling */ | |
/* values that will convert from 8bit channels to whatever the supplied ddpf */ | |
/* uses. Also we will generate shift values that will be used to get move */ | |
/* each component of the pixel into place. */ | |
/* I have now added a special case for a 1bit alpha channel. If I find a 1b*/ | |
/* alpha then I will set the scale to -1.0 which should be unique. Later I */ | |
/* can check the alpha scale value too see if its -1.0 and thus handle it. I*/ | |
/* was finding that the case was not working tom my advantage so this is my */ | |
/* HACK for the day. As a TODO I should work on this... */ | |
/*===========================================================================*/ | |
/* RETURN: */ | |
/*===========================================================================*/ | |
void Solve8BitChannelPixelFormat( DDPIXELFORMAT *pddpf, PPIXELINFO pPixel ) | |
{ | |
DPF(( DBG_FUNC, "Solve8BitChannelPixelFromat();" )); | |
memset( pPixel, 0, sizeof(PPIXELINFO) ); | |
/* Check too see if the color space is valid in the PF. */ | |
if ( pddpf->dwFlags & DDPF_RGB ) | |
{ | |
/* Solve the red stuff. */ | |
pPixel->dwRMask = pddpf->dwRBitMask; | |
pPixel->rShift = CountTrailingZeros( pPixel->dwRMask ); | |
pPixel->rScale = (float)0.00392156 * (float)(pPixel->dwRMask >> pPixel->rShift); | |
/* Solve the green thingy's. */ | |
pPixel->dwGMask = pddpf->dwGBitMask; | |
pPixel->gShift = CountTrailingZeros( pPixel->dwGMask ); | |
pPixel->gScale = (float)0.00392156 * (float)(pPixel->dwGMask >> pPixel->gShift); | |
/* Solve the blues. */ | |
pPixel->dwBMask = pddpf->dwBBitMask; | |
pPixel->bShift = CountTrailingZeros( pddpf->dwBBitMask ); | |
pPixel->bScale = (float)0.00392156 * (float)(pddpf->dwBBitMask >> pPixel->bShift); | |
} | |
/* Do the alpha channel if there is one. */ | |
if ( pddpf->dwFlags & DDPF_ALPHAPIXELS ) | |
{ | |
pPixel->dwAMask = pddpf->dwRGBAlphaBitMask; | |
pPixel->aShift = CountTrailingZeros( pPixel->dwAMask ); | |
/* Special case a 1bit alpha. */ | |
if ( (pPixel->dwAMask >> pPixel->aShift) == 1 ) | |
pPixel->aScale = -1.0; | |
else | |
pPixel->aScale = (float)0.00392156 * (float)(pPixel->dwAMask >> pPixel->aShift); | |
} | |
/* Get the size of the pixel in bytes. Should work as dwRGBBitCount is in a union. */ | |
pPixel->cb = pddpf->dwRGBBitCount / 8; | |
} | |
/*===========================================================================*/ | |
/* See RETURN :) */ | |
/*===========================================================================*/ | |
/* RETURN: number of contiguous zeros starting from the right. */ | |
/*===========================================================================*/ | |
static int CountTrailingZeros( DWORD dwMask ) | |
{ | |
DWORD Mask; | |
if ( dwMask == 0 ) | |
return 32; | |
/* Can't take credit for this one! */ | |
Mask = dwMask & -(int)dwMask; | |
return ((Mask & 0xFFFF0000)!=0) << 4 | |
| ((Mask & 0xFF00FF00)!=0) << 3 | |
| ((Mask & 0xF0F0F0F0)!=0) << 2 | |
| ((Mask & 0xCCCCCCCC)!=0) << 1 | |
| ((Mask & 0xAAAAAAAA)!=0); | |
} | |
/*===========================================================================*/ | |
/* This function will convert the DDraw error code to its macro string. The*/ | |
/* returned pointer is static so you need not worry about memory managemnet */ | |
/* but the error message gets written over from call to call... */ | |
/*===========================================================================*/ | |
/* RETURN: pointer to the single static buffer that hold the error message. */ | |
/*===========================================================================*/ | |
char *ErrorStringD3D( HRESULT hr ) | |
{ | |
static char errorString[128]; | |
switch( hr ) | |
{ | |
case DDERR_ALREADYINITIALIZED: | |
strcpy( errorString, "DDERR_ALREADYINITIALIZED" ); | |
break; | |
case DDERR_CANNOTATTACHSURFACE: | |
strcpy( errorString, "DDERR_CANNOTATTACHSURFACE" ); | |
break; | |
case DDERR_CANNOTDETACHSURFACE: | |
strcpy( errorString, "DDERR_CANNOTDETACHSURFACE" ); | |
break; | |
case DDERR_CURRENTLYNOTAVAIL: | |
strcpy( errorString, "DDERR_CURRENTLYNOTAVAIL" ); | |
break; | |
case DDERR_EXCEPTION: | |
strcpy( errorString, "DDERR_EXCEPTION" ); | |
break; | |
case DDERR_GENERIC: | |
strcpy( errorString, "DDERR_GENERIC" ); | |
break; | |
case DDERR_HEIGHTALIGN: | |
strcpy( errorString, "DDERR_HEIGHTALIGN" ); | |
break; | |
case DDERR_INCOMPATIBLEPRIMARY: | |
strcpy( errorString, "DDERR_INCOMPATIBLEPRIMARY" ); | |
break; | |
case DDERR_INVALIDCAPS: | |
strcpy( errorString, "DDERR_INVALIDCAPS" ); | |
break; | |
case DDERR_INVALIDCLIPLIST: | |
strcpy( errorString, "DDERR_INVALIDCLIPLIST" ); | |
break; | |
case DDERR_INVALIDMODE: | |
strcpy( errorString, "DDERR_INVALIDMODE" ); | |
break; | |
case DDERR_INVALIDOBJECT: | |
strcpy( errorString, "DDERR_INVALIDOBJECT" ); | |
break; | |
case DDERR_INVALIDPARAMS: | |
strcpy( errorString, "DDERR_INVALIDPARAMS" ); | |
break; | |
case DDERR_INVALIDPIXELFORMAT: | |
strcpy( errorString, "DDERR_INVALIDPIXELFORMAT" ); | |
break; | |
case DDERR_INVALIDRECT: | |
strcpy( errorString, "DDERR_INVALIDRECT" ); | |
break; | |
case DDERR_LOCKEDSURFACES: | |
strcpy( errorString, "DDERR_LOCKEDSURFACES" ); | |
break; | |
case DDERR_NO3D: | |
strcpy( errorString, "DDERR_NO3D" ); | |
break; | |
case DDERR_NOALPHAHW: | |
strcpy( errorString, "DDERR_NOALPHAHW" ); | |
break; | |
case DDERR_NOCLIPLIST: | |
strcpy( errorString, "DDERR_NOCLIPLIST" ); | |
break; | |
case DDERR_NOCOLORCONVHW: | |
strcpy( errorString, "DDERR_NOCOLORCONVHW" ); | |
break; | |
case DDERR_NOCOOPERATIVELEVELSET: | |
strcpy( errorString, "DDERR_NOCOOPERATIVELEVELSET" ); | |
break; | |
case DDERR_NOCOLORKEY: | |
strcpy( errorString, "DDERR_NOCOLORKEY" ); | |
break; | |
case DDERR_NOCOLORKEYHW: | |
strcpy( errorString, "DDERR_NOCOLORKEYHW" ); | |
break; | |
case DDERR_NODIRECTDRAWSUPPORT: | |
strcpy( errorString, "DDERR_NODIRECTDRAWSUPPORT" ); | |
break; | |
case DDERR_NOEXCLUSIVEMODE: | |
strcpy( errorString, "DDERR_NOEXCLUSIVEMODE" ); | |
break; | |
case DDERR_NOFLIPHW: | |
strcpy( errorString, "DDERR_NOFLIPHW" ); | |
break; | |
case DDERR_NOGDI: | |
strcpy( errorString, "DDERR_NOGDI" ); | |
break; | |
case DDERR_NOMIRRORHW: | |
strcpy( errorString, "DDERR_NOMIRRORHW" ); | |
break; | |
case DDERR_NOTFOUND: | |
strcpy( errorString, "DDERR_NOTFOUND" ); | |
break; | |
case DDERR_NOOVERLAYHW: | |
strcpy( errorString, "DDERR_NOOVERLAYHW" ); | |
break; | |
case DDERR_OVERLAPPINGRECTS: | |
strcpy( errorString, "DDERR_OVERLAPPINGRECTS" ); | |
break; | |
case DDERR_NORASTEROPHW: | |
strcpy( errorString, "DDERR_NORASTEROPHW" ); | |
break; | |
case DDERR_NOROTATIONHW: | |
strcpy( errorString, "DDERR_NOROTATIONHW" ); | |
break; | |
case DDERR_NOSTRETCHHW: | |
strcpy( errorString, "DDERR_NOSTRETCHHW" ); | |
break; | |
case DDERR_NOT4BITCOLOR: | |
strcpy( errorString, "DDERR_NOT4BITCOLOR" ); | |
break; | |
case DDERR_NOT4BITCOLORINDEX: | |
strcpy( errorString, "DDERR_NOT4BITCOLORINDEX" ); | |
break; | |
case DDERR_NOT8BITCOLOR: | |
strcpy( errorString, "DDERR_NOT8BITCOLOR" ); | |
break; | |
case DDERR_NOTEXTUREHW: | |
strcpy( errorString, "DDERR_NOTEXTUREHW" ); | |
break; | |
case DDERR_NOVSYNCHW: | |
strcpy( errorString, "DDERR_NOVSYNCHW" ); | |
break; | |
case DDERR_NOZBUFFERHW: | |
strcpy( errorString, "DDERR_NOZBUFFERHW" ); | |
break; | |
case DDERR_NOZOVERLAYHW: | |
strcpy( errorString, "DDERR_NOZOVERLAYHW" ); | |
break; | |
case DDERR_OUTOFCAPS: | |
strcpy( errorString, "DDERR_OUTOFCAPS" ); | |
break; | |
case DDERR_OUTOFMEMORY: | |
strcpy( errorString, "DDERR_OUTOFMEMORY" ); | |
break; | |
case DDERR_OUTOFVIDEOMEMORY: | |
strcpy( errorString, "DDERR_OUTOFVIDEOMEMORY" ); | |
break; | |
case DDERR_OVERLAYCANTCLIP: | |
strcpy( errorString, "DDERR_OVERLAYCANTCLIP" ); | |
break; | |
case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: | |
strcpy( errorString, "DDERR_OVERLAYCOLORKEYONLYONEACTIVE" ); | |
break; | |
case DDERR_PALETTEBUSY: | |
strcpy( errorString, "DDERR_PALETTEBUSY" ); | |
break; | |
case DDERR_COLORKEYNOTSET: | |
strcpy( errorString, "DDERR_COLORKEYNOTSET" ); | |
break; | |
case DDERR_SURFACEALREADYATTACHED: | |
strcpy( errorString, "DDERR_SURFACEALREADYATTACHED" ); | |
break; | |
case DDERR_SURFACEALREADYDEPENDENT: | |
strcpy( errorString, "DDERR_SURFACEALREADYDEPENDENT" ); | |
break; | |
case DDERR_SURFACEBUSY: | |
strcpy( errorString, "DDERR_SURFACEBUSY" ); | |
break; | |
case DDERR_CANTLOCKSURFACE: | |
strcpy( errorString, "DDERR_CANTLOCKSURFACE" ); | |
break; | |
case DDERR_SURFACEISOBSCURED: | |
strcpy( errorString, "DDERR_SURFACEISOBSCURED" ); | |
break; | |
case DDERR_SURFACELOST: | |
strcpy( errorString, "DDERR_SURFACELOST" ); | |
break; | |
case DDERR_SURFACENOTATTACHED: | |
strcpy( errorString, "DDERR_SURFACENOTATTACHED" ); | |
break; | |
case DDERR_TOOBIGHEIGHT: | |
strcpy( errorString, "DDERR_TOOBIGHEIGHT" ); | |
break; | |
case DDERR_TOOBIGSIZE: | |
strcpy( errorString, "DDERR_TOOBIGSIZE" ); | |
break; | |
case DDERR_TOOBIGWIDTH: | |
strcpy( errorString, "DDERR_TOOBIGWIDTH" ); | |
break; | |
case DDERR_UNSUPPORTED: | |
strcpy( errorString, "DDERR_UNSUPPORTED" ); | |
break; | |
case DDERR_UNSUPPORTEDFORMAT: | |
strcpy( errorString, "DDERR_UNSUPPORTEDFORMAT" ); | |
break; | |
case DDERR_UNSUPPORTEDMASK: | |
strcpy( errorString, "DDERR_UNSUPPORTEDMASK" ); | |
break; | |
case DDERR_INVALIDSTREAM: | |
strcpy( errorString, "DDERR_INVALIDSTREAM" ); | |
break; | |
case DDERR_VERTICALBLANKINPROGRESS: | |
strcpy( errorString, "DDERR_VERTICALBLANKINPROGRESS" ); | |
break; | |
case DDERR_WASSTILLDRAWING: | |
strcpy( errorString, "DDERR_WASSTILLDRAWING" ); | |
break; | |
case DDERR_XALIGN: | |
strcpy( errorString, "DDERR_XALIGN" ); | |
break; | |
case DDERR_INVALIDDIRECTDRAWGUID: | |
strcpy( errorString, "DDERR_INVALIDDIRECTDRAWGUID" ); | |
break; | |
case DDERR_DIRECTDRAWALREADYCREATED: | |
strcpy( errorString, "DDERR_DIRECTDRAWALREADYCREATED" ); | |
break; | |
case DDERR_NODIRECTDRAWHW: | |
strcpy( errorString, "DDERR_NODIRECTDRAWHW" ); | |
break; | |
case DDERR_PRIMARYSURFACEALREADYEXISTS: | |
strcpy( errorString, "DDERR_PRIMARYSURFACEALREADYEXISTS" ); | |
break; | |
case DDERR_NOEMULATION: | |
strcpy( errorString, "DDERR_NOEMULATION" ); | |
break; | |
case DDERR_REGIONTOOSMALL: | |
strcpy( errorString, "DDERR_REGIONTOOSMALL" ); | |
break; | |
case DDERR_CLIPPERISUSINGHWND: | |
strcpy( errorString, "DDERR_CLIPPERISUSINGHWND" ); | |
break; | |
case DDERR_NOCLIPPERATTACHED: | |
strcpy( errorString, "DDERR_NOCLIPPERATTACHED" ); | |
break; | |
case DDERR_NOHWND: | |
strcpy( errorString, "DDERR_NOHWND" ); | |
break; | |
case DDERR_HWNDSUBCLASSED: | |
strcpy( errorString, "DDERR_HWNDSUBCLASSED" ); | |
break; | |
case DDERR_HWNDALREADYSET: | |
strcpy( errorString, "DDERR_HWNDALREADYSET" ); | |
break; | |
case DDERR_NOPALETTEATTACHED: | |
strcpy( errorString, "DDERR_NOPALETTEATTACHED" ); | |
break; | |
case DDERR_NOPALETTEHW: | |
strcpy( errorString, "DDERR_NOPALETTEHW" ); | |
break; | |
case DDERR_BLTFASTCANTCLIP: | |
strcpy( errorString, "DDERR_BLTFASTCANTCLIP" ); | |
break; | |
case DDERR_NOBLTHW: | |
strcpy( errorString, "DDERR_NOBLTHW" ); | |
break; | |
case DDERR_NODDROPSHW: | |
strcpy( errorString, "DDERR_NODDROPSHW" ); | |
break; | |
case DDERR_OVERLAYNOTVISIBLE: | |
strcpy( errorString, "DDERR_OVERLAYNOTVISIBLE" ); | |
break; | |
case DDERR_NOOVERLAYDEST: | |
strcpy( errorString, "DDERR_NOOVERLAYDEST" ); | |
break; | |
case DDERR_INVALIDPOSITION: | |
strcpy( errorString, "DDERR_INVALIDPOSITION" ); | |
break; | |
case DDERR_NOTAOVERLAYSURFACE: | |
strcpy( errorString, "DDERR_NOTAOVERLAYSURFACE" ); | |
break; | |
case DDERR_EXCLUSIVEMODEALREADYSET: | |
strcpy( errorString, "DDERR_EXCLUSIVEMODEALREADYSET" ); | |
break; | |
case DDERR_NOTFLIPPABLE: | |
strcpy( errorString, "DDERR_NOTFLIPPABLE" ); | |
break; | |
case DDERR_CANTDUPLICATE: | |
strcpy( errorString, "DDERR_CANTDUPLICATE" ); | |
break; | |
case DDERR_NOTLOCKED: | |
strcpy( errorString, "DDERR_NOTLOCKED" ); | |
break; | |
case DDERR_CANTCREATEDC: | |
strcpy( errorString, "DDERR_CANTCREATEDC" ); | |
break; | |
case DDERR_NODC: | |
strcpy( errorString, "DDERR_NODC" ); | |
break; | |
case DDERR_WRONGMODE: | |
strcpy( errorString, "DDERR_WRONGMODE" ); | |
break; | |
case DDERR_IMPLICITLYCREATED: | |
strcpy( errorString, "DDERR_IMPLICITLYCREATED" ); | |
break; | |
case DDERR_NOTPALETTIZED: | |
strcpy( errorString, "DDERR_NOTPALETTIZED" ); | |
break; | |
case DDERR_UNSUPPORTEDMODE: | |
strcpy( errorString, "DDERR_UNSUPPORTEDMODE" ); | |
break; | |
case DDERR_NOMIPMAPHW: | |
strcpy( errorString, "DDERR_NOMIPMAPHW" ); | |
break; | |
case DDERR_INVALIDSURFACETYPE: | |
strcpy( errorString, "DDERR_INVALIDSURFACETYPE" ); | |
break; | |
case DDERR_NOOPTIMIZEHW: | |
strcpy( errorString, "DDERR_NOOPTIMIZEHW" ); | |
break; | |
case DDERR_NOTLOADED: | |
strcpy( errorString, "DDERR_NOTLOADED" ); | |
break; | |
case DDERR_NOFOCUSWINDOW: | |
strcpy( errorString, "DDERR_NOFOCUSWINDOW" ); | |
break; | |
case DDERR_DCALREADYCREATED: | |
strcpy( errorString, "DDERR_DCALREADYCREATED" ); | |
break; | |
case DDERR_NONONLOCALVIDMEM: | |
strcpy( errorString, "DDERR_NONONLOCALVIDMEM" ); | |
break; | |
case DDERR_CANTPAGELOCK: | |
strcpy( errorString, "DDERR_CANTPAGELOCK" ); | |
break; | |
case DDERR_CANTPAGEUNLOCK: | |
strcpy( errorString, "DDERR_CANTPAGEUNLOCK" ); | |
break; | |
case DDERR_NOTPAGELOCKED: | |
strcpy( errorString, "DDERR_NOTPAGELOCKED" ); | |
break; | |
case DDERR_MOREDATA: | |
strcpy( errorString, "DDERR_MOREDATA" ); | |
break; | |
case DDERR_EXPIRED: | |
strcpy( errorString, "DDERR_EXPIRED" ); | |
break; | |
case DDERR_VIDEONOTACTIVE: | |
strcpy( errorString, "DDERR_VIDEONOTACTIVE" ); | |
break; | |
case DDERR_DEVICEDOESNTOWNSURFACE: | |
strcpy( errorString, "DDERR_DEVICEDOESNTOWNSURFACE" ); | |
break; | |
case DDERR_NOTINITIALIZED: | |
strcpy( errorString, "DDERR_NOTINITIALIZED" ); | |
break; | |
default: | |
strcpy( errorString, "<unknown error code>" ); | |
break; | |
} | |
return &errorString[0]; | |
} | |