Ignore:
Timestamp:
Jun 26, 1999, 1:34:43 PM (26 years ago)
Author:
hugh
Message:

DX 6 Version of ddraw rel files

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/ddraw/OS2SURFACE.CPP

    r97 r210  
    1 /* $Id: OS2SURFACE.CPP,v 1.3 1999-06-10 17:10:56 phaller Exp $ */
    2 
    3 /*
    4  * DirectDraw Surface class
    5  *
    6  * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
    7  *
    8  * Project Odin Software License can be found in LICENSE.TXT
    9  *
    10  */
    11 /*@Const************************************************************************
    12 *   Defined Constants                                                          *
    13 *******************************************************************************/
    14 #define INIT_GUID
    15 #define INCL_MM_OS2
    16 #define WIN32SDK_NOPOSTWRAPPER
    17 
    18 #define BYTE0(a)    (char)(a & 0xFF)
    19 #define BYTE1(a)    (char)((a>>8) & 0xFF)
    20 #define BYTE2(a)    (char)((a>>16) & 0xFF)
    21 #define BYTE3(a)    (char)(a>>24)
    22 
    23 /*@Header***********************************************************************
    24 *   Header Files                                                               *
    25 *******************************************************************************/
    26 #include <os2win.h>
    27 #include <dive.h>
    281#include <stdlib.h>
    292#include <string.h>
    303#include <memory.h>
    31 
    32 #include "no.h"
    33 #include <w_windows.h>
    34 #include <ddraw.h>
    35 #include <d3d.h>
    36 #include <Win32SDKPostWrapper.h>
    37 
     4#define mmioFOURCC( ch0, ch1, ch2, ch3 )                         \
     5                  ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) |    \
     6                  ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
    387#include <fourcc.h>
    39 
    40 #include "os2ddraw.h"
    418#include "os2surface.h"
     9#define _OS2WIN_H
     10#define FAR
    4211#include "misc.h"
    43 #include "os2util.h"
    4412#include "asmutil.h"
    45 
     13#include <winerror.h>
    4614#ifndef __WATCOMC__
    47     #include <builtin.h>
     15#include <builtin.h>
    4816#endif
    4917
    50 
    51 /* KSO Apr 19 1999: Set correct interface.           *
    52  * (INTERFACE is used in the THIS and THIS_ macros)  */
    53 #undef  INTERFACE
    54 #define INTERFACE   IDirectDrawSurface2
    55 
    56 extern DIVE_CAPS dcaps;
    57 extern FOURCC    fccFormats[100];
    58 
    59 //******************************************************************************
    60 //Assumes 8 bits or more per pixel
     18extern FOURCC  SupportedFourCCs[];
     19// ToDo: Move the following 2 defines in the right WINE headers.
     20
     21#define CBM_CREATEDIB   0x02L   /* create DIB bitmap */
     22#define BI_BITFIELDS  0x03L
     23#ifdef DEBUG
     24
     25// ******************************************************************************
     26// *    internal helper functions from WINE
     27// *
     28
     29static void _dump_DDBLTFX(DWORD flagmask) {
     30  int  i;
     31  const struct {
     32    DWORD  mask;
     33    char  *name;
     34  } flags[] = {
     35#define FE(x) { x, #x},
     36    FE(DDBLTFX_ARITHSTRETCHY)
     37    FE(DDBLTFX_MIRRORLEFTRIGHT)
     38    FE(DDBLTFX_MIRRORUPDOWN)
     39    FE(DDBLTFX_NOTEARING)
     40    FE(DDBLTFX_ROTATE180)
     41    FE(DDBLTFX_ROTATE270)
     42    FE(DDBLTFX_ROTATE90)
     43    FE(DDBLTFX_ZBUFFERRANGE)
     44    FE(DDBLTFX_ZBUFFERBASEDEST)
     45  };
     46  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
     47     if (flags[i].mask & flagmask) {
     48        WriteLog("%s ",flags[i].name);
     49     };
     50  WriteLog("\n");
     51
     52}
     53
     54static void _dump_DDBLTFAST(DWORD flagmask) {
     55  int  i;
     56  const struct {
     57    DWORD  mask;
     58    char  *name;
     59  } flags[] = {
     60#define FE(x) { x, #x},
     61    FE(DDBLTFAST_NOCOLORKEY)
     62    FE(DDBLTFAST_SRCCOLORKEY)
     63    FE(DDBLTFAST_DESTCOLORKEY)
     64    FE(DDBLTFAST_WAIT)
     65  };
     66  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
     67    if (flags[i].mask & flagmask)
     68      WriteLog("%s ",flags[i].name);
     69  WriteLog("\n");
     70}
     71
     72static void _dump_DDBLT(DWORD flagmask) {
     73  int  i;
     74  const struct {
     75    DWORD  mask;
     76    char  *name;
     77  } flags[] = {
     78#define FE(x) { x, #x},
     79    FE(DDBLT_ALPHADEST)
     80    FE(DDBLT_ALPHADESTCONSTOVERRIDE)
     81    FE(DDBLT_ALPHADESTNEG)
     82    FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
     83    FE(DDBLT_ALPHAEDGEBLEND)
     84    FE(DDBLT_ALPHASRC)
     85    FE(DDBLT_ALPHASRCCONSTOVERRIDE)
     86    FE(DDBLT_ALPHASRCNEG)
     87    FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
     88    FE(DDBLT_ASYNC)
     89    FE(DDBLT_COLORFILL)
     90    FE(DDBLT_DDFX)
     91    FE(DDBLT_DDROPS)
     92    FE(DDBLT_KEYDEST)
     93    FE(DDBLT_KEYDESTOVERRIDE)
     94    FE(DDBLT_KEYSRC)
     95    FE(DDBLT_KEYSRCOVERRIDE)
     96    FE(DDBLT_ROP)
     97    FE(DDBLT_ROTATIONANGLE)
     98    FE(DDBLT_ZBUFFER)
     99    FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
     100    FE(DDBLT_ZBUFFERDESTOVERRIDE)
     101    FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
     102    FE(DDBLT_ZBUFFERSRCOVERRIDE)
     103    FE(DDBLT_WAIT)
     104    FE(DDBLT_DEPTHFILL)
     105  };
     106  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
     107    if (flags[i].mask & flagmask)
     108      WriteLog("%s ",flags[i].name);
     109}
     110
     111static void _dump_DDSCAPS(DWORD flagmask) {
     112  int  i;
     113  const struct {
     114    DWORD  mask;
     115    char  *name;
     116  } flags[] = {
     117#define FE(x) { x, #x},
     118    FE(DDSCAPS_RESERVED1)
     119    FE(DDSCAPS_ALPHA)
     120    FE(DDSCAPS_BACKBUFFER)
     121    FE(DDSCAPS_COMPLEX)
     122    FE(DDSCAPS_FLIP)
     123    FE(DDSCAPS_FRONTBUFFER)
     124    FE(DDSCAPS_OFFSCREENPLAIN)
     125    FE(DDSCAPS_OVERLAY)
     126    FE(DDSCAPS_PALETTE)
     127    FE(DDSCAPS_PRIMARYSURFACE)
     128    FE(DDSCAPS_PRIMARYSURFACELEFT)
     129    FE(DDSCAPS_SYSTEMMEMORY)
     130    FE(DDSCAPS_TEXTURE)
     131    FE(DDSCAPS_3DDEVICE)
     132    FE(DDSCAPS_VIDEOMEMORY)
     133    FE(DDSCAPS_VISIBLE)
     134    FE(DDSCAPS_WRITEONLY)
     135    FE(DDSCAPS_ZBUFFER)
     136    FE(DDSCAPS_OWNDC)
     137    FE(DDSCAPS_LIVEVIDEO)
     138    FE(DDSCAPS_HWCODEC)
     139    FE(DDSCAPS_MODEX)
     140    FE(DDSCAPS_MIPMAP)
     141    FE(DDSCAPS_RESERVED2)
     142    FE(DDSCAPS_ALLOCONLOAD)
     143    FE(DDSCAPS_VIDEOPORT)
     144    FE(DDSCAPS_LOCALVIDMEM)
     145    FE(DDSCAPS_NONLOCALVIDMEM)
     146    FE(DDSCAPS_STANDARDVGAMODE)
     147    FE(DDSCAPS_OPTIMIZED)
     148  };
     149  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
     150    if (flags[i].mask & flagmask)
     151      WriteLog("%s ",flags[i].name);
     152  WriteLog("\n");
     153}
     154
     155static void _dump_DDSD(DWORD flagmask) {
     156  int  i;
     157  const struct {
     158    DWORD  mask;
     159    char  *name;
     160  } flags[] = {
     161    FE(DDSD_CAPS)
     162    FE(DDSD_HEIGHT)
     163    FE(DDSD_WIDTH)
     164    FE(DDSD_PITCH)
     165    FE(DDSD_BACKBUFFERCOUNT)
     166    FE(DDSD_ZBUFFERBITDEPTH)
     167    FE(DDSD_ALPHABITDEPTH)
     168    FE(DDSD_PIXELFORMAT)
     169    FE(DDSD_CKDESTOVERLAY)
     170    FE(DDSD_CKDESTBLT)
     171    FE(DDSD_CKSRCOVERLAY)
     172    FE(DDSD_CKSRCBLT)
     173    FE(DDSD_MIPMAPCOUNT)
     174    FE(DDSD_REFRESHRATE)
     175    FE(DDSD_LINEARSIZE)
     176    FE(DDSD_LPSURFACE)
     177    FE(DDSD_TEXTURESTAGE)
     178  };
     179  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
     180    if (flags[i].mask & flagmask)
     181      WriteLog("%s ",flags[i].name);
     182  WriteLog("\n");
     183}
     184
     185static void _dump_DDCOLORKEY(DWORD flagmask) {
     186  int  i;
     187  const struct {
     188    DWORD  mask;
     189    char  *name;
     190  } flags[] = {
     191#define FE(x) { x, #x},
     192          FE(DDPF_ALPHAPIXELS)
     193    FE(DDPF_ALPHA)
     194    FE(DDPF_FOURCC)
     195    FE(DDPF_PALETTEINDEXED4)
     196    FE(DDPF_PALETTEINDEXEDTO8)
     197    FE(DDPF_PALETTEINDEXED8)
     198    FE(DDPF_RGB)
     199    FE(DDPF_COMPRESSED)
     200    FE(DDPF_RGBTOYUV)
     201    FE(DDPF_YUV)
     202    FE(DDPF_ZBUFFER)
     203    FE(DDPF_PALETTEINDEXED1)
     204    FE(DDPF_PALETTEINDEXED2)
     205    FE(DDPF_ZPIXELS)
     206  };
     207  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
     208    if (flags[i].mask & flagmask)
     209      WriteLog("%s ",flags[i].name);
     210  WriteLog("\n");
     211}
     212
     213static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
     214  _dump_DDCOLORKEY(pf->dwFlags);
     215  WriteLog("dwFourCC : %ld\n", pf->dwFourCC);
     216  WriteLog("RBG bit cbout : %ld\n", pf->dwRGBBitCount);
     217  WriteLog("Masks : R %08lx  G %08lx  B %08lx  A %08lx\n",
     218       pf->dwRBitMask, pf->dwGBitMask, pf->dwBBitMask, pf->dwRGBAlphaBitMask);
     219}
     220
     221// End of Internal Helpers
     222#endif
     223
     224//******************************************************************************
    61225//******************************************************************************
    62226OS2IDirectDrawSurface::OS2IDirectDrawSurface(OS2IDirectDraw *lpDirectDraw,
    63                          LPDDSURFACEDESC lpDDSurfaceDesc) :
    64                            Referenced(0), lastError(DD_OK),
    65                            diveBufNr(-1), lpClipper(NULL),
    66                            lpPalette(NULL), lpDraw(NULL),
    67                            fLocked(FALSE), hdcImage(NULL),
    68                            hbmImage(NULL), bitmapData(NULL),
    69                            pFrameBuffer(NULL), attached(NULL),
    70                            flip(NULL),lpBuffer(NULL), ColorKeyFlags(0)
    71 {
    72  ULONG rc;
    73 
    74   lpVtbl                        = &Vtbl;
    75   Vtbl.AddRef                   = SurfAddRef;
    76   Vtbl.Release                  = SurfRelease;
    77   Vtbl.QueryInterface           = SurfQueryInterface;
    78   Vtbl.AddAttachedSurface       = SurfAddAttachedSurface;
    79   Vtbl.AddOverlayDirtyRect      = SurfAddOverlayDirtyRect;
    80   Vtbl.Blt                      = SurfBlt;
    81   Vtbl.BltBatch                 = SurfBltBatch;
    82   Vtbl.BltFast                  = SurfBltFast;
    83   Vtbl.DeleteAttachedSurface    = SurfDeleteAttachedSurface;
    84   Vtbl.EnumAttachedSurfaces     = SurfEnumAttachedSurfaces;
    85   Vtbl.EnumOverlayZOrders       = SurfEnumOverlayZOrders;
    86   Vtbl.Flip                     = SurfFlip;
    87   Vtbl.GetAttachedSurface       = SurfGetAttachedSurface;
    88   Vtbl.GetBltStatus             = SurfGetBltStatus;
    89   Vtbl.GetCaps                  = SurfGetCaps;
    90   Vtbl.GetClipper               = SurfGetClipper;
    91   Vtbl.GetColorKey              = SurfGetColorKey;
    92   Vtbl.W32_GetDC                = SurfGetDC;    //KSO Apr 19 1999: side effect of the wrapper...
    93   Vtbl.GetFlipStatus            = SurfGetFlipStatus;
    94   Vtbl.GetOverlayPosition       = SurfGetOverlayPosition;
    95   Vtbl.GetPalette               = SurfGetPalette;
    96   Vtbl.GetPixelFormat           = SurfGetPixelFormat;
    97   Vtbl.GetSurfaceDesc           = SurfGetSurfaceDesc;
    98   Vtbl.Initialize               = SurfInitialize;
    99   Vtbl.IsLost                   = SurfIsLost;
    100   Vtbl.Lock                     = SurfLock;
    101   Vtbl.W32_ReleaseDC            = SurfReleaseDC;//KSO Apr 19 1999: side effect of the wrapper...
    102   Vtbl.Restore                  = SurfRestore;
    103   Vtbl.SetClipper               = SurfSetClipper;
    104   Vtbl.SetColorKey              = SurfSetColorKey;
    105   Vtbl.SetOverlayPosition       = SurfSetOverlayPosition;
    106   Vtbl.SetPalette               = SurfSetPalette;
    107   Vtbl.Unlock                   = SurfUnlock;
    108   Vtbl.UpdateOverlay            = SurfUpdateOverlay;
    109   Vtbl.UpdateOverlayDisplay     = SurfUpdateOverlayDisplay;
    110   Vtbl.UpdateOverlayZOrder      = SurfUpdateOverlayZOrder;
    111   Vtbl.GetDDInterface           = SurfGetDDInterface;
    112   Vtbl.PageLock                 = SurfPageLock;
    113   Vtbl.PageUnlock               = SurfPageUnlock;
    114 
    115   lpDraw                        = lpDirectDraw;
    116   lpDraw->Vtbl.AddRef((IDirectDraw2*)lpDraw);
    117   hDive                         = lpDirectDraw->GetDiveInstance();
    118   surfaceType                   = DDSCAPS_OFFSCREENPLAIN;
    119 
    120   memcpy((char *)&DDSurfaceDesc, (char *)lpDDSurfaceDesc, sizeof(DDSURFACEDESC));
    121 
    122   //TODO: finish up and do better error checking (can't create multiple
    123   //      primary surfaces etc etc
    124   if(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)
    125         height = lpDDSurfaceDesc->dwHeight;
    126   if(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)
    127         width = lpDDSurfaceDesc->dwWidth;
    128 
    129   if(height == 0)
    130         height = lpDraw->GetScreenHeight();
    131   if(width == 0)
    132         width = lpDraw->GetScreenWidth();
    133 //test
    134   lpDDSurfaceDesc->dwHeight = height;
    135   lpDDSurfaceDesc->dwWidth  = width;
    136 
    137   //SvL: TODO: Check if DIVE supports all ddraw fourcc codes
    138   if(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) {
    139     if(lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
    140         fccColorFormat = lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC;
    141     }
    142     else {
    143         dprintf(("   Unsupported pixel format, defaulting to LUT8"));
    144         fccColorFormat = FOURCC_LUT8;
    145     }
    146   }
    147   else  fccColorFormat = FOURCC_LUT8;
    148   screenXFact    = 1.0;
    149   screenYFact    = 1.0;
    150   //TODO: base this on the fourcc value!!
    151   bpp            = 8;
    152 
    153   if(lpDDSurfaceDesc->dwFlags & DDSD_CAPS) {
     227               LPDDSURFACEDESC2 lpDDSurfaceDesc, BOOL Implicit, BOOL Mainchain) :
     228                  Referenced(0), lastError(DD_OK),
     229                 diveBufNr(-1), lpClipper(NULL),
     230                 lpPalette(NULL), lpDraw(NULL),
     231                 fLocked(FALSE), hdcImage(NULL),
     232                 hbmImage(NULL),
     233                 pFrameBuffer(NULL),Updated(FALSE),
     234                 fOverlayValid(FALSE),
     235                 BackBuffer(NULL),FrontBuffer(NULL)
     236
     237{
     238  ULONG rc;
     239  DWORD i;
     240  DIVE_CAPS dCaps;
     241  DDSURFACEDESC2 ComplexSurfaceDesc;
     242  OS2IDirectDrawSurface *AttachedSurface;
     243
     244  lpVtbl                     = &Vtbl;
     245  Vtbl.AddRef                = SurfAddRef;
     246  Vtbl.Release               = SurfRelease;
     247  Vtbl.QueryInterface        = SurfQueryInterface;
     248  Vtbl.AddAttachedSurface    = SurfAddAttachedSurface4;
     249  Vtbl.AddOverlayDirtyRect   = SurfAddOverlayDirtyRect;
     250  Vtbl.Blt                   = SurfBlt4;
     251  Vtbl.BltBatch              = SurfBltBatch;
     252  Vtbl.BltFast               = SurfBltFast4;
     253  Vtbl.DeleteAttachedSurface = SurfDeleteAttachedSurface4;
     254  Vtbl.EnumAttachedSurfaces  = SurfEnumAttachedSurfaces4;
     255  Vtbl.EnumOverlayZOrders    = SurfEnumOverlayZOrders4;
     256  Vtbl.Flip                  = SurfFlip4;
     257  Vtbl.GetAttachedSurface    = SurfGetAttachedSurface4;
     258  Vtbl.GetBltStatus          = SurfGetBltStatus;
     259  Vtbl.GetCaps               = SurfGetCaps4;
     260  Vtbl.GetClipper            = SurfGetClipper;
     261  Vtbl.GetColorKey           = SurfGetColorKey;
     262  Vtbl.GetDC                 = SurfGetDC;
     263  Vtbl.GetFlipStatus         = SurfGetFlipStatus;
     264  Vtbl.GetOverlayPosition    = SurfGetOverlayPosition;
     265  Vtbl.GetPalette            = SurfGetPalette;
     266  Vtbl.GetPixelFormat        = SurfGetPixelFormat;
     267  Vtbl.GetSurfaceDesc        = SurfGetSurfaceDesc4;
     268  Vtbl.Initialize            = SurfInitialize4;
     269  Vtbl.IsLost                = SurfIsLost;
     270  Vtbl.Lock                  = SurfLock4;
     271  Vtbl.ReleaseDC             = SurfReleaseDC;
     272  Vtbl.Restore               = SurfRestore;
     273  Vtbl.SetClipper            = SurfSetClipper;
     274  Vtbl.SetColorKey           = SurfSetColorKey;
     275  Vtbl.SetOverlayPosition    = SurfSetOverlayPosition;
     276  Vtbl.SetPalette            = SurfSetPalette;
     277  Vtbl.Unlock                = SurfUnlock;
     278  Vtbl.UpdateOverlay         = SurfUpdateOverlay4;
     279  Vtbl.UpdateOverlayDisplay  = SurfUpdateOverlayDisplay;
     280  Vtbl.UpdateOverlayZOrder   = SurfUpdateOverlayZOrder4;
     281  Vtbl.GetDDInterface        = SurfGetDDInterface;
     282  Vtbl.PageLock              = SurfPageLock;
     283  Vtbl.PageUnlock            = SurfPageUnlock;
     284  Vtbl.SetSurfaceDesc        = SurfSetSurfaceDesc4;
     285  Vtbl.SetPrivateData        = SurfSetPrivateData;
     286  Vtbl.GetPrivateData        = SurfGetPrivateData;
     287  Vtbl.FreePrivateData       = SurfFreePrivateData;
     288  Vtbl.ChangeUniquenessValue = SurfChangeUniquenessValue;
     289  Vtbl.GetUniquenessValue    = SurfGetUniquenessValue;
     290  lpDraw                     = lpDirectDraw;
     291  lpDraw->Vtbl.AddRef(lpDraw);
     292
     293  ImplicitSurface = Implicit;
     294
     295  hDive                      = lpDirectDraw->GetDiveInstance();
     296  surfaceType                = DDSCAPS_OFFSCREENPLAIN;
     297  memcpy((char *)&DDSurfaceDesc, (char *)lpDDSurfaceDesc, sizeof(DDSURFACEDESC2));
     298
     299  if(lpDraw->dCaps.ulDepth != 15)
     300  {
     301    if(lpDraw->dCaps.ulDepth >= 8)
     302      dwBytesPPDive = lpDraw->dCaps.ulDepth >> 3;
     303    else
     304      dwBytesPPDive = 1; // not sure if this is the case
     305  }
     306  else
     307    dwBytesPPDive = 2; // 2 bytes for 15Bit
     308
     309  // Setting up Cursors for handling attached Surfaces
     310  try
     311  {
     312    SurfaceCursorMipMap = SurfaceSequenceMipMap.newCursor();
     313  }
     314  catch(IOutOfMemory)
     315  {
     316    #ifdef DEBUG
     317      WriteLog("Internal : Error creating Cursor\n");
     318    #endif
     319    lastError = DDERR_OUTOFMEMORY ;
     320    return;
     321  }
     322
     323  try
     324  {
     325    SurfaceCursorAttached = SurfaceSequenceAttached.newCursor();
     326  }
     327  catch(IOutOfMemory)
     328  {
     329    #ifdef DEBUG
     330      WriteLog("Internal : Error creating Cursor\n");
     331    #endif
     332    lastError = DDERR_OUTOFMEMORY ;
     333    return;
     334  }
     335
     336  if( lpDDSurfaceDesc->dwFlags & DDSD_CAPS )
     337  {
     338    // First check if we want to create a primary surface while the ddraw object already has one
    154339    surfaceType = lpDDSurfaceDesc->ddsCaps.dwCaps;
    155     if(surfaceType & DDSCAPS_PRIMARYSURFACE) {
    156         dprintf(("   Primary surface!\n"));
     340
     341    if( surfaceType & DDSCAPS_PRIMARYSURFACE)
     342    {
     343      if( lpDraw->HasPrimarySurface())
     344      {
     345        lastError = DDERR_PRIMARYSURFACEALREADYEXISTS;
     346        return;
     347      }
     348
     349      #ifdef DEBUG
     350        WriteLog("Primary surface!\n");
     351      #endif
     352      if( (lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) ||
     353          (lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)  ||
     354          (lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT)
     355        )
     356      {
     357        // Dx doc says passing width,height etc. for primary surface in not permitted!!
     358        WriteLog("Invalid parameters\n\n");
     359        lastError = DDERR_INVALIDPARAMS;
     360        return;
     361      }
     362
     363      // Check if OS/2 is running in the requested colormode
     364
     365      if( lpDraw->dCaps.ulDepth == lpDraw->GetScreenBpp() )
     366      {
     367        WriteLog("DirectScreenAccess possible\n");
     368
     369        // Yes so direct access to framebuffer is possible
     370
    157371        diveBufNr    = DIVE_BUFFER_SCREEN;
    158372        pFrameBuffer = lpDraw->GetFrameBuffer();
    159         //SvL: Needed for stretching if we're not running in 640x480
    160         if(lpDraw->IsFullScreen() == TRUE) {
    161             screenYFact  = (double)dcaps.ulVerticalResolution/(double)height;
    162             screenXFact  = (double)dcaps.ulHorizontalResolution/(double)width;
    163         }
    164         fccColorFormat = FOURCC_SCRN;
    165         bpp            = dcaps.ulDepth;
    166     }
    167     if(!(surfaceType & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN))) {
    168         lastError = DDERR_INVALIDPARAMS;
    169     }
    170   }
    171   else  surfaceType = 0;
    172 
    173   dprintf(("   fccColorFormat %c%c%c%c", BYTE0(fccColorFormat), BYTE1(fccColorFormat), BYTE2(fccColorFormat), BYTE3(fccColorFormat)));
    174 
    175   if(height && width && diveBufNr == -1) {
    176     diveBufNr = 0;  //need to set to 0 for new buffer!
    177     lpBuffer = (PBYTE)OS2AllocMem(width*height*bpp/8);
    178     if(lpBuffer == NULL) {
    179         lastError = DDERR_INVALIDPARAMS;
    180         return;
    181     }
    182     dprintf(("   lpBuffer = %X", lpBuffer));
    183     rc = DiveAllocImageBuffer(hDive, &diveBufNr, fccColorFormat, width, height, width, lpBuffer);
    184     if(rc != DIVE_SUCCESS) {
    185         dprintf(("   DiveAllocImageBuffer failed with %d", rc));
    186         lastError = DDERR_INVALIDPARAMS;    //TODO: better errors
    187         return;
    188     }
    189     else {
    190         dprintf(("   DiveAllocImageBuffer returned %d", diveBufNr));
    191     }
    192   }
    193 
    194   dprintf(("   Buf %X Screen Caps (%d,%d), bitcount %d\n", this, dcaps.ulVerticalResolution, dcaps.ulHorizontalResolution,
    195        dcaps.ulDepth));
    196 
    197   //todo: checking for flip & complex bits if backbuffer bit present!
    198   if(lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT) {
    199     OS2IDirectDrawSurface *attachedSurface, *tmpSurface = NULL;
    200     DDSURFACEDESC          surfDescription;
    201 
    202     dprintf(("   Create %d background surface(s)", lpDDSurfaceDesc->dwBackBufferCount));
    203     memcpy((char *)&surfDescription, (char *)lpDDSurfaceDesc, sizeof(DDSURFACEDESC));
    204     surfDescription.ddsCaps.dwCaps   &= ~DDSCAPS_PRIMARYSURFACE;
    205     surfDescription.dwBackBufferCount = 0;
    206     surfDescription.ddsCaps.dwCaps    = DDSCAPS_BACKBUFFER; //only the first one!
    207 
    208     //SvL: Create background surfaces
    209     for(int i=0;i<lpDDSurfaceDesc->dwBackBufferCount;i++) {
    210         attachedSurface = new OS2IDirectDrawSurface(lpDirectDraw,
    211                                     &surfDescription);
    212         if(tmpSurface) {
    213             tmpSurface->attached = attachedSurface;
    214         }
    215         else {
    216             attached = attachedSurface;
    217             flip     = attached;
    218         }
    219 
    220         tmpSurface = attachedSurface;
    221         //SvL: All other back surfaces have the flip bit set
    222         surfDescription.ddsCaps.dwCaps = DDSCAPS_FLIP;
    223     }
    224   }
    225   memset((char *)&SurfaceCaps, 0, sizeof(DDCAPS));
    226   SurfaceCaps.ddsCaps.dwCaps = surfaceType;
    227   SurfaceCaps.dwSize         = sizeof(DDCAPS);
    228   //TODO: might need to change some flags
    229   SurfaceCaps.dwCaps         = DDCAPS_COLORKEY | DDCAPS_NOHARDWARE;
    230   SurfaceCaps.dwCaps2        = DDCAPS2_CERTIFIED; //of course we're certified
    231   //TODO: might need to change some flags as we might support more in the future
    232   SurfaceCaps.dwCKeyCaps     = DDCKEYCAPS_SRCBLT;
    233   SurfaceCaps.dwFXCaps       = 0;
    234   SurfaceCaps.dwFXAlphaCaps  = 0;
    235   //TODO
    236   if(bpp == 8) {
    237       SurfaceCaps.dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
    238   }
    239   SurfaceCaps.dwVidMemTotal  = 1024*1024;   //todo
    240   SurfaceCaps.dwVidMemFree   = SurfaceCaps.dwVidMemTotal - dcaps.ulVerticalResolution*dcaps.ulVerticalResolution*dcaps.ulDepth/8;
    241   SurfaceCaps.dwNumFourCCCodes   = 1;
    242   SurfaceCaps.dwAlignBoundarySrc = 4;
    243   SurfaceCaps.dwAlignSizeDest    = 4;
    244   SurfaceCaps.dwAlignStrideAlign = 4;
    245 
    246   dprintf(("DirectDrawSurface ctor end!"));
     373        pDiveBuffer  = pFrameBuffer;
     374        dwPitchDB    = lpDraw->dCaps.ulScanLineBytes;
     375        dwPitchFB    = dwPitchDB;
     376        DDSurfaceDesc.lPitch = dwPitchDB;
     377      }
     378      else
     379      {
     380        // No so we create a virtual framebuffer which the program can access
     381        // and blit to the real framebuffer on Unlock to do color conversion
     382
     383        WriteLog( "Need Color conversation %d => %d Bit\n",
     384                  lpDraw->GetScreenBpp(),
     385                  lpDraw->dCaps.ulDepth
     386                );
     387
     388        dwPitchFB = (lpDraw->GetScreenWidth() * lpDraw->GetScreenBpp() +7) & ~7;
     389        DDSurfaceDesc.lPitch = dwPitchFB;
     390
     391        // 24 byte more to enable alignment and speed up blitting
     392
     393        pFBreal = (char*)malloc( lpDraw->GetScreenHeight() * dwPitchFB + 24);
     394        pFrameBuffer = (char*)(((int)pFBreal + 7) & ~7); // align to QWORD
     395
     396        // DiveBuffer points to real framebuffer
     397        dwPitchDB    = lpDraw->dCaps.ulScanLineBytes;
     398        pDiveBuffer = lpDraw->GetFrameBuffer();
     399
     400      }
     401
     402      // Update passed in and local Surface description
     403
     404      #ifdef DEBUG
     405        WriteLog("Setting up Surface\n");
     406      #endif
     407      DDSurfaceDesc.dwFlags     |= DDSD_WIDTH | DDSD_HEIGHT |
     408                                   DDSD_PITCH | DDSD_LPSURFACE |
     409                                   DDSD_PIXELFORMAT;
     410      DDSurfaceDesc.dwHeight     = lpDraw->GetScreenHeight();
     411      DDSurfaceDesc.dwWidth      = lpDraw->GetScreenWidth();
     412      DDSurfaceDesc.lpSurface    = pFrameBuffer;
     413      lpDDSurfaceDesc->dwFlags   = DDSurfaceDesc.dwFlags;
     414      lpDDSurfaceDesc->dwHeight  = DDSurfaceDesc.dwHeight;
     415      lpDDSurfaceDesc->dwWidth   = DDSurfaceDesc.dwWidth;
     416      lpDDSurfaceDesc->lpSurface = pFrameBuffer;
     417      lpDDSurfaceDesc->lPitch    = DDSurfaceDesc.lPitch;
     418
     419      lpDDSurfaceDesc->ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
     420      DDSurfaceDesc.ddsCaps.dwCaps    |= DDSCAPS_VISIBLE;
     421      lpDraw->SetPrimarySurface(TRUE);
     422      lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
     423      lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC = (DWORD) lpDraw->GetScreenFourCC();
     424      lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = lpDraw->GetScreenBpp();
     425      DDSurfaceDesc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
     426      DDSurfaceDesc.ddpfPixelFormat.dwFourCC = (DWORD) lpDraw->GetScreenFourCC();
     427      DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = lpDraw->GetScreenBpp();
     428
     429      switch(DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
     430      {
     431        case 4:
     432          lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4 | DDPF_RGB;
     433          DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4 | DDPF_RGB;
     434          break;
     435        case 8:
     436          lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_RGB;
     437          DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_RGB;
     438          break;
     439        case 16:
     440          lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
     441          lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x0000F800;
     442          lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x000007E0;
     443          lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000001F;
     444          DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
     445          DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x0000F800;
     446          DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x000007E0;
     447          DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x0000001F;
     448          break;
     449        case 24:
     450        case 32:
     451          lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
     452          lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
     453          lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     454          lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x000000FF;
     455          DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
     456          DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
     457          DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     458          DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
     459          break;
     460        default:
     461          // Remove the Pixelformat flag
     462          lpDDSurfaceDesc->dwFlags &= ~DDSD_PIXELFORMAT;
     463          DDSurfaceDesc.dwFlags    &= ~DDSD_PIXELFORMAT;
     464          #ifdef DEBUG
     465            WriteLog("Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp());
     466          #endif
     467          break;
     468      } // end switch
     469
     470      #ifdef DEBUG
     471        WriteLog("Surface set up, checking other Caps\n");
     472      #endif
     473
     474      if( DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
     475      {
     476        #ifdef DEBUG
     477          WriteLog("Complex Surface\n");
     478        #endif
     479
     480        if(lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
     481        {
     482          #ifdef DEBUG
     483            WriteLog("Backbuffer # = %d\n",lpDDSurfaceDesc->dwBackBufferCount);
     484          #endif
     485          memset( &ComplexSurfaceDesc,
     486                  0,
     487                  sizeof(DDSURFACEDESC2));
     488
     489          ComplexSurfaceDesc.dwSize  = sizeof(DDSURFACEDESC2);
     490          ComplexSurfaceDesc.dwFlags = DDSD_CAPS |
     491                                       DDSD_WIDTH |
     492                                       DDSD_HEIGHT |
     493                                       DDSD_PIXELFORMAT;
     494          ComplexSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
     495          ComplexSurfaceDesc.dwHeight = DDSurfaceDesc.dwHeight;
     496          ComplexSurfaceDesc.dwWidth = DDSurfaceDesc.dwWidth;
     497          ComplexSurfaceDesc.ddpfPixelFormat.dwFlags = DDSurfaceDesc.ddpfPixelFormat.dwFlags;
     498          ComplexSurfaceDesc.ddpfPixelFormat.dwRBitMask = DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
     499          ComplexSurfaceDesc.ddpfPixelFormat.dwGBitMask = DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
     500          ComplexSurfaceDesc.ddpfPixelFormat.dwBBitMask = DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
     501          ComplexSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
     502
     503          if(lpDDSurfaceDesc->dwBackBufferCount>1)
     504          {
     505            ComplexSurfaceDesc.dwFlags |=DDSD_BACKBUFFERCOUNT;
     506            ComplexSurfaceDesc.dwBackBufferCount = lpDDSurfaceDesc->dwBackBufferCount -1;
     507            ComplexSurfaceDesc.ddsCaps.dwCaps|= DDSCAPS_COMPLEX;
     508          }
     509
     510          BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, TRUE);
     511          if (BackBuffer->GetLastError()==DD_OK)
     512          {
     513            // Our Primary Buffer is also the frontbuffer of a flipchain
     514            DDSurfaceDesc.dwFlags |= DDSCAPS_FRONTBUFFER | DDSCAPS_FLIP;
     515            BackBuffer->SetFrontBuffer(this);
     516          }
     517        }
     518        else
     519        {
     520          #ifdef DEBUG
     521            WriteLog("Unsupported Complex Surface\n");
     522            _dump_DDSCAPS(lpDDSurfaceDesc->dwFlags);
     523          #endif
     524          lastError = DDERR_OUTOFMEMORY;
     525          return;
     526        } //endif Backbuffer
     527      } // endif DDSCAPS_COMPLEX
     528      lastError = DD_OK;
     529      return;
     530    } // endif  DDSCAPS_PRIMARYSURFACE
     531
     532    //
     533    // ToDo : Do better calulation of Bitmap Size to support the compressed Bitmaps in Dx6
     534    //
     535
     536    if( (DDSurfaceDesc.dwFlags & DDSD_HEIGHT) &&
     537        (DDSurfaceDesc.dwFlags & DDSD_WIDTH)
     538      )
     539
     540    {
     541      DWORD dwBpp;
     542      DWORD dwCaps;
     543      if(DDSurfaceDesc.dwFlags & DDSD_PIXELFORMAT)         // Pixelformat passed in ?
     544      {
     545        // YES use it
     546        if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_RGB)
     547        {
     548          dwBpp = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
     549        }
     550        else
     551        {
     552          if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
     553            dwBpp = 8;
     554          if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
     555            dwBpp = 4;
     556        }
     557      }
     558      else
     559        dwBpp = dwBytesPPDive << 3; // No use Screenformat
     560
     561      // three possible situaltions
     562      // 1. User supplied pointer to surface -> use it
     563      // 2. Delayed allocation of a texture -> don't alloc
     564      // 3. Normal allocation
     565      // After this check for complex flag.
     566
     567      dwCaps = DDSurfaceDesc.ddsCaps.dwCaps;
     568
     569      if(DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
     570      {
     571        // 1.
     572
     573        if(NULL==DDSurfaceDesc.lpSurface)
     574        {
     575          // pointer is NULL! Stupid user ;)
     576          lastError = DDERR_INVALIDPARAMS;
     577          return;
     578        }
     579
     580        // User allocated the Buffer for the surface so we don't have to
     581
     582        Updated = TRUE; // Set Flag to indicate User supplied buffer so we don't free it
     583
     584        // As we allready copied the surface description we are done if the # of colors
     585        // of the surface is the same then the screen
     586
     587        pFrameBuffer = (char*)DDSurfaceDesc.lpSurface;
     588        diveBufNr    = -1;
     589        dwPitchFB    = DDSurfaceDesc.lPitch;
     590
     591        if( (lpDraw->dCaps.ulDepth ) == dwBpp )
     592        {
     593          // Yes No Colorconversion is needed so point to the same buffer
     594          dwPitchDB    = dwPitchFB;
     595          pDiveBuffer  = pFrameBuffer;
     596        }
     597        else
     598        {
     599          // No so we must create the Divebuffer to do the color conversion
     600          // and blit to the real framebuffer on Unlock to do color conversion
     601
     602          dwPitchDB = (lpDDSurfaceDesc->dwWidth * dwBytesPPDive +7) & ~7;
     603
     604          // 24 byte more to enable alignment and speed up blitting
     605
     606          pDBreal = (char*)malloc( lpDDSurfaceDesc->dwHeight * dwPitchDB + 24);
     607          pDiveBuffer = (char*)(((int)pDBreal + 7) & ~7); // align to QWORD
     608
     609          // Not sure if that is ok but we need this for translation
     610          // I hope no game uses YUV or such a crap
     611
     612          DDSurfaceDesc.ddpfPixelFormat.dwFourCC = SupportedFourCCs[dwBpp>>3];
     613        }
     614
     615      }
     616      else
     617      {
     618
     619        if(dwCaps & DDSCAPS_ALLOCONLOAD)
     620        {
     621          // 2.
     622
     623          dwCaps &= ~DDSCAPS_ALLOCONLOAD; // remove flag
     624
     625          // only allow this flag for textures
     626          if(!dwCaps & DDSCAPS_TEXTURE)
     627          {
     628            lastError = DDERR_INVALIDPARAMS;
     629            return;
     630          }
     631
     632          dwCaps &= ~DDSCAPS_TEXTURE; // remove flag
     633          pFrameBuffer = NULL;
     634          pDiveBuffer  = NULL;
     635
     636          // This surface isn't allocated yet, but when the texture is loaded
     637          #ifdef DEBUG
     638            WriteLog("Warning : Delayed memory allocation on request\n");
     639          #endif
     640          DDSurfaceDesc.lpSurface = NULL;
     641          lpDDSurfaceDesc->lpSurface = NULL;
     642        }
     643        else
     644        {
     645          // 3.
     646
     647          lpDDSurfaceDesc->dwFlags  |= DDSD_PITCH|DDSD_LPSURFACE;
     648          DDSurfaceDesc.dwFlags      = lpDDSurfaceDesc->dwFlags;
     649
     650          dwPitchFB = lpDDSurfaceDesc->dwWidth * (dwBpp<8?1:dwBpp/8);
     651          dwPitchFB = (dwPitchFB +7) & ~7;  // Align on QWords
     652
     653          DDSurfaceDesc.lPitch    = dwPitchFB;
     654          lpDDSurfaceDesc->lPitch = dwPitchFB;
     655
     656          #ifdef DEBUG
     657            if(dwBpp<8)
     658            {
     659              WriteLog("1 or 4 Bit Surface encountered may not work !");
     660            }
     661          #endif
     662
     663
     664          // 24 byte more to enable alignment and speed up blitting
     665
     666          pFBreal = (char*)malloc( lpDDSurfaceDesc->dwHeight * dwPitchFB + 24);
     667
     668          if(NULL==pFBreal)
     669          {
     670            lastError = DDERR_OUTOFMEMORY;
     671            return;
     672          }
     673
     674          pFrameBuffer = (char*)(((int)pFBreal + 7) & ~7); // align to QWORD
     675
     676          lpDDSurfaceDesc->lpSurface = pFrameBuffer;
     677          DDSurfaceDesc.lpSurface    = pFrameBuffer;
     678
     679          if(Mainchain)
     680          {
     681            // This surface is part of flipchain with the primary surface use dive to alloc
     682            diveBufNr = 0;
     683            DiveAllocImageBuffer( hDive,
     684                                  &diveBufNr,
     685                                  lpDraw->dCaps.fccColorEncoding,
     686                                  lpDDSurfaceDesc->dwWidth,
     687                                  lpDDSurfaceDesc->dwHeight,
     688                                  (lpDDSurfaceDesc->dwWidth * (lpDraw->dCaps.ulDepth/8) +7) & ~7,
     689                                  (PBYTE)pDiveBuffer);
     690          }
     691
     692          if( (lpDraw->dCaps.ulDepth ) == dwBpp )
     693          {
     694            // Yes => No Colorconversion is needed so point to the same buffer
     695            pDiveBuffer  = pFrameBuffer;
     696          }
     697          else
     698          {
     699            // No so we must create the Divebuffer to do the colortranslation
     700            // and blit to the real framebuffer on Unlock to do color conversion
     701            pDiveBuffer = (char*)malloc( lpDDSurfaceDesc->dwHeight *
     702                                 ((lpDDSurfaceDesc->dwWidth * (lpDraw->dCaps.ulDepth/8) +7) & ~7) );
     703
     704          }
     705
     706        }  // end of 3rd case
     707      } // End of alloc surfaces
     708
     709      if( dwCaps & DDSCAPS_COMPLEX)
     710      {
     711        // remove the flag
     712        dwCaps &= ~DDSCAPS_COMPLEX;
     713        #ifdef DEBUG
     714          WriteLog("Complex Surface\n");
     715        #endif
     716
     717        if(lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
     718        {
     719          lpDDSurfaceDesc->dwFlags &= ~DDSD_BACKBUFFERCOUNT;
     720          #ifdef DEBUG
     721            WriteLog("Backbuffer # = %d\n",lpDDSurfaceDesc->dwBackBufferCount);
     722          #endif
     723          memcpy(&ComplexSurfaceDesc,lpDDSurfaceDesc,sizeof(DDSURFACEDESC2));
     724          ComplexSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;        // set flip
     725          ComplexSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; // remove backbuffer
     726
     727          if(ComplexSurfaceDesc.dwBackBufferCount>1)
     728          {
     729            ComplexSurfaceDesc.dwBackBufferCount--;
     730          }
     731          else
     732          {
     733            ComplexSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
     734            ComplexSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_COMPLEX;
     735          }
     736
     737          BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, Mainchain);
     738          if (BackBuffer->GetLastError()==DD_OK)
     739          {
     740            DDSurfaceDesc.dwFlags |= DDSCAPS_FLIP;
     741            BackBuffer->SetFrontBuffer(this);
     742          }
     743
     744        }
     745
     746        // MipMap Surfaces are handled here
     747        if( (lpDDSurfaceDesc->dwFlags & DDSD_MIPMAPCOUNT) &&
     748            (dwCaps & DDSCAPS_TEXTURE) &&
     749            (dwCaps & DDSCAPS_MIPMAP) )
     750        {
     751          dwCaps &= ~ (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP);
     752
     753          lpDDSurfaceDesc->dwFlags &= ~DDSD_MIPMAPCOUNT;
     754          #ifdef DEBUG
     755            WriteLog("Mipmpa # = %d\n",lpDDSurfaceDesc->dwMipMapCount);
     756          #endif
     757          memcpy(&ComplexSurfaceDesc,lpDDSurfaceDesc,sizeof(DDSURFACEDESC2));
     758          ComplexSurfaceDesc.dwMipMapCount = 0;
     759
     760          for(int i =0; i < lpDDSurfaceDesc->dwMipMapCount; i++)
     761          {
     762            #ifdef DEBUG
     763              WriteLog("Creating MipMap %d\n",i);
     764            #endif
     765            // Mpmaps shirnk by 2
     766            ComplexSurfaceDesc.dwWidth  /= 2;
     767            ComplexSurfaceDesc.dwHeight /= 2;
     768            try
     769            {
     770              SurfaceSequenceMipMap.addAsLast(new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE),
     771                                      *SurfaceCursorMipMap);
     772            }
     773            catch(IOutOfMemory)
     774            {
     775              #ifdef DEBUG
     776                WriteLog("Internal : ISet.add OutOfMemory\n");
     777              #endif
     778              lastError = DDERR_OUTOFMEMORY;
     779              return;
     780            }
     781            catch(ICursorInvalidException)
     782            {
     783              #ifdef DEBUG
     784                WriteLog("Internal: Invalid Cursor\n");
     785              #endif
     786              lastError = DDERR_OUTOFMEMORY;
     787              return;
     788            }
     789
     790            if( !SurfaceCursorMipMap->isValid() )
     791            {
     792              // We shouldn't get in here as add sould have raised IOutOfMemory
     793              // If it couldn't create the surface
     794              #ifdef DEBUG
     795                WriteLog("Internal : Cursor is Invalid => OutOfMemory\n");
     796              #endif
     797              lastError = DDERR_OUTOFMEMORY;
     798              return;
     799            }
     800            else
     801            {
     802              AttachedSurface = SurfaceCursorMipMap->element();
     803              if(AttachedSurface->GetLastError() != DD_OK)
     804              {
     805                lastError = AttachedSurface->GetLastError();
     806                #ifdef DEBUG
     807                  WriteLog("Attached surface creation returned error %d\n",lastError);
     808                #endif
     809                return;
     810              } // Endif Errorcheck
     811            } //Endif Cursorcheck
     812          } //End for(i =0; i < lpDDSurfaceDesc->dwMipMapCount; i++)
     813        } // End of MipMaps
     814
     815        #ifdef DEBUG
     816          if(lpDDSurfaceDesc->dwFlags)
     817            WriteLog("Unsupported Complex Surface\n");
     818        #endif
     819      } // Endif DDSCAPS_COMPLEX
     820    }
     821    else
     822    {
     823      lastError = DDERR_INVALIDPARAMS;
     824    }
     825  } // Endif DDCAPS is valid
     826  else
     827    lastError = DDERR_INVALIDPARAMS;
     828
     829  #ifdef DEBUG
     830    WriteLog("Buf %X Screen Caps (%d,%d), bitcount %d\n\n", this, lpDraw->GetScreenHeight(), lpDraw->GetScreenWidth(),
     831    lpDraw->dCaps.ulDepth);
     832    if(DD_OK!=lastError)
     833    {
     834      WriteLog("Some Error Check Flags\n");
     835      _dump_DDSCAPS(lpDDSurfaceDesc->dwFlags);
     836    }
     837  #endif
     838}
     839//******************************************************************************
     840//******************************************************************************
     841HRESULT OS2IDirectDrawSurface::ColorFill(LPRECT lpDestRect,DWORD dwFillColor)
     842{
     843
     844  int i,j, FillWidth, FillHeight;
     845  char *pLine, *pFillPos;
     846
     847  DWORD *pColor, dwColor,y;
     848
     849  #ifdef DEBUG
     850    WriteLog("ColorFill\n");
     851  #endif
     852
     853  if(NULL!=lpDestRect)
     854  {
     855    #ifdef DEBUG
     856      WriteLog("Fill only Rect(%d,%d)(%d,%d)\n", lpDestRect->left, lpDestRect->top,
     857               lpDestRect->right, lpDestRect->bottom);
     858    #endif
     859    FillWidth  = lpDestRect->right - lpDestRect->left;
     860    FillHeight = lpDestRect->bottom - lpDestRect->top -1;
     861    pLine = pDiveBuffer +
     862            (lpDestRect->top*dwPitchDB) +
     863            (lpDestRect->left*dwBytesPPDive);
     864  }
     865  else
     866  {
     867    FillWidth  = width;
     868    FillHeight = height -1;
     869    pLine = pDiveBuffer;
     870  }
     871
     872
     873  switch(dwBytesPPDive)
     874  {
     875    case 1:
     876      dwColor = (dwFillColor<<24) + (dwFillColor<<16) +
     877                (dwFillColor<<8)  + (dwFillColor);
     878      for(i=0,pColor = (DWORD*)pLine;i<(FillWidth/4);i++)
     879        pColor[i] = dwColor;
     880      if(FillWidth % 4)
     881      {
     882         pFillPos = (char*) (&pColor[i-1]);
     883        for(i=0;i<FillWidth % 4;i++)
     884         pFillPos[i] = (UCHAR) dwColor;
     885      }
     886      break;
     887    case 2:
     888      dwColor = (dwFillColor<<16) + (dwFillColor);
     889      for(i=0,pColor = (DWORD*)pLine;i<(FillWidth/2);i++)
     890        pColor[i] = dwColor;
     891      if(FillWidth % 2)
     892      {
     893         pFillPos = (char*)(&pColor[i-1]);
     894        *((USHORT*)pFillPos) = (USHORT)dwColor;
     895      }
     896      break;
     897    case 3:
     898      dwColor = (dwFillColor<<8);
     899      for(i=0 ; i<FillWidth ; i++)
     900      {
     901         char* pColor = (char*)pLine+(i*3);
     902        *pColor = dwColor;
     903      }
     904      break;
     905    case 4:
     906      dwColor = dwFillColor;
     907      for(i=0,pColor = (DWORD*)pLine;i<FillWidth;i++)
     908        pColor[i] = dwColor;
     909      break;
     910    default:
     911      #ifdef DEBUG
     912        WriteLog("Unexpected Bitdepth\n");
     913      #endif
     914      return DDERR_GENERIC;
     915  } // end switch(dest->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
     916
     917
     918  pFillPos = pLine + dwPitchDB;
     919
     920  for( y=0;y<FillHeight;y++,pFillPos+=dwPitchDB)
     921  {
     922    #ifdef USE_ASM
     923      // ToDo get the loop into an asm function as well to speed up filling
     924      // maybe remove the creation of the first fill line in an all asm
     925      // function and use MMX regs to set 8 bytes
     926      MemFlip(pFillPos,pLine,FillWidth);
     927    #else
     928      memcpy(pFillPos,pLine,FillWidth);
     929    #endif
     930  }
     931
     932  return(DD_OK);
     933
     934#if 0 // rest of old code for resuse/move to a function to get closest syscolor
     935      // for colorconversion modes color fills
     936  else
     937  {
     938    // Yeah! Color conversion needed ;)
     939    #ifdef DEBUG
     940       WriteLog("Color converion ! Urks, may not work \n");
     941    #endif
     942
     943    switch(dest->lpDraw->dCaps.ulDepth)
     944    {
     945      case 8:  // 256 Mode bad thing as programm wants to run in a higher mode might look ugly
     946        GetSystemPaletteEntries(GetDC(HWND_DESKTOP),0,255,&SysPal[1]);
     947        pLogPal->palVersion = 0;
     948        pLogPal->palNumEntries = 256;
     949
     950        hPal = CreatePalette(pLogPal);
     951        if(hPal!=NULL)
     952        {
     953          if(dest->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount==16)
     954          {
     955            ulColor = ((lpDDBltFx->dwFillColor & 0x0000001F) <<3) +
     956                      ((lpDDBltFx->dwFillColor & 0x000007E0) <<5) +
     957                      ((lpDDBltFx->dwFillColor & 0x0000F800) <<8);
     958          }
     959          else
     960            ulColor = lpDDBltFx->dwFillColor;
     961
     962          ulColor = GetNearestPaletteIndex(hPal,ulColor);
     963          ulColor = (ulColor & 0x000000FF) + ((ulColor & 0x000000FF) << 8) +
     964                    ((ulColor & 0x000000FF) << 16) + ((ulColor & 0x000000FF) << 24);
     965        }
     966        else
     967        {
     968          #ifdef DEBUG
     969            WriteLog("Error creating Palette default to 0");
     970          #endif
     971          ulColor = 0;
     972        }
     973        for(i=0,(char*)pColor = ScanLine;i<(FillWidth/4)+1;i++)
     974           *(pColor+i) = ulColor;
     975        break;
     976      case 16:
     977        if(dest->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount==8)
     978        {
     979          if(lpDDBltFx->dwFillColor > 255)
     980            return DDERR_INVALIDPARAMS;
     981
     982          if(dest->lpPalette!=NULL)
     983            dest->lpPalette->lpVtbl->GetEntries(dest->lpPalette,0,0,256,(LPPALETTEENTRY)&SysPal);
     984          else
     985            GetSystemPaletteEntries(GetDC(HWND_DESKTOP),0,255,(PPALETTEENTRY)&SysPal);
     986
     987          SysPal[lpDDBltFx->dwFillColor].peBlue  >>3;
     988          SysPal[lpDDBltFx->dwFillColor].peGreen >>2;
     989          SysPal[lpDDBltFx->dwFillColor].peRed   >>3;
     990          ulColor = ULONG(SysPal[lpDDBltFx->dwFillColor].peRed) << 11 +
     991                    ULONG(SysPal[lpDDBltFx->dwFillColor].peGreen) << 5 +
     992                    ULONG(SysPal[lpDDBltFx->dwFillColor].peBlue);
     993        }
     994        else
     995        {
     996          ulColor = (lpDDBltFx->dwFillColor & 0x000000FF)>>3 +
     997                    (((lpDDBltFx->dwFillColor & 0x0000FF00)>>5) & 0x000007E0) +
     998                    (((lpDDBltFx->dwFillColor & 0x00FF0000)>>8) & 0x0000F800);
     999        }
     1000        ulColor += ulColor << 16;
     1001        for(i=0,(char*)pColor = ScanLine;i<(FillWidth/2)+1;i++)
     1002          *(pColor+i) = ulColor;
     1003        break;
     1004      case 24:
     1005        if(dest->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount==8)
     1006        {
     1007          if(lpDDBltFx->dwFillColor > 255)
     1008            return DDERR_INVALIDPARAMS;
     1009
     1010          if(dest->lpPalette!=NULL)
     1011            dest->lpPalette->lpVtbl->GetEntries(dest->lpPalette,0,0,256,(LPPALETTEENTRY)&SysPal);
     1012          else
     1013            GetSystemPaletteEntries(GetDC(HWND_DESKTOP),0,255,(PPALETTEENTRY)&SysPal);
     1014
     1015          ulColor = ULONG(SysPal[lpDDBltFx->dwFillColor].peRed) <<24 +
     1016                    ULONG(SysPal[lpDDBltFx->dwFillColor].peGreen) <<16 +
     1017                    ULONG(SysPal[lpDDBltFx->dwFillColor].peBlue) <<8;
     1018        }
     1019        else
     1020        {
     1021          if(dest->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount==16)
     1022          {
     1023            ulColor = ((lpDDBltFx->dwFillColor & 0x0000001F) <<11) +
     1024                       ((lpDDBltFx->dwFillColor & 0x000007E0) <<13) +
     1025                       ((lpDDBltFx->dwFillColor & 0x0000F800) <<18);
     1026          }
     1027          else
     1028            ulColor = lpDDBltFx->dwFillColor << 8 ;
     1029        }
     1030
     1031        for(i=0;i<FillWidth;i++)
     1032        {
     1033          char* pColor = (char*)Scanline+(i*3);
     1034          *pColor = ulColor;
     1035        }
     1036        break;
     1037      case 32:
     1038        if(dest->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount==8)
     1039        {
     1040          if(lpDDBltFx->dwFillColor > 255)
     1041            return DDERR_INVALIDPARAMS;
     1042
     1043          if(dest->lpPalette!=NULL)
     1044            dest->lpPalette->lpVtbl->GetEntries(dest->lpPalette,0,0,256,(LPPALETTEENTRY)&SysPal);
     1045          else
     1046            GetSystemPaletteEntries(GetDC(HWND_DESKTOP),0,255,(PPALETTEENTRY)&SysPal);
     1047
     1048          ulColor = ULONG(SysPal[lpDDBltFx->dwFillColor].peRed) <<16 +
     1049                    ULONG(SysPal[lpDDBltFx->dwFillColor].peGreen) <<8 +
     1050                    ULONG(SysPal[lpDDBltFx->dwFillColor].peBlue);
     1051        }
     1052        else
     1053        {
     1054          if(dest->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount==16)
     1055          {
     1056            ulColor = ((lpDDBltFx->dwFillColor & 0x0000001F) <<3) +
     1057                      ((lpDDBltFx->dwFillColor & 0x000007E0) <<5) +
     1058                      ((lpDDBltFx->dwFillColor & 0x0000F800) <<8);
     1059          }
     1060          else
     1061            ulColor = lpDDBltFx->dwFillColor & 0x00FFFFFF;
     1062        }
     1063
     1064        for(i=0,(char*)pColor = ScanLine;i<(FillWidth/4);i++)
     1065          *(pColor+i) = ulColor;
     1066        break;
     1067      default:
     1068        #ifdef DEBUG
     1069          WriteLog("Unexpected Bitdepth\n");
     1070        #endif
     1071        return DDERR_GENERIC;
     1072    } // end switch (dest->lpDraw->dCaps.ulDepth)
     1073  }// end of Scanline setup
     1074#endif
     1075
     1076}
     1077//******************************************************************************
     1078//******************************************************************************
     1079void OS2IDirectDrawSurface::ColorConversion(LPRECT lpRect)
     1080{
     1081  SETUP_BLITTER sBlt;
     1082  ULONG ulDN1, ulDN2;
     1083
     1084  ulDN1 = ulDN2 = 0;
     1085
     1086  memset(&sBlt,0,sizeof(sBlt));
     1087  sBlt.ulStructLen = sizeof(sBlt);
     1088  sBlt.fccSrcColorFormat = (FOURCC) DDSurfaceDesc.ddpfPixelFormat.dwFourCC;
     1089  if (NULL!=lpRect)
     1090  {
     1091    sBlt.ulSrcWidth        = lpRect->right - lpRect->left;
     1092    sBlt.ulSrcHeight       = lpRect->top   - lpRect->bottom;
     1093    sBlt.ulSrcPosX         = lpRect->left;
     1094    sBlt.ulSrcPosY         = height - lpRect->top;
     1095  }
     1096  else
     1097  {
     1098    sBlt.ulSrcWidth        = width;
     1099    sBlt.ulSrcHeight       = height;
     1100    sBlt.ulSrcPosX         = 0;
     1101    sBlt.ulSrcPosY         = 0;
     1102  }
     1103  sBlt.fccDstColorFormat = FOURCC_SCRN;
     1104  sBlt.ulDstWidth        = sBlt.ulSrcWidth;
     1105  sBlt.ulDstHeight       = sBlt.ulSrcHeight;
     1106  sBlt.lDstPosX          = sBlt.ulSrcPosX;
     1107  sBlt.lDstPosY          = sBlt.ulSrcPosY;
     1108  sBlt.ulNumDstRects     = DIVE_FULLY_VISIBLE;
     1109
     1110  DiveAllocImageBuffer( hDiveCC,
     1111                        &ulDN1,
     1112                        sBlt.fccSrcColorFormat,
     1113                        width,
     1114                        height,
     1115                        dwPitchFB,
     1116                        (PBYTE)pFrameBuffer);
     1117  DiveAllocImageBuffer( hDiveCC,
     1118                        &ulDN2,
     1119                        sBlt.fccDstColorFormat,
     1120                        width,
     1121                        height,
     1122                        dwPitchDB,
     1123                        (PBYTE)pDiveBuffer);
     1124  DiveSetupBlitter(hDiveCC,&sBlt);
     1125  DiveBlitImage(hDiveCC,ulDN1,ulDN2);
     1126  DiveFreeImageBuffer(hDiveCC,ulDN1);
     1127  DiveFreeImageBuffer(hDiveCC,ulDN2);
    2471128}
    2481129//******************************************************************************
     
    2501131OS2IDirectDrawSurface::~OS2IDirectDrawSurface()
    2511132{
    252   if(diveBufNr != -1) {
    253     if(fLocked)
     1133  OS2IDirectDrawSurface  *AttachedSurface;
     1134
     1135  if(DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
     1136  {
     1137    lpDraw->SetPrimarySurface(FALSE);
     1138    if(lpPalette)
     1139      lpPalette->RestorePhysPalette();
     1140  }
     1141  else
     1142  {
     1143    if( diveBufNr != -1)
     1144    {
     1145      if(fLocked)
    2541146        DiveEndImageBufferAccess(hDive, diveBufNr);
     1147      DiveFreeImageBuffer(hDive, diveBufNr);
     1148    }
     1149    else
     1150    {
     1151      // Memory Surfaces
     1152      if (!Updated)  // check for user handled buffer
     1153        free(DDSurfaceDesc.lpSurface);
     1154    }
     1155
     1156
    2551157    fLocked = FALSE;
    256     DiveFreeImageBuffer(hDive, diveBufNr);
    2571158    diveBufNr = -1;
    2581159  }
    259   if(lpClipper) {
     1160
     1161  // Free the translation buffer
     1162  if(pFrameBuffer != pDiveBuffer)
     1163    free(pDiveBuffer);
     1164
     1165  // Clear the list of locked rectangles
     1166  if (!LockedRectSequence.isEmpty())
     1167    LockedRectSequence.removeAll();
     1168
     1169  if(lpClipper)
     1170  {
    2601171    lpClipper->Vtbl.Release((IDirectDrawClipper*)lpClipper);
    2611172    lpClipper = NULL;
    2621173  }
    263   if(lpPalette) {
    264     if(surfaceType & DDSCAPS_PRIMARYSURFACE)
    265         lpPalette->RestorePhysPalette();
     1174
     1175  if(lpPalette)
     1176  {
    2661177    lpPalette->Vtbl.Release((IDirectDrawPalette*)lpPalette);
    2671178    lpPalette = NULL;
    2681179  }
    269   if(lpBuffer)
    270     OS2FreeMem((char *)lpBuffer);
     1180
    2711181  if(hbmImage)
    272     DeleteObject((HANDLE)hbmImage);
     1182    DeleteObject(hbmImage);
     1183
    2731184  if(hdcImage)
    2741185    DeleteDC(hdcImage);
    275   if(bitmapData)
    276     free(bitmapData);
    277   lpDraw->Vtbl.Release((IDirectDraw2*)lpDraw);
    278 }
    279 //******************************************************************************
    280 //******************************************************************************
    281 HRESULT __stdcall SurfQueryInterface(THIS, REFIID riid, LPVOID FAR * ppvObj)
    282 {
    283   dprintf(("OS2IDirectDrawSurface::SurfQueryInterface\n"));
     1186
     1187  if (NULL!=BackBuffer)
     1188    BackBuffer->Vtbl.Release(AttachedSurface);
     1189
     1190  while( !SurfaceSequenceMipMap.isEmpty())
     1191  {
     1192    try
     1193    {
     1194      AttachedSurface = SurfaceSequenceMipMap.firstElement();
     1195      AttachedSurface->Vtbl.Release(AttachedSurface);
     1196      SurfaceSequenceMipMap.removeFirst();
     1197    }
     1198    catch(...)
     1199    {
     1200      #ifdef DEBUG
     1201        WriteLog("Internal : Error deleting MipMap Surfaces\n");
     1202      #endif
     1203    }
     1204  }
     1205
     1206  while( !SurfaceSequenceAttached.isEmpty())
     1207  {
     1208    try
     1209    {
     1210      AttachedSurface = SurfaceSequenceAttached.firstElement();
     1211      AttachedSurface->Vtbl.Release(AttachedSurface);
     1212      SurfaceSequenceAttached.removeFirst();
     1213    }
     1214    catch(...)
     1215    {
     1216      #ifdef DEBUG
     1217        WriteLog("Internal : Error deleting other attached\n");
     1218      #endif
     1219    }
     1220  }
     1221
     1222  lpDraw->Vtbl.Release(lpDraw);
     1223}
     1224//******************************************************************************
     1225//******************************************************************************
     1226inline  void OS2IDirectDrawSurface::SetFrontBuffer( OS2IDirectDrawSurface* NewFBuffer)
     1227{
     1228  FrontBuffer = NewFBuffer;
     1229  if (NULL==NewFBuffer)
     1230  {
     1231    // The real Frontbuffer was removed check if I'm now the one
     1232    if(NULL!=BackBuffer)
     1233    {
     1234      DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER;
     1235      DDSurfaceDesc.ddsCaps.dwCaps |=  DDSCAPS_FRONTBUFFER;
     1236      BackBuffer->SetFrontBuffer(this);
     1237    }
     1238    else
     1239    {
     1240      // Flipchain is destroyed
     1241      DDSurfaceDesc.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER | DDSCAPS_FLIP);
     1242    }
     1243  }
     1244  else
     1245  {
     1246    if(NULL==NewFBuffer->GetFrontBuffer())
     1247    {
     1248      DDSurfaceDesc.ddsCaps.dwCaps |=  DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
     1249    }
     1250    else
     1251    {
     1252      DDSurfaceDesc.ddsCaps.dwCaps &=  ~DDSCAPS_BACKBUFFER ;
     1253      DDSurfaceDesc.ddsCaps.dwCaps |=  DDSCAPS_FLIP;
     1254    }
     1255
     1256    if(NULL!=BackBuffer)
     1257      BackBuffer->SetFrontBuffer(this);
     1258
     1259    DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER;
     1260  }
     1261}
     1262//******************************************************************************
     1263//******************************************************************************
     1264HRESULT __stdcall SurfQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj)
     1265{
     1266  // ToDo: Add Interface handling for D3D Textures
     1267
     1268  #ifdef DEBUG
     1269    WriteLog("OS2IDirectDrawSurface::SurfQueryInterface\n");
     1270  #endif
     1271
    2841272  *ppvObj = NULL;
    2851273
     
    2971285//******************************************************************************
    2981286//******************************************************************************
    299 ULONG __stdcall SurfAddRef(THIS)
     1287ULONG __stdcall SurfAddRef(THIS This)
    3001288{
    3011289 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    3021290
    303   dprintf(("OS2IDirectDrawSurface::SurfAddRef %d\n", me->Referenced+1));
     1291  #ifdef DEBUG
     1292    WriteLog("OS2IDirectDrawSurface::SurfAddRef %d\n", me->Referenced+1);
     1293  #endif
     1294
    3041295  return ++me->Referenced;
    3051296}
    3061297//******************************************************************************
    3071298//******************************************************************************
    308 ULONG __stdcall SurfRelease(THIS)
     1299ULONG __stdcall SurfRelease(THIS This)
    3091300{
    3101301 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    3111302
    312   dprintf(("OS2IDirectDrawSurface::SurfRelease %d\n", me->Referenced-1));
    313   if(me->Referenced) {
     1303  #ifdef DEBUG
     1304    WriteLog("OS2IDirectDrawSurface::SurfRelease %d\n", me->Referenced-1);
     1305    WriteLog("OS2IDirectDrawSurface::Surface %X\n", me);
     1306  #endif
     1307  if(me->Referenced)
     1308  {
    3141309    me->Referenced--;
    315     if(me->Referenced == 0) {
    316         delete me;
    317         return(0);
    318     }
    319     else    return me->Referenced;
    320   }
    321   else  return(0);
    322 }
    323 //******************************************************************************
    324 //******************************************************************************
    325 HRESULT __stdcall SurfAddAttachedSurface(THIS_ LPDIRECTDRAWSURFACE2)
    326 {
    327   dprintf(("SurfAddAttachedSurfacer\n"));
     1310    if(me->Referenced == 0)
     1311    {
     1312      delete me;
     1313      #ifndef __WATCOMC__
     1314        //_interrupt(3);
     1315      #endif
     1316      return(0);
     1317    }
     1318    else
     1319      return me->Referenced;
     1320  }
     1321  else
     1322    return(0);
     1323}
     1324//******************************************************************************
     1325//******************************************************************************
     1326HRESULT __stdcall SurfAddAttachedSurface(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurface)
     1327{
     1328
     1329  #ifdef DEBUG
     1330    WriteLog("SurfAddAttachedSurface\n");
     1331  #endif
     1332  return SurfAddAttachedSurface4(This, (LPDIRECTDRAWSURFACE4)lpDDSurface);
     1333}
     1334//******************************************************************************
     1335//******************************************************************************
     1336HRESULT __stdcall SurfAddAttachedSurface4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurface)
     1337{
     1338  OS2IDirectDrawSurface *AttachedSurface;
     1339  OS2IDirectDrawSurface *BBCursor;
     1340  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     1341  #ifdef DEBUG
     1342    WriteLog("SurfAddAttachedSurface4\n");
     1343  #endif
     1344
     1345  if (NULL==lpDDSurface)
     1346    return DDERR_INVALIDPARAMS;
     1347
     1348  AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface;
     1349
     1350  if(AttachedSurface->IsImplicitSurface())
     1351  {
     1352    #ifdef DEBUG
     1353     WriteLog("Internal : Can't attach an implicit created surface to an other surface\n");
     1354    #endif
     1355    return(DDERR_CANNOTATTACHSURFACE);
     1356  }
     1357
     1358  if(This == AttachedSurface)
     1359  {
     1360    #ifdef DEBUG
     1361     WriteLog("Can't attach an surface to itself\n");
     1362    #endif
     1363    return(DDERR_CANNOTATTACHSURFACE);
     1364  }
     1365
     1366  if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)
     1367  {
     1368    if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
     1369    {
     1370      if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
     1371      {
     1372        try
     1373        {
     1374          me->SurfaceSequenceMipMap.addAsLast(AttachedSurface);
     1375          me->SurfaceCursorMipMap->setToFirst();
     1376
     1377          me->DDSurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT;
     1378          me->DDSurfaceDesc.dwMipMapCount++;
     1379
     1380          AttachedSurface->Vtbl.AddRef(AttachedSurface);
     1381        }
     1382        catch(...)
     1383        {
     1384          #ifdef DEBUG
     1385            WriteLog("Internal : Error attaching to MipMap\n");
     1386          #endif
     1387          return(DDERR_CANNOTATTACHSURFACE);
     1388        }
     1389      }
     1390      else
     1391      {
     1392        #ifdef DEBUG
     1393          WriteLog("Target Surface isn't a MipMap\n");
     1394        #endif
     1395        return(DDERR_CANNOTATTACHSURFACE);
     1396      }
     1397    }
     1398    else
     1399    {
     1400      try
     1401      {
     1402        me->SurfaceSequenceAttached.addAsLast(AttachedSurface);
     1403        // add made the last cursor invalid so start from the begining
     1404        me->SurfaceCursorAttached->setToFirst();
     1405
     1406        AttachedSurface->Vtbl.AddRef(AttachedSurface);
     1407      }
     1408      catch(...)
     1409      {
     1410        #ifdef DEBUG
     1411          WriteLog("Internal : Error attaching to general Set\n");
     1412        #endif
     1413        return(DDERR_CANNOTATTACHSURFACE);
     1414      }
     1415    }
     1416  } // endif DDSCAPS_TEXTURE
     1417  else
     1418  {
     1419    if( (AttachedSurface->DDSurfaceDesc.dwWidth != me->DDSurfaceDesc.dwWidth)
     1420        || (AttachedSurface->DDSurfaceDesc.dwHeight != me->DDSurfaceDesc.dwHeight)
     1421    //    || (AttachedSurface->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount !=
     1422    //        me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
     1423       )
     1424    {
     1425      #ifdef DEBUG
     1426        WriteLog("Surfaces don't have same dimensions\n");
     1427      #endif
     1428      return(DDERR_CANNOTATTACHSURFACE);
     1429    }
     1430    else
     1431    {
     1432      if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)
     1433      {
     1434        if( (AttachedSurface->GetFrontBuffer()!=NULL) || (AttachedSurface->BackBuffer!= NULL))
     1435        {
     1436          #ifdef DEBUG
     1437            WriteLog("Surfaces already has a front/backbuffer\n");
     1438          #endif
     1439          return(DDERR_SURFACEALREADYATTACHED);
     1440        }
     1441
     1442        if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
     1443        {
     1444          if(NULL!=me->BackBuffer)
     1445          {
     1446            BBCursor = me->BackBuffer;
     1447            while(NULL!=BBCursor)
     1448            {
     1449              BBCursor->DDSurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
     1450              BBCursor->DDSurfaceDesc.dwBackBufferCount++;
     1451              BBCursor->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
     1452              BBCursor = BBCursor->BackBuffer;
     1453            }
     1454            BBCursor->BackBuffer = AttachedSurface;
     1455            AttachedSurface->SetFrontBuffer(BBCursor);
     1456          }
     1457          else
     1458          {
     1459            me->BackBuffer = AttachedSurface;
     1460            AttachedSurface->SetFrontBuffer(me);
     1461          }
     1462          me->DDSurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
     1463          me->DDSurfaceDesc.dwBackBufferCount++;
     1464          me->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
     1465
     1466          AttachedSurface->Vtbl.AddRef(AttachedSurface);
     1467          return (DD_OK);
     1468        }
     1469        else
     1470        {
     1471          #ifdef DEBUG
     1472            WriteLog("Can't attach backbuffer to anything but a frontbuffer\n");
     1473          #endif
     1474         return(DDERR_CANNOTATTACHSURFACE);
     1475        }
     1476      }
     1477      else
     1478      {
     1479        if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
     1480        {
     1481          if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
     1482          {
     1483            try
     1484            {
     1485              me->SurfaceSequenceMipMap.addAsLast(AttachedSurface);
     1486              me->SurfaceCursorMipMap->setToFirst();
     1487
     1488              me->DDSurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT;
     1489              me->DDSurfaceDesc.dwMipMapCount++;
     1490              me->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
     1491
     1492              AttachedSurface->Vtbl.AddRef(AttachedSurface);
     1493            }
     1494            catch(...)
     1495            {
     1496              #ifdef DEBUG
     1497                WriteLog("Internal : Error attaching to MipMap\n");
     1498              #endif
     1499             return(DDERR_CANNOTATTACHSURFACE);
     1500            }
     1501          }
     1502          else
     1503          {
     1504            #ifdef DEBUG
     1505              WriteLog("Tagget Surface isn't a MipMap\n");
     1506            #endif
     1507           return(DDERR_CANNOTATTACHSURFACE);
     1508          }
     1509        }
     1510        else
     1511        {
     1512          try
     1513          {
     1514            me->SurfaceSequenceAttached.addAsLast(AttachedSurface);
     1515            // add made the last cursor invalid so start from the begining
     1516            me->SurfaceCursorAttached->setToFirst();
     1517
     1518            AttachedSurface->Vtbl.AddRef(AttachedSurface);
     1519          }
     1520          catch(...)
     1521          {
     1522            #ifdef DEBUG
     1523              WriteLog("Internal : Error attaching to general Set\n");
     1524            #endif
     1525           return(DDERR_CANNOTATTACHSURFACE);
     1526          }
     1527        }
     1528      }// End if not DDSCAPS_BACKBUFFER
     1529    }
     1530  }
     1531
    3281532  return(DD_OK);
    3291533}
    3301534//******************************************************************************
    3311535//******************************************************************************
    332 HRESULT __stdcall SurfAddOverlayDirtyRect(THIS_ W32_LPRECT)
    333 {
    334   dprintf(("SurfAddOverlayDirtyRect\n"));
     1536HRESULT __stdcall SurfAddOverlayDirtyRect(THIS, LPRECT)
     1537{
     1538  #ifdef DEBUG
     1539    WriteLog("SurfAddOverlayDirtyRect Not implemented by M$ in V 6.0! \n");
     1540  #endif
     1541
    3351542  return(DD_OK);
    3361543}
    3371544//******************************************************************************
    3381545//******************************************************************************
    339 HRESULT __stdcall SurfBlt(THIS_ W32_LPRECT lpDestRect, LPDIRECTDRAWSURFACE2 lpDDSrcSurface,
    340               W32_LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
    341 {
     1546HRESULT __stdcall SurfBlt(THIS This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE2 lpDDSrcSurface,
     1547        LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
     1548{
     1549 return SurfBlt4( This,
     1550                  lpDestRect,
     1551                  (LPDIRECTDRAWSURFACE4)lpDDSrcSurface,
     1552                  lpSrcRect,
     1553                  dwFlags,
     1554                  lpDDBltFx);
     1555}
     1556//******************************************************************************
     1557//******************************************************************************
     1558HRESULT __stdcall SurfBlt4(THIS This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE4 lpDDSrcSurface,
     1559        LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
     1560{
     1561   // We have determine between 3 different blit senarios.
     1562   // 1. Blitting between Divebuffers (Front/Backbuffer and primary surface)
     1563   // 2. Blitting between memory and Divebuffers (Front/Backbuffer and primary surface).
     1564   // 3. Blitting between memory buffers.
     1565   // 1 and 3 are easy. DiveBlitImage or memcpy will do the job for non transparent blits
     1566   // 2 is now also easy as we do colorconverion via Dive after each unlocking of a surface
     1567   // The advantage is that we don't have to call DiveSetupBlitter each time. The Blitter will be
     1568   // setup only when the screen resolution is changed by ddraw. I guess we should see a big performance
     1569   // increase by doing it this way, unless the software blits directly from memory to the primary surface)
     1570   // But even then this could be faster as the SetupBlitter call is timeconsumeing and DIVE does emulate
     1571   // the blit in SW anyway as there is no interface in the driver to blit with HW support from the sysmem.
     1572
    3421573 OS2IDirectDrawSurface *dest = (OS2IDirectDrawSurface *)This;
    3431574 OS2IDirectDrawSurface *src  = (OS2IDirectDrawSurface *)lpDDSrcSurface;
    344  SETUP_BLITTER          blit;
    345  ULONG                  rc;
     1575 ISequence<IRectangle*>::Cursor *EnumCursor;
     1576
     1577 HRESULT                rc;
     1578 ULONG                  ulColor, *pColor;
    3461579 RECTL                  cliprect;
    3471580
    348   dprintf(("SurfBlt to (%d,%d)(%d,%d) from (%d,%d)(%d,%d)\n", lpDestRect->left, lpDestRect->top,
    349            lpDestRect->right, lpDestRect->bottom, lpSrcRect->left, lpSrcRect->top,
    350        lpSrcRect->right, lpSrcRect->bottom));
    351 
    352   blit.ulStructLen = sizeof(blit);
    353   blit.fInvert     = FALSE;
    354   blit.fccSrcColorFormat = src->fccColorFormat;
    355   blit.ulSrcWidth  = lpSrcRect->right  - lpSrcRect->left;
    356   blit.ulSrcHeight = lpSrcRect->bottom - lpSrcRect->top;
    357   blit.ulSrcPosX   = lpSrcRect->left;
    358   blit.ulSrcPosY   = lpSrcRect->top;
    359 
    360   blit.fccDstColorFormat = dest->fccColorFormat;
    361   blit.ulDstWidth  = lpDestRect->right  - lpDestRect->left;
    362   blit.ulDstHeight = lpDestRect->bottom - lpDestRect->top;
    363   blit.lDstPosX    = lpDestRect->left;
    364   blit.lDstPosY    = dcaps.ulVerticalResolution - lpDestRect->bottom;
    365   blit.lScreenPosX = 0;
    366   blit.lScreenPosY = 0;
    367   blit.ulNumDstRects = 1;
    368   blit.pVisDstRects  = &cliprect;
    369   cliprect.top     = 0;
    370   cliprect.bottom  = dcaps.ulVerticalResolution;
    371   cliprect.left    = lpDestRect->left;
    372   cliprect.right   = lpDestRect->right;
    373 #if 0
    374   rc = DiveSetupBlitter(dest->hDive, &blit);
    375   if(rc != DIVE_SUCCESS) {
    376     dprintf(("Error setting up blitter %d\n", rc));
    377     return(DDERR_GENERIC);
    378   }
    379   rc = DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
    380   if(rc != DIVE_SUCCESS) {
    381     dprintf(("Error while blitting %d\n", rc));
    382     return(DDERR_GENERIC);
    383   }
    384 #else
    385   char *srcbuf, *destbuf;
    386   ULONG srcscanbytes, destscanbytes, i, nrScanLines;
    387   OS2RECTL rectl;
    388 
    389   if(dest->diveBufNr == DIVE_BUFFER_SCREEN) {
    390         dprintf(("Dest == DIVE_BUFFER_SCREEN\n"));
    391         rectl.xLeft    = blit.lDstPosX;
    392         rectl.yBottom  = blit.lDstPosY;
    393         rectl.xRight   = blit.lDstPosX + blit.ulSrcWidth;
    394         rectl.yTop     = blit.lDstPosY + blit.ulSrcHeight;
    395         destscanbytes  = dcaps.ulHorizontalResolution;
    396         destbuf        = dest->pFrameBuffer;
    397         rc = DiveAcquireFrameBuffer(dest->hDive, (PRECTL)&rectl);
    398         if(rc != DIVE_SUCCESS) {
    399             dprintf(("frame buffer access error %d\n", rc));
    400             return(DDERR_INVALIDPARAMS);
    401         }
    402   }
    403   else {
    404     rc = DiveBeginImageBufferAccess(dest->hDive, dest->diveBufNr, (PBYTE *)&destbuf,
    405                             &destscanbytes, &nrScanLines);
    406     if(rc != DIVE_SUCCESS) {
    407         dprintf(("dest bufffer access error %d\n", rc));
    408         return(DDERR_INVALIDPARAMS);
    409     }
    410   }
    411   rc = DiveBeginImageBufferAccess(src->hDive, src->diveBufNr, (PBYTE *)&srcbuf,
    412                       &srcscanbytes, &nrScanLines);
    413   if(rc != DIVE_SUCCESS) {
    414     dprintf(("src bufffer access error %d\n", rc));
     1581 int                    x, y, i, j, BlitWidth, BlitHeight;
     1582 PALETTEENTRY           SysPal[257];
     1583 PLOGPALETTE            pLogPal = (PLOGPALETTE) SysPal;
     1584 char                   *pBltPos, *pSrcPos;
     1585 DDSURFACEDESC2         DestSurfaceDesc, SrcSurfaceDesc;
     1586 IRectangle             *pIRectDest,*pIRectSrc,*pIRectTest;
     1587 RECTL                  DestRect, SrcRect;
     1588 BOOL Found;
     1589 DWORD dwSrcColor, dwDestColor;
     1590
     1591  #ifdef DEBUG
     1592    if ( (NULL!=lpDestRect)&& (NULL!=lpSrcRect))
     1593      WriteLog("SurfBlt4 to (%d,%d)(%d,%d) from (%d,%d)(%d,%d)\n", lpDestRect->left, lpDestRect->top,
     1594               lpDestRect->right, lpDestRect->bottom, lpSrcRect->left, lpSrcRect->top,
     1595               lpSrcRect->right, lpSrcRect->bottom);
     1596  #endif
     1597
     1598  if (NULL!=lpDestRect)
     1599  {
     1600    pIRectDest = new IRectangle( lpDestRect->left,
     1601                                 lpDestRect->bottom,
     1602                                 lpDestRect->right,
     1603                                 lpDestRect->top);
     1604    memcpy(&DestRect,lpDestRect,sizeof(RECTL) );
     1605  }
     1606  else
     1607  {
     1608    pIRectDest = new IRectangle( 0, dest->height, dest->width, 0);
     1609    DestRect.top    = 0;
     1610    DestRect.left   = 0;
     1611    DestRect.bottom = dest->height;
     1612    DestRect.right  = dest->width;
     1613  }
     1614
     1615  if(dest->fLocked)
     1616  {
     1617    if (NULL==lpDestRect)
     1618    {
     1619      // If anything is locked we can't blit to the complete surface as
     1620      // a part is locked
     1621      Found = TRUE;
     1622    }
     1623    else
     1624    {
     1625      // If the dest Rectangle intersects with any of the locked rectangles
     1626      // we can't blit to it
     1627
     1628      EnumCursor = dest->LockedRectSequence.newCursor();
     1629      EnumCursor->setToFirst();
     1630      Found = FALSE;
     1631
     1632      while((EnumCursor->isValid() ) && !Found)
     1633      {
     1634        pIRectTest = EnumCursor->element();
     1635        Found = pIRectDest->intersects(*pIRectTest);
     1636        EnumCursor->setToNext();
     1637      }
     1638
     1639      delete EnumCursor;
     1640
     1641    }
     1642
     1643    if (Found)
     1644    {
     1645      delete pIRectDest;
     1646      #ifdef DEBUG
     1647        WriteLog("Blt: Dest Surface partly locked\n");
     1648      #endif
     1649      return(DDERR_SURFACEBUSY);
     1650    }
     1651  }
     1652
     1653  DestSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
     1654  SrcSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
     1655
     1656  // First check the simple first
     1657
     1658  dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC); // FIXME: can't handle right now
     1659
     1660  if(dwFlags & DDBLT_COLORFILL)
     1661  {
     1662    if((NULL==lpDDBltFx)||(lpDDBltFx->dwSize!=sizeof(DDBLTFX)) )
     1663      return DDERR_INVALIDPARAMS;
     1664
     1665    // ToDo : as we fill the DiveBuffer check if we need to convert the
     1666    // specified color
     1667
     1668    dest->ColorFill(lpDestRect,lpDDBltFx->dwFillColor);
     1669
     1670    return(DD_OK); // according to the M$ DDK only one flag shall/can be set.
     1671  } // end of colorfill
     1672
     1673  if (dwFlags & DDBLT_DEPTHFILL)
     1674  {
     1675  #ifdef USE_OPENGL
     1676    GLboolean ztest;
     1677    // Todo support more than one Z-Buffer
     1678    // Clears the screen
     1679    WriteLog("Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
     1680    glClearDepth(lpDDBltFx->b.dwFillDepth / 65535.0); // We suppose a 16 bit Z Buffer
     1681    glGetBooleanv(GL_DEPTH_TEST, &ztest);
     1682    glDepthMask(GL_TRUE); // Enables Z writing to be sure to delete also the Z buffer
     1683    glClear(GL_DEPTH_BUFFER_BIT);
     1684    glDepthMask(ztest);
     1685
     1686    return (DD_OK);
     1687  #endif // USE_OPENGL
     1688  }
     1689
     1690  if(dwFlags & DDBLT_ROP)
     1691  {
     1692    // HEL and we only support the following ROPS
     1693    // SRC_COPY
     1694    // BLACKNESS
     1695    // WHITENESS
     1696    //
     1697    if(lpDDBltFx->dwROP & SRCCOPY)
     1698      dwFlags = 0;  // srccopy is a normal fast blt
     1699    else
     1700    {
     1701      if(lpDDBltFx->dwROP & BLACKNESS)
     1702      {
     1703        if(1==dest->dwBytesPPDive)
     1704        {
     1705          // ToDo: Realy implement code to get the correct index for black in 8 Bitmode
     1706          dest->ColorFill(lpDestRect, 0 );
     1707        }
     1708        else
     1709          dest->ColorFill(lpDestRect, 0);
     1710        return DD_OK;
     1711      }
     1712
     1713      if(lpDDBltFx->dwROP & WHITENESS)
     1714      {
     1715        if(1==dest->dwBytesPPDive)
     1716        {
     1717          // ToDo: Realy implement code to get the correct index for black in 8 Bitmode
     1718          dest->ColorFill(lpDestRect, 0xFFFFFFFF );
     1719        }
     1720        else
     1721          dest->ColorFill(lpDestRect, 0xFFFFFFFF);
     1722        return DD_OK;
     1723      }
     1724
     1725      return DDERR_NORASTEROPHW;
     1726    }
     1727  }
     1728
     1729  if(NULL==src)
     1730  {
     1731    #ifdef DEBUG
     1732      WriteLog("Unsupported sourceless FX operation. Flags = 0x%04X\n",dwFlags);
     1733    #endif
     1734    return DD_OK;
     1735  }
     1736
     1737  if (NULL!=lpSrcRect)
     1738  {
     1739    pIRectSrc = new IRectangle( lpSrcRect->left,
     1740                                lpSrcRect->bottom,
     1741                                lpSrcRect->right,
     1742                                lpSrcRect->top);
     1743    memcpy(&SrcRect,lpSrcRect,sizeof(RECTL) );
     1744  }
     1745  else
     1746  {
     1747    pIRectSrc = new IRectangle( 0, src->height, src->width, 0);
     1748    SrcRect.top    = 0;
     1749    SrcRect.left   = 0;
     1750    SrcRect.bottom = src->height;
     1751    SrcRect.right  = src->width;
     1752  }
     1753
     1754  if(src->fLocked)
     1755  {
     1756    if (NULL==lpSrcRect)
     1757    {
     1758      // If anything is locked we can't blit from the complete surface as
     1759      // a part is locked
     1760      Found = TRUE;
     1761    }
     1762    else
     1763    {
     1764      // If the src Rectangle intersects with any of the locked rectangles of the
     1765      // source surface we can't blit from it
     1766
     1767      EnumCursor = src->LockedRectSequence.newCursor();
     1768      EnumCursor->setToFirst();
     1769      Found = FALSE;
     1770
     1771      while((EnumCursor->isValid() ) && !Found)
     1772      {
     1773        pIRectTest = EnumCursor->element();
     1774        Found = pIRectSrc->intersects(*pIRectTest);
     1775        EnumCursor->setToNext();
     1776      }
     1777
     1778      delete EnumCursor;
     1779
     1780    }
     1781
     1782    if (Found)
     1783    {
     1784      delete pIRectSrc;
     1785      #ifdef DEBUG
     1786        WriteLog("Blt: Src Surface partly locked\n");
     1787      #endif
     1788      return(DDERR_SURFACEBUSY);
     1789    }
     1790  }
     1791
     1792  if( ( (NULL==lpDestRect) && (NULL!=lpSrcRect) ) ||
     1793      ( (NULL==lpSrcRect) && (NULL!=lpDestRect) ) )
     1794  {
     1795    #ifdef DEBUG
     1796      WriteLog("Blitting with scaleing\n Not supported.\n");
     1797    #endif
     1798    return DDERR_NOSTRETCHHW;
     1799  }
     1800
     1801  if( ( pIRectDest->width()  != pIRectSrc->width() ) ||
     1802      ( pIRectDest->height() != pIRectSrc->height() )
     1803    )
     1804  {
     1805    // Stretching not supported
     1806    return DDERR_NOSTRETCHHW;
     1807  }
     1808
     1809  if (dest->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
     1810  {
     1811    if(src->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
     1812    {
     1813      // special Type 1 : Bliting between parts of the screen
     1814
     1815      if( *pIRectDest == *pIRectSrc)
     1816        return DD_OK; // rects are the same => no blit needed
     1817
     1818      // Todo: might add transparent blits but I don't think they are used here, so later!
     1819
     1820      MoveRects( dest->pDiveBuffer,
     1821                 (LPRECT)&DestRect,
     1822                 (LPRECT)&SrcRect,
     1823                 dest->dwBytesPPDive,
     1824                 dest->dwPitchDB);
     1825
     1826      // End of Special Type 1 blitting on the screen
     1827    }
     1828    else
     1829    {
     1830      if( src->diveBufNr>0)
     1831      {
     1832
     1833        if( (NULL==lpSrcRect)&&( NULL== lpDestRect))
     1834        {
     1835          // No Rectangles so use Dive to blit everything
     1836          // ToDo : Implement transparent blitting but that seams more
     1837          //        inportant for partial blits.
     1838          //        If we do this later we could skip this check and don't
     1839          //        use Dive .This keeps our simpler and smaler
     1840          //
     1841          DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
     1842
     1843        }
     1844      }
     1845
     1846      // Everything else we do yourselfs
     1847      // Type 2 Sysmem to Primarysurface ca also be handled by this
     1848
     1849      pBltPos = (char*) dest->pDiveBuffer + (DestRect.top * dest->dwPitchDB) +
     1850                (DestRect.left * dest->dwBytesPPDive);
     1851
     1852      pSrcPos = (char*) src->pDiveBuffer + (SrcRect.top * src->dwPitchDB) +
     1853                (SrcRect.left * src->dwBytesPPDive);
     1854
     1855      BlitHeight = pIRectDest->height();
     1856      BlitWidth = pIRectDest->width();
     1857
     1858      if(!dwFlags)
     1859      {
     1860        BlitWidth *= dest->dwBytesPPDive;
     1861
     1862        #ifdef USE_ASM
     1863        BltRec(pBltPos, pSrcPos, BlitWidth, BlitHeight,
     1864               dest->dwPitchDB,
     1865               src->dwPitchDB);
     1866        #else
     1867        // Solid Blit
     1868        while(1)
     1869        {
     1870          memcpy(pBltPos,pSrcPos,BlitWidth);
     1871          pBltPos += dest->dwPitchDB;
     1872          pSrcPos += src->dwPitchDB;
     1873          if(! (--BlitHeight))
     1874            break;
     1875        }
     1876        #endif
     1877      }
     1878      else
     1879      {
     1880        // Transparent Blit
     1881        if( (dwFlags &DDBLT_KEYSRC) || (dwFlags & DDBLT_KEYSRCOVERRIDE) )
     1882        {
     1883        }
     1884        else
     1885        {
     1886          WriteLog("Unhandled Flags Destination colorkey ? 0x%04X",dwFlags);
     1887        }
     1888      }
     1889    } // end of handling blitting to primary
     1890  }  // end of target primary surface
     1891  else
     1892  {
     1893    if(0==src->diveBufNr)
     1894    {
     1895      // copy from the screen to a buffer
     1896
     1897      if( (NULL==lpDestRect) &&
     1898          (NULL==lpSrcRect) &&
     1899          (dest->diveBufNr>0) )
     1900      {
     1901        // Blitting everything from frontbuffer to a Divebuffer
     1902        // ToDo: Might should add checking for flags here
     1903        DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
     1904      }
     1905      else
     1906      {
     1907        // DIVE => DIVE  or Mem => Dive
     1908        // or a rectangle from streen to a buffer can be handelt in the same way
     1909        pBltPos = (char*) dest->pDiveBuffer + (DestRect.top * dest->dwPitchDB) +
     1910                  (DestRect.left * dest->dwBytesPPDive);
     1911
     1912        pSrcPos = (char*) src->pDiveBuffer + (SrcRect.top * src->dwPitchDB) +
     1913                  (SrcRect.left * src->dwBytesPPDive);
     1914
     1915        BlitHeight = pIRectDest->height();
     1916        BlitWidth = pIRectDest->width();
     1917
     1918        // Check for transparent blit
     1919        if(!dwFlags)
     1920        {
     1921          BlitWidth *= dest->dwBytesPPDive;
     1922
     1923          #ifdef USE_ASM
     1924          BltRec(pBltPos, pSrcPos, BlitWidth, BlitHeight,
     1925                 dest->dwPitchDB,
     1926                 src->dwPitchDB);
     1927          #else
     1928          // Solid Blit
     1929          while(1)
     1930          {
     1931            memcpy(pBltPos,pSrcPos,BlitWidth);
     1932            pBltPos += dest->dwPitchDB;
     1933            pSrcPos += src->dwPitchDB;
     1934            if(! (--BlitHeight))
     1935              break;
     1936          }
     1937          #endif
     1938        }
     1939        else
     1940        {
     1941          if(dwFlags & DDBLT_KEYSRC)
     1942          {
     1943            if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_SRCBLT))
     1944            {
     1945            }
     1946          }
     1947          else
     1948          {
     1949            if(dwFlags & DDBLT_KEYSRCOVERRIDE)
     1950            {
     1951            }
     1952            else
     1953            {
     1954            }
     1955          }
     1956        }
     1957      }
     1958    } // end handling source screen
     1959    else
     1960    {
     1961      // DIVE => DIVE  or Mem => Dive can be handelt in the same way
     1962
     1963      if( (src->pDiveBuffer == dest->pDiveBuffer) &&
     1964          (pIRectDest->intersects(*pIRectSrc) ) )
     1965      {
     1966        // Overlapping rects  on the same surface ?
     1967
     1968        // ToDo : Maybe implement all the fancy blit flags here too ? ;)
     1969
     1970        MoveRects( dest->pDiveBuffer,
     1971                   (LPRECT)&DestRect,
     1972                   (LPRECT)&SrcRect,
     1973                   dest->dwBytesPPDive,
     1974                   dest->dwPitchDB);
     1975
     1976        return DD_OK;
     1977      }
     1978
     1979      pBltPos = (char*) dest->pDiveBuffer + (DestRect.top * dest->dwPitchDB) +
     1980                (DestRect.left * dest->dwBytesPPDive);
     1981
     1982      pSrcPos = (char*) src->pDiveBuffer + (SrcRect.top * src->dwPitchDB) +
     1983                (SrcRect.left * src->dwBytesPPDive);
     1984
     1985      BlitHeight = pIRectDest->height();
     1986      BlitWidth = pIRectDest->width();
     1987
     1988      // Check for transparent blit
     1989      if(!dwFlags)
     1990      {
     1991        BlitWidth *= dest->dwBytesPPDive;
     1992
     1993        #ifdef USE_ASM
     1994        BltRec(pBltPos, pSrcPos, BlitWidth, BlitHeight,
     1995               dest->dwPitchDB,
     1996               src->dwPitchDB);
     1997        #else
     1998        // Solid Blit
     1999        while(1)
     2000        {
     2001          memcpy(pBltPos,pSrcPos,BlitWidth);
     2002          pBltPos += dest->dwPitchDB;
     2003          pSrcPos += src->dwPitchDB;
     2004          if(! (--BlitHeight))
     2005            break;
     2006        }
     2007        #endif
     2008      }
     2009      else
     2010      {
     2011        DWORD dwPitch = dest->dwPitchDB;
     2012
     2013        if(dwFlags &DDBLT_ROTATIONANGLE)
     2014        {
     2015          return DDERR_NOROTATIONHW;
     2016        }
     2017
     2018        if(dwFlags & DDBLT_DDFX)
     2019        {
     2020          DWORD dwFx;
     2021          DWORD dwSrcColor, dwDestColor;
     2022
     2023          dwFlags &= ~DDBLT_DDFX; // remove the handled flag
     2024
     2025          if( NULL==lpDDBltFx)
     2026            return DDERR_INVALIDPARAMS;
     2027
     2028          dwFx = lpDDBltFx->dwDDFX;
     2029
     2030          // Remove unsupported Flags
     2031          dwFx &= ~(DDBLTFX_ARITHSTRETCHY |    // Not streach support
     2032                    DDBLTFX_ZBUFFERBASEDEST |  // All ZBuffer flags are not
     2033                    DDBLTFX_ZBUFFERRANGE |     // implementet in M$ Dx 6
     2034                    DDBLTFX_NOTEARING );       // No sync with VRetrace yet
     2035
     2036          if(dwFx & DDBLTFX_ROTATE180)
     2037          {
     2038            // 180 degree turn is a mix of a flip up/down and one left/right
     2039            dwFx |= (DDBLTFX_MIRRORUPDOWN | DDBLTFX_MIRRORLEFTRIGHT);
     2040            dwFx &= ~DDBLTFX_ROTATE180; // remove handled flag
     2041          }
     2042          if(dwFx & DDBLTFX_MIRRORUPDOWN)
     2043          {
     2044            // switching the the direction can be integrated with other flags
     2045            dwPitch = -dwPitch;
     2046            pBltPos = (char*) dest->pDiveBuffer +
     2047                      ((DestRect.top +BlitHeight)* dest->dwPitchDB) +
     2048                      (DestRect.left * dest->dwBytesPPDive);
     2049
     2050            dwFx &= ~DDBLTFX_MIRRORUPDOWN;  // remove handled flag
     2051          }
     2052
     2053          if(dwFx & DDBLTFX_MIRRORLEFTRIGHT)
     2054          {
     2055            // 180 degree turn or a LR Mirroring
     2056            // don't support any other dwFlags like transparent at the moment
     2057
     2058            switch(dest->dwBytesPPDive)
     2059            {
     2060              case 1:
     2061                while(BlitHeight--)
     2062                {
     2063                  x = BlitWidth;
     2064                  while(x)
     2065                  {
     2066                    pBltPos[BlitWidth-x] = pSrcPos[x];
     2067                    x--;
     2068                  }
     2069                  pBltPos += dwPitch;
     2070                  pSrcPos += src->dwPitchDB;
     2071                }
     2072                break;
     2073              case 2:
     2074                while(BlitHeight--)
     2075                {
     2076                  x = BlitWidth;
     2077                  while(x)
     2078                  {
     2079                    ((USHORT*)pBltPos)[BlitWidth-x] = ((USHORT*)pSrcPos)[x];
     2080                    x--;
     2081                  }
     2082                  pBltPos += dwPitch;
     2083                  pSrcPos += src->dwPitchDB;
     2084                }
     2085                break;
     2086              case 3:
     2087                BlitWidth *= 3;
     2088                while(BlitHeight--)
     2089                {
     2090                  x = BlitWidth;
     2091                  while(x)
     2092                  {
     2093                    pBltPos[BlitWidth-x] = pSrcPos[x-2];
     2094                    x--;
     2095                    pBltPos[BlitWidth-x] = pSrcPos[x];
     2096                    x--;
     2097                    pBltPos[BlitWidth-x] = pSrcPos[x+2];
     2098                    x--;
     2099                  }
     2100                  pBltPos += dwPitch;
     2101                  pSrcPos += src->dwPitchDB;
     2102                }
     2103                break;
     2104              case 4:
     2105                while(BlitHeight--)
     2106                {
     2107                  x = BlitWidth;
     2108                  while(x)
     2109                  {
     2110                    ((DWORD*)pBltPos)[BlitWidth-x] = ((DWORD*)pSrcPos)[x];
     2111                    x--;
     2112                  }
     2113                  pBltPos += dwPitch;
     2114                  pSrcPos += src->dwPitchDB;
     2115                }
     2116                break;
     2117            }  // end switch
     2118            dest->lpVtbl->ChangeUniquenessValue(dest);
     2119            return DD_OK;
     2120          }
     2121
     2122          #ifdef DEBUG
     2123            if(dwFx)
     2124              _dump_DDBLTFX(dwFx);
     2125          #endif
     2126          // We ignore unhandled flags at the moment
     2127        }
     2128
     2129        if( (dwFlags & DDBLT_KEYSRC) |
     2130            (dwFlags & DDBLT_KEYSRCOVERRIDE) )
     2131        {
     2132          if(dwFlags & DDBLT_KEYSRCOVERRIDE)
     2133          {
     2134
     2135            if( NULL==lpDDBltFx)
     2136              return DDERR_INVALIDPARAMS;
     2137
     2138            dwFlags &= ~DDBLT_KEYSRCOVERRIDE;
     2139
     2140            // We work like the HEL and test only the low value
     2141            dwSrcColor = lpDDBltFx->ddckSrcColorkey.dwColorSpaceLowValue;
     2142
     2143          }
     2144          else
     2145          {
     2146
     2147            dwFlags &= ~DDBLT_KEYSRC;
     2148
     2149            // Not sure if that is OK maybe check if one is set ?
     2150            // if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_SRCBLT)) return DDERR_WRONGPARAM;?
     2151
     2152            dwSrcColor = src->DDSurfaceDesc.ddckCKSrcBlt.dwColorSpaceLowValue;
     2153          }
     2154
     2155          // ToDo : We currently indicate that we don't support
     2156          // DDBLT_KEYDEST but HEL does change that!
     2157          // also add this key in the get/setColorKey functions
     2158
     2159          if( (dwFlags & DDBLT_KEYDEST) |
     2160              (dwFlags & DDBLT_KEYDESTOVERRIDE) )
     2161          {
     2162            // Source and dest color keying SLOW!!!
     2163            if(dwFlags & DDBLT_KEYDESTOVERRIDE)
     2164            {
     2165              if( NULL==lpDDBltFx)
     2166                return DDERR_INVALIDPARAMS;
     2167
     2168              dwFlags &= ~DDBLT_KEYDESTOVERRIDE;
     2169
     2170              // We work like the HEL and test only the low value
     2171              dwDestColor = lpDDBltFx->ddckDestColorkey.dwColorSpaceLowValue;
     2172
     2173            }
     2174            else
     2175            {
     2176
     2177              dwFlags &= ~DDBLT_KEYDEST;
     2178
     2179              // Not sure if that is OK maybe check if one is set ?
     2180              // if(!(Dest->DDSurfaceDesc.dwFlags & DDCKEY_DESTBLT)) return DDERR_WRONGPARAM;?
     2181
     2182              dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
     2183            }
     2184
     2185            // This will be be slow maybe move to ASM ?
     2186            // using MMX should be much faster
     2187            switch(dest->dwBytesPPDive)
     2188            {
     2189              case 1:
     2190                while(BlitHeight--)
     2191                {
     2192                  x = 0;
     2193                  while(x<BlitWidth)
     2194                  {
     2195                    if(pSrcPos[x] != (char) dwSrcColor)
     2196                    {
     2197                      if(pBltPos[x] != (char) dwDestColor)
     2198                        pBltPos[x] = pSrcPos[x];
     2199                    }
     2200                    x++;
     2201                  }
     2202                  pBltPos += dwPitch;
     2203                  pSrcPos += src->dwPitchDB;
     2204                }
     2205                break;
     2206              case 2:
     2207                while(BlitHeight--)
     2208                {
     2209                  x = 0;
     2210                  while(x<BlitWidth)
     2211                  {
     2212                    if(((USHORT*)pSrcPos)[x] != (USHORT) dwSrcColor)
     2213                    {
     2214                      if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
     2215                        ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
     2216                    }
     2217                    x++;
     2218                  }
     2219                  pBltPos += dwPitch;
     2220                  pSrcPos += src->dwPitchDB;
     2221                }
     2222                break;
     2223              case 3:
     2224              {
     2225                char *pSC, *pDC;
     2226                pSC = (char*)&dwSrcColor;
     2227                pDC = (char*)&dwDestColor;
     2228                BlitWidth *=3;
     2229
     2230                while(BlitHeight--)
     2231                {
     2232                  x = 0;
     2233
     2234                  while(x<BlitWidth)
     2235                  {
     2236                    if( (pSrcPos[x]   != pSC[1]) &&
     2237                        (pSrcPos[x+1] != pSC[2]) &&
     2238                        (pSrcPos[x+2] != pSC[3])
     2239                      )
     2240                    {
     2241                      if( (pBltPos[x]   != pDC[1]) &&
     2242                          (pBltPos[x+1] != pDC[2]) &&
     2243                          (pBltPos[x+2] != pDC[3])
     2244                        )
     2245                        {
     2246                          pBltPos[x] = pSrcPos[x];
     2247                          pBltPos[x+1] = pSrcPos[x+2];
     2248                          pBltPos[x+1] = pSrcPos[x+2];
     2249                        }
     2250                    }
     2251                    x +=3;
     2252                  }
     2253                  pBltPos += dwPitch;
     2254                  pSrcPos += src->dwPitchDB;
     2255                }
     2256                break;
     2257              }
     2258              case 4:
     2259                while(BlitHeight--)
     2260                {
     2261                  x = 0;
     2262                  while(x<BlitWidth)
     2263                  {
     2264                    if(((DWORD*)pSrcPos)[x] != dwSrcColor)
     2265                    {
     2266                      if(((DWORD*)pBltPos)[x] != dwDestColor)
     2267                        ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
     2268                    }
     2269                    x++;
     2270                  }
     2271                  pBltPos += dwPitch;
     2272                  pSrcPos += src->dwPitchDB;
     2273                }
     2274                break;
     2275            }  // End switch
     2276          }
     2277          else
     2278          {
     2279            // Only Source colorkey
     2280          }
     2281          dest->lpVtbl->ChangeUniquenessValue(dest);
     2282          return DD_OK;
     2283        }
     2284
     2285        if( (dwFlags & DDBLT_KEYDEST) |
     2286            (dwFlags & DDBLT_KEYDESTOVERRIDE) )
     2287        {
     2288          // Dest color keying SLOW!!!
     2289          if(dwFlags & DDBLT_KEYSRCOVERRIDE)
     2290          {
     2291            if( NULL==lpDDBltFx)
     2292              return DDERR_INVALIDPARAMS;
     2293
     2294            dwFlags &= ~DDBLT_KEYSRCOVERRIDE;
     2295
     2296            // We work like the HEL and test only the low value
     2297            dwDestColor = lpDDBltFx->ddckDestColorkey.dwColorSpaceLowValue;
     2298
     2299          }
     2300          else
     2301          {
     2302
     2303            dwFlags &= ~DDBLT_KEYDEST;
     2304
     2305            // Not sure if that is OK maybe check if one is set ?
     2306            // if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_DESTBLT)) return DDERR_WRONGPARAM;?
     2307
     2308            dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
     2309          }
     2310
     2311          // This will be be slow maybe move to ASM ?
     2312          // using MMX should be much faster
     2313          switch(dest->dwBytesPPDive)
     2314          {
     2315            case 1:
     2316              while(BlitHeight--)
     2317              {
     2318                x = 0;
     2319                while(x<BlitWidth)
     2320                {
     2321                  if(pBltPos[x] != (char) dwDestColor)
     2322                    pBltPos[x] = pSrcPos[x];
     2323                  x++;
     2324                }
     2325                pBltPos += dwPitch;
     2326                pSrcPos += src->dwPitchDB;
     2327              }
     2328              break;
     2329            case 2:
     2330              while(BlitHeight--)
     2331              {
     2332                x = 0;
     2333                while(x<BlitWidth)
     2334                {
     2335                  if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
     2336                    ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
     2337                  x++;
     2338                }
     2339                pBltPos += dwPitch;
     2340                pSrcPos += src->dwPitchDB;
     2341              }
     2342              break;
     2343            case 3:
     2344            {
     2345              char *pSC, *pDC;
     2346              pSC = (char*)&dwSrcColor;
     2347              pDC = (char*)&dwDestColor;
     2348              BlitWidth *=3;
     2349
     2350              while(BlitHeight--)
     2351              {
     2352                x = 0;
     2353
     2354                while(x<BlitWidth)
     2355                {
     2356                  if( (pBltPos[x]   != pDC[1]) &&
     2357                      (pBltPos[x+1] != pDC[2]) &&
     2358                      (pBltPos[x+2] != pDC[3])
     2359                    )
     2360                  {
     2361                    pBltPos[x] = pSrcPos[x];
     2362                    pBltPos[x+1] = pSrcPos[x+2];
     2363                    pBltPos[x+1] = pSrcPos[x+2];
     2364                  }
     2365                  x +=3;
     2366                }
     2367                pBltPos += dwPitch;
     2368                pSrcPos += src->dwPitchDB;
     2369              }
     2370              break;
     2371            }
     2372            case 4:
     2373              while(BlitHeight--)
     2374              {
     2375                x = 0;
     2376                while(x<BlitWidth)
     2377                {
     2378                  if( ((DWORD*)pBltPos)[x] != dwDestColor)
     2379                    ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
     2380                  x++;
     2381                }
     2382                pBltPos += dwPitch;
     2383                pSrcPos += src->dwPitchDB;
     2384              }
     2385              break;
     2386          }  // End switch
     2387        } // End of Dest ColorKey
     2388
     2389
     2390      }// end  handling dwFlags
     2391    } // End handling source not Framebuffer
     2392
     2393  }// end handling destination not framebuffer
     2394
     2395  dest->lpVtbl->ChangeUniquenessValue(dest);
     2396  return(DD_OK);
     2397}
     2398//******************************************************************************
     2399//******************************************************************************
     2400HRESULT __stdcall SurfBltBatch(THIS, LPDDBLTBATCH, DWORD, DWORD )
     2401{
     2402  #ifdef DEBUG
     2403    WriteLog("SurfBltBatch Not implemented by M$\n");
     2404  #endif
     2405
     2406  return(DD_OK);
     2407}
     2408//******************************************************************************
     2409//******************************************************************************
     2410HRESULT __stdcall SurfBltFast(THIS, DWORD,DWORD,LPDIRECTDRAWSURFACE2, LPRECT,DWORD)
     2411{
     2412  #ifdef DEBUG
     2413    WriteLog("SurfBltFast\n");
     2414  #endif
     2415
     2416  return(DD_OK);
     2417}
     2418//******************************************************************************
     2419//******************************************************************************
     2420HRESULT __stdcall SurfBltFast4( THIS This,
     2421                                DWORD dwX,
     2422                                DWORD dwY,
     2423                                LPDIRECTDRAWSURFACE4 lpDDSrcSurface,
     2424                                LPRECT lpSrcRect,
     2425                                DWORD dwTrans)
     2426{
     2427  OS2IDirectDrawSurface *dest = (OS2IDirectDrawSurface *)This;
     2428  OS2IDirectDrawSurface *src  = (OS2IDirectDrawSurface *)lpDDSrcSurface;
     2429  RECTL SrcRect;
     2430  char *pBltPos, *pSrcPos;
     2431  DWORD dwDestColor, dwSrcColor, BlitWidth, BlitHeight,x,y;
     2432  #ifdef DEBUG
     2433    WriteLog("SurfBltFast (%d, %d)\n",dwX,dwY);
     2434  #endif
     2435
     2436  if( (NULL==lpDDSrcSurface) ||
     2437      (dwX<0) || (dwY<0) ||
     2438      (dwX>dest->width) ||
     2439      (dwY>dest->height))
     2440    return DDERR_INVALIDPARAMS;
     2441
     2442  if (NULL!=lpSrcRect)
     2443  {
     2444    memcpy(&SrcRect,lpSrcRect,sizeof(RECTL) );
     2445  }
     2446  else
     2447  {
     2448    SrcRect.top    = 0;
     2449    SrcRect.left   = 0;
     2450    SrcRect.bottom = src->height;
     2451    SrcRect.right  = src->width;
     2452  }
     2453
     2454  pBltPos = (char*) dest->pDiveBuffer + (dwY * dest->dwPitchDB) +
     2455            (dwX * dest->dwBytesPPDive);
     2456
     2457  pSrcPos = (char*) src->pDiveBuffer + (SrcRect.top * src->dwPitchDB) +
     2458            (SrcRect.left * src->dwBytesPPDive);
     2459
     2460  BlitHeight = SrcRect.bottom - SrcRect.top;
     2461  BlitWidth  = (SrcRect.right - SrcRect.left) * src->dwBytesPPDive;
     2462
     2463  if(dwTrans & DDBLTFAST_NOCOLORKEY)
     2464  {
     2465    #ifdef USE_ASM
     2466    BltRec(pBltPos, pSrcPos, BlitWidth, BlitHeight,
     2467           dest->dwPitchDB,
     2468           src->dwPitchDB);
     2469    #else
     2470    // Solid Blit
     2471    while(1)
     2472    {
     2473      memcpy(pBltPos,pSrcPos,BlitWidth);
     2474      pBltPos += dest->dwPitchDB;
     2475      pSrcPos += src->dwPitchDB;
     2476      if(! (--BlitHeight))
     2477        break;
     2478    }
     2479    #endif
     2480
     2481  }
     2482  else
     2483  {
     2484    if(dwTrans & DDBLTFAST_SRCCOLORKEY)
     2485    {
     2486      // transparent source
     2487      dwSrcColor = src->DDSurfaceDesc.ddckCKSrcBlt.dwColorSpaceLowValue;
     2488      if(dwTrans & DDBLTFAST_DESTCOLORKEY)
     2489      {
     2490        dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
     2491        // Source and dest colorkeying
     2492        switch(dest->dwBytesPPDive)
     2493        {
     2494          case 1:
     2495            while(BlitHeight--)
     2496            {
     2497              x = 0;
     2498              while(x<BlitWidth)
     2499              {
     2500                if(pSrcPos[x] != (char) dwSrcColor)
     2501                {
     2502                  if(pBltPos[x] != (char) dwDestColor)
     2503                    pBltPos[x] = pSrcPos[x];
     2504                }
     2505                x++;
     2506              }
     2507              pBltPos += dest->dwPitchDB;
     2508              pSrcPos += src->dwPitchDB;
     2509            }
     2510            break;
     2511          case 2:
     2512            while(BlitHeight--)
     2513            {
     2514              x = 0;
     2515              while(x<BlitWidth)
     2516              {
     2517                if(((USHORT*)pSrcPos)[x] != (USHORT) dwSrcColor)
     2518                {
     2519                  if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
     2520                    ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
     2521                }
     2522                x++;
     2523              }
     2524              pBltPos += dest->dwPitchDB;
     2525              pSrcPos += src->dwPitchDB;
     2526            }
     2527            break;
     2528          case 3:
     2529          {
     2530            char *pSC, *pDC;
     2531            pSC = (char*)&dwSrcColor;
     2532            pDC = (char*)&dwDestColor;
     2533            BlitWidth *=3;
     2534
     2535            while(BlitHeight--)
     2536            {
     2537              x = 0;
     2538
     2539              while(x<BlitWidth)
     2540              {
     2541                if( (pSrcPos[x]   != pSC[1]) &&
     2542                    (pSrcPos[x+1] != pSC[2]) &&
     2543                    (pSrcPos[x+2] != pSC[3])
     2544                  )
     2545                {
     2546                  if( (pBltPos[x]   != pDC[1]) &&
     2547                      (pBltPos[x+1] != pDC[2]) &&
     2548                      (pBltPos[x+2] != pDC[3])
     2549                    )
     2550                    {
     2551                      pBltPos[x] = pSrcPos[x];
     2552                      pBltPos[x+1] = pSrcPos[x+2];
     2553                      pBltPos[x+1] = pSrcPos[x+2];
     2554                    }
     2555                }
     2556                x +=3;
     2557              }
     2558              pBltPos += dest->dwPitchDB;
     2559              pSrcPos += src->dwPitchDB;
     2560            }
     2561            break;
     2562          }
     2563          case 4:
     2564            while(BlitHeight--)
     2565            {
     2566              x = 0;
     2567              while(x<BlitWidth)
     2568              {
     2569                if(((DWORD*)pSrcPos)[x] != dwSrcColor)
     2570                {
     2571                  if(((DWORD*)pBltPos)[x] != dwDestColor)
     2572                    ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
     2573                }
     2574                x++;
     2575              }
     2576              pBltPos += dest->dwPitchDB;
     2577              pSrcPos += src->dwPitchDB;
     2578            }
     2579            break;
     2580        }  // End switch
     2581      }
     2582      else
     2583      {
     2584        // This MMX detection should be moved into OS2Draw
     2585        // and into the surface constructor a setup for blitting pointers
     2586
     2587        switch(dest->dwBytesPPDive)
     2588        {
     2589          case 1:
     2590            if(CPUHasMMX())
     2591              while(BlitHeight--)
     2592              {
     2593                BlitColorKey8MMX((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
     2594                pBltPos += dest->dwPitchDB;
     2595                pSrcPos += src->dwPitchDB;
     2596              }
     2597            else
     2598              while(BlitHeight--)
     2599              {
     2600                BlitColorKey8((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
     2601                pBltPos += dest->dwPitchDB;
     2602                pSrcPos += src->dwPitchDB;
     2603              }
     2604            break;
     2605          case 2:
     2606
     2607            if(CPUHasMMX())
     2608              while(BlitHeight--)
     2609              {
     2610                BlitColorKey16MMX((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
     2611                pBltPos += dest->dwPitchDB;
     2612                pSrcPos += src->dwPitchDB;
     2613              }
     2614            else
     2615              while(BlitHeight--)
     2616              {
     2617                BlitColorKey16((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
     2618                pBltPos += dest->dwPitchDB;
     2619                pSrcPos += src->dwPitchDB;
     2620              }
     2621            break;
     2622          case 3:
     2623            char *pSC;
     2624            pSC = (char*)&dwSrcColor;
     2625            BlitWidth *=3;
     2626
     2627            while(BlitHeight--)
     2628            {
     2629              x = 0;
     2630
     2631              while(x<BlitWidth)
     2632              {
     2633                if( (pSrcPos[x]   != pSC[1]) &&
     2634                    (pSrcPos[x+1] != pSC[2]) &&
     2635                    (pSrcPos[x+2] != pSC[3])
     2636                  )
     2637                {
     2638                  pBltPos[x] = pSrcPos[x];
     2639                  pBltPos[x+1] = pSrcPos[x+1];
     2640                  pBltPos[x+1] = pSrcPos[x+2];
     2641                }
     2642                x +=3;
     2643              }
     2644              pBltPos += dest->dwPitchDB;
     2645              pSrcPos += src->dwPitchDB;
     2646            }
     2647            break;
     2648          case 4:
     2649            break;
     2650        }
     2651      }
     2652    }
     2653    else
     2654    {
     2655      if(dwTrans & DDBLTFAST_DESTCOLORKEY)
     2656      {
     2657        dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
     2658        switch(dest->dwBytesPPDive)
     2659        {
     2660          case 1:
     2661            while(BlitHeight--)
     2662            {
     2663              x = 0;
     2664              while(x<BlitWidth)
     2665              {
     2666                if(pBltPos[x] != (char) dwDestColor)
     2667                  pBltPos[x] = pSrcPos[x];
     2668                x++;
     2669              }
     2670              pBltPos += dest->dwPitchDB;
     2671              pSrcPos += src->dwPitchDB;
     2672            }
     2673            break;
     2674          case 2:
     2675            while(BlitHeight--)
     2676            {
     2677              x = 0;
     2678              while(x<BlitWidth)
     2679              {
     2680                if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
     2681                  ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
     2682                x++;
     2683              }
     2684              pBltPos += dest->dwPitchDB;
     2685              pSrcPos += src->dwPitchDB;
     2686            }
     2687            break;
     2688          case 3:
     2689          {
     2690            char *pSC, *pDC;
     2691            pSC = (char*)&dwSrcColor;
     2692            pDC = (char*)&dwDestColor;
     2693            BlitWidth *=3;
     2694
     2695            while(BlitHeight--)
     2696            {
     2697              x = 0;
     2698
     2699              while(x<BlitWidth)
     2700              {
     2701                if( (pBltPos[x]   != pDC[1]) &&
     2702                    (pBltPos[x+1] != pDC[2]) &&
     2703                    (pBltPos[x+2] != pDC[3])
     2704                  )
     2705                {
     2706                  pBltPos[x] = pSrcPos[x];
     2707                  pBltPos[x+1] = pSrcPos[x+2];
     2708                  pBltPos[x+1] = pSrcPos[x+2];
     2709                }
     2710                x +=3;
     2711              }
     2712              pBltPos += dest->dwPitchDB;
     2713              pSrcPos += src->dwPitchDB;
     2714            }
     2715            break;
     2716          }
     2717          case 4:
     2718            while(BlitHeight--)
     2719            {
     2720              x = 0;
     2721              while(x<BlitWidth)
     2722              {
     2723                if(((DWORD*)pBltPos)[x] != dwDestColor)
     2724                  ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
     2725                x++;
     2726              }
     2727              pBltPos += dest->dwPitchDB;
     2728              pSrcPos += src->dwPitchDB;
     2729            }
     2730            break;
     2731        }  // End switch
     2732      }
     2733    }
     2734  }
     2735  dest->lpVtbl->ChangeUniquenessValue(dest);
     2736
     2737  return(DD_OK);
     2738}
     2739//******************************************************************************
     2740//******************************************************************************
     2741HRESULT __stdcall SurfDeleteAttachedSurface(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSurface)
     2742{
     2743  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     2744  #ifdef DEBUG
     2745    WriteLog("SurfDeleteAttachedSurface\n");
     2746  #endif
     2747
     2748  return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
     2749}
     2750//******************************************************************************
     2751//******************************************************************************
     2752HRESULT __stdcall SurfDeleteAttachedSurface4(THIS This, DWORD dwFlags , LPDIRECTDRAWSURFACE4 lpDDSurface)
     2753{
     2754
     2755  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     2756  OS2IDirectDrawSurface *AttachedSurface;
     2757  OS2IDirectDrawSurface *SurfaceCursor;
     2758
     2759  ISequence<OS2IDirectDrawSurface*>::Cursor *EnumCursor;
     2760  BOOL Found = FALSE;
     2761  #ifdef DEBUG
     2762    WriteLog("SurfDeleteAttachedSurface\n");
     2763  #endif
     2764
     2765  if((0!=dwFlags)||(NULL==lpDDSurface))
    4152766    return(DDERR_INVALIDPARAMS);
    416   }
    417   dprintf(("src %X, dest %X\n", srcbuf, destbuf));
    418 
    419   for(i=0;i<blit.ulSrcHeight;i++) {
    420  #ifdef DEBUG1
    421     dprintf(("%d blit (%d,%d) from (%d,%d) len %d\n", i, blit.lDstPosX, destscanbytes*lpDestRect->top + i*destscanbytes,
    422          blit.ulSrcPosX, srcscanbytes*blit.ulSrcPosY + i*srcscanbytes, blit.ulSrcWidth));
    423     dprintf(("dest address %X\n", destbuf + blit.lDstPosX + destscanbytes*lpDestRect->top + i*destscanbytes + blit.ulSrcWidth - 1));
    424  #endif
    425     memcpy(destbuf + blit.lDstPosX + destscanbytes*lpDestRect->top + i*destscanbytes,
    426            srcbuf  + blit.ulSrcPosX + srcscanbytes*blit.ulSrcPosY + i*srcscanbytes,
    427            blit.ulSrcWidth);
    428   }
    429 
    430   if(dest->diveBufNr == DIVE_BUFFER_SCREEN) {
    431        DiveDeacquireFrameBuffer(dest->hDive);
    432   }
    433   else DiveEndImageBufferAccess(dest->hDive, dest->diveBufNr);
    434 
    435   DiveEndImageBufferAccess(src->hDive, src->diveBufNr);
    436 
    437 #endif
     2767
     2768  AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface;
     2769  if (AttachedSurface->IsImplicitSurface())
     2770    return (DDERR_CANNOTDETACHSURFACE);
     2771
     2772  if ( (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP | DDSCAPS_BACKBUFFER)) &&
     2773       !(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) )
     2774  {
     2775    // Surface seams to be a backbuffer in a flipchain search it
     2776
     2777    // Goto top of list
     2778    if(me->FrontBuffer!=NULL)
     2779    {
     2780      SurfaceCursor = me->FrontBuffer;
     2781      while(SurfaceCursor->GetFrontBuffer()!=NULL)
     2782        SurfaceCursor = SurfaceCursor->GetFrontBuffer();
     2783    }
     2784    else
     2785      SurfaceCursor = me;
     2786
     2787    // now iterrate through the list skip first in list as we don't remove the frontbuffer
     2788
     2789    SurfaceCursor = SurfaceCursor->BackBuffer;
     2790    while((SurfaceCursor!= AttachedSurface)&&(SurfaceCursor!=NULL))
     2791      SurfaceCursor = SurfaceCursor->BackBuffer;
     2792
     2793    if(SurfaceCursor!=NULL)
     2794    {
     2795      Found = TRUE;
     2796      // remove the Surface from the list
     2797      SurfaceCursor->FrontBuffer->BackBuffer = SurfaceCursor->BackBuffer;
     2798      if(SurfaceCursor->BackBuffer!=NULL)
     2799      {
     2800        SurfaceCursor->BackBuffer->SetFrontBuffer(SurfaceCursor->FrontBuffer);
     2801
     2802      }
     2803      else
     2804      {
     2805        // we were the last buffer in the list have we been the only backbuffer?
     2806        if(SurfaceCursor->FrontBuffer->FrontBuffer == NULL)
     2807        {
     2808          // Yepp so "destroy" the flipchain
     2809          SurfaceCursor->FrontBuffer->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
     2810          SurfaceCursor->FrontBuffer->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
     2811        }
     2812      }
     2813      // decrement the backbuffer count of all buffers in the chain in front of us
     2814      while(SurfaceCursor->GetFrontBuffer()!=NULL)
     2815      {
     2816        SurfaceCursor = SurfaceCursor->GetFrontBuffer();
     2817        SurfaceCursor->DDSurfaceDesc.dwBackBufferCount-- ;
     2818      }
     2819
     2820      AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
     2821      AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
     2822      AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
     2823      AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; // Set this flag as adding to the chain removed it
     2824      AttachedSurface->lpVtbl->Release(AttachedSurface);
     2825
     2826    }
     2827  } //endif delete back/frontbuffers
     2828
     2829  if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP & DDSCAPS_FRONTBUFFER)) )
     2830  {
     2831    // seams like someone wants a new frontbuffer
     2832
     2833    // Goto top of list
     2834
     2835    if(me->FrontBuffer!=NULL)
     2836    {
     2837      SurfaceCursor = me->FrontBuffer;
     2838      while(SurfaceCursor->GetFrontBuffer()!=NULL)
     2839        SurfaceCursor = SurfaceCursor->GetFrontBuffer();
     2840    }
     2841    else
     2842      SurfaceCursor = me;
     2843
     2844    if(SurfaceCursor == AttachedSurface)
     2845    {
     2846      Found = TRUE;
     2847      SurfaceCursor->BackBuffer->SetFrontBuffer(NULL);
     2848      AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
     2849      AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
     2850      AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
     2851      AttachedSurface->lpVtbl->Release(AttachedSurface);
     2852    }
     2853
     2854  }
     2855
     2856  if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &  DDSCAPS_MIPMAP ) )
     2857  {
     2858    // Surface seams to be a mipmap
     2859    EnumCursor = me->SurfaceSequenceMipMap.newCursor();
     2860    EnumCursor->setToFirst();
     2861    while((EnumCursor->isValid() ) && !Found)
     2862    {
     2863      if (EnumCursor->element() == AttachedSurface)
     2864      {
     2865        Found = TRUE;
     2866        me->SurfaceSequenceMipMap.removeAt(*EnumCursor);
     2867        me->SurfaceCursorMipMap->setToFirst();
     2868        AttachedSurface->lpVtbl->Release(AttachedSurface);
     2869        // adjust our info
     2870        me->DDSurfaceDesc.dwMipMapCount-- ;
     2871        if (!me->DDSurfaceDesc.dwMipMapCount)
     2872        {
     2873          me->DDSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT;
     2874        }
     2875      }
     2876    }
     2877    delete EnumCursor;
     2878  }
     2879
     2880  if(!Found)
     2881  {
     2882    // Surface seams to be a mipmap
     2883    EnumCursor = me->SurfaceSequenceAttached.newCursor();
     2884    EnumCursor->setToFirst();
     2885    while((EnumCursor->isValid() ) && !Found)
     2886    {
     2887      if (EnumCursor->element() == AttachedSurface)
     2888      {
     2889        Found = TRUE;
     2890        me->SurfaceSequenceAttached.removeAt(*EnumCursor);
     2891        me->SurfaceCursorAttached->setToFirst();
     2892        AttachedSurface->lpVtbl->Release(AttachedSurface);
     2893      }
     2894    }
     2895    delete EnumCursor;
     2896  }
     2897
     2898  return(Found?DD_OK:DDERR_SURFACENOTATTACHED);
     2899}
     2900//******************************************************************************
     2901//******************************************************************************
     2902HRESULT __stdcall SurfEnumAttachedSurfaces(THIS This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpCallBack)
     2903{
     2904  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     2905  #ifdef DEBUG
     2906    WriteLog("SurfEnumAttachedSurfaces\n");
     2907  #endif
     2908
     2909  return(SurfEnumAttachedSurfaces4(me,lpContext, (LPDDENUMSURFACESCALLBACK2) lpCallBack));
     2910}
     2911//******************************************************************************
     2912//******************************************************************************
     2913HRESULT __stdcall SurfEnumAttachedSurfaces4(THIS This, LPVOID lpContext ,LPDDENUMSURFACESCALLBACK2 lpCallBack)
     2914{
     2915  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     2916  OS2IDirectDrawSurface *EnumSurface;
     2917  DDSURFACEDESC2         EnumDesc;
     2918
     2919  ISequence<OS2IDirectDrawSurface*>::Cursor *EnumCursor;
     2920  HRESULT rc;
     2921
     2922  #ifdef DEBUG
     2923    WriteLog("SurfEnumAttachedSurfaces\n");
     2924  #endif
     2925  if (NULL==lpCallBack)
     2926    return (DDERR_INVALIDPARAMS);
     2927
     2928  rc = DDENUMRET_OK;
     2929
     2930  if(me->BackBuffer != NULL)
     2931  {
     2932    memcpy(&EnumDesc,&(me->DDSurfaceDesc),sizeof(DDSURFACEDESC2));
     2933    rc = lpCallBack((LPDIRECTDRAWSURFACE4)me->BackBuffer,&EnumDesc,lpContext);
     2934  }
     2935
     2936  if(!me->SurfaceSequenceMipMap.isEmpty())
     2937  {
     2938    EnumCursor = me->SurfaceSequenceMipMap.newCursor();
     2939    EnumCursor->setToFirst();
     2940    while( (DDENUMRET_OK == rc) && EnumCursor->isValid() )
     2941    {
     2942      EnumSurface = EnumCursor->element();
     2943      memcpy(&EnumDesc,&(EnumSurface->DDSurfaceDesc),sizeof(DDSURFACEDESC2));
     2944      rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
     2945      EnumCursor->setToNext();
     2946    }
     2947    delete EnumCursor;
     2948  }
     2949
     2950  if(!me->SurfaceSequenceAttached.isEmpty())
     2951  {
     2952    EnumCursor = me->SurfaceSequenceAttached.newCursor();
     2953    EnumCursor->setToFirst();
     2954    while( (DDENUMRET_OK == rc) && EnumCursor->isValid() )
     2955    {
     2956      EnumSurface = EnumCursor->element();
     2957      memcpy(&EnumDesc,&(EnumSurface->DDSurfaceDesc),sizeof(DDSURFACEDESC2));
     2958      rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
     2959      EnumCursor->setToNext();
     2960    }
     2961    delete EnumCursor;
     2962  }
     2963
    4382964  return(DD_OK);
    4392965}
    4402966//******************************************************************************
    4412967//******************************************************************************
    442 HRESULT __stdcall SurfBltBatch(THIS_ LPDDBLTBATCH, DWORD, DWORD )
    443 {
    444   dprintf(("SurfBltBatch\n"));
     2968HRESULT __stdcall SurfEnumOverlayZOrders(THIS, DWORD,LPVOID,LPDDENUMSURFACESCALLBACK)
     2969{
     2970  #ifdef DEBUG
     2971    WriteLog("SurfEnumOverlayZOrders\n");
     2972  #endif
     2973
    4452974  return(DD_OK);
    4462975}
    4472976//******************************************************************************
    4482977//******************************************************************************
    449 HRESULT __stdcall SurfBltFast(THIS_ DWORD dwDestX, DWORD dwDestY,
    450                   LPDIRECTDRAWSURFACE2 srcSurface,
    451                   W32_LPRECT lpSrcRect, DWORD dwTrans)
    452 {
    453  OS2IDirectDrawSurface *src  = (OS2IDirectDrawSurface *)srcSurface;
    454  OS2IDirectDrawSurface *dest = (OS2IDirectDrawSurface *)This;
    455  SETUP_BLITTER          blit;
    456  ULONG                  rc;
    457  RECTL                  cliprect;
    458 
    459   dprintf(("SurfBltFast (%d,%d) (%d,%d) to (%d,%d) dest %X src %X\n", lpSrcRect->left, lpSrcRect->top, lpSrcRect->right, lpSrcRect->bottom, dwDestX, dwDestY, dest, src));
    460 
    461   blit.ulStructLen = sizeof(blit);
    462   blit.fInvert     = FALSE;
    463   blit.fccSrcColorFormat = src->fccColorFormat;
    464   blit.ulSrcWidth  = lpSrcRect->right  - lpSrcRect->left;
    465   blit.ulSrcHeight = lpSrcRect->bottom - lpSrcRect->top;
    466   blit.ulSrcPosX   = lpSrcRect->left;
    467   blit.ulSrcPosY   = lpSrcRect->top;
    468 
    469   //to prevent inaccuracies when stretching
    470   if(blit.ulSrcWidth == src->lpDraw->GetScreenWidth()) {
    471     blit.ulDstWidth  = dcaps.ulHorizontalResolution;
    472   }
    473   else  blit.ulDstWidth  = (int)((double)blit.ulSrcWidth*dest->screenXFact);
    474 
    475   //to prevent inaccuracies when stretching
    476   if(blit.ulSrcHeight == src->lpDraw->GetScreenHeight()) {
    477     blit.ulDstHeight = dcaps.ulVerticalResolution;
    478   }
    479   else  blit.ulDstHeight = (int)((double)blit.ulSrcHeight*dest->screenYFact);
    480 
    481   blit.fccDstColorFormat = dest->fccColorFormat;
    482   blit.lDstPosX    = (int)((double)dwDestX*dest->screenXFact);
    483   blit.lDstPosY    = (int)((double)dwDestY*dest->screenXFact);
    484   blit.lScreenPosX = 0;
    485   blit.lScreenPosY = 0;
    486 
    487   blit.ulNumDstRects = 1;
    488   blit.pVisDstRects  = &cliprect;
    489   cliprect.top       = 0;
    490   cliprect.bottom    = dcaps.ulVerticalResolution;
    491   cliprect.left      = 0;
    492   cliprect.right     = dcaps.ulHorizontalResolution;
    493 
    494   //We can't do anything but simple 1:1 blitting ourselves
    495   if(src->diveBufNr == DIVE_BUFFER_SCREEN || dest->diveBufNr == DIVE_BUFFER_SCREEN ||
    496      blit.fccSrcColorFormat != blit.fccDstColorFormat ||
    497      blit.ulDstWidth != blit.ulSrcWidth || blit.ulDstHeight != blit.ulSrcHeight)
    498   {
    499 //SvL: Other color key types not supported in dive (dest)
    500     if(dwTrans & DDBLTFAST_SRCCOLORKEY && src->ColorKeyFlags & DDCKEY_SRCBLT) {
    501         dprintf(("Set colorkey for blitting"));
    502         rc = DiveSetTransparentBlitMode(dest->hDive, DIVE_TBM_EXCLUDE_SOURCE_VALUE,
    503                         src->ColorSpaceLowValue[COLORKEY_SRC],
    504                         src->ColorSpaceHighValue[COLORKEY_SRC]);
    505         if(rc != DIVE_SUCCESS) {
    506             dprintf(("Error setting up colorkey for blitter %d\n", rc));
    507             return(DDERR_GENERIC);
    508         }
    509     }
    510 //  dprintf(("Blit: (%d,%d) (%d,%d) to (%d,%d) (%d,%d)", blit.ulSrcPosX, blit.ulSrcPosY, blit.ulSrcWidth, blit.ulSrcHeight, blit.lDstPosX, blit.lDstPosY, blit.ulDstWidth, blit.ulDstHeight));
    511     rc = DiveSetupBlitter(dest->hDive, &blit);
    512     if(rc != DIVE_SUCCESS) {
    513         dprintf(("Error setting up blitter %d\n", rc));
    514         return(DDERR_GENERIC);
    515     }
    516     rc = DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
    517     if(rc != DIVE_SUCCESS) {
    518         dprintf(("Error while blitting %d\n", rc));
    519         return(DDERR_GENERIC);
    520     }
    521   }
    522   else { //manual blit
    523    PBYTE srcbuf, destbuf;
    524    ULONG i, j, destscanlinesize, srcscanlinesize, blitlinesize;
    525 
    526      srcbuf   = src->lpBuffer  + blit.ulSrcPosX + src->width*blit.ulSrcPosY;
    527      destbuf  = dest->lpBuffer + blit.lDstPosX  + dest->width*blit.lDstPosY;
    528 
    529      if(blit.ulSrcWidth == src->width && blit.ulSrcWidth == dest->width) {
    530     //TODO: other colorkey types, ranges and only 8 bits supported now!!
    531     if(dwTrans & DDBLTFAST_SRCCOLORKEY && src->ColorKeyFlags & DDCKEY_SRCBLT) {
    532         BlitColorKey8(destbuf, srcbuf, src->ColorSpaceLowValue[COLORKEY_SRC],
    533                   blit.ulSrcWidth*blit.ulSrcHeight*src->bpp/8);
    534     }
    535     else {
    536         memcpy(destbuf, srcbuf, blit.ulSrcWidth*blit.ulSrcHeight*src->bpp/8);
    537     }
    538      }
    539      else {
    540         destscanlinesize = dest->width*dest->bpp/8;
    541         srcscanlinesize  = src->width*src->bpp/8;
    542     blitlinesize     = blit.ulSrcWidth*src->bpp/8;
    543 
    544     //TODO: other colorkey types, ranges and only 8 bits supported now!!
    545     if(dwTrans & DDBLTFAST_SRCCOLORKEY && src->ColorKeyFlags & DDCKEY_SRCBLT) {
    546 #if 0
    547          BYTE colorkey = (BYTE)src->ColorSpaceLowValue[COLORKEY_SRC];
    548      PBYTE endpos;
    549         for(i=0;i<blit.ulSrcHeight;i++) {
    550             endpos = destbuf + blitlinesize;
    551             while(destbuf < endpos) {
    552                 if(*srcbuf == colorkey) {
    553                     destbuf++;
    554                 }
    555                 else    *destbuf++ = *srcbuf;
    556                 srcbuf++;
    557             }
    558             destbuf += (destscanlinesize-blitlinesize);
    559             srcbuf  += (srcscanlinesize-blitlinesize);
    560         }
    561 #else
    562         for(i=0;i<blit.ulSrcHeight;i++) {
    563             BlitColorKey8(destbuf+i*destscanlinesize, srcbuf+i*srcscanlinesize,
    564                       src->ColorSpaceLowValue[COLORKEY_SRC], blitlinesize);
    565         }
    566 #endif
    567     }
    568     else {
    569         for(i=0;i<blit.ulSrcHeight;i++) {
    570          memcpy(destbuf + i*destscanlinesize, srcbuf + i*srcscanlinesize,
    571                 blitlinesize);
    572         }
    573          }
    574     }
    575   }
     2978HRESULT __stdcall SurfEnumOverlayZOrders4(THIS, DWORD,LPVOID,LPDDENUMSURFACESCALLBACK2)
     2979{
     2980  #ifdef DEBUG
     2981    WriteLog("SurfEnumOverlayZOrders\n");
     2982  #endif
     2983
    5762984  return(DD_OK);
    5772985}
    5782986//******************************************************************************
    5792987//******************************************************************************
    580 HRESULT __stdcall SurfDeleteAttachedSurface(THIS_ DWORD,LPDIRECTDRAWSURFACE2)
    581 {
    582   dprintf(("SurfDeleteAttachedSurface\n"));
     2988HRESULT __stdcall SurfFlip(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurf, DWORD dwFlags)
     2989{
     2990  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     2991  #ifdef DEBUG
     2992    WriteLog("SurfFlip\n");
     2993  #endif
     2994
     2995  return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
     2996}
     2997//******************************************************************************
     2998//******************************************************************************
     2999HRESULT __stdcall SurfFlip4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurf, DWORD dwFlags)
     3000{
     3001  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3002  OS2IDirectDrawSurface *FlipSurface;
     3003  OS2IDirectDrawSurface *FlipCursor;
     3004  LPVOID Data;
     3005  char *pcrFB,*pcFB,*pcrDB,*pcDB;
     3006
     3007  #ifdef DEBUG
     3008    WriteLog("SurfFlip4\n");
     3009  #endif
     3010  if(!((me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) &&
     3011       (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FLIP))
     3012    )
     3013  {
     3014    #ifdef DEBUG
     3015      WriteLog("Flip called on none Frontbuffer/Flip surface\n Flags:\n");
     3016      _dump_DDSCAPS(me->DDSurfaceDesc.ddsCaps.dwCaps);
     3017    #endif
     3018    return(DDERR_NOTFLIPPABLE);
     3019  }
     3020
     3021  if(NULL!=lpDDSurf)
     3022  {
     3023    // We got an override surface check if it is in the flipchain
     3024    FlipSurface = (OS2IDirectDrawSurface*) lpDDSurf;
     3025    FlipCursor = me->BackBuffer;
     3026    while((NULL!=FlipCursor)&&(FlipCursor!=FlipSurface))
     3027    {
     3028      FlipCursor = FlipCursor->BackBuffer;
     3029    }
     3030
     3031    if(FlipCursor!=FlipSurface)
     3032    {
     3033      #ifdef DEBUG
     3034        WriteLog("Surface not in Flipchain!\n");
     3035      #endif
     3036      return (DDERR_INVALIDPARAMS); // Not sure if the returnvalue is right
     3037    }
     3038  }
     3039  else
     3040    FlipSurface = me->NextFlip; // Take the next Surface in the Flipchain
     3041
     3042
     3043  if((me->fLocked)||(FlipSurface->fLocked))
     3044  {
     3045    #ifdef DEBUG
     3046      WriteLog("Locked surface(s) Dest %d Src %d\n",me->fLocked,FlipSurface->fLocked);
     3047    #endif
     3048    return(DDERR_SURFACEBUSY);
     3049  }
     3050
     3051  if(-1 != me->diveBufNr)
     3052  {
     3053    // we got some DIVE surfaces
     3054    // On Dive Buffers More then Double buffering won't get any perf. gain
     3055    // as we have to move all the data to the Frontbuffer and can't simply exchange the pointers
     3056    // Doulebuffering should work best.
     3057
     3058    DiveBlitImage(me->hDive, FlipSurface->diveBufNr, me->diveBufNr);
     3059
     3060    if(NULL==lpDDSurf)
     3061    {
     3062      // advance in the flipchain if no valid override surface was passed in
     3063      me->NextFlip = FlipSurface->BackBuffer!=NULL?FlipSurface->BackBuffer:me->BackBuffer;
     3064    }
     3065  }
     3066  else
     3067  {
     3068    // Memory Flipchain
     3069    //
     3070    // ToDo : Check what happens to src/dest colorkeys etc do the move also ?
     3071    //
     3072    // We only change the memory pointer to the buffers no need to copy all the data
     3073    // So the NextFlip is here allways the Backbuffer so we won't advance this
     3074    //
     3075    // Sample  (triple buffering) :               Before Flip    After Flip
     3076    //                               Buffer:      FB  BB  TB     FB  BB  TB
     3077    //                               Memory:      11  22  33     22  33  11
     3078    //
     3079    Data  = me->DDSurfaceDesc.lpSurface;
     3080    pcrFB = me->pFBreal;
     3081    pcFB  = me->pFrameBuffer;
     3082    pcrDB = me->pDBreal;
     3083    pcDB  = me->pDiveBuffer;
     3084    me->DDSurfaceDesc.lpSurface = FlipSurface->DDSurfaceDesc.lpSurface;
     3085    me->pFBreal                 = FlipSurface->pFBreal;
     3086    me->pFrameBuffer            = FlipSurface->pFrameBuffer;
     3087    me->pDBreal                 = FlipSurface->pDBreal;
     3088    me->pDiveBuffer             = FlipSurface->pDiveBuffer;
     3089
     3090    if(NULL==lpDDSurf)
     3091    {
     3092      while(NULL!=FlipSurface->BackBuffer)
     3093      {
     3094        FlipSurface->DDSurfaceDesc.lpSurface = FlipSurface->BackBuffer->DDSurfaceDesc.lpSurface;
     3095        FlipSurface->pFBreal                 = FlipSurface->BackBuffer->pFBreal;
     3096        FlipSurface->pFrameBuffer            = FlipSurface->BackBuffer->pFrameBuffer;
     3097        FlipSurface->pDBreal                 = FlipSurface->BackBuffer->pDBreal;
     3098        FlipSurface->pDiveBuffer             = FlipSurface->BackBuffer->pDiveBuffer;
     3099        FlipSurface = FlipSurface->BackBuffer;
     3100      }
     3101    }
     3102    FlipSurface->DDSurfaceDesc.lpSurface = Data;
     3103    FlipSurface->pFBreal                 = pcrFB;
     3104    FlipSurface->pFrameBuffer            = pcFB;
     3105    FlipSurface->pDBreal                 = pcrDB;
     3106    FlipSurface->pDiveBuffer             = pcDB;
     3107  }
     3108
    5833109  return(DD_OK);
    5843110}
    5853111//******************************************************************************
    5863112//******************************************************************************
    587 HRESULT __stdcall SurfEnumAttachedSurfaces(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK)
    588 {
    589   dprintf(("SurfEnumAttachedSurfaces\n"));
     3113HRESULT __stdcall SurfGetAttachedSurface(THIS This, LPDDSCAPS lpDDCaps,
     3114                                         LPDIRECTDRAWSURFACE2 FAR * lpDDSurf)
     3115{
     3116  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3117  #ifdef DEBUG
     3118    WriteLog("SurfGetAttachedSurface\n");
     3119  #endif
     3120
     3121  return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
     3122}
     3123//******************************************************************************
     3124//******************************************************************************
     3125HRESULT __stdcall SurfGetAttachedSurface4(THIS This, LPDDSCAPS2 lpDDCaps,
     3126                                          LPDIRECTDRAWSURFACE4 FAR * lpDDSurf)
     3127{
     3128  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3129  OS2IDirectDrawSurface *EnumSurface = NULL;
     3130  OS2IDirectDrawSurface *AttachedSurface = NULL;
     3131  ISequence<OS2IDirectDrawSurface*>::Cursor *EnumCursor;
     3132  #ifdef DEBUG
     3133    WriteLog("SurfGetAttachedSurface4\n>Requested Caps: ");
     3134    _dump_DDSCAPS(lpDDCaps->dwCaps);
     3135    WriteLog("\n");
     3136  #endif
     3137
     3138  if( (NULL==lpDDCaps)||(NULL==lpDDSurf))
     3139  {
     3140    WriteLog("Invalid params\n\n");
     3141    return (DDERR_INVALIDPARAMS);
     3142  }
     3143
     3144  if( (me->BackBuffer!=NULL) && (me->BackBuffer->DDSurfaceDesc.ddsCaps.dwCaps & lpDDCaps->dwCaps) )
     3145  {
     3146    WriteLog("Return Backbuffer\n");
     3147    AttachedSurface = me->BackBuffer;
     3148  }
     3149
     3150  if(!me->SurfaceSequenceMipMap.isEmpty())
     3151  {
     3152    EnumCursor = me->SurfaceSequenceMipMap.newCursor();
     3153    EnumCursor->setToFirst();
     3154    while( EnumCursor->isValid() )
     3155    {
     3156      EnumSurface = EnumCursor->element();
     3157      if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
     3158      {
     3159        if(NULL==AttachedSurface)
     3160          AttachedSurface = EnumSurface;
     3161        else
     3162          return(DDERR_NOTFOUND); // Not sure if this is the right return value,
     3163                                  // but function must fail if more then one surface fits
     3164
     3165      }
     3166      EnumCursor->setToNext();
     3167    }
     3168    delete EnumCursor;
     3169  }
     3170
     3171  if(!me->SurfaceSequenceAttached.isEmpty())
     3172  {
     3173    EnumCursor = me->SurfaceSequenceAttached.newCursor();
     3174    EnumCursor->setToFirst();
     3175    while( EnumCursor->isValid() )
     3176    {
     3177      EnumSurface = EnumCursor->element();
     3178      if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
     3179      {
     3180        if(NULL==AttachedSurface)
     3181          AttachedSurface = EnumSurface;
     3182        else
     3183          return(DDERR_NOTFOUND); // Not sure if this is the right return value,
     3184                                  // but function must fail if more then one surface fits
     3185
     3186      }
     3187      EnumCursor->setToNext();
     3188    }
     3189    delete EnumCursor;
     3190  }
     3191
     3192  if(NULL!=AttachedSurface)
     3193  {
     3194    *lpDDSurf = (IDirectDrawSurface4*)AttachedSurface;
     3195    // not sure but as we returned an reference rains usage count
     3196    AttachedSurface->lpVtbl->AddRef(AttachedSurface);
     3197    return(DD_OK);
     3198  }
     3199  else
     3200    *lpDDSurf = NULL;
     3201
     3202  return(DDERR_NOTFOUND);
     3203}
     3204//******************************************************************************
     3205//******************************************************************************
     3206HRESULT __stdcall SurfGetBltStatus(THIS This, DWORD)
     3207{
     3208  #ifdef DEBUG
     3209    WriteLog("SurfGetBltStatus\n");
     3210  #endif
     3211
    5903212  return(DD_OK);
    5913213}
    5923214//******************************************************************************
    5933215//******************************************************************************
    594 HRESULT __stdcall SurfEnumOverlayZOrders(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK)
    595 {
    596   dprintf(("SurfEnumOverlayZOrders\n"));
     3216HRESULT __stdcall SurfGetCaps(THIS This, LPDDSCAPS lpDDCaps)
     3217{
     3218  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3219
     3220  #ifdef DEBUG
     3221    WriteLog("SurfGetCaps\n");
     3222  #endif
     3223
     3224  if(NULL==lpDDCaps)
     3225    return(DDERR_INVALIDPARAMS);
     3226
     3227  lpDDCaps->dwCaps = me->DDSurfaceDesc.ddsCaps.dwCaps;
     3228
    5973229  return(DD_OK);
    5983230}
    5993231//******************************************************************************
    6003232//******************************************************************************
    601 HRESULT __stdcall SurfFlip(THIS_ LPDIRECTDRAWSURFACE2 lpDDSurfaceTargetOverride, DWORD dwFlags)
    602 {
    603  OS2IDirectDrawSurface *dest = (OS2IDirectDrawSurface *)This;
    604  OS2IDirectDrawSurface *src  = (OS2IDirectDrawSurface *)dest->flip;
    605  SETUP_BLITTER          blit;
    606  ULONG                  rc;
    607  RECTL                  cliprect;
    608 
    609   dprintf(("SurfFlip dest %X, src %X", dest, src));
    610   if(dest == NULL || src == NULL) {
    611     return DDERR_INVALIDOBJECT;
    612   }
    613   if(lpDDSurfaceTargetOverride) {
    614     dprintf(("SurfFlip, lpDDSurfaceTargetOverride not supported yet\n"));
    615     return(DDERR_UNSUPPORTED);
    616   }
    617   if(!(dest->surfaceType & DDSCAPS_PRIMARYSURFACE) ||
    618      src == NULL) {
    619     return(DDERR_INVALIDOBJECT);
    620   }
    621 
    622   dprintf(("SurfFlip (%d,%d) (%d,%d) %d %d", src->width, src->height, dest->width, dest->height, src->diveBufNr, dest->diveBufNr));
    623 
    624   blit.ulStructLen = sizeof(blit);
    625   blit.fInvert     = FALSE;
    626   blit.fccSrcColorFormat = src->fccColorFormat;
    627   blit.ulSrcWidth  = src->width;
    628   blit.ulSrcHeight = src->height;
    629   blit.ulSrcPosX   = 0;
    630   blit.ulSrcPosY   = 0;
    631 
    632   //to prevent inaccuracies when stretching
    633   if(blit.ulSrcWidth == src->lpDraw->GetScreenWidth()) {
    634     blit.ulDstWidth  = dcaps.ulHorizontalResolution;
    635   }
    636   else  blit.ulDstWidth  = (int)((double)blit.ulSrcWidth*dest->screenXFact);
    637 
    638   //to prevent inaccuracies when stretching
    639   if(blit.ulSrcHeight == src->lpDraw->GetScreenHeight()) {
    640     blit.ulDstHeight = dcaps.ulVerticalResolution;
    641   }
    642   else  blit.ulDstHeight = (int)((double)blit.ulSrcHeight*dest->screenYFact);
    643 
    644   blit.fccDstColorFormat = dest->fccColorFormat;
    645   blit.lDstPosX    = 0;
    646   blit.lDstPosY    = 0;
    647   blit.lScreenPosX = 0;
    648   blit.lScreenPosY = 0;
    649   blit.ulNumDstRects = 1;
    650   blit.pVisDstRects  = &cliprect;
    651   cliprect.top     = 0;
    652   cliprect.bottom  = blit.ulDstHeight;
    653   cliprect.left    = 0;
    654   cliprect.right   = blit.ulDstWidth;
    655 
    656 //  dprintf(("Flip: (%d,%d) (%d,%d) to (%d,%d) (%d,%d)", blit.ulSrcPosX, blit.ulSrcPosY, blit.ulSrcWidth, blit.ulSrcHeight, blit.lDstPosX, blit.lDstPosY, blit.ulDstWidth, blit.ulDstHeight));
    657   rc = DiveSetupBlitter(dest->hDive, &blit);
    658   if(rc != DIVE_SUCCESS) {
    659     dprintf(("Error setting up blitter %d\n", rc));
    660     return(DDERR_GENERIC);
    661   }
    662   rc = DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
    663   if(rc != DIVE_SUCCESS) {
    664     dprintf(("Error while blitting %d\n", rc));
    665     return(DDERR_GENERIC);
    666   }
    667 
    668   //find next flip back surface if present
    669   if(src->attached) {
    670     dest->flip = src->attached;
    671   }
    672   else  dest->flip = dest->attached;    //start with first back buffer
     3233HRESULT __stdcall SurfGetCaps4(THIS This, LPDDSCAPS2 lpDDCaps)
     3234{
     3235  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3236  #ifdef DEBUG
     3237    WriteLog("SurfGetCaps4\n");
     3238  #endif
     3239
     3240  if(NULL==lpDDCaps)
     3241    return(DDERR_INVALIDPARAMS);
     3242
     3243  memcpy(lpDDCaps, &(me->DDSurfaceDesc.ddsCaps), sizeof(DDSCAPS2) );
     3244
    6733245  return(DD_OK);
    6743246}
    6753247//******************************************************************************
    6763248//******************************************************************************
    677 HRESULT __stdcall SurfGetAttachedSurface(THIS_ LPDDSCAPS lpddscaps, LPDIRECTDRAWSURFACE2 FAR *lpAttachedSurface)
    678 {
    679  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    680  OS2IDirectDrawSurface *attached = me->attached;
    681 
    682   if(me == NULL) {
    683     return DDERR_INVALIDOBJECT;
    684   }
    685   while(attached) {
    686     dprintf(("SurfGetAttachedSurface %x %x\n", attached->DDSurfaceDesc.ddsCaps.dwCaps, lpddscaps->dwCaps));
    687     if(attached->DDSurfaceDesc.ddsCaps.dwCaps == lpddscaps->dwCaps) {
    688         *lpAttachedSurface = (LPDIRECTDRAWSURFACE2)attached;
    689         return(DD_OK);
    690     }
    691     attached = attached->attached;
    692   }
    693   return(DDERR_NOTFOUND);
    694 }
    695 //******************************************************************************
    696 //******************************************************************************
    697 HRESULT __stdcall SurfGetBltStatus(THIS_ DWORD)
    698 {
    699  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    700 
    701   dprintf(("SurfGetBltStatus\n"));
    702   if(me == NULL) {
    703     return DDERR_INVALIDOBJECT;
    704   }
    705   return(DD_OK);
    706 }
    707 //******************************************************************************
    708 //******************************************************************************
    709 HRESULT __stdcall SurfGetCaps(THIS_ LPDDSCAPS lpCaps)
    710 {
    711  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    712 
    713   dprintf(("SurfGetCaps\n"));
    714   if(me == NULL || lpCaps == NULL) {
    715     return DDERR_INVALIDOBJECT;
    716   }
    717   lpCaps->dwCaps = me->surfaceType;
    718 
    719   return(DD_OK);
    720 }
    721 //******************************************************************************
    722 //******************************************************************************
    723 HRESULT __stdcall SurfGetClipper(THIS_ LPDIRECTDRAWCLIPPER FAR *lplpClipper)
    724 {
    725  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    726 
    727   dprintf(("SurfGetClipper\n"));
    728   if(me == NULL) {
    729     return DDERR_INVALIDOBJECT;
    730   }
    731   if(me->lpClipper) {
     3249HRESULT __stdcall SurfGetClipper(THIS This, LPDIRECTDRAWCLIPPER FAR *lplpClipper)
     3250{
     3251  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3252
     3253  #ifdef DEBUG
     3254    WriteLog("SurfGetClipper\n");
     3255  #endif
     3256
     3257  if(me->lpClipper)
     3258  {
    7323259    *lplpClipper = (LPDIRECTDRAWCLIPPER) me->lpClipper;
    7333260    return(DD_OK);
    7343261  }
    735   else  return(DDERR_NOCLIPPERATTACHED);
    736 }
    737 //******************************************************************************
    738 //******************************************************************************
    739 HRESULT __stdcall SurfGetColorKey(THIS_ DWORD dwFlags, LPDDCOLORKEY lpColorkey)
     3262  else
     3263    return(DDERR_NOCLIPPERATTACHED);
     3264}
     3265//******************************************************************************
     3266//******************************************************************************
     3267HRESULT __stdcall SurfGetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
     3268{
     3269  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3270
     3271#ifdef DEBUG
     3272  WriteLog("SurfGetColorKey\n");
     3273#endif
     3274
     3275  if ((0==dwFlags) || (NULL==lpDDColKey))
     3276    return (DDERR_INVALIDPARAMS);
     3277
     3278  // as we report only src colorkey in the caps return error on all others flags
     3279  if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY) & dwFlags)
     3280    return(DDERR_UNSUPPORTED);
     3281
     3282  if(me->DDSurfaceDesc.dwFlags & dwFlags)
     3283  {
     3284    if(DDCKEY_SRCBLT & dwFlags)
     3285    {
     3286      memcpy(lpDDColKey,&(me->DDSurfaceDesc.ddckCKSrcBlt),sizeof(DDCOLORKEY) );
     3287    }
     3288    else
     3289      return (DDERR_INVALIDPARAMS); // some other flags where set => error
     3290  }
     3291  else
     3292    return(DDERR_NOCOLORKEY); // surface doesn't have a color key set
     3293
     3294  return (DD_OK);
     3295}
     3296//******************************************************************************
     3297//******************************************************************************
     3298HRESULT __stdcall SurfGetDC(THIS This, HDC FAR *hdc)
    7403299{
    7413300 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    742 
    743   dprintf(("SurfGetColorKey\n"));
    744   if(me == NULL) {
    745     return DDERR_INVALIDOBJECT;
    746   }
    747 
    748   if(dwFlags & DDCKEY_DESTBLT) {
    749     lpColorkey->dwColorSpaceLowValue  = me->ColorSpaceLowValue[COLORKEY_DEST];
    750     lpColorkey->dwColorSpaceHighValue = me->ColorSpaceHighValue[COLORKEY_DEST];
    751     return(DD_OK);
    752   }
    753   if(dwFlags & DDCKEY_DESTOVERLAY) {
    754     lpColorkey->dwColorSpaceLowValue  = me->ColorSpaceLowValue[COLORKEY_DESTOVERLAY];
    755     lpColorkey->dwColorSpaceHighValue = me->ColorSpaceHighValue[COLORKEY_DESTOVERLAY];
    756     return(DD_OK);
    757   }
    758   if(dwFlags & DDCKEY_SRCBLT) {
    759     lpColorkey->dwColorSpaceLowValue  = me->ColorSpaceLowValue[COLORKEY_SRC];
    760     lpColorkey->dwColorSpaceHighValue = me->ColorSpaceHighValue[COLORKEY_SRC];
    761     return(DD_OK);
    762   }
    763   if(dwFlags & DDCKEY_SRCOVERLAY) {
    764     lpColorkey->dwColorSpaceLowValue  = me->ColorSpaceLowValue[COLORKEY_SRCOVERLAY];
    765     lpColorkey->dwColorSpaceHighValue = me->ColorSpaceHighValue[COLORKEY_SRCOVERLAY];
    766     return(DD_OK);
    767   }
    768   return(DDERR_INVALIDPARAMS);
    769 }
    770 //******************************************************************************
    771 //******************************************************************************
    772 HRESULT __stdcall SurfGetDC(THIS_ W32_HDC FAR *hdc)
     3301 DDSURFACEDESC2        LockedSurfaceDesc;
     3302
     3303 struct
     3304 {
     3305   BITMAPINFOHEADER  bmiHead;
     3306   RGBQUAD           bmiCols[256];
     3307 } BitmapInfo;
     3308
     3309  #ifdef DEBUG
     3310    WriteLog("SurfGetDC\n");
     3311  #endif
     3312
     3313  if (NULL==hdc)
     3314    return(DDERR_INVALIDPARAMS);
     3315
     3316  LockedSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
     3317
     3318  if(DD_OK != me->Vtbl.Lock(me,NULL,&LockedSurfaceDesc,0,0))
     3319  {
     3320    return(DDERR_DCALREADYCREATED);
     3321  }
     3322
     3323  if(me->hdcImage == NULL)
     3324  {
     3325    // Create a Device context
     3326    me->hdcImage = CreateCompatibleDC(NULL);
     3327    if(me->hdcImage == NULL)
     3328    {
     3329      #ifdef DEBUG
     3330        WriteLog("Can't create compatible DC!\n");
     3331      #endif
     3332      me->Vtbl.Unlock(me,NULL);
     3333      return(DDERR_GENERIC);
     3334    }
     3335  }
     3336
     3337  if(me->hbmImage == NULL)
     3338  {
     3339    memset(&BitmapInfo, 0, sizeof(BitmapInfo));
     3340    BitmapInfo.bmiHead.biSize   = sizeof(BITMAPINFOHEADER);
     3341    BitmapInfo.bmiHead.biWidth  = LockedSurfaceDesc.lPitch/ (LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
     3342    BitmapInfo.bmiHead.biHeight = LockedSurfaceDesc.dwHeight;
     3343    BitmapInfo.bmiHead.biPlanes = 1;
     3344    BitmapInfo.bmiHead.biBitCount    = LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
     3345    switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
     3346    {
     3347      case 1:
     3348      case 4:
     3349      case 8:
     3350        BitmapInfo.bmiHead.biCompression = BI_RGB;
     3351        GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
     3352        me->hbmImage = CreateDIBitmap( me->hdcImage,
     3353                                       NULL,
     3354                                       CBM_CREATEDIB,
     3355                                       LockedSurfaceDesc.lpSurface,
     3356                                       (PBITMAPINFO)&BitmapInfo,
     3357                                       DIB_RGB_COLORS);
     3358        break;
     3359      case 16:
     3360      case 32:
     3361        BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
     3362        BitmapInfo.bmiHead.biClrUsed     = 3;
     3363        *((DWORD *) &(BitmapInfo.bmiCols[0])) = LockedSurfaceDesc.ddpfPixelFormat.dwRBitMask;
     3364        *((DWORD *) &(BitmapInfo.bmiCols[1])) = LockedSurfaceDesc.ddpfPixelFormat.dwGBitMask;
     3365        *((DWORD *) &(BitmapInfo.bmiCols[2])) = LockedSurfaceDesc.ddpfPixelFormat.dwBBitMask;
     3366        me->hbmImage = CreateDIBitmap(me->hdcImage,NULL,CBM_CREATEDIB,LockedSurfaceDesc.lpSurface,
     3367                                      (PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
     3368        break;
     3369      case 24:
     3370        BitmapInfo.bmiHead.biCompression = BI_RGB;
     3371        me->hbmImage = CreateDIBitmap(me->hdcImage,NULL,CBM_CREATEDIB,LockedSurfaceDesc.lpSurface,
     3372                                      (PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
     3373        break;
     3374      default:
     3375        #ifdef DEBUG
     3376          WriteLog("Unexptected BitCount %d \n",LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount);
     3377        #endif
     3378        me->hbmImage=NULL;
     3379    } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
     3380
     3381    if(me->hbmImage == NULL)
     3382    {
     3383      #ifdef DEBUG
     3384        WriteLog("Can't create bitmap!\n");
     3385      #endif
     3386      DeleteDC(me->hdcImage);
     3387      me->hdcImage = NULL;
     3388      me->Vtbl.Unlock(me,NULL);
     3389      return(DDERR_GENERIC);
     3390    }
     3391  }
     3392  else
     3393  {
     3394    if(me->dwLastDCUnique != me->dwUniqueValue)
     3395    {
     3396      #ifdef DEBUG
     3397        WriteLog("The Surface was locked/unlocked after the last DC was created =>Update Bitmap!\n");
     3398      #endif
     3399
     3400      memset(&BitmapInfo,0, sizeof(BitmapInfo));
     3401      BitmapInfo.bmiHead.biSize     = sizeof(BITMAPINFOHEADER);
     3402      BitmapInfo.bmiHead.biWidth    = LockedSurfaceDesc.lPitch/ (LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
     3403      BitmapInfo.bmiHead.biHeight   = LockedSurfaceDesc.dwHeight;
     3404      BitmapInfo.bmiHead.biPlanes   = 1;
     3405      BitmapInfo.bmiHead.biBitCount = LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
     3406
     3407      switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
     3408      {
     3409        case 1:
     3410        case 4:
     3411        case 8:
     3412          BitmapInfo.bmiHead.biCompression = BI_RGB;
     3413          GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
     3414          SetDIBits(me->hdcImage, me->hbmImage, 0, LockedSurfaceDesc.dwHeight,
     3415                    me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
     3416          break;
     3417        case 16:
     3418        case 32:
     3419          BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
     3420          BitmapInfo.bmiHead.biClrUsed     = 3;
     3421          *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
     3422          *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
     3423          *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
     3424          SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
     3425                    me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
     3426          break;
     3427        case 24:
     3428          BitmapInfo.bmiHead.biCompression = BI_RGB;
     3429          SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
     3430                    me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
     3431          break;
     3432        default:
     3433          #ifdef DEBUG
     3434            WriteLog("Unexptected BitCount %d => Bitmap not updated!\n",LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount);
     3435          #endif
     3436          break;
     3437      } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
     3438
     3439    }
     3440  }
     3441
     3442  // Allways selct the bitmap into the DC! No matter if the old or a new one
     3443
     3444  if((me->hgdiOld = SelectObject(me->hdcImage, me->hbmImage)) == NULL)
     3445  {
     3446    #ifdef DEBUG
     3447      WriteLog("Can't select bitmap into dc!\n");
     3448    #endif
     3449    DeleteDC(me->hdcImage);
     3450    me->hdcImage = NULL;
     3451    DeleteObject(me->hbmImage);
     3452    me->hbmImage = NULL;
     3453    me->Vtbl.Unlock(me,NULL);
     3454    return(DDERR_GENERIC);
     3455  }
     3456
     3457  *hdc = me->hdcImage;
     3458
     3459  return(DD_OK);
     3460}
     3461//******************************************************************************
     3462//******************************************************************************
     3463HRESULT __stdcall SurfGetFlipStatus(THIS This, DWORD dwFlags)
     3464{
     3465  #ifdef DEBUG
     3466    WriteLog("SurfGetFlipStatus\n");
     3467  #endif
     3468
     3469  if( (DDGFS_CANFLIP!=dwFlags) && (DDGFS_ISFLIPDONE!=dwFlags) )
     3470    return DDERR_INVALIDPARAMS;
     3471
     3472  return(DD_OK);
     3473}
     3474//******************************************************************************
     3475//******************************************************************************
     3476HRESULT __stdcall SurfGetOverlayPosition(THIS This, LPLONG lplX, LPLONG lplY)
     3477{
     3478  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3479  #ifdef DEBUG
     3480    WriteLog("SurfGetOverlayPosition\n");
     3481  #endif
     3482
     3483  // Maybe simply return dderr_notsupported as we retun a max overlay value of 0 in the caps ?
     3484
     3485  if( (NULL==lplX) || (NULL==lplY))
     3486    return DDERR_INVALIDPARAMS;
     3487
     3488  if(!(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_OVERLAY))
     3489    return DDERR_NOTAOVERLAYSURFACE;
     3490
     3491  if(!(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_VISIBLE))
     3492    return DDERR_OVERLAYNOTVISIBLE;
     3493
     3494  if(!me->fOverlayValid)
     3495    return DDERR_NOOVERLAYDEST;
     3496
     3497  *lplX = me->lOverlayX;
     3498  *lplY = me->lOverlayY;
     3499
     3500  return(DD_OK);
     3501}
     3502//******************************************************************************
     3503//******************************************************************************
     3504HRESULT __stdcall SurfGetPalette(THIS This, LPDIRECTDRAWPALETTE FAR *lplpPalette)
    7733505{
    7743506 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    7753507
    776   dprintf(("SurfGetDC %X\n", me));
    777   if(me == NULL) {
    778     return DDERR_INVALIDOBJECT;
    779   }
    780 
    781   if(me->surfaceType & DDSCAPS_PRIMARYSURFACE) {
    782     dprintf(("Primary surface!\n"));
    783   }
    784 
    785   if(me->fLocked) {
    786     return(DDERR_DCALREADYCREATED);
    787   }
    788   me->fLocked = TRUE;
    789   if(me->hdcImage == NULL && me->hbmImage == NULL) {
    790     me->hdcImage = CreateCompatibleDC(NULL);
    791     if(me->hdcImage == NULL) {
    792         dprintf(("Can't create compatible DC!\n"));
    793         me->fLocked = FALSE;
    794         return(DDERR_GENERIC);
    795     }
    796     dprintf(("CreateBitmap %d %d", me->width, me->height));
    797     me->hbmImage = (HBITMAP)CreateBitmap(me->width, me->height, 1, me->bpp, NULL); //KSO Apr 19 1999: TODO! Why do I have to case this?
    798     if(me->hbmImage == NULL) {
    799         dprintf(("Can't create compatible bitmap!\n"));
    800         DeleteDC(me->hdcImage);
    801         me->hdcImage = NULL;
    802         me->fLocked = FALSE;
    803         return(DDERR_GENERIC);
    804     }
    805     if((me->hgdiOld = SelectObject(me->hdcImage, (HGDIOBJ)me->hbmImage)) == NULL) {
    806         dprintf(("Can't select bitmap into dc!\n"));
    807         DeleteDC(me->hdcImage);
    808         me->hdcImage = NULL;
    809         DeleteObject((HANDLE)me->hbmImage);
    810         me->hbmImage = NULL;
    811         me->fLocked = FALSE;
    812         return(DDERR_GENERIC);
    813     }
    814     me->bitmapData = (char *)malloc(sizeof(BITMAPINFOHEADER) +
    815                         me->width*me->height*me->bpp/8);
    816   }
    817   *hdc = (W32_HDC)me->hdcImage;
    818   return(DD_OK);
    819 }
    820 //******************************************************************************
    821 //******************************************************************************
    822 HRESULT __stdcall SurfGetFlipStatus(THIS_ DWORD)
    823 {
    824   dprintf(("SurfGetFlipStatus\n"));
    825   return(DD_OK);
    826 }
    827 //******************************************************************************
    828 //******************************************************************************
    829 HRESULT __stdcall SurfGetOverlayPosition(THIS_ LPLONG, LPLONG )
    830 {
    831   dprintf(("SurfGetOverlayPosition\n"));
    832   return(DD_OK);
    833 }
    834 //******************************************************************************
    835 //******************************************************************************
    836 HRESULT __stdcall SurfGetPalette(THIS_ LPDIRECTDRAWPALETTE FAR *lplpPalette)
    837 {
    838  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    839 
    840   dprintf(("SurfGetPalette\n"));
    841   if(me == NULL) {
    842     return DDERR_INVALIDOBJECT;
    843   }
    844   if(me->lpPalette) {
     3508  #ifdef DEBUG
     3509    WriteLog("SurfGetPalette\n");
     3510  #endif
     3511
     3512  if(me->lpPalette)
     3513  {
    8453514    *lplpPalette = (LPDIRECTDRAWPALETTE)me->lpPalette;
    8463515    return(DD_OK);
    8473516  }
    848   else  return(DDERR_NOPALETTEATTACHED);
    849 }
    850 //******************************************************************************
    851 //******************************************************************************
    852 HRESULT __stdcall SurfGetPixelFormat(THIS_ LPDDPIXELFORMAT)
    853 {
    854   dprintf(("SurfGetPixelFormat\n"));
     3517  else
     3518    return(DDERR_NOPALETTEATTACHED);
     3519}
     3520//******************************************************************************
     3521//******************************************************************************
     3522HRESULT __stdcall SurfGetPixelFormat(THIS This, LPDDPIXELFORMAT lpPixelFormat)
     3523{
     3524  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3525
     3526  #ifdef DEBUG
     3527    WriteLog("SurfGetPixelFormat\n");
     3528  #endif
     3529
     3530  if(NULL==lpPixelFormat)
     3531    return DDERR_INVALIDPARAMS;
     3532
     3533  memcpy((char*)lpPixelFormat,(char*)&(me->DDSurfaceDesc.ddpfPixelFormat), sizeof(DDPIXELFORMAT));
     3534
    8553535  return(DD_OK);
    8563536}
    8573537//******************************************************************************
    8583538//******************************************************************************
    859 HRESULT __stdcall SurfGetSurfaceDesc(THIS_ LPDDSURFACEDESC lpSurface)
     3539HRESULT __stdcall SurfGetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurface)
     3540{
     3541  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3542
     3543  #ifdef DEBUG
     3544    WriteLog("SurfGetSurfaceDesc\n");
     3545  #endif
     3546
     3547  if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC)) )
     3548    return(DDERR_INVALIDPARAMS);
     3549
     3550  memcpy((char *)lpSurface, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC));
     3551
     3552  return(DD_OK);
     3553}
     3554//******************************************************************************
     3555//******************************************************************************
     3556HRESULT __stdcall SurfGetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurface)
     3557{
     3558  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3559
     3560  #ifdef DEBUG
     3561    WriteLog("SurfGetSurfaceDesc4\n");
     3562  #endif
     3563
     3564  if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC2)) )
     3565    return(DDERR_INVALIDPARAMS);
     3566
     3567  memcpy((char *)lpSurface, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC2));
     3568
     3569  return(DD_OK);
     3570}
     3571//******************************************************************************
     3572//******************************************************************************
     3573HRESULT __stdcall SurfInitialize(THIS, LPDIRECTDRAW, LPDDSURFACEDESC)
     3574{
     3575  #ifdef DEBUG
     3576    WriteLog("SurfInitialize\n");
     3577  #endif
     3578
     3579  return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
     3580}
     3581//******************************************************************************
     3582//******************************************************************************
     3583HRESULT __stdcall SurfInitialize4(THIS, LPDIRECTDRAW, LPDDSURFACEDESC2)
     3584{
     3585  #ifdef DEBUG
     3586    WriteLog("SurfInitialize\n");
     3587  #endif
     3588
     3589  return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
     3590}
     3591//******************************************************************************
     3592//******************************************************************************
     3593HRESULT __stdcall SurfIsLost(THIS)
     3594{
     3595  // We don't loose any surface ;)
     3596  // But we might shoud check for primary and/or Dive Buffers as I don't know
     3597  // if  they are preserved if switching to a FS DOS/OS2 session
     3598  //
     3599  #ifdef DEBUG
     3600    WriteLog("SurfIsLost\n");
     3601  #endif
     3602
     3603  return(DD_OK);
     3604}
     3605//******************************************************************************
     3606//******************************************************************************
     3607HRESULT __stdcall SurfLock(THIS This, LPRECT lpRect, LPDDSURFACEDESC lpSurfaceDesc,
     3608         DWORD dwFlags, HANDLE hEvent)
     3609{
     3610  DDSURFACEDESC2 SurfaceDesc4;
     3611  HRESULT rc;
     3612
     3613  #ifdef DEBUG
     3614    WriteLog("SurfLock %d %d %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent);
     3615  #endif
     3616
     3617  if((NULL==lpSurfaceDesc)||(NULL!=hEvent))
     3618    return DDERR_INVALIDPARAMS;
     3619
     3620  if(lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC))
     3621    return DDERR_INVALIDPARAMS;
     3622
     3623  SurfaceDesc4.dwSize = sizeof(DDSURFACEDESC2);
     3624
     3625  rc = SurfLock4(This, lpRect, &SurfaceDesc4, dwFlags, hEvent);
     3626  if (DD_OK==rc)
     3627  {
     3628    memcpy((char*)lpSurfaceDesc,(char*)&SurfaceDesc4, sizeof(DDSURFACEDESC) );
     3629  }
     3630
     3631  return(rc);
     3632}
     3633//******************************************************************************
     3634//******************************************************************************
     3635HRESULT __stdcall SurfLock4(THIS This, LPRECT lpRect, LPDDSURFACEDESC2 lpSurfaceDesc,
     3636         DWORD dwFlags, HANDLE hEvent)
     3637{
     3638
     3639  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3640  ISequence<IRectangle*>::Cursor *EnumCursor;
     3641
     3642  BOOL Found;
     3643  ULONG  nrScanLines, rc;
     3644  char *pBuffer;
     3645  IRectangle *pIRectCurrent,*pIRectNew;
     3646  static int times = 0;
     3647
     3648  #ifdef DEBUG
     3649    WriteLog("SurfLock4 %d %d %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent);
     3650  #endif
     3651
     3652  if( (NULL==lpSurfaceDesc) ||
     3653      (NULL!=hEvent)
     3654    )
     3655    return DDERR_INVALIDPARAMS;
     3656
     3657  if (NULL!=lpRect)
     3658    pIRectNew = new IRectangle( lpRect->left, lpRect->bottom, lpRect->right, lpRect->top);
     3659  else
     3660    pIRectNew = new IRectangle( 0, me->height, me->width, 0);
     3661
     3662  // ToDo : the lockchecking should be done in a critcal seq.
     3663
     3664  if(me->fLocked)
     3665  {
     3666    if (NULL==lpRect)
     3667    {
     3668      // If anything is locked we can't locke the complete surface
     3669      Found = TRUE;
     3670    }
     3671    else
     3672    {
     3673      // If the new Rectangle intersects with any of the already locked rectangles it can't
     3674      // be locked so check for this
     3675
     3676      EnumCursor = me->LockedRectSequence.newCursor();
     3677      EnumCursor->setToFirst();
     3678      Found = FALSE;
     3679
     3680      while((EnumCursor->isValid() ) && !Found)
     3681      {
     3682        pIRectCurrent = EnumCursor->element();
     3683        Found = pIRectCurrent->intersects(*pIRectNew);
     3684        EnumCursor->setToNext();
     3685      }
     3686
     3687      delete EnumCursor;
     3688
     3689    }
     3690
     3691    if (Found)
     3692    {
     3693      delete pIRectNew;
     3694      #ifdef DEBUG
     3695        WriteLog("SurfLock4: Surface already locked\n");
     3696      #endif
     3697      return(DDERR_SURFACEBUSY);
     3698    }
     3699  }
     3700
     3701  memcpy((char *)lpSurfaceDesc, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC2));
     3702
     3703  if(lpRect != NULL)
     3704  {
     3705    lpSurfaceDesc->lpSurface =  (LPVOID)((char*)me->pFrameBuffer +
     3706                                (lpRect->top * me->dwPitchFB) +
     3707                                (lpRect->left * (lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount>>3)));
     3708    #ifdef DEBUG
     3709      WriteLog("SurfLock4 %d (x,y) = (%d,%d)\n", lpSurfaceDesc->lpSurface, lpRect->top, lpRect->left);
     3710    #endif
     3711  }
     3712  else
     3713  {
     3714    #ifdef DEBUG
     3715      WriteLog("SurfLock4 %d \n", lpSurfaceDesc->lpSurface);
     3716    #endif
     3717  }
     3718  // Add the rectangle to the list of locked rectangles
     3719
     3720  me->LockedRectSequence.addAsLast(pIRectNew);
     3721
     3722  me->fLocked = TRUE;
     3723
     3724  return(DD_OK);
     3725}
     3726//******************************************************************************
     3727//******************************************************************************
     3728HRESULT __stdcall SurfReleaseDC(THIS This, HDC hdc)
    8603729{
    8613730 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    862  ULONG dwFlags;
    863 
    864   if(me == NULL) {
    865     return DDERR_INVALIDOBJECT;
    866   }
    867   if(lpSurface == NULL)
    868     return(DDERR_INVALIDPARAMS);
    869 
    870   dwFlags = lpSurface->dwFlags;
    871   dprintf(("SurfGetSurfaceDesc %X\n", lpSurface->dwFlags));
    872   memcpy((char *)lpSurface, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC));
    873 
    874   lpSurface->dwFlags = dwFlags;
    875   if(lpSurface->dwFlags & DDSD_HEIGHT) {
    876     lpSurface->dwHeight = me->height;
    877   }
    878   if(lpSurface->dwFlags & DDSD_WIDTH) {
    879     lpSurface->dwWidth = me->width;
    880   }
    881   //TODO: handle rest of flags
     3731 struct
     3732 {
     3733   BITMAPINFOHEADER  bmiHead;
     3734   RGBQUAD           bmiCols[256];
     3735 } BitmapInfo;
     3736 int                    i;
     3737
     3738  #ifdef DEBUG
     3739    WriteLog("SurfReleaseDC\n");
     3740  #endif
     3741
     3742  if(hdc != me->hdcImage)
     3743    return(DDERR_INVALIDOBJECT);
     3744
     3745  //unselect our bitmap
     3746  SelectObject(me->hdcImage, me->hgdiOld);
     3747
     3748  memset(&BitmapInfo,0, sizeof(BitmapInfo));
     3749  BitmapInfo.bmiHead.biSize     = sizeof(BITMAPINFOHEADER);
     3750  BitmapInfo.bmiHead.biWidth    = me->DDSurfaceDesc.lPitch/ (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
     3751  BitmapInfo.bmiHead.biHeight   = me->DDSurfaceDesc.dwHeight;
     3752  BitmapInfo.bmiHead.biPlanes   = 1;
     3753  BitmapInfo.bmiHead.biBitCount = me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
     3754
     3755  switch(me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
     3756  {
     3757    case 1:
     3758    case 4:
     3759    case 8:
     3760      BitmapInfo.bmiHead.biCompression = BI_RGB;
     3761      GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
     3762      GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
     3763                me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_PAL_COLORS);
     3764      break;
     3765    case 16:
     3766    case 32:
     3767      BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
     3768      BitmapInfo.bmiHead.biClrUsed     = 3;
     3769      *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
     3770      *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
     3771      *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
     3772      GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
     3773                me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
     3774      break;
     3775    case 24:
     3776      BitmapInfo.bmiHead.biCompression = BI_RGB;
     3777      GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
     3778                me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
     3779      break;
     3780    default:
     3781      #ifdef DEBUG
     3782        WriteLog("Unexptected BitCount %d => Surface unlocked but no data copied back\n",me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount);
     3783      #endif
     3784      // we might could keep the surface locked and return an error but this is more "safe"
     3785      break;
     3786  } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
     3787
     3788  me->Vtbl.Unlock(me,NULL);
     3789  me->dwLastDCUnique = me->dwUniqueValue; // Store this to see if the surface was locked after we released the DC
     3790
    8823791  return(DD_OK);
    8833792}
    8843793//******************************************************************************
    8853794//******************************************************************************
    886 HRESULT __stdcall SurfInitialize(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC)
    887 {
    888   dprintf(("SurfInitialize\n"));
     3795HRESULT __stdcall SurfRestore(THIS)
     3796{
     3797  #ifdef DEBUG
     3798    WriteLog("SurfRestore\n");
     3799  #endif
     3800
    8893801  return(DD_OK);
    8903802}
    8913803//******************************************************************************
    8923804//******************************************************************************
    893 HRESULT __stdcall SurfIsLost(THIS)
    894 {
    895   dprintf(("SurfIsLost\n"));
    896   return(DD_OK);
    897 }
    898 //******************************************************************************
    899 //******************************************************************************
    900 HRESULT __stdcall SurfLock(THIS_ W32_LPRECT lpRect, LPDDSURFACEDESC lpSurfaceDesc,
    901                DWORD dwFlags, W32_HANDLE hEvent)
     3805HRESULT __stdcall SurfSetClipper(THIS This, LPDIRECTDRAWCLIPPER lpClipper)
    9023806{
    9033807 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    904  ULONG                  pImageBuffer, nrBytesPerScanLine, nrScanLines, rc;
    905  OS2RECTL   rectl;
    906  static int times = 0;
    907 
    908   dprintf(("SurfLock %X %X %d %d\n", me, (int)lpRect, dwFlags, hEvent));
    909   if(me == NULL) {
    910     return DDERR_INVALIDOBJECT;
    911   }
    912 
    913   if(me->fLocked) {
    914     dprintf(("SurfLock: Surface already locked\n"));
    915     return(DDERR_SURFACEBUSY);
    916   }
    917   me->fLocked = TRUE;       //TODO: not really safe
    918   if(me->diveBufNr == DIVE_BUFFER_SCREEN) {
    919     if(lpRect) {
    920         rectl.xLeft    = lpRect->left;
    921             rectl.yBottom  = lpRect->bottom;
    922             rectl.xRight   = lpRect->right;
    923             rectl.yTop     = lpRect->top;
    924     }
    925     else {
    926         rectl.xLeft    = 0;
    927             rectl.yBottom  = me->lpDraw->GetScreenHeight();
    928             rectl.xRight   = me->lpDraw->GetScreenWidth();
    929             rectl.yTop     = 0;
    930     }
    931     dprintf(("SurfLock: Screen buffer!\n"));
    932     rc = DiveAcquireFrameBuffer(me->hDive, (PRECTL)&rectl);
    933     if(rc != DIVE_SUCCESS) {
    934         dprintf(("frame buffer access error %d\n", rc));
    935         me->fLocked = FALSE;
    936         return(DDERR_INVALIDPARAMS);
    937     }
    938     pImageBuffer = (ULONG)me->pFrameBuffer;
    939   }
    940   else {
    941     rc = DiveBeginImageBufferAccess(me->hDive, me->diveBufNr, (PBYTE *)&pImageBuffer,
    942                             &nrBytesPerScanLine, &nrScanLines);
    943     if(rc != DIVE_SUCCESS) {
    944         dprintf(("SurfLock: DiveBeginImageBufferAccess returned %d\n", rc));
    945         me->fLocked = FALSE;
    946         return(DDERR_INVALIDPARAMS);
    947     }
    948   }
    949 
    950   if(!(dwFlags & DDLOCK_SURFACEMEMORYPTR) && lpRect != NULL) {
    951     pImageBuffer += lpRect->top*nrBytesPerScanLine + lpRect->left;
    952     lpSurfaceDesc->lpSurface = (LPVOID)pImageBuffer;
    953         dprintf(("SurfLock %X (x,y) = (%d,%d)\n", pImageBuffer, lpRect->top, lpRect->left));
    954   }
    955   else {
    956     dprintf(("SurfLock %X \n", pImageBuffer));
    957   }
    958   //copy buffer address in surface structure
    959   me->DDSurfaceDesc.lpSurface = (LPVOID)pImageBuffer;
    960   memcpy((char *)lpSurfaceDesc, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC));
    961 
    962   lpSurfaceDesc->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT;
    963   lpSurfaceDesc->dwHeight = me->height;
    964   lpSurfaceDesc->dwWidth  = me->width;
    965   lpSurfaceDesc->lPitch   = me->width*me->bpp/8;
    966   memset((char *)&lpSurfaceDesc->ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT));
    967   lpSurfaceDesc->ddpfPixelFormat.dwFourCC = me->fccColorFormat;
    968   lpSurfaceDesc->ddpfPixelFormat.dwSize   = sizeof(DDPIXELFORMAT);
    969   lpSurfaceDesc->ddpfPixelFormat.dwFlags  = DDPF_FOURCC | DDPF_PALETTEINDEXED8 | DDPF_RGB;
    970   lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = 8;
    971   return(DD_OK);
    972 }
    973 //******************************************************************************
    974 //******************************************************************************
    975 HRESULT __stdcall SurfReleaseDC(THIS_ W32_HDC hdc)
    976 {
    977  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    978  ULONG                  pImageBuffer, nrBytesPerScanLine, nrScanLines, rc;
    979  int                    i;
    980 
    981   dprintf(("SurfReleaseDC %X\n", me));
    982   if(me == NULL) {
    983     return DDERR_INVALIDOBJECT;
    984   }
    985 
    986   if((HDC)hdc != me->hdcImage) {
    987     dprintf(("hdc != me->hdcImage %d != %d", hdc, me->hdcImage));
    988     return(DDERR_INVALIDOBJECT);
    989   }
    990   rc = GetBitmapBits((HANDLE)me->hbmImage, me->width*me->height*me->bpp/8, me->bitmapData);
    991   if(rc == 0) {
    992     dprintf(("GetBitmapBits error"));
    993     return(DDERR_INVALIDOBJECT);
    994   }
    995 
    996   rc = DiveBeginImageBufferAccess(me->hDive, me->diveBufNr, (PBYTE *)&pImageBuffer,
    997                       &nrBytesPerScanLine, &nrScanLines);
    998   if(rc != DIVE_SUCCESS) {
    999     dprintf(("DiveBeginImageBufferAccess returned %d", rc));
    1000     me->fLocked = FALSE;
    1001     return(DDERR_GENERIC);
    1002   }
    1003   dprintf(("SurfReleaseDC; copy bitmap to image buffer %d %d", me->width, me->height));
    1004 
    1005   if(memcmp((char *)pImageBuffer, me->bitmapData, me->height*me->width*me->bpp/8) == 0) {
    1006     dprintf(("identical!!"));
    1007   }
    1008   memcpy((char *)pImageBuffer, me->bitmapData, me->height*me->width*me->bpp/8);
    1009 
    1010   DiveEndImageBufferAccess(me->hDive, me->diveBufNr);
    1011   me->fLocked = FALSE;
    1012   return(DD_OK);
    1013 }
    1014 //******************************************************************************
    1015 //******************************************************************************
    1016 HRESULT __stdcall SurfRestore(THIS)
    1017 {
    1018   dprintf(("SurfRestore\n"));
    1019   return(DD_OK);
    1020 }
    1021 //******************************************************************************
    1022 //******************************************************************************
    1023 HRESULT __stdcall SurfSetClipper(THIS_ LPDIRECTDRAWCLIPPER lpClipper)
    1024 {
    1025  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    1026 
    1027   dprintf(("SurfSetClipper\n"));
    1028   if(me == NULL) {
    1029     return DDERR_INVALIDOBJECT;
    1030   }
    1031   if(lpClipper == NULL) {//deattach surface
    1032     if(me->lpClipper) {
    1033         me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper);
    1034         me->lpClipper = NULL;
    1035         return(DD_OK);
    1036     }
    1037     else    return(DDERR_NOCLIPPERATTACHED);
    1038   }
     3808
     3809  #ifdef DEBUG
     3810    WriteLog("SurfSetClipper\n");
     3811  #endif
     3812
     3813  if(lpClipper == NULL)
     3814  {
     3815    //deattach surface
     3816    if(me->lpClipper)
     3817    {
     3818      me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper);
     3819      me->lpClipper = NULL;
     3820      return(DD_OK);
     3821    }
     3822    else
     3823      return(DDERR_NOCLIPPERATTACHED);
     3824  }
     3825
    10393826  if(lpClipper == (LPDIRECTDRAWCLIPPER)me->lpClipper)
    10403827    return(DD_OK);  //already attached
    1041   if(me->lpClipper != NULL) {
    1042     me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper); //attach other surface
     3828
     3829  if(me->lpClipper != NULL)
     3830  {
     3831    me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper);  //attach other surface
    10433832    return(DD_OK);
    10443833  }
     3834
    10453835  me->lpClipper = (OS2IDirectDrawClipper *)lpClipper;
    10463836  me->lpClipper->Vtbl.AddRef((IDirectDrawClipper*)me->lpClipper);
     3837
    10473838  return(DD_OK);
    10483839}
    10493840//******************************************************************************
    10503841//******************************************************************************
    1051 HRESULT __stdcall SurfSetColorKey(THIS_ DWORD dwFlags, LPDDCOLORKEY lpColorkey)
    1052 {
    1053  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    1054 
    1055   dprintf(("SurfSetColorKey\n"));
    1056   if(me == NULL) {
    1057     return DDERR_INVALIDOBJECT;
    1058   }
    1059   me->ColorKeyFlags |= dwFlags;
    1060   if(dwFlags & DDCKEY_DESTBLT) {
    1061     me->ColorSpaceLowValue[COLORKEY_DEST]  = lpColorkey->dwColorSpaceLowValue;
    1062     me->ColorSpaceHighValue[COLORKEY_DEST] = lpColorkey->dwColorSpaceHighValue;
     3842HRESULT __stdcall SurfSetColorKey(THIS  This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
     3843{
     3844  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3845
     3846  #ifdef DEBUG
     3847    WriteLog("SurfSetColorKey\n");
     3848  #endif
     3849
     3850  if (0==dwFlags)
     3851    return (DDERR_INVALIDPARAMS);
     3852
     3853  // as we report only src colorkey in the caps return error on all others flags
     3854  if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY|DDCKEY_COLORSPACE) & dwFlags)
     3855    return(DDERR_UNSUPPORTED);
     3856
     3857  if(DDCKEY_SRCBLT & dwFlags)
     3858  {
     3859    me->lpVtbl->ChangeUniquenessValue(me); // we changed somethin so change this value
     3860    if(NULL!=lpDDColKey)
     3861    {
     3862      memcpy(&(me->DDSurfaceDesc.ddckCKSrcBlt), lpDDColKey, sizeof(DDCOLORKEY) );
     3863      me->DDSurfaceDesc.dwFlags |= DDCKEY_SRCBLT;
     3864
     3865      // ToDo: Generate a maskbitmap for transparent blitting here
     3866    }
     3867    else
     3868    {
     3869      memset(&(me->DDSurfaceDesc.ddckCKSrcBlt), 0, sizeof(DDCOLORKEY) );
     3870      me->DDSurfaceDesc.dwFlags &= ~DDCKEY_SRCBLT;
     3871    }
     3872  }
     3873  else
     3874    return (DDERR_INVALIDPARAMS); // some other flags where set => error
     3875
     3876  return(DD_OK);
     3877}
     3878//******************************************************************************
     3879//******************************************************************************
     3880HRESULT __stdcall SurfSetOverlayPosition(THIS This, LONG lX, LONG lY)
     3881{
     3882  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3883
     3884  #ifdef DEBUG
     3885    WriteLog("SurfSetOverlayPosition\n");
     3886  #endif
     3887
     3888  if( (me->DDSurfaceDesc.dwFlags & DDSD_CAPS) &&
     3889      (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
     3890  {
     3891    if(me->fOverlayValid)
     3892      return(DDERR_NOOVERLAYDEST);
     3893
     3894    if(!(me->DDSurfaceDesc.dwFlags & DDSCAPS_VISIBLE))
     3895      return(DDERR_OVERLAYNOTVISIBLE);
     3896
     3897    // ToDo: If we implement alignment restricions to the Overlay position
     3898    // check if the new values are OK otherwiese return DDERR_INVALIDPOSITION
     3899
     3900    me->lOverlayX = lX;
     3901    me->lOverlayY = lY;
    10633902    return(DD_OK);
    10643903  }
    1065   if(dwFlags & DDCKEY_DESTOVERLAY) {
    1066     me->ColorSpaceLowValue[COLORKEY_DESTOVERLAY]  = lpColorkey->dwColorSpaceLowValue;
    1067     me->ColorSpaceHighValue[COLORKEY_DESTOVERLAY] = lpColorkey->dwColorSpaceHighValue;
    1068     return(DD_OK);
    1069   }
    1070   if(dwFlags & DDCKEY_SRCBLT) {
    1071     me->ColorSpaceLowValue[COLORKEY_SRC]  = lpColorkey->dwColorSpaceLowValue;
    1072     me->ColorSpaceHighValue[COLORKEY_SRC] = lpColorkey->dwColorSpaceHighValue;
    1073     return(DD_OK);
    1074   }
    1075   if(dwFlags & DDCKEY_SRCOVERLAY) {
    1076     me->ColorSpaceLowValue[COLORKEY_SRCOVERLAY]  = lpColorkey->dwColorSpaceLowValue;
    1077     me->ColorSpaceHighValue[COLORKEY_SRCOVERLAY] = lpColorkey->dwColorSpaceHighValue;
    1078     return(DD_OK);
    1079   }
    1080   return(DDERR_INVALIDPARAMS);
    1081 }
    1082 //******************************************************************************
    1083 //******************************************************************************
    1084 HRESULT __stdcall SurfSetOverlayPosition(THIS_ LONG, LONG )
    1085 {
    1086   dprintf(("SurfSetOverlayPosition\n"));
    1087   return(DD_OK);
    1088 }
    1089 //******************************************************************************
    1090 //******************************************************************************
    1091 HRESULT __stdcall SurfSetPalette(THIS_ LPDIRECTDRAWPALETTE lpPalette)
    1092 {
    1093  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    1094 
    1095   dprintf(("SurfSetPalette %X\n", me));
    1096   if(me == NULL) {
    1097     return DDERR_INVALIDOBJECT;
    1098   }
    1099   if(lpPalette == NULL) {//deattach palette
    1100     if(me->lpPalette) {
    1101         me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette);
    1102         me->lpPalette = NULL;
    1103         return(DD_OK);
    1104     }
    1105     else    return(DDERR_NOCLIPPERATTACHED);
    1106   }
     3904
     3905  return(DDERR_NOTAOVERLAYSURFACE);
     3906}
     3907//******************************************************************************
     3908//******************************************************************************
     3909HRESULT __stdcall SurfSetPalette(THIS This, LPDIRECTDRAWPALETTE lpPalette)
     3910{
     3911  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3912
     3913  #ifdef DEBUG
     3914    WriteLog("SurfSetPalette\n");
     3915  #endif
     3916
     3917  if(lpPalette == NULL)
     3918  {
     3919    //deattach palette
     3920    if(me->lpPalette)
     3921    {
     3922      // If removed from a primary surface notify
     3923      // palette that it is no longer attached to the
     3924      // primary surface => doesn't modify physical palette
     3925      if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
     3926        me->lpPalette->SetIsPrimary(FALSE);
     3927
     3928      me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette);
     3929      me->lpPalette = NULL;
     3930      return(DD_OK);
     3931    }
     3932    else
     3933      return(DDERR_NOPALETTEATTACHED);
     3934  }
     3935
    11073936  if(lpPalette == (LPDIRECTDRAWPALETTE)me->lpPalette)
    11083937    return(DD_OK);  //already attached
    1109 //?????
    1110 #if 0
    1111   if(me->lpPalette != NULL) {
    1112     me->lpClipper->Vtbl.Release(me->lpPalette); //attach other palette
     3938
     3939  if(me->lpPalette != NULL)
     3940  {
     3941    me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette); //attach other palette
    11133942    return(DD_OK);
    11143943  }
    1115 #endif
    1116 
    11173944  me->lpPalette = (OS2IDirectDrawPalette *)lpPalette;
    11183945  me->lpPalette->Vtbl.AddRef((IDirectDrawPalette*)me->lpPalette);
     3946
     3947  // If Attached to a primary surface notify
     3948  // palette that it is attached to the primary surface
     3949  //  => It does modify physical palette.
     3950  // This is important as an palette can be attached to
     3951  // multiple surfaces. If one is the primary surface
     3952  // changes done to it via any surface must result in
     3953  // changes in the phys pal.
     3954
    11193955  if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
    1120     me->lpPalette->SetPhysPalette();
     3956    me->lpPalette->SetIsPrimary(TRUE);
     3957
     3958  me->lpVtbl->ChangeUniquenessValue(me);
    11213959
    11223960  return(DD_OK);
     
    11243962//******************************************************************************
    11253963//******************************************************************************
    1126 HRESULT __stdcall SurfUnlock(THIS_ LPVOID lpSurfaceData)
     3964HRESULT __stdcall SurfUnlock(THIS This, LPRECT lpSurfaceRect)
     3965{
     3966
     3967
     3968  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     3969  ISequence<IRectangle*>::Cursor *EnumCursor;
     3970  IRectangle *pIRectUnlock;
     3971  BOOL Found = FALSE;
     3972
     3973  #ifdef DEBUG
     3974    WriteLog("SurfUnlock\n");
     3975  #endif
     3976
     3977  if(me->fLocked == FALSE)
     3978  {
     3979    #ifdef DEBUG
     3980      WriteLog("Surface not locked!\n");
     3981    #endif
     3982    return(DDERR_NOTLOCKED);
     3983  }
     3984
     3985  if(NULL!=lpSurfaceRect)
     3986  {
     3987    WriteLog("Unlock rectangle\n");
     3988    pIRectUnlock = new IRectangle( lpSurfaceRect->left,
     3989                                   lpSurfaceRect->bottom,
     3990                                   lpSurfaceRect->right,
     3991                                   lpSurfaceRect->top);
     3992  }
     3993  else
     3994  {
     3995    WriteLog("Unlock complete surface\n");
     3996    pIRectUnlock = new IRectangle( 0, me->height, me->width, 0);
     3997  }
     3998
     3999  #ifdef DEBUG
     4000    WriteLog("StartEmuneration of Locked Rects\n");
     4001  #endif
     4002
     4003  EnumCursor = me->LockedRectSequence.newCursor();
     4004  EnumCursor->setToFirst();
     4005  while(EnumCursor->isValid() && !Found)
     4006  {
     4007    Found = (*(EnumCursor->element()) == *pIRectUnlock);
     4008    if(!Found)
     4009    {
     4010      #ifdef DEBUG
     4011        WriteLog("Not Found, try Next rect\n");
     4012      #endif
     4013      EnumCursor->setToNext();
     4014    }
     4015    #ifdef DEBUG
     4016    else
     4017    {
     4018      WriteLog("Found Rect\n");
     4019    }
     4020    #endif
     4021  }
     4022
     4023  if(!Found)
     4024  {
     4025    #ifdef DEBUG
     4026      WriteLog("Rectangle not locked, wrong Rect!\n\n");
     4027    #endif
     4028    return(DDERR_INVALIDRECT);
     4029  }
     4030
     4031  #ifdef DEBUG
     4032    WriteLog("Remove Rect from Seq.\n");
     4033  #endif
     4034
     4035  me->LockedRectSequence.removeAt(*EnumCursor);
     4036
     4037  if(me->LockedRectSequence.isEmpty())  // Do we have unlocked last rectangle
     4038  {
     4039    #ifdef DEBUG
     4040      WriteLog("No Locked Rects left for surface\n");
     4041    #endif
     4042    me->fLocked = FALSE;
     4043  }
     4044
     4045  if(me->pFrameBuffer != me->pDiveBuffer)
     4046  {
     4047    #ifdef DEBUG
     4048      WriteLog( "ColorConversion Needed %08X != %08X\n",
     4049                me->pFrameBuffer,
     4050                me->pDiveBuffer);
     4051    #endif
     4052    me->ColorConversion(lpSurfaceRect);
     4053  }
     4054
     4055  me->lpVtbl->ChangeUniquenessValue(me);
     4056
     4057  WriteLog("Unlock OK\n\n");
     4058
     4059  return(DD_OK);
     4060}
     4061//******************************************************************************
     4062//******************************************************************************
     4063HRESULT __stdcall SurfUpdateOverlay(THIS This, LPRECT, LPDIRECTDRAWSURFACE2,LPRECT,DWORD, LPDDOVERLAYFX)
     4064{
     4065  #ifdef DEBUG
     4066    WriteLog("SurfUpdateOverlay\n");
     4067  #endif
     4068  return(DD_OK);
     4069}
     4070//******************************************************************************
     4071//******************************************************************************
     4072HRESULT __stdcall SurfUpdateOverlay4(THIS, LPRECT, LPDIRECTDRAWSURFACE4,LPRECT,DWORD, LPDDOVERLAYFX)
     4073{
     4074  #ifdef DEBUG
     4075    WriteLog("SurfUpdateOverlay\n");
     4076  #endif
     4077  return(DD_OK);
     4078}
     4079//******************************************************************************
     4080//******************************************************************************
     4081HRESULT __stdcall SurfUpdateOverlayDisplay(THIS, DWORD)
     4082{
     4083  #ifdef DEBUG
     4084    WriteLog("SurfUpdateOverlayDisplay\n");
     4085  #endif
     4086  return(DD_OK);
     4087}
     4088//******************************************************************************
     4089//******************************************************************************
     4090HRESULT __stdcall SurfUpdateOverlayZOrder(THIS, DWORD, LPDIRECTDRAWSURFACE2)
     4091{
     4092  #ifdef DEBUG
     4093    WriteLog("SurfUpdateOverlayZOrder\n");
     4094  #endif
     4095  return(DD_OK);
     4096}
     4097//******************************************************************************
     4098//******************************************************************************
     4099HRESULT __stdcall SurfUpdateOverlayZOrder4(THIS, DWORD, LPDIRECTDRAWSURFACE4)
     4100{
     4101  #ifdef DEBUG
     4102    WriteLog("SurfUpdateOverlayZOrder4\n");
     4103  #endif
     4104  return(DD_OK);
     4105}
     4106//******************************************************************************
     4107//******************************************************************************
     4108HRESULT __stdcall SurfGetDDInterface(THIS This, LPVOID FAR *lplpDirectDraw)
    11274109{
    11284110 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    11294111
    1130   dprintf(("SurfUnlock\n"));
    1131   if(me == NULL) {
    1132     return DDERR_INVALIDOBJECT;
    1133   }
    1134   if(me->fLocked == FALSE)
    1135     return(DDERR_NOTLOCKED);
    1136 
    1137   if(me->diveBufNr == DIVE_BUFFER_SCREEN) {
    1138         DiveDeacquireFrameBuffer(me->hDive);
    1139     dprintf(("SurfUnlock: Frame buffer unlocked\n"));
    1140     me->fLocked = FALSE;
    1141     return(DD_OK);
    1142   }
    1143 
    1144   if(lpSurfaceData != NULL &&
    1145      ((int)lpSurfaceData < (int)me->DDSurfaceDesc.lpSurface ||
    1146       (int)lpSurfaceData > (int)me->DDSurfaceDesc.lpSurface + me->height*me->width)) {
    1147     dprintf(("SurfUnlock: invalid params\n"));
    1148     return(DDERR_INVALIDPARAMS);
    1149   }
    1150   me->fLocked = FALSE;
    1151   DiveEndImageBufferAccess(me->hDive, me->diveBufNr);
    1152 
    1153   dprintf(("SurfUnlock ok\n"));
    1154   return(DD_OK);
    1155 }
    1156 //******************************************************************************
    1157 //******************************************************************************
    1158 HRESULT __stdcall SurfUpdateOverlay(THIS_ W32_LPRECT, LPDIRECTDRAWSURFACE2, W32_LPRECT,DWORD, LPDDOVERLAYFX)
    1159 {
    1160   dprintf(("SurfUpdateOverlay\n"));
    1161   return(DD_OK);
    1162 }
    1163 //******************************************************************************
    1164 //******************************************************************************
    1165 HRESULT __stdcall SurfUpdateOverlayDisplay(THIS_ DWORD)
    1166 {
    1167   dprintf(("SurfUpdateOverlayDisplay\n"));
    1168   return(DD_OK);
    1169 }
    1170 //******************************************************************************
    1171 //******************************************************************************
    1172 HRESULT __stdcall SurfUpdateOverlayZOrder(THIS_ DWORD, LPDIRECTDRAWSURFACE2)
    1173 {
    1174   dprintf(("SurfUpdateOverlayZOrder\n"));
    1175   return(DD_OK);
    1176 }
    1177 //******************************************************************************
    1178 //******************************************************************************
    1179 HRESULT __stdcall SurfGetDDInterface(THIS_ LPVOID FAR *lplpDirectDraw)
    1180 {
    1181  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
    1182 
    1183   dprintf(("SurfGetDDInterface\n"));
    1184   if(me == NULL) {
    1185     return DDERR_INVALIDOBJECT;
    1186   }
     4112  #ifdef DEBUG
     4113    WriteLog("SurfGetDDInterface\n");
     4114  #endif
    11874115  *lplpDirectDraw = (LPVOID FAR *)me->lpDraw;
    11884116  return(DD_OK);
     
    11904118//******************************************************************************
    11914119//******************************************************************************
    1192 HRESULT __stdcall SurfPageLock(THIS_ DWORD)
    1193 {
    1194   dprintf(("SurfPageLock\n"));
     4120HRESULT __stdcall SurfPageLock(THIS, DWORD)
     4121{
     4122  // Only used for DMA memory access
     4123  // If we implement this for the None dive buffers with a pdd the we must change
     4124  // from malloc to DosAllocMem and use OBJ_TILE flag
     4125  #ifdef DEBUG
     4126    WriteLog("SurfPageLock\n");
     4127  #endif
    11954128  return(DD_OK);
    11964129}
    11974130//******************************************************************************
    11984131//******************************************************************************
    1199 HRESULT __stdcall SurfPageUnlock(THIS_ DWORD)
    1200 {
    1201   dprintf(("SurfPageUnlock\n"));
     4132HRESULT __stdcall SurfPageUnlock(THIS, DWORD)
     4133{
     4134  #ifdef DEBUG
     4135    WriteLog("SurfPageUnlock\n");
     4136  #endif
    12024137  return(DD_OK);
    12034138}
    12044139//******************************************************************************
    12054140//******************************************************************************
     4141// V3 Interface Functions
     4142
     4143HRESULT __stdcall SurfSetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurfDesc, DWORD dwFlags)
     4144{
     4145  #ifdef DEBUG
     4146    WriteLog("SurfSetSurfaceDesc\n");
     4147  #endif
     4148
     4149  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     4150  if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
     4151    return DDERR_INVALIDPARAMS;
     4152
     4153  // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
     4154  //  if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
     4155  //       ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
     4156  //       ( DDSCAPS_BACKBUFFER  == me->DDSurfaceDesc.ddsCaps.dwCaps) )
     4157  if(-1==me->diveBufNr)
     4158    return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
     4159
     4160  if (!me->Updated)
     4161  {
     4162    me->Updated = TRUE;
     4163    // free our allocated Memory
     4164    if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
     4165      free(me->DDSurfaceDesc.lpSurface);
     4166  }
     4167  me->lpVtbl->ChangeUniquenessValue(me);
     4168  memcpy((char *)&(me->DDSurfaceDesc), (char *)lpSurfDesc, sizeof(DDSURFACEDESC));
     4169
     4170
     4171  return DD_OK;
     4172}
     4173//******************************************************************************
     4174//******************************************************************************
     4175HRESULT __stdcall SurfSetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurfDesc, DWORD dwFlags)
     4176{
     4177  #ifdef DEBUG
     4178    WriteLog("SurfSetSurfaceDesc4\n");
     4179  #endif
     4180
     4181  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     4182  if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
     4183    return DDERR_INVALIDPARAMS;
     4184
     4185  // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
     4186  //  if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
     4187  //       ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
     4188  //       ( DDSCAPS_BACKBUFFER  == me->DDSurfaceDesc.ddsCaps.dwCaps) )
     4189  if(-1==me->diveBufNr)
     4190    return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
     4191
     4192  if (!me->Updated)
     4193  {
     4194    me->Updated = TRUE;
     4195    // free our allocated Memory
     4196    if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
     4197      free(me->DDSurfaceDesc.lpSurface);
     4198  }
     4199  me->lpVtbl->ChangeUniquenessValue(me);
     4200  memcpy((char *)&(me->DDSurfaceDesc), (char *)lpSurfDesc, sizeof(DDSURFACEDESC2));
     4201
     4202  return DD_OK;
     4203}
     4204//******************************************************************************
     4205//******************************************************************************
     4206// V4 Interface Functions
     4207
     4208HRESULT __stdcall SurfSetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData,
     4209                                     DWORD dwDataSize, DWORD dwFlags)
     4210{
     4211  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     4212  ISequence<PSURFPRIVATEDATA>::Cursor * EnumCursor;
     4213  PSURFPRIVATEDATA pSData;
     4214  void *pBuffer;
     4215  BOOL bFound = FALSE;
     4216
     4217  #ifdef DEBUG
     4218    WriteLog("SurfSetPrivateData\n");
     4219  #endif
     4220
     4221  if(NULL==me)
     4222    return(DDERR_INVALIDOBJECT);
     4223
     4224  if((NULL==lpData)||(0==dwDataSize)||
     4225     (dwFlags & ~(DDSPD_IUNKNOWNPOINTER|DDSPD_VOLATILE)))
     4226    return(DDERR_INVALIDPARAMS);
     4227
     4228  // first check if the refGUID is stored as then the content will be updated
     4229  if(! me->SurfaceSequencePrivateData.isEmpty() )
     4230  {
     4231    EnumCursor = me->SurfaceSequencePrivateData.newCursor();
     4232    EnumCursor->setToFirst();
     4233    while(EnumCursor->isValid() && !bFound)
     4234    {
     4235      pSData = EnumCursor->element();
     4236
     4237      if (IsEqualGUID(pSData->guidTag,refGUID))
     4238        bFound = TRUE;
     4239
     4240      EnumCursor->setToNext();
     4241    }
     4242    delete EnumCursor;
     4243  }
     4244
     4245  if(bFound)
     4246  {
     4247    // update Private Data
     4248
     4249    if (!pSData->isValid)
     4250    {
     4251      // Current data is invalid we need to update/allocate
     4252
     4253      if(dwFlags & DDSPD_IUNKNOWNPOINTER)
     4254      {
     4255        pSData->pData = lpData;
     4256        pSData->dwSize = 4;
     4257        pSData->dwFlags = dwFlags;
     4258        pSData->isValid = TRUE;
     4259        ((OS2IDirectDrawSurface *) lpData)->lpVtbl->AddRef(lpData);
     4260      }
     4261      else
     4262      {
     4263        pSData->pData = malloc(dwDataSize);
     4264        if(NULL!=pSData->pData)
     4265        {
     4266          memcpy(pSData->pData,lpData,dwDataSize);
     4267          pSData->dwSize  = dwDataSize;
     4268          pSData->dwFlags = dwFlags;
     4269          pSData->isValid = TRUE;
     4270        }
     4271        else
     4272        {
     4273          delete pSData;
     4274          return (DDERR_OUTOFMEMORY);
     4275        }
     4276      }
     4277    }
     4278    else
     4279    {
     4280      if(pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
     4281      {
     4282        if(dwFlags & DDSPD_IUNKNOWNPOINTER)
     4283        {
     4284          if(pSData->pData != lpData)
     4285          {
     4286            // Change of IUNKOWNPOINTER => release old and add ref to new one
     4287            ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
     4288            ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
     4289            pSData->pData = lpData;
     4290          }
     4291          pSData->dwFlags = dwFlags; // Update the flags, size is the same
     4292        }
     4293        else
     4294        {
     4295          // Replace IUNKOWN through data
     4296          pBuffer = malloc(dwDataSize); // get new buffer first
     4297          if(NULL!=pBuffer)
     4298          {
     4299            // release old ref and copy data
     4300            ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
     4301            memcpy(pBuffer,lpData,dwDataSize);
     4302            pSData->pData = pBuffer;
     4303            pSData->dwSize = dwDataSize; // Update the size
     4304            pSData->dwFlags = dwFlags;   // Update the flags
     4305          }
     4306          else
     4307            return(DDERR_OUTOFMEMORY);
     4308        }
     4309      }
     4310      else
     4311      {
     4312        if(dwFlags & DDSPD_IUNKNOWNPOINTER)
     4313        {
     4314          // Change of data to IUNKOWNPOINTER => free old memory and add ref to new one
     4315          free(pSData->pData);
     4316          ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
     4317          pSData->pData = lpData;
     4318          pSData->dwSize = dwDataSize; // Update the size
     4319          pSData->dwFlags = dwFlags;   // Update the flags
     4320        }
     4321        else
     4322        {
     4323          //  Update/Replace data
     4324          if(pSData->dwSize!=dwDataSize)
     4325            pBuffer = realloc(pSData->pData,dwDataSize); // update buffer to new size
     4326          else
     4327            pBuffer = pSData->pData;
     4328
     4329          if(NULL!=pBuffer)
     4330          {
     4331            // release old ref and copy data
     4332            memcpy(pBuffer,lpData,dwDataSize);
     4333            pSData->pData = pBuffer;
     4334            pSData->dwSize = dwDataSize; // Update the size
     4335            pSData->dwFlags = dwFlags;   // Update the flags
     4336          }
     4337          else
     4338            return(DDERR_OUTOFMEMORY);
     4339        }
     4340      }
     4341    }
     4342  }
     4343  else
     4344  {
     4345    // New data
     4346
     4347    pSData = new(SURFPRIVATEDATA);
     4348    if (NULL!=pSData)
     4349    {
     4350      if(dwFlags & DDSPD_IUNKNOWNPOINTER)
     4351      {
     4352        memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
     4353        pSData->pData = lpData;
     4354        pSData->dwSize = 4;
     4355        pSData->dwFlags = dwFlags;
     4356        pSData->isValid = TRUE;
     4357        ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
     4358      }
     4359      else
     4360      {
     4361        pSData->pData = malloc(dwDataSize);
     4362        if(NULL!=pSData->pData)
     4363        {
     4364          memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
     4365          memcpy(pSData->pData,lpData,dwDataSize);
     4366          pSData->dwSize  = dwDataSize;
     4367          pSData->dwFlags = dwFlags;
     4368          pSData->isValid = TRUE;
     4369        }
     4370        else
     4371        {
     4372          delete pSData;
     4373          return (DDERR_OUTOFMEMORY);
     4374        }
     4375      }
     4376    }
     4377    else
     4378      return (DDERR_OUTOFMEMORY);
     4379  }
     4380  return(DD_OK);
     4381}
     4382//******************************************************************************
     4383//******************************************************************************
     4384HRESULT __stdcall SurfGetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData, LPDWORD lpDataSize)
     4385{
     4386  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     4387  ISequence<PSURFPRIVATEDATA>::Cursor * EnumCursor;
     4388  PSURFPRIVATEDATA pSData;
     4389  BOOL bFound = FALSE;
     4390  #ifdef DEBUG
     4391    WriteLog("SurfGetPrivateData\n");
     4392  #endif
     4393  if(NULL==me)
     4394    return(DDERR_INVALIDOBJECT);
     4395
     4396  if((NULL==lpData)||(NULL==lpDataSize))
     4397    return(DDERR_INVALIDPARAMS);
     4398
     4399  if(! me->SurfaceSequencePrivateData.isEmpty() )
     4400  {
     4401    EnumCursor = me->SurfaceSequencePrivateData.newCursor();
     4402    EnumCursor->setToFirst();
     4403    while(EnumCursor->isValid() && !bFound)
     4404    {
     4405      pSData = EnumCursor->element();
     4406
     4407      if (IsEqualGUID(pSData->guidTag,refGUID))
     4408        bFound = TRUE;
     4409
     4410      EnumCursor->setToNext();
     4411    }
     4412    delete EnumCursor;
     4413  }
     4414
     4415  if(bFound)
     4416  {
     4417    if(!pSData->isValid)
     4418      return(DDERR_EXPIRED);
     4419
     4420    if(pSData->dwSize > *lpDataSize)
     4421    {
     4422      // Buffer to small return needed Size
     4423      *lpDataSize = pSData->dwSize;
     4424      return(DDERR_MOREDATA);
     4425    }
     4426
     4427    memcpy(lpData,pSData->pData,pSData->dwSize);
     4428    return(DD_OK);
     4429  }
     4430
     4431  return (DDERR_NOTFOUND);
     4432}
     4433//******************************************************************************
     4434//******************************************************************************
     4435HRESULT __stdcall SurfFreePrivateData(THIS This, REFGUID refGUID)
     4436{
     4437  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     4438  ISequence<PSURFPRIVATEDATA>::Cursor * EnumCursor;
     4439  PSURFPRIVATEDATA pSData;
     4440  BOOL bFound = FALSE;
     4441  #ifdef DEBUG
     4442    WriteLog("SurfFreePrivateData\n");
     4443  #endif
     4444  if(NULL==me)
     4445    return(DDERR_INVALIDOBJECT);
     4446
     4447  if(! me->SurfaceSequencePrivateData.isEmpty() )
     4448  {
     4449    EnumCursor = me->SurfaceSequencePrivateData.newCursor();
     4450    EnumCursor->setToFirst();
     4451    while(EnumCursor->isValid() && !bFound)
     4452    {
     4453      pSData = EnumCursor->element();
     4454
     4455      if (IsEqualGUID(pSData->guidTag,refGUID))
     4456      {
     4457        bFound = TRUE;
     4458
     4459        if(pSData->isValid)
     4460        {
     4461          // delete the data if valid
     4462          if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
     4463          {
     4464            // pointer to com stored so calll its release
     4465            ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
     4466          }
     4467          else
     4468          {
     4469            // Free allocated data
     4470            free( pSData->pData);
     4471          }
     4472        }
     4473        // Now remove the entry from the list
     4474        me->SurfaceSequencePrivateData.removeAt(*EnumCursor);
     4475        delete pSData; // free alocated Data
     4476      }
     4477      EnumCursor->setToNext();
     4478    }
     4479    delete EnumCursor;
     4480  }
     4481  return (bFound?DD_OK:DDERR_NOTFOUND);
     4482}
     4483//******************************************************************************
     4484//******************************************************************************
     4485HRESULT __stdcall SurfGetUniquenessValue(THIS This, LPDWORD lpValue)
     4486{
     4487  #ifdef DEBUG
     4488    WriteLog("SurfGetUniquenessValue\n");
     4489  #endif
     4490  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     4491  if (NULL==lpValue)
     4492    return DDERR_INVALIDPARAMS;
     4493
     4494  *lpValue = me->dwUniqueValue;
     4495  return DD_OK;
     4496}
     4497//******************************************************************************
     4498//******************************************************************************
     4499HRESULT __stdcall SurfChangeUniquenessValue(THIS This)
     4500{
     4501  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
     4502  ISequence<PSURFPRIVATEDATA>::Cursor * EnumCursor;
     4503  PSURFPRIVATEDATA pSData;
     4504
     4505  #ifdef DEBUG
     4506    WriteLog("SurfChangeUniquenessValue\n");
     4507  #endif
     4508  me->dwUniqueValue++;
     4509
     4510  if(! me->SurfaceSequencePrivateData.isEmpty() )
     4511  {
     4512    EnumCursor = me->SurfaceSequencePrivateData.newCursor();
     4513    EnumCursor->setToFirst();
     4514    while(EnumCursor->isValid())
     4515    {
     4516      pSData = EnumCursor->element();
     4517      if (pSData->dwFlags & DDSPD_VOLATILE)
     4518      {
     4519        // Data becomes unvalid after a Surface change
     4520        if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
     4521        {
     4522          // pointer to com stored so calll its release
     4523          ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
     4524        }
     4525        else
     4526        {
     4527          // Free allocated data
     4528          free( pSData->pData);
     4529        }
     4530        pSData->pData = NULL;
     4531        pSData->isValid = FALSE; // set flag to invalid
     4532      }
     4533      EnumCursor->setToNext();
     4534    }
     4535    delete EnumCursor;
     4536  }
     4537
     4538  return (DD_OK);
     4539}
     4540
     4541//******************************************************************************
     4542//
     4543//  Pupose function copies one part of the bitmap inside the same bitmap
     4544//
     4545//******************************************************************************
     4546
     4547void __cdecl MoveRects(char* pBuffer, LPRECT lpDestRect, LPRECT lpSrcRect, int bpp, LONG lPitch)
     4548{
     4549  char *pBltPos, *pSrcPos;
     4550  int BlitWidth,BlitHeight;
     4551  static char Scanline[6400];  // sufficient for 1600 at 32 bit
     4552  // Bridge, we may got a problem ;)
     4553  // Check for Overlapping Rects
     4554
     4555  pBltPos = pBuffer;
     4556  pSrcPos = pBuffer;
     4557
     4558  if(lpDestRect->top <= lpSrcRect->top)
     4559  {
     4560    //  +-------+     +-------+      +-------+
     4561    //  |S      |     |S      |      |S      |  +---+---+---+
     4562    //  |   +---|---+ +-------+  +---|---+   |  |S/D|D/S|   |
     4563    //  |   | D |   | | D     |  | D |   |   |  |   |   |   |
     4564    //  +-------+   | +-------+  |   +-------+  |   |   |   |
     4565    //      |       | |       |  |       |      +---+---+---+
     4566    //      +-------+ +-------+  +-------+
     4567    //
     4568    // We got one of the above cases (or no overlapping) so copy from bottom up
     4569
     4570    pBltPos += (lpDestRect->left * bpp) + lPitch * lpDestRect->top;
     4571    pSrcPos += (lpSrcRect->left * bpp)  + lPitch * (lpSrcRect->bottom-1);
     4572    BlitHeight = lpDestRect->bottom - lpDestRect->top;
     4573    BlitWidth  = (lpDestRect->right - lpDestRect->left) * bpp;
     4574
     4575    while(1)
     4576    {
     4577      memcpy(Scanline,pSrcPos,BlitWidth);
     4578      memcpy(pBltPos,Scanline,BlitWidth);
     4579      pBltPos += lPitch;
     4580      pSrcPos -= lPitch;
     4581      if(! (--BlitHeight))
     4582        break;
     4583    }
     4584  }
     4585  else
     4586  {
     4587    //  +-------+     +-------+      +-------+
     4588    //  | D     |     | D     |      | D     |
     4589    //  |   +---|---+ +-------+  +---|---+   |
     4590    //  |   |S  |   | |S      |  |S  |   |   |
     4591    //  +-------+   | +-------+  |   +-------+
     4592    //      |       | |       |  |       |
     4593    //      +-------+ +-------+  +-------+
     4594    //
     4595    // We got one of the above cases so copy top down
     4596
     4597    pBltPos += (lpDestRect->left * bpp) + lPitch * lpDestRect->top;
     4598    pSrcPos += (lpSrcRect->left  * bpp) + lPitch * lpSrcRect->top;
     4599    BlitHeight = lpDestRect->bottom - lpDestRect->top;
     4600    BlitWidth  = (lpDestRect->right - lpDestRect->left) * bpp;
     4601
     4602    while(1)
     4603    {
     4604      memcpy(Scanline,pSrcPos,BlitWidth);
     4605      memcpy(pBltPos,Scanline,BlitWidth);
     4606      pBltPos += lPitch;
     4607      pSrcPos += lPitch;
     4608      if(! (--BlitHeight))
     4609        break;
     4610    }
     4611  }
     4612
     4613}
     4614
     4615//******************************************************************************
     4616//
     4617//  Purpose : Do a blit using the precalced Transbuffer
     4618//            That is the only way to do fast blits if a colorrange is used
     4619//            and we can find totally transparent lines and don't blit them
     4620//            and detect if the part of the line is transparent
     4621//
     4622//            Idea for a kind of mask buffer
     4623//            Format of Transparentbuffer (each line):
     4624//            the first DWORD contains 2 WORDS with Offset of First Non transparent
     4625//            pixel in the low word and the last non transparent pixel in a row in
     4626//            the high word. => 0 = line totally transparent!
     4627//            This limits the max supported width to 2^16 but I thing this is enougth
     4628//            The size per line is 1+((Width+31) & ~31) DWORDS => each Bit represents
     4629//            1 pixel
     4630//
     4631//            TransparentBufferCreate(lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight);
     4632//
     4633//          Layout of a DWORD:
     4634//             UUVVWWXX  dword is processed LS Byte FIRST ...
     4635//             Each bit in a byte stands for one pixel. MS Bit First
     4636//
     4637//          example: Bitmap (16x5) (X= opaque, . = Transparent)
     4638//                   ...XX...XX....XX
     4639//                   ..XXXX....XXXX..
     4640//                   ................
     4641//                   .........XXXXXX.
     4642//                   ...XX...X......X
     4643//
     4644//                   Transparent buffer (2DWORDS) per line
     4645//
     4646//         0x00100003, 0x0000C318
     4647//         0x000E0002, 0x00003C3C
     4648//         0x00000000, 0x00000000
     4649//         0x000F000A, 0x00007E00
     4650//         0x00100003, 0x00008118
     4651//******************************************************************************
     4652
     4653void __cdecl TransSRCBlit8(LPDDSURFACEDESC2 pDestDesc, LPDDSURFACEDESC2 pSrcDesc,  char *pAlpha, LPRECT lpSrcRect)
     4654{
     4655  DWORD *pdwTLine; // pointer to the transparent buffer
     4656  DWORD dwTLineLen;      // # of DWORDS in each tBuffer line
     4657  DWORD dwTLineStart;     // # DWORD in which the first transinfo is
     4658  DWORD dwTDWStart;       // byte in which the firs transinfo is
     4659  DWORD dwTrans;          // current transparentvalue
     4660  DWORD BlitWidth;
     4661  dwTLineLen = 1 + ((pSrcDesc->dwWidth + 31) & ~31);
     4662  pdwTLine = (DWORD*)pAlpha + (dwTLineLen* lpSrcRect->top);
     4663  dwTLineStart = 1+(lpSrcRect->left/32);
     4664  dwTDWStart   = (lpSrcRect->left+8)/8;
     4665}
     4666
     4667
Note: See TracChangeset for help on using the changeset viewer.