/*===========================================================================*/ /* */ /* 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]; }