'   0 IDirectDrawSurface_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
'   1 IDirectDrawSurface_AddRef(p)                    (p)->lpVtbl->AddRef(p)
'   2 IDirectDrawSurface_Release(p)                   (p)->lpVtbl->Release(p)
'   3 IDirectDrawSurface_AddAttachedSurface(p,a)      (p)->lpVtbl->AddAttachedSurface(p,a)
'   4 IDirectDrawSurface_AddOverlayDirtyRect(p,a)     (p)->lpVtbl->AddOverlayDirtyRect(p,a)
'   5 IDirectDrawSurface_Blt(p,a,b,c,d,e)             (p)->lpVtbl->Blt(p,a,b,c,d,e)
'   6 IDirectDrawSurface_BltBatch(p,a,b,c)            (p)->lpVtbl->BltBatch(p,a,b,c)
'   7 IDirectDrawSurface_BltFast(p,a,b,c,d,e)         (p)->lpVtbl->BltFast(p,a,b,c,d,e)
'   8 IDirectDrawSurface_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
'   9 IDirectDrawSurface_EnumAttachedSurfaces(p,a,b)  (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
'  10 IDirectDrawSurface_EnumOverlayZOrders(p,a,b,c)  (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
'  11 IDirectDrawSurface_Flip(p,a,b)                  (p)->lpVtbl->Flip(p,a,b)
'  12 IDirectDrawSurface_GetAttachedSurface(p,a,b)    (p)->lpVtbl->GetAttachedSurface(p,a,b)
'  13 IDirectDrawSurface_GetBltStatus(p,a)            (p)->lpVtbl->GetBltStatus(p,a)
'  14 IDirectDrawSurface_GetCaps(p,b)                 (p)->lpVtbl->GetCaps(p,b)
'  15 IDirectDrawSurface_GetClipper(p,a)              (p)->lpVtbl->GetClipper(p,a)
'  16 IDirectDrawSurface_GetColorKey(p,a,b)           (p)->lpVtbl->GetColorKey(p,a,b)
'  17 IDirectDrawSurface_GetDC(p,a)                   (p)->lpVtbl->GetDC(p,a)
'  18 IDirectDrawSurface_GetFlipStatus(p,a)           (p)->lpVtbl->GetFlipStatus(p,a)
'  19 IDirectDrawSurface_GetOverlayPosition(p,a,b)    (p)->lpVtbl->GetOverlayPosition(p,a,b)
'  20 IDirectDrawSurface_GetPalette(p,a)              (p)->lpVtbl->GetPalette(p,a)
'  21 IDirectDrawSurface_GetPixelFormat(p,a)          (p)->lpVtbl->GetPixelFormat(p,a)
'  22 IDirectDrawSurface_GetSurfaceDesc(p,a)          (p)->lpVtbl->GetSurfaceDesc(p,a)
'  23 IDirectDrawSurface_Initialize(p,a,b)            (p)->lpVtbl->Initialize(p,a,b)
'  24 IDirectDrawSurface_IsLost(p)                    (p)->lpVtbl->IsLost(p)
'  25 IDirectDrawSurface_Lock(p,a,b,c,d)              (p)->lpVtbl->Lock(p,a,b,c,d)
'  26 IDirectDrawSurface_ReleaseDC(p,a)               (p)->lpVtbl->ReleaseDC(p,a)
'  27 IDirectDrawSurface_Restore(p)                   (p)->lpVtbl->Restore(p)
'  28 IDirectDrawSurface_SetClipper(p,a)              (p)->lpVtbl->SetClipper(p,a)
'  29 IDirectDrawSurface_SetColorKey(p,a,b)           (p)->lpVtbl->SetColorKey(p,a,b)
'  30 IDirectDrawSurface_SetOverlayPosition(p,a,b)    (p)->lpVtbl->SetOverlayPosition(p,a,b)
'  31 IDirectDrawSurface_SetPalette(p,a)              (p)->lpVtbl->SetPalette(p,a)
'  32 IDirectDrawSurface_Unlock(p,b)                  (p)->lpVtbl->Unlock(p,b)
'  33 IDirectDrawSurface_UpdateOverlay(p,a,b,c,d,e)   (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
'  34 IDirectDrawSurface_UpdateOverlayDisplay(p,a)    (p)->lpVtbl->UpdateOverlayDisplay(p,a)
'  35 IDirectDrawSurface_UpdateOverlayZOrder(p,a,b)   (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
'  36 IDirectDrawSurface2_GetDDInterface(p,a)         (p)->lpVtbl->GetDDInterface(p,a)
'  37 IDirectDrawSurface2_PageLock(p,a)               (p)->lpVtbl->PageLock(p,a)
'  38 IDirectDrawSurface2_PageUnlock(p,a)             (p)->lpVtbl->PageUnlock(p,a)

' ***************************************************************************************
function ddSurfacePrototype() as hresult  
  FatalError("iDirectDraw.Surface::#%i Function not implemented",DDSURFACEPROTOID)    
  return DDERR_UNSUPPORTED
  
  asm
    .balign 32
    _ddSurfaceProtoTable_:  
    #macro ProtoNum(X)
    mov dword ptr [DDSURFACEPROTOID],X
    jmp ddSurfacePrototype
    .balign 32
    #endmacro
    ProtoNum(0)
    ProtoNum(1)
    ProtoNum(2)
    ProtoNum(3)
    ProtoNum(4)
    ProtoNum(5)
    ProtoNum(6)
    ProtoNum(7)
    ProtoNum(8)
    ProtoNum(9)
    ProtoNum(10)
    ProtoNum(11)
    ProtoNum(12)
    ProtoNum(13)
    ProtoNum(14)
    ProtoNum(15)
    ProtoNum(16)
    ProtoNum(17)
    ProtoNum(18)
    ProtoNum(19)
    ProtoNum(20)
    ProtoNum(21)
    ProtoNum(22)
    ProtoNum(23)
    ProtoNum(24)
    ProtoNum(25)
    ProtoNum(26)
    ProtoNum(27)
    ProtoNum(28)
    ProtoNum(29)
    ProtoNum(30)
    ProtoNum(31)
    ProtoNum(32)
    ProtoNum(33)
    ProtoNum(34)
    ProtoNum(35)
    ProtoNum(36) '2
    ProtoNum(37) '2
    ProtoNum(38) '2
  end asm  
  
end function
sub FBgfx_Update(iThread as integer)
  static as integer FPS
  static as double FPT
  dim as any ptr MYIMAGE
  if abs(timer-FPT) >= 2 then FPT = timer
  FPS += 1: if (timer-FPT) >= 1 then FPT+=1:FPSHOW=FPS:FPS=0
    
  'MYIMAGE = ImageCreate(64,12)    
  'Get(0,0)-(63,11),MYIMAGE    
  #ifndef Render_OpenGL
  Draw String (1,1),FPSHOW & " fps ",255  
  #endif
    
  LastFrame=timer  
    
  #ifdef Render_OpenGL
    mt_Screensync()  
    #ifdef DebugDeviceTime
      if CURRDEVICE then
        dim as zstring*256 sText
        sprintf(sText,!"Flip:%2.3g(%i)\n",(timer-DeviceTime)*1000,GetCurrentThreadID())
        printf(sText):cout(sText):DeviceTime = timer
      end if
    #endif
  #endif
  
  if FPSLIMIT > 2 then
    static as double TMR
    if abs(timer-TMR) > 1 then TMR = timer    
    while (timer-TMR) < 1/FPSLIMIT
      sleepex 1,1
    wend        
    TMR += 1/FPSLIMIT    
  elseif FPSLIMIT=1 then
    sleepex 1,1
  else
    #ifndef Render_OpenGL
    screensync 
    #endif
    'sleepex 1,1
    SwitchToThread()
  end if
  'put(0,0),MYIMAGE,pset
  'Imagedestroy(MYIMAGE)
end sub

' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 IID as any ptr
#define P3 ppOutObj as any ptr ptr
function ddSurface_0_QueryInterface(P1,P2,P3) as hresult
  #ifdef MyDebugX
  Cout("IDirectDraw::Surface.QueryInterface (0)" + chr$(13,10) + _
  " >> THIS: "+hexptr(pTHIS) + "  IID: "+GetGuid(IID)+ _
  "Query: "+QueryGUIDString(IID)+"  OUT: "+hexptr(ppOutObj))
  #endif
  #ifdef Enable3D
  dim as string TMPQUERYS
  var QUERYRESULT = CheckGUID(IID,TMPQUERYS)
  select case QUERYRESULT
  case giIDirectDrawSurface2
    *ppOutObj = pTHIS: pTHIS->refcnt += 1
  case giIDirect3DTexture2
    *ppOutObj = new d3dTexture2Object
    d3dTexture2Funcs(d3dTexture2_FUNCS())  
    with *cptr(d3dTexture2Object ptr,*ppOutObj)
      .VTABLE = @d3dTexture2_FUNCS(0)        
      .Interface = itD3DTexture2
      .Surface = pTHIS
    end with
  case else
    ddrawError(E_NOINTERFACE)
  end select   
  return DD_OK
  #else
  return E_NOINTERFACE
  #endif
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
function ddSurface_2_Release(P1) as hresult
  DirectLock(DDMUTEX)
  #ifdef MyDebugX
  'ShowInterfaceType(pTHIS)
  Cout("IDirectDraw::Surface.Release (2)" + " THIS: "+hexptr(pTHIS)+"  Primary:" & pThis->Primary)
  #endif
  with *pTHIS
    if .fbImage then       
      TotalMemory -= .fbimage->pitch*.fbimage->height: TotalAllocs -= 1
      #ifdef DebugMemory
      printf(!"Deallocate %s:%i(%3.2g)\n",__FUNCTION__,__LINE__,TotalMemory/(1024*1024))
      #endif
      imagedestroy(.fbimage):.fbimage=0
    end if
    if .Primary then DirectUnlock(DDMUTEX):return DD_OK    
    #ifdef Enable3D
    if .ID > 0 then      
      mt_glDeleteTextures(1, @.ID)
      if .ID = ogl.LastBind then 
        ogl.LastBind=0: ogl.LastSurface=0
      end if
      .ID = 0      
    end if
    #endif
    if .refcnt then .refcnt -= 1 else Delete pTHIS    
  end with  
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 lpDestRect as rect ptr
#define P3 lpDDSrcSurface as ddSurfaceObject ptr
#define P4 lpSrcRect as rect ptr
#define P5 dwFlags as dword
#define P6 lpDDBltFx as DDBLTFX ptr
function ddSurface_5_Blt(P1,P2,P3,P4,P5,P6) as hresult
  DirectLock(DDMUTEX)
  if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then
    'lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
  end if
  #ifdef MyDebugX
  'ShowInterfaceType(pTHIS)
  dim as string DTMP
  if (dwFlags and DDBLT_ALPHADEST)                then DTMP += "AlphaDest "
  if (dwFlags and DDBLT_ALPHADESTCONSTOVERRIDE)   then DTMP += "AlphaDestX "
  if (dwFlags and DDBLT_ALPHADESTNEG)             then DTMP += "-AlphaDest "
  if (dwFlags and DDBLT_ALPHADESTSURFACEOVERRIDE) then DTMP += "AlphaddX "
  if (dwFlags and DDBLT_ALPHAEDGEBLEND)           then DTMP += "EdgeBlend "
  if (dwFlags and DDBLT_ALPHASRC)                 then DTMP += "AlphaSrc "
  if (dwFlags and DDBLT_ALPHASRCCONSTOVERRIDE)    then DTMP += "AlphaSrcX"
  if (dwFlags and DDBLT_ALPHASRCNEG)              then DTMP += "-AlphaSrc "
  if (dwFlags and DDBLT_ALPHASRCSURFACEOVERRIDE)  then DTMP += "AlphassX "
  if (dwFlags and DDBLT_ASYNC)                    then DTMP += "Async "
  if (dwFlags and DDBLT_COLORFILL)                then DTMP += "Fill "
  if (dwFlags and DDBLT_DDFX)                     then DTMP += "ddfx "
  if (dwFlags and DDBLT_DDROPS)                   then DTMP += "ddrops "
  if (dwFlags and DDBLT_DEPTHFILL)                then DTMP += "DepthFill "
  if (dwFlags and DDBLT_KEYDEST)                  then DTMP += "KeyDest "
  if (dwFlags and DDBLT_KEYDESTOVERRIDE)          then DTMP += "KeyDestX "
  if (dwFlags and DDBLT_KEYSRC)                   then DTMP += "KeySrc "
  if (dwFlags and DDBLT_KEYSRCOVERRIDE)           then DTMP += "KeySrcX "
  if (dwFlags and DDBLT_ROP)                      then DTMP += "Rop "
  if (dwFlags and DDBLT_ROTATIONANGLE)            then DTMP += "Rotate "
  if (dwFlags and DDBLT_WAIT)                     then DTMP += "Wait "
  if (dwFlags and DDBLT_ZBUFFER)                  then DTMP += "Zbuffer "
  if (dwFlags and DDBLT_ZBUFFERDESTCONSTOVERRIDE) then DTMP += "ZbuffX2 "
  if (dwFlags and DDBLT_ZBUFFERDESTOVERRIDE)      then DTMP += "ZbuffX3 "
  if (dwFlags and DDBLT_ZBUFFERSRCCONSTOVERRIDE)  then DTMP += "ZbuffX4 "
  if (dwFlags and DDBLT_ZBUFFERSRCOVERRIDE)       then DTMP += "ZbuffX5 "
  with *lpDDSrcSurface
    Cout("IDirectDraw::Surface.Blt (5) >> THIS: "+hexptr(pTHIS)+chr$(13,10)+ _
    " >> DstRct: " & lpDestRect & " Src:"+hexptr(lpDDSrcSurface)+ _
    " SrcRct: " & lpSrcRect & " fx: " & lpDDBltFx & " Flags: " & DTMP+"  Primary:" & pThis->Primary)
    lcout(" >> srcimg: "+HexPtr(.fbimage)+" " & .wid & "x" & .hei & " bpp: " & .bpp)
    lcout(" >> tgtimg: "+HexPtr(pThis->fbimage)+" " & pThis->wid & "x" & pThis->hei & " bpp: " & pThis->bpp)    
  end with
  #endif  
  
  'static as integer BLT
  'BLT += 1
  'bsave "Blits\Src-" & BLT & ".bmp",lpDDSrcSurface->fbimage
  'bsave "Blits\Dst-" & BLT & ".bmp",pThis->fbImage
  
  #ifdef Enable3D
  var NotInScene = (ogl.InScene=0)
  if NotInScene then mutexlock(RenderMutex)
  #endif
  dim as integer DX,DY,DXX,DYY
  dim as integer SX,SY,SXX,SYY
  dim as ddSurfaceObject ptr SRC = lpDDSrcSurface
  dim as any ptr pTarget = pThis->fbimage  
  if pThis->primary or SRC=0 then 
    #ifdef Enable3D
    if NotInScene then mutexunlock(RenderMutex)
    #endif
    DirectUnlock(DDMUTEX):return DD_OK
    'pTarget=0
  end if
  #ifdef Enable3D
  if pThis->ID > 0 then 
    pThis->NeedUpdate = 1
    if ogl.LastSurface = pThis then
      #ifdef MyDebugD3D
      lcout("Need update current selected Texture!!!")
      #endif
    end if
  end if
  #endif
  'if SRC=0 then SRC=pTHIS
  if SRC->fbimage=0 and SRC->primary=0 then    
    #ifdef MyDebugz
    lCout("Invalid fbimage (surface) to plot")
    #endif
    #ifdef Enable3D
    if NotInScene then mutexunlock(RenderMutex)
    #endif
    DirectUnlock(DDMUTEX):return DD_OK
  end if
  #if 1
  if lpDestRect then 
    DX=lpDestRect->left: DY=lpDestRect->top
  end if  
  if lpSrcRect then
    with *lpSrcRect
      SX=.left:SY=.top:SXX=.right:SYY=.bottom
    end with    
    put pTarget,(DX,DY),SRC->fbImage,(SX,SY)-(SXX,SYY),pset
  else    
    put pTarget,(DX,DY),SRC->fbImage,pset
  end if
  #endif
  
  #ifdef DumpBlits
  static as integer X
  X += 1  
  with *SRC  
    dim as string sName = X & ".bmp"    
    if .bpp = 8 then
      var hSz = sizeof(bitmapfileheader)+sizeof(bitmapinfoheader)+256*4
      dim as bitmapfileheader bfh = type(cvshort("BM"),hSz+(.pitch*.hei),0,0,hSz)
      dim as bitmapinfoheader bih = type(sizeof(bitmapinfoheader), _
      .pitch,-.hei,1,8,BI_RGB,0,null,null,null,null)
      var f = freefile()
      if open("blits\"+sName for binary access write as #f) then
        'lcout("Failed to dump!!! :(")
      else
        put #f,,bfh
        put #f,,bih
        var pPal = .pal
        if pPal = 0 then pPal = BACKBUFFER.pal
        if pPal = 0 then pPal = FRONTBUFFER.pal
        if ppal=0 then
          'lcout("no pal????")
          for CNT as integer = 0 to 255
            var iPix = rgba(CNT,CNT,CNT,0)
            put #f,,iPix
          next CNT
        else
          put #f,,ppal->pal()
        end if
        put #f,,*cptr(ubyte ptr,.fbimage+1),.pitch*.hei
        close #f
      end if
    else
      bsave("blits\"+sName,.fbimage)
    end if
  end with
  #endif
  #ifdef Enable3D
  if NotInScene then mutexunlock(RenderMutex)
  #endif
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 dwX as dword
#define P3 dwY as dword
#define P4 lpDDSrcSurface as ddSurfaceObject ptr
#define P5 lpSrcRect as Rect ptr
#define P6 dwTrans as dword
function ddSurface_7_BltFast(P1,P2,P3,P4,P5,P6) as hresult
  DirectLock(DDMUTEX)
  if pTHIS->Primary=0 then 'andalso pTHIS->ID <> -1 or pTHIS->refcnt then
    #ifdef MyDebugErr
    lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
    #endif
  end if
  #ifdef MyDebugX
  ShowInterfaceType(pTHIS)
  dim as string DTMP
  if (dwTrans and DDBLTFAST_DESTCOLORKEY) then DTMP += "DestColorKey "
  if (dwTrans and DDBLTFAST_NOCOLORKEY) then DTMP += "NoColorKey "
  if (dwTrans and DDBLTFAST_SRCCOLORKEY) then DTMP += "SrcColorKey "  
  if (dwTrans and DDBLTFAST_WAIT) then DTMP += "Wait "  
  if DTMP = "" then DTMP = "--"
  Cout("IDirectDraw::Surface.BltFast (7)" + chr$(13,10) + _
  " >> THIS:"+hex$(cast(uinteger,pTHIS),8) + _
  " X:" & dwX & " Y:" & dwY & " SrcSurface:" & lpDDSrcSurface & _
  " SrcRect:" & lpSrcRect & " Flags:"+DTMP+"  Primary:" & pThis->Primary)
  #endif  
  dim as ddSurfaceObject ptr SRC = lpDDSrcSurface
  if SRC=0 then SRC=pTHIS
  with *SRC
    if .fbImage then put(dwX,dwY),.fbimage,pset
  end with  
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 lpDDSurfaceTargetOverride as ddSurfaceObject ptr
#define P3 dwFlags as dword
function ddSurface_11_Flip(P1,P2,P3) as hresult
  DirectLock(DDMUTEX)
  #ifdef MyDebugErr
  if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then    
    lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)    
  end if
  #endif
  #ifdef MyDebugQuick
  ShowInterfaceType(pTHIS)
  dim as string STMP
  STMP = ""  
  if (dwFlags and DDFLIP_EVEN) then STMP += "even "
  if (dwFlags and DDFLIP_ODD) then STMP += "odd "
  if (dwFlags and DDFLIP_WAIT) then STMP += "wait "
  if STMP = "" then STMP = "--"    
  Cout("IDirectDraw::Surface.Flip (11)" + chr$(13,10) + _
  " > THIS:"+hex$(cast(uinteger,pTHIS))+" Target:"+hex$(cast(uinteger,lpDDSurfaceTargetOverride))+ _
  " Caps: "+STMP+"  Primary:" & pThis->Primary)
  #endif  
  'if (dwflags and DDFLIP_WAIT) then
  '  'screensync
  'end if
  #ifdef Render_OpenGL
  ogl.DoFrameUpdate = 1
  #endif
  FBgfx_Update(0)  
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 lpDDSCaps as DDSCAPS ptr
#define P3 LPDIRECTDRAWSURFACE3 as any ptr ptr
function ddSurface_12_GetAttachedSurface(P1,P2,P3) as hresult
  DirectLock(DDMUTEX)
  #ifdef MyDebugErr
  if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then
    lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
  end if
  #endif
  #ifdef MyDebugX
  ShowInterfaceType(pTHIS)
  dim as string STMP
  STMP = ""
  with *lpDDSCaps
    if (.dwcaps and DDSCAPS_ALPHA)           then STMP += "OnlyAlpha "
    if (.dwcaps and DDSCAPS_BACKBUFFER)      then STMP += "BackBuffer "
    'if (.dwcaps and DDSCAPS_DYNAMIC)         then STMP += "Dynamic "
    if (.dwcaps and DDSCAPS_FLIP)            then STMP += "Flip "
    if (.dwcaps and DDSCAPS_FRONTBUFFER)     then STMP += "FronBuffer "
    'if (.dwcaps and DDSCAPS_NOTUSERLOCKABLE) then STMP += "NotLock "
    if (.dwcaps and DDSCAPS_OVERLAY)         then STMP += "Overlay "
    if (.dwcaps and DDSCAPS_PALETTE)         then STMP += "Palette "
    if (.dwcaps and DDSCAPS_PRIMARYSURFACE)  then STMP += "Primary "            
    'if (.dwcaps and DDSCAPS_READONLY)        then STMP += "ReadOnly "
    if (.dwcaps and DDSCAPS_SYSTEMMEMORY)    then STMP += "System "
    if (.dwcaps and DDSCAPS_VIDEOMEMORY)     then STMP += "Video "
    if (.dwcaps and DDSCAPS_WRITEONLY)       then STMP += "WriteOnly "
  end with
  Cout("IDirectDraw::Surface.GetAttachedSurface (12)" + chr$(13,10) + _
  " > THIS: "+hex$(cast(uinteger,pTHIS),8)+" CAPS: "+STMP+"  Primary:" & pThis->Primary)
  #endif
  if lpDDSCaps->dwcaps and DDSCAPS_BACKBUFFER then
    *LPDIRECTDRAWSURFACE3 = @BackBuffer.VTABLE
  end if
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS   as ddSurfaceObject ptr
#define P2 dwFlags as DWORD
function ddSurface_13_GetBltStatus(P1,P2) as hresult
  '#ifdef MyDebugQuick
  'Cout("IDirectDraw::Surface.IsLost (24)"+chr$(13,10)+ _
  '" > THIS: "+hex$(cast(uinteger,pTHIS)))  
  '#endif    
  return DD_OK  
end function

' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 lphDC as HDC ptr
function ddSurface_17_GetDC(P1,P2) as hresult
  DirectLock(DDMUTEX)
  #ifdef MyDebugErr
  if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then
    lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
  end if
  #endif
  #ifdef MyDebugX
  ShowInterfaceType(pTHIS)
  Cout("IDirectDraw::Surface.GetDC (17)"+chr$(13,10)+ _
  " > THIS: "+hex$(cast(uinteger,pTHIS))+ _
  " DCptr:"+hex$(cast(uinteger,lphDC))+"  Primary:" & pThis->Primary)
  #endif
  #if 0
  with *lpDDPixelFormat
    .dwSize = sizeof(DDPIXELFORMAT)
    select case pTHIS->bpp    
    case 8     
      .dwflags = DDPF_RGB or DDPF_PALETTEINDEXEDTO8 or DDPF_PALETTEINDEXED8
      .dwRGBBitCount = 8      
    case 16
      .dwflags = DDPF_RGB
      .dwRGBBitCount = 16    
      .dwRBitMask        = &b1111100000000000
      .dwGBitMask        = &b0000011111100000
      .dwBBitMask        = &b0000000000011111
      .dwRGBAlphaBitMask = &b0000000000000000
    case 32
      .dwflags = DDPF_RGB or DDPF_ALPHAPIXELS
      .dwRGBBitCount = 32
      .dwRBitMask        = &b00000000111111110000000000000000
      .dwGBitMask        = &b00000000000000001111111100000000
      .dwBBitMask        = &b00000000000000000000000011111111
      .dwRGBAlphaBitMask = &b11111111000000000000000000000000
    end select
  end with
  #endif
  'dim as hwnd TMPWND = GetDesktopWindow()
  'static as hdc TMPDC
  'TMPDC = GetDC(TMPWND)
  'lcout("Tmpdc: " & TMPDC)
  '*lphDC = TMPDC
  DirectUnlock(DDMUTEX)
  return DD_OK
end function  
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 lpDDPixelFormat as DDPIXELFORMAT ptr
function ddSurface_21_GetPixelFormat(P1,P2) as hresult
  DirectLock(DDMUTEX)
  #ifdef MyDebugErr
  if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then
    lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
  end if
  #endif
  #ifdef MyDebugX
  ShowInterfaceType(pTHIS)
  Cout("IDirectDraw::Surface.GetPixelFormat (21)"+chr$(13,10)+ _
  " > THIS: "+hex$(cast(uinteger,pTHIS))+ _
  " Format:"+hex$(cast(uinteger,lpDDPixelFormat))+"  Primary:" & pThis->Primary)
  #endif
  with *lpDDPixelFormat
    .dwSize = sizeof(DDPIXELFORMAT)
    select case pTHIS->bpp    
    case 8     
      .dwflags = DDPF_RGB or DDPF_PALETTEINDEXEDTO8 or DDPF_PALETTEINDEXED8
      .dwRGBBitCount = 8      
    case 16
      .dwflags = DDPF_RGB
      .dwRGBBitCount = 16    
      .dwRBitMask        = &b1111100000000000
      .dwGBitMask        = &b0000011111100000
      .dwBBitMask        = &b0000000000011111
      .dwRGBAlphaBitMask = &b0000000000000000
    case 32
      .dwflags = DDPF_RGB or DDPF_ALPHAPIXELS
      .dwRGBBitCount = 32
      .dwRBitMask        = &b00000000111111110000000000000000
      .dwGBitMask        = &b00000000000000001111111100000000
      .dwBBitMask        = &b00000000000000000000000011111111
      .dwRGBAlphaBitMask = &b11111111000000000000000000000000
    end select
  end with
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 lpDDSurfaceDesc as DDSurfaceDesc ptr
function ddSurface_22_GetSurfaceDesc(P1,P2) as hresult
  DirectLock(DDMUTEX)
  #ifdef MyDebugErr
  if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then
    lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
  end if
  #endif
  #ifdef MyDebugX
  ShowInterfaceType(pTHIS)
  Cout("IDirectDraw::Surface.GetSurfaceDesc (22)"+chr$(13,10)+ _
  " > THIS: "+hex$(cast(uinteger,pTHIS))+ _
  " Desc:"+hex$(cast(uinteger,lpDDSurfaceDesc))+"  Primary:" & pThis->Primary)
  #endif
  with *lpDDSurfaceDesc
    .dwSize = sizeof(DDSurfaceDesc)
    .dwWidth = pTHIS->Wid
    .dwHeight = pTHIS->Hei
    .lPitch = pTHIS->Pitch
    .dwFlags = DDSD_HEIGHT or DDSD_WIDTH or DDSD_PITCH or DDSD_PIXELFORMAT
  end with
  with lpDDSurfaceDesc->ddpfPixelFormat
    .dwSize = sizeof(DDPIXELFORMAT)
    select case pTHIS->bpp    
    case 8     
      .dwflags = DDPF_RGB or DDPF_PALETTEINDEXEDTO8 or DDPF_PALETTEINDEXED8
      .dwRGBBitCount = 8      
    case 16
      .dwflags = DDPF_RGB
      .dwRGBBitCount = 16    
      .dwRBitMask        = &b1111100000000000
      .dwGBitMask        = &b0000011111100000
      .dwBBitMask        = &b0000000000011111
      .dwRGBAlphaBitMask = &b0000000000000000
    case 32
      .dwflags = DDPF_RGB or DDPF_ALPHAPIXELS
      .dwRGBBitCount = 32
      .dwRBitMask        = &b00000000111111110000000000000000
      .dwGBitMask        = &b00000000000000001111111100000000
      .dwBBitMask        = &b00000000000000000000000011111111
      .dwRGBAlphaBitMask = &b11111111000000000000000000000000
    end select
  end with
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
function ddSurface_24_IsLost(P1) as hresult
  '#ifdef MyDebugQuick
  'Cout("IDirectDraw::Surface.IsLost (24)"+chr$(13,10)+ _
  '" > THIS: "+hex$(cast(uinteger,pTHIS)))  
  '#endif  
  if CURRDEVICE andalso pTHIS->IsLost then
    return DDERR_SURFACELOST    
  else
    return DD_OK
  end if
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 lpDestRect as rect ptr
#define P3 lpDDSurfaceDesc as DDSURFACEDESC ptr
#define P4 dwFlags as dword
#define P5 hEvent as handle
function ddSurface_25_Lock(P1,P2,P3,P4,P5) as hresult  
  'if CURRDEVICE then return DD_OK
  DirectLock(DDMUTEX)  
  'if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then
  '  lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
  'end if
  #ifdef MyDebugX
    'ShowInterfaceType(pTHIS)
    dim as string STMP
    STMP = ""  
    if (dwFlags and DDLOCK_EVENT)            then STMP += "Event "
    if (dwFlags and DDLOCK_NOSYSLOCK)        then STMP += "NoSysLock "
    if (dwFlags and DDLOCK_READONLY)         then STMP += "ReadOnly "
    if (dwFlags and DDLOCK_SURFACEMEMORYPTR) then STMP += "SurfacePtr "
    if (dwFlags and DDLOCK_WAIT)             then STMP += "Wait "
    if (dwFlags and DDLOCK_WRITEONLY)        then STMP += "WriteOnly "
    #ifdef MyDebugQuick
      if STMP = "" then STMP = "--"
    #endif
    if len(STMP) then
      Cout("IDirectDraw::Surface.Lock (25)"+chr$(13,10)+ _
      " > THIS: "+hex$(cast(uinteger,pTHIS))+ _
      " Rect:"+hex$(cast(uinteger,lpDestRect))+ _
      " Desc:"+hex$(cast(uinteger,lpDDSurfaceDesc))+" Flags: "+STMP+"  Primary:" & pThis->Primary)
    end if
  #endif  
  if lpDDSurfaceDesc->dwSize = 0 then 
    #ifdef MyDebugZ
      lcout("Error: Invalid SurfaceDesc size (DDERR_INVALIDPARAMS)")
    #endif
    DirectUnlock(DDMUTEX)
    ddrawError(DDERR_INVALIDPARAMS)
  end if  
  with *pTHIS
    if .Locked then 
      #ifdef MyDebugZ
        lcout("Error: Surface is already locked (DDERR_SURFACEBUSY)")
      #endif
      DirectUnlock(DDMUTEX)
      ddrawError(DDERR_SURFACEBUSY)
    else 
      .Locked=1
    end if    
  end with
  with *lpDDSurfaceDesc
    .dwFlags = DDSD_WIDTH or DDSD_HEIGHT or DDSD_PITCH or DDSD_LPSURFACE
    .dwWidth = pTHIS->wid
    .dwHeight = pTHIS->hei
    .lPitch = pTHIS->pitch
    .lpSurface = pTHIS->DataPtr    
  end with  
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 hDC as hdc
function ddSurface_26_ReleaseDC(P1,P2) as hresult
  DirectLock(DDMUTEX)
  #ifdef MyDebugErr
  if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then
    lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
  end if
  #endif
  #ifdef MyDebugX
  ShowInterfaceType(pTHIS)
  Cout("IDirectDraw::Surface.ReleaseDC (26)"+chr$(13,10)+ _
  " > THIS: "+hex$(cast(uinteger,pTHIS))+ _
  " HDC:"+hex$(cast(uinteger,hdc))+"  Primary:" & pThis->Primary)
  #endif  
  'dim as hwnd TMPWND = GetDesktopWindow()
  'releaseDC(TMPWND,HDC)
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
#define P1 pTHIS as ddSurfaceObject ptr
function ddSurface_27_Restore(P1) as hresult
  #ifdef MyDebugQuick
  Cout("IDirectDraw::Surface.Restore (24)"+chr$(13,10)+ _
  " > THIS: "+hex$(cast(uinteger,pTHIS))+"  Primary:" & pThis->Primary)  
  #endif  
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 DDCLIPPER as ddClipperObject ptr
function ddSurface_28_SetClipper(P1,P2) as hresult
  #ifdef MyDebugErr
  if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then
    lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
  end if
  #endif
  #ifdef MyDebugX
  Cout("IDirectDraw::Surface.SetClipper (28)" + chr$(13,10) + _
  " > THIS: "+hex$(cast(uinteger,pTHIS),8)+ _
  " Clipper: "+hex$(cast(uinteger,DDCLIPPER),8)+"  Primary:" & pThis->Primary)
  #endif
  with *pTHIS
    .Clip = DDCLIPPER    
  end with  
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 dwFlags as dword
#define P3 lpDDColorKey as DDColorKey ptr
function ddSurface_29_SetColorKey(P1,P2,P3) as hresult
  #ifdef MyDebugErr
  if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then
    lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
  end if
  #endif
  #ifdef MyDebugX
  dim as string DTMP
  if (dwFlags and DDCKEY_COLORSPACE) then DTMP += "ColorSpace "
  if (dwFlags and DDCKEY_DESTBLT) then DTMP += "DestBlit "
  if (dwFlags and DDCKEY_DESTOVERLAY) then DTMP += "DestOverlay "
  if (dwFlags and DDCKEY_SRCBLT) then DTMP += "SrcBlit "
  if (dwFlags and DDCKEY_SRCOVERLAY) then DTMP += "SrcOverlay "    
  Cout("IDirectDraw::Surface.SetColorKey (29)" + chr$(13,10) + _
  " > THIS: "+hex$(cast(uinteger,pTHIS),8)+ _
  " ColorKey: "+hex$(cast(uinteger,lpDDColorKey),8)+" Flags: "+DTMP+"  Primary:" & pThis->Primary)
  #endif
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 DDPALETTE as ddPaletteObject ptr
function ddSurface_31_SetPalette(P1,P2) as hresult
  DirectLock(DDMUTEX)
  'if pTHIS->Primary=0 andalso pTHIS->ID <> -1 or pTHIS->refcnt then
  '  lcout("{{{{{{{{{{{{{{ ACTION REQUIRED [" & hexptr(pTHIS) & "] }}}}}}}}}}}}}}} - " & __FUNCTION__ & ":" & __LINE__)
  'end if
  #ifdef MyDebugX
  Cout("IDirectDraw::Surface.SetPalette (31)" + chr$(13,10) + _
  " > THIS: "+hex$(cast(uinteger,pTHIS),8)+ _
  " Palette: "+hex$(cast(uinteger,DDPALETTE),8)+"  Primary:" & pThis->Primary)
  #endif
  with *pTHIS
    .Pal = DDPALETTE: BackBuffer.pal = DDPALETTE
    #if 0
    if 0 andalso .Primary andalso .bpp = 8 then
      if COPYBUFF then
        static as integer TMPPAL(255)
        for CNT as integer = 0 to DDPALETTE->Colors          
          with DDPALETTE->Pal(CNT).c
            TMPPAL(CNT) = (.G shr 3)+((.G shr 2) shl 5)+((.R shr 3) shl 11)
          end with
        next CNT
        for CNT as integer = 0 to 65535
          dim as integer C1=CNT and 255,C2=CNT shr 8
          PAL16(CNT) = TMPPAL(C1) or (TMPPAL(C2) shl 16)
        next CNT       
      else
        for CNT as integer = 0 to DDPALETTE->Colors
          with DDPALETTE->Pal(CNT).c
            Palette CNT,.r,.g,.b
          end with
        next CNT
      end if
    end if
    #endif
    if .Primary then PALETTECHANGED = 1
  end with  
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS as ddSurfaceObject ptr
#define P2 lpSurfaceData as any ptr
function ddSurface_32_Unlock(P1,P2) as hresult
  DirectLock(DDMUTEX)  
  with *pTHIS
    
    #ifdef MyDebugQuick  
      if .primary then
        ShowInterfaceType(pTHIS)
        Cout("IDirectDraw::Surface.Unlock (32)"+chr$(13,10)+ _
        " > THIS: "+hex$(cast(uinteger,pTHIS))+ _  
        " Data:"+hex$(cast(uinteger,lpSurfaceData))+"  Primary:" & pThis->Primary)      
      end if
    #else
      #ifdef MyDebugD3D
        if .primary=0 then
          Cout("IDirectDraw::Surface.Unlock (32)"+chr$(13,10)+ _
          " > THIS: "+hex$(cast(uinteger,pTHIS))+ _  
          " Data:"+hex$(cast(uinteger,lpSurfaceData))+"  Primary:" & pThis->Primary)
        end if
      #endif
    #endif
    
    if .Locked=0 then 
      #ifdef MyDebugZ
      lcout("Error: Surface not locked (DDERR_NOTLOCKED)")
      #endif
      DirectUnlock(DDMUTEX)
      ddrawError(DDERR_NOTLOCKED)      
    end if
    .Locked=0
    #ifdef Enable3D
      #ifdef DumpTextures        
        if (.desc.ddsCaps.dwcaps and DDSCAPS_TEXTURE) then
          dim as uinteger pTemp(2) = {cuint(.DataPtr),.pitch*.hei,.pitch*.hei}
          var sName = MD5(*cast(string ptr,@pTemp(0)))+".bmp"
          lcout("Dumping: "+sName)
          if .bpp = 8 then
            var hSz = sizeof(bitmapfileheader)+sizeof(bitmapinfoheader)+256*4
            dim as bitmapfileheader bfh = type(cvshort("BM"),hSz+(.pitch*.hei),0,0,hSz)
            dim as bitmapinfoheader bih = type(sizeof(bitmapinfoheader), _
            .pitch,-.hei,1,8,BI_RGB,0,null,null,null,null)
            var f = freefile()
            if open("TexDump\"+sName for binary access write as #f) then
              lcout("Failed to dump!!! :(")
            else
              put #f,,bfh
              put #f,,bih
              var pPal = .pal
              if pPal = 0 then pPal = BACKBUFFER.pal
              if pPal = 0 then pPal = FRONTBUFFER.pal
              if ppal=0 then
                lcout("no pal????")
                for CNT as integer = 0 to 255
                  var iPix = rgba(CNT,CNT,CNT,0)
                  put #f,,iPix
                next CNT
              else
                .pal = pPal
                put #f,,ppal->pal()
              end if
              put #f,,*cptr(ubyte ptr,.fbimage+1),.pitch*.hei
              close #f
            end if
          else
            bsave("TexDump\"+sName,.fbimage)
          end if
          #if 0
            dim as fb.image ptr pImage = ImageCreate(.wid,.hei,0,32)
            dim as any ptr pIn = .DataPtr,pOut = pImage+1
            dim as integer iWid=.wid,iHei=.hei
            Convert16to32(pIn,pOut,iWid,iHei,2)
            png_save("TexDump\"+sName,pImage)
            imagedestroy(pImage)
          #endif
        end if
      #endif      
      if .ID > 0 then .NeedUpdate = 1
    #endif
      
    if .Primary then
      if .bpp=8 then        
        if .pal = 0 then
          #ifdef MyDebugErr
          lcout("No Palette defined for Primary surface")
          #endif
        else
          for CNT as integer = 0 to 255
            with .pal->Pal(CNT).c            
              #ifdef Render_OpenGL
              ogl.fb_gfx->device_palette[CNT] = rgb(.b,.g,.r)
              #else
              palette CNT,.r,.g,.b
              #endif          
            end with
          next CNT
        end if    
        if FLIPPED=0 andalso CURRDEVICE=0 then Fbgfx_Update(1)
      end if
      FLIPPED=0
    end if
    
  end with  
  DirectUnlock(DDMUTEX)
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS   as ddSurfaceObject ptr
#define P2 dwFlags as dword
function ddSurface_37_PageLock(P1,P2) as hresult
  #ifdef MyDebugX
  Cout("IDirectDraw::Surface.PageLock (37)"+ _
  " > THIS: "+hex$(cast(uinteger,pTHIS))+"  Flags:"+hex$(dwFlags)+"  Primary:" & pThis->Primary)  
  #endif  
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 pTHIS   as ddSurfaceObject ptr
#define P2 dwFlags as dword
function ddSurface_38_PageUnlock(P1,P2) as hresult
  #ifdef MyDebugX
  Cout("IDirectDraw::Surface.PageUnlock (38)"+ _
  " > THIS: "+hex$(cast(uinteger,pTHIS))+"  Flags:"+hex$(dwFlags)+"  Primary:" & pThis->Primary)  
  #endif  
  return DD_OK
end function
' ****************************************************************************************

sub SurfaceFuncs(VTABLE() as any ptr)
  dim as any ptr PROTOTABLE
  asm mov dword ptr [PROTOTABLE], offset _ddSurfaceProtoTable_
  for CNT as integer = 0 to 35+3
    VTABLE(CNT) = PROTOTABLE+CNT*32
  next CNT
  VTABLE(00) = @ddSurface_0_QueryInterface
  VTABLE(02) = @ddSurface_2_Release  
  VTABLE(05) = @ddSurface_5_Blt
  VTABLE(07) = @ddSurface_7_BltFast
  VTABLE(11) = @ddSurface_11_Flip
  VTABLE(12) = @ddSurface_12_GetAttachedSurface
  VTABLE(13) = @ddSurface_13_GetBltStatus
  VTABLE(17) = @ddSurface_17_GetDC
  VTABLE(21) = @ddSurface_21_GetPixelFormat
  VTABLE(22) = @ddSurface_22_GetSurfaceDesc
  VTABLE(24) = @ddSurface_24_IsLost
  VTABLE(25) = @ddSurface_25_Lock
  VTABLE(26) = @ddSurface_26_ReleaseDC
  VTABLE(27) = @ddSurface_27_Restore
  VTABLE(28) = @ddSurface_28_SetClipper
  VTABLE(29) = @ddSurface_29_SetColorKey
  VTABLE(31) = @ddSurface_31_SetPalette
  VTABLE(32) = @ddSurface_32_Unlock
  VTABLE(37) = @ddSurface_37_PageLock
  VTABLE(38) = @ddSurface_38_PageUnlock

end sub