/* Copyright 2003 TransGaming Technologies Inc. */

#ifndef __WINE_D3D9_PRIVATE_H
#define __WINE_D3D9_PRIVATE_H

#ifdef DDRAW_SAVE_AND_RESTORE_FPU_HACK
#include "wine/d3d_fpuctl.h"
#endif

#include "winuser.h"
#include "ddrawi.h"

#include "d3dtypes.h"
#include "d3dcaps.h"
#include "d3dhal.h"
#include "wine/d3dhalp.h"

/* If you want to have experimental AGP memory allocation define this */
/* #define WINE_D3D9_ENABLE_HAL_ALLOCATE_AGP_MEM_FULL */
#define WINE_D3D9_ENABLE_HAL_ALLOCATE_AGP_MEM 

typedef struct IDirect3D9Impl IDirect3D9Impl;
typedef struct IDirect3DDevice9Impl IDirect3DDevice9Impl;
typedef struct IDirect3DResource9Impl IDirect3DResource9Impl;
typedef struct IDirect3DBaseTexture9Impl IDirect3DBaseTexture9Impl;
typedef struct IDirect3DTexture9Impl IDirect3DTexture9Impl;
typedef struct IDirect3DVolumeTexture9Impl IDirect3DVolumeTexture9Impl;
typedef struct IDirect3DCubeTexture9Impl IDirect3DCubeTexture9Impl;
typedef struct IDirect3DVertexBuffer9Impl IDirect3DVertexBuffer9Impl;
typedef struct IDirect3DIndexBuffer9Impl IDirect3DIndexBuffer9Impl;
typedef struct IDirect3DSurface9Impl IDirect3DSurface9Impl;
typedef struct IDirect3DVertexDeclaration9Impl IDirect3DVertexDeclaration9Impl;
typedef struct IDirect3DVertexShader9Impl IDirect3DVertexShader9Impl;
typedef struct IDirect3DSwapChain9Impl IDirect3DSwapChain9Impl;

typedef struct D3D9StateBlock {
  ICOM_VFIELD(IDirect3DStateBlock9);
  DWORD ref;
  IDirect3DDevice9Impl *parent;
  DWORD state_block; /* driver's state block */
  DWORD dirty_tex, dirty_stream;
  BOOL dirty_indices;
  LPDIRECT3DBASETEXTURE9 tex[8];
  LPDIRECT3DVERTEXBUFFER9 streamsource[16];
  UINT streamstride[16];
  LPDIRECT3DINDEXBUFFER9 indices;
  BOOL dirty_fvf, dirty_vdecl, dirty_vshader;
  DWORD vertex_fvf;
  IDirect3DVertexDeclaration9 *vertex_decl;
  IDirect3DVertexShader9 *vertex_shader;
} D3D9StateBlock;

typedef struct D3D9Palette {
  DDRAWI_DDRAWPALETTE_LCL local;
  DDRAWI_DDRAWPALETTE_GBL global;
  DDRAWI_DDRAWPALETTE_INT inter;
} D3D9Palette;

struct IDirect3D9Impl {
  ICOM_VFIELD(IDirect3D9);

  DWORD ref;
};

struct IDirect3DDevice9Impl {
  ICOM_VFIELD(IDirect3DDevice9);

  DWORD ref;
  IDirect3D9Impl* parent;
  D3DCAPS9* caps;

  DDRAWI_DIRECTDRAW_LCL local;

  LPVOID ip_ctx;

  D3D_P d3dp;

  D3DDISPLAYMODE mode;

  D3D9StateBlock state, *current;

  DWORD curpalette, numpalettes;
  D3D9Palette **palette;

  BOOL dirty_textures;

  void WINAPI (*demolish_texture)(LPVOID ctx, DWORD dwTexture);

  HRESULT WINAPI (*alloc_state_block)(LPVOID ctx, LPDWORD lpdwBlock);
  HRESULT WINAPI (*free_state_block)(LPVOID ctx, DWORD dwBlock);

  HRESULT WINAPI (*start_dp2)(LPVOID ctx, DWORD dwFlags,
                              DWORD dwVertexType, LPVOID lpVertices,
                              DWORD dwVertexOffset, DWORD dwVertexLength,
                              DWORD dwReqVertexBufSize, DWORD dwReqCommandBufSize);
  HRESULT WINAPI (*start_dp2_sd)(LPVOID ctx, DWORD dwFlags,
                                 DWORD dwVertexType, LPVOID lpVertices,
                                 DWORD dwVertexOffset, DWORD dwVertexLength,
                                 DWORD dwReqVertexBufSize, DWORD dwReqCommandBufSize,
                                 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStridedData);
  HRESULT WINAPI (*emit_dp2)(LPVOID ctx, LPD3DHAL_DP2COMMAND cmd,
                             LPCVOID data1, DWORD dwSize1,
                             LPCVOID data2, DWORD dwSize2);
  HRESULT WINAPI (*flush_dp2)(LPVOID ctx);

  HRESULT WINAPI (*validate_device)(LPVOID ctx, LPDWORD lpdwPasses);

  BOOL windowed, auto_zbuffer;
  WNDPROC old_wndproc;
  DWORD old_style;
  DWORD behavior;

  IDirect3DSurface9* primary;
  IDirect3DSurface9* backbuf;
  IDirect3DSurface9* zbuffer;
  IDirect3DSurface9* target;
  IDirect3DSurface9* ztarget;

  HDC mem_dc;
  HBITMAP old_bmp;

  D3DGAMMARAMP orig_gamma;

  IDirect3DBaseTexture9Impl *textures;
  VertexShader *vshaders;
  
#if defined( DDRAW_SAVE_AND_RESTORE_FPU_HACK )
  fpu_control_t fpucw; /* FPU control word - saved while in a scene */
#endif
};

struct IDirect3DResource9Impl {
  LPVOID fake_vtbl;
    
  DWORD ref;
  IDirect3DDevice9Impl* parent;
  DWORD intref;
}; 

struct IDirect3DBaseTexture9Impl {
  ICOM_VFIELD(IDirect3DBaseTexture9);

  DWORD ref;
  IDirect3DDevice9Impl* parent;
  DWORD intref;
  
  IDirect3DBaseTexture9Impl *prev_device;
  IDirect3DBaseTexture9Impl *next_device;

  BOOL IsDirty;
  LPDIRECT3DSURFACE9 main;
  HRESULT (*AddDirtyRect)(IDirect3DBaseTexture9Impl*, LPDIRECT3DSURFACE9, CONST RECT*);
  HRESULT (*UpdateTexture)(IDirect3DBaseTexture9Impl*, IDirect3DBaseTexture9Impl*);
  HRESULT (*UnloadTexture)(IDirect3DBaseTexture9Impl*);
};

#define TEXTURE_HANDLE(This) ((DWORD)&((IDirect3DSurface9Impl*)(This)->main)->t)

struct IDirect3DTexture9Impl {
  ICOM_VFIELD(IDirect3DTexture9);

  DWORD ref;
  IDirect3DDevice9Impl* parent;
  DWORD intref;

  IDirect3DBaseTexture9Impl *prev_device;
  IDirect3DBaseTexture9Impl *next_device;

  BOOL IsDirty;
  LPDIRECT3DSURFACE9 main;
  HRESULT (*AddDirtyRect)(IDirect3DTexture9Impl* This, LPDIRECT3DSURFACE9 surf, CONST RECT* pDirtyRect);
  HRESULT (*UpdateTexture)(IDirect3DTexture9Impl* This, IDirect3DTexture9Impl* pDest);
  HRESULT (*UnloadTexture)(IDirect3DTexture9Impl*);

  UINT Width, Height, Levels;
  DWORD Usage;
  D3DFORMAT Format;
  RECT DirtyRect;

  LPDIRECT3DSURFACE9 surf[1];
};

#if 0
struct IDirect3DVolumeTexture9Impl {
  ICOM_VFIELD(IDirect3DVolumeTexture9);

  DWORD ref;
  IDirect3DDevice9Impl* parent;
  DWORD intref;

  IDirect3DBaseTexture9Impl *prev_device;
  IDirect3DBaseTexture9Impl *next_device;

  BOOL IsDirty;
  LPDIRECT3DVOLUME8 main;
  HRESULT (*AddDirtyRect)(IDirect3DVolumeTexture9Impl* This, LPDIRECT3DSURFACE9 surf, CONST RECT* pDirtyRect);
  HRESULT (*UpdateTexture)(IDirect3DVolumeTexture9Impl* This, IDirect3DVolumeTexture9Impl* pDest);
  HRESULT (*UnloadTexture)(IDirect3DVolumeTexture9Impl*);

  UINT Width, Height, Depth, Levels;
  DWORD Usage;
  D3DFORMAT Format;
  D3DBOX DirtyBox;

  LPDIRECT3DVOLUME8 vol[1];
};
#endif

struct IDirect3DCubeTexture9Impl {
  ICOM_VFIELD(IDirect3DCubeTexture9);

  DWORD ref;
  IDirect3DDevice9Impl* parent;
  DWORD intref;

  IDirect3DBaseTexture9Impl *prev_device;
  IDirect3DBaseTexture9Impl *next_device;

  BOOL IsDirty;
  LPDIRECT3DSURFACE9 main;
  HRESULT (*AddDirtyRect)(IDirect3DCubeTexture9Impl* This, LPDIRECT3DSURFACE9 surf, CONST RECT* pDirtyRect);
  HRESULT (*UpdateTexture)(IDirect3DCubeTexture9Impl* This, IDirect3DCubeTexture9Impl* pDest);
  HRESULT (*UnloadTexture)(IDirect3DCubeTexture9Impl*);

  UINT EdgeLength, Levels;
  DWORD Usage;
  D3DFORMAT Format;
  RECT DirtyRect[6];

  LPDIRECT3DSURFACE9 surf[1];
};

struct IDirect3DVertexBuffer9Impl {
  ICOM_VFIELD(IDirect3DVertexBuffer9);

  DWORD ref;
  IDirect3DDevice9Impl* parent;
  DWORD intref;

  LPBYTE ptr;
  DWORD Usage;

  D3D_T t;

  DDSURFACEDESC2 surface_desc;
};

struct IDirect3DIndexBuffer9Impl {
  ICOM_VFIELD(IDirect3DIndexBuffer9);

  DWORD ref;
  IDirect3DDevice9Impl* parent;
  DWORD intref;

  LPBYTE ptr;
  D3DFORMAT Format;
  DWORD Usage;

  D3D_T t;
};

struct IDirect3DSurface9Impl {
  ICOM_VFIELD(IDirect3DSurface9);

  DWORD ref;
  IDirect3DDevice9Impl* parent;

  DWORD intref;
  LPUNKNOWN container;
  HBITMAP dib;
  BOOL own_memory;
  UINT Pitch;
  D3DFORMAT Format;

  D3D_T t;

  DDSURFACEDESC2 surface_desc;

  ATTACHLIST sibling;
};

struct IDirect3DVertexDeclaration9Impl {
  ICOM_VFIELD(IDirect3DVertexDeclaration9);

  DWORD ref;
  IDirect3DDevice9Impl* parent;

  CONST D3DVERTEXELEMENT9* pDeclaration;
  UINT DeclarationLength;
  UINT Streams;
  DWORD FVF;

  VertexShader* vs;
};

struct vs_cache {
  IDirect3DVertexDeclaration9Impl* decl;
  VertexShader* vs;
};

struct IDirect3DVertexShader9Impl {
  ICOM_VFIELD(IDirect3DVertexShader9);

  DWORD ref;
  IDirect3DDevice9Impl* parent;

  CONST DWORD* pFunction;
  UINT FunctionLength;

  VertexShader* vs;

  struct vs_cache* cache;
  unsigned cache_size;
};

struct IDirect3DSwapChain9Impl {
  ICOM_VFIELD(IDirect3DSwapChain9);

  DWORD ref;
  IDirect3DDevice9Impl* parent;
};

extern HANDLE buffer_heap, surface_heap;
extern BOOL dx8_hal, dx9_hal;

ULONG WINAPI IDirect3DResource9_AddRefInternal(LPDIRECT3DRESOURCE9 iface);
ULONG WINAPI IDirect3DResource9_ReleaseInternal(LPDIRECT3DRESOURCE9 iface);

/* surface.c */
D3DFORMAT D3D9_FindPixelFormat(LPDDPIXELFORMAT pfmt);
void D3D9_GetPixelFormat(LPDDPIXELFORMAT pfmt, D3DFORMAT fmt);
HRESULT WINAPI Direct3DDevice9_CreateSurface(LPDIRECT3DDEVICE9 iface,
					     LPUNKNOWN container,
					     UINT Width,
					     UINT Height,
					     D3DFORMAT Format,
					     DDSCAPS2* ddsCaps,
					     IDirect3DSurface9** ppSurface,
					     BOOL internal);
HRESULT WINAPI Direct3DDevice9_AttachSurface(IDirect3DSurface9* pParent,
					     IDirect3DSurface9* pChild);
HRESULT WINAPI Direct3DDevice9_CreateRenderTarget(LPDIRECT3DDEVICE9 iface,
						  UINT Width,
						  UINT Height,
						  D3DFORMAT Format,
						  D3DMULTISAMPLE_TYPE MultiSampleType,
						  DWORD MultiSampleQuality,
						  BOOL Lockable,
						  IDirect3DSurface9** ppSurface,
						  HANDLE* pSharedHandle);
HRESULT WINAPI Direct3DDevice9_CreateDepthStencilSurface(LPDIRECT3DDEVICE9 iface,
							 UINT Width,
							 UINT Height,
							 D3DFORMAT Format,
							 D3DMULTISAMPLE_TYPE MultiSampleType,
							 DWORD MultiSampleQuality,
							 BOOL Discard,
							 IDirect3DSurface9** ppSurface,
							 HANDLE* pSharedHandle);
HRESULT WINAPI Direct3DDevice9_CreateOffscreenPlainSurface(LPDIRECT3DDEVICE9 iface,
						           UINT Width,
						           UINT Height,
						           D3DFORMAT Format,
							   D3DPOOL Pool,
						           IDirect3DSurface9** ppSurface,
							   HANDLE *pHandle);

/* texture.c */
HRESULT WINAPI Direct3DDevice9_CreateTexture(LPDIRECT3DDEVICE9 iface,
					     UINT Width,
					     UINT Height,
					     UINT Levels,
					     DWORD Usage,
					     D3DFORMAT Format,
					     D3DPOOL Pool,
					     IDirect3DTexture9** ppTexture,
					     HANDLE* pSharedHandle);
HRESULT WINAPI Direct3DBaseTexture9_UpdateTexture(IDirect3DDevice9Impl* dev,
						  UINT Width, UINT Height, UINT Levels,
						  UINT Skip, RECT* pDirtyRect, BOOL force,
						  LPDIRECT3DSURFACE9* src, LPDIRECT3DSURFACE9* dst);

/* cubetex.c */
HRESULT WINAPI Direct3DDevice9_CreateCubeTexture(LPDIRECT3DDEVICE9 iface,
						 UINT EdgeLength,
						 UINT Levels,
						 DWORD Usage,
						 D3DFORMAT Format,
						 D3DPOOL Pool,
						 IDirect3DCubeTexture9** ppTexture,
						 HANDLE* pSharedHandle);
VOID WINAPI Direct3DCubeTexture9_UpdateDirty(LPDIRECT3DCUBETEXTURE9 iface, BOOL force);

/* vbuffer.c */
HRESULT WINAPI Direct3DDevice9_CreateVertexBuffer(LPDIRECT3DDEVICE9 iface,
						  UINT Length,
						  DWORD Usage,
						  DWORD FVF,
						  D3DPOOL Pool,
						  IDirect3DVertexBuffer9** ppVertexBuffer,
						  HANDLE* pSharedHandle);

/* ibuffer.c */
HRESULT WINAPI Direct3DDevice9_CreateIndexBuffer(LPDIRECT3DDEVICE9 iface,
						 UINT Length,
						 DWORD Usage,
						 D3DFORMAT Format,
						 D3DPOOL Pool,
						 IDirect3DIndexBuffer9** ppIndexBuffer,
						 HANDLE* pSharedHandle);

/* vshader.c */
HRESULT WINAPI Direct3DDevice9_CreateVertexDeclaration(LPDIRECT3DDEVICE9 iface,
						       CONST D3DVERTEXELEMENT9* pVertexElements,
						       IDirect3DVertexDeclaration9** ppDecl);
HRESULT WINAPI Direct3DDevice9_SetVertexDeclaration(LPDIRECT3DDEVICE9 iface,
						    IDirect3DVertexDeclaration9* pDecl);
HRESULT WINAPI Direct3DDevice9_GetVertexDeclaration(LPDIRECT3DDEVICE9 iface,
						    IDirect3DVertexDeclaration9** ppDecl);
HRESULT WINAPI Direct3DDevice9_CreateVertexShader(LPDIRECT3DDEVICE9 iface,
						  const DWORD* pFunction,
						  IDirect3DVertexShader9** ppShader);
HRESULT WINAPI Direct3DDevice9_SetVertexShader(LPDIRECT3DDEVICE9 iface,
					       IDirect3DVertexShader9* pShader);
HRESULT WINAPI Direct3DDevice9_GetVertexShader(LPDIRECT3DDEVICE9 iface,
					       IDirect3DVertexShader9** ppShader);
HRESULT WINAPI Direct3DDevice9_SetVertexShaderConstantF(LPDIRECT3DDEVICE9 iface,
							UINT StartRegister,
							CONST float* pConstantData,
							UINT Vector4fCount);
HRESULT WINAPI Direct3DDevice9_GetVertexShaderConstantF(LPDIRECT3DDEVICE9 iface,
							UINT StartRegister,
							float* pConstantData,
							UINT Vector4fCount);
HRESULT WINAPI Direct3DDevice9_BuildVertexShader(LPDIRECT3DDEVICE9 iface,
						 IDirect3DVertexDeclaration9Impl* pDecl,
						 IDirect3DVertexShader9Impl* pShader,
						 VertexShader** pvs);
HRESULT WINAPI Direct3DDevice9_GetStridedData(LPDIRECT3DDEVICE9 iface,
					      LPD3DDRAWPRIMITIVESTRIDEDDATA lpData);
HRESULT WINAPI Direct3DDevice9_GetStridedDataUP(LPDIRECT3DDEVICE9 iface,
						LPD3DDRAWPRIMITIVESTRIDEDDATA lpData,
						CONST void* vertex_data,
						UINT vertex_stride,
						BOOL verify_stride);

/* pshader.c */
HRESULT WINAPI Direct3DDevice9_SetPixelShader(LPDIRECT3DDEVICE9 iface,
					      IDirect3DPixelShader9* pShader);
HRESULT WINAPI Direct3DDevice9_GetPixelShader(LPDIRECT3DDEVICE9 iface,
					      IDirect3DPixelShader9** ppShader);
HRESULT WINAPI Direct3DDevice9_CreatePixelShader(LPDIRECT3DDEVICE9 iface, 
                                                 CONST DWORD *pFunction,
                                                 IDirect3DPixelShader9** ppShader);
HRESULT WINAPI Direct3DDevice9_SetPixelShaderConstantF(LPDIRECT3DDEVICE9 iface,
						       UINT StartRegister,
						       CONST float* pConstantData,
						       UINT Vector4fCount);

/* state.c */
HRESULT WINAPI Direct3DDevice9_SetTransform(LPDIRECT3DDEVICE9 iface,
					    D3DTRANSFORMSTATETYPE dtstType,
					    CONST D3DMATRIX* lpD3DMatrix);
HRESULT WINAPI Direct3DDevice9_GetTransform(LPDIRECT3DDEVICE9 iface,
					    D3DTRANSFORMSTATETYPE dtstType,
					    D3DMATRIX* lpD3DMatrix);
HRESULT WINAPI Direct3DDevice9_SetViewport(LPDIRECT3DDEVICE9 iface,
					   CONST D3DVIEWPORT9* lpData);
HRESULT WINAPI Direct3DDevice9_GetViewport(LPDIRECT3DDEVICE9 iface,
					   D3DVIEWPORT9* lpData);
HRESULT WINAPI Direct3DDevice9_SetMaterial(LPDIRECT3DDEVICE9 iface,
					   CONST D3DMATERIAL9* lpMat);
HRESULT WINAPI Direct3DDevice9_GetMaterial(LPDIRECT3DDEVICE9 iface,
					   D3DMATERIAL9* lpMat);
HRESULT WINAPI Direct3DDevice9_SetLight(LPDIRECT3DDEVICE9 iface,
					DWORD dwIndex,
					CONST D3DLIGHT9* lpLight);
HRESULT WINAPI Direct3DDevice9_GetLight(LPDIRECT3DDEVICE9 iface,
					DWORD dwIndex,
					D3DLIGHT9* lpLight);
HRESULT WINAPI Direct3DDevice9_LightEnable(LPDIRECT3DDEVICE9 iface,
					   DWORD dwIndex,
					   BOOL bEnable);
HRESULT WINAPI Direct3DDevice9_GetLightEnable(LPDIRECT3DDEVICE9 iface,
					      DWORD dwIndex,
					      LPBOOL lpbEnable);
HRESULT WINAPI Direct3DDevice9_SetClipPlane(LPDIRECT3DDEVICE9 iface,
					    DWORD dwIndex,
					    CONST float* pPlane);
HRESULT WINAPI Direct3DDevice9_GetClipPlane(LPDIRECT3DDEVICE9 iface,
					    DWORD dwIndex,
					    float* pPlane);
HRESULT WINAPI Direct3DDevice9_SetRenderState(LPDIRECT3DDEVICE9 iface,
					      D3DRENDERSTATETYPE d3dType,
					      DWORD dwState);
HRESULT WINAPI Direct3DDevice9_GetRenderState(LPDIRECT3DDEVICE9 iface,
					      D3DRENDERSTATETYPE d3dType,
					      LPDWORD lpdwState);
HRESULT WINAPI Direct3DDevice9_CreateStateBlock(LPDIRECT3DDEVICE9 iface,
						D3DSTATEBLOCKTYPE type,
						IDirect3DStateBlock9** ppSB);
HRESULT WINAPI Direct3DDevice9_BeginStateBlock(LPDIRECT3DDEVICE9 iface);
HRESULT WINAPI Direct3DDevice9_EndStateBlock(LPDIRECT3DDEVICE9 iface,
					     IDirect3DStateBlock9** ppSB);
HRESULT WINAPI Direct3DDevice9_GetTexture(LPDIRECT3DDEVICE9 iface,
					  DWORD dwStage,
					  LPDIRECT3DBASETEXTURE9* lplpTexture);
HRESULT WINAPI Direct3DDevice9_SetTexture(LPDIRECT3DDEVICE9 iface,
					  DWORD dwStage,
					  LPDIRECT3DBASETEXTURE9 lpTexture);
HRESULT WINAPI Direct3DDevice9_GetTextureStageState(LPDIRECT3DDEVICE9 iface,
						    DWORD dwStage,
						    D3DTEXTURESTAGESTATETYPE d3dType,
						    LPDWORD lpdwState);
HRESULT WINAPI Direct3DDevice9_SetTextureStageState(LPDIRECT3DDEVICE9 iface,
						    DWORD dwStage,
						    D3DTEXTURESTAGESTATETYPE d3dType,
						    DWORD dwState);
HRESULT WINAPI Direct3DDevice9_GetSamplerState(LPDIRECT3DDEVICE9 iface,
					       DWORD Sampler,
					       D3DSAMPLERSTATETYPE Type,
					       DWORD* pValue);
HRESULT WINAPI Direct3DDevice9_SetSamplerState(LPDIRECT3DDEVICE9 iface,
					       DWORD Sampler,
					       D3DSAMPLERSTATETYPE Type,
					       DWORD Value);
HRESULT WINAPI Direct3DDevice9_ValidateDevice(LPDIRECT3DDEVICE9 iface,
					      DWORD* pNumPasses);
HRESULT WINAPI Direct3DDevice9_SetStreamSource(LPDIRECT3DDEVICE9 iface,
					       UINT StreamNumber,
					       LPDIRECT3DVERTEXBUFFER9 pStreamData,
					       UINT OffsetInBytes,
					       UINT Stride);
HRESULT WINAPI Direct3DDevice9_GetStreamSource(LPDIRECT3DDEVICE9 iface,
					       UINT StreamNumber,
					       LPDIRECT3DVERTEXBUFFER9* ppStreamData,
					       UINT* pOffsetInBytes,
					       UINT* pStride);
HRESULT WINAPI Direct3DDevice9_SetIndices(LPDIRECT3DDEVICE9 iface,
					  LPDIRECT3DINDEXBUFFER9 pIndexData);
HRESULT WINAPI Direct3DDevice9_GetIndices(LPDIRECT3DDEVICE9 iface,
					  LPDIRECT3DINDEXBUFFER9* ppIndexData);
HRESULT WINAPI Direct3DDevice9_SetFVF(LPDIRECT3DDEVICE9 iface,
                                      DWORD FVF);
HRESULT WINAPI Direct3DDevice9_GetFVF(LPDIRECT3DDEVICE9 iface,
                                      DWORD *FVF);

/* draw.c */
HRESULT WINAPI Direct3DDevice9_Present(LPDIRECT3DDEVICE9 iface,
				       CONST RECT* pSourceRect,
				       CONST RECT* pDestRect,
				       HWND hDestWindowOverride,
				       CONST RGNDATA* pDirtyRegion);
VOID WINAPI Direct3DDevice9_SetGammaRamp(LPDIRECT3DDEVICE9 iface,
					 UINT iSwapChain,
					 DWORD Flags,
					 CONST D3DGAMMARAMP* pRamp);
VOID WINAPI Direct3DDevice9_GetGammaRamp(LPDIRECT3DDEVICE9 iface,
					 UINT iSwapChain,
					 D3DGAMMARAMP* pRamp);
#if 0
HRESULT WINAPI Direct3DDevice9_CopyRects(LPDIRECT3DDEVICE9 iface,
					 IDirect3DSurface9* pSourceSurface,
					 CONST RECT* pSourceRectsArray,
					 UINT cRects,
					 IDirect3DSurface9* pDestSurface,
					 CONST POINT* pDestPointsArray);
#endif
HRESULT WINAPI Direct3DDevice9_UpdateTexture(LPDIRECT3DDEVICE9 iface,
                                             IDirect3DBaseTexture9* pSourceTexture,
                                             IDirect3DBaseTexture9* pDestinationTexture);
HRESULT WINAPI Direct3DDevice9_BeginScene(LPDIRECT3DDEVICE9 iface);
HRESULT WINAPI Direct3DDevice9_EndScene(LPDIRECT3DDEVICE9 iface);
HRESULT WINAPI Direct3DDevice9_Clear(LPDIRECT3DDEVICE9 iface, DWORD dwCount,
				     CONST D3DRECT* lpRects, DWORD dwFlags,
				     D3DCOLOR dwColor, D3DVALUE dvZ,
				     DWORD dwStencil);
HRESULT WINAPI Direct3DDevice9_DrawPrimitive(LPDIRECT3DDEVICE9 iface,
					     D3DPRIMITIVETYPE PrimType,
					     UINT StartVertex,
					     UINT PrimitiveCount);
HRESULT WINAPI Direct3DDevice9_DrawIndexedPrimitive(LPDIRECT3DDEVICE9 iface,
						    D3DPRIMITIVETYPE PrimType,
						    INT BaseVertexIndex,
						    UINT MinIndex,
						    UINT NumVertices,
						    UINT StartIndex,
						    UINT PrimitiveCount);
HRESULT WINAPI Direct3DDevice9_DrawPrimitiveUP(LPDIRECT3DDEVICE9 iface,
					       D3DPRIMITIVETYPE PrimType,
					       UINT PrimitiveCount,
					       CONST void* vertex_data,
					       UINT vertex_stride);
HRESULT WINAPI Direct3DDevice9_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE9 iface,
						      D3DPRIMITIVETYPE PrimType,
						      UINT MinIndex,
						      UINT NumVertices,
						      UINT PrimitiveCount,
						      CONST void* index_data,
						      D3DFORMAT index_format,
						      CONST void* vertex_data,
						      UINT vertex_stride);

/* palette.c */
HRESULT WINAPI Direct3DDevice9_SetPaletteEntries(LPDIRECT3DDEVICE9 iface,
						 UINT PaletteNumber,
						 CONST PALETTEENTRY* pEntries);
HRESULT WINAPI Direct3DDevice9_GetPaletteEntries(LPDIRECT3DDEVICE9 iface,
						 UINT PaletteNumber,
						 PALETTEENTRY* pEntries);
HRESULT WINAPI Direct3DDevice9_SetCurrentTexturePalette(LPDIRECT3DDEVICE9 iface,
							UINT PaletteNumber);
HRESULT WINAPI Direct3DDevice9_GetCurrentTexturePalette(LPDIRECT3DDEVICE9 iface,
							UINT* pPaletteNumber);
HRESULT WINAPI Direct3DDevice9_DestroyPalettes(LPDIRECT3DDEVICE9 iface);

/* cursor.c */
HRESULT WINAPI Direct3DDevice9_SetCursorProperties(LPDIRECT3DDEVICE9 iface,
						   UINT XHotSpot,
						   UINT YHotSpot,
						   IDirect3DSurface9* pCursorBitmap);
VOID WINAPI Direct3DDevice9_SetCursorPosition(LPDIRECT3DDEVICE9 iface,
					      UINT XScreenSpace,
					      UINT YScreenSpace,
					      DWORD Flags);
BOOL WINAPI Direct3DDevice9_ShowCursor(LPDIRECT3DDEVICE9 iface,
				       BOOL bShow);

/* swapchain.c */
HRESULT WINAPI Direct3DDevice9_GetSwapChain(
                   LPDIRECT3DDEVICE9 iface, UINT iSwapChain, IDirect3DSwapChain9 **ppSwapChain );
UINT WINAPI Direct3DDevice9_GetNumberOfSwapChains( LPDIRECT3DDEVICE9 iface );
HRESULT WINAPI Direct3DDevice9_CreateAdditionalSwapChain( 
 LPDIRECT3DDEVICE9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** ppSwapChain );

#endif
