function gfxSubClass (HWND as hwnd,UMSG as integer,WPARAM as wparam,LPARAM as lparam) as lresult
  'static as integer icnt
  'icnt += 1
  'printf(!"gfxSubClass! %i\r",icnt)
  'while CantLoseFocus=0
  '  sleepex 1,1
  'wend
  
  select case UMSG
  case WM_ACTIVATE
    'if CantLoseFocus then
      if loword(wparam) = WA_CLICKACTIVE then
        Setforegroundwindow(DDRAWCOOP.hwnd)
      end if
    'end if
  end select
  
  return CallWindowProc(ORGPROC,HWND,UMSG,WPARAM,LPARAM)
end function
sub fbGfxResize(FIRST as integer=0)
  scope
    if FIRST then
      dim as zstring*512 TITLE    
      GetWindowText(DDRAWCOOP.hwnd,TITLE,512)
      'WindowTitle "fbgfx: "+TITLE
    end if
    dim as rect DESKRECT 
    GetClientRect(GetDesktopWindow(),@DESKRECT)
    
    with DESKRECT
      dim as integer RESX=WINX,RESY=WINY   
      if RESX=0 then RESX=DDRAWCOOP.wwid : RESY=DDRAWCOOP.whei        
      'dim as integer RESX=dwWidth,RESY=dwHeight
      .right -= .left: .bottom -= .top
      if .right < RESX then RESX = .right
      if .bottom < RESY then RESY = .bottom
      if FULLSCREEN then RESX = .right:RESY = .bottom
      .left = (.right-RESX)/2: .top = (.bottom-RESY)/2
      
      if FIRST then SetParent(FBWND,DDRAWCOOP.hwnd)
      'Screencontrol(fb.SET_WINDOW_POS,0,0)
      SetWindowPos(FBWND,null,0,0,RESX,RESY,SWP_NOZORDER)
      
      if FIRST then ShowWindow(DDRAWCOOP.hwnd,SW_SHOW)
      'SetWindowPos(DDRAWCOOP.hwnd,HWND_BOTTOM,x,y,dwWidth,dwHeight,null)
      dim as long TMP    
      if FULLSCREEN then 
        TMP = GetWindowLong(DDRAWCOOP.hwnd,GWL_STYLE)
        TMP = (TMP and (not WS_OVERLAPPEDWINDOW)) or WS_POPUPWINDOW
        SetWindowLong(DDRAWCOOP.hwnd,GWL_STYLE,TMP)
      else
        TMP = GetWindowLong(DDRAWCOOP.hwnd,GWL_STYLE)
        TMP = (TMP and (not WS_POPUPWINDOW)) or TMP or WS_OVERLAPPEDWINDOW
        SetWindowLong(DDRAWCOOP.hwnd,GWL_STYLE,TMP)
        dim as RECT ADJRECT
        ADJRECT.right = RESX: ADJRECT.bottom = RESY
        AdjustWindowRect(@ADJRECT,TMP,False)
        RESX = ADJRECT.right-ADJRECT.left
        RESY = ADJRECT.bottom-ADJRECT.top
      end if  
      'if ISMAIN=0 then .left = -1024
      SetWindowPos(DDRAWCOOP.hwnd,HWND_BOTTOM,.left,.top,RESX,RESY,SWP_NOZORDER)
      if FIRST then SetForegroundWindow(DDRAWCOOP.hwnd)
      
      
    end with    
  end scope  
end sub
function dwSubClass (HWND as hwnd,UMSG as integer,WPARAM as wparam,LPARAM as lparam) as lresult
  if DWORGPROC=0 then return 0
  'return CallWindowProc(DWORGPROC,HWND,UMSG,WPARAM,LPARAM)
  'cout("Message: " & HWND & " / " & UMSG)
  static as integer icnt
  if icnt=0 then
    icnt += 1  
    select case UMSG    
    case WM_CLOSE
      for CNT as integer = 0 to 15
        screenunlock
      next CNT      
      screen 0
      ExitProcess(0)
    case WM_SYSKEYUP
      if wparam = VK_RETURN then
        FULLSCREEN xor= 1
        fbGfxResize()      
      end if
    case WM_NCDESTROY
      'screenunlock
      'screen 0
      'ExitProcess(0)
    end select
    icnt -= 1
  end if
  return CallWindowProc(DWORGPROC,HWND,UMSG,WPARAM,LPARAM)
end function

sub IDirectDrawPrototype()
  #ifdef MyDebugX    
  Cout("IDirectDraw Function not implemented: " & IDDPROTOID)
  Cout("Press Any Key to exit...")
  console.sleep()
  #endif  
  'end
  exit sub
  
  asm
    .balign 32
    _DDrawProtoTable_:  
    #macro ProtoNum(X)
    mov dword ptr [IDDPROTOID],X
    jmp IDirectDrawPrototype
    .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)
  end asm  
  
end sub
' ****************************************************************************************

UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
#define P2 IID as GUID ptr
#define P3 IOBJECT as any ptr ptr
function IDirectDraw_0_QueryInterface(P1,P2,P3) as hresult
  
  return DDERR_INVALIDOBJECT
  
  dim as string TMPQUERYS = "Unknown",TMPIID = "0x" + hex$(cast(any ptr,IID),8)
  dim as integer FUNCRESULT=DDERR_INVALIDOBJECT,QUERYRESULT = -1 
  
  if IID andalso isBadReadPtr(IID,sizeof(GUID))=0 then    
    #ifdef MyDebugX
    TMPIID = ""
    for CNT as integer = 0 to sizeof(GUID)-1
      TMPIID += hex$(cptr(ubyte ptr,IID)[CNT],2)
    next CNT
    #endif
    QUERYRESULT = CheckGUID(IID,TMPQUERYS)    
  end if
  
  if QUERYRESULT <> -1 then    
    select case QUERYRESULT
    case giIDirect3D2
      *IOBJECT = new iDirect3D2Object
      iDirect3D2Funcs(IDIRECT3D2_FUNCS())  
      with *cptr(iDirect3D2Object ptr,*IOBJECT)
        .VTABLE = @IDIRECT3D2_FUNCS(0)
        .Interface = itDirect3D2
      end with  
      FUNCRESULT = DD_OK
    case giIDirectDraw2
      *IOBJECT = new iDirectDraw2Object
      iDirectDraw2Funcs(IDIRECTDRAW2_FUNCS())  
      with *cptr(iDirectDraw2Object ptr,*IOBJECT)
        .VTABLE = @IDIRECTDRAW2_FUNCS(0)
        .Interface = itDirectDraw2
      end with        
      FUNCRESULT = DD_OK
    case else 
      *IOBJECT = new ddSpecialObject
      SpecialFuncs(DDSPECIAL_FUNCS())  
      with *cptr(ddSpecialObject ptr,*IOBJECT)
        .VTABLE = @DDSPECIAL_FUNCS(0)
        .Interface = itSpecial
      end with  
      FUNCRESULT = DD_OK
    end select  
  end if
  
  #ifdef MyDebugX  
  Cout("IDirectDraw.QueryInterface (0)" + chr$(13,10) + _
  " >> TDDRAW: "+hex$(cast(uinteger,TDDRAW),8) + _
  " IID: " + TMPIID + " - Query: "+TMPQUERYS+" = "+HexPtr(*IOBJECT))
  #endif  
  return FUNCRESULT
  
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
function IDirectDraw_2_Release(P1) as hresult
  #ifdef MyDebugX
  Cout("IDirectDraw.Release (2)" + chr$(13,10) + _
  " >> TDDRAW: "+hex$(cast(uinteger,TDDRAW),8))
  #endif
  screenunlock
  screen 0 
  BACKBUFFER.DataPtr=0
  FRONTBUFFER.DataPtr=0
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
function IDirectDraw_3_Compact(P1) as hresult
  #ifdef MyDebugX
  Cout("IDirectDraw.Compact (3)" + chr$(13,10) + _
  " >> TDDRAW: "+hex$(cast(uinteger,TDDRAW),8))
  #endif  
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
#define P2 dwFlags as dword
#define P3 LPDIRECTDRAWCLIPPER as ddClipperObject ptr ptr
#define P4 pUnkOuter as any ptr
function IDirectDraw_4_CreateClipper(P1,P2,P3,P4) as hresult
  #ifdef MyDebugX  
  Cout("IDirectDraw.CreateClipper (5)" + chr$(13,10) + _
  " > Object:"+hex$(cast(uinteger,TDDRAW))+ _  
  " ClipObject:"+hex$(cast(uinteger,LPDIRECTDRAWCLIPPER)))
  #endif  
  
  *LPDIRECTDRAWCLIPPER = new ddClipperobject
  ClipperFuncs(DDCLIPPER_FUNCS())
  
  dim as integer ENTRYCNT
  
  with **LPDIRECTDRAWCLIPPER
    .VTABLE = @DDCLIPPER_FUNCS(0)    
    .Interface = itClipper
  end with
  
  return DD_OK
  
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
#define P2 dwFlags as dword
#define P3 lpColorTable as PaletteEntry ptr
#define P4 LPDIRECTDRAWPALETTE as ddPaletteObject ptr ptr
#define P5 pUnkOuter as any ptr
function IDirectDraw_5_CreatePalette(P1,P2,P3,P4,P5) as hresult
  #ifdef MyDebugX
  dim as string STMP
  if (dwFlags and DDPCAPS_1BIT)        then STMP += "1-bit "
  if (dwFlags and DDPCAPS_2BIT)        then STMP += "2-bit "
  if (dwFlags and DDPCAPS_4BIT)        then STMP += "4-bit "
  if (dwFlags and DDPCAPS_8BITENTRIES) then STMP += "as8bit "
  if (dwFlags and DDPCAPS_8BIT)        then STMP += "8-bit "
  if (dwFlags and DDPCAPS_ALLOW256)    then STMP += "AllEntries "
  Cout("IDirectDraw.CreatePalette (5)" + chr$(13,10) + _
  " > Object:"+hex$(cast(uinteger,TDDRAW))+ _
  " Table:"+hex$(cast(uinteger,lpColorTable))+ _
  " PalObject:"+hex$(cast(uinteger,LPDIRECTDRAWPALETTE))+" Flags:"+STMP)
  #endif  
  
  *LPDIRECTDRAWPALETTE = new ddPaletteObject
  PaletteFuncs(DDPALETTE_FUNCS())
  
  dim as integer ENTRYCNT
  if (dwFlags and DDPCAPS_1BIT) then ENTRYCNT = 2
  if (dwFlags and DDPCAPS_2BIT) then ENTRYCNT = 4
  if (dwFlags and DDPCAPS_4BIT) then ENTRYCNT = 16
  if (dwFlags and DDPCAPS_8BIT) then ENTRYCNT = 256
  
  with **LPDIRECTDRAWPALETTE
    .VTABLE = @DDPALETTE_FUNCS(0)
    .Interface = itPalette
    .Colors = ENTRYCNT
    for CNT as integer = 0 to ENTRYCNT-1
      .Pal(CNT).c.r = lpColorTable[CNT].peRed
      .Pal(CNT).c.g = lpColorTable[CNT].peGreen
      .Pal(CNT).c.b = lpColorTable[CNT].peBlue
    next CNT
  end with
  
  return DD_OK
  
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
#define P2 lpDDSurfaceDesc as DDSURFACEDESC ptr
#define P3 lplpDDSurface as ddSurfaceObject ptr ptr
#define P4 pUnkOuter as any ptr
function IDirectDraw_6_CreateSurface(P1,P2,P3,P4) as hresult  
  #ifdef MyDebugX
  Cout("IDirectDraw.CreateSurface (6)" + chr$(13,10) + _
  " >> Object: "+hex$(cast(uinteger,TDDRAW),8)+ _
  " - lpDDSurfaceDesc: "+hex$(cast(integer,lpDDSurfaceDesc),8)+ _
  " - lplpDDSurface: "+hex$(cast(integer,lplpDDSurface),8))
  #endif    
  if lpDDSurfaceDesc = 0 then return DDERR_INVALIDPARAMS  
  if lplpDDSurface  = 0 then return DDERR_INVALIDPARAMS  
  
  dim as byte PRIMARY  
  static as ddSurfaceObject PRIMARYSURFACE
  
  scope
    dim as string STMP    
    with *lpDDSurfaceDesc    
      #ifdef MyDebugX
      LCout(" >> Size > width: " & .dwWidth & " - Height: " & .dwHeight)    
      #endif
      if (.dwflags and DDSD_CAPS) then        
        with lpDDSurfaceDesc->ddsCaps
          if (.dwcaps and DDSCAPS_PRIMARYSURFACE) then 
            PRIMARY = 1
          end if
          #ifdef MyDebugX
          STMP = ""
          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 "
          LCout(" >> Capabilites > "+STMP)
          #endif
        end with
      end if            
      if (.dwflags and DDSD_PIXELFORMAT) then        
        with lpDDSurfaceDesc->ddpfPixelFormat
          #ifdef MyDebugX
          STMP = ""
          if (.dwflags and DDPF_ALPHA)          then STMP += "OnlyAlpha "
          if (.dwflags and DDPF_ALPHAPIXELS)    then STMP += "Alpha "
          if (.dwflags and DDPF_ALPHAPREMULT)   then STMP += "PreMul "
          if (.dwflags and DDPF_FOURCC)         then STMP += "FourCC "
          'if (.dwflags and DDPF_PALETTEINDEXED) then STMP += "Palette "
          if (.dwflags and DDPF_RGB)            then STMP += "RGB "
          if STMP = "" then STMP = "--"
          LCout(" >> Pixel > bits: " & .dwRGBBitCount & " - flags: " & STMP)
          #endif
        end with
      end if
    end with
  end scope
  
  if DDSURFACE_FUNCS(0)=0 then
    SurfaceFuncs(DDSURFACE_FUNCS())
  end if  
  
  if PRIMARY then    
    dim as integer w,h,d,b,p,r
    screeninfo w,h,d,b,p,r
    if USEHQ then w/=2:h/=2:p/=2
    if COPYBUFF andalso REALBPP=8 then b/=2:p/=2
    with  PRIMARYSURFACE
      .VTABLE = @DDSURFACE_FUNCS(0)
      .Interface = itSurface
      .wid = w
      .hei = h
      .bpp = d
      .pitch = p
      .Primary = 1
      if COPYBUFF andalso BACKIMG then
        .DataPtr = BACKIMG+sizeof(fb.image)
      else
        .DataPtr = screenptr
      end if
      *lplpDDSurface = @.VTABLE
    end with
  else
    dim as ddSurfaceObject ptr MYSURFACE = new ddSurfaceObject
    *lplpDDSurface = MYSURFACE
    dim as integer w,h,d,b,p,r
    with *lpDDSurfaceDesc          
      w = .dwWidth
      h = .dwHeight
      d = .ddpfPixelFormat.dwRGBBitCount      
    end with
    if d = 15 then d = 16
    if d <> 16 and d<>8 then d=32    
    with *MYSURFACE      
      .VTABLE = @DDSURFACE_FUNCS(0)      
      .Interface = itSurface
      .Primary = 0      
      .wid = w      
      .hei = h      
      .bpp = d      
      .fbImage = ImageCreate(w,h,0,d)      
      .DataPtr = .fbimage+1      
      .pitch = .fbimage->pitch
    end with    
  end if
  #ifdef MyDebugZ
  lCout(" > Created Surface: " & hex$(cast(uinteger,*lplpDDSurface),8))
  #endif
  
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
#define P2 dwFlags as dword
#define P3 lpDDSurfaceDesc as DDSURFACEDESC ptr
#define P4 lpContext as any ptr
#define P5 lpEnumModesCallback as any ptr
function IDirectDraw_8_EnumDisplayModes(P1,P2,P3,P4,P5) as hresult
  dim F as function (as DDSURFACEDESC ptr, as any ptr) as hresult
  dim as integer SMODE
  dim as DDSURFACEDESC DESC
  dim as integer BITS,ENUMCOUNT
  
  #ifdef MyDebugX
  Cout("IDirectDraw.EnumDisplayModes (8)" + chr$(13,10) + _
  " >> TDDRAW: "+hex$(cast(uinteger,TDDRAW),8)+ _
  " - Surface: "+hex$(cast(integer,lpDDSurfaceDesc),8)+ _
  " - Callback: "+hex$(cast(integer,lpEnumModesCallback),8)+ _
  " - Context: " & lpContext)
  #endif
  
  if lpEnumModesCallback=0 then return DDERR_INVALIDPARAMS
  F=lpEnumModesCallback
  if lpDDSurfaceDesc then
    BITS = lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount
  end if
  
  with DESC
    .dwSize = sizeof(DDSURFACEDESC)
    .dwFlags = DDSD_ALL
    .dwBackBufferCount = 2
    .dwRefreshRate = 60
    .ddscaps.dwCaps = -1
    with DESC.ddpfPixelFormat
      .dwflags = DDPF_RGB or DDPF_PALETTEINDEXEDTO8 or DDPF_PALETTEINDEXED8
      .dwRGBBitCount = 8      
    end with
    .dwWidth = 320 : .dwHeight = 200: .lPitch = .DwWidth: F(@DESC,lpContext)
    .dwWidth = 320 : .dwHeight = 240: .lPitch = .DwWidth: F(@DESC,lpContext)
    .dwWidth = 400 : .dwHeight = 300: .lPitch = .DwWidth: F(@DESC,lpContext)
    .dwWidth = 512 : .dwHeight = 384: .lPitch = .DwWidth: F(@DESC,lpContext)
  end with
  
  do
    if BITS=0 or BITS=8 then
      with DESC.ddpfPixelFormat
        .dwflags = DDPF_RGB or DDPF_PALETTEINDEXEDTO8 or DDPF_PALETTEINDEXED8
        .dwRGBBitCount = 8      
      end with
      SMODE = ScreenList(8)  
      while SMODE
        with DESC
          .dwWidth = HiWord(SMODE)
          .dwHeight = LoWord(SMODE)
          '.lXPitch = 1
          .lPitch = .DwWidth*1 'lXPitch
          '.dwSurfaceSize = .lPitch*.dwHeight 
          'lCout("Mode: " & .dwWidth & "x" & .dwHeight & "x8@60")
        end with      
        ENUMCOUNT += 1
        if F(@DESC,lpContext) =  DDENUMRET_CANCEL then exit do
        SMODE = ScreenList()
      wend
    end if
    
    if BITS=0 or BITS=16 then
      with DESC.ddpfPixelFormat
        .dwflags = DDPF_RGB
        .dwRGBBitCount = 16    
        .dwRBitMask        = &b1111100000000000
        .dwGBitMask        = &b0000011111100000
        .dwBBitMask        = &b0000000000011111
        .dwRGBAlphaBitMask = &b0000000000000000
      end with
      SMODE = ScreenList(16)  
      while SMODE
        with DESC
          .dwWidth = HiWord(SMODE)
          .dwHeight = LoWord(SMODE)
          '.lXPitch = 2
          .lPitch = .DwWidth*2 'lXPitch
          '.dwSurfaceSize = .lPitch*.dwHeight 
          'lCout("Mode: " & .dwWidth & "x" & .dwHeight & "x16@60")
        end with
        ENUMCOUNT += 1
        if F(@DESC,lpContext) =  DDENUMRET_CANCEL then exit do
        SMODE = ScreenList()
      wend
    end if
    
    if BITS<>8 and BITS<>16 then  
      with DESC.ddpfPixelFormat
        .dwflags = DDPF_RGB or DDPF_ALPHAPIXELS
        .dwRGBBitCount = 32
        .dwRBitMask        = &b00000000111111110000000000000000
        .dwGBitMask        = &b00000000000000001111111100000000
        .dwBBitMask        = &b00000000000000000000000011111111
        .dwRGBAlphaBitMask = &b11111111000000000000000000000000
      end with
      SMODE = ScreenList(32)  
      while SMODE
        with DESC
          .dwWidth = HiWord(SMODE)
          .dwHeight = LoWord(SMODE)
          '.lXPitch = 4
          .lPitch = .DwWidth*4 'lXPitch        
          '.dwSurfaceSize = .lPitch*.dwHeight 
          'lCout("Mode: " & .dwWidth & "x" & .dwHeight & "x32@60")
        end with
        ENUMCOUNT += 1
        if F(@DESC,lpContext) =  DDENUMRET_CANCEL then exit do
        SMODE = ScreenList()
      wend
    end if
  loop until 1
  
  #ifdef MyDebugX
  'LCout(" >> Enumerated " & ENUMCOUNT & " modes..." )
  #endif
  
  return DD_OK
  
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
function IDirectDraw_10_FlipToGDISurface(P1) as hresult  
  #ifdef MyDebugX
  Cout("IDirectDraw.FlipToGDISurface (10)" + chr$(13,10) + _
  " >> TDDRAW: "+hex$(cast(uinteger,TDDRAW),8))
  #endif
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
#define P2 lpDDDriverCaps as DDCAPS ptr
#define P3 lpDDEmulCaps as DDCAPS ptr
function IDirectDraw_11_GetCaps(P1,P2,P3) as hresult
  
  #ifdef MyDebugX
  Cout("IDirectDraw.GetCaps (11)" + chr$(13,10) + _
  " >> TDDRAW: "+hex$(cast(uinteger,TDDRAW),8)+ _
  " - lpDDDriverCaps: "+hex$(cast(integer,lpDDDriverCaps),8)+ _
  " - lpDDEmulCaps: "+hex$(cast(integer,lpDDEmulCaps),8))
  #endif
  
  if TDDRAW=0 then return DDERR_INVALIDOBJECT
  if lpDDDriverCaps=0 and lpDDEmulCaps=0 then 
    #ifdef MyDebugZ
    lcout("Error: both driver and emulated caps are null (invalid params)")
    #endif
    return DDERR_INVALIDPARAMS
  end if
  
  #macro TempCaps()
  if 0 then '.dwSize <> sizeof(DDCAPS) then 
    #ifdef MyDebugZ
    lcout("Error: invalid size of DDCAPS (invalid params)")
    #endif
    return DDERR_INVALIDPARAMS  
  end if    
  .dwCaps = -1
  .dwCaps2 = -1
  .dwCKeyCaps = -1
  .dwFXCaps = -1
  .dwFXAlphaCaps = -1
  .dwPalCaps = -1
  .dwSVCaps = -1
  .dwVidMemTotal = 16*1024*1024
  .dwVidMemFree = 16*1024*1024
  .dwMaxVisibleOverlays = 16
  #endMacro
  
  if lpDDDriverCaps then
    with *lpDDDriverCaps      
      TempCaps()
    end with
  end if
  if lpDDEmulCaps then
    with *lpDDEmulCaps
      TempCaps()
    end with
  end if
  
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
#define P2 lpDDSurfaceDesc as DDSURFACEDESC ptr
function IDirectDraw_12_GetDisplayMode(P1,P2) as hresult
  #ifdef MyDebugX
  Cout("IDirectDraw.GetDisplayMode (12)" + chr$(13,10) + _
  " >> TDDRAW: "+hex$(cast(uinteger,TDDRAW),8))
  #endif
  dim as integer w,h,d,b,p,r
  screeninfo w,h,d,b,p,r  
  if USEHQ then w/=2:h/=2:p/=2
  if COPYBUFF andalso REALBPP=8 then b/=2:p/=2
  if BACKBUFFER.DataPtr=0 then
    w=640:h=480:d=16:b=2:p=4:r=0
  end if
  
  with *lpDDSurfaceDesc
    .dwSize = sizeof(DDSURFACEDESC)
    .dwFlags = DDSD_ALL
    .dwBackBufferCount = 2
    .dwRefreshRate = r
    .ddscaps.dwCaps = -1
    .dwWidth = w
    .dwHeight = h
    .lPitch = p
    '.lXPitch = b
  end with  
  
  with lpDDSurfaceDesc->ddpfPixelFormat
    select case d
    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
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
function IDirectDraw_19_RestoreDisplayMode(P1) as hresult  
  #ifdef MyDebugX
  Cout("IDirectDraw.RestoreDisplayMode (19)" + chr$(13,10) + _
  " >> TDDRAW: "+hex$(cast(uinteger,TDDRAW),8))  
  #endif
  'if BACKIMG then ImageDestroy(BACKIMG):BACKIMG=0
  'screenunlock: screen 0
  return DD_OK
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
#define P2 HWND as hwnd
#define P3 DWFLAGS as dword
function IDirectDraw_20_SetCooperativeLevel(P1,P2,P3) as hresult
  dim as string SFLAGS
  dim as hresult RESU
  if (DWFLAGS and DDSCL_ALLOWMODEX)      then SFLAGS += "modex "
  if (DWFLAGS and DDSCL_ALLOWREBOOT)     then SFLAGS += "reboot "  
  if (DWFLAGS and DDSCL_EXCLUSIVE)       then SFLAGS += "exclusive "
  if (DWFLAGS and DDSCL_FULLSCREEN)      then SFLAGS += "full "
  if (DWFLAGS and DDSCL_NORMAL)          then SFLAGS += "normal "
  if (DWFLAGS and DDSCL_NOWINDOWCHANGES) then SFLAGS += "block"  
  #ifdef MyDebugX
  Cout("IDirectDraw.SetCooperativeLevel (20)" + chr$(13,10) + _
  " >> TDDRAW: "+hex$(cast(uinteger,TDDRAW),8)+" - HWND: "+ _
  hex$(cast(integer,HWND),8)+" - Flags: "+SFLAGS)
  #endif        
  
  if COPYBUFF = 0 then screenunlock
  DDRAWCOOP.hwnd = HWND            
  'with DDRAWCOOP
  '  SetWindowPos(.hwnd,HWND_NOTOPMOST,.wposx,.wposy,.wwid,.whei,null)
  '  dim as long TMP
  '  TMP = GetWindowLong(.hwnd,GWL_WNDPROC)
  '  if TMP <> cast(long,@dwSubClass) then
  '    'DWORGPROC = cast(any ptr,TMP)
  '    'SetWindowLong(.hwnd,GWL_WNDPROC,cast(long,@dwSubClass))
  '  end if      
  'end with
  SetForegroundWindow(DDRAWCOOP.hwnd)
  if COPYBUFF = 0 then screenlock
  
  'RESU = ddraw_SetCooperativeLevel(TDDRAW,HWND,DWFLAGS)    
  'ShowWindow(HWND,SW_HIDE)
  return DD_OK  
end function
' ****************************************************************************************
UndefAll()
#define P1 TDDRAW as DirectDrawObject ptr
#define P2 dwWidth as dword
#define P3 dwHeight as dword
#define P4 dwBPP as dword
#define P5 dwRefreshRate as dword
#define P6 dwFlags as dword
function IDirectDraw_21_SetDisplayMode(P1,P2,P3,P4) as hresult
  #ifdef MyDebugX
  Cout("IDirectDraw.SetDisplayMode (21)" + chr$(13,10) + _
  " >> Mode: " & dwWidth & "x" & dwHeight & "x" & dwBPP)
  #endif  
  dim as integer FLAG
  if dwWidth<>BACKBUFFER.wid or dwHeight<>BACKBUFFER.hei or dwHeight<>BACKBUFFER.bpp then
    'screencontrol(fb.SET_DRIVER_NAME,"gdi")
    if COPYBUFF=0 then
      for CNT as integer = 0 to 10
        screenunlock
      next CNT
    end if    
    const FLAGS = fb.GFX_NO_SWITCH or fb.gfx_no_frame or fb.gfx_high_priority
    if BACKIMG then Imagedestroy(BACKIMG):BACKIMG=0
    if BACKIMG2 then Imagedestroy(BACKIMG2):BACKIMG2=0    
    REALBPP=dwBPP    
    if COPYBUFF then
      dim as integer TMPWID=dwWidth,TMPHEI=dwHeight      
      if USEHQ then TMPWID shl= 1: TMPHEI shl= 1      
      screenres TMPWID,TMPHEI,16,1,FLAGS
      BACKIMG = ImageCreate(dwWidth,dwHeight,0,16)
      BACKIMG2 = ImageCreate(dwWidth,dwHeight,0,16)      
    else
      screenres dwWidth,dwHeight,dwBPP,1,FLAGS     
    end if    
    dim as integer x,y    
    screencontrol(fb.GET_WINDOW_HANDLE,*cptr(integer ptr,@FBWND))    
    screencontrol(fb.GET_WINDOW_POS,x,y)
    DDRAWCOOP.wwid=dwWidth:DDRAWCOOP.whei=dwHeight
    DDRAWCOOP.wposx=x:DDRAWCOOP.wposy=y
    'ORGPROC = cast(any ptr,SetWindowLong(FBWND,GWL_WNDPROC,cast(long,@gfxSubClass)))    
    fbGfxResize(True)    
  end if  
  if DDSURFACE_FUNCS(0)=0 then
    SurfaceFuncs(DDSURFACE_FUNCS())
  end if
  with BACKBUFFER
    .wid = dwWidth
    .hei = dwHeight
    .bpp = dwBPP
    .pitch = dwWidth*(dwBPP/8)
    .VTABLE = @DDSURFACE_FUNCS(0)
    .Interface = itSurface
    .Primary = 1
    .BackBuffer = 1
    .fbImage = 0
    if COPYBUFF andalso BACKIMG then
      .Dataptr = BACKIMG+sizeof(fb.image)
    else      
      .DataPtr = screenptr      
    end if
  end with
  if COPYBUFF=0 then screenlock
  return DD_OK
end function

type