mirror of
https://github.com/DxWnd/DxWnd.reloaded
synced 2024-12-30 09:25:35 +01:00
5700 lines
256 KiB
C++
5700 lines
256 KiB
C++
#define _CRT_SECURE_NO_WARNINGS
|
|
#define INITGUID
|
|
//#define FULLHEXDUMP
|
|
|
|
#include <windows.h>
|
|
#include <ddraw.h>
|
|
#include "dxwnd.h"
|
|
#include "dxhook.h"
|
|
#include "ddrawi.h"
|
|
#include "dxwcore.hpp"
|
|
#include "stdio.h"
|
|
#include "hddraw.h"
|
|
#include "dxhelper.h"
|
|
#include "syslibs.h"
|
|
|
|
#define HANDLEFLIPPABLE
|
|
|
|
#ifdef CHECKMETHODPOINTERS
|
|
static void NullMethodPointer(char *s)
|
|
{
|
|
char msg[80];
|
|
sprintf(msg, "NULL %s method", s);
|
|
MessageBox(0, msg, "DxWnd", MB_OK);
|
|
}
|
|
#define CHECKPTR(p, s) if(!p) NullMethodPointer(s)
|
|
#else
|
|
#define CHECKPTR(p, s)
|
|
#endif
|
|
|
|
extern BOOL IsChangeDisplaySettingsHotPatched;
|
|
extern void TextureHandling(LPDIRECTDRAWSURFACE, int);
|
|
extern void SetMinimalCaps(int, LPDDCAPS, LPDDCAPS);
|
|
ColorConversion_Type pColorConversion = NULL;
|
|
extern HRESULT WINAPI extQueryInterfaceDX(int, QueryInterface_Type, void *, REFIID, LPVOID *);
|
|
|
|
HDC hFlippedDC = NULL;
|
|
BOOL bFlippedDC = FALSE;
|
|
DWORD dwBackBufferCaps = 0;
|
|
BOOL bVSyncDone;
|
|
|
|
// DirectDraw API
|
|
HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *);
|
|
HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *, LPDIRECTDRAW FAR *, REFIID, IUnknown FAR *);
|
|
HRESULT WINAPI extDirectDrawEnumerateA(LPDDENUMCALLBACKA, LPVOID);
|
|
HRESULT WINAPI extDirectDrawEnumerateExA(LPDDENUMCALLBACKEXA, LPVOID, DWORD);
|
|
HRESULT WINAPI extDirectDrawEnumerateW(LPDDENUMCALLBACKW, LPVOID);
|
|
HRESULT WINAPI extDirectDrawEnumerateExW(LPDDENUMCALLBACKEXW, LPVOID, DWORD);
|
|
HRESULT WINAPI extDirectDrawCreateClipper(DWORD, LPDIRECTDRAWCLIPPER *, IUnknown *);
|
|
|
|
// DirectDraw
|
|
HRESULT WINAPI extQueryInterfaceD1(void *, REFIID, LPVOID *);
|
|
HRESULT WINAPI extQueryInterfaceD2(void *, REFIID, LPVOID *);
|
|
HRESULT WINAPI extQueryInterfaceD3(void *, REFIID, LPVOID *);
|
|
HRESULT WINAPI extQueryInterfaceD4(void *, REFIID, LPVOID *);
|
|
HRESULT WINAPI extQueryInterfaceD7(void *, REFIID, LPVOID *);
|
|
ULONG WINAPI extReleaseD1(LPDIRECTDRAW);
|
|
ULONG WINAPI extReleaseD2(LPDIRECTDRAW);
|
|
ULONG WINAPI extReleaseD3(LPDIRECTDRAW);
|
|
ULONG WINAPI extReleaseD4(LPDIRECTDRAW);
|
|
ULONG WINAPI extReleaseD7(LPDIRECTDRAW);
|
|
|
|
/*** IDirectDraw methods ***/
|
|
HRESULT WINAPI extCompact(LPDIRECTDRAW); // unimplemented method ???
|
|
HRESULT WINAPI extCreateClipper1(LPDIRECTDRAW, DWORD, LPDIRECTDRAWCLIPPER FAR* , IUnknown FAR*);
|
|
HRESULT WINAPI extCreateClipper2(LPDIRECTDRAW, DWORD, LPDIRECTDRAWCLIPPER FAR* , IUnknown FAR*);
|
|
HRESULT WINAPI extCreateClipper3(LPDIRECTDRAW, DWORD, LPDIRECTDRAWCLIPPER FAR* , IUnknown FAR*);
|
|
HRESULT WINAPI extCreateClipper4(LPDIRECTDRAW, DWORD, LPDIRECTDRAWCLIPPER FAR* , IUnknown FAR*);
|
|
HRESULT WINAPI extCreateClipper7(LPDIRECTDRAW, DWORD, LPDIRECTDRAWCLIPPER FAR* , IUnknown FAR*);
|
|
HRESULT WINAPI extCreatePalette1(LPDIRECTDRAW, DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE *, IUnknown *);
|
|
HRESULT WINAPI extCreatePalette2(LPDIRECTDRAW, DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE *, IUnknown *);
|
|
HRESULT WINAPI extCreatePalette3(LPDIRECTDRAW, DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE *, IUnknown *);
|
|
HRESULT WINAPI extCreatePalette4(LPDIRECTDRAW, DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE *, IUnknown *);
|
|
HRESULT WINAPI extCreatePalette7(LPDIRECTDRAW, DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE *, IUnknown *);
|
|
HRESULT WINAPI extCreateSurface1(LPDIRECTDRAW, DDSURFACEDESC *, LPDIRECTDRAWSURFACE *, void *);
|
|
HRESULT WINAPI extCreateSurface2(LPDIRECTDRAW, DDSURFACEDESC *, LPDIRECTDRAWSURFACE *, void *);
|
|
HRESULT WINAPI extCreateSurface3(LPDIRECTDRAW, DDSURFACEDESC *, LPDIRECTDRAWSURFACE *, void *);
|
|
HRESULT WINAPI extCreateSurface4(LPDIRECTDRAW, DDSURFACEDESC2 *, LPDIRECTDRAWSURFACE *, void *);
|
|
HRESULT WINAPI extCreateSurface7(LPDIRECTDRAW, DDSURFACEDESC2 *, LPDIRECTDRAWSURFACE *, void *);
|
|
HRESULT WINAPI extDuplicateSurface1(LPDIRECTDRAW, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR *);
|
|
HRESULT WINAPI extDuplicateSurface2(LPDIRECTDRAW, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR *);
|
|
HRESULT WINAPI extDuplicateSurface3(LPDIRECTDRAW, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR *);
|
|
HRESULT WINAPI extDuplicateSurface4(LPDIRECTDRAW, LPDIRECTDRAWSURFACE4, LPDIRECTDRAWSURFACE4 FAR *);
|
|
HRESULT WINAPI extDuplicateSurface7(LPDIRECTDRAW, LPDIRECTDRAWSURFACE7, LPDIRECTDRAWSURFACE7 FAR *);
|
|
HRESULT WINAPI extFlipToGDISurface1(LPDIRECTDRAW);
|
|
HRESULT WINAPI extFlipToGDISurface2(LPDIRECTDRAW);
|
|
HRESULT WINAPI extFlipToGDISurface3(LPDIRECTDRAW);
|
|
HRESULT WINAPI extFlipToGDISurface4(LPDIRECTDRAW);
|
|
HRESULT WINAPI extFlipToGDISurface7(LPDIRECTDRAW);
|
|
HRESULT WINAPI extGetDisplayMode1(LPDIRECTDRAW, LPDDSURFACEDESC);
|
|
HRESULT WINAPI extGetDisplayMode2(LPDIRECTDRAW, LPDDSURFACEDESC);
|
|
HRESULT WINAPI extGetDisplayMode3(LPDIRECTDRAW, LPDDSURFACEDESC);
|
|
HRESULT WINAPI extGetDisplayMode4(LPDIRECTDRAW, LPDDSURFACEDESC2);
|
|
HRESULT WINAPI extGetDisplayMode7(LPDIRECTDRAW, LPDDSURFACEDESC2);
|
|
HRESULT WINAPI extGetGDISurface1(LPDIRECTDRAW, LPDIRECTDRAWSURFACE *);
|
|
HRESULT WINAPI extGetGDISurface2(LPDIRECTDRAW, LPDIRECTDRAWSURFACE *);
|
|
HRESULT WINAPI extGetGDISurface3(LPDIRECTDRAW, LPDIRECTDRAWSURFACE *);
|
|
HRESULT WINAPI extGetGDISurface4(LPDIRECTDRAW, LPDIRECTDRAWSURFACE *);
|
|
HRESULT WINAPI extGetGDISurface7(LPDIRECTDRAW, LPDIRECTDRAWSURFACE *);
|
|
HRESULT WINAPI extEnumDisplayModes1(LPDIRECTDRAW, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK);
|
|
HRESULT WINAPI extEnumDisplayModes2(LPDIRECTDRAW, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK);
|
|
HRESULT WINAPI extEnumDisplayModes3(LPDIRECTDRAW, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK);
|
|
HRESULT WINAPI extEnumDisplayModes4(LPDIRECTDRAW, DWORD, LPDDSURFACEDESC2, LPVOID, LPDDENUMMODESCALLBACK2);
|
|
HRESULT WINAPI extEnumDisplayModes7(LPDIRECTDRAW, DWORD, LPDDSURFACEDESC2, LPVOID, LPDDENUMMODESCALLBACK2);
|
|
HRESULT WINAPI extInitialize1(LPDIRECTDRAW, FAR GUID *);
|
|
HRESULT WINAPI extInitialize2(LPDIRECTDRAW, FAR GUID *);
|
|
HRESULT WINAPI extInitialize3(LPDIRECTDRAW, FAR GUID *);
|
|
HRESULT WINAPI extInitialize4(LPDIRECTDRAW, FAR GUID *);
|
|
HRESULT WINAPI extInitialize7(LPDIRECTDRAW, FAR GUID *);
|
|
HRESULT WINAPI extRestoreDisplayMode1(LPDIRECTDRAW);
|
|
HRESULT WINAPI extRestoreDisplayMode2(LPDIRECTDRAW);
|
|
HRESULT WINAPI extRestoreDisplayMode3(LPDIRECTDRAW);
|
|
HRESULT WINAPI extRestoreDisplayMode4(LPDIRECTDRAW);
|
|
HRESULT WINAPI extRestoreDisplayMode7(LPDIRECTDRAW);
|
|
HRESULT WINAPI extSetCooperativeLevel1(LPDIRECTDRAW, HWND, DWORD);
|
|
HRESULT WINAPI extSetCooperativeLevel2(LPDIRECTDRAW, HWND, DWORD);
|
|
HRESULT WINAPI extSetCooperativeLevel3(LPDIRECTDRAW, HWND, DWORD);
|
|
HRESULT WINAPI extSetCooperativeLevel4(LPDIRECTDRAW, HWND, DWORD);
|
|
HRESULT WINAPI extSetCooperativeLevel7(LPDIRECTDRAW, HWND, DWORD);
|
|
HRESULT WINAPI extSetDisplayMode1(LPDIRECTDRAW, DWORD, DWORD, DWORD);
|
|
HRESULT WINAPI extSetDisplayMode2(LPDIRECTDRAW, DWORD, DWORD, DWORD, DWORD, DWORD);
|
|
HRESULT WINAPI extSetDisplayMode3(LPDIRECTDRAW, DWORD, DWORD, DWORD, DWORD, DWORD);
|
|
HRESULT WINAPI extSetDisplayMode4(LPDIRECTDRAW, DWORD, DWORD, DWORD, DWORD, DWORD);
|
|
HRESULT WINAPI extSetDisplayMode7(LPDIRECTDRAW, DWORD, DWORD, DWORD, DWORD, DWORD);
|
|
HRESULT WINAPI extWaitForVerticalBlank1(LPDIRECTDRAW, DWORD, HANDLE);
|
|
HRESULT WINAPI extWaitForVerticalBlank2(LPDIRECTDRAW, DWORD, HANDLE);
|
|
HRESULT WINAPI extWaitForVerticalBlank3(LPDIRECTDRAW, DWORD, HANDLE);
|
|
HRESULT WINAPI extWaitForVerticalBlank4(LPDIRECTDRAW, DWORD, HANDLE);
|
|
HRESULT WINAPI extWaitForVerticalBlank7(LPDIRECTDRAW, DWORD, HANDLE);
|
|
/*** Added in the V2 Interface ***/
|
|
HRESULT WINAPI extGetAvailableVidMem2(LPDIRECTDRAW, LPDDSCAPS, LPDWORD, LPDWORD);
|
|
HRESULT WINAPI extGetAvailableVidMem3(LPDIRECTDRAW, LPDDSCAPS, LPDWORD, LPDWORD);
|
|
HRESULT WINAPI extGetAvailableVidMem4(LPDIRECTDRAW, LPDDSCAPS2, LPDWORD, LPDWORD);
|
|
HRESULT WINAPI extGetAvailableVidMem7(LPDIRECTDRAW, LPDDSCAPS2, LPDWORD, LPDWORD);
|
|
/*** Added in the V4 Interface ***/
|
|
HRESULT WINAPI extTestCooperativeLevel4(LPDIRECTDRAW);
|
|
HRESULT WINAPI extTestCooperativeLevel7(LPDIRECTDRAW);
|
|
// STDMETHOD(StartModeTest)(THIS_ LPSIZE, DWORD, DWORD ) PURE;
|
|
// STDMETHOD(EvaluateMode)(THIS_ DWORD, DWORD * ) PURE;
|
|
HRESULT WINAPI extGetCaps1D(LPDIRECTDRAW, LPDDCAPS, LPDDCAPS);
|
|
HRESULT WINAPI extGetCaps2D(LPDIRECTDRAW, LPDDCAPS, LPDDCAPS);
|
|
HRESULT WINAPI extGetCaps3D(LPDIRECTDRAW, LPDDCAPS, LPDDCAPS);
|
|
HRESULT WINAPI extGetCaps4D(LPDIRECTDRAW, LPDDCAPS, LPDDCAPS);
|
|
HRESULT WINAPI extGetCaps7D(LPDIRECTDRAW, LPDDCAPS, LPDDCAPS);
|
|
HRESULT WINAPI extGetScanLine1(LPDIRECTDRAW, LPDWORD);
|
|
HRESULT WINAPI extGetScanLine2(LPDIRECTDRAW, LPDWORD);
|
|
HRESULT WINAPI extGetScanLine3(LPDIRECTDRAW, LPDWORD);
|
|
HRESULT WINAPI extGetScanLine4(LPDIRECTDRAW, LPDWORD);
|
|
HRESULT WINAPI extGetScanLine7(LPDIRECTDRAW, LPDWORD);
|
|
/*** Added in the V7 Interface ??? ***/
|
|
HRESULT WINAPI extStartModeTest(LPDIRECTDRAW, LPSIZE, DWORD, DWORD);
|
|
HRESULT WINAPI extEvaluateMode(LPDIRECTDRAW, DWORD, DWORD *);
|
|
|
|
// DirectDrawSurface
|
|
HRESULT WINAPI extQueryInterfaceS1(void *, REFIID, LPVOID *);
|
|
HRESULT WINAPI extQueryInterfaceS2(void *, REFIID, LPVOID *);
|
|
HRESULT WINAPI extQueryInterfaceS3(void *, REFIID, LPVOID *);
|
|
HRESULT WINAPI extQueryInterfaceS4(void *, REFIID, LPVOID *);
|
|
HRESULT WINAPI extQueryInterfaceS7(void *, REFIID, LPVOID *);
|
|
HRESULT WINAPI extReleaseS1(LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extReleaseS2(LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extReleaseS3(LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extReleaseS4(LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extReleaseS7(LPDIRECTDRAWSURFACE);
|
|
|
|
/*** IDirectDrawSurface methods ***/
|
|
HRESULT WINAPI extAddAttachedSurface1(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extAddAttachedSurface2(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extAddAttachedSurface3(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extAddAttachedSurface4(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extAddAttachedSurface7(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extBlt1(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX);
|
|
HRESULT WINAPI extBlt2(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX);
|
|
HRESULT WINAPI extBlt3(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX);
|
|
HRESULT WINAPI extBlt4(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX);
|
|
HRESULT WINAPI extBlt7(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX);
|
|
HRESULT WINAPI extBltFast1(LPDIRECTDRAWSURFACE, DWORD, DWORD, LPDIRECTDRAWSURFACE, LPRECT, DWORD);
|
|
HRESULT WINAPI extBltFast2(LPDIRECTDRAWSURFACE, DWORD, DWORD, LPDIRECTDRAWSURFACE, LPRECT, DWORD);
|
|
HRESULT WINAPI extBltFast3(LPDIRECTDRAWSURFACE, DWORD, DWORD, LPDIRECTDRAWSURFACE, LPRECT, DWORD);
|
|
HRESULT WINAPI extBltFast4(LPDIRECTDRAWSURFACE, DWORD, DWORD, LPDIRECTDRAWSURFACE, LPRECT, DWORD);
|
|
HRESULT WINAPI extBltFast7(LPDIRECTDRAWSURFACE, DWORD, DWORD, LPDIRECTDRAWSURFACE, LPRECT, DWORD);
|
|
HRESULT WINAPI extDeleteAttachedSurface1(LPDIRECTDRAWSURFACE, DWORD, LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extDeleteAttachedSurface2(LPDIRECTDRAWSURFACE, DWORD, LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extDeleteAttachedSurface3(LPDIRECTDRAWSURFACE, DWORD, LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extDeleteAttachedSurface4(LPDIRECTDRAWSURFACE, DWORD, LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extDeleteAttachedSurface7(LPDIRECTDRAWSURFACE, DWORD, LPDIRECTDRAWSURFACE);
|
|
HRESULT WINAPI extEnumAttachedSurfaces1(LPDIRECTDRAWSURFACE, LPVOID, LPDDENUMSURFACESCALLBACK);
|
|
HRESULT WINAPI extEnumAttachedSurfaces2(LPDIRECTDRAWSURFACE, LPVOID, LPDDENUMSURFACESCALLBACK);
|
|
HRESULT WINAPI extEnumAttachedSurfaces3(LPDIRECTDRAWSURFACE, LPVOID, LPDDENUMSURFACESCALLBACK);
|
|
HRESULT WINAPI extEnumAttachedSurfaces4(LPDIRECTDRAWSURFACE, LPVOID, LPDDENUMSURFACESCALLBACK);
|
|
HRESULT WINAPI extEnumAttachedSurfaces7(LPDIRECTDRAWSURFACE, LPVOID, LPDDENUMSURFACESCALLBACK);
|
|
HRESULT WINAPI extFlip1(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE, DWORD);
|
|
HRESULT WINAPI extFlip2(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE, DWORD);
|
|
HRESULT WINAPI extFlip3(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE, DWORD);
|
|
HRESULT WINAPI extFlip4(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE, DWORD);
|
|
HRESULT WINAPI extFlip7(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE, DWORD);
|
|
HRESULT WINAPI extGetAttachedSurface1(LPDIRECTDRAWSURFACE, LPDDSCAPS, LPDIRECTDRAWSURFACE *);
|
|
HRESULT WINAPI extGetAttachedSurface2(LPDIRECTDRAWSURFACE, LPDDSCAPS, LPDIRECTDRAWSURFACE *);
|
|
HRESULT WINAPI extGetAttachedSurface3(LPDIRECTDRAWSURFACE, LPDDSCAPS, LPDIRECTDRAWSURFACE *);
|
|
HRESULT WINAPI extGetAttachedSurface4(LPDIRECTDRAWSURFACE, LPDDSCAPS2, LPDIRECTDRAWSURFACE *);
|
|
HRESULT WINAPI extGetAttachedSurface7(LPDIRECTDRAWSURFACE, LPDDSCAPS2, LPDIRECTDRAWSURFACE *);
|
|
HRESULT WINAPI extGetCaps1S(LPDIRECTDRAWSURFACE, LPDDSCAPS);
|
|
HRESULT WINAPI extGetCaps2S(LPDIRECTDRAWSURFACE, LPDDSCAPS);
|
|
HRESULT WINAPI extGetCaps3S(LPDIRECTDRAWSURFACE, LPDDSCAPS);
|
|
HRESULT WINAPI extGetCaps4S(LPDIRECTDRAWSURFACE, LPDDSCAPS2);
|
|
HRESULT WINAPI extGetCaps7S(LPDIRECTDRAWSURFACE, LPDDSCAPS2);
|
|
HRESULT WINAPI extGetColorKey1(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY);
|
|
HRESULT WINAPI extGetColorKey2(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY);
|
|
HRESULT WINAPI extGetColorKey3(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY);
|
|
HRESULT WINAPI extGetColorKey4(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY);
|
|
HRESULT WINAPI extGetColorKey7(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY);
|
|
HRESULT WINAPI extGetDC1(LPDIRECTDRAWSURFACE, HDC FAR *);
|
|
HRESULT WINAPI extGetDC2(LPDIRECTDRAWSURFACE, HDC FAR *);
|
|
HRESULT WINAPI extGetDC3(LPDIRECTDRAWSURFACE, HDC FAR *);
|
|
HRESULT WINAPI extGetDC4(LPDIRECTDRAWSURFACE, HDC FAR *);
|
|
HRESULT WINAPI extGetDC7(LPDIRECTDRAWSURFACE, HDC FAR *);
|
|
HRESULT WINAPI extGetPalette1(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE *);
|
|
HRESULT WINAPI extGetPalette2(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE *);
|
|
HRESULT WINAPI extGetPalette3(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE *);
|
|
HRESULT WINAPI extGetPalette4(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE *);
|
|
HRESULT WINAPI extGetPalette7(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE *);
|
|
HRESULT WINAPI extGetPixelFormat1(LPDIRECTDRAWSURFACE, LPDDPIXELFORMAT);
|
|
HRESULT WINAPI extGetPixelFormat2(LPDIRECTDRAWSURFACE, LPDDPIXELFORMAT);
|
|
HRESULT WINAPI extGetPixelFormat3(LPDIRECTDRAWSURFACE, LPDDPIXELFORMAT);
|
|
HRESULT WINAPI extGetPixelFormat4(LPDIRECTDRAWSURFACE, LPDDPIXELFORMAT);
|
|
HRESULT WINAPI extGetPixelFormat7(LPDIRECTDRAWSURFACE, LPDDPIXELFORMAT);
|
|
HRESULT WINAPI extGetSurfaceDesc1(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd);
|
|
HRESULT WINAPI extGetSurfaceDesc2(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd);
|
|
HRESULT WINAPI extGetSurfaceDesc3(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd);
|
|
HRESULT WINAPI extGetSurfaceDesc4(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 lpddsd);
|
|
HRESULT WINAPI extGetSurfaceDesc7(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 lpddsd);
|
|
HRESULT WINAPI extLock1(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
|
|
HRESULT WINAPI extLock2(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
|
|
HRESULT WINAPI extLock3(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
|
|
HRESULT WINAPI extLock4(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
|
|
HRESULT WINAPI extLock7(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
|
|
HRESULT WINAPI extLockDir1(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
|
|
HRESULT WINAPI extLockDir2(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
|
|
HRESULT WINAPI extLockDir3(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
|
|
HRESULT WINAPI extLockDir4(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
|
|
HRESULT WINAPI extLockDir7(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
|
|
HRESULT WINAPI extReleaseDC1(LPDIRECTDRAWSURFACE, HDC);
|
|
HRESULT WINAPI extReleaseDC2(LPDIRECTDRAWSURFACE, HDC);
|
|
HRESULT WINAPI extReleaseDC3(LPDIRECTDRAWSURFACE, HDC);
|
|
HRESULT WINAPI extReleaseDC4(LPDIRECTDRAWSURFACE, HDC);
|
|
HRESULT WINAPI extReleaseDC7(LPDIRECTDRAWSURFACE, HDC);
|
|
HRESULT WINAPI extSetClipper1(LPDIRECTDRAWSURFACE, LPDIRECTDRAWCLIPPER);
|
|
HRESULT WINAPI extSetClipper2(LPDIRECTDRAWSURFACE, LPDIRECTDRAWCLIPPER);
|
|
HRESULT WINAPI extSetClipper3(LPDIRECTDRAWSURFACE, LPDIRECTDRAWCLIPPER);
|
|
HRESULT WINAPI extSetClipper4(LPDIRECTDRAWSURFACE, LPDIRECTDRAWCLIPPER);
|
|
HRESULT WINAPI extSetClipper7(LPDIRECTDRAWSURFACE, LPDIRECTDRAWCLIPPER);
|
|
HRESULT WINAPI extSetColorKey1(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY);
|
|
HRESULT WINAPI extSetColorKey2(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY);
|
|
HRESULT WINAPI extSetColorKey3(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY);
|
|
HRESULT WINAPI extSetColorKey4(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY);
|
|
HRESULT WINAPI extSetColorKey7(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY);
|
|
HRESULT WINAPI extSetPalette1(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE);
|
|
HRESULT WINAPI extSetPalette2(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE);
|
|
HRESULT WINAPI extSetPalette3(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE);
|
|
HRESULT WINAPI extSetPalette4(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE);
|
|
HRESULT WINAPI extSetPalette7(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE);
|
|
HRESULT WINAPI extUnlock1(LPDIRECTDRAWSURFACE, LPVOID);
|
|
HRESULT WINAPI extUnlock2(LPDIRECTDRAWSURFACE, LPVOID);
|
|
HRESULT WINAPI extUnlock3(LPDIRECTDRAWSURFACE, LPVOID);
|
|
HRESULT WINAPI extUnlock4(LPDIRECTDRAWSURFACE, LPRECT);
|
|
HRESULT WINAPI extUnlock7(LPDIRECTDRAWSURFACE, LPRECT);
|
|
HRESULT WINAPI extUnlockDir1(LPDIRECTDRAWSURFACE, LPVOID);
|
|
HRESULT WINAPI extUnlockDir2(LPDIRECTDRAWSURFACE, LPVOID);
|
|
HRESULT WINAPI extUnlockDir3(LPDIRECTDRAWSURFACE, LPVOID);
|
|
HRESULT WINAPI extUnlockDir4(LPDIRECTDRAWSURFACE, LPRECT);
|
|
HRESULT WINAPI extUnlockDir7(LPDIRECTDRAWSURFACE, LPRECT);
|
|
HRESULT WINAPI extEnumOverlayZOrders1(LPDIRECTDRAWSURFACE, DWORD, LPVOID, LPDDENUMSURFACESCALLBACK);
|
|
HRESULT WINAPI extEnumOverlayZOrders2(LPDIRECTDRAWSURFACE, DWORD, LPVOID, LPDDENUMSURFACESCALLBACK);
|
|
HRESULT WINAPI extEnumOverlayZOrders3(LPDIRECTDRAWSURFACE, DWORD, LPVOID, LPDDENUMSURFACESCALLBACK);
|
|
HRESULT WINAPI extEnumOverlayZOrders4(LPDIRECTDRAWSURFACE, DWORD, LPVOID, LPDDENUMSURFACESCALLBACK);
|
|
HRESULT WINAPI extEnumOverlayZOrders7(LPDIRECTDRAWSURFACE, DWORD, LPVOID, LPDDENUMSURFACESCALLBACK);
|
|
HRESULT WINAPI extAddOverlayDirtyRect1(LPDIRECTDRAWSURFACE, LPRECT);
|
|
HRESULT WINAPI extAddOverlayDirtyRect2(LPDIRECTDRAWSURFACE, LPRECT);
|
|
HRESULT WINAPI extAddOverlayDirtyRect3(LPDIRECTDRAWSURFACE, LPRECT);
|
|
HRESULT WINAPI extAddOverlayDirtyRect4(LPDIRECTDRAWSURFACE, LPRECT);
|
|
HRESULT WINAPI extAddOverlayDirtyRect7(LPDIRECTDRAWSURFACE, LPRECT);
|
|
HRESULT WINAPI extGetOverlayPosition1(LPDIRECTDRAWSURFACE, LPLONG, LPLONG);
|
|
HRESULT WINAPI extGetOverlayPosition2(LPDIRECTDRAWSURFACE, LPLONG, LPLONG);
|
|
HRESULT WINAPI extGetOverlayPosition3(LPDIRECTDRAWSURFACE, LPLONG, LPLONG);
|
|
HRESULT WINAPI extGetOverlayPosition4(LPDIRECTDRAWSURFACE, LPLONG, LPLONG);
|
|
HRESULT WINAPI extGetOverlayPosition7(LPDIRECTDRAWSURFACE, LPLONG, LPLONG);
|
|
HRESULT WINAPI extSetOverlayPosition1(LPDIRECTDRAWSURFACE, LONG, LONG);
|
|
HRESULT WINAPI extSetOverlayPosition2(LPDIRECTDRAWSURFACE, LONG, LONG);
|
|
HRESULT WINAPI extSetOverlayPosition3(LPDIRECTDRAWSURFACE, LONG, LONG);
|
|
HRESULT WINAPI extSetOverlayPosition4(LPDIRECTDRAWSURFACE, LONG, LONG);
|
|
HRESULT WINAPI extSetOverlayPosition7(LPDIRECTDRAWSURFACE, LONG, LONG);
|
|
|
|
extern HRESULT WINAPI extCreateSurface(int, CreateSurface_Type, LPDIRECTDRAW, DDSURFACEDESC2 *, LPDIRECTDRAWSURFACE *, void *);
|
|
HRESULT WINAPI extSetSurfaceDesc3(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, DWORD);
|
|
HRESULT WINAPI extSetSurfaceDesc4(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, DWORD);
|
|
HRESULT WINAPI extSetSurfaceDesc7(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, DWORD);
|
|
|
|
// DirectDrawClipper
|
|
HRESULT WINAPI extReleaseC(LPDIRECTDRAWCLIPPER);
|
|
HRESULT WINAPI extGetClipList(LPDIRECTDRAWCLIPPER, LPRECT, LPRGNDATA, LPDWORD);
|
|
HRESULT WINAPI extSetClipList(LPDIRECTDRAWCLIPPER, LPRGNDATA, DWORD);
|
|
HRESULT WINAPI extSetHWnd(LPDIRECTDRAWCLIPPER, DWORD, HWND);
|
|
|
|
// DirectDrawPalette
|
|
HRESULT WINAPI extReleaseP(LPDIRECTDRAWPALETTE);
|
|
// STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD, LPPALETTEENTRY) PURE;
|
|
HRESULT WINAPI extSetEntries(LPDIRECTDRAWPALETTE, DWORD, DWORD, DWORD, LPPALETTEENTRY);
|
|
|
|
// GammaRamp
|
|
HRESULT WINAPI extDDSetGammaRamp(LPDIRECTDRAWSURFACE, DWORD, LPDDGAMMARAMP);
|
|
HRESULT WINAPI extDDGetGammaRamp(LPDIRECTDRAWSURFACE, DWORD, LPDDGAMMARAMP);
|
|
|
|
|
|
HDC WINAPI extGDIGetDC(HWND);
|
|
HDC WINAPI extGDIGetWindowDC(HWND);
|
|
int WINAPI extGDIReleaseDC(HWND, HDC);
|
|
|
|
/* DirectDraw APIs */
|
|
DirectDrawCreate_Type pDirectDrawCreate = NULL;
|
|
DirectDrawCreateEx_Type pDirectDrawCreateEx = NULL;
|
|
DirectDrawEnumerateA_Type pDirectDrawEnumerateA = NULL;
|
|
DirectDrawEnumerateW_Type pDirectDrawEnumerateW = NULL;
|
|
DirectDrawEnumerateExA_Type pDirectDrawEnumerateExA = NULL;
|
|
DirectDrawEnumerateExW_Type pDirectDrawEnumerateExW = NULL;
|
|
DirectDrawCreateClipper_Type pDirectDrawCreateClipper = NULL;
|
|
HandleDDThreadLock_Type pAcquireDDThreadLock = NULL;
|
|
HandleDDThreadLock_Type pReleaseDDThreadLock = NULL;
|
|
StartModeTest_Type pStartModeTest = NULL;
|
|
EvaluateMode_Type pEvaluateMode = NULL;
|
|
|
|
/* DirectDraw hook pointers */
|
|
QueryInterface_Type pQueryInterfaceD1, pQueryInterfaceD2, pQueryInterfaceD3, pQueryInterfaceD4, pQueryInterfaceD7;
|
|
AddRefD_Type pAddRefD;
|
|
ReleaseD_Type pReleaseD1, pReleaseD2, pReleaseD3, pReleaseD4, pReleaseD7;
|
|
Compact_Type pCompact;
|
|
CreateClipper_Type pCreateClipper1, pCreateClipper2, pCreateClipper3, pCreateClipper4, pCreateClipper7;
|
|
CreatePalette_Type pCreatePalette1, pCreatePalette2, pCreatePalette3, pCreatePalette4, pCreatePalette7;
|
|
CreateSurface1_Type pCreateSurface1, pCreateSurface2, pCreateSurface3, pCreateSurface4, pCreateSurface7;
|
|
DuplicateSurface_Type pDuplicateSurface1, pDuplicateSurface2, pDuplicateSurface3;
|
|
DuplicateSurface4_Type pDuplicateSurface4;
|
|
DuplicateSurface7_Type pDuplicateSurface7;
|
|
EnumDisplayModes1_Type pEnumDisplayModes1, pEnumDisplayModes2, pEnumDisplayModes3;
|
|
EnumDisplayModes4_Type pEnumDisplayModes4, pEnumDisplayModes7;
|
|
EnumSurfaces1_Type pEnumSurfaces1;
|
|
EnumSurfaces4_Type pEnumSurfaces4;
|
|
FlipToGDISurface_Type pFlipToGDISurface1, pFlipToGDISurface2, pFlipToGDISurface3, pFlipToGDISurface4, pFlipToGDISurface7;
|
|
GetCapsD_Type pGetCaps1D, pGetCaps2D, pGetCaps3D, pGetCaps4D, pGetCaps7D;
|
|
GetDisplayMode_Type pGetDisplayMode1, pGetDisplayMode2, pGetDisplayMode3;
|
|
GetDisplayMode4_Type pGetDisplayMode4, pGetDisplayMode7;
|
|
GetFourCCCodes_Type pGetFourCCCodes;
|
|
GetGDISurface_Type pGetGDISurface1, pGetGDISurface2, pGetGDISurface3, pGetGDISurface4, pGetGDISurface7;
|
|
GetMonitorFrequency_Type pGetMonitorFrequency;
|
|
GetScanLine_Type pGetScanLine;
|
|
GetVerticalBlankStatus_Type pGetVerticalBlankStatus;
|
|
Initialize_Type pInitialize1, pInitialize2, pInitialize3, pInitialize4, pInitialize7;
|
|
RestoreDisplayMode_Type pRestoreDisplayMode;
|
|
SetCooperativeLevel_Type pSetCooperativeLevel1, pSetCooperativeLevel2, pSetCooperativeLevel3, pSetCooperativeLevel4, pSetCooperativeLevel7;
|
|
SetDisplayMode1_Type pSetDisplayMode1;
|
|
SetDisplayMode2_Type pSetDisplayMode2, pSetDisplayMode3, pSetDisplayMode4, pSetDisplayMode7;
|
|
WaitForVerticalBlank_Type pWaitForVerticalBlank1, pWaitForVerticalBlank2, pWaitForVerticalBlank3, pWaitForVerticalBlank4, pWaitForVerticalBlank7;
|
|
GetSurfaceFromDC_Type pGetSurfaceFromDC;
|
|
GetAvailableVidMem_Type pGetAvailableVidMem2, pGetAvailableVidMem3;
|
|
GetAvailableVidMem4_Type pGetAvailableVidMem4, pGetAvailableVidMem7;
|
|
RestoreAllSurfaces_Type pRestoreAllSurfaces;
|
|
TestCooperativeLevel_Type pTestCooperativeLevel4, pTestCooperativeLevel7;
|
|
GetDeviceIdentifier_Type pGetDeviceIdentifier;
|
|
RestoreDisplayMode_Type pRestoreDisplayMode1, pRestoreDisplayMode2, pRestoreDisplayMode3, pRestoreDisplayMode4, pRestoreDisplayMode7;
|
|
GetScanLine_Type pGetScanLine1, pGetScanLine2, pGetScanLine3, pGetScanLine4, pGetScanLine7;
|
|
|
|
/* DirectDrawSurface hook pointers */
|
|
QueryInterface_Type pQueryInterfaceS1, pQueryInterfaceS2, pQueryInterfaceS3, pQueryInterfaceS4, pQueryInterfaceS7;
|
|
ReleaseS_Type pReleaseS1, pReleaseS2, pReleaseS3, pReleaseS4, pReleaseS7;
|
|
AddAttachedSurface_Type pAddAttachedSurface1, pAddAttachedSurface2, pAddAttachedSurface3, pAddAttachedSurface4, pAddAttachedSurface7;
|
|
AddOverlayDirtyRect_Type pAddOverlayDirtyRect;
|
|
Blt_Type pBlt1, pBlt2, pBlt3, pBlt4, pBlt7;
|
|
//BltBatch_Type pBltBatch;
|
|
BltFast_Type pBltFast1, pBltFast2, pBltFast3, pBltFast4, pBltFast7;
|
|
DeleteAttachedSurface_Type pDeleteAttachedSurface1, pDeleteAttachedSurface2, pDeleteAttachedSurface3, pDeleteAttachedSurface4, pDeleteAttachedSurface7;
|
|
EnumAttachedSurfaces_Type pEnumAttachedSurfaces1, pEnumAttachedSurfaces2, pEnumAttachedSurfaces3, pEnumAttachedSurfaces4, pEnumAttachedSurfaces7;
|
|
EnumOverlayZOrders_Type pEnumOverlayZOrders;
|
|
Flip_Type pFlip1, pFlip2, pFlip3, pFlip4, pFlip7;
|
|
GetAttachedSurface_Type pGetAttachedSurface1, pGetAttachedSurface2, pGetAttachedSurface3, pGetAttachedSurface4, pGetAttachedSurface7;
|
|
GetBltStatus_Type pGetBltStatus;
|
|
GetCapsS_Type pGetCaps1S, pGetCaps2S, pGetCaps3S, pGetCaps4S, pGetCaps7S;
|
|
GetClipper_Type pGetClipper;
|
|
GetColorKey_Type pGetColorKey1, pGetColorKey2, pGetColorKey3, pGetColorKey4, pGetColorKey7;
|
|
GetDC_Type pGetDC1, pGetDC2, pGetDC3, pGetDC4, pGetDC7;
|
|
GetFlipStatus_Type pGetFlipStatus;
|
|
GetOverlayPosition_Type pGetOverlayPosition1, pGetOverlayPosition2, pGetOverlayPosition3, pGetOverlayPosition4, pGetOverlayPosition7;
|
|
SetOverlayPosition_Type pSetOverlayPosition1, pSetOverlayPosition2, pSetOverlayPosition3, pSetOverlayPosition4, pSetOverlayPosition7;
|
|
GetPalette_Type pGetPalette1, pGetPalette2, pGetPalette3, pGetPalette4, pGetPalette7;
|
|
GetPixelFormat_Type pGetPixelFormat1, pGetPixelFormat2, pGetPixelFormat3, pGetPixelFormat4, pGetPixelFormat7;
|
|
GetSurfaceDesc_Type pGetSurfaceDesc1, pGetSurfaceDesc2, pGetSurfaceDesc3;
|
|
GetSurfaceDesc2_Type pGetSurfaceDesc4, pGetSurfaceDesc7;
|
|
Lock_Type pLock1, pLock2, pLock3, pLock4, pLock7;
|
|
EnumOverlayZOrders_Type pEnumOverlayZOrders1, pEnumOverlayZOrders2, pEnumOverlayZOrders3, pEnumOverlayZOrders4, pEnumOverlayZOrders7;
|
|
AddOverlayDirtyRect_Type pAddOverlayDirtyRect1, pAddOverlayDirtyRect2, pAddOverlayDirtyRect3, pAddOverlayDirtyRect4, pAddOverlayDirtyRect7;
|
|
|
|
//Initialize
|
|
IsLost_Type pIsLost;
|
|
ReleaseDC_Type pReleaseDC1, pReleaseDC2, pReleaseDC3, pReleaseDC4, pReleaseDC7;
|
|
Restore_Type pRestore;
|
|
SetClipper_Type pSetClipper1, pSetClipper2, pSetClipper3, pSetClipper4, pSetClipper7;
|
|
SetColorKey_Type pSetColorKey1, pSetColorKey2, pSetColorKey3, pSetColorKey4, pSetColorKey7;
|
|
SetOverlayPosition_Type pSetOverlayPosition;
|
|
SetPalette_Type pSetPalette1, pSetPalette2, pSetPalette3, pSetPalette4, pSetPalette7;
|
|
Unlock1_Type pUnlock1, pUnlock2, pUnlock3;
|
|
Unlock4_Type pUnlock4, pUnlock7;
|
|
UpdateOverlay_Type pUpdateOverlay;
|
|
UpdateOverlayDisplay_Type pUpdateOverlayDisplay;
|
|
UpdateOverlayZOrder_Type pUpdateOverlayZOrder;
|
|
SetSurfaceDesc_Type pSetSurfaceDesc3, pSetSurfaceDesc4, pSetSurfaceDesc7;
|
|
|
|
/* DirectDrawClipper hook pointers */
|
|
QueryInterface_Type pQueryInterfaceC;
|
|
AddRefC_Type pAddRefC;
|
|
ReleaseC_Type pReleaseC;
|
|
GetClipList_Type pGetClipList;
|
|
SetClipList_Type pSetClipList;
|
|
GetHWnd_Type pGetHWnd;
|
|
InitializeC_Type pInitializeC;
|
|
IsClipListChanged_Type pIsClipListChanged;
|
|
SetHWnd_Type pSetHWnd;
|
|
|
|
/* DirectDrawPalette hook pointers */
|
|
QueryInterfaceP_Type pQueryInterfaceP;
|
|
AddRefP_Type pAddRefP;
|
|
ReleaseP_Type pReleaseP;
|
|
/*** IDirectDrawPalette methods ***/
|
|
GetCapsP_Type pGetCapsP;
|
|
GetEntries_Type pGetEntries;
|
|
// STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD, LPPALETTEENTRY) PURE;
|
|
SetEntries_Type pSetEntries;
|
|
|
|
// GammaRamp
|
|
GammaRamp_Type pDDGetGammaRamp;
|
|
GammaRamp_Type pDDSetGammaRamp;
|
|
|
|
// ddraw global variables, constants & so on
|
|
|
|
extern PALETTEENTRY DefaultSystemPalette[256];
|
|
LPDIRECTDRAWSURFACE lpDDSEmu_Prim=NULL;
|
|
LPDIRECTDRAWSURFACE lpDDSEmu_Back=NULL;
|
|
LPDIRECTDRAWSURFACE lpDDZBuffer=NULL; // BEWARE! Likely, this global is useless ....
|
|
int ZBufferSize;
|
|
// v2.1.87: lpPrimaryDD is the DIRECTDRAW object to which the primary surface and all
|
|
// the service objects (emulated backbuffer, emulater primary, ....) are attached.
|
|
LPDIRECTDRAW lpPrimaryDD=NULL;
|
|
int iBakBufferVersion;
|
|
int iDirectDrawVersion;
|
|
LPDIRECTDRAWPALETTE lpDDP=NULL;
|
|
LPDIRECTDRAWCLIPPER lpddC=NULL;
|
|
int iDDPExtraRefCounter=0;
|
|
// v2.02.37: globals to store requested main surface capabilities
|
|
DDSURFACEDESC2 DDSD_Prim;
|
|
DWORD PaletteEntries[256];
|
|
DWORD *Palette16BPP = NULL;
|
|
void *EmuScreenBuffer = NULL; // to implement pitch bug fix
|
|
DWORD rPitch = 0;
|
|
LPVOID rSurface = NULL;
|
|
void SetPixFmt(LPDDSURFACEDESC2);
|
|
void GetPixFmt(LPDDSURFACEDESC2);
|
|
|
|
static HookEntryEx_Type ddHooks[]={
|
|
{HOOK_HOT_CANDIDATE, 0x08, "DirectDrawCreate", (FARPROC)NULL, (FARPROC *)&pDirectDrawCreate, (FARPROC)extDirectDrawCreate},
|
|
{HOOK_HOT_CANDIDATE, 0x0A, "DirectDrawCreateEx", (FARPROC)NULL, (FARPROC *)&pDirectDrawCreateEx, (FARPROC)extDirectDrawCreateEx},
|
|
{HOOK_HOT_CANDIDATE, 0x0B, "DirectDrawEnumerateA", (FARPROC)NULL, (FARPROC *)&pDirectDrawEnumerateA, (FARPROC)extDirectDrawEnumerateA},
|
|
{HOOK_HOT_CANDIDATE, 0x0C, "DirectDrawEnumerateExA", (FARPROC)NULL, (FARPROC *)&pDirectDrawEnumerateExA, (FARPROC)extDirectDrawEnumerateExA},
|
|
{HOOK_HOT_CANDIDATE, 0x09, "DirectDrawCreateClipper", (FARPROC)NULL, (FARPROC *)&pDirectDrawCreateClipper, (FARPROC)extDirectDrawCreateClipper},
|
|
{HOOK_HOT_CANDIDATE, 0x01, "AcquireDDThreadLock", (FARPROC)NULL, (FARPROC *)&pAcquireDDThreadLock, (FARPROC)NULL},
|
|
{HOOK_HOT_CANDIDATE, 0x15, "ReleaseDDThreadLock", (FARPROC)NULL, (FARPROC *)&pReleaseDDThreadLock, (FARPROC)NULL},
|
|
{HOOK_IAT_CANDIDATE, 0x0E, "DirectDrawEnumerateW", (FARPROC)NULL, (FARPROC *)&pDirectDrawEnumerateW, (FARPROC)extDirectDrawCreate},
|
|
{HOOK_IAT_CANDIDATE, 0x0D, "DirectDrawEnumerateExW", (FARPROC)NULL, (FARPROC *)&pDirectDrawEnumerateExW, (FARPROC)extDirectDrawCreate},
|
|
{HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
FARPROC Remap_ddraw_ProcAddress(LPCSTR proc, HMODULE hModule)
|
|
{
|
|
FARPROC addr;
|
|
if (dxw.dwTargetDDVersion == HOOKDDRAWNONE) return NULL;
|
|
if (addr=RemapLibraryEx(proc, hModule, ddHooks)) return addr;
|
|
return NULL;
|
|
}
|
|
|
|
extern HRESULT WINAPI sBlt(int, Blt_Type pBlt, char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL);
|
|
|
|
/* ------------------------------------------------------------------------------ */
|
|
// auxiliary (static) functions
|
|
/* ------------------------------------------------------------------------------ */
|
|
|
|
DWORD gdwRefreshRate;
|
|
#define MAXREFRESHDELAYCOUNT 20
|
|
int iRefreshDelays[MAXREFRESHDELAYCOUNT]={16, 17};
|
|
int iRefreshDelayCount=2;
|
|
|
|
static HRESULT myGetDisplayMode(int dxversion, LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpdds)
|
|
{
|
|
HRESULT res;
|
|
switch(dxversion){
|
|
default:
|
|
case 1: res=(*pGetDisplayMode1)(lpdd, lpdds); break;
|
|
case 2: res=(*pGetDisplayMode2)(lpdd, lpdds); break;
|
|
case 3: res=(*pGetDisplayMode3)(lpdd, lpdds); break;
|
|
case 4: res=(*pGetDisplayMode4)(lpdd, (LPDDSURFACEDESC2)lpdds); break;
|
|
case 7: res=(*pGetDisplayMode7)(lpdd, (LPDDSURFACEDESC2)lpdds); break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
void SetVSyncDelays(int dxversion, LPDIRECTDRAW lpdd)
|
|
{
|
|
DDSURFACEDESC2 ddsdRefreshRate;
|
|
HRESULT res;
|
|
|
|
memset(&ddsdRefreshRate, 0, sizeof(ddsdRefreshRate));
|
|
ddsdRefreshRate.dwSize = sizeof(DDSURFACEDESC);
|
|
res=myGetDisplayMode(dxversion, lpdd, (LPDDSURFACEDESC)&ddsdRefreshRate);
|
|
if(res) return;
|
|
dxw.SetVSyncDelays(ddsdRefreshRate.dwRefreshRate);
|
|
}
|
|
|
|
static DWORD GetBltWaitFlags(DWORD dwBltFlags)
|
|
{
|
|
if(dxw.dwFlags8 & FORCEWAIT) {
|
|
dwBltFlags |= DDBLT_WAIT;
|
|
dwBltFlags &= ~DDBLT_DONOTWAIT;
|
|
}
|
|
if(dxw.dwFlags8 & FORCENOWAIT){
|
|
dwBltFlags |= DDBLT_DONOTWAIT;
|
|
dwBltFlags &= ~DDBLT_WAIT;
|
|
}
|
|
return dwBltFlags;
|
|
}
|
|
|
|
static DWORD GetFlipWaitFlags(DWORD dwFlipFlags)
|
|
{
|
|
if(dxw.dwFlags8 & FORCEWAIT) {
|
|
dwFlipFlags |= DDFLIP_WAIT;
|
|
dwFlipFlags &= ~DDFLIP_DONOTWAIT;
|
|
}
|
|
if(dxw.dwFlags8 & FORCENOWAIT){
|
|
dwFlipFlags |= DDFLIP_DONOTWAIT;
|
|
dwFlipFlags &= ~DDFLIP_WAIT;
|
|
}
|
|
return dwFlipFlags;
|
|
}
|
|
|
|
static DWORD SetPrimaryCaps(DWORD dwCaps)
|
|
{
|
|
dwCaps |= (DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_VISIBLE); // primary surfaces must be this way
|
|
dwCaps &= ~(DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN); // primary surfaces can't be this way
|
|
return dwCaps;
|
|
}
|
|
|
|
static DWORD SetBackBufferCaps(DWORD dwCaps)
|
|
{
|
|
// v2.03.11: added DDSCAPS_FLIP capability to backbuffer surface: "Ignition" checks for it before Flip-ping to primary
|
|
dwCaps |= (DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP|DDSCAPS_LOCALVIDMEM); // you never know....
|
|
dwCaps &= ~(DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN); // backbuffer surfaces can't be this way
|
|
return dwCaps;
|
|
}
|
|
|
|
static DWORD SetZBufferCaps(DWORD dwCaps)
|
|
{
|
|
// beware! the ZBUFFER surface could have never been registered!
|
|
// in this case better adapt to the primary/backbuffer ones, since a ZBUFFER with no good caps won't work.
|
|
|
|
// input caps not null or simply DDSCAPS_ZBUFFER, supposedly good, don't touch ....
|
|
if(dwCaps & ~DDSCAPS_ZBUFFER) return dwCaps;
|
|
|
|
// ... else try to cope with primary surface caps
|
|
dwCaps = dxwss.GetCaps(dxwss.GetPrimarySurface());
|
|
dwCaps &= ~(DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_3DDEVICE|DDSCAPS_COMPLEX);
|
|
dwCaps |= DDSCAPS_ZBUFFER;
|
|
return dwCaps;
|
|
}
|
|
|
|
static void Stopper(char *s, int line)
|
|
{
|
|
char sMsg[81];
|
|
sprintf(sMsg,"break: \"%s\"", s);
|
|
MessageBox(0, sMsg, "break", MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
|
|
//#define STOPPER_TEST // comment out to eliminate
|
|
#ifdef STOPPER_TEST
|
|
#define STOPPER(s) Stopper(s, __LINE__)
|
|
#else
|
|
#define STOPPER(s)
|
|
#endif
|
|
|
|
char *DumpPixelFormat(LPDDSURFACEDESC2 lpddsd)
|
|
{
|
|
return ExplainPixelFormat(&(lpddsd->ddpfPixelFormat));
|
|
}
|
|
|
|
CHAR *LogSurfaceAttributes(LPDDSURFACEDESC2 lpddsd, char *label, int line)
|
|
{
|
|
static char sInfo[1024];
|
|
sprintf(sInfo, "SurfaceDesc: %s Flags=%x(%s)",
|
|
label,
|
|
lpddsd->dwFlags, ExplainFlags(lpddsd->dwFlags));
|
|
if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) sprintf(sInfo, "%s BackBufferCount=%d", sInfo, lpddsd->dwBackBufferCount);
|
|
if (lpddsd->dwFlags & DDSD_WIDTH) sprintf(sInfo, "%s Width=%d", sInfo, lpddsd->dwWidth);
|
|
if (lpddsd->dwFlags & DDSD_HEIGHT) sprintf(sInfo, "%s Height=%d", sInfo, lpddsd->dwHeight);
|
|
if (lpddsd->dwFlags & DDSD_PITCH) sprintf(sInfo, "%s Pitch=%d", sInfo, lpddsd->lPitch);
|
|
if (lpddsd->dwFlags & DDSD_MIPMAPCOUNT) sprintf(sInfo, "%s MipMapCount=%d", sInfo, lpddsd->dwMipMapCount);
|
|
if (lpddsd->dwFlags & DDSD_CAPS) {
|
|
sprintf(sInfo, "%s Caps=%x(%s)", sInfo, lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps));
|
|
if(lpddsd->dwSize==sizeof(DDSURFACEDESC2)){
|
|
LPDDSURFACEDESC2 lpddsd2=lpddsd;
|
|
sprintf(sInfo, "%s Caps2=%x(%s)", sInfo, lpddsd2->ddsCaps.dwCaps2, ExplainDDSCaps2(lpddsd2->ddsCaps.dwCaps2));
|
|
sprintf(sInfo, "%s Caps3=%x(%s)", sInfo, lpddsd2->ddsCaps.dwCaps3, ExplainDDSCaps3(lpddsd2->ddsCaps.dwCaps3));
|
|
sprintf(sInfo, "%s Caps4=%x(%s)", sInfo, lpddsd2->ddsCaps.dwCaps4, ExplainDDSCaps4(lpddsd2->ddsCaps.dwCaps4));
|
|
}
|
|
}
|
|
if (lpddsd->dwFlags & DDSD_CKDESTBLT ) sprintf(sInfo, "%s CKDestBlt=(%x,%x)", sInfo, lpddsd->ddckCKDestBlt.dwColorSpaceLowValue, lpddsd->ddckCKDestBlt.dwColorSpaceHighValue);
|
|
if (lpddsd->dwFlags & DDSD_CKDESTOVERLAY ) sprintf(sInfo, "%s CKDestOverlay=(%x,%x)", sInfo, lpddsd->ddckCKDestOverlay.dwColorSpaceLowValue, lpddsd->ddckCKDestOverlay.dwColorSpaceHighValue);
|
|
if (lpddsd->dwFlags & DDSD_CKSRCBLT ) sprintf(sInfo, "%s CKSrcBlt=(%x,%x)", sInfo, lpddsd->ddckCKSrcBlt.dwColorSpaceLowValue, lpddsd->ddckCKSrcBlt.dwColorSpaceHighValue);
|
|
if (lpddsd->dwFlags & DDSD_CKSRCOVERLAY ) sprintf(sInfo, "%s CKSrcOverlay=(%x,%x)", sInfo, lpddsd->ddckCKSrcOverlay.dwColorSpaceLowValue, lpddsd->ddckCKSrcOverlay.dwColorSpaceHighValue);
|
|
if (lpddsd->dwFlags & DDSD_PIXELFORMAT ) sprintf(sInfo, "%s %s", sInfo, DumpPixelFormat((LPDDSURFACEDESC2)lpddsd));
|
|
if (lpddsd->dwFlags & DDSD_LPSURFACE) sprintf(sInfo, "%s Surface=%x", sInfo, lpddsd->lpSurface);
|
|
if ((lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) && (lpddsd->dwSize==sizeof(DDSURFACEDESC))) sprintf(sInfo, "%s ZBufferBitDepth=%d", sInfo, ((LPDDSURFACEDESC)lpddsd)->dwZBufferBitDepth);
|
|
if (lpddsd->dwFlags & DDSD_ALPHABITDEPTH) sprintf(sInfo, "%s AlphaBitDepth=%d", sInfo, lpddsd->dwAlphaBitDepth);
|
|
if (lpddsd->dwReserved) sprintf(sInfo, "%s Reserved=%d", sInfo, lpddsd->dwReserved);
|
|
if (lpddsd->dwFlags & DDSD_REFRESHRATE) sprintf(sInfo, "%s RefreshRate=%d", sInfo, lpddsd->dwRefreshRate);
|
|
if (lpddsd->dwFlags & DDSD_LINEARSIZE) sprintf(sInfo, "%s LinearSize=%d", sInfo, lpddsd->dwLinearSize);
|
|
if (lpddsd->dwSize == sizeof(DDSURFACEDESC2)){
|
|
if (lpddsd->dwFlags & DDSD_TEXTURESTAGE) sprintf(sInfo, "%s TextureStage=%x", sInfo, ((LPDDSURFACEDESC2)lpddsd)->dwTextureStage);
|
|
if (lpddsd->dwFlags & DDSD_FVF) sprintf(sInfo, "%s FVF=%x", sInfo, ((LPDDSURFACEDESC2)lpddsd)->dwFVF);
|
|
}
|
|
|
|
return sInfo;
|
|
}
|
|
|
|
void DumpPixFmt(LPDDSURFACEDESC2 lpdds)
|
|
{
|
|
OutTrace("PixelFormat: lpdds=%x %s\n", DumpPixelFormat(lpdds));
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------------ */
|
|
// auxiliary (static) functions for palette handling
|
|
/* ------------------------------------------------------------------------------ */
|
|
|
|
BOOL isPaletteUpdated;
|
|
|
|
void mySetPalette(int dwstart, int dwcount, LPPALETTEENTRY lpentries)
|
|
{
|
|
int i;
|
|
extern DXWNDSTATUS *pStatus;
|
|
|
|
// if has reserved palette entries, recover them
|
|
if(dxw.dwFlags5 & LOCKRESERVEDPALETTE){
|
|
int nStatCols, nPalEntries;
|
|
PALETTEENTRY SysPalEntry[256];
|
|
LPPALETTEENTRY lpEntry;
|
|
extern GetSystemPaletteEntries_Type pGDIGetSystemPaletteEntries;
|
|
extern GetDeviceCaps_Type pGDIGetDeviceCaps;
|
|
|
|
// The number of static colours should be 20, but inquire it anyway
|
|
nStatCols = (*pGDIGetDeviceCaps)(GetDC(0), NUMRESERVED);
|
|
|
|
// fix the first nStatCols/2 and the last nStatCols/2 entries
|
|
nPalEntries=(*pGDIGetSystemPaletteEntries)(GetDC(0), 0, 256, SysPalEntry);
|
|
|
|
for (i = 0; i < 256; i++){
|
|
// skip intermediate un-reserved palette entries
|
|
if(i==(nStatCols / 2)) i=256 - (nStatCols / 2);
|
|
lpEntry = &lpentries[i];
|
|
if(lpEntry->peFlags==0){
|
|
lpEntry->peRed = SysPalEntry[i].peRed;
|
|
lpEntry->peGreen = SysPalEntry[i].peGreen;
|
|
lpEntry->peBlue = SysPalEntry[i].peBlue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// copy the palette entries on the current system palette
|
|
for(int idx=0; idx<dwcount; idx++)
|
|
pStatus->Palette[dwstart+idx]= lpentries[idx];
|
|
|
|
for(i = 0; i < dwcount; i ++){
|
|
PALETTEENTRY PalColor;
|
|
PalColor = lpentries[i];
|
|
if (dxw.dwFlags3 & BLACKWHITE){
|
|
// (http://www.codeproject.com/Articles/66253/Converting-Colors-to-Gray-Shades):
|
|
// gray = (red * 0.30) + (green * 0.59) + (blue * 0.11)
|
|
DWORD grayscale;
|
|
//grayscale = ((DWORD)lpentries[i].peRed + (DWORD)lpentries[i].peGreen + (DWORD)lpentries[i].peBlue) / 3;
|
|
grayscale = (((DWORD)PalColor.peRed * 30) + ((DWORD)PalColor.peGreen * 59) + ((DWORD)PalColor.peBlue) * 11) / 100;
|
|
PalColor.peRed = PalColor.peGreen = PalColor.peBlue = (BYTE)grayscale;
|
|
}
|
|
switch (dxw.ActualPixelFormat.dwRGBBitCount){
|
|
case 32:
|
|
PaletteEntries[i + dwstart] =
|
|
(((DWORD)PalColor.peRed) << 16) + (((DWORD)PalColor.peGreen) << 8) + ((DWORD)PalColor.peBlue);
|
|
break;
|
|
case 16:
|
|
PaletteEntries[i + dwstart] = (dxw.ActualPixelFormat.dwGBitMask == 0x03E0) ?
|
|
(((DWORD)PalColor.peRed & 0xF8) << 8) + (((DWORD)PalColor.peGreen & 0xFC) << 3) + (((DWORD)PalColor.peBlue &0xF8) >> 3)
|
|
:
|
|
(((DWORD)PalColor.peRed & 0xF8) << 8) + (((DWORD)PalColor.peGreen & 0xF8) << 3) + (((DWORD)PalColor.peBlue &0xF8) >> 3);
|
|
break;
|
|
case 8: // it may happen in unemulated modes
|
|
PaletteEntries[i + dwstart] =
|
|
(((DWORD)PalColor.peRed) << 16) + (((DWORD)PalColor.peGreen) << 8) + ((DWORD)PalColor.peBlue);
|
|
break;
|
|
default:
|
|
OutTraceDW("ASSERT: unsupported Color BPP=%d\n", dxw.ActualPixelFormat.dwRGBBitCount);
|
|
break;
|
|
}
|
|
}
|
|
|
|
isPaletteUpdated = TRUE;
|
|
}
|
|
|
|
void InitDDScreenParameters(int dxversion, LPDIRECTDRAW lpdd)
|
|
{
|
|
HRESULT res;
|
|
DDSURFACEDESC2 ddsd;
|
|
ddsd.dwSize=sizeof(DDSURFACEDESC);
|
|
res=myGetDisplayMode(dxversion, lpdd, (LPDDSURFACEDESC)&ddsd);
|
|
if(res){
|
|
OutTraceE("GetDisplayMode: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return;
|
|
}
|
|
|
|
OutTraceDW("InitDDScreenParameters: Actual %s\n", DumpPixelFormat((LPDDSURFACEDESC2)&ddsd));
|
|
dxw.ActualPixelFormat=ddsd.ddpfPixelFormat;
|
|
if(dxw.VirtualPixelFormat.dwRGBBitCount==0) dxw.VirtualPixelFormat=ddsd.ddpfPixelFormat;
|
|
SetBltTransformations(dxversion);
|
|
return;
|
|
}
|
|
|
|
void InitScreenParameters(int dxversion)
|
|
{
|
|
extern void FixPixelFormat(int , DDPIXELFORMAT *);
|
|
DEVMODE CurrDevMode;
|
|
static int DoOnce = FALSE;
|
|
DWORD dwVJoyStatus;
|
|
|
|
if(DoOnce) return;
|
|
DoOnce = TRUE;
|
|
|
|
// set default VGA mode 800x600
|
|
// should I make it configurable ? (640x480, 800x600, 1024x768)
|
|
dxw.SetScreenSize(); // 800 x 600 by default
|
|
GetHookInfo()->Height=(short)dxw.GetScreenHeight();
|
|
GetHookInfo()->Width=(short)dxw.GetScreenWidth();
|
|
GetHookInfo()->ColorDepth=0; // unknown
|
|
GetHookInfo()->DXVersion=0; // unknown
|
|
GetHookInfo()->isLogging=(dxw.dwTFlags & OUTTRACE);
|
|
|
|
dwVJoyStatus = GetHookInfo()->VJoyStatus;
|
|
dwVJoyStatus &= ~VJOYPRESENT;
|
|
if(dxw.dwFlags6 & VIRTUALJOYSTICK) dwVJoyStatus |= VJOYPRESENT;
|
|
GetHookInfo()->VJoyStatus = dwVJoyStatus;
|
|
|
|
if(!(*pEnumDisplaySettings)(NULL, ENUM_CURRENT_SETTINGS, &CurrDevMode)){
|
|
OutTraceE("EnumDisplaySettings: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
return;
|
|
}
|
|
memset(&dxw.ActualPixelFormat, 0, sizeof(DDPIXELFORMAT));
|
|
// initialize to default null values, but dwRGBBitCount
|
|
dxw.ActualPixelFormat.dwRGBBitCount=CurrDevMode.dmBitsPerPel;
|
|
dxw.VirtualPixelFormat.dwRGBBitCount=CurrDevMode.dmBitsPerPel; // until set differently
|
|
if(dxw.dwFlags2 & INIT8BPP) FixPixelFormat(8, &dxw.VirtualPixelFormat);
|
|
if(dxw.dwFlags2 & INIT16BPP) FixPixelFormat(16, &dxw.VirtualPixelFormat);
|
|
if(dxw.dwFlags7 & INIT24BPP) FixPixelFormat(24, &dxw.VirtualPixelFormat);
|
|
if(dxw.dwFlags7 & INIT32BPP) FixPixelFormat(32, &dxw.VirtualPixelFormat);
|
|
OutTraceDW("InitScreenParameters: dxversion=%d RGBBitCount=%d\n", dxversion, CurrDevMode.dmBitsPerPel);
|
|
SetBltTransformations(dxversion);
|
|
|
|
return;
|
|
}
|
|
|
|
void FixPixelFormat(int ColorDepth, DDPIXELFORMAT *pf)
|
|
{
|
|
pf->dwFlags = DDPF_RGB;
|
|
switch(ColorDepth){
|
|
case 8:
|
|
pf->dwFlags |= DDPF_PALETTEINDEXED8;
|
|
pf->dwRGBBitCount = 8;
|
|
pf->dwRBitMask = 0;
|
|
pf->dwGBitMask = 0;
|
|
pf->dwBBitMask = 0;
|
|
pf->dwRGBAlphaBitMask = 0x0000;
|
|
break;
|
|
case 15: // v2.02.53: Hesperian Wars - so far the only game setting color depth to 15 BPP!
|
|
case 16:
|
|
pf->dwRGBBitCount = 16;
|
|
if (dxw.dwFlags1 & USERGB565){
|
|
pf->dwRBitMask = 0xf800;
|
|
pf->dwGBitMask = 0x07e0;
|
|
pf->dwBBitMask = 0x001f;
|
|
pf->dwRGBAlphaBitMask = 0x0000;
|
|
}
|
|
else {
|
|
if(!(dxw.dwFlags4 & NOALPHACHANNEL) && (ColorDepth == 16)) pf->dwFlags |= DDPF_ALPHAPIXELS; // v2.02.33,40,53
|
|
pf->dwRBitMask = 0x7c00;
|
|
pf->dwGBitMask = 0x03e0;
|
|
pf->dwBBitMask = 0x001f;
|
|
pf->dwRGBAlphaBitMask = 0x8000;
|
|
}
|
|
break;
|
|
case 24:
|
|
pf->dwRGBBitCount = 24;
|
|
pf->dwRBitMask = 0x00FF0000;
|
|
pf->dwGBitMask = 0x0000FF00;
|
|
pf->dwBBitMask = 0x000000FF;
|
|
pf->dwRGBAlphaBitMask = 0x00000000;
|
|
break;
|
|
case 32:
|
|
if(!(dxw.dwFlags4 & NOALPHACHANNEL)) pf->dwFlags |= DDPF_ALPHAPIXELS; // v2.02.33
|
|
pf->dwRGBBitCount = 32;
|
|
pf->dwRBitMask = 0x00FF0000;
|
|
pf->dwGBitMask = 0x0000FF00;
|
|
pf->dwBBitMask = 0x000000FF;
|
|
pf->dwRGBAlphaBitMask = 0xFF000000;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void ddSetCompatibility()
|
|
{
|
|
typedef HRESULT (WINAPI *SetAppCompatData_Type)(DWORD, DWORD);
|
|
SetAppCompatData_Type pSetAppCompatData;
|
|
HRESULT res;
|
|
HINSTANCE hinst;
|
|
|
|
hinst=(*pLoadLibraryA)("ddraw.dll");
|
|
if(!hinst){
|
|
OutTraceDW("LoadLibrary ddraw.dll ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
}
|
|
pSetAppCompatData=(SetAppCompatData_Type)(*pGetProcAddress)(hinst, "SetAppCompatData");
|
|
if(pSetAppCompatData) {
|
|
if (dxw.dwFlags2 & SETCOMPATIBILITY){
|
|
// v2.03.27: set DWM Off for both primary Lock and Blt. Good for Age of Empires intro movie!
|
|
res=(*pSetAppCompatData)(1, 0);
|
|
res=(*pSetAppCompatData)(2, 0);
|
|
OutTraceDW("HookDirectDraw: SetAppCompatData(2,0) ret=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
if (dxw.dwFlags6 & DISABLEMAXWINMODE){
|
|
res=(*pSetAppCompatData)(12, 0);
|
|
OutTraceDW("HookDirectDraw: SetAppCompatData(12,0) ret=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
}
|
|
else{
|
|
OutTraceDW("HookDirectDraw: missing SetAppCompatData call\n");
|
|
}
|
|
(*pFreeLibrary)(hinst);
|
|
}
|
|
|
|
static void BypassGOGDDrawRedirector()
|
|
{
|
|
// this procedure bypasses the GOG proxy ddraw.dll that sometimes is found in the GOG game folders.
|
|
// This way, there will be no more the need to rename or delete this file.
|
|
char sSysLibraryPath[MAX_PATH+10];
|
|
HMODULE hinst;
|
|
|
|
GetSystemDirectory(sSysLibraryPath, MAX_PATH);
|
|
strcat(sSysLibraryPath, "\\ddraw.dll");
|
|
hinst = (*pLoadLibraryA)(sSysLibraryPath);
|
|
pDirectDrawEnumerateA = (DirectDrawEnumerateA_Type)GetProcAddress(hinst, "DirectDrawEnumerateA");
|
|
pDirectDrawEnumerateExA = (DirectDrawEnumerateExA_Type)GetProcAddress(hinst, "DirectDrawEnumerateExA");
|
|
pDirectDrawEnumerateW = (DirectDrawEnumerateW_Type)GetProcAddress(hinst, "DirectDrawEnumerateW");
|
|
pDirectDrawEnumerateExW = (DirectDrawEnumerateExW_Type)GetProcAddress(hinst, "DirectDrawEnumerateExW");
|
|
pDirectDrawCreate = (DirectDrawCreate_Type)GetProcAddress(hinst, "DirectDrawCreate");
|
|
pDirectDrawCreateEx = (DirectDrawCreateEx_Type)GetProcAddress(hinst, "DirectDrawCreateEx");
|
|
}
|
|
|
|
int HookDirectDraw(HMODULE module, int version)
|
|
{
|
|
if(dxw.dwTargetDDVersion == HOOKDDRAWNONE) return 0;
|
|
|
|
if ((dxw.dwFlags2 & SETCOMPATIBILITY) ||
|
|
(dxw.dwFlags6 & DISABLEMAXWINMODE)){
|
|
static BOOL AlreadyDone = FALSE;
|
|
if(!AlreadyDone){
|
|
ddSetCompatibility();
|
|
AlreadyDone = TRUE;
|
|
}
|
|
}
|
|
|
|
if(dxw.dwFlags6 & BYPASSGOGLIBS) {
|
|
BypassGOGDDrawRedirector();
|
|
return TRUE;
|
|
}
|
|
|
|
if(dxw.dwFlags4 & HOTPATCH) {
|
|
// hot-patch all APIs and that's all folks!
|
|
HookLibraryEx(module, ddHooks, "ddraw.dll");
|
|
return TRUE;
|
|
}
|
|
|
|
//const GUID dd7 = {0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b};
|
|
HMODULE hinst;
|
|
|
|
OutTraceB("HookDirectDraw version=%d\n", version); //GHO
|
|
switch(version){
|
|
case 0: // automatic
|
|
HookLibraryEx(module, ddHooks, "ddraw.dll");
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
HookLibraryEx(module, ddHooks, "ddraw.dll");
|
|
if(!pDirectDrawCreate){ // required for IAT patching
|
|
hinst = (*pLoadLibraryA)("ddraw.dll");
|
|
if(!hinst) OutTraceE("LoadLibrary ddraw.dll ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
pDirectDrawCreate = (DirectDrawCreate_Type)GetProcAddress(hinst, "DirectDrawCreate");
|
|
pDirectDrawEnumerateA = (DirectDrawEnumerateA_Type)GetProcAddress(hinst, "DirectDrawEnumerateA");
|
|
}
|
|
if(pDirectDrawCreate){
|
|
LPDIRECTDRAW lpdd;
|
|
BOOL res;
|
|
HookLibraryEx(module, ddHooks, "ddraw.dll");
|
|
res=extDirectDrawCreate(0, &lpdd, 0);
|
|
if (res){
|
|
OutTraceE("DirectDrawCreate: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
lpdd->Release();
|
|
}
|
|
break;
|
|
case 7:
|
|
HookLibraryEx(module, ddHooks, "ddraw.dll");
|
|
if(!pDirectDrawCreate){ // required for IAT patching in "Crimson skies"
|
|
hinst = (*pLoadLibraryA)("ddraw.dll");
|
|
if(!hinst) OutTraceE("LoadLibrary ddraw.dll ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
pDirectDrawEnumerateA = (DirectDrawEnumerateA_Type)GetProcAddress(hinst, "DirectDrawEnumerateA");
|
|
pDirectDrawEnumerateExA = (DirectDrawEnumerateExA_Type)GetProcAddress(hinst, "DirectDrawEnumerateExA");
|
|
pDirectDrawCreate = (DirectDrawCreate_Type)GetProcAddress(hinst, "DirectDrawCreate");
|
|
pDirectDrawCreateEx = (DirectDrawCreateEx_Type)GetProcAddress(hinst, "DirectDrawCreateEx");
|
|
}
|
|
if(pDirectDrawCreate){
|
|
LPDIRECTDRAW lpdd;
|
|
BOOL res;
|
|
res=extDirectDrawCreate(0, &lpdd, 0);
|
|
if (res) OutTraceE("DirectDrawCreate: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
lpdd->Release();
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(pDirectDrawCreate || pDirectDrawCreateEx) return 1;
|
|
return 0;
|
|
}
|
|
|
|
CreatePalette_Type pCreatePaletteMethod(int dxversion)
|
|
{
|
|
CreatePalette_Type pCreatePalette;
|
|
switch(dxversion){
|
|
case 1: pCreatePalette = pCreatePalette1; break;
|
|
case 2: pCreatePalette = pCreatePalette2; break;
|
|
case 3: pCreatePalette = pCreatePalette3; break;
|
|
case 4: pCreatePalette = pCreatePalette4; break;
|
|
case 7: pCreatePalette = pCreatePalette7; break;
|
|
}
|
|
CHECKPTR(pCreatePalette, "CreatePalette");
|
|
return pCreatePalette;
|
|
}
|
|
|
|
SetPalette_Type pSetPaletteMethod(int dxversion)
|
|
{
|
|
SetPalette_Type pSetPalette;
|
|
switch(dxversion){
|
|
case 1: pSetPalette=pSetPalette1; break;
|
|
case 2: pSetPalette=pSetPalette2; break;
|
|
case 3: pSetPalette=pSetPalette3; break;
|
|
case 4: pSetPalette=pSetPalette4; break;
|
|
case 7: pSetPalette=pSetPalette7; break;
|
|
}
|
|
CHECKPTR(pSetPalette, "SetPalette");
|
|
return pSetPalette;
|
|
}
|
|
|
|
ReleaseS_Type pReleaseSMethod(int dxversion)
|
|
{
|
|
ReleaseS_Type pReleaseS;
|
|
switch(dxversion){
|
|
case 1: pReleaseS=pReleaseS1; break;
|
|
case 2: pReleaseS=pReleaseS2; break;
|
|
case 3: pReleaseS=pReleaseS3; break;
|
|
case 4: pReleaseS=pReleaseS4; break;
|
|
case 7: pReleaseS=pReleaseS7; break;
|
|
}
|
|
CHECKPTR(pReleaseS, "Surface::Release");
|
|
return pReleaseS;
|
|
}
|
|
|
|
ReleaseDC_Type pReleaseDCMethod()
|
|
{
|
|
ReleaseDC_Type pReleaseDC;
|
|
switch(iBakBufferVersion){
|
|
case 1: pReleaseDC=pReleaseDC1; break;
|
|
case 2: pReleaseDC=pReleaseDC2; break;
|
|
case 3: pReleaseDC=pReleaseDC3; break;
|
|
case 4: pReleaseDC=pReleaseDC4; break;
|
|
case 7: pReleaseDC=pReleaseDC7; break;
|
|
}
|
|
CHECKPTR(pReleaseDC, "ReleaseDC");
|
|
return pReleaseDC;
|
|
}
|
|
|
|
SetClipper_Type pSetClipperMethod(int dxversion)
|
|
{
|
|
SetClipper_Type pSetClipper;
|
|
switch(dxversion){
|
|
case 1: pSetClipper=pSetClipper1; break;
|
|
case 2: pSetClipper=pSetClipper2; break;
|
|
case 3: pSetClipper=pSetClipper3; break;
|
|
case 4: pSetClipper=pSetClipper4; break;
|
|
case 7: pSetClipper=pSetClipper7; break;
|
|
}
|
|
CHECKPTR(pSetClipper, "SetClipper");
|
|
return pSetClipper;
|
|
}
|
|
|
|
Blt_Type pGetBltMethod(int dxversion)
|
|
{
|
|
Blt_Type pBlt;
|
|
switch(dxversion){
|
|
case 1: pBlt=pBlt1; break;
|
|
case 2: pBlt=pBlt2; break;
|
|
case 3: pBlt=pBlt3; break;
|
|
case 4: pBlt=pBlt4; break;
|
|
case 7: pBlt=pBlt7; break;
|
|
}
|
|
CHECKPTR(pBlt, "Blt");
|
|
return pBlt;
|
|
}
|
|
|
|
Blt_Type pBltMethod()
|
|
{
|
|
Blt_Type pBlt;
|
|
switch(iBakBufferVersion){
|
|
case 1: pBlt=pBlt1; break;
|
|
case 2: pBlt=pBlt2; break;
|
|
case 3: pBlt=pBlt3; break;
|
|
case 4: pBlt=pBlt4; break;
|
|
case 7: pBlt=pBlt7; break;
|
|
}
|
|
CHECKPTR(pBlt, "Blt");
|
|
return pBlt;
|
|
}
|
|
|
|
GetDC_Type pGetDCMethod()
|
|
{
|
|
GetDC_Type pGetDC;
|
|
switch(iBakBufferVersion){
|
|
case 1: pGetDC=pGetDC1; break;
|
|
case 2: pGetDC=pGetDC2; break;
|
|
case 3: pGetDC=pGetDC3; break;
|
|
case 4: pGetDC=pGetDC4; break;
|
|
case 7: pGetDC=pGetDC7; break;
|
|
}
|
|
CHECKPTR(pGetDC, "GetDC");
|
|
return pGetDC;
|
|
}
|
|
|
|
Unlock4_Type pUnlockMethod(int dxversion)
|
|
{
|
|
Unlock4_Type pUnlock;
|
|
switch(dxversion){
|
|
case 1: pUnlock=(Unlock4_Type)pUnlock1; break;
|
|
case 2: pUnlock=(Unlock4_Type)pUnlock2; break;
|
|
case 3: pUnlock=(Unlock4_Type)pUnlock3; break;
|
|
case 4: pUnlock=(Unlock4_Type)pUnlock4; break;
|
|
case 7: pUnlock=(Unlock4_Type)pUnlock7; break;
|
|
}
|
|
CHECKPTR(pUnlock, "Unlock");
|
|
return pUnlock;
|
|
}
|
|
|
|
Lock_Type pLockMethod(int dxversion)
|
|
{
|
|
Lock_Type pLock;
|
|
switch(dxversion){
|
|
case 1: pLock=pLock1; break;
|
|
case 2: pLock=pLock2; break;
|
|
case 3: pLock=pLock3; break;
|
|
case 4: pLock=pLock4; break;
|
|
case 7: pLock=pLock7; break;
|
|
}
|
|
CHECKPTR(pLock, "Lock");
|
|
return pLock;
|
|
}
|
|
|
|
CreateSurface2_Type pCreateSurfaceMethod(int dxversion)
|
|
{
|
|
CreateSurface2_Type pCreateSurface;
|
|
switch(dxversion){
|
|
case 1: pCreateSurface=(CreateSurface2_Type)pCreateSurface1; break;
|
|
case 2: pCreateSurface=(CreateSurface2_Type)pCreateSurface2; break;
|
|
case 3: pCreateSurface=(CreateSurface2_Type)pCreateSurface3; break;
|
|
case 4: pCreateSurface=(CreateSurface2_Type)pCreateSurface4; break;
|
|
case 7: pCreateSurface=(CreateSurface2_Type)pCreateSurface7; break;
|
|
}
|
|
CHECKPTR(pCreateSurface, "CreateSurface");
|
|
return pCreateSurface;
|
|
}
|
|
|
|
GetSurfaceDesc2_Type pGetSurfaceDescMethod()
|
|
{
|
|
GetSurfaceDesc2_Type pGetSurfaceDesc;
|
|
pGetSurfaceDesc = NULL;
|
|
switch(iBakBufferVersion){
|
|
case 1: pGetSurfaceDesc=(GetSurfaceDesc2_Type)pGetSurfaceDesc1; break;
|
|
case 2: pGetSurfaceDesc=(GetSurfaceDesc2_Type)pGetSurfaceDesc2; break;
|
|
case 3: pGetSurfaceDesc=(GetSurfaceDesc2_Type)pGetSurfaceDesc3; break;
|
|
case 4: pGetSurfaceDesc=(GetSurfaceDesc2_Type)pGetSurfaceDesc4; break;
|
|
case 7: pGetSurfaceDesc=(GetSurfaceDesc2_Type)pGetSurfaceDesc7; break;
|
|
}
|
|
CHECKPTR(pGetSurfaceDesc, "GetSurfaceDesc");
|
|
return pGetSurfaceDesc;
|
|
}
|
|
|
|
GetGDISurface_Type pGetGDISurfaceMethod(int dxversion)
|
|
{
|
|
GetGDISurface_Type pGetGDISurface;
|
|
switch(dxversion){
|
|
default:
|
|
case 1: pGetGDISurface = pGetGDISurface1; break;
|
|
case 2: pGetGDISurface = pGetGDISurface2; break;
|
|
case 3: pGetGDISurface = pGetGDISurface3; break;
|
|
case 4: pGetGDISurface = pGetGDISurface4; break;
|
|
case 7: pGetGDISurface = pGetGDISurface7; break;
|
|
}
|
|
CHECKPTR(pGetGDISurface, "GetGDISurface");
|
|
return pGetGDISurface;
|
|
}
|
|
|
|
int lpddsHookedVersion()
|
|
{
|
|
return iBakBufferVersion;
|
|
}
|
|
|
|
void DescribeSurface(LPDIRECTDRAWSURFACE lpdds, int dxversion, char *label, int line)
|
|
{
|
|
DDSURFACEDESC2 ddsd;
|
|
HRESULT res;
|
|
GetSurfaceDesc2_Type pGetSurfaceDesc = NULL;
|
|
int dwSize = (dxversion<4)?sizeof(DDSURFACEDESC):sizeof(DDSURFACEDESC2);
|
|
memset(&ddsd, 0, dwSize);
|
|
ddsd.dwSize = dwSize;
|
|
pGetSurfaceDesc = pGetSurfaceDescMethod();
|
|
if(pGetSurfaceDesc==NULL) return;
|
|
res=(*pGetSurfaceDescMethod())((LPDIRECTDRAWSURFACE2)lpdds, &ddsd);
|
|
if(res)return;
|
|
OutTraceDW("Surface %s: ddsd=%x dxversion=%d %s\n",
|
|
label, lpdds, dxversion, LogSurfaceAttributes(&ddsd, label, line));
|
|
}
|
|
|
|
void RegisterPixelFormat(int dxversion, LPDIRECTDRAWSURFACE lpdds)
|
|
{
|
|
DDSURFACEDESC2 ddsdpix;
|
|
memset((void *)&ddsdpix, 0, sizeof(DDSURFACEDESC2));
|
|
ddsdpix.dwSize = (dxversion < 4) ? sizeof(DDSURFACEDESC) : sizeof(DDSURFACEDESC2);
|
|
ddsdpix.dwFlags = DDSD_PIXELFORMAT;
|
|
switch(dxversion){
|
|
case 1: if(pGetSurfaceDesc1)(*pGetSurfaceDesc1)((LPDIRECTDRAWSURFACE)lpdds, (LPDDSURFACEDESC)&ddsdpix); break;
|
|
case 2: if(pGetSurfaceDesc2)(*pGetSurfaceDesc2)((LPDIRECTDRAWSURFACE)lpdds, (LPDDSURFACEDESC)&ddsdpix); break;
|
|
case 3: if(pGetSurfaceDesc3)(*pGetSurfaceDesc3)((LPDIRECTDRAWSURFACE)lpdds, (LPDDSURFACEDESC)&ddsdpix); break;
|
|
case 4: if(pGetSurfaceDesc4)(*pGetSurfaceDesc4)((LPDIRECTDRAWSURFACE2)lpdds, &ddsdpix); break;
|
|
case 7: if(pGetSurfaceDesc7)(*pGetSurfaceDesc7)((LPDIRECTDRAWSURFACE2)lpdds, &ddsdpix); break;
|
|
}
|
|
GetHookInfo()->pfd=ddsdpix.ddpfPixelFormat; // v2.02.88
|
|
OutTraceB("RegisterPixelFormat: lpdds=%x %s\n", lpdds, DumpPixelFormat(&ddsdpix));
|
|
}
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
// SetPixFmt: builds a pixel format descriptor when no one is specified, starting from the color depth, the current
|
|
// desktop pixel format (when the color depth is the same) or the config flags
|
|
|
|
void SetPixFmt(LPDDSURFACEDESC2 lpdd)
|
|
{
|
|
OutTraceDW("SetPixFmt: BPP=%d Use565=%d NoAlpha=%d\n",
|
|
dxw.VirtualPixelFormat.dwRGBBitCount,
|
|
dxw.dwFlags1 & USERGB565 ? 1:0,
|
|
dxw.dwFlags4 & NOALPHACHANNEL ? 1:0);
|
|
|
|
memset(&lpdd->ddpfPixelFormat,0,sizeof(DDPIXELFORMAT));
|
|
lpdd->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
|
|
|
switch (dxw.VirtualPixelFormat.dwRGBBitCount)
|
|
{
|
|
case 8:
|
|
case 15:
|
|
case 16:
|
|
case 24:
|
|
case 32:
|
|
FixPixelFormat(dxw.VirtualPixelFormat.dwRGBBitCount, &lpdd->ddpfPixelFormat);
|
|
break;
|
|
default:
|
|
OutTraceE("CreateSurface ERROR: Unsupported resolution ColorBPP=%d\n", dxw.VirtualPixelFormat.dwRGBBitCount);
|
|
break;
|
|
}
|
|
|
|
// remember current virtual settings
|
|
dxw.VirtualPixelFormat=lpdd->ddpfPixelFormat;
|
|
OutTraceDW("SetPixFmt: %s\n", DumpPixelFormat(lpdd));
|
|
}
|
|
|
|
// retrieves the stored pixel format
|
|
|
|
void GetPixFmt(LPDDSURFACEDESC2 lpdd)
|
|
{
|
|
lpdd->ddpfPixelFormat = dxw.VirtualPixelFormat;
|
|
OutTraceDW("GetPixFmt: %s\n", DumpPixelFormat(lpdd));
|
|
}
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
// hook query functions that determines the object versioning ....
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
int Set_dwSize_From_Surface()
|
|
{
|
|
int size;
|
|
switch(iBakBufferVersion){
|
|
case 1: size=sizeof(DDSURFACEDESC); break;
|
|
case 2: size=sizeof(DDSURFACEDESC); break;
|
|
case 3: size=sizeof(DDSURFACEDESC); break;
|
|
case 4: size=sizeof(DDSURFACEDESC2); break;
|
|
case 7: size=sizeof(DDSURFACEDESC2); break;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
void HookDDSession(LPDIRECTDRAW *lplpdd, int dxversion)
|
|
{
|
|
OutTraceDW("Hooking directdraw session dd=%x dxversion=%d thread_id=%x\n",
|
|
*lplpdd, dxversion, GetCurrentThreadId());
|
|
|
|
iDirectDrawVersion = dxversion; // save for ddraw session operations
|
|
|
|
// unimplemented, but better not hook it with a single wrapper
|
|
//SetHook((void *)(**(DWORD **)lplpdd + 12), extCompact, (void **)&pCompact, "Compact");
|
|
switch(dxversion) {
|
|
case 1:
|
|
SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD1, (void **)&pQueryInterfaceD1, "QueryInterface(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD1, (void **)&pReleaseD1, "Release(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper1, (void **)&pCreateClipper1, "CreateClipper(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette1, (void **)&pCreatePalette1, "CreatePalette(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface1, (void **)&pCreateSurface1, "CreateSurface(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface1, (void **)&pDuplicateSurface1, "DuplicateSurface(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes1, (void **)&pEnumDisplayModes1, "EnumDisplayModes(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface1, (void **)&pFlipToGDISurface1, "FlipToGDISurface(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCaps1D, (void **)&pGetCaps1D, "GetCaps(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 48), extGetDisplayMode1, (void **)&pGetDisplayMode1, "GetDisplayMode(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 56), extGetGDISurface1, (void **)&pGetGDISurface1, "GetGDISurface(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 64), extGetScanLine1, (void **)&pGetScanLine1, "GetScanLine(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 72), extInitialize1, (void **)&pInitialize1, "Initialize(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 76), extRestoreDisplayMode1, (void **)&pRestoreDisplayMode1, "RestoreDisplayMode(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 80), extSetCooperativeLevel1, (void **)&pSetCooperativeLevel1, "SetCooperativeLevel(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 84), extSetDisplayMode1, (void **)&pSetDisplayMode1, "SetDisplayMode(D1)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 88), extWaitForVerticalBlank1, (void **)&pWaitForVerticalBlank1, "WaitForVerticalBlank(D1)");
|
|
break;
|
|
case 2:
|
|
SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD2, (void **)&pQueryInterfaceD2, "QueryInterface(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD2, (void **)&pReleaseD2, "Release(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper2, (void **)&pCreateClipper2, "CreateClipper(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette2, (void **)&pCreatePalette2, "CreatePalette(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface2, (void **)&pCreateSurface2, "CreateSurface(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface2, (void **)&pDuplicateSurface2, "DuplicateSurface(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes2, (void **)&pEnumDisplayModes2, "EnumDisplayModes(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface2, (void **)&pFlipToGDISurface2, "FlipToGDISurface(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCaps2D, (void **)&pGetCaps2D, "GetCaps(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 48), extGetDisplayMode2, (void **)&pGetDisplayMode2, "GetDisplayMode(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 56), extGetGDISurface2, (void **)&pGetGDISurface2, "GetGDISurface(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 64), extGetScanLine2, (void **)&pGetScanLine2, "GetScanLine(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 72), extInitialize2, (void **)&pInitialize2, "Initialize(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 76), extRestoreDisplayMode2, (void **)&pRestoreDisplayMode2, "RestoreDisplayMode(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 80), extSetCooperativeLevel2, (void **)&pSetCooperativeLevel2, "SetCooperativeLevel(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 84), extSetDisplayMode2, (void **)&pSetDisplayMode2, "SetDisplayMode(D2)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 88), extWaitForVerticalBlank2, (void **)&pWaitForVerticalBlank2, "WaitForVerticalBlank(D2)");
|
|
// added in v2 interface
|
|
SetHook((void *)(**(DWORD **)lplpdd + 92), extGetAvailableVidMem2, (void **)&pGetAvailableVidMem2, "GetAvailableVidMem(D2)");
|
|
break;
|
|
case 3:
|
|
SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD3, (void **)&pReleaseD3, "Release(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper3, (void **)&pCreateClipper3, "CreateClipper(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette3, (void **)&pCreatePalette3, "CreatePalette(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface3, (void **)&pCreateSurface3, "CreateSurface(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface3, (void **)&pDuplicateSurface3, "DuplicateSurface(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes3, (void **)&pEnumDisplayModes3, "EnumDisplayModes(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface3, (void **)&pFlipToGDISurface3, "FlipToGDISurface(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCaps3D, (void **)&pGetCaps3D, "GetCaps(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 48), extGetDisplayMode3, (void **)&pGetDisplayMode3, "GetDisplayMode(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 56), extGetGDISurface3, (void **)&pGetGDISurface3, "GetGDISurface(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 64), extGetScanLine3, (void **)&pGetScanLine3, "GetScanLine(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 72), extInitialize3, (void **)&pInitialize3, "Initialize(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 76), extRestoreDisplayMode3, (void **)&pRestoreDisplayMode3, "RestoreDisplayMode(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 80), extSetCooperativeLevel3, (void **)&pSetCooperativeLevel3, "SetCooperativeLevel(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 84), extSetDisplayMode3, (void **)&pSetDisplayMode3, "SetDisplayMode(D3)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 88), extWaitForVerticalBlank3, (void **)&pWaitForVerticalBlank3, "WaitForVerticalBlank(D3)");
|
|
// added in v2 interface
|
|
SetHook((void *)(**(DWORD **)lplpdd + 92), extGetAvailableVidMem3, (void **)&pGetAvailableVidMem3, "GetAvailableVidMem(D3)");
|
|
break;
|
|
case 4:
|
|
SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD4, (void **)&pQueryInterfaceD4, "QueryInterface(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD4, (void **)&pReleaseD4, "Release(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper4, (void **)&pCreateClipper4, "CreateClipper(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette4, (void **)&pCreatePalette4, "CreatePalette(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface4, (void **)&pCreateSurface4, "CreateSurface(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface4, (void **)&pDuplicateSurface4, "DuplicateSurface(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes4, (void **)&pEnumDisplayModes4, "EnumDisplayModes(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface4, (void **)&pFlipToGDISurface4, "FlipToGDISurface(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCaps4D, (void **)&pGetCaps4D, "GetCaps(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 48), extGetDisplayMode4, (void **)&pGetDisplayMode4, "GetDisplayMode(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 56), extGetGDISurface4, (void **)&pGetGDISurface4, "GetGDISurface(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 64), extGetScanLine4, (void **)&pGetScanLine4, "GetScanLine(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 72), extInitialize4, (void **)&pInitialize4, "Initialize(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 76), extRestoreDisplayMode4, (void **)&pRestoreDisplayMode4, "RestoreDisplayMode(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 80), extSetCooperativeLevel4, (void **)&pSetCooperativeLevel4, "SetCooperativeLevel(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 84), extSetDisplayMode4, (void **)&pSetDisplayMode4, "SetDisplayMode(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 88), extWaitForVerticalBlank4, (void **)&pWaitForVerticalBlank4, "WaitForVerticalBlank(D4)");
|
|
// added in v2 interface
|
|
SetHook((void *)(**(DWORD **)lplpdd + 92), extGetAvailableVidMem4, (void **)&pGetAvailableVidMem4, "GetAvailableVidMem(D4)");
|
|
// added in v4 interface
|
|
SetHook((void *)(**(DWORD **)lplpdd + 104), extTestCooperativeLevel4, (void **)&pTestCooperativeLevel4, "TestCooperativeLevel(D4)");
|
|
break;
|
|
case 7:
|
|
SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD7, (void **)&pQueryInterfaceD7, "QueryInterface(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD7, (void **)&pReleaseD7, "Release(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper7, (void **)&pCreateClipper7, "CreateClipper(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette7, (void **)&pCreatePalette7, "CreatePalette(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface7, (void **)&pCreateSurface7, "CreateSurface(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface7, (void **)&pDuplicateSurface7, "DuplicateSurface(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes7, (void **)&pEnumDisplayModes7, "EnumDisplayModes(D4)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface7, (void **)&pFlipToGDISurface7, "FlipToGDISurface(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCaps7D, (void **)&pGetCaps7D, "GetCaps(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 48), extGetDisplayMode7, (void **)&pGetDisplayMode7, "GetDisplayMode(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 56), extGetGDISurface7, (void **)&pGetGDISurface7, "GetGDISurface(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 64), extGetScanLine7, (void **)&pGetScanLine7, "GetScanLine(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 72), extInitialize7, (void **)&pInitialize7, "Initialize(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 76), extRestoreDisplayMode7, (void **)&pRestoreDisplayMode7, "RestoreDisplayMode(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 80), extSetCooperativeLevel7, (void **)&pSetCooperativeLevel7, "SetCooperativeLevel(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 84), extSetDisplayMode7, (void **)&pSetDisplayMode7, "SetDisplayMode(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 88), extWaitForVerticalBlank7, (void **)&pWaitForVerticalBlank7, "WaitForVerticalBlank(D7)");
|
|
// added in v2 interface
|
|
SetHook((void *)(**(DWORD **)lplpdd + 92), extGetAvailableVidMem7, (void **)&pGetAvailableVidMem7, "GetAvailableVidMem(D7)");
|
|
// added in v4 interface
|
|
SetHook((void *)(**(DWORD **)lplpdd + 104), extTestCooperativeLevel7, (void **)&pTestCooperativeLevel7, "TestCooperativeLevel(D7)");
|
|
// added in v7 interface
|
|
SetHook((void *)(**(DWORD **)lplpdd + 112), extStartModeTest, (void **)&pStartModeTest, "StartModeTest(D7)");
|
|
SetHook((void *)(**(DWORD **)lplpdd + 116), extEvaluateMode, (void **)&pEvaluateMode, "EvaluateMode(D7)");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void HookDDClipper(LPDIRECTDRAWCLIPPER FAR* lplpDDClipper)
|
|
{
|
|
OutTraceDW("Hooking directdraw clipper dd=%x\n", *lplpDDClipper);
|
|
|
|
SetHook((void *)(**(DWORD **)lplpDDClipper + 8), extReleaseC, (void **)&pReleaseC, "Release(C)");
|
|
SetHook((void *)(**(DWORD **)lplpDDClipper + 12), extGetClipList, (void **)&pGetClipList, "GetClipList(C)");
|
|
SetHook((void *)(**(DWORD **)lplpDDClipper + 28), extSetClipList, (void **)&pSetClipList, "SetClipList(C)");
|
|
SetHook((void *)(**(DWORD **)lplpDDClipper + 32), extSetHWnd, (void **)&pSetHWnd, "SetHWnd(C)");
|
|
}
|
|
|
|
static void HookDDPalette(LPDIRECTDRAWPALETTE FAR* lplpDDPalette)
|
|
{
|
|
OutTraceDW("Hooking directdraw palette dd=%x\n", *lplpDDPalette);
|
|
|
|
/*** IDirectDrawPalette methods ***/
|
|
SetHook((void *)(**(DWORD **)lplpDDPalette + 8), extReleaseP, (void **)&pReleaseP, "Release(P)");
|
|
SetHook((void *)(**(DWORD **)lplpDDPalette + 24), extSetEntries, (void **)&pSetEntries, "SetEntries(P)");
|
|
}
|
|
|
|
void HookDDSurface(LPDIRECTDRAWSURFACE *lplpdds, int dxversion, BOOL isPrim)
|
|
{
|
|
BOOL bEmu = dxw.IsEmulated;
|
|
if(iBakBufferVersion==0) iBakBufferVersion=dxversion; // v2.03.60
|
|
|
|
OutTraceDW("Hooking surface dds=%x dxversion=%d prim=%x thread_id=%x\n",
|
|
*lplpdds, dxversion, isPrim, GetCurrentThreadId());
|
|
|
|
switch(dxversion) {
|
|
case 1:
|
|
SetHook((void *)(**(DWORD **)lplpdds), extQueryInterfaceS1, (void **)&pQueryInterfaceS1, "QueryInterface(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 8), extReleaseS1, (void **)&pReleaseS1, "Release(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 12), extAddAttachedSurface1, (void **)&pAddAttachedSurface1, "AddAttachedSurface(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 16), extAddOverlayDirtyRect1, (void **)&pAddOverlayDirtyRect1, "AddOverlayDirtyRect(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 28), extBltFast1, (void **)&pBltFast1, "BltFast(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 20), extBlt1, (void **)&pBlt1, "Blt(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 32), extDeleteAttachedSurface1, (void **)&pDeleteAttachedSurface1, "DeleteAttachedSurface(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 36), extEnumAttachedSurfaces1, (void **)&pEnumAttachedSurfaces1, "EnumAttachedSurfaces(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 40), extEnumOverlayZOrders1, (void **)&pEnumOverlayZOrders1, "EnumOverlayZOrders(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 44), extFlip1, (void **)&pFlip1, "Flip(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface1, (void **)&pGetAttachedSurface1, "GetAttachedSurface(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps1S, (void **)&pGetCaps1S, "GetCaps(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 64), extGetColorKey1, (void **)&pGetColorKey1, "GetColorKey(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 68), extGetDC1, (void **)&pGetDC1, "GetDC(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 76), extGetOverlayPosition1, (void **)&pGetOverlayPosition1, "GetOverlayPosition(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 80), extGetPalette1, (void **)&pGetPalette1, "GetPalette(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 84), extGetPixelFormat1, (void **)&pGetPixelFormat1, "GetPixelFormat(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc1, (void **)&pGetSurfaceDesc1, "GetSurfaceDesc(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 100), bEmu ? extLock1 : extLockDir1, (void **)&pLock1, "Lock(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 128), bEmu ? extUnlock1 : extUnlockDir1, (void **)&pUnlock1, "Unlock(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 104), extReleaseDC1, (void **)&pReleaseDC1, "ReleaseDC(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 120), extSetOverlayPosition1, (void **)&pSetOverlayPosition1, "SetOverlayPosition(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 124), extSetPalette1, (void **)&pSetPalette1, "SetPalette(S1)");
|
|
break;
|
|
case 2:
|
|
SetHook((void *)(**(DWORD **)lplpdds), extQueryInterfaceS2, (void **)&pQueryInterfaceS2, "QueryInterface(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 8), extReleaseS2, (void **)&pReleaseS2, "Release(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 12), extAddAttachedSurface2, (void **)&pAddAttachedSurface2, "AddAttachedSurface(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 16), extAddOverlayDirtyRect2, (void **)&pAddOverlayDirtyRect2, "AddOverlayDirtyRect(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 28), extBltFast2, (void **)&pBltFast2, "BltFast(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 20), extBlt2, (void **)&pBlt2, "Blt(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 32), extDeleteAttachedSurface2, (void **)&pDeleteAttachedSurface2, "DeleteAttachedSurface(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 36), extEnumAttachedSurfaces2, (void **)&pEnumAttachedSurfaces2, "EnumAttachedSurfaces(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 40), extEnumOverlayZOrders2, (void **)&pEnumOverlayZOrders2, "EnumOverlayZOrders(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 44), extFlip2, (void **)&pFlip2, "Flip(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface2, (void **)&pGetAttachedSurface2, "GetAttachedSurface(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps2S, (void **)&pGetCaps2S, "GetCaps(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 64), extGetColorKey2, (void **)&pGetColorKey2, "GetColorKey(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 68), extGetDC2, (void **)&pGetDC2, "GetDC(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 76), extGetOverlayPosition2, (void **)&pGetOverlayPosition2, "GetOverlayPosition(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 80), extGetPalette2, (void **)&pGetPalette2, "GetPalette(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 84), extGetPixelFormat2, (void **)&pGetPixelFormat2, "GetPixelFormat(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc2, (void **)&pGetSurfaceDesc2, "GetSurfaceDesc(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 100), bEmu ? extLock2 : extLockDir2, (void **)&pLock2, "Lock(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 128), bEmu ? extUnlock2 : extUnlockDir2, (void **)&pUnlock2, "Unlock(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 104), extReleaseDC2, (void **)&pReleaseDC2, "ReleaseDC(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 120), extSetOverlayPosition2, (void **)&pSetOverlayPosition2, "SetOverlayPosition(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 124), extSetPalette2, (void **)&pSetPalette2, "SetPalette(S2)");
|
|
break;
|
|
case 3:
|
|
SetHook((void *)(**(DWORD **)lplpdds), extQueryInterfaceS3, (void **)&pQueryInterfaceS3, "QueryInterface(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 8), extReleaseS3, (void **)&pReleaseS3, "Release(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 12), extAddAttachedSurface3, (void **)&pAddAttachedSurface3, "AddAttachedSurface(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 16), extAddOverlayDirtyRect3, (void **)&pAddOverlayDirtyRect3, "AddOverlayDirtyRect(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 28), extBltFast3, (void **)&pBltFast3, "BltFast(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 20), extBlt3, (void **)&pBlt3, "Blt(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 32), extDeleteAttachedSurface3, (void **)&pDeleteAttachedSurface3, "DeleteAttachedSurface(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 36), extEnumAttachedSurfaces3, (void **)&pEnumAttachedSurfaces3, "EnumAttachedSurfaces(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 40), extEnumOverlayZOrders3, (void **)&pEnumOverlayZOrders3, "EnumOverlayZOrders(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 44), extFlip3, (void **)&pFlip3, "Flip(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface3, (void **)&pGetAttachedSurface3, "GetAttachedSurface(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps3S, (void **)&pGetCaps3S, "GetCaps(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 64), extGetColorKey3, (void **)&pGetColorKey3, "GetColorKey(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 68), extGetDC3, (void **)&pGetDC3, "GetDC(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 76), extGetOverlayPosition3, (void **)&pGetOverlayPosition3, "GetOverlayPosition(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 80), extGetPalette3, (void **)&pGetPalette3, "GetPalette(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 84), extGetPixelFormat3, (void **)&pGetPixelFormat3, "GetPixelFormat(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc3, (void **)&pGetSurfaceDesc3, "GetSurfaceDesc(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 100), bEmu ? extLock3 : extLockDir3, (void **)&pLock3, "Lock(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 128), bEmu ? extUnlock3 : extUnlockDir3, (void **)&pUnlock3, "Unlock(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 104), extReleaseDC3, (void **)&pReleaseDC3, "ReleaseDC(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 120), extSetOverlayPosition3, (void **)&pSetOverlayPosition3, "SetOverlayPosition(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 124), extSetPalette3, (void **)&pSetPalette3, "SetPalette(S3)");
|
|
// added in interface version 3
|
|
SetHook((void *)(**(DWORD **)lplpdds + 156), extSetSurfaceDesc3, (void **)&pSetSurfaceDesc3, "SetSurfaceDesc(S3)");
|
|
break;
|
|
case 4:
|
|
SetHook((void *)(**(DWORD **)lplpdds), extQueryInterfaceS4, (void **)&pQueryInterfaceS4, "QueryInterface(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 8), extReleaseS4, (void **)&pReleaseS4, "Release(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 12), extAddAttachedSurface4, (void **)&pAddAttachedSurface4, "AddAttachedSurface(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 16), extAddOverlayDirtyRect4, (void **)&pAddOverlayDirtyRect4, "AddOverlayDirtyRect(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 28), extBltFast4, (void **)&pBltFast4, "BltFast(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 20), extBlt4, (void **)&pBlt4, "Blt(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 32), extDeleteAttachedSurface4, (void **)&pDeleteAttachedSurface4, "DeleteAttachedSurface(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 36), extEnumAttachedSurfaces4, (void **)&pEnumAttachedSurfaces4, "EnumAttachedSurfaces(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 40), extEnumOverlayZOrders4, (void **)&pEnumOverlayZOrders4, "EnumOverlayZOrders(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 44), extFlip4, (void **)&pFlip4, "Flip(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface4, (void **)&pGetAttachedSurface4, "GetAttachedSurface(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps4S, (void **)&pGetCaps4S, "GetCaps(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 64), extGetColorKey4, (void **)&pGetColorKey4, "GetColorKey(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 68), extGetDC4, (void **)&pGetDC4, "GetDC(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 76), extGetOverlayPosition4, (void **)&pGetOverlayPosition4, "GetOverlayPosition(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 80), extGetPalette4, (void **)&pGetPalette4, "GetPalette(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 84), extGetPixelFormat4, (void **)&pGetPixelFormat4, "GetPixelFormat(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc4, (void **)&pGetSurfaceDesc4, "GetSurfaceDesc(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 100), bEmu ? extLock4 : extLockDir4, (void **)&pLock4, "Lock(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 128), bEmu ? extUnlock4 : extUnlockDir4, (void **)&pUnlock4, "Unlock(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 104), extReleaseDC4, (void **)&pReleaseDC4, "ReleaseDC(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 120), extSetOverlayPosition4, (void **)&pSetOverlayPosition4, "SetOverlayPosition(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 124), extSetPalette4, (void **)&pSetPalette4, "SetPalette(S4)");
|
|
// added in interface version 3
|
|
SetHook((void *)(**(DWORD **)lplpdds + 156), extSetSurfaceDesc4, (void **)&pSetSurfaceDesc4, "SetSurfaceDesc(S4)");
|
|
break;
|
|
case 7:
|
|
SetHook((void *)(**(DWORD **)lplpdds), extQueryInterfaceS7, (void **)&pQueryInterfaceS7, "QueryInterface(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 8), extReleaseS7, (void **)&pReleaseS7, "Release(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 12), extAddAttachedSurface7, (void **)&pAddAttachedSurface7, "AddAttachedSurface(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 16), extAddOverlayDirtyRect7, (void **)&pAddOverlayDirtyRect7, "AddOverlayDirtyRect(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 28), extBltFast7, (void **)&pBltFast7, "BltFast(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 20), extBlt7, (void **)&pBlt7, "Blt(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 32), extDeleteAttachedSurface7, (void **)&pDeleteAttachedSurface7, "DeleteAttachedSurface(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 36), extEnumAttachedSurfaces7, (void **)&pEnumAttachedSurfaces7, "EnumAttachedSurfaces(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 40), extEnumOverlayZOrders7, (void **)&pEnumOverlayZOrders7, "EnumOverlayZOrders(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 44), extFlip7, (void **)&pFlip7, "Flip(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface7, (void **)&pGetAttachedSurface7, "GetAttachedSurface(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps7S, (void **)&pGetCaps7S, "GetCaps(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 64), extGetColorKey7, (void **)&pGetColorKey7, "GetColorKey(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 68), extGetDC7, (void **)&pGetDC7, "GetDC(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 76), extGetOverlayPosition7, (void **)&pGetOverlayPosition7, "GetOverlayPosition(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 80), extGetPalette7, (void **)&pGetPalette7, "GetPalette(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 84), extGetPixelFormat7, (void **)&pGetPixelFormat7, "GetPixelFormat(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc7, (void **)&pGetSurfaceDesc7, "GetSurfaceDesc(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 100), bEmu ? extLock7 : extLockDir7, (void **)&pLock7, "Lock(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 128), bEmu ? extUnlock7 : extUnlockDir7, (void **)&pUnlock7, "Unlock(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 104), extReleaseDC7, (void **)&pReleaseDC7, "ReleaseDC(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 120), extSetOverlayPosition7, (void **)&pSetOverlayPosition7, "SetOverlayPosition(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 124), extSetPalette7, (void **)&pSetPalette7, "SetPalette(S7)");
|
|
// added in interface version 3
|
|
SetHook((void *)(**(DWORD **)lplpdds + 156), extSetSurfaceDesc7, (void **)&pSetSurfaceDesc7, "SetSurfaceDesc(S7)");
|
|
break;
|
|
}
|
|
|
|
if (!isPrim) return;
|
|
|
|
switch(dxversion) {
|
|
case 1:
|
|
SetHook((void *)(**(DWORD **)lplpdds + 112), extSetClipper1, (void **)&pSetClipper1, "SetClipper(S1)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 116), extSetColorKey1, (void **)&pSetColorKey1, "SetColorKey(S1)");
|
|
break;
|
|
case 2:
|
|
SetHook((void *)(**(DWORD **)lplpdds + 112), extSetClipper2, (void **)&pSetClipper2, "SetClipper(S2)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 116), extSetColorKey2, (void **)&pSetColorKey2, "SetColorKey(S2)");
|
|
break;
|
|
case 3:
|
|
SetHook((void *)(**(DWORD **)lplpdds + 112), extSetClipper3, (void **)&pSetClipper3, "SetClipper(S3)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 116), extSetColorKey3, (void **)&pSetColorKey3, "SetColorKey(S3)");
|
|
break;
|
|
case 4:
|
|
SetHook((void *)(**(DWORD **)lplpdds + 112), extSetClipper4, (void **)&pSetClipper4, "SetClipper(S4)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 116), extSetColorKey4, (void **)&pSetColorKey4, "SetColorKey(S4)");
|
|
break;
|
|
case 7:
|
|
SetHook((void *)(**(DWORD **)lplpdds + 112), extSetClipper7, (void **)&pSetClipper7, "SetClipper(S7)");
|
|
SetHook((void *)(**(DWORD **)lplpdds + 116), extSetColorKey7, (void **)&pSetColorKey7, "SetColorKey(S7)");
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void HookGammaControl(LPVOID *obp)
|
|
{
|
|
// IDirectDrawGammaControl::GetGammaRamp
|
|
SetHook((void *)(**(DWORD **)obp + 12), extDDGetGammaRamp, (void **)&pDDGetGammaRamp, "GetGammaRamp(G)");
|
|
// IDirectDrawGammaControl::SetGammaRamp
|
|
SetHook((void *)(**(DWORD **)obp + 16), extDDSetGammaRamp, (void **)&pDDSetGammaRamp, "SetGammaRamp(G)");
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------------ */
|
|
// CleanRect:
|
|
// takes care of a corrupted RECT struct where some elements are not valid pointers.
|
|
// In this case, the whole RECT * variable is set to NULL, a value that is interpreted
|
|
// by directdraw functions as the whole surface area.
|
|
/* ------------------------------------------------------------------------------ */
|
|
|
|
static void CleanRect(RECT **lprect, int line)
|
|
{
|
|
__try {
|
|
// normally unharmful statements
|
|
if(*lprect){
|
|
int i;
|
|
i=(*lprect)->bottom;
|
|
i=(*lprect)->top;
|
|
i=(*lprect)->left;
|
|
i=(*lprect)->right;
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER){
|
|
OutTraceE("Rectangle exception caught at %d: invalid RECT\n", __LINE__);
|
|
if(IsAssertEnabled) MessageBox(0, "Rectangle exception", "CleanRect", MB_OK | MB_ICONEXCLAMATION);
|
|
*lprect=NULL;
|
|
}
|
|
}
|
|
|
|
static void MaskCapsD(LPDDCAPS c1, LPDDCAPS c2)
|
|
{
|
|
FILE *capfile;
|
|
//char sBuf[80+1];
|
|
DWORD val;
|
|
if(IsDebug){
|
|
char CapsBuf[3*sizeof(DDCAPS_DX7)+20];
|
|
int i;
|
|
unsigned char *p;
|
|
if(c1){
|
|
p=(unsigned char *)c1;
|
|
for(i=0; i<sizeof(DDCAPS_DX7); i++) sprintf(&CapsBuf[3*i], "%02.2X,", p[i]);
|
|
OutTrace("CapsDump(c1:HW)=%s\n", CapsBuf);
|
|
}
|
|
if(c2){
|
|
p=(unsigned char *)c2;
|
|
for(i=0; i<sizeof(DDCAPS_DX7); i++) sprintf(&CapsBuf[3*i], "%02.2X,", p[i]);
|
|
OutTrace("CapsDump(c2:SW)=%s\n", CapsBuf);
|
|
}
|
|
}
|
|
capfile=fopen("dxwnd.caps.txt", "r");
|
|
if(!capfile) return;
|
|
|
|
int HwSwCap;
|
|
int WordOffset;
|
|
char Operator;
|
|
LPDDCAPS Caps;
|
|
LPDWORD lpDWord;
|
|
while(TRUE){
|
|
if(fscanf(capfile, "C%d.%x[%c]=%x\n", &HwSwCap, &WordOffset, &Operator, &val)!=4) break;
|
|
OutTrace("MaskCaps: C%d.%x[%c].x%08.8X\n", HwSwCap, WordOffset, Operator, val);
|
|
Caps = (HwSwCap == 1) ? c1 : c2;
|
|
if(!Caps) continue;
|
|
lpDWord = &(Caps->dwSize) + WordOffset;
|
|
switch(Operator){
|
|
case '&': *lpDWord &= val; break;
|
|
case '|': *lpDWord |= val; break;
|
|
case '-': *lpDWord &= (~val); break;
|
|
case '=':
|
|
default: *lpDWord = val; break;
|
|
}
|
|
}
|
|
fclose(capfile);
|
|
|
|
if(c1) {
|
|
OutTrace("MaskCaps(D-HW): caps=%x(%s) caps2=%x(%s) fxcaps=%x(%s) fxalphacaps=%x(%s) keycaps=%x(%s)\n",
|
|
c1->dwCaps, ExplainDDDCaps(c1->dwCaps),
|
|
c1->dwCaps2, ExplainDDDCaps2(c1->dwCaps2),
|
|
c1->dwFXCaps, ExplainDDFXCaps(c1->dwFXCaps),
|
|
c1->dwFXAlphaCaps, ExplainDDFXALPHACaps(c1->dwFXAlphaCaps),
|
|
c1->dwCKeyCaps, ExplainDDCKeyCaps(c1->dwCKeyCaps));
|
|
}
|
|
if(c2) {
|
|
OutTrace("MaskCaps(D-SW): caps=%x(%s) caps2=%x(%s) fxcaps=%x(%s) fxalphacaps=%x(%s) keycaps=%x(%s)\n",
|
|
c2->dwCaps, ExplainDDDCaps(c2->dwCaps),
|
|
c2->dwCaps2, ExplainDDDCaps2(c2->dwCaps2),
|
|
c2->dwFXCaps, ExplainDDFXCaps(c2->dwFXCaps),
|
|
c2->dwFXAlphaCaps, ExplainDDFXALPHACaps(c2->dwFXAlphaCaps),
|
|
c2->dwCKeyCaps, ExplainDDCKeyCaps(c2->dwCKeyCaps));
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------------ */
|
|
// directdraw method hooks
|
|
/* ------------------------------------------------------------------------------ */
|
|
|
|
static void HandleCapsD(char *sLabel, LPDDCAPS c)
|
|
{
|
|
const DWORD dwMaxMem = 0x70000000;
|
|
const DWORD dwHugeMem = 0xFFFFFFFF;
|
|
|
|
OutTraceDDRAW(
|
|
"GetCaps(%s): caps=%x(%s) caps2=%x(%s) palcaps=%x(%s) "
|
|
"fxcaps=%x(%s) fxalphacaps=%x(%s) keycaps=%x(%s)\n",
|
|
sLabel,
|
|
c->dwCaps, ExplainDDDCaps(c->dwCaps),
|
|
c->dwCaps2, ExplainDDDCaps2(c->dwCaps2),
|
|
c->dwPalCaps, ExplainDDPalCaps(c->dwPalCaps),
|
|
c->dwFXCaps, ExplainDDFXCaps(c->dwFXCaps),
|
|
c->dwFXAlphaCaps, ExplainDDFXALPHACaps(c->dwFXAlphaCaps),
|
|
c->dwCKeyCaps, ExplainDDCKeyCaps(c->dwCKeyCaps));
|
|
OutTraceDDRAW("GetCaps(%s): VidMemTotal=%x VidMemFree=%x ZBufferBitDepths=%x(%s)\n",
|
|
sLabel, c->dwVidMemTotal, c->dwVidMemFree, c->dwZBufferBitDepths, ExplainZBufferBitDepths(c->dwZBufferBitDepths));
|
|
OutTraceDDRAW("GetCaps(%s): MaxVisibleOverlays=%x CurrVisibleOverlays=%x\n",
|
|
sLabel, c->dwMaxVisibleOverlays, c->dwCurrVisibleOverlays);
|
|
if(IsTraceHex) HexTrace((unsigned char *)c, c->dwSize);
|
|
|
|
if(dxw.bHintActive){
|
|
if(c->dwVidMemTotal > dwMaxMem) ShowHint(HINT_LIMITMEM);
|
|
if(c->dwVidMemFree > dwMaxMem) ShowHint(HINT_LIMITMEM);
|
|
}
|
|
|
|
if(dxw.dwFlags2 & LIMITRESOURCES){ // check for memory value overflow
|
|
if(c->dwVidMemTotal > dwMaxMem) c->dwVidMemTotal = dwMaxMem;
|
|
if(c->dwVidMemFree > dwMaxMem) c->dwVidMemFree = dwMaxMem;
|
|
}
|
|
if(dxw.dwFlags5 & STRESSRESOURCES){
|
|
c->dwVidMemTotal = dwHugeMem;
|
|
c->dwVidMemFree = dwHugeMem;
|
|
}
|
|
if(dxw.dwFlags6 & SETZBUFFERBITDEPTHS){
|
|
// From MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/gg426101%28v=vs.85%29.aspx :
|
|
// dwZBufferBitDepths
|
|
// DDBD_8, DDBD_16, DDBD_24, or DDBD_32. (Indicate 8, 16, 24, or 32 bits per pixel.)
|
|
// This member is obsolete for DirectX 6.0 and later.
|
|
// Use the IDirect3D7::EnumZBufferFormats to retrieve information about supported depth buffer formats.
|
|
// v2.03.35: needed to bypass the "Banzai Bug" initial controls
|
|
if (c->dwZBufferBitDepths == 0) {
|
|
c->dwZBufferBitDepths = (DDBD_8|DDBD_16|DDBD_24|DDBD_32);
|
|
OutTraceDDRAW("GetCaps(%s): FIXED ZBufferBitDepths=%x(%s)\n",
|
|
sLabel, c->dwZBufferBitDepths, ExplainZBufferBitDepths(c->dwZBufferBitDepths));
|
|
}
|
|
}
|
|
if((dxw.dwFlags5 & STRESSRESOURCES) || (dxw.dwFlags2 & LIMITRESOURCES))
|
|
OutTraceDDRAW("GetCaps(%s): FIXED VidMemTotal=%x VidMemFree=%x\n", sLabel, c->dwVidMemTotal, c->dwVidMemFree);
|
|
}
|
|
|
|
static HRESULT WINAPI extGetCapsD(int dxversion, GetCapsD_Type pGetCapsD, LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2)
|
|
{
|
|
HRESULT res;
|
|
OutTraceDDRAW("GetCaps(D%d): lpdd=%x %s %s\n", dxversion, lpdd, c1?"c1":"NULL", c2?"c2":"NULL");
|
|
res=(*pGetCapsD)(lpdd, c1, c2);
|
|
if(res) {
|
|
OutTraceE("GetCaps(D): ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
if (c1) HandleCapsD("D-HW", c1);
|
|
if (c2) HandleCapsD("D-SW", c2);
|
|
|
|
if((dxw.dwFlags3 & FORCESHEL) && c1) {
|
|
DDCAPS_DX7 swcaps; // DDCAPS_DX7 because it is the bigger in size
|
|
int size;
|
|
size=c1->dwSize;
|
|
if (!c2) {
|
|
memset(&swcaps, 0, sizeof(DDCAPS_DX7));
|
|
swcaps.dwSize=size;
|
|
c2=&swcaps;
|
|
res=(*pGetCapsD)(lpdd, NULL, c2);
|
|
}
|
|
DWORD dwVidMemTotal=c1->dwVidMemTotal;
|
|
DWORD dwVidMemFree=c1->dwVidMemFree;
|
|
memcpy((void *)c1, (void *)c2, size);
|
|
if(c1->dwVidMemTotal == 0) c1->dwVidMemTotal=dwVidMemTotal;
|
|
if(c1->dwVidMemFree == 0) c1->dwVidMemFree =dwVidMemFree;
|
|
if(c1->dwVidMemTotal == 0) c1->dwVidMemTotal=0x20000000; // 500 MB
|
|
if(c1->dwVidMemFree == 0) c1->dwVidMemFree =0x20000000; // 500 MB
|
|
if (c1) HandleCapsD("D-HW(fixed)", c1);
|
|
if (c2) HandleCapsD("D-SW(fixed)", c2);
|
|
}
|
|
|
|
if((dxw.dwFlags8 & NOHALDEVICE) && c1) {
|
|
OutTraceDW("GetCaps(D): NOHALDEVICE\n");
|
|
c1->ddsCaps.dwCaps = DDCAPS_NOHARDWARE;
|
|
c1->ddsCaps.dwCaps2 = DDCAPS2_CANRENDERWINDOWED;
|
|
c1->dwPalCaps = 0;
|
|
c1->dwFXCaps = 0;
|
|
c1->dwFXAlphaCaps = 0;
|
|
c1->dwCKeyCaps = 0;
|
|
c1->dwVidMemTotal = c1->dwVidMemFree = 0;
|
|
c1->dwZBufferBitDepths = 0;
|
|
c1->dwMaxVisibleOverlays = c1->dwCurrVisibleOverlays = 0;
|
|
HandleCapsD("D-HW(NoHAL)", c1);
|
|
}
|
|
|
|
if((dxw.dwFlags3 & MINIMALCAPS)) SetMinimalCaps(dxversion, c1, c2);
|
|
|
|
if(dxw.dwFlags3 & CAPMASK) MaskCapsD(c1, c2);
|
|
|
|
#define OVERLAYLAYERCAPS \
|
|
(DDCAPS_OVERLAY|DDCAPS_OVERLAYCANTCLIP|\
|
|
DDCAPS_OVERLAYFOURCC|DDCAPS_OVERLAYSTRETCH)
|
|
#define OVERLAYKEYCAPS \
|
|
(DDCKEYCAPS_DESTOVERLAY|DDCKEYCAPS_DESTOVERLAYYUV|\
|
|
DDCKEYCAPS_SRCOVERLAY|DDCKEYCAPS_SRCOVERLAYYUV|\
|
|
DDCKEYCAPS_SRCOVERLAYCLRSPACE|DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV)
|
|
|
|
if(dxw.dwFlags7 & SUPPRESSOVERLAY){
|
|
if(c1){
|
|
c1->ddsCaps.dwCaps &= ~OVERLAYLAYERCAPS;
|
|
c1->dwCKeyCaps &= ~OVERLAYKEYCAPS;
|
|
c1->dwMaxVisibleOverlays = c1->dwCurrVisibleOverlays = 0;
|
|
}
|
|
if(c2){
|
|
c2->ddsCaps.dwCaps &= ~OVERLAYLAYERCAPS;
|
|
c2->dwCKeyCaps &= ~OVERLAYKEYCAPS;
|
|
c2->dwMaxVisibleOverlays = c2->dwCurrVisibleOverlays = 0;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extGetCaps1D(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2)
|
|
{ return extGetCapsD(1, pGetCaps1D, lpdd, c1, c2); }
|
|
HRESULT WINAPI extGetCaps2D(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2)
|
|
{ return extGetCapsD(2, pGetCaps2D, lpdd, c1, c2); }
|
|
HRESULT WINAPI extGetCaps3D(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2)
|
|
{ return extGetCapsD(3, pGetCaps3D, lpdd, c1, c2); }
|
|
HRESULT WINAPI extGetCaps4D(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2)
|
|
{ return extGetCapsD(4, pGetCaps4D, lpdd, c1, c2); }
|
|
HRESULT WINAPI extGetCaps7D(LPDIRECTDRAW lpdd, LPDDCAPS_DX7 c1, LPDDCAPS_DX7 c2)
|
|
{ return extGetCapsD(7, pGetCaps7D, lpdd, (LPDDCAPS)c1, (LPDDCAPS)c2); }
|
|
|
|
HRESULT WINAPI extDirectDrawCreate(GUID FAR *lpguid, LPDIRECTDRAW FAR *lplpdd, IUnknown FAR *pu)
|
|
{
|
|
HRESULT res;
|
|
GUID FAR *lpPrivGuid = lpguid;
|
|
|
|
OutTraceDDRAW("DirectDrawCreate: guid=%x(%s)\n", lpguid, ExplainGUID(lpguid));
|
|
|
|
if(!pDirectDrawCreate){ // not hooked yet....
|
|
HINSTANCE hinst;
|
|
hinst = (*pLoadLibraryA)("ddraw.dll");
|
|
if(!hinst){
|
|
OutTraceE("LoadLibrary ddraw.dll ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
}
|
|
pDirectDrawCreate =
|
|
(DirectDrawCreate_Type)GetProcAddress(hinst, "DirectDrawCreate");
|
|
if(pDirectDrawCreate)
|
|
HookAPI(hinst, "ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreate); // v2.02.52
|
|
else{
|
|
char sMsg[81];
|
|
sprintf_s(sMsg, 80, "DirectDrawCreate hook failed: error=%d\n", GetLastError());
|
|
OutTraceDW(sMsg);
|
|
if(IsAssertEnabled) MessageBox(0, sMsg, "Hook", MB_OK | MB_ICONEXCLAMATION);
|
|
return DDERR_GENERIC; // is there a better one?
|
|
}
|
|
}
|
|
|
|
if((dxw.dwFlags3 & FORCESHEL) && (lpguid==NULL)) lpPrivGuid=(GUID FAR *)DDCREATE_EMULATIONONLY;
|
|
|
|
res = (*pDirectDrawCreate)(lpPrivGuid, lplpdd, pu);
|
|
if(res) {
|
|
OutTraceE("DirectDrawCreate: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
if(dxw.dwFlags3 & COLORFIX) (*((DDRAWI_DIRECTDRAW_INT **)lplpdd))->lpLcl->dwAppHackFlags |= 0x800;
|
|
|
|
dxw.dwDDVersion=1;
|
|
char *mode;
|
|
switch ((DWORD)lpPrivGuid){
|
|
case 0: mode="NULL"; break;
|
|
case DDCREATE_HARDWAREONLY: mode="DDCREATE_HARDWAREONLY"; break;
|
|
case DDCREATE_EMULATIONONLY: mode="DDCREATE_EMULATIONONLY"; break;
|
|
default:
|
|
switch (*(DWORD *)lpguid){
|
|
case 0x6C14DB80: dxw.dwDDVersion=1; mode="IID_IDirectDraw"; break;
|
|
case 0xB3A6F3E0: dxw.dwDDVersion=2; mode="IID_IDirectDraw2"; break;
|
|
case 0x618f8ad4: dxw.dwDDVersion=3; mode="IID_IDirectDraw3"; break;
|
|
case 0x9c59509a: dxw.dwDDVersion=4; mode="IID_IDirectDraw4"; break;
|
|
case 0x15e65ec0: dxw.dwDDVersion=7; mode="IID_IDirectDraw7"; break;
|
|
default: mode="unknown"; break;
|
|
}
|
|
break;
|
|
}
|
|
OutTraceDDRAW("DirectDrawCreate: lpdd=%x guid=%s DDVersion=%d\n", *lplpdd, mode, dxw.dwDDVersion);
|
|
|
|
HookDDSession(lplpdd, dxw.dwDDVersion);
|
|
|
|
// beware: old ddraw games seem to reuse a closed ddraw handle. The theory is that maybe whenever
|
|
// you created a ddraw session, you got more than one reference count, so that releasing it once
|
|
// did not destroy the object.... but why? when (I mean, in which situations? Maybe not always...)
|
|
// and for which releases? The fix here assumes that this fact is true and holds always for ddraw 1
|
|
// sessions.
|
|
// update: this is no good for "Jet Moto" that created a ddraw session and expects to Release it
|
|
// with a refcount zero.
|
|
|
|
//if(dxw.dwDDVersion==1) (*lplpdd)->AddRef(); // seems to fix problems in "Warhammer 40K Rites Of War"
|
|
|
|
if(IsDebug){
|
|
DDCAPS DriverCaps, EmulCaps;
|
|
memset(&DriverCaps, 0, sizeof(DriverCaps));
|
|
DriverCaps.dwSize=sizeof(DriverCaps);
|
|
memset(&EmulCaps, 0, sizeof(EmulCaps));
|
|
EmulCaps.dwSize=sizeof(EmulCaps);
|
|
(LPDIRECTDRAW)(*lplpdd)->GetCaps(&DriverCaps, &EmulCaps);
|
|
//OutTrace("DirectDrawCreate: drivercaps=%x(%s) emulcaps=%x(%s)\n", DriverCaps.ddsCaps, "???", EmulCaps.ddsCaps, "???");
|
|
}
|
|
|
|
if(lpPrimaryDD==NULL) lpPrimaryDD=*lplpdd; // do not override the value set when creating the primary surface!
|
|
bFlippedDC = FALSE; // v02.03.30
|
|
#ifdef AUTOSETCOOPERATIVELEVEL
|
|
OutTrace("Setting cooperative level version=%d hwnd=%x\n", dxw.dwDDVersion, dxw.GethWnd());
|
|
switch(dxw.dwDDVersion){
|
|
case 1: res=(*pSetCooperativeLevel1)(*lplpdd, dxw.GethWnd(), DDSCL_NORMAL); break;
|
|
case 2: res=(*pSetCooperativeLevel2)(*lplpdd, dxw.GethWnd(), DDSCL_NORMAL); break;
|
|
case 4: res=(*pSetCooperativeLevel4)(*lplpdd, dxw.GethWnd(), DDSCL_NORMAL); break;
|
|
case 7: res=(*pSetCooperativeLevel7)(*lplpdd, dxw.GethWnd(), DDSCL_NORMAL); break;
|
|
}
|
|
if(res) OutTraceE("SetCooperativeLevel ERROR: err=%x(%s)\n", res, ExplainDDError(res));
|
|
#endif
|
|
return DD_OK;
|
|
}
|
|
|
|
HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *lpguid,
|
|
LPDIRECTDRAW FAR *lplpdd, REFIID iid, IUnknown FAR *pu)
|
|
{
|
|
HRESULT res;
|
|
GUID FAR *lpPrivGuid = lpguid;
|
|
|
|
OutTraceDDRAW("DirectDrawCreateEx: guid=%x(%s) refiid=%x\n", lpguid, ExplainGUID(lpguid), iid);
|
|
|
|
// v2.1.70: auto-hooking (just in case...)
|
|
if(!pDirectDrawCreateEx){ // not hooked yet....
|
|
HINSTANCE hinst;
|
|
hinst = (*pLoadLibraryA)("ddraw.dll");
|
|
if(!hinst){
|
|
OutTraceE("LoadLibrary ddraw.dll ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
}
|
|
pDirectDrawCreateEx =
|
|
(DirectDrawCreateEx_Type)GetProcAddress(hinst, "DirectDrawCreateEx");
|
|
if(pDirectDrawCreateEx)
|
|
HookAPI(hinst, "ddraw.dll", pDirectDrawCreateEx, "DirectDrawCreateEx", extDirectDrawCreateEx); // v2.02.52
|
|
else{
|
|
char sMsg[81];
|
|
sprintf_s(sMsg, 80, "DirectDrawCreateEx hook failed: error=%d\n", GetLastError());
|
|
OutTraceDW(sMsg);
|
|
if(IsAssertEnabled) MessageBox(0, sMsg, "Hook", MB_OK | MB_ICONEXCLAMATION);
|
|
return DDERR_GENERIC; // is there a better one?
|
|
}
|
|
}
|
|
|
|
if((dxw.dwFlags3 & FORCESHEL) && (lpguid==NULL)) lpPrivGuid=(GUID FAR *)DDCREATE_EMULATIONONLY;
|
|
|
|
res = (*pDirectDrawCreateEx)(lpPrivGuid, lplpdd, iid, pu);
|
|
if (res){
|
|
OutTraceDW("DirectDrawCreateEx: res=%x(%s)\n",res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
if(dxw.dwFlags3 & COLORFIX) (*((DDRAWI_DIRECTDRAW_INT **)lplpdd))->lpLcl->dwAppHackFlags |= 0x800;
|
|
|
|
dxw.dwDDVersion=7;
|
|
char *mode;
|
|
switch ((DWORD)lpPrivGuid){
|
|
case 0: mode="NULL"; break;
|
|
case DDCREATE_HARDWAREONLY: mode="DDCREATE_HARDWAREONLY"; break;
|
|
case DDCREATE_EMULATIONONLY: mode="DDCREATE_EMULATIONONLY"; break;
|
|
default:
|
|
switch (*(DWORD *)lpguid){
|
|
case 0x6C14DB80: dxw.dwDDVersion=1; mode="IID_IDirectDraw"; break;
|
|
case 0xB3A6F3E0: dxw.dwDDVersion=2; mode="IID_IDirectDraw2"; break;
|
|
case 0x618f8ad4: dxw.dwDDVersion=3; mode="IID_IDirectDraw3"; break;
|
|
case 0x9c59509a: dxw.dwDDVersion=4; mode="IID_IDirectDraw4"; break;
|
|
case 0x15e65ec0: dxw.dwDDVersion=7; mode="IID_IDirectDraw7"; break;
|
|
default: mode="unknown"; break;
|
|
}
|
|
break;
|
|
}
|
|
OutTraceDDRAW("DirectDrawCreateEx: lpdd=%x guid=%s DDVersion=%d\n", *lplpdd, mode, dxw.dwDDVersion);
|
|
|
|
HookDDSession(lplpdd, dxw.dwDDVersion);
|
|
|
|
if(IsDebug){
|
|
DDCAPS DriverCaps, EmulCaps;
|
|
memset(&DriverCaps, 0, sizeof(DriverCaps));
|
|
DriverCaps.dwSize=sizeof(DriverCaps);
|
|
memset(&EmulCaps, 0, sizeof(EmulCaps));
|
|
EmulCaps.dwSize=sizeof(EmulCaps);
|
|
(LPDIRECTDRAW)(*lplpdd)->GetCaps(&DriverCaps, &EmulCaps);
|
|
//OutTrace("DirectDrawCreate: drivercaps=%x(%s) emulcaps=%x(%s)\n", DriverCaps.ddsCaps, "???", EmulCaps.ddsCaps, "???");
|
|
}
|
|
|
|
if(lpPrimaryDD==NULL) lpPrimaryDD=*lplpdd; // do not override the value set when creating the primary surface!
|
|
bFlippedDC = FALSE; // v02.03.30: fix for Powerslide
|
|
return DD_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI extInitialize(int dxversion, Initialize_Type pInitialize, LPDIRECTDRAW lpdd, GUID FAR *lpguid)
|
|
{
|
|
HRESULT res;
|
|
GUID FAR *lpPrivGuid = lpguid;
|
|
|
|
OutTraceDDRAW("Initialize(%d): lpdd=%x guid=%x(%s)\n", dxversion, lpdd, lpguid, ExplainGUID(lpguid));
|
|
|
|
if((dxw.dwFlags3 & FORCESHEL) && (lpguid==NULL)) lpPrivGuid=(GUID FAR *)DDCREATE_EMULATIONONLY;
|
|
|
|
res=(*pInitialize)(lpdd, lpPrivGuid);
|
|
|
|
if(res == DDERR_ALREADYINITIALIZED) {
|
|
OutTrace("Initialize: SKIP DDERR_ALREADYINITIALIZED error\n");
|
|
res=DD_OK; // v2.03.18: this error could be caused by the CoCreateInstance implementation
|
|
}
|
|
if(dxw.dwFlags3 & COLORFIX) (((DDRAWI_DIRECTDRAW_INT *)lpdd))->lpLcl->dwAppHackFlags |= 0x800;
|
|
if(res) OutTraceE("Initialize ERROR: res=%x(%s)\n", res, ExplainDDError(res));
|
|
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extInitialize1(LPDIRECTDRAW lpdd, GUID FAR *lpguid)
|
|
{ return extInitialize(1, pInitialize1, lpdd, lpguid); }
|
|
HRESULT WINAPI extInitialize2(LPDIRECTDRAW lpdd, GUID FAR *lpguid)
|
|
{ return extInitialize(2, pInitialize2, lpdd, lpguid); }
|
|
HRESULT WINAPI extInitialize3(LPDIRECTDRAW lpdd, GUID FAR *lpguid)
|
|
{ return extInitialize(3, pInitialize3, lpdd, lpguid); }
|
|
HRESULT WINAPI extInitialize4(LPDIRECTDRAW lpdd, GUID FAR *lpguid)
|
|
{ return extInitialize(4, pInitialize4, lpdd, lpguid); }
|
|
HRESULT WINAPI extInitialize7(LPDIRECTDRAW lpdd, GUID FAR *lpguid)
|
|
{ return extInitialize(7, pInitialize7, lpdd, lpguid); }
|
|
|
|
static HRESULT WINAPI extRestoreDisplayMode(int dxversion, RestoreDisplayMode_Type pRestoreDisplayMode, LPDIRECTDRAW lpdd)
|
|
{
|
|
OutTraceDW("RestoreDisplayMode(%d): lpdd=%x\n", dxversion, lpdd);
|
|
if(dxw.IsEmulated){
|
|
OutTraceDW("RestoreDisplayMode: BYPASS\n");
|
|
return DD_OK;
|
|
}
|
|
return (*pRestoreDisplayMode)(lpdd);
|
|
}
|
|
|
|
HRESULT WINAPI extRestoreDisplayMode1(LPDIRECTDRAW lpdd)
|
|
{ return extRestoreDisplayMode(1, pRestoreDisplayMode1, lpdd); }
|
|
HRESULT WINAPI extRestoreDisplayMode2(LPDIRECTDRAW lpdd)
|
|
{ return extRestoreDisplayMode(2, pRestoreDisplayMode2, lpdd); }
|
|
HRESULT WINAPI extRestoreDisplayMode3(LPDIRECTDRAW lpdd)
|
|
{ return extRestoreDisplayMode(3, pRestoreDisplayMode3, lpdd); }
|
|
HRESULT WINAPI extRestoreDisplayMode4(LPDIRECTDRAW lpdd)
|
|
{ return extRestoreDisplayMode(4, pRestoreDisplayMode4, lpdd); }
|
|
HRESULT WINAPI extRestoreDisplayMode7(LPDIRECTDRAW lpdd)
|
|
{ return extRestoreDisplayMode(7, pRestoreDisplayMode7, lpdd); }
|
|
|
|
HRESULT WINAPI extGetScanLine(int dxversion, GetScanLine_Type pGetScanLine, LPDIRECTDRAW lpdd, LPDWORD lpdwScanLine)
|
|
{
|
|
HRESULT res;
|
|
res = pGetScanLine(lpdd, lpdwScanLine);
|
|
OutTraceB("GetScanLine(%d): lpdd=%x res=%x line=%d\n", dxversion, lpdd, res, *lpdwScanLine);
|
|
|
|
if(!res && dxw.Windowize && dxw.dwRealScreenHeight){
|
|
*lpdwScanLine = (*lpdwScanLine * dxw.GetScreenHeight()) / dxw.dwRealScreenHeight;
|
|
OutTraceB("GetScanLine(%d): FIXED line=%d\n", *lpdwScanLine);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extGetScanLine1(LPDIRECTDRAW lpdd, LPDWORD lpdwScanLine)
|
|
{ return extGetScanLine(1, pGetScanLine1, lpdd, lpdwScanLine); }
|
|
HRESULT WINAPI extGetScanLine2(LPDIRECTDRAW lpdd, LPDWORD lpdwScanLine)
|
|
{ return extGetScanLine(2, pGetScanLine2, lpdd, lpdwScanLine); }
|
|
HRESULT WINAPI extGetScanLine3(LPDIRECTDRAW lpdd, LPDWORD lpdwScanLine)
|
|
{ return extGetScanLine(3, pGetScanLine3, lpdd, lpdwScanLine); }
|
|
HRESULT WINAPI extGetScanLine4(LPDIRECTDRAW lpdd, LPDWORD lpdwScanLine)
|
|
{ return extGetScanLine(4, pGetScanLine4, lpdd, lpdwScanLine); }
|
|
HRESULT WINAPI extGetScanLine7(LPDIRECTDRAW lpdd, LPDWORD lpdwScanLine)
|
|
{ return extGetScanLine(7, pGetScanLine7, lpdd, lpdwScanLine); }
|
|
|
|
HRESULT WINAPI extQueryInterfaceD1(void *lpdd, REFIID riid, LPVOID *obp)
|
|
{ return extQueryInterfaceDX(1, pQueryInterfaceD1, lpdd, riid, obp); }
|
|
HRESULT WINAPI extQueryInterfaceD2(void *lpdd, REFIID riid, LPVOID *obp)
|
|
{ return extQueryInterfaceDX(2, pQueryInterfaceD2, lpdd, riid, obp); }
|
|
HRESULT WINAPI extQueryInterfaceD3(void *lpdd, REFIID riid, LPVOID *obp)
|
|
{ return extQueryInterfaceDX(3, pQueryInterfaceD3, lpdd, riid, obp); }
|
|
HRESULT WINAPI extQueryInterfaceD4(void *lpdd, REFIID riid, LPVOID *obp)
|
|
{ return extQueryInterfaceDX(4, pQueryInterfaceD4, lpdd, riid, obp); }
|
|
HRESULT WINAPI extQueryInterfaceD7(void *lpdd, REFIID riid, LPVOID *obp)
|
|
{ return extQueryInterfaceDX(7, pQueryInterfaceD7, lpdd, riid, obp); }
|
|
|
|
HRESULT WINAPI extQueryInterfaceS1(void *lpdds, REFIID riid, LPVOID *obp)
|
|
{ return extQueryInterfaceDX(1, pQueryInterfaceS1, lpdds, riid, obp); }
|
|
HRESULT WINAPI extQueryInterfaceS2(void *lpdds, REFIID riid, LPVOID *obp)
|
|
{ return extQueryInterfaceDX(2, pQueryInterfaceS2, lpdds, riid, obp); }
|
|
HRESULT WINAPI extQueryInterfaceS3(void *lpdds, REFIID riid, LPVOID *obp)
|
|
{ return extQueryInterfaceDX(3, pQueryInterfaceS3, lpdds, riid, obp); }
|
|
HRESULT WINAPI extQueryInterfaceS4(void *lpdds, REFIID riid, LPVOID *obp)
|
|
{ return extQueryInterfaceDX(4, pQueryInterfaceS4, lpdds, riid, obp); }
|
|
HRESULT WINAPI extQueryInterfaceS7(void *lpdds, REFIID riid, LPVOID *obp)
|
|
{ return extQueryInterfaceDX(7, pQueryInterfaceS7, lpdds, riid, obp); }
|
|
|
|
HRESULT WINAPI extSetDisplayMode(int dxversion, LPDIRECTDRAW lpdd,
|
|
DWORD dwwidth, DWORD dwheight, DWORD dwbpp, DWORD dwrefreshrate, DWORD dwflags)
|
|
{
|
|
DDSURFACEDESC2 ddsd;
|
|
HRESULT res = 0;
|
|
|
|
if(IsTraceDDRAW){
|
|
char sInfo[81];
|
|
strcpy(sInfo, "");
|
|
if (dxversion>=4) sprintf(sInfo, " dwRefresh=%i dwFlags=%x", dwrefreshrate, dwflags);
|
|
OutTrace("SetDisplayMode(%d): dwWidth=%i dwHeight=%i dwBPP=%i%s\n",
|
|
dxversion, dwwidth, dwheight, dwbpp, sInfo);
|
|
}
|
|
|
|
// binkplayer fix
|
|
if((int)dwwidth < 0) dwwidth = dxw.GetScreenWidth();
|
|
if((int)dwheight < 0) dwheight = dxw.GetScreenHeight();
|
|
|
|
// v2.03.90: add LOCKCOLORDEPTH, easiest way to manage "Ahlgrens bisplet"!
|
|
if(dxw.dwFlags7 & LOCKCOLORDEPTH){
|
|
OutTraceDW("SetDisplayMode: LOCKCOLORDEPTH bpp=%d->%d\n", dwbpp, dxw.ActualPixelFormat.dwRGBBitCount);
|
|
dwbpp = dxw.ActualPixelFormat.dwRGBBitCount;
|
|
}
|
|
|
|
dxw.SetScreenSize(dwwidth, dwheight);
|
|
GetHookInfo()->Height=(short)dxw.GetScreenHeight();
|
|
GetHookInfo()->Width=(short)dxw.GetScreenWidth();
|
|
GetHookInfo()->ColorDepth=(short)dwbpp;
|
|
if(dxw.Windowize) AdjustWindowFrame(dxw.GethWnd(), dwwidth, dwheight);
|
|
|
|
if(dxw.dwFlags1 & EMULATESURFACE){
|
|
// in EMULATESURFACE mode, let SetPixFmt decide upon the PixelFormat
|
|
dxw.VirtualPixelFormat.dwRGBBitCount = dwbpp;
|
|
memset(&ddsd, 0, sizeof(ddsd));
|
|
ddsd.dwSize=sizeof(ddsd);
|
|
SetPixFmt(&ddsd);
|
|
SetBltTransformations(dxversion);
|
|
if(dxw.Windowize) {
|
|
OutTraceDW("SetDisplayMode: mode=EMULATE %s ret=OK\n", DumpPixelFormat(&ddsd));
|
|
SetVSyncDelays(dxversion, lpdd);
|
|
return DD_OK;
|
|
}
|
|
}
|
|
else{
|
|
OutTraceDW("SetDisplayMode: mode=STANDARD BPP=%d\n", dwbpp);
|
|
dxw.VirtualPixelFormat.dwRGBBitCount = dwbpp;
|
|
dxw.ActualPixelFormat.dwRGBBitCount = dwbpp;
|
|
}
|
|
|
|
ZeroMemory(&ddsd, sizeof(ddsd));
|
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_REFRESHRATE;
|
|
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
|
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
|
switch(dxversion){
|
|
default:
|
|
case 1: ddsd.dwSize=sizeof(LPDDSURFACEDESC); res=(*pGetDisplayMode1)(lpdd, (LPDDSURFACEDESC)&ddsd); break;
|
|
case 2: ddsd.dwSize=sizeof(LPDDSURFACEDESC); res=(*pGetDisplayMode2)(lpdd, (LPDDSURFACEDESC)&ddsd); break;
|
|
case 3: ddsd.dwSize=sizeof(LPDDSURFACEDESC); res=(*pGetDisplayMode3)(lpdd, (LPDDSURFACEDESC)&ddsd); break;
|
|
case 4: ddsd.dwSize=sizeof(LPDDSURFACEDESC2); res=(*pGetDisplayMode4)(lpdd, &ddsd); break;
|
|
case 7: ddsd.dwSize=sizeof(LPDDSURFACEDESC2); res=(*pGetDisplayMode7)(lpdd, &ddsd); break;
|
|
}
|
|
|
|
if(res){
|
|
OutTraceE("SetDisplayMode: GetDisplayMode err=%x(%s)\n", res, ExplainDDError(res));
|
|
// fix for Win10 platform returning DDERR_INVALIDPARAMS
|
|
RECT desktop;
|
|
ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
|
|
(*pGetClientRect)((*pGetDesktopWindow)(), &desktop);
|
|
ddsd.dwWidth = desktop.right;
|
|
ddsd.dwHeight = desktop.bottom;
|
|
}
|
|
|
|
OutTraceB("SetDisplayMode: detected screen size=(%dx%d)\n", ddsd.dwWidth, ddsd.dwHeight);
|
|
|
|
if(dxw.Windowize){
|
|
if(!IsChangeDisplaySettingsHotPatched){
|
|
dwwidth = ddsd.dwWidth;
|
|
dwheight = ddsd.dwHeight;
|
|
}
|
|
OutTraceDW("SetDisplayMode: fixing colordepth current=%d required=%d size=(%dx%d)\n",
|
|
ddsd.ddpfPixelFormat.dwRGBBitCount, dwbpp, dwwidth, dwheight);
|
|
}
|
|
|
|
if(dxw.dwFlags1 & EMULATESURFACE){
|
|
dwbpp = ddsd.ddpfPixelFormat.dwRGBBitCount;
|
|
}
|
|
|
|
switch(dxversion){
|
|
default:
|
|
case 1: res=(*pSetDisplayMode1)(lpdd, dwwidth, dwheight, dwbpp); break;
|
|
case 2: res=(*pSetDisplayMode2)(lpdd, dwwidth, dwheight, dwbpp, ddsd.dwRefreshRate, 0); break;
|
|
case 3: res=(*pSetDisplayMode3)(lpdd, dwwidth, dwheight, dwbpp, ddsd.dwRefreshRate, 0); break;
|
|
case 4: res=(*pSetDisplayMode4)(lpdd, dwwidth, dwheight, dwbpp, ddsd.dwRefreshRate, 0); break;
|
|
case 7: res=(*pSetDisplayMode7)(lpdd, dwwidth, dwheight, dwbpp, ddsd.dwRefreshRate, 0); break;
|
|
}
|
|
if(res) OutTraceE("SetDisplayMode: error=%x(%s)\n", res, ExplainDDError(res));
|
|
|
|
SetVSyncDelays(dxversion, lpdd);
|
|
|
|
// set a default palette ???
|
|
if(dxw.VirtualPixelFormat.dwRGBBitCount == 8) mySetPalette(0, 256, DefaultSystemPalette);
|
|
|
|
if(dxw.bAutoScale) dxw.AutoScale();
|
|
|
|
return DD_OK;
|
|
}
|
|
|
|
HRESULT WINAPI extSetDisplayMode1(LPDIRECTDRAW lpdd, DWORD dwwidth, DWORD dwheight, DWORD dwbpp)
|
|
{ return extSetDisplayMode(1, lpdd, dwwidth, dwheight, dwbpp, 0, 0); }
|
|
HRESULT WINAPI extSetDisplayMode2(LPDIRECTDRAW lpdd, DWORD dwwidth, DWORD dwheight, DWORD dwbpp, DWORD dwrefreshrate, DWORD dwflags)
|
|
{ return extSetDisplayMode(2, lpdd, dwwidth, dwheight, dwbpp, dwrefreshrate, dwflags); }
|
|
HRESULT WINAPI extSetDisplayMode3(LPDIRECTDRAW lpdd, DWORD dwwidth, DWORD dwheight, DWORD dwbpp, DWORD dwrefreshrate, DWORD dwflags)
|
|
{ return extSetDisplayMode(3, lpdd, dwwidth, dwheight, dwbpp, dwrefreshrate, dwflags); }
|
|
HRESULT WINAPI extSetDisplayMode4(LPDIRECTDRAW lpdd, DWORD dwwidth, DWORD dwheight, DWORD dwbpp, DWORD dwrefreshrate, DWORD dwflags)
|
|
{ return extSetDisplayMode(4, lpdd, dwwidth, dwheight, dwbpp, dwrefreshrate, dwflags); }
|
|
HRESULT WINAPI extSetDisplayMode7(LPDIRECTDRAW lpdd, DWORD dwwidth, DWORD dwheight, DWORD dwbpp, DWORD dwrefreshrate, DWORD dwflags)
|
|
{ return extSetDisplayMode(7, lpdd, dwwidth, dwheight, dwbpp, dwrefreshrate, dwflags);}
|
|
|
|
HRESULT WINAPI extGetDisplayMode(int dxversion, GetDisplayMode_Type pGetDisplayMode, LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd)
|
|
{
|
|
OutTraceDDRAW("GetDisplayMode(D%d): lpdd=%x lpddsd=%x\n", dxversion, lpdd, lpddsd);
|
|
|
|
(*pGetDisplayMode)(lpdd, lpddsd);
|
|
if(dxw.dwFlags1 & EMULATESURFACE) {
|
|
GetPixFmt((LPDDSURFACEDESC2)lpddsd);
|
|
if(!lpddsd->ddpfPixelFormat.dwFlags) SetPixFmt((LPDDSURFACEDESC2)lpddsd);
|
|
}
|
|
|
|
dxw.dwRealScreenWidth = lpddsd->dwWidth;
|
|
dxw.dwRealScreenHeight = lpddsd->dwHeight;
|
|
if(dxw.Windowize){
|
|
lpddsd->dwWidth = dxw.GetScreenWidth();
|
|
lpddsd->dwHeight = dxw.GetScreenHeight();
|
|
}
|
|
|
|
// v2.1.96: fake screen color depth
|
|
// v2.03.96: moved out from dxw.Windowize condition
|
|
if((dxw.dwFlags2 & (INIT8BPP|INIT16BPP)) || (dxw.dwFlags7 & (INIT24BPP|INIT32BPP))){ // v2.02.32 fix
|
|
if(dxw.dwFlags2 & INIT8BPP) FixPixelFormat(8, &lpddsd->ddpfPixelFormat);
|
|
if(dxw.dwFlags2 & INIT16BPP) FixPixelFormat(16, &lpddsd->ddpfPixelFormat);
|
|
if(dxw.dwFlags7 & INIT24BPP) FixPixelFormat(24, &lpddsd->ddpfPixelFormat);
|
|
if(dxw.dwFlags7 & INIT32BPP) FixPixelFormat(32, &lpddsd->ddpfPixelFormat);
|
|
OutTraceDW("GetDisplayMode: fix RGBBitCount=%d\n", lpddsd->ddpfPixelFormat.dwRGBBitCount);
|
|
}
|
|
|
|
//OutTraceDW("GetDisplayMode: returning WxH=(%dx%d) PixelFormat Flags=%x(%s) RGBBitCount=%d RGBAmask=(%x,%x,%x,%x) Caps=%x(%s)\n",
|
|
// lpddsd->dwWidth, lpddsd->dwHeight,
|
|
// lpddsd->ddpfPixelFormat.dwFlags, ExplainPixelFormatFlags(lpddsd->ddpfPixelFormat.dwFlags),
|
|
// lpddsd->ddpfPixelFormat.dwRGBBitCount,
|
|
// lpddsd->ddpfPixelFormat.dwRBitMask, lpddsd->ddpfPixelFormat.dwGBitMask, lpddsd->ddpfPixelFormat.dwBBitMask,
|
|
// lpddsd->ddpfPixelFormat.dwRGBAlphaBitMask,
|
|
// lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps));
|
|
|
|
OutTraceDDRAW("GetDisplayMode: returning size=(%dx%d) %s\n", lpddsd->dwWidth, lpddsd->dwHeight, DumpPixelFormat((LPDDSURFACEDESC2)lpddsd));
|
|
|
|
return DD_OK;
|
|
}
|
|
|
|
HRESULT WINAPI extGetDisplayMode1(LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd)
|
|
{ return extGetDisplayMode(1, pGetDisplayMode1, lpdd, lpddsd); }
|
|
HRESULT WINAPI extGetDisplayMode2(LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd)
|
|
{ return extGetDisplayMode(2, pGetDisplayMode2, lpdd, lpddsd); }
|
|
HRESULT WINAPI extGetDisplayMode3(LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd)
|
|
{ return extGetDisplayMode(3, pGetDisplayMode3, lpdd, lpddsd); }
|
|
HRESULT WINAPI extGetDisplayMode4(LPDIRECTDRAW lpdd, LPDDSURFACEDESC2 lpddsd)
|
|
{ return extGetDisplayMode(4, (GetDisplayMode_Type)pGetDisplayMode4, lpdd, (LPDDSURFACEDESC)lpddsd); }
|
|
HRESULT WINAPI extGetDisplayMode7(LPDIRECTDRAW lpdd, LPDDSURFACEDESC2 lpddsd)
|
|
{ return extGetDisplayMode(7, (GetDisplayMode_Type)pGetDisplayMode7, lpdd, (LPDDSURFACEDESC)lpddsd); }
|
|
|
|
static HWND CreateVirtualDesktop(LPRECT TargetPos)
|
|
{
|
|
HWND hDesktopWindow;
|
|
HINSTANCE hinst=NULL;
|
|
|
|
HWND hParent = GetDesktopWindow(); // not hooked yet !
|
|
hDesktopWindow=(*pCreateWindowExA)(0, "Static", "DxWnd Desktop", WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, hParent, NULL, hinst, NULL);
|
|
if(hDesktopWindow){
|
|
(*pMoveWindow)(hDesktopWindow, TargetPos->left, TargetPos->top, TargetPos->right-TargetPos->left, TargetPos->bottom-TargetPos->top, TRUE);
|
|
(*pSetWindowLong)(hDesktopWindow, GWL_STYLE, WS_OVERLAPPEDWINDOW);
|
|
(*pShowWindow)(hDesktopWindow, SW_RESTORE);
|
|
OutTraceDW("created desktop emulation: hwnd=%x\n", hDesktopWindow);
|
|
return hDesktopWindow;
|
|
|
|
}
|
|
else{
|
|
OutTraceE("CreateWindowEx ERROR: err=%d at %d\n", GetLastError(), __LINE__);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
HRESULT WINAPI extSetCooperativeLevel(int dxversion, SetCooperativeLevel_Type pSetCooperativeLevel, LPDIRECTDRAW lpdd, HWND hwnd, DWORD dwflags)
|
|
{
|
|
HRESULT res;
|
|
BOOL bFixFrame = FALSE;
|
|
|
|
OutTraceDDRAW("SetCooperativeLevel(D%d): lpdd=%x hwnd=%x dwFlags=%x(%s)\n",
|
|
dxversion, lpdd, hwnd, dwflags,ExplainCoopFlags(dwflags));
|
|
|
|
// when SetCooperativeLevel is called for the only purpose of setting the FPU policy,
|
|
// just proxy the call. Seen in "G-Darius".
|
|
switch(dwflags){
|
|
case DDSCL_FPUSETUP:
|
|
case DDSCL_FPUPRESERVE:
|
|
res=(*pSetCooperativeLevel)(lpdd, hwnd, dwflags);
|
|
if(res){
|
|
OutTraceE("SetCooperativeLevel: ERROR bypass err=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
return DD_OK;
|
|
break;
|
|
}
|
|
|
|
DDSURFACEDESC2 ddsd;
|
|
switch(dxversion){
|
|
default:
|
|
case 1: ddsd.dwSize=sizeof(DDSURFACEDESC); res=(*pGetDisplayMode1)(lpdd, (LPDDSURFACEDESC)&ddsd); break;
|
|
case 2: ddsd.dwSize=sizeof(DDSURFACEDESC); res=(*pGetDisplayMode2)(lpdd, (LPDDSURFACEDESC)&ddsd); break;
|
|
case 3: ddsd.dwSize=sizeof(DDSURFACEDESC); res=(*pGetDisplayMode3)(lpdd, (LPDDSURFACEDESC)&ddsd); break;
|
|
case 4: ddsd.dwSize=sizeof(DDSURFACEDESC2); res=(*pGetDisplayMode4)(lpdd, &ddsd); break;
|
|
case 7: ddsd.dwSize=sizeof(DDSURFACEDESC2); res=(*pGetDisplayMode7)(lpdd, &ddsd); break;
|
|
}
|
|
if(res){
|
|
OutTraceE("SetCooperativeLevel: GetDisplayMode ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
|
|
OutTraceDW("InitDDScreenParameters: Actual size=(%dx%d)%s\n", ddsd.dwWidth, ddsd.dwHeight, DumpPixelFormat((LPDDSURFACEDESC2)&ddsd));
|
|
dxw.ActualPixelFormat=ddsd.ddpfPixelFormat;
|
|
if(dxw.VirtualPixelFormat.dwRGBBitCount==0) dxw.VirtualPixelFormat=ddsd.ddpfPixelFormat;
|
|
SetBltTransformations(dxversion);
|
|
|
|
if(dxw.Windowize || (dxw.dwFlags7 & NODDEXCLUSIVEMODE)){
|
|
if (dwflags & DDSCL_FULLSCREEN){
|
|
|
|
// v2.04.01: CREATEDESKTOP option for games that despite all efforts don't have
|
|
// a valid main window, so we build one.
|
|
// Fixes (somehow) "Man TT Super Bike".
|
|
if(dxw.dwFlags6 & CREATEDESKTOP){
|
|
static BOOL bDoOnce = TRUE;
|
|
if(bDoOnce){
|
|
RECT desktop = dxw.GetUnmappedScreenRect();
|
|
hwnd = CreateVirtualDesktop(&desktop);
|
|
dxw.SethWnd(hwnd);
|
|
bDoOnce=FALSE;
|
|
}
|
|
}
|
|
|
|
// v2.01.82 fix:
|
|
// WARN: Tomb Raider 4 demo is setting cooperative level against hwnd 0 (desktop)
|
|
// so in this case better use the registered hWnd value. Same as GP500, who uses
|
|
// the desktop window handle.
|
|
// v2.02.31 fix:
|
|
// Hooligans - Storm over Europe wants to set cooperative level NORMAL to hwnd 0
|
|
// that is legitimate, but setting against desktop window gives an error code - so
|
|
// the zero hwnd redirection had to be moved within the FULLSCREEN if case.
|
|
if(dxw.IsRealDesktop(hwnd)){
|
|
OutTraceDW("SetCooperativeLevel: desktop hwnd=%x -> %x\n", hwnd, dxw.GethWnd());
|
|
hwnd=dxw.GethWnd();
|
|
}
|
|
// v2.03.40 fix:
|
|
// WARN: "Reah" creates a main window undetected. Setting a FULLSCREEN cooperative level
|
|
// against it is a good enough proof that this is the real main window!
|
|
if(hwnd != dxw.GethWnd()){
|
|
OutTraceDW("SetCooperativeLevel: setting new main hwnd=%x -> %x\n", dxw.GethWnd(), hwnd);
|
|
dxw.SethWnd(hwnd);
|
|
}
|
|
dxw.SetFullScreen(TRUE);
|
|
// v2.03.41: added suppression of DDSCL_SETDEVICEWINDOW DDSCL_CREATEDEVICEWINDOW DDSCL_SETFOCUSWINDOW used by "PBA Bowling 2"
|
|
dwflags &= ~(DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWMODEX | DDSCL_SETDEVICEWINDOW | DDSCL_CREATEDEVICEWINDOW | DDSCL_SETFOCUSWINDOW);
|
|
dwflags |= DDSCL_NORMAL;
|
|
bFixFrame = TRUE;
|
|
}
|
|
else{
|
|
// v2.03.77: the game "Portugal 1111" calls SetCooperativeLevel with hwnd=0.
|
|
// in such a case, you can get the window size, so better leave the previous
|
|
// FullScreen setting unchanged. This is a wise politic also in case of any
|
|
// sort of GetClientRect error code.
|
|
if(hwnd){
|
|
RECT client;
|
|
BOOL ret;
|
|
ret=(*pGetClientRect)(hwnd, &client);
|
|
// v2.02.11:
|
|
// Non fullscreen cooperative mode means windowed, unless the window occupies the whole desktop area
|
|
if (ret) dxw.SetFullScreen(client.right==dxw.iSizX && client.bottom==dxw.iSizY);
|
|
}
|
|
}
|
|
}
|
|
|
|
res=(*pSetCooperativeLevel)(lpdd, hwnd, dwflags);
|
|
if(res){
|
|
switch(res){
|
|
case DDERR_EXCLUSIVEMODEALREADYSET: // v2.04.15 - "Sid Meier's Alpha Centauri" in non-windowed mode
|
|
OutTraceDW("SetCooperativeLevel: bypass DDERR_EXCLUSIVEMODEALREADYSET\n");
|
|
res = 0;
|
|
break;
|
|
case DDERR_INVALIDPARAMS:
|
|
//hwnd = GetForegroundWindow();
|
|
PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
|
|
Sleep(1000);
|
|
res=(*pSetCooperativeLevel)(lpdd, hwnd, dwflags);
|
|
break;
|
|
}
|
|
if(res){
|
|
OutTraceE("SetCooperativeLevel: ERROR lpdd=%x hwnd=%x Flags=%x err=%x(%s) at %d\n",
|
|
lpdd, hwnd, dwflags, res, ExplainDDError(res), __LINE__);
|
|
}
|
|
}
|
|
|
|
if(bFixFrame){
|
|
AdjustWindowFrame(hwnd, dxw.GetScreenWidth(), dxw.GetScreenHeight());
|
|
if ((dxw.dwFlags1 & FIXWINFRAME) || (dxw.dwFlags9 & FIXTHINFRAME)) dxw.FixWindowFrame(hwnd);
|
|
}
|
|
|
|
GetHookInfo()->IsFullScreen=dxw.IsFullScreen();
|
|
|
|
// WARN: GP500 was setting cooperative level against the desktop! This can be partially
|
|
// intercepted by hooking the GetDesktopWindow() call, but in windowed mode this can't be
|
|
// done, so better repeat the check here.
|
|
|
|
if ((res==DD_OK) && (hwnd!=NULL)){
|
|
if (hwnd==(*pGetDesktopWindow)()){
|
|
OutTraceE("SetCooperativeLevel: attempt to work on desktop window\n");
|
|
}
|
|
else
|
|
dxw.SethWnd(hwnd); // save the good one
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extSetCooperativeLevel1(LPDIRECTDRAW lpdd, HWND hwnd, DWORD dwflags)
|
|
{ return extSetCooperativeLevel(1, pSetCooperativeLevel1, lpdd, hwnd, dwflags); }
|
|
HRESULT WINAPI extSetCooperativeLevel2(LPDIRECTDRAW lpdd, HWND hwnd, DWORD dwflags)
|
|
{ return extSetCooperativeLevel(2, pSetCooperativeLevel2, lpdd, hwnd, dwflags); }
|
|
HRESULT WINAPI extSetCooperativeLevel3(LPDIRECTDRAW lpdd, HWND hwnd, DWORD dwflags)
|
|
{ return extSetCooperativeLevel(3, pSetCooperativeLevel3, lpdd, hwnd, dwflags); }
|
|
HRESULT WINAPI extSetCooperativeLevel4(LPDIRECTDRAW lpdd, HWND hwnd, DWORD dwflags)
|
|
{ return extSetCooperativeLevel(4, pSetCooperativeLevel4, lpdd, hwnd, dwflags); }
|
|
HRESULT WINAPI extSetCooperativeLevel7(LPDIRECTDRAW lpdd, HWND hwnd, DWORD dwflags)
|
|
{ return extSetCooperativeLevel(7, pSetCooperativeLevel7, lpdd, hwnd, dwflags); }
|
|
|
|
void FixSurfaceCapsInner(LPDDSURFACEDESC2 lpddsd, int dxversion)
|
|
{
|
|
// rules of thumb:
|
|
// 1) textures should be left untouched (switching to SYSTEMMEMORY when forcing HEL may even fail!)
|
|
// 1.1) textures with no DDSD_PIXELFORMAT specification should have one when virtual color depth is not equal to real color depth?
|
|
// 2) if a pixel format is specified, if DDSCAPS_SYSTEMMEMORY add DDSCAPS_OFFSCREENPLAY (if pixel formats are different?), otherwise do not touch anything.
|
|
// 3) if the surface is used as a buffer (DDSD_WIDTH set, DDSD_HEIGHT unset) do not touch anything.
|
|
// 4) zbuffer surfaces (DDSCAPS_ZBUFFER set) must have DDSCAPS_SYSTEMMEMORY
|
|
// 5) DDSCAPS_3DDEVICE surfaces should have a defined pixel format
|
|
// 6) in all remaining cases, adjust the pixel format and ensure you have DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN
|
|
|
|
if(!(lpddsd->dwFlags & DDSD_CAPS)) lpddsd->ddsCaps.dwCaps = 0;
|
|
|
|
// DDSCAPS_TEXTURE surfaces must be left untouched, unless you set FORCESHEL: in this case switch VIDEOMEMORY to SYSTEMMEMORY
|
|
if((lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_TEXTURE)){
|
|
if (dxw.dwFlags3 & FORCESHEL) {
|
|
lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
|
|
lpddsd->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
|
}
|
|
if((dxw.dwFlags5 & TEXTUREFORMAT) && !(lpddsd->dwFlags & DDSD_PIXELFORMAT)){
|
|
// TEXTURE: enforce PIXELFORMAT on MEMORY
|
|
lpddsd->dwFlags |= DDSD_PIXELFORMAT;
|
|
GetPixFmt(lpddsd);
|
|
// trytry
|
|
// lpddsd->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; // OFFSCREENPLAIN to set a different pixel format
|
|
}
|
|
if((lpddsd->dwFlags & DDSD_PIXELFORMAT) &&
|
|
(lpddsd->ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
|
|
(dxw.dwFlags7 & CLEARTEXTUREFOURCC)){
|
|
lpddsd->ddpfPixelFormat = dxw.VirtualPixelFormat;
|
|
lpddsd->ddpfPixelFormat.dwFourCC = 0;
|
|
lpddsd->ddpfPixelFormat.dwFlags &= ~DDPF_FOURCC;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if((lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) { // z-buffer surface - set to memory
|
|
if(dxw.dwFlags8 & OFFSCREENZBUFFER) return;
|
|
lpddsd->ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
|
|
if (dxw.dwFlags8 & ALLOWSYSMEMON3DDEV) lpddsd->ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_ZBUFFER;
|
|
return;
|
|
}
|
|
|
|
// this is valid just in case the above block eliminated TEXTURE surfaces....
|
|
if (lpddsd->dwFlags & DDSD_PIXELFORMAT){ // pixel format defined
|
|
// trytry
|
|
//if (lpddsd->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) lpddsd->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; // to allow for pixel format conversion (Quest for Glory 5 - GOG version)
|
|
lpddsd->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
|
|
return;
|
|
}
|
|
|
|
// buffer surface
|
|
if ((lpddsd->dwFlags & (DDSD_WIDTH|DDSD_HEIGHT)) == DDSD_WIDTH) return;
|
|
|
|
// 3DDEVICE no TEXTURE: enforce PIXELFORMAT
|
|
// v2.02.90: added for "Zoo Tycoon" textures
|
|
// v2.03.48 - there are two situations
|
|
// "Arx fatalis" asks for DDSCAPS_3DDEVICE+DDSCAPS_OFFSCREENPLAIN capability and needs no DDSCAPS_SYSTEMMEMORY capability
|
|
// "Bunnies must die" asks for DDSCAPS_3DDEVICE+DDSCAPS_OFFSCREENPLAIN+DDSCAPS_VIDEOMEMORY capability and requires DDSCAPS_SYSTEMMEMORY capability
|
|
// we try to manage them by checking for the DDSCAPS_VIDEOMEMORY capability ...
|
|
if((lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)){
|
|
lpddsd->dwFlags |= DDSD_PIXELFORMAT;
|
|
GetPixFmt(lpddsd);
|
|
if(dxw.dwFlags8 & OFFSCREENZBUFFER) {
|
|
// add OFFSCREENPLAIN to set a different pixel format
|
|
lpddsd->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
|
|
return;
|
|
}
|
|
if(lpddsd->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
|
|
lpddsd->ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE|DDSCAPS_SYSTEMMEMORY); // good for "Bunnies must die", NO "Arx Fatalis"
|
|
else
|
|
lpddsd->ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE); // good for "Arx Fatalis", NO "Bunnies must die"
|
|
return;
|
|
}
|
|
|
|
// default case: adjust pixel format
|
|
OutTraceB("FixSurfaceCaps: suppress DDSCAPS_VIDEOMEMORY case\n");
|
|
lpddsd->dwFlags |= (DDSD_CAPS|DDSD_PIXELFORMAT);
|
|
if(!(dxw.dwFlags8 & OFFSCREENZBUFFER)){
|
|
lpddsd->ddsCaps.dwCaps &= ~(DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); // v2.02.43
|
|
lpddsd->ddsCaps.dwCaps |= (DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN);
|
|
}
|
|
if(!(dxw.dwFlags3 & NOPIXELFORMAT)) GetPixFmt(lpddsd);
|
|
return;
|
|
}
|
|
|
|
void FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd, int dxversion)
|
|
{
|
|
OutTraceDW("FixSurfaceCaps: INPUT Flags=%x(%s) Caps=%x(%s)\n",
|
|
lpddsd->dwFlags, ExplainFlags(lpddsd->dwFlags), lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps));
|
|
|
|
FixSurfaceCapsInner(lpddsd, dxversion);
|
|
|
|
OutTraceDW("FixSurfaceCaps: OUTPUT Flags=%x(%s) Caps=%x(%s)\n",
|
|
lpddsd->dwFlags, ExplainFlags(lpddsd->dwFlags), lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps));
|
|
}
|
|
|
|
HRESULT WINAPI extCreateSurface1(LPDIRECTDRAW lpdd, DDSURFACEDESC *lpddsd, LPDIRECTDRAWSURFACE *lplpdds, void *pu)
|
|
{ return extCreateSurface(1, (CreateSurface_Type)pCreateSurface1, lpdd, (DDSURFACEDESC2 *)lpddsd, lplpdds, pu); }
|
|
HRESULT WINAPI extCreateSurface2(LPDIRECTDRAW lpdd, DDSURFACEDESC *lpddsd, LPDIRECTDRAWSURFACE *lplpdds, void *pu)
|
|
{ return extCreateSurface(2, (CreateSurface_Type)pCreateSurface2, lpdd, (DDSURFACEDESC2 *)lpddsd, lplpdds, pu); }
|
|
HRESULT WINAPI extCreateSurface3(LPDIRECTDRAW lpdd, DDSURFACEDESC *lpddsd, LPDIRECTDRAWSURFACE *lplpdds, void *pu)
|
|
{ return extCreateSurface(3, (CreateSurface_Type)pCreateSurface3, lpdd, (DDSURFACEDESC2 *)lpddsd, lplpdds, pu); }
|
|
HRESULT WINAPI extCreateSurface4(LPDIRECTDRAW lpdd, DDSURFACEDESC2 *lpddsd, LPDIRECTDRAWSURFACE *lplpdds, void *pu)
|
|
{ return extCreateSurface(4, (CreateSurface_Type)pCreateSurface4, lpdd, (DDSURFACEDESC2 *)lpddsd, lplpdds, pu); }
|
|
HRESULT WINAPI extCreateSurface7(LPDIRECTDRAW lpdd, DDSURFACEDESC2 *lpddsd, LPDIRECTDRAWSURFACE *lplpdds, void *pu)
|
|
{ return extCreateSurface(7, (CreateSurface_Type)pCreateSurface7, lpdd, (DDSURFACEDESC2 *)lpddsd, lplpdds, pu); }
|
|
|
|
|
|
HRESULT WINAPI extGetAttachedSurface(int dxversion, GetAttachedSurface_Type pGetAttachedSurface,
|
|
LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS2 lpddsc, LPDIRECTDRAWSURFACE *lplpddas)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsPrim;
|
|
BOOL IsBack;
|
|
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
IsBack=dxwss.IsABackBufferSurface(lpdds);
|
|
if(IsTraceDDRAW){
|
|
char sCaps2[60];
|
|
strcpy(sCaps2, "");
|
|
if(dxversion >= 4) sprintf(sCaps2, " caps2=%x caps3=%x caps4=%x", lpddsc->dwCaps2, lpddsc->dwCaps3, lpddsc->dwCaps4);
|
|
OutTrace("GetAttachedSurface(%d): lpdds=%x%s caps=%x(%s)%s\n",
|
|
dxversion, lpdds, (IsPrim?"(PRIM)":(IsBack ? "(BACK)":"")),
|
|
lpddsc->dwCaps, ExplainDDSCaps(lpddsc->dwCaps), sCaps2);
|
|
}
|
|
|
|
if(dxw.dwFlags1 & EMULATESURFACE){
|
|
|
|
// v2.1.81: fix to make "Silver" working: if the primary surface was created with
|
|
// backbuffercount == 2, the game expects some more surface to be attached to
|
|
// the attached backbuffer. Since there would be no use for it, just return
|
|
// the attached backbuffer itself. Makes Silver working, anyway....
|
|
// beware: "Snowboard Racer" fails if you return an attached surface anyhow! There,
|
|
// the primary surface was created with back buffer count == 1.
|
|
// v2.2.62 fix: a check to implement doublebuffer emulation only in case of DDSCAPS_BACKBUFFER
|
|
// requests. A call to GetAttachedSurface can be made to retrieve DDSCAPS_ZBUFFER surfaces, and in
|
|
// this case the BackBuffer surface can't be returned.
|
|
// v2.03.56.fix1: the double buffer trick for Silver works in generic EMULATESURFACE mode, but the
|
|
// surface is requested also as a DDSCAPS_VIDEOMEMORY one.
|
|
|
|
if (IsBack && (DDSD_Prim.dwBackBufferCount > 1) && (lpddsc->dwCaps & (DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY))){
|
|
*lplpddas = lpdds;
|
|
OutTraceDW("GetAttachedSurface(%d): DOUBLEBUFFER attached to BACK=%x\n", dxversion, lpdds);
|
|
return DD_OK;
|
|
}
|
|
|
|
// on primary surface return the backbuffer surface coming from either an explicit
|
|
// AddAttachedSurface, or a primary complex surface creation otherwise....
|
|
|
|
if(IsPrim && (lpddsc->dwCaps & (DDSCAPS_BACKBUFFER|DDSCAPS_FLIP))) { // v2.02.42 added DDSCAPS_FLIP for Empire Earth
|
|
// in "Tomb Raider III" GOG release, the primary surface is queryed and has no attached
|
|
// backbuffer, but a backbuffer does exist and has to be retrieved by GetBackBufferSurface.
|
|
LPDIRECTDRAWSURFACE lpddsback = dxwss.GetBackBufferSurface();
|
|
if (lpddsback) {
|
|
*lplpddas = lpddsback;
|
|
OutTraceDW("GetAttachedSurface(%d): BACKBUFFER attached=%x\n", dxversion, *lplpddas);
|
|
return DD_OK;
|
|
}
|
|
else {
|
|
*lplpddas = NULL;
|
|
OutTraceDW("GetAttachedSurface(%d): no attached BACKBUFFER\n", dxversion);
|
|
return DDERR_NOTFOUND;
|
|
}
|
|
}
|
|
|
|
if((dxw.dwFlags8 & NOHALDEVICE) && (lpddsc->dwCaps & DDSCAPS_ZBUFFER)){
|
|
// tested with "Grand Prix World": if a ZBUFFER is returned, CreateDevice fails!
|
|
*lplpddas = NULL;
|
|
OutTraceDW("GetAttachedSurface(%d): NOHALDEVICE no attached ZBUFFER\n", dxversion);
|
|
return DDERR_NOTFOUND;
|
|
}
|
|
|
|
// attempt to fix S.C.A.R.S. black screen bug ... failed
|
|
//if(lpddsc->dwCaps == (DDSCAPS_TEXTURE|DDSCAPS_MIPMAP)) lpddsc->dwCaps = DDSCAPS_TEXTURE;
|
|
}
|
|
else {
|
|
// Virtual primary surfaces are created with no DDSCAPS_3DDEVICE caps, so don't look for it ....
|
|
if(IsPrim && (lpddsc->dwCaps & (DDSCAPS_BACKBUFFER|DDSCAPS_FLIP)))
|
|
lpddsc->dwCaps &= ~DDSCAPS_3DDEVICE;
|
|
}
|
|
|
|
// proxy the call...
|
|
|
|
res=(*pGetAttachedSurface)(lpdds, (LPDDSCAPS)lpddsc, lplpddas);
|
|
if(res) {
|
|
// if possible, simulate a backbuffer attached to primary surface
|
|
if (IsPrim && (DDSD_Prim.dwBackBufferCount > 0) && (lpddsc->dwCaps & (DDSCAPS_BACKBUFFER|DDSCAPS_FLIP))){
|
|
LPDIRECTDRAWSURFACE lpBackBuffer;
|
|
lpBackBuffer = dxwss.GetBackBufferSurface();
|
|
if(lpBackBuffer){
|
|
*lplpddas = lpBackBuffer;
|
|
OutTraceDW("GetAttachedSurface(%d): SIMULATE BACKBUF attach to PRIM=%x\n", dxversion, lpdds);
|
|
return DD_OK;
|
|
}
|
|
}
|
|
|
|
// Warning: AVOID simulating a ZBUFFER attach to any surface that has not it really attached
|
|
// otherwise the program steps over but crashes afterwards, as soon as it tries to use the ZBUFFER.
|
|
// Better return the error (most programs overcome the problem) or change caps policy so that the
|
|
// ZBUFFER becomes attached.
|
|
// Ref: "Arx Fatalis", "TOCA Touring Car Championship"
|
|
|
|
OutTraceE("GetAttachedSurface(%d): ERROR res=%x(%s) at %d\n", dxversion, res, ExplainDDError(res), __LINE__);
|
|
}
|
|
else {
|
|
OutTraceDDRAW("GetAttachedSurface(%d): attached=%x\n", dxversion, *lplpddas);
|
|
|
|
if(lpddsc->dwCaps & DDSCAPS_ZBUFFER){
|
|
char *sMode;
|
|
// Martian Gothic and others: if the ZBUFFER is unknown, then you must register virtual capabilities
|
|
// compatible with those of the original surface!
|
|
DWORD dwCaps;
|
|
lpDDZBuffer = *lplpddas;
|
|
dwCaps = dxwss.GetCaps(*lplpddas);
|
|
// v2.04.17 - beware: the caps db is not properly cleaned on surface destruction, so it may happen
|
|
// that you get a fake-known case where the caps are referred to some other surface type.
|
|
// Happened in "Star Treck: Armada" where the ZBUFFER collects an old PRIMARY caps entry.
|
|
if(!dwCaps || !(dwCaps & DDSCAPS_ZBUFFER)){
|
|
dwCaps = dxwss.GetCaps(lpdds);
|
|
if(dwCaps){
|
|
dwCaps &= ~(DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_3DDEVICE|DDSCAPS_COMPLEX);
|
|
dwCaps |= DDSCAPS_ZBUFFER;
|
|
//if(dwCaps & DDSCAPS_VIDEOMEMORY) dwCaps|=DDSCAPS_LOCALVIDMEM;
|
|
dxwss.PushZBufferSurface(*lplpddas, dxversion, dwCaps);
|
|
sMode = "derived";
|
|
}
|
|
else sMode = "unknown";
|
|
}
|
|
else {
|
|
sMode = "known";
|
|
}
|
|
OutTraceDW("GetAttachedSurface(%d): ZBUFFER caps=%x(%s) (%s)\n", dxversion, dwCaps, ExplainDDSCaps(dwCaps), sMode);
|
|
}
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
HRESULT WINAPI extGetAttachedSurface1(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpddsc, LPDIRECTDRAWSURFACE *lplpddas)
|
|
{ return extGetAttachedSurface(1, pGetAttachedSurface1, lpdds, (LPDDSCAPS2)lpddsc, lplpddas); }
|
|
HRESULT WINAPI extGetAttachedSurface2(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpddsc, LPDIRECTDRAWSURFACE *lplpddas)
|
|
{ return extGetAttachedSurface(2, pGetAttachedSurface2, lpdds, (LPDDSCAPS2)lpddsc, lplpddas); }
|
|
HRESULT WINAPI extGetAttachedSurface3(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpddsc, LPDIRECTDRAWSURFACE *lplpddas)
|
|
{ return extGetAttachedSurface(3, pGetAttachedSurface3, lpdds, (LPDDSCAPS2)lpddsc, lplpddas); }
|
|
HRESULT WINAPI extGetAttachedSurface4(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS2 lpddsc, LPDIRECTDRAWSURFACE *lplpddas)
|
|
{ return extGetAttachedSurface(4, pGetAttachedSurface4, lpdds, lpddsc, lplpddas); }
|
|
HRESULT WINAPI extGetAttachedSurface7(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS2 lpddsc, LPDIRECTDRAWSURFACE *lplpddas)
|
|
{ return extGetAttachedSurface(7, pGetAttachedSurface7, lpdds, lpddsc, lplpddas); }
|
|
|
|
void BlitError(HRESULT res, LPRECT lps, LPRECT lpd, int line)
|
|
{
|
|
char sInfo[512];
|
|
sprintf(sInfo, "Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), line);
|
|
if (res==DDERR_INVALIDRECT){
|
|
if (lps)
|
|
sprintf(sInfo, "%s src=(%d,%d)-(%d,%d)", sInfo, lps->left, lps->top, lps->right, lps->bottom);
|
|
else
|
|
sprintf(sInfo, "%s src=(NULL)", sInfo);
|
|
if (lpd)
|
|
sprintf(sInfo, "%s dest=(%d,%d)-(%d,%d)", sInfo, lpd->left, lpd->top, lpd->right, lpd->bottom);
|
|
else
|
|
sprintf(sInfo, "%s dest=(NULL)", sInfo);
|
|
}
|
|
strcat(sInfo, "\n");
|
|
OutTrace(sInfo);
|
|
return;
|
|
}
|
|
|
|
void BlitTrace(char *label, LPRECT lps, LPRECT lpd, int line)
|
|
{
|
|
char sInfo[512];
|
|
sprintf(sInfo, "[%s]", label);
|
|
if (lps)
|
|
sprintf(sInfo, "%s src=(%d,%d)-(%d,%d)", sInfo, lps->left, lps->top, lps->right, lps->bottom);
|
|
else
|
|
sprintf(sInfo, "%s src=(NULL)", sInfo);
|
|
if (lpd)
|
|
sprintf(sInfo, "%s dest=(%d,%d)-(%d,%d)", sInfo, lpd->left, lpd->top, lpd->right, lpd->bottom);
|
|
else
|
|
sprintf(sInfo, "%s dest=(NULL)", sInfo);
|
|
sprintf(sInfo, "%s at %d\n", sInfo, line);
|
|
OutTrace(sInfo);
|
|
return;
|
|
}
|
|
|
|
HRESULT WINAPI PrimaryBlt(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, LPDDBLTFX lpddbltfx)
|
|
{
|
|
HRESULT res;
|
|
res = (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect, GetBltWaitFlags(DDBLT_WAIT), lpddbltfx);
|
|
if(res == DDERR_SURFACELOST) {
|
|
if(lpdds->IsLost()) {
|
|
OutTraceDW("RECOVERY of lost surface lpdds=%x\n", lpdds);
|
|
lpdds->Restore();
|
|
if(res) {
|
|
OutTraceE("PrimaryBlt: Restore ERROR lpdds=%x err=%x(%s) at %d\n", lpdds, res, ExplainDDError(res), __LINE__);
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI PrimaryFastBlt(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, LPDDBLTFX lpddbltfx)
|
|
{
|
|
HRESULT res;
|
|
RECT client;
|
|
int iXOffset, iYOffset; // offsets to center surface area to window
|
|
(*pGetClientRect)(dxw.GethWnd(), &client);
|
|
iXOffset = (client.right - dxw.GetScreenWidth()) >> 1;
|
|
iYOffset = (client.bottom - dxw.GetScreenHeight()) >> 1;
|
|
if(dxw.dwFlags3 & FORCECLIPPER){
|
|
RECT destrect;
|
|
destrect.left = iXOffset + lpdestrect->left;
|
|
destrect.right = iXOffset + lpdestrect->right;
|
|
destrect.top = iYOffset + lpdestrect->top;
|
|
destrect.bottom = iYOffset + lpdestrect->bottom;
|
|
res = (*pBlt)(lpdds, &destrect, lpddssrc, lpsrcrect, GetBltWaitFlags(DDBLT_WAIT), 0);
|
|
}
|
|
else {
|
|
BltFast_Type pBltFast;
|
|
switch(dxversion){
|
|
case 1: pBltFast=pBltFast1; break;
|
|
case 2: pBltFast=pBltFast2; break;
|
|
case 3: pBltFast=pBltFast3; break;
|
|
case 4: pBltFast=pBltFast4; break;
|
|
case 7: pBltFast=pBltFast7; break;
|
|
}
|
|
res= (*pBltFast)(lpdds, iXOffset + lpdestrect->left, iYOffset + lpdestrect->top, lpddssrc, lpsrcrect, GetFlipWaitFlags(DDFLIP_WAIT));
|
|
}
|
|
if(res == DDERR_SURFACELOST) {
|
|
if(lpdds->IsLost()) {
|
|
OutTraceDW("RECOVERY of lost surface lpdds=%x\n", lpdds);
|
|
res = lpdds->Restore();
|
|
if(res) {
|
|
OutTraceE("PrimaryBlt: Restore ERROR lpdds=%x err=%x(%s) at %d\n", lpdds, res, ExplainDDError(res), __LINE__);
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI PrimaryStretchBlt(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, LPDDBLTFX lpddbltfx)
|
|
{
|
|
HRESULT res;
|
|
DDSURFACEDESC2 ddsd;
|
|
RECT TmpRect;
|
|
LPDIRECTDRAWSURFACE lpddsTmp;
|
|
LPDIRECTDRAWSURFACE lpddsBak;
|
|
DDSCAPS caps;
|
|
CreateSurface1_Type pCreateSurface;
|
|
CreateClipper_Type pCreateClipper;
|
|
SetClipper_Type pSetClipper;
|
|
BltFast_Type pBltFast;
|
|
int dwSize;
|
|
static BOOL bUseFastBlt = !(dxw.dwFlags3 & FORCECLIPPER);
|
|
|
|
switch(iBakBufferVersion){
|
|
default:
|
|
case 1: pBltFast=pBltFast1; pCreateSurface=pCreateSurface1; dwSize = sizeof(DDSURFACEDESC); break;
|
|
case 2: pBltFast=pBltFast2; pCreateSurface=(CreateSurface1_Type)pCreateSurface2; dwSize = sizeof(DDSURFACEDESC); break;
|
|
case 3: pBltFast=pBltFast3; pCreateSurface=(CreateSurface1_Type)pCreateSurface3; dwSize = sizeof(DDSURFACEDESC); break;
|
|
case 4: pBltFast=pBltFast4; pCreateSurface=(CreateSurface1_Type)pCreateSurface4; dwSize = sizeof(DDSURFACEDESC2); break;
|
|
case 7: pBltFast=pBltFast7; pCreateSurface=(CreateSurface1_Type)pCreateSurface7; dwSize = sizeof(DDSURFACEDESC2); break;
|
|
}
|
|
caps.dwCaps = DDSCAPS_BACKBUFFER;
|
|
memset(&ddsd, 0, sizeof(ddsd));
|
|
ddsd.dwSize = dwSize;
|
|
if(lpddssrc==NULL){
|
|
// blit from backbuffer
|
|
lpdds->GetAttachedSurface(&caps, &(LPDIRECTDRAWSURFACE)lpddsBak);
|
|
if(lpddsBak == NULL) {
|
|
OutTraceE("PrimaryStretchBlt: skip - lpddsBak=%x at %d\n", lpddsBak, __LINE__);
|
|
return DD_OK; // fake a success ...
|
|
}
|
|
lpddsBak->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
|
|
}
|
|
else{
|
|
// blit from surface
|
|
lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
|
|
}
|
|
TmpRect.left = TmpRect.top = 0;
|
|
TmpRect.bottom = ddsd.dwHeight = lpdestrect->bottom - lpdestrect->top;
|
|
TmpRect.right = ddsd.dwWidth = lpdestrect->right - lpdestrect->left;
|
|
if((TmpRect.bottom==0) || (TmpRect.right==0)) return DD_OK; // avoid blitting to null areas (Fifa 2000 D3D)
|
|
ddsd.dwFlags = (DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS);
|
|
// capabilities must cope with primary / backbuffer surface capabilities to get speedy operations
|
|
ddsd.ddsCaps.dwCaps = dwBackBufferCaps;
|
|
res=(*pCreateSurface)(lpPrimaryDD, (LPDDSURFACEDESC)&ddsd, &lpddsTmp, NULL);
|
|
if(res) {
|
|
OutTraceE("PrimaryStretchBlt: CreateSurface ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
OutTraceB("PrimaryStretchBlt: CreateSurface %s\n", LogSurfaceAttributes(&ddsd, "[Gateway]", __LINE__));
|
|
return res;
|
|
}
|
|
// stretch-blit to target size on OFFSCREENPLAIN temp surface
|
|
res= (*pBlt)(lpddsTmp, &TmpRect, lpddssrc, lpsrcrect, DDBLT_WAIT, 0);
|
|
if(res) {
|
|
OutTraceE("PrimaryStretchBlt: Blt ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
}
|
|
else {
|
|
while(TRUE) {
|
|
if(bUseFastBlt){
|
|
res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, GetFlipWaitFlags(DDBLTFAST_WAIT));
|
|
}
|
|
else{
|
|
res= (*pBlt)(lpdds, lpdestrect, lpddsTmp, &TmpRect, GetBltWaitFlags(DDBLT_WAIT), 0);
|
|
}
|
|
if(res == DDERR_INVALIDRECT){
|
|
OutTraceDW("PrimaryStretchBlt: adding clipper ddversion=%x at %d\n", iDirectDrawVersion, __LINE__);
|
|
bUseFastBlt = FALSE;
|
|
switch(iDirectDrawVersion){
|
|
case 1: pCreateClipper = pCreateClipper1; break;
|
|
case 2: pCreateClipper = pCreateClipper2; break;
|
|
case 3: pCreateClipper = pCreateClipper3; break;
|
|
case 4: pCreateClipper = pCreateClipper4; break;
|
|
case 7: pCreateClipper = pCreateClipper7; break;
|
|
}
|
|
switch(iBakBufferVersion){
|
|
case 1: pSetClipper = pSetClipper1; break;
|
|
case 2: pSetClipper = pSetClipper2; break;
|
|
case 3: pSetClipper = pSetClipper3; break;
|
|
case 4: pSetClipper = pSetClipper4; break;
|
|
case 7: pSetClipper = pSetClipper7; break;
|
|
}
|
|
if(!lpddC){
|
|
res=(*pCreateClipper)(lpPrimaryDD, 0, &lpddC, NULL);
|
|
if(res) OutTraceE("CreateClipper ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
}
|
|
//res=(*pSetHWnd)(lpddC, 0, dxw.GethWnd()); // no good, cliper object could be unhooked yet! "Settlers III" would crash!
|
|
res=lpddC->SetHWnd(0, dxw.GethWnd());
|
|
if(res) OutTraceE("SetHWnd ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
res=(*pSetClipper)(lpdds, lpddC);
|
|
if(res) OutTraceE("SetClipper ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
OutTraceDW("PrimaryStretchBlt: added clipper lpddc=%x at %d\n", lpddC, __LINE__);
|
|
|
|
res= (*pBlt)(lpdds, lpdestrect, lpddsTmp, &TmpRect, GetBltWaitFlags(DDBLT_WAIT), 0);
|
|
}
|
|
if(res) OutTraceE("PrimaryStretchBlt: %s ERROR %x(%s) at %d\n", bUseFastBlt?"BltFast":"Blt", res, ExplainDDError(res), __LINE__);
|
|
if(res == DDERR_SURFACELOST){
|
|
if(lpdds->IsLost()) {
|
|
OutTraceDW("RECOVERY of lost surface lpdds=%x\n", lpdds);
|
|
res = lpdds->Restore();
|
|
if(res) {
|
|
OutTraceE("PrimaryStretchBlt: Restore ERROR lpdds=%x err=%x(%s) at %d\n", lpdds, res, ExplainDDError(res), __LINE__);
|
|
}
|
|
}
|
|
if(lpddsTmp->IsLost()) {
|
|
OutTraceDW("RECOVERY of lost surface lpdds=%x\n", lpddsTmp);
|
|
res = lpddsTmp->Restore();
|
|
if(res) {
|
|
OutTraceE("PrimaryStretchBlt: Restore ERROR lpdds=%x err=%x(%s) at %d\n", lpddsTmp, res, ExplainDDError(res), __LINE__);
|
|
}
|
|
}
|
|
if(!res) {
|
|
OutTraceDW("PrimaryStretchBlt: surface sucessfully recovered, retry\n");
|
|
continue;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
(*pReleaseSMethod(dxversion))(lpddsTmp);
|
|
return res;
|
|
}
|
|
|
|
void *LoadFilter(char *apiname)
|
|
{
|
|
HMODULE filterlib;
|
|
#define MAX_FILE_PATH 512
|
|
char sSourcePath[MAX_FILE_PATH+1];
|
|
char *p;
|
|
DWORD dwAttrib;
|
|
|
|
dwAttrib = GetFileAttributes("dxwnd.dll");
|
|
if (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) return NULL;
|
|
GetModuleFileName(GetModuleHandle("dxwnd"), sSourcePath, MAX_FILE_PATH);
|
|
p=&sSourcePath[strlen(sSourcePath)-strlen("dxwnd.dll")];
|
|
|
|
*p=0;
|
|
SetDllDirectory(sSourcePath);
|
|
|
|
strcpy(p, "filter.dll");
|
|
filterlib=(*pLoadLibraryA)(sSourcePath);
|
|
if(!filterlib) {
|
|
OutTraceDW("DXWND: Load lib=\"%s\" failed err=%d\n", sSourcePath, GetLastError());
|
|
return NULL;
|
|
}
|
|
return (*pGetProcAddress)(filterlib, apiname);
|
|
}
|
|
|
|
HRESULT WINAPI PrimaryBilinearBlt(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, LPDDBLTFX lpddbltfx)
|
|
{
|
|
HRESULT res;
|
|
typedef void (WINAPI *Resize_HQ_Type)( unsigned char*, RECT *, int, unsigned char*, RECT *, int);
|
|
static Resize_HQ_Type pResize_HQ = NULL;
|
|
/* to be implemented .... */
|
|
|
|
DDSURFACEDESC2 ddsd;
|
|
RECT TmpRect, SrcRect;
|
|
LPDIRECTDRAWSURFACE lpddsTmp;
|
|
LPDIRECTDRAWSURFACE lpddsBak;
|
|
LPDIRECTDRAWSURFACE lpddsCopy=NULL;
|
|
DDSCAPS caps;
|
|
BYTE *bSourceBuf, *bDestBuf;
|
|
LONG dwWidth, dwHeight;
|
|
int SrcPitch, DestPitch;
|
|
CreateSurface1_Type pCreateSurface;
|
|
BltFast_Type pBltFast;
|
|
int dwSize;
|
|
|
|
switch(iBakBufferVersion){ // v2.04.03.fx1 fix: must use iBakBufferVersion, not dxversion!
|
|
default:
|
|
case 1: pBltFast=pBltFast1; pCreateSurface=pCreateSurface1; dwSize = sizeof(DDSURFACEDESC); break;
|
|
case 2: pBltFast=pBltFast2; pCreateSurface=(CreateSurface1_Type)pCreateSurface2; dwSize = sizeof(DDSURFACEDESC); break;
|
|
case 3: pBltFast=pBltFast3; pCreateSurface=(CreateSurface1_Type)pCreateSurface3; dwSize = sizeof(DDSURFACEDESC); break;
|
|
case 4: pBltFast=pBltFast4; pCreateSurface=(CreateSurface1_Type)pCreateSurface4; dwSize = sizeof(DDSURFACEDESC2); break;
|
|
case 7: pBltFast=pBltFast7; pCreateSurface=(CreateSurface1_Type)pCreateSurface7; dwSize = sizeof(DDSURFACEDESC2); break;
|
|
}
|
|
|
|
caps.dwCaps = DDSCAPS_BACKBUFFER;
|
|
memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
|
ddsd.dwSize = dwSize;
|
|
if(lpddssrc==NULL){
|
|
// blit from backbuffer
|
|
lpdds->GetAttachedSurface(&caps, &lpddsBak);
|
|
if(lpddsBak) lpddsBak->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
|
|
}
|
|
else{
|
|
// blit from surface
|
|
lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
|
|
}
|
|
|
|
// assign source RECT values anyway....
|
|
if(!lpsrcrect){
|
|
lpsrcrect = &SrcRect;
|
|
lpsrcrect->left = lpsrcrect->top = 0;
|
|
lpsrcrect->right = dxw.GetScreenWidth();
|
|
lpsrcrect->bottom = dxw.GetScreenHeight();
|
|
}
|
|
|
|
dwWidth = lpdestrect->right - lpdestrect->left;
|
|
dwHeight = lpdestrect->bottom - lpdestrect->top;
|
|
TmpRect.left = TmpRect.top = 0;
|
|
TmpRect.bottom = ddsd.dwHeight = dwHeight;
|
|
TmpRect.right = ddsd.dwWidth = dwWidth;
|
|
ddsd.dwFlags = (DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS);
|
|
// capabilities must cope with primary / backbuffer surface capabilities to get speedy operations
|
|
ddsd.ddsCaps.dwCaps = dwBackBufferCaps;
|
|
res=(*pCreateSurface)(lpPrimaryDD, (LPDDSURFACEDESC)&ddsd, &lpddsTmp, NULL);
|
|
if(res) OutTraceE("PrimaryBilinearBlt: CreateSurface ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
|
|
// get informations
|
|
memset(&ddsd,0,dwSize);
|
|
ddsd.dwSize = dwSize;
|
|
ddsd.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
|
|
res=(*pLockMethod(dxversion))(lpddssrc, 0, (LPDDSURFACEDESC)&ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_READONLY, 0);
|
|
if(res) {
|
|
OutTraceE("PrimaryBilinearBlt: Lock ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return DD_OK;
|
|
}
|
|
bSourceBuf = (BYTE *)ddsd.lpSurface;
|
|
SrcPitch = ddsd.lPitch;
|
|
memset(&ddsd,0,dwSize);
|
|
ddsd.dwSize = dwSize;
|
|
ddsd.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
|
|
res=(*pLockMethod(dxversion))(lpddsTmp, 0, (LPDDSURFACEDESC)&ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0);
|
|
if(res) {
|
|
OutTraceE("PrimaryBilinearBlt: Lock ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return DD_OK;
|
|
}
|
|
bDestBuf = (BYTE *)ddsd.lpSurface;
|
|
DestPitch = ddsd.lPitch;
|
|
|
|
// do the filtering
|
|
if(!pResize_HQ) {
|
|
char *filter;
|
|
HMODULE filterlib;
|
|
switch(ddsd.ddpfPixelFormat.dwGBitMask)
|
|
{
|
|
default:
|
|
case 0x00FF00:
|
|
filter = "Resize_HQ_4ch";
|
|
break;
|
|
case 0x0007E0: // RGB565
|
|
filter = "Resize_HQ_2ch565";
|
|
break;
|
|
case 0x0003E0: // RGB555
|
|
filter = "Resize_HQ_2ch555";
|
|
break;
|
|
}
|
|
|
|
filterlib=(*pLoadLibraryA)("filter.dll");
|
|
if(!filterlib) {
|
|
char sMsg[80+1];
|
|
sprintf(sMsg, "DXWND: ERROR can't load lib=\"filter.dll\" err=%x\n", GetLastError());
|
|
OutTraceE(sMsg);
|
|
MessageBox(0, sMsg, "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
|
exit(0);
|
|
}
|
|
pResize_HQ = (Resize_HQ_Type)(*pGetProcAddress)(filterlib, filter);
|
|
if(!pResize_HQ){
|
|
char sMsg[80+1];
|
|
sprintf(sMsg, "DXWND: ERROR can't load name=\"%s\"\n", filter);
|
|
OutTraceE(sMsg);
|
|
MessageBox(0, sMsg, "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
|
exit(0);
|
|
}
|
|
}
|
|
(*pResize_HQ)(bSourceBuf, lpsrcrect, SrcPitch, bDestBuf, lpdestrect, DestPitch);
|
|
|
|
// fast-blit to primary
|
|
(*pUnlockMethod(dxversion))(lpddssrc, NULL);
|
|
(*pUnlockMethod(dxversion))(lpddsTmp, NULL);
|
|
if(dxw.dwFlags3 & FORCECLIPPER) {
|
|
res= (*pBlt)(lpdds, lpdestrect, lpddsTmp, &TmpRect, DDBLT_WAIT, 0);
|
|
if(res) OutTraceE("PrimaryBilinearBlt: Blt ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
}
|
|
else {
|
|
res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, DDBLTFAST_WAIT);
|
|
if(res) OutTraceE("PrimaryBilinearBlt: BltFast ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
}
|
|
(*pReleaseSMethod(dxversion))(lpddsTmp);
|
|
if(lpddsCopy) (*pReleaseSMethod(dxversion))(lpddsCopy);
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI PrimaryNoBlt(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, LPDDBLTFX lpddbltfx)
|
|
{
|
|
return DD_OK;
|
|
}
|
|
|
|
typedef HRESULT (WINAPI *ColorConversion_Type)(int, LPDIRECTDRAWSURFACE, RECT, LPDIRECTDRAWSURFACE *);
|
|
|
|
HRESULT WINAPI ColorConversionEmulated(int dxversion, LPDIRECTDRAWSURFACE lpdds, RECT emurect, LPDIRECTDRAWSURFACE *lpddssource)
|
|
{
|
|
HRESULT res;
|
|
Blt_Type pBlt;
|
|
RECT srcrect, destrect;
|
|
pBlt = pGetBltMethod(dxversion);
|
|
// v2.04.01.fx6: copy emurect since pEmuBlt will alter values!
|
|
srcrect=destrect=emurect;
|
|
res=(*pEmuBlt)(dxversion, pBlt, lpDDSEmu_Back, &destrect, lpdds, &srcrect, DDBLT_WAIT, 0);
|
|
if(res==DDERR_SURFACEBUSY){
|
|
(*pUnlockMethod(dxversion))(lpdds, NULL);
|
|
(*pUnlockMethod(dxversion))(lpDDSEmu_Back, NULL);
|
|
//srcrect=destrect=emurect;
|
|
//res=(*pEmuBlt)(dxversion, pBlt, lpDDSEmu_Back, &destrect, lpdds, &srcrect, DDBLT_WAIT, 0);
|
|
res=DD_OK;
|
|
}
|
|
if(res) {
|
|
BlitError(res, &emurect, &emurect, __LINE__);
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0;
|
|
}
|
|
*lpddssource = lpDDSEmu_Back;
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI ColorConversionGDI(int version, LPDIRECTDRAWSURFACE lpdds, RECT emurect, LPDIRECTDRAWSURFACE *lpddssource)
|
|
{
|
|
// GDICOLORCONV: use GDI capabilities to convert color depth by BitBlt-ting between different hdc
|
|
HRESULT res;
|
|
GetDC_Type pGetDC = pGetDCMethod();
|
|
ReleaseDC_Type pReleaseDC = pReleaseDCMethod();
|
|
do {
|
|
HDC hdc_source, hdc_dest;
|
|
res=(*pGetDC)(lpdds, &hdc_source);
|
|
if(res) {
|
|
OutTraceE("GetDC ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
break;
|
|
}
|
|
res=(*pGetDC)(lpDDSEmu_Back, &hdc_dest);
|
|
if(res) {
|
|
OutTraceE("GetDC ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
break;
|
|
}
|
|
if(!BitBlt(hdc_dest, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight(), hdc_source, 0, 0, SRCCOPY)){
|
|
OutTraceE("BitBlt ERROR: err=%d at %d\n", GetLastError(), __LINE__);
|
|
}
|
|
res=(*pReleaseDC)(lpdds, hdc_source);
|
|
if(res) {
|
|
OutTraceE("ReleaseDC ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
break;
|
|
}
|
|
res=(*pReleaseDC)(lpDDSEmu_Back, hdc_dest);
|
|
if(res) {
|
|
OutTraceE("ReleaseDC ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
break;
|
|
}
|
|
} while(FALSE);
|
|
*lpddssource = lpDDSEmu_Back;
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI ColorConversionDDRAW(int dxversion, LPDIRECTDRAWSURFACE lpdds, RECT emurect, LPDIRECTDRAWSURFACE *lpddssource)
|
|
{
|
|
*lpddssource = lpdds;
|
|
return DD_OK;
|
|
}
|
|
|
|
HRESULT WINAPI extFlip(int dxversion, Flip_Type pFlip, LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, DWORD dwflags)
|
|
{
|
|
BOOL IsPrim;
|
|
HRESULT res;
|
|
DDSURFACEDESC2 ddsd;
|
|
LPDIRECTDRAWSURFACE lpddsTmp;
|
|
LPDIRECTDRAWSURFACE lpDDSBack;
|
|
DWORD dwBltFlags;
|
|
BOOL bEmulatedFlip;
|
|
|
|
bEmulatedFlip = dxw.Windowize || dxw.IsEmulated;
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
OutTraceDDRAW("Flip(%d): %s lpdds=%x%s, src=%x, flags=%x(%s)\n",
|
|
dxversion, bEmulatedFlip?"EMULATED":"GENUINE",
|
|
lpdds, IsPrim?"(PRIM)":"", lpddssrc, dwflags, ExplainFlipFlags(dwflags));
|
|
|
|
Blt_Type pBlt;
|
|
pBlt = pGetBltMethod(dxversion);
|
|
|
|
if (!IsPrim){
|
|
if(lpddssrc){
|
|
res=(*pFlip)(lpdds, lpddssrc, dwflags);
|
|
}
|
|
else{
|
|
LPDIRECTDRAWSURFACE lpddsAttached;
|
|
DDSCAPS ddsc;
|
|
DDSURFACEDESC2 sd;
|
|
|
|
sd.dwSize=Set_dwSize_From_Surface();
|
|
res=lpdds->GetSurfaceDesc((DDSURFACEDESC *)&sd);
|
|
if (res) OutTraceDW("Flip: GetSurfaceDesc res=%x at %d\n",res, __LINE__);
|
|
|
|
// replace these CAPS (good for seven kingdoms II) with same as lpdds surface
|
|
ddsc.dwCaps=sd.ddsCaps.dwCaps;
|
|
|
|
res=lpdds->GetAttachedSurface(&ddsc, &lpddsAttached);
|
|
if(res){
|
|
OutTraceE("Flip: GetAttachedSurface ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
res=sBlt(dxversion, pBlt, "Flip", lpdds, NULL, lpddsAttached, NULL, DDBLT_WAIT, 0, TRUE);
|
|
if(res){
|
|
OutTraceE("Flip: Blt ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
}
|
|
if(res) OutTraceE("Flip: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
|
|
#ifdef HANDLEFLIPPABLE
|
|
if(!bEmulatedFlip){
|
|
dwBltFlags = GetFlipWaitFlags(dwflags);
|
|
res=(*pFlip)(lpdds, lpddssrc, dwBltFlags);
|
|
if(res) OutTraceE("Flip: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
#endif
|
|
|
|
// emulation to primary surface Flip - you can't flip to window surfaces,
|
|
// so you have to replace it with Blt operations.
|
|
// v2.03.98: moved closer to actual video operations to avoid the risk of losing the end of vertical blank period
|
|
// while doing calculations
|
|
//if((dwflags & DDFLIP_WAIT) || (dxw.dwFlags1 & SAVELOAD)) lpPrimaryDD->WaitForVerticalBlank(DDWAITVB_BLOCKEND , 0);
|
|
|
|
lpDDSBack = dxwss.GetBackBufferSurface();
|
|
|
|
// from ddraw.h:
|
|
// On IDirectDrawSurface7 and higher interfaces, the default is DDFLIP_WAIT. If you wish
|
|
// to override the default and use time when the accelerator is busy (as denoted by
|
|
// the DDERR_WASSTILLDRAWING return code) then use DDFLIP_DONOTWAIT.
|
|
|
|
if(dxversion >= 7)
|
|
dwBltFlags = (dwflags & DDFLIP_DONOTWAIT) ? DDBLT_DONOTWAIT : DDBLT_WAIT;
|
|
else
|
|
dwBltFlags = (dwflags & DDFLIP_WAIT) ? DDBLT_WAIT : 0;
|
|
|
|
dwBltFlags = GetBltWaitFlags(dwBltFlags);
|
|
|
|
if(dxw.dwFlags4 & NOFLIPEMULATION){
|
|
HRESULT res2;
|
|
// create a temporary working surface
|
|
memset(&ddsd, 0, sizeof(ddsd));
|
|
ddsd.dwSize = (dxversion <4) ? sizeof(DDSURFACEDESC) : sizeof(DDSURFACEDESC2); // v2.03.60 insidious bug fix !!!
|
|
// v2.02.80: the BackBuffer may not exist? see "HellCopter"
|
|
if(lpDDSBack){
|
|
(*pGetSurfaceDescMethod())((LPDIRECTDRAWSURFACE2)lpDDSBack, &ddsd);
|
|
ddsd.dwFlags &= ~DDSD_PITCH;
|
|
}
|
|
else{
|
|
ddsd.dwFlags = (DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS);
|
|
ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN);
|
|
ddsd.dwHeight = dxw.GetScreenHeight();
|
|
ddsd.dwWidth = dxw.GetScreenWidth();
|
|
}
|
|
// v2.04.09 fix: dxversion replaced with iBakBufferVersion - fixes "Gruntz" crash
|
|
res2=(*pCreateSurfaceMethod(iBakBufferVersion))(lpPrimaryDD, &ddsd, &lpddsTmp, NULL);
|
|
if(res2) {
|
|
OutTraceE("CreateSurface: ERROR %x(%s) at %d\n", res2, ExplainDDError(res2), __LINE__);
|
|
OutTraceE("Size=%d lpPrimaryDD=%x lpDDSBack=%x %s\n",
|
|
ddsd.dwSize, lpPrimaryDD, lpDDSBack, LogSurfaceAttributes(&ddsd, "[FlipBuf]", __LINE__));
|
|
}
|
|
//OutTrace("DEBUG: copied surface size=(%dx%d)\n", ddsd.dwWidth, ddsd.dwHeight);
|
|
// copy front buffer
|
|
if(dxw.dwFlags1 & EMULATESURFACE){
|
|
// in emulated mode, the primary surface is virtual and you can pick it all
|
|
// needed for "Gruntz"
|
|
res2= (*pBlt)(lpddsTmp, NULL, lpdds, NULL, DDBLT_WAIT, NULL);
|
|
if(res2) BlitError(res2, NULL, NULL, __LINE__);
|
|
}
|
|
else {
|
|
// in no-emulated mode, the primary surface is the whole screen, so you have to pick...
|
|
// needed for "Black Thorn"
|
|
RECT clip;
|
|
if(dxw.dwFlags1 & EMULATEBUFFER)
|
|
clip=dxw.GetScreenRect();
|
|
else
|
|
clip=dxw.GetUnmappedScreenRect();
|
|
res2= (*pBlt)(lpddsTmp, NULL, lpdds, &clip, DDBLT_WAIT, NULL);
|
|
if(res2) BlitError(res2, &clip, NULL, __LINE__);
|
|
}
|
|
}
|
|
|
|
if(lpddssrc){
|
|
//res=lpdds->Blt(0, lpddssrc, 0, DDBLT_WAIT, 0);
|
|
res=sBlt(dxversion, pBlt, "Flip", lpdds, NULL, lpddssrc, NULL, dwBltFlags, 0, TRUE);
|
|
}
|
|
else{
|
|
if(!lpDDSBack){
|
|
OutTraceE("Flip: no backbuffer\n");
|
|
return DDERR_INVALIDPARAMS;
|
|
}
|
|
if (dxw.dwFlags2 & BACKBUFATTACH){
|
|
RECT NullArea;
|
|
NullArea.left=NullArea.top=0;
|
|
NullArea.bottom=dxw.GetScreenHeight();
|
|
NullArea.right=dxw.GetScreenWidth();
|
|
res=sBlt(dxversion, pBlt, "Flip", lpdds, NULL, lpDDSBack, &NullArea, dwBltFlags, 0, TRUE);
|
|
}
|
|
else
|
|
res=sBlt(dxversion, pBlt, "Flip", lpdds, NULL, lpDDSBack, NULL, dwBltFlags, 0, TRUE);
|
|
|
|
lpddssrc = lpDDSBack;
|
|
}
|
|
|
|
if(dxw.dwFlags4 & NOFLIPEMULATION){
|
|
HRESULT res2;
|
|
// restore flipped backbuffer and delete temporary surface
|
|
res2= (*pBlt)(lpddssrc, NULL, lpddsTmp, NULL, DDBLT_WAIT, NULL);
|
|
if(res2) OutTraceE("Blt: ERROR %x(%s) at %d\n", res2, ExplainDDError(res2), __LINE__);
|
|
(*pReleaseSMethod(dxversion))(lpddsTmp);
|
|
}
|
|
|
|
if(res) OutTraceE("Flip: Blt ERROR %x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extFlip1(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, DWORD dwflags)
|
|
{ return extFlip(1, pFlip1, lpdds, lpddssrc, dwflags); }
|
|
HRESULT WINAPI extFlip2(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, DWORD dwflags)
|
|
{ return extFlip(2, pFlip2, lpdds, lpddssrc, dwflags); }
|
|
HRESULT WINAPI extFlip3(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, DWORD dwflags)
|
|
{ return extFlip(3, pFlip3, lpdds, lpddssrc, dwflags); }
|
|
HRESULT WINAPI extFlip4(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, DWORD dwflags)
|
|
{ return extFlip(4, pFlip4, lpdds, lpddssrc, dwflags); }
|
|
HRESULT WINAPI extFlip7(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, DWORD dwflags)
|
|
{ return extFlip(7, pFlip7, lpdds, lpddssrc, dwflags); }
|
|
|
|
HRESULT WINAPI extBlt(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
|
|
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx)
|
|
{
|
|
if ((dxw.dwFlags2 & FULLRECTBLT) && dxwss.IsAPrimarySurface(lpdds)){
|
|
lpsrcrect=NULL;
|
|
lpdestrect=NULL;
|
|
}
|
|
|
|
return sBlt(dxversion, pBlt, "Blt", lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx, FALSE);
|
|
}
|
|
|
|
HRESULT WINAPI extBlt1(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx)
|
|
{ return extBlt(1, pBlt1, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); }
|
|
HRESULT WINAPI extBlt2(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx)
|
|
{ return extBlt(2, pBlt2, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); }
|
|
HRESULT WINAPI extBlt3(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx)
|
|
{ return extBlt(3, pBlt3, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); }
|
|
HRESULT WINAPI extBlt4(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx)
|
|
{ return extBlt(4, pBlt4, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); }
|
|
HRESULT WINAPI extBlt7(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx)
|
|
{ return extBlt(7, pBlt7, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); }
|
|
|
|
static HRESULT WINAPI extBltFast(int dxversion, Blt_Type pBlt, BltFast_Type pBltFast,
|
|
LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy,
|
|
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans)
|
|
{
|
|
// BltFast is supported just on screen surfaces, so it has to be replaced
|
|
// by ordinary Blt operation in EMULATESURFACE mode.
|
|
// Mind that screen surface doesn't necessarily mean PRIMARY surfaces!
|
|
|
|
RECT srcrect, destrect;
|
|
DWORD flags = 0;
|
|
DDSURFACEDESC2 ddsd;
|
|
HRESULT ret;
|
|
BOOL ToPrim, FromPrim;
|
|
|
|
ToPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
FromPrim=dxwss.IsAPrimarySurface(lpddssrc);
|
|
|
|
CleanRect(&lpsrcrect,__LINE__);
|
|
|
|
if(IsTraceDDRAW){
|
|
char sRect[81];
|
|
if (lpsrcrect) sprintf(sRect, "(%d,%d)-(%d,%d)", lpsrcrect->left, lpsrcrect->top, lpsrcrect->right, lpsrcrect->bottom);
|
|
else strcpy(sRect, "(NULL)");
|
|
OutTrace("BltFast(%d): dest=%x%s src=%x%s dwTrans=%x(%s) (x,y)=(%d,%d) srcrect=%s\n",
|
|
dxversion, lpdds, ToPrim?"(PRIM)":"", lpddssrc, FromPrim?"(PRIM)":"", dwtrans, ExplainBltFastFlags(dwtrans), dwx, dwy, sRect);
|
|
}
|
|
|
|
// try the actual method first, it may work in some corcumstances....
|
|
// when ret is DDERR_UNSUPPORTED try the emulated path.
|
|
if(!(ToPrim || FromPrim)) {
|
|
if(dxw.dwFlags5 & MESSAGEPUMP) dxw.MessagePump();
|
|
ret = pBltFast(lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans);
|
|
if(ret != DDERR_UNSUPPORTED) {
|
|
if(ret) OutTraceE("BltFast ERROR: res=%x(%s)\n", ret, ExplainDDError(ret));
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
// consistency check ....
|
|
// situation found for instance in "Warlords Battlecry II demo".
|
|
if (lpsrcrect)
|
|
if((lpsrcrect->left >= lpsrcrect->right) || (lpsrcrect->top >= lpsrcrect->bottom)) {
|
|
OutTraceDW("BltFast: ASSERT bad rect at %d\n", __LINE__);
|
|
return 0;
|
|
}
|
|
|
|
flags = 0;
|
|
if(dwtrans & DDBLTFAST_WAIT) flags = DDBLT_WAIT;
|
|
if(dwtrans & DDBLTFAST_DESTCOLORKEY) flags |= DDBLT_KEYDEST;
|
|
if(dwtrans & DDBLTFAST_SRCCOLORKEY) flags |= DDBLT_KEYSRC;
|
|
|
|
if ((dxw.dwFlags2 & FULLRECTBLT) && ToPrim){
|
|
ret = sBlt(dxversion, pBlt, "BltFast", lpdds, NULL, lpddssrc, lpsrcrect, flags, NULL, FALSE);
|
|
if(ret) {
|
|
OutTraceE("BltFast FULLRECBLT res=%x\n", ret);
|
|
}
|
|
else {
|
|
OutTraceDDRAW("BltFast FULLRECBLT res=DD_OK\n");
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
destrect.left = dwx;
|
|
destrect.top = dwy;
|
|
if(lpsrcrect){
|
|
destrect.right = destrect.left + lpsrcrect->right - lpsrcrect->left;
|
|
destrect.bottom = destrect.top + lpsrcrect->bottom - lpsrcrect->top;
|
|
// avoid altering pointed values....
|
|
srcrect=*lpsrcrect;
|
|
ret=sBlt(dxversion, pBlt, "BltFast", lpdds, &destrect, lpddssrc, &srcrect, flags, NULL, FALSE);
|
|
}
|
|
else{
|
|
// does it EVER goes through here? NULL is not a valid rect value for BltFast call....
|
|
// yes, forced in FULLRECTBLT mode!
|
|
// yes, when BltFast on DDBLTFAST_SRCCOLORKEY!! (Pax Corpus)
|
|
if(lpddssrc){
|
|
ddsd.dwSize=Set_dwSize_From_Surface();
|
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
|
|
ret=lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
|
|
if (ret){
|
|
OutTraceE("BltFast: GetSurfaceDesc ERROR %x at %d\n", ret, __LINE__);
|
|
return DD_OK;
|
|
}
|
|
destrect.right = destrect.left + ddsd.dwWidth;
|
|
destrect.bottom = destrect.top + ddsd.dwHeight;
|
|
ret=sBlt(dxversion, pBlt, "BltFast", lpdds, &destrect, lpddssrc, NULL, flags, NULL, FALSE);
|
|
}
|
|
else{
|
|
//ret=sBlt("BltFast", lpdds, NULL, lpddssrc, NULL, flags, NULL, FALSE);
|
|
OutTraceDW("BltFast FAKE res=DD_OK at %d\n", __LINE__);
|
|
ret=DD_OK;
|
|
}
|
|
}
|
|
|
|
if(ret) {
|
|
OutTraceE("BltFast ERROR: res=%x(%s)\n", ret, ExplainDDError(ret));
|
|
}
|
|
else {
|
|
OutTraceDDRAW("BltFast: res=DD_OK\n");
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
HRESULT WINAPI extBltFast1(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans)
|
|
{ return extBltFast(1, pBlt1, pBltFast1, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); }
|
|
HRESULT WINAPI extBltFast2(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans)
|
|
{ return extBltFast(2, pBlt2, pBltFast2, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); }
|
|
HRESULT WINAPI extBltFast3(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans)
|
|
{ return extBltFast(3, pBlt3, pBltFast3, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); }
|
|
HRESULT WINAPI extBltFast4(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans)
|
|
{ return extBltFast(4, pBlt4, pBltFast4, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); }
|
|
HRESULT WINAPI extBltFast7(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans)
|
|
{ return extBltFast(7, pBlt7, pBltFast7, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); }
|
|
|
|
HRESULT WINAPI extWaitForVerticalBlank(WaitForVerticalBlank_Type pWaitForVerticalBlank, LPDIRECTDRAW lpdd, DWORD dwflags, HANDLE hevent)
|
|
{
|
|
// set a global to avoid double calls
|
|
bVSyncDone = TRUE;
|
|
|
|
if(dxw.dwFlags8 & FORCENOVSYNC) return DD_OK;
|
|
|
|
if(dxw.dwFlags1 & SAVELOAD){
|
|
dxw.VSyncWait();
|
|
return DD_OK;
|
|
}
|
|
|
|
if(dxw.dwFlags8 & VSYNCSCANLINE){
|
|
dxw.VSyncWaitLine(((DWORD)dxw.ScanLine * 100) / dxw.GetScreenHeight());
|
|
return DD_OK;
|
|
}
|
|
|
|
return (*pWaitForVerticalBlank)(lpdd, dwflags, hevent);
|
|
}
|
|
|
|
HRESULT WINAPI extWaitForVerticalBlank1(LPDIRECTDRAW lpdd, DWORD dwflags, HANDLE hevent)
|
|
{ return extWaitForVerticalBlank(pWaitForVerticalBlank1, lpdd, dwflags, hevent); }
|
|
HRESULT WINAPI extWaitForVerticalBlank2(LPDIRECTDRAW lpdd, DWORD dwflags, HANDLE hevent)
|
|
{ return extWaitForVerticalBlank(pWaitForVerticalBlank2, lpdd, dwflags, hevent); }
|
|
HRESULT WINAPI extWaitForVerticalBlank3(LPDIRECTDRAW lpdd, DWORD dwflags, HANDLE hevent)
|
|
{ return extWaitForVerticalBlank(pWaitForVerticalBlank3, lpdd, dwflags, hevent); }
|
|
HRESULT WINAPI extWaitForVerticalBlank4(LPDIRECTDRAW lpdd, DWORD dwflags, HANDLE hevent)
|
|
{ return extWaitForVerticalBlank(pWaitForVerticalBlank4, lpdd, dwflags, hevent); }
|
|
HRESULT WINAPI extWaitForVerticalBlank7(LPDIRECTDRAW lpdd, DWORD dwflags, HANDLE hevent)
|
|
{ return extWaitForVerticalBlank(pWaitForVerticalBlank7, lpdd, dwflags, hevent); }
|
|
|
|
#define DDPCAPS_INITIALIZE_LEGACY 0x00000008l
|
|
|
|
HRESULT WINAPI extCreatePalette(int version, CreatePalette_Type pCreatePalette,
|
|
LPDIRECTDRAW lpdd, DWORD dwflags, LPPALETTEENTRY lpddpa, LPDIRECTDRAWPALETTE *lplpddp, IUnknown *pu)
|
|
{
|
|
HRESULT res;
|
|
|
|
OutTraceDDRAW("CreatePalette: lpdd=%x dwFlags=%x(%s)\n", lpdd, dwflags, ExplainCreatePaletteFlags(dwflags));
|
|
if(IsDebug && (dwflags & DDPCAPS_8BIT)) dxw.DumpPalette(256, lpddpa);
|
|
|
|
if(dxw.dwFlags1 & EMULATESURFACE) dwflags &= ~DDPCAPS_PRIMARYSURFACE;
|
|
res = (*pCreatePalette)(lpdd, dwflags, lpddpa, lplpddp, pu);
|
|
if (res) {
|
|
OutTraceE("CreatePalette: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
OutTraceDDRAW("CreatePalette: OK lpddp=%x\n", *lplpddp);
|
|
HookDDPalette(lplpddp);
|
|
return DD_OK;
|
|
}
|
|
|
|
HRESULT WINAPI extCreatePalette1(LPDIRECTDRAW lpdd, DWORD dwflags, LPPALETTEENTRY lpddpa, LPDIRECTDRAWPALETTE *lplpddp, IUnknown *pu)
|
|
{ return extCreatePalette(1, (CreatePalette_Type)pCreatePalette1, lpdd, dwflags, lpddpa, lplpddp, pu); }
|
|
HRESULT WINAPI extCreatePalette2(LPDIRECTDRAW lpdd, DWORD dwflags, LPPALETTEENTRY lpddpa, LPDIRECTDRAWPALETTE *lplpddp, IUnknown *pu)
|
|
{ return extCreatePalette(2, (CreatePalette_Type)pCreatePalette2, lpdd, dwflags, lpddpa, lplpddp, pu); }
|
|
HRESULT WINAPI extCreatePalette3(LPDIRECTDRAW lpdd, DWORD dwflags, LPPALETTEENTRY lpddpa, LPDIRECTDRAWPALETTE *lplpddp, IUnknown *pu)
|
|
{ return extCreatePalette(3, (CreatePalette_Type)pCreatePalette3, lpdd, dwflags, lpddpa, lplpddp, pu); }
|
|
HRESULT WINAPI extCreatePalette4(LPDIRECTDRAW lpdd, DWORD dwflags, LPPALETTEENTRY lpddpa, LPDIRECTDRAWPALETTE *lplpddp, IUnknown *pu)
|
|
{ return extCreatePalette(4, (CreatePalette_Type)pCreatePalette4, lpdd, dwflags, lpddpa, lplpddp, pu); }
|
|
HRESULT WINAPI extCreatePalette7(LPDIRECTDRAW lpdd, DWORD dwflags, LPPALETTEENTRY lpddpa, LPDIRECTDRAWPALETTE *lplpddp, IUnknown *pu)
|
|
{ return extCreatePalette(7, (CreatePalette_Type)pCreatePalette7, lpdd, dwflags, lpddpa, lplpddp, pu); }
|
|
|
|
HRESULT WINAPI extGetPalette(int dxversion, GetPalette_Type pGetPalette, LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp)
|
|
{
|
|
HRESULT res;
|
|
BOOL isPrim, isBack;
|
|
|
|
isPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
isBack=dxwss.IsABackBufferSurface(lpdds);
|
|
OutTraceDDRAW("GetPalette(%d): lpdds=%x%s%s\n", dxversion, lpdds, isPrim?"(PRIM)":"", isBack?"(BACK)":"");
|
|
|
|
res = DD_OK;
|
|
lpdds->AddRef();
|
|
if(lpdds->Release()) res=(*pGetPalette)(lpdds, lplpddp);
|
|
|
|
// v2.03.07: in "Die Hard Trilogy" the backbuffer surface is queryed for the palette
|
|
// v2.03.08: in "Viper Racing" lpDDP is still NULL (how could it be?)
|
|
if((dxw.dwFlags1 & EMULATESURFACE) && (res == DDERR_NOPALETTEATTACHED) && (isPrim||isBack) && lpDDP){
|
|
OutTraceDW("GetPalette: retrieve PRIMARY palette for emulated surface lpDDP=%x\n", lpDDP);
|
|
*lplpddp = lpDDP;
|
|
lpDDP->AddRef();
|
|
iDDPExtraRefCounter++;
|
|
res=DD_OK;
|
|
}
|
|
|
|
if (res) {
|
|
OutTraceE("GetPalette: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
else {
|
|
OutTraceDDRAW("GetPalette: OK lplpddp=%x\n", *lplpddp);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extGetPalette1(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp)
|
|
{ return extGetPalette(1, pGetPalette1, lpdds, lplpddp); }
|
|
HRESULT WINAPI extGetPalette2(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp)
|
|
{ return extGetPalette(2, pGetPalette2, lpdds, lplpddp); }
|
|
HRESULT WINAPI extGetPalette3(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp)
|
|
{ return extGetPalette(3, pGetPalette3, lpdds, lplpddp); }
|
|
HRESULT WINAPI extGetPalette4(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp)
|
|
{ return extGetPalette(4, pGetPalette4, lpdds, lplpddp); }
|
|
HRESULT WINAPI extGetPalette7(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp)
|
|
{ return extGetPalette(7, pGetPalette7, lpdds, lplpddp); }
|
|
|
|
HRESULT WINAPI extSetPalette(int dxversion, SetPalette_Type pSetPalette, LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp)
|
|
{
|
|
PALETTEENTRY *lpentries;
|
|
BOOL isPrim;
|
|
HRESULT res;
|
|
|
|
isPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
OutTraceDDRAW("SetPalette(%d): lpdds=%x%s lpddp=%x\n", dxversion, lpdds, isPrim?"(PRIM)":"", lpddp);
|
|
|
|
res=(*pSetPalette)(lpdds, lpddp);
|
|
if(res){
|
|
OutTraceE("SetPalette: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
// from MSDN, about lpddp:
|
|
// A pointer to the IDirectDrawPalette interface for the palette object to be used with this surface.
|
|
// If NULL, the current palette is detached.
|
|
if(lpddp) lpddp->AddRef(); // to allow final Release() without crash - fixes "Heavy Gear" crash at end of mission
|
|
}
|
|
else OutTraceDDRAW("SetPalette: OK\n");
|
|
res=DD_OK;
|
|
|
|
if((dxw.dwFlags1 & EMULATESURFACE) && isPrim){
|
|
OutTraceDW("SetPalette: register PRIMARY palette lpDDP=%x\n", lpddp);
|
|
lpDDP = lpddp;
|
|
LPDIRECTDRAWSURFACE lpDDSBack;
|
|
if(lpddp){
|
|
HRESULT res2;
|
|
lpentries = (LPPALETTEENTRY)PaletteEntries;
|
|
res2=lpddp->GetEntries(0, 0, 256, lpentries);
|
|
if(res2) OutTraceE("SetPalette: GetEntries ERROR res=%x(%s)\n", res2, ExplainDDError(res2));
|
|
mySetPalette(0, 256, lpentries); // v2.02.76: necessary for "Requiem Avenging Angel" in SURFACEEMULATION mode
|
|
}
|
|
// Apply palette to backbuffer surface. This is necessary on some games: "Duckman private dick", "Total Soccer 2000", ...
|
|
lpDDSBack = dxwss.GetBackBufferSurface();
|
|
if (lpDDSBack){
|
|
OutTraceDW("SetPalette: apply PRIMARY palette lpDDP=%x to DDSBack=%x\n", lpddp, lpDDSBack);
|
|
res=(*pSetPalette)(lpDDSBack, lpddp);
|
|
if(res) OutTraceE("SetPalette: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
}
|
|
// add a reference to simulate what would happen in reality....
|
|
if(lpddp) lpdds->AddRef();
|
|
res=DD_OK;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extSetPalette1(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp)
|
|
{ return extSetPalette(1, pSetPalette1, lpdds, lpddp); }
|
|
HRESULT WINAPI extSetPalette2(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp)
|
|
{ return extSetPalette(2, pSetPalette2, lpdds, lpddp); }
|
|
HRESULT WINAPI extSetPalette3(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp)
|
|
{ return extSetPalette(3, pSetPalette3, lpdds, lpddp); }
|
|
HRESULT WINAPI extSetPalette4(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp)
|
|
{ return extSetPalette(4, pSetPalette4, lpdds, lpddp); }
|
|
HRESULT WINAPI extSetPalette7(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp)
|
|
{ return extSetPalette(7, pSetPalette7, lpdds, lpddp); }
|
|
|
|
HRESULT WINAPI extSetEntries(LPDIRECTDRAWPALETTE lpddp, DWORD dwflags, DWORD dwstart, DWORD dwcount, LPPALETTEENTRY lpentries)
|
|
{
|
|
HRESULT res;
|
|
|
|
OutTraceDDRAW("SetEntries: lpddp=%x dwFlags=%x, start=%d, count=%d entries=%x\n", //GHO: added trace infos
|
|
lpddp, dwflags, dwstart, dwcount, lpentries);
|
|
if(IsDebug) dxw.DumpPalette(dwcount, &lpentries[dwstart]);
|
|
|
|
if((dxw.dwFlags1 & EMULATESURFACE) && (lpDDP == lpddp)){
|
|
OutTraceDW("SetEntries: update PRIMARY palette lpDDP=%x\n", lpddp);
|
|
if ((dwstart + dwcount > 256) || (dwstart<0)){
|
|
dwcount=256;
|
|
dwstart=0;
|
|
OutTraceDW("SetEntries: ASSERT start+count > 256\n");
|
|
}
|
|
|
|
mySetPalette(dwstart, dwcount, lpentries);
|
|
|
|
// GHO: needed for fixed rect and variable palette animations,
|
|
// e.g. dungeon keeper loading screen, Warcraft II splash, ...
|
|
// GHO: but refreshing cause flickering when GDI was used without updating the primary surface
|
|
// e.g. Tomb Raider 2 intro titles, Virtua Fighter PC, ...
|
|
// v2.03.10: do not blit also in case of GDI mode
|
|
if ((dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags2 & NOPALETTEUPDATE) && !(dxw.dwFlags5 & GDIMODE)) dxw.ScreenRefresh();
|
|
}
|
|
|
|
// this part (setentry against all surfaces, including virtual primary) can be necessary whenever the game uses mixed access to the
|
|
// screen (like ddraw & GDI) and is necessary on "Road Rash".
|
|
res = (*pSetEntries)(lpddp, dwflags, dwstart, dwcount, lpentries);
|
|
if(res) OutTraceE("SetEntries: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
else OutTraceDDRAW("SetEntries: OK\n");
|
|
return res;
|
|
}
|
|
|
|
static HRESULT WINAPI extSetClipper(int dxversion, SetClipper_Type pSetClipper, LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWCLIPPER lpddc)
|
|
{
|
|
HRESULT res;
|
|
BOOL isPrim;
|
|
isPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
OutTraceDDRAW("SetClipper(%d): lpdds=%x%s lpddc=%x\n", dxversion, lpdds, isPrim?"(PRIM)":"", lpddc);
|
|
|
|
// v2.1.84: SUPPRESSCLIPPING flag - improves "Monopoly Edition 3D" where continuous
|
|
// clipping ON & OFF affects blitting on primary surface.
|
|
// Needed also to avoid "New Yourk Racer" intro movie clipping.
|
|
if(dxw.dwFlags1 & SUPPRESSCLIPPING) return 0;
|
|
|
|
if(dxw.IsEmulated){
|
|
if (dxw.dwFlags3 & FORCECLIPPER){
|
|
// v2.03.48: FORCECLIPPER ensures that a valid clipper is issued on the real primary surface
|
|
// and on the main game window. Then, you won't be able to BltFast any longer....
|
|
if ((isPrim || dxwss.IsABackBufferSurface(lpdds)) && lpDDSEmu_Prim){
|
|
OutTraceDW("SetClipper: redirect surface to primary hwnd=%x lpdds=%x%s->%x\n",
|
|
dxw.GethWnd(), lpdds, isPrim?"(PRIM)":"", lpDDSEmu_Prim);
|
|
res=(*pSetHWnd)(lpddc, 0, dxw.GethWnd());
|
|
//res=lpddc->SetHWnd(0, dxw.GethWnd());
|
|
if (res) OutTraceE("SetClipper: SetHWnd ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
res=(*pSetClipper)(lpDDSEmu_Prim, lpddc);
|
|
if (res) OutTraceE("SetClipper: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
}
|
|
else {
|
|
if ((isPrim && lpDDSEmu_Prim) ||
|
|
(dxwss.IsABackBufferSurface(lpdds) && lpDDSEmu_Back)){
|
|
OutTraceDW("SetClipper: skip primary/backbuffer lpdds=%x\n", lpdds);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
res=(*pSetClipper)(lpdds, lpddc);
|
|
|
|
if (res)
|
|
OutTraceE("SetClipper: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extSetClipper1(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWCLIPPER lpddc)
|
|
{ return extSetClipper(1, pSetClipper1, lpdds, lpddc); }
|
|
HRESULT WINAPI extSetClipper2(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWCLIPPER lpddc)
|
|
{ return extSetClipper(2, pSetClipper2, lpdds, lpddc); }
|
|
HRESULT WINAPI extSetClipper3(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWCLIPPER lpddc)
|
|
{ return extSetClipper(3, pSetClipper3, lpdds, lpddc); }
|
|
HRESULT WINAPI extSetClipper4(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWCLIPPER lpddc)
|
|
{ return extSetClipper(4, pSetClipper4, lpdds, lpddc); }
|
|
HRESULT WINAPI extSetClipper7(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWCLIPPER lpddc)
|
|
{ return extSetClipper(7, pSetClipper7, lpdds, lpddc); }
|
|
|
|
DDSURFACEDESC SaveSurfaceDesc;
|
|
LPDIRECTDRAWSURFACE SaveSurface = NULL;
|
|
LPRECT SaveLockedlpRect = NULL;
|
|
RECT SaveLockedRect;
|
|
LPDIRECTDRAWSURFACE SaveLockedSurface = NULL;
|
|
|
|
static void PushLockedRect(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect)
|
|
{
|
|
SaveLockedSurface = lpdds;
|
|
SaveLockedlpRect = lprect;
|
|
if(SaveLockedlpRect) SaveLockedRect = *lprect;
|
|
}
|
|
|
|
static LPRECT PopLockedRect(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect)
|
|
{
|
|
if(lpdds == SaveLockedSurface){
|
|
SaveLockedSurface = NULL;
|
|
return SaveLockedlpRect;
|
|
}
|
|
else
|
|
return lprect;
|
|
}
|
|
|
|
static HRESULT WINAPI extLock(int dxversion, Lock_Type pLock, LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{
|
|
HRESULT res;
|
|
|
|
CleanRect(&lprect, __LINE__);
|
|
|
|
if(IsTraceDDRAW){
|
|
BOOL IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
char sRect[81];
|
|
if (lprect) sprintf_s(sRect, 80, "(%d,%d)-(%d,%d)", lprect->left, lprect->top, lprect->right, lprect->bottom);
|
|
else strcpy(sRect, "(NULL)");
|
|
OutTrace("Lock(%d): lpdds=%x%s flags=%x(%s) lpDDSurfaceDesc=%x rect=%s\n",
|
|
dxversion, lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpDDSurfaceDesc, sRect);
|
|
}
|
|
|
|
PushLockedRect(lpdds, lprect);
|
|
|
|
res=(*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent);
|
|
if(res==DDERR_SURFACEBUSY){ // v70: fix for "Ancient Evil"
|
|
(*pUnlockMethod(dxversion))(lpdds, NULL);
|
|
res = (*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent);
|
|
OutTraceDW("Lock SURFACEBUSY RETRY: ret=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
if(res==DDERR_SURFACELOST){
|
|
lpdds->Restore();
|
|
res = (*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent);
|
|
OutTraceDW("Lock SURFACELOST RETRY: ret=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
if(res) OutTraceE("Lock ERROR: ret=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
OutTraceB("Lock: lPitch=%d lpSurface=%x %s\n",
|
|
lpDDSurfaceDesc->lPitch, lpDDSurfaceDesc->lpSurface, LogSurfaceAttributes((LPDDSURFACEDESC2)lpDDSurfaceDesc, "[Locked]", __LINE__));
|
|
|
|
// v2.03.60: necessary for "Mech Commander 2"
|
|
if(dxw.dwFlags6 & SETZBUFFERBITDEPTHS)
|
|
lpDDSurfaceDesc->dwZBufferBitDepth = dxw.VirtualPixelFormat.dwRGBBitCount;
|
|
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
|
|
if((dxw.dwFlags6 & FIXPITCH) || (dxw.dwFlags3 & MARKLOCK)){
|
|
SaveSurfaceDesc = *lpDDSurfaceDesc;
|
|
SaveSurface = lpdds;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extLock1(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{ return extLock(1, pLock1, lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); }
|
|
HRESULT WINAPI extLock2(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{ return extLock(2, pLock2, lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); }
|
|
HRESULT WINAPI extLock3(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{ return extLock(3, pLock3, lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); }
|
|
HRESULT WINAPI extLock4(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{ return extLock(4, pLock4, lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); }
|
|
HRESULT WINAPI extLock7(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{ return extLock(7, pLock7, lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); }
|
|
|
|
LPDIRECTDRAWSURFACE2 lpDDSBuffer = NULL;
|
|
|
|
static HRESULT WINAPI extLockDir(int dxversion, Lock_Type pLock, LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{
|
|
HRESULT res, res2;
|
|
static RECT client;
|
|
POINT upleft={0,0};
|
|
Blt_Type pBlt;
|
|
GetGDISurface_Type pGetGDISurface;
|
|
|
|
// this hooker operates on
|
|
// Beware!!! for strange reason, the function gets hooked to ANY surface, also non primary ones!!!
|
|
// to find out whether it is the primary or not, using lpdds==lpPrimaryDD->GetGDISurface(&lpDDSPrim);
|
|
|
|
if(IsTraceDDRAW){
|
|
BOOL IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
char sRect[81];
|
|
if (lprect) sprintf_s(sRect, 80, "(%d,%d)-(%d,%d)", lprect->left, lprect->top, lprect->right, lprect->bottom);
|
|
else strcpy(sRect, "(NULL)");
|
|
OutTrace("Lock(%d): lpdds=%x%s flags=%x(%s) lpDDSurfaceDesc=%x rect=%s\n",
|
|
dxversion, lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpDDSurfaceDesc, sRect);
|
|
}
|
|
|
|
PushLockedRect(lpdds, lprect);
|
|
|
|
// v2.04.09: for IDirectDraw methods use iBakBufferVersion instead of dxversion ...
|
|
pBlt = pGetBltMethod(dxversion);
|
|
pGetGDISurface = pGetGDISurfaceMethod(iBakBufferVersion);
|
|
|
|
// V2.02.43: Empire Earth does some test Lock operations apparently before the primary surface is created
|
|
if(lpPrimaryDD){
|
|
LPDIRECTDRAWSURFACE lpDDSPrim = 0;
|
|
res2=(*pGetGDISurface)(lpPrimaryDD, &lpDDSPrim);
|
|
if(res2)
|
|
OutTraceE("Lock: GetGDISurface ERROR res=%x(%s) at %d\n", res2, ExplainDDError(res2), __LINE__);
|
|
else
|
|
(*pReleaseSMethod(dxversion))(lpDDSPrim);
|
|
if(lpdds==lpDDSPrim){
|
|
if(dxw.dwFlags1 & LOCKEDSURFACE){
|
|
DDSURFACEDESC2 ddsd;
|
|
DDBLTFX fx;
|
|
memset(&ddsd, 0, sizeof(ddsd));
|
|
ddsd.dwSize=sizeof(DDSURFACEDESC);
|
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
|
|
ddsd.dwWidth = dxw.GetScreenWidth();
|
|
ddsd.dwHeight = dxw.GetScreenHeight();
|
|
ddsd.ddsCaps.dwCaps = 0;
|
|
OutTraceB("Lock: %s\n", LogSurfaceAttributes(&ddsd, "[Dir FixBuf]" , __LINE__));
|
|
res=(*pCreateSurface1)(lpPrimaryDD, (DDSURFACEDESC *)&ddsd, (LPDIRECTDRAWSURFACE *)&lpDDSBuffer, 0);
|
|
if(res){
|
|
OutTraceE("CreateSurface: ERROR on DDSBuffer res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
memset(&fx, 0, sizeof(fx));
|
|
fx.dwSize=sizeof(DDBLTFX);
|
|
fx.dwFillColor=0;
|
|
res=(*pBlt)((LPDIRECTDRAWSURFACE)lpDDSBuffer, NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
|
|
if(res){
|
|
OutTraceE("Blt: ERROR on DDSBuffer res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__);
|
|
}
|
|
lpdds=(LPDIRECTDRAWSURFACE)lpDDSBuffer;
|
|
}
|
|
else{
|
|
// since it can't scale, at least the updated rect is centered into the window.
|
|
HWND hwnd;
|
|
hwnd = dxw.GethWnd();
|
|
(*pGetClientRect)(hwnd, &client);
|
|
(*pClientToScreen)(hwnd, &upleft);
|
|
if (!lprect) lprect=&client;
|
|
OffsetRect(lprect,
|
|
upleft.x+(client.right-dxw.GetScreenWidth())/2,
|
|
upleft.y+(client.bottom-dxw.GetScreenHeight())/2);
|
|
OutTraceDW("Lock: NULL rect remapped to (%d,%d)-(%d,%d)\n",
|
|
lprect->left, lprect->top, lprect->right, lprect->bottom);
|
|
}
|
|
}
|
|
}
|
|
|
|
res=(*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent);
|
|
if(res==DDERR_SURFACEBUSY){ // v70: fix for "Ancient Evil"
|
|
(*pUnlockMethod(dxversion))(lpdds, NULL);
|
|
res = (*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent);
|
|
OutTraceDW("Lock SURFACEBUSY RETRY: ret=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
if(res==DDERR_SURFACELOST){
|
|
lpdds->Restore();
|
|
res = (*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent);
|
|
OutTraceDW("Lock SURFACELOST RETRY: ret=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
|
|
if(res) OutTraceE("Lock ERROR: ret=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
OutTraceB("Lock: lPitch=%d lpSurface=%x %s\n",
|
|
lpDDSurfaceDesc->lPitch, lpDDSurfaceDesc->lpSurface, LogSurfaceAttributes((LPDDSURFACEDESC2)lpDDSurfaceDesc, "[Locked]", __LINE__));
|
|
|
|
// v2.03.60: necessary for "Mech Commander 2"
|
|
if(dxw.dwFlags6 & SETZBUFFERBITDEPTHS)
|
|
lpDDSurfaceDesc->dwZBufferBitDepth = dxw.VirtualPixelFormat.dwRGBBitCount;
|
|
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
|
|
if((dxw.dwFlags6 & FIXPITCH) || (dxw.dwFlags3 & MARKLOCK)){
|
|
SaveSurfaceDesc = *lpDDSurfaceDesc;
|
|
SaveSurface = lpdds;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extLockDir1(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{ return extLockDir(1, pLock1, lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); }
|
|
HRESULT WINAPI extLockDir2(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{ return extLockDir(2, pLock2, lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); }
|
|
HRESULT WINAPI extLockDir3(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{ return extLockDir(3, pLock3, lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); }
|
|
HRESULT WINAPI extLockDir4(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{ return extLockDir(4, pLock4, lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); }
|
|
HRESULT WINAPI extLockDir7(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent)
|
|
{ return extLockDir(7, pLock7, lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); }
|
|
|
|
#define MARK16COLOR 0x7C1F
|
|
#define MARK32COLOR 0x00FF00FF
|
|
|
|
static HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRAWSURFACE lpdds, LPRECT lprect)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsPrim;
|
|
BOOL IsBack;
|
|
Blt_Type pBlt;
|
|
RECT rect;
|
|
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
IsBack=dxwss.IsABackBufferSurface(lpdds);
|
|
|
|
if(IsTraceDDRAW){
|
|
char sRect[81];
|
|
switch(dxversion){
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
sprintf_s(sRect, 80, "lpvoid=%x", lprect);
|
|
break;
|
|
case 4:
|
|
case 7:
|
|
if (lprect) sprintf_s(sRect, 80, "rect=(%d,%d)-(%d,%d)", lprect->left, lprect->top, lprect->right, lprect->bottom);
|
|
else strcpy(sRect, "rect=(NULL)");
|
|
break;
|
|
}
|
|
OutTrace("Unlock(%d): lpdds=%x%s %s\n", dxversion, lpdds, (IsPrim ? "(PRIM)": (IsBack ? "(BACK)" : "")), sRect);
|
|
}
|
|
|
|
if ((dxw.dwFlags8 & ZBUFFERHARDCLEAN) && dxwss.IsAZBufferSurface(lpdds)){
|
|
DWORD dwSize = (dxversion<4)?sizeof(DDSURFACEDESC):sizeof(DDSURFACEDESC2);
|
|
DDSURFACEDESC2 ddsd;
|
|
memset(&ddsd, 0, dwSize);
|
|
ddsd.dwSize = dwSize;
|
|
res=(*pUnlock)(lpdds, NULL);
|
|
if(res) OutTraceDW("Unlock ZBUFFER: Unlock err=%x at %d\n", res, __LINE__);
|
|
res=(*pLockMethod(dxversion))(lpdds, NULL, (LPDDSURFACEDESC)&ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, 0);
|
|
if(res) OutTraceDW("Unlock ZBUFFER: Lock err=%x at %d\n", res, __LINE__);
|
|
memset(ddsd.lpSurface, 0xFF, ZBufferSize);
|
|
res=(*pUnlock)(lpdds, lprect);
|
|
if(res) OutTraceDW("Unlock ZBUFFER: Unlock err=%x at %d\n", res, __LINE__);
|
|
return res;
|
|
}
|
|
|
|
switch(dxversion){
|
|
case 4:
|
|
// v2.02.92: found in Fifa 2000: lpRect is completely ignored, receiving bogus values like (-1, -1, -1, -1}
|
|
// or {0, 0, 0, 0}, or {-109119151, -109119151, -109119151, -109119151}.
|
|
// better use the Lock-ed rect
|
|
// v2.04.21: the fix is proper only when lprect is not NULL, when NULL better leave it unaltered.
|
|
// Fixing the lprect value unconditionally breaks "Shadow Watch" text blitting on game menus.
|
|
if(lprect) lprect = PopLockedRect(lpdds, lprect);
|
|
break;
|
|
case 7:
|
|
if(lprect){
|
|
rect = *lprect;
|
|
lprect = ▭
|
|
// v2.03.20: apparently, it seems that in ddraw 7 you can set an empty rectangle to mean the whole area ....
|
|
// this fixes the black screen otherwise present in "Arcanum".
|
|
if(IsPrim && ((lprect->right - lprect->left) == 0) && ((lprect->bottom - lprect->top) == 0)) lprect = NULL;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if((dxw.dwFlags6 & FIXPITCH) && !(IsPrim||IsBack) && (lpdds == SaveSurface)){
|
|
OutTrace("DEBUG: fixing lpdds=%x size=(%dx%d) surface=%x pitch=%d bpp=%d\n",
|
|
lpdds, SaveSurfaceDesc.dwWidth, SaveSurfaceDesc.dwHeight, SaveSurfaceDesc.lpSurface, SaveSurfaceDesc.lPitch, SaveSurfaceDesc.ddpfPixelFormat.dwRGBBitCount);
|
|
int y;
|
|
LONG lVirtualPitch;
|
|
LPVOID p1, p2;
|
|
lVirtualPitch = (((SaveSurfaceDesc.dwWidth+1)>>1) * SaveSurfaceDesc.ddpfPixelFormat.dwRGBBitCount) >> 2;
|
|
if(lVirtualPitch != SaveSurfaceDesc.lPitch){ // do just if necessary ...
|
|
for (y=SaveSurfaceDesc.dwHeight-1; y; y--){ // for each scan line ...
|
|
p1 = (LPVOID)((DWORD)SaveSurfaceDesc.lpSurface + (y * lVirtualPitch));
|
|
p2 = (LPVOID)((DWORD)SaveSurfaceDesc.lpSurface + (y * SaveSurfaceDesc.lPitch));
|
|
memcpy(p2, p1, SaveSurfaceDesc.lPitch); // copy line to correct offset
|
|
}
|
|
}
|
|
}
|
|
|
|
if((dxw.dwFlags3 & MARKLOCK) && !(IsPrim||IsBack) && (lpdds == SaveSurface)){
|
|
switch(SaveSurfaceDesc.ddpfPixelFormat.dwRGBBitCount){
|
|
case 16:
|
|
for (UINT y=0; y<SaveSurfaceDesc.dwHeight; y++){ // for each scan line ...
|
|
USHORT *p;
|
|
p = (USHORT *)((DWORD)SaveSurfaceDesc.lpSurface + (y * SaveSurfaceDesc.lPitch));
|
|
p[0] = MARK16COLOR;
|
|
p[SaveSurfaceDesc.dwWidth-1] = MARK16COLOR;
|
|
if((y==0) || (y==(SaveSurfaceDesc.dwHeight-1)))
|
|
for (UINT x=0; x<SaveSurfaceDesc.dwWidth; x++) p[x] = MARK16COLOR;
|
|
}
|
|
break;
|
|
case 32:
|
|
for (UINT y=0; y<SaveSurfaceDesc.dwHeight; y++){ // for each scan line ...
|
|
ULONG *p;
|
|
p = (ULONG *)((DWORD)SaveSurfaceDesc.lpSurface + (y * SaveSurfaceDesc.lPitch));
|
|
p[0] = MARK32COLOR;
|
|
p[SaveSurfaceDesc.dwWidth-1] = MARK32COLOR;
|
|
if((y==0) || (y==(SaveSurfaceDesc.dwHeight-1)))
|
|
for (UINT x=0; x<SaveSurfaceDesc.dwWidth; x++) p[x] = MARK32COLOR;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
res=(*pUnlock)(lpdds, lprect);
|
|
if(res==DDERR_NOTLOCKED) res=DD_OK; // ignore not locked error
|
|
if (IsPrim && res==DD_OK) {
|
|
pBlt = pGetBltMethod(dxversion);
|
|
if(dxversion < 4) lprect=NULL; // v2.03.60
|
|
res=sBlt(dxversion, pBlt, "Unlock", lpdds, lprect, lpdds, lprect, NULL, 0, FALSE);
|
|
}
|
|
if (res) OutTraceE("Unlock ERROR res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__);
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
if((dxw.dwFlags5 & TEXTUREMASK) && (!IsPrim)) {
|
|
// Texture Handling on Unlock
|
|
TextureHandling(lpdds, dxversion);
|
|
}
|
|
OutTraceB("Unlock OK\n");
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extUnlock1(LPDIRECTDRAWSURFACE lpdds, LPVOID lpvoid)
|
|
{ return extUnlock(1, (Unlock4_Type)pUnlock1, lpdds, (LPRECT)lpvoid); }
|
|
HRESULT WINAPI extUnlock2(LPDIRECTDRAWSURFACE lpdds, LPVOID lpvoid)
|
|
{ return extUnlock(2, (Unlock4_Type)pUnlock2, lpdds, (LPRECT)lpvoid); }
|
|
HRESULT WINAPI extUnlock3(LPDIRECTDRAWSURFACE lpdds, LPVOID lpvoid)
|
|
{ return extUnlock(3, (Unlock4_Type)pUnlock3, lpdds, (LPRECT)lpvoid); }
|
|
HRESULT WINAPI extUnlock4(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect)
|
|
{ return extUnlock(4, pUnlock4, lpdds, lprect); }
|
|
HRESULT WINAPI extUnlock7(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect)
|
|
{ return extUnlock(7, pUnlock7, lpdds, lprect); }
|
|
|
|
static HRESULT WINAPI extUnlockDir(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRAWSURFACE lpdds, LPRECT lprect)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsPrim;
|
|
BOOL IsBack;
|
|
Blt_Type pBlt;
|
|
RECT rect;
|
|
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
IsBack=dxwss.IsABackBufferSurface(lpdds);
|
|
|
|
if(IsTraceDDRAW){
|
|
char sRect[81];
|
|
switch(dxversion){
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
sprintf_s(sRect, 80, "lpvoid=%x", lprect);
|
|
break;
|
|
case 4:
|
|
case 7:
|
|
if (lprect) sprintf_s(sRect, 80, "rect=(%d,%d)-(%d,%d)", lprect->left, lprect->top, lprect->right, lprect->bottom);
|
|
else strcpy(sRect, "rect=(NULL)");
|
|
break;
|
|
}
|
|
OutTrace("Unlock(%d): lpdds=%x%s %s\n", dxversion, lpdds, (IsPrim ? "(PRIM)": (IsBack ? "(BACK)" : "")), sRect);
|
|
}
|
|
|
|
if ((dxw.dwFlags8 & ZBUFFERHARDCLEAN) && dxwss.IsAZBufferSurface(lpdds)){
|
|
DWORD dwSize = (dxversion<4)?sizeof(DDSURFACEDESC):sizeof(DDSURFACEDESC2);
|
|
DDSURFACEDESC2 ddsd;
|
|
memset(&ddsd, 0, dwSize);
|
|
ddsd.dwSize = dwSize;
|
|
res=(*pUnlock)(lpdds, NULL);
|
|
if(res) OutTraceDW("Unlock ZBUFFER: Unlock err=%x at %d\n", res, __LINE__);
|
|
res=(*pLockMethod(dxversion))(lpdds, NULL, (LPDDSURFACEDESC)&ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, 0);
|
|
if(res) OutTraceDW("Unlock ZBUFFER: Lock err=%x at %d\n", res, __LINE__);
|
|
memset(ddsd.lpSurface, 0xFF, ZBufferSize);
|
|
res=(*pUnlock)(lpdds, lprect);
|
|
if(res) OutTraceDW("Unlock ZBUFFER: Unlock err=%x at %d\n", res, __LINE__);
|
|
return res;
|
|
}
|
|
|
|
switch(dxversion){
|
|
case 4:
|
|
// v2.02.92: found in Fifa 2000: lpRect is completely ignored, receiving bogus values like (-1, -1, -1, -1}
|
|
// or {0, 0, 0, 0}, or {-109119151, -109119151, -109119151, -109119151}.
|
|
// better use the Lock-ed rect
|
|
// v2.04.21: the fix is proper only when lprect is not NULL, when NULL better leave it unaltered.
|
|
// Fixing the lprect value unconditionally breaks "Shadow Watch" text blitting on game menus.
|
|
if(lprect) lprect = PopLockedRect(lpdds, lprect);
|
|
break;
|
|
case 7:
|
|
if(lprect){
|
|
rect = *lprect;
|
|
lprect = ▭
|
|
// v2.03.20: apparently, it seems that in ddraw 7 you can set an empty rectangle to mean the whole area ....
|
|
// this fixes the black screen otherwise present in "Arcanum".
|
|
if(IsPrim && ((lprect->right - lprect->left) == 0) && ((lprect->bottom - lprect->top) == 0)) lprect = NULL;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// v2.04.09: for IDirectDraw methods use iBakBufferVersion instead of dxversion ...
|
|
pBlt = pGetBltMethod(dxversion);
|
|
|
|
if(dxw.dwFlags1 & LOCKEDSURFACE){
|
|
LPDIRECTDRAWSURFACE lpDDSPrim = 0;
|
|
GetGDISurface_Type pGetGDISurface = pGetGDISurfaceMethod(iBakBufferVersion);
|
|
|
|
(*pGetGDISurface)(lpPrimaryDD, &lpDDSPrim);
|
|
if(lpdds==lpDDSPrim && lpDDSBuffer){
|
|
RECT client;
|
|
POINT upleft={0,0};
|
|
(*pGetClientRect)(dxw.GethWnd(), &client);
|
|
(*pClientToScreen)(dxw.GethWnd(), &upleft);
|
|
if (!lprect) lprect=&client;
|
|
OffsetRect(lprect, upleft.x, upleft.y);
|
|
res=(*pUnlock)((LPDIRECTDRAWSURFACE)lpDDSBuffer, lprect);
|
|
(*pBlt)(lpdds, lprect, (LPDIRECTDRAWSURFACE)lpDDSBuffer, NULL, DDBLT_WAIT, 0);
|
|
(*pReleaseSMethod(dxversion))((LPDIRECTDRAWSURFACE)lpDDSBuffer);
|
|
lpDDSBuffer = NULL;
|
|
}
|
|
(*pReleaseSMethod(dxversion))(lpDDSPrim); // to leave a correct refcount
|
|
}
|
|
|
|
res=(*pUnlock)(lpdds, lprect);
|
|
if(res==DDERR_NOTLOCKED) res=DD_OK; // ignore not locked error
|
|
if (IsPrim && res==DD_OK) {
|
|
if(dxversion < 4) lprect=NULL; // v2.03.60
|
|
res=sBlt(dxversion, pBlt, "Unlock", lpdds, lprect, lpdds, lprect, NULL, 0, FALSE);
|
|
}
|
|
if (res) OutTraceE("Unlock ERROR res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__);
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
if((dxw.dwFlags5 & TEXTUREMASK) && (!IsPrim)) {
|
|
// Texture Handling on Unlock
|
|
TextureHandling(lpdds, dxversion);
|
|
}
|
|
OutTraceB("Unlock OK\n");
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extUnlockDir1(LPDIRECTDRAWSURFACE lpdds, LPVOID lpvoid)
|
|
{ return extUnlockDir(1, (Unlock4_Type)pUnlock1, lpdds, (LPRECT)lpvoid); }
|
|
HRESULT WINAPI extUnlockDir2(LPDIRECTDRAWSURFACE lpdds, LPVOID lpvoid)
|
|
{ return extUnlockDir(2, (Unlock4_Type)pUnlock2, lpdds, (LPRECT)lpvoid); }
|
|
HRESULT WINAPI extUnlockDir3(LPDIRECTDRAWSURFACE lpdds, LPVOID lpvoid)
|
|
{ return extUnlockDir(3, (Unlock4_Type)pUnlock3, lpdds, (LPRECT)lpvoid); }
|
|
HRESULT WINAPI extUnlockDir4(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect)
|
|
{ return extUnlockDir(4, pUnlock4, lpdds, lprect); }
|
|
HRESULT WINAPI extUnlockDir7(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect)
|
|
{ return extUnlockDir(7, pUnlock7, lpdds, lprect); }
|
|
|
|
/* to do: instead of calling GDI GetDC, try to map GetDC with Lock and
|
|
ReleaseDC with Unlock, returning the surface memory ptr (???) as HDC
|
|
and avoiding the consistency check performed by surface::GetDC (why
|
|
should it bother if the screen is 32BPP and the surface is not??? */
|
|
|
|
static HRESULT WINAPI extGetDC(int dxversion, GetDC_Type pGetDC, LPDIRECTDRAWSURFACE lpdds, HDC FAR *pHDC)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsPrim;
|
|
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
OutTraceDDRAW("GetDC: lpdss=%x%s\n",lpdds, IsPrim?"(PRIM)":"");
|
|
|
|
// In non-emulated mode, better return the window DC rather than the actual primary surfce DC,
|
|
// because that would refer to the whole desktop
|
|
if (!(dxw.dwFlags1 & EMULATESURFACE) && IsPrim) {
|
|
*pHDC = (*pGDIGetDC)(dxw.GethWnd());
|
|
return DD_OK;
|
|
}
|
|
|
|
res=(*pGetDC)(lpdds, pHDC);
|
|
|
|
if (res==DDERR_CANTCREATEDC &&
|
|
(dxw.dwFlags1 & EMULATESURFACE) &&
|
|
dxw.VirtualPixelFormat.dwRGBBitCount==8) {
|
|
// for 8BPP palettized surfaces, connect them to either the ddraw emulated palette or the GDI emulated palette
|
|
OutTraceDW("GetDC: adding 8BPP palette to surface lpdds=%x\n", lpdds);
|
|
if(lpDDP==NULL){
|
|
// should link here to the GDI palette? See Hyperblade....
|
|
dxw.palNumEntries=256;
|
|
res=(*pCreatePaletteMethod(dxversion))(lpPrimaryDD, DDPCAPS_ALLOW256|DDPCAPS_8BIT|DDPCAPS_INITIALIZE, dxw.palPalEntry, &lpDDP, NULL);
|
|
if (res) {
|
|
OutTraceE("GetDC: CreatePalette ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
}
|
|
res=(*pSetPaletteMethod(dxversion))(lpdds, lpDDP);
|
|
if (res) {
|
|
OutTraceE("GetDC: SetPalette ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
iDDPExtraRefCounter++;
|
|
// retry ....
|
|
res=(*pGetDC)(lpdds, pHDC);
|
|
}
|
|
|
|
OutTraceDDRAW("GetDC: res=%x(%s) hdc=%x\n", res, ExplainDDError(res), *pHDC);
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extGetDC1(LPDIRECTDRAWSURFACE lpdds, HDC FAR *pHDC)
|
|
{ return extGetDC(1, pGetDC1, lpdds, pHDC); }
|
|
HRESULT WINAPI extGetDC2(LPDIRECTDRAWSURFACE lpdds, HDC FAR *pHDC)
|
|
{ return extGetDC(2, pGetDC2, lpdds, pHDC); }
|
|
HRESULT WINAPI extGetDC3(LPDIRECTDRAWSURFACE lpdds, HDC FAR *pHDC)
|
|
{ return extGetDC(3, pGetDC3, lpdds, pHDC); }
|
|
HRESULT WINAPI extGetDC4(LPDIRECTDRAWSURFACE lpdds, HDC FAR *pHDC)
|
|
{ return extGetDC(4, pGetDC4, lpdds, pHDC); }
|
|
HRESULT WINAPI extGetDC7(LPDIRECTDRAWSURFACE lpdds, HDC FAR *pHDC)
|
|
{ return extGetDC(7, pGetDC7, lpdds, pHDC); }
|
|
|
|
HRESULT WINAPI extReleaseDC(int dxversion, ReleaseDC_Type pReleaseDC, LPDIRECTDRAWSURFACE lpdds, HDC FAR hdc)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsPrim;
|
|
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
OutTraceDDRAW("ReleaseDC: lpdss=%x%s hdc=%x\n",lpdds, IsPrim?"(PRIM)":"", hdc);
|
|
res=(*pReleaseDC)(lpdds, hdc);
|
|
if((IsPrim) && (dxw.dwFlags1 & EMULATESURFACE)) {
|
|
Blt_Type pBlt;
|
|
GetGDISurface_Type pGetGDISurface;
|
|
// v2.04.09: for IDirectDraw methods use iBakBufferVersion instead of dxversion ...
|
|
pBlt = pGetBltMethod(dxversion);
|
|
pGetGDISurface = pGetGDISurfaceMethod(iBakBufferVersion);
|
|
sBlt(dxversion, pBlt, "ReleaseDC", lpdds, NULL, lpdds, NULL, 0, NULL, FALSE);
|
|
}
|
|
if (res) OutTraceE("ReleaseDC: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extReleaseDC1(LPDIRECTDRAWSURFACE lpdds, HDC FAR hdc)
|
|
{ return extReleaseDC(1, pReleaseDC1, lpdds, hdc); }
|
|
HRESULT WINAPI extReleaseDC2(LPDIRECTDRAWSURFACE lpdds, HDC FAR hdc)
|
|
{ return extReleaseDC(2, pReleaseDC2, lpdds, hdc); }
|
|
HRESULT WINAPI extReleaseDC3(LPDIRECTDRAWSURFACE lpdds, HDC FAR hdc)
|
|
{ return extReleaseDC(3, pReleaseDC3, lpdds, hdc); }
|
|
HRESULT WINAPI extReleaseDC4(LPDIRECTDRAWSURFACE lpdds, HDC FAR hdc)
|
|
{ return extReleaseDC(4, pReleaseDC4, lpdds, hdc); }
|
|
HRESULT WINAPI extReleaseDC7(LPDIRECTDRAWSURFACE lpdds, HDC FAR hdc)
|
|
{ return extReleaseDC(7, pReleaseDC7, lpdds, hdc); }
|
|
|
|
|
|
HRESULT WINAPI extFlipToGDISurface(FlipToGDISurface_Type pFlipToGDISurface, LPDIRECTDRAW lpdd)
|
|
{
|
|
// HRESULT res;
|
|
|
|
OutTraceDDRAW("FlipToGDISurface: lpdd=%x\n", lpdd);
|
|
// to revise: so far, it seems the best thing to do is NOTHING, just return 0.
|
|
// res=(*pFlipToGDISurface)(lpdd);
|
|
// if (res) OutTraceE("FlipToGDISurface: ERROR res=%x(%s), skipping\n", res, ExplainDDError(res));
|
|
// pretend you flipped anyway....
|
|
|
|
if(dxw.dwFlags6 & SHAREDDC) bFlippedDC = TRUE;
|
|
|
|
return DD_OK;
|
|
}
|
|
|
|
HRESULT WINAPI extFlipToGDISurface1(LPDIRECTDRAW lpdd)
|
|
{ return extFlipToGDISurface(pFlipToGDISurface1, lpdd); }
|
|
HRESULT WINAPI extFlipToGDISurface2(LPDIRECTDRAW lpdd)
|
|
{ return extFlipToGDISurface(pFlipToGDISurface2, lpdd); }
|
|
HRESULT WINAPI extFlipToGDISurface3(LPDIRECTDRAW lpdd)
|
|
{ return extFlipToGDISurface(pFlipToGDISurface3, lpdd); }
|
|
HRESULT WINAPI extFlipToGDISurface4(LPDIRECTDRAW lpdd)
|
|
{ return extFlipToGDISurface(pFlipToGDISurface4, lpdd); }
|
|
HRESULT WINAPI extFlipToGDISurface7(LPDIRECTDRAW lpdd)
|
|
{ return extFlipToGDISurface(pFlipToGDISurface7, lpdd); }
|
|
|
|
HRESULT WINAPI extGetGDISurface(int dxversion, GetGDISurface_Type pGetGDISurface, LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE *w)
|
|
{
|
|
int res;
|
|
|
|
OutTraceDDRAW("GetGDISurface(%d): lpdd=%x\n", dxversion, lpdd);
|
|
|
|
// v2.02.31:
|
|
// in EMULATED mode, should not return the actual ddraw primary surface, but the virtual one.
|
|
if(dxw.dwFlags1 & EMULATESURFACE){
|
|
*w=dxwss.GetPrimarySurface();
|
|
OutTraceDW("GetGDISurface: EMULATED lpdd=%x w=%x\n", lpdd, *w);
|
|
return DD_OK;
|
|
}
|
|
|
|
res=(*pGetGDISurface)(lpdd, w);
|
|
if (res) {
|
|
OutTraceE("GetGDISurface: ERROR lpdd=%x res=%x(%s)\n", lpdd, res, ExplainDDError(res));
|
|
}
|
|
else {
|
|
OutTraceDDRAW("GetGDISurface: lpdd=%x w=%x\n", lpdd, *w);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extGetGDISurface1(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE *w)
|
|
{ return extGetGDISurface(1, pGetGDISurface1, lpdd, w); }
|
|
HRESULT WINAPI extGetGDISurface2(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE *w)
|
|
{ return extGetGDISurface(2, pGetGDISurface2, lpdd, w); }
|
|
HRESULT WINAPI extGetGDISurface3(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE *w)
|
|
{ return extGetGDISurface(3, pGetGDISurface3, lpdd, w); }
|
|
HRESULT WINAPI extGetGDISurface4(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE *w)
|
|
{ return extGetGDISurface(4, pGetGDISurface4, lpdd, w); }
|
|
HRESULT WINAPI extGetGDISurface7(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE *w)
|
|
{ return extGetGDISurface(7, pGetGDISurface7, lpdd, w); }
|
|
|
|
// debug function to dump all video modes queried by the DirectDrav::EnumDisplayModes method
|
|
|
|
HRESULT WINAPI EnumModesCallbackDumper(LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext)
|
|
{
|
|
OutTrace("EnumModesCallback:\n");
|
|
OutTrace("\tdwSize=%d\n", lpDDSurfaceDesc->dwSize);
|
|
OutTrace("\tddpfPixelFormat depth=%d rgba=(%X-%X-%X-%X)\n",
|
|
lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount,
|
|
lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask,
|
|
lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask,
|
|
lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask,
|
|
lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask);
|
|
OutTrace("\tdwFlags=%x(%s)\n", lpDDSurfaceDesc->dwFlags, ExplainFlags(lpDDSurfaceDesc->dwFlags));
|
|
OutTrace("\tdwWidth x dwHeight=(%d,%d)\n", lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight);
|
|
OutTrace("\tlPitch=%d\n", lpDDSurfaceDesc->lPitch);
|
|
//OutTrace("\tdwBackBufferCount=%d\n", lpDDSurfaceDesc->dwBackBufferCount);
|
|
OutTrace("\tdwRefreshRate=%d\n", lpDDSurfaceDesc->dwRefreshRate);
|
|
//OutTrace("\tlpSurface=%x\n", lpDDSurfaceDesc->lpSurface);
|
|
//OutTrace("\tCaps=%x(%s)\n", lpDDSurfaceDesc->ddsCaps.dwCaps, ExplainDDSCaps(lpDDSurfaceDesc->ddsCaps.dwCaps));
|
|
//if ((NewContext_Type *)lpContext->dxversion >= 4) {
|
|
// OutTrace("\tddpfPixelFormat %s\n", DumpPixelFormat((LPDDSURFACEDESC2)lpDDSurfaceDesc));
|
|
//}
|
|
|
|
#ifdef FULLHEXDUMP
|
|
OutTrace("DDSurfaceDesc=");
|
|
OutTraceHex((BYTE *)lpDDSurfaceDesc, sizeof(DDSURFACEDESC));
|
|
#endif
|
|
|
|
return DDENUMRET_OK;
|
|
}
|
|
|
|
typedef HRESULT (WINAPI *EnumModesCallback_Type)(LPDDSURFACEDESC, LPVOID);
|
|
typedef struct {
|
|
LPVOID lpContext;
|
|
EnumModesCallback_Type lpCallback;
|
|
DWORD dwWidth;
|
|
DWORD dwHeight;
|
|
int dxversion;
|
|
} NewContext_Type;
|
|
|
|
static BOOL CheckResolutionLimit(LPDDSURFACEDESC lpDDSurfaceDesc)
|
|
{
|
|
if(dxw.dwFlags4 & LIMITSCREENRES) {
|
|
#define HUGE 100000
|
|
DWORD maxw, maxh;
|
|
maxw=HUGE; maxh=HUGE;
|
|
switch(dxw.MaxScreenRes){
|
|
case DXW_LIMIT_320x200: maxw=320; maxh=200; break;
|
|
case DXW_LIMIT_640x480: maxw=640; maxh=480; break;
|
|
case DXW_LIMIT_800x600: maxw=800; maxh=600; break;
|
|
case DXW_LIMIT_1024x768: maxw=1024; maxh=768; break;
|
|
case DXW_LIMIT_1280x960: maxw=1280; maxh=960; break;
|
|
}
|
|
if((lpDDSurfaceDesc->dwWidth > maxw) || (lpDDSurfaceDesc->dwHeight > maxh)){
|
|
OutTraceDW("EnumDisplaySettings: hide device mode=(%d,%d)\n", maxw, maxh);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if(dxw.dwFlags7 & MAXIMUMRES) {
|
|
if((lpDDSurfaceDesc->dwWidth > (DWORD)dxw.iMaxW) || (lpDDSurfaceDesc->dwHeight > (DWORD)dxw.iMaxH)){
|
|
OutTraceDW("EnumDisplaySettings: hide device mode=(%d,%d)\n", dxw.iMaxW, dxw.iMaxH);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
HRESULT WINAPI myEnumModesFilterDirect(LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext)
|
|
{
|
|
HRESULT res;
|
|
SupportedRes_Type *SupportedRes;
|
|
|
|
if ((((NewContext_Type *)lpContext)->dwHeight != lpDDSurfaceDesc->dwHeight) ||
|
|
(((NewContext_Type *)lpContext)->dwWidth != lpDDSurfaceDesc->dwWidth)) return DDENUMRET_OK;
|
|
|
|
if (IsDebug) EnumModesCallbackDumper(lpDDSurfaceDesc, NULL);
|
|
|
|
// tricky part: for each color depth related to current video resolution, fake each of the
|
|
// supported resolutions, unless is greater than maximum allowed
|
|
|
|
SupportedRes = (dxw.dwFlags4 & SUPPORTHDTV) ? &SupportedHDTVRes[0] : &SupportedSVGARes[0];
|
|
|
|
for (int ResIdx=0; SupportedRes[ResIdx].h; ResIdx++){
|
|
lpDDSurfaceDesc->dwHeight=SupportedRes[ResIdx].h;
|
|
lpDDSurfaceDesc->dwWidth=SupportedRes[ResIdx].w;
|
|
if(CheckResolutionLimit(lpDDSurfaceDesc)) return DDENUMRET_OK;
|
|
res=(*((NewContext_Type *)lpContext)->lpCallback)(lpDDSurfaceDesc, ((NewContext_Type *)lpContext)->lpContext);
|
|
OutTraceDW("EnumDisplayModes(D): proposed size[%d]=(%d,%d) res=%x\n", ResIdx, SupportedRes[ResIdx].w, SupportedRes[ResIdx].h, res);
|
|
if(res==DDENUMRET_CANCEL) break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI myEnumModesFilterNative(LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext)
|
|
{
|
|
HRESULT res;
|
|
|
|
if (IsDebug) EnumModesCallbackDumper(lpDDSurfaceDesc, NULL);
|
|
|
|
if (dxw.dwFlags1 & PREVENTMAXIMIZE){
|
|
// if PREVENTMAXIMIZE is set, don't let the caller know about forbidden screen settings.
|
|
if((lpDDSurfaceDesc->dwHeight > dxw.GetScreenHeight()) ||
|
|
(lpDDSurfaceDesc->dwWidth > dxw.GetScreenWidth())){
|
|
OutTraceDW("EnumDisplayModes: skipping screen size=(%d,%d)\n", lpDDSurfaceDesc->dwHeight, lpDDSurfaceDesc->dwWidth);
|
|
return DDENUMRET_OK;
|
|
}
|
|
}
|
|
|
|
if(CheckResolutionLimit(lpDDSurfaceDesc)) return DDENUMRET_OK;
|
|
res=(*((NewContext_Type *)lpContext)->lpCallback)(lpDDSurfaceDesc, ((NewContext_Type *)lpContext)->lpContext);
|
|
OutTraceDW("EnumDisplayModes(D): native size=(%d,%d) bpp=%d res=%x\n", lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, res);
|
|
return res;
|
|
}
|
|
|
|
static char *sDisplayModesFlags(DWORD dwFlags)
|
|
{
|
|
static char sBuf[81];
|
|
size_t l;
|
|
strcpy(sBuf, "DDEDM_");
|
|
if(dwFlags & DDEDM_REFRESHRATES) strcat(sBuf, "REFRESHRATES+");
|
|
if(dwFlags & DDEDM_STANDARDVGAMODES) strcat(sBuf, "STANDARDVGAMODES+");
|
|
l=strlen(sBuf);
|
|
if (l>strlen("DDEDM_")) sBuf[l-1]=0; // delete last '+' if any
|
|
else sBuf[0]=0;
|
|
return(sBuf);
|
|
}
|
|
|
|
HRESULT WINAPI extEnumDisplayModes(int dxversion, EnumDisplayModes1_Type pEnumDisplayModes, LPDIRECTDRAW lpdd, DWORD dwflags, LPDDSURFACEDESC lpddsd, LPVOID lpContext, LPDDENUMMODESCALLBACK cb)
|
|
{
|
|
HRESULT res;
|
|
SupportedRes_Type *SupportedRes;
|
|
NewContext_Type NewContext;
|
|
|
|
OutTraceDDRAW("EnumDisplayModes(D%d): lpdd=%x flags=%x lpddsd=%x callback=%x\n", dxversion, lpdd, dwflags, lpddsd, cb);
|
|
if(lpddsd) OutTraceDDRAW("EnumDisplayModes(D): %s\n", LogSurfaceAttributes((LPDDSURFACEDESC2)lpddsd, "EnumDisplayModes", __LINE__));
|
|
|
|
if ((dxw.dwFlags4 & NATIVERES) ||
|
|
(!(dxw.dwFlags1 & EMULATESURFACE) && !dxw.Windowize)){ // v2.04.14 - make nonemulated nonwindowed mode work ...
|
|
NewContext.dwWidth = 0;
|
|
NewContext.dwHeight = 0;
|
|
NewContext.lpContext = lpContext;
|
|
NewContext.lpCallback = cb;
|
|
NewContext.dxversion = dxversion;
|
|
res=(*pEnumDisplayModes)(lpdd, dwflags, lpddsd, &NewContext, myEnumModesFilterNative);
|
|
if(res) OutTraceE("EnumDisplayModes(D): ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
|
|
// note: extEnumDisplayModes serves both the EnumDisplayModes and EnumDisplayModes2 interfaces:
|
|
// they differ for the lpddsd argument that should point to either DDSURFACEDESC or DDSURFACEDESC2
|
|
// structures, but unification is possible if the lpddsd->dwSize is properly set and is left untouched.
|
|
|
|
if((dxw.dwFlags1 & EMULATESURFACE)){
|
|
int SupportedDepths[5]={8,16,24,32,0};
|
|
int ResIdx, DepthIdx;
|
|
DDSURFACEDESC2 EmuDesc;
|
|
DWORD dwSize;
|
|
|
|
EmuDesc.dwRefreshRate = 0;
|
|
EmuDesc.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
|
if (lpddsd) dwSize=lpddsd->dwSize; // sizeof either DDSURFACEDESC or DDSURFACEDESC2 !!!
|
|
else dwSize= (dxversion < 4) ? sizeof(DDSURFACEDESC) : sizeof(DDSURFACEDESC2);
|
|
memset(&EmuDesc, 0, dwSize);
|
|
EmuDesc.dwSize=dwSize;
|
|
EmuDesc.dwFlags=DDSD_PIXELFORMAT|DDSD_REFRESHRATE|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH;
|
|
SupportedRes = (dxw.dwFlags4 & SUPPORTHDTV) ? &SupportedHDTVRes[0] : &SupportedSVGARes[0];
|
|
res=DD_OK;
|
|
for (ResIdx=0; SupportedRes[ResIdx].h; ResIdx++){
|
|
EmuDesc.dwHeight=SupportedRes[ResIdx].h;
|
|
EmuDesc.dwWidth=SupportedRes[ResIdx].w;
|
|
if(CheckResolutionLimit((LPDDSURFACEDESC)&EmuDesc)) break;
|
|
EmuDesc.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT);
|
|
EmuDesc.ddpfPixelFormat.dwFlags=DDPF_RGB;
|
|
for (DepthIdx=0; SupportedDepths[DepthIdx]; DepthIdx++) {
|
|
// v2.03.24: if lpddsd is not null, compatible colr depth must be selected. Skip incompatible ones.
|
|
// Fixes "Total Annihilation Kingdoms" crash
|
|
if(lpddsd && (lpddsd->dwFlags & DDSD_PIXELFORMAT) && (lpddsd->ddpfPixelFormat.dwRGBBitCount != SupportedDepths[DepthIdx])) continue;
|
|
EmuDesc.ddpfPixelFormat.dwRGBBitCount=SupportedDepths[DepthIdx];
|
|
EmuDesc.lPitch=SupportedRes[ResIdx].w * SupportedDepths[DepthIdx] / 8;
|
|
FixPixelFormat(EmuDesc.ddpfPixelFormat.dwRGBBitCount, &(EmuDesc.ddpfPixelFormat));
|
|
if(IsDebug) EnumModesCallbackDumper((LPDDSURFACEDESC)&EmuDesc, lpContext);
|
|
res=(*cb)((LPDDSURFACEDESC)&EmuDesc, lpContext);
|
|
if(res==DDENUMRET_CANCEL) break;
|
|
}
|
|
if(res==DDENUMRET_CANCEL) break;
|
|
}
|
|
res=DD_OK;
|
|
}
|
|
else{
|
|
DDSURFACEDESC2 EmuDesc;
|
|
memset(&EmuDesc, 0, sizeof(EmuDesc));
|
|
EmuDesc.dwSize = sizeof(DDSURFACEDESC); // using release 1 type ....
|
|
res=myGetDisplayMode(dxversion, lpdd, (LPDDSURFACEDESC)&EmuDesc);
|
|
if(res){
|
|
OutTraceE("EnumDisplayModes(D): GetDisplayMode ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
NewContext_Type NewContext;
|
|
NewContext.dwWidth = EmuDesc.dwWidth;
|
|
NewContext.dwHeight = EmuDesc.dwHeight;
|
|
NewContext.lpContext=lpContext;
|
|
NewContext.lpCallback=cb;
|
|
res=(*pEnumDisplayModes)(lpdd, dwflags, lpddsd, &NewContext, myEnumModesFilterDirect);
|
|
}
|
|
if(res) OutTraceE("EnumDisplayModes(D): ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extEnumDisplayModes1(LPDIRECTDRAW lpdd, DWORD dwflags, LPDDSURFACEDESC lpddsd, LPVOID lpContext, LPDDENUMMODESCALLBACK cb)
|
|
{ return extEnumDisplayModes(1, pEnumDisplayModes1, lpdd, dwflags, lpddsd, lpContext, cb); }
|
|
HRESULT WINAPI extEnumDisplayModes2(LPDIRECTDRAW lpdd, DWORD dwflags, LPDDSURFACEDESC lpddsd, LPVOID lpContext, LPDDENUMMODESCALLBACK cb)
|
|
{ return extEnumDisplayModes(2, pEnumDisplayModes2, lpdd, dwflags, lpddsd, lpContext, cb); }
|
|
HRESULT WINAPI extEnumDisplayModes3(LPDIRECTDRAW lpdd, DWORD dwflags, LPDDSURFACEDESC lpddsd, LPVOID lpContext, LPDDENUMMODESCALLBACK cb)
|
|
{ return extEnumDisplayModes(3, pEnumDisplayModes3, lpdd, dwflags, lpddsd, lpContext, cb); }
|
|
HRESULT WINAPI extEnumDisplayModes4(LPDIRECTDRAW lpdd, DWORD dwflags, LPDDSURFACEDESC2 lpddsd, LPVOID lpContext, LPDDENUMMODESCALLBACK2 cb)
|
|
{ return extEnumDisplayModes(4, (EnumDisplayModes1_Type)pEnumDisplayModes4, lpdd, dwflags, (LPDDSURFACEDESC)lpddsd, lpContext, (LPDDENUMMODESCALLBACK)cb); }
|
|
HRESULT WINAPI extEnumDisplayModes7(LPDIRECTDRAW lpdd, DWORD dwflags, LPDDSURFACEDESC2 lpddsd, LPVOID lpContext, LPDDENUMMODESCALLBACK2 cb)
|
|
{ return extEnumDisplayModes(7, (EnumDisplayModes1_Type)pEnumDisplayModes7, lpdd, dwflags, (LPDDSURFACEDESC)lpddsd, lpContext, (LPDDENUMMODESCALLBACK)cb); }
|
|
|
|
HRESULT WINAPI extGetPixelFormat(GetPixelFormat_Type pGetPixelFormat, LPDIRECTDRAWSURFACE lpdds, LPDDPIXELFORMAT p)
|
|
{
|
|
DWORD res;
|
|
BOOL IsPrim;
|
|
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
OutTraceDDRAW("GetPixelFormat: lpdds=%x%s\n", lpdds, IsPrim?"(PRIM)":"");
|
|
res=(*pGetPixelFormat)(lpdds, p);
|
|
if(res){
|
|
OutTraceE("GetPixelFormat: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
else{
|
|
OutTraceDDRAW("GetPixelFormat: Flags=%x(%s) FourCC=%x BitCount=%d RGBA=(%x,%x,%x,%x)\n",
|
|
p->dwFlags, ExplainPixelFormatFlags(p->dwFlags), p->dwFourCC, p->dwRGBBitCount,
|
|
p->dwRBitMask, p->dwGBitMask, p->dwBBitMask, p->dwRGBAlphaBitMask );
|
|
}
|
|
|
|
// fix: virtual pixel definition is helpful not only on promary surfaces, but more in general
|
|
// on every surface that returns an error. It fixes "Arx Fatalis" crash.
|
|
if ((dxw.dwFlags1 & EMULATESURFACE) && res){
|
|
p->dwFlags = dxw.VirtualPixelFormat.dwFlags;
|
|
p->dwRGBBitCount= dxw.VirtualPixelFormat.dwRGBBitCount;
|
|
p->dwRBitMask = dxw.VirtualPixelFormat.dwRBitMask;
|
|
p->dwGBitMask = dxw.VirtualPixelFormat.dwGBitMask;
|
|
p->dwBBitMask = dxw.VirtualPixelFormat.dwBBitMask;
|
|
p->dwRGBAlphaBitMask = dxw.VirtualPixelFormat.dwRGBAlphaBitMask;
|
|
OutTraceDW("GetPixelFormat: EMULATED BitCount=%d RGBA=(%x,%x,%x,%x)\n",
|
|
p->dwRGBBitCount, p->dwRBitMask, p->dwGBitMask, p->dwBBitMask, p->dwRGBAlphaBitMask );
|
|
res = DD_OK;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extGetPixelFormat1(LPDIRECTDRAWSURFACE lpdds, LPDDPIXELFORMAT p)
|
|
{ return extGetPixelFormat(pGetPixelFormat1, lpdds, p); }
|
|
HRESULT WINAPI extGetPixelFormat2(LPDIRECTDRAWSURFACE lpdds, LPDDPIXELFORMAT p)
|
|
{ return extGetPixelFormat(pGetPixelFormat2, lpdds, p); }
|
|
HRESULT WINAPI extGetPixelFormat3(LPDIRECTDRAWSURFACE lpdds, LPDDPIXELFORMAT p)
|
|
{ return extGetPixelFormat(pGetPixelFormat3, lpdds, p); }
|
|
HRESULT WINAPI extGetPixelFormat4(LPDIRECTDRAWSURFACE lpdds, LPDDPIXELFORMAT p)
|
|
{ return extGetPixelFormat(pGetPixelFormat4, lpdds, p); }
|
|
HRESULT WINAPI extGetPixelFormat7(LPDIRECTDRAWSURFACE lpdds, LPDDPIXELFORMAT p)
|
|
{ return extGetPixelFormat(pGetPixelFormat7, lpdds, p); }
|
|
|
|
HRESULT WINAPI extTestCooperativeLevel(TestCooperativeLevel_Type pTestCooperativeLevel, LPDIRECTDRAW lpdd)
|
|
{
|
|
HRESULT res;
|
|
res=(*pTestCooperativeLevel)(lpdd);
|
|
OutTraceB("TestCooperativeLevel: lpdd=%x res=%x(%s)\n", lpdd, res, ExplainDDError(res));
|
|
if(res==DDERR_WRONGMODE) {
|
|
res=((LPDIRECTDRAW7)lpdd)->RestoreAllSurfaces();
|
|
if(res) OutTraceE("TestCooperativeLevel: RestoreAllSurfaces ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extTestCooperativeLevel4(LPDIRECTDRAW lpdd)
|
|
{ return extTestCooperativeLevel(pTestCooperativeLevel4, lpdd); }
|
|
HRESULT WINAPI extTestCooperativeLevel7(LPDIRECTDRAW lpdd)
|
|
{ return extTestCooperativeLevel(pTestCooperativeLevel7, lpdd); }
|
|
|
|
HRESULT WINAPI extReleaseS(ReleaseS_Type pReleaseS, LPDIRECTDRAWSURFACE lpdds)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsPrim;
|
|
BOOL IsBack;
|
|
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
IsBack=dxwss.IsABackBufferSurface(lpdds);
|
|
|
|
// fix for Tetris World .... ???
|
|
if (IsBack && (dxw.dwFlags6 & SUPPRESSRELEASE)) {
|
|
OutTraceDDRAW("Release(S): SUPPRESS lpdds=%x%s res=0\n", lpdds, dxwss.ExplainSurfaceRole(lpdds));
|
|
return 0;
|
|
}
|
|
|
|
__try { // try/except useful when using proxy dll
|
|
res = (*pReleaseS)(lpdds);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER){
|
|
OutTraceE("Release(S): EXCEPTION lpdds=%x%s res=0\n", lpdds, dxwss.ExplainSurfaceRole(lpdds));
|
|
res = 0;
|
|
}
|
|
|
|
OutTraceDDRAW("Release(S): lpdds=%x%s refcount=%d\n", lpdds, dxwss.ExplainSurfaceRole(lpdds), res);
|
|
if (res==0) { // common precondition
|
|
// erase surface from primary or backbuffer list
|
|
// v2-03-20: d3d 1-7 play a dirty trick: it Release the surface passed as argument until refcount == 0,
|
|
// but then rebuilds it with the original attributes! So, better not forget them.
|
|
if(IsPrim || IsBack) dxwss.UnrefSurface(lpdds);
|
|
|
|
// when releasing primary surface, erase clipping region
|
|
// v2.04.14: commented out, better not to! The game could close and reopen a new primary surface.
|
|
// fixes "Settlers III" clipping problems
|
|
// if(IsPrim && (dxw.dwFlags1 & CLIPCURSOR)) dxw.EraseClipCursor();
|
|
|
|
// clear service surface pointers
|
|
if (dxw.dwFlags1 & EMULATESURFACE) {
|
|
if(lpdds==lpDDSEmu_Prim) {
|
|
OutTraceDW("Release(S): Clearing lpDDSEmu_Prim pointer\n");
|
|
lpDDSEmu_Prim=NULL;
|
|
}
|
|
if(lpdds==lpDDSEmu_Back) {
|
|
OutTraceDW("Release(S): Clearing lpDDSEmu_Back pointer\n");
|
|
lpDDSEmu_Back=NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(dxw.dwFlags4 & RETURNNULLREF) return 0;
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extReleaseS1(LPDIRECTDRAWSURFACE lpdds)
|
|
{ return extReleaseS(pReleaseS1, lpdds); }
|
|
HRESULT WINAPI extReleaseS2(LPDIRECTDRAWSURFACE lpdds)
|
|
{ return extReleaseS(pReleaseS2, lpdds); }
|
|
HRESULT WINAPI extReleaseS3(LPDIRECTDRAWSURFACE lpdds)
|
|
{ return extReleaseS(pReleaseS3, lpdds); }
|
|
HRESULT WINAPI extReleaseS4(LPDIRECTDRAWSURFACE lpdds)
|
|
{ return extReleaseS(pReleaseS4, lpdds); }
|
|
HRESULT WINAPI extReleaseS7(LPDIRECTDRAWSURFACE lpdds)
|
|
{ return extReleaseS(pReleaseS7, lpdds); }
|
|
|
|
static HRESULT WINAPI extSetColorKey(SetColorKey_Type pSetColorKey, LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsPrim;
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
if(IsTraceDDRAW){
|
|
char sInfo[81];
|
|
if (lpDDColorKey) sprintf(sInfo, "(L:%x,H:%x)",lpDDColorKey->dwColorSpaceLowValue, lpDDColorKey->dwColorSpaceHighValue);
|
|
else strcpy(sInfo, "(NULL)");
|
|
OutTrace("SetColorKey: lpdds=%x%s flags=%x(%s) colors=%s\n",
|
|
lpdds, (IsPrim ? "(PRIM)" : ""), flags, ExplainColorKeyFlag(flags), sInfo);
|
|
}
|
|
|
|
res=(*pSetColorKey)(lpdds, flags, lpDDColorKey);
|
|
if(res) OutTraceE("SetColorKey: ERROR flags=%x lpdds=%x res=%x(%s)\n",
|
|
flags, lpdds, res, ExplainDDError(res));
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extSetColorKey1(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{ return extSetColorKey(pSetColorKey1, lpdds, flags, lpDDColorKey); }
|
|
HRESULT WINAPI extSetColorKey2(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{ return extSetColorKey(pSetColorKey2, lpdds, flags, lpDDColorKey); }
|
|
HRESULT WINAPI extSetColorKey3(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{ return extSetColorKey(pSetColorKey3, lpdds, flags, lpDDColorKey); }
|
|
HRESULT WINAPI extSetColorKey4(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{ return extSetColorKey(pSetColorKey4, lpdds, flags, lpDDColorKey); }
|
|
HRESULT WINAPI extSetColorKey7(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{ return extSetColorKey(pSetColorKey7, lpdds, flags, lpDDColorKey); }
|
|
|
|
static HRESULT WINAPI extGetColorKey(int dxversion, GetColorKey_Type pGetColorKey, LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsPrim;
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
OutTraceDDRAW("GetColorKey(S%d): lpdds=%x%s flags=%x(%s)\n",
|
|
dxversion, lpdds, (IsPrim ? "(PRIM)" : ""), flags, ExplainColorKeyFlag(flags));
|
|
res=(*pGetColorKey)(lpdds, flags, lpDDColorKey);
|
|
if(res)
|
|
OutTraceE("GetColorKey: ERROR lpdds=%x flags=%x res=%x(%s)\n", lpdds, flags, res, ExplainDDError(res));
|
|
else
|
|
OutTraceDDRAW("GetColorKey: colors=(L:%x,H:%x)\n",
|
|
lpDDColorKey->dwColorSpaceLowValue, lpDDColorKey->dwColorSpaceHighValue);
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extGetColorKey1(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{ return extGetColorKey(1, pGetColorKey1, lpdds, flags, lpDDColorKey); }
|
|
HRESULT WINAPI extGetColorKey2(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{ return extGetColorKey(2, pGetColorKey2, lpdds, flags, lpDDColorKey); }
|
|
HRESULT WINAPI extGetColorKey3(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{ return extGetColorKey(3, pGetColorKey3, lpdds, flags, lpDDColorKey); }
|
|
HRESULT WINAPI extGetColorKey4(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{ return extGetColorKey(4, pGetColorKey4, lpdds, flags, lpDDColorKey); }
|
|
HRESULT WINAPI extGetColorKey7(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey)
|
|
{ return extGetColorKey(7, pGetColorKey7, lpdds, flags, lpDDColorKey); }
|
|
|
|
static HRESULT WINAPI extEnumAttachedSurfaces(EnumAttachedSurfaces_Type pEnumAttachedSurfaces, LPDIRECTDRAWSURFACE lpdds, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsPrim, IsBack;
|
|
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
IsBack=dxwss.IsABackBufferSurface(lpdds);
|
|
|
|
OutTraceDDRAW("EnumAttachedSurfaces: lpdds=%x%s Context=%x Callback=%x\n",
|
|
lpdds, (IsPrim ? "(PRIM)":""), lpContext, lpEnumSurfacesCallback);
|
|
|
|
if (IsPrim){
|
|
LPDIRECTDRAWSURFACE lpDDSBack;
|
|
// A Primary surface has not backbuffer attached surfaces actually,
|
|
// so don't rely on ddraw and call the callback function directly.
|
|
// Needed to make Nox working.
|
|
DDSURFACEDESC2 ddsd;
|
|
// first, call hooked function
|
|
res=(*pEnumAttachedSurfaces)(lpdds, lpContext, lpEnumSurfacesCallback);
|
|
if (res)
|
|
OutTraceE("EnumAttachedSurfaces: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
if(lpDDSBack = dxwss.GetBackBufferSurface()){
|
|
ddsd.dwSize=Set_dwSize_From_Surface();
|
|
res=lpDDSBack->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
|
|
if(res){
|
|
OutTraceE("EnumAttachedSurfaces: GetSurfaceDesc ERROR %x(%s)\n",
|
|
res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
res=(lpEnumSurfacesCallback)(lpDDSBack, (LPDDSURFACEDESC)&ddsd, lpContext);
|
|
OutTraceDW("EnumSurfacesCallback: on DDSBack res=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
return DD_OK; // for Black Dahlia
|
|
}
|
|
|
|
if(IsBack){
|
|
LPDIRECTDRAWSURFACE lpDDSPrim;
|
|
// A Primary surface has not backbuffer attached surfaces actually,
|
|
// so don't rely on ddraw and call the callback function directly.
|
|
// Needed to make Nox working.
|
|
DDSURFACEDESC2 ddsd;
|
|
// first, call hooked function
|
|
res=(*pEnumAttachedSurfaces)(lpdds, lpContext, lpEnumSurfacesCallback);
|
|
if (res)
|
|
OutTraceE("EnumAttachedSurfaces: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
if(lpDDSPrim = dxwss.GetPrimarySurface()){
|
|
ddsd.dwSize=Set_dwSize_From_Surface();
|
|
res=lpDDSPrim->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
|
|
if(res){
|
|
OutTraceE("EnumAttachedSurfaces: GetSurfaceDesc ERROR %x(%s)\n",
|
|
res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
res=(lpEnumSurfacesCallback)(lpDDSPrim, (LPDDSURFACEDESC)&ddsd, lpContext);
|
|
OutTraceDW("EnumSurfacesCallback: on DDSPrim res=%x(%s)\n", res, ExplainDDError(res));
|
|
}
|
|
return DD_OK; // for GTA (first episode, window version "gtawin.exe")
|
|
}
|
|
res=(*pEnumAttachedSurfaces)(lpdds, lpContext, lpEnumSurfacesCallback);
|
|
if (res)
|
|
OutTraceE("EnumAttachedSurfaces: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extEnumAttachedSurfaces1(LPDIRECTDRAWSURFACE lpdds, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
|
|
{ return extEnumAttachedSurfaces(pEnumAttachedSurfaces1, lpdds, lpContext, lpEnumSurfacesCallback); }
|
|
HRESULT WINAPI extEnumAttachedSurfaces2(LPDIRECTDRAWSURFACE lpdds, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
|
|
{ return extEnumAttachedSurfaces(pEnumAttachedSurfaces2, lpdds, lpContext, lpEnumSurfacesCallback); }
|
|
HRESULT WINAPI extEnumAttachedSurfaces3(LPDIRECTDRAWSURFACE lpdds, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
|
|
{ return extEnumAttachedSurfaces(pEnumAttachedSurfaces3, lpdds, lpContext, lpEnumSurfacesCallback); }
|
|
HRESULT WINAPI extEnumAttachedSurfaces4(LPDIRECTDRAWSURFACE lpdds, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
|
|
{ return extEnumAttachedSurfaces(pEnumAttachedSurfaces4, lpdds, lpContext, lpEnumSurfacesCallback); }
|
|
HRESULT WINAPI extEnumAttachedSurfaces7(LPDIRECTDRAWSURFACE lpdds, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
|
|
{ return extEnumAttachedSurfaces(pEnumAttachedSurfaces7, lpdds, lpContext, lpEnumSurfacesCallback); }
|
|
|
|
static HRESULT WINAPI extAddAttachedSurface(AddAttachedSurface_Type pAddAttachedSurface, LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsPrim, IsBack;
|
|
|
|
// You can add backbuffers to primary surfaces to join the flipping chain, but you can't do that
|
|
// to an emulated primary surface, and you receive a DDERR_CANNOTATTACHSURFACE error code.
|
|
// In that case, it's worth to try to emulate the attach, and since the Flip method is emulated,
|
|
// just remember this for further handling in the Flip operation.
|
|
// But beware: this holds to BACKBUFFER surfaces only, and NOT for attached ZBUFFERS or similar!
|
|
|
|
// If the surface was created with DDSCAPS_BACKBUFFER/ZBUFFER capabilities, it should be in the
|
|
// surface stack already, so better avoid setting unknown version and capabilities here...
|
|
|
|
// Note: should DxWnd trace the difference between a potential BACK/ZBUFFER surface and an active one?
|
|
// The program can create a surface with backbuffer/zbuffer capabilities, but assign the effective
|
|
// role afterwards, here while performing the attach to the master surface.
|
|
|
|
IsPrim=dxwss.IsAPrimarySurface(lpdds);
|
|
IsBack=dxwss.IsABackBufferSurface(lpdds);
|
|
OutTraceDDRAW("AddAttachedSurface: lpdds=%x%s lpddsadd=%x%s\n", lpdds, IsPrim?"(PRIM)":(IsBack?"(BACK)":""), lpddsadd, (lpddsadd==lpDDZBuffer)?"(ZBUF)":"");
|
|
|
|
//if(!lpddsadd) return DDERR_CANNOTATTACHSURFACE; // to avoid a crash...
|
|
res=(*pAddAttachedSurface)(lpdds, lpddsadd);
|
|
if (res) {
|
|
HRESULT sdres;
|
|
DDSURFACEDESC2 sd;
|
|
if (res) OutTraceE("AddAttachedSurface: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
|
|
sd.dwSize=Set_dwSize_From_Surface();
|
|
sdres=lpddsadd->GetSurfaceDesc((DDSURFACEDESC *)&sd);
|
|
if (sdres)
|
|
OutTraceE("AddAttachedSurface: GetSurfaceDesc ERROR res=%x at %d\n", sdres, __LINE__);
|
|
else
|
|
OutTraceDW("AddAttachedSurface: GetSurfaceDesc dwCaps=%x(%s)\n",
|
|
sd.ddsCaps.dwCaps, ExplainDDSCaps(sd.ddsCaps.dwCaps));
|
|
if (IsPrim){
|
|
if (sd.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)
|
|
if ((dxw.dwFlags1 & EMULATESURFACE) && (res==DDERR_CANNOTATTACHSURFACE) ||
|
|
(res==DDERR_NOEXCLUSIVEMODE))
|
|
OutTraceDW("AddAttachedSurface: emulating BACKBUFFER attach on PRIMARY\n");
|
|
res=DD_OK;
|
|
}
|
|
//else if (IsBack) {
|
|
else {
|
|
// v2.02.13: emulate ZBUFFER attach to backbuffer/plain surface: do nothing and return OK
|
|
// this trick makes at least "Nocturne" work also in emulated mode when hardware acceleration
|
|
// is set in the game "Options" menu.
|
|
if (sd.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) // DDSCAPS_BACKBUFFER for double buffering ???
|
|
if ((dxw.dwFlags1 & EMULATESURFACE) && (res==DDERR_CANNOTATTACHSURFACE)){
|
|
OutTraceDW("AddAttachedSurface: emulating ZBUFFER attach on %s surface\n", IsBack ? "BACKBUFFER" : "PLAIN");
|
|
res=DD_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (res) OutTraceE("AddAttachedSurface: ERROR %x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extAddAttachedSurface1(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd)
|
|
{ return extAddAttachedSurface(pAddAttachedSurface1, lpdds, lpddsadd); }
|
|
HRESULT WINAPI extAddAttachedSurface2(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd)
|
|
{ return extAddAttachedSurface(pAddAttachedSurface2, lpdds, lpddsadd); }
|
|
HRESULT WINAPI extAddAttachedSurface3(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd)
|
|
{ return extAddAttachedSurface(pAddAttachedSurface3, lpdds, lpddsadd); }
|
|
HRESULT WINAPI extAddAttachedSurface4(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd)
|
|
{ return extAddAttachedSurface(pAddAttachedSurface4, lpdds, lpddsadd); }
|
|
HRESULT WINAPI extAddAttachedSurface7(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd)
|
|
{ return extAddAttachedSurface(pAddAttachedSurface7, lpdds, lpddsadd); }
|
|
|
|
static HRESULT WINAPI extDeleteAttachedSurface(DeleteAttachedSurface_Type pDeleteAttachedSurface, LPDIRECTDRAWSURFACE lpdds, DWORD dwflags, LPDIRECTDRAWSURFACE lpddsdel)
|
|
{
|
|
HRESULT res;
|
|
OutTraceDDRAW("DeleteAttachedSurface: lpdds=%x flags=%x lpddsdel=%x\n", lpdds, dwflags, lpddsdel);
|
|
res=(*pDeleteAttachedSurface)(lpdds, dwflags, lpddsdel);
|
|
if(res) OutTraceE("DeleteAttachedSurface: ERROR %x(%s)\n", res, ExplainDDError(res));
|
|
if (res && dxwss.IsABackBufferSurface(lpddsdel)){
|
|
OutTraceDW("DeleteAttachedSurface: emulating surface detach lpdds=%x\n", lpddsdel);
|
|
res = DD_OK;
|
|
}
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extDeleteAttachedSurface1(LPDIRECTDRAWSURFACE lpdds, DWORD dwflags, LPDIRECTDRAWSURFACE lpddsdel)
|
|
{ return extDeleteAttachedSurface(pDeleteAttachedSurface1, lpdds, dwflags, lpddsdel); }
|
|
HRESULT WINAPI extDeleteAttachedSurface2(LPDIRECTDRAWSURFACE lpdds, DWORD dwflags, LPDIRECTDRAWSURFACE lpddsdel)
|
|
{ return extDeleteAttachedSurface(pDeleteAttachedSurface2, lpdds, dwflags, lpddsdel); }
|
|
HRESULT WINAPI extDeleteAttachedSurface3(LPDIRECTDRAWSURFACE lpdds, DWORD dwflags, LPDIRECTDRAWSURFACE lpddsdel)
|
|
{ return extDeleteAttachedSurface(pDeleteAttachedSurface3, lpdds, dwflags, lpddsdel); }
|
|
HRESULT WINAPI extDeleteAttachedSurface4(LPDIRECTDRAWSURFACE lpdds, DWORD dwflags, LPDIRECTDRAWSURFACE lpddsdel)
|
|
{ return extDeleteAttachedSurface(pDeleteAttachedSurface4, lpdds, dwflags, lpddsdel); }
|
|
HRESULT WINAPI extDeleteAttachedSurface7(LPDIRECTDRAWSURFACE lpdds, DWORD dwflags, LPDIRECTDRAWSURFACE lpddsdel)
|
|
{ return extDeleteAttachedSurface(pDeleteAttachedSurface7, lpdds, dwflags, lpddsdel); }
|
|
|
|
HRESULT WINAPI cbDump(LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext)
|
|
{
|
|
OutTraceDW("EnumDisplayModes: CALLBACK lpdds=%x Context=%x Caps=%x(%s)\n",
|
|
lpDDSurfaceDesc, lpContext,
|
|
lpDDSurfaceDesc->ddsCaps.dwCaps, ExplainDDSCaps(lpDDSurfaceDesc->ddsCaps.dwCaps));
|
|
return 1;
|
|
}
|
|
|
|
// BEWARE!!!
|
|
// in order to meet Direct3D expectations, it seems that we require this policy:
|
|
// when a ZBUFFER surface is created, its dwCaps value must be saved and restored identically on GetSurfaceDesc and GetCaps
|
|
// A surface is known to be virtually a primary or backbuffer only by looking at the surfaces stack dxwss
|
|
// On the contrary, a surface is known to be a ZBUFFER only after retrieving its capabilities with pGetCaps or pGetSurfaceDesc
|
|
// hence the IsZBuf flag is set after the query and can't be reflected in the first log line!
|
|
// The same comment / logic is valid also for extGetSurfaceDesc wrapper
|
|
|
|
static HRESULT WINAPI extGetCapsS(int dxInterface, GetCapsS_Type pGetCapsS, LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS caps)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsFixed=FALSE;
|
|
int role;
|
|
SurfaceDB_Type *ps;
|
|
char *sLabel;
|
|
|
|
ps = dxwss.GetSurface(lpdds);
|
|
|
|
// BEWARE: ZBUFFER surfaces could be created automatically so that they could exist without
|
|
// being regisered in surface stack. You must query the actual surface capabilities.
|
|
res=(*pGetCapsS)(lpdds, caps);
|
|
if(res)
|
|
OutTraceE("GetCaps(S%d): ERROR lpdds=%x err=%x(%s)\n", dxInterface, lpdds, res, ExplainDDError(res));
|
|
else
|
|
OutTraceDDRAW("GetCaps(S%d): lpdds=%x caps=%x(%s)\n", dxInterface, lpdds, caps->dwCaps, ExplainDDSCaps(caps->dwCaps));
|
|
|
|
sLabel="";
|
|
role = SURFACE_ROLE_UNKNOWN;
|
|
if (ps) {
|
|
role = ps->uRole;
|
|
switch(role){
|
|
case SURFACE_ROLE_PRIMARY: sLabel="(PRIM)"; break;
|
|
case SURFACE_ROLE_BACKBUFFER: sLabel="(BACK)"; break;
|
|
case SURFACE_ROLE_ZBUFFER: sLabel="(ZBUF)"; break;
|
|
case SURFACE_ROLE_3DREF: sLabel="(3DREF)"; break;
|
|
}
|
|
}
|
|
else {
|
|
if (caps->dwCaps & DDSCAPS_ZBUFFER) {
|
|
sLabel="(ZBUF)";
|
|
role = SURFACE_ROLE_ZBUFFER;
|
|
}
|
|
}
|
|
|
|
if(!(dxw.IsEmulated || dxw.Windowize)) return res;
|
|
|
|
switch(role) {
|
|
case SURFACE_ROLE_PRIMARY:
|
|
IsFixed=TRUE;
|
|
caps->dwCaps = SetPrimaryCaps(dxwss.GetCaps(lpdds));
|
|
break;
|
|
case SURFACE_ROLE_BACKBUFFER:
|
|
IsFixed=TRUE;
|
|
caps->dwCaps = SetBackBufferCaps(dxwss.GetCaps(lpdds));
|
|
break;
|
|
case SURFACE_ROLE_ZBUFFER:
|
|
IsFixed=TRUE;
|
|
caps->dwCaps = SetZBufferCaps(dxwss.GetCaps(lpdds));
|
|
break;
|
|
case SURFACE_ROLE_3DREF:
|
|
IsFixed=TRUE;
|
|
caps->dwCaps = dxwss.GetCaps(lpdds);
|
|
break;
|
|
}
|
|
|
|
if(IsFixed) OutTraceDW("GetCaps(S%d): lpdds=%x FIXED %s caps=%x(%s)\n", dxInterface, lpdds, sLabel, caps->dwCaps, ExplainDDSCaps(caps->dwCaps));
|
|
if(IsTraceHex) HexTrace((unsigned char *)caps, sizeof(DDSCAPS));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extGetCaps1S(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS caps)
|
|
{ return extGetCapsS(1, pGetCaps1S, lpdds, caps); }
|
|
HRESULT WINAPI extGetCaps2S(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS caps)
|
|
{ return extGetCapsS(2, pGetCaps2S, lpdds, caps); }
|
|
HRESULT WINAPI extGetCaps3S(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS caps)
|
|
{ return extGetCapsS(3, pGetCaps3S, lpdds, caps); }
|
|
HRESULT WINAPI extGetCaps4S(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS2 caps)
|
|
{ return extGetCapsS(4, (GetCapsS_Type)pGetCaps4S, lpdds, (LPDDSCAPS)caps); }
|
|
HRESULT WINAPI extGetCaps7S(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS2 caps)
|
|
{ return extGetCapsS(7, (GetCapsS_Type)pGetCaps7S, lpdds, (LPDDSCAPS)caps); }
|
|
|
|
static HRESULT WINAPI extGetSurfaceDesc(int dxversion, GetSurfaceDesc_Type pGetSurfaceDesc, LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd)
|
|
{
|
|
HRESULT res;
|
|
BOOL IsFixed = FALSE;
|
|
SurfaceDB_Type *ps;
|
|
int role;
|
|
char *sLabel;
|
|
|
|
if (!pGetSurfaceDesc) {
|
|
OutTraceE("GetSurfaceDesc: ERROR no hooked function\n");
|
|
return DDERR_INVALIDPARAMS;
|
|
}
|
|
|
|
ps = dxwss.GetSurface(lpdds);
|
|
|
|
int prevsize = lpddsd->dwSize;
|
|
switch(dxversion){
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
lpddsd->dwSize = sizeof(DDSURFACEDESC);
|
|
break;
|
|
case 4:
|
|
case 7:
|
|
lpddsd->dwSize = sizeof(DDSURFACEDESC2);
|
|
break;
|
|
}
|
|
if(prevsize != lpddsd->dwSize) OutTraceDW("GetSurfaceDesc(%d): FIXED dwSize=%d->%d\n", dxversion, prevsize, lpddsd->dwSize);
|
|
|
|
res=(*pGetSurfaceDesc)(lpdds, lpddsd);
|
|
if(res) {
|
|
OutTraceE("GetSurfaceDesc(%d): ERROR err=%x(%s)\n", dxversion, res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
sLabel="";
|
|
role = SURFACE_ROLE_UNKNOWN;
|
|
if (ps) {
|
|
role = ps->uRole;
|
|
switch(role){
|
|
case SURFACE_ROLE_PRIMARY: sLabel="(PRIM)"; break;
|
|
case SURFACE_ROLE_BACKBUFFER: sLabel="(BACK)"; break;
|
|
case SURFACE_ROLE_ZBUFFER: sLabel="(ZBUF)"; break;
|
|
case SURFACE_ROLE_3DREF: sLabel="(3DREF)"; break;
|
|
}
|
|
}
|
|
else {
|
|
if (lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) {
|
|
sLabel="(ZBUF)";
|
|
role = SURFACE_ROLE_ZBUFFER;
|
|
}
|
|
}
|
|
|
|
OutTraceDDRAW("GetSurfaceDesc(%d): lpdds=%x%s %s\n", dxversion, lpdds, sLabel, LogSurfaceAttributes((LPDDSURFACEDESC2)lpddsd, "GetSurfaceDesc", __LINE__));
|
|
|
|
if(!(dxw.IsEmulated || dxw.Windowize)) return res;
|
|
|
|
switch(role) {
|
|
case SURFACE_ROLE_PRIMARY:
|
|
IsFixed=TRUE;
|
|
//if (dxw.dwFlags1 & EMULATESURFACE) lpddsd->ddpfPixelFormat = dxw.VirtualPixelFormat;
|
|
lpddsd->ddsCaps.dwCaps = SetPrimaryCaps(dxwss.GetCaps(lpdds));
|
|
lpddsd->dwBackBufferCount=DDSD_Prim.dwBackBufferCount;
|
|
lpddsd->dwHeight=dxw.GetScreenHeight();
|
|
lpddsd->dwWidth=dxw.GetScreenWidth();
|
|
break;
|
|
case SURFACE_ROLE_BACKBUFFER:
|
|
IsFixed=TRUE;
|
|
//if (dxw.dwFlags1 & EMULATESURFACE) lpddsd->ddpfPixelFormat = dxw.VirtualPixelFormat; // v2.04.20
|
|
lpddsd->ddsCaps.dwCaps = SetBackBufferCaps(dxwss.GetCaps(lpdds));
|
|
break;
|
|
case SURFACE_ROLE_ZBUFFER:
|
|
IsFixed=TRUE;
|
|
lpddsd->ddsCaps.dwCaps = SetZBufferCaps(dxwss.GetCaps(lpdds));
|
|
break;
|
|
case SURFACE_ROLE_3DREF:
|
|
IsFixed=TRUE;
|
|
lpddsd->ddsCaps.dwCaps = dxwss.GetCaps(lpdds);
|
|
break;
|
|
}
|
|
|
|
if(IsFixed) OutTraceDW("GetSurfaceDesc: FIXED lpdds=%x %s\n", lpdds, LogSurfaceAttributes((LPDDSURFACEDESC2)lpddsd, sLabel, __LINE__));
|
|
if(IsTraceHex) HexTrace((unsigned char *)lpddsd, sizeof(DDSURFACEDESC));
|
|
return DD_OK;
|
|
}
|
|
|
|
// Beware: despite the surface version, some game (The Sims!!!) intentionally uses a different dwSize, so that
|
|
// you shouldn't reset the value
|
|
|
|
HRESULT WINAPI extGetSurfaceDesc1(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd)
|
|
{ return extGetSurfaceDesc(1, pGetSurfaceDesc1, lpdds, lpddsd); }
|
|
HRESULT WINAPI extGetSurfaceDesc2(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd)
|
|
{ return extGetSurfaceDesc(2, pGetSurfaceDesc2, lpdds, lpddsd); }
|
|
HRESULT WINAPI extGetSurfaceDesc3(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd)
|
|
{ return extGetSurfaceDesc(3, pGetSurfaceDesc3, lpdds, lpddsd); }
|
|
HRESULT WINAPI extGetSurfaceDesc4(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 lpddsd)
|
|
{ return extGetSurfaceDesc(4, (GetSurfaceDesc_Type)pGetSurfaceDesc4, (LPDIRECTDRAWSURFACE)lpdds, (LPDDSURFACEDESC)lpddsd); }
|
|
HRESULT WINAPI extGetSurfaceDesc7(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 lpddsd)
|
|
{ return extGetSurfaceDesc(7, (GetSurfaceDesc_Type)pGetSurfaceDesc7, (LPDIRECTDRAWSURFACE)lpdds, (LPDDSURFACEDESC)lpddsd); }
|
|
|
|
static ULONG WINAPI extReleaseD(int dxversion, ReleaseD_Type pReleaseD, LPDIRECTDRAW lpdd)
|
|
{
|
|
ULONG ActualRef;
|
|
LONG VirtualRef;
|
|
|
|
OutTraceDDRAW("Release(D%d): lpdd=%x\n", dxversion, lpdd);
|
|
if((ReleaseD_Type)extReleaseD == pReleaseD) {
|
|
OutTraceE("Release(D) ERROR: bad hooker pReleaseD=%x\n", pReleaseD);
|
|
return 0;
|
|
}
|
|
|
|
ActualRef=(*pReleaseD)(lpdd);
|
|
VirtualRef=(LONG)ActualRef;
|
|
OutTraceDW("Release(D): lpdd=%x service_lpdd=%x ref=%d\n", lpdd, lpPrimaryDD, ActualRef);
|
|
|
|
if (lpdd == lpPrimaryDD) { // v2.1.87: fix for Dungeon Keeper II
|
|
if(dxw.dwFlags4 & FIXREFCOUNTER){
|
|
// v2.02.41: fix the ref counter to sumulate the unwindowed original situation
|
|
--VirtualRef; // why ????
|
|
if(dxwss.GetBackBufferSurface()) --VirtualRef;
|
|
if(dxw.dwFlags1 & EMULATESURFACE){
|
|
if(lpDDSEmu_Prim) --VirtualRef;
|
|
if(lpDDSEmu_Back) --VirtualRef;
|
|
if(lpDDZBuffer) --VirtualRef; // is it correct ? Inserted to fix "Microsoft International Soccer 2000" in hw mode
|
|
}
|
|
if(VirtualRef<0) VirtualRef=0;
|
|
OutTraceDW("Release(D): fixed ref counter %d->%d\n", ActualRef, VirtualRef);
|
|
}
|
|
if((dxversion<4) && (ActualRef==0)){
|
|
// directdraw old versions automatically free all linked objects when the parent session is closed.
|
|
OutTraceDW("Release(D): RefCount=0 - service object RESET condition\n");
|
|
lpDDSEmu_Prim=NULL;
|
|
lpDDSEmu_Back=NULL;
|
|
lpDDP=NULL;
|
|
iDDPExtraRefCounter = 0;
|
|
}
|
|
if(ActualRef==0) lpPrimaryDD=NULL; // v2.03.61
|
|
}
|
|
|
|
// when lpdd session is closed (ref==0) the system restores the default color depth
|
|
// so if FORCE16BPP is set, dxwnd must restore the 16BPP value
|
|
//extern void SwitchTo16BPP();
|
|
//if((ActualRef==0) && (dxw.dwFlags3 & FORCE16BPP)) SwitchTo16BPP();
|
|
|
|
if(dxw.dwFlags4 & RETURNNULLREF) VirtualRef = 0;
|
|
|
|
OutTraceDDRAW("Release(D): lpdd=%x ref=%x\n", lpdd, VirtualRef);
|
|
return (ULONG)VirtualRef;
|
|
}
|
|
|
|
ULONG WINAPI extReleaseD1(LPDIRECTDRAW lpdd)
|
|
{ return extReleaseD(1, pReleaseD1, lpdd); }
|
|
ULONG WINAPI extReleaseD2(LPDIRECTDRAW lpdd)
|
|
{ return extReleaseD(2, pReleaseD2, lpdd); }
|
|
ULONG WINAPI extReleaseD3(LPDIRECTDRAW lpdd)
|
|
{ return extReleaseD(3, pReleaseD3, lpdd); }
|
|
ULONG WINAPI extReleaseD4(LPDIRECTDRAW lpdd)
|
|
{ return extReleaseD(4, pReleaseD4, lpdd); }
|
|
ULONG WINAPI extReleaseD7(LPDIRECTDRAW lpdd)
|
|
{ return extReleaseD(7, pReleaseD7, lpdd); }
|
|
|
|
static HRESULT WINAPI extCreateClipper(int dxversion, CreateClipper_Type pCreateClipper, LPDIRECTDRAW lpdd, DWORD dwflags,
|
|
LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter)
|
|
{
|
|
HRESULT res;
|
|
OutTraceDDRAW("CreateClipper(%d): lpdd=%x flags=%x\n", dxversion, lpdd, dwflags);
|
|
res=(*pCreateClipper)(lpdd, dwflags, lplpDDClipper, pUnkOuter);
|
|
if(res) {
|
|
OutTraceE("CreateClipper: ERROR res=%x(%s)\n", lpdd, res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
OutTraceDDRAW("CreateClipper: OK lpddclipper=%x\n", *lplpDDClipper);
|
|
HookDDClipper(lplpDDClipper); // there is a single Clipper intrface!
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extCreateClipper1(LPDIRECTDRAW lpdd, DWORD dwflags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter)
|
|
{ return extCreateClipper(1, pCreateClipper1, lpdd, dwflags, lplpDDClipper, pUnkOuter); }
|
|
HRESULT WINAPI extCreateClipper2(LPDIRECTDRAW lpdd, DWORD dwflags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter)
|
|
{ return extCreateClipper(2, pCreateClipper2, lpdd, dwflags, lplpDDClipper, pUnkOuter); }
|
|
HRESULT WINAPI extCreateClipper3(LPDIRECTDRAW lpdd, DWORD dwflags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter)
|
|
{ return extCreateClipper(3, pCreateClipper3, lpdd, dwflags, lplpDDClipper, pUnkOuter); }
|
|
HRESULT WINAPI extCreateClipper4(LPDIRECTDRAW lpdd, DWORD dwflags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter)
|
|
{ return extCreateClipper(4, pCreateClipper4, lpdd, dwflags, lplpDDClipper, pUnkOuter); }
|
|
HRESULT WINAPI extCreateClipper7(LPDIRECTDRAW lpdd, DWORD dwflags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter)
|
|
{ return extCreateClipper(7, pCreateClipper7, lpdd, dwflags, lplpDDClipper, pUnkOuter); }
|
|
|
|
HRESULT WINAPI extReleaseC(LPDIRECTDRAWCLIPPER lpddClip)
|
|
{
|
|
ULONG ref;
|
|
|
|
ref = (*pReleaseC)(lpddClip);
|
|
|
|
OutTraceDDRAW("Release(C): PROXED lpddClip=%x ref=%x\n", lpddClip, ref);
|
|
return ref;
|
|
}
|
|
|
|
HRESULT WINAPI extGetClipList(LPDIRECTDRAWCLIPPER lpddClip, LPRECT lpRect, LPRGNDATA lpRgnData, LPDWORD lpw)
|
|
{
|
|
HRESULT res;
|
|
|
|
// returned clip region (both RgnData and single RECT array) should be relocated in window mode
|
|
// an easy way to do that, though not accurate, is to consider the clip region as the whole virtual screen
|
|
// a better way is to use the dxw.UnmapWindow(RECT *) method
|
|
// this makes "Full Pipe" working without clipping problems.
|
|
|
|
if(IsTraceDDRAW){
|
|
char sInfo[81];
|
|
if (lpRect) sprintf(sInfo, "rect=(%d,%d)-(%d,%d) ", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
else sprintf(sInfo, "rect=(NULL) ");
|
|
OutTrace("GetClipList(C): lpddClip=%x %s\n", lpddClip, sInfo);
|
|
}
|
|
res=(*pGetClipList)(lpddClip, lpRect, lpRgnData, lpw);
|
|
if(IsTraceDDRAW){
|
|
if(res) OutTrace("GetClipList(C): ERROR err=%x(%s)\n", res, ExplainDDError(res));
|
|
else{
|
|
if(lpRgnData){
|
|
OutTrace("GetClipList(C): w=%x rgndataheader{size=%d type=%x count=%d RgnSize=%d bound=(%d,%d)-(%d,%d)}\n",
|
|
*lpw, lpRgnData->rdh.dwSize, lpRgnData->rdh.iType, lpRgnData->rdh.nCount, lpRgnData->rdh.nRgnSize,
|
|
lpRgnData->rdh.rcBound.left, lpRgnData->rdh.rcBound.top, lpRgnData->rdh.rcBound.right, lpRgnData->rdh.rcBound.bottom);
|
|
if(dxw.Windowize && (dxw.dwFlags1 & CLIENTREMAPPING)){
|
|
dxw.UnmapWindow(&lpRgnData->rdh.rcBound);
|
|
//lpRgnData->rdh.rcBound = dxw.GetScreenRect();
|
|
OutTraceDW("GetClipList(C): w=%x rgndataheader{size=%d type=%x count=%d RgnSize=%d REMAPPED bound=(%d,%d)-(%d,%d)}\n",
|
|
*lpw, lpRgnData->rdh.dwSize, lpRgnData->rdh.iType, lpRgnData->rdh.nCount, lpRgnData->rdh.nRgnSize,
|
|
lpRgnData->rdh.rcBound.left, lpRgnData->rdh.rcBound.top, lpRgnData->rdh.rcBound.right, lpRgnData->rdh.rcBound.bottom);
|
|
}
|
|
if(IsDebug){
|
|
RECT *rgns;
|
|
rgns = (RECT *)lpRgnData->Buffer;
|
|
for(DWORD i=0; i<lpRgnData->rdh.nCount; i++){
|
|
OutTrace("GetClipList(C): rect[%d]=(%d,%d)-(%d,%d)\n",
|
|
i, rgns[i].left, rgns[i].top, rgns[i].right, rgns[i].bottom);
|
|
if(dxw.Windowize && (dxw.dwFlags1 & CLIENTREMAPPING)){
|
|
dxw.UnmapWindow(&rgns[i]);
|
|
//rgns[i] = dxw.GetScreenRect();
|
|
OutTrace("GetClipList(C): REMAPPED rect[%d]=(%d,%d)-(%d,%d)\n",
|
|
i, rgns[i].left, rgns[i].top, rgns[i].right, rgns[i].bottom);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
OutTrace("GetClipList(C): w=%x\n", *lpw);
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extSetClipList(LPDIRECTDRAWCLIPPER lpddClip, LPRGNDATA lpClipList, DWORD dwFlags)
|
|
{
|
|
HRESULT res;
|
|
OutTraceP("SetClipList(C): lpddClip=%x lpcliplist=%x flags=%x\n", lpddClip, lpClipList, dwFlags);
|
|
res = (*pSetClipList)(lpddClip, lpClipList, dwFlags);
|
|
if(res) OutTraceP("SetClipList(C): ERROR err=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extSetHWnd(LPDIRECTDRAWCLIPPER lpddClip, DWORD w, HWND hwnd)
|
|
{
|
|
HRESULT res;
|
|
OutTraceP("SetHWnd(C): lpddClip=%x w=%x hwnd=%x\n", lpddClip, w, hwnd);
|
|
res=(*pSetHWnd)(lpddClip, w, hwnd);
|
|
if(res) OutTraceP("SetHWnd(C): ERROR err=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extReleaseP(LPDIRECTDRAWPALETTE lpddPalette)
|
|
{
|
|
ULONG ref;
|
|
|
|
ref = (*pReleaseP)(lpddPalette);
|
|
OutTraceDDRAW("Release(P): lpddPalette=%x ref=%x\n", lpddPalette, ref);
|
|
|
|
if (lpddPalette == lpDDP) {
|
|
if(dxw.dwFlags4 & FIXREFCOUNTER) {
|
|
OutTraceDW("Release(P): lpDDP extrarefcount=%d\n", iDDPExtraRefCounter);
|
|
if((ULONG)iDDPExtraRefCounter >= ref){
|
|
while(ref) ref = (*pReleaseP)(lpddPalette);
|
|
lpDDP=NULL;
|
|
iDDPExtraRefCounter = 0;
|
|
return 0;
|
|
}
|
|
ref -= iDDPExtraRefCounter;
|
|
}
|
|
if (ref <= 0) {
|
|
ref = 0;
|
|
OutTraceDW("Release(P): clearing lpDDP=%x->NULL\n", lpDDP);
|
|
lpDDP=NULL;
|
|
}
|
|
if(dxw.dwFlags4 & RETURNNULLREF) ref = 0;
|
|
}
|
|
|
|
return ref;
|
|
}
|
|
|
|
static BOOL IsMatchingDeviceW(LPWSTR lpDriverName)
|
|
{
|
|
WCHAR MatchDev[20];
|
|
wsprintfW(MatchDev, L"DISPLAY%d", dxw.MonitorId+1);
|
|
return (wcsstr(lpDriverName, MatchDev) != NULL);
|
|
}
|
|
|
|
static BOOL IsMatchingDeviceA(LPCSTR lpDriverName)
|
|
{
|
|
CHAR MatchDev[20];
|
|
sprintf(MatchDev, "DISPLAY%d", dxw.MonitorId+1);
|
|
return (strstr(lpDriverName, MatchDev) != NULL);
|
|
}
|
|
|
|
BOOL FAR PASCAL DDEnumerateCallbackFilterW(GUID FAR *lpGuid, LPWSTR lpDriverDescription, LPWSTR lpDriverName, LPVOID lpContext)
|
|
{
|
|
BOOL res;
|
|
typedef struct {LPDDENUMCALLBACKW lpCallback; LPVOID lpContext;} Context_Type;
|
|
Context_Type *p=(Context_Type *)lpContext;
|
|
OutTraceDW("DDEnumerateCallback: guid=%x DriverDescription=\"%ls\" DriverName=\"%ls\" Context=%x\n",
|
|
lpGuid, lpDriverDescription, lpDriverName, p->lpContext);
|
|
if(dxw.MonitorId != -1){
|
|
if(IsMatchingDeviceW(lpDriverName)){
|
|
(*p->lpCallback)(lpGuid, lpDriverDescription, lpDriverName, p->lpContext);
|
|
res=FALSE;
|
|
}
|
|
else {
|
|
OutTraceDW("DDEnumerateCallback: SKIP DriverName=\"%ls\"\n", lpDriverName);
|
|
res=TRUE;
|
|
}
|
|
}
|
|
else{
|
|
if((lpGuid==NULL) || !(dxw.dwFlags2 & HIDEMULTIMONITOR)) res=(*p->lpCallback)(lpGuid, lpDriverDescription, lpDriverName, p->lpContext);
|
|
if((lpGuid==NULL) && (dxw.dwFlags2 & HIDEMULTIMONITOR)) res=FALSE;
|
|
}
|
|
OutTraceDW("DDEnumerateCallback: res=%x(%s)\n", res, res?"continue":"break");
|
|
return res;
|
|
}
|
|
|
|
BOOL FAR PASCAL DDEnumerateCallbackExFilterW(GUID FAR *lpGuid, LPWSTR lpDriverDescription, LPWSTR lpDriverName, LPVOID lpContext, HMONITOR hm)
|
|
{
|
|
BOOL res;
|
|
typedef struct {LPDDENUMCALLBACKEXW lpCallback; LPVOID lpContext;} Context_Type;
|
|
Context_Type *p=(Context_Type *)lpContext;
|
|
OutTraceDW("DDEnumerateCallbackEx: guid=%x DriverDescription=\"%ls\" DriverName=\"%ls\" Context=%x hm=%x\n",
|
|
lpGuid, lpDriverDescription, lpDriverName, lpContext, hm);
|
|
res=TRUE;
|
|
// single monitor handling
|
|
if(dxw.MonitorId != -1){
|
|
if(IsMatchingDeviceW(lpDriverName)){
|
|
(*p->lpCallback)(lpGuid, lpDriverDescription, lpDriverName, p->lpContext, hm);
|
|
res=FALSE;
|
|
}
|
|
else{
|
|
OutTraceDW("DDEnumerateCallbackEx: SKIP DriverName=\"%ls\"\n", lpDriverName);
|
|
res=TRUE;
|
|
}
|
|
}
|
|
else{
|
|
if((lpGuid==NULL) || !(dxw.dwFlags2 & HIDEMULTIMONITOR)) res=(*p->lpCallback)(lpGuid, lpDriverDescription, lpDriverName, p->lpContext, hm);
|
|
if((lpGuid==NULL) && (dxw.dwFlags2 & HIDEMULTIMONITOR)) res=FALSE;
|
|
}
|
|
OutTraceDW("DDEnumerateCallbackEx: res=%x(%s)\n", res, res?"continue":"break");
|
|
return res;
|
|
}
|
|
|
|
BOOL FAR PASCAL DDEnumerateCallbackFilterA(GUID FAR *lpGuid, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext)
|
|
{
|
|
BOOL res;
|
|
typedef struct {LPDDENUMCALLBACK lpCallback; LPVOID lpContext;} Context_Type;
|
|
Context_Type *p=(Context_Type *)lpContext;
|
|
OutTraceDW("DDEnumerateCallback: guid=%x DriverDescription=\"%s\" DriverName=\"%s\" Context=%x\n",
|
|
lpGuid, lpDriverDescription, lpDriverName, p->lpContext);
|
|
res=TRUE;
|
|
if(dxw.MonitorId != -1){
|
|
if(IsMatchingDeviceA(lpDriverName)){
|
|
(*p->lpCallback)(lpGuid, lpDriverDescription, lpDriverName, p->lpContext);
|
|
res=FALSE;
|
|
}
|
|
else{
|
|
OutTraceDW("DDEnumerateCallback: SKIP DriverName=\"%s\"\n", lpDriverName);
|
|
res=TRUE;
|
|
}
|
|
}
|
|
else{
|
|
if((lpGuid==NULL) || !(dxw.dwFlags2 & HIDEMULTIMONITOR)) res=(*p->lpCallback)(lpGuid, lpDriverDescription, lpDriverName, p->lpContext);
|
|
if((lpGuid==NULL) && (dxw.dwFlags2 & HIDEMULTIMONITOR)) res=FALSE;
|
|
}
|
|
OutTraceDW("DDEnumerateCallback: res=%x(%s)\n", res, res?"continue":"break");
|
|
return res;
|
|
}
|
|
|
|
BOOL FAR PASCAL DDEnumerateCallbackExFilterA(GUID FAR *lpGuid, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext, HMONITOR hm)
|
|
{
|
|
BOOL res;
|
|
typedef struct {LPDDENUMCALLBACKEX lpCallback; LPVOID lpContext;} Context_Type;
|
|
Context_Type *p=(Context_Type *)lpContext;
|
|
OutTraceDW("DDEnumerateCallbackEx: guid=%x DriverDescription=\"%s\" DriverName=\"%s\" Context=%x hm=%x\n",
|
|
lpGuid, lpDriverDescription, lpDriverName, lpContext, hm);
|
|
res=TRUE;
|
|
if(dxw.MonitorId != -1){
|
|
if(IsMatchingDeviceA(lpDriverName)){
|
|
(*p->lpCallback)(lpGuid, lpDriverDescription, lpDriverName, p->lpContext, hm);
|
|
res=FALSE;
|
|
}
|
|
else{
|
|
OutTraceDW("DDEnumerateCallbackEx: SKIP DriverName=\"%s\"\n", lpDriverName);
|
|
res=TRUE;
|
|
}
|
|
}
|
|
else{
|
|
if((lpGuid==NULL) || !(dxw.dwFlags2 & HIDEMULTIMONITOR)) res=(*p->lpCallback)(lpGuid, lpDriverDescription, lpDriverName, p->lpContext, hm);
|
|
if((lpGuid==NULL) && (dxw.dwFlags2 & HIDEMULTIMONITOR)) res=FALSE;
|
|
}
|
|
OutTraceDW("DDEnumerateCallbackEx: res=%x(%s)\n", res, res?"continue":"break");
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extDirectDrawEnumerateA(LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
|
|
{
|
|
HRESULT ret;
|
|
OutTraceDDRAW("DirectDrawEnumerate[A]: lpCallback=%x lpContext=%x\n", lpCallback, lpContext);
|
|
if((dxw.dwFlags2 & HIDEMULTIMONITOR) || (dxw.dwTFlags & OUTDEBUG) || (dxw.MonitorId != -1)){
|
|
struct {LPDDENUMCALLBACKA lpCallback; LPVOID lpContext;} myContext;
|
|
myContext.lpCallback=lpCallback;
|
|
myContext.lpContext=lpContext;
|
|
ret=(*pDirectDrawEnumerateA)(DDEnumerateCallbackFilterA, (LPVOID)&myContext);
|
|
}
|
|
else
|
|
ret=(*pDirectDrawEnumerateA)(lpCallback, lpContext);
|
|
if(ret) OutTraceE("DirectDrawEnumerate: ERROR res=%x(%s)\n", ret, ExplainDDError(ret));
|
|
return ret;
|
|
}
|
|
|
|
HRESULT WINAPI extDirectDrawEnumerateW(LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
|
|
{
|
|
HRESULT ret;
|
|
OutTraceDDRAW("DirectDrawEnumerate[W]: lpCallback=%x lpContext=%x\n", lpCallback, lpContext);
|
|
if((dxw.dwFlags2 & HIDEMULTIMONITOR) || (dxw.dwTFlags & OUTDEBUG) || (dxw.MonitorId != -1)){
|
|
struct {LPDDENUMCALLBACKW lpCallback; LPVOID lpContext;} myContext;
|
|
myContext.lpCallback=lpCallback;
|
|
myContext.lpContext=lpContext;
|
|
ret=(*pDirectDrawEnumerateW)(DDEnumerateCallbackFilterW, (LPVOID)&myContext);
|
|
}
|
|
else
|
|
ret=(*pDirectDrawEnumerateW)(lpCallback, lpContext);
|
|
if(ret) OutTraceE("DirectDrawEnumerate: ERROR res=%x(%s)\n", ret, ExplainDDError(ret));
|
|
return ret;
|
|
}
|
|
|
|
HRESULT WINAPI extDirectDrawEnumerateExA(LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
|
|
{
|
|
HRESULT ret;
|
|
OutTraceDDRAW("DirectDrawEnumerateEx[A]: lpCallback=%x lpContext=%x Flags=%x(%s)\n",
|
|
lpCallback, lpContext, dwFlags, ExplainDDEnumerateFlags(dwFlags));
|
|
if((dxw.dwFlags2 & HIDEMULTIMONITOR) || (dxw.dwTFlags & OUTDEBUG) || (dxw.MonitorId != -1)){
|
|
struct {LPDDENUMCALLBACKEXA lpCallback; LPVOID lpContext;} myContext;
|
|
myContext.lpCallback=lpCallback;
|
|
myContext.lpContext=lpContext;
|
|
if(dxw.dwFlags2 & HIDEMULTIMONITOR){
|
|
dwFlags &= ~(DDENUM_ATTACHEDSECONDARYDEVICES|DDENUM_DETACHEDSECONDARYDEVICES|DDENUM_NONDISPLAYDEVICES);
|
|
}
|
|
ret=(*pDirectDrawEnumerateExA)(DDEnumerateCallbackExFilterA, (LPVOID)&myContext, dwFlags);
|
|
}
|
|
else{
|
|
ret=(*pDirectDrawEnumerateExA)(lpCallback, lpContext, dwFlags);
|
|
}
|
|
if(ret) OutTraceE("DirectDrawEnumerateEx: ERROR res=%x(%s)\n", ret, ExplainDDError(ret));
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) ret=DD_OK;
|
|
return ret;
|
|
}
|
|
|
|
HRESULT WINAPI extDirectDrawEnumerateExW(LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
|
|
{
|
|
HRESULT ret;
|
|
OutTraceDDRAW("DirectDrawEnumerateEx[W]: lpCallback=%x lpContext=%x Flags=%x(%s)\n",
|
|
lpCallback, lpContext, dwFlags, ExplainDDEnumerateFlags(dwFlags));
|
|
if((dxw.dwFlags2 & HIDEMULTIMONITOR) || (dxw.dwTFlags & OUTDEBUG) || (dxw.MonitorId != -1)){
|
|
struct {LPDDENUMCALLBACKEXW lpCallback; LPVOID lpContext;} myContext;
|
|
myContext.lpCallback=lpCallback;
|
|
myContext.lpContext=lpContext;
|
|
if(dxw.dwFlags2 & HIDEMULTIMONITOR){
|
|
dwFlags &= ~(DDENUM_ATTACHEDSECONDARYDEVICES|DDENUM_DETACHEDSECONDARYDEVICES|DDENUM_NONDISPLAYDEVICES);
|
|
}
|
|
ret=(*pDirectDrawEnumerateExW)(DDEnumerateCallbackExFilterW, (LPVOID)&myContext, dwFlags);
|
|
}
|
|
else{
|
|
ret=(*pDirectDrawEnumerateExW)(lpCallback, lpContext, dwFlags);
|
|
}
|
|
if(ret) OutTraceE("DirectDrawEnumerateEx: ERROR res=%x(%s)\n", ret, ExplainDDError(ret));
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) ret=DD_OK;
|
|
return ret;
|
|
}
|
|
|
|
HRESULT WINAPI extDDGetGammaRamp(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPDDGAMMARAMP lpgr)
|
|
{
|
|
HRESULT ret;
|
|
OutTraceDDRAW("GetGammaRamp: dds=%x dwFlags=%x\n", lpdds, dwFlags);
|
|
|
|
if(dxwss.IsAPrimarySurface(lpdds)) lpdds=lpDDSEmu_Prim;
|
|
|
|
ret=(*pDDGetGammaRamp)(lpdds, dwFlags, lpgr);
|
|
if(ret) {
|
|
OutTraceE("GetGammaRamp: ERROR res=%x(%s)\n", ret, ExplainDDError(ret));
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) {
|
|
// clear the error code, and provide a reasonable gamma ramp array
|
|
for(int i=0; i<256; i++) lpgr->red[i]=lpgr->green[i]=lpgr->blue[i]=(i * 0x100);
|
|
ret=0;
|
|
}
|
|
}
|
|
else{
|
|
if(IsDebug){
|
|
OutTrace("GetGammaRamp: RGB=");
|
|
for(int i=0; i<256; i++) OutTrace("(%x,%x,%x)", lpgr->red[i], lpgr->green[i], lpgr->blue[i]);
|
|
OutTrace("\n");
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
HRESULT WINAPI extDDSetGammaRamp(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPDDGAMMARAMP lpgr)
|
|
{
|
|
HRESULT ret;
|
|
OutTraceDDRAW("SetGammaRamp: dds=%x dwFlags=%x\n", lpdds, dwFlags);
|
|
if(IsDebug){
|
|
OutTrace("GetGammaRamp: RGB=");
|
|
for(int i=0; i<256; i++) OutTrace("(%x,%x,%x)", lpgr->red[i], lpgr->green[i], lpgr->blue[i]);
|
|
OutTrace("\n");
|
|
}
|
|
if (dxw.dwFlags2 & DISABLEGAMMARAMP) return DD_OK;
|
|
ret=(*pDDSetGammaRamp)(lpdds, dwFlags, lpgr);
|
|
if(ret) OutTraceE("SetGammaRamp: ERROR res=%x(%s)\n", ret, ExplainDDError(ret));
|
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) ret = DD_OK;
|
|
return ret;
|
|
}
|
|
|
|
static HRESULT WINAPI extGetAvailableVidMem(int dxversion, GetAvailableVidMem4_Type pGetAvailableVidMem, LPDIRECTDRAW lpdd, LPDDSCAPS2 lpDDSCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree)
|
|
{
|
|
HRESULT res;
|
|
//const DWORD dwMaxMem = 0x7FFFF000;
|
|
// v03.01.01: limit to smaller value to allow "Breath of Fire IV" card detection
|
|
const DWORD dwMaxMem = 0x70000000;
|
|
const DWORD dwHugeMem = 0xF0000000;
|
|
OutTraceDDRAW("GetAvailableVidMem(D%d): lpdd=%x\n", dxversion, lpdd);
|
|
res=(*pGetAvailableVidMem)(lpdd, lpDDSCaps, lpdwTotal, lpdwFree);
|
|
if(res){
|
|
if((dxw.dwFlags3 & FORCESHEL) && (res==DDERR_NODIRECTDRAWHW)){
|
|
// fake some video memory....
|
|
OutTraceDW("GetAvailableVidMem(D): FORCESHEL mode Total=Free=%x\n", dwMaxMem);
|
|
if(lpdwTotal) *lpdwTotal = dwMaxMem;
|
|
if(lpdwFree) *lpdwFree = dwMaxMem;
|
|
return DD_OK;
|
|
}
|
|
OutTraceE("GetAvailableVidMem(D): ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
if(dxversion < 4){ // fix: should include also dxversion 3!!!
|
|
OutTraceDW("GetAvailableVidMem(D%d): DDSCaps=%x(%s) Total=%x Free=%x\n",
|
|
dxversion,
|
|
lpDDSCaps->dwCaps, ExplainDDSCaps(lpDDSCaps->dwCaps),
|
|
lpdwTotal?*lpdwTotal:0, lpdwFree?*lpdwFree:0);
|
|
}
|
|
else{
|
|
OutTraceDW("GetAvailableVidMem(D%d): DDSCaps=%x(%s).%x.%x.%x volumedepth=%d Total=%x Free=%x\n",
|
|
dxversion,
|
|
lpDDSCaps->dwCaps, ExplainDDSCaps(lpDDSCaps->dwCaps),
|
|
lpDDSCaps->dwCaps2, lpDDSCaps->dwCaps3, lpDDSCaps->dwCaps4, lpDDSCaps->dwVolumeDepth,
|
|
lpdwTotal?*lpdwTotal:0, lpdwFree?*lpdwFree:0);
|
|
}
|
|
|
|
if(!(dxw.dwFlags2 & LIMITRESOURCES)) return res;
|
|
|
|
// may need hints ....
|
|
if(dxw.bHintActive){
|
|
if(lpdwTotal && (*lpdwTotal > dwMaxMem)) ShowHint(HINT_LIMITMEM);
|
|
if(lpdwFree && (*lpdwFree > dwMaxMem)) ShowHint(HINT_LIMITMEM);
|
|
}
|
|
|
|
// simulate a value overflow condition
|
|
if(dxw.dwFlags5 & STRESSRESOURCES){
|
|
if(lpdwTotal) *lpdwTotal = dwHugeMem;
|
|
if(lpdwFree) *lpdwFree = dwHugeMem;
|
|
return DD_OK;
|
|
}
|
|
|
|
// check for memory value overflow - see "Mageslayer" and "Take no Prisoners"
|
|
DWORD dwLocalTotal;
|
|
if(lpdwTotal == NULL) {
|
|
lpdwTotal = &dwLocalTotal; // point to usable memory....
|
|
res=(*pGetAvailableVidMem)(lpdd, lpDDSCaps, lpdwTotal, lpdwFree); // do it again to get total memory
|
|
}
|
|
if(*lpdwTotal > dwMaxMem){
|
|
if(lpdwFree != NULL){
|
|
DWORD dwDiff = *lpdwTotal - *lpdwFree;
|
|
if(dwDiff > dwMaxMem){
|
|
*lpdwFree = dwMaxMem;
|
|
}
|
|
else{
|
|
*lpdwFree = dwMaxMem - dwDiff;
|
|
}
|
|
}
|
|
*lpdwTotal = dwMaxMem;
|
|
OutTraceDW("GetAvailableVidMem(D): FIXED Total=%x Free=%x\n", *lpdwTotal, *lpdwFree);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extGetAvailableVidMem2(LPDIRECTDRAW lpdd, LPDDSCAPS lpDDSCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree)
|
|
{ return extGetAvailableVidMem(2, (GetAvailableVidMem4_Type)pGetAvailableVidMem2, lpdd, (LPDDSCAPS2)lpDDSCaps, lpdwTotal, lpdwFree); }
|
|
HRESULT WINAPI extGetAvailableVidMem3(LPDIRECTDRAW lpdd, LPDDSCAPS lpDDSCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree)
|
|
{ return extGetAvailableVidMem(3, (GetAvailableVidMem4_Type)pGetAvailableVidMem3, lpdd, (LPDDSCAPS2)lpDDSCaps, lpdwTotal, lpdwFree); }
|
|
HRESULT WINAPI extGetAvailableVidMem4(LPDIRECTDRAW lpdd, LPDDSCAPS2 lpDDSCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree)
|
|
{ return extGetAvailableVidMem(4, pGetAvailableVidMem4, lpdd, lpDDSCaps, lpdwTotal, lpdwFree); }
|
|
HRESULT WINAPI extGetAvailableVidMem7(LPDIRECTDRAW lpdd, LPDDSCAPS2 lpDDSCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree)
|
|
{ return extGetAvailableVidMem(7, pGetAvailableVidMem7, lpdd, lpDDSCaps, lpdwTotal, lpdwFree); }
|
|
|
|
HRESULT WINAPI extSetSurfaceDesc(SetSurfaceDesc_Type pSetSurfaceDesc, LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpDDsd2, DWORD dwFlags)
|
|
{
|
|
HRESULT res;
|
|
OutTrace("SetSurfaceDesc: REACHED\n");
|
|
res = (*pSetSurfaceDesc)(lpdds, lpDDsd2, dwFlags);
|
|
if(res) OutTraceE("SetSurfaceDesc: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extSetSurfaceDesc3(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpDDsd2, DWORD dwFlags)
|
|
{ return extSetSurfaceDesc(pSetSurfaceDesc3, lpdds, lpDDsd2, dwFlags); }
|
|
HRESULT WINAPI extSetSurfaceDesc4(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpDDsd2, DWORD dwFlags)
|
|
{ return extSetSurfaceDesc(pSetSurfaceDesc4, lpdds, lpDDsd2, dwFlags); }
|
|
HRESULT WINAPI extSetSurfaceDesc7(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpDDsd2, DWORD dwFlags)
|
|
{ return extSetSurfaceDesc(pSetSurfaceDesc7, lpdds, lpDDsd2, dwFlags); }
|
|
|
|
HRESULT WINAPI extDirectDrawCreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter)
|
|
{
|
|
HRESULT res;
|
|
OutTraceDW("DirectDrawCreateClipper: flags=%x\n", dwFlags);
|
|
res = (*pDirectDrawCreateClipper)(dwFlags, lplpDDClipper, pUnkOuter);
|
|
if(res) {
|
|
OutTraceE("DirectDrawCreateClipper: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
OutTraceDW("DirectDrawCreateClipper: OK lpclipper=%x\n", *lplpDDClipper);
|
|
HookDDClipper(lplpDDClipper);
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extEnumOverlayZOrders(int dxversion, EnumOverlayZOrders_Type pEnumOverlayZOrders, LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback)
|
|
{
|
|
HRESULT res;
|
|
OutTrace("EnumOverlayZOrders(%d): lpdds=%x flags=%x(%s)\n", dxversion, lpdds, dwFlags, dwFlags?"FRONTTOBACK":"BACKTOFRONT");
|
|
res = (*pEnumOverlayZOrders)(lpdds, dwFlags, lpContext, lpfnCallback);
|
|
OutTrace("EnumOverlayZOrders: res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extEnumOverlayZOrders1(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback)
|
|
{ return extEnumOverlayZOrders(1, pEnumOverlayZOrders1, lpdds, dwFlags, lpContext, lpfnCallback); }
|
|
HRESULT WINAPI extEnumOverlayZOrders2(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback)
|
|
{ return extEnumOverlayZOrders(2, pEnumOverlayZOrders2, lpdds, dwFlags, lpContext, lpfnCallback); }
|
|
HRESULT WINAPI extEnumOverlayZOrders3(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback)
|
|
{ return extEnumOverlayZOrders(3, pEnumOverlayZOrders3, lpdds, dwFlags, lpContext, lpfnCallback); }
|
|
HRESULT WINAPI extEnumOverlayZOrders4(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback)
|
|
{ return extEnumOverlayZOrders(4, pEnumOverlayZOrders4, lpdds, dwFlags, lpContext, lpfnCallback); }
|
|
HRESULT WINAPI extEnumOverlayZOrders7(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback)
|
|
{ return extEnumOverlayZOrders(7, pEnumOverlayZOrders7, lpdds, dwFlags, lpContext, lpfnCallback); }
|
|
|
|
HRESULT WINAPI extAddOverlayDirtyRect(int dxversion, AddOverlayDirtyRect_Type pAddOverlayDirtyRect, LPDIRECTDRAWSURFACE lpdds, LPRECT lpRect)
|
|
{
|
|
HRESULT res;
|
|
char sInfo[128];
|
|
if (lpRect)
|
|
sprintf(sInfo, "(%d,%d)-(%d,%d)", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
|
|
else
|
|
sprintf(sInfo, "(NULL)");
|
|
|
|
OutTrace("AddOverlayDirtyRect(%d): lpdds=%x rect=%s\n", dxversion, lpdds, sInfo);
|
|
res=(*pAddOverlayDirtyRect)(lpdds, lpRect);
|
|
OutTrace("AddOverlayDirtyRect: res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extAddOverlayDirtyRect1(LPDIRECTDRAWSURFACE lpdds, LPRECT lpRect)
|
|
{ return extAddOverlayDirtyRect(1, pAddOverlayDirtyRect1, lpdds, lpRect); }
|
|
HRESULT WINAPI extAddOverlayDirtyRect2(LPDIRECTDRAWSURFACE lpdds, LPRECT lpRect)
|
|
{ return extAddOverlayDirtyRect(2, pAddOverlayDirtyRect2, lpdds, lpRect); }
|
|
HRESULT WINAPI extAddOverlayDirtyRect3(LPDIRECTDRAWSURFACE lpdds, LPRECT lpRect)
|
|
{ return extAddOverlayDirtyRect(3, pAddOverlayDirtyRect3, lpdds, lpRect); }
|
|
HRESULT WINAPI extAddOverlayDirtyRect4(LPDIRECTDRAWSURFACE lpdds, LPRECT lpRect)
|
|
{ return extAddOverlayDirtyRect(4, pAddOverlayDirtyRect4, lpdds, lpRect); }
|
|
HRESULT WINAPI extAddOverlayDirtyRect7(LPDIRECTDRAWSURFACE lpdds, LPRECT lpRect)
|
|
{ return extAddOverlayDirtyRect(7, pAddOverlayDirtyRect7, lpdds, lpRect); }
|
|
|
|
HRESULT WINAPI extCompact(LPDIRECTDRAW lpdd)
|
|
{
|
|
OutTraceDW("Compact: lpdd=%x\n", lpdd);
|
|
return DD_OK;
|
|
}
|
|
|
|
HRESULT WINAPI extDuplicateSurface(int dxversion, DuplicateSurface_Type pDuplicateSurface, LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE lpddssrc, LPDIRECTDRAWSURFACE FAR *lpddsdest)
|
|
{
|
|
HRESULT res;
|
|
OutTrace("DuplicateSurface(%d): lpdd=%x lpddsrc=%x\n", dxversion, lpdd, lpddssrc);
|
|
res = (*pDuplicateSurface)(lpdd, lpddssrc, lpddsdest);
|
|
if(res)
|
|
OutTrace("DuplicateSurface: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
else
|
|
OutTrace("DuplicateSurface: lpddsdest=%x\n", *lpddsdest);
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extDuplicateSurface1(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE lpddssrc, LPDIRECTDRAWSURFACE FAR *lpddsdest)
|
|
{ return extDuplicateSurface(1, pDuplicateSurface1, lpdd, lpddssrc, lpddsdest); }
|
|
HRESULT WINAPI extDuplicateSurface2(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE lpddssrc, LPDIRECTDRAWSURFACE FAR *lpddsdest)
|
|
{ return extDuplicateSurface(2, pDuplicateSurface2, lpdd, lpddssrc, lpddsdest); }
|
|
HRESULT WINAPI extDuplicateSurface3(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE lpddssrc, LPDIRECTDRAWSURFACE FAR *lpddsdest)
|
|
{ return extDuplicateSurface(3, pDuplicateSurface3, lpdd, lpddssrc, lpddsdest); }
|
|
HRESULT WINAPI extDuplicateSurface4(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE4 lpddssrc, LPDIRECTDRAWSURFACE4 FAR *lpddsdest)
|
|
{ return extDuplicateSurface(4, (DuplicateSurface_Type)pDuplicateSurface4, lpdd, (LPDIRECTDRAWSURFACE)lpddssrc, (LPDIRECTDRAWSURFACE *)lpddsdest); }
|
|
HRESULT WINAPI extDuplicateSurface7(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE7 lpddssrc, LPDIRECTDRAWSURFACE7 FAR *lpddsdest)
|
|
{ return extDuplicateSurface(7, (DuplicateSurface_Type)pDuplicateSurface7, lpdd, (LPDIRECTDRAWSURFACE)lpddssrc, (LPDIRECTDRAWSURFACE *)lpddsdest); }
|
|
|
|
static HRESULT WINAPI extSetOverlayPosition(int dxversion, SetOverlayPosition_Type pSetOverlayPosition, LPDIRECTDRAWSURFACE lpdds, LONG lX, LONG lY)
|
|
{
|
|
HRESULT res;
|
|
OutTrace("SetOverlayPosition(%d): lpdds=%x pos=(%ld,%ld)\n", dxversion, lpdds, lX, lY);
|
|
res = (*pSetOverlayPosition)(lpdds, lX, lY);
|
|
if(res)
|
|
OutTraceE("SetOverlayPosition: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extSetOverlayPosition1(LPDIRECTDRAWSURFACE lpdds, LONG lX, LONG lY)
|
|
{ return extSetOverlayPosition(1, pSetOverlayPosition1, lpdds, lX, lY); }
|
|
HRESULT WINAPI extSetOverlayPosition2(LPDIRECTDRAWSURFACE lpdds, LONG lX, LONG lY)
|
|
{ return extSetOverlayPosition(2, pSetOverlayPosition2, lpdds, lX, lY); }
|
|
HRESULT WINAPI extSetOverlayPosition3(LPDIRECTDRAWSURFACE lpdds, LONG lX, LONG lY)
|
|
{ return extSetOverlayPosition(3, pSetOverlayPosition3, lpdds, lX, lY); }
|
|
HRESULT WINAPI extSetOverlayPosition4(LPDIRECTDRAWSURFACE lpdds, LONG lX, LONG lY)
|
|
{ return extSetOverlayPosition(4, pSetOverlayPosition4, lpdds, lX, lY); }
|
|
HRESULT WINAPI extSetOverlayPosition7(LPDIRECTDRAWSURFACE lpdds, LONG lX, LONG lY)
|
|
{ return extSetOverlayPosition(7, pSetOverlayPosition7, lpdds, lX, lY); }
|
|
|
|
static HRESULT WINAPI extGetOverlayPosition(int dxversion, GetOverlayPosition_Type pGetOverlayPosition, LPDIRECTDRAWSURFACE lpdds, LPLONG lX, LPLONG lY)
|
|
{
|
|
HRESULT res;
|
|
OutTrace("GetOverlayPosition(%d): lpdds=%x\n", dxversion, lpdds);
|
|
res = (*pGetOverlayPosition)(lpdds, lX, lY);
|
|
if(res)
|
|
OutTraceE("GetOverlayPosition: ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
|
else{
|
|
OutTraceDW("GetOverlayPosition: pos=(%ld,%ld)\n", *lX, *lY);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extGetOverlayPosition1(LPDIRECTDRAWSURFACE lpdds, LPLONG lX, LPLONG lY)
|
|
{ return extGetOverlayPosition(1, pGetOverlayPosition1, lpdds, lX, lY); }
|
|
HRESULT WINAPI extGetOverlayPosition2(LPDIRECTDRAWSURFACE lpdds, LPLONG lX, LPLONG lY)
|
|
{ return extGetOverlayPosition(2, pGetOverlayPosition2, lpdds, lX, lY); }
|
|
HRESULT WINAPI extGetOverlayPosition3(LPDIRECTDRAWSURFACE lpdds, LPLONG lX, LPLONG lY)
|
|
{ return extGetOverlayPosition(3, pGetOverlayPosition3, lpdds, lX, lY); }
|
|
HRESULT WINAPI extGetOverlayPosition4(LPDIRECTDRAWSURFACE lpdds, LPLONG lX, LPLONG lY)
|
|
{ return extGetOverlayPosition(4, pGetOverlayPosition4, lpdds, lX, lY); }
|
|
HRESULT WINAPI extGetOverlayPosition7(LPDIRECTDRAWSURFACE lpdds, LPLONG lX, LPLONG lY)
|
|
{ return extGetOverlayPosition(7, pGetOverlayPosition7, lpdds, lX, lY); }
|
|
|
|
HRESULT WINAPI extStartModeTest(LPDIRECTDRAW lpdds, LPSIZE lpModesToTest, DWORD dwNumEntries, DWORD dwFlags)
|
|
{
|
|
HRESULT res;
|
|
if(IsTraceDW){
|
|
char sBuf[80];
|
|
OutTrace("StartModeTest(7): lpdds=%x flags=%x num=%d modes=", lpdds, dwFlags, dwNumEntries);
|
|
for(DWORD i=0; i<dwNumEntries; i++) {
|
|
sprintf(sBuf, "(%d x %d)", lpModesToTest[i].cx, lpModesToTest[i].cy);
|
|
OutTrace(sBuf);
|
|
}
|
|
}
|
|
res=(*pStartModeTest)(lpdds, lpModesToTest, dwNumEntries, dwFlags);
|
|
OutTraceDW("StartModeTest: res=%x\n", res);
|
|
return res;
|
|
}
|
|
|
|
HRESULT WINAPI extEvaluateMode(LPDIRECTDRAW lpdds, DWORD dwFlags, DWORD *pSecondsUntilTimeout)
|
|
{
|
|
HRESULT res;
|
|
OutTraceDW("EvaluateMode(7): lpdds=%x flags=%x\n", lpdds, dwFlags);
|
|
res = (*pEvaluateMode)(lpdds, dwFlags, pSecondsUntilTimeout);
|
|
OutTraceDW("EvaluateMode: res=%x timeout=%d\n", res, *pSecondsUntilTimeout);
|
|
return res;
|
|
}
|
|
|