diff --git a/ddraw.def b/ddraw.def index 8262efb..fe68c2c 100644 --- a/ddraw.def +++ b/ddraw.def @@ -3,8 +3,9 @@ LIBRARY ddraw.dll EXPORTS DirectDrawCreate @8 DirectDrawCreateClipper @9 + DirectDrawCreateEx @10 DirectDrawEnumerateA @11 GameHandlesClose DATA NvOptimusEnablement DATA AmdPowerXpressRequestHighPerformance DATA - pvBmpBits = g_fake_primary_surface_export DATA + pvBmpBits = FakePrimarySurface DATA diff --git a/inc/dd.h b/inc/dd.h index d82360d..2c4d5ad 100644 --- a/inc/dd.h +++ b/inc/dd.h @@ -17,6 +17,7 @@ HRESULT dd_GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDEmulCaps); HRESULT dd_GetMonitorFrequency(LPDWORD lpdwFreq); HRESULT dd_GetAvailableVidMem(void* lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree); HRESULT dd_GetVerticalBlankStatus(LPBOOL lpbIsInVB); +HRESULT dd_CreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOuter); typedef struct speed_limiter { diff --git a/inc/dllmain.h b/inc/dllmain.h index 58a90ca..da9e9ff 100644 --- a/inc/dllmain.h +++ b/inc/dllmain.h @@ -5,7 +5,7 @@ #include extern BOOL GameHandlesClose; -extern void* g_fake_primary_surface_export; +extern void* FakePrimarySurface; extern HMODULE g_ddraw_module; typedef enum PROCESS_DPI_AWARENESS { diff --git a/src/IDirectDraw/IDirectDraw.c b/src/IDirectDraw/IDirectDraw.c index 1fb7cb8..3e2cf79 100644 --- a/src/IDirectDraw/IDirectDraw.c +++ b/src/IDirectDraw/IDirectDraw.c @@ -19,41 +19,46 @@ HRESULT __stdcall IDirectDraw__QueryInterface(IDirectDrawImpl* This, REFIID riid IsEqualGUID(&IID_IDirectDraw4, riid) || IsEqualGUID(&IID_IDirectDraw7, riid)) { - dprintf(" GUID = %08X (IID_IDirectDrawX)\n", ((GUID*)riid)->Data1); - IDirectDrawImpl* dd = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl)); + + dprintf(" GUID = %08X (IID_IDirectDrawX), ddraw = %p\n", ((GUID*)riid)->Data1, dd); + dd->lpVtbl = &g_dd_vtblx; + IDirectDraw_AddRef(dd); *obj = dd; - IDirectDraw_AddRef(dd); ret = S_OK; } else if (IsEqualGUID(&IID_IDirectDraw, riid)) { - dprintf(" GUID = %08X (IID_IDirectDraw)\n", ((GUID*)riid)->Data1); - IDirectDrawImpl* dd = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl)); + + dprintf(" GUID = %08X (IID_IDirectDraw), ddraw = %p\n", ((GUID*)riid)->Data1, dd); + dd->lpVtbl = &g_dd_vtbl1; + IDirectDraw_AddRef(dd); *obj = dd; - IDirectDraw_AddRef(dd); ret = S_OK; } else if (IsEqualGUID(&IID_IDirect3D, riid)) { - dprintf(" GUID = %08X (IID_IDirect3D)\n", ((GUID*)riid)->Data1); - IDirect3DImpl* d3d = (IDirect3DImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl)); + + dprintf(" GUID = %08X (IID_IDirect3D), d3d = %p\n", ((GUID*)riid)->Data1, d3d); + d3d->lpVtbl = &g_d3d_vtbl1; + d3d->lpVtbl->AddRef(d3d); *obj = d3d; - d3d->lpVtbl->AddRef(d3d); ret = S_OK; } - else if (IsEqualGUID(&IID_IDirect3D2, riid) || IsEqualGUID(&IID_IDirect3D3, riid) || IsEqualGUID(&IID_IDirect3D7, riid)) + else if (IsEqualGUID(&IID_IDirect3D2, riid) || + IsEqualGUID(&IID_IDirect3D3, riid) || + IsEqualGUID(&IID_IDirect3D7, riid)) { dprintf(" GUID = %08X (IID_IDirect3DX)\n", ((GUID*)riid)->Data1); diff --git a/src/dd.c b/src/dd.c index af1310e..dff20e0 100644 --- a/src/dd.c +++ b/src/dd.c @@ -1,4 +1,5 @@ #include +#include "IDirectDraw.h" #include "ddraw.h" #include "dd.h" #include "hook.h" @@ -821,3 +822,61 @@ HRESULT dd_GetVerticalBlankStatus(LPBOOL lpbIsInVB) *lpbIsInVB = TRUE; return DD_OK; } + +HRESULT dd_CreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOuter) +{ + if (g_ddraw) + { + /* FIXME: check the calling module before passing the call! */ + if (iid && IsEqualGUID(&IID_IDirectDraw, iid) && g_ddraw->DirectDrawCreate) + { + return g_ddraw->DirectDrawCreate(lpGuid, (LPDIRECTDRAW*)lplpDD, pUnkOuter); + } + + return DDERR_DIRECTDRAWALREADYCREATED; + } + + g_ddraw = (cnc_ddraw*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(cnc_ddraw)); + + IDirectDrawImpl* dd = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl)); + + if (iid && IsEqualGUID(&IID_IDirectDraw, iid)) + { + dprintf(" GUID = %08X (IID_IDirectDraw), ddraw = %p\n", ((GUID*)iid)->Data1, dd); + + dd->lpVtbl = &g_dd_vtbl1; + } + else + { + dprintf(" GUID = %08X (IID_IDirectDrawX), ddraw = %p\n", iid ? ((GUID*)iid)->Data1 : NULL, dd); + + dd->lpVtbl = &g_dd_vtblx; + } + + IDirectDraw_AddRef(dd); + + *lplpDD = (LPVOID)dd; + + if (!g_ddraw->real_dll) + { + g_ddraw->real_dll = LoadLibrary("system32\\ddraw.dll"); + } + + if (g_ddraw->real_dll && !g_ddraw->DirectDrawCreate) + { + g_ddraw->DirectDrawCreate = + (HRESULT(WINAPI*)(GUID FAR*, LPDIRECTDRAW FAR*, IUnknown FAR*))GetProcAddress(g_ddraw->real_dll, "DirectDrawCreate"); + + if (g_ddraw->DirectDrawCreate == DirectDrawCreate) + g_ddraw->DirectDrawCreate = NULL; + } + + InitializeCriticalSection(&g_ddraw->cs); + + g_ddraw->render.sem = CreateSemaphore(NULL, 0, 1, NULL); + g_ddraw->wine = GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0; + + cfg_load(); + + return DD_OK; +} diff --git a/src/ddclipper.c b/src/ddclipper.c index 81847f6..fb99b12 100644 --- a/src/ddclipper.c +++ b/src/ddclipper.c @@ -11,11 +11,13 @@ HRESULT dd_CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR *lplpDDClipper, return DDERR_INVALIDPARAMS; IDirectDrawClipperImpl *c = (IDirectDrawClipperImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawClipperImpl)); - c->lpVtbl = &g_ddc_vtbl; + dprintf(" Clipper = %p\n", c); - *lplpDDClipper = (LPDIRECTDRAWCLIPPER)c; + c->lpVtbl = &g_ddc_vtbl; IDirectDrawClipper_AddRef(c); + *lplpDDClipper = (LPDIRECTDRAWCLIPPER)c; + return DD_OK; } diff --git a/src/ddpalette.c b/src/ddpalette.c index 892ad91..4c67043 100644 --- a/src/ddpalette.c +++ b/src/ddpalette.c @@ -53,13 +53,14 @@ HRESULT ddp_SetEntries(IDirectDrawPaletteImpl *This, DWORD dwFlags, DWORD dwStar HRESULT dd_CreatePalette(DWORD dwFlags, LPPALETTEENTRY lpDDColorArray, LPDIRECTDRAWPALETTE FAR * lpDDPalette, IUnknown FAR * unkOuter) { IDirectDrawPaletteImpl *p = (IDirectDrawPaletteImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawPaletteImpl)); - p->lpVtbl = &g_ddp_vtbl; + dprintf(" Palette = %p\n", p); - *lpDDPalette = (LPDIRECTDRAWPALETTE)p; + p->lpVtbl = &g_ddp_vtbl; ddp_SetEntries(p, dwFlags, 0, 256, lpDDColorArray); - IDirectDrawPalette_AddRef(p); + *lpDDPalette = (LPDIRECTDRAWPALETTE)p; + return DD_OK; } diff --git a/src/ddsurface.c b/src/ddsurface.c index 484bc14..4052078 100644 --- a/src/ddsurface.c +++ b/src/ddsurface.c @@ -879,7 +879,7 @@ HRESULT dd_CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FA if (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { - g_fake_primary_surface_export = dst_surface->surface; + FakePrimarySurface = dst_surface->surface; } SelectObject(dst_surface->hdc, dst_surface->bitmap); diff --git a/src/dllmain.c b/src/dllmain.c index b02628d..49273bd 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -7,7 +7,6 @@ #include "debug.h" #include "config.h" #include "directinput.h" -#include "IDirectDraw.h" #include "hook.h" // exports to force usage of discrete high performance graphics device @@ -18,7 +17,7 @@ DWORD AmdPowerXpressRequestHighPerformance = 1; BOOL GameHandlesClose; // export for some warcraft II tools -void *g_fake_primary_surface_export; +PVOID FakePrimarySurface; HMODULE g_ddraw_module; @@ -138,49 +137,15 @@ HRESULT WINAPI DirectDrawCreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR* l HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter) { dprintf("-> %s(lpGUID=%p, lplpDD=%p, pUnkOuter=%p)\n", __FUNCTION__, lpGUID, lplpDD, pUnkOuter); - - if (g_ddraw) - { - /* FIXME: check the calling module before passing the call! */ - if (g_ddraw->DirectDrawCreate) - { - dprintf("<- %s\n", __FUNCTION__); - return g_ddraw->DirectDrawCreate(lpGUID, lplpDD, pUnkOuter); - } - - dprintf("<- %s\n", __FUNCTION__); - return DDERR_DIRECTDRAWALREADYCREATED; - } - - g_ddraw = (cnc_ddraw*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(cnc_ddraw)); - - IDirectDrawImpl* dst_ddraw = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl)); - dst_ddraw->lpVtbl = &g_dd_vtbl1; - - *lplpDD = (LPDIRECTDRAW)dst_ddraw; - IDirectDraw_AddRef(dst_ddraw); - - if (!g_ddraw->real_dll) - { - g_ddraw->real_dll = LoadLibrary("system32\\ddraw.dll"); - } - - if (g_ddraw->real_dll && !g_ddraw->DirectDrawCreate) - { - g_ddraw->DirectDrawCreate = - (HRESULT(WINAPI*)(GUID FAR*, LPDIRECTDRAW FAR*, IUnknown FAR*))GetProcAddress(g_ddraw->real_dll, "DirectDrawCreate"); - - if (g_ddraw->DirectDrawCreate == DirectDrawCreate) - g_ddraw->DirectDrawCreate = NULL; - } - - InitializeCriticalSection(&g_ddraw->cs); - - g_ddraw->render.sem = CreateSemaphore(NULL, 0, 1, NULL); - g_ddraw->wine = GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0; - - cfg_load(); - + HRESULT ret = dd_CreateEx(lpGUID, (LPVOID*)lplpDD, &IID_IDirectDraw, pUnkOuter); dprintf("<- %s\n", __FUNCTION__); - return DD_OK; + return ret; +} + +HRESULT WINAPI DirectDrawCreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOuter) +{ + dprintf("-> %s(lpGUID=%p, lplpDD=%p, riid=%08X, pUnkOuter=%p)\n", __FUNCTION__, lpGuid, lplpDD, iid, pUnkOuter); + HRESULT ret = dd_CreateEx(lpGuid, lplpDD, iid, pUnkOuter); + dprintf("<- %s\n", __FUNCTION__); + return ret; }