Changeset 210 for trunk/src


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

DX 6 Version of ddraw rel files

Location:
trunk/src/ddraw
Files:
2 added
8 edited

Legend:

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

    r97 r210  
    1 /* $Id: OS2CLIPPER.CPP,v 1.3 1999-06-10 17:10:56 phaller Exp $ */
    2 
    3 /*
    4  * DirectDraw Clipper 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 
    12 /*@Const************************************************************************
    13 *   Defined Constants                                                          *
    14 *******************************************************************************/
    15 #define INCL_GUID
    16 #define WIN32SDK_NOPOSTWRAPPER
    17 
    18 /*@Header***********************************************************************
    19 *   Header Files                                                               *
    20 *******************************************************************************/
    21 #include <os2win.h>
    22 #include <dive.h>
    23 
    241#include <memory.h>
    252
    26 #include "no.h"
    27 #include <w_windows.h>
    28 #include <ddraw.h>
    29 #include <d3d.h>
    30 #include <Win32SDKPostWrapper.h>
    31 
     3#define INITGUID
    324#include "os2ddraw.h"
    335#include "os2clipper.h"
     6#define _OS2WIN_H
     7#define FAR
    348#include "misc.h"
    35 
    36 /*** IDirect3D methods ***/
    37 /* KSO Apr 19 1999: Set correct interface.           *
    38  * (INTERFACE is used in the THIS and THIS_ macros)  */
    39 #undef  INTERFACE
    40 #define INTERFACE   IDirectDrawClipper
    41 
     9#include <winerror.h>
    4210
    4311//******************************************************************************
    4412//******************************************************************************
    4513OS2IDirectDrawClipper::OS2IDirectDrawClipper(OS2IDirectDraw *lpDirectDraw) :
    46                            Referenced(0), lastError(DD_OK),
    47                            clipWindow(0)
     14                 Referenced(0), lastError(DD_OK),
     15                 clipWindow(0)
    4816{
    49   lpVtbl                    = &Vtbl;
    50   Vtbl.AddRef               = ClipAddRef;
    51   Vtbl.Release              = ClipRelease;
    52   Vtbl.QueryInterface       = ClipQueryInterface;
    53   Vtbl.GetClipList          = ClipGetClipList;
    54   Vtbl.GetHWnd              = ClipGetHWnd;
    55   Vtbl.Initialize           = ClipInitialize;
    56   Vtbl.IsClipListChanged    = ClipIsClipListChanged;
    57   Vtbl.SetClipList          = ClipSetClipList;
    58   Vtbl.SetHWnd              = ClipSetHWnd;
     17  lpVtbl                  = &Vtbl;
     18  Vtbl.AddRef             = ClipAddRef;
     19  Vtbl.Release            = ClipRelease;
     20  Vtbl.QueryInterface     = ClipQueryInterface;
     21  Vtbl.GetClipList        = ClipGetClipList;
     22  Vtbl.GetHWnd            = ClipGetHWnd;
     23  Vtbl.Initialize         = ClipInitialize;
     24  Vtbl.IsClipListChanged  = ClipIsClipListChanged;
     25  Vtbl.SetClipList        = ClipSetClipList;
     26  Vtbl.SetHWnd            = ClipSetHWnd;
    5927
    60   lpDraw                        = lpDirectDraw;
    61   lpDraw->Vtbl.AddRef((IDirectDraw2*)lpDraw);
    62   hDive                         = lpDirectDraw->GetDiveInstance();
     28  lpDraw                  = lpDirectDraw;
     29  lpDraw->Vtbl.AddRef(lpDraw);
     30  hDive                   = lpDirectDraw->GetDiveInstance();
    6331}
    6432//******************************************************************************
     
    6634OS2IDirectDrawClipper::~OS2IDirectDrawClipper()
    6735{
    68   lpDraw->Vtbl.Release((IDirectDraw2*)lpDraw);
     36  lpDraw->Vtbl.Release(lpDraw);
    6937}
    7038//******************************************************************************
    7139//******************************************************************************
    72 HRESULT __stdcall ClipQueryInterface(THIS_ REFIID riid, LPVOID FAR * ppvObj)
     40HRESULT __stdcall ClipQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj)
    7341{
    74   dprintf(("ClipQueryInterface\n"));
     42  #ifdef DEBUG
     43    WriteLog("ClipQueryInterface\n");
     44  #endif
     45
    7546  *ppvObj = NULL;
    7647
     
    7849     !IsEqualGUID(riid, CLSID_DirectDrawClipper))
    7950//&& !IsEqualGUID(riid, IID_IUnknown))
    80     return E_NOINTERFACE;
     51  return E_NOINTERFACE;
    8152
    8253  *ppvObj = This;
     
    8758//******************************************************************************
    8859//******************************************************************************
    89 ULONG   __stdcall ClipAddRef(THIS)
     60ULONG   __stdcall ClipAddRef(THIS This)
    9061{
    9162 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
    9263
    93   dprintf(("OS2IDirectDrawClipper::AddRef %d\n", me->Referenced+1));
     64  #ifdef DEBUG
     65    WriteLog("OS2IDirectDrawClipper::AddRef %d\n", me->Referenced+1);
     66  #endif
     67
    9468  return ++me->Referenced;
    9569}
    9670//******************************************************************************
    9771//******************************************************************************
    98 ULONG   __stdcall ClipRelease(THIS)
     72ULONG   __stdcall ClipRelease(THIS This)
    9973{
    10074 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
    10175
    102   dprintf(("OS2IDirectDrawClipper::Release %d\n", me->Referenced-1));
    103   if(me->Referenced) {
     76  #ifdef DEBUG
     77    WriteLog("OS2IDirectDrawClipper::Release %d\n", me->Referenced-1);
     78  #endif
     79
     80  if(me->Referenced)
     81  {
    10482    me->Referenced--;
    105     if(me->Referenced == 0) {
    106         delete me;
    107         return(0);
     83    if(me->Referenced == 0)
     84    {
     85      delete me;
     86      return(0);
    10887    }
    109     else    return me->Referenced;
     88    else
     89      return me->Referenced;
    11090  }
    111   else  return(0);
     91  else
     92   return(0);
    11293}
    11394//******************************************************************************
    11495//******************************************************************************
    115 HRESULT __stdcall ClipGetClipList(THIS_ W32_LPRECT, W32_LPRGNDATA, LPDWORD)
     96HRESULT __stdcall ClipGetClipList(THIS, LPRECT, LPRGNDATA, LPDWORD)
    11697{
    117   dprintf(("ClipGetClipList\n"));
     98  #ifdef DEBUG
     99    WriteLog("ClipGetClipList\n");
     100  #endif
     101
    118102  return(DD_OK);
    119103}
    120104//******************************************************************************
    121105//******************************************************************************
    122 HRESULT __stdcall ClipGetHWnd(THIS_ W32_HWND FAR *pHwnd)
     106HRESULT __stdcall ClipGetHWnd(THIS This, HWND FAR *pHwnd)
    123107{
    124108 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
    125109
    126   dprintf(("ClipGetHWnd\n"));
     110  #ifdef DEBUG
     111    WriteLog("ClipGetHWnd\n");
     112  #endif
     113
    127114  *pHwnd = me->clipWindow;
    128115  return(DD_OK);
     
    130117//******************************************************************************
    131118//******************************************************************************
    132 HRESULT __stdcall ClipInitialize(THIS_ LPDIRECTDRAW, DWORD)
     119HRESULT __stdcall ClipInitialize(THIS, LPDIRECTDRAW, DWORD)
    133120{
    134   dprintf(("ClipInitialize\n"));
     121  #ifdef DEBUG
     122    WriteLog("ClipInitialize\n");
     123  #endif
     124
     125  return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
     126}
     127//******************************************************************************
     128//******************************************************************************
     129HRESULT __stdcall ClipIsClipListChanged(THIS, BOOL FAR *)
     130{
     131  #ifdef DEBUG
     132    WriteLog("ClipIsClipListChanged\n");
     133  #endif
     134
    135135  return(DD_OK);
    136136}
    137137//******************************************************************************
    138138//******************************************************************************
    139 HRESULT __stdcall ClipIsClipListChanged(THIS_ BOOL FAR *)
     139HRESULT __stdcall ClipSetClipList(THIS, LPRGNDATA,DWORD)
    140140{
    141   dprintf(("ClipIsClipListChanged\n"));
    142   return(DD_OK);
    143 }
    144 //******************************************************************************
    145 //******************************************************************************
    146 HRESULT __stdcall ClipSetClipList(THIS_ W32_LPRGNDATA,DWORD)
    147 {
    148   dprintf(("ClipSetClipList\n"));
     141  #ifdef DEBUG
     142    WriteLog("ClipSetClipList\n");
     143  #endif
     144
    149145  return(DD_OK);
    150146}
     
    152148//DWORD param not used in DirectX 3
    153149//******************************************************************************
    154 HRESULT __stdcall ClipSetHWnd(THIS_ DWORD reserved, W32_HWND hwnd)
     150HRESULT __stdcall ClipSetHWnd(THIS This, DWORD reserved, HWND hwnd)
    155151{
    156152 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
    157153
    158   dprintf(("ClipSetHWnd\n"));
     154  #ifdef DEBUG
     155    WriteLog("ClipSetHWnd\n");
     156  #endif
     157
    159158  me->clipWindow = hwnd;
    160159  return(DD_OK);
  • trunk/src/ddraw/OS2D3D.CPP

    r97 r210  
    1 /* $Id: OS2D3D.CPP,v 1.3 1999-06-10 17:10:56 phaller Exp $ */
    2 
    3 //******************************************************************************
    4 //******************************************************************************
    5 // Direct3D Main Class
    6 //
    7 // Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
    8 //******************************************************************************
    9 //******************************************************************************
    10 // *
    11 // * Project Odin Software License can be found in LICENSE.TXT
    12 // *
    13 
    14 /*@Const************************************************************************
    15 *   Defined Constants                                                          *
    16 *******************************************************************************/
    17 #define WIN32SDK_NOPOSTWRAPPER
    18 
    19 /*@Header***********************************************************************
    20 *   Header Files                                                               *
    21 *******************************************************************************/
    22 #include <os2win.h>
    23 #include <dive.h>
    24 
    25 #include <builtin.h>
    261#include <memory.h>
    272
    28 #include "no.h"
    29 #include <w_windows.h>
    30 #include <ddraw.h>
    31 #include <d3d.h>
    32 #include <Win32SDKPostWrapper.h>
    33 
     3#define INITGUID
    344#include "os2ddraw.h"
    355#include "os2clipper.h"
    366#include "os2palette.h"
    377#include "os2surface.h"
     8#define _OS2WIN_H
     9#define FAR
    3810#include "misc.h"
    39 
    40 /*** IDirect3D methods ***/
    41 /* KSO Apr 19 1999: Set correct interface.           *
    42  * (INTERFACE is used in the THIS and THIS_ macros)  */
    43 #undef  INTERFACE
    44 #define INTERFACE   IDirect3D
    45 
     11#include <winerror.h>
     12#include <builtin.h>
     13#undef THIS
     14#define THIS VOID*
    4615
    4716//******************************************************************************
    4817//******************************************************************************
    49 HRESULT __stdcall D3DQueryInterface(THIS, REFIID riid, LPVOID FAR * ppvObj)
     18HRESULT __stdcall D3DQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj)
    5019{
    5120  dprintf(("D3DQueryInterface\n"));
     
    5322
    5423  if(IID_IDirect3D != (GUID &)&riid)
    55     return E_NOINTERFACE;
     24  return E_NOINTERFACE;
    5625
    5726  *ppvObj = This;
     
    6231//******************************************************************************
    6332//******************************************************************************
    64 ULONG __stdcall D3DAddRef(THIS)
     33ULONG __stdcall D3DAddRef(THIS This)
    6534{
    6635 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
     
    7140//******************************************************************************
    7241//******************************************************************************
    73 ULONG __stdcall D3DRelease(THIS)
     42ULONG __stdcall D3DRelease(THIS This)
    7443{
    7544 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
     
    7847  dprintf(("OS2IDirectDraw::%X \n", me));
    7948  if(me->Referenced) {
    80     me->Referenced--;
    81     if(me->Referenced == 0) {
    82         delete me;
    83         return(0);
    84     }
    85     else    return me->Referenced;
     49  me->Referenced--;
     50  if(me->Referenced == 0) {
     51    delete me;
     52    return(0);
     53  }
     54  else    return me->Referenced;
    8655  }
    8756  else  return(0);
     
    8958//******************************************************************************
    9059//******************************************************************************
    91 HRESULT __stdcall D3DInitialize(THIS_ REFIID)
     60HRESULT __stdcall D3DInitialize(THIS This, REFIID)
    9261{
    9362  dprintf(("D3DInitialize\n"));
     
    9665//******************************************************************************
    9766//******************************************************************************
    98 HRESULT __stdcall D3DEnumDevices(THIS_ LPD3DENUMDEVICESCALLBACK, LPVOID)
     67HRESULT __stdcall D3DEnumDevices(THIS This, LPD3DENUMDEVICESCALLBACK, LPVOID)
    9968{
    10069  dprintf(("D3DEnumDevices\n"));
     
    10372//******************************************************************************
    10473//******************************************************************************
    105 HRESULT __stdcall D3DCreateLight(THIS_ LPDIRECT3DLIGHT*, IUnknown*)
     74HRESULT __stdcall D3DCreateLight(THIS This, LPDIRECT3DLIGHT*, IUnknown*)
    10675{
    10776  dprintf(("D3DCreateLight\n"));
     
    11079//******************************************************************************
    11180//******************************************************************************
    112 HRESULT __stdcall D3DCreateMaterial(THIS_ LPDIRECT3DMATERIAL*, IUnknown*)
     81HRESULT __stdcall D3DCreateMaterial(THIS This, LPDIRECT3DMATERIAL*, IUnknown*)
    11382{
    11483  dprintf(("D3DCreateMaterial\n"));
     
    11786//******************************************************************************
    11887//******************************************************************************
    119 HRESULT __stdcall D3DCreateViewport(THIS_ LPDIRECT3DVIEWPORT*, IUnknown*)
     88HRESULT __stdcall D3DCreateViewport(THIS This, LPDIRECT3DVIEWPORT*, IUnknown*)
    12089{
    12190  dprintf(("D3DCreateViewport\n"));
     
    12493//******************************************************************************
    12594//******************************************************************************
    126 HRESULT __stdcall D3DFindDevice(THIS_ LPD3DFINDDEVICESEARCH, LPD3DFINDDEVICERESULT)
     95HRESULT __stdcall D3DFindDevice(THIS This, LPD3DFINDDEVICESEARCH, LPD3DFINDDEVICERESULT)
    12796{
    12897  dprintf(("D3DCreateFindDevice\n"));
  • trunk/src/ddraw/OS2DDRAW.CPP

    r97 r210  
    1 /* $Id: OS2DDRAW.CPP,v 1.3 1999-06-10 17:10:56 phaller Exp $ */
    2 
    3 /*
    4  * DirectDraw main 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 WIN32SDK_NOPOSTWRAPPER
    15 
    16 /*@Header***********************************************************************
    17 *   Header Files                                                               *
    18 *******************************************************************************/
    19 #include <os2win.h>
    20 #include <dive.h>
    21 
    221#include <memory.h>
    23 #include <builtin.h>
    24 
    25 #include "no.h"
    26 #include <w_windows.h>
    27 #include <ddraw.h>
    28 #include <d3d.h>
    29 #include <Win32SDKPostWrapper.h>
    30 
    31 #include <fourcc.h>
    32 
     2
     3#define INITGUID
    334#include "os2ddraw.h"
    345#include "os2clipper.h"
    356#include "os2palette.h"
    367#include "os2surface.h"
     8#define _OS2WIN_H
     9#define FAR
    3710#include "misc.h"
    38 #include "os2util.h"
    39 
    40 
    41 /* KSO Apr 19 1999: Set correct interface.           *
    42  * (INTERFACE is used in the THIS and THIS_ macros)  */
    43 #undef  INTERFACE
    44 #define INTERFACE   IDirectDraw2
    45 
    46 
    47 
    48 DIVE_CAPS dcaps           = {0};
    49 FOURCC    fccFormats[100] = {0};        /* Color format code                 */
    50 
    51 
     11#include <winreg.h>
     12#include <winuser.h>
     13#include <winerror.h>
     14#include <builtin.h>
     15#include "cio2.h"
     16
     17// include with the videomodes we support
     18// better would be to get these modes from the card
     19// But for now we use standard VESA 2.0 modes with 70Hz
     20#include "os2ddrawmodes.h"
     21#include "os2DDWindow.h"
     22
     23#define KEY_DIRECT2 "\\Software\\Win32OS2\\Direct2"
     24#define KEY_DIRECT2DRAW "\\Software\\Win32OS2\\Direct2\\Draw"
     25
     26FOURCC  SupportedFourCCs[] = {FOURCC_LUT8,FOURCC_R565,FOURCC_RGB3,FOURCC_RGB4};
    5227//******************************************************************************
    5328//******************************************************************************
    5429OS2IDirectDraw::OS2IDirectDraw(GUID *lpGUID) :
    55        Referenced(0), lastError(DD_OK),
    56        pFrameBuffer(NULL), hwndClient(0), screenwidth(640),
    57        screenheight(480), screenbpp(8), fFullScreen(TRUE)
    58 {
    59   if(lpGUID && *lpGUID == IID_IDirect3D) {
    60       lpVtbl = (IDirectDraw2Vtbl *)&Vtbl3D;
    61       Vtbl3D.AddRef             = D3DAddRef;
    62       Vtbl3D.Release            = D3DRelease;
    63       Vtbl3D.QueryInterface     = D3DQueryInterface;
    64       Vtbl3D.Initialize         = D3DInitialize;
    65       Vtbl3D.EnumDevices        = D3DEnumDevices;
    66       Vtbl3D.CreateLight        = D3DCreateLight;
    67       Vtbl3D.CreateMaterial     = D3DCreateMaterial;
    68       Vtbl3D.CreateViewport     = D3DCreateViewport;
    69       Vtbl3D.FindDevice         = D3DFindDevice;
    70   }
    71   else {
    72       lpVtbl = &Vtbl;
    73       Vtbl.AddRef                   = DrawAddRef;
    74       Vtbl.Release                  = DrawRelease;
    75       Vtbl.QueryInterface           = DrawQueryInterface;
    76       Vtbl.Compact                  = DrawCompact;
    77       Vtbl.CreateClipper            = DrawCreateClipper;
    78       Vtbl.W32_CreatePalette        = DrawCreatePalette; //KSO Apr 19 1999: Sideeffect of the wrapping...
    79       Vtbl.CreateSurface            = DrawCreateSurface;
    80       Vtbl.DuplicateSurface         = DrawDuplicateSurface;
    81       Vtbl.EnumDisplayModes         = DrawEnumDisplayModes;
    82       Vtbl.EnumSurfaces             = DrawEnumSurfaces;
    83       Vtbl.FlipToGDISurface         = DrawFlipToGDISurface;
    84       Vtbl.GetCaps                  = DrawGetCaps;
    85       Vtbl.GetDisplayMode           = DrawGetDisplayMode;
    86       Vtbl.GetFourCCCodes           = DrawGetFourCCCodes;
    87       Vtbl.GetGDISurface            = DrawGetGDISurface;
    88       Vtbl.GetMonitorFrequency      = DrawGetMonitorFrequency;
    89       Vtbl.GetScanLine              = DrawGetScanLine;
    90       Vtbl.GetVerticalBlankStatus   = DrawGetVerticalBlankStatus;
    91       Vtbl.Initialize               = DrawInitialize;
    92       Vtbl.RestoreDisplayMode       = DrawRestoreDisplayMode;
    93       Vtbl.SetCooperativeLevel      = DrawSetCooperativeLevel;
    94 
    95       if(lpGUID && *lpGUID == IID_IDirectDraw2)
    96             *(ULONG *)&Vtbl.SetDisplayMode  = (ULONG)DrawSetDisplayMode2;
    97       else  *(ULONG *)&Vtbl.SetDisplayMode  = (ULONG)DrawSetDisplayMode;
    98 
    99       Vtbl.WaitForVerticalBlank = DrawWaitForVerticalBlank;
    100       Vtbl.GetAvailableVidMem   = DrawGetAvailableVidMem;
     30     Referenced(0), lastError(DD_OK),
     31     pFrameBuffer(NULL), hwndClient(0), screenwidth(640),
     32     screenheight(480), screenbpp(8),PrimaryExists(false)
     33
     34{
     35  HKEY  hkDirectDraw2;
     36  DWORD dwVSize, dwVType;
     37
     38  // Setup table for 3d devices
     39  Vtbl3D.AddRef         = D3DAddRef;
     40  Vtbl3D.Release        = D3DRelease;
     41  Vtbl3D.QueryInterface = D3DQueryInterface;
     42  Vtbl3D.Initialize     = D3DInitialize;
     43  Vtbl3D.EnumDevices    = D3DEnumDevices;
     44  Vtbl3D.CreateLight    = D3DCreateLight;
     45  Vtbl3D.CreateMaterial = D3DCreateMaterial;
     46  Vtbl3D.CreateViewport = D3DCreateViewport;
     47  Vtbl3D.FindDevice     = D3DFindDevice;
     48
     49  // old V2 Interface
     50  Vtbl.AddRef                 = DrawAddRef;
     51  Vtbl.Release                = DrawRelease;
     52  Vtbl.QueryInterface         = DrawQueryInterface;
     53  Vtbl.Compact                = DrawCompact;
     54  Vtbl.CreateClipper          = DrawCreateClipper;
     55  Vtbl.CreatePalette          = DrawCreatePalette;
     56  Vtbl.CreateSurface          = DrawCreateSurface;
     57  Vtbl.DuplicateSurface       = DrawDuplicateSurface;
     58  Vtbl.EnumDisplayModes       = DrawEnumDisplayModes;
     59  Vtbl.EnumSurfaces           = DrawEnumSurfaces;
     60  Vtbl.FlipToGDISurface       = DrawFlipToGDISurface;
     61  Vtbl.GetCaps                = DrawGetCaps;
     62  Vtbl.GetDisplayMode         = DrawGetDisplayMode;
     63  Vtbl.GetFourCCCodes         = DrawGetFourCCCodes;
     64  Vtbl.GetGDISurface          = DrawGetGDISurface;
     65  Vtbl.GetMonitorFrequency    = DrawGetMonitorFrequency;
     66  Vtbl.GetScanLine            = DrawGetScanLine;
     67  Vtbl.GetVerticalBlankStatus = DrawGetVerticalBlankStatus;
     68  Vtbl.Initialize             = DrawInitialize;
     69  Vtbl.RestoreDisplayMode     = DrawRestoreDisplayMode;
     70  Vtbl.SetCooperativeLevel    = DrawSetCooperativeLevel;
     71  if(lpGUID && *lpGUID == IID_IDirectDraw2)
     72    *(ULONG *)&Vtbl.SetDisplayMode = (ULONG)DrawSetDisplayMode2;
     73  else
     74    *(ULONG *)&Vtbl.SetDisplayMode = (ULONG)DrawSetDisplayMode;
     75  Vtbl.WaitForVerticalBlank   = DrawWaitForVerticalBlank;
     76  Vtbl.GetAvailableVidMem     = DrawGetAvailableVidMem;
     77
     78  // New V4 interface
     79  Vtbl4.AddRef                 = DrawAddRef;   // todo change to a DrawAddRef4 as handling this has changed
     80  Vtbl4.Release                = DrawRelease;  // see above
     81  Vtbl4.QueryInterface         = DrawQueryInterface;
     82  Vtbl4.Compact                = DrawCompact;
     83  Vtbl4.CreateClipper          = DrawCreateClipper;
     84  Vtbl4.CreateSurface          = DrawCreateSurface4;//
     85  Vtbl4.DuplicateSurface       = DrawDuplicateSurface4;//
     86  Vtbl4.EnumDisplayModes       = DrawEnumDisplayModes4;//
     87  Vtbl4.EnumSurfaces           = DrawEnumSurfaces4; //
     88  Vtbl4.FlipToGDISurface       = DrawFlipToGDISurface;
     89  Vtbl4.GetCaps                = DrawGetCaps;
     90  Vtbl4.GetDisplayMode         = DrawGetDisplayMode4;//
     91  Vtbl4.GetFourCCCodes         = DrawGetFourCCCodes;
     92  Vtbl4.GetGDISurface          = DrawGetGDISurface4;//
     93  Vtbl4.GetMonitorFrequency    = DrawGetMonitorFrequency;
     94  Vtbl4.GetScanLine            = DrawGetScanLine;
     95  Vtbl4.GetVerticalBlankStatus = DrawGetVerticalBlankStatus;
     96  Vtbl4.Initialize             = DrawInitialize;
     97  Vtbl4.RestoreDisplayMode     = DrawRestoreDisplayMode;
     98  Vtbl4.SetCooperativeLevel    = DrawSetCooperativeLevel;
     99  Vtbl4.SetDisplayMode         = DrawSetDisplayMode2;
     100  Vtbl4.WaitForVerticalBlank   = DrawWaitForVerticalBlank;
     101  Vtbl4.GetAvailableVidMem     = DrawGetAvailableVidMem4;
     102  Vtbl4.GetSurfaceFromDC       = DrawGetSurfaceFromDC;
     103  Vtbl4.RestoreAllSurfaces     = DrawRestoreAllSurfaces;
     104  Vtbl4.TestCooperativeLevel   = DrawTestCooperativeLevel;
     105  Vtbl4.GetDeviceIdentifier    = DrawGetDeviceIdentifier;
     106
     107  if(lpGUID && *lpGUID == IID_IDirect3D)
     108  {
     109    WriteLog("D3D Interface\n");
     110
     111    lpVtbl = (IDirectDraw4Vtbl *)&Vtbl3D;
     112  }
     113  else
     114  {
     115    if(lpGUID && *lpGUID == IID_IDirectDraw4)
     116    {
     117      WriteLog("V4 Interface\n");
     118      lpVtbl = &Vtbl4;
     119    }
     120    else
     121    {
     122      WriteLog("<V4 Interface\n");
     123      lpVtbl = (IDirectDraw4Vtbl *) &Vtbl;
     124    }
    101125  }
    102126
    103127  ULONG rc = DiveOpen(&hDive, FALSE, &pFrameBuffer);
    104   if(rc) {
    105     dprintf(("ERROR: DiveOpen returned %d\n", rc));
     128  if(rc)
     129  {
     130    WriteLog("ERROR: DiveOpen returned %d\n", rc);
    106131    lastError = DDERR_GENERIC;
    107132    hDive     = NULL;
    108133  }
    109   dcaps.pFormatData    = fccFormats;
    110   dcaps.ulFormatLength = sizeof(fccFormats);
    111   dcaps.ulStructLen    = sizeof(dcaps);
    112   DiveQueryCaps(&dcaps, DIVE_BUFFER_SCREEN);
     134  else
     135  {
     136    rc = DiveQueryCaps(&dCaps,DIVE_BUFFER_SCREEN);
     137  }
     138
     139  // Shall we run in FS mode ?
     140  if(ERROR_SUCCESS==RegOpenKeyA(HKEY_LOCAL_MACHINE,KEY_DIRECT2DRAW,&hkDirectDraw2))
     141  {
     142    dwVSize = 4;
     143    dwVType = REG_DWORD;
     144    if(ERROR_SUCCESS!=RegQueryValueExA(hkDirectDraw2,"Fullscreen",NULL,&dwVType,(LPBYTE)&bScale,&dwVSize))
     145      bScale = FALSE;
     146  }
     147  else
     148    bScale = FALSE;
    113149}
    114150//******************************************************************************
     
    117153{
    118154  dprintf(("OS2IDirectDraw::~OS2IDirectDraw()\n"));
    119   if(hDive) DiveClose(hDive);
    120 }
    121 //******************************************************************************
    122 //******************************************************************************
    123 HRESULT __stdcall DrawQueryInterface(THIS, REFIID riid, LPVOID FAR * ppvObj)
    124 {
    125 #ifdef DEBUG
    126   WriteLog("OS2IDirectDraw::QueryInterface\n");
    127 #endif
     155  if(hDive)
     156    DiveClose(hDive);
     157}
     158//******************************************************************************
     159//******************************************************************************
     160FOURCC OS2IDirectDraw::GetScreenFourCC()
     161{
     162  return SupportedFourCCs[screenbpp>>3];
     163}
     164//******************************************************************************
     165//******************************************************************************
     166HRESULT __stdcall DrawQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj)
     167{
     168 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
     169  #ifdef DEBUG
     170    WriteLog("OS2IDirectDraw::QueryInterface\n");
     171  #endif
     172
    128173  *ppvObj = NULL;
    129174
    130175  if(!IsEqualGUID(riid, CLSID_DirectDraw) &&
    131176     !IsEqualGUID(riid, IID_IDirectDraw) &&
    132      !IsEqualGUID(riid, IID_IDirectDraw2))
     177     !IsEqualGUID(riid, IID_IDirectDraw2) &&
     178     !IsEqualGUID(riid, IID_IDirectDraw4))
    133179//&& !IsEqualGUID(riid, IID_IUnknown))
    134     return E_NOINTERFACE;
    135 
     180  return E_NOINTERFACE;
     181
     182  // ToDo Better way of returning differnent intterfaces for same class
     183
     184  if(IsEqualGUID(riid, IID_IDirectDraw4))
     185  {
     186    WriteLog("IID_IDirectDraw4 Interface\n");
     187    me->lpVtbl = &me->Vtbl4;
     188  }
     189  else
     190  {
     191    WriteLog("No IID_IDirectDraw4 Interface\n");
     192    me->lpVtbl = (IDirectDraw4Vtbl *) &me->Vtbl;
     193  }
    136194  *ppvObj = This;
    137 
    138195  DrawAddRef(This);
    139196  return(DD_OK);
     
    141198//******************************************************************************
    142199//******************************************************************************
    143 ULONG __stdcall DrawAddRef(THIS)
     200ULONG __stdcall DrawAddRef(THIS This)
    144201{
    145202 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
    146203
    147 #ifdef DEBUG
    148   WriteLog("OS2IDirectDraw::AddRef %d\n", me->Referenced+1);
    149 #endif
     204  #ifdef DEBUG
     205    WriteLog("OS2IDirectDraw::AddRef %d\n", me->Referenced+1);
     206  #endif
     207
    150208  return ++me->Referenced;
    151209}
    152210//******************************************************************************
    153211//******************************************************************************
    154 ULONG __stdcall DrawRelease(THIS)
     212ULONG __stdcall DrawRelease(THIS This)
    155213{
    156214 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
    157215
    158 #ifdef DEBUG
    159   WriteLog("OS2IDirectDraw::Release %d\n", me->Referenced-1);
    160   WriteLog("OS2IDirectDraw::%X \n", me);
    161 #endif
    162   if(me->Referenced) {
    163         me->Referenced--;
    164         if(me->Referenced == 0) {
    165             delete me;
    166             return(0);
    167         }
    168         else    return me->Referenced;
    169   }
    170   else  return(0);
     216  #ifdef DEBUG
     217    WriteLog("OS2IDirectDraw::Release %d\n", me->Referenced-1);
     218    WriteLog("OS2IDirectDraw::%X \n", me);
     219  #endif
     220
     221  if(me->Referenced)
     222  {
     223
     224    me->Referenced--;
     225    if(me->Referenced == 0)
     226    {
     227      delete me;
     228      return(0);
     229    }
     230    else
     231      return me->Referenced;
     232  }
     233  else
     234    return(0);
    171235}
    172236//******************************************************************************
     
    174238HRESULT __stdcall DrawCompact(THIS)
    175239{
    176 #ifdef DEBUG
    177   WriteLog("Compact\n");
    178 #endif
    179   return(DD_OK);
    180 }
    181 //******************************************************************************
    182 //******************************************************************************
    183 HRESULT __stdcall DrawCreateClipper(THIS, DWORD, LPDIRECTDRAWCLIPPER FAR *lplpDD, IUnknown FAR * )
     240  #ifdef DEBUG
     241    WriteLog("Compact\n");
     242  #endif
     243
     244  return(DD_OK);
     245}
     246//******************************************************************************
     247//******************************************************************************
     248HRESULT __stdcall DrawCreateClipper(THIS This, DWORD, LPDIRECTDRAWCLIPPER FAR *lplpDD, IUnknown FAR * )
    184249{
    185250 OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
     
    187252 HRESULT                rc;
    188253
    189 #ifdef DEBUG
    190   WriteLog("CreateClipper\n");
    191 #endif
    192   if(newclip == NULL)   return(DDERR_OUTOFMEMORY);
     254  #ifdef DEBUG
     255    WriteLog("CreateClipper\n");
     256  #endif
     257
     258  if(newclip == NULL)
     259    return(DDERR_OUTOFMEMORY);
    193260
    194261  newclip->Vtbl.AddRef((IDirectDrawClipper *)newclip);
    195262  rc = newclip->GetLastError();
    196   if(rc != DD_OK) {
    197         *lplpDD = NULL;
    198         delete newclip;
    199   }
    200   else  *lplpDD = (IDirectDrawClipper *)newclip;
     263  if(rc != DD_OK)
     264  {
     265    *lplpDD = NULL;
     266    delete newclip;
     267  }
     268  else
     269    *lplpDD = (IDirectDrawClipper *)newclip;
    201270
    202271  return(rc);
     
    204273//******************************************************************************
    205274//******************************************************************************
    206 HRESULT __stdcall DrawCreatePalette(THIS, DWORD dwFlags,
    207                     W32_LPPALETTEENTRY lpColorTable,
    208                     LPDIRECTDRAWPALETTE FAR *lplpDD,
    209                     IUnknown FAR *pUnkOuter)
    210 {
    211  OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
    212  OS2IDirectDrawPalette *newpal;
    213  HRESULT                rc;
    214  int                    palsize = 0;
    215 
    216   if(dwFlags & (DDPCAPS_2BIT | DDPCAPS_4BIT) && !(dwFlags & DDPCAPS_8BITENTRIES)) {
    217     //only support 8 bits color palettes...
     275HRESULT __stdcall DrawCreatePalette(THIS This, DWORD dwFlags,
     276            LPPALETTEENTRY lpColorTable,
     277            LPDIRECTDRAWPALETTE FAR *lplpDD,
     278            IUnknown FAR *pUnkOuter)
     279{
     280  OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
     281  OS2IDirectDrawPalette *newpal;
     282  HRESULT                rc;
     283  int                    palsize = 0;
     284
     285  if(dwFlags & DDPCAPS_8BITENTRIES)
     286  {
     287    // We Don't support Indexed palettes...
     288
    218289    return DDERR_INVALIDPARAMS;
    219290  }
    220   if(dwFlags & DDPCAPS_2BIT)     palsize = 4;
    221   if(dwFlags & DDPCAPS_4BIT)     palsize = 16;
    222   if(dwFlags & DDPCAPS_8BIT)     palsize = 256;
    223   if(dwFlags & DDPCAPS_ALLOW256) palsize = 256;
    224   if(palsize == 0)  return DDERR_INVALIDPARAMS;
    225 
    226   dprintf(("CreatePalette with %d colors\n", palsize));
    227 
    228   newpal = new OS2IDirectDrawPalette(me, palsize, lpColorTable);
    229   if(newpal == NULL)    return(DDERR_OUTOFMEMORY);
     291
     292  if(dwFlags & DDPCAPS_2BIT)
     293    palsize = 4;
     294  if(dwFlags & DDPCAPS_4BIT)
     295    palsize = 16;
     296  if(dwFlags & DDPCAPS_8BIT)
     297    palsize = 256;
     298  if(dwFlags & DDPCAPS_ALLOW256)
     299    palsize = 256;
     300
     301  if(palsize == 0)
     302    return DDERR_INVALIDPARAMS;
     303
     304  #ifdef DEBUG
     305    WriteLog("CreatePalette with %d colors\n", palsize);
     306  #endif
     307
     308  newpal = new OS2IDirectDrawPalette(me, palsize, lpColorTable, dwFlags);
     309  if(newpal == NULL)
     310    return(DDERR_OUTOFMEMORY);
    230311
    231312  newpal->Vtbl.AddRef((IDirectDrawPalette *)newpal);
    232313  rc = newpal->GetLastError();
    233   if(rc != DD_OK) {
    234         *lplpDD = NULL;
    235         delete newpal;
    236   }
    237   else  *lplpDD = (IDirectDrawPalette *)newpal;
     314  if(rc != DD_OK)
     315  {
     316    *lplpDD = NULL;
     317    delete newpal;
     318  }
     319  else
     320    *lplpDD = (IDirectDrawPalette *)newpal;
    238321
    239322  return(rc);
     
    241324//******************************************************************************
    242325//******************************************************************************
    243 HRESULT __stdcall DrawCreateSurface(THIS, LPDDSURFACEDESC lpDDSurfaceDesc,
    244                     LPDIRECTDRAWSURFACE FAR *lplpDD,
    245                     IUnknown FAR *pUnkOuter)
     326HRESULT __stdcall DrawCreateSurface(THIS This, LPDDSURFACEDESC lpDDSurfaceDesc,
     327            LPDIRECTDRAWSURFACE FAR *lplpDD,
     328            IUnknown FAR *pUnkOuter)
    246329{
    247330 OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
     
    249332 HRESULT                rc;
    250333
     334  #ifdef DEBUG
     335    WriteLog("CreateSurface\n");
     336    WriteLog("dwSize %d\n", lpDDSurfaceDesc->dwSize);
     337    WriteLog("dwFlags %X\n", lpDDSurfaceDesc->dwFlags);
     338    WriteLog("dwHeight %d\n", lpDDSurfaceDesc->dwHeight);
     339    WriteLog("dwWidth %d\n", lpDDSurfaceDesc->dwWidth);
     340    WriteLog("lPitch %d\n", lpDDSurfaceDesc->lPitch);
     341    WriteLog("dwBackBufferCount %d\n", lpDDSurfaceDesc->dwBackBufferCount);
     342    WriteLog("dwMipMapCount %d\n", lpDDSurfaceDesc->dwMipMapCount);
     343    WriteLog("dwAlphaBitDepth %d\n", lpDDSurfaceDesc->dwAlphaBitDepth);
     344    WriteLog("ddsCaps.dwCaps %X\n", lpDDSurfaceDesc->ddsCaps.dwCaps);
     345  #endif
     346
     347  newsurf = new OS2IDirectDrawSurface(me, (LPDDSURFACEDESC2)lpDDSurfaceDesc);
     348
     349  if(newsurf == NULL)
     350    return(DDERR_OUTOFMEMORY);
     351
     352  newsurf->Vtbl.AddRef((IDirectDrawSurface *)newsurf);
     353  rc = newsurf->GetLastError();
     354  if(rc != DD_OK)
     355  {
     356    WriteLog("Error createing Surface");
     357    *lplpDD = NULL;
     358    delete newsurf;
     359  }
     360  else
     361    *lplpDD = (IDirectDrawSurface *)newsurf;
     362
     363  return(rc);
     364}
     365//******************************************************************************
     366//******************************************************************************
     367HRESULT __stdcall DrawCreateSurface4(THIS This, LPDDSURFACEDESC2 lpDDSurfaceDesc2,
     368            LPDIRECTDRAWSURFACE4 FAR *lplpDD,
     369            IUnknown FAR *pUnkOuter)
     370{
     371 OS2IDirectDraw         *me = (OS2IDirectDraw *)This;
     372 OS2IDirectDrawSurface *newsurf;
     373 HRESULT                rc;
     374
    251375#ifdef DEBUG
    252   WriteLog("CreateSurface\n");
    253   WriteLog("  dwSize %d\n", lpDDSurfaceDesc->dwSize);
    254   WriteLog("  dwFlags %X\n", lpDDSurfaceDesc->dwFlags);
    255   WriteLog("  dwHeight %d\n", lpDDSurfaceDesc->dwHeight);
    256   WriteLog("  dwWidth %d\n", lpDDSurfaceDesc->dwWidth);
    257   WriteLog("  lPitch %d\n", lpDDSurfaceDesc->lPitch);
    258   WriteLog("  lpSurface %d\n", lpDDSurfaceDesc->lpSurface);
    259   WriteLog("  dwBackBufferCount %d\n", lpDDSurfaceDesc->dwBackBufferCount);
    260   WriteLog("  dwMipMapCount %d\n", lpDDSurfaceDesc->dwMipMapCount);
    261   WriteLog("  dwAlphaBitDepth %d\n", lpDDSurfaceDesc->dwAlphaBitDepth);
    262   WriteLog("  ddsCaps.dwCaps %X\n", lpDDSurfaceDesc->ddsCaps.dwCaps);
     376  WriteLog("CreateSurface4\n");
     377  WriteLog("dwSize %d\n", lpDDSurfaceDesc2->dwSize);
     378  WriteLog("dwHeight %d\n", lpDDSurfaceDesc2->dwHeight);
     379  WriteLog("dwWidth %d\n", lpDDSurfaceDesc2->dwWidth);
     380  WriteLog("lPitch %d\n", lpDDSurfaceDesc2->lPitch);
     381  WriteLog("dwBackBufferCount %d\n", lpDDSurfaceDesc2->dwBackBufferCount);
     382  WriteLog("dwMipMapCount %d\n", lpDDSurfaceDesc2->dwMipMapCount);
     383  WriteLog("dwAlphaBitDepth %d\n", lpDDSurfaceDesc2->dwAlphaBitDepth);
     384  WriteLog("ddsCaps.dwCaps %X\n", lpDDSurfaceDesc2->ddsCaps.dwCaps);
    263385#endif
    264386
    265   newsurf = new OS2IDirectDrawSurface(me, lpDDSurfaceDesc);
    266   if(newsurf == NULL)   return(DDERR_OUTOFMEMORY);
    267 
    268   newsurf->Vtbl.AddRef((IDirectDrawSurface2 *)newsurf);
     387  newsurf = new OS2IDirectDrawSurface(me, lpDDSurfaceDesc2);
     388
     389  if(newsurf == NULL)
     390    return(DDERR_OUTOFMEMORY);
     391
     392  newsurf->Vtbl.AddRef((IDirectDrawSurface *)newsurf);
    269393  rc = newsurf->GetLastError();
    270   if(rc != DD_OK) {
    271         *lplpDD = NULL;
    272         delete newsurf;
    273   }
    274   else  *lplpDD = (IDirectDrawSurface *)newsurf;
     394  if(rc != DD_OK)
     395  {
     396    WriteLog("Error createing Surface");
     397    *lplpDD = NULL;
     398    delete newsurf;
     399  }
     400  else
     401    *lplpDD = (IDirectDrawSurface4 *)newsurf;
    275402
    276403  return(rc);
     
    280407HRESULT __stdcall DrawDuplicateSurface(THIS, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * )
    281408{
     409  #ifdef DEBUG
     410    WriteLog("DuplicateSurface\n");
     411  #endif
     412  return(DD_OK);
     413}
     414//******************************************************************************
     415//******************************************************************************
     416HRESULT __stdcall DrawDuplicateSurface4(THIS, LPDIRECTDRAWSURFACE4, LPDIRECTDRAWSURFACE4 FAR * )
     417{
     418  #ifdef DEBUG
     419    WriteLog("DuplicateSurface\n");
     420  #endif
     421
     422  return(DD_OK);
     423}
     424//******************************************************************************
     425//******************************************************************************
     426HRESULT __stdcall DrawEnumDisplayModes(THIS This, DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc,
     427                                       LPVOID lpContext, LPDDENUMMODESCALLBACK lpDDEnumModesCallback)
     428{
     429  int iMode = 0;
     430  DDSURFACEDESC DDSurfAct;
     431  BOOL fCallAgain;
     432  OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
     433
     434  #ifdef DEBUG
     435    WriteLog("EnumDisplayModes\n");
     436  #endif
     437
     438  // Check for Pointer to callback function
     439  if (NULL == lpDDEnumModesCallback)
     440  {
     441    #ifdef DEBUG
     442      WriteLog("EnumDisplayModes : Error NO EnumFunction passed in\n");
     443    #endif
     444
     445    return(DDERR_GENERIC);
     446  }
     447
     448
     449  // Setting up the surface
     450  // During enum we report resolution and bitdepth, maybe we should
     451  // also report back : Caps and Pitch
     452  memset(&DDSurfAct,0,sizeof(DDSURFACEDESC));
     453  DDSurfAct.dwSize = sizeof(DDSURFACEDESC);
     454  DDSurfAct.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT ;
     455  // Only report the bitdepth hope this is ok this way, we must set the BitMask fields
     456
     457  DDSurfAct.ddpfPixelFormat.dwSize  = sizeof (DDPIXELFORMAT);
     458  DDSurfAct.ddpfPixelFormat.dwFlags = DDPF_RGB;
     459  // Check if we use DIVE or Voodoo
     460  if(me->lpVtbl != (IDirectDraw4Vtbl *) &(me->Vtbl3D))
     461  {
     462    // DIVE modes
     463
     464    // Enumerate all modes ?
     465    if (NULL==lpDDSurfaceDesc)
     466    {
     467      // Check if we shall report 320x200 mode
     468
     469      if(dwFlags && DDEDM_STANDARDVGAMODES)
     470      {
     471        DDSurfAct.dwHeight = ModesDive[0].iYRes;
     472        DDSurfAct.dwWidth  = ModesDive[0].iXRes;
     473        DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesDive[0].iBits;
     474        if(!lpDDEnumModesCallback(&DDSurfAct,lpContext))
     475          return (DD_OK);
     476      }
     477      // Don't know the flag for Mode X so we skip reporting it
     478
     479      // Now report all our modes
     480      iMode = 2;
     481      fCallAgain = TRUE;
     482      do
     483      {
     484        // if the mode fits in the current resolution report it
     485        // Change this if we support Fullscreen later !!!
     486        if(ModesDive[iMode].iXRes < me->dCaps.ulHorizontalResolution)
     487        {
     488          DDSurfAct.dwHeight = ModesDive[iMode].iYRes;
     489          DDSurfAct.dwWidth  = ModesDive[iMode].iXRes;
     490          DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesDive[iMode].iBits;
     491          switch(ModesDive[iMode].iBits)
     492          {
     493            case 16:
     494              // VESA uses 565 encoding in 16 bit modes
     495              lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x0000F800;
     496              lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x000007E0;
     497              lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000001F;
     498              break;
     499            case 24:
     500              // VESA uses per default RGB4
     501              lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
     502              lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     503              lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x000000FF;
     504              break;
     505            default:
     506              break;
     507          }
     508          fCallAgain = lpDDEnumModesCallback(&DDSurfAct,lpContext);
     509        }
     510        iMode++;
     511      }
     512      while((ModesDive[iMode].iBits <= me->dCaps.ulDepth) &&
     513            (iMode < NUM_MODES_DIVE) && (TRUE==fCallAgain));
     514    }
     515    else
     516    {
     517      // No, so filter modes with lpDDSurfaceDesc
     518
     519      // Return Error if the program want to use other than the 3 supported values
     520      // for filtering
     521
     522      if (lpDDSurfaceDesc->dwFlags & !(DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT))
     523        return(DDERR_INVALIDPARAMS);
     524
     525      iMode = 0;
     526      if( (dwFlags && DDEDM_STANDARDVGAMODES) &&
     527         (
     528          (((lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)&&
     529            (ModesDive[iMode].iXRes==lpDDSurfaceDesc->dwWidth)
     530           )||(!(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)))&&
     531          (((lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)&&
     532            (ModesDive[iMode].iYRes==lpDDSurfaceDesc->dwHeight))||
     533           (!(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)))&&
     534          (((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
     535            (ModesDive[iMode].iBits==lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount))||
     536           (!(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT)))
     537         )
     538        )
     539      {
     540        DDSurfAct.dwHeight = ModesDive[0].iYRes;
     541        DDSurfAct.dwWidth  = ModesDive[0].iXRes;
     542        DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesDive[0].iBits;
     543        if(!lpDDEnumModesCallback(&DDSurfAct,lpContext))
     544          return (DD_OK);
     545      }
     546      // Don't know the flag for Mode X so we skip reporting it
     547
     548      // Now report all our modes
     549      iMode = 2;
     550      fCallAgain = TRUE;
     551      do
     552      {
     553        // if the mode fits in the current resolution and the filter applies report it
     554        // Change this if we support Fullscreen later !!!
     555        if( (ModesDive[iMode].iXRes < me->dCaps.ulHorizontalResolution)&&
     556           (
     557            (((lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)&&
     558              (ModesDive[iMode].iXRes==lpDDSurfaceDesc->dwWidth))||
     559             (!(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)))&&
     560            (((lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)&&
     561              (ModesDive[iMode].iYRes==lpDDSurfaceDesc->dwHeight))||
     562             (!(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)))&&
     563            (((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
     564              (ModesDive[iMode].iBits==lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount))||
     565             (!(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT)))
     566           )
     567          )
     568        {
     569          DDSurfAct.dwHeight = ModesDive[iMode].iYRes;
     570          DDSurfAct.dwWidth  = ModesDive[iMode].iXRes;
     571          DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesDive[iMode].iBits;
     572
     573          fCallAgain = lpDDEnumModesCallback(&DDSurfAct,lpContext);
     574        }
     575        iMode++;
     576      }
     577      while((ModesDive[iMode].iBits <= me->dCaps.ulDepth) &&
     578            (iMode < NUM_MODES_DIVE) && (TRUE==fCallAgain));
     579
     580    }
     581  }
     582  else
     583  {
     584
     585    // VOODOO modes
     586
     587    // Enumerate all modes ?
     588    if (NULL==lpDDSurfaceDesc)
     589    {
     590
     591      // report all our modes
     592      iMode = 0;
     593      fCallAgain = TRUE;
     594      do
     595      {
     596        DDSurfAct.dwHeight = ModesVoodoo[iMode].iYRes;
     597        DDSurfAct.dwWidth  = ModesVoodoo[iMode].iXRes;
     598        DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesVoodoo[iMode].iBits;
     599
     600        fCallAgain = lpDDEnumModesCallback(&DDSurfAct,lpContext);
     601        iMode++;
     602      }
     603      while((iMode < NUM_MODES_VOODOO) && (TRUE==fCallAgain));
     604    }
     605    else
     606    {
     607      // No, so filter modes with lpDDSurfaceDesc
     608
     609      // Return Error if the program want to use other than the 3 supported values
     610      // for filtering
     611
     612      if (lpDDSurfaceDesc->dwFlags & !(DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT))
     613        return(DDERR_INVALIDPARAMS);
     614
     615      iMode = 2;
     616      fCallAgain = TRUE;
     617      do
     618      {
     619        // if the mode fits the filter applies report it
     620        if(
     621            (((lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)&&
     622              (ModesVoodoo[iMode].iXRes==lpDDSurfaceDesc->dwWidth))||
     623             (!(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)))&&
     624            (((lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)&&
     625              (ModesVoodoo[iMode].iYRes==lpDDSurfaceDesc->dwHeight))||
     626             (!(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)))&&
     627            (((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
     628              (ModesVoodoo[iMode].iBits==lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount))||
     629             (!(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT)))
     630          )
     631        {
     632          DDSurfAct.dwHeight = ModesVoodoo[iMode].iYRes;
     633          DDSurfAct.dwWidth  = ModesVoodoo[iMode].iXRes;
     634          DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesVoodoo[iMode].iBits;
     635
     636          fCallAgain = lpDDEnumModesCallback(&DDSurfAct,lpContext);
     637        }
     638        iMode++;
     639      }
     640      while((iMode < NUM_MODES_VOODOO) && (TRUE==fCallAgain));
     641
     642    }
     643
     644  }
     645
     646  return(DD_OK);
     647}
     648//******************************************************************************
     649//******************************************************************************
     650HRESULT __stdcall DrawEnumDisplayModes4(THIS This, DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc2,
     651                                       LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpDDEnumModesCallback2)
     652{
     653  int iMode = 0;
     654  DDSURFACEDESC DDSurfAct;
     655  BOOL fCallAgain;
     656  OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
     657
     658  #ifdef DEBUG
     659    WriteLog("EnumDisplayModes4\n");
     660  #endif
     661  return(DD_OK);
     662}
     663//******************************************************************************
     664//******************************************************************************
     665HRESULT __stdcall DrawEnumSurfaces(THIS, DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK )
     666{
     667  #ifdef DEBUG
     668    WriteLog("EnumSurfaces\n");
     669  #endif
     670
     671  return(DD_OK);
     672}
     673//******************************************************************************
     674//******************************************************************************
     675HRESULT __stdcall DrawEnumSurfaces4(THIS, DWORD, LPDDSURFACEDESC2, LPVOID,LPDDENUMSURFACESCALLBACK2 )
     676{
     677  #ifdef DEBUG
     678    WriteLog("EnumSurfaces4\n");
     679  #endif
     680
     681  return(DD_OK);
     682}
     683//******************************************************************************
     684//******************************************************************************
     685HRESULT __stdcall DrawFlipToGDISurface(THIS)
     686{
     687  #ifdef DEBUG
     688    WriteLog("FlipToGDISurface\n");
     689  #endif
     690
     691  return(DD_OK);
     692}
     693//******************************************************************************
     694//******************************************************************************
     695HRESULT __stdcall DrawGetCaps(THIS, LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps)
     696{
     697  #ifdef DEBUG
     698    WriteLog("GetCaps\n");
     699  #endif
     700
     701  if( (NULL==lpDDDriverCaps) && (NULL==lpDDHELCaps) )
     702    return(DDERR_INVALIDPARAMS);
     703
     704  if(NULL!=lpDDDriverCaps)
     705  {
     706    // Caller want Driver Caps
     707
     708    if(sizeof(DDCAPS)!=lpDDDriverCaps->dwSize)
     709      return(DDERR_INVALIDPARAMS);
     710
     711    // Clear structure so we only have to set the supported flags
     712    memset(lpDDDriverCaps,0,sizeof(DDCAPS));
     713
     714    // Reset the size
     715    lpDDDriverCaps->dwSize = sizeof(DDCAPS);
     716
     717    // Now report the CAPs back which we support
     718   lpDDDriverCaps->dwCaps = DDCAPS_BLT |              // We do blitting
     719                            DDCAPS_BLTCOLORFILL |     // We do colorfills
     720                            DDCAPS_COLORKEY |         // We support Colorkeying
     721                            DDCAPS_COLORKEYHWASSIST | // But we (may) use the CPU
     722                            DDCAPS_GDI |              // Maybe check if we are on Voodoo ?
     723                            DDCAPS_PALETTEVSYNC;      // Got VSync
     724
     725    lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED |         // Who cares so say yes
     726                              DDCAPS2_CANRENDERWINDOWED | // Better check for Voodoo ?!
     727                              DDCAPS2_COPYFOURCC |        // yepp memcpy will do this
     728                              DDCAPS2_NONLOCALVIDMEM |    // All surfaces are in memory
     729                              DDCAPS2_WIDESURFACES;       // Any size you want!
     730
     731    lpDDDriverCaps->dwCKeyCaps = DDCKEYCAPS_SRCBLT;      // Only source transparent blitting
     732
     733//    lpDDDriverCaps->dwFXCaps = DDFXCAPS_BLTMIRRORUPDOWN; // DIVE supports this, do we also ?
     734                                                         // Maybe later add stretching support?
     735
     736    lpDDDriverCaps->dwPalCaps = DDPCAPS_8BIT |          // Only 8 Bits pals
     737                                DDPCAPS_ALLOW256 |      // But all 256 colors
     738                                DDPCAPS_VSYNC  |        // Vsync yet
     739                                DDPCAPS_PRIMARYSURFACE; //
     740    lpDDDriverCaps->dwVidMemTotal = 2048*1024;           // total video memory
     741    lpDDDriverCaps->dwVidMemFree  = 2048*1024;            // total free video memory
     742    lpDDDriverCaps->dwNumFourCCCodes;        // number of supported FOURCC codes
     743    lpDDDriverCaps->dwRops[DD_ROP_SPACE];    // supported raster ops
     744    lpDDDriverCaps->dwSVBCaps = DDCAPS_BLT |              // We do blitting
     745                                DDCAPS_BLTCOLORFILL |     // We do colorfills
     746                                DDCAPS_COLORKEY |         // We support Colorkeying
     747                                DDCAPS_COLORKEYHWASSIST;
     748    lpDDDriverCaps->dwSVBCKeyCaps = DDCKEYCAPS_SRCBLT;      // Only source transparent blitting
     749    lpDDDriverCaps->dwSVBFXCaps;             //  .
     750    lpDDDriverCaps->dwSVBRops[DD_ROP_SPACE]; //  .
     751    lpDDDriverCaps->dwVSBCaps = DDCAPS_BLT |              // We do blitting
     752                                DDCAPS_BLTCOLORFILL |     // We do colorfills
     753                                DDCAPS_COLORKEY |         // We support Colorkeying
     754                                DDCAPS_COLORKEYHWASSIST;
     755    lpDDDriverCaps->dwVSBCKeyCaps = DDCKEYCAPS_SRCBLT;      // Only source transparent blitting
     756    lpDDDriverCaps->dwVSBFXCaps;             //  .
     757    lpDDDriverCaps->dwVSBRops[DD_ROP_SPACE]; //  .
     758    lpDDDriverCaps->dwSSBCaps = DDCAPS_BLT |              // We do blitting
     759                                DDCAPS_BLTCOLORFILL |     // We do colorfills
     760                                DDCAPS_COLORKEY |         // We support Colorkeying
     761                                DDCAPS_COLORKEYHWASSIST;
     762    lpDDDriverCaps->dwSSBCKeyCaps = DDCKEYCAPS_SRCBLT;      // Only source transparent blitting
     763    lpDDDriverCaps->dwSSBFXCaps;            //  .
     764    lpDDDriverCaps->dwSSBRops[DD_ROP_SPACE]; //  .
     765    lpDDDriverCaps->dwSVBCaps2 = DDCAPS2_CANRENDERWINDOWED | // Better check for Voodoo ?!
     766                                 DDCAPS2_COPYFOURCC |        // yepp memcpy will do this
     767                                 DDCAPS2_WIDESURFACES;       // Any size you want!
     768    lpDDDriverCaps->dwNLVBCaps = DDCAPS_BLT |              // We do blitting
     769                                 DDCAPS_BLTCOLORFILL |     // We do colorfills
     770                                 DDCAPS_COLORKEY |         // We support Colorkeying
     771                                 DDCAPS_COLORKEYHWASSIST;
     772    lpDDDriverCaps->dwNLVBCaps2 = DDCAPS2_CANRENDERWINDOWED | // Better check for Voodoo ?!
     773                                  DDCAPS2_COPYFOURCC |        // yepp memcpy will do this
     774                                  DDCAPS2_WIDESURFACES;       // Any size you want!
     775    lpDDDriverCaps->dwNLVBCKeyCaps = DDCKEYCAPS_SRCBLT;      // Only source transparent blitting
     776    lpDDDriverCaps->dwNLVBFXCaps;            //  .
     777    lpDDDriverCaps->dwNLVBRops[DD_ROP_SPACE];//  .
     778    DDSCAPS2 ddsCaps;                 // general surface caps
     779
     780  }
     781
     782  if(NULL!=lpDDHELCaps)
     783  {
     784    // Caler wants HEL Caps
     785    if(sizeof(DDCAPS)!=lpDDHELCaps->dwSize)
     786      return(DDERR_INVALIDPARAMS);
     787
     788  }
     789
     790  return(DD_OK);
     791}
     792//******************************************************************************
     793//******************************************************************************
     794HRESULT __stdcall DrawGetDisplayMode(THIS This, LPDDSURFACEDESC lpDDSurfaceDesc)
     795{
     796  OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
     797  #ifdef DEBUG
     798    WriteLog("GetDisplayMode\n");
     799  #endif
     800
     801  // Check Parameter
     802  if(NULL==lpDDSurfaceDesc)
     803    return(DDERR_INVALIDPARAMS);
     804
     805  if(sizeof(DDSURFACEDESC)!=lpDDSurfaceDesc->dwSize)
     806    return(DDERR_INVALIDPARAMS);
     807
     808  // We report back the DIVE caps. maybe we should set up a local DDSURFACEDESC
     809  // for the object so we can change the values when we switch modes (or say so)
     810  // as a program may use this function to check the values after a mode change
     811  // An other reason to to so is Voodoo supports maybe more functions
     812
     813  // Tell what we report
     814  lpDDSurfaceDesc->dwFlags  = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
     815  lpDDSurfaceDesc->dwHeight = me->dCaps.ulHorizontalResolution;
     816  lpDDSurfaceDesc->dwWidth  = me->dCaps.ulVerticalResolution;
     817  // Set the PixelFormat
     818  lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
     819
     820  lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC = me->dCaps.fccColorEncoding;
     821  lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = me->dCaps.ulDepth;
     822  lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask = 0; // No Alpha support
     823  switch(me->dCaps.ulDepth)
     824  {
     825    case 4:
     826      // Assume that no one will run OS/2 PM with less then 16 colors and try
     827      // to start a DirectX program ;)
     828      lpDDSurfaceDesc->ddpfPixelFormat.dwFlags =  DDPF_RGB | DDPF_PALETTEINDEXED4;
     829      lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0;
     830      lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0;
     831      lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0;
     832      break;
     833    case 8:
     834      lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8 |
     835                                                 DDPF_FOURCC;
     836      lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0;
     837      lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0;
     838      lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0;
     839      break;
     840    case 15:
     841    case 16:
     842      lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = 16; // No sure about 15Bit modes
     843      lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
     844      if (FOURCC_R555 == me->dCaps.fccColorEncoding)
     845      {
     846        lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x00007C00;
     847        lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x000003E0;
     848        lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000001F;
     849      }
     850      else
     851      {
     852        if(FOURCC_R565 == me->dCaps.fccColorEncoding)
     853        {
     854          lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x0000F800;
     855          lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x000007E0;
     856          lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000001F;
     857        }
     858        else
     859        {
     860          // R664
     861          lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x0000F800;
     862          lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x000003F0;
     863          lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000000F;
     864        }
     865      }
     866      break;
     867    case 24:
     868      lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
     869      if(FOURCC_RGB3 == me->dCaps.fccColorEncoding)
     870      {
     871        lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
     872        lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     873        lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x000000FF;
     874      }
     875      else
     876      {
     877        // BGR3
     878        lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x000000FF;
     879        lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     880        lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x00FF0000;
     881      }
     882      break;
     883    case 32:
     884      lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
     885      if(FOURCC_RGB4 == me->dCaps.fccColorEncoding)
     886      {
     887        lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
     888        lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     889        lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x000000FF;
     890      }
     891      else
     892      {
     893        // BGR4
     894        lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x000000FF;
     895        lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     896        lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x00FF0000;
     897      }
     898      break;
     899    default:
     900      #ifdef DEBUG
     901        WriteLog("Unsupported mode\n");
     902      #endif
     903      return(DDERR_UNSUPPORTEDMODE);
     904  }
     905
     906  return(DD_OK);
     907}
     908//******************************************************************************
     909//******************************************************************************
     910HRESULT __stdcall DrawGetDisplayMode4(THIS This, LPDDSURFACEDESC2 lpDDSurfaceDesc2)
     911{
     912  OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
     913  #ifdef DEBUG
     914    WriteLog("GetDisplayMode\n");
     915  #endif
     916
     917  // Check Parameter
     918  if(NULL==lpDDSurfaceDesc2)
     919    return(DDERR_INVALIDPARAMS);
     920
     921  if(sizeof(DDSURFACEDESC)!=lpDDSurfaceDesc2->dwSize)
     922    return(DDERR_INVALIDPARAMS);
     923
     924  // We report back the DIVE caps. maybe we should set up a local DDSURFACEDESC
     925  // for the object so we can change the values when we switch modes (or say so)
     926  // as a program may use this function to check the values after a mode change
     927  // An other reason to to so is Voodoo supports maybe more functions
     928
     929  // Tell what we report
     930  lpDDSurfaceDesc2->dwFlags  = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
     931  lpDDSurfaceDesc2->dwHeight = me->dCaps.ulHorizontalResolution;
     932  lpDDSurfaceDesc2->dwWidth  = me->dCaps.ulVerticalResolution;
     933  // Set the PixelFormat
     934  lpDDSurfaceDesc2->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
     935
     936  lpDDSurfaceDesc2->ddpfPixelFormat.dwFourCC = me->dCaps.fccColorEncoding;
     937  lpDDSurfaceDesc2->ddpfPixelFormat.dwRGBBitCount = me->dCaps.ulDepth;
     938  lpDDSurfaceDesc2->ddpfPixelFormat.dwRGBAlphaBitMask = 0; // No Alpha support
     939  switch(me->dCaps.ulDepth)
     940  {
     941    case 4:
     942      // Assume that no one will run OS/2 PM with less then 16 colors and try
     943      // to start a DirectX program ;)
     944      lpDDSurfaceDesc2->ddpfPixelFormat.dwFlags =  DDPF_RGB | DDPF_PALETTEINDEXED4;
     945      lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0;
     946      lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0;
     947      lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0;
     948      break;
     949    case 8:
     950      lpDDSurfaceDesc2->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8 |
     951                                                 DDPF_FOURCC;
     952      lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0;
     953      lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0;
     954      lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0;
     955      break;
     956    case 15:
     957    case 16:
     958      lpDDSurfaceDesc2->ddpfPixelFormat.dwRGBBitCount = 16; // No sure about 15Bit modes
     959      lpDDSurfaceDesc2->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
     960      if (FOURCC_R555 == me->dCaps.ulDepth)
     961      {
     962        lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x00007C00;
     963        lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x000003E0;
     964        lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x0000001F;
     965      }
     966      else
     967      {
     968        if(FOURCC_R565 == me->dCaps.fccColorEncoding)
     969        {
     970          lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x0000F800;
     971          lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x000007E0;
     972          lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x0000001F;
     973        }
     974        else
     975        {
     976          // R664
     977          lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x0000F800;
     978          lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x000003F0;
     979          lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x0000000F;
     980        }
     981      }
     982      break;
     983    case 24:
     984      lpDDSurfaceDesc2->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
     985      if(FOURCC_RGB3 == me->dCaps.fccColorEncoding)
     986      {
     987        lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
     988        lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     989        lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x000000FF;
     990      }
     991      else
     992      {
     993        // BGR3
     994        lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x000000FF;
     995        lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     996        lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x00FF0000;
     997      }
     998      break;
     999    case 32:
     1000      lpDDSurfaceDesc2->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
     1001      if(FOURCC_RGB4 == me->dCaps.fccColorEncoding)
     1002      {
     1003        lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
     1004        lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     1005        lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x000000FF;
     1006      }
     1007      else
     1008      {
     1009        // BGR4
     1010        lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x000000FF;
     1011        lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
     1012        lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x00FF0000;
     1013      }
     1014      break;
     1015    default:
     1016      #ifdef DEBUG
     1017        WriteLog("Unsupported mode\n");
     1018      #endif
     1019      return(DDERR_UNSUPPORTEDMODE);
     1020  }
     1021
     1022  return(DD_OK);
     1023}
     1024//******************************************************************************
     1025//******************************************************************************
     1026HRESULT __stdcall DrawGetFourCCCodes(THIS, LPDWORD lpNumCodes, LPDWORD lpCodes)
     1027{
     1028  DWORD dwFCC[3] = {FOURCC_LUT8,FOURCC_R565,FOURCC_RGB3};
     1029  #ifdef DEBUG
     1030    WriteLog("GetFourCCCodes\n");
     1031  #endif
     1032
     1033  if(NULL==lpNumCodes)
     1034    return(DDERR_INVALIDPARAMS);
     1035
     1036  if(NULL==lpCodes)
     1037  {
     1038    *lpNumCodes = 3; // LUT8, R565, RGB3 are the FourCC we support for now
     1039  }
     1040  else
     1041  {
     1042    for(int i=0;(i<3)&&(i<*lpNumCodes);i++)
     1043    {
     1044      *lpCodes = dwFCC[i];
     1045      lpCodes +=4;
     1046    }
     1047    if(*lpNumCodes < 3)
     1048      *lpNumCodes = 3;
     1049  }
     1050  return(DD_OK);
     1051}
     1052//******************************************************************************
     1053//******************************************************************************
     1054HRESULT __stdcall DrawGetGDISurface(THIS, LPDIRECTDRAWSURFACE FAR *)
     1055{
     1056  #ifdef DEBUG
     1057    WriteLog("GetGDISurface\n");
     1058  #endif
     1059
     1060  return(DD_OK);
     1061}
     1062//******************************************************************************
     1063//******************************************************************************
     1064HRESULT __stdcall DrawGetGDISurface4(THIS, LPDIRECTDRAWSURFACE4 FAR *)
     1065{
     1066  #ifdef DEBUG
     1067    WriteLog("GetGDISurface\n");
     1068  #endif
     1069
     1070  return(DD_OK);
     1071}
     1072//******************************************************************************
     1073//******************************************************************************
     1074HRESULT __stdcall DrawGetMonitorFrequency(THIS This, LPDWORD lpdwFreq)
     1075{
     1076  ULONG ulTime1, ulTime2;
     1077  DWORD dwFlags = DDWAITVB_BLOCKBEGIN;
     1078  #ifdef DEBUG
     1079    WriteLog("GetMonitorFrequency\n");
     1080  #endif
     1081  if(NULL==lpdwFreq)
     1082    return(DDERR_INVALIDPARAMS);
     1083
     1084  if(DD_OK==DrawWaitForVerticalBlank(This, dwFlags, 0))
     1085  {
     1086    ulTime1 = GetTickCount();
     1087    // Timer has an accuracy of 4 ms so call it al least 4 times
     1088    DrawWaitForVerticalBlank(This, dwFlags, 0);
     1089    DrawWaitForVerticalBlank(This, dwFlags, 0);
     1090    DrawWaitForVerticalBlank(This, dwFlags, 0);
     1091    DrawWaitForVerticalBlank(This, dwFlags, 0);
     1092    ulTime2 = GetTickCount();
     1093    ulTime2 -= ulTime1;
     1094    if(ulTime2) // paranoid check to avoid DIV0
     1095      *lpdwFreq = 4000 / ulTime2;
     1096    else
     1097      *lpdwFreq = 70;
     1098  }
     1099  else
     1100  {
     1101    // Assume 70 Hz maybe better return DDERR_UNSUPPORTED if this function isn't mandatory
     1102    *lpdwFreq = 70;
     1103  }
     1104  return(DD_OK);
     1105}
     1106//******************************************************************************
     1107//******************************************************************************
     1108HRESULT __stdcall DrawGetScanLine(THIS, LPDWORD lpdwLine)
     1109{
     1110  BOOL bVertBlank;
     1111  #ifdef DEBUG
     1112    WriteLog("GetScanLine\n");
     1113  #endif
     1114  // ToDO find a way to get this position, so for now simply return DDERR_UNSUPPORTED
     1115  // as we indicated in DDCAPS we don't support this.
     1116
     1117  return(DDERR_UNSUPPORTED);
     1118
     1119  //the following code could be used if we implement this
     1120  /*
     1121  if(NULL==lpdwLine)
     1122    return(DDERR_INVALIDPARAMS);
     1123  DrawGetVertcalBlackStatus(This,&bVertBlank);
     1124  if(bVertBlank)
     1125    return (DDERR_VERTICALBLANKINPROGRESS);
     1126  *lpdwLine = GetLine(); // GetLine would be the function which gets us the line
     1127  return(DD_OK);
     1128  */
     1129}
     1130//******************************************************************************
     1131//******************************************************************************
     1132HRESULT __stdcall DrawGetVerticalBlankStatus(THIS , LPBOOL lpbIsInVB)
     1133{
     1134  #ifdef DEBUG
     1135    WriteLog("GetVerticalBlankStatus\n");
     1136  #endif
     1137  if(NULL==lpbIsInVB)
     1138    return(DDERR_INVALIDPARAMS);
     1139  if(0==io_init1())  // try to get IOPL for the thread
     1140  {
     1141    *lpbIsInVB = (c_inb1(0x3da)&0x08)!=0;
     1142    io_exit1(); // reset IOPL
     1143    return(DD_OK);
     1144  }
     1145
     1146  return(DDERR_UNSUPPORTED);
     1147}
     1148//******************************************************************************
     1149//******************************************************************************
     1150HRESULT __stdcall DrawInitialize(THIS, GUID FAR *)
     1151{
     1152  #ifdef DEBUG
     1153    WriteLog("Initialize\n");
     1154  #endif
     1155
     1156  return(DD_OK);
     1157}
     1158//******************************************************************************
     1159//******************************************************************************
     1160HRESULT __stdcall DrawRestoreDisplayMode(THIS)
     1161{
     1162  #ifdef DEBUG
     1163    WriteLog("RestoreDisplayMod\n");
     1164  #endif
     1165
     1166  return(DD_OK);
     1167}
     1168//******************************************************************************
     1169//******************************************************************************
     1170HRESULT __stdcall DrawSetCooperativeLevel(THIS This, HWND hwndClient, DWORD dwFlags)
     1171{
     1172 OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
     1173
     1174  #ifdef DEBUG
     1175    WriteLog("SetCooperativeLevel: hwnd %X, Flags %X\n", hwndClient, dwFlags);
     1176  #endif
     1177
     1178  me->hwndClient = hwndClient;
     1179  #if 0
     1180  OS2DDSubclassWindow(hwndClient);
     1181  #endif
     1182  return(DD_OK);
     1183}
     1184//******************************************************************************
     1185//Backwards compatibility, what's that??
     1186//******************************************************************************
     1187HRESULT __stdcall DrawSetDisplayMode2(THIS This, DWORD dwWidth, DWORD dwHeight,
     1188              DWORD dwBPP, DWORD dwRefreshRate,
     1189              DWORD dwFlags)
     1190{
     1191 OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
     1192
    2821193#ifdef DEBUG
    283   WriteLog("DuplicateSurface\n");
     1194  WriteLog("SetDisplayMode2 to %dx%d with %d bits colors\n", dwWidth, dwHeight, dwBPP);
    2841195#endif
    285   return(DD_OK);
    286 }
    287 //******************************************************************************
    288 //******************************************************************************
    289 HRESULT __stdcall DrawEnumDisplayModes(THIS, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK )
    290 {
    291 #ifdef DEBUG
    292   WriteLog("EnumDisplayModes\n");
    293 #endif
    294   return(DD_OK);
    295 }
    296 //******************************************************************************
    297 //******************************************************************************
    298 HRESULT __stdcall DrawEnumSurfaces(THIS, DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK )
    299 {
    300 #ifdef DEBUG
    301   WriteLog("EnumSurfaces\n");
    302 #endif
    303   return(DD_OK);
    304 }
    305 //******************************************************************************
    306 //******************************************************************************
    307 HRESULT __stdcall DrawFlipToGDISurface(THIS)
    308 {
    309 #ifdef DEBUG
    310   WriteLog("FlipToGDISurface\n");
    311 #endif
    312   return(DD_OK);
    313 }
    314 //******************************************************************************
    315 //******************************************************************************
    316 HRESULT __stdcall DrawGetCaps(THIS, LPDDCAPS, LPDDCAPS)
    317 {
    318 #ifdef DEBUG
    319   WriteLog("GetCaps\n");
    320 #endif
    321   return(DD_OK);
    322 }
    323 //******************************************************************************
    324 //******************************************************************************
    325 HRESULT __stdcall DrawGetDisplayMode(THIS, LPDDSURFACEDESC)
    326 {
    327 #ifdef DEBUG
    328   WriteLog("GetDisplayMode\n");
    329 #endif
    330   return(DD_OK);
    331 }
    332 //******************************************************************************
    333 //******************************************************************************
    334 HRESULT __stdcall DrawGetFourCCCodes(THIS, LPDWORD, LPDWORD)
    335 {
    336 #ifdef DEBUG
    337   WriteLog("GetFourCCCodes\n");
    338 #endif
    339   return(DD_OK);
    340 }
    341 //******************************************************************************
    342 //******************************************************************************
    343 HRESULT __stdcall DrawGetGDISurface(THIS, LPDIRECTDRAWSURFACE FAR *)
    344 {
    345 #ifdef DEBUG
    346   WriteLog("GetGDISurface\n");
    347 #endif
    348   return(DD_OK);
    349 }
    350 //******************************************************************************
    351 //******************************************************************************
    352 HRESULT __stdcall DrawGetMonitorFrequency(THIS, LPDWORD)
    353 {
    354 #ifdef DEBUG
    355   WriteLog("GetMonitorFrequency\n");
    356 #endif
    357   return(DD_OK);
    358 }
    359 //******************************************************************************
    360 //******************************************************************************
    361 HRESULT __stdcall DrawGetScanLine(THIS, LPDWORD)
    362 {
    363 #ifdef DEBUG
    364   WriteLog("GetScanLine\n");
    365 #endif
    366   return(DD_OK);
    367 }
    368 //******************************************************************************
    369 //******************************************************************************
    370 HRESULT __stdcall DrawGetVerticalBlankStatus(THIS, LPBOOL)
    371 {
    372 #ifdef DEBUG
    373   WriteLog("GetVerticalBlankStatus\n");
    374 #endif
    375   return(DD_OK);
    376 }
    377 //******************************************************************************
    378 //******************************************************************************
    379 HRESULT __stdcall DrawInitialize(THIS, GUID FAR *)
    380 {
    381 #ifdef DEBUG
    382   WriteLog("Initialize\n");
    383 #endif
    384   return(DD_OK);
    385 }
    386 //******************************************************************************
    387 //******************************************************************************
    388 HRESULT __stdcall DrawRestoreDisplayMode(THIS)
    389 {
    390 #ifdef DEBUG
    391   WriteLog("RestoreDisplayMod\n");
    392 #endif
    393   return(DD_OK);
    394 }
    395 //******************************************************************************
    396 //******************************************************************************
    397 HRESULT __stdcall DrawSetCooperativeLevel(THIS, W32_HWND hwndClient, DWORD dwFlags)
    398 {
    399  OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
    400 
    401   dprintf(("SetCooperativeLevel: hwnd %X, Flags %X\n", hwndClient, dwFlags));
    402   if(dwFlags & DDSCL_FULLSCREEN) {
    403         me->fFullScreen = TRUE;
    404   }
    405   else  me->fFullScreen = FALSE;
    406 
    407   me->hwndClient = hwndClient;
    408   OS2MaximizeWindow((HWND)hwndClient);
    409   return(DD_OK);
    410 }
    411 //******************************************************************************
    412 //Backwards compatibility, what's that??
    413 //******************************************************************************
    414 HRESULT __stdcall DrawSetDisplayMode2(THIS, DWORD dwWidth, DWORD dwHeight,
    415                       DWORD dwBPP, DWORD dwRefreshRate,
    416                       DWORD dwFlags)
    417 {
    418  OS2IDirectDraw *me = (OS2IDirectDraw *)This;
    419 
    420   dprintf(("SetDisplayMode2 to %dx%d with %d bits colors\n", dwWidth, dwHeight, dwBPP));
    4211196  me->screenwidth  = dwWidth;
    4221197  me->screenheight = dwHeight;
    4231198  me->screenbpp    = dwBPP;
    424   return(DD_OK);
    425 }
    426 //******************************************************************************
    427 //******************************************************************************
    428 HRESULT __stdcall DrawSetDisplayMode(THIS, DWORD dwWidth, DWORD dwHeight,
    429                      DWORD dwBPP)
     1199//  _interrupt(3);
     1200  return(DD_OK);
     1201}
     1202//******************************************************************************
     1203//******************************************************************************
     1204HRESULT __stdcall DrawSetDisplayMode(THIS This, DWORD dwWidth, DWORD dwHeight,
     1205             DWORD dwBPP)
    4301206{
    4311207 OS2IDirectDraw        *me = (OS2IDirectDraw *)This;
    4321208
    433 //  _interrupt(3);
    434   dprintf(("SetDisplayMode to %dx%d with %d bits colors\n", dwWidth, dwHeight, dwBPP));
     1209#ifdef DEBUG
     1210  WriteLog("SetDisplayMode to %dx%d with %d bits colors\n", dwWidth, dwHeight, dwBPP);
     1211#endif
    4351212  me->screenwidth  = dwWidth;
    4361213  me->screenheight = dwHeight;
    4371214  me->screenbpp    = dwBPP;
    438   return(DD_OK);
    439 }
    440 //******************************************************************************
    441 //******************************************************************************
    442 HRESULT __stdcall DrawWaitForVerticalBlank(THIS, DWORD, W32_HANDLE)
    443 {
    444   dprintf(("WaitForVerticalBlank\n"));
    445   return(DD_OK);
    446 }
    447 //******************************************************************************
    448 /*** Added in the v2 interface ***/
    449 //******************************************************************************
    450 HRESULT __stdcall DrawGetAvailableVidMem(THIS, LPDDSCAPS, LPDWORD, LPDWORD)
    451 {
    452   dprintf(("GetAvailableVidMem\n"));
    453   return(DD_OK);
    454 }
    455 //******************************************************************************
    456 //******************************************************************************
     1215//  _interrupt(3);
     1216  return(DD_OK);
     1217}
     1218//******************************************************************************
     1219//******************************************************************************
     1220HRESULT __stdcall DrawWaitForVerticalBlank(THIS, DWORD dwFlags, HANDLE hEvent)
     1221{
     1222  HRESULT rc;
     1223  #ifdef DEBUG
     1224    WriteLog("WaitForVerticalBlank\n");
     1225  #endif
     1226
     1227  if(DDWAITVB_BLOCKBEGINEVENT == dwFlags) // This parameter isn't support in DX
     1228    return (DDERR_UNSUPPORTED);
     1229
     1230  if(io_init1())  // try to get IOPL for the thread
     1231    return (DDERR_UNSUPPORTED);  // we failed so return error that we don't support this
     1232
     1233  // AT this point we should have IOPL so lets use it!
     1234
     1235  rc = DDERR_INVALIDPARAMS; // set returnvalue to fail
     1236
     1237  if(DDWAITVB_BLOCKBEGIN == dwFlags)
     1238  {
     1239    while ((c_inb1(0x3da)&0x08)!=0); // Wait for end of vert. retrace if one is running
     1240    while ((c_inb1(0x3da)&0x08)==0); // Wait for new start of retrace
     1241    rc = DD_OK;
     1242  }
     1243
     1244  if(DDWAITVB_BLOCKEND == dwFlags)
     1245  {
     1246    rc = DD_OK;
     1247    if((c_inb1(0x3da)&0x08)!=0)        // Are we in a vert. retrace
     1248    {
     1249      while ((c_inb1(0x3da)&0x08)!=0); // Wait for end of retrace
     1250    }
     1251    else
     1252    {
     1253      while ((c_inb1(0x3da)&0x08)==0); // Wait for new start of retrace
     1254      while ((c_inb1(0x3da)&0x08)!=0); // Wait for end of vert. retrace
     1255    }
     1256
     1257  }
     1258
     1259  io_exit1();
     1260
     1261  return (rc);
     1262
     1263}
     1264//******************************************************************************
     1265//*** Added in the v2 interface ***
     1266//******************************************************************************
     1267HRESULT __stdcall DrawGetAvailableVidMem(THIS, LPDDSCAPS lpDDSCaps,
     1268                                         LPDWORD lpdwTotal, LPDWORD lpdwFree)
     1269{
     1270  #ifdef DEBUG
     1271    WriteLog("GetAvailableVidMem\n");
     1272  #endif
     1273
     1274  // Check parameters
     1275  if(NULL==lpDDSCaps)
     1276    return(DDERR_INVALIDPARAMS);
     1277
     1278  if((NULL==lpdwTotal)&&(NULL==lpdwFree))
     1279    return(DDERR_INVALIDPARAMS);
     1280
     1281  if(NULL!=lpdwTotal)
     1282    *lpdwTotal = 2048 *1024;
     1283
     1284  if(NULL!=lpdwFree)
     1285    *lpdwFree = 2048 *1024;
     1286
     1287  return(DD_OK);
     1288}
     1289//******************************************************************************
     1290//
     1291//******************************************************************************
     1292HRESULT __stdcall DrawGetAvailableVidMem4(THIS, LPDDSCAPS2 lpDDSCaps2,
     1293                                         LPDWORD lpdwTotal, LPDWORD lpdwFree)
     1294{
     1295  #ifdef DEBUG
     1296    WriteLog("GetAvailableVidMem\n");
     1297  #endif
     1298
     1299  // Check parameters
     1300  if(NULL==lpDDSCaps2)
     1301    return(DDERR_INVALIDPARAMS);
     1302
     1303  if((NULL==lpdwTotal)&&(NULL==lpdwFree))
     1304    return(DDERR_INVALIDPARAMS);
     1305
     1306  if(NULL!=lpdwTotal)
     1307    *lpdwTotal = 2048 *1024;
     1308
     1309  if(NULL!=lpdwFree)
     1310    *lpdwFree = 2048 *1024;
     1311
     1312  return(DD_OK);
     1313}
     1314//******************************************************************************
     1315//*** Added in the v4 interface ***
     1316//******************************************************************************
     1317HRESULT __stdcall DrawGetSurfaceFromDC(THIS, HDC hdc, LPDIRECTDRAWSURFACE4 *)
     1318{
     1319  #ifdef DEBUG
     1320    WriteLog("GetSurfaceFromDC Unimplemented Stub\n");
     1321  #endif
     1322
     1323  return(DD_OK);
     1324}
     1325//******************************************************************************
     1326//******************************************************************************
     1327HRESULT __stdcall DrawRestoreAllSurfaces(THIS)
     1328{
     1329  #ifdef DEBUG
     1330    WriteLog("RestoreAllSurfaces\n");
     1331  #endif
     1332
     1333  return(DD_OK);
     1334}
     1335//******************************************************************************
     1336//******************************************************************************
     1337HRESULT __stdcall DrawTestCooperativeLevel(THIS)
     1338{
     1339  #ifdef DEBUG
     1340    WriteLog("TestCooperativeLevel\n");
     1341  #endif
     1342
     1343  return(DD_OK);
     1344}
     1345//******************************************************************************
     1346//******************************************************************************
     1347HRESULT __stdcall DrawGetDeviceIdentifier( THIS, LPDDDEVICEIDENTIFIER lpdddi,
     1348                                           DWORD dwFlags)
     1349{
     1350  #ifdef DEBUG
     1351    WriteLog("GetDeviceIdentifier Flags = %d\n",dwFlags);
     1352  #endif
     1353  if(NULL==lpdddi)
     1354    return DDERR_INVALIDPARAMS;
     1355
     1356  memset( lpdddi,
     1357          0,
     1358          sizeof(DDDEVICEIDENTIFIER));
     1359  // ToDo: Cretae a GUID and put some better data inside
     1360  strcpy( lpdddi->szDriver,
     1361          "OS/2 DIVE Driver");
     1362  strcpy( lpdddi->szDescription,
     1363          "ODIN DD Emulation Driver");
     1364  return(DD_OK);
     1365}
     1366//******************************************************************************
     1367//******************************************************************************
     1368VOID OS2IDirectDraw::SwitchDisplay(HWND hwnd)
     1369{
     1370  DWORD dwVType, dwVSize;
     1371  HKEY hkDirectDraw2;
     1372
     1373  if (bScale)
     1374  {
     1375    if (ERROR_SUCCESS==RegOpenKeyA(HKEY_LOCAL_MACHINE,KEY_DIRECT2DRAW,&hkDirectDraw2))
     1376    {
     1377      dwVSize = 4;
     1378      dwVType = REG_DWORD;
     1379      if (ERROR_SUCCESS!=RegQueryValueExA( hkDirectDraw2, "Fullscreen", NULL, &dwVType,
     1380                                         (LPBYTE)&bScale, &dwVSize))
     1381        bScale = FALSE;
     1382    }
     1383    else
     1384      bScale = FALSE;
     1385  }
     1386}
     1387//******************************************************************************
     1388//******************************************************************************
     1389
  • trunk/src/ddraw/OS2PALETTE.CPP

    r97 r210  
    1 /* $Id: OS2PALETTE.CPP,v 1.3 1999-06-10 17:10:56 phaller Exp $ */
    2 
    3 /*
    4  * DirectDraw Palette 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 
    12 /*@Const************************************************************************
    13 *   Defined Constants                                                          *
    14 *******************************************************************************/
    15 #define INCL_GUID
    16 #define WIN32SDK_NOPOSTWRAPPER
    17 
    18 /*@Header***********************************************************************
    19 *   Header Files                                                               *
    20 *******************************************************************************/
    21 #include <os2win.h>
    22 #include <dive.h>
    23 
    241#include <stdio.h>
    252#include <stdlib.h>
    263#include <string.h>
    274#include <memory.h>
    28 
    29 #include "no.h"
    30 #include <w_windows.h>
    31 #include <ddraw.h>
    32 #include <d3d.h>
    33 #include <Win32SDKPostWrapper.h>
    34 
    35 #include "os2ddraw.h"
     5#define INITGUID
    366#include "os2palette.h"
     7#define _OS2WIN_H
     8#define FAR
    379#include "misc.h"
    3810#include "os2palset.h"
    39 
    40 extern DIVE_CAPS dcaps;
    41 
    42 //******************************************************************************
    43 //******************************************************************************
    44 OS2IDirectDrawPalette::OS2IDirectDrawPalette(OS2IDirectDraw *lpDirectDraw,
    45                          int palsize,
    46                          W32_LPPALETTEENTRY lpColorTable) :
    47                          Referenced(0), os2pal(NULL),
    48                          lastError(DD_OK), lpDraw(NULL)
    49 {
    50   lpVtbl                        = &Vtbl;
    51   Vtbl.AddRef           = PalAddRef;
    52   Vtbl.Release              = PalRelease;
    53   Vtbl.QueryInterface       = PalQueryInterface;
    54   Vtbl.GetCaps          = PalGetCaps;
    55   Vtbl.GetEntries       = PalGetEntries;
    56   Vtbl.Initialize       = PalInitialize;
    57   Vtbl.SetEntries       = PalSetEntries;
     11#include <winerror.h>
     12
     13//******************************************************************************
     14//******************************************************************************
     15OS2IDirectDrawPalette::OS2IDirectDrawPalette( OS2IDirectDraw *lpDirectDraw,
     16                                              int palsize,
     17                                              LPPALETTEENTRY lpColorTable,
     18                                              DWORD dwPalFlags) :
     19                                              Referenced(0), os2pal(NULL),
     20                                              lastError(DD_OK), lpDraw(NULL)
     21{
     22  lpVtbl              = &Vtbl;
     23  Vtbl.AddRef         = PalAddRef;
     24  Vtbl.Release        = PalRelease;
     25  Vtbl.QueryInterface = PalQueryInterface;
     26  Vtbl.GetCaps        = PalGetCaps;
     27  Vtbl.GetEntries     = PalGetEntries;
     28  Vtbl.Initialize     = PalInitialize;
     29  Vtbl.SetEntries     = PalSetEntries;
    5830
    5931  lpDraw                        = lpDirectDraw;
    60   lpDraw->Vtbl.AddRef((IDirectDraw2*)lpDraw);
     32  lpDraw->Vtbl.AddRef(lpDraw);
    6133  hDive                         = lpDirectDraw->GetDiveInstance();
    62   nrColors                      = palsize;
    63 
    64   dprintf(("OS2IDirectDrawPalette::OS2IDirectDrawPalette nr colors %d", palsize));
    65   os2pal = (W32_LPPALETTEENTRY)malloc(palsize*sizeof(PALETTEENTRY));
     34  dwCaps                        = dwPalFlags;
     35
     36  dwSize = palsize;
     37  if(256==dwSize)
     38    dwCaps |= DDPCAPS_ALLOW256;
     39  dwCaps &= ~DDPCAPS_VSYNC; // No sync change
     40
     41  os2pal = (LPPALETTEENTRY)malloc(palsize*sizeof(PALETTEENTRY));
    6642  memcpy((char *)os2pal, (char *)lpColorTable, palsize*sizeof(PALETTEENTRY));
    6743}
     
    7046OS2IDirectDrawPalette::~OS2IDirectDrawPalette()
    7147{
    72   if(os2pal)    free(os2pal);
    73   lpDraw->Vtbl.Release((IDirectDraw2*)lpDraw);
    74   RestorePhysPalette();
    75 }
    76 //******************************************************************************
    77 //******************************************************************************
    78 HRESULT __stdcall PalQueryInterface(THIS, REFIID riid, LPVOID FAR * ppvObj)
    79 {
    80   dprintf(("OS2IDirectDrawPalette::PalQueryInterface\n"));
     48  if(os2pal)
     49    free(os2pal);
     50  lpDraw->Vtbl.Release(lpDraw);
     51}
     52//******************************************************************************
     53//******************************************************************************
     54HRESULT __stdcall PalQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj)
     55{
     56  #ifdef DEBUG
     57    WriteLog("OS2IDirectDrawPalette::PalQueryInterface\n");
     58  #endif
     59
    8160  *ppvObj = NULL;
    8261
    8362  if(!IsEqualGUID(riid, IID_IDirectDrawPalette))
    8463//&& !IsEqualGUID(riid, IID_IUnknown))
    85     return E_NOINTERFACE;
     64  return E_NOINTERFACE;
    8665
    8766  *ppvObj = This;
     
    9271//******************************************************************************
    9372//******************************************************************************
    94 ULONG __stdcall PalAddRef(THIS)
     73ULONG __stdcall PalAddRef(THIS This)
     74{
     75  OS2IDirectDrawPalette *me = (OS2IDirectDrawPalette *)This;
     76
     77  #ifdef DEBUG
     78    WriteLog("OS2IDirectDrawPalette::PalAddRef %d\n", me->Referenced+1);
     79  #endif
     80
     81  return (++me->Referenced);
     82}
     83//******************************************************************************
     84//******************************************************************************
     85ULONG __stdcall PalRelease(THIS This)
     86{
     87  OS2IDirectDrawPalette *me = (OS2IDirectDrawPalette *)This;
     88
     89  #ifdef DEBUG
     90    WriteLog("OS2IDirectDrawPalette::PalRelease %d\n", me->Referenced-1);
     91  #endif
     92
     93  if(me->Referenced)
     94  {
     95    me->Referenced--;
     96    if(me->Referenced == 0)
     97    {
     98      delete me;
     99      return(0);
     100    }
     101    else
     102      return (me->Referenced);
     103  }
     104  else
     105    return(0);
     106}
     107//******************************************************************************
     108//******************************************************************************
     109HRESULT __stdcall PalGetCaps(THIS This, LPDWORD lpdwCaps)
     110{
     111  OS2IDirectDrawPalette *me = (OS2IDirectDrawPalette *)This;
     112
     113  #ifdef DEBUG
     114    WriteLog("OS2IDirectDrawPalette::GetCaps\n");
     115  #endif
     116
     117  if(NULL== lpdwCaps)
     118    return(DDERR_INVALIDPARAMS);
     119
     120  *lpdwCaps = me->dwCaps;
     121
     122  if(me->fAttachedToPrimary)
     123    *lpdwCaps |= DDPCAPS_PRIMARYSURFACE;
     124
     125  return(DD_OK);
     126}
     127//******************************************************************************
     128//******************************************************************************
     129HRESULT __stdcall PalGetEntries(THIS This, DWORD dwFlags,
     130                                      DWORD dwBase,
     131                                      DWORD dwNumEntries,
     132                                      LPPALETTEENTRY lpEntries)
    95133{
    96134 OS2IDirectDrawPalette *me = (OS2IDirectDrawPalette *)This;
    97135
    98   dprintf(("OS2IDirectDrawPalette::PalAddRef %d\n", me->Referenced+1));
    99   return ++me->Referenced;
    100 }
    101 //******************************************************************************
    102 //******************************************************************************
    103 ULONG __stdcall PalRelease(THIS)
     136  #ifdef DEBUG
     137    WriteLog("OS2IDirectDrawPalette::PalGetEntries\n");
     138  #endif
     139
     140  if( (NULL== lpEntries) ||(0!=dwFlags) ||(dwBase<0) ||((dwBase + dwNumEntries)>me->dwSize) )
     141    return(DDERR_INVALIDPARAMS);
     142
     143  memcpy( (char *)lpEntries,
     144          (char *)(me->os2pal + dwBase),
     145          dwNumEntries*sizeof(PALETTEENTRY));
     146  return(DD_OK);
     147}
     148//******************************************************************************
     149//******************************************************************************
     150HRESULT __stdcall PalInitialize(THIS, LPDIRECTDRAW, DWORD, LPPALETTEENTRY)
     151{
     152  #ifdef DEBUG
     153    WriteLog("OS2IDirectDrawPalette::PalInitialize\n");
     154  #endif
     155  return(DDERR_ALREADYINITIALIZED);
     156}
     157//******************************************************************************
     158//******************************************************************************
     159HRESULT __stdcall PalSetEntries(THIS This, DWORD dwFlags,
     160                                      DWORD dwBase,
     161                                      DWORD dwNumEntries,
     162                                      LPPALETTEENTRY lpNewEntries)
    104163{
    105164 OS2IDirectDrawPalette *me = (OS2IDirectDrawPalette *)This;
    106165
    107   dprintf(("OS2IDirectDrawPalette::PalRelease %d\n", me->Referenced-1));
    108   if(me->Referenced) {
    109     me->Referenced--;
    110     if(me->Referenced == 0) {
    111         delete me;
    112         return(0);
    113     }
    114     else    return me->Referenced;
    115   }
    116   else  return(0);
    117 }
    118 //******************************************************************************
    119 //******************************************************************************
    120 HRESULT __stdcall PalGetCaps(THIS_ LPDWORD)
    121 {
    122   dprintf(("OS2IDirectDrawPalette::GetCaps\n"));
    123   return(DD_OK);
    124 }
    125 //******************************************************************************
    126 //******************************************************************************
    127 HRESULT __stdcall PalGetEntries(THIS_ DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries,
    128                         W32_LPPALETTEENTRY lpEntries)
    129 {
    130  OS2IDirectDrawPalette *me = (OS2IDirectDrawPalette *)This;
    131 
    132   dprintf(("OS2IDirectDrawPalette::PalGetEntries %d %d\n", dwBase, dwNumEntries));
    133 
    134   if(dwBase + dwNumEntries > 256)
    135     return(DDERR_UNSUPPORTED);
    136 
    137   memcpy((char *)lpEntries, (char *)(me->os2pal + dwBase), dwNumEntries*sizeof(PALETTEENTRY));
    138   return(DD_OK);
    139 }
    140 //******************************************************************************
    141 //******************************************************************************
    142 HRESULT __stdcall PalInitialize(THIS_ LPDIRECTDRAW, DWORD, W32_LPPALETTEENTRY)
    143 {
    144   dprintf(("OS2IDirectDrawPalette::PalInitialize\n"));
    145   return(DD_OK);
    146 }
    147 //******************************************************************************
    148    #pragma pack(1)          /* pack on wordboundary */
    149 
    150    typedef struct _RGB2         /* rgb2 */
    151    {
    152       BYTE bBlue;              /* Blue component of the color definition */
    153       BYTE bGreen;             /* Green component of the color definition*/
    154       BYTE bRed;               /* Red component of the color definition  */
    155       BYTE fcOptions;          /* Reserved, must be zero                 */
    156    } RGB2;
    157    typedef RGB2 *PRGB2;
    158  #pragma pack()
    159 //******************************************************************************
    160 HRESULT __stdcall PalSetEntries(THIS_ DWORD dwFlags, DWORD dwStartingEntry,
    161                 DWORD dwCount, W32_LPPALETTEENTRY lpEntries)
    162 {
    163  OS2IDirectDrawPalette *me = (OS2IDirectDrawPalette *)This;
    164  int i, rc;
    165  RGB2 os2rgb[256];
    166 
    167    dprintf(("OS2IDirectDrawPalette::PalSetEntries %X %X %d %d\n", me, dwFlags, dwStartingEntry, dwCount));
    168    memcpy(&me->os2pal[dwStartingEntry], lpEntries, sizeof(PALETTEENTRY)*dwCount);
    169 
    170    for(i=0;i<256;i++) {
    171     os2rgb[i].bBlue     = me->os2pal[i].peBlue;
    172     os2rgb[i].bGreen    = me->os2pal[i].peGreen;
    173     os2rgb[i].bRed      = me->os2pal[i].peRed;
    174     os2rgb[i].fcOptions = 0;
    175 //  dprintf(("pal (%3d,%3d,%3d) %d\n", me->os2pal[i].peBlue, me->os2pal[i].peGreen, me->os2pal[i].peRed, me->os2pal[i].peFlags));
    176    }
    177 #if 0
    178    rc = DiveSetSourcePalette(me->hDive, dwStartingEntry, dwCount, (PBYTE)os2rgb);
    179    if(rc != DIVE_SUCCESS) {
    180     dprintf(("DiveSetSourcePalette returned %d\n", rc));
     166  #ifdef DEBUG
     167    WriteLog("OS2IDirectDrawPalette::PalSetEntries\n");
     168  #endif
     169  if( (NULL== lpNewEntries) ||(0!=dwFlags) ||(dwBase<0) ||((dwBase + dwNumEntries)>me->dwSize) )
    181170    return(DDERR_INVALIDPARAMS);
    182    }
    183    if(dcaps.ulDepth == 8) {
    184     rc = DiveSetDestinationPalette(me->hDive, dwStartingEntry, dwCount, (PBYTE)os2rgb);
    185     if(rc != DIVE_SUCCESS) {
    186         dprintf(("DiveSetDestinationPalette returned %d\n", rc));
    187         return(DDERR_INVALIDPARAMS);
    188     }
    189    }
    190 #else
    191    if(dcaps.ulDepth == 8) {
    192     OS2SetPhysPalette((HWND)me->lpDraw->GetWindowHandle(), me->os2pal);
    193     rc = DiveSetDestinationPalette(me->hDive, 0, 0, 0);
    194     if(rc != DIVE_SUCCESS) {
    195         dprintf(("DiveSetDestinationPalette returned %d\n", rc));
    196         return(DDERR_INVALIDPARAMS);
    197     }
    198    }
    199    else {
    200     rc = DiveSetSourcePalette(me->hDive, 0, me->nrColors, (PBYTE)os2rgb);
    201     if(rc != DIVE_SUCCESS) {
    202         dprintf(("DiveSetSourcePalette returned %d\n", rc));
    203         return(DDERR_INVALIDPARAMS);
    204     }
    205    }
    206 #endif
    207    return(DD_OK);
     171  memcpy((char *)(me->os2pal + dwBase),
     172         (char *)lpNewEntries,
     173         dwNumEntries*sizeof(PALETTEENTRY));
     174
     175  if(me->fAttachedToPrimary)
     176    me->SetPhysPalette();
     177
     178  return(DD_OK);
    208179}
    209180//******************************************************************************
     
    211182void OS2IDirectDrawPalette::SetPhysPalette()
    212183{
    213  int i, rc;
    214  RGB2 os2rgb[256];
    215 
    216    for(i=0;i<nrColors;i++) {
    217     os2rgb[i].bBlue     = os2pal[i].peBlue;
    218     os2rgb[i].bGreen    = os2pal[i].peGreen;
    219     os2rgb[i].bRed      = os2pal[i].peRed;
    220     os2rgb[i].fcOptions = 0;
    221     dprintf(("pal (%3d,%3d,%3d) %d\n", os2pal[i].peBlue, os2pal[i].peGreen, os2pal[i].peRed, os2pal[i].peFlags));
    222    }
    223 #if 0
    224    rc = DiveSetSourcePalette(hDive, 0, nrColors, (PBYTE)os2rgb);
    225    if(rc != DIVE_SUCCESS) {
    226     dprintf(("DiveSetSourcePalette returned %d\n", rc));
     184  OS2SetPhysPalette(os2pal);
     185}
     186//******************************************************************************
     187//******************************************************************************
     188void OS2IDirectDrawPalette::RestorePhysPalette()
     189{
     190  OS2ResetPhysPalette();
     191}
     192//******************************************************************************
     193//******************************************************************************
     194void OS2IDirectDrawPalette::SetIsPrimary(BOOL fNewVal)
     195{
     196  if(fNewVal==fAttachedToPrimary)
    227197    return;
    228    }
    229    if(dcaps.ulDepth == 8) {
    230     rc = DiveSetDestinationPalette(hDive, 0, nrColors, (PBYTE)os2rgb);
    231     if(rc != DIVE_SUCCESS) {
    232         dprintf(("DiveSetDestinationPalette returned %d\n", rc));
    233         return;
    234     }
    235    }
    236 #else
    237    if(dcaps.ulDepth == 8) {
    238     OS2SetPhysPalette((HWND)lpDraw->GetWindowHandle(), os2pal);
    239     rc = DiveSetDestinationPalette(hDive, 0, 0, 0);
    240     if(rc != DIVE_SUCCESS) {
    241         dprintf(("DiveSetDestinationPalette returned %d\n", rc));
    242         return;
    243     }
    244   }
    245   else {
    246     rc = DiveSetSourcePalette(hDive, 0, nrColors, (PBYTE)os2rgb);
    247     if(rc != DIVE_SUCCESS) {
    248         dprintf(("DiveSetSourcePalette returned %d\n", rc));
    249         return;
    250     }
    251   }
    252 #endif
    253 }
    254 //******************************************************************************
    255 //******************************************************************************
    256 void OS2IDirectDrawPalette::RestorePhysPalette()
    257 {
    258    if(dcaps.ulDepth == 8) {
    259     OS2ResetPhysPalette();
    260    }
    261 }
    262 //******************************************************************************
    263 //******************************************************************************
    264 
     198  fAttachedToPrimary = fNewVal;
     199  if(fAttachedToPrimary)
     200    SetPhysPalette();
     201
     202}
     203//******************************************************************************
     204//******************************************************************************
     205
  • trunk/src/ddraw/OS2PALSET.CPP

    r97 r210  
    1 /* $Id: OS2PALSET.CPP,v 1.3 1999-06-10 17:10:56 phaller Exp $ */
    2 
    3 /*
    4  * OS/2 Palette functions
    5  *
    6  * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
    7  *
    8  * Project Odin Software License can be found in LICENSE.TXT
    9  *
    10  */
    111#define INCL_GREALL
    12 #define INCL_WIN
    132#define INCL_GPI
    14 #include <os2.h>
     3#include <os2wrap.h>
    154#include <pmddi.h>
    165#include <stdio.h>
    176#include <stdlib.h>
    187#include <string.h>
     8#include "os2palset.h"
     9#define FAR
    1910#include "misc.h"
    20 #include "os2palset.h"
    2111
    2212//******************************************************************************
    2313//******************************************************************************
    24 void OS2SetPhysPalette(HWND hwndClient, void *pal)
     14void OS2SetPhysPalette(void *pal)
    2515{
    2616 PALETTEENTRY *pDirectXPal = (PALETTEENTRY *)pal;
     
    2919 RGB2 os2rgb[256];
    3020 int  i;
    31  ULONG cclr;
    3221
    33    hps = WinGetPS(HWND_DESKTOP);
    34    hdc = GpiQueryDevice(hps);
    35    for(i=0;i<256;i++) {
     22  hps = WinGetPS(HWND_DESKTOP);
     23  hdc = GpiQueryDevice(hps);
     24
     25  for(i=0;i<256;i++)
     26  {
    3627    os2rgb[i].bBlue     = pDirectXPal[i].peBlue;
    3728    os2rgb[i].bGreen    = pDirectXPal[i].peGreen;
    3829    os2rgb[i].bRed      = pDirectXPal[i].peRed;
    39     os2rgb[i].fcOptions = PC_RESERVED;
    40    }
     30    os2rgb[i].fcOptions = 0;
     31  }
    4132
    42    GpiCreateLogColorTable(hps, LCOL_PURECOLOR | LCOL_REALIZABLE,
    43                           LCOLF_CONSECRGB, 0, 256, (PLONG)&os2rgb);
    44    Gre32Entry3(hdc, 0L, 0x000060C6L);
    45 //   WinInvalidateRect(HWND_DESKTOP, (PRECTL)NULL, TRUE);
    46    WinRealizePalette(hwndClient, hps, &cclr);
    47    WinReleasePS(hps);
     33  GpiCreateLogColorTable( hps, LCOL_PURECOLOR | LCOL_REALIZABLE,
     34                          LCOLF_CONSECRGB,
     35                          0,
     36                          256,
     37                          (PLONG)&os2rgb);
     38  Gre32Entry3( hdc,
     39               0L,
     40               0x000060C6L);
     41
     42  WinInvalidateRect( HWND_DESKTOP,
     43                     (PRECTL)NULL,
     44                     TRUE);
     45  WinReleasePS(hps);
    4846}
    4947//******************************************************************************
     
    5452 HDC hdc;
    5553
    56    hps = WinGetPS(HWND_DESKTOP);
    57    hdc = GpiQueryDevice(hps);
    58    Gre32Entry3(hdc, 0L, 0x000060C7L);
    59    WinInvalidateRect(HWND_DESKTOP, (PRECTL)NULL, TRUE);
    60    WinReleasePS(hps);
     54  hps = WinGetPS( HWND_DESKTOP);
     55
     56  hdc = GpiQueryDevice( hps);
     57
     58  Gre32Entry3( hdc,
     59               0L,
     60               0x000060C7L);
     61
     62  WinInvalidateRect( HWND_DESKTOP,
     63                    (PRECTL)NULL,
     64                    TRUE);
     65
     66  WinReleasePS(hps);
    6167}
    6268//******************************************************************************
  • 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
  • trunk/src/ddraw/ddraw.CPP

    r97 r210  
    1 /* $Id: ddraw.CPP,v 1.3 1999-06-10 17:10:57 phaller Exp $ */
     1#include <memory.h>
    22
    3 /*
    4  * DirectDraw exported APIs
    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 
    12 /*@Const************************************************************************
    13 *   Defined Constants                                                          *
    14 *******************************************************************************/
     3#include <builtin.h>
    154#define INITGUID
    16 #define INCL_GUIDS
    17 #define WIN32SDK_NOPOSTWRAPPER
    18 
    19 /*@Header***********************************************************************
    20 *   Header Files                                                               *
    21 *******************************************************************************/
    22 #include <os2win.h>
    23 #include <memory.h>
    24 #include <builtin.h>
    25 #include <dive.h>
    26 
    27 #include <w_windows.h>
    28 #include <ddraw.h>
    29 #include <d3d.h>
    30 #include <Win32SDKPostWrapper.h>
    31 
    325#include "os2ddraw.h"
     6// define the following as we include winnt.h
     7#define _OS2WIN_H
     8#define FAR
    339#include "misc.h"
    3410
    3511//******************************************************************************
    3612//******************************************************************************
    37 HRESULT WIN32API OS2DirectDrawCreate(GUID FAR *lpGUID,
    38                                  LPDIRECTDRAW FAR *lplpDD,
    39                              IUnknown FAR *pUnkOuter)
     13HRESULT WIN32API OS2DirectDrawCreate( GUID FAR *lpGUID,
     14                                      LPDIRECTDRAW FAR *lplpDD,
     15                                      IUnknown FAR *pUnkOuter)
    4016{
    41  OS2IDirectDraw *newdraw = new OS2IDirectDraw(lpGUID);;
    42  HRESULT         rc;
     17  OS2IDirectDraw *newdraw;
     18  HRESULT         rc;
    4319
    44   dprintf(("DirectDrawCreate %X %X %X\n", lpGUID, lplpDD, pUnkOuter));
     20  WriteLog("DirectDrawCreate %X %X %X\n", lpGUID, lplpDD, pUnkOuter);
     21  newdraw = new OS2IDirectDraw(lpGUID);
    4522
    46   if(newdraw == NULL)   return(DDERR_NODIRECTDRAWHW);
     23  if(newdraw == NULL)
     24    return(DDERR_NODIRECTDRAWHW);
    4725
    4826//  newdraw->Vtbl.AddRef((IDirectDraw *)newdraw);
    4927  rc = newdraw->GetLastError();
    50   if(rc != DD_OK) {
     28  if(rc != DD_OK)
     29  {
    5130    *lplpDD = NULL;
    5231    delete newdraw;
    5332  }
    54   else  *lplpDD = (LPDIRECTDRAW)newdraw;
     33  else
     34    *lplpDD = (LPDIRECTDRAW)newdraw;
     35
    5536  return(rc);
    5637}
    5738//******************************************************************************
    58 #if 0  //KSO Apr 19 1999: not needed any longer!
    5939typedef BOOL (FAR PASCAL * LPDDENUMCALLBACKA)(GUID FAR *, LPSTR, LPSTR, LPVOID);
    60 #endif
    6140//******************************************************************************
    6241HRESULT WIN32API OS2DirectDrawEnumerateA(LPDDENUMCALLBACKA lpCallback,
    63                              LPVOID lpContext)
     42               LPVOID lpContext)
    6443{
    65   dprintf(("DirectDrawEnumerateA\n"));
     44  WriteLog("DirectDrawEnumerateA\n Callback for DIVE\n");
    6645  //call it twice for the DirectDraw & Direct3D classes
    67   if(lpCallback(NULL, "DIVE DirectDraw for OS/2",
    68         "DirectDraw/2 v0.1", lpContext) == DDENUMRET_CANCEL) {
     46 if(lpCallback(NULL, "DIVE DirectDraw for OS/2",
     47                "DirectDraw/2 v0.1", lpContext) == DDENUMRET_CANCEL)
     48  {
     49    WriteLog("Cancel Callback\n");
    6950    return(DD_OK);
    7051  }
    7152  else //now for Direct3D
    72   if(lpCallback((GUID *)&IID_IDirect3D, "3Dfx Voodoo Direct3D/2",
    73         "Direct3D/2 v0.1", lpContext) == DDENUMRET_CANCEL) {
    74     return(DD_OK);
     53  {
     54    WriteLog("Callback for 3Dfx Voodoo");
     55    if(lpCallback((GUID *)&IID_IDirect3D, "3Dfx Voodoo Direct3D/2",
     56      "Direct3D/2 v0.1", lpContext) == DDENUMRET_CANCEL)
     57    {
     58      WriteLog("Cancel Callback\n");
     59      return(DD_OK);
     60    }
    7561  }
     62  WriteLog("Done Enumeration\n\n");
     63
    7664  return(DD_OK);
     65}
     66//******************************************************************************
     67typedef struct
     68{
     69  LPDDENUMCALLBACKEXA lpCallbackEx;
     70  LPVOID lpContext;
     71} ENUMDATA, *PENUMDATA;
     72
     73BOOL FAR PASCAL SimpleEnum ( GUID FAR *lpGUID,
     74                             LPSTR  lpDriverDescription,
     75                             LPSTR  lpDriverName,
     76                             LPVOID lpContext)
     77{
     78  BOOL rc;
     79  PENUMDATA pData;
     80
     81  WriteLog("SimpleEnum\n");
     82
     83  pData = (PENUMDATA)lpContext;
     84  rc = pData->lpCallbackEx( lpGUID,
     85                            lpDriverDescription,
     86                            lpDriverName,
     87                            pData->lpContext,
     88                            NULL);
     89
     90  WriteLog("Callback returned");
     91  return rc;
     92}
     93
     94//******************************************************************************
     95HRESULT WIN32API OS2DirectDrawEnumerateExA( LPDDENUMCALLBACKEXA lpCallbackEx,
     96                                            LPVOID lpContext,
     97                                            DWORD dwFlags)
     98{
     99  ENUMDATA data;
     100
     101  WriteLog("DirectDrawEnumerateExA\n");
     102
     103  data.lpCallbackEx = lpCallbackEx;
     104  data.lpContext    = lpContext;
     105
     106   OS2DirectDrawEnumerateA( SimpleEnum,
     107                            &data);
     108  return (DD_OK);
    77109}
    78110//******************************************************************************
     
    80112DWORD WIN32API DDHAL32_VidMemFree(DWORD address)
    81113{
    82   dprintf(("DDHAL32_VidMemFree, not supported\n"));
     114  WriteLog("DDHAL32_VidMemFree, not supported\n");
    83115  return(0);
    84116}
     
    87119DWORD WIN32API DDHAL32_VidMemAlloc(DWORD size)
    88120{
    89   dprintf(("DDHAL32_VidMemAlloc, not supported\n"));
     121  WriteLog("DDHAL32_VidMemAlloc, not supported\n");
    90122  return(0);
    91123}
  • trunk/src/ddraw/initterm.cpp

    r120 r210  
    1 /* $Id: initterm.cpp,v 1.3 1999-06-19 10:54:39 sandervl Exp $ */
    21
    32/*
    4  * DLL entry point
    5  *
    6  * Copyright 1998 Sander van Leeuwen
    7  * Copyright 1998 Peter Fitzsimmons
    8  *
    9  *
    10  * Project Odin Software License can be found in LICENSE.TXT
    11  *
     3
     4 * This file was created for Sander van Leeuwen
     5
     6 * by Project Smarts on 8 May 1997.
     7
    128 */
    139
     
    2723#define  INCL_DOSMODULEMGR
    2824#define  INCL_DOSPROCESS
    29 #include <os2wrap.h>    //Odin32 OS/2 api wrappers
     25#include <os2wrap.h>
    3026#include <stdlib.h>
    3127#include <stdio.h>
    3228#include <string.h>
    3329#include <odin.h>
    34 #include <misc.h>       /*PLF Wed  98-03-18 23:18:15*/
     30#include <misc.h>       /*PLF Wed  98-03-18 23:18:29*/
    3531
    36 extern "C" {
    3732/*-------------------------------------------------------------------*/
    3833/* _CRT_init is the C run-time environment initialization function.  */
    3934/* It will return 0 to indicate success and -1 to indicate failure.  */
    4035/*-------------------------------------------------------------------*/
    41 int CDECL CRT_init(void);
     36int _CRT_init(void);
    4237/*-------------------------------------------------------------------*/
    4338/* _CRT_term is the C run-time environment termination function.     */
     
    4540/* statically linked.                                                */
    4641/*-------------------------------------------------------------------*/
    47 void CDECL CRT_term(void);
    48 void CDECL _ctordtorInit( void );
    49 void CDECL _ctordtorTerm( void );
    50 }
     42void _CRT_term(void);
     43void __ctordtorInit( void );
     44void __ctordtorTerm( void );
    5145
    5246/*-------------------------------------------------------------------*/
     
    5953
    6054
     55
    6156/****************************************************************************/
    6257/* _DLL_InitTerm is the function that gets called by the operating system   */
     
    6762/* calling this function.                                                   */
    6863/****************************************************************************/
    69 unsigned long SYSTEM _DLL_InitTerm(unsigned long hModule, unsigned long
    70                                    ulFlag)
     64unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long
     65                                    ulFlag)
    7166{
    7267   size_t i;
     
    8883         /*******************************************************************/
    8984
    90          if (CRT_init() == -1)
     85         if (_CRT_init() == -1)
    9186            return 0UL;
    92          _ctordtorInit();
     87     __ctordtorInit();
    9388
    94          CheckVersionFromHMOD(PE2LX_VERSION, hModule); /*PLF Wed  98-03-18 05:28:48*/
     89//SvL: Temporarily disabled
     90#if 0
     91        CheckVersionFromHMOD(PE2LX_VERSION, hModule); /*PLF Wed  98-03-18 05:28:48*/
     92#endif
     93
    9594         /*******************************************************************/
    9695         /* A DosExitList routine must be used to clean up if runtime calls */
     
    10099         rc = DosExitList(0x0000FF00|EXLST_ADD, cleanup);
    101100         if(rc)
    102                 return 0UL;
     101    return 0UL;
    103102
    104103         break;
     
    118117static void APIENTRY cleanup(ULONG ulReason)
    119118{
    120    _ctordtorTerm(); 
    121    CRT_term();
     119   __ctordtorTerm();
     120   _CRT_term();
    122121   DosExitList(EXLST_EXIT, cleanup);
    123122   return ;
Note: See TracChangeset for help on using the changeset viewer.