/* $Id: surface.cpp,v 1.4 2002-12-30 14:05:43 sandervl Exp $ */ /* * DirectDraw Surface class implementaion * * Copyright 1999 Markus Montkowski * Copyright 2000 Michal Necasek * Copyright 1998-2001 Sander van Leeuwen * * Project Odin Software License can be found in LICENSE.TXT * */ #define _OS2WIN_H #define FAR #include #include #include #include #include #define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \ ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) ) #include #define CINTERFACE #include "ddraw2d.h" #include "clipper.h" #include "palette.h" #include "surface.h" #include "surfacehlp.h" #include "os2util.h" #include "rectangle.h" #include #include "asmutil.h" #include "bltFunc.h" #include "colorconv.h" #include "fillfunc.h" #include #include #include #include "asmutil.h" #include "wndproc.h" #ifdef __IBMC__ #include #endif extern IDirectDrawSurface4Vtbl DDrawSurfaceV4Table; extern IDirectDrawSurface3Vtbl DDrawSurfaceV3Table; extern IDirectDrawSurface2Vtbl DDrawSurfaceV2Table; //****************************************************************************** //****************************************************************************** OS2IDirectDrawSurface::OS2IDirectDrawSurface(OS2IDirectDraw *lpDirectDraw, LPDDSURFACEDESC2 lpDDSurfaceDesc, BOOL Implicit, BOOL Mainchain) : Referenced(0), lastError(DD_OK), diveBufNr(-1), lpClipper(NULL), lpPalette(NULL), lpDraw(NULL), fLocked(FALSE), hdcImage(NULL), hbmImage(NULL), pFrameBuffer(NULL),Updated(FALSE), fOverlayValid(FALSE), BackBuffer(NULL),FrontBuffer(NULL), pDBreal(NULL),pFBreal(NULL), hwndFullScreen(0) { DWORD rc; DDSURFACEDESC2 ComplexSurfaceDesc; OS2IDirectDrawSurface *MipMapSurface; memset(&sBlt, 0, sizeof(sBlt)); lpVtbl = &Vtbl2; lpVtbl2 = &Vtbl2; dwUnknownData = 0xDEADDEAD; //copy DirectDraw V2, V3 & V4 tables Vtbl = DDrawSurfaceV4Table; Vtbl3 = DDrawSurfaceV3Table; Vtbl2 = DDrawSurfaceV2Table; lpDraw = lpDirectDraw; lpDraw->Vtbl.fnAddRef(lpDraw); ImplicitSurface = Implicit; hDive = lpDirectDraw->GetDiveInstance(); hDiveCC = lpDirectDraw->GetCCDiveInstance(); surfaceType = DDSCAPS_OFFSCREENPLAIN; memcpy((char *)&DDSurfaceDesc, (char *)lpDDSurfaceDesc, sizeof(DDSURFACEDESC2)); dprintf(("Pixel format:")); _dump_pixelformat(&lpDDSurfaceDesc->ddpfPixelFormat); dprintf(("Capabilities")); _dump_DDSCAPS(lpDDSurfaceDesc->ddsCaps.dwCaps); _dump_DDSCAPS2(lpDDSurfaceDesc->ddsCaps.dwCaps2); if(lpDraw->dCaps.ulDepth != 15) { if(lpDraw->dCaps.ulDepth >= 8) dwBytesPPDive = lpDraw->dCaps.ulDepth >> 3; else dwBytesPPDive = 1; // not sure if this is the case } else dwBytesPPDive = 2; // 2 bytes for 15Bit // Setting up Cursors for handling attached Surfaces DPA_SurfaceMipMaps = DPA_Create(8); if(NULL==DPA_SurfaceMipMaps) { dprintf(("DDRAW: Internal : Error creating DPA for MipMaps\n")); lastError = DDERR_OUTOFMEMORY ; return; } DPA_SurfaceAttached = DPA_Create(8); if(NULL==DPA_SurfaceAttached) { dprintf(("DDRAW: Internal : Error creating DPA for attached surfaces\n")); lastError = DDERR_OUTOFMEMORY ; return; } DPA_LockedRects = DPA_Create(8); if(NULL==DPA_LockedRects) { dprintf(("DDRAW: Internal : Error creating DPA for Locked Rectangles\n")); lastError = DDERR_OUTOFMEMORY ; return; } DPA_SurfacePrivateData = DPA_Create(8); if(NULL==DPA_SurfacePrivateData) { dprintf(("DDRAW: Internal : Error creating DPA for private surface Data\n")); lastError = DDERR_OUTOFMEMORY ; return; } switch(lpDraw->GetScreenBpp()) { case 8: switch(lpDraw->dCaps.ulDepth) { case 8: BltSolid = &BltSolid8to8; ColorConv = NULL; ColorFill = &Fill8on8; break; case 16: BltSolid = &BltSolid8to16; ColorConv = &Conv8to16; ColorFill = &Fill8on16; break; case 24: BltSolid = &BltSolid8to24; ColorConv = &Conv8to24; ColorFill = &Fill8on24; break; case 32: BltSolid = &BltSolid8to32; ColorConv = &Conv8to32; ColorFill = &Fill8on32; break; default: dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth)); BltSolid = NULL; ColorConv = NULL; ColorFill = NULL; break; } break; case 16: switch(lpDraw->dCaps.ulDepth) { case 8: BltSolid = &BltSolid16to8; ColorConv = &Conv16to8; ColorFill = &Fill16on8; break; case 16: BltSolid = &BltSolid16to16; ColorConv = NULL; ColorFill = &Fill16on16; break; case 24: BltSolid = &BltSolid16to24; ColorConv = &Conv16to24; ColorFill = &Fill16on24; break; case 32: BltSolid = &BltSolid16to32; ColorConv = &Conv16to32; ColorFill = &Fill16on32; break; default: dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth)); BltSolid = NULL; ColorConv = NULL; ColorFill = NULL; break; } break; case 24: switch(lpDraw->dCaps.ulDepth) { case 8: BltSolid = &BltSolid24to8; ColorConv = &Conv24to8; ColorFill = &Fill24on8; break; case 16: BltSolid = &BltSolid24to16; ColorConv = &Conv24to16; ColorFill = &Fill24on16; break; case 24: BltSolid = &BltSolid24to24; ColorConv = NULL; ColorFill = &Fill24on24; break; case 32: BltSolid = &BltSolid24to32; ColorConv = &Conv24to32; ColorFill = &Fill24on32; break; default: dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth)); BltSolid = NULL; ColorConv = NULL; ColorFill = NULL; break; } break; case 32: switch(lpDraw->dCaps.ulDepth) { case 8: BltSolid = &BltSolid32to8; ColorConv = &Conv32to8; ColorFill = &Fill32on8; break; case 16: BltSolid = &BltSolid32to16; ColorConv = &Conv32to16; ColorFill = &Fill32on16; break; case 24: BltSolid = &BltSolid32to24; ColorConv = &Conv32to24; ColorFill = &Fill32on24; break; case 32: BltSolid = &BltSolid32to32; ColorConv = NULL; ColorFill = &Fill32on32; break; default: dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth)); BltSolid = NULL; ColorConv = NULL; ColorFill = NULL; break; } break; default: dprintf(("DDRAW: Unsupported DX ColorDepth %d",lpDraw->GetScreenBpp())); BltSolid = NULL; ColorConv = NULL; ColorFill = NULL; break; } // hack set DDSD_CAPS if the value is other than 0 if( DDSurfaceDesc.ddsCaps.dwCaps) DDSurfaceDesc.dwFlags |= DDSD_CAPS; if( DDSurfaceDesc.dwFlags & DDSD_CAPS ) { #if 0 //TODO: Docs say this is done, but does it really happen in windows? // check for invalid flag combinations switch(lpDDSurfaceDesc->ddsCaps.dwCaps2 & (DDSCAPS2_OPAQUE|DDSCAPS2_HINTDYNAMIC|DDSCAPS2_HINTSTATIC)) { case 0: case DDSCAPS2_OPAQUE: case DDSCAPS2_HINTDYNAMIC: case DDSCAPS2_HINTSTATIC: break; default: dprintf(("DDRAW: Internal : illegal ddscaps2 flag combination (static/dynamic/opaque)")); lastError = DDERR_INVALIDCAPS ; return; } #endif // First check if we want to create a primary surface while the ddraw object already has one surfaceType = DDSurfaceDesc.ddsCaps.dwCaps; if( surfaceType & DDSCAPS_PRIMARYSURFACE) { dprintf(("DDRAW: Primary surface!\n")); if( lpDraw->HasPrimarySurface()) { dprintf(("DDRAW: Primary surface already exits!\n")); lastError = DDERR_PRIMARYSURFACEALREADYEXISTS; return; } if( (DDSurfaceDesc.dwFlags & DDSD_HEIGHT) || (DDSurfaceDesc.dwFlags & DDSD_WIDTH) || (DDSurfaceDesc.dwFlags & DDSD_PIXELFORMAT) ) { // Dx doc says passing width,height etc. for primary surface in not permitted!! dprintf(("DDRAW: Invalid parameters\n\n")); lastError = DDERR_INVALIDPARAMS; return; } // Check if OS/2 is running in the requested colormode diveBufNr = DIVE_BUFFER_SCREEN; if( lpDraw->dCaps.ulDepth == lpDraw->GetScreenBpp() ) { dprintf(("DDRAW: Direct Screen Access possible\n")); // Yes so direct access to framebuffer is possible pFrameBuffer = lpDraw->GetFrameBuffer(); pDiveBuffer = pFrameBuffer; dwPitchDB = lpDraw->dCaps.ulScanLineBytes; dwPitchFB = dwPitchDB; DDSurfaceDesc.lPitch = dwPitchDB; } else { // No so we create a virtual framebuffer which the program can access // and blit to the real framebuffer on Unlock to do color conversion dprintf( ("Need Color conversion %d => %d Bit\n", lpDraw->GetScreenBpp(), lpDraw->dCaps.ulDepth )); dwPitchFB = (lpDraw->GetScreenWidth() * lpDraw->GetScreenBpp() +7) & ~7; DDSurfaceDesc.lPitch = dwPitchFB; // 24 byte more to enable alignment and speed up blitting pFBreal = (char*)malloc( lpDraw->GetScreenHeight() * dwPitchFB + 24); pFrameBuffer = (char*)(((int)pFBreal + 7) & ~7); // align to QWORD // DiveBuffer points to real framebuffer dwPitchDB = lpDraw->dCaps.ulScanLineBytes; pDiveBuffer = lpDraw->GetFrameBuffer(); } // Update passed in and local Surface description dprintf(("DDRAW: Setting up Surface\n")); DDSurfaceDesc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_LPSURFACE | DDSD_PIXELFORMAT; DDSurfaceDesc.dwHeight = lpDraw->GetScreenHeight(); DDSurfaceDesc.dwWidth = lpDraw->GetScreenWidth(); DDSurfaceDesc.lpSurface = pFrameBuffer; DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE; lpDraw->SetPrimarySurface(TRUE); DDSurfaceDesc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); DDSurfaceDesc.ddpfPixelFormat.dwFourCC = (DWORD) lpDraw->GetScreenFourCC(); DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = lpDraw->GetScreenBpp(); switch(DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount) { case 4: DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4 | DDPF_RGB; break; case 8: DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_RGB; break; case 16: DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB; DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x0000F800; DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x000007E0; DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x0000001F; break; case 24: case 32: DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB; DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000; DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00; DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF; break; default: // Remove the Pixelformat flag DDSurfaceDesc.dwFlags &= ~DDSD_PIXELFORMAT; dprintf(("DDRAW: Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp())); break; } // end switch dprintf(("DDRAW: Surface set up, checking other Caps\n")); if( DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_COMPLEX) { dprintf(("DDRAW: Complex Surface\n")); if(DDSurfaceDesc.dwFlags & DDSD_BACKBUFFERCOUNT) { dprintf(("DDRAW: Backbuffer # = %d\n",DDSurfaceDesc.dwBackBufferCount)); memset( &ComplexSurfaceDesc, 0, sizeof(DDSURFACEDESC2)); ComplexSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2); ComplexSurfaceDesc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ComplexSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_FLIP; ComplexSurfaceDesc.dwHeight = DDSurfaceDesc.dwHeight; ComplexSurfaceDesc.dwWidth = DDSurfaceDesc.dwWidth; ComplexSurfaceDesc.ddpfPixelFormat.dwFlags = DDSurfaceDesc.ddpfPixelFormat.dwFlags; ComplexSurfaceDesc.ddpfPixelFormat.dwRBitMask = DDSurfaceDesc.ddpfPixelFormat.dwRBitMask; ComplexSurfaceDesc.ddpfPixelFormat.dwGBitMask = DDSurfaceDesc.ddpfPixelFormat.dwGBitMask; ComplexSurfaceDesc.ddpfPixelFormat.dwBBitMask = DDSurfaceDesc.ddpfPixelFormat.dwBBitMask; ComplexSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; if(DDSurfaceDesc.dwBackBufferCount>1) { ComplexSurfaceDesc.dwFlags |=DDSD_BACKBUFFERCOUNT; ComplexSurfaceDesc.dwBackBufferCount = DDSurfaceDesc.dwBackBufferCount -1; ComplexSurfaceDesc.ddsCaps.dwCaps|= DDSCAPS_COMPLEX; } BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, TRUE); BackBuffer->Vtbl.fnAddRef((IDirectDrawSurface *)BackBuffer); if (BackBuffer->GetLastError()==DD_OK) { dprintf(("DDRAW: created backbuffer")); // Our Primary Buffer is also the frontbuffer of a flipchain DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER | DDSCAPS_FLIP; BackBuffer->SetFrontBuffer(this); } else { dprintf(("DDRAW: Error creating backbuffer")); } } else { dprintf(("DDRAW: Unsupported Complex Surface\n")); _dump_DDSCAPS(DDSurfaceDesc.dwFlags); lastError = DDERR_OUTOFMEMORY; return; } //endif Backbuffer } // endif DDSCAPS_COMPLEX width = DDSurfaceDesc.dwWidth; height = DDSurfaceDesc.dwHeight; lpDraw->pPrimSurf = this; lastError = DD_OK; #if 0 //NOTE: This isn't working at all (interferes with mouse messages for application // window) //If in fullscreen mode, create transparent window covering the entire desktop if(lpDraw->GetCooperativeLevel() & DDSCL_FULLSCREEN) { DirectDrawSurface_RegisterClass(); hwndFullScreen = DirectDrawSurface_CreateWindow(DDSurfaceDesc.dwWidth, DDSurfaceDesc.dwHeight, lpDraw->GetClientWindow()); if(hwndFullScreen == 0) { DebugInt3(); lastError = DDERR_OUTOFMEMORY; } dprintf(("DDRAW: Created fullscreen transparent window %x", hwndFullScreen)); } #endif return; } // endif DDSCAPS_PRIMARYSURFACE // // ToDo : Do better calulation of Bitmap Size to support the compressed Bitmaps in Dx6 // if( (DDSurfaceDesc.dwFlags & DDSD_HEIGHT) && (DDSurfaceDesc.dwFlags & DDSD_WIDTH) ) { DWORD dwBpp; DWORD dwCaps; dprintf(( " Requested Size %dx%d\n", DDSurfaceDesc.dwWidth, DDSurfaceDesc.dwHeight)); if(DDSurfaceDesc.dwFlags & DDSD_PIXELFORMAT) // Pixelformat passed in ? { dprintf(("DDRAW: Pixelformat requested :")); // YES use it if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_RGB) { dwBpp = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; } else { if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) dwBpp = 8; else if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) dwBpp = 4; else if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_FOURCC) { dprintf(("DDRAW: Pixelformat FOURCC %4s", &DDSurfaceDesc.ddpfPixelFormat.dwFourCC)); switch(DDSurfaceDesc.ddpfPixelFormat.dwFourCC) { case FOURCC_RGB3: dwBpp = 24; break; case FOURCC_RGB4: dwBpp = 32; break; default: dprintf(("DDRAW: Unsupported FOURCC!")); lastError = DDERR_UNSUPPORTEDFORMAT; return; } } } } else { dprintf(("DDRAW: Use Screen Format :")); dwBpp = lpDraw->GetScreenBpp(); // No use Screenformat DDSurfaceDesc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); DDSurfaceDesc.ddpfPixelFormat.dwFourCC = (DWORD) lpDraw->GetScreenFourCC(); DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = dwBpp; switch(DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount) { case 4: DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4 | DDPF_RGB; break; case 8: DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_RGB; break; case 16: DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB; DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x0000F800; DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x000007E0; DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x0000001F; break; case 24: case 32: DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB; DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000; DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00; DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF; break; default: // Remove the Pixelformat flag DDSurfaceDesc.dwFlags &= ~DDSD_PIXELFORMAT; dprintf(("DDRAW: Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp())); break; } // end switch } dprintf(("DDRAW: %d Bits\n",dwBpp)); // three possible situaltions // 1. User supplied pointer to surface -> use it // 2. Delayed allocation of a texture -> don't alloc // 3. Normal allocation // After this check for complex flag. dwCaps = DDSurfaceDesc.ddsCaps.dwCaps; if(DDSurfaceDesc.dwFlags & DDSD_LPSURFACE) { // 1. dprintf(("DDRAW: Usersupplied Surface\n")); if(NULL==DDSurfaceDesc.lpSurface) { // pointer is NULL! Stupid user ;) lastError = DDERR_INVALIDPARAMS; return; } // User allocated the Buffer for the surface so we don't have to Updated = TRUE; // Set Flag to indicate User supplied buffer so we don't free it // As we allready copied the surface description we are done if the # of colors // of the surface is the same then the screen pFrameBuffer = (char*)DDSurfaceDesc.lpSurface; diveBufNr = -1; dwPitchFB = DDSurfaceDesc.lPitch; if( lpDraw->dCaps.ulDepth == dwBpp ) { // Yes No Colorconversion is needed so point to the same buffer dwPitchDB = dwPitchFB; pDiveBuffer = pFrameBuffer; } else { // No so we must create the Divebuffer to do the color conversion // and blit to the real framebuffer on Unlock to do color conversion dwPitchDB = (DDSurfaceDesc.dwWidth * dwBytesPPDive +7) & ~7; // 24 byte more to enable alignment and speed up blitting pDBreal = (char*)malloc( DDSurfaceDesc.dwHeight * dwPitchDB + 24); pDiveBuffer = (char*)(((int)pDBreal + 7) & ~7); // align to QWORD // Not sure if that is ok but we need this for translation // I hope no game uses YUV or such a crap DDSurfaceDesc.ddpfPixelFormat.dwFourCC = SupportedFourCCs[dwBpp>>3]; } } else { if(dwCaps & DDSCAPS_ALLOCONLOAD) { // 2. dprintf(("DDRAW: Alloc on Load Texture?!\n")); dwCaps &= ~DDSCAPS_ALLOCONLOAD; // remove flag // only allow this flag for textures if(!dwCaps & DDSCAPS_TEXTURE) { lastError = DDERR_INVALIDPARAMS; return; } dwCaps &= ~DDSCAPS_TEXTURE; // remove flag pFrameBuffer = NULL; pDiveBuffer = NULL; // This surface isn't allocated yet, but when the texture is loaded dprintf(("DDRAW: Warning : Delayed memory allocation on request\n")); DDSurfaceDesc.lpSurface = NULL; } else { // 3. dprintf(("DDRAW: Alloc now!\n")); DDSurfaceDesc.dwFlags = DDSurfaceDesc.dwFlags; dwPitchFB = DDSurfaceDesc.dwWidth * (dwBpp<8?1:dwBpp/8); //SvL: //align on dword boundary; makes it easier to deal with GetDIBits/SetDIBits (they //expect dword alignment) dwPitchFB = (dwPitchFB + 3) & ~3; // Align on DWords //// dwPitchFB = (dwPitchFB +7) & ~7; // Align on QWords DDSurfaceDesc.lPitch = dwPitchFB; if(dwBpp<8) { dprintf(("DDRAW: 1 or 4 Bit Surface encountered may not work !")); } // 24 byte more to enable alignment and speed up blitting pFBreal = (char*)malloc( DDSurfaceDesc.dwHeight * dwPitchFB + 24); if(NULL==pFBreal) { lastError = DDERR_OUTOFMEMORY; return; } pFrameBuffer = (char*)(((int)pFBreal + 7) & ~7); // align to QWORD dprintf(("DDRAW: Framebuffer @ %08X QWAligned @ %08X with a Pitch of %d\n", pFBreal, pFrameBuffer, dwPitchFB)); DDSurfaceDesc.lpSurface = pFrameBuffer; if( (lpDraw->dCaps.ulDepth ) == dwBpp ) { dprintf(("DDRAW: No CC_Buffer needed\n")); // Yes => No Colorconversion is needed so point to the same buffer pDiveBuffer = pFrameBuffer; dwPitchDB = dwPitchFB; } else { dwPitchDB = (DDSurfaceDesc.dwWidth * (lpDraw->dCaps.ulDepth/8) +7) & ~7; dprintf( ("DDRAW: Alloc CCBuf with malloc (%dx%d) Pitch %d ", DDSurfaceDesc.dwHeight, DDSurfaceDesc.dwWidth, dwPitchDB)); // No so we must create the Divebuffer to do the colortranslation // and blit to the real framebuffer on Unlock to do color conversion pDBreal = (char*)malloc( DDSurfaceDesc.dwHeight * dwPitchDB + 24); pDiveBuffer = (char*)(((int)pDBreal + 7) & ~7); // align to QWORD dprintf(( " @ %08X\n", pDiveBuffer)); } // if(Mainchain) // { diveBufNr = 0; rc = DiveAllocImageBuffer( hDive, &diveBufNr, lpDraw->dCaps.fccColorEncoding, DDSurfaceDesc.dwWidth, DDSurfaceDesc.dwHeight, dwPitchDB, (PBYTE)pDiveBuffer); dprintf(("DDRAW: DiveAllocImageBuffer %x -> %d (rc=%d)",pDiveBuffer, diveBufNr, rc)); // } } // end of 3rd case } // End of alloc surfaces width = DDSurfaceDesc.dwWidth; height = DDSurfaceDesc.dwHeight; if( dwCaps & DDSCAPS_COMPLEX) { // remove the flag dwCaps &= ~DDSCAPS_COMPLEX; dprintf(("DDRAW: Complex Surface\n")); if(DDSurfaceDesc.dwFlags & DDSD_BACKBUFFERCOUNT) { dprintf(("DDRAW: Backbuffer # = %d\n",DDSurfaceDesc.dwBackBufferCount)); #if 1 memset( &ComplexSurfaceDesc, 0, sizeof(DDSURFACEDESC2)); ComplexSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2); ComplexSurfaceDesc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ComplexSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_FLIP; ComplexSurfaceDesc.dwHeight = DDSurfaceDesc.dwHeight; ComplexSurfaceDesc.dwWidth = DDSurfaceDesc.dwWidth; ComplexSurfaceDesc.ddpfPixelFormat.dwFlags = DDSurfaceDesc.ddpfPixelFormat.dwFlags; ComplexSurfaceDesc.ddpfPixelFormat.dwRBitMask = DDSurfaceDesc.ddpfPixelFormat.dwRBitMask; ComplexSurfaceDesc.ddpfPixelFormat.dwGBitMask = DDSurfaceDesc.ddpfPixelFormat.dwGBitMask; ComplexSurfaceDesc.ddpfPixelFormat.dwBBitMask = DDSurfaceDesc.ddpfPixelFormat.dwBBitMask; ComplexSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; if(DDSurfaceDesc.dwBackBufferCount>1) { ComplexSurfaceDesc.dwFlags |=DDSD_BACKBUFFERCOUNT; ComplexSurfaceDesc.dwBackBufferCount = DDSurfaceDesc.dwBackBufferCount -1; ComplexSurfaceDesc.ddsCaps.dwCaps|= DDSCAPS_COMPLEX; } BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, TRUE); BackBuffer->Vtbl.fnAddRef((IDirectDrawSurface *)BackBuffer); if (BackBuffer->GetLastError()==DD_OK) { dprintf(("DDRAW: created backbuffer")); DDSurfaceDesc.dwFlags |= DDSCAPS_FLIP; BackBuffer->SetFrontBuffer(this); } else { dprintf(("DDRAW: Error creating backbuffer")); } #else memcpy( &ComplexSurfaceDesc, &DDSurfaceDesc, sizeof(DDSURFACEDESC2)); ComplexSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; ComplexSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP; // set flip ComplexSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; // remove backbuffer if(ComplexSurfaceDesc.dwBackBufferCount>1) { ComplexSurfaceDesc.dwBackBufferCount--; } else { ComplexSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; ComplexSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_COMPLEX; } BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, Mainchain); BackBuffer->Vtbl.fnAddRef((IDirectDrawSurface *)BackBuffer); if (BackBuffer->GetLastError()==DD_OK) { DDSurfaceDesc.dwFlags |= DDSCAPS_FLIP; BackBuffer->SetFrontBuffer(this); } #endif } // MipMap Surfaces are handled here if( (DDSurfaceDesc.dwFlags & DDSD_MIPMAPCOUNT) && (dwCaps & DDSCAPS_TEXTURE) && (dwCaps & DDSCAPS_MIPMAP) ) { dwCaps &= ~ (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP); dprintf(("DDRAW: Mipmpa # = %d\n",DDSurfaceDesc.dwMipMapCount)); memcpy( &ComplexSurfaceDesc, &DDSurfaceDesc, sizeof(DDSURFACEDESC2)); ComplexSurfaceDesc.dwMipMapCount = 0; ComplexSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT; for(int i =0; i < DDSurfaceDesc.dwMipMapCount; i++) { dprintf(("DDRAW: Creating MipMap %d\n",i)); // Mpmaps shirnk by 2 ComplexSurfaceDesc.dwWidth /= 2; ComplexSurfaceDesc.dwHeight /= 2; MipMapSurface = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE); MipMapSurface->Vtbl.fnAddRef((IDirectDrawSurface *)MipMapSurface); DPA_InsertPtr( DPA_SurfaceMipMaps, DPA_GetPtrCount(DPA_SurfaceMipMaps), MipMapSurface); if(MipMapSurface->GetLastError() != DD_OK) { lastError = MipMapSurface->GetLastError(); dprintf(("DDRAW: Attached surface creation returned error %d\n",lastError)); return; } // Endif Errorcheck } //End for(i =0; i < DDSurfaceDesc.dwMipMapCount; i++) } // End of MipMaps #if 0 if(DDSurfaceDesc.dwFlags) dprintf(("DDRAW: Unsupported Complex Surface\n")); #endif } // Endif DDSCAPS_COMPLEX } else { lastError = DDERR_INVALIDPARAMS; } } // Endif DDCAPS is valid else { dprintf(("DDRAW: CAPS not valid\n")); lastError = DDERR_INVALIDPARAMS; } dprintf(("DDRAW: Buf %X Screen Caps (%d,%d), bitcount %d\n\n", this, lpDraw->GetScreenHeight(), lpDraw->GetScreenWidth(), lpDraw->dCaps.ulDepth)); if(DD_OK!=lastError) { dprintf(("DDRAW: Some Error Check Flags\n")); _dump_DDSCAPS(DDSurfaceDesc.dwFlags); } } //****************************************************************************** //****************************************************************************** HRESULT OS2IDirectDrawSurface::DoColorFill(LPRECT lpDestRect,DWORD dwFillColor) { int FillWidth, FillHeight, Top, Left; DWORD *pPal24; WORD *pPal16; dprintf(("DDRAW: ColorFill with %08X\n", dwFillColor)); if(NULL!=lpDestRect) { dprintf(("DDRAW: Fill only Rect(%d,%d)(%d,%d) (%d,%d)", lpDestRect->left, lpDestRect->top, lpDestRect->right, lpDestRect->bottom, width, height)); FillWidth = RECT_WIDTH(lpDestRect); FillHeight = RECT_HEIGHT(lpDestRect); Top = lpDestRect->top; Left = lpDestRect->left; if(Top + FillHeight > height) { FillHeight = height - Top; dprintf(("correcting FillHeight to %d", FillHeight)); } if(Left + FillWidth > width) { FillWidth = width - Left; dprintf(("correcting FillWidth to %d", FillWidth)); } } else { dprintf(("DDRAW: Fill all at addr ")); Top = 0; Left = 0; FillWidth = width; FillHeight = height; //pLine = pDiveBuffer; } //dprintf(("DDRAW: 0x%08X (%d/%d) at\n", pLine,FillWidth,FillHeight)); // Better safe than sorry if (FillHeight <= 0) return(DD_OK); if(pDiveBuffer!=pFrameBuffer) { if( (NULL== lpDraw->pPrimSurf) || (NULL== ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette) ) { if(!fPalInit) { for(DWORD i=0;i<256;i++) { wDefaultPalete16[i] = (DefaultPalette[i*3+2]>>3) + ((DefaultPalette[i*3+1]>>2) <<5) + ((DefaultPalette[i*3]>>3) << 11); dwDefaultPalete24[i]= ((DefaultPalette[i*3+2]>>3) <<8)+ ((DefaultPalette[i*3+1]>>2) <<16) + ((DefaultPalette[i*3]>>3) << 24); dprintf(( " # %d : RGB=%02X/%02X/%02X => %04X\n", i, DefaultPalette[i*3], DefaultPalette[i*3+1], DefaultPalette[i*3+2], wDefaultPalete16[i])); // aPal24[i] = (lpColorTable[i].peBlue <<8) + // (lpColorTable[i].peGreen<<16) + // (lpColorTable[i].peRed<<24); } fPalInit = TRUE; } pPal16 = &wDefaultPalete16[0]; pPal24 = &dwDefaultPalete24[0]; } else { pPal16 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal16; pPal24 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal24; } } if(NULL!=ColorFill) { ColorFill( pDiveBuffer, pFrameBuffer, Top, Left, FillWidth, FillHeight, dwPitchDB,dwPitchFB, dwFillColor,(16==lpDraw->dCaps.ulDepth)?(VOID*)pPal16:(VOID*)pPal24); SurfChangeUniquenessValue(this); } else { dprintf(("DDRAW: ColorFill function is NULL!!")); } return(DD_OK); } //****************************************************************************** //****************************************************************************** void OS2IDirectDrawSurface::ColorConversion(LPRECT lpRect) { //char *pSrc,*pDst,*pSLine,*pDLine; DWORD CCwidth,CCheight,x,y; DWORD *pPal24; WORD *pPal16; if( (NULL== lpDraw->pPrimSurf) || (NULL== ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette) ) { if(!fPalInit) { for(DWORD i=0;i<256;i++) { wDefaultPalete16[i] = (DefaultPalette[i*3+2]>>3) + ((DefaultPalette[i*3+1]>>2) <<5) + ((DefaultPalette[i*3]>>3) << 11); dwDefaultPalete24[i]= ((DefaultPalette[i*3+2]>>3) <<8)+ ((DefaultPalette[i*3+1]>>2) <<16) + ((DefaultPalette[i*3]>>3) << 24); dprintf(( " # %d : RGB=%02X/%02X/%02X => %04X\n", i, DefaultPalette[i*3], DefaultPalette[i*3+1], DefaultPalette[i*3+2], wDefaultPalete16[i])); // aPal24[i] = (lpColorTable[i].peBlue <<8) + // (lpColorTable[i].peGreen<<16) + // (lpColorTable[i].peRed<<24); } fPalInit = TRUE; } pPal16 = &wDefaultPalete16[0]; pPal24 = &dwDefaultPalete24[0]; } else { pPal16 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal16; pPal24 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal24; } if(NULL==lpRect) { //pSrc = pFrameBuffer; //pDst = pDiveBuffer; CCwidth = width; CCheight = height; x = 0; y = 0; } else { // ToDo: Check why the top/bottom values come in swaped here // for now simply reverse them with the following 3 lines y = lpRect->top; lpRect->top = lpRect->bottom; lpRect->bottom = y; // end of hack #if 0 pSrc = pFrameBuffer + (lpRect->top * dwPitchFB) + (lpRect->left* (lpDraw->dCaps.ulDepth/8)); pDst = pDiveBuffer + (lpRect->top * dwPitchDB) + (lpRect->left* dwBytesPPDive); #endif y = lpRect->top; x = lpRect->left; CCwidth = lpRect->right - lpRect->left; CCheight = lpRect->bottom - lpRect->top; } // dprintf( ("H: %d W: %d\n SRC @ %08X\n DST @ %08X\n", // CCheight, CCwidth, pSrc,pDst)); if(NULL!=ColorConv) ColorConv( pDiveBuffer, pFrameBuffer, y, x, CCwidth, CCheight, dwPitchDB,dwPitchFB, 16==lpDraw->dCaps.ulDepth?(VOID*)pPal16:(VOID*)pPal24); else { dprintf(("DDRAW: ColorConv function is NULL!!")); } /* pSLine = pSrc; pDLine = pDst; switch(lpDraw->dCaps.ulDepth) { case 8: dprintf(("DDRAW: 8Bit target CC not implemented\n")); break; case 15: dprintf(("DDRAW: 15 Bit not implemented using 16bit might look ugly\n")); case 16: if(8==lpDraw->GetScreenBpp()) { dprintf(("DDRAW: 8->16Bit CC\n")); for(y=0;CCheight;CCheight--,y++) { for(x=0;x16Bit Not implemented",lpDraw->GetScreenBpp())); } break; case 24: if(8==lpDraw->GetScreenBpp()) { dprintf(("DDRAW: 8->24Bit CC")); for(y=0;CCheight;CCheight--,y++) { char *pIter; for(x=0,pIter=pDLine;x24Bit Not implemented",lpDraw->GetScreenBpp())); } break; case 32: if(8==lpDraw->GetScreenBpp()) { dprintf(("DDRAW: 8->32Bit CC")); for(y=0;CCheight;CCheight--,y++) { for(x=0;x32Bit Not implemented",lpDraw->GetScreenBpp())); } break; default: dprintf( ("Unexpected Screen Bitdepth %d\n", lpDraw->dCaps.ulDepth)); break; } */ } //****************************************************************************** //****************************************************************************** // Internal callbacks uses by destructor INT CALLBACK DestroyRects(LPVOID lpItem, DWORD dwRes) { DDRectangle *pItem = (DDRectangle*) lpItem; delete(pItem); return 1; } INT CALLBACK ReleaseSurfaces(LPVOID lpItem, DWORD dwRes) { OS2IDirectDrawSurface *pSurf; pSurf = (OS2IDirectDrawSurface *)lpItem; pSurf->Vtbl.fnRelease(pSurf); return 1; } //****************************************************************************** //****************************************************************************** OS2IDirectDrawSurface::~OS2IDirectDrawSurface() { if(hwndFullScreen) { DestroyWindow(hwndFullScreen); } if(DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { lpDraw->SetPrimarySurface(FALSE); if(lpPalette) lpPalette->RestorePhysPalette(); } else { if( diveBufNr != -1) { if(fLocked) DiveEndImageBufferAccess(hDive, diveBufNr); DiveFreeImageBuffer(hDive, diveBufNr); } fLocked = FALSE; diveBufNr = -1; } // Free Buffers if they have been allocated // DIVE Buffer if(NULL!=pDBreal) free(pDBreal); // FrameBuffer if(NULL!=pFBreal) free(pFBreal); // Clear the list of locked rectangles if (DPA_GetPtrCount(DPA_LockedRects)>0) { DPA_DestroyCallback( DPA_LockedRects, DestroyRects, 0); } if(lpClipper) { lpClipper->Vtbl.fnRelease((IDirectDrawClipper*)lpClipper); lpClipper = NULL; } if(lpPalette) { lpPalette->Vtbl.fnRelease((IDirectDrawPalette*)lpPalette); lpPalette = NULL; } if(hbmImage) DeleteObject(hbmImage); if(hdcImage) DeleteDC(hdcImage); if (NULL!=BackBuffer) BackBuffer->Vtbl.fnRelease(BackBuffer); if (DPA_GetPtrCount(DPA_SurfaceMipMaps)>0) { DPA_DestroyCallback( DPA_SurfaceMipMaps, ReleaseSurfaces, 0); } if (DPA_GetPtrCount(DPA_SurfaceAttached)>0) { DPA_DestroyCallback( DPA_SurfaceAttached, ReleaseSurfaces, 0); } lpDraw->Vtbl.fnRelease(lpDraw); } //****************************************************************************** //****************************************************************************** inline void OS2IDirectDrawSurface::SetFrontBuffer( OS2IDirectDrawSurface* NewFBuffer) { FrontBuffer = NewFBuffer; if (NULL==NewFBuffer) { dprintf(("DDRAW: Remove Frontbuffer\n")); // The real Frontbuffer was removed check if I'm now the one if(NULL!=BackBuffer) { dprintf(("DDRAW: We have the a backbuffer so we're the Frontbuffer\n")); NextFlip = BackBuffer; DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; BackBuffer->SetFrontBuffer(this); } else { // Flipchain is destroyed dprintf(("DDRAW: No longer part of a flipchain\n")); DDSurfaceDesc.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER | DDSCAPS_FLIP); } } else { dprintf(("DDRAW: Set new Frontbuffer to 0x%08X\n",NewFBuffer)); if(NULL==NewFBuffer->GetFrontBuffer()) { dprintf(("DDRAW: We're the 1st backbuffer\n")); DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER | DDSCAPS_FLIP; FrontBuffer->NextFlip = this; } else { dprintf(("DDRAW: We are one of many buffers\n")); DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER ; DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP; } if(NULL!=BackBuffer) BackBuffer->SetFrontBuffer(this); DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER; } } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj) { // ToDo: Add Interface handling for D3D Textures HRESULT rc; OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: OS2IDirectDrawSurface::SurfQueryInterface\n")); if(NULL==ppvObj) { rc = DDERR_INVALIDPARAMS; goto RetFn; } rc = E_NOINTERFACE; *ppvObj = NULL; if(IsEqualGUID(riid, &IID_IDirectDrawSurface)) { *ppvObj = &me->lpVtbl; // ToDo DO a real V1 table rc = DD_OK; goto RetFn; } if(IsEqualGUID(riid, &IID_IDirectDrawSurface2)) { *ppvObj = &me->lpVtbl2; rc = DD_OK; goto RetFn; } if(IsEqualGUID(riid, &IID_IDirectDrawSurface3)) { *ppvObj = &me->Vtbl3; rc = DD_OK; goto RetFn; } if(IsEqualGUID(riid, &IID_IDirectDrawSurface4)) { *ppvObj = This; rc =DD_OK; } //if(IsEqualGUID(riid, &IID_IUnknown)) ... RetFn: if(DD_OK==rc) SurfAddRef(This); return(rc); } //****************************************************************************** //****************************************************************************** ULONG WIN32API SurfAddRef(THIS This) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: OS2IDirectDrawSurface::SurfAddRef %d\n", me->Referenced+1)); return ++me->Referenced; } //****************************************************************************** //****************************************************************************** ULONG WIN32API SurfRelease(THIS This) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: OS2IDirectDrawSurface::SurfRelease %d\n", me->Referenced-1)); dprintf(("DDRAW: OS2IDirectDrawSurface::Surface %X\n", me)); if(me->Referenced) { me->Referenced--; if(me->Referenced == 0) { delete( me); #ifndef __WATCOMC__ //_interrupt(3); #endif return(0); } else return me->Referenced; } else return(0); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfAddAttachedSurface(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurface) { dprintf(("DDRAW: SurfAddAttachedSurface\n")); return SurfAddAttachedSurface4(This, (LPDIRECTDRAWSURFACE4)lpDDSurface); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfAddAttachedSurface3(THIS This, LPDIRECTDRAWSURFACE3 lpDDSurface) { dprintf(("DDRAW: SurfAddAttachedSurface\n")); return SurfAddAttachedSurface4(This, (LPDIRECTDRAWSURFACE4)lpDDSurface); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfAddAttachedSurface4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurface) { OS2IDirectDrawSurface *AttachedSurface; OS2IDirectDrawSurface *BBCursor; OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; int rc; dprintf(("DDRAW: SurfAddAttachedSurface4\n")); if (NULL==lpDDSurface) return DDERR_INVALIDPARAMS; AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface; if(AttachedSurface->IsImplicitSurface()) { dprintf(("DDRAW: Internal : Can't attach an implicitly created surface to another surface\n")); return(DDERR_CANNOTATTACHSURFACE); } if(This == AttachedSurface) { dprintf(("DDRAW: Can't attach a surface to itself\n")); return(DDERR_CANNOTATTACHSURFACE); } if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) { if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { rc = DPA_InsertPtr( me->DPA_SurfaceMipMaps, DPA_GetPtrCount(me->DPA_SurfaceMipMaps), AttachedSurface); if( rc>=0) { me->DDSurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT; me->DDSurfaceDesc.dwMipMapCount++; AttachedSurface->Vtbl.fnAddRef(AttachedSurface); } else { dprintf(("DDRAW: Internal : Error attaching to MipMap\n")); return(DDERR_CANNOTATTACHSURFACE); } } else { dprintf(("DDRAW: Target Surface isn't a MipMap\n")); return(DDERR_CANNOTATTACHSURFACE); } } else { rc = DPA_InsertPtr( me->DPA_SurfaceAttached, DPA_GetPtrCount(me->DPA_SurfaceAttached), AttachedSurface); if(rc>=0) { AttachedSurface->Vtbl.fnAddRef(AttachedSurface); } else { dprintf(("DDRAW: Internal : Error attaching to general Set\n")); return(DDERR_CANNOTATTACHSURFACE); } } } // endif DDSCAPS_TEXTURE else { if( (AttachedSurface->DDSurfaceDesc.dwWidth != me->DDSurfaceDesc.dwWidth) || (AttachedSurface->DDSurfaceDesc.dwHeight != me->DDSurfaceDesc.dwHeight) // || (AttachedSurface->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount != // me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount) ) { dprintf(("DDRAW: Surfaces don't have equal dimensions\n")); return(DDERR_CANNOTATTACHSURFACE); } else { if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER) { if( (AttachedSurface->GetFrontBuffer()!=NULL) || (AttachedSurface->BackBuffer!= NULL)) { dprintf(("DDRAW: Surface already has a front/backbuffer\n")); return(DDERR_SURFACEALREADYATTACHED); } if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) { if(NULL!=me->BackBuffer) { BBCursor = me->BackBuffer; while(NULL!=BBCursor) { BBCursor->DDSurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT; BBCursor->DDSurfaceDesc.dwBackBufferCount++; BBCursor->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP; BBCursor = BBCursor->BackBuffer; } BBCursor->BackBuffer = AttachedSurface; AttachedSurface->SetFrontBuffer(BBCursor); } else { me->BackBuffer = AttachedSurface; AttachedSurface->SetFrontBuffer(me); } me->DDSurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT; me->DDSurfaceDesc.dwBackBufferCount++; me->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP; AttachedSurface->Vtbl.fnAddRef(AttachedSurface); return (DD_OK); } else { dprintf(("DDRAW: Can't attach backbuffer to anything but a frontbuffer\n")); return(DDERR_CANNOTATTACHSURFACE); } } else { if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { if( DPA_InsertPtr( me->DPA_SurfaceMipMaps, DPA_GetPtrCount(me->DPA_SurfaceMipMaps), AttachedSurface) >=0) { me->DDSurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT; me->DDSurfaceDesc.dwMipMapCount++; me->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; AttachedSurface->Vtbl.fnAddRef(AttachedSurface); } else { dprintf(("DDRAW: Internal : Error attaching to MipMap\n")); return(DDERR_CANNOTATTACHSURFACE); } } else { dprintf(("DDRAW: Target Surface isn't a MipMap\n")); return(DDERR_CANNOTATTACHSURFACE); } } else { if( DPA_InsertPtr( me->DPA_SurfaceAttached, DPA_GetPtrCount(me->DPA_SurfaceAttached), AttachedSurface) >=0) { AttachedSurface->Vtbl.fnAddRef(AttachedSurface); } else { dprintf(("DDRAW: Internal : Error attaching to general Set\n")); return(DDERR_CANNOTATTACHSURFACE); } } }// End if not DDSCAPS_BACKBUFFER } } dprintf(("DDRAW: Surface attached\n")); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfDeleteAttachedSurface(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSurface) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfDeleteAttachedSurface\n")); return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface)); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfDeleteAttachedSurface3(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSurface) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfDeleteAttachedSurface\n")); return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface)); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfDeleteAttachedSurface4(THIS This, DWORD dwFlags , LPDIRECTDRAWSURFACE4 lpDDSurface) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; OS2IDirectDrawSurface *AttachedSurface; OS2IDirectDrawSurface *SurfaceCursor; int i; BOOL Found = FALSE; dprintf(("DDRAW: SurfDeleteAttachedSurface\n")); if((0!=dwFlags)||(NULL==lpDDSurface)) return(DDERR_INVALIDPARAMS); AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface; if (AttachedSurface->IsImplicitSurface()) return (DDERR_CANNOTDETACHSURFACE); if ( (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP | DDSCAPS_BACKBUFFER)) && !(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) ) { // Surface seams to be a backbuffer in a flipchain search it // Goto top of list if(me->FrontBuffer!=NULL) { SurfaceCursor = me->FrontBuffer; while(SurfaceCursor->GetFrontBuffer()!=NULL) SurfaceCursor = SurfaceCursor->GetFrontBuffer(); } else SurfaceCursor = me; // now iterrate through the list skip first in list as we don't remove the frontbuffer SurfaceCursor = SurfaceCursor->BackBuffer; while((SurfaceCursor!= AttachedSurface)&&(SurfaceCursor!=NULL)) SurfaceCursor = SurfaceCursor->BackBuffer; if(SurfaceCursor!=NULL) { Found = TRUE; // remove the Surface from the list SurfaceCursor->FrontBuffer->BackBuffer = SurfaceCursor->BackBuffer; if(SurfaceCursor->BackBuffer!=NULL) { SurfaceCursor->BackBuffer->SetFrontBuffer(SurfaceCursor->FrontBuffer); } else { // we were the last buffer in the list have we been the only backbuffer? if(SurfaceCursor->FrontBuffer->FrontBuffer == NULL) { // Yepp so "destroy" the flipchain SurfaceCursor->FrontBuffer->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP; SurfaceCursor->FrontBuffer->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; } } // decrement the backbuffer count of all buffers in the chain in front of us while(SurfaceCursor->GetFrontBuffer()!=NULL) { SurfaceCursor = SurfaceCursor->GetFrontBuffer(); SurfaceCursor->DDSurfaceDesc.dwBackBufferCount-- ; } AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0; AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP; AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; // Set this flag as adding to the chain removed it AttachedSurface->lpVtbl->fnRelease(AttachedSurface); } } //endif delete back/frontbuffers if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP & DDSCAPS_FRONTBUFFER)) ) { // seams like someone wants a new frontbuffer // Goto top of list if(me->FrontBuffer!=NULL) { SurfaceCursor = me->FrontBuffer; while(SurfaceCursor->GetFrontBuffer()!=NULL) SurfaceCursor = SurfaceCursor->GetFrontBuffer(); } else SurfaceCursor = me; if(SurfaceCursor == AttachedSurface) { Found = TRUE; SurfaceCursor->BackBuffer->SetFrontBuffer(NULL); AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0; AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP; AttachedSurface->lpVtbl->fnRelease(AttachedSurface); } } if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP ) ) { // Surface seams to be a mipmap i = 0; while((DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>i ) && !Found) { if (DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i) == AttachedSurface) { Found = TRUE; DPA_DeletePtr(me->DPA_SurfaceMipMaps,i); AttachedSurface->lpVtbl->fnRelease(AttachedSurface); // adjust our info me->DDSurfaceDesc.dwMipMapCount-- ; if (!me->DDSurfaceDesc.dwMipMapCount) { me->DDSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT; } } i++; } } if(!Found) { // Surface seams to be an attached one i = 0; while((DPA_GetPtrCount(me->DPA_SurfaceAttached)>i ) && !Found) { if (DPA_FastGetPtr(me->DPA_SurfaceAttached,i) == AttachedSurface) { Found = TRUE; DPA_DeletePtr(me->DPA_SurfaceAttached,i); AttachedSurface->lpVtbl->fnRelease(AttachedSurface); } i++; } } return(Found?DD_OK:DDERR_SURFACENOTATTACHED); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfEnumAttachedSurfaces(THIS This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpCallBack) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfEnumAttachedSurfaces\n")); return(SurfEnumAttachedSurfaces4(me,lpContext, (LPDDENUMSURFACESCALLBACK2) lpCallBack)); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfEnumAttachedSurfaces4(THIS This, LPVOID lpContext ,LPDDENUMSURFACESCALLBACK2 lpCallBack) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; OS2IDirectDrawSurface *EnumSurface; DDSURFACEDESC2 EnumDesc; int i,count; HRESULT rc; dprintf(("DDRAW: SurfEnumAttachedSurfaces\n")); if (NULL==lpCallBack) return (DDERR_INVALIDPARAMS); rc = DDENUMRET_OK; if(me->BackBuffer != NULL) { memcpy(&EnumDesc,&(me->DDSurfaceDesc),sizeof(DDSURFACEDESC2)); rc = lpCallBack((LPDIRECTDRAWSURFACE4)me->BackBuffer,&EnumDesc,lpContext); } count = DPA_GetPtrCount(me->DPA_SurfaceMipMaps); if(count>0) { i=0; while( (DDENUMRET_OK == rc) && iDPA_SurfaceMipMaps,i); memcpy( &EnumDesc, &(EnumSurface->DDSurfaceDesc), sizeof(DDSURFACEDESC2)); // Calling back into WIN32 app so we had to reset FS rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext); i++; } } count = DPA_GetPtrCount(me->DPA_SurfaceAttached); if(count>0) { i=0; while( (DDENUMRET_OK == rc) && iDPA_SurfaceAttached,i); memcpy( &EnumDesc, &(EnumSurface->DDSurfaceDesc), sizeof(DDSURFACEDESC2)); rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext); i++; } } return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfFlip(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurf, DWORD dwFlags) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfFlip\n")); return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags)); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfFlip3(THIS This, LPDIRECTDRAWSURFACE3 lpDDSurf, DWORD dwFlags) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfFlip\n")); return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags)); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfFlip4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurf, DWORD dwFlags) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; OS2IDirectDrawSurface *FlipSurface; OS2IDirectDrawSurface *FlipCursor; LPVOID Data; char *pcrFB,*pcFB,*pcrDB,*pcDB; dprintf(("DDRAW: SurfFlip4\n")); if(!((me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) && (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FLIP)) ) { dprintf(("DDRAW: Flip called on none Frontbuffer/Flip surface\n Flags:\n")); _dump_DDSCAPS(me->DDSurfaceDesc.ddsCaps.dwCaps); dprintf(("DDRAW: \n")); return(DDERR_NOTFLIPPABLE); } if(NULL!=lpDDSurf) { dprintf(("DDRAW: Check if Surface is in Flipchain!\n")); // We got an override surface check if it is in the flipchain FlipSurface = (OS2IDirectDrawSurface*) lpDDSurf; FlipCursor = me->BackBuffer; while((NULL!=FlipCursor)&&(FlipCursor!=FlipSurface)) { FlipCursor = FlipCursor->BackBuffer; } if(FlipCursor!=FlipSurface) { dprintf(("DDRAW: Surface not in Flipchain!\n")); return (DDERR_INVALIDPARAMS); // Not sure if the returnvalue is right } } else { FlipSurface = me->NextFlip; // Take the next Surface in the Flipchain dprintf(("DDRAW: Next Surface @ 0x%08X\n",FlipSurface)); } if((me->fLocked)||(FlipSurface->fLocked)) { dprintf(("DDRAW: Locked surface(s) Dest %d Src %d\n",me->fLocked,FlipSurface->fLocked)); return(DDERR_SURFACEBUSY); } if (-1 != me->diveBufNr) { //dprintf(("DDRAW: DIVE Flipchain DiveBuffer #%d",FlipSurface->diveBufNr)); // we got some DIVE surfaces // On Dive Buffers More then Double buffering won't get any perf. gain // as we have to move all the data to the Frontbuffer and can't simply exchange the pointers // Doulebuffering should work best. //rc = DiveBlitImage(me->hDive, FlipSurface->diveBufNr, me->diveBufNr); //dprintf(("DDRAW: DiveBlitImage rc = 0x%08X\n")); SurfBltFast4( me, 0, 0, (LPDIRECTDRAWSURFACE4)FlipSurface, NULL, DDBLTFAST_NOCOLORKEY); if(NULL==lpDDSurf) { // advance in the flipchain if no valid override surface was passed in // if we reached the end of the flipchain The Frontbuffer is the next to flip to me->NextFlip = FlipSurface->BackBuffer!=NULL?FlipSurface->BackBuffer:me->BackBuffer; } } else { dprintf(("DDRAW: Memory Flipchain")); // Memory Flipchain // // ToDo : Check what happens to src/dest colorkeys etc do the move also ? // // We only change the memory pointer to the buffers no need to copy all the data // So the NextFlip is here allways the Backbuffer so we won't advance this // // Sample (triple buffering) : Before Flip After Flip // Buffer: FB BB TB FB BB TB // Memory: 11 22 33 22 33 11 // Data = me->DDSurfaceDesc.lpSurface; pcrFB = me->pFBreal; pcFB = me->pFrameBuffer; pcrDB = me->pDBreal; pcDB = me->pDiveBuffer; me->DDSurfaceDesc.lpSurface = FlipSurface->DDSurfaceDesc.lpSurface; me->pFBreal = FlipSurface->pFBreal; me->pFrameBuffer = FlipSurface->pFrameBuffer; me->pDBreal = FlipSurface->pDBreal; me->pDiveBuffer = FlipSurface->pDiveBuffer; if (NULL==lpDDSurf) { while (NULL!=FlipSurface->BackBuffer) { FlipSurface->DDSurfaceDesc.lpSurface = FlipSurface->BackBuffer->DDSurfaceDesc.lpSurface; FlipSurface->pFBreal = FlipSurface->BackBuffer->pFBreal; FlipSurface->pFrameBuffer = FlipSurface->BackBuffer->pFrameBuffer; FlipSurface->pDBreal = FlipSurface->BackBuffer->pDBreal; FlipSurface->pDiveBuffer = FlipSurface->BackBuffer->pDiveBuffer; FlipSurface = FlipSurface->BackBuffer; } } FlipSurface->DDSurfaceDesc.lpSurface = Data; FlipSurface->pFBreal = pcrFB; FlipSurface->pFrameBuffer = pcFB; FlipSurface->pDBreal = pcrDB; FlipSurface->pDiveBuffer = pcDB; } return DD_OK; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetAttachedSurface(THIS This, LPDDSCAPS lpDDCaps, LPDIRECTDRAWSURFACE2 FAR * lpDDSurf) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetAttachedSurface\n")); return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf)); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetAttachedSurface3(THIS This, LPDDSCAPS lpDDCaps, LPDIRECTDRAWSURFACE3 FAR * lpDDSurf) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetAttachedSurface3\n")); return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf)); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetAttachedSurface4(THIS This, LPDDSCAPS2 lpDDCaps, LPDIRECTDRAWSURFACE4 FAR * lpDDSurf) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; OS2IDirectDrawSurface *EnumSurface = NULL; OS2IDirectDrawSurface *AttachedSurface = NULL; HRESULT rc; int i; dprintf(("DDRAW: SurfGetAttachedSurface4\n>Requested Caps: ")); _dump_DDSCAPS(lpDDCaps->dwCaps); dprintf(("DDRAW: \n")); if( (NULL==lpDDCaps)||(NULL==lpDDSurf)) { dprintf(("DDRAW: Invalid params\n\n")); return (DDERR_INVALIDPARAMS); } rc = DD_OK; if( (me->BackBuffer!=NULL) && (me->BackBuffer->DDSurfaceDesc.ddsCaps.dwCaps & lpDDCaps->dwCaps) ) { dprintf(("DDRAW: Return Backbuffer\n")); AttachedSurface = me->BackBuffer; } if(DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>0) { i=0; while( iDPA_SurfaceMipMaps) ) { EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i); if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps) { if(NULL==AttachedSurface) AttachedSurface = EnumSurface; else rc = DDERR_NOTFOUND; // Not sure if this is the right return value, // but function must fail if more then one surface fits } i++; } } if(DPA_GetPtrCount(me->DPA_SurfaceAttached)>0) { i=0; while( iDPA_SurfaceAttached) ) { EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i); if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps) { if(NULL==AttachedSurface) AttachedSurface = EnumSurface; else rc = DDERR_NOTFOUND; // Not sure if this is the right return value, // but function must fail if more then one surface fits } i++; } } if( (DD_OK==rc) && (NULL!=AttachedSurface) ) { *lpDDSurf = (IDirectDrawSurface4*)AttachedSurface; // not sure but as we returned an reference rains usage count AttachedSurface->lpVtbl->fnAddRef(AttachedSurface); } else { *lpDDSurf = NULL; rc = DDERR_NOTFOUND; } return rc; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetBltStatus(THIS This, DWORD) { dprintf(("DDRAW: SurfGetBltStatus\n")); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetCaps(THIS This, LPDDSCAPS lpDDCaps) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetCaps\n")); if(NULL==lpDDCaps) return(DDERR_INVALIDPARAMS); lpDDCaps->dwCaps = me->DDSurfaceDesc.ddsCaps.dwCaps; _dump_DDSCAPS(lpDDCaps->dwCaps); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetCaps4(THIS This, LPDDSCAPS2 lpDDCaps) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetCaps4\n")); if(NULL==lpDDCaps) return(DDERR_INVALIDPARAMS); memcpy(lpDDCaps, &(me->DDSurfaceDesc.ddsCaps), sizeof(DDSCAPS2) ); _dump_DDSCAPS(lpDDCaps->dwCaps); _dump_DDSCAPS2(lpDDCaps->dwCaps2); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetClipper(THIS This, LPDIRECTDRAWCLIPPER FAR *lplpClipper) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetClipper\n")); if(me->lpClipper) { *lplpClipper = (LPDIRECTDRAWCLIPPER) me->lpClipper; return(DD_OK); } else return(DDERR_NOCLIPPERATTACHED); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetColorKey\n")); if ((0==dwFlags) || (NULL==lpDDColKey)) return (DDERR_INVALIDPARAMS); // as we report only src colorkey in the caps return error on all others flags if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY) & dwFlags) return(DDERR_UNSUPPORTED); if(me->DDSurfaceDesc.dwFlags & dwFlags) { if(DDCKEY_SRCBLT & dwFlags) { memcpy(lpDDColKey,&(me->DDSurfaceDesc.ddckCKSrcBlt),sizeof(DDCOLORKEY) ); } else return (DDERR_INVALIDPARAMS); // some other flags where set => error } else return(DDERR_NOCOLORKEY); // surface doesn't have a color key set return (DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetFlipStatus(THIS This, DWORD dwFlags) { dprintf(("DDRAW: SurfGetFlipStatus\n")); if( (DDGFS_CANFLIP!=dwFlags) && (DDGFS_ISFLIPDONE!=dwFlags) ) return DDERR_INVALIDPARAMS; return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetPalette(THIS This, LPDIRECTDRAWPALETTE FAR *lplpPalette) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetPalette\n")); if(me->lpPalette) { *lplpPalette = (LPDIRECTDRAWPALETTE)me->lpPalette; return(DD_OK); } else return(DDERR_NOPALETTEATTACHED); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetPixelFormat(THIS This, LPDDPIXELFORMAT lpPixelFormat) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetPixelFormat %x %x", This, lpPixelFormat)); if(NULL==lpPixelFormat) return DDERR_INVALIDPARAMS; _dump_pixelformat(&me->DDSurfaceDesc.ddpfPixelFormat); memcpy( (char*)lpPixelFormat, (char*)&(me->DDSurfaceDesc.ddpfPixelFormat), sizeof(DDPIXELFORMAT)); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurface) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetSurfaceDesc\n")); if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC)) ) return(DDERR_INVALIDPARAMS); memcpy( (char *)lpSurface, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC)); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurface) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetSurfaceDesc4\n")); if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC2)) ) return(DDERR_INVALIDPARAMS); memcpy( (char *)lpSurface, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC2)); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfInitialize(THIS, LPDIRECTDRAW, LPDDSURFACEDESC) { dprintf(("DDRAW: SurfInitialize\n")); return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfInitialize4(THIS, LPDIRECTDRAW, LPDDSURFACEDESC2) { dprintf(("DDRAW: SurfInitialize\n")); return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfIsLost(THIS) { // We don't loose any surface ;) // But we might shoud check for primary and/or Dive Buffers as I don't know // if they are preserved if switching to a FS DOS/OS2 session // dprintf(("DDRAW: SurfIsLost\n")); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfLock( THIS This, LPRECT lpRect, LPDDSURFACEDESC lpSurfaceDesc, DWORD dwFlags, HANDLE hEvent) { DDSURFACEDESC2 SurfaceDesc4; HRESULT rc; dprintf(("DDRAW: SurfLock %d %08X %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent)); if((NULL==lpSurfaceDesc)|| ((dwFlags & DDLOCK_EVENT) && NULL != hEvent)) { dprintf(("Invalid parameters")); return DDERR_INVALIDPARAMS; } if(lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC) && lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC2)) { dprintf(("Invalid parameters")); return DDERR_INVALIDPARAMS; } SurfaceDesc4.dwSize = sizeof(DDSURFACEDESC2); rc = SurfLock4( This, lpRect, &SurfaceDesc4, dwFlags, hEvent); if (DD_OK==rc) { memcpy( (char*)lpSurfaceDesc, (char*)&SurfaceDesc4, lpSurfaceDesc->dwSize ); } return(rc); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfLock4( THIS This, LPRECT lpRect, LPDDSURFACEDESC2 lpSurfaceDesc, DWORD dwFlags, HANDLE hEvent) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; int i; BOOL Found; DDRectangle *pIRectCurrent,*pIRectNew; HRESULT rc; dprintf( ("SurfLock4 %08X %08X %08X %d %d\n", me, (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent) ); if( (NULL==lpSurfaceDesc) || (NULL!=hEvent) ) { dprintf(("DDERR_INVALIDPARAMS")); return DDERR_INVALIDPARAMS; } if (NULL!=lpRect) pIRectNew = new DDRectangle( lpRect->left, lpRect->top, lpRect->right, lpRect->bottom ); else pIRectNew = new DDRectangle( 0, 0, me->width, me->height); // ToDo : the lockchecking should be done in a critcal seq. dprintf( ("Lock Rectangle (%d/%d) x (%d/%d)\n", pIRectNew->Left(), pIRectNew->Top(), pIRectNew->Right(), pIRectNew->Bottom())); rc = DD_OK; if(me->fLocked) { if (NULL==lpRect) { // If anything is locked we can't lock the complete surface dprintf(("DDRAW: Surface has locked Rectangles and we want to completely lock it\n")); Found = TRUE; } else { // If the new Rectangle intersects with any of the already locked rectangles it can't // be locked so check for this dprintf(("DDRAW: Surface has locked Rectangles, check if they overlap\n")); i=0; Found = FALSE; while(iDPA_LockedRects) && !Found) { pIRectCurrent = (DDRectangle*) DPA_FastGetPtr(me->DPA_LockedRects,i); dprintf( ("Test with Rectangle (%d/%d) x (%d/%d)\n", pIRectCurrent->Top(), pIRectCurrent->Left(), pIRectCurrent->Bottom(), pIRectCurrent->Right() )); Found = pIRectCurrent->intersects(*pIRectNew); i++; } } if (Found) { delete pIRectNew; dprintf(("DDRAW: SurfLock4: Surface already locked\n\n")); rc = DDERR_SURFACEBUSY; } } if(DD_OK == rc) { memcpy((char *)lpSurfaceDesc, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC2)); if(lpRect != NULL) { lpSurfaceDesc->lpSurface = (LPVOID)((char*)me->pFrameBuffer + (lpRect->top * me->dwPitchFB) + (lpRect->left * (lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount>>3))); dprintf(("DDRAW: SurfLock4 %08X (x,y) = (%d,%d)\n\n", lpSurfaceDesc->lpSurface, lpRect->top, lpRect->left)); } else { dprintf(("DDRAW: SurfLock4 %08X \n\n", lpSurfaceDesc->lpSurface)); } // Add the rectangle to the list of locked rectangles pIRectNew->SetMemPtr(lpSurfaceDesc->lpSurface); DPA_InsertPtr( me->DPA_LockedRects, DPA_GetPtrCount(me->DPA_LockedRects), pIRectNew); #if 0 if(me->diveBufNr == DIVE_BUFFER_SCREEN) { OS2RECTL rectOS2; rectOS2.xLeft = pIRectNew->Left(); rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectNew->Bottom(); rectOS2.xRight = pIRectNew->Right(); rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectNew->Top(); dprintf(("DiveAcquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop)); int ret = DiveAcquireFrameBuffer(me->hDive, (PRECTL)&rectOS2); if(ret) { dprintf(("ERROR: DiveAcquireFrameBuffer failed with %d", ret)); } } #endif me->fLocked = TRUE; if(me->diveBufNr == DIVE_BUFFER_SCREEN) { //If fHideCursorOnLock is set, then we hide the cursor to prevent //the app from corruption the mouse cursor (color/animated pointers) if(fHideCursorOnLock) ShowCursor(FALSE); } } return rc; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetDC(THIS This, HDC FAR *hdc) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; DDSURFACEDESC2 LockedSurfaceDesc; HRESULT rc; BITMAP bmpSurface; struct { BITMAPINFOHEADER bmiHead; RGBQUAD bmiCols[256]; } BitmapInfo; dprintf(("DDRAW: SurfGetDC\n")); if (hdc == NULL) return(DDERR_INVALIDPARAMS); LockedSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2); if(DD_OK != me->Vtbl.fnLock(me,NULL,&LockedSurfaceDesc,0,0)) { return(DDERR_DCALREADYCREATED); } rc = DD_OK; if(me->hdcImage == NULL) { // Create a Device context me->hdcImage = CreateCompatibleDC(NULL); if(me->hdcImage == NULL) { dprintf(("DDRAW: Can't create compatible DC!\n")); me->Vtbl.fnUnlock(me,NULL); rc = DDERR_GENERIC; } } if( (DD_OK==rc) && (me->hbmImage == NULL) ) { OS2IDirectDrawPalette *ddpal = NULL; dprintf( ("Trying to create Bitmap (%d/%d) at %d Bit\n", LockedSurfaceDesc.dwWidth, LockedSurfaceDesc.dwHeight, LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount )); memset(&BitmapInfo, 0, sizeof(BitmapInfo)); BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER); BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.dwWidth; BitmapInfo.bmiHead.biHeight = -LockedSurfaceDesc.dwHeight; BitmapInfo.bmiHead.biPlanes = 1; BitmapInfo.bmiHead.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount) { case 1: case 4: dprintf(("DDRAW: 1/4 Bit Not yet supported\n")); break; case 8: BitmapInfo.bmiHead.biCompression = BI_RGB; if (me->lpPalette != NULL) ddpal = me->lpPalette; if ((me->FrontBuffer != NULL) && (me->FrontBuffer->lpPalette != NULL)) ddpal = me->FrontBuffer->lpPalette; if (ddpal != NULL) { ddpal->Vtbl.fnGetEntries((IDirectDrawPalette*)ddpal, 0, 0, 256, (PPALETTEENTRY)&BitmapInfo.bmiCols[0]); } else { dprintf(("DDRAW: Using default palette\n")); for (DWORD i = 0; i < 256; i++) { BitmapInfo.bmiCols[i].rgbBlue = DefaultPalette[i*3+2]; BitmapInfo.bmiCols[i].rgbGreen = DefaultPalette[i*3+1]; BitmapInfo.bmiCols[i].rgbRed = DefaultPalette[i*3]; BitmapInfo.bmiCols[i].rgbReserved = 0; } } me->hbmImage = CreateDIBitmap( me->hdcImage, &BitmapInfo.bmiHead, CBM_INIT, LockedSurfaceDesc.lpSurface, (PBITMAPINFO)&BitmapInfo, DIB_RGB_COLORS); break; case 16: case 24: case 32: BitmapInfo.bmiHead.biCompression = BI_BITFIELDS; BitmapInfo.bmiHead.biClrUsed = 3; *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask; *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask; *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask; me->hbmImage = CreateDIBitmap( me->hdcImage, &BitmapInfo.bmiHead, CBM_INIT, LockedSurfaceDesc.lpSurface, (PBITMAPINFO)&BitmapInfo, DIB_RGB_COLORS ); break; default: dprintf( ("Unexpected BitCount %d \n", LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)); me->hbmImage=NULL; } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount) if(me->hbmImage == NULL) { dprintf(("DDRAW: Can't create bitmap!\n")); DeleteDC(me->hdcImage); me->hdcImage = NULL; me->Vtbl.fnUnlock(me,NULL); rc = DDERR_GENERIC; } } else { if( (DD_OK==rc) && (me->dwLastDCUnique != me->dwUniqueValue) ) { dprintf(("DDRAW: The Surface was locked/unlocked after the last DC was created =>Update Bitmap!\n")); memset(&BitmapInfo,0, sizeof(BitmapInfo)); BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER); BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.dwWidth; BitmapInfo.bmiHead.biHeight = -LockedSurfaceDesc.dwHeight; BitmapInfo.bmiHead.biPlanes = 1; BitmapInfo.bmiHead.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount) { case 1: case 4: case 8: BitmapInfo.bmiHead.biCompression = BI_RGB; GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]); SetDIBits(me->hdcImage, me->hbmImage, 0, LockedSurfaceDesc.dwHeight, me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS); break; case 16: case 32: BitmapInfo.bmiHead.biCompression = BI_BITFIELDS; BitmapInfo.bmiHead.biClrUsed = 3; *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask; *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask; *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask; SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight, me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS); break; case 24: BitmapInfo.bmiHead.biCompression = BI_RGB; SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight, me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS); break; default: dprintf(("DDRAW: Unexpected BitCount %d => Bitmap not updated!\n",LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)); break; } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount) } } // Allways select the bitmap into the DC! No matter if the old or a new one if (DD_OK==rc) { if ((me->hgdiOld = SelectObject(me->hdcImage, me->hbmImage)) == NULL) { dprintf(("DDRAW: Can't select bitmap into DC!\n")); DeleteDC(me->hdcImage); me->hdcImage = NULL; DeleteObject(me->hbmImage); me->hbmImage = NULL; me->Vtbl.fnUnlock(me,NULL); rc = DDERR_GENERIC; } else { *hdc = me->hdcImage; } } return rc; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfReleaseDC(THIS This, HDC hdc) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; struct { BITMAPINFOHEADER bmiHead; RGBQUAD bmiCols[256]; } BitmapInfo; int rc; dprintf(("DDRAW: SurfReleaseDC\n")); if(hdc != me->hdcImage) return(DDERR_INVALIDOBJECT); //unselect our bitmap SelectObject(me->hdcImage, me->hgdiOld); memset(&BitmapInfo,0, sizeof(BitmapInfo)); BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER); BitmapInfo.bmiHead.biBitCount = me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; BitmapInfo.bmiHead.biPlanes = 1; BitmapInfo.bmiHead.biWidth = me->DDSurfaceDesc.dwWidth; /// (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3); BitmapInfo.bmiHead.biHeight = -me->DDSurfaceDesc.dwHeight; switch(me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount) { case 1: case 4: case 8: BitmapInfo.bmiHead.biCompression = BI_RGB; //GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]); rc = GetDIBits( hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight, NULL, (PBITMAPINFO)&BitmapInfo, DIB_RGB_COLORS); BitmapInfo.bmiHead.biHeight = -BitmapInfo.bmiHead.biHeight; dprintf( ("GetDIBits rc=%d\n Size :%d\n Width :%d\n Height :%d\n" " Planes :%d\n BitCount :%d\nLastEror = %d\nPixel[0,0] = 0x%02X\n", rc, BitmapInfo.bmiHead.biSize, BitmapInfo.bmiHead.biWidth, BitmapInfo.bmiHead.biHeight, BitmapInfo.bmiHead.biPlanes, BitmapInfo.bmiHead.biBitCount, GetLastError(), ((char*)me->DDSurfaceDesc.lpSurface)[0])); rc = GetDIBits( hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight, me->DDSurfaceDesc.lpSurface, (PBITMAPINFO)&BitmapInfo, DIB_RGB_COLORS); dprintf( ("GetDIBits rc=%d\n LastEror = %d\nPixel[0,0] = 0x%02X\n", rc, GetLastError(), ((char*)me->DDSurfaceDesc.lpSurface)[0])); break; case 16: BitmapInfo.bmiHead.biCompression = BI_BITFIELDS; BitmapInfo.bmiHead.biClrUsed = 3; *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask; *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask; *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask; GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight, me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS); break; case 32: BitmapInfo.bmiHead.biCompression = BI_BITFIELDS; BitmapInfo.bmiHead.biClrUsed = 3; *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask; *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask; *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask; GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight, me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS); break; case 24: BitmapInfo.bmiHead.biCompression = BI_RGB; GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight, me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS); break; default: dprintf(("DDRAW: Unexpected BitCount %d => Surface unlocked but no data copied back\n",me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)); // we might could keep the surface locked and return an error but this is more "safe" break; } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount) me->Vtbl.fnUnlock(me,NULL); me->dwLastDCUnique = me->dwUniqueValue; // Store this to see if the surface was locked after we released the DC return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfRestore(THIS) { dprintf(("DDRAW: SurfRestore\n")); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfSetClipper(THIS This, LPDIRECTDRAWCLIPPER lpClipper) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfSetClipper %x %x", This, lpClipper)); if(lpClipper == NULL) { //deattach surface if(me->lpClipper) { me->lpClipper->Vtbl.fnRelease((IDirectDrawClipper*)me->lpClipper); me->lpClipper = NULL; return(DD_OK); } else return(DDERR_NOCLIPPERATTACHED); } if(lpClipper == (LPDIRECTDRAWCLIPPER)me->lpClipper) return(DD_OK); //already attached if(me->lpClipper != NULL) { me->lpClipper->Vtbl.fnRelease((IDirectDrawClipper*)me->lpClipper); //attach other surface return(DD_OK); } me->lpClipper = (OS2IDirectDrawClipper *)lpClipper; me->lpClipper->Vtbl.fnAddRef((IDirectDrawClipper*)me->lpClipper); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfSetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; HRESULT rc; dprintf(("DDRAW: SurfSetColorKey %d %08X\n", dwFlags, lpDDColKey)); if (0==dwFlags) { return (DDERR_INVALIDPARAMS); } // as we report only src colorkey in the caps return error on all others flags if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY|DDCKEY_COLORSPACE) & dwFlags) { dprintf(("Unspported colorkey\n")); return(DDERR_UNSUPPORTED); } if(DDCKEY_SRCBLT & dwFlags) { //(me->lpVtbl == me->Vtbl4) // me->Vtbl4->ChangeUniquenessValue(me); // we changed somethin so change this value if(NULL!=lpDDColKey) { dprintf(("copy colorkey")); memcpy(&(me->DDSurfaceDesc.ddckCKSrcBlt), lpDDColKey, sizeof(DDCOLORKEY) ); me->DDSurfaceDesc.dwFlags |= DDCKEY_SRCBLT; // ToDo: Generate a maskbitmap for transparent blitting here } else { dprintf(("clear colorkey")); memset(&(me->DDSurfaceDesc.ddckCKSrcBlt), 0, sizeof(DDCOLORKEY) ); me->DDSurfaceDesc.dwFlags &= ~DDCKEY_SRCBLT; } rc = DD_OK; } else { dprintf(("Unsupported flags")); _dump_DDCOLORKEY(dwFlags); rc = DDERR_INVALIDPARAMS; // some other flags where set => error } return rc; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfSetPalette(THIS This, LPDIRECTDRAWPALETTE lpPalette) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfSetPalette\n")); if(lpPalette == NULL) { //deattach palette if(me->lpPalette) { // If removed from a primary surface notify // palette that it is no longer attached to the // primary surface => doesn't modify physical palette if(me->surfaceType & DDSCAPS_PRIMARYSURFACE) { me->lpPalette->SetIsPrimary(FALSE); } me->lpPalette->Vtbl.fnRelease((IDirectDrawPalette*)me->lpPalette); me->lpPalette = NULL; return(DD_OK); } else return(DDERR_NOPALETTEATTACHED); } if(lpPalette == (LPDIRECTDRAWPALETTE)me->lpPalette) return(DD_OK); //already attached if(me->lpPalette != NULL) { me->lpPalette->Vtbl.fnRelease((IDirectDrawPalette*)me->lpPalette); //attach other palette //return(DD_OK); } me->lpPalette = (OS2IDirectDrawPalette *)lpPalette; me->lpPalette->Vtbl.fnAddRef((IDirectDrawPalette*)me->lpPalette); // If Attached to a primary surface notify // palette that it is attached to the primary surface // => It does modify physical palette. // This is important as an palette can be attached to // multiple surfaces. If one is the primary surface // changes done to it via any surface must result in // changes in the phys pal. if(me->surfaceType & DDSCAPS_PRIMARYSURFACE) { me->lpPalette->SetIsPrimary(TRUE); } // me->lpVtbl->ChangeUniquenessValue(me); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfUnlock(THIS This, LPVOID lpSurfaceData) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; int i; DDRectangle *pIRectUnlock, *pIRectEnum; BOOL Found = FALSE; OS2RECTL CCRect; HRESULT rc; dprintf(("DDRAW: SurfUnlock at %08X\n",lpSurfaceData)); if(me->fLocked == FALSE) { dprintf(("DDRAW: Surface not locked!\n")); return(DDERR_NOTLOCKED); } i=0; if(NULL!=lpSurfaceData) { dprintf(("DDRAW: Buffer Pointer Compare")); // We got a pinter to the surface memory so we must search for // this pointer in the locked rects DPA to unlock the right rect. while(i < DPA_GetPtrCount(me->DPA_LockedRects) && !Found) { pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i); dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n", i, pIRectEnum->Top(), pIRectEnum->Left(), pIRectEnum->Bottom(), pIRectEnum->Right(), pIRectEnum->GetMemPtr() )); Found = ( pIRectEnum->GetMemPtr() == lpSurfaceData); if(!Found) { dprintf(("DDRAW: Not Found, try Next rect\n")); i++; } else { dprintf(("DDRAW: Found Rect\n")); } } } else { // If a NULL pointer was passed in the SW tries to unlock the // complete surface so we must compare the rects. dprintf(("DDRAW: Rectangle compare")); #if 1 i = 0; pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,0); Found = (pIRectEnum != NULL); #else pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height); while(iDPA_LockedRects) && !Found) { pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i); dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n", i, pIRectEnum->Top(), pIRectEnum->Left(), pIRectEnum->Bottom(), pIRectEnum->Right(), pIRectEnum->GetMemPtr() )); Found = (*pIRectEnum == *pIRectUnlock); if(!Found) { dprintf(("DDRAW: Not Found, try Next rect\n")); i++; } else { dprintf(("DDRAW: Found Rect\n")); } } delete pIRectUnlock; #endif } if(!Found) { dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n")); rc = DDERR_INVALIDRECT; } else { dprintf(("DDRAW: Remove Rect %d from Seq.\n",i)); DPA_DeletePtr(me->DPA_LockedRects,i); dprintf(("DDRAW: Test if locked Rects main\n")); if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle { dprintf(("DDRAW: No Locked Rects left for surface\n")); me->fLocked = FALSE; } else dprintf(( "%d Rects in Seq\n", DPA_GetPtrCount(me->DPA_LockedRects))); if(me->pFrameBuffer != me->pDiveBuffer) { dprintf(( "ColorConversion Needed %08X != %08X\n", me->pFrameBuffer, me->pDiveBuffer)); if(NULL!=lpSurfaceData) { CCRect.yTop = pIRectEnum->Top(); CCRect.xLeft = pIRectEnum->Left(); CCRect.xRight = pIRectEnum->Right(); CCRect.yBottom = pIRectEnum->Bottom(); me->ColorConversion( (LPRECT)&CCRect); } else { me->ColorConversion(NULL); } } else dprintf( ("No ColorConversion Needed")); #if 0 if(me->diveBufNr == DIVE_BUFFER_SCREEN) { OS2RECTL rectOS2; rectOS2.xLeft = pIRectEnum->Left(); rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectEnum->Bottom(); rectOS2.xRight = pIRectEnum->Right(); rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectEnum->Top(); dprintf(("DiveDeacquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop)); int ret = DiveDeacquireFrameBuffer(me->hDive); if(ret) { dprintf(("ERROR: DiveDeacquireFrameBuffer failed with %d", ret)); } } #endif // delete tne DDRectobject of the found rectangle delete pIRectEnum; // me->lpVtbl->ChangeUniquenessValue(me); dprintf(("DDRAW: Unlock OK\n\n")); rc = DD_OK; if(me->diveBufNr == DIVE_BUFFER_SCREEN) { //If fHideCursorOnLock is set, then we hide the cursor to prevent in SurfLock4 //the app from corruption the mouse cursor (color/animated pointers) //We need to show it again here if(fHideCursorOnLock) ShowCursor(TRUE); } } return rc; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfUnlock4(THIS This, LPRECT lpSurfaceRect) { // MS changed the parameter from LPVOID to LPRECT with DX6 // as DX-6 allways returns a DDSurface4 on create surface this // is a problem i not NULL is passed in. // Solution We first test with the pointer ns assuming a rectangle // if we don't find a rect Which is very likely if we get a pointer // SurfaceMemory we call SurfUnlock and test for the pointer there. OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; int i; DDRectangle *pIRectUnlock, *pIRectEnum; BOOL Found = FALSE; HRESULT rc; dprintf(("DDRAW: SurfUnlock4\n")); if(me->fLocked == FALSE) { dprintf(("DDRAW: Surface not locked!\n")); return(DDERR_NOTLOCKED); } if(NULL!=lpSurfaceRect) { dprintf(("DDRAW: Unlock rectangle\n")); pIRectUnlock = new DDRectangle( lpSurfaceRect->left, lpSurfaceRect->top, lpSurfaceRect->right, lpSurfaceRect->bottom); } else { dprintf(("DDRAW: Unlock complete surface\n")); pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height); } dprintf(( "Try to Unlock Rectangle (%d/%d) x (%d/%d)\n", pIRectUnlock->Top(), pIRectUnlock->Left(), pIRectUnlock->Bottom(), pIRectUnlock->Right() )); dprintf(("DDRAW: Start Enumeration of Locked Rects\n")); i=0; while(iDPA_LockedRects) && !Found) { pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i); dprintf(( "Test with Rectangle (%d/%d) x (%d/%d)\n", pIRectEnum->Top(), pIRectEnum->Left(), pIRectEnum->Bottom(), pIRectEnum->Right() )); Found = (*pIRectEnum == *pIRectUnlock); if(!Found) { dprintf(("DDRAW: Not Found, try Next rect\n")); i++; } else { dprintf(("DDRAW: Found Rect\n")); } } if(!Found) { if(NULL==lpSurfaceRect) { dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n")); return(DDERR_INVALIDRECT); } else rc = SurfUnlock(This, (LPVOID)lpSurfaceRect); } else { dprintf(("DDRAW: Remove Rect from Seq.\n")); DPA_DeletePtr(me->DPA_LockedRects,i); if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle { dprintf(("DDRAW: No Locked Rects left for surface\n")); me->fLocked = FALSE; } if(me->pFrameBuffer != me->pDiveBuffer) { dprintf(( "ColorConversion Needed %08X != %08X\n", me->pFrameBuffer, me->pDiveBuffer)); me->ColorConversion(lpSurfaceRect); } // me->lpVtbl->ChangeUniquenessValue(me); dprintf(("DDRAW: Unlock OK\n\n")); rc = DD_OK; } return rc; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetDDInterface(THIS This, LPVOID FAR *lplpDirectDraw) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; dprintf(("DDRAW: SurfGetDDInterface\n")); *lplpDirectDraw = (LPVOID FAR *)me->lpDraw; return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfPageLock(THIS, DWORD) { // Only used for DMA memory access // If we implement this for the None dive buffers with a pdd the we must change // from malloc to DosAllocMem and use OBJ_TILE flag dprintf(("DDRAW: SurfPageLock\n")); return(DD_OK); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfPageUnlock(THIS, DWORD) { dprintf(("DDRAW: SurfPageUnlock\n")); return(DD_OK); } //****************************************************************************** //****************************************************************************** // V3 Interface Functions HRESULT WIN32API SurfSetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurfDesc, DWORD dwFlags) { dprintf(("DDRAW: SurfSetSurfaceDesc\n")); OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; if ( (NULL==lpSurfDesc) || (dwFlags!=0) ) return DDERR_INVALIDPARAMS; // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one. // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) || // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) || // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ) if(-1==me->diveBufNr) return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces if (!me->Updated) { me->Updated = TRUE; // free our allocated Memory if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE) { if(me->pFBreal) free(me->pFBreal); if(me->pDBreal) free(me->pFBreal); } } // me->lpVtbl->ChangeUniquenessValue(me); memcpy( (char*)&(me->DDSurfaceDesc), (char*)lpSurfDesc, sizeof(DDSURFACEDESC)); me->dwPitchFB = me->DDSurfaceDesc.lPitch; if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() ) { // create CC buffer .... me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7; me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24); me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD } return DD_OK; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfSetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurfDesc, DWORD dwFlags) { dprintf(("DDRAW: SurfSetSurfaceDesc4\n")); OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; if ( (NULL==lpSurfDesc) || (dwFlags!=0) ) return DDERR_INVALIDPARAMS; // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one. // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) || // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) || // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ) if(-1==me->diveBufNr) return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces if (!me->Updated) { me->Updated = TRUE; // free our allocated Memory // free our allocated Memory if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE) { if(me->pFBreal) free(me->pFBreal); if(me->pDBreal) free(me->pFBreal); } } // me->lpVtbl->ChangeUniquenessValue(me); memcpy( (char *)&(me->DDSurfaceDesc), (char*)lpSurfDesc, sizeof(DDSURFACEDESC2)); me->dwPitchFB = me->DDSurfaceDesc.lPitch; if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() ) { // create CC buffer .... me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7; me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24); me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD } return DD_OK; } //****************************************************************************** //****************************************************************************** // V4 Interface Functions HRESULT WIN32API SurfSetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; int i; PSURFPRIVATEDATA pSData; void *pBuffer; BOOL bFound = FALSE; HRESULT rc; dprintf(("DDRAW: SurfSetPrivateData\n")); if(NULL==me) return(DDERR_INVALIDOBJECT); if((NULL==lpData)||(0==dwDataSize)|| (dwFlags & ~(DDSPD_IUNKNOWNPOINTER|DDSPD_VOLATILE))) return(DDERR_INVALIDPARAMS); // first check if the refGUID is stored as then the content will be updated if( DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0 ) { i=0; while(iDPA_SurfacePrivateData) && !bFound) { pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i); if (IsEqualGUID(&pSData->guidTag,refGUID)) bFound = TRUE; i++; } } if(bFound) { // update Private Data if (!pSData->isValid) { // Current data is invalid we need to update/allocate if(dwFlags & DDSPD_IUNKNOWNPOINTER) { pSData->pData = lpData; pSData->dwSize = 4; pSData->dwFlags = dwFlags; pSData->isValid = TRUE; ((OS2IDirectDrawSurface *) lpData)->lpVtbl->fnAddRef(lpData); } else { pSData->pData = malloc(dwDataSize); if(NULL!=pSData->pData) { memcpy(pSData->pData,lpData,dwDataSize); pSData->dwSize = dwDataSize; pSData->dwFlags = dwFlags; pSData->isValid = TRUE; } else { delete pSData; rc = DDERR_OUTOFMEMORY; } } } else { if(pSData->dwFlags & DDSPD_IUNKNOWNPOINTER) { if(dwFlags & DDSPD_IUNKNOWNPOINTER) { if(pSData->pData != lpData) { // Change of IUNKOWNPOINTER => release old and add ref to new one ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->fnRelease(pSData->pData); ((OS2IDirectDrawSurface *)lpData)->lpVtbl->fnAddRef(lpData); pSData->pData = lpData; } pSData->dwFlags = dwFlags; // Update the flags, size is the same } else { // Replace IUNKOWN through data pBuffer = malloc(dwDataSize); // get new buffer first if(NULL!=pBuffer) { // release old ref and copy data ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->fnRelease(pSData->pData); memcpy(pBuffer,lpData,dwDataSize); pSData->pData = pBuffer; pSData->dwSize = dwDataSize; // Update the size pSData->dwFlags = dwFlags; // Update the flags } else rc = DDERR_OUTOFMEMORY; } } else { if(dwFlags & DDSPD_IUNKNOWNPOINTER) { // Change of data to IUNKOWNPOINTER => free old memory and add ref to new one free(pSData->pData); ((OS2IDirectDrawSurface *)lpData)->lpVtbl->fnAddRef(lpData); pSData->pData = lpData; pSData->dwSize = dwDataSize; // Update the size pSData->dwFlags = dwFlags; // Update the flags } else { // Update/Replace data if(pSData->dwSize!=dwDataSize) pBuffer = realloc(pSData->pData,dwDataSize); // update buffer to new size else pBuffer = pSData->pData; if(NULL!=pBuffer) { // release old ref and copy data memcpy(pBuffer,lpData,dwDataSize); pSData->pData = pBuffer; pSData->dwSize = dwDataSize; // Update the size pSData->dwFlags = dwFlags; // Update the flags } else rc = DDERR_OUTOFMEMORY; } } } } else { // New data pSData = new(SURFPRIVATEDATA); if (NULL!=pSData) { if(dwFlags & DDSPD_IUNKNOWNPOINTER) { memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID)); pSData->pData = lpData; pSData->dwSize = 4; pSData->dwFlags = dwFlags; pSData->isValid = TRUE; ((OS2IDirectDrawSurface *)lpData)->lpVtbl->fnAddRef(lpData); } else { pSData->pData = malloc(dwDataSize); if(NULL!=pSData->pData) { memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID)); memcpy(pSData->pData,lpData,dwDataSize); pSData->dwSize = dwDataSize; pSData->dwFlags = dwFlags; pSData->isValid = TRUE; if( DPA_InsertPtr( me->DPA_SurfacePrivateData, DPA_GetPtrCount(me->DPA_SurfacePrivateData), pSData) <0) { delete(pSData); rc = DDERR_OUTOFMEMORY; } } else { delete(pSData); rc = DDERR_OUTOFMEMORY; } } } else rc = DDERR_OUTOFMEMORY; } return rc; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData, LPDWORD lpDataSize) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; int i; PSURFPRIVATEDATA pSData; HRESULT rc; BOOL bFound = FALSE; dprintf(("DDRAW: SurfGetPrivateData\n")); if(NULL==me) return(DDERR_INVALIDOBJECT); if((NULL==lpData)||(NULL==lpDataSize)) return(DDERR_INVALIDPARAMS); if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0) { i=0; while(iDPA_SurfacePrivateData) && !bFound) { pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i); if (IsEqualGUID(&pSData->guidTag,refGUID)) bFound = TRUE; i++; } } if(bFound) { if(!pSData->isValid) { rc =DDERR_EXPIRED; } else { if(pSData->dwSize > *lpDataSize) { // Buffer to small return needed Size *lpDataSize = pSData->dwSize; rc = DDERR_MOREDATA; } else { memcpy(lpData,pSData->pData,pSData->dwSize); rc = DD_OK; } } } else rc = DDERR_NOTFOUND; return rc; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfFreePrivateData(THIS This, REFGUID refGUID) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; int i; PSURFPRIVATEDATA pSData; BOOL bFound = FALSE; dprintf(("DDRAW: SurfFreePrivateData\n")); if(NULL==me) return(DDERR_INVALIDOBJECT); if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0) { i=0; while(iDPA_SurfacePrivateData) && !bFound) { pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i); if (IsEqualGUID(&pSData->guidTag,refGUID)) { bFound = TRUE; if(pSData->isValid) { // delete the data if valid if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER) { // pointer to com stored so calll its release ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->fnRelease(pSData->pData); } else { // Free allocated data free( pSData->pData); } } // Now remove the entry from the list DPA_DeletePtr(me->DPA_SurfacePrivateData,i); } i++; } } return (bFound?DD_OK:DDERR_NOTFOUND); } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfGetUniquenessValue(THIS This, LPDWORD lpValue) { dprintf(("DDRAW: SurfGetUniquenessValue\n")); OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; if (NULL==lpValue) return DDERR_INVALIDPARAMS; *lpValue = me->dwUniqueValue; return DD_OK; } //****************************************************************************** //****************************************************************************** HRESULT WIN32API SurfChangeUniquenessValue(THIS This) { OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This; int i; PSURFPRIVATEDATA pSData; dprintf(("DDRAW: SurfChangeUniquenessValue\n")); me->dwUniqueValue++; if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0) { i=0; while(iDPA_SurfacePrivateData)) { pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i); if (pSData->dwFlags & DDSPD_VOLATILE) { // Data becomes unvalid after a Surface change if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER) { // pointer to com stored so call its release ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->fnRelease(pSData->pData); } else { // Free allocated data free( pSData->pData); } pSData->pData = NULL; pSData->isValid = FALSE; // set flag to invalid } i++; } } return (DD_OK); } //****************************************************************************** //****************************************************************************** IDirectDrawSurface4Vtbl DDrawSurfaceV4Table = { SurfQueryInterface, SurfAddRef, SurfRelease, SurfAddAttachedSurface4, SurfAddOverlayDirtyRect, SurfBlt4, SurfBltBatch, SurfBltFast4, SurfDeleteAttachedSurface4, SurfEnumAttachedSurfaces4, SurfEnumOverlayZOrders4, SurfFlip4, SurfGetAttachedSurface4, SurfGetBltStatus, SurfGetCaps4, SurfGetClipper, SurfGetColorKey, SurfGetDC, SurfGetFlipStatus, SurfGetOverlayPosition, SurfGetPalette, SurfGetPixelFormat, SurfGetSurfaceDesc4, SurfInitialize4, SurfIsLost, SurfLock4, SurfReleaseDC, SurfRestore, SurfSetClipper, SurfSetColorKey, SurfSetOverlayPosition, SurfSetPalette, SurfUnlock4, SurfUpdateOverlay4, SurfUpdateOverlayDisplay, SurfUpdateOverlayZOrder4, SurfGetDDInterface, SurfPageLock, SurfPageUnlock, SurfSetSurfaceDesc4, SurfSetPrivateData, SurfGetPrivateData, SurfFreePrivateData, SurfGetUniquenessValue, SurfChangeUniquenessValue }; //****************************************************************************** //****************************************************************************** IDirectDrawSurface3Vtbl DDrawSurfaceV3Table = { SurfQueryInterface, SurfAddRef, SurfRelease, SurfAddAttachedSurface3, SurfAddOverlayDirtyRect, SurfBlt3, SurfBltBatch, SurfBltFast3, SurfDeleteAttachedSurface3, SurfEnumAttachedSurfaces, SurfEnumOverlayZOrders, SurfFlip3, SurfGetAttachedSurface3, SurfGetBltStatus, SurfGetCaps, SurfGetClipper, SurfGetColorKey, SurfGetDC, SurfGetFlipStatus, SurfGetOverlayPosition, SurfGetPalette, SurfGetPixelFormat, SurfGetSurfaceDesc, SurfInitialize, SurfIsLost, SurfLock, SurfReleaseDC, SurfRestore, SurfSetClipper, SurfSetColorKey, SurfSetOverlayPosition, SurfSetPalette, SurfUnlock, SurfUpdateOverlay3, SurfUpdateOverlayDisplay, SurfUpdateOverlayZOrder3, SurfGetDDInterface, SurfPageLock, SurfPageUnlock, SurfSetSurfaceDesc }; //****************************************************************************** //****************************************************************************** IDirectDrawSurface2Vtbl DDrawSurfaceV2Table = { SurfQueryInterface, SurfAddRef, SurfRelease, SurfAddAttachedSurface, SurfAddOverlayDirtyRect, SurfBlt, SurfBltBatch, SurfBltFast, SurfDeleteAttachedSurface, SurfEnumAttachedSurfaces, SurfEnumOverlayZOrders, SurfFlip, SurfGetAttachedSurface, SurfGetBltStatus, SurfGetCaps, SurfGetClipper, SurfGetColorKey, SurfGetDC, SurfGetFlipStatus, SurfGetOverlayPosition, SurfGetPalette, SurfGetPixelFormat, SurfGetSurfaceDesc, SurfInitialize, SurfIsLost, SurfLock, SurfReleaseDC, SurfRestore, SurfSetClipper, SurfSetColorKey, SurfSetOverlayPosition, SurfSetPalette, SurfUnlock, SurfUpdateOverlay, SurfUpdateOverlayDisplay, SurfUpdateOverlayZOrder, SurfGetDDInterface, SurfPageLock, SurfPageUnlock }; //****************************************************************************** //******************************************************************************