HRESULT __stdcall DDRAW4_HOOK_QueryInterface(LPVOID *ppvOut, REFIID riid, LPVOID FAR *ppvObj)
{
	const unsigned int hpos = 0;

	DDRAW4_QueryInterface_Type ofn = (DDRAW4_QueryInterface_Type)ddraw4_hooks[hpos].oldFunc;
	HRESULT ret = ofn(ppvOut, riid, ppvObj);
	LogDXError(ret);

	Log("IDirectDraw4::%s(%#010lx, { %#010lx, %#06x, %#06x, { %#04x, %#04x, %#04x, %#04x, %#04x, %#04x, %#04x, %#04x } }, %#010lx)\n", ddraw4_hooks[hpos].name, ppvOut, riid.Data1, riid.Data2, riid.Data3, riid.Data4[0], riid.Data4[1], riid.Data4[2], riid.Data4[3], riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7], ppvObj);
	if(ret == S_OK)
	{
		if(riid == IID_IDirect3D && ishooked_d3d_hooks == false)
		{
			HookVTBLCalls(ppvObj, d3d_hooks, count_d3d_hooks, "IDirect3D");
			ishooked_d3d_hooks = true;
		}
		else if(riid == IID_IDirect3D3 && ishooked_d3d3_hooks == false)
		{
			HookVTBLCalls(ppvObj, d3d3_hooks, count_d3d3_hooks, "IDirect3D3");
			ishooked_d3d3_hooks = true;
		}
	}

	return ret;
}
HRESULT __stdcall MyDirectDrawCreate(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter ) {
	DirectDrawCreate_Type OldFn = (DirectDrawCreate_Type)DLLHooks[0]->Functions[0].OrigFn;
	HRESULT ret = OldFn(lpGUID, lplpDD, pUnkOuter);

	Log("_EXPORT::DirectDrawCreate()\n");
	if(ret == S_OK && ishooked_ddraw_hooks == false) {
		HookVTBLCalls((LPVOID *)lplpDD, ddraw_hooks, count_ddraw_hooks, "IDirectDraw");
		ishooked_ddraw_hooks = true;
	}

	return ret;
}
HRESULT __stdcall MyDirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT *lplpDirectInput, LPUNKNOWN pUnkOuter) {
	DirectInputCreateA_Type OldFn = (DirectInputCreateA_Type)DLLHooks[1]->Functions[0].OrigFn;
	HRESULT ret = OldFn(hinst, dwVersion, lplpDirectInput, pUnkOuter);

	Log("_EXPORT::DirectInputCreateA(hinst=%#010lx, dwVersion=%#010lx, lplpDirectInput=%#010lx *[%#010lx], pUnkOuter=%#010lx)\n", hinst, dwVersion, lplpDirectInput, (lplpDirectInput != NULL ? *lplpDirectInput : NULL), pUnkOuter);
	if(ret == S_OK && ishooked_dinput_hooks == false) {
		HookVTBLCalls((LPVOID *)lplpDirectInput, dinput_hooks, count_dinput_hooks, "IDirectInput");
		ishooked_dinput_hooks = true;
	}

	return ret;
}
HRESULT __stdcall DDRAWSURFACE4_HOOK_QueryInterface(LPVOID *ppvOut, REFIID riid, LPVOID FAR *ppvObj) {
	const unsigned int hpos = 0;

	DDRAWSURFACE4_QueryInterface_Type ofn = (DDRAWSURFACE4_QueryInterface_Type)ddrawsurface4_hooks[hpos].oldFunc;
	HRESULT ret = ofn(ppvOut, riid, ppvObj);
	LogDXError(ret);

	Log("IDirectDrawSurface4::%s(%#010lx, { %#010lx, %#06x, %#06x, { %#04x, %#04x, %#04x, %#04x, %#04x, %#04x, %#04x, %#04x } }, %#010lx *[%#010lx])\n", ddrawsurface4_hooks[hpos].name, ppvOut, riid.Data1, riid.Data2, riid.Data3, riid.Data4[0], riid.Data4[1], riid.Data4[2], riid.Data4[3], riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7], ppvObj, *ppvObj);
	if(ret == S_OK && riid == IID_IDirect3DTexture2 && ishooked_d3dtexture2_hooks == false) {
		HookVTBLCalls((LPVOID *)ppvObj, d3dtexture2_hooks, count_d3dtexture2_hooks, "IDirect3DTexture2");
		ishooked_d3dtexture2_hooks = true;
	}
	if(ret == S_OK && riid == IID_IDirect3DTexture2) {
		textures[(LPDIRECT3DTEXTURE2)*ppvObj] = (LPDIRECTDRAWSURFACE4)ppvOut;
		Log("textures[%#010lx] = %#010lx;\n", (DWORD)*ppvObj, (DWORD)ppvOut);
	}

	return ret;
}
HRESULT __stdcall DDRAW4_HOOK_CreateSurface(LPVOID *ppvOut, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE4 FAR *lplpDDSurface4, IUnknown FAR *pUnkOuter) {
	const unsigned int hpos = 6;

	DDRAW4_CreateSurface_Type ofn = (DDRAW4_CreateSurface_Type)ddraw4_hooks[hpos].oldFunc;
	HRESULT ret = ofn(ppvOut, lpDDSurfaceDesc, lplpDDSurface4, pUnkOuter);
	LogDXError(ret);
	
	Log("IDirectDraw4::%s(this=%#010lx, lpDDSurfaceDesc=%#010lx, lplpDDSurface=%#010lx *[%#010lx], pUnkOuter=%#010lx)\n", ddraw4_hooks[hpos].name, ppvOut, lpDDSurfaceDesc, lplpDDSurface4, (lplpDDSurface4 != NULL ? *lplpDDSurface4 : NULL), pUnkOuter);
	if(lpDDSurfaceDesc != NULL) {
		char dwFlags_buffer[LOGBUFFER_MAX], ddscaps1_buffer[LOGBUFFER_MAX], ddpf_buffer[LOGBUFFER_MAX];
		FlagsToString(FLAGS_DDSD, CFLAGS_DDSD, lpDDSurfaceDesc->dwFlags, (char *)&dwFlags_buffer, LOGBUFFER_MAX);
		FlagsToString(FLAGS_DDSCAPS1, CFLAGS_DDSCAPS1, lpDDSurfaceDesc->ddsCaps.dwCaps, (char *)&ddscaps1_buffer, LOGBUFFER_MAX);
		FlagsToString(FLAGS_DDPF, CFLAGS_DDPF, lpDDSurfaceDesc->ddpfPixelFormat.dwFlags, (char *)&ddpf_buffer, LOGBUFFER_MAX);

		Log("->lpDDSurfaceDesc { dwSize=%#010lx, dwFlags=%#010lx (%s), dwWidth=%#010lx (%d), dwHeight=%#010lx (%d), lPitch=%#010lx , dwLinearSize=%#010lx, dwBackBufferCount=%#010lx, dwMipMapCount=%#010lx, dwRefreshRate=%#010lx, dwAlphaBitDepth=%#010lx, dwReserved=%#010lx,\n"
			"  lpSurface=%#010lx, ddckCKDestOverlay={ %#010lx, %#010lx }, ddckCKDestBlt={ %#010lx, %#010lx }, ddckCKSrcOverlay={ %#010lx, %#010lx }, ddckCKSrcBlt={ %#010lx, %#010lx },\n"
			"  ddpfPixelFormat={ dwSize=%#010lx, dwFlags=%#010lx (%s), dwFourCC=%#010lx, dwRGBBitCount=%#010lx, dwYUVBitCount=%#010lx, dwZBufferBitDepth=%#010lx, dwAlphaBitDepth=%#010lx, dwLuminanceBitCount=%#010lx, dwBumpBitCount=%#010lx, dwRBitMask=%#010lx,\n"
			"    dwYBitMask=%#010lx, dwStencilBitDepth=%#010lx, dwLuminanceBitMask=%#010lx, dwBumpDuBitMask=%#010lx, dwGBitMask=%#010lx, dwUBitMask=%#010lx, dwZBitMask=%#010lx, dwBumpDvBitMask=%#010lx, dwBBitMask=%#010lx, dwVBitMask=%#010lx, dwStencilBitMask=%#010lx,\n"
			"    dwBumpLuminanceBitMask=%#010lx, dwRGBAlphaBitMask=%#010lx, dwYUVAlphaBitMask=%#010lx, dwLuminanceAlphaBitMask=%#010lx, dwRGBZBitMask=%#010lx, dwYUVZBitMask=%#010lx },\n"
			"  ddsCaps={ %#010lx (%s), %#010lx, %#010lx, %#010lx }, dwTextureStage=%#010lx }\n",
			lpDDSurfaceDesc->dwSize, lpDDSurfaceDesc->dwFlags, dwFlags_buffer, lpDDSurfaceDesc->dwWidth, (unsigned int)lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight, (unsigned int)lpDDSurfaceDesc->dwHeight, lpDDSurfaceDesc->lPitch,
			lpDDSurfaceDesc->dwLinearSize, lpDDSurfaceDesc->dwBackBufferCount, lpDDSurfaceDesc->dwMipMapCount, lpDDSurfaceDesc->dwRefreshRate, lpDDSurfaceDesc->dwAlphaBitDepth, lpDDSurfaceDesc->dwReserved, lpDDSurfaceDesc->lpSurface,
			lpDDSurfaceDesc->ddckCKDestOverlay.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKDestOverlay.dwColorSpaceHighValue, lpDDSurfaceDesc->ddckCKDestBlt.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKDestBlt.dwColorSpaceHighValue,
			lpDDSurfaceDesc->ddckCKSrcOverlay.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKSrcOverlay.dwColorSpaceHighValue, lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceHighValue,
			
			lpDDSurfaceDesc->ddpfPixelFormat.dwSize, lpDDSurfaceDesc->ddpfPixelFormat.dwFlags, ddpf_buffer, lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, lpDDSurfaceDesc->ddpfPixelFormat.dwYUVBitCount,
			lpDDSurfaceDesc->ddpfPixelFormat.dwZBufferBitDepth, lpDDSurfaceDesc->ddpfPixelFormat.dwAlphaBitDepth, lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceBitCount, lpDDSurfaceDesc->ddpfPixelFormat.dwBumpBitCount,
			lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwYBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwStencilBitDepth, lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpDuBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwUBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwZBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwBumpDvBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwVBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwStencilBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwBumpLuminanceBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwYUVAlphaBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceAlphaBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBZBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVZBitMask,
			
			lpDDSurfaceDesc->ddsCaps.dwCaps, ddscaps1_buffer, lpDDSurfaceDesc->ddsCaps.dwCaps2, lpDDSurfaceDesc->ddsCaps.dwCaps3, lpDDSurfaceDesc->ddsCaps.dwCaps4, lpDDSurfaceDesc->dwTextureStage
		);
	}
	if(ret == S_OK && ishooked_ddrawsurface4_hooks == false) {
		HookVTBLCalls((LPVOID *)lplpDDSurface4, ddrawsurface4_hooks, count_ddrawsurface4_hooks, "IDirectDrawSurface4");
		ishooked_ddrawsurface4_hooks = true;
	}

	return ret;
}
HRESULT __stdcall DDRAW4_HOOK_CreateSurface(LPVOID *ppvOut, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE4 FAR *lplpDDSurface4, IUnknown FAR *pUnkOuter)
{
	const unsigned int hpos = 6;

	if(g_config.displaymode != 0)
	{
		/*if((void *)lpDDSurfaceDesc == (void *)0x00134518) {
				lpDDSurfaceDesc->dwWidth = displaymode_options[g_config.displaymode].resX;
				lpDDSurfaceDesc->dwHeight = displaymode_options[g_config.displaymode].resY;
		}*/
		if(lpDDSurfaceDesc != NULL && lpDDSurfaceDesc->dwWidth == 640 && lpDDSurfaceDesc->dwHeight == 480) {
				lpDDSurfaceDesc->dwWidth = displaymode_options[g_config.displaymode].resX;
				lpDDSurfaceDesc->dwHeight = displaymode_options[g_config.displaymode].resY;
		}
	}

	// 8-bit Paletted Textures Fix (VISTA Compatible)
	if(g_config.b8_paletted_textures_fix >= 1)
	{
		if(lpDDSurfaceDesc != NULL && (lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_ALLOCONLOAD | DDSCAPS_TEXTURE)) == (DDSCAPS_ALLOCONLOAD | DDSCAPS_TEXTURE)) {
			lpDDSurfaceDesc->dwFlags |= DDSD_CKSRCBLT;
			lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceLowValue = 0x000000;
			lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceHighValue = 0x000000;
		}
	}

#ifdef FF8_WINDOWED
	if((void *)lpDDSurfaceDesc == (void *)0x00134658)
	{
		Log("IF[lpDDSurfaceDesc == 0x00134658] THEN\n");
		lpDDSurfaceDesc->dwFlags &= ~(DDSD_BACKBUFFERCOUNT);
		//lpDDSurfaceDesc->dwFlags |= (DDSD_WIDTH | DDSD_HEIGHT);
		lpDDSurfaceDesc->dwWidth = 0;
		lpDDSurfaceDesc->dwHeight = 0;
		lpDDSurfaceDesc->dwBackBufferCount = 0;
		lpDDSurfaceDesc->ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE );
		lpDDSurfaceDesc->ddsCaps.dwCaps |= (DDSCAPS_PRIMARYSURFACE);
	} /*else if((lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_ALLOCONLOAD | DDSCAPS_TEXTURE)) && (lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) && (lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) && lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask == 0x7c00 && lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask == 0x3e0 && lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask == 0x1f) {
		lpDDSurfaceDesc->ddpfPixelFormat.dwFlags &= ~(DDPF_ALPHAPIXELS);
		lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVAlphaBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceAlphaBitMask = 
			lpDDSurfaceDesc->ddpfPixelFormat.dwRGBZBitMask = 
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVZBitMask = 0x00;
	//Does not work: Crash in battle swirl
	}*/ /*else if((lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE)) && (lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) && (lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) && lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 0x020) {
		lpDDSurfaceDesc->ddpfPixelFormat.dwFlags &= ~(DDPF_ALPHAPIXELS);
		lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount =
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVBitCount =
			lpDDSurfaceDesc->ddpfPixelFormat.dwZBufferBitDepth =
			lpDDSurfaceDesc->ddpfPixelFormat.dwAlphaBitDepth =
			lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceBitCount =
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpBitCount = 0x10;
		lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwYBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwStencilBitDepth =
			lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpDuBitMask = 0xf800;
		lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwUBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwZBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpDvBitMask = 0x7e0;
		lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwVBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwStencilBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpLuminanceBitMask = 0x1f;
		lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVAlphaBitMask =
			lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceAlphaBitMask = 
			lpDDSurfaceDesc->ddpfPixelFormat.dwRGBZBitMask = 
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVZBitMask = 0x00;
	}*/

/*
16BIT
->lpDDSurfaceDesc { dwSize=0x0000007c, dwFlags=0x00001007 (DDSD_CAPS | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_WIDTH), dwWidth=0x00000100 (256), dwHeight=0x00000100 (256), lPitch=0000000000 , dwLinearSize=0000000000, dwBackBufferCount=0000000000, dwMipMapCount=0000000000, dwRefreshRate=0000000000, dwAlphaBitDepth=0000000000, dwReserved=0000000000,
lpSurface=0000000000, ddckCKDestOverlay={ 0000000000, 0000000000 }, ddckCKDestBlt={ 0000000000, 0000000000 }, ddckCKSrcOverlay={ 0000000000, 0000000000 }, ddckCKSrcBlt={ 0000000000, 0000000000 },
ddpfPixelFormat={ dwSize=0x00000020, dwFlags=0x00000040 (DDPF_RGB), dwFourCC=0000000000, dwRGBBitCount=0x00000010, dwYUVBitCount=0x00000010, dwZBufferBitDepth=0x00000010, dwAlphaBitDepth=0x00000010, dwLuminanceBitCount=0x00000010, dwBumpBitCount=0x00000010, dwRBitMask=0x0000f800,
dwYBitMask=0x0000f800, dwStencilBitDepth=0x0000f800, dwLuminanceBitMask=0x0000f800, dwBumpDuBitMask=0x0000f800, dwGBitMask=0x000007e0, dwUBitMask=0x000007e0, dwZBitMask=0x000007e0, dwBumpDvBitMask=0x000007e0, dwBBitMask=0x0000001f, dwVBitMask=0x0000001f, dwStencilBitMask=0x0000001f,
dwBumpLuminanceBitMask=0x0000001f, dwRGBAlphaBitMask=0000000000, dwYUVAlphaBitMask=0000000000, dwLuminanceAlphaBitMask=0000000000, dwRGBZBitMask=0000000000, dwYUVZBitMask=0000000000 },
ddsCaps={ 0x00001800 (DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE), 0000000000, 0000000000, 0000000000 }, dwTextureStage=0000000000 }

32BIT
->lpDDSurfaceDesc { dwSize=0x0000007c, dwFlags=0x00001007 (DDSD_CAPS | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_WIDTH), dwWidth=0x00000100 (256), dwHeight=0x00000100 (256), lPitch=0000000000 , dwLinearSize=0000000000, dwBackBufferCount=0000000000, dwMipMapCount=0000000000, dwRefreshRate=0000000000, dwAlphaBitDepth=0000000000, dwReserved=0000000000,
lpSurface=0000000000, ddckCKDestOverlay={ 0000000000, 0000000000 }, ddckCKDestBlt={ 0000000000, 0000000000 }, ddckCKSrcOverlay={ 0000000000, 0000000000 }, ddckCKSrcBlt={ 0000000000, 0000000000 },
ddpfPixelFormat={ dwSize=0x00000020, dwFlags=0x00000041 (DDPF_ALPHAPIXELS | DDPF_RGB), dwFourCC=0000000000, dwRGBBitCount=0x00000020, dwYUVBitCount=0x00000020, dwZBufferBitDepth=0x00000020, dwAlphaBitDepth=0x00000020, dwLuminanceBitCount=0x00000020, dwBumpBitCount=0x00000020, dwRBitMask=0x00ff0000,
dwYBitMask=0x00ff0000, dwStencilBitDepth=0x00ff0000, dwLuminanceBitMask=0x00ff0000, dwBumpDuBitMask=0x00ff0000, dwGBitMask=0x0000ff00, dwUBitMask=0x0000ff00, dwZBitMask=0x0000ff00, dwBumpDvBitMask=0x0000ff00, dwBBitMask=0x000000ff, dwVBitMask=0x000000ff, dwStencilBitMask=0x000000ff,
dwBumpLuminanceBitMask=0x000000ff, dwRGBAlphaBitMask=0xff000000, dwYUVAlphaBitMask=0xff000000, dwLuminanceAlphaBitMask=0xff000000, dwRGBZBitMask=0xff000000, dwYUVZBitMask=0xff000000 },
ddsCaps={ 0x00001800 (DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE), 0000000000, 0000000000, 0000000000 }, dwTextureStage=0000000000 }
*/
#endif

	DDRAW4_CreateSurface_Type ofn = (DDRAW4_CreateSurface_Type)ddraw4_hooks[hpos].oldFunc;
	HRESULT ret = ofn(ppvOut, lpDDSurfaceDesc, lplpDDSurface4, pUnkOuter);
	LogDXError(ret);
	
	Log("IDirectDraw4::%s(this=%#010lx, lpDDSurfaceDesc=%#010lx, lplpDDSurface=%#010lx *[%#010lx], pUnkOuter=%#010lx)\n", ddraw4_hooks[hpos].name, ppvOut, lpDDSurfaceDesc, lplpDDSurface4, (lplpDDSurface4 != NULL ? *lplpDDSurface4 : NULL), pUnkOuter);
	if(lpDDSurfaceDesc != NULL)
	{
		char dwFlags_buffer[LOGBUFFER_MAX], ddscaps1_buffer[LOGBUFFER_MAX], ddpf_buffer[LOGBUFFER_MAX];
		FlagsToString(FLAGS_DDSD, CFLAGS_DDSD, lpDDSurfaceDesc->dwFlags, (char *)&dwFlags_buffer, LOGBUFFER_MAX);
		FlagsToString(FLAGS_DDSCAPS1, CFLAGS_DDSCAPS1, lpDDSurfaceDesc->ddsCaps.dwCaps, (char *)&ddscaps1_buffer, LOGBUFFER_MAX);
		FlagsToString(FLAGS_DDPF, CFLAGS_DDPF, lpDDSurfaceDesc->ddpfPixelFormat.dwFlags, (char *)&ddpf_buffer, LOGBUFFER_MAX);

		Log("->lpDDSurfaceDesc { dwSize=%#010lx, dwFlags=%#010lx (%s), dwWidth=%#010lx (%d), dwHeight=%#010lx (%d), lPitch=%#010lx , dwLinearSize=%#010lx, dwBackBufferCount=%#010lx, dwMipMapCount=%#010lx, dwRefreshRate=%#010lx, dwAlphaBitDepth=%#010lx, dwReserved=%#010lx,\n"
			"  lpSurface=%#010lx, ddckCKDestOverlay={ %#010lx, %#010lx }, ddckCKDestBlt={ %#010lx, %#010lx }, ddckCKSrcOverlay={ %#010lx, %#010lx }, ddckCKSrcBlt={ %#010lx, %#010lx },\n"
			"  ddpfPixelFormat={ dwSize=%#010lx, dwFlags=%#010lx (%s), dwFourCC=%#010lx, dwRGBBitCount=%#010lx, dwYUVBitCount=%#010lx, dwZBufferBitDepth=%#010lx, dwAlphaBitDepth=%#010lx, dwLuminanceBitCount=%#010lx, dwBumpBitCount=%#010lx, dwRBitMask=%#010lx,\n"
			"    dwYBitMask=%#010lx, dwStencilBitDepth=%#010lx, dwLuminanceBitMask=%#010lx, dwBumpDuBitMask=%#010lx, dwGBitMask=%#010lx, dwUBitMask=%#010lx, dwZBitMask=%#010lx, dwBumpDvBitMask=%#010lx, dwBBitMask=%#010lx, dwVBitMask=%#010lx, dwStencilBitMask=%#010lx,\n"
			"    dwBumpLuminanceBitMask=%#010lx, dwRGBAlphaBitMask=%#010lx, dwYUVAlphaBitMask=%#010lx, dwLuminanceAlphaBitMask=%#010lx, dwRGBZBitMask=%#010lx, dwYUVZBitMask=%#010lx },\n"
			"  ddsCaps={ %#010lx (%s), %#010lx, %#010lx, %#010lx }, dwTextureStage=%#010lx }\n",
			lpDDSurfaceDesc->dwSize, lpDDSurfaceDesc->dwFlags, dwFlags_buffer, lpDDSurfaceDesc->dwWidth, (unsigned int)lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight, (unsigned int)lpDDSurfaceDesc->dwHeight, lpDDSurfaceDesc->lPitch,
			lpDDSurfaceDesc->dwLinearSize, lpDDSurfaceDesc->dwBackBufferCount, lpDDSurfaceDesc->dwMipMapCount, lpDDSurfaceDesc->dwRefreshRate, lpDDSurfaceDesc->dwAlphaBitDepth, lpDDSurfaceDesc->dwReserved, lpDDSurfaceDesc->lpSurface,
			lpDDSurfaceDesc->ddckCKDestOverlay.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKDestOverlay.dwColorSpaceHighValue, lpDDSurfaceDesc->ddckCKDestBlt.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKDestBlt.dwColorSpaceHighValue,
			lpDDSurfaceDesc->ddckCKSrcOverlay.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKSrcOverlay.dwColorSpaceHighValue, lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceLowValue, lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceHighValue,
			
			lpDDSurfaceDesc->ddpfPixelFormat.dwSize, lpDDSurfaceDesc->ddpfPixelFormat.dwFlags, ddpf_buffer, lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, lpDDSurfaceDesc->ddpfPixelFormat.dwYUVBitCount,
			lpDDSurfaceDesc->ddpfPixelFormat.dwZBufferBitDepth, lpDDSurfaceDesc->ddpfPixelFormat.dwAlphaBitDepth, lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceBitCount, lpDDSurfaceDesc->ddpfPixelFormat.dwBumpBitCount,
			lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwYBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwStencilBitDepth, lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwBumpDuBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwUBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwZBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwBumpDvBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwVBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwStencilBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwBumpLuminanceBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwYUVAlphaBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwLuminanceAlphaBitMask, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBZBitMask,
			lpDDSurfaceDesc->ddpfPixelFormat.dwYUVZBitMask,
			
			lpDDSurfaceDesc->ddsCaps.dwCaps, ddscaps1_buffer, lpDDSurfaceDesc->ddsCaps.dwCaps2, lpDDSurfaceDesc->ddsCaps.dwCaps3, lpDDSurfaceDesc->ddsCaps.dwCaps4, lpDDSurfaceDesc->dwTextureStage
		);
	}
	if(ishooked_ddrawsurface4_hooks == false)
	{
		HookVTBLCalls((LPVOID *)lplpDDSurface4, ddrawsurface4_hooks, count_ddrawsurface4_hooks, "IDirectDrawSurface4");
		ishooked_ddrawsurface4_hooks = true;
	}

	// ------------------------------------------------------------------
	// Create a DirectX window
	// ----------------------------
#ifdef FF8_WINDOWED
	if((void *)lpDDSurfaceDesc == (void *)0x00134658)
	{
		Log("IF[lpDDSurfaceDesc == 0x00134658] THEN\n");
		if(SUCCEEDED(ret))
		{

			LPDIRECTDRAWCLIPPER pcClipper;
			if(FAILED(((LPDIRECTDRAW4)ppvOut)->CreateClipper(0, &pcClipper, NULL)))
			{
				Log("ERROR: Couldn't create clipper\n");
			}

			// Associate the clipper with the window
			Log("g_hwnd=%#01lx\n", g_hwnd);
			pcClipper->SetHWnd(0, g_hwnd);
			(*lplpDDSurface4)->SetClipper(pcClipper);
			//SAFE_RELEASE(pcClipper);

			HRESULT hr = 0;
			LPDIRECTDRAWSURFACE4 lpddsB = NULL;
			LPDIRECTDRAWSURFACE4 lpddsZ = NULL;
			DDSURFACEDESC2 ddsd;
			ZeroMemory(&ddsd, sizeof(ddsd));
			ddsd.dwSize = sizeof(ddsd);
			ddsd.dwFlags = (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT);
			ddsd.ddsCaps.dwCaps    = (lpDDSurfaceDesc->ddsCaps.dwCaps);
			ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_PRIMARYSURFACE);
			ddsd.ddsCaps.dwCaps |= (DDSCAPS_OFFSCREENPLAIN);
			ddsd.dwWidth           = 640;
			ddsd.dwHeight          = 480;
			//hRes = lpdd->lpVtbl->CreateSurface(lpdd, &ddsd, &lpddZBuffer,NULL);
			hr = ((LPDIRECTDRAW4)ppvOut)->CreateSurface(&ddsd, &lpddsB, NULL);
			if(FAILED(hr))
			{
				Log("ERROR: Failed to create WINDOWED backbuffer!");
			} else {
				//hr = (*lplpDDSurface4)->AddAttachedSurface(lpddsB);
				//if(FAILED(hr)) {
				//	Log("ERROR: Failed to attach WINDOWED backbuffer to frontbuffer!");
				//} else {
					g_frontbuffer = (*lplpDDSurface4);
					g_backbuffer = lpddsB;
					/*hr = ((LPDIRECTDRAW4)ppvOut)->CreateSurface(&ddsd, &lpddsZ, NULL);
					if(FAILED(hr)) {
						Log("ERROR: Failed to create WINDOWED z-buffer!");
					} else {
						hr = lpddsB->AddAttachedSurface(lpddsZ);
						if(FAILED(hr)) {
							Log("ERROR: Failed to attach WINDOWED z-buffer to backbuffer!");
						} else {
							
						}
					}*/
				//}
			}
		}
	}
#endif
	// ----------------------------------

	return ret;
}