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