2013-07-21 12:38:09 -04:00
// to do: duplicate EnumSurfaces(D) handling
// fix Unlock duplicate hook in Judge Dredd Pinball
2013-08-25 12:38:13 -04:00
# define _CRT_SECURE_NO_WARNINGS
2013-07-21 12:38:09 -04:00
# define INITGUID
2014-09-21 12:39:48 -04:00
//#define FULLHEXDUMP
2013-07-21 12:38:09 -04:00
# include <windows.h>
# include <ddraw.h>
# include "dxwnd.h"
# include "dxhook.h"
2013-11-10 11:38:24 -05:00
# include "ddrawi.h"
2013-07-21 12:38:09 -04:00
# include "dxwcore.hpp"
# include "stdio.h"
# include "hddraw.h"
2013-11-16 11:38:27 -05:00
# include "ddproxy.h"
2013-07-21 12:38:09 -04:00
# include "dxhelper.h"
# include "syslibs.h"
2014-05-14 12:39:12 -04:00
extern BOOL IsChangeDisplaySettingsHotPatched ;
2014-06-07 12:39:29 -04:00
BOOL bDontReleaseBackBuffer = FALSE ;
2014-11-19 11:40:00 -05:00
DWORD dwBackBufferCaps ;
extern void TextureHandling ( LPDIRECTDRAWSURFACE ) ;
2014-05-14 12:39:12 -04:00
2013-07-21 12:38:09 -04:00
// DirectDraw API
HRESULT WINAPI extDirectDrawCreate ( GUID FAR * , LPDIRECTDRAW FAR * , IUnknown FAR * ) ;
HRESULT WINAPI extDirectDrawCreateEx ( GUID FAR * , LPDIRECTDRAW FAR * , REFIID , IUnknown FAR * ) ;
HRESULT WINAPI extDirectDrawEnumerate ( LPDDENUMCALLBACK , LPVOID ) ;
HRESULT WINAPI extDirectDrawEnumerateEx ( LPDDENUMCALLBACKEX , LPVOID , DWORD ) ;
// DirectDraw
HRESULT WINAPI extQueryInterfaceD ( void * , REFIID , LPVOID * ) ;
ULONG WINAPI extReleaseD ( LPDIRECTDRAW ) ;
/*** IDirectDraw methods ***/
HRESULT WINAPI extCreateClipper ( LPDIRECTDRAW , DWORD , LPDIRECTDRAWCLIPPER FAR * , IUnknown FAR * ) ;
HRESULT WINAPI extCreatePalette ( LPDIRECTDRAW , DWORD , LPPALETTEENTRY , LPDIRECTDRAWPALETTE * , IUnknown * ) ;
HRESULT WINAPI extCreateSurface1 ( LPDIRECTDRAW , DDSURFACEDESC * , LPDIRECTDRAWSURFACE * , void * ) ;
HRESULT WINAPI extCreateSurface2 ( LPDIRECTDRAW , DDSURFACEDESC * , LPDIRECTDRAWSURFACE * , void * ) ;
HRESULT WINAPI extCreateSurface4 ( LPDIRECTDRAW , DDSURFACEDESC2 * , LPDIRECTDRAWSURFACE * , void * ) ;
HRESULT WINAPI extCreateSurface7 ( LPDIRECTDRAW , DDSURFACEDESC2 * , LPDIRECTDRAWSURFACE * , void * ) ;
HRESULT WINAPI extDuplicateSurface ( LPDIRECTDRAW , LPDIRECTDRAWSURFACE , LPDIRECTDRAWSURFACE * ) ;
HRESULT WINAPI extFlipToGDISurface ( LPDIRECTDRAW ) ;
HRESULT WINAPI extGetDisplayMode ( LPDIRECTDRAW , LPDDSURFACEDESC ) ;
HRESULT WINAPI extGetGDISurface ( LPDIRECTDRAW , LPDIRECTDRAWSURFACE * ) ;
HRESULT WINAPI extEnumDisplayModes1 ( LPDIRECTDRAW , DWORD , LPDDSURFACEDESC , LPVOID , LPDDENUMMODESCALLBACK ) ;
HRESULT WINAPI extEnumDisplayModes4 ( LPDIRECTDRAW , DWORD , LPDDSURFACEDESC2 , LPVOID , LPDDENUMMODESCALLBACK2 ) ;
2013-11-10 11:38:24 -05:00
HRESULT WINAPI extInitialize ( LPDIRECTDRAW , FAR GUID * ) ;
2013-07-21 12:38:09 -04:00
HRESULT WINAPI extSetCooperativeLevel ( void * , HWND , DWORD ) ;
HRESULT WINAPI extSetDisplayMode1 ( LPDIRECTDRAW , DWORD , DWORD , DWORD ) ;
HRESULT WINAPI extSetDisplayMode2 ( LPDIRECTDRAW , DWORD , DWORD , DWORD , DWORD , DWORD ) ;
HRESULT WINAPI extWaitForVerticalBlank ( LPDIRECTDRAW , DWORD , HANDLE ) ;
2013-12-22 11:38:36 -05:00
/*** Added in the V2 Interface ***/
HRESULT WINAPI extGetAvailableVidMem2 ( LPDIRECTDRAW , LPDDSCAPS , LPDWORD , LPDWORD ) ;
HRESULT WINAPI extGetAvailableVidMem4 ( LPDIRECTDRAW , LPDDSCAPS , LPDWORD , LPDWORD ) ;
2013-07-21 12:38:09 -04:00
/*** Added in the V4 Interface ***/
HRESULT WINAPI extTestCooperativeLevel ( LPDIRECTDRAW ) ;
// STDMETHOD(StartModeTest)(THIS_ LPSIZE, DWORD, DWORD ) PURE;
// STDMETHOD(EvaluateMode)(THIS_ DWORD, DWORD * ) PURE;
HRESULT WINAPI extGetCapsD ( LPDIRECTDRAW , LPDDCAPS , LPDDCAPS ) ;
// DirectDrawSurface
HRESULT WINAPI extQueryInterfaceS ( void * , REFIID , LPVOID * ) ;
HRESULT WINAPI extReleaseS ( LPDIRECTDRAWSURFACE ) ;
/*** IDirectDrawSurface methods ***/
HRESULT WINAPI extAddAttachedSurface ( LPDIRECTDRAWSURFACE , LPDIRECTDRAWSURFACE ) ;
HRESULT WINAPI extBlt ( LPDIRECTDRAWSURFACE , LPRECT , LPDIRECTDRAWSURFACE , LPRECT , DWORD , LPDDBLTFX ) ;
HRESULT WINAPI extBltFast ( LPDIRECTDRAWSURFACE , DWORD , DWORD , LPDIRECTDRAWSURFACE , LPRECT , DWORD ) ;
HRESULT WINAPI extDeleteAttachedSurface ( LPDIRECTDRAWSURFACE , DWORD , LPDIRECTDRAWSURFACE ) ;
HRESULT WINAPI extEnumAttachedSurfaces ( LPDIRECTDRAWSURFACE , LPVOID , LPDDENUMSURFACESCALLBACK ) ;
HRESULT WINAPI extFlip ( LPDIRECTDRAWSURFACE , LPDIRECTDRAWSURFACE , DWORD ) ;
HRESULT WINAPI extGetAttachedSurface1 ( LPDIRECTDRAWSURFACE , DDSCAPS * , LPDIRECTDRAWSURFACE * ) ;
HRESULT WINAPI extGetAttachedSurface3 ( LPDIRECTDRAWSURFACE , DDSCAPS * , LPDIRECTDRAWSURFACE * ) ;
HRESULT WINAPI extGetAttachedSurface4 ( LPDIRECTDRAWSURFACE , DDSCAPS * , LPDIRECTDRAWSURFACE * ) ;
HRESULT WINAPI extGetAttachedSurface7 ( LPDIRECTDRAWSURFACE , DDSCAPS * , 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 extGetColorKey ( LPDIRECTDRAWSURFACE , DWORD , LPDDCOLORKEY ) ;
HRESULT WINAPI extGetDC ( LPDIRECTDRAWSURFACE , HDC FAR * ) ;
HRESULT WINAPI extGetPalette ( LPDIRECTDRAWSURFACE , LPDIRECTDRAWPALETTE * ) ;
HRESULT WINAPI extGetPixelFormat ( LPDIRECTDRAWSURFACE , LPDDPIXELFORMAT ) ;
HRESULT WINAPI extGetSurfaceDesc1 ( LPDIRECTDRAWSURFACE lpdds , LPDDSURFACEDESC lpddsd ) ;
HRESULT WINAPI extGetSurfaceDesc2 ( LPDIRECTDRAWSURFACE2 lpdds , LPDDSURFACEDESC2 lpddsd ) ;
2014-02-02 11:38:46 -05:00
HRESULT WINAPI extGetSurfaceDesc7 ( LPDIRECTDRAWSURFACE2 lpdds , LPDDSURFACEDESC2 lpddsd ) ;
2013-07-21 12:38:09 -04:00
// STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC2) PURE;
2014-03-21 12:38:57 -04:00
HRESULT WINAPI extLock ( LPDIRECTDRAWSURFACE , LPRECT , LPDDSURFACEDESC , DWORD , HANDLE ) ;
HRESULT WINAPI extLockDir ( LPDIRECTDRAWSURFACE , LPRECT , LPDDSURFACEDESC , DWORD , HANDLE ) ;
2013-07-21 12:38:09 -04:00
HRESULT WINAPI extReleaseDC ( LPDIRECTDRAWSURFACE , HDC ) ;
HRESULT WINAPI extSetClipper ( LPDIRECTDRAWSURFACE , LPDIRECTDRAWCLIPPER ) ;
HRESULT WINAPI extSetColorKey ( LPDIRECTDRAWSURFACE , DWORD , LPDDCOLORKEY ) ;
HRESULT WINAPI extSetPalette ( LPDIRECTDRAWSURFACE , LPDIRECTDRAWPALETTE ) ;
HRESULT WINAPI extUnlock4 ( LPDIRECTDRAWSURFACE , LPRECT ) ;
HRESULT WINAPI extUnlock1 ( LPDIRECTDRAWSURFACE , LPVOID ) ;
2013-07-30 12:38:11 -04:00
HRESULT WINAPI extUnlockDir4 ( LPDIRECTDRAWSURFACE , LPRECT ) ;
HRESULT WINAPI extUnlockDir1 ( LPDIRECTDRAWSURFACE , LPVOID ) ;
2013-07-21 12:38:09 -04:00
HRESULT WINAPI extCreateSurface ( int , CreateSurface_Type , LPDIRECTDRAW , DDSURFACEDESC2 * , LPDIRECTDRAWSURFACE * , void * ) ;
2014-01-24 11:38:44 -05:00
HRESULT WINAPI extSetSurfaceDesc ( LPDIRECTDRAWSURFACE , LPDDSURFACEDESC , DWORD ) ;
2013-07-21 12:38:09 -04:00
// DirectDrawClipper
HRESULT WINAPI extReleaseC ( LPDIRECTDRAWCLIPPER ) ;
// DirectDrawPalette
HRESULT WINAPI extReleaseP ( LPDIRECTDRAWPALETTE ) ;
// STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD, LPPALETTEENTRY) PURE;
HRESULT WINAPI extSetEntries ( LPDIRECTDRAWPALETTE , DWORD , DWORD , DWORD , LPPALETTEENTRY ) ;
2013-11-10 11:38:21 -05:00
// GammaRamp
HRESULT WINAPI extDDSetGammaRamp ( LPDIRECTDRAWSURFACE , DWORD , LPDDGAMMARAMP ) ;
HRESULT WINAPI extDDGetGammaRamp ( LPDIRECTDRAWSURFACE , DWORD , LPDDGAMMARAMP ) ;
2013-07-21 12:38:09 -04:00
HDC WINAPI extGDIGetDC ( HWND ) ;
HDC WINAPI extGDIGetWindowDC ( HWND ) ;
int WINAPI extGDIReleaseDC ( HWND , HDC ) ;
/* DirectDraw APIs */
2013-11-10 11:38:21 -05:00
DirectDrawCreate_Type pDirectDrawCreate = NULL ;
DirectDrawCreateEx_Type pDirectDrawCreateEx = NULL ;
DirectDrawEnumerate_Type pDirectDrawEnumerate = NULL ;
DirectDrawEnumerateEx_Type pDirectDrawEnumerateEx = NULL ;
2013-07-21 12:38:09 -04:00
/* DirectDraw hook pointers */
QueryInterface_Type pQueryInterfaceD ;
AddRefD_Type pAddRefD ;
ReleaseD_Type pReleaseD ;
Compact_Type pCompact ;
CreateClipper_Type pCreateClipper = NULL ;
CreatePalette_Type pCreatePalette ;
CreateSurface1_Type pCreateSurface1 ;
CreateSurface1_Type pCreateSurface2 ;
CreateSurface1_Type pCreateSurface3 ;
CreateSurface2_Type pCreateSurface4 ;
CreateSurface2_Type pCreateSurface7 ;
DuplicateSurface_Type pDuplicateSurface ;
EnumDisplayModes1_Type pEnumDisplayModes1 ;
EnumDisplayModes4_Type pEnumDisplayModes4 ;
EnumSurfaces1_Type pEnumSurfaces1 ;
EnumSurfaces4_Type pEnumSurfaces4 ;
FlipToGDISurface_Type pFlipToGDISurface ;
GetCapsD_Type pGetCapsD ;
GetDisplayMode_Type pGetDisplayMode ;
GetFourCCCodes_Type pGetFourCCCodes ;
GetGDISurface_Type pGetGDISurface ;
GetMonitorFrequency_Type pGetMonitorFrequency ;
GetScanLine_Type pGetScanLine ;
GetVerticalBlankStatus_Type pGetVerticalBlankStatus ;
2013-11-10 11:38:24 -05:00
Initialize_Type pInitialize ;
2013-07-21 12:38:09 -04:00
RestoreDisplayMode_Type pRestoreDisplayMode ;
SetCooperativeLevel_Type pSetCooperativeLevel ;
SetDisplayMode1_Type pSetDisplayMode1 ;
SetDisplayMode2_Type pSetDisplayMode2 ;
WaitForVerticalBlank_Type pWaitForVerticalBlank ;
GetSurfaceFromDC_Type pGetSurfaceFromDC ;
GetAvailableVidMem_Type pGetAvailableVidMem ;
2013-12-22 11:38:36 -05:00
GetAvailableVidMem_Type pGetAvailableVidMem2 ;
GetAvailableVidMem_Type pGetAvailableVidMem4 ;
2013-07-21 12:38:09 -04:00
RestoreAllSurfaces_Type pRestoreAllSurfaces ;
TestCooperativeLevel_Type pTestCooperativeLevel ;
GetDeviceIdentifier_Type pGetDeviceIdentifier ;
/* DirectDrawSurface hook pointers */
QueryInterface_Type pQueryInterfaceS ;
AddRefS_Type pAddRefS ;
ReleaseS_Type pReleaseS ;
AddAttachedSurface_Type pAddAttachedSurface ;
AddOverlayDirtyRect_Type pAddOverlayDirtyRect ;
Blt_Type pBlt ;
BltBatch_Type pBltBatch ;
BltFast_Type pBltFast ;
DeleteAttachedSurface_Type pDeleteAttachedSurface ;
EnumAttachedSurfaces_Type pEnumAttachedSurfaces ;
EnumOverlayZOrders_Type pEnumOverlayZOrders ;
Flip_Type pFlip ;
GetAttachedSurface_Type pGetAttachedSurface1 ;
GetAttachedSurface_Type pGetAttachedSurface3 ;
GetAttachedSurface_Type pGetAttachedSurface4 ;
GetAttachedSurface_Type pGetAttachedSurface7 ;
GetBltStatus_Type pGetBltStatus ;
GetCapsS_Type pGetCaps1S ;
GetCapsS_Type pGetCaps2S ;
GetCapsS_Type pGetCaps3S ;
GetCaps2S_Type pGetCaps4S ;
GetCaps2S_Type pGetCaps7S ;
GetClipper_Type pGetClipper ;
GetColorKey_Type pGetColorKey ;
GetDC_Type pGetDC ;
GetFlipStatus_Type pGetFlipStatus ;
GetOverlayPosition_Type pGetOverlayPosition ;
GetPalette_Type pGetPalette ;
GetPixelFormat_Type pGetPixelFormat ;
GetSurfaceDesc_Type pGetSurfaceDesc1 ;
GetSurfaceDesc2_Type pGetSurfaceDesc4 ;
2014-02-02 11:38:46 -05:00
GetSurfaceDesc2_Type pGetSurfaceDesc7 ;
2013-07-21 12:38:09 -04:00
//Initialize
IsLost_Type pIsLost ;
Lock_Type pLock ;
ReleaseDC_Type pReleaseDC ;
Restore_Type pRestore ;
SetClipper_Type pSetClipper ;
SetColorKey_Type pSetColorKey ;
SetOverlayPosition_Type pSetOverlayPosition ;
SetPalette_Type pSetPalette ;
Unlock1_Type pUnlock1 ;
Unlock4_Type pUnlock4 ;
UpdateOverlay_Type pUpdateOverlay ;
UpdateOverlayDisplay_Type pUpdateOverlayDisplay ;
UpdateOverlayZOrder_Type pUpdateOverlayZOrder ;
2014-01-24 11:38:44 -05:00
SetSurfaceDesc_Type pSetSurfaceDesc ;
2013-07-21 12:38:09 -04:00
/* DirectDrawClipper hook pointers */
QueryInterface_Type pQueryInterfaceC ;
AddRefC_Type pAddRefC ;
ReleaseC_Type pReleaseC ;
GetClipList_Type pGetClipList ;
GetHWnd_Type pGetHWnd ;
InitializeC_Type pInitializeC ;
IsClipListChanged_Type pIsClipListChanged ;
SetClipList_Type pSetClipList ;
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 ;
2013-11-10 11:38:21 -05:00
// GammaRamp
GammaRamp_Type pDDGetGammaRamp ;
GammaRamp_Type pDDSetGammaRamp ;
// ddraw global variables, constants & so on
2013-07-21 12:38:09 -04:00
# define MAXBACKBUFFERS 4
2013-11-10 11:38:21 -05:00
LPDIRECTDRAWSURFACE lpDDSEmu_Prim = NULL ;
LPDIRECTDRAWSURFACE lpDDSEmu_Back = NULL ;
2013-07-21 12:38:09 -04:00
LPDIRECTDRAWSURFACE lpDDSBack = NULL ;
2013-07-09 12:38:16 -04:00
LPDIRECTDRAWSURFACE lpDDZBuffer = NULL ;
2013-11-10 11:38:21 -05:00
LPDIRECTDRAWSURFACE lpDDTexture = NULL ;
2013-08-25 12:38:13 -04:00
// 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 ;
LPDIRECTDRAW lpBackBufferDD = NULL ;
int iBakBufferVersion ;
2013-07-21 12:38:09 -04:00
LPDIRECTDRAWPALETTE lpDDP = NULL ;
2013-11-10 11:38:21 -05:00
// v2.02.37: globals to store requested main surface capabilities
DDSURFACEDESC2 DDSD_Prim ;
DDSURFACEDESC2 DDSD_Back ;
DDSURFACEDESC2 DDSD_ZBuffer ;
2013-10-21 12:38:23 -04:00
DWORD DDZBufferCaps ;
2013-07-21 12:38:09 -04:00
DWORD PaletteEntries [ 256 ] ;
DWORD * Palette16BPP = NULL ;
void * EmuScreenBuffer = NULL ; // to implement pitch bug fix
DWORD rPitch = 0 ;
LPVOID rSurface = NULL ;
2013-11-10 11:38:26 -05:00
static void SetPixFmt ( LPDDSURFACEDESC2 ) ;
static void GetPixFmt ( LPDDSURFACEDESC2 ) ;
static HookEntry_Type ddHooks [ ] = {
2014-10-06 12:39:20 -04:00
{ HOOK_HOT_CANDIDATE , " DirectDrawCreate " , ( FARPROC ) NULL , ( FARPROC * ) & pDirectDrawCreate , ( FARPROC ) extDirectDrawCreate } ,
{ HOOK_HOT_CANDIDATE , " DirectDrawCreateEx " , ( FARPROC ) NULL , ( FARPROC * ) & pDirectDrawCreateEx , ( FARPROC ) extDirectDrawCreateEx } ,
{ HOOK_HOT_CANDIDATE , " DirectDrawEnumerateA " , ( FARPROC ) NULL , ( FARPROC * ) & pDirectDrawEnumerate , ( FARPROC ) extDirectDrawEnumerate } ,
{ HOOK_HOT_CANDIDATE , " DirectDrawEnumerateExA " , ( FARPROC ) NULL , ( FARPROC * ) & pDirectDrawEnumerateEx , ( FARPROC ) extDirectDrawEnumerateEx } ,
2014-05-14 12:39:12 -04:00
//{HOOK_IAT_CANDIDATE, "DirectDrawEnumerateW", (FARPROC)NULL, (FARPROC *)&pDirectDrawEnumerateW, (FARPROC)extDirectDrawCreate},
//{HOOK_IAT_CANDIDATE, "DirectDrawEnumerateExW", (FARPROC)NULL, (FARPROC *)&pDirectDrawEnumerateExW, (FARPROC)extDirectDrawCreate},
{ HOOK_IAT_CANDIDATE , 0 , NULL , 0 , 0 } // terminator
2013-11-10 11:38:26 -05:00
} ;
2013-07-21 12:38:09 -04:00
FARPROC Remap_ddraw_ProcAddress ( LPCSTR proc , HMODULE hModule )
{
2013-11-10 11:38:26 -05:00
FARPROC addr ;
if ( addr = RemapLibrary ( proc , hModule , ddHooks ) ) return addr ;
2013-07-21 12:38:09 -04:00
return NULL ;
}
/* ------------------------------------------------------------------------------ */
// auxiliary (static) functions
/* ------------------------------------------------------------------------------ */
2014-03-23 12:38:58 -04:00
DWORD gdwRefreshRate ;
# define MAXREFRESHDELAYCOUNT 20
int iRefreshDelays [ MAXREFRESHDELAYCOUNT ] = { 16 , 17 } ;
int iRefreshDelayCount = 2 ;
void SetVSyncDelays ( LPDIRECTDRAW lpdd )
{
2014-07-28 12:39:37 -04:00
DDSURFACEDESC2 ddsdRefreshRate ;
HRESULT res ;
2014-03-23 12:38:58 -04:00
memset ( & ddsdRefreshRate , 0 , sizeof ( ddsdRefreshRate ) ) ;
2014-07-28 12:39:37 -04:00
ddsdRefreshRate . dwSize = sizeof ( DDSURFACEDESC ) ;
res = ( * pGetDisplayMode ) ( lpdd , ( LPDDSURFACEDESC ) & ddsdRefreshRate ) ;
if ( res = = DDERR_GENERIC ) { // handling Win8 missing support for old ddraw interface
ddsdRefreshRate . dwSize = sizeof ( DDSURFACEDESC2 ) ;
res = ( * pGetDisplayMode ) ( lpdd , ( LPDDSURFACEDESC ) & ddsdRefreshRate ) ;
}
if ( res ) return ;
2014-10-08 12:39:38 -04:00
dxw . SetVSyncDelays ( ddsdRefreshRate . dwRefreshRate ) ;
2014-03-23 12:38:58 -04:00
}
2013-11-10 11:38:21 -05:00
static void Stopper ( char * s , int line )
{
char sMsg [ 81 ] ;
sprintf ( sMsg , " break: \" %s \" " , s ) ;
MessageBox ( 0 , sMsg , " break " , MB_OK | MB_ICONEXCLAMATION ) ;
}
2013-11-10 11:38:26 -05:00
//#define STOPPER_TEST // comment out to eliminate
2013-11-10 11:38:21 -05:00
# ifdef STOPPER_TEST
# define STOPPER(s) Stopper(s, __LINE__)
# else
# define STOPPER(s)
# endif
2013-07-09 12:38:16 -04:00
static char * sFourCC ( DWORD fcc )
{
static char sRet [ 5 ] ;
char c ;
int i ;
char * t = & sRet [ 0 ] ;
for ( i = 0 ; i < 4 ; i + + ) {
c = fcc & ( 0xFF ) ;
* t + + = isprint ( c ) ? c : ' . ' ;
c = c > > 8 ;
}
* t = 0 ;
return sRet ;
}
2013-09-16 12:38:17 -04:00
2013-11-10 11:38:21 -05:00
static char * DumpPixelFormat ( LPDDSURFACEDESC2 lpddsd )
2013-07-21 12:38:09 -04:00
{
2013-11-10 11:38:21 -05:00
static char sBuf [ 512 ] ;
char sItem [ 256 ] ;
DWORD flags = lpddsd - > ddpfPixelFormat . dwFlags ;
2014-02-19 11:38:50 -05:00
sprintf ( sBuf , " PixelFormat flags=%x(%s) BPP=%d " ,
flags , ExplainPixelFormatFlags ( flags ) , lpddsd - > ddpfPixelFormat . dwRGBBitCount ) ;
2013-11-10 11:38:21 -05:00
if ( flags & DDPF_RGB ) {
2013-11-10 11:38:26 -05:00
if ( flags & DDPF_ALPHAPIXELS ) {
sprintf ( sItem , " RGBA=(%x,%x,%x,%x) " ,
lpddsd - > ddpfPixelFormat . dwRBitMask ,
lpddsd - > ddpfPixelFormat . dwGBitMask ,
lpddsd - > ddpfPixelFormat . dwBBitMask ,
lpddsd - > ddpfPixelFormat . dwRGBAlphaBitMask ) ;
}
else {
sprintf ( sItem , " RGB=(%x,%x,%x) " ,
lpddsd - > ddpfPixelFormat . dwRBitMask ,
lpddsd - > ddpfPixelFormat . dwGBitMask ,
lpddsd - > ddpfPixelFormat . dwBBitMask ) ;
}
2013-11-10 11:38:21 -05:00
strcat ( sBuf , sItem ) ;
}
if ( flags & DDPF_YUV ) {
sprintf ( sItem , " YUVA=(%x,%x,%x,%x) " ,
2013-09-16 12:38:17 -04:00
lpddsd - > ddpfPixelFormat . dwYBitMask ,
lpddsd - > ddpfPixelFormat . dwUBitMask ,
lpddsd - > ddpfPixelFormat . dwVBitMask ,
lpddsd - > ddpfPixelFormat . dwYUVAlphaBitMask ) ;
2013-11-10 11:38:21 -05:00
strcat ( sBuf , sItem ) ;
}
if ( flags & DDPF_ZBUFFER ) {
sprintf ( sItem , " SdZSbL=(%x,%x,%x,%x) " ,
2013-09-16 12:38:17 -04:00
lpddsd - > ddpfPixelFormat . dwStencilBitDepth ,
lpddsd - > ddpfPixelFormat . dwZBitMask ,
lpddsd - > ddpfPixelFormat . dwStencilBitMask ,
lpddsd - > ddpfPixelFormat . dwLuminanceAlphaBitMask ) ;
2013-11-10 11:38:21 -05:00
strcat ( sBuf , sItem ) ;
}
if ( flags & DDPF_ALPHA ) {
sprintf ( sItem , " LBdBlZ=(%x,%x,%x,%x) " ,
2013-09-16 12:38:17 -04:00
lpddsd - > ddpfPixelFormat . dwLuminanceBitMask ,
lpddsd - > ddpfPixelFormat . dwBumpDvBitMask ,
lpddsd - > ddpfPixelFormat . dwBumpLuminanceBitMask ,
lpddsd - > ddpfPixelFormat . dwRGBZBitMask ) ;
2013-11-10 11:38:21 -05:00
strcat ( sBuf , sItem ) ;
}
if ( flags & DDPF_LUMINANCE ) {
sprintf ( sItem , " BMbMF=(%x,%x,%x,%x) " ,
2013-09-16 12:38:17 -04:00
lpddsd - > ddpfPixelFormat . dwBumpDuBitMask ,
lpddsd - > ddpfPixelFormat . MultiSampleCaps . wBltMSTypes ,
lpddsd - > ddpfPixelFormat . MultiSampleCaps . wFlipMSTypes ,
lpddsd - > ddpfPixelFormat . dwYUVZBitMask ) ;
2013-11-10 11:38:21 -05:00
strcat ( sBuf , sItem ) ;
}
if ( flags & DDPF_BUMPDUDV ) {
sprintf ( sItem , " O=(%x) " ,
2013-09-16 12:38:17 -04:00
lpddsd - > ddpfPixelFormat . dwOperations ) ;
2013-11-10 11:38:21 -05:00
strcat ( sBuf , sItem ) ;
}
if ( flags & DDPF_FOURCC ) {
sprintf ( sItem , " FourCC=%x(%s) " ,
lpddsd - > ddpfPixelFormat . dwFourCC , sFourCC ( lpddsd - > ddpfPixelFormat . dwFourCC ) ) ;
strcat ( sBuf , sItem ) ;
}
return sBuf ;
}
static void LogSurfaceAttributes ( LPDDSURFACEDESC lpddsd , char * label , int line )
{
2013-12-22 11:38:36 -05:00
if ( ! IsTraceDDRAW ) return ;
2013-11-23 11:38:29 -05:00
OutTrace ( " SurfaceDesc: %s Flags=%x(%s) " ,
2013-11-10 11:38:21 -05:00
label ,
lpddsd - > dwFlags , ExplainFlags ( lpddsd - > dwFlags ) ) ;
2013-11-23 11:38:29 -05:00
if ( lpddsd - > dwFlags & DDSD_BACKBUFFERCOUNT ) OutTrace ( " BackBufferCount=%d " , lpddsd - > dwBackBufferCount ) ;
if ( lpddsd - > dwFlags & DDSD_WIDTH ) OutTrace ( " Width=%d " , lpddsd - > dwWidth ) ;
if ( lpddsd - > dwFlags & DDSD_HEIGHT ) OutTrace ( " Height=%d " , lpddsd - > dwHeight ) ;
if ( lpddsd - > dwFlags & DDSD_PITCH ) OutTrace ( " Pitch=%d " , lpddsd - > lPitch ) ;
if ( lpddsd - > dwFlags & DDSD_MIPMAPCOUNT ) OutTrace ( " MipMapCount=%d " , lpddsd - > dwMipMapCount ) ;
2013-11-10 11:38:21 -05:00
if ( lpddsd - > dwFlags & DDSD_CAPS ) {
2013-11-23 11:38:29 -05:00
OutTrace ( " Caps=%x(%s) " , lpddsd - > ddsCaps . dwCaps , ExplainDDSCaps ( lpddsd - > ddsCaps . dwCaps ) ) ;
2013-11-10 11:38:21 -05:00
if ( lpddsd - > dwSize = = sizeof ( DDSURFACEDESC2 ) ) {
LPDDSURFACEDESC2 lpddsd2 = ( LPDDSURFACEDESC2 ) lpddsd ;
2013-11-23 11:38:29 -05:00
OutTrace ( " Caps2=%x(%s) " , lpddsd2 - > ddsCaps . dwCaps2 , ExplainDDSCaps2 ( lpddsd2 - > ddsCaps . dwCaps2 ) ) ;
OutTrace ( " Caps3=%x(%s) " , lpddsd2 - > ddsCaps . dwCaps3 , ExplainDDSCaps3 ( lpddsd2 - > ddsCaps . dwCaps3 ) ) ;
2013-11-10 11:38:21 -05:00
}
2013-07-09 12:38:16 -04:00
}
2013-11-23 11:38:29 -05:00
if ( lpddsd - > dwFlags & DDSD_CKDESTBLT ) OutTrace ( " CKDestBlt=(%x,%x) " , lpddsd - > ddckCKDestBlt . dwColorSpaceLowValue , lpddsd - > ddckCKDestBlt . dwColorSpaceHighValue ) ;
if ( lpddsd - > dwFlags & DDSD_CKDESTOVERLAY ) OutTrace ( " CKDestOverlay=(%x,%x) " , lpddsd - > ddckCKDestOverlay . dwColorSpaceLowValue , lpddsd - > ddckCKDestOverlay . dwColorSpaceHighValue ) ;
if ( lpddsd - > dwFlags & DDSD_CKSRCBLT ) OutTrace ( " CKSrcBlt=(%x,%x) " , lpddsd - > ddckCKSrcBlt . dwColorSpaceLowValue , lpddsd - > ddckCKSrcBlt . dwColorSpaceHighValue ) ;
if ( lpddsd - > dwFlags & DDSD_CKSRCOVERLAY ) OutTrace ( " CKSrcOverlay=(%x,%x) " , lpddsd - > ddckCKSrcOverlay . dwColorSpaceLowValue , lpddsd - > ddckCKSrcOverlay . dwColorSpaceHighValue ) ;
if ( lpddsd - > dwFlags & DDSD_PIXELFORMAT ) OutTrace ( " %s " , DumpPixelFormat ( ( LPDDSURFACEDESC2 ) lpddsd ) ) ;
if ( lpddsd - > dwFlags & DDSD_LPSURFACE ) OutTrace ( " Surface=%x " , lpddsd - > lpSurface ) ;
2014-09-20 12:39:46 -04:00
if ( lpddsd - > dwFlags & DDSD_ZBUFFERBITDEPTH ) OutTrace ( " ZBufferBitDepth=%d " , lpddsd - > dwZBufferBitDepth ) ;
if ( lpddsd - > dwFlags & DDSD_ALPHABITDEPTH ) OutTrace ( " AlphaBitDepth=%d " , lpddsd - > dwAlphaBitDepth ) ;
if ( lpddsd - > dwFlags & DDSD_REFRESHRATE ) OutTrace ( " RefreshRate=%d " , lpddsd - > dwRefreshRate ) ;
if ( lpddsd - > dwFlags & DDSD_LINEARSIZE ) OutTrace ( " LinearSize=%d " , lpddsd - > dwLinearSize ) ;
2014-11-15 11:39:58 -05:00
if ( lpddsd - > dwSize = = sizeof ( DDSURFACEDESC2 ) ) {
if ( lpddsd - > dwFlags & DDSD_TEXTURESTAGE ) OutTrace ( " TextureStage=%x " , ( ( LPDDSURFACEDESC2 ) lpddsd ) - > dwTextureStage ) ;
if ( lpddsd - > dwFlags & DDSD_FVF ) OutTrace ( " FVF=%x " , ( ( LPDDSURFACEDESC2 ) lpddsd ) - > dwFVF ) ;
}
2014-09-20 12:39:46 -04:00
2013-11-23 11:38:29 -05:00
OutTrace ( " \n " ) ;
2013-07-21 12:38:09 -04:00
}
2013-11-10 11:38:21 -05:00
static void DumpPixFmt ( LPDDSURFACEDESC2 lpdds )
{
2013-12-22 11:38:36 -05:00
OutTrace ( " PixelFormat: lpddsd=%x %s \n " , DumpPixelFormat ( lpdds ) ) ;
2013-11-10 11:38:21 -05:00
}
2013-07-21 12:38:09 -04:00
static void DumpSurfaceAttributes ( LPDDSURFACEDESC lpddsd , char * label , int line )
{
if ( ! IsDebug ) return ;
LogSurfaceAttributes ( lpddsd , label , line ) ;
}
2013-09-16 12:38:17 -04:00
static void DescribeSurface ( LPDIRECTDRAWSURFACE lpdds , int dxversion , char * label , int line )
{
DDSURFACEDESC2 ddsd ;
HRESULT res ;
int dwSize = ( dxversion < 4 ) ? sizeof ( DDSURFACEDESC ) : sizeof ( DDSURFACEDESC2 ) ;
memset ( & ddsd , 0 , dwSize ) ;
ddsd . dwSize = dwSize ;
2014-02-02 11:38:46 -05:00
switch ( dxversion ) {
case 0 :
case 1 :
case 2 :
case 3 :
2013-09-16 12:38:17 -04:00
if ( pGetSurfaceDesc1 )
res = ( * pGetSurfaceDesc1 ) ( lpdds , ( LPDDSURFACEDESC ) & ddsd ) ;
else
res = lpdds - > GetSurfaceDesc ( ( LPDDSURFACEDESC ) & ddsd ) ;
2014-02-02 11:38:46 -05:00
break ;
case 4 :
case 5 :
case 6 :
2013-09-16 12:38:17 -04:00
if ( pGetSurfaceDesc4 )
res = ( * pGetSurfaceDesc4 ) ( ( LPDIRECTDRAWSURFACE2 ) lpdds , & ddsd ) ;
else
res = lpdds - > GetSurfaceDesc ( ( LPDDSURFACEDESC ) & ddsd ) ;
2014-02-02 11:38:46 -05:00
break ;
case 7 :
if ( pGetSurfaceDesc7 )
res = ( * pGetSurfaceDesc7 ) ( ( LPDIRECTDRAWSURFACE2 ) lpdds , & ddsd ) ;
else
res = lpdds - > GetSurfaceDesc ( ( LPDDSURFACEDESC ) & ddsd ) ;
break ;
2013-09-16 12:38:17 -04:00
}
if ( res ) return ;
2014-06-02 12:38:47 -04:00
OutTraceDW ( " Surface %s: ddsd=%x dxversion=%d " , label , lpdds , dxversion ) ;
2013-11-10 11:38:21 -05:00
LogSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , label , line ) ;
2013-07-21 12:38:09 -04:00
}
/* ------------------------------------------------------------------------------ */
2013-11-10 11:38:21 -05:00
// auxiliary (static) functions for palette handling
2013-07-21 12:38:09 -04:00
/* ------------------------------------------------------------------------------ */
BOOL isPaletteUpdated ;
void mySetPalette ( int dwstart , int dwcount , LPPALETTEENTRY lpentries )
{
int i ;
2013-11-10 11:38:24 -05:00
extern DXWNDSTATUS * pStatus ;
for ( int idx = 0 ; idx < dwcount ; idx + + )
pStatus - > Palette [ dwstart + idx ] = lpentries [ idx ] ;
2013-11-28 11:38:31 -05:00
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)
2013-07-21 12:38:09 -04:00
DWORD grayscale ;
2013-07-09 12:38:16 -04:00
//grayscale = ((DWORD)lpentries[i].peRed + (DWORD)lpentries[i].peGreen + (DWORD)lpentries[i].peBlue) / 3;
2013-11-28 11:38:31 -05:00
grayscale = ( ( ( DWORD ) PalColor . peRed * 30 ) + ( ( DWORD ) PalColor . peGreen * 59 ) + ( ( DWORD ) PalColor . peBlue ) * 11 ) / 100 ;
PalColor . peRed = PalColor . peGreen = PalColor . peBlue = ( BYTE ) grayscale ;
2013-07-21 12:38:09 -04:00
}
2013-11-28 11:38:31 -05:00
switch ( dxw . ActualPixelFormat . dwRGBBitCount ) {
case 32 :
2013-07-21 12:38:09 -04:00
PaletteEntries [ i + dwstart ] =
2013-11-28 11:38:31 -05:00
( ( ( DWORD ) PalColor . peRed ) < < 16 ) + ( ( ( DWORD ) PalColor . peGreen ) < < 8 ) + ( ( DWORD ) PalColor . peBlue ) ;
break ;
case 16 :
2013-07-21 12:38:09 -04:00
PaletteEntries [ i + dwstart ] = ( dxw . ActualPixelFormat . dwGBitMask = = 0x03E0 ) ?
2013-11-28 11:38:31 -05:00
( ( ( DWORD ) PalColor . peRed & 0xF8 ) < < 8 ) + ( ( ( DWORD ) PalColor . peGreen & 0xFC ) < < 3 ) + ( ( ( DWORD ) PalColor . peBlue & 0xF8 ) > > 3 )
2013-07-21 12:38:09 -04:00
:
2013-11-28 11:38:31 -05:00
( ( ( DWORD ) PalColor . peRed & 0xF8 ) < < 8 ) + ( ( ( DWORD ) PalColor . peGreen & 0xF8 ) < < 3 ) + ( ( ( DWORD ) PalColor . peBlue & 0xF8 ) > > 3 ) ;
break ;
default :
2013-12-22 11:38:36 -05:00
OutTraceDW ( " ASSERT: unsupported Color BPP=%d \n " , dxw . ActualPixelFormat . dwRGBBitCount ) ;
2013-11-28 11:38:31 -05:00
break ;
2013-07-21 12:38:09 -04:00
}
}
isPaletteUpdated = TRUE ;
}
void InitDDScreenParameters ( LPDIRECTDRAW lpdd )
{
HRESULT res ;
2014-07-28 12:39:37 -04:00
DDSURFACEDESC2 ddsd ;
2013-07-21 12:38:09 -04:00
ddsd . dwSize = sizeof ( DDSURFACEDESC ) ;
2014-07-28 12:39:37 -04:00
res = ( * pGetDisplayMode ) ( lpdd , ( LPDDSURFACEDESC ) & ddsd ) ;
if ( res = = DDERR_GENERIC ) { // Win8 missing support for old ddraw interfaces
ddsd . dwSize = sizeof ( DDSURFACEDESC2 ) ;
res = ( * pGetDisplayMode ) ( lpdd , ( LPDDSURFACEDESC ) & ddsd ) ;
}
if ( res ) {
2013-07-21 12:38:09 -04:00
OutTraceE ( " GetDisplayMode: ERROR res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
return ;
}
2013-12-22 11:38:36 -05:00
OutTraceDW ( " InitDDScreenParameters: Actual %s \n " , DumpPixelFormat ( ( LPDDSURFACEDESC2 ) & ddsd ) ) ;
2013-07-21 12:38:09 -04:00
dxw . ActualPixelFormat = ddsd . ddpfPixelFormat ;
2013-11-10 11:38:26 -05:00
if ( dxw . VirtualPixelFormat . dwRGBBitCount = = 0 ) dxw . VirtualPixelFormat = ddsd . ddpfPixelFormat ;
2013-07-21 12:38:09 -04:00
SetBltTransformations ( ) ;
return ;
}
void InitDSScreenParameters ( LPDIRECTDRAWSURFACE lpdds )
{
HRESULT res ;
DDPIXELFORMAT p ;
2013-11-10 11:38:26 -05:00
DDSURFACEDESC2 ddsd ;
2013-07-21 12:38:09 -04:00
p . dwSize = sizeof ( DDPIXELFORMAT ) ;
if ( res = ( * pGetPixelFormat ) ( lpdds , & p ) ) {
OutTraceE ( " GetPixelFormat: ERROR res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
return ;
}
2013-11-10 11:38:26 -05:00
ddsd . ddpfPixelFormat = p ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " InitDSScreenParameters: Actual %s \n " , DumpPixelFormat ( & ddsd ) ) ;
2013-11-28 11:38:31 -05:00
dxw . ActualPixelFormat = p ;
2013-07-21 12:38:09 -04:00
SetBltTransformations ( ) ;
return ;
}
void InitScreenParameters ( )
{
DEVMODE CurrDevMode ;
static int DoOnce = FALSE ;
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 ) ;
2014-08-29 12:39:42 -04:00
if ( ! ( * pEnumDisplaySettings ) ( NULL , ENUM_CURRENT_SETTINGS , & CurrDevMode ) ) {
2013-07-21 12:38:09 -04:00
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
2013-12-22 11:38:36 -05:00
OutTraceDW ( " InitScreenParameters: RGBBitCount=%d \n " , CurrDevMode . dmBitsPerPel ) ;
2013-07-21 12:38:09 -04:00
SetBltTransformations ( ) ;
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 ;
2014-11-01 12:38:41 -04:00
case 15 : // v2.02.53: Hesperian Wars - so far the only game setting color depth to 15 BPP!
2013-07-21 12:38:09 -04:00
case 16 :
pf - > dwRGBBitCount = 16 ;
if ( dxw . dwFlags1 & USERGB565 ) {
pf - > dwRBitMask = 0xf800 ;
pf - > dwGBitMask = 0x07e0 ;
pf - > dwBBitMask = 0x001f ;
2013-11-10 11:38:26 -05:00
pf - > dwRGBAlphaBitMask = 0x0000 ;
2013-07-21 12:38:09 -04:00
}
else {
2014-11-01 12:38:41 -04:00
if ( ! ( dxw . dwFlags4 & NOALPHACHANNEL ) & & ( ColorDepth = = 16 ) ) pf - > dwFlags | = DDPF_ALPHAPIXELS ; // v2.02.33,40,53
2013-07-21 12:38:09 -04:00
pf - > dwRBitMask = 0x7c00 ;
pf - > dwGBitMask = 0x03e0 ;
pf - > dwBBitMask = 0x001f ;
2013-11-10 11:38:26 -05:00
pf - > dwRGBAlphaBitMask = 0x8000 ;
2013-07-21 12:38:09 -04:00
}
break ;
case 24 :
pf - > dwRGBBitCount = 24 ;
pf - > dwRBitMask = 0x00FF0000 ;
pf - > dwGBitMask = 0x0000FF00 ;
pf - > dwBBitMask = 0x000000FF ;
pf - > dwRGBAlphaBitMask = 0x00000000 ;
break ;
case 32 :
2013-11-10 11:38:26 -05:00
if ( ! ( dxw . dwFlags4 & NOALPHACHANNEL ) ) pf - > dwFlags | = DDPF_ALPHAPIXELS ; // v2.02.33
2013-07-21 12:38:09 -04:00
pf - > dwRGBBitCount = 32 ;
pf - > dwRBitMask = 0x00FF0000 ;
pf - > dwGBitMask = 0x0000FF00 ;
pf - > dwBBitMask = 0x000000FF ;
pf - > dwRGBAlphaBitMask = 0xFF000000 ;
break ;
}
}
2014-10-06 12:39:20 -04:00
static void ddSetCompatibility ( )
2013-07-21 12:38:09 -04:00
{
2014-10-06 12:39:20 -04:00
typedef HRESULT ( WINAPI * SetAppCompatData_Type ) ( DWORD , DWORD ) ;
SetAppCompatData_Type pSetAppCompatData ;
HRESULT res ;
2013-07-21 12:38:09 -04:00
HINSTANCE hinst ;
2014-10-06 12:39:20 -04:00
hinst = LoadLibrary ( " ddraw.dll " ) ;
pSetAppCompatData = ( SetAppCompatData_Type ) ( * pGetProcAddress ) ( hinst , " SetAppCompatData " ) ;
if ( pSetAppCompatData ) {
res = ( * pSetAppCompatData ) ( 2 , 0 ) ;
OutTraceDW ( " HookDirectDraw: SetAppCompatData(2,0) ret=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-07-21 12:38:09 -04:00
}
2014-09-20 12:39:46 -04:00
else
OutTraceDW ( " HookDirectDraw: missing SetAppCompatData call \n " ) ;
2014-10-06 12:39:20 -04:00
FreeLibrary ( hinst ) ;
}
int HookDirectDraw ( HMODULE module , int version )
{
2014-11-19 11:40:00 -05:00
if ( dxw . dwFlags2 & SETCOMPATIBILITY ) {
static BOOL AlreadyDone = FALSE ;
if ( ! AlreadyDone ) {
ddSetCompatibility ( ) ;
AlreadyDone = TRUE ;
}
}
2014-10-06 12:39:20 -04:00
2014-06-14 12:39:22 -04:00
if ( dxw . dwFlags4 & HOTPATCH ) {
// hot-patch all APIs and that's all folks!
HookLibrary ( module , ddHooks , " ddraw.dll " ) ;
return TRUE ;
}
2014-10-06 12:39:20 -04:00
2014-10-07 12:39:31 -04:00
//const GUID dd7 = {0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b};
2014-06-14 12:39:22 -04:00
HMODULE hinst ;
2013-07-21 12:38:09 -04:00
OutTraceB ( " HookDirectDraw version=%d \n " , version ) ; //GHO
switch ( version ) {
case 0 : // automatic
2014-10-06 12:39:20 -04:00
HookLibrary ( module , ddHooks , " ddraw.dll " ) ;
2013-07-21 12:38:09 -04:00
break ;
case 1 :
case 2 :
case 3 :
case 5 :
case 6 :
2014-10-06 12:39:20 -04:00
HookLibrary ( module , ddHooks , " ddraw.dll " ) ;
2014-06-14 12:39:22 -04:00
if ( ! pDirectDrawCreate ) { // required for IAT patching
hinst = LoadLibrary ( " ddraw.dll " ) ;
pDirectDrawCreate = ( DirectDrawCreate_Type ) GetProcAddress ( hinst , " DirectDrawCreate " ) ;
pDirectDrawEnumerate = ( DirectDrawEnumerate_Type ) GetProcAddress ( hinst , " DirectDrawEnumerateA " ) ;
}
if ( pDirectDrawCreate ) {
LPDIRECTDRAW lpdd ;
BOOL res ;
HookLibrary ( module , ddHooks , " ddraw.dll " ) ;
res = extDirectDrawCreate ( 0 , & lpdd , 0 ) ;
if ( res ) {
OutTraceE ( " DirectDrawCreate: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
}
lpdd - > Release ( ) ;
}
break ;
2013-07-21 12:38:09 -04:00
case 7 :
2014-10-06 12:39:20 -04:00
//hinst = LoadLibrary("ddraw.dll");
2014-06-14 12:39:22 -04:00
HookLibrary ( module , ddHooks , " ddraw.dll " ) ;
if ( ! pDirectDrawCreate ) { // required for IAT patching in "Crimson skies"
hinst = LoadLibrary ( " ddraw.dll " ) ;
pDirectDrawEnumerate = ( DirectDrawEnumerate_Type ) GetProcAddress ( hinst , " DirectDrawEnumerateA " ) ;
pDirectDrawEnumerateEx = ( DirectDrawEnumerateEx_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 ( ) ;
}
2014-10-06 12:39:20 -04:00
//if(pDirectDrawCreateEx){
// LPDIRECTDRAW lpdd;
// BOOL res;
2014-06-14 12:39:22 -04:00
// HookLibrary(module, ddHooks, "ddraw.dll");
2014-10-06 12:39:20 -04:00
// res=extDirectDrawCreateEx(0, &lpdd, dd7, 0);
// if (res) OutTraceE("DirectDrawCreateEx: ERROR res=%x(%s)\n", res, ExplainDDError(res));
// lpdd->Release();
//}
2013-07-21 12:38:09 -04:00
break ;
}
if ( pDirectDrawCreate | | pDirectDrawCreateEx ) return 1 ;
return 0 ;
}
Unlock4_Type pUnlockMethod ( LPDIRECTDRAWSURFACE lpdds )
{
2014-12-10 11:39:52 -05:00
// to do: return extUnlock for unhooked surfaces
2013-07-21 12:38:09 -04:00
char sMsg [ 81 ] ;
2014-11-28 11:40:02 -05:00
void * extUnlock = NULL ;
if ( lpdds ) {
__try { // v2.02.31: catch some possible exception (i.e. Abomination in EMULATION mode)
extUnlock = ( void * ) * ( DWORD * ) ( * ( DWORD * ) lpdds + 128 ) ;
}
__except ( EXCEPTION_EXECUTE_HANDLER ) {
OutTraceE ( " Exception at %d \n " , __LINE__ ) ;
extUnlock = NULL ;
} ;
if ( extUnlock = = ( void * ) extUnlock1 ) return ( Unlock4_Type ) pUnlock1 ;
if ( extUnlock = = ( void * ) extUnlock4 ) return ( Unlock4_Type ) pUnlock4 ;
if ( extUnlock = = ( void * ) extUnlockDir1 ) return ( Unlock4_Type ) pUnlock1 ;
if ( extUnlock = = ( void * ) extUnlockDir4 ) return ( Unlock4_Type ) pUnlock4 ;
}
2013-07-21 12:38:09 -04:00
sprintf_s ( sMsg , 80 , " pUnlockMethod: pUnlock(%x) can't match %x \n " , lpdds , extUnlock ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( sMsg ) ;
2013-07-21 12:38:09 -04:00
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " pUnlockMethod " , MB_OK | MB_ICONEXCLAMATION ) ;
if ( pUnlock4 ) return pUnlock4 ;
return ( Unlock4_Type ) pUnlock1 ;
}
2014-06-07 12:39:29 -04:00
#if 0
Lock_Type pLockMethod ( LPDIRECTDRAWSURFACE lpdds )
{
char sMsg [ 81 ] ;
2014-11-28 11:40:02 -05:00
void * extLock = NULL ;
if ( lpdds ) {
__try { // v2.02.31: catch some possible exception (i.e. Abomination in EMULATION mode)
extLock = ( void * ) * ( DWORD * ) ( * ( DWORD * ) lpdds + 128 ) ;
}
__except ( EXCEPTION_EXECUTE_HANDLER ) {
OutTraceE ( " Exception at %d \n " , __LINE__ ) ;
extLock = NULL ;
} ;
if ( extUnlock = = ( void * ) extUnlock1 ) return pLock1 ;
if ( extUnlock = = ( void * ) extUnlock4 ) return pLock4 ;
if ( extUnlock = = ( void * ) extUnlockDir1 ) return pLock1 ;
if ( extUnlock = = ( void * ) extUnlockDir4 ) return pLock4 ;
}
sprintf_s ( sMsg , 80 , " pLockMethod: pUnlock(%x) can't match %x \n " , lpdds , extLock ) ;
2014-06-07 12:39:29 -04:00
OutTraceDW ( sMsg ) ;
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " pLockMethod " , MB_OK | MB_ICONEXCLAMATION ) ;
if ( pLock4 ) return pLock4 ;
return pLock1 ;
}
# endif
2013-07-21 12:38:09 -04:00
CreateSurface2_Type pCreateSurfaceMethod ( LPDIRECTDRAWSURFACE lpdds )
{
char sMsg [ 81 ] ;
2014-11-28 11:40:02 -05:00
void * extUnlock = NULL ;
if ( lpdds ) {
__try { // v2.02.31: catch some possible exception (i.e. Abomination in EMULATION mode)
extUnlock = ( void * ) * ( DWORD * ) ( * ( DWORD * ) lpdds + 128 ) ; }
__except ( EXCEPTION_EXECUTE_HANDLER ) {
OutTraceE ( " Exception at %d \n " , __LINE__ ) ;
extUnlock = NULL ;
} ;
if ( extUnlock = = ( void * ) extUnlock1 ) return ( CreateSurface2_Type ) pCreateSurface1 ;
if ( extUnlock = = ( void * ) extUnlock4 ) return pCreateSurface7 ? ( CreateSurface2_Type ) pCreateSurface7 : ( CreateSurface2_Type ) pCreateSurface4 ;
if ( extUnlock = = ( void * ) extUnlockDir1 ) return ( CreateSurface2_Type ) pCreateSurface1 ;
if ( extUnlock = = ( void * ) extUnlockDir4 ) return pCreateSurface7 ? ( CreateSurface2_Type ) pCreateSurface7 : ( CreateSurface2_Type ) pCreateSurface4 ;
}
2013-07-21 12:38:09 -04:00
sprintf_s ( sMsg , 80 , " pCreateSurfaceMethod: pUnlock(%x) can't match %x \n " , lpdds , extUnlock ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( sMsg ) ;
2013-07-21 12:38:09 -04:00
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " pCreateSurfaceMethod " , MB_OK | MB_ICONEXCLAMATION ) ;
2014-11-28 11:40:02 -05:00
if ( pCreateSurface7 ) return pCreateSurface7 ;
2013-07-21 12:38:09 -04:00
if ( pCreateSurface4 ) return pCreateSurface4 ;
return ( CreateSurface2_Type ) pCreateSurface1 ;
}
2014-02-03 11:38:53 -05:00
GetSurfaceDesc2_Type pGetSurfaceDescMethod ( LPDIRECTDRAWSURFACE lpdds )
{
char sMsg [ 81 ] ;
void * extUnlock ;
extUnlock = ( void * ) * ( DWORD * ) ( * ( DWORD * ) lpdds + 128 ) ;
if ( extUnlock = = ( void * ) extUnlock1 ) return ( GetSurfaceDesc2_Type ) pGetSurfaceDesc1 ;
if ( extUnlock = = ( void * ) extUnlock4 ) return pGetSurfaceDesc7 ? pGetSurfaceDesc7 : pGetSurfaceDesc4 ;
if ( extUnlock = = ( void * ) extUnlockDir1 ) return ( GetSurfaceDesc2_Type ) pGetSurfaceDesc1 ;
if ( extUnlock = = ( void * ) extUnlockDir4 ) return pGetSurfaceDesc7 ? pGetSurfaceDesc7 : pGetSurfaceDesc4 ;
sprintf_s ( sMsg , 80 , " pGetSurfaceDescMethod: pUnlock(%x) can't match %x \n " , lpdds , extUnlock ) ;
OutTraceDW ( sMsg ) ;
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " pGetSurfaceDescMethod " , MB_OK | MB_ICONEXCLAMATION ) ;
if ( pGetSurfaceDesc4 ) return pGetSurfaceDesc4 ;
return ( GetSurfaceDesc2_Type ) pGetSurfaceDesc1 ;
}
2013-07-30 12:38:11 -04:00
int SurfaceDescrSize ( LPDIRECTDRAWSURFACE lpdds )
{
char sMsg [ 81 ] ;
void * extUnlock ;
extUnlock = ( void * ) * ( DWORD * ) ( * ( DWORD * ) lpdds + 128 ) ;
if ( extUnlock = = ( void * ) extUnlock1 ) return sizeof ( DDSURFACEDESC ) ;
if ( extUnlock = = ( void * ) extUnlock4 ) return sizeof ( DDSURFACEDESC2 ) ;
if ( extUnlock = = ( void * ) extUnlockDir1 ) return sizeof ( DDSURFACEDESC ) ;
if ( extUnlock = = ( void * ) extUnlockDir4 ) return sizeof ( DDSURFACEDESC2 ) ;
sprintf_s ( sMsg , 80 , " pCreateSurfaceMethod: pUnlock(%x) can't match %x \n " , lpdds , extUnlock ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( sMsg ) ;
2013-07-30 12:38:11 -04:00
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " SurfaceDescrSize " , MB_OK | MB_ICONEXCLAMATION ) ;
return sizeof ( DDSURFACEDESC ) ;
}
2013-07-21 12:38:09 -04:00
int lpddsHookedVersion ( LPDIRECTDRAWSURFACE lpdds )
{
char sMsg [ 81 ] ;
2014-11-28 11:40:02 -05:00
void * extGetCaps = NULL ;
if ( lpdds ) {
__try {
extGetCaps = ( void * ) * ( DWORD * ) ( * ( DWORD * ) lpdds + 56 ) ;
}
__except ( EXCEPTION_EXECUTE_HANDLER ) {
extGetCaps = NULL ;
} ;
if ( extGetCaps = = ( void * ) extGetCaps1S ) return 1 ;
if ( extGetCaps = = ( void * ) extGetCaps2S ) return 2 ;
if ( extGetCaps = = ( void * ) extGetCaps3S ) return 3 ;
if ( extGetCaps = = ( void * ) extGetCaps4S ) return 4 ;
if ( extGetCaps = = ( void * ) extGetCaps7S ) return 7 ;
}
2013-07-21 12:38:09 -04:00
sprintf_s ( sMsg , 80 , " lpddsHookedVersion(%x) can't match %x \n " , lpdds , extGetCaps ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( sMsg ) ;
2013-07-21 12:38:09 -04:00
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " lpddsHookedVersion " , MB_OK | MB_ICONEXCLAMATION ) ;
return 0 ;
}
int lpddHookedVersion ( LPDIRECTDRAW lpdd )
{
char sMsg [ 81 ] ;
2014-11-28 11:40:02 -05:00
void * extCreateSurface = NULL ;
if ( lpPrimaryDD ) {
__try {
extCreateSurface = ( void * ) * ( DWORD * ) ( * ( DWORD * ) lpdd + 24 ) ;
}
__except ( EXCEPTION_EXECUTE_HANDLER ) {
extCreateSurface = NULL ;
} ;
if ( extCreateSurface = = ( void * ) extCreateSurface7 ) return 7 ;
if ( extCreateSurface = = ( void * ) extCreateSurface4 ) return 4 ;
if ( extCreateSurface = = ( void * ) extCreateSurface2 ) return 2 ;
if ( extCreateSurface = = ( void * ) extCreateSurface1 ) return 1 ;
}
2013-07-21 12:38:09 -04:00
sprintf_s ( sMsg , 80 , " lpddHookedVersion(%x) can't match %x \n " , lpdd , extCreateSurface ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( sMsg ) ;
2013-07-21 12:38:09 -04:00
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " lpddHookedVersion " , MB_OK | MB_ICONEXCLAMATION ) ;
return 0 ;
}
2014-08-29 12:39:42 -04:00
void RegisterPixelFormat ( LPDIRECTDRAWSURFACE lpdds )
{
DDSURFACEDESC2 ddsdpix ;
memset ( ( void * ) & ddsdpix , 0 , sizeof ( DDSURFACEDESC2 ) ) ;
ddsdpix . dwSize = SurfaceDescrSize ( lpdds ) ;
ddsdpix . dwFlags = DDSD_PIXELFORMAT ;
( * pGetSurfaceDescMethod ( lpdds ) ) ( ( LPDIRECTDRAWSURFACE2 ) lpdds , & ddsdpix ) ;
GetHookInfo ( ) - > pfd = ddsdpix . ddpfPixelFormat ; // v2.02.88
OutTraceB ( " RegisterPixelFormat: lpdds=%x %s \n " , lpdds , DumpPixelFormat ( & ddsdpix ) ) ;
}
2013-07-21 12:38:09 -04:00
/* ------------------------------------------------------------------ */
2013-11-10 11:38:26 -05:00
// 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
static void SetPixFmt ( LPDDSURFACEDESC2 lpdd )
2013-07-21 12:38:09 -04:00
{
2013-12-22 11:38:36 -05:00
OutTraceDW ( " SetPixFmt: BPP=%d Use565=%d NoAlpha=%d \n " ,
2013-11-10 11:38:26 -05:00
dxw . VirtualPixelFormat . dwRGBBitCount ,
dxw . dwFlags1 & USERGB565 ? 1 : 0 ,
dxw . dwFlags4 & NOALPHACHANNEL ? 1 : 0 ) ;
2013-08-30 12:38:14 -04:00
2013-07-21 12:38:09 -04:00
memset ( & lpdd - > ddpfPixelFormat , 0 , sizeof ( DDPIXELFORMAT ) ) ;
lpdd - > ddpfPixelFormat . dwSize = sizeof ( DDPIXELFORMAT ) ;
2013-11-10 11:38:26 -05:00
switch ( dxw . VirtualPixelFormat . dwRGBBitCount )
2013-07-21 12:38:09 -04:00
{
2013-11-10 11:38:26 -05:00
case 8 :
2014-11-01 12:38:41 -04:00
case 15 :
2013-11-10 11:38:26 -05:00
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 ;
2013-07-21 12:38:09 -04:00
}
2013-11-10 11:38:26 -05:00
2013-07-21 12:38:09 -04:00
// remember current virtual settings
dxw . VirtualPixelFormat = lpdd - > ddpfPixelFormat ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " SetPixFmt: %s \n " , DumpPixelFormat ( lpdd ) ) ;
2013-11-10 11:38:26 -05:00
}
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:26 -05:00
// retrieves the stored pixel format
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:26 -05:00
static void GetPixFmt ( LPDDSURFACEDESC2 lpdd )
{
lpdd - > ddpfPixelFormat = dxw . VirtualPixelFormat ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetPixFmt: %s \n " , DumpPixelFormat ( lpdd ) ) ;
2013-07-21 12:38:09 -04:00
}
/* ------------------------------------------------------------------ */
// hook query functions that determines the object versioning ....
/* ------------------------------------------------------------------ */
int Set_dwSize_From_Surface ( LPDIRECTDRAWSURFACE lpdds )
{
int dxversion ;
if ( lpdds = = NULL | |
lpdds = = lpDDSEmu_Prim | |
lpdds = = lpDDSEmu_Back
)
2013-08-25 12:38:13 -04:00
dxversion = lpddHookedVersion ( lpPrimaryDD ) ; // v2.01.87-v2.02.31 fix
2013-07-21 12:38:09 -04:00
else
dxversion = lpddsHookedVersion ( lpdds ) ;
return ( dxversion < 4 ) ? sizeof ( DDSURFACEDESC ) : sizeof ( DDSURFACEDESC2 ) ;
}
int Set_dwSize_From_DDraw ( LPDIRECTDRAW lpdd )
{
return ( lpddHookedVersion ( lpdd ) < 4 ) ? sizeof ( DDSURFACEDESC ) : sizeof ( DDSURFACEDESC2 ) ;
}
2014-04-01 12:38:40 -04:00
void HookDDSession ( LPDIRECTDRAW * lplpdd , int dxversion )
2013-07-21 12:38:09 -04:00
{
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Hooking directdraw session dd=%x dxversion=%d thread_id=%x \n " ,
2013-07-21 12:38:09 -04:00
* lplpdd , dxversion , GetCurrentThreadId ( ) ) ;
// IDIrectDraw::QueryInterface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd ) , extQueryInterfaceD , ( void * * ) & pQueryInterfaceD , " QueryInterface(D) " ) ;
// IDIrectDraw::Release
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 8 ) , extReleaseD , ( void * * ) & pReleaseD , " Release(D) " ) ;
// IDIrectDraw::CreateClipper
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 16 ) , extCreateClipper , ( void * * ) & pCreateClipper , " CreateClipper(D) " ) ;
// IDIrectDraw::CreatePalette
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 20 ) , extCreatePalette , ( void * * ) & pCreatePalette , " CreatePalette(D) " ) ;
// IDIrectDraw::CreateSurface
switch ( dxversion ) {
case 1 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 24 ) , extCreateSurface1 , ( void * * ) & pCreateSurface1 , " CreateSurface(S1) " ) ;
break ;
case 2 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 24 ) , extCreateSurface2 , ( void * * ) & pCreateSurface2 , " CreateSurface(S2) " ) ;
break ;
case 4 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 24 ) , extCreateSurface4 , ( void * * ) & pCreateSurface4 , " CreateSurface(S4) " ) ;
break ;
case 7 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 24 ) , extCreateSurface7 , ( void * * ) & pCreateSurface7 , " CreateSurface(S7) " ) ;
break ;
}
// IDIrectDraw::DuplicateSurface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 28 ) , extDuplicateSurface , ( void * * ) & pDuplicateSurface , " DuplicateSurface(D) " ) ;
// IDIrectDraw::EnumDisplayModes
switch ( dxversion ) {
case 1 :
case 2 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 32 ) , extEnumDisplayModes1 , ( void * * ) & pEnumDisplayModes1 , " EnumDisplayModes(D1) " ) ;
break ;
case 4 :
case 7 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 32 ) , extEnumDisplayModes4 , ( void * * ) & pEnumDisplayModes4 , " EnumDisplayModes(D4) " ) ;
break ;
}
// IDIrectDraw::FlipToGDISurface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 40 ) , extFlipToGDISurface , ( void * * ) & pFlipToGDISurface , " FlipToGDISurface(D) " ) ;
// IDIrectDraw::GetDisplayMode
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 48 ) , extGetDisplayMode , ( void * * ) & pGetDisplayMode , " GetDisplayMode(D) " ) ;
// IDIrectDraw::GetGDISurface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 56 ) , extGetGDISurface , ( void * * ) & pGetGDISurface , " GetGDISurface(D) " ) ;
2013-11-10 11:38:24 -05:00
// IDIrectDraw::Initialize
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 72 ) , extInitialize , ( void * * ) & pInitialize , " Initialize(D) " ) ;
2013-07-21 12:38:09 -04:00
// IDIrectDraw::SetCooperativeLevel
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 80 ) , extSetCooperativeLevel , ( void * * ) & pSetCooperativeLevel , " SetCooperativeLevel(D) " ) ;
// IDIrectDraw::SetDisplayMode
if ( dxversion > 1 )
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 84 ) , extSetDisplayMode2 , ( void * * ) & pSetDisplayMode2 , " SetDisplayMode(D2) " ) ;
else
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 84 ) , extSetDisplayMode1 , ( void * * ) & pSetDisplayMode1 , " SetDisplayMode(D1) " ) ;
// IDIrectDraw::WaitForVerticalBlank
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 88 ) , extWaitForVerticalBlank , ( void * * ) & pWaitForVerticalBlank , " WaitForVerticalBlank(D) " ) ;
2013-12-22 11:38:36 -05:00
// IDIrectDraw::GetAvailableVidMem
if ( dxversion = = 2 )
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 92 ) , extGetAvailableVidMem2 , ( void * * ) & pGetAvailableVidMem2 , " GetAvailableVidMem(D2) " ) ;
2014-04-01 12:38:40 -04:00
if ( dxversion > = 4 ) {
// IDIrectDraw::GetAvailableVidMem
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 92 ) , extGetAvailableVidMem4 , ( void * * ) & pGetAvailableVidMem4 , " GetAvailableVidMem(D4) " ) ;
// IDIrectDraw::TestCooperativeLevel
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 104 ) , extTestCooperativeLevel , ( void * * ) & pTestCooperativeLevel , " TestCooperativeLevel(D) " ) ;
}
2013-07-21 12:38:09 -04:00
if ( ! ( dxw . dwTFlags & OUTPROXYTRACE ) ) return ;
// Just proxed ...
// IDIrectDraw::AddRef
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 4 ) , extAddRefDProxy , ( void * * ) & pAddRefD , " AddRef(D) " ) ;
// IDIrectDraw::Compact
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 12 ) , extCompactProxy , ( void * * ) & pCompact , " Compact(D) " ) ;
// IDIrectDraw::EnumSurfaces
if ( dxversion < 4 )
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 36 ) , extEnumSurfacesProxy1 , ( void * * ) & pEnumSurfaces1 , " EnumSurfaces(D1) " ) ;
else
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 36 ) , extEnumSurfacesProxy4 , ( void * * ) & pEnumSurfaces4 , " EnumSurfaces(D4) " ) ;
// IDIrectDraw::GetCaps
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 44 ) , extGetCapsD , ( void * * ) & pGetCapsD , " GetCaps(D) " ) ;
// IDIrectDraw::GetFourCCCodes
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 52 ) , extGetFourCCCodesProxy , ( void * * ) & pGetFourCCCodes , " GetFourCCCodes(D) " ) ;
// IDIrectDraw::GetMonitorFrequency
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 60 ) , extGetMonitorFrequencyProxy , ( void * * ) & pGetMonitorFrequency , " GetMonitorFrequency(D) " ) ;
// IDIrectDraw::GetScanLine
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 64 ) , extGetScanLineProxy , ( void * * ) & pGetScanLine , " GetScanLine(D) " ) ;
// IDIrectDraw::GetVerticalBlankStatus
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 68 ) , extGetVerticalBlankStatusProxy , ( void * * ) & pGetVerticalBlankStatus , " GetVerticalBlankStatus(D) " ) ;
// IDIrectDraw::RestoreDisplayMode
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 76 ) , extRestoreDisplayModeProxy , ( void * * ) & pRestoreDisplayMode , " RestoreDisplayMode(D) " ) ;
if ( dxversion > = 4 ) {
// IDIrectDraw::GetSurfaceFromDC
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 96 ) , extGetSurfaceFromDCProxy , ( void * * ) & pGetSurfaceFromDC , " GetSurfaceFromDC(D) " ) ;
// IDIrectDraw::RestoreAllSurfaces
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 100 ) , extRestoreAllSurfacesProxy , ( void * * ) & pRestoreAllSurfaces , " RestoreAllSurfaces(D) " ) ;
// IDIrectDraw::GetDeviceIdentifier
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdd + 108 ) , extGetDeviceIdentifierProxy , ( void * * ) & pGetDeviceIdentifier , " GetDeviceIdentifier(D) " ) ;
}
}
static void HookDDClipper ( LPDIRECTDRAWCLIPPER FAR * lplpDDClipper )
{
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Hooking directdraw clipper dd=%x \n " , * lplpDDClipper ) ;
2013-07-21 12:38:09 -04:00
// IDirectDrawClipper::Release
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDClipper + 8 ) , extReleaseC , ( void * * ) & pReleaseC , " Release(C) " ) ;
if ( ! ( dxw . dwTFlags & OUTPROXYTRACE ) ) return ;
// Just proxed ...
// IDirectDrawClipper::QueryInterface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDClipper ) , extQueryInterfaceCProxy , ( void * * ) & pQueryInterfaceC , " QueryInterface(C) " ) ;
// IDirectDrawClipper::AddRef
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDClipper + 4 ) , extAddRefCProxy , ( void * * ) & pAddRefC , " AddRef(C) " ) ;
// IDirectDrawClipper::GetClipList
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDClipper + 12 ) , extGetClipListProxy , ( void * * ) & pGetClipList , " GetClipList(C) " ) ;
// IDirectDrawClipper::GetHWnd
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDClipper + 16 ) , extGetHWndProxy , ( void * * ) & pGetHWnd , " GetHWnd(C) " ) ;
// IDirectDrawClipper::Initialize
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDClipper + 20 ) , extInitializeCProxy , ( void * * ) & pInitializeC , " Initialize(C) " ) ;
// IDirectDrawClipper::IsClipListChanged
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDClipper + 24 ) , extIsClipListChangedProxy , ( void * * ) & pIsClipListChanged , " IsClipListChanged(C) " ) ;
// IDirectDrawClipper::SetClipList
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDClipper + 28 ) , extSetClipListProxy , ( void * * ) & pSetClipList , " SetClipList(C) " ) ;
// IDirectDrawClipper::SetHWnd
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDClipper + 32 ) , extSetHWndProxy , ( void * * ) & pSetHWnd , " SetHWnd(C) " ) ;
return ;
}
static void HookDDPalette ( LPDIRECTDRAWPALETTE FAR * lplpDDPalette )
{
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Hooking directdraw palette dd=%x \n " , * lplpDDPalette ) ;
2013-07-21 12:38:09 -04:00
/*** IDirectDrawPalette methods ***/
// IDirectDrawPalette::Release
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDPalette + 8 ) , extReleaseP , ( void * * ) & pReleaseP , " Release(P) " ) ;
// IDirectDrawPalette::SetEntries
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDPalette + 24 ) , extSetEntries , ( void * * ) & pSetEntries , " SetEntries(P) " ) ;
if ( ! ( dxw . dwTFlags & OUTPROXYTRACE ) ) return ;
// IDirectDrawPalette::QueryInterface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDPalette ) , extQueryInterfacePProxy , ( void * * ) & pQueryInterfaceP , " QueryInterface(P) " ) ;
// IDirectDrawPalette::AddRef
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDPalette + 4 ) , extAddRefPProxy , ( void * * ) & pAddRefP , " AddRef(P) " ) ;
// IDirectDrawPalette::GetCaps
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDPalette + 12 ) , extGetCapsPProxy , ( void * * ) & pGetCapsP , " GetCaps(P) " ) ;
// IDirectDrawPalette::GetEntries
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpDDPalette + 16 ) , extGetEntriesProxy , ( void * * ) & pGetEntries , " GetEntries(P) " ) ;
return ;
}
static void HookDDSurfacePrim ( LPDIRECTDRAWSURFACE * lplpdds , int dxversion )
{
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Hooking surface as primary dds=%x dxversion=%d thread_id=%x \n " ,
2013-07-21 12:38:09 -04:00
* lplpdds , dxversion , GetCurrentThreadId ( ) ) ;
// IDirectDrawSurface::Query
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds ) , extQueryInterfaceS , ( void * * ) & pQueryInterfaceS , " QueryInterface(S) " ) ;
// IDirectDrawSurface::Release
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 8 ) , extReleaseS , ( void * * ) & pReleaseS , " Release(S) " ) ;
// IDirectDrawSurface::AddAttachedSurface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 12 ) , extAddAttachedSurface , ( void * * ) & pAddAttachedSurface , " AddAttachedSurface(S) " ) ;
// IDirectDrawSurface::Blt
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 20 ) , extBlt , ( void * * ) & pBlt , " Blt(S) " ) ;
// IDirectDrawSurface::BltFast
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 28 ) , extBltFast , ( void * * ) & pBltFast , " BltFast(S) " ) ;
// IDirectDrawSurface::DeleteAttachedSurface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 32 ) , extDeleteAttachedSurface , ( void * * ) & pDeleteAttachedSurface , " DeleteAttachedSurface(S) " ) ;
// IDirectDrawSurface::EnumAttachedSurfaces
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 36 ) , extEnumAttachedSurfaces , ( void * * ) & pEnumAttachedSurfaces , " EnumAttachedSurfaces(S) " ) ;
// IDirectDrawSurface::Flip
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 44 ) , extFlip , ( void * * ) & pFlip , " Flip(S) " ) ;
// IDirectDrawSurface::GetAttachedSurface
switch ( dxversion ) {
case 1 :
case 2 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 48 ) , extGetAttachedSurface1 , ( void * * ) & pGetAttachedSurface1 , " GetAttachedSurface(S1) " ) ;
break ;
case 3 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 48 ) , extGetAttachedSurface3 , ( void * * ) & pGetAttachedSurface3 , " GetAttachedSurface(S3) " ) ;
break ;
case 4 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 48 ) , extGetAttachedSurface4 , ( void * * ) & pGetAttachedSurface4 , " GetAttachedSurface(S4) " ) ;
break ;
case 7 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 48 ) , extGetAttachedSurface7 , ( void * * ) & pGetAttachedSurface7 , " GetAttachedSurface(S7) " ) ;
break ;
}
// IDirectDrawSurface::GetCaps
switch ( dxversion ) {
case 1 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 56 ) , extGetCaps1S , ( void * * ) & pGetCaps1S , " GetCaps(S1) " ) ;
break ;
case 2 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 56 ) , extGetCaps2S , ( void * * ) & pGetCaps2S , " GetCaps(S2) " ) ;
break ;
case 3 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 56 ) , extGetCaps3S , ( void * * ) & pGetCaps3S , " GetCaps(S3) " ) ;
break ;
case 4 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 56 ) , extGetCaps4S , ( void * * ) & pGetCaps4S , " GetCaps(S4) " ) ;
break ;
case 7 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 56 ) , extGetCaps7S , ( void * * ) & pGetCaps7S , " GetCaps(S7) " ) ;
break ;
}
// IDirectDrawSurface::GetColorKey
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 64 ) , extGetColorKey , ( void * * ) & pGetColorKey , " GetColorKey(S) " ) ;
// IDirectDrawSurface::GetPalette
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 80 ) , extGetPalette , ( void * * ) & pGetPalette , " GetPalette(S) " ) ;
// IDirectDrawSurface::GetPixelFormat
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 84 ) , extGetPixelFormat , ( void * * ) & pGetPixelFormat , " GetPixelFormat(S) " ) ;
// IDirectDrawSurface::GetSurfaceDesc
if ( dxversion < 4 ) {
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 88 ) , extGetSurfaceDesc1 , ( void * * ) & pGetSurfaceDesc1 , " GetSurfaceDesc(S1) " ) ;
}
2014-02-02 11:38:46 -05:00
if ( ( dxversion > = 4 ) & & ( dxversion < 7 ) ) {
2013-07-21 12:38:09 -04:00
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 88 ) , extGetSurfaceDesc2 , ( void * * ) & pGetSurfaceDesc4 , " GetSurfaceDesc(S4) " ) ;
}
2014-02-02 11:38:46 -05:00
if ( dxversion = = 7 ) {
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 88 ) , extGetSurfaceDesc7 , ( void * * ) & pGetSurfaceDesc7 , " GetSurfaceDesc(S7) " ) ;
}
2013-07-21 12:38:09 -04:00
// IDirectDrawSurface::SetClipper
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 112 ) , extSetClipper , ( void * * ) & pSetClipper , " SetClipper(S) " ) ;
// IDirectDrawSurface::SetColorKey
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 116 ) , extSetColorKey , ( void * * ) & pSetColorKey , " SetColorKey(S) " ) ;
// IDirectDrawSurface::SetPalette
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 124 ) , extSetPalette , ( void * * ) & pSetPalette , " SetPalette(S) " ) ;
// IDirectDrawSurface::GetDC
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 68 ) , extGetDC , ( void * * ) & pGetDC , " GetDC(S) " ) ;
// IDirectDrawSurface::ReleaseDC
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 104 ) , extReleaseDC , ( void * * ) & pReleaseDC , " ReleaseDC(S) " ) ;
if ( dxw . dwFlags1 & ( EMULATESURFACE | EMULATEBUFFER ) ) {
// IDirectDrawSurface::Lock
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 100 ) , extLock , ( void * * ) & pLock , " Lock(S) " ) ;
// IDirectDrawSurface::Unlock
if ( dxversion < 4 )
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 128 ) , extUnlock1 , ( void * * ) & pUnlock1 , " Unlock(S1) " ) ;
else
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 128 ) , extUnlock4 , ( void * * ) & pUnlock4 , " Unlock(S4) " ) ;
}
2013-07-30 12:38:11 -04:00
else {
// IDirectDrawSurface::Lock
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 100 ) , extLockDir , ( void * * ) & pLock , " Lock(S) " ) ;
// IDirectDrawSurface::Unlock
if ( dxversion < 4 )
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 128 ) , extUnlockDir1 , ( void * * ) & pUnlock1 , " Unlock(S1) " ) ;
else
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 128 ) , extUnlockDir4 , ( void * * ) & pUnlock4 , " Unlock(S4) " ) ;
}
2013-07-21 12:38:09 -04:00
if ( ! ( dxw . dwTFlags & OUTPROXYTRACE ) ) return ;
// Just proxed ...
// IDirectDrawSurface::AddRef
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 4 ) , extAddRefSProxy , ( void * * ) & pAddRefS , " AddRef(S) " ) ;
// IDirectDrawSurface::AddOverlayDirtyRect
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 16 ) , extAddOverlayDirtyRectProxy , ( void * * ) & pAddOverlayDirtyRect , " AddOverlayDirtyRect(S) " ) ;
// IDirectDrawSurface::BltBatch
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 24 ) , extBltBatchProxy , ( void * * ) & pBltBatch , " BltBatch(S) " ) ;
// IDirectDrawSurface::EnumOverlayZOrders
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 40 ) , extEnumOverlayZOrdersProxy , ( void * * ) & pEnumOverlayZOrders , " EnumOverlayZOrders(S) " ) ;
// IDirectDrawSurface::GetBltStatus
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 52 ) , extGetBltStatusProxy , ( void * * ) & pGetBltStatus , " GetBltStatus(S) " ) ;
// IDirectDrawSurface::GetClipper
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 60 ) , extGetClipperProxy , ( void * * ) & pGetClipper , " GetClipper(S) " ) ;
// IDirectDrawSurface::GetFlipStatus
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 72 ) , extGetFlipStatusProxy , ( void * * ) & pGetFlipStatus , " GetFlipStatus(S) " ) ;
// IDirectDrawSurface::GetOverlayPosition
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 76 ) , extGetOverlayPositionProxy , ( void * * ) & pGetOverlayPosition , " GetOverlayPosition(S) " ) ;
// IDirectDrawSurface::IsLost
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 96 ) , extIsLostProxy , ( void * * ) & pIsLost , " IsLost(S) " ) ;
// IDirectDrawSurface::Restore
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 108 ) , extRestoreProxy , ( void * * ) & pRestore , " Restore(S) " ) ;
// IDirectDrawSurface::SetOverlayPosition
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 120 ) , extSetOverlayPositionProxy , ( void * * ) & pSetOverlayPosition , " SetOverlayPosition(S) " ) ;
// IDirectDrawSurface::UpdateOverlay
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 132 ) , extUpdateOverlayProxy , ( void * * ) & pUpdateOverlay , " UpdateOverlay(S) " ) ;
// IDirectDrawSurface::UpdateOverlayDisplay
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 136 ) , extUpdateOverlayDisplayProxy , ( void * * ) & pUpdateOverlayDisplay , " UpdateOverlayDisplay(S) " ) ;
// IDirectDrawSurface::UpdateOverlayZOrder
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 140 ) , extUpdateOverlayZOrderProxy , ( void * * ) & pUpdateOverlayZOrder , " UpdateOverlayZOrder(S) " ) ;
}
static void HookDDSurfaceGeneric ( LPDIRECTDRAWSURFACE * lplpdds , int dxversion )
{
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Hooking surface as generic dds=%x dxversion=%d thread_id=%x \n " ,
2013-07-21 12:38:09 -04:00
* lplpdds , dxversion , GetCurrentThreadId ( ) ) ;
2013-11-10 11:38:21 -05:00
// IDirectDrawSurface::QueryInterface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds ) , extQueryInterfaceS , ( void * * ) & pQueryInterfaceS , " QueryInterface(S) " ) ;
2013-07-21 12:38:09 -04:00
// IDirectDrawSurface::Release
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 8 ) , extReleaseS , ( void * * ) & pReleaseS , " Release(S) " ) ;
2013-11-10 11:38:21 -05:00
// IDirectDrawSurface::AddAttachedSurface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 12 ) , extAddAttachedSurface , ( void * * ) & pAddAttachedSurface , " AddAttachedSurface(S) " ) ;
2013-07-21 12:38:09 -04:00
// IDirectDrawSurface::Flip
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 44 ) , extFlip , ( void * * ) & pFlip , " Flip(S) " ) ;
// IDirectDrawSurface::Blt
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 20 ) , extBlt , ( void * * ) & pBlt , " Blt(S) " ) ;
// IDirectDrawSurface::BltFast
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 28 ) , extBltFast , ( void * * ) & pBltFast , " BltFast(S) " ) ;
// IDirectDrawSurface::DeleteAttachedSurface
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 32 ) , extDeleteAttachedSurface , ( void * * ) & pDeleteAttachedSurface , " DeleteAttachedSurface(S) " ) ;
2013-09-22 12:38:19 -04:00
// IDirectDrawSurface::GetAttachedSurface
switch ( dxversion ) {
case 1 :
2013-12-22 11:38:36 -05:00
case 2 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 48 ) , extGetAttachedSurface1 , ( void * * ) & pGetAttachedSurface1 , " GetAttachedSurface(S1) " ) ;
2013-09-22 12:38:19 -04:00
break ;
case 3 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 48 ) , extGetAttachedSurface3 , ( void * * ) & pGetAttachedSurface3 , " GetAttachedSurface(S3) " ) ;
break ;
case 4 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 48 ) , extGetAttachedSurface4 , ( void * * ) & pGetAttachedSurface4 , " GetAttachedSurface(S4) " ) ;
break ;
case 7 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 48 ) , extGetAttachedSurface7 , ( void * * ) & pGetAttachedSurface7 , " GetAttachedSurface(S7) " ) ;
break ;
}
2013-07-21 12:38:09 -04:00
// IDirectDrawSurface::GetCaps
switch ( dxversion ) {
case 1 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 56 ) , extGetCaps1S , ( void * * ) & pGetCaps1S , " GetCaps(S1) " ) ;
break ;
case 2 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 56 ) , extGetCaps2S , ( void * * ) & pGetCaps2S , " GetCaps(S2) " ) ;
break ;
case 3 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 56 ) , extGetCaps3S , ( void * * ) & pGetCaps3S , " GetCaps(S3) " ) ;
break ;
case 4 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 56 ) , extGetCaps4S , ( void * * ) & pGetCaps4S , " GetCaps(S4) " ) ;
break ;
case 7 :
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 56 ) , extGetCaps7S , ( void * * ) & pGetCaps7S , " GetCaps(S7) " ) ;
break ;
}
2013-07-30 12:38:11 -04:00
// IDirectDrawSurface::GetDC
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 68 ) , extGetDC , ( void * * ) & pGetDC , " GetDC(S) " ) ; // IDirectDrawSurface::GetSurfaceDesc
2013-07-21 12:38:09 -04:00
// IDirectDrawSurface::GetSurfaceDesc
if ( dxversion < 4 ) {
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 88 ) , extGetSurfaceDesc1 , ( void * * ) & pGetSurfaceDesc1 , " GetSurfaceDesc(S1) " ) ;
}
else {
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 88 ) , extGetSurfaceDesc2 , ( void * * ) & pGetSurfaceDesc4 , " GetSurfaceDesc(S4) " ) ;
}
// IDirectDrawSurface::ReleaseDC
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 104 ) , extReleaseDC , ( void * * ) & pReleaseDC , " ReleaseDC(S) " ) ;
2013-07-09 12:38:16 -04:00
if ( dxw . dwFlags1 & ( EMULATESURFACE | EMULATEBUFFER ) ) {
// IDirectDrawSurface::Lock
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 100 ) , extLock , ( void * * ) & pLock , " Lock(S) " ) ;
// IDirectDrawSurface::Unlock
if ( dxversion < 4 )
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 128 ) , extUnlock1 , ( void * * ) & pUnlock1 , " Unlock(S1) " ) ;
else
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 128 ) , extUnlock4 , ( void * * ) & pUnlock4 , " Unlock(S4) " ) ;
}
else {
// IDirectDrawSurface::Lock
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 100 ) , extLockDir , ( void * * ) & pLock , " Lock(S) " ) ;
// IDirectDrawSurface::Unlock
if ( dxversion < 4 )
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 128 ) , extUnlockDir1 , ( void * * ) & pUnlock1 , " Unlock(S1) " ) ;
else
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 128 ) , extUnlockDir4 , ( void * * ) & pUnlock4 , " Unlock(S4) " ) ;
}
2014-01-24 11:38:44 -05:00
if ( dxversion = = 7 )
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 156 ) , extSetSurfaceDesc , ( void * * ) & pSetSurfaceDesc , " SetSurfaceDesc(S3) " ) ;
2013-07-21 12:38:09 -04:00
if ( ! ( dxw . dwTFlags & OUTPROXYTRACE ) ) return ;
// just proxed ....
// IDirectDrawSurface::AddRef
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 4 ) , extAddRefSProxy , ( void * * ) & pAddRefS , " AddRef(S) " ) ;
// IDirectDrawSurface::AddOverlayDirtyRect
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 16 ) , extAddOverlayDirtyRectProxy , ( void * * ) & pAddOverlayDirtyRect , " AddOverlayDirtyRect(S) " ) ;
// IDirectDrawSurface::BltBatch
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 24 ) , extBltBatchProxy , ( void * * ) & pBltBatch , " BltBatch(S) " ) ;
// IDirectDrawSurface::EnumAttachedSurfaces
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 36 ) , extEnumAttachedSurfaces , ( void * * ) & pEnumAttachedSurfaces , " EnumAttachedSurfaces(S) " ) ;
// IDirectDrawSurface::EnumOverlayZOrders
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 40 ) , extEnumOverlayZOrdersProxy , ( void * * ) & pEnumOverlayZOrders , " EnumOverlayZOrders(S) " ) ;
// IDirectDrawSurface::GetBltStatus
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 52 ) , extGetBltStatusProxy , ( void * * ) & pGetBltStatus , " GetBltStatus(S) " ) ;
// IDirectDrawSurface::GetClipper
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 60 ) , extGetClipperProxy , ( void * * ) & pGetClipper , " GetClipper(S) " ) ;
// IDirectDrawSurface::GetFlipStatus
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 72 ) , extGetFlipStatusProxy , ( void * * ) & pGetFlipStatus , " GetFlipStatus(S) " ) ;
// IDirectDrawSurface::GetOverlayPosition
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 76 ) , extGetOverlayPositionProxy , ( void * * ) & pGetOverlayPosition , " GetOverlayPosition(S) " ) ;
// IDirectDrawSurface::IsLost
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 96 ) , extIsLostProxy , ( void * * ) & pIsLost , " IsLost(S) " ) ;
// IDirectDrawSurface::Lock
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 100 ) , extLock , ( void * * ) & pLock , " Lock(S) " ) ;
// IDirectDrawSurface::Restore
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 108 ) , extRestoreProxy , ( void * * ) & pRestore , " Restore(S) " ) ;
// IDirectDrawSurface::SetOverlayPosition
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 120 ) , extSetOverlayPositionProxy , ( void * * ) & pSetOverlayPosition , " SetOverlayPosition(S) " ) ;
// IDirectDrawSurface::Unlock
if ( dxversion < 4 )
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 128 ) , extUnlock1 , ( void * * ) & pUnlock1 , " Unlock(S1) " ) ;
else
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 128 ) , extUnlock4 , ( void * * ) & pUnlock4 , " Unlock(S4) " ) ;
// IDirectDrawSurface::UpdateOverlay
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 132 ) , extUpdateOverlayProxy , ( void * * ) & pUpdateOverlay , " UpdateOverlay(S) " ) ;
// IDirectDrawSurface::UpdateOverlayDisplay
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 136 ) , extUpdateOverlayDisplayProxy , ( void * * ) & pUpdateOverlayDisplay , " UpdateOverlayDisplay(S) " ) ;
// IDirectDrawSurface::UpdateOverlayZOrder
SetHook ( ( void * ) ( * * ( DWORD * * ) lplpdds + 140 ) , extUpdateOverlayZOrderProxy , ( void * * ) & pUpdateOverlayZOrder , " UpdateOverlayZOrder(S) " ) ;
}
2014-11-19 11:40:00 -05:00
static 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) " ) ;
}
2013-11-10 11:38:24 -05:00
/* ------------------------------------------------------------------------------ */
// 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];
char token [ 20 + 1 ] ;
DWORD val ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " MaskCaps \n " ) ;
2013-11-10 11:38:24 -05:00
capfile = fopen ( " dxwnd.cap " , " r " ) ;
if ( ! capfile ) return ;
2014-01-03 11:38:52 -05:00
if ( c1 ) {
while ( TRUE ) {
if ( fscanf ( capfile , " %s=%x " , token , & val ) ! = 2 ) break ;
if ( ! strcmp ( token , " dwCaps " ) ) c1 - > dwCaps & = val ;
if ( ! strcmp ( token , " dwCaps2 " ) ) c1 - > dwCaps2 & = val ;
if ( ! strcmp ( token , " dwCKeyCaps " ) ) c1 - > dwCKeyCaps & = val ;
if ( ! strcmp ( token , " dwFXCaps " ) ) c1 - > dwFXCaps & = val ;
}
OutTraceDW ( " 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 ) {
while ( TRUE ) {
if ( fscanf ( capfile , " %s=%x " , token , & val ) ! = 2 ) break ;
if ( ! strcmp ( token , " dwCaps " ) ) c2 - > dwCaps & = val ;
if ( ! strcmp ( token , " dwCaps2 " ) ) c2 - > dwCaps2 & = val ;
if ( ! strcmp ( token , " dwCKeyCaps " ) ) c2 - > dwCKeyCaps & = val ;
if ( ! strcmp ( token , " dwFXCaps " ) ) c2 - > dwFXCaps & = val ;
}
OutTraceDW ( " MaskCaps(D-HW): 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 ) ) ;
}
2013-11-10 11:38:24 -05:00
fclose ( capfile ) ;
}
2013-07-21 12:38:09 -04:00
/* ------------------------------------------------------------------------------ */
// directdraw method hooks
/* ------------------------------------------------------------------------------ */
HRESULT WINAPI extGetCapsD ( LPDIRECTDRAW lpdd , LPDDCAPS c1 , LPDDCAPS c2 )
{
HRESULT res ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetCaps(D): lpdd=%x \n " , lpdd ) ;
2013-07-21 12:38:09 -04:00
res = ( * pGetCapsD ) ( lpdd , c1 , c2 ) ;
if ( res )
OutTraceE ( " GetCaps(D): ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
else {
2013-12-22 11:38:36 -05:00
if ( c1 ) OutTraceDDRAW ( " GetCaps(D-HW): caps=%x(%s) caps2=%x(%s) palcaps=%x(%s) fxcaps=%x(%s) fxalphacaps=%x(%s) keycaps=%x(%s) \n " ,
2013-07-09 12:38:16 -04:00
c1 - > dwCaps , ExplainDDDCaps ( c1 - > dwCaps ) ,
c1 - > dwCaps2 , ExplainDDDCaps2 ( c1 - > dwCaps2 ) ,
2013-11-10 11:38:26 -05:00
c1 - > dwPalCaps , ExplainDDPalCaps ( c1 - > dwPalCaps ) ,
2013-07-09 12:38:16 -04:00
c1 - > dwFXCaps , ExplainDDFXCaps ( c1 - > dwFXCaps ) ,
c1 - > dwFXAlphaCaps , ExplainDDFXALPHACaps ( c1 - > dwFXAlphaCaps ) ,
c1 - > dwCKeyCaps , ExplainDDCKeyCaps ( c1 - > dwCKeyCaps ) ) ;
2013-12-22 11:38:36 -05:00
if ( c2 ) OutTraceDDRAW ( " GetCaps(D-SW): caps=%x(%s) caps2=%x(%s) palcaps=%x(%s) fxcaps=%x(%s) fxalphacaps=%x(%s) keycaps=%x(%s) \n " ,
2013-07-09 12:38:16 -04:00
c2 - > dwCaps , ExplainDDDCaps ( c2 - > dwCaps ) ,
c2 - > dwCaps2 , ExplainDDDCaps2 ( c2 - > dwCaps2 ) ,
2013-11-10 11:38:26 -05:00
c2 - > dwPalCaps , ExplainDDPalCaps ( c2 - > dwPalCaps ) ,
2013-07-09 12:38:16 -04:00
c2 - > dwFXCaps , ExplainDDFXCaps ( c2 - > dwFXCaps ) ,
c2 - > dwFXAlphaCaps , ExplainDDFXALPHACaps ( c2 - > dwFXAlphaCaps ) ,
c2 - > dwCKeyCaps , ExplainDDCKeyCaps ( c2 - > dwCKeyCaps ) ) ;
2013-07-21 12:38:09 -04:00
}
2013-11-10 11:38:24 -05:00
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 ) ;
}
2013-11-10 11:38:26 -05:00
//DWORD AlphaCaps;
//AlphaCaps=c1->dwFXAlphaCaps;
2013-11-10 11:38:24 -05:00
memcpy ( ( void * ) c1 , ( void * ) c2 , size ) ;
2013-11-10 11:38:26 -05:00
//c1->dwFXAlphaCaps=AlphaCaps;
2013-11-10 11:38:24 -05:00
}
2014-01-03 11:38:52 -05:00
if ( dxw . dwFlags3 & CAPMASK ) MaskCapsD ( c1 , c2 ) ;
2013-11-10 11:38:24 -05:00
2013-07-21 12:38:09 -04:00
return res ;
}
HRESULT WINAPI extDirectDrawCreate ( GUID FAR * lpguid , LPDIRECTDRAW FAR * lplpdd , IUnknown FAR * pu )
{
HRESULT res ;
2013-11-10 11:38:24 -05:00
GUID FAR * lpPrivGuid = lpguid ;
2013-07-21 12:38:09 -04:00
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " DirectDrawCreate: guid=%x(%s) \n " , lpguid , ExplainGUID ( lpguid ) ) ;
2013-07-21 12:38:09 -04:00
if ( ! pDirectDrawCreate ) { // not hooked yet....
HINSTANCE hinst ;
hinst = LoadLibrary ( " ddraw.dll " ) ;
2014-04-01 12:38:40 -04:00
if ( ! hinst ) {
OutTraceE ( " LoadLibrary ERROR err=%d at %d \n " , GetLastError ( ) , __LINE__ ) ;
}
2013-07-21 12:38:09 -04:00
pDirectDrawCreate =
( DirectDrawCreate_Type ) GetProcAddress ( hinst , " DirectDrawCreate " ) ;
if ( pDirectDrawCreate )
2014-04-01 12:38:40 -04:00
HookAPI ( hinst , " ddraw.dll " , pDirectDrawCreate , " DirectDrawCreate " , extDirectDrawCreate ) ; // v2.02.52
2013-07-21 12:38:09 -04:00
else {
char sMsg [ 81 ] ;
sprintf_s ( sMsg , 80 , " DirectDrawCreate hook failed: error=%d \n " , GetLastError ( ) ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( sMsg ) ;
2013-07-21 12:38:09 -04:00
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " Hook " , MB_OK | MB_ICONEXCLAMATION ) ;
return DDERR_GENERIC ; // is there a better one?
}
}
2013-11-10 11:38:24 -05:00
if ( ( dxw . dwFlags3 & FORCESHEL ) & & ( lpguid = = NULL ) ) lpPrivGuid = ( GUID FAR * ) DDCREATE_EMULATIONONLY ;
res = ( * pDirectDrawCreate ) ( lpPrivGuid , lplpdd , pu ) ;
2013-07-21 12:38:09 -04:00
if ( res ) {
OutTraceE ( " DirectDrawCreate: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
return res ;
}
2013-11-10 11:38:24 -05:00
if ( dxw . dwFlags3 & COLORFIX ) ( * ( ( DDRAWI_DIRECTDRAW_INT * * ) lplpdd ) ) - > lpLcl - > dwAppHackFlags | = 0x800 ;
2013-07-21 12:38:09 -04:00
dxw . dwDDVersion = 1 ;
char * mode ;
2013-11-10 11:38:24 -05:00
switch ( ( DWORD ) lpPrivGuid ) {
2013-07-21 12:38:09 -04:00
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 0x9c59509a : dxw . dwDDVersion = 4 ; mode = " IID_IDirectDraw4 " ; break ;
case 0x15e65ec0 : dxw . dwDDVersion = 7 ; mode = " IID_IDirectDraw7 " ; break ;
default : mode = " unknown " ; break ;
}
break ;
}
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " DirectDrawCreate: lpdd=%x guid=%s DDVersion=%d \n " , * lplpdd , mode , dxw . dwDDVersion ) ;
2013-07-21 12:38:09 -04:00
HookDDSession ( lplpdd , dxw . dwDDVersion ) ;
2014-02-19 11:38:50 -05:00
// 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.
2014-03-21 12:38:57 -04:00
// 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"
2014-02-19 11:38:50 -05:00
2013-07-09 12:38:16 -04:00
if ( IsDebug & & ( dxw . dwTFlags & OUTPROXYTRACE ) ) {
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, "???");
}
2013-11-16 11:38:27 -05:00
2014-11-28 11:40:02 -05:00
if ( lpPrimaryDD = = NULL ) lpPrimaryDD = * lplpdd ; // do not override the value set when creating the primary surface!
2014-05-20 12:39:14 -04:00
return DD_OK ;
2013-07-21 12:38:09 -04:00
}
HRESULT WINAPI extDirectDrawCreateEx ( GUID FAR * lpguid ,
LPDIRECTDRAW FAR * lplpdd , REFIID iid , IUnknown FAR * pu )
{
HRESULT res ;
2013-11-10 11:38:24 -05:00
GUID FAR * lpPrivGuid = lpguid ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " DirectDrawCreateEx: guid=%x(%s) refiid=%x \n " , lpguid , ExplainGUID ( lpguid ) , iid ) ;
2013-07-21 12:38:09 -04:00
// v2.1.70: auto-hooking (just in case...)
if ( ! pDirectDrawCreateEx ) { // not hooked yet....
HINSTANCE hinst ;
hinst = LoadLibrary ( " ddraw.dll " ) ;
if ( ! hinst ) {
OutTraceE ( " LoadLibrary ERROR err=%d at %d \n " , GetLastError ( ) , __LINE__ ) ;
}
pDirectDrawCreateEx =
( DirectDrawCreateEx_Type ) GetProcAddress ( hinst , " DirectDrawCreateEx " ) ;
if ( pDirectDrawCreateEx )
2014-04-01 12:38:40 -04:00
HookAPI ( hinst , " ddraw.dll " , pDirectDrawCreateEx , " DirectDrawCreateEx " , extDirectDrawCreateEx ) ; // v2.02.52
2013-07-21 12:38:09 -04:00
else {
char sMsg [ 81 ] ;
sprintf_s ( sMsg , 80 , " DirectDrawCreateEx hook failed: error=%d \n " , GetLastError ( ) ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( sMsg ) ;
2013-07-21 12:38:09 -04:00
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " Hook " , MB_OK | MB_ICONEXCLAMATION ) ;
return DDERR_GENERIC ; // is there a better one?
}
}
2013-11-10 11:38:24 -05:00
if ( ( dxw . dwFlags3 & FORCESHEL ) & & ( lpguid = = NULL ) ) lpPrivGuid = ( GUID FAR * ) DDCREATE_EMULATIONONLY ;
res = ( * pDirectDrawCreateEx ) ( lpPrivGuid , lplpdd , iid , pu ) ;
2013-07-21 12:38:09 -04:00
if ( res ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " DirectDrawCreateEx: res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
2013-11-10 11:38:24 -05:00
if ( dxw . dwFlags3 & COLORFIX ) ( * ( ( DDRAWI_DIRECTDRAW_INT * * ) lplpdd ) ) - > lpLcl - > dwAppHackFlags | = 0x800 ;
2013-07-21 12:38:09 -04:00
dxw . dwDDVersion = 7 ;
char * mode ;
2013-11-10 11:38:24 -05:00
switch ( ( DWORD ) lpPrivGuid ) {
2013-07-21 12:38:09 -04:00
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 0x9c59509a : dxw . dwDDVersion = 4 ; mode = " IID_IDirectDraw4 " ; break ;
case 0x15e65ec0 : dxw . dwDDVersion = 7 ; mode = " IID_IDirectDraw7 " ; break ;
default : mode = " unknown " ; break ;
}
break ;
}
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " DirectDrawCreateEx: lpdd=%x guid=%s DDVersion=%d \n " , * lplpdd , mode , dxw . dwDDVersion ) ;
2013-07-21 12:38:09 -04:00
2014-04-01 12:38:40 -04:00
HookDDSession ( lplpdd , dxw . dwDDVersion ) ;
2013-07-21 12:38:09 -04:00
2014-05-20 12:39:14 -04:00
if ( IsDebug & & ( dxw . dwTFlags & OUTPROXYTRACE ) ) {
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, "???");
}
2014-11-28 11:40:02 -05:00
if ( lpPrimaryDD = = NULL ) lpPrimaryDD = * lplpdd ; // do not override the value set when creating the primary surface!
2014-05-20 12:39:14 -04:00
return DD_OK ;
2013-07-21 12:38:09 -04:00
}
2013-11-10 11:38:24 -05:00
HRESULT WINAPI extInitialize ( LPDIRECTDRAW lpdd , GUID FAR * lpguid )
{
HRESULT res ;
GUID FAR * lpPrivGuid = lpguid ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " Initialize: lpdd=%x guid=%x(%s) \n " , lpdd , lpguid , ExplainGUID ( lpguid ) ) ;
2013-11-10 11:38:24 -05:00
if ( ( dxw . dwFlags3 & FORCESHEL ) & & ( lpguid = = NULL ) ) lpPrivGuid = ( GUID FAR * ) DDCREATE_EMULATIONONLY ;
res = ( * pInitialize ) ( lpdd , lpPrivGuid ) ;
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 ;
}
2013-07-21 12:38:09 -04:00
HRESULT WINAPI extQueryInterfaceD ( void * lpdd , REFIID riid , LPVOID * obp )
{
HRESULT res ;
unsigned int dwLocalDDVersion ;
2013-11-10 11:38:21 -05:00
unsigned int dwLocalD3DVersion ;
2013-07-21 12:38:09 -04:00
res = ( * pQueryInterfaceD ) ( lpdd , riid , obp ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " QueryInterface(D): lpdd=%x REFIID=%x(%s) obp=%x ret=%x at %d \n " ,
2013-11-10 11:38:21 -05:00
lpdd , riid . Data1 , ExplainGUID ( ( GUID * ) & riid ) , * obp , res , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
if ( res ) return res ;
dwLocalDDVersion = 0 ;
2013-11-10 11:38:21 -05:00
dwLocalD3DVersion = 0 ;
2013-07-21 12:38:09 -04:00
switch ( riid . Data1 ) {
case 0x6C14DB80 : //DirectDraw1
dwLocalDDVersion = 1 ;
break ;
case 0xB3A6F3E0 : //DirectDraw2
dwLocalDDVersion = 2 ;
break ;
2013-11-10 11:38:21 -05:00
case 0x9c59509a : //DirectDraw4
2013-07-21 12:38:09 -04:00
dwLocalDDVersion = 4 ;
break ;
case 0x15e65ec0 : //DirectDraw7
dwLocalDDVersion = 7 ;
break ;
2013-11-10 11:38:21 -05:00
case 0x3BBA0080 : //Direct3D
dwLocalD3DVersion = 1 ;
break ;
case 0x6aae1ec1 : //Direct3D2
2014-02-02 11:38:46 -05:00
dwLocalD3DVersion = 2 ;
2013-11-10 11:38:21 -05:00
break ;
case 0xbb223240 : //Direct3D3
2014-02-02 11:38:46 -05:00
dwLocalD3DVersion = 3 ;
2013-11-10 11:38:21 -05:00
break ;
case 0xf5049e77 : //Direct3D7
dwLocalD3DVersion = 7 ;
break ;
2013-07-21 12:38:09 -04:00
}
2014-04-01 12:38:40 -04:00
if ( ! * obp ) {
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " QueryInterface(D): Interface for DX version %d not found \n " , dwLocalDDVersion ) ;
2013-07-21 12:38:09 -04:00
return ( 0 ) ;
}
2013-12-22 11:38:36 -05:00
if ( dwLocalDDVersion ) OutTraceDW ( " QueryInterface(D): Got interface for DX version %d \n " , dwLocalDDVersion ) ;
if ( dwLocalD3DVersion ) OutTraceDW ( " QueryInterface(D): Got interface for D3D version %d \n " , dwLocalD3DVersion ) ;
2013-07-21 12:38:09 -04:00
if ( dwLocalDDVersion > dxw . dwMaxDDVersion ) {
* obp = NULL ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface(D): lpdd=%x REFIID=%x obp=(NULL) ret=%x at %d \n " ,
2013-07-21 12:38:09 -04:00
lpdd , riid . Data1 , res , __LINE__ ) ;
return ( 0 ) ;
}
switch ( dwLocalDDVersion ) {
case 1 : // you never know ....
case 2 :
case 4 :
// it's not supposed to be written for DDVersion==7, but it works ....
case 7 :
dxw . dwDDVersion = dwLocalDDVersion ;
HookDDSession ( ( LPDIRECTDRAW * ) obp , dxw . dwDDVersion ) ;
2013-11-10 11:38:21 -05:00
break ;
}
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:21 -05:00
extern void HookDirect3DSession ( LPDIRECTDRAW * , int ) ;
switch ( dwLocalD3DVersion ) {
case 1 :
2014-02-02 11:38:46 -05:00
case 2 :
case 3 :
2013-11-10 11:38:21 -05:00
case 7 :
HookDirect3DSession ( ( LPDIRECTDRAW * ) obp , dwLocalD3DVersion ) ;
2013-07-21 12:38:09 -04:00
break ;
}
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " QueryInterface(D): lpdd=%x REFIID=%x obp=%x DDVersion=%d ret=0 \n " ,
2013-07-21 12:38:09 -04:00
lpdd , riid . Data1 , * obp , dxw . dwDDVersion ) ;
return 0 ;
}
2013-08-25 12:38:13 -04:00
// some unhandled interfaces in emulation mode:
// REFIID={84e63de0-46aa-11cf-816f-0000c020156e}: IID_IDirect3DHALDevice
2013-07-21 12:38:09 -04:00
HRESULT WINAPI extQueryInterfaceS ( void * lpdds , REFIID riid , LPVOID * obp )
{
HRESULT res ;
BOOL IsPrim ;
2013-11-10 11:38:21 -05:00
BOOL IsBack ;
BOOL IsGammaRamp ;
2013-07-21 12:38:09 -04:00
unsigned int dwLocalDDVersion ;
2014-11-19 11:40:00 -05:00
unsigned int dwLocalTexVersion ;
2013-07-21 12:38:09 -04:00
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " QueryInterface(S): lpdds=%x REFIID=%x(%s) obp=%x \n " ,
2013-11-10 11:38:21 -05:00
lpdds , riid . Data1 , ExplainGUID ( ( GUID * ) & riid ) , * obp ) ;
2013-07-21 12:38:09 -04:00
IsPrim = dxw . IsAPrimarySurface ( ( LPDIRECTDRAWSURFACE ) lpdds ) ;
2013-11-10 11:38:21 -05:00
IsBack = dxw . IsABackBufferSurface ( ( LPDIRECTDRAWSURFACE ) lpdds ) ;
IsGammaRamp = FALSE ;
2013-07-21 12:38:09 -04:00
dwLocalDDVersion = 0 ;
2014-11-19 11:40:00 -05:00
dwLocalTexVersion = 0 ;
2013-07-21 12:38:09 -04:00
switch ( riid . Data1 ) {
case 0x6C14DB81 :
dwLocalDDVersion = 1 ;
break ;
case 0x57805885 : //DDSurface2 - WIP (Dark Reign)
dwLocalDDVersion = 2 ;
break ;
case 0xDA044E00 : //DDSurface3
dwLocalDDVersion = 3 ;
break ;
case 0x0B2B8630 :
dwLocalDDVersion = 4 ;
break ;
case 0x06675a80 :
dwLocalDDVersion = 7 ;
break ;
2013-08-25 12:38:13 -04:00
case 0x84e63de0 :
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface: IID_IDirect3DHALDevice \n " ) ;
2013-08-25 12:38:13 -04:00
break ;
2013-10-21 12:38:23 -04:00
case 0xA4665C60 : // IID_IDirect3DRGBDevice
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface: IID_IDirect3DRGBDevice \n " ) ;
2013-10-21 12:38:23 -04:00
break ;
case 0xF2086B20 : // IID_IDirect3DRampDevice
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface: IID_IDirect3DRampDevice \n " ) ;
2013-10-21 12:38:23 -04:00
break ;
case 0x881949a1 : // IID_IDirect3DMMXDevice
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface: IID_IDirect3DMMXDevice \n " ) ;
2013-10-21 12:38:23 -04:00
break ;
2013-11-10 11:38:21 -05:00
case 0x4B9F0EE0 :
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface: IID_IDirectDrawColorControl \n " ) ;
2013-11-10 11:38:21 -05:00
break ;
case 0x69C11C3E :
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface: IID_IDirectDrawGammaControl \n " ) ;
2013-11-10 11:38:21 -05:00
IsGammaRamp = TRUE ;
break ;
2014-11-19 11:40:00 -05:00
// textures
case 0x2CDCD9E0 :
OutTraceDW ( " QueryInterface: IID_IDirect3DTexture \n " ) ;
dwLocalTexVersion = 1 ;
break ;
case 0x93281502 :
OutTraceDW ( " QueryInterface: IID_IDirect3DTexture2 \n " ) ;
dwLocalTexVersion = 2 ;
break ;
2013-11-10 11:38:21 -05:00
}
2013-07-21 12:38:09 -04:00
if ( dwLocalDDVersion > dxw . dwMaxDDVersion ) {
* obp = NULL ;
2014-10-30 12:39:54 -04:00
OutTraceDW ( " QueryInterface(S): DDVersion=%d SUPPRESS lpdds=%x(%s) REFIID=%x obp=(NULL) ret=0 at %d \n " ,
2013-07-21 12:38:09 -04:00
dwLocalDDVersion , lpdds , IsPrim ? " " : " (PRIM) " , riid . Data1 , __LINE__ ) ;
return ( 0 ) ;
}
2014-04-12 12:40:05 -04:00
// fix the target for gamma ramp creation: if it is a primary surface, use the real one!!
if ( dxw . IsAPrimarySurface ( ( LPDIRECTDRAWSURFACE ) lpdds ) & & IsGammaRamp ) lpdds = lpDDSEmu_Prim ;
2013-07-21 12:38:09 -04:00
res = ( * pQueryInterfaceS ) ( lpdds , riid , obp ) ;
if ( res ) // added trace
{
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface(S): ERROR lpdds=%x%s REFIID=%x obp=%x ret=%x(%s) at %d \n " ,
2013-07-21 12:38:09 -04:00
lpdds , IsPrim ? " (PRIM) " : " " , riid . Data1 , * obp , res , ExplainDDError ( res ) , __LINE__ ) ;
return res ;
}
if ( ! * obp ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface(S): Interface for DX version %d not found \n " , dwLocalDDVersion ) ;
2014-11-19 11:40:00 -05:00
return 0 ;
2013-07-21 12:38:09 -04:00
}
// added trace
2014-11-19 11:40:00 -05:00
OutTraceDW ( " QueryInterface(S): lpdds=%x%s REFIID=%x obp=%x DDVersion=%d TexVersion=%d GammaRamp=%d ret=0 \n " ,
lpdds , IsPrim ? " (PRIM) " : " " , riid . Data1 , * obp , dwLocalDDVersion , dwLocalTexVersion , IsGammaRamp ) ;
if ( dwLocalDDVersion ) {
switch ( dwLocalDDVersion ) {
case 1 : // added for The Sims
case 2 :
case 3 :
case 4 :
case 7 :
dxw . dwDDVersion = dwLocalDDVersion ;
if ( IsPrim ) {
OutTraceDW ( " QueryInterface(S): primary=%x new=%x \n " , lpdds , * obp ) ;
dxw . MarkPrimarySurface ( ( LPDIRECTDRAWSURFACE ) * obp ) ;
HookDDSurfacePrim ( ( LPDIRECTDRAWSURFACE * ) obp , dxw . dwDDVersion ) ;
}
else {
if ( IsBack ) dxw . MarkBackBufferSurface ( ( LPDIRECTDRAWSURFACE ) * obp ) ;
else dxw . MarkRegularSurface ( ( LPDIRECTDRAWSURFACE ) * obp ) ;
// v2.02.13: seems that hooking inconditionally gives troubles. What is the proper safe hook condition?
HookDDSurfaceGeneric ( ( LPDIRECTDRAWSURFACE * ) obp , dxw . dwDDVersion ) ;
}
break ;
2013-07-21 12:38:09 -04:00
}
2014-11-19 11:40:00 -05:00
if ( lpdds = = lpDDSBack ) {
// assume that you always use the newer interface version, if available.
if ( dwLocalDDVersion > ( UINT ) iBakBufferVersion ) {
OutTraceDW ( " QueryInterface(S): switching backbuffer %x -> %x \n " , lpDDSBack , * obp ) ;
lpDDSBack = ( LPDIRECTDRAWSURFACE ) * obp ;
iBakBufferVersion = dwLocalDDVersion ;
}
2013-07-21 12:38:09 -04:00
}
}
2014-11-19 11:40:00 -05:00
if ( dwLocalTexVersion ) {
if ( dxw . dwFlags5 & ( TEXTUREHIGHLIGHT | TEXTUREDUMP | TEXTUREHACK ) ) TextureHandling ( ( LPDIRECTDRAWSURFACE ) lpdds ) ;
HookTexture ( obp , dwLocalTexVersion ) ;
2013-07-21 12:38:09 -04:00
}
2014-11-19 11:40:00 -05:00
if ( IsGammaRamp ) HookGammaControl ( obp ) ;
2013-09-22 12:38:19 -04:00
2013-07-21 12:38:09 -04:00
return 0 ;
}
HRESULT WINAPI extSetDisplayMode ( int version , LPDIRECTDRAW lpdd ,
DWORD dwwidth , DWORD dwheight , DWORD dwbpp , DWORD dwrefreshrate , DWORD dwflags )
{
DDSURFACEDESC2 ddsd ;
HRESULT res = 0 ;
2013-12-22 11:38:36 -05:00
if ( IsTraceDDRAW ) {
2013-07-21 12:38:09 -04:00
OutTrace ( " SetDisplayMode: version=%d dwWidth=%i dwHeight=%i dwBPP=%i " ,
version , dwwidth , dwheight , dwbpp ) ;
2013-11-10 11:38:26 -05:00
if ( version = = 2 ) OutTrace ( " dwRefresh=%i dwFlags=%x \n " , dwrefreshrate , dwflags ) ;
else OutTrace ( " \n " ) ;
2013-07-21 12:38:09 -04:00
}
dxw . SetScreenSize ( dwwidth , dwheight ) ;
GetHookInfo ( ) - > Height = ( short ) dxw . GetScreenHeight ( ) ;
GetHookInfo ( ) - > Width = ( short ) dxw . GetScreenWidth ( ) ;
2014-10-08 12:39:38 -04:00
GetHookInfo ( ) - > ColorDepth = ( short ) dwbpp ;
2014-02-05 11:39:10 -05:00
if ( dxw . Windowize ) AdjustWindowFrame ( dxw . GethWnd ( ) , dwwidth , dwheight ) ;
2013-07-21 12:38:09 -04:00
if ( dxw . dwFlags1 & EMULATESURFACE ) {
2013-11-10 11:38:26 -05:00
// in EMULATESURFACE mode, let SetPixFmt decide upon the PixelFormat
2013-07-21 12:38:09 -04:00
dxw . VirtualPixelFormat . dwRGBBitCount = dwbpp ;
2013-11-16 11:38:27 -05:00
memset ( & ddsd , 0 , sizeof ( ddsd ) ) ;
ddsd . dwSize = sizeof ( ddsd ) ;
2013-11-10 11:38:26 -05:00
SetPixFmt ( & ddsd ) ;
2013-07-21 12:38:09 -04:00
SetBltTransformations ( ) ;
2014-02-05 11:39:10 -05:00
if ( dxw . Windowize ) {
OutTraceDW ( " SetDisplayMode: mode=EMULATE %s ret=OK \n " , DumpPixelFormat ( & ddsd ) ) ;
SetVSyncDelays ( lpdd ) ;
return DD_OK ;
}
}
else {
OutTraceDW ( " SetDisplayMode: mode=STANDARD BPP=%d \n " , dwbpp ) ;
2014-10-08 12:39:38 -04:00
dxw . VirtualPixelFormat . dwRGBBitCount = dwbpp ;
2014-02-05 11:39:10 -05:00
dxw . ActualPixelFormat . dwRGBBitCount = dwbpp ;
2013-07-21 12:38:09 -04:00
}
2013-11-10 11:38:26 -05:00
2013-07-21 12:38:09 -04:00
ZeroMemory ( & ddsd , sizeof ( ddsd ) ) ;
ddsd . dwSize = Set_dwSize_From_DDraw ( lpdd ) ;
ddsd . dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_REFRESHRATE ;
ddsd . ddpfPixelFormat . dwSize = sizeof ( DDPIXELFORMAT ) ;
ddsd . ddpfPixelFormat . dwFlags = DDPF_RGB ;
2014-07-28 12:39:37 -04:00
res = ( * pGetDisplayMode ) ( lpdd , ( LPDDSURFACEDESC ) & ddsd ) ;
if ( res = = DDERR_GENERIC ) { // handling Win8 missing support for old ddraw interface
ddsd . dwSize = sizeof ( DDSURFACEDESC2 ) ;
res = ( * pGetDisplayMode ) ( lpdd , ( LPDDSURFACEDESC ) & ddsd ) ;
}
2014-02-05 11:39:10 -05:00
if ( dxw . Windowize ) {
2014-05-14 12:39:12 -04:00
if ( ! IsChangeDisplaySettingsHotPatched ) {
dwwidth = ddsd . dwWidth ;
dwheight = ddsd . dwHeight ;
}
2014-02-05 11:39:10 -05:00
OutTraceDW ( " SetDisplayMode: fixing colordepth current=%d required=%d size=(%dx%d) \n " ,
ddsd . ddpfPixelFormat . dwRGBBitCount , dwbpp , dwwidth , dwheight ) ;
}
2014-12-10 11:39:52 -05:00
2014-02-05 11:39:10 -05:00
if ( dxw . dwFlags1 & EMULATESURFACE ) {
dwbpp = ddsd . ddpfPixelFormat . dwRGBBitCount ;
}
2013-11-10 11:38:26 -05:00
if ( version = = 1 )
2014-02-05 11:39:10 -05:00
res = ( * pSetDisplayMode1 ) ( lpdd , dwwidth , dwheight , dwbpp ) ;
2013-11-10 11:38:26 -05:00
else
2014-02-05 11:39:10 -05:00
res = ( * pSetDisplayMode2 ) ( lpdd , dwwidth , dwheight , dwbpp , ddsd . dwRefreshRate , 0 ) ;
2013-07-21 12:38:09 -04:00
2014-12-10 11:39:52 -05:00
if ( res ) OutTraceE ( " SetDisplayMode: error=%x \n " , res ) ;
2014-03-23 12:38:58 -04:00
SetVSyncDelays ( lpdd ) ;
2014-12-10 11:39:52 -05:00
return DD_OK ;
2013-07-21 12:38:09 -04:00
}
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 extSetDisplayMode1 ( LPDIRECTDRAW lpdd ,
DWORD dwwidth , DWORD dwheight , DWORD dwbpp )
{
return extSetDisplayMode ( 1 , lpdd , dwwidth , dwheight , dwbpp , 0 , 0 ) ;
}
HRESULT WINAPI extGetDisplayMode ( LPDIRECTDRAW lpdd , LPDDSURFACEDESC lpddsd )
{
2014-02-02 11:38:46 -05:00
OutTraceDDRAW ( " GetDisplayMode: lpdd=%x lpddsd=%x \n " , lpdd , lpddsd ) ;
2013-07-21 12:38:09 -04:00
( * pGetDisplayMode ) ( lpdd , lpddsd ) ;
2013-11-10 11:38:26 -05:00
if ( dxw . dwFlags1 & EMULATESURFACE ) {
GetPixFmt ( ( LPDDSURFACEDESC2 ) lpddsd ) ;
if ( ! lpddsd - > ddpfPixelFormat . dwFlags ) SetPixFmt ( ( LPDDSURFACEDESC2 ) lpddsd ) ;
}
2013-07-21 12:38:09 -04:00
2014-02-05 11:39:10 -05:00
if ( dxw . Windowize ) {
lpddsd - > dwWidth = dxw . GetScreenWidth ( ) ;
lpddsd - > dwHeight = dxw . GetScreenHeight ( ) ;
// v2.1.96: fake screen color depth
if ( dxw . dwFlags2 & ( INIT8BPP | INIT16BPP ) ) { // v2.02.32 fix
if ( dxw . dwFlags2 & INIT8BPP ) FixPixelFormat ( 8 , & lpddsd - > ddpfPixelFormat ) ;
if ( dxw . dwFlags2 & INIT16BPP ) FixPixelFormat ( 16 , & lpddsd - > ddpfPixelFormat ) ;
OutTraceDW ( " GetDisplayMode: fix RGBBitCount=%d \n " , lpddsd - > ddpfPixelFormat . dwRGBBitCount ) ;
}
2013-07-21 12:38:09 -04:00
}
2013-12-22 11:38:36 -05:00
//OutTraceDW("GetDisplayMode: returning WxH=(%dx%d) PixelFormat Flags=%x(%s) RGBBitCount=%d RGBAmask=(%x,%x,%x,%x) Caps=%x(%s)\n",
2013-11-10 11:38:26 -05:00
// 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));
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetDisplayMode: returning size=(%dx%d) %s \n " , lpddsd - > dwWidth , lpddsd - > dwHeight , DumpPixelFormat ( ( LPDDSURFACEDESC2 ) lpddsd ) ) ;
2013-07-21 12:38:09 -04:00
return 0 ;
}
HRESULT WINAPI extSetCooperativeLevel ( void * lpdd , HWND hwnd , DWORD dwflags )
{
HRESULT res ;
2014-04-24 12:39:09 -04:00
OutTraceDDRAW ( " SetCooperativeLevel: lpdd=%x hwnd=%x dwFlags=%x(%s) \n " ,
lpdd , hwnd , dwflags , ExplainCoopFlags ( dwflags ) ) ;
2013-07-21 12:38:09 -04:00
InitDDScreenParameters ( ( LPDIRECTDRAW ) lpdd ) ;
2014-02-05 11:39:10 -05:00
if ( dxw . Windowize ) {
if ( dwflags & DDSCL_FULLSCREEN ) {
// 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 ( ) ;
}
dxw . SetFullScreen ( TRUE ) ;
dwflags & = ~ ( DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWMODEX ) ;
dwflags | = DDSCL_NORMAL ;
res = ( * pSetCooperativeLevel ) ( lpdd , hwnd , dwflags ) ;
AdjustWindowFrame ( hwnd , dxw . GetScreenWidth ( ) , dxw . GetScreenHeight ( ) ) ;
if ( dxw . dwFlags1 & FIXWINFRAME ) dxw . FixWindowFrame ( hwnd ) ;
}
else {
RECT client ;
( * pGetClientRect ) ( hwnd , & client ) ;
// v2.02.11:
// Non fullscreen cooperative mode means windowed, unless the window occupies the whole desktop area
dxw . SetFullScreen ( client . right = = dxw . iSizX & & client . bottom = = dxw . iSizY ) ;
//dxw.SetFullScreen(FALSE);
res = ( * pSetCooperativeLevel ) ( lpdd , hwnd , dwflags ) ;
2013-08-25 12:38:13 -04:00
}
2013-07-21 12:38:09 -04:00
}
2014-02-05 11:39:10 -05:00
else {
2013-07-21 12:38:09 -04:00
res = ( * pSetCooperativeLevel ) ( lpdd , hwnd , dwflags ) ;
}
2014-02-05 11:39:10 -05:00
2013-07-21 12:38:09 -04:00
if ( res )
2014-02-05 11:39:10 -05:00
OutTraceE ( " SetCooperativeLevel: ERROR lpdd=%x hwnd=%x Flags=%x err=%x(%s) at %d \n " ,
lpdd , hwnd , dwflags , res , ExplainDDError ( res ) , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
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 ) ) {
2013-08-25 12:38:13 -04:00
if ( hwnd = = ( * pGetDesktopWindow ) ( ) ) {
2013-07-21 12:38:09 -04:00
OutTraceE ( " SetCooperativeLevel: attempt to work on desktop window \n " ) ;
}
else
dxw . SethWnd ( hwnd ) ; // save the good one
}
return res ;
}
2013-11-10 11:38:21 -05:00
2013-10-21 12:38:23 -04:00
static void FixSurfaceCaps ( LPDDSURFACEDESC2 lpddsd , int dxversion )
{
// rules of thumb:
2014-11-15 11:39:58 -05:00
// 1) textures should be left untouched (switching to SYSTEMMEMORY when forcing HEL may even fail!)
// 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
2013-10-21 12:38:23 -04:00
if ( ! ( lpddsd - > dwFlags & DDSD_CAPS ) ) lpddsd - > ddsCaps . dwCaps = 0 ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " FixSurfaceCaps: Flags=%x(%s) Caps=%x(%s) \n " ,
2013-10-21 12:38:23 -04:00
lpddsd - > dwFlags , ExplainFlags ( lpddsd - > dwFlags ) , lpddsd - > ddsCaps . dwCaps , ExplainDDSCaps ( lpddsd - > ddsCaps . dwCaps ) ) ;
2014-11-15 11:39:58 -05:00
// 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 ;
}
return ;
}
2013-10-21 12:38:23 -04:00
2014-11-15 11:39:58 -05:00
// this is valid just in case the above block eliminated TEXTURE surfaces....
if ( lpddsd - > dwFlags & DDSD_PIXELFORMAT ) { // pixel format defined
if ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_SYSTEMMEMORY ) lpddsd - > ddsCaps . dwCaps | = DDSCAPS_OFFSCREENPLAIN ; // to allow for pixel format conversion (Quest for Glory 5 - GOG version)
2013-10-21 12:38:23 -04:00
return ;
}
2014-11-15 11:39:58 -05:00
if ( ( lpddsd - > dwFlags & ( DDSD_WIDTH | DDSD_HEIGHT ) ) = = DDSD_WIDTH ) { // buffer surface
2013-11-10 11:38:21 -05:00
return ;
}
2014-11-15 11:39:58 -05:00
2013-11-10 11:38:21 -05:00
if ( ( lpddsd - > dwFlags & DDSD_CAPS ) & & ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_ZBUFFER ) ) { // z-buffer surface - set to memory
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_ZBUFFER ) ;
return ;
}
2014-11-15 11:39:58 -05:00
2014-08-29 12:39:42 -04:00
if ( ( lpddsd - > dwFlags & DDSD_CAPS ) & &
2014-11-15 11:39:58 -05:00
( lpddsd - > ddsCaps . dwCaps & DDSCAPS_3DDEVICE ) ) // v2.02.90: added for "Zoo Tycoon" textures
2014-08-29 12:39:42 -04:00
{ // 3DDEVICE no TEXTURE: enforce PIXELFORMAT on MEMORY
2013-11-10 11:38:21 -05:00
lpddsd - > dwFlags | = DDSD_PIXELFORMAT ;
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY | DDSCAPS_3DDEVICE ) ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
}
2013-12-27 11:38:38 -05:00
2013-11-10 11:38:21 -05:00
// default case: adjust pixel format
2013-07-21 12:38:09 -04:00
OutTraceB ( " FixSurfaceCaps: suppress DDSCAPS_VIDEOMEMORY case \n " ) ;
2013-09-22 12:38:19 -04:00
lpddsd - > dwFlags | = ( DDSD_CAPS | DDSD_PIXELFORMAT ) ;
2013-11-23 11:38:29 -05:00
lpddsd - > ddsCaps . dwCaps & = ~ ( DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM ) ; // v2.02.43
2013-09-22 12:38:19 -04:00
lpddsd - > ddsCaps . dwCaps | = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ;
2013-11-10 11:38:26 -05:00
if ( ! ( dxw . dwFlags3 & NOPIXELFORMAT ) ) GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
2013-07-21 12:38:09 -04:00
}
2013-09-16 12:38:17 -04:00
static void ClearSurfaceDesc ( void * ddsd , int dxversion )
{
int size ;
size = ( dxversion < 4 ) ? sizeof ( DDSURFACEDESC ) : sizeof ( DDSURFACEDESC2 ) ;
memset ( ddsd , 0 , size ) ; // Clean all
( ( LPDDSURFACEDESC ) ddsd ) - > dwSize = size ;
}
static HRESULT BuildPrimaryEmu ( LPDIRECTDRAW lpdd , CreateSurface_Type pCreateSurface , LPDDSURFACEDESC2 lpddsd , int dxversion , LPDIRECTDRAWSURFACE * lplpdds , void * pu )
2013-07-21 12:38:09 -04:00
{
DDSURFACEDESC2 ddsd ;
2013-09-16 12:38:17 -04:00
HRESULT res ;
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
// emulated primary surface
2013-09-22 12:38:19 -04:00
memcpy ( ( void * ) & ddsd , lpddsd , lpddsd - > dwSize ) ;
2013-11-10 11:38:26 -05:00
// handle the surface attributes before the ddsd.dwFlags gets updated:
// if a surface desc is NOT specified, build one
if ( ! ( ddsd . dwFlags & DDSD_PIXELFORMAT ) ) SetPixFmt ( ( LPDDSURFACEDESC2 ) & ddsd ) ;
// then save it
dxw . VirtualPixelFormat = ddsd . ddpfPixelFormat ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " DDSD_PIXELFORMAT: color=%d flags=%x \n " , dxw . VirtualPixelFormat . dwRGBBitCount , dxw . VirtualPixelFormat . dwFlags ) ;
2013-09-22 12:38:19 -04:00
ddsd . dwFlags & = ~ ( DDSD_BACKBUFFERCOUNT | DDSD_REFRESHRATE ) ;
ddsd . dwFlags | = ( DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT ) ;
ddsd . ddsCaps . dwCaps & = ~ ( DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM ) ;
// DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces
2014-08-10 12:39:50 -04:00
ddsd . ddsCaps . dwCaps | = ( DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY ) ;
// on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it....
if ( dxw . dwFlags5 & NOSYSTEMEMULATED ) ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_SYSTEMMEMORY ;
2013-09-22 12:38:19 -04:00
ddsd . dwWidth = dxw . GetScreenWidth ( ) ;
ddsd . dwHeight = dxw . GetScreenHeight ( ) ;
2013-09-16 12:38:17 -04:00
// create Primary surface
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , " [Primary] " , __LINE__ ) ;
res = ( * pCreateSurface ) ( lpdd , & ddsd , lplpdds , 0 ) ;
if ( res ) {
if ( res = = DDERR_PRIMARYSURFACEALREADYEXISTS ) {
LPDIRECTDRAWSURFACE lpPrim ;
OutTraceE ( " CreateSurface: CreateSurface DDERR_PRIMARYSURFACEALREADYEXISTS workaround \n " ) ;
( * pGetGDISurface ) ( lpPrimaryDD , & lpPrim ) ;
while ( ( * pReleaseS ) ( lpPrim ) ) ;
res = ( * pCreateSurface ) ( lpdd , & ddsd , lplpdds , 0 ) ;
}
/* fall through */
if ( res ) {
OutTraceE ( " CreateSurface: ERROR on DDSPrim res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
if ( res = = DDERR_INVALIDPIXELFORMAT ) DumpPixFmt ( & ddsd ) ;
return res ;
}
2013-07-21 12:38:09 -04:00
}
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: created PRIMARY DDSPrim=%x \n " , * lplpdds ) ;
2013-09-16 12:38:17 -04:00
if ( IsDebug ) DescribeSurface ( * lplpdds , dxversion , " DDSPrim " , __LINE__ ) ;
HookDDSurfacePrim ( lplpdds , dxversion ) ;
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
if ( lpDDSEmu_Prim = = NULL ) {
ClearSurfaceDesc ( ( void * ) & ddsd , dxversion ) ;
ddsd . dwFlags = DDSD_CAPS ;
ddsd . ddsCaps . dwCaps = DDSCAPS_PRIMARYSURFACE ;
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , " [EmuPrim] " , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
res = ( * pCreateSurface ) ( lpdd , & ddsd , & lpDDSEmu_Prim , 0 ) ;
if ( res = = DDERR_PRIMARYSURFACEALREADYEXISTS ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: ASSERT DDSEmu_Prim already exists \n " ) ;
2014-02-05 11:39:10 -05:00
if ( dxw . Windowize ) {
// in Winowize mode, the desktop properties are untouched, then the current primary surface can be recycled
res = ( * pGetGDISurface ) ( lpdd , & lpDDSEmu_Prim ) ;
( * pReleaseS ) ( lpDDSEmu_Prim ) ;
}
else {
// in non-Windowized mode, the primary surface must be released and rebuilt with the proper properties
res = ( * pGetGDISurface ) ( lpdd , & lpDDSEmu_Prim ) ;
if ( lpDDSEmu_Prim ) while ( ( * pReleaseS ) ( lpDDSEmu_Prim ) ) ;
res = ( * pCreateSurface ) ( lpdd , & ddsd , & lpDDSEmu_Prim , 0 ) ;
}
2013-07-21 12:38:09 -04:00
}
2013-09-16 12:38:17 -04:00
if ( res ) {
OutTraceE ( " CreateSurface: ERROR on DDSEmu_Prim res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
if ( res = = DDERR_INVALIDPIXELFORMAT ) DumpPixFmt ( & ddsd ) ;
return res ;
2013-07-21 12:38:09 -04:00
}
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: created new DDSEmu_Prim=%x \n " , lpDDSEmu_Prim ) ;
2013-09-16 12:38:17 -04:00
if ( IsDebug ) DescribeSurface ( lpDDSEmu_Prim , dxversion , " DDSEmu_Prim " , __LINE__ ) ;
InitDSScreenParameters ( lpDDSEmu_Prim ) ;
2013-11-10 11:38:21 -05:00
dxw . MarkRegularSurface ( lpDDSEmu_Prim ) ;
2013-09-16 12:38:17 -04:00
// can't hook lpDDSEmu_Prim as generic, since the Flip method is unimplemented for a PRIMARY surface!
// better avoid it or hook just useful methods.
//if (dxw.dwTFlags & OUTPROXYTRACE) HookDDSurfaceGeneric(&lpDDSEmu_Prim, dxw.dwDDVersion);
}
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
if ( lpDDSEmu_Back = = NULL ) {
ClearSurfaceDesc ( ( void * ) & ddsd , dxversion ) ;
ddsd . dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT ;
2014-08-10 12:39:50 -04:00
// DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces
2014-11-15 11:39:58 -05:00
// DDSCAPS_SYSTEMMEMORY makes operations faster, but it is not always good...
2014-08-10 12:39:50 -04:00
ddsd . ddsCaps . dwCaps = ( DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY ) ;
// on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it....
if ( dxw . dwFlags5 & NOSYSTEMEMULATED ) ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_SYSTEMMEMORY ;
2014-11-19 11:40:00 -05:00
dwBackBufferCaps = ddsd . ddsCaps . dwCaps ;
2013-07-21 12:38:09 -04:00
ddsd . dwWidth = dxw . GetScreenWidth ( ) ;
ddsd . dwHeight = dxw . GetScreenHeight ( ) ;
2014-08-10 12:39:50 -04:00
if ( dxw . dwFlags4 & BILINEAR2XFILTER ) {
2014-07-17 12:39:35 -04:00
// double backbuffer size
ddsd . dwWidth = dxw . GetScreenWidth ( ) < < 1 ;
ddsd . dwHeight = dxw . GetScreenHeight ( ) < < 1 ;
}
2013-09-16 12:38:17 -04:00
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , " [EmuBack] " , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
res = ( * pCreateSurface ) ( lpdd , & ddsd , & lpDDSEmu_Back , 0 ) ;
2013-07-21 12:38:09 -04:00
if ( res ) {
2013-09-16 12:38:17 -04:00
OutTraceE ( " CreateSurface: CreateSurface ERROR on DDSEmuBack : res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
if ( res = = DDERR_INVALIDPIXELFORMAT ) DumpPixFmt ( & ddsd ) ;
return res ;
2013-07-21 12:38:09 -04:00
}
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: created new DDSEmu_Back=%x \n " , lpDDSEmu_Back ) ;
2013-09-16 12:38:17 -04:00
if ( IsDebug ) DescribeSurface ( lpDDSEmu_Back , dxversion , " DDSEmu_Back " , __LINE__ ) ;
2013-11-10 11:38:21 -05:00
dxw . MarkRegularSurface ( lpDDSEmu_Back ) ;
2013-09-16 12:38:17 -04:00
if ( dxw . dwTFlags & OUTPROXYTRACE ) HookDDSurfaceGeneric ( & lpDDSEmu_Back , dxversion ) ;
}
2013-07-21 12:38:09 -04:00
2014-11-28 11:40:02 -05:00
// "Hoyle Casino Empire" opens a primary surface and NOT a backbuffer ....
iBakBufferVersion = dxversion ; // v2.03.01
2013-09-16 12:38:17 -04:00
return DD_OK ;
}
static HRESULT BuildPrimaryDir ( LPDIRECTDRAW lpdd , CreateSurface_Type pCreateSurface , LPDDSURFACEDESC2 lpddsd , int dxversion , LPDIRECTDRAWSURFACE * lplpdds , void * pu )
{
DDSURFACEDESC2 ddsd ;
HRESULT res ;
// genuine primary surface
memcpy ( ( void * ) & ddsd , lpddsd , lpddsd - > dwSize ) ;
ddsd . dwFlags & = ~ ( DDSD_WIDTH | DDSD_HEIGHT | DDSD_BACKBUFFERCOUNT | DDSD_REFRESHRATE | DDSD_PIXELFORMAT ) ;
2013-09-22 12:38:19 -04:00
ddsd . ddsCaps . dwCaps & = ~ ( DDSCAPS_FLIP | DDSCAPS_COMPLEX ) ;
2014-09-21 12:39:48 -04:00
// v2.02.93: don't move primary / backbuf surfaces on systemmemory when 3DDEVICE is requested
// this impact also on capabilities for temporary surfaces for AERO optimized handling
2014-11-19 11:40:00 -05:00
if ( ( lpddsd - > dwFlags & DDSD_CAPS ) & & ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_3DDEVICE ) ) ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_SYSTEMMEMORY ;
2013-09-16 12:38:17 -04:00
// create Primary surface
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , " [Primary] " , __LINE__ ) ;
res = ( * pCreateSurface ) ( lpdd , & ddsd , lplpdds , 0 ) ;
if ( res ) {
if ( res = = DDERR_PRIMARYSURFACEALREADYEXISTS ) {
LPDIRECTDRAWSURFACE lpPrim ;
OutTraceE ( " CreateSurface: CreateSurface DDERR_PRIMARYSURFACEALREADYEXISTS workaround \n " ) ;
( * pGetGDISurface ) ( lpPrimaryDD , & lpPrim ) ;
while ( ( * pReleaseS ) ( lpPrim ) ) ;
res = ( * pCreateSurface ) ( lpdd , & ddsd , lplpdds , 0 ) ;
}
/* fall through */
if ( res ) {
OutTraceE ( " CreateSurface: ERROR on DDSPrim res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
if ( res = = DDERR_INVALIDPIXELFORMAT ) DumpPixFmt ( & ddsd ) ;
return res ;
2013-07-21 12:38:09 -04:00
}
2013-09-16 12:38:17 -04:00
}
2013-07-21 12:38:09 -04:00
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: created PRIMARY DDSPrim=%x \n " , * lplpdds ) ;
2013-09-16 12:38:17 -04:00
if ( IsDebug ) DescribeSurface ( * lplpdds , dxversion , " DDSPrim " , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
if ( dxw . dwFlags1 & EMULATEBUFFER ) {
lpDDSEmu_Prim = * lplpdds ;
2013-11-10 11:38:21 -05:00
dxw . MarkRegularSurface ( lpDDSEmu_Prim ) ;
2013-09-16 12:38:17 -04:00
ddsd . dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS ;
// warning: can't create zero sized backbuffer surface !!!!
ddsd . dwWidth = dxw . GetScreenWidth ( ) ;
ddsd . dwHeight = dxw . GetScreenHeight ( ) ;
ddsd . ddsCaps . dwCaps = 0 ;
if ( dxversion > = 4 ) ddsd . ddsCaps . dwCaps | = DDSCAPS_OFFSCREENPLAIN ;
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , " [Dir FixBuf] " , __LINE__ ) ;
res = ( * pCreateSurface ) ( lpdd , & ddsd , lplpdds , 0 ) ;
if ( res ) {
OutTraceE ( " CreateSurface: ERROR on DDSPrim res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
return res ;
}
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: created FIX DDSPrim=%x \n " , * lplpdds ) ;
2013-09-16 12:38:17 -04:00
if ( IsDebug ) DescribeSurface ( * lplpdds , dxversion , " DDSPrim(2) " , __LINE__ ) ;
}
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
HookDDSurfacePrim ( lplpdds , dxversion ) ;
if ( dxw . dwFlags1 & CLIPCURSOR ) dxw . SetClipCursor ( ) ;
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
return DD_OK ;
}
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
static HRESULT BuildBackBufferEmu ( LPDIRECTDRAW lpdd , CreateSurface_Type pCreateSurface , LPDDSURFACEDESC2 lpddsd , int dxversion , LPDIRECTDRAWSURFACE * lplpdds , void * pu )
{
DDSURFACEDESC2 ddsd ;
HRESULT res ;
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
// create BackBuffer surface
2013-09-22 12:38:19 -04:00
memcpy ( & ddsd , lpddsd , lpddsd - > dwSize ) ;
ddsd . dwFlags & = ~ ( DDSD_WIDTH | DDSD_HEIGHT | DDSD_BACKBUFFERCOUNT | DDSD_REFRESHRATE ) ;
ddsd . dwFlags | = ( DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT ) ;
ddsd . ddsCaps . dwCaps & = ~ ( DDSCAPS_BACKBUFFER | DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM ) ;
// DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces
2014-09-20 12:39:46 -04:00
ddsd . ddsCaps . dwCaps | = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ;
2014-11-19 11:40:00 -05:00
if ( ddsd . ddsCaps . dwCaps & DDSCAPS_3DDEVICE ) ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_SYSTEMMEMORY ; // necessary: Martian Gotic crashes otherwise
2014-08-10 12:39:50 -04:00
// on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it....
if ( dxw . dwFlags5 & NOSYSTEMMEMORY ) ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_SYSTEMMEMORY ;
2013-09-22 12:38:19 -04:00
ddsd . dwWidth = dxw . GetScreenWidth ( ) ;
ddsd . dwHeight = dxw . GetScreenHeight ( ) ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( & ddsd ) ;
2013-09-22 12:38:19 -04:00
2013-09-16 12:38:17 -04:00
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , " [Backbuf] " , __LINE__ ) ;
res = ( * pCreateSurface ) ( lpdd , & ddsd , lplpdds , 0 ) ;
if ( res ) {
OutTraceE ( " CreateSurface ERROR: res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
if ( res = = DDERR_INVALIDPIXELFORMAT ) DumpPixFmt ( & ddsd ) ;
return res ;
}
2013-11-10 11:38:21 -05:00
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: created BACK DDSBack=%x \n " , * lplpdds ) ;
2013-09-16 12:38:17 -04:00
if ( IsDebug ) DescribeSurface ( * lplpdds , dxversion , " DDSBack " , __LINE__ ) ;
HookDDSurfaceGeneric ( lplpdds , dxversion ) ; // added !!!
lpBackBufferDD = lpdd ; // v2.02.31
iBakBufferVersion = dxversion ; // v2.02.31
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
return DD_OK ;
}
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
static HRESULT BuildBackBufferDir ( LPDIRECTDRAW lpdd , CreateSurface_Type pCreateSurface , LPDDSURFACEDESC2 lpddsd , int dxversion , LPDIRECTDRAWSURFACE * lplpdds , void * pu )
{
DDSURFACEDESC2 ddsd ;
HRESULT res ;
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
// create BackBuffer surface
2013-09-18 12:38:18 -04:00
// ClearSurfaceDesc((void *)&ddsd, dxversion);
memcpy ( & ddsd , lpddsd , lpddsd - > dwSize ) ;
ddsd . dwFlags & = ~ ( DDSD_WIDTH | DDSD_HEIGHT | DDSD_BACKBUFFERCOUNT | DDSD_REFRESHRATE | DDSD_PIXELFORMAT ) ;
ddsd . dwFlags | = ( DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH ) ;
ddsd . ddsCaps . dwCaps & = ~ ( DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX ) ;
2014-09-21 12:39:48 -04:00
// v2.02.93: don't move primary / backbuf surfaces on systemmemory when 3DDEVICE is requested
if ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_3DDEVICE )
ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_SYSTEMMEMORY ;
else
ddsd . ddsCaps . dwCaps | = DDSCAPS_SYSTEMMEMORY ;
2013-09-16 12:38:17 -04:00
if ( dxversion > = 4 ) ddsd . ddsCaps . dwCaps | = DDSCAPS_OFFSCREENPLAIN ;
ddsd . dwWidth = dxw . GetScreenWidth ( ) ;
ddsd . dwHeight = dxw . GetScreenHeight ( ) ;
if ( dxw . dwFlags2 & BACKBUFATTACH ) {
LPDIRECTDRAWSURFACE lpPrim ;
DDSURFACEDESC2 prim ;
( * pGetGDISurface ) ( lpPrimaryDD , & lpPrim ) ;
2013-09-18 12:38:18 -04:00
memset ( & prim , 0 , sizeof ( DDSURFACEDESC2 ) ) ;
prim . dwSize = ( dxversion > = 4 ) ? sizeof ( DDSURFACEDESC2 ) : sizeof ( DDSURFACEDESC ) ;
2013-09-16 12:38:17 -04:00
res = lpPrim - > GetSurfaceDesc ( ( DDSURFACEDESC * ) & prim ) ;
( * pReleaseS ) ( lpPrim ) ;
ddsd . dwWidth = prim . dwWidth ;
ddsd . dwHeight = prim . dwHeight ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " BMX FIX: res=%x(%s) wxh=(%dx%d) \n " , res , ExplainDDError ( res ) , ddsd . dwWidth , ddsd . dwHeight ) ;
2013-09-16 12:38:17 -04:00
}
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , " [Backbuf] " , __LINE__ ) ;
res = ( * pCreateSurface ) ( lpdd , & ddsd , lplpdds , 0 ) ;
if ( res ) {
2013-09-18 12:38:18 -04:00
if ( ( dxw . dwFlags1 & SWITCHVIDEOMEMORY ) & & ( res = = DDERR_OUTOFVIDEOMEMORY ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: CreateSurface DDERR_OUTOFVIDEOMEMORY ERROR at %d, retry in SYSTEMMEMORY \n " , __LINE__ ) ;
2014-09-13 12:39:44 -04:00
ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_VIDEOMEMORY ;
2014-09-20 12:39:46 -04:00
ddsd . ddsCaps . dwCaps | = DDSCAPS_SYSTEMMEMORY ;
2013-09-18 12:38:18 -04:00
res = ( * pCreateSurface ) ( lpdd , & ddsd , lplpdds , 0 ) ;
}
if ( res ) {
OutTraceE ( " CreateSurface ERROR: res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
return res ;
}
2013-09-16 12:38:17 -04:00
}
2013-11-10 11:38:21 -05:00
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: created BACK DDSBack=%x \n " , * lplpdds ) ;
2013-09-16 12:38:17 -04:00
if ( IsDebug ) DescribeSurface ( * lplpdds , dxversion , " DDSBack " , __LINE__ ) ;
HookDDSurfaceGeneric ( lplpdds , dxversion ) ; // added !!!
lpBackBufferDD = lpdd ; // v2.02.31
iBakBufferVersion = dxversion ; // v2.02.31
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
return DD_OK ;
}
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
static HRESULT BuildGenericEmu ( LPDIRECTDRAW lpdd , CreateSurface_Type pCreateSurface , LPDDSURFACEDESC2 lpddsd , int dxversion , LPDIRECTDRAWSURFACE * lplpdds , void * pu )
{
DDSURFACEDESC2 ddsd ;
HRESULT res ;
memcpy ( & ddsd , lpddsd , lpddsd - > dwSize ) ; // Copy over ....
2013-11-10 11:38:21 -05:00
FixSurfaceCaps ( & ddsd , dxversion ) ;
2014-10-30 12:39:54 -04:00
if ( ddsd . ddsCaps . dwCaps & ( DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER ) ) ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_SYSTEMMEMORY ; // v2.02.96 !!
2014-08-10 12:39:50 -04:00
// on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it....
if ( dxw . dwFlags5 & NOSYSTEMMEMORY ) ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_SYSTEMMEMORY ;
2013-09-22 12:38:19 -04:00
2013-07-21 12:38:09 -04:00
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , " [Emu Generic] " , __LINE__ ) ;
res = ( * pCreateSurface ) ( lpdd , & ddsd , lplpdds , pu ) ;
2013-12-27 11:38:38 -05:00
if ( ( dxw . dwFlags1 & SWITCHVIDEOMEMORY ) & & ( res = = DDERR_OUTOFVIDEOMEMORY ) ) {
OutTraceDW ( " CreateSurface ERROR: res=%x(%s) at %d, retry \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_VIDEOMEMORY ;
2014-09-20 12:39:46 -04:00
ddsd . ddsCaps . dwCaps | = DDSCAPS_SYSTEMMEMORY ;
2013-12-27 11:38:38 -05:00
res = ( * pCreateSurface ) ( lpdd , & ddsd , lplpdds , pu ) ;
}
2013-07-21 12:38:09 -04:00
if ( res ) {
2013-09-16 12:38:17 -04:00
OutTraceE ( " CreateSurface: ERROR on Emu_Generic res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
2013-11-16 11:38:27 -05:00
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: created Emu_Generic dds=%x \n " , * lplpdds ) ;
2013-09-16 12:38:17 -04:00
if ( IsDebug ) DescribeSurface ( * lplpdds , dxversion , " DDSEmu_Generic " , __LINE__ ) ;
2014-03-29 12:39:00 -04:00
// v2.02.66: if 8BPP paletized surface and a primary palette exixts, apply.
// fixes "Virtua Fighter PC" palette bug
if ( lpDDP & & ( ddsd . ddpfPixelFormat . dwFlags & DDPF_PALETTEINDEXED8 ) ) {
res = ( * pSetPalette ) ( * lplpdds , lpDDP ) ;
if ( res )
OutTraceE ( " SetPalette: ERROR on lpdds=%x(Emu_Generic) res=%x(%s) at %d \n " , * lplpdds , res , ExplainDDError ( res ) , __LINE__ ) ;
else
OutTraceDW ( " CreateSurface: applied lpddp=%x to lpdds=%x \n " , lpDDP , * lplpdds ) ;
}
2013-07-21 12:38:09 -04:00
// diagnostic hooks ....
HookDDSurfaceGeneric ( lplpdds , dxversion ) ;
2013-09-16 12:38:17 -04:00
return DD_OK ;
2013-07-21 12:38:09 -04:00
}
2013-09-16 12:38:17 -04:00
static HRESULT BuildGenericDir ( LPDIRECTDRAW lpdd , CreateSurface_Type pCreateSurface , LPDDSURFACEDESC2 lpddsd , int dxversion , LPDIRECTDRAWSURFACE * lplpdds , void * pu )
{
HRESULT res ;
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) lpddsd , " [Dir Generic] " , __LINE__ ) ;
2013-10-21 12:38:23 -04:00
2013-09-16 12:38:17 -04:00
res = ( * pCreateSurface ) ( lpdd , lpddsd , lplpdds , 0 ) ;
if ( res ) {
2014-01-03 11:38:52 -05:00
// v2.02.60: Ref. game Incoming GOG release, post by Marek, error DDERR_UNSUPPORTED while trying to create ZBUFFER surface
if ( ( dxw . dwFlags1 & SWITCHVIDEOMEMORY ) & & ( ( res = = DDERR_OUTOFVIDEOMEMORY ) | | ( res = = DDERR_UNSUPPORTED ) ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface ERROR: res=%x(%s) at %d, retry \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
2013-09-16 12:38:17 -04:00
lpddsd - > ddsCaps . dwCaps & = ~ DDSCAPS_VIDEOMEMORY ;
2014-09-20 12:39:46 -04:00
lpddsd - > ddsCaps . dwCaps | = DDSCAPS_SYSTEMMEMORY ;
2013-09-16 12:38:17 -04:00
res = ( * pCreateSurface ) ( lpdd , lpddsd , lplpdds , 0 ) ;
}
if ( res ) {
OutTraceE ( " CreateSurface: CreateSurface ERROR res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
return res ;
}
}
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: created GENERIC surface dds=%x flags=%x(%s) caps=%x(%s) \n " ,
2013-09-16 12:38:17 -04:00
* lplpdds , lpddsd - > dwFlags , ExplainFlags ( lpddsd - > dwFlags ) , lpddsd - > ddsCaps . dwCaps , ExplainDDSCaps ( lpddsd - > ddsCaps . dwCaps ) ) ;
// hooks ....
HookDDSurfaceGeneric ( lplpdds , dxversion ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: created lpdds=%x type=Generic ret=%x \n " , * lplpdds , res ) ;
2013-11-28 11:38:31 -05:00
if ( IsDebug ) DescribeSurface ( * lplpdds , dxversion , " Generic " , __LINE__ ) ; //v2.02.44 bug fix
2013-09-16 12:38:17 -04:00
return DD_OK ;
}
static HRESULT WINAPI extCreateSurface ( int dxversion , CreateSurface_Type pCreateSurface , LPDIRECTDRAW lpdd , DDSURFACEDESC2 * lpddsd ,
2013-07-21 12:38:09 -04:00
LPDIRECTDRAWSURFACE * lplpdds , void * pu )
{
HRESULT res ;
2013-11-10 11:38:21 -05:00
DDSURFACEDESC2 ddsd ;
2013-07-21 12:38:09 -04:00
LPDIRECTDRAWSURFACE lpDDSPrim ;
2013-09-16 12:38:17 -04:00
DWORD CurFlags ;
int TargetSize ;
typedef HRESULT ( * BuildSurface_Type ) ( LPDIRECTDRAW , CreateSurface_Type , LPDDSURFACEDESC2 , int , LPDIRECTDRAWSURFACE * , void * ) ;
BuildSurface_Type BuildPrimary ;
BuildSurface_Type BuildBackBuffer ;
BuildSurface_Type BuildGeneric ;
if ( dxw . dwFlags1 & EMULATESURFACE ) {
BuildPrimary = BuildPrimaryEmu ;
BuildBackBuffer = BuildBackBufferEmu ;
BuildGeneric = BuildGenericEmu ;
}
else {
BuildPrimary = BuildPrimaryDir ;
BuildBackBuffer = BuildBackBufferDir ;
BuildGeneric = BuildGenericDir ;
}
2013-12-22 11:38:36 -05:00
if ( IsTraceDDRAW ) {
2013-09-16 12:38:17 -04:00
OutTrace ( " CreateSurface: Version=%d lpdd=%x " , dxversion , lpdd ) ;
LogSurfaceAttributes ( ( LPDDSURFACEDESC ) lpddsd , " [CreateSurface] " , __LINE__ ) ;
}
// check for lpddsd->dwSize value
TargetSize = ( dxversion < 4 ) ? sizeof ( DDSURFACEDESC ) : sizeof ( DDSURFACEDESC2 ) ;
if ( lpddsd - > dwSize ! = TargetSize ) {
char sMsg [ 81 ] ;
sprintf_s ( sMsg , 80 , " CreateSurface: ASSERT bad dwSize=%d dxversion=%d \n " ,
lpddsd - > dwSize , dxversion ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( sMsg ) ;
2013-09-16 12:38:17 -04:00
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " CreateSurface " , MB_OK | MB_ICONEXCLAMATION ) ;
return DDERR_INVALIDPARAMS ;
}
//GHO workaround (needed for WarWind, Rogue Spear):
if ( lpddsd - > dwFlags & & ! ( lpddsd - > dwFlags & 0x1 ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: fixing illegal dwFlags value: %x -> %x \n " ,
2013-09-16 12:38:17 -04:00
lpddsd - > dwFlags , lpddsd - > dwFlags + 1 ) ;
lpddsd - > dwFlags + + ;
}
2013-07-21 12:38:09 -04:00
memcpy ( & ddsd , lpddsd , lpddsd - > dwSize ) ; // Copy
2013-10-21 12:38:23 -04:00
// v2.02.38: this is odd: in "Star Force Deluxe" there is no PRIMARY surface, but a surface with
// 0 flags and 0 capabilities serves for this purpose. Is it a side-effect of old ddraw releases?
if ( ( dxversion = = 1 ) & & ( ddsd . dwFlags = = 0 ) ) { // Star Force Deluxe
ddsd . dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH ;
ddsd . ddsCaps . dwCaps = DDSCAPS_PRIMARYSURFACE ;
2013-11-16 11:38:27 -05:00
//if(dxw.VirtualPixelFormat.dwRGBBitCount == 8) ddsd.ddsCaps.dwCaps |= DDSCAPS_PALETTE;
2013-10-21 12:38:23 -04:00
}
2013-09-16 12:38:17 -04:00
// creation of the primary surface....
2013-07-21 12:38:09 -04:00
if ( ddsd . dwFlags & DDSD_CAPS & & ddsd . ddsCaps . dwCaps & DDSCAPS_PRIMARYSURFACE ) {
2014-03-23 12:38:58 -04:00
SetVSyncDelays ( lpdd ) ;
2013-07-21 12:38:09 -04:00
GetHookInfo ( ) - > Height = ( short ) dxw . GetScreenHeight ( ) ;
GetHookInfo ( ) - > Width = ( short ) dxw . GetScreenWidth ( ) ;
GetHookInfo ( ) - > ColorDepth = ( short ) dxw . VirtualPixelFormat . dwRGBBitCount ;
GetHookInfo ( ) - > DXVersion = dxversion ;
2013-09-16 12:38:17 -04:00
lpPrimaryDD = lpdd ; // v2.1.87
2013-11-10 11:38:21 -05:00
memcpy ( & DDSD_Prim , lpddsd , sizeof ( DDSD_Prim ) ) ; // v2.02.37
2013-07-21 12:38:09 -04:00
// beware of the different behaviour between older and newer directdraw releases...
2013-09-16 12:38:17 -04:00
if ( dxversion > = 4 ) {
if ( lpDDSEmu_Back ) while ( lpDDSEmu_Back - > Release ( ) ) ;
if ( lpDDSEmu_Prim ) while ( lpDDSEmu_Prim - > Release ( ) ) ;
2013-10-21 12:38:23 -04:00
if ( ddsd . dwFlags & DDSD_BACKBUFFERCOUNT ) { // Praetorians !!!!
2013-09-16 12:38:17 -04:00
if ( lpDDSBack ) while ( lpDDSBack - > Release ( ) ) ;
lpBackBufferDD = NULL ;
2013-07-21 12:38:09 -04:00
}
}
2013-09-16 12:38:17 -04:00
lpDDSEmu_Back = NULL ;
lpDDSEmu_Prim = NULL ;
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
int BBCount = 0 ; // or 1 ??
2013-07-21 12:38:09 -04:00
if ( ddsd . dwFlags & DDSD_BACKBUFFERCOUNT ) BBCount = ddsd . dwBackBufferCount ;
2013-08-25 12:38:13 -04:00
if ( ( BBCount > 0 ) & & ( iBakBufferVersion < 4 ) ) {
2013-07-21 12:38:09 -04:00
lpDDSBack = NULL ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: backbuffer cleared - BackBufferCount=%d \n " , BBCount ) ;
2013-07-21 12:38:09 -04:00
}
2013-09-16 12:38:17 -04:00
if ( BBCount > MAXBACKBUFFERS ) {
char sMsg [ 81 ] ;
sprintf_s ( sMsg , 80 , " CreateSurface: BackBufferCount=%d \n " , BBCount ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( sMsg ) ;
2013-09-16 12:38:17 -04:00
if ( IsAssertEnabled ) MessageBox ( 0 , sMsg , " CreateSurface " , MB_OK | MB_ICONEXCLAMATION ) ;
// recover ...
BBCount = MAXBACKBUFFERS ;
2013-07-21 12:38:09 -04:00
}
2013-09-16 12:38:17 -04:00
// build emulated primary surface, real primary and backbuffer surfaces
CurFlags = ddsd . dwFlags ;
res = BuildPrimary ( lpdd , pCreateSurface , lpddsd , dxversion , lplpdds , NULL ) ;
if ( res ) return res ;
lpDDSPrim = * lplpdds ;
2013-11-10 11:38:21 -05:00
dxw . MarkPrimarySurface ( lpDDSPrim ) ;
2014-08-29 12:39:42 -04:00
RegisterPixelFormat ( lpDDSPrim ) ;
2014-10-08 12:39:38 -04:00
2013-09-16 12:38:17 -04:00
if ( BBCount ) {
// build emulated backbuffer surface
res = BuildBackBuffer ( lpdd , pCreateSurface , lpddsd , dxversion , & lpDDSBack , NULL ) ;
if ( res ) return res ;
2013-11-10 11:38:21 -05:00
dxw . MarkBackBufferSurface ( lpDDSBack ) ;
2013-09-16 12:38:17 -04:00
// V2.1.85/V2.2.34: tricky !!!!
// When a real backbuffer is created, it has a reference to its frontbuffer.
// some games (Monopoly 3D) may depend on this setting - i.e. they could close
// the exceeding references - so this is better be replicated adding an initial
// reference to the zero count. But you don't have to do this if the backbuffer
// is created independently by the primary surface.
lpDDSBack - > AddRef ( ) ; // should it be repeated BBCount times????
}
2013-12-22 11:38:36 -05:00
if ( IsTraceDDRAW ) {
2013-09-16 12:38:17 -04:00
OutTrace ( " CreateSurface: created DDSPrim=%x DDSBack=%x " , lpDDSPrim , lpDDSBack ) ;
if ( dxw . dwFlags1 & ( EMULATESURFACE | EMULATEBUFFER ) ) OutTrace ( " DDSEmu_Prim=%x " , lpDDSEmu_Prim ) ;
if ( dxw . dwFlags1 & EMULATESURFACE ) OutTrace ( " DDSEmu_Back=%x " , lpDDSEmu_Back ) ;
OutTrace ( " \n " ) ;
2013-07-21 12:38:09 -04:00
}
2013-09-16 12:38:17 -04:00
// rebuild the clipper area
2013-08-25 12:38:13 -04:00
if ( dxw . dwFlags1 & CLIPCURSOR ) dxw . SetClipCursor ( ) ;
2014-03-21 12:38:57 -04:00
// v2.2.64: added extra ref needed to preserve ddraw session for later use. Is it a ddraw1 legacy?
// seems to fix problems in "Warhammer 40K Rites Of War" that uses a ddraw session after reaching 0 refcount.
2014-10-07 12:39:31 -04:00
// v2.2.84: avoid the extra referenced in non windowed mode since it causes the window shift reported by gsky916
// for Wind Fantasy SP.
if ( ( dxw . dwDDVersion = = 1 ) & & dxw . Windowize ) lpdd - > AddRef ( ) ;
2014-03-21 12:38:57 -04:00
2013-09-16 12:38:17 -04:00
return DD_OK ;
}
2013-07-21 12:38:09 -04:00
2013-09-16 12:38:17 -04:00
// a request for a separate (not complex) backbuffer to attach later on, maybe.
if ( ( ddsd . dwFlags & DDSD_CAPS ) & & ( ddsd . ddsCaps . dwCaps & DDSCAPS_BACKBUFFER ) ) {
if ( lpDDSBack ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: returning current DDSBack=%x \n " , lpDDSBack ) ;
2013-09-16 12:38:17 -04:00
* lplpdds = lpDDSBack ;
return DD_OK ;
2013-07-21 12:38:09 -04:00
}
2013-09-16 12:38:17 -04:00
res = BuildBackBuffer ( lpdd , pCreateSurface , lpddsd , dxversion , lplpdds , NULL ) ;
lpDDSBack = * lplpdds ;
2013-11-10 11:38:21 -05:00
dxw . MarkBackBufferSurface ( lpDDSBack ) ;
2013-09-16 12:38:17 -04:00
return res ;
2013-07-21 12:38:09 -04:00
}
2013-10-21 12:38:23 -04:00
// if nothing else, it's a generic/zbuffer surface
if ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_ZBUFFER ) {
lpDDZBuffer = * lplpdds ;
DDZBufferCaps = lpddsd - > ddsCaps . dwCaps ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " CreateSurface: lpDDZBuffer=%x save ZBUFFER caps=%x(%s) \n " , lpDDZBuffer , DDZBufferCaps , ExplainDDSCaps ( DDZBufferCaps ) ) ;
2013-10-21 12:38:23 -04:00
}
2013-09-16 12:38:17 -04:00
res = BuildGeneric ( lpdd , pCreateSurface , lpddsd , dxversion , lplpdds , pu ) ;
2013-11-10 11:38:21 -05:00
if ( ! res ) dxw . MarkRegularSurface ( * lplpdds ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
2013-09-16 12:38:17 -04:00
2013-07-21 12:38:09 -04:00
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 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 , LPDDSCAPS lpddsc , LPDIRECTDRAWSURFACE * lplpddas )
{
HRESULT res ;
BOOL IsPrim ;
2013-11-10 11:38:21 -05:00
BOOL IsBack ;
2013-07-21 12:38:09 -04:00
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-11-10 11:38:21 -05:00
IsBack = dxw . IsABackBufferSurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetAttachedSurface(%d): lpdds=%x%s caps=%x(%s) \n " ,
2013-11-10 11:38:21 -05:00
dxversion , lpdds , ( IsPrim ? " (PRIM) " : ( IsBack ? " (BACK) " : " " ) ) , lpddsc - > dwCaps , ExplainDDSCaps ( lpddsc - > dwCaps ) ) ;
2013-07-21 12:38:09 -04:00
2013-03-12 12:38:32 -04:00
// this is yet to be proven utility.....
// v2.02.45: No - it prevents "Praetorians" to work!!! -> commented out.
//
//if (IsBack && (lpddsc->dwCaps & DDSCAPS_ZBUFFER) && lpDDZBuffer){
// *lplpddas = lpDDZBuffer;
2013-12-22 11:38:36 -05:00
// OutTraceDW("GetAttachedSurface(%d): emulating ZBUFFER attach on BACKBUFFER lpddsadd=%x\n", dxversion, *lplpddas);
2013-03-12 12:38:32 -04:00
// return 0;
//}
2013-07-21 12:38:09 -04:00
// 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.
2014-11-03 11:38:55 -05:00
// 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 lpDDSBack surface can't be returned.
2013-07-21 12:38:09 -04:00
2014-11-03 11:38:55 -05:00
if ( IsBack & & ( DDSD_Prim . dwBackBufferCount > 1 ) & & ( lpddsc - > dwCaps & DDSCAPS_BACKBUFFER ) ) {
//if (IsBack && (DDSD_Prim.dwBackBufferCount > 1)){
2013-11-10 11:38:21 -05:00
* lplpddas = lpDDSBack ;
2014-11-03 11:38:55 -05:00
OutTraceDW ( " GetAttachedSurface(%d): DOUBLEBUFFER attached to BACK=%x \n " , dxversion , * lplpddas ) ;
return DD_OK ;
2013-11-10 11:38:21 -05:00
}
2013-07-21 12:38:09 -04:00
// on primary surface return the lpDDSBack surface coming from either an explicit
// AddAttachedSurface, or a primary complex surface creation otherwise....
2013-11-17 11:38:28 -05:00
if ( IsPrim & & ( lpddsc - > dwCaps & ( DDSCAPS_BACKBUFFER | DDSCAPS_FLIP ) ) ) { // v2.02.42 added DDSCAPS_FLIP for Empire Earth
2013-07-21 12:38:09 -04:00
if ( lpDDSBack ) {
* lplpddas = lpDDSBack ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetAttachedSurface(%d): BACKBUFFER attached=%x \n " , dxversion , * lplpddas ) ;
2014-11-03 11:38:55 -05:00
return DD_OK ;
2013-07-21 12:38:09 -04:00
}
else {
* lplpddas = NULL ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetAttachedSurface(%d): no attached BACKBUFFER \n " , dxversion ) ;
2013-07-21 12:38:09 -04:00
return DDERR_NOTFOUND ;
}
}
2014-11-03 11:38:55 -05:00
2013-11-17 11:38:28 -05:00
// proxy the call...
res = ( * pGetAttachedSurface ) ( lpdds , lpddsc , lplpddas ) ;
if ( res )
OutTraceE ( " GetAttachedSurface(%d): ERROR res=%x(%s) at %d \n " , dxversion , res , ExplainDDError ( res ) , __LINE__ ) ;
else
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetAttachedSurface(%d): attached=%x \n " , dxversion , * lplpddas ) ;
2014-12-10 11:39:52 -05:00
2013-11-17 11:38:28 -05:00
return res ;
2013-07-21 12:38:09 -04:00
}
HRESULT WINAPI extGetAttachedSurface1 ( LPDIRECTDRAWSURFACE lpdds , LPDDSCAPS lpddsc , LPDIRECTDRAWSURFACE * lplpddas )
{
return extGetAttachedSurface ( 1 , pGetAttachedSurface1 , lpdds , lpddsc , lplpddas ) ;
}
HRESULT WINAPI extGetAttachedSurface3 ( LPDIRECTDRAWSURFACE lpdds , LPDDSCAPS lpddsc , LPDIRECTDRAWSURFACE * lplpddas )
{
return extGetAttachedSurface ( 3 , pGetAttachedSurface3 , lpdds , lpddsc , lplpddas ) ;
}
HRESULT WINAPI extGetAttachedSurface4 ( LPDIRECTDRAWSURFACE lpdds , LPDDSCAPS lpddsc , LPDIRECTDRAWSURFACE * lplpddas )
{
return extGetAttachedSurface ( 4 , pGetAttachedSurface4 , lpdds , lpddsc , lplpddas ) ;
}
HRESULT WINAPI extGetAttachedSurface7 ( LPDIRECTDRAWSURFACE lpdds , LPDDSCAPS lpddsc , LPDIRECTDRAWSURFACE * lplpddas )
{
return extGetAttachedSurface ( 7 , pGetAttachedSurface7 , lpdds , lpddsc , lplpddas ) ;
}
static void BlitError ( HRESULT res , LPRECT lps , LPRECT lpd , int line )
{
2013-12-22 11:38:36 -05:00
OutTrace ( " Blt: ERROR %x(%s) at %d " , res , ExplainDDError ( res ) , line ) ;
2013-07-21 12:38:09 -04:00
if ( res = = DDERR_INVALIDRECT ) {
if ( lps )
2013-12-22 11:38:36 -05:00
OutTrace ( " src=(%d,%d)-(%d,%d) " , lps - > left , lps - > top , lps - > right , lps - > bottom ) ;
2013-07-21 12:38:09 -04:00
else
2013-12-22 11:38:36 -05:00
OutTrace ( " src=(NULL) " ) ;
2013-07-21 12:38:09 -04:00
if ( lpd )
2013-12-22 11:38:36 -05:00
OutTrace ( " dest=(%d,%d)-(%d,%d) " , lpd - > left , lpd - > top , lpd - > right , lpd - > bottom ) ;
2013-07-21 12:38:09 -04:00
else
2013-12-22 11:38:36 -05:00
OutTrace ( " dest=(NULL) " ) ;
2013-07-21 12:38:09 -04:00
}
2013-12-22 11:38:36 -05:00
OutTrace ( " \n " ) ;
2013-07-21 12:38:09 -04:00
return ;
}
2013-10-08 12:38:12 -04:00
static void BlitTrace ( char * label , LPRECT lps , LPRECT lpd , int line )
2013-07-21 12:38:09 -04:00
{
2013-10-08 12:38:12 -04:00
extern HANDLE hTraceMutex ;
WaitForSingleObject ( hTraceMutex , INFINITE ) ;
2013-07-21 12:38:09 -04:00
OutTrace ( " Blt: %s " , label ) ;
if ( lps )
OutTrace ( " src=(%d,%d)-(%d,%d) " , lps - > left , lps - > top , lps - > right , lps - > bottom ) ;
else
OutTrace ( " src=(NULL) " ) ;
if ( lpd )
OutTrace ( " dest=(%d,%d)-(%d,%d) " , lpd - > left , lpd - > top , lpd - > right , lpd - > bottom ) ;
else
OutTrace ( " dest=(NULL) " ) ;
2013-08-25 12:38:13 -04:00
OutTrace ( " at %d \n " , line ) ;
2013-10-08 12:38:12 -04:00
ReleaseMutex ( hTraceMutex ) ;
2013-07-21 12:38:09 -04:00
return ;
}
2014-09-13 12:39:44 -04:00
HRESULT WINAPI PrimaryBlt ( LPDIRECTDRAWSURFACE lpdds , LPRECT lpdestrect , LPDIRECTDRAWSURFACE lpddssrc , LPRECT lpsrcrect )
{
return ( * pBlt ) ( lpdds , lpdestrect , lpddssrc , lpsrcrect , DDBLT_WAIT , 0 ) ;
}
HRESULT WINAPI PrimaryFastBlt ( LPDIRECTDRAWSURFACE lpdds , LPRECT lpdestrect , LPDIRECTDRAWSURFACE lpddssrc , LPRECT lpsrcrect )
{
return ( * pBltFast ) ( lpdds , lpdestrect - > left , lpdestrect - > top , lpddssrc , lpsrcrect , DDBLTFAST_WAIT ) ;
}
HRESULT WINAPI PrimaryStretchBlt ( LPDIRECTDRAWSURFACE lpdds , LPRECT lpdestrect , LPDIRECTDRAWSURFACE lpddssrc , LPRECT lpsrcrect )
{
HRESULT res ;
2014-11-15 11:39:58 -05:00
DDSURFACEDESC2 ddsd ;
2014-09-13 12:39:44 -04:00
RECT TmpRect ;
LPDIRECTDRAWSURFACE lpddsTmp ;
2014-09-20 12:39:46 -04:00
LPDIRECTDRAWSURFACE lpddsBak ;
DDSCAPS caps ;
2014-11-15 11:39:58 -05:00
CreateSurface1_Type pCreateSurface ;
int dwSize ;
switch ( iBakBufferVersion ) {
default :
case 1 : pCreateSurface = pCreateSurface1 ; dwSize = sizeof ( DDSURFACEDESC ) ; break ;
case 2 : pCreateSurface = ( CreateSurface1_Type ) pCreateSurface2 ; dwSize = sizeof ( DDSURFACEDESC ) ; break ;
case 3 : pCreateSurface = ( CreateSurface1_Type ) pCreateSurface3 ; dwSize = sizeof ( DDSURFACEDESC ) ; break ;
case 4 : pCreateSurface = ( CreateSurface1_Type ) pCreateSurface4 ; dwSize = sizeof ( DDSURFACEDESC2 ) ; break ;
case 7 : pCreateSurface = ( CreateSurface1_Type ) pCreateSurface7 ; dwSize = sizeof ( DDSURFACEDESC2 ) ; break ;
}
2014-09-20 12:39:46 -04:00
caps . dwCaps = DDSCAPS_BACKBUFFER ;
2014-09-13 12:39:44 -04:00
memset ( & ddsd , 0 , sizeof ( ddsd ) ) ;
2014-11-15 11:39:58 -05:00
ddsd . dwSize = dwSize ;
2014-09-20 12:39:46 -04:00
if ( lpddssrc = = NULL ) {
// blit from backbuffer
2014-11-15 11:39:58 -05:00
lpdds - > GetAttachedSurface ( & caps , & ( LPDIRECTDRAWSURFACE ) lpddsBak ) ;
lpddsBak - > GetSurfaceDesc ( ( LPDDSURFACEDESC ) & ddsd ) ;
2014-09-20 12:39:46 -04:00
}
else {
// blit from surface
2014-11-15 11:39:58 -05:00
lpddssrc - > GetSurfaceDesc ( ( LPDDSURFACEDESC ) & ddsd ) ;
2014-09-20 12:39:46 -04:00
}
2014-09-13 12:39:44 -04:00
TmpRect . left = TmpRect . top = 0 ;
TmpRect . bottom = ddsd . dwHeight = lpdestrect - > bottom - lpdestrect - > top ;
TmpRect . right = ddsd . dwWidth = lpdestrect - > right - lpdestrect - > left ;
2014-11-15 11:39:58 -05:00
if ( ( TmpRect . bottom = = 0 ) | | ( TmpRect . right = = 0 ) ) return DD_OK ; // avoid blitting to null areas (Fifa 2000 D3D)
2014-09-13 12:39:44 -04:00
ddsd . dwFlags = ( DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS ) ;
2014-09-21 12:39:48 -04:00
// capabilities must cope with primary / backbuffer surface capabilities to get speedy operations
2014-11-19 11:40:00 -05:00
ddsd . ddsCaps . dwCaps = dwBackBufferCaps ;
2014-11-15 11:39:58 -05:00
res = ( * pCreateSurface ) ( lpPrimaryDD , ( LPDDSURFACEDESC ) & ddsd , & lpddsTmp , NULL ) ;
if ( res ) {
OutTraceE ( " CreateSurface: ERROR %x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
if ( IsDebug ) DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , " [Gateway] " , __LINE__ ) ;
return res ;
}
2014-09-13 12:39:44 -04:00
// stretch-blit to target size on OFFSCREENPLAIN temp surface
res = ( * pBlt ) ( lpddsTmp , & TmpRect , lpddssrc , lpsrcrect , DDBLT_WAIT , 0 ) ;
if ( res ) OutTraceE ( " Blt: ERROR %x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
// fast-blit to primary
res = ( * pBltFast ) ( lpdds , lpdestrect - > left , lpdestrect - > top , lpddsTmp , & TmpRect , DDBLTFAST_WAIT ) ;
if ( res ) OutTraceE ( " Blt: ERROR %x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
if ( res ) BlitError ( res , lpsrcrect , lpdestrect , __LINE__ ) ;
( * pReleaseS ) ( lpddsTmp ) ;
return res ;
}
2014-11-19 11:40:00 -05:00
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 ) ;
2014-11-28 11:40:02 -05:00
strcpy ( p , " filter.dll " ) ;
2014-11-19 11:40:00 -05:00
filterlib = ( * pLoadLibraryA ) ( sSourcePath ) ;
if ( ! filterlib ) {
OutTraceDW ( " DXWND: Load lib= \" %s \" failed err=%d \n " , sSourcePath , GetLastError ( ) ) ;
return NULL ;
}
return ( * pGetProcAddress ) ( filterlib , apiname ) ;
}
2014-08-10 12:39:50 -04:00
HRESULT WINAPI PrimaryBilinearBlt ( LPDIRECTDRAWSURFACE lpdds , LPRECT lpdestrect , LPDIRECTDRAWSURFACE lpddssrc , LPRECT lpsrcrect )
{
HRESULT res ;
2014-11-19 11:40:00 -05:00
typedef void ( WINAPI * Resize_HQ_Type ) ( unsigned char * , RECT * , int , unsigned char * , RECT * , int ) ;
static Resize_HQ_Type pResize_HQ = NULL ;
2014-08-10 12:39:50 -04:00
/* to be implemented .... */
2014-11-19 11:40:00 -05:00
2014-11-15 11:39:58 -05:00
DDSURFACEDESC2 ddsd ;
2014-08-10 12:39:50 -04:00
RECT TmpRect , SrcRect ;
LPDIRECTDRAWSURFACE lpddsTmp ;
LPDIRECTDRAWSURFACE lpddsBak ;
LPDIRECTDRAWSURFACE lpddsCopy = NULL ;
DDSCAPS caps ;
BYTE * bSourceBuf , * bDestBuf ;
LONG dwWidth , dwHeight ;
int SrcPitch , DestPitch ;
2014-11-15 11:39:58 -05:00
CreateSurface1_Type pCreateSurface ;
int dwSize ;
switch ( iBakBufferVersion ) {
default :
case 1 : pCreateSurface = pCreateSurface1 ; dwSize = sizeof ( DDSURFACEDESC ) ; break ;
case 2 : pCreateSurface = ( CreateSurface1_Type ) pCreateSurface2 ; dwSize = sizeof ( DDSURFACEDESC ) ; break ;
case 3 : pCreateSurface = ( CreateSurface1_Type ) pCreateSurface3 ; dwSize = sizeof ( DDSURFACEDESC ) ; break ;
case 4 : pCreateSurface = ( CreateSurface1_Type ) pCreateSurface4 ; dwSize = sizeof ( DDSURFACEDESC2 ) ; break ;
case 7 : pCreateSurface = ( CreateSurface1_Type ) pCreateSurface7 ; dwSize = sizeof ( DDSURFACEDESC2 ) ; break ;
}
2014-08-10 12:39:50 -04:00
caps . dwCaps = DDSCAPS_BACKBUFFER ;
memset ( & ddsd , 0 , sizeof ( DDSURFACEDESC ) ) ;
2014-11-15 11:39:58 -05:00
ddsd . dwSize = dwSize ;
2014-08-10 12:39:50 -04:00
if ( lpddssrc = = NULL ) {
// blit from backbuffer
lpdds - > GetAttachedSurface ( & caps , & lpddsBak ) ;
2014-11-15 11:39:58 -05:00
if ( lpddsBak ) lpddsBak - > GetSurfaceDesc ( ( LPDDSURFACEDESC ) & ddsd ) ;
2014-08-10 12:39:50 -04:00
}
else {
// blit from surface
2014-11-15 11:39:58 -05:00
lpddssrc - > GetSurfaceDesc ( ( LPDDSURFACEDESC ) & ddsd ) ;
2014-08-10 12:39:50 -04:00
}
// 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
2014-11-19 11:40:00 -05:00
ddsd . ddsCaps . dwCaps = dwBackBufferCaps ;
2014-11-15 11:39:58 -05:00
res = ( * pCreateSurface ) ( lpPrimaryDD , ( LPDDSURFACEDESC ) & ddsd , & lpddsTmp , NULL ) ;
2014-08-10 12:39:50 -04:00
if ( res ) OutTraceE ( " CreateSurface: ERROR %x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
// get informations
2014-11-15 11:39:58 -05:00
memset ( & ddsd , 0 , dwSize ) ;
ddsd . dwSize = dwSize ;
2014-08-10 12:39:50 -04:00
ddsd . dwFlags = DDSD_LPSURFACE | DDSD_PITCH ;
res = ( * pLock ) ( lpddssrc , 0 , ( LPDDSURFACEDESC ) & ddsd , DDLOCK_SURFACEMEMORYPTR | DDLOCK_READONLY , 0 ) ;
if ( res ) OutTraceE ( " Lock: ERROR %x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
bSourceBuf = ( BYTE * ) ddsd . lpSurface ;
SrcPitch = ddsd . lPitch ;
2014-11-15 11:39:58 -05:00
memset ( & ddsd , 0 , dwSize ) ;
ddsd . dwSize = dwSize ;
2014-08-10 12:39:50 -04:00
ddsd . dwFlags = DDSD_LPSURFACE | DDSD_PITCH ;
res = ( * pLock ) ( lpddsTmp , 0 , ( LPDDSURFACEDESC ) & ddsd , DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY | DDLOCK_WAIT , 0 ) ;
if ( res ) OutTraceE ( " Lock: ERROR %x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
bDestBuf = ( BYTE * ) ddsd . lpSurface ;
DestPitch = ddsd . lPitch ;
// do the filtering
2014-11-19 11:40:00 -05:00
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 ;
}
2014-11-28 11:40:02 -05:00
filterlib = ( * pLoadLibraryA ) ( " filter.dll " ) ;
2014-11-19 11:40:00 -05:00
if ( ! filterlib ) {
char sMsg [ 80 + 1 ] ;
2014-11-28 11:40:02 -05:00
sprintf ( sMsg , " DXWND: ERROR can't load lib= \" filter.dll \" err=%x \n " , GetLastError ( ) ) ;
2014-11-19 11:40:00 -05:00
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 ) ;
2014-08-10 12:39:50 -04:00
// fast-blit to primary
2014-11-15 11:39:58 -05:00
( * pUnlockMethod ( lpddssrc ) ) ( lpddssrc , NULL ) ;
( * pUnlockMethod ( lpddsTmp ) ) ( lpddsTmp , NULL ) ;
2014-08-10 12:39:50 -04:00
res = ( * pBltFast ) ( lpdds , lpdestrect - > left , lpdestrect - > top , lpddsTmp , & TmpRect , DDBLTFAST_WAIT ) ;
if ( res ) OutTraceE ( " BltFast: ERROR %x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
( * pReleaseS ) ( lpddsTmp ) ;
if ( lpddsCopy ) ( * pReleaseS ) ( lpddsCopy ) ;
return res ;
}
2014-09-13 12:39:44 -04:00
HRESULT WINAPI PrimaryNoBlt ( LPDIRECTDRAWSURFACE lpdds , LPRECT lpdestrect , LPDIRECTDRAWSURFACE lpddssrc , LPRECT lpsrcrect )
{
return DD_OK ;
}
2013-07-21 12:38:09 -04:00
HRESULT WINAPI sBlt ( char * api , LPDIRECTDRAWSURFACE lpdds , LPRECT lpdestrect ,
LPDIRECTDRAWSURFACE lpddssrc , LPRECT lpsrcrect , DWORD dwflags , LPDDBLTFX lpddbltfx , BOOL isFlipping )
{
RECT emurect , destrect ;
POINT p = { 0 , 0 } ;
HRESULT res ;
BOOL ToPrim , FromPrim , ToScreen , FromScreen ;
2014-09-13 12:39:44 -04:00
extern PrimaryBlt_Type pPrimaryBlt ;
2013-07-21 12:38:09 -04:00
//CkArg arg;
ToPrim = dxw . IsAPrimarySurface ( lpdds ) ;
FromPrim = dxw . IsAPrimarySurface ( lpddssrc ) ;
ToScreen = ToPrim & & ! ( dxw . dwFlags1 & EMULATESURFACE ) ;
2014-05-29 12:39:18 -04:00
FromScreen = FromPrim & & ! ( dxw . dwFlags1 & EMULATESURFACE ) & & ! ( dxw . dwFlags1 & EMULATEBUFFER ) ; // v2.02.77
2013-07-21 12:38:09 -04:00
CleanRect ( & lpdestrect , __LINE__ ) ;
CleanRect ( & lpsrcrect , __LINE__ ) ;
// log
2013-12-22 11:38:36 -05:00
if ( IsTraceDW ) {
2013-11-10 11:38:21 -05:00
char sLog [ 256 ] ;
char sInfo [ 128 ] ;
sprintf ( sLog , " %s: dest=%x%s src=%x%s dwFlags=%x(%s) " ,
2013-07-21 12:38:09 -04:00
api , lpdds , ( ToPrim ? " (PRIM) " : " " ) , lpddssrc , ( FromPrim ? " (PRIM) " : " " ) , dwflags , ExplainBltFlags ( dwflags ) ) ;
if ( lpdestrect )
2013-11-10 11:38:21 -05:00
sprintf ( sInfo , " destrect=(%d,%d)-(%d,%d) " , lpdestrect - > left , lpdestrect - > top , lpdestrect - > right , lpdestrect - > bottom ) ;
2013-07-21 12:38:09 -04:00
else
2013-11-10 11:38:21 -05:00
sprintf ( sInfo , " destrect=(NULL) " ) ;
strcat ( sLog , sInfo ) ;
2013-07-21 12:38:09 -04:00
if ( lpsrcrect )
2013-11-10 11:38:21 -05:00
sprintf ( sInfo , " srcrect=(%d,%d)-(%d,%d) " , lpsrcrect - > left , lpsrcrect - > top , lpsrcrect - > right , lpsrcrect - > bottom ) ;
2013-07-21 12:38:09 -04:00
else
2013-11-10 11:38:21 -05:00
sprintf ( sInfo , " srcrect=(NULL) " ) ;
strcat ( sLog , sInfo ) ;
if ( lpddbltfx ) {
if ( dwflags & DDBLT_COLORFILL ) {
sprintf ( sInfo , " ddbltfx.FillColor=%x " , lpddbltfx - > dwFillColor ) ;
strcat ( sLog , sInfo ) ;
}
if ( dwflags & DDBLT_KEYDESTOVERRIDE ) {
sprintf ( sInfo , " ddbltfx.DestColorkey=%x " , lpddbltfx - > ddckDestColorkey ) ;
strcat ( sLog , sInfo ) ;
}
if ( dwflags & DDBLT_KEYSRCOVERRIDE ) {
sprintf ( sInfo , " ddbltfx.SrcColorkey=%x " , lpddbltfx - > ddckSrcColorkey ) ;
strcat ( sLog , sInfo ) ;
}
if ( dwflags & DDBLT_ROP ) {
sprintf ( sInfo , " ddbltfx.ROP=%x " , lpddbltfx - > dwROP ) ;
strcat ( sLog , sInfo ) ;
}
2013-10-21 12:38:23 -04:00
if ( dwflags & DDBLT_DEPTHFILL ) {
sprintf ( sInfo , " ddbltfx.FillDepth=%x " , lpddbltfx - > dwFillDepth ) ;
strcat ( sLog , sInfo ) ;
}
2013-11-10 11:38:21 -05:00
}
strcat ( sLog , " \n " ) ;
OutTrace ( sLog ) ;
2013-07-21 12:38:09 -04:00
}
2013-11-10 11:38:24 -05:00
// debug suppressions
if ( ToPrim ) {
2013-11-10 11:38:26 -05:00
if ( isFlipping ) {
2013-11-10 11:38:24 -05:00
if ( dxw . dwFlags3 & NODDRAWFLIP ) return DD_OK ;
2013-11-10 11:38:26 -05:00
}
else {
2013-11-10 11:38:24 -05:00
if ( dxw . dwFlags3 & NODDRAWBLT ) return DD_OK ;
2013-11-16 11:38:27 -05:00
}
2013-11-10 11:38:26 -05:00
}
2013-11-10 11:38:24 -05:00
2013-07-21 12:38:09 -04:00
# ifdef ONEPIXELFIX
if ( lpdestrect ) {
if ( ( lpdestrect - > top = = 0 ) & & ( lpdestrect - > bottom = = dxw . GetScreenHeight ( ) - 1 ) ) lpdestrect - > bottom = dxw . GetScreenHeight ( ) ;
if ( ( lpdestrect - > left = = 0 ) & & ( lpdestrect - > right = = dxw . GetScreenWidth ( ) - 1 ) ) lpdestrect - > right = dxw . GetScreenWidth ( ) ;
}
if ( lpsrcrect ) {
if ( ( lpsrcrect - > top = = 0 ) & & ( lpsrcrect - > bottom = = dxw . GetScreenHeight ( ) - 1 ) ) lpsrcrect - > bottom = dxw . GetScreenHeight ( ) ;
if ( ( lpsrcrect - > left = = 0 ) & & ( lpsrcrect - > right = = dxw . GetScreenWidth ( ) - 1 ) ) lpsrcrect - > right = dxw . GetScreenWidth ( ) ;
}
# endif
# define FIXBIGGERRECT 1
2013-08-25 12:38:13 -04:00
# if FIXBIGGERRECT
2013-07-21 12:38:09 -04:00
if ( ToPrim & & lpdestrect ) {
2013-11-10 11:38:21 -05:00
if ( ( DWORD ) lpdestrect - > top < 0 ) lpdestrect - > top = 0 ;
if ( ( DWORD ) lpdestrect - > left < 0 ) lpdestrect - > left = 0 ;
2013-07-21 12:38:09 -04:00
if ( ( DWORD ) lpdestrect - > bottom > dxw . GetScreenHeight ( ) ) lpdestrect - > bottom = dxw . GetScreenHeight ( ) ;
if ( ( DWORD ) lpdestrect - > right > dxw . GetScreenWidth ( ) ) lpdestrect - > right = dxw . GetScreenWidth ( ) ;
}
# endif
// blit to non primary surface
if ( ! ToPrim ) {
//RECT srcrect, winrect;
RECT srcrect ;
// make a working copy of srcrect if not NULL
if ( lpsrcrect ) {
srcrect = * lpsrcrect ;
}
// when blitting from a primary surface on screen (that is in non emulated mode), correct offsets
// You should take account also for scaled primary surfaces, but that would be a hard task:
// a reduced primary surface (in not-emulated mode) would bring quality loss!!!
// v2.1.83: BLITFROMBACKBUFFER mode, let you chose to blit from backbuffer, where the surface size
// is fixed no matter how the window/primary surface is scaled.
// In "The Sims" there is no quality loss, but some scrolling artifact.
if ( lpsrcrect & & FromScreen ) {
if ( lpDDSBack & & ( dxw . dwFlags1 & BLITFROMBACKBUFFER ) ) {
lpddssrc = lpDDSBack ;
srcrect = dxw . GetScreenRect ( ) ;
}
else {
srcrect = dxw . MapWindowRect ( lpsrcrect ) ;
}
}
2013-10-08 12:38:12 -04:00
if ( IsDebug ) BlitTrace ( " NOPRIM " , lpsrcrect , lpdestrect , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
res = ( * pBlt ) ( lpdds , lpdestrect , lpddssrc , lpsrcrect ? & srcrect : NULL , dwflags , lpddbltfx ) ;
// Blitting compressed data may work to screen surfaces only. In this case, it may be worth
// trying blitting directly to lpDDSEmu_Prim: it makes DK2 intro movies working.
2013-11-10 11:38:26 -05:00
// Wrong guess!!! The cause was not compression, but simply a pixelformat mismatch. Better
// configure things properly and avoid this branch.
2013-07-21 12:38:09 -04:00
switch ( res ) {
case DDERR_UNSUPPORTED :
if ( dxw . dwFlags1 & EMULATESURFACE ) {
2013-11-10 11:38:21 -05:00
RECT targetrect ;
2013-10-08 12:38:12 -04:00
if ( IsDebug ) BlitTrace ( " UNSUPP " , lpsrcrect ? & srcrect : NULL , lpdestrect , __LINE__ ) ;
2013-11-10 11:38:21 -05:00
targetrect = * lpdestrect ;
dxw . MapWindowRect ( & targetrect ) ;
res = ( * pBlt ) ( lpDDSEmu_Prim , & targetrect , lpddssrc , lpsrcrect ? & srcrect : NULL , dwflags , lpddbltfx ) ;
2013-07-21 12:38:09 -04:00
}
break ;
case DDERR_SURFACEBUSY :
( * pUnlockMethod ( lpdds ) ) ( lpdds , NULL ) ;
if ( lpddssrc ) ( * pUnlockMethod ( lpddssrc ) ) ( lpddssrc , NULL ) ;
2013-10-08 12:38:12 -04:00
if ( IsDebug ) BlitTrace ( " BUSY " , lpsrcrect ? & srcrect : NULL , lpdestrect , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
res = ( * pBlt ) ( lpdds , lpdestrect , lpddssrc , lpsrcrect ? & srcrect : NULL , dwflags | DDBLT_WAIT , lpddbltfx ) ;
break ;
default :
break ;
}
if ( res ) BlitError ( res , & srcrect , lpdestrect , __LINE__ ) ;
2013-11-16 11:38:27 -05:00
if ( IsDebug ) {
DescribeSurface ( lpdds , 0 , " [DST] " , __LINE__ ) ;
if ( lpddssrc ) DescribeSurface ( lpddssrc , 0 , " [SRC] " , __LINE__ ) ; // lpddssrc could be NULL!!!
}
2013-07-21 12:38:09 -04:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = 0 ;
2014-11-19 11:40:00 -05:00
if ( dxw . dwFlags5 & ( TEXTUREHIGHLIGHT | TEXTUREDUMP | TEXTUREHACK ) ) TextureHandling ( lpdds ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
2014-09-13 12:39:44 -04:00
// =========================
2013-07-21 12:38:09 -04:00
// Blit to primary surface
2014-09-13 12:39:44 -04:00
// =========================
2013-07-21 12:38:09 -04:00
2014-08-10 12:39:50 -04:00
if ( dxw . dwFlags5 & QUARTERBLT ) {
BOOL QuarterUpdate ;
QuarterUpdate = lpdestrect ?
( ( ( lpdestrect - > bottom - lpdestrect - > top ) * ( lpdestrect - > right - lpdestrect - > left ) ) > ( ( LONG ) ( dxw . GetScreenHeight ( ) * dxw . GetScreenWidth ( ) ) > > 2 ) )
:
TRUE ;
if ( QuarterUpdate ) if ( dxw . HandleFPS ( ) ) return DD_OK ;
}
else
2014-09-20 12:39:46 -04:00
if ( dxw . HandleFPS ( ) ) return DD_OK ;
2014-09-13 12:39:44 -04:00
if ( dxw . dwFlags5 & NOBLT ) return DD_OK ;
2013-08-25 12:38:13 -04:00
2013-07-21 12:38:09 -04:00
destrect = dxw . MapWindowRect ( lpdestrect ) ;
2014-12-10 11:39:52 -05:00
OutTraceB ( " DESTRECT=(%d,%d)-(%d,%d) Screen=(%dx%d) \n " ,
destrect . left , destrect . top , destrect . right , destrect . bottom ,
dxw . GetScreenWidth ( ) , dxw . GetScreenHeight ( ) ) ;
2013-07-21 12:38:09 -04:00
2014-09-13 12:39:44 -04:00
// =========================
// Blit to primary direct surface
// =========================
2013-07-21 12:38:09 -04:00
if ( ! ( dxw . dwFlags1 & ( EMULATESURFACE | EMULATEBUFFER ) ) ) {
2014-09-13 12:39:44 -04:00
res = DD_OK ;
2013-07-21 12:38:09 -04:00
// blit only when source and dest surface are different. Should make ScreenRefresh faster.
if ( lpdds ! = lpddssrc ) {
2013-03-12 12:38:32 -04:00
dxw . ShowOverlay ( lpddssrc ) ;
2013-10-08 12:38:12 -04:00
if ( IsDebug ) BlitTrace ( " PRIM-NOEMU " , lpsrcrect , & destrect , __LINE__ ) ;
2014-09-13 12:39:44 -04:00
res = ( * pPrimaryBlt ) ( lpdds , & destrect , lpddssrc , lpsrcrect ) ;
2013-07-21 12:38:09 -04:00
}
if ( res ) {
BlitError ( res , lpsrcrect , & destrect , __LINE__ ) ;
2014-09-02 12:38:49 -04:00
if ( IsDebug ) {
DescribeSurface ( lpdds , 0 , " [DST] " , __LINE__ ) ;
if ( lpddssrc ) DescribeSurface ( lpddssrc , 0 , " [SRC] " , __LINE__ ) ; // lpddssrc could be NULL!!!
}
2013-07-21 12:38:09 -04:00
// Try to handle HDC lock concurrency....
if ( res = = DDERR_SURFACEBUSY ) {
( * pUnlockMethod ( lpdds ) ) ( lpdds , NULL ) ;
2013-10-08 12:38:12 -04:00
if ( IsDebug ) BlitTrace ( " BUSY " , lpsrcrect , & destrect , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
res = ( * pBlt ) ( lpdds , & destrect , lpddssrc , lpsrcrect , dwflags , lpddbltfx ) ;
if ( res ) BlitError ( res , lpsrcrect , & destrect , __LINE__ ) ;
}
2014-09-02 12:38:49 -04:00
// Try to handle DDBLT_KEYSRC on primary surface
if ( ( res = = DDERR_INVALIDPARAMS ) & & ( dwflags & DDBLT_KEYSRC ) ) {
// to do: handle possible situations with surface 2 / 4 / 7 types
DDSURFACEDESC ddsd ;
LPDIRECTDRAWSURFACE lpddsTmp ;
if ( IsDebug ) BlitTrace ( " KEYSRC " , lpsrcrect , & destrect , __LINE__ ) ;
memset ( & ddsd , 0 , sizeof ( ddsd ) ) ;
ddsd . dwSize = sizeof ( ddsd ) ;
lpddssrc - > GetSurfaceDesc ( & ddsd ) ;
res = ( * pCreateSurface1 ) ( lpPrimaryDD , & ddsd , & lpddsTmp , NULL ) ;
if ( res ) OutTraceE ( " CreateSurface: ERROR %x(%s) at %d " , res , ExplainDDError ( res ) , __LINE__ ) ;
// copy background
res = ( * pBlt ) ( lpddsTmp , lpsrcrect , lpdds , & destrect , DDBLT_WAIT , NULL ) ;
if ( res ) OutTraceE ( " Blt: ERROR %x(%s) at %d " , res , ExplainDDError ( res ) , __LINE__ ) ;
// overlay texture
res = ( * pBlt ) ( lpddsTmp , lpsrcrect , lpddssrc , lpsrcrect , dwflags , lpddbltfx ) ;
if ( res ) OutTraceE ( " Blt: ERROR %x(%s) at %d " , res , ExplainDDError ( res ) , __LINE__ ) ;
// copy back to destination
res = ( * pBlt ) ( lpdds , & destrect , lpddsTmp , lpsrcrect , DDBLT_WAIT , lpddbltfx ) ;
if ( res ) OutTraceE ( " Blt: ERROR %x(%s) at %d " , res , ExplainDDError ( res ) , __LINE__ ) ;
if ( res ) BlitError ( res , lpsrcrect , & destrect , __LINE__ ) ;
( * pReleaseS ) ( lpddsTmp ) ;
}
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = DD_OK ;
2013-07-21 12:38:09 -04:00
}
return res ;
}
// ... else blitting on emulated surface
2014-09-13 12:39:44 -04:00
// =========================
2013-07-21 12:38:09 -04:00
// Blit/Flip to emulated primary surface
2014-09-13 12:39:44 -04:00
// =========================
2013-07-21 12:38:09 -04:00
if ( ! lpddssrc ) {
if ( isFlipping ) {
// handle the flipping chain ...
lpddssrc = lpDDSBack ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Flip: setting flip chain to lpdds=%x \n " , lpddssrc ) ;
2013-07-21 12:38:09 -04:00
}
}
if ( lpdestrect ) {
emurect = * lpdestrect ;
}
else {
// emurect: emulated rect is full surface (dwWidth x dwHeight)
emurect . left = 0 ;
emurect . top = 0 ;
emurect . right = dxw . GetScreenWidth ( ) ;
emurect . bottom = dxw . GetScreenHeight ( ) ;
}
res = 0 ;
// blit only when source and dest surface are different. Should make ScreenRefresh faster.
if ( lpdds ! = lpddssrc ) {
2013-10-08 12:38:12 -04:00
if ( IsDebug ) BlitTrace ( " SRC2EMU " , & emurect , & destrect , __LINE__ ) ;
2014-08-10 12:39:50 -04:00
if ( destrect . top = = - 32000 ) return DD_OK ; // happens when window is minimized & do not notify on task switch ...
2013-07-21 12:38:09 -04:00
res = ( * pBlt ) ( lpdds , & emurect , lpddssrc , lpsrcrect , dwflags , lpddbltfx ) ;
}
if ( res ) {
BlitError ( res , lpsrcrect , & emurect , __LINE__ ) ;
2013-11-10 11:38:21 -05:00
DescribeSurface ( lpdds , 0 , " [DST] " , __LINE__ ) ;
if ( lpddssrc ) DescribeSurface ( lpddssrc , 0 , " [SRC] " , __LINE__ ) ; // lpddssrc could be NULL!!!
2013-07-21 12:38:09 -04:00
/*
Dungeon Keeper II intro movies bug . . . .
it seems that you can ' t blit from compressed or different surfaces in memory ,
while the operation COULD be supported to video . As a mater of fact , it DOES
2014-11-15 11:39:58 -05:00
work on my PC . The error code is DDERR_UNSUPPORTED .
v2 .02 .98 update . . . .
The same thing happens with New York Racer , but with DDERR_EXCEPTION error code .
2013-07-21 12:38:09 -04:00
*/
2014-11-15 11:39:58 -05:00
if ( ( res = = DDERR_UNSUPPORTED ) | | ( res = = DDERR_EXCEPTION ) ) {
2013-03-12 12:38:32 -04:00
dxw . ShowOverlay ( lpddssrc ) ;
2013-10-08 12:38:12 -04:00
if ( IsDebug ) BlitTrace ( " UNSUPP " , & emurect , & destrect , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
res = ( * pBlt ) ( lpDDSEmu_Prim , & destrect , lpddssrc , lpsrcrect , dwflags , lpddbltfx ) ;
if ( res ) BlitError ( res , lpsrcrect , & destrect , __LINE__ ) ;
}
// Try to handle HDC lock concurrency....
if ( res = = DDERR_SURFACEBUSY ) {
res = ( * pUnlockMethod ( lpddssrc ) ) ( lpddssrc , NULL ) ;
if ( res ) OutTraceE ( " Unlock ERROR: err=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-10-08 12:38:12 -04:00
if ( IsDebug ) BlitTrace ( " BUSY " , & emurect , & destrect , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
res = ( * pBlt ) ( lpdds , & emurect , lpddssrc , lpsrcrect , dwflags , lpddbltfx ) ;
if ( res ) BlitError ( res , lpsrcrect , & destrect , __LINE__ ) ;
}
2014-09-13 12:39:44 -04:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = DD_OK ;
2013-07-21 12:38:09 -04:00
return res ;
}
LPDIRECTDRAWSURFACE lpDDSSource ;
if ( dxw . dwFlags1 & EMULATESURFACE ) {
res = ( * pEmuBlt ) ( lpDDSEmu_Back , & emurect , lpdds , & emurect , DDBLT_WAIT , 0 ) ;
if ( res = = DDERR_SURFACEBUSY ) {
( * pUnlockMethod ( lpdds ) ) ( lpdds , NULL ) ;
( * pUnlockMethod ( lpDDSEmu_Back ) ) ( lpDDSEmu_Back , NULL ) ;
res = ( * pEmuBlt ) ( lpDDSEmu_Back , & emurect , lpdds , & emurect , DDBLT_WAIT , 0 ) ;
}
if ( res ) {
2014-11-19 11:40:00 -05:00
BlitError ( res , & emurect , & emurect , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = 0 ;
return res ;
}
lpDDSSource = lpDDSEmu_Back ;
}
else {
lpDDSSource = lpdds ;
}
2013-03-12 12:38:32 -04:00
dxw . ShowOverlay ( lpDDSSource ) ;
2013-10-08 12:38:12 -04:00
if ( IsDebug ) BlitTrace ( " BACK2PRIM " , & emurect , & destrect , __LINE__ ) ;
2014-09-13 12:39:44 -04:00
res = ( * pPrimaryBlt ) ( lpDDSEmu_Prim , & destrect , lpDDSSource , & emurect ) ;
2013-07-21 12:38:09 -04:00
if ( res ) BlitError ( res , & emurect , & destrect , __LINE__ ) ;
2014-09-13 12:39:44 -04:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = DD_OK ;
2013-07-21 12:38:09 -04:00
if ( IsDebug ) OutTrace ( " %s: done ret=%x at %d \n " , api , res , __LINE__ ) ;
return res ;
}
HRESULT WINAPI extFlip ( LPDIRECTDRAWSURFACE lpdds , LPDIRECTDRAWSURFACE lpddssrc , DWORD dwflags )
{
BOOL IsPrim ;
HRESULT res ;
2014-02-03 11:38:53 -05:00
DDSURFACEDESC2 ddsd ;
LPDIRECTDRAWSURFACE lpddsTmp ;
2013-07-21 12:38:09 -04:00
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " Flip: lpdds=%x%s, src=%x, flags=%x(%s) \n " ,
2013-07-21 12:38:09 -04:00
lpdds , IsPrim ? " (PRIM) " : " " , lpddssrc , dwflags , ExplainFlipFlags ( dwflags ) ) ;
if ( ! IsPrim ) {
if ( lpddssrc ) {
res = ( * pFlip ) ( lpdds , lpddssrc , dwflags ) ;
}
else {
LPDIRECTDRAWSURFACE lpddsAttached ;
DDSCAPS ddsc ;
DDSURFACEDESC2 sd ;
sd . dwSize = Set_dwSize_From_Surface ( lpdds ) ;
res = lpdds - > GetSurfaceDesc ( ( DDSURFACEDESC * ) & sd ) ;
2013-12-22 11:38:36 -05:00
if ( res ) OutTraceDW ( " Flip: GetSurfaceDesc res=%x at %d \n " , res , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
// replace these CAPS (good for seven kingdoms II) with same as lpdds surface
//ddsc.dwCaps=DDSCAPS_OFFSCREENPLAIN+DDSCAPS_SYSTEMMEMORY;
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 ( " 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 ;
}
// emulation to primary surface Flip - you can't flip to window surfaces,
// so you have to replace it with Blt operations.
2013-08-25 12:38:13 -04:00
if ( ( dwflags & DDFLIP_WAIT ) | | ( dxw . dwFlags1 & SAVELOAD ) ) lpPrimaryDD - > WaitForVerticalBlank ( DDWAITVB_BLOCKEND , 0 ) ;
2013-07-21 12:38:09 -04:00
2014-02-03 11:38:53 -05:00
if ( dxw . dwFlags4 & NOFLIPEMULATION ) {
2014-06-22 12:39:24 -04:00
HRESULT res2 ;
2014-03-23 12:38:58 -04:00
// create a temporary working surface
2014-02-03 11:38:53 -05:00
memset ( & ddsd , 0 , sizeof ( ddsd ) ) ;
ddsd . dwSize = SurfaceDescrSize ( lpdds ) ;
2014-06-22 12:39:24 -04:00
// v2.02.80: the BackBuffer may not exist? see "HellCopter"
if ( lpDDSBack ) {
( * pGetSurfaceDescMethod ( lpdds ) ) ( ( 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 ( ) ;
}
res2 = ( * pCreateSurfaceMethod ( lpdds ) ) ( lpPrimaryDD , & ddsd , & lpddsTmp , NULL ) ;
if ( res2 ) {
OutTraceE ( " CreateSurface: ERROR %x(%s) at %d \n " , res2 , ExplainDDError ( res2 ) , __LINE__ ) ;
OutTrace ( " Size=%d lpPrimaryDD=%x lpDDSBack=%x \n " , ddsd . dwSize , lpPrimaryDD , lpDDSBack ) ;
LogSurfaceAttributes ( ( LPDDSURFACEDESC ) & ddsd , " [FlipBuf] " , __LINE__ ) ;
//dxw.dwFlags4 &= ~NOFLIPEMULATION;
}
2014-03-23 12:38:58 -04:00
//OutTrace("DEBUG: copied surface size=(%dx%d)\n", ddsd.dwWidth, ddsd.dwHeight);
2014-02-03 11:38:53 -05:00
// copy front buffer
2014-03-15 12:38:56 -04:00
if ( dxw . dwFlags1 & EMULATESURFACE ) {
// in emulated mode, the primary surface is virtual and you can pick it all
// needed for "Gruntz"
2014-06-22 12:39:24 -04:00
res2 = ( * pBlt ) ( lpddsTmp , NULL , lpdds , NULL , DDBLT_WAIT , NULL ) ;
if ( res2 ) BlitError ( res2 , NULL , NULL , __LINE__ ) ;
2014-03-15 12:38:56 -04:00
}
else {
// in no-emulated mode, the primary surface is the whole screen, so you have to pick...
// needed for "Black Thorn"
RECT clip ;
2014-05-29 12:39:18 -04:00
if ( dxw . dwFlags1 & EMULATEBUFFER )
clip = dxw . GetScreenRect ( ) ;
else
2014-03-15 12:38:56 -04:00
clip = dxw . GetUnmappedScreenRect ( ) ;
2014-06-22 12:39:24 -04:00
res2 = ( * pBlt ) ( lpddsTmp , NULL , lpdds , & clip , DDBLT_WAIT , NULL ) ;
if ( res2 ) BlitError ( res2 , & clip , NULL , __LINE__ ) ;
2014-03-15 12:38:56 -04:00
}
2014-02-03 11:38:53 -05:00
}
2013-07-21 12:38:09 -04:00
if ( lpddssrc ) {
//res=lpdds->Blt(0, lpddssrc, 0, DDBLT_WAIT, 0);
res = sBlt ( " Flip " , lpdds , NULL , lpddssrc , NULL , DDBLT_WAIT , 0 , TRUE ) ;
}
else {
2013-10-21 12:38:23 -04:00
//v2.02.38: look for a valid BackBuffer surface
if ( ! lpDDSBack ) lpDDSBack = dxw . GetBackBufferSurface ( ) ;
if ( ! lpDDSBack ) {
OutTraceE ( " Flip: no backbuffer \n " ) ;
return DDERR_INVALIDPARAMS ;
}
2013-07-21 12:38:09 -04:00
if ( dxw . dwFlags2 & BACKBUFATTACH ) {
RECT NullArea ;
NullArea . left = NullArea . top = 0 ;
NullArea . bottom = dxw . GetScreenHeight ( ) ;
NullArea . right = dxw . GetScreenWidth ( ) ;
res = sBlt ( " Flip " , lpdds , NULL , lpDDSBack , & NullArea , DDBLT_WAIT , 0 , TRUE ) ;
}
else
res = sBlt ( " Flip " , lpdds , NULL , lpDDSBack , NULL , DDBLT_WAIT , 0 , TRUE ) ;
2014-02-03 11:38:53 -05:00
lpddssrc = lpDDSBack ;
}
if ( dxw . dwFlags4 & NOFLIPEMULATION ) {
2014-06-22 12:39:24 -04:00
HRESULT res2 ;
2014-03-23 12:38:58 -04:00
// restore flipped backbuffer and delete temporary surface
2014-06-22 12:39:24 -04:00
res2 = ( * pBlt ) ( lpddssrc , NULL , lpddsTmp , NULL , DDBLT_WAIT , NULL ) ;
if ( res2 ) OutTraceE ( " Blt: ERROR %x(%s) at %d \n " , res2 , ExplainDDError ( res2 ) , __LINE__ ) ;
2014-02-03 11:38:53 -05:00
( * pReleaseS ) ( lpddsTmp ) ;
2013-07-21 12:38:09 -04:00
}
if ( res ) OutTraceE ( " Flip: Blt ERROR %x(%s) \n " , res , ExplainDDError ( res ) ) ;
return res ;
}
HRESULT WINAPI extBlt ( LPDIRECTDRAWSURFACE lpdds , LPRECT lpdestrect ,
LPDIRECTDRAWSURFACE lpddssrc , LPRECT lpsrcrect , DWORD dwflags , LPDDBLTFX lpddbltfx )
{
if ( ( dxw . dwFlags2 & FULLRECTBLT ) & & dxw . IsAPrimarySurface ( lpdds ) ) {
lpsrcrect = NULL ;
lpdestrect = NULL ;
}
return sBlt ( " Blt " , lpdds , lpdestrect , lpddssrc , lpsrcrect , dwflags , lpddbltfx , FALSE ) ;
}
HRESULT WINAPI extBltFast ( 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 = dxw . IsAPrimarySurface ( lpdds ) ;
FromPrim = dxw . IsAPrimarySurface ( lpddssrc ) ;
CleanRect ( & lpsrcrect , __LINE__ ) ;
2013-12-22 11:38:36 -05:00
if ( IsTraceDDRAW ) {
2013-07-21 12:38:09 -04:00
OutTrace ( " BltFast: dest=%x%s src=%x%s dwTrans=%x(%s) (x,y)=(%d,%d) " ,
lpdds , ToPrim ? " (PRIM) " : " " , lpddssrc , FromPrim ? " (PRIM) " : " " , dwtrans , ExplainBltFastFlags ( dwtrans ) , dwx , dwy ) ;
if ( lpsrcrect )
OutTrace ( " srcrect=(%d,%d)-(%d,%d) \n " ,
lpsrcrect - > left , lpsrcrect - > top , lpsrcrect - > right , lpsrcrect - > bottom ) ;
else
OutTrace ( " srcrect=(NULL) \n " ) ;
}
// consistency check ....
if ( lpsrcrect )
if ( ( lpsrcrect - > left > = lpsrcrect - > right ) | | ( lpsrcrect - > top > = lpsrcrect - > bottom ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " BltFast: ASSERT bad rect at %d \n " , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
return 0 ;
}
2014-09-02 12:38:49 -04:00
flags = 0 ;
2013-07-21 12:38:09 -04:00
if ( dwtrans & DDBLTFAST_WAIT ) flags = DDBLT_WAIT ;
if ( dwtrans & DDBLTFAST_DESTCOLORKEY ) flags | = DDBLT_KEYDEST ;
if ( dwtrans & DDBLTFAST_SRCCOLORKEY ) flags | = DDBLT_KEYSRC ;
2014-10-08 12:39:38 -04:00
//if(dwtrans & DDBLTFAST_SRCCOLORKEY) flags |= DDBLT_COLORFILL;
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:21 -05:00
if ( ( dxw . dwFlags2 & FULLRECTBLT ) & & ToPrim ) {
2014-09-02 12:38:49 -04:00
return sBlt ( " BltFast " , lpdds , NULL , lpddssrc , lpsrcrect , flags , NULL , FALSE ) ;
2013-11-10 11:38:21 -05:00
}
2013-07-21 12:38:09 -04:00
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 ;
2014-09-02 12:38:49 -04:00
ret = sBlt ( " BltFast " , lpdds , & destrect , lpddssrc , & srcrect , flags , NULL , FALSE ) ;
2013-07-21 12:38:09 -04:00
}
else {
// does it EVER goes through here? NULL is not a valid rect value for BltFast call....
2013-11-10 11:38:21 -05:00
// yes, forced in FULLRECTBLT mode!
2014-10-08 12:39:38 -04:00
// yes, when BltFast on DDBLTFAST_SRCCOLORKEY!! (Pax Corpus)
if ( lpddssrc ) {
ddsd . dwSize = Set_dwSize_From_Surface ( lpddssrc ) ;
ddsd . dwFlags = DDSD_WIDTH | DDSD_HEIGHT ;
ret = lpddssrc - > GetSurfaceDesc ( ( LPDDSURFACEDESC ) & ddsd ) ;
if ( ret ) {
OutTraceE ( " BltFast: GetSurfaceDesc ERROR %x at %d \n " , ret , __LINE__ ) ;
return 0 ;
}
destrect . right = destrect . left + ddsd . dwWidth ;
destrect . bottom = destrect . top + ddsd . dwHeight ;
ret = sBlt ( " BltFast " , lpdds , & destrect , lpddssrc , NULL , flags , NULL , FALSE ) ;
}
else {
//ret=sBlt("BltFast", lpdds, NULL, lpddssrc, NULL, flags, NULL, FALSE);
ret = DD_OK ;
2013-07-21 12:38:09 -04:00
}
}
return ret ;
}
2013-11-10 11:38:26 -05:00
HRESULT WINAPI extWaitForVerticalBlank ( LPDIRECTDRAW lpdd , DWORD dwflags , HANDLE hevent )
{
2014-10-08 12:39:38 -04:00
if ( dxw . dwFlags1 & SAVELOAD ) {
dxw . VSyncWait ( ) ;
return 0 ;
}
return ( * pWaitForVerticalBlank ) ( lpdd , dwflags , hevent ) ;
2013-11-10 11:38:26 -05:00
}
2013-10-21 12:38:23 -04:00
# define DDPCAPS_INITIALIZE_LEGACY 0x00000008l
2013-07-21 12:38:09 -04:00
HRESULT WINAPI extCreatePalette ( LPDIRECTDRAW lpdd , DWORD dwflags , LPPALETTEENTRY lpddpa ,
LPDIRECTDRAWPALETTE * lplpddp , IUnknown * pu )
{
HRESULT res ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " CreatePalette: dwFlags=%x(%s) \n " , dwflags , ExplainCreatePaletteFlags ( dwflags ) ) ;
2013-11-28 11:38:31 -05:00
if ( IsDebug & & ( dwflags & DDPCAPS_8BIT ) ) dxw . DumpPalette ( 256 , lpddpa ) ;
2013-07-21 12:38:09 -04:00
2013-03-12 12:38:32 -04:00
//if (dwflags & ~(DDPCAPS_PRIMARYSURFACE|DDPCAPS_8BIT|DDPCAPS_ALLOW256|DDPCAPS_INITIALIZE_LEGACY)) STOPPER("Palette flags");
2013-10-21 12:38:23 -04:00
2013-11-10 11:38:26 -05:00
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 ) ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
2013-12-22 11:38:36 -05:00
else OutTraceDDRAW ( " CreatePalette: OK lpddp=%x \n " , * lplpddp ) ;
2013-07-21 12:38:09 -04:00
HookDDPalette ( lplpddp ) ;
return 0 ;
}
HRESULT WINAPI extGetPalette ( LPDIRECTDRAWSURFACE lpdds , LPDIRECTDRAWPALETTE * lplpddp )
{
HRESULT res ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetPalette: lpdds=%x \n " , lpdds ) ;
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:26 -05:00
res = ( * pGetPalette ) ( lpdds , lplpddp ) ;
if ( res ) OutTraceE ( " GetPalette: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-12-22 11:38:36 -05:00
else OutTraceDDRAW ( " GetPalette: OK \n " ) ;
2013-11-10 11:38:26 -05:00
return res ;
2013-07-21 12:38:09 -04:00
}
HRESULT WINAPI extSetPalette ( LPDIRECTDRAWSURFACE lpdds , LPDIRECTDRAWPALETTE lpddp )
{
PALETTEENTRY * lpentries ;
BOOL isPrim ;
HRESULT res ;
isPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " SetPalette: lpdds=%x%s lpddp=%x \n " , lpdds , isPrim ? " (PRIM) " : " " , lpddp ) ;
2013-07-21 12:38:09 -04:00
res = ( * pSetPalette ) ( lpdds , lpddp ) ;
if ( res ) OutTraceE ( " SetPalette: ERROR res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
2013-12-22 11:38:36 -05:00
else OutTraceDDRAW ( " SetPalette: OK \n " ) ;
2014-03-23 12:38:58 -04:00
res = DD_OK ;
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:26 -05:00
if ( ( dxw . dwFlags1 & EMULATESURFACE ) & & isPrim ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " SetPalette: register PRIMARY palette lpDDP=%x \n " , lpddp ) ;
2013-07-21 12:38:09 -04:00
lpDDP = lpddp ;
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 ) ) ;
2014-05-24 12:39:16 -04:00
mySetPalette ( 0 , 256 , lpentries ) ; // v2.02.76: necessary for "Requiem Avenging Angel" in SURFACEEMULATION mode
2013-07-21 12:38:09 -04:00
}
2014-03-21 12:38:57 -04:00
// Apply palette to backbuffer surface. This is necessary on some games: "Duckman private dick", "Total Soccer 2000", ...
if ( lpDDSBack ) {
2014-03-23 12:38:58 -04:00
OutTraceDW ( " SetPalette: apply PRIMARY palette lpDDP=%x to DDSBack=%x \n " , lpddp , lpDDSBack ) ;
2014-03-21 12:38:57 -04:00
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....
lpdds - > AddRef ( ) ;
2014-03-23 12:38:58 -04:00
res = DD_OK ;
2013-07-21 12:38:09 -04:00
}
return res ;
}
HRESULT WINAPI extSetEntries ( LPDIRECTDRAWPALETTE lpddp , DWORD dwflags , DWORD dwstart , DWORD dwcount , LPPALETTEENTRY lpentries )
{
HRESULT res ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " SetEntries: lpddp=%x dwFlags=%x, start=%d, count=%d entries=%x \n " , //GHO: added trace infos
2013-10-21 12:38:23 -04:00
lpddp , dwflags , dwstart , dwcount , lpentries ) ;
2013-11-28 11:38:31 -05:00
if ( IsDebug ) dxw . DumpPalette ( dwcount , & lpentries [ dwstart ] ) ;
2013-07-21 12:38:09 -04:00
res = ( * pSetEntries ) ( lpddp , dwflags , dwstart , dwcount , lpentries ) ;
if ( res ) OutTraceE ( " SetEntries: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-12-22 11:38:36 -05:00
else OutTraceDDRAW ( " SetEntries: OK \n " ) ;
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:26 -05:00
if ( ( dxw . dwFlags1 & EMULATESURFACE ) & & ( lpDDP = = lpddp ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " SetEntries: update PRIMARY palette lpDDP=%x \n " , lpddp ) ;
2013-11-10 11:38:26 -05:00
if ( ( dwstart + dwcount > 256 ) | | ( dwstart < 0 ) ) {
dwcount = 256 ;
dwstart = 0 ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " SetEntries: ASSERT start+count > 256 \n " ) ;
2013-11-10 11:38:26 -05:00
}
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:26 -05:00
mySetPalette ( dwstart , dwcount , lpentries ) ;
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:26 -05:00
// 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, ...
if ( ( dxw . dwFlags1 & EMULATESURFACE ) & & ! ( dxw . dwFlags2 & NOPALETTEUPDATE ) ) dxw . ScreenRefresh ( ) ;
}
return res ;
2013-07-21 12:38:09 -04:00
}
HRESULT WINAPI extSetClipper ( LPDIRECTDRAWSURFACE lpdds , LPDIRECTDRAWCLIPPER lpddc )
{
HRESULT res ;
BOOL isPrim ;
isPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " SetClipper: lpdds=%x%s lpddc=%x \n " , lpdds , isPrim ? " (PRIM) " : " " , lpddc ) ;
2013-07-21 12:38:09 -04:00
// v2.1.84: SUPPRESSCLIPPING flag - improves "Monopoly Edition 3D" where continuous
// clipping ON & OFF affects blitting on primary surface.
2014-02-19 11:38:50 -05:00
// Needed also to avoid "New Yourk Racer" intro movie clipping.
2013-07-21 12:38:09 -04:00
if ( dxw . dwFlags1 & SUPPRESSCLIPPING ) return 0 ;
if ( dxw . dwFlags1 & ( EMULATESURFACE | EMULATEBUFFER ) ) {
if ( ( isPrim & & lpDDSEmu_Prim ) | |
( ( lpdds = = lpDDSBack ) & & lpDDSEmu_Back ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " SetClipper: skip primary/backbuffer lpdds=%x \n " , lpdds ) ;
2013-07-21 12:38:09 -04:00
res = 0 ;
}
else
res = ( * pSetClipper ) ( lpdds , lpddc ) ;
}
else
res = ( * pSetClipper ) ( lpdds , lpddc ) ;
if ( res )
OutTraceE ( " SetClipper: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
return res ;
}
2014-03-21 12:38:57 -04:00
HRESULT WINAPI extLock ( LPDIRECTDRAWSURFACE lpdds , LPRECT lprect , LPDDSURFACEDESC lpDDSurfaceDesc , DWORD flags , HANDLE hEvent )
2013-07-21 12:38:09 -04:00
{
HRESULT res ;
BOOL IsPrim ;
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-11-10 11:38:21 -05:00
CleanRect ( & lprect , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
2014-05-11 12:39:56 -04:00
if ( IsTraceDW ) {
2014-03-21 12:38:57 -04:00
OutTrace ( " Lock: lpdds=%x%s flags=%x(%s) lpDDSurfaceDesc=%x " ,
lpdds , ( IsPrim ? " (PRIM) " : " " ) , flags , ExplainLockFlags ( flags ) , lpDDSurfaceDesc ) ;
2013-07-21 12:38:09 -04:00
if ( lprect )
OutTrace ( " rect=(%d,%d)-(%d,%d) \n " , lprect - > left , lprect - > top , lprect - > right , lprect - > bottom ) ;
else
OutTrace ( " rect=(NULL) \n " ) ;
}
2014-03-21 12:38:57 -04:00
res = ( * pLock ) ( lpdds , lprect , lpDDSurfaceDesc , flags , hEvent ) ;
2013-07-21 12:38:09 -04:00
if ( res = = DDERR_SURFACEBUSY ) { // v70: fix for "Ancient Evil"
( * pUnlockMethod ( lpdds ) ) ( lpdds , NULL ) ;
2014-03-21 12:38:57 -04:00
res = ( * pLock ) ( lpdds , lprect , lpDDSurfaceDesc , flags , hEvent ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Lock RETRY: ret=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-07-21 12:38:09 -04:00
}
if ( res ) OutTraceE ( " Lock ERROR: ret=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2014-03-21 12:38:57 -04:00
DumpSurfaceAttributes ( lpDDSurfaceDesc , " [Locked] " , __LINE__ ) ;
2014-07-17 12:39:35 -04:00
OutTraceB ( " Lock: lPitch=%d lpSurface=%x \n " , lpDDSurfaceDesc - > lPitch , lpDDSurfaceDesc - > lpSurface ) ;
2013-07-21 12:38:09 -04:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = DD_OK ;
2014-04-12 12:40:05 -04:00
// Pitch fix: some video cards require alignement to a wide boundary, e.g. 128 bytes.
// on "Risk II" (Microprose version) you get a 800x600 generic surface that has a wider
// pitch (1664 bytes, that is the smaller 128 multiple of 800 * 2) that should be treated
// as if it were a smaller one (1600 = 800 * 2) to get a good blit.
// both fixes below are working (one is commented out).
if ( dxw . dwFlags1 & EMULATESURFACE )
lpDDSurfaceDesc - > lPitch = ( lpDDSurfaceDesc - > dwWidth * lpDDSurfaceDesc - > ddpfPixelFormat . dwRGBBitCount ) > > 3 ;
//lpDDSurfaceDesc->lPitch = (lpDDSurfaceDesc->lPitch / lpDDSurfaceDesc->dwWidth) * lpDDSurfaceDesc->dwWidth;
2013-07-21 12:38:09 -04:00
return res ;
}
2013-07-30 12:38:11 -04:00
LPDIRECTDRAWSURFACE2 lpDDSBuffer = NULL ;
2014-03-21 12:38:57 -04:00
HRESULT WINAPI extLockDir ( LPDIRECTDRAWSURFACE lpdds , LPRECT lprect , LPDDSURFACEDESC lpDDSurfaceDesc , DWORD flags , HANDLE hEvent )
2013-07-30 12:38:11 -04:00
{
2013-11-23 11:38:29 -05:00
HRESULT res , res2 ;
2013-07-30 12:38:11 -04:00
static RECT client ;
POINT upleft = { 0 , 0 } ;
LPDIRECTDRAWSURFACE lpDDSPrim ;
// this hooker operates on
// Beware!!! for strange reason, the function gets hooked to ANY surface, also non primary ones!!!
2013-08-25 12:38:13 -04:00
// to find out whether it is the primary or not, using lpdds==lpPrimaryDD->GetGDISurface(&lpDDSPrim);
2013-07-30 12:38:11 -04:00
2013-12-22 11:38:36 -05:00
if ( IsTraceDDRAW ) {
2014-03-21 12:38:57 -04:00
OutTrace ( " Lock: lpdds=%x flags=%x(%s) lpDDSurfaceDesc=%x " ,
lpdds , flags , ExplainLockFlags ( flags ) , lpDDSurfaceDesc ) ;
2013-07-30 12:38:11 -04:00
if ( lprect )
OutTrace ( " rect=(%d,%d)-(%d,%d) \n " , lprect - > left , lprect - > top , lprect - > right , lprect - > bottom ) ;
else
OutTrace ( " rect=(NULL) \n " ) ;
}
2013-11-23 11:38:29 -05:00
// V2.02.43: Empire Earth does some test Lock operations apparently before the primary surface is created
if ( lpPrimaryDD ) {
lpDDSPrim = 0 ;
res2 = ( * pGetGDISurface ) ( lpPrimaryDD , & lpDDSPrim ) ;
if ( res2 )
OutTraceE ( " Lock: GetGDISurface ERROR res=%x(%s) at %d \n " , res2 , ExplainDDError ( res2 ) , __LINE__ ) ;
else
2013-11-28 11:38:31 -05:00
( * pReleaseS ) ( lpDDSPrim ) ;
if ( lpdds = = lpDDSPrim ) {
if ( dxw . dwFlags1 & LOCKEDSURFACE ) {
DDSURFACEDESC2 ddsd ;
DDBLTFX fx ;
memset ( & ddsd , 0 , sizeof ( ddsd ) ) ;
//ddsd.dwSize=SurfaceDescrSize(lpdds);
ddsd . dwSize = sizeof ( DDSURFACEDESC ) ;
ddsd . dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS ;
ddsd . dwWidth = dxw . GetScreenWidth ( ) ;
ddsd . dwHeight = dxw . GetScreenHeight ( ) ;
ddsd . ddsCaps . dwCaps = 0 ;
//if (SurfaceDescrSize(lpdds)==sizeof(DDSURFACEDESC2)) ddsd.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) & 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 ;
2013-07-30 12:38:11 -04:00
}
2013-11-28 11:38:31 -05:00
else {
// since it can't scale, at least the updated rect is centered into the window.
( * pGetClientRect ) ( dxw . GethWnd ( ) , & client ) ;
( * pClientToScreen ) ( dxw . GethWnd ( ) , & upleft ) ;
if ( ! lprect ) lprect = & client ;
OffsetRect ( lprect ,
upleft . x + ( client . right - dxw . GetScreenWidth ( ) ) / 2 ,
upleft . y + ( client . bottom - dxw . GetScreenHeight ( ) ) / 2 ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Lock: NULL rect remapped to (%d,%d)-(%d,%d) \n " ,
2013-11-28 11:38:31 -05:00
lprect - > left , lprect - > top , lprect - > right , lprect - > bottom ) ;
2013-07-30 12:38:11 -04:00
}
}
2013-11-23 11:38:29 -05:00
}
2013-07-30 12:38:11 -04:00
2014-03-21 12:38:57 -04:00
res = ( * pLock ) ( lpdds , lprect , lpDDSurfaceDesc , flags , hEvent ) ;
2013-07-30 12:38:11 -04:00
if ( res ) OutTraceE ( " Lock ERROR: ret=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2014-03-21 12:38:57 -04:00
DumpSurfaceAttributes ( ( LPDDSURFACEDESC ) lpDDSurfaceDesc , " [Locked] " , __LINE__ ) ;
2013-07-30 12:38:11 -04:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = DD_OK ;
return res ;
}
2013-07-21 12:38:09 -04:00
HRESULT WINAPI extUnlock ( int dxversion , Unlock4_Type pUnlock , LPDIRECTDRAWSURFACE lpdds , LPRECT lprect )
{
HRESULT res ;
//RECT screen, rect;
BOOL IsPrim ;
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
if ( ( dxversion = = 4 ) & & lprect ) CleanRect ( & lprect , __LINE__ ) ;
2013-12-22 11:38:36 -05:00
if ( IsTraceDDRAW ) {
2014-06-07 12:39:29 -04:00
OutTrace ( " Unlock(%d): lpdds=%x%s " , dxversion , lpdds , ( IsPrim ? " (PRIM) " : " " ) ) ;
2013-07-21 12:38:09 -04:00
if ( dxversion = = 4 ) {
if ( lprect ) {
OutTrace ( " rect=(%d,%d)-(%d,%d) \n " , lprect - > left , lprect - > top , lprect - > right , lprect - > bottom ) ;
}
else
OutTrace ( " rect=(NULL) \n " ) ;
}
else
OutTrace ( " lpvoid=%x \n " , lprect ) ;
}
res = ( * pUnlock ) ( lpdds , lprect ) ;
2014-05-20 12:39:14 -04:00
if ( res = = DDERR_NOTLOCKED ) res = DD_OK ; // ignore not locked error
2013-07-21 12:38:09 -04:00
if ( res ) OutTraceE ( " Unlock ERROR res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
2014-05-11 12:39:56 -04:00
if ( IsPrim & & res = = DD_OK ) {
2014-11-15 11:39:58 -05:00
if ( dxversion = = 1 ) {
res = sBlt ( " Unlock " , lpdds , NULL , lpdds , NULL , NULL , 0 , FALSE ) ;
if ( IsPrim ) ( * pInvalidateRect ) ( dxw . GethWnd ( ) , NULL , FALSE ) ; // to fix "Deadlock II" mouse trails....
}
else {
res = sBlt ( " Unlock " , lpdds , lprect , lpdds , lprect , NULL , 0 , FALSE ) ;
if ( IsPrim ) ( * pInvalidateRect ) ( dxw . GethWnd ( ) , lprect , FALSE ) ;
2014-05-11 12:39:56 -04:00
}
}
2014-05-20 12:39:14 -04:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = DD_OK ;
2014-11-19 11:40:00 -05:00
if ( ( dxw . dwFlags5 & ( TEXTUREHIGHLIGHT | TEXTUREDUMP | TEXTUREHACK ) ) & & ( ! IsPrim ) ) TextureHandling ( lpdds ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
HRESULT WINAPI extUnlock4 ( LPDIRECTDRAWSURFACE lpdds , LPRECT lprect )
{
return extUnlock ( 4 , pUnlock4 , lpdds , lprect ) ;
}
HRESULT WINAPI extUnlock1 ( LPDIRECTDRAWSURFACE lpdds , LPVOID lpvoid )
{
return extUnlock ( 1 , ( Unlock4_Type ) pUnlock1 , lpdds , ( LPRECT ) lpvoid ) ;
}
2013-07-30 12:38:11 -04:00
HRESULT WINAPI extUnlockDir ( int dxversion , Unlock4_Type pUnlock , LPDIRECTDRAWSURFACE lpdds , LPRECT lprect )
{
HRESULT res ;
//RECT screen, rect;
BOOL IsPrim ;
LPDIRECTDRAWSURFACE lpDDSPrim ;
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-09-16 12:38:17 -04:00
if ( ( dxversion > = 4 ) & & lprect ) CleanRect ( & lprect , __LINE__ ) ;
2013-07-30 12:38:11 -04:00
2013-12-22 11:38:36 -05:00
if ( IsTraceDDRAW ) {
2013-07-30 12:38:11 -04:00
OutTrace ( " Unlock: lpdds=%x%s " , lpdds , ( IsPrim ? " (PRIM) " : " " ) ) ;
if ( dxversion = = 4 ) {
if ( lprect ) {
OutTrace ( " rect=(%d,%d)-(%d,%d) \n " , lprect - > left , lprect - > top , lprect - > right , lprect - > bottom ) ;
}
else
OutTrace ( " rect=(NULL) \n " ) ;
}
else
OutTrace ( " lpvoid=%x \n " , lprect ) ;
}
2013-09-16 12:38:17 -04:00
if ( dxw . dwFlags1 & LOCKEDSURFACE ) {
2014-05-20 12:39:14 -04:00
( * 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 ) ;
( * pReleaseS ) ( ( LPDIRECTDRAWSURFACE ) lpDDSBuffer ) ;
lpDDSBuffer = NULL ;
}
2013-09-16 12:38:17 -04:00
( * pReleaseS ) ( lpDDSPrim ) ; // to leave a correct refcount
2013-07-30 12:38:11 -04:00
}
2013-09-16 12:38:17 -04:00
res = ( * pUnlock ) ( lpdds , lprect ) ;
2014-05-20 12:39:14 -04:00
if ( res = = DDERR_NOTLOCKED ) res = DD_OK ; // ignore not locked error
2013-07-30 12:38:11 -04:00
if ( res ) OutTraceE ( " Unlock ERROR res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
if ( IsPrim & & res = = DD_OK ) sBlt ( " Unlock " , lpdds , NULL , lpdds , NULL , NULL , 0 , FALSE ) ;
2013-08-12 12:38:35 -04:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = DD_OK ;
2013-07-30 12:38:11 -04:00
return res ;
}
HRESULT WINAPI extUnlockDir4 ( LPDIRECTDRAWSURFACE lpdds , LPRECT lprect )
{
return extUnlockDir ( 4 , pUnlock4 , lpdds , lprect ) ;
}
HRESULT WINAPI extUnlockDir1 ( LPDIRECTDRAWSURFACE lpdds , LPVOID lpvoid )
{
return extUnlockDir ( 1 , ( Unlock4_Type ) pUnlock1 , lpdds , ( LPRECT ) lpvoid ) ;
}
2013-07-21 12:38:09 -04:00
/* 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 32 BPP and the surface is not ? ? ? */
HRESULT WINAPI extGetDC ( LPDIRECTDRAWSURFACE lpdds , HDC FAR * pHDC )
{
HRESULT res ;
BOOL IsPrim ;
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetDC: lpdss=%x%s \n " , lpdds , IsPrim ? " (PRIM) " : " " ) ;
2013-07-21 12:38:09 -04:00
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
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetDC: adding 8BPP palette to surface lpdds=%x \n " , lpdds ) ;
2013-07-21 12:38:09 -04:00
if ( lpDDP = = NULL ) {
// should link here to the GDI palette? See Hyperblade....
dxw . palNumEntries = 256 ;
2013-08-25 12:38:13 -04:00
res = ( * pCreatePalette ) ( lpPrimaryDD , DDPCAPS_ALLOW256 | DDPCAPS_8BIT | DDPCAPS_INITIALIZE , dxw . palPalEntry , & lpDDP , NULL ) ;
2013-07-21 12:38:09 -04:00
if ( res ) {
2013-10-08 12:38:12 -04:00
OutTraceE ( " GetDC: CreatePalette ERROR res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
}
res = ( * pSetPalette ) ( lpdds , lpDDP ) ;
if ( res ) {
2013-10-08 12:38:12 -04:00
OutTraceE ( " GetDC: SetPalette ERROR res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
// retry ....
res = ( * pGetDC ) ( lpdds , pHDC ) ;
}
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetDC: res=%x hdc=%x \n " , res , * pHDC ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
HRESULT WINAPI extReleaseDC ( LPDIRECTDRAWSURFACE lpdds , HDC FAR hdc )
{
HRESULT res ;
BOOL IsPrim ;
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " ReleaseDC: lpdss=%x%s hdc=%x \n " , lpdds , IsPrim ? " (PRIM) " : " " , hdc ) ;
2014-04-22 12:39:07 -04:00
res = ( * pReleaseDC ) ( lpdds , hdc ) ;
2013-07-21 12:38:09 -04:00
if ( ( IsPrim ) & & ( dxw . dwFlags1 & EMULATESURFACE ) ) sBlt ( " ReleaseDC " , lpdds , NULL , lpdds , NULL , 0 , NULL , FALSE ) ;
if ( res ) OutTraceE ( " ReleaseDC: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-12-22 11:38:36 -05:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = DD_OK ;
2013-07-21 12:38:09 -04:00
return res ;
}
HRESULT WINAPI extFlipToGDISurface ( LPDIRECTDRAW lpdd )
{
//HRESULT res;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " FlipToGDISurface: lpdd=%x \n " , lpdd ) ;
2013-07-21 12:38:09 -04:00
// 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....
return 0 ;
}
HRESULT WINAPI extGetGDISurface ( LPDIRECTDRAW lpdd , LPDIRECTDRAWSURFACE * w )
{
int res ;
2013-08-25 12:38:13 -04:00
// v2.02.31:
// in EMULATED mode, should not return the actual ddraw primary surface, but the virtual one.
if ( dxw . dwFlags1 & EMULATESURFACE ) {
* w = dxw . GetPrimarySurface ( ) ;
return DD_OK ;
}
2013-07-21 12:38:09 -04:00
res = ( * pGetGDISurface ) ( lpdd , w ) ;
if ( res ) {
OutTraceE ( " GetGDISurface: ERROR lpdd=%x res=%x(%s) \n " , lpdd , res , ExplainDDError ( res ) ) ;
}
else {
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetGDISurface: lpdd=%x w=%x \n " , lpdd , * w ) ;
2013-07-21 12:38:09 -04:00
}
return res ;
}
// debug function to dump all video modes queried by the DirectDrav::EnumDisplayModes method
HRESULT WINAPI EnumModesCallbackDumper ( LPDDSURFACEDESC lpDDSurfaceDesc , LPVOID lpContext )
{
OutTrace ( " EnumModesCallback: \n " ) ;
OutTrace ( " \t dwSize=%d \n " , lpDDSurfaceDesc - > dwSize ) ;
OutTrace ( " \t dwFlags=%x(%s) \n " , lpDDSurfaceDesc - > dwFlags , ExplainFlags ( lpDDSurfaceDesc - > dwFlags ) ) ;
OutTrace ( " \t dwHeight x dwWidth=(%d,%d) \n " , lpDDSurfaceDesc - > dwHeight , lpDDSurfaceDesc - > dwWidth ) ;
OutTrace ( " \t lPitch=%d \n " , lpDDSurfaceDesc - > lPitch ) ;
OutTrace ( " \t dwBackBufferCount=%d \n " , lpDDSurfaceDesc - > dwBackBufferCount ) ;
OutTrace ( " \t dwRefreshRate=%d \n " , lpDDSurfaceDesc - > dwRefreshRate ) ;
OutTrace ( " \t lpSurface=%x \n " , lpDDSurfaceDesc - > lpSurface ) ;
2013-11-10 11:38:26 -05:00
OutTrace ( " \t ddpfPixelFormat %s \n " , DumpPixelFormat ( ( LPDDSURFACEDESC2 ) lpDDSurfaceDesc ) ) ;
2014-09-20 12:39:46 -04:00
# ifdef FULLHEXDUMP
OutTrace ( " DDSurfaceDesc= " ) ;
OutTraceHex ( ( BYTE * ) lpDDSurfaceDesc , sizeof ( DDSURFACEDESC ) ) ;
# endif
2013-07-21 12:38:09 -04:00
return DDENUMRET_OK ;
}
typedef HRESULT ( WINAPI * EnumModesCallback_Type ) ( LPDDSURFACEDESC , LPVOID ) ;
2014-02-04 11:39:01 -05:00
typedef struct {
LPVOID lpContext ;
EnumModesCallback_Type lpCallback ;
DWORD dwWidth ;
DWORD dwHeight ;
} NewContext_Type ;
2014-04-04 12:39:03 -04:00
typedef struct {
2014-02-04 11:39:01 -05:00
int w ;
int h ;
2014-04-04 12:39:03 -04:00
} SupportedRes_Type ;
2014-08-13 12:39:40 -04:00
static SupportedRes_Type SupportedSVGARes [ 10 ] = {
2014-02-04 11:39:01 -05:00
{ 320 , 200 } ,
{ 320 , 240 } ,
2014-08-13 12:39:40 -04:00
{ 512 , 384 } , // needed by "Outcast" loading screen
2014-02-04 11:39:01 -05:00
{ 640 , 400 } ,
{ 640 , 480 } ,
2014-04-04 12:39:03 -04:00
{ 720 , 480 } ,
2014-02-04 11:39:01 -05:00
{ 800 , 600 } ,
2014-04-04 12:39:03 -04:00
{ 1024 , 768 } , // XGA
{ 1280 , 800 } , // WXGA
{ 0 , 0 }
} ;
static SupportedRes_Type SupportedHDTVRes [ 10 ] = {
{ 640 , 360 } , // nHD
{ 720 , 480 } , // DVD
{ 720 , 576 } , // DV-PAL
{ 960 , 540 } , // qHD
{ 1176 , 1000 } ,
{ 1280 , 720 } , // HD
{ 1440 , 960 } ,
{ 1600 , 900 } , // HD+
{ 1920 , 1080 } , // FHD
2014-02-04 11:39:01 -05:00
{ 0 , 0 }
} ;
2013-07-21 12:38:09 -04:00
2014-04-04 12:39:03 -04:00
static BOOL CheckResolutionLimit ( LPDDSURFACEDESC lpDDSurfaceDesc )
{
# define HUGE 100000
DWORD maxw , maxh ;
2014-04-13 12:39:06 -04:00
maxw = HUGE ; maxh = HUGE ;
2014-04-04 12:39:03 -04:00
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 ;
}
return FALSE ;
}
2014-02-04 11:39:01 -05:00
HRESULT WINAPI myEnumModesFilterDirect ( LPDDSURFACEDESC lpDDSurfaceDesc , LPVOID lpContext )
2013-07-21 12:38:09 -04:00
{
2014-02-04 11:39:01 -05:00
HRESULT res ;
2014-04-04 12:39:03 -04:00
SupportedRes_Type * SupportedRes ;
2014-02-04 11:39:01 -05:00
if ( ( ( ( NewContext_Type * ) lpContext ) - > dwHeight ! = lpDDSurfaceDesc - > dwHeight ) | |
( ( ( NewContext_Type * ) lpContext ) - > dwWidth ! = lpDDSurfaceDesc - > dwWidth ) ) return DDENUMRET_OK ;
2013-07-21 12:38:09 -04:00
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 ( ) ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " EnumDisplayModes: skipping screen size=(%d,%d) \n " , lpDDSurfaceDesc - > dwHeight , lpDDSurfaceDesc - > dwWidth ) ;
2013-07-21 12:38:09 -04:00
return DDENUMRET_OK ;
}
}
2014-02-04 11:39:01 -05:00
// tricky part: for each color depth related to current video resolution, fake each of the
// supported resolutions, unless is greater than maximum allowed
2013-07-21 12:38:09 -04:00
2014-04-04 12:39:03 -04:00
SupportedRes = ( dxw . dwFlags4 & SUPPORTHDTV ) ? & SupportedHDTVRes [ 0 ] : & SupportedSVGARes [ 0 ] ;
2014-02-04 11:39:01 -05:00
for ( int ResIdx = 0 ; SupportedRes [ ResIdx ] . h ; ResIdx + + ) {
lpDDSurfaceDesc - > dwHeight = SupportedRes [ ResIdx ] . h ;
lpDDSurfaceDesc - > dwWidth = SupportedRes [ ResIdx ] . w ;
2014-04-04 12:39:03 -04:00
if ( ( dxw . dwFlags4 & LIMITSCREENRES ) & & CheckResolutionLimit ( lpDDSurfaceDesc ) ) return DDENUMRET_OK ;
2014-02-04 11:39:01 -05:00
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 ;
2013-07-21 12:38:09 -04:00
}
2014-02-04 11:39:01 -05:00
return res ;
2013-07-21 12:38:09 -04:00
}
2014-04-04 12:39:03 -04:00
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 ( ( dxw . dwFlags4 & LIMITSCREENRES ) & & CheckResolutionLimit ( lpDDSurfaceDesc ) ) return DDENUMRET_OK ;
res = ( * ( ( NewContext_Type * ) lpContext ) - > lpCallback ) ( lpDDSurfaceDesc , ( ( NewContext_Type * ) lpContext ) - > lpContext ) ;
2014-04-13 12:39:06 -04:00
OutTraceDW ( " EnumDisplayModes(D): native size=(%d,%d) res=%x \n " , lpDDSurfaceDesc - > dwWidth , lpDDSurfaceDesc - > dwHeight , res ) ;
2014-04-04 12:39:03 -04:00
return res ;
}
2013-07-21 12:38:09 -04:00
HRESULT WINAPI extEnumDisplayModes ( EnumDisplayModes1_Type pEnumDisplayModes , LPDIRECTDRAW lpdd , DWORD dwflags , LPDDSURFACEDESC lpddsd , LPVOID lpContext , LPDDENUMMODESCALLBACK cb )
{
HRESULT res ;
2014-04-04 12:39:03 -04:00
SupportedRes_Type * SupportedRes ;
NewContext_Type NewContext ;
2014-09-20 12:39:46 -04:00
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " EnumDisplayModes(D): lpdd=%x flags=%x lpddsd=%x callback=%x \n " , lpdd , dwflags , lpddsd , cb ) ;
2013-07-21 12:38:09 -04:00
2014-09-20 12:39:46 -04:00
if ( dxw . dwFlags4 & NATIVERES ) {
2014-04-04 12:39:03 -04:00
NewContext . dwWidth = 0 ;
NewContext . dwHeight = 0 ;
NewContext . lpContext = lpContext ;
NewContext . lpCallback = cb ;
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 ;
}
2013-07-21 12:38:09 -04:00
// 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.
2014-02-04 11:39:01 -05:00
if ( ( dxw . dwFlags1 & EMULATESURFACE ) ) {
2013-07-21 12:38:09 -04:00
int SupportedDepths [ 5 ] = { 8 , 16 , 24 , 32 , 0 } ;
2014-02-04 11:39:01 -05:00
int ResIdx , DepthIdx ;
2013-07-21 12:38:09 -04:00
DDSURFACEDESC2 EmuDesc ;
2014-09-20 12:39:46 -04:00
DWORD dwSize ;
2013-07-21 12:38:09 -04:00
EmuDesc . dwRefreshRate = 0 ;
EmuDesc . ddpfPixelFormat . dwFlags = DDPF_RGB ;
2014-09-20 12:39:46 -04:00
if ( lpddsd ) dwSize = lpddsd - > dwSize ; // sizeof either DDSURFACEDESC or DDSURFACEDESC2 !!!
else dwSize = sizeof ( DDSURFACEDESC2 ) ;
if ( dwSize > sizeof ( DDSURFACEDESC2 ) ) dwSize = sizeof ( DDSURFACEDESC2 ) ;
memset ( & EmuDesc , 0 , dwSize ) ;
EmuDesc . dwSize = dwSize ;
2013-07-21 12:38:09 -04:00
EmuDesc . dwFlags = DDSD_PIXELFORMAT | DDSD_REFRESHRATE | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH ;
2014-04-04 12:39:03 -04:00
SupportedRes = ( dxw . dwFlags4 & SUPPORTHDTV ) ? & SupportedHDTVRes [ 0 ] : & SupportedSVGARes [ 0 ] ;
2014-02-04 11:39:01 -05:00
for ( ResIdx = 0 ; SupportedRes [ ResIdx ] . h ; ResIdx + + ) {
2013-07-21 12:38:09 -04:00
EmuDesc . dwHeight = SupportedRes [ ResIdx ] . h ;
EmuDesc . dwWidth = SupportedRes [ ResIdx ] . w ;
EmuDesc . ddpfPixelFormat . dwSize = sizeof ( DDPIXELFORMAT ) ;
EmuDesc . ddpfPixelFormat . dwFlags = DDPF_RGB ;
2014-02-04 11:39:01 -05:00
for ( DepthIdx = 0 ; SupportedDepths [ DepthIdx ] ; DepthIdx + + ) {
EmuDesc . ddpfPixelFormat . dwRGBBitCount = SupportedDepths [ DepthIdx ] ;
2014-06-22 12:39:24 -04:00
EmuDesc . lPitch = SupportedRes [ ResIdx ] . w * SupportedDepths [ DepthIdx ] / 8 ;
2014-02-04 11:39:01 -05:00
FixPixelFormat ( EmuDesc . ddpfPixelFormat . dwRGBBitCount , & ( EmuDesc . ddpfPixelFormat ) ) ;
2014-09-20 12:39:46 -04:00
EnumModesCallbackDumper ( ( LPDDSURFACEDESC ) & EmuDesc , lpContext ) ;
2013-07-21 12:38:09 -04:00
res = ( * cb ) ( ( LPDDSURFACEDESC ) & EmuDesc , lpContext ) ;
if ( res = = DDENUMRET_CANCEL ) break ;
}
if ( res = = DDENUMRET_CANCEL ) break ;
}
2014-02-04 11:39:01 -05:00
res = DD_OK ;
}
else {
DDSURFACEDESC2 EmuDesc ;
memset ( & EmuDesc , 0 , sizeof ( EmuDesc ) ) ;
EmuDesc . dwSize = sizeof ( DDSURFACEDESC ) ; // using release 1 type ....
res = ( * pGetDisplayMode ) ( lpdd , ( LPDDSURFACEDESC ) & EmuDesc ) ;
2014-07-28 12:39:37 -04:00
if ( res = = DDERR_GENERIC ) { // Win8 missing support for old ddraw interface
EmuDesc . dwSize = sizeof ( DDSURFACEDESC2 ) ; // using release 2 type ....
res = ( * pGetDisplayMode ) ( lpdd , ( LPDDSURFACEDESC ) & EmuDesc ) ;
}
2014-02-04 11:39:01 -05:00
if ( res ) {
OutTraceE ( " GetDisplayMode(D): ERROR res=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
return res ;
}
2013-07-21 12:38:09 -04:00
NewContext_Type NewContext ;
2014-02-04 11:39:01 -05:00
NewContext . dwWidth = EmuDesc . dwWidth ;
NewContext . dwHeight = EmuDesc . dwHeight ;
2013-07-21 12:38:09 -04:00
NewContext . lpContext = lpContext ;
NewContext . lpCallback = cb ;
2014-02-04 11:39:01 -05:00
res = ( * pEnumDisplayModes ) ( lpdd , dwflags , lpddsd , & NewContext , myEnumModesFilterDirect ) ;
2013-07-21 12:38:09 -04:00
}
2013-12-22 11:38:36 -05:00
if ( res ) OutTraceE ( " EnumDisplayModes(D): ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
HRESULT WINAPI extEnumDisplayModes1 ( LPDIRECTDRAW lpdd , DWORD dwflags , LPDDSURFACEDESC lpddsd , LPVOID lpContext , LPDDENUMMODESCALLBACK cb )
{
return extEnumDisplayModes ( pEnumDisplayModes1 , lpdd , dwflags , lpddsd , lpContext , cb ) ;
}
HRESULT WINAPI extEnumDisplayModes4 ( LPDIRECTDRAW lpdd , DWORD dwflags , LPDDSURFACEDESC2 lpddsd , LPVOID lpContext , LPDDENUMMODESCALLBACK2 cb )
{
return extEnumDisplayModes ( ( EnumDisplayModes1_Type ) pEnumDisplayModes4 , lpdd , dwflags , ( LPDDSURFACEDESC ) lpddsd , lpContext , ( LPDDENUMMODESCALLBACK ) cb ) ;
}
HRESULT WINAPI extDuplicateSurface ( LPDIRECTDRAW lpdd , LPDIRECTDRAWSURFACE s , LPDIRECTDRAWSURFACE * sp )
{
int res ;
res = ( * pDuplicateSurface ) ( lpdd , s , sp ) ;
if ( res )
OutTraceE ( " DuplicateSurface: ERROR dds=%x res=%x(%s) \n " , s , res , ExplainDDError ( res ) ) ;
else
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " DuplicateSurface: dds=%x pdds=%x \n " , s , * sp ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
HRESULT WINAPI extGetPixelFormat ( LPDIRECTDRAWSURFACE lpdds , LPDDPIXELFORMAT p )
{
DWORD res ;
BOOL IsPrim ;
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetPixelFormat: lpdds=%x%s \n " , lpdds , IsPrim ? " (PRIM) " : " " ) ;
2013-07-21 12:38:09 -04:00
res = ( * pGetPixelFormat ) ( lpdds , p ) ;
if ( res ) {
OutTraceE ( " GetPixelFormat: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
}
else {
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetPixelFormat: Flags=%x(%s) FourCC=%x BitCount=%d RGBA=(%x,%x,%x,%x) \n " ,
2013-07-21 12:38:09 -04:00
p - > dwFlags , ExplainPixelFormatFlags ( p - > dwFlags ) , p - > dwFourCC , p - > dwRGBBitCount ,
p - > dwRBitMask , p - > dwGBitMask , p - > dwBBitMask , p - > dwRGBAlphaBitMask ) ;
}
if ( ( dxw . dwFlags1 & EMULATESURFACE ) & & IsPrim ) {
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 ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetPixelFormat: EMULATED BitCount=%d RGBA=(%x,%x,%x,%x) \n " ,
2013-07-21 12:38:09 -04:00
p - > dwRGBBitCount , p - > dwRBitMask , p - > dwGBitMask , p - > dwBBitMask , p - > dwRGBAlphaBitMask ) ;
}
return res ;
}
HRESULT WINAPI extTestCooperativeLevel ( LPDIRECTDRAW lpdd )
{
HRESULT res ;
res = ( * pTestCooperativeLevel ) ( lpdd ) ;
2013-11-23 11:38:29 -05:00
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 ) ) ;
}
2013-12-22 11:38:36 -05:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = DD_OK ;
2013-11-23 11:38:29 -05:00
return res ;
2013-07-21 12:38:09 -04:00
}
HRESULT WINAPI extReleaseS ( LPDIRECTDRAWSURFACE lpdds )
{
HRESULT res ;
BOOL IsPrim ;
2013-11-10 11:38:21 -05:00
BOOL IsBack ;
2013-07-21 12:38:09 -04:00
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-11-10 11:38:21 -05:00
IsBack = dxw . IsABackBufferSurface ( lpdds ) ;
2014-06-07 12:39:29 -04:00
if ( IsBack & & bDontReleaseBackBuffer ) {
OutTraceDDRAW ( " Release(S): SKIP RELEASE on lpdds=%x \n " , lpdds ) ;
res = 0 ;
}
else
res = ( * pReleaseS ) ( lpdds ) ;
2013-07-21 12:38:09 -04:00
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " Release(S): lpdds=%x%s refcount=%d \n " , lpdds , IsPrim ? " (PRIM) " : ( IsBack ? " (BACK) " : " " ) , res ) ;
2013-07-21 12:38:09 -04:00
if ( res = = 0 ) { // common precondition
// when releasing primary surface, erase clipping region
if ( IsPrim & & ( dxw . dwFlags1 & CLIPCURSOR ) ) dxw . EraseClipCursor ( ) ;
if ( dxw . dwFlags1 & EMULATESURFACE ) {
if ( lpdds = = lpDDSEmu_Prim ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Release(S): Clearing lpDDSEmu_Prim pointer \n " ) ;
2013-07-21 12:38:09 -04:00
lpDDSEmu_Prim = NULL ;
}
if ( lpdds = = lpDDSEmu_Back ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Release(S): Clearing lpDDSEmu_Back pointer \n " ) ;
2013-07-21 12:38:09 -04:00
lpDDSEmu_Back = NULL ;
}
if ( lpdds = = dxw . lpDDSPrimHDC ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Release(S): Clearing lpDDSPrimHDC pointer \n " ) ;
2013-07-21 12:38:09 -04:00
dxw . ResetPrimarySurface ( ) ;
}
}
2013-10-21 12:38:23 -04:00
if ( lpdds = = lpDDSBack ) { // v2.02.38
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Release(S): Clearing lpDDSBack pointer \n " ) ;
2013-10-21 12:38:23 -04:00
lpDDSBack = NULL ;
}
2013-07-21 12:38:09 -04:00
}
2014-03-21 12:38:57 -04:00
if ( dxw . dwFlags4 & RETURNNULLREF ) return 0 ;
2013-07-21 12:38:09 -04:00
return res ;
}
HRESULT WINAPI extSetColorKey ( LPDIRECTDRAWSURFACE lpdds , DWORD flags , LPDDCOLORKEY lpDDColorKey )
{
HRESULT res ;
BOOL IsPrim ;
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
if ( IsTraceDDRAW ) {
2013-07-21 12:38:09 -04:00
OutTrace ( " SetColorKey: lpdds=%x%s flags=%x(%s) " ,
lpdds , ( IsPrim ? " (PRIM) " : " " ) , flags , ExplainColorKeyFlag ( flags ) ) ;
if ( lpDDColorKey )
OutTrace ( " colors=(L:%x,H:%x) \n " , lpDDColorKey - > dwColorSpaceLowValue , lpDDColorKey - > dwColorSpaceHighValue ) ;
else
OutTrace ( " colors=(NULL) \n " ) ;
}
res = ( * pSetColorKey ) ( lpdds , flags , lpDDColorKey ) ;
if ( res ) OutTraceE ( " SetColorKey: ERROR flags=%x lpdds=%x res=%x(%s) \n " ,
flags , lpdds , res , ExplainDDError ( res ) ) ;
return res ;
}
HRESULT WINAPI extGetColorKey ( LPDIRECTDRAWSURFACE lpdds , DWORD flags , LPDDCOLORKEY lpDDColorKey )
{
HRESULT res ;
BOOL IsPrim ;
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetColorKey(S): lpdds=%x%s flags=%x(%s) \n " ,
2013-07-21 12:38:09 -04:00
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
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetColorKey: colors=(L:%x,H:%x) \n " ,
2014-09-02 12:38:49 -04:00
lpDDColorKey - > dwColorSpaceLowValue , lpDDColorKey - > dwColorSpaceHighValue ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
HRESULT WINAPI extEnumAttachedSurfaces ( LPDIRECTDRAWSURFACE lpdds , LPVOID lpContext , LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback )
{
HRESULT res ;
BOOL IsPrim ;
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " EnumAttachedSurfaces: lpdds=%x%s Context=%x Callback=%x \n " ,
2013-07-21 12:38:09 -04:00
lpdds , ( IsPrim ? " (PRIM) " : " " ) , lpContext , lpEnumSurfacesCallback ) ;
if ( IsPrim ) {
// 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 ) {
ddsd . dwSize = Set_dwSize_From_Surface ( lpDDSBack ) ;
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 ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " EnumSurfacesCallback: on DDSBack res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-07-21 12:38:09 -04:00
}
res = 0 ; // for Black Dahlia
}
else {
res = ( * pEnumAttachedSurfaces ) ( lpdds , lpContext , lpEnumSurfacesCallback ) ;
if ( res )
OutTraceE ( " EnumAttachedSurfaces: ERROR %x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
}
return res ;
}
HRESULT WINAPI extAddAttachedSurface ( LPDIRECTDRAWSURFACE lpdds , LPDIRECTDRAWSURFACE lpddsadd )
{
HRESULT res ;
BOOL IsPrim ;
// 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!
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " AddAttachedSurface: lpdds=%x%s lpddsadd=%x \n " , lpdds , IsPrim ? " (PRIM) " : " " , lpddsadd ) ;
2013-08-25 12:38:13 -04:00
//if(!lpddsadd) return DDERR_CANNOTATTACHSURFACE; // to avoid a crash...
2013-07-21 12:38:09 -04:00
res = ( * pAddAttachedSurface ) ( lpdds , lpddsadd ) ;
if ( res ) {
HRESULT sdres ;
DDSURFACEDESC2 sd ;
sd . dwSize = Set_dwSize_From_Surface ( lpddsadd ) ;
sdres = lpddsadd - > GetSurfaceDesc ( ( DDSURFACEDESC * ) & sd ) ;
if ( sdres )
OutTraceE ( " AddAttachedSurface: GetSurfaceDesc ERROR res=%x at %d \n " , sdres , __LINE__ ) ;
else
2013-12-22 11:38:36 -05:00
OutTraceDW ( " AddAttachedSurface: GetSurfaceDesc dwCaps=%x(%s) \n " ,
2013-07-21 12:38:09 -04:00
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 ) )
2013-12-22 11:38:36 -05:00
OutTraceDW ( " AddAttachedSurface: emulating BACKBUFFER attach on PRIMARY \n " ) ;
2013-07-21 12:38:09 -04:00
lpDDSBack = lpddsadd ;
if ( pAddRefS ) ( * pAddRefS ) ( lpdds ) ;
res = DD_OK ;
}
else if ( lpdds = = lpDDSBack ) {
// v2.02.13: emulate ZBUFFER attach to backbuffer: 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 ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " AddAttachedSurface: emulating ZBUFFER attach on BACKBUFFER \n " ) ;
2013-07-21 12:38:09 -04:00
if ( pAddRefS ) ( * pAddRefS ) ( lpdds ) ;
res = DD_OK ;
}
}
}
if ( res ) OutTraceE ( " AddAttachedSurface: ERROR %x(%s) \n " , res , ExplainDDError ( res ) ) ;
return res ;
}
HRESULT WINAPI extDeleteAttachedSurface ( LPDIRECTDRAWSURFACE lpdds , DWORD dwflags , LPDIRECTDRAWSURFACE lpddsdel )
{
HRESULT res ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " DeleteAttachedSurface: lpdds=%x flags=%x lpddsdel=%x \n " , lpdds , dwflags , lpddsdel ) ;
2013-07-21 12:38:09 -04:00
res = ( * pDeleteAttachedSurface ) ( lpdds , dwflags , lpddsdel ) ;
if ( res ) OutTraceE ( " DeleteAttachedSurface: ERROR %x(%s) \n " , res , ExplainDDError ( res ) ) ;
if ( res & & ( lpddsdel = = lpDDSBack ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " DeleteAttachedSurface: emulating surface detach lpdds=%x \n " , lpddsdel ) ;
2013-07-21 12:38:09 -04:00
lpDDSBack - > Release ( ) ; // GHO TRY
lpDDSBack = NULL ;
res = 0 ;
}
return res ;
}
HRESULT WINAPI cbDump ( LPDDSURFACEDESC lpDDSurfaceDesc , LPVOID lpContext )
{
2013-12-22 11:38:36 -05:00
OutTraceDW ( " EnumDisplayModes: CALLBACK lpdds=%x Context=%x Caps=%x(%s) \n " ,
2013-07-21 12:38:09 -04:00
lpDDSurfaceDesc , lpContext ,
lpDDSurfaceDesc - > ddsCaps . dwCaps , ExplainDDSCaps ( lpDDSurfaceDesc - > ddsCaps . dwCaps ) ) ;
return 1 ;
}
HRESULT WINAPI extGetCapsS ( int dxInterface , GetCapsS_Type pGetCapsS , LPDIRECTDRAWSURFACE lpdds , LPDDSCAPS caps )
{
HRESULT res ;
2013-11-10 11:38:21 -05:00
BOOL IsPrim , IsBack , IsFixed ;
2013-07-21 12:38:09 -04:00
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-11-10 11:38:21 -05:00
IsBack = dxw . IsABackBufferSurface ( lpdds ) ;
IsFixed = FALSE ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetCaps(S%d): lpdds=%x%s, lpcaps=%x \n " , dxInterface , lpdds , IsPrim ? " (PRIM) " : " " , caps ) ;
2013-07-21 12:38:09 -04:00
res = ( * pGetCapsS ) ( lpdds , caps ) ;
if ( res )
OutTraceE ( " GetCaps(S%d): ERROR %x(%s) \n " , dxInterface , res , ExplainDDError ( res ) ) ;
else
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetCaps(S%d): lpdds=%x caps=%x(%s) \n " , dxInterface , lpdds , caps - > dwCaps , ExplainDDSCaps ( caps - > dwCaps ) ) ;
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:21 -05:00
if ( IsPrim ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetCaps(S%d): fixing PRIMARY surface \n " , dxInterface ) ;
2013-11-10 11:38:21 -05:00
IsFixed = TRUE ;
caps - > dwCaps | = DDSD_Prim . ddsCaps . dwCaps ;
caps - > dwCaps | = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE ; // primary surfaces must be this way
caps - > dwCaps & = ~ ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ; // primary surfaces can't be this way
}
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:21 -05:00
if ( IsBack ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetCaps(S%d): fixing BACKBUFFER surface \n " , dxInterface ) ;
2013-11-10 11:38:21 -05:00
IsFixed = TRUE ;
caps - > dwCaps | = ( DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM ) ; // you never know....
caps - > dwCaps & = ~ ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ; // backbuffer surfaces can't be this way
}
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:21 -05:00
if ( ( caps - > dwCaps & DDSCAPS_ZBUFFER ) | | ( lpdds = = lpDDZBuffer ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetCaps(S%d): fixing ZBUFFER surface \n " , dxInterface ) ;
2013-11-10 11:38:21 -05:00
IsFixed = TRUE ;
2013-10-21 12:38:23 -04:00
if ( DDZBufferCaps & DDSCAPS_SYSTEMMEMORY ) {
caps - > dwCaps | = ( DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY ) ;
caps - > dwCaps & = ~ ( DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM ) ;
}
else {
caps - > dwCaps | = ( DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM ) ;
caps - > dwCaps & = ~ DDSCAPS_SYSTEMMEMORY ;
}
2013-07-21 12:38:09 -04:00
}
2013-12-22 11:38:36 -05:00
if ( IsFixed ) OutTraceDW ( " GetCaps(S%d): lpdds=%x FIXED caps=%x(%s) \n " , dxInterface , lpdds , caps - > dwCaps , ExplainDDSCaps ( caps - > dwCaps ) ) ;
2013-07-21 12:38:09 -04:00
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 ) ;
}
ULONG WINAPI extReleaseD ( LPDIRECTDRAW lpdd )
{
2013-11-16 11:38:27 -05:00
ULONG ActualRef ;
LONG VirtualRef ;
2013-07-21 12:38:09 -04:00
int dxversion ;
dxversion = lpddHookedVersion ( lpdd ) ; // must be called BEFORE releasing the session!!
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " Release(D): lpdd=%x dxversion=%d \n " , lpdd , dxversion ) ;
2013-07-21 12:38:09 -04:00
2013-11-16 11:38:27 -05:00
ActualRef = ( * pReleaseD ) ( lpdd ) ;
VirtualRef = ( LONG ) ActualRef ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Release(D): lpdd=%x service_lpdd=%x ref=%d \n " , lpdd , lpPrimaryDD , ActualRef ) ;
2013-07-21 12:38:09 -04:00
2013-08-25 12:38:13 -04:00
if ( lpdd = = lpPrimaryDD ) { // v2.1.87: fix for Dungeon Keeper II
2013-11-17 11:38:28 -05:00
if ( dxw . dwFlags4 & FIXREFCOUNTER ) {
2013-11-16 11:38:27 -05:00
// v2.02.41: fix the ref counter to sumulate the unwindowed original situation
- - VirtualRef ; // why ????
if ( lpDDSBack ) - - VirtualRef ;
if ( dxw . dwFlags1 & EMULATESURFACE ) {
if ( lpDDSEmu_Prim ) - - VirtualRef ;
if ( lpDDSEmu_Back ) - - VirtualRef ;
}
if ( VirtualRef < 0 ) VirtualRef = 0 ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Release(D): fixed ref counter %d->%d \n " , ActualRef , VirtualRef ) ;
2013-11-16 11:38:27 -05:00
}
if ( ( dxversion < 4 ) & & ( ActualRef = = 0 ) ) {
2013-07-21 12:38:09 -04:00
// directdraw old versions automatically free all linked objects when the parent session is closed.
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Release(D): RefCount=0 - service object RESET condition \n " ) ;
2013-07-21 12:38:09 -04:00
lpDDSEmu_Prim = NULL ;
lpDDSEmu_Back = NULL ;
lpDDP = NULL ;
2013-08-25 12:38:13 -04:00
lpPrimaryDD = NULL ; // v2.02.31
if ( lpBackBufferDD = = lpdd ) {
lpBackBufferDD = NULL ;
lpDDSBack = NULL ; // beware: Silent Hunter II seems to require the backbuffer ....
}
2013-07-21 12:38:09 -04:00
}
}
2013-11-23 11:38:29 -05:00
// 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();
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " Release(D): lpdd=%x ref=%x \n " , lpdd , VirtualRef ) ;
2014-03-21 12:38:57 -04:00
if ( dxw . dwFlags4 & RETURNNULLREF ) return 0 ;
2013-11-16 11:38:27 -05:00
return ( ULONG ) VirtualRef ;
2013-07-21 12:38:09 -04:00
}
HRESULT WINAPI extCreateClipper ( LPDIRECTDRAW lpdd , DWORD dwflags ,
LPDIRECTDRAWCLIPPER FAR * lplpDDClipper , IUnknown FAR * pUnkOuter )
{
HRESULT res ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " CreateClipper: lpdd=%x flags=%x \n " , lpdd , dwflags ) ;
2013-07-21 12:38:09 -04:00
res = ( * pCreateClipper ) ( lpdd , dwflags , lplpDDClipper , pUnkOuter ) ;
if ( res ) {
OutTraceE ( " CreateClipper: ERROR res=%x(%s) \n " , lpdd , res , ExplainDDError ( res ) ) ;
return res ;
}
HookDDClipper ( lplpDDClipper ) ;
return res ;
}
HRESULT WINAPI extReleaseC ( LPDIRECTDRAWCLIPPER lpddClip )
{
ULONG ref ;
2013-11-10 11:38:21 -05:00
ref = ( * pReleaseC ) ( lpddClip ) ;
2013-07-21 12:38:09 -04:00
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " Release(C): PROXED lpddClip=%x ref=%x \n " , lpddClip , ref ) ;
2013-07-21 12:38:09 -04:00
return ref ;
}
HRESULT WINAPI extGetSurfaceDesc ( GetSurfaceDesc_Type pGetSurfaceDesc , LPDIRECTDRAWSURFACE lpdds , LPDDSURFACEDESC lpddsd )
{
HRESULT res ;
2013-11-10 11:38:21 -05:00
BOOL IsPrim , IsBack , IsFixed ;
2013-07-21 12:38:09 -04:00
IsPrim = dxw . IsAPrimarySurface ( lpdds ) ;
2013-11-10 11:38:21 -05:00
IsBack = dxw . IsABackBufferSurface ( lpdds ) ;
2013-07-21 12:38:09 -04:00
IsFixed = FALSE ;
if ( ! pGetSurfaceDesc ) {
OutTraceE ( " GetSurfaceDesc: ERROR no hooked function \n " ) ;
return DDERR_INVALIDPARAMS ;
}
res = ( * pGetSurfaceDesc ) ( lpdds , lpddsd ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetSurfaceDesc: %slpdds=%x%s res=%x(%s) \n " ,
2013-11-10 11:38:21 -05:00
res ? " ERROR " : " " , lpdds , IsPrim ? " (PRIM) " : ( IsBack ? " (BACK) " : " " ) , res , ExplainDDError ( res ) ) ;
2013-07-21 12:38:09 -04:00
if ( res ) {
OutTraceE ( " GetSurfaceDesc: ERROR err=%d(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
return res ;
}
LogSurfaceAttributes ( lpddsd , " GetSurfaceDesc " , __LINE__ ) ;
if ( IsPrim ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetSurfaceDesc: fixing PRIMARY surface \n " ) ;
2013-07-21 12:38:09 -04:00
IsFixed = TRUE ;
2013-11-10 11:38:21 -05:00
if ( dxw . dwFlags1 & EMULATESURFACE ) lpddsd - > ddpfPixelFormat = dxw . VirtualPixelFormat ;
lpddsd - > ddsCaps . dwCaps | = DDSD_Prim . ddsCaps . dwCaps ;
lpddsd - > ddsCaps . dwCaps | = ( DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE ) ; // primary surfaces must be this way
lpddsd - > ddsCaps . dwCaps & = ~ ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ; // primary surfaces can't be this way
lpddsd - > dwBackBufferCount = DDSD_Prim . dwBackBufferCount ;
2013-07-21 12:38:09 -04:00
lpddsd - > dwHeight = dxw . GetScreenHeight ( ) ;
lpddsd - > dwWidth = dxw . GetScreenWidth ( ) ;
}
2013-11-10 11:38:21 -05:00
if ( IsBack ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetSurfaceDesc: fixing BACKBUFFER surface \n " ) ;
2013-07-21 12:38:09 -04:00
IsFixed = TRUE ;
2013-11-10 11:38:21 -05:00
lpddsd - > ddsCaps . dwCaps | = ( DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM ) ; // you never know....
lpddsd - > ddsCaps . dwCaps & = ~ ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ; // primary surfaces can't be this way
2013-07-21 12:38:09 -04:00
}
2013-11-10 11:38:21 -05:00
if ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_ZBUFFER ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetSurfaceDesc: fixing ZBUFFER surface \n " ) ;
2013-11-10 11:38:21 -05:00
IsFixed = TRUE ;
2013-10-21 12:38:23 -04:00
if ( DDZBufferCaps & DDSCAPS_SYSTEMMEMORY ) {
lpddsd - > ddsCaps . dwCaps | = ( DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY ) ;
lpddsd - > ddsCaps . dwCaps & = ~ ( DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM ) ;
}
else {
lpddsd - > ddsCaps . dwCaps | = ( DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM ) ;
lpddsd - > ddsCaps . dwCaps & = ~ DDSCAPS_SYSTEMMEMORY ;
}
2013-07-21 12:38:09 -04:00
}
2013-10-21 12:38:23 -04:00
2013-11-10 11:38:21 -05:00
if ( IsFixed ) LogSurfaceAttributes ( lpddsd , " GetSurfaceDesc [FIXED] " , __LINE__ ) ;
2013-10-21 12:38:23 -04:00
2013-07-21 12:38:09 -04:00
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 )
{
if ( ! lpddsd - > dwSize ) lpddsd - > dwSize = sizeof ( DDSURFACEDESC ) ; // enforce correct dwSize value
switch ( lpddsd - > dwSize ) {
case sizeof ( DDSURFACEDESC ) :
if ( pGetSurfaceDesc1 ) return extGetSurfaceDesc ( pGetSurfaceDesc1 , lpdds , lpddsd ) ;
2014-12-10 11:39:52 -05:00
//else return lpdds->GetSurfaceDesc((LPDDSURFACEDESC)lpddsd);
if ( pGetSurfaceDesc4 ) return extGetSurfaceDesc ( ( GetSurfaceDesc_Type ) pGetSurfaceDesc4 , ( LPDIRECTDRAWSURFACE ) lpdds , ( LPDDSURFACEDESC ) lpddsd ) ;
2013-07-21 12:38:09 -04:00
break ;
case sizeof ( DDSURFACEDESC2 ) :
if ( pGetSurfaceDesc4 ) return extGetSurfaceDesc ( ( GetSurfaceDesc_Type ) pGetSurfaceDesc4 , ( LPDIRECTDRAWSURFACE ) lpdds , ( LPDDSURFACEDESC ) lpddsd ) ;
2014-12-10 11:39:52 -05:00
//else return lpdds->GetSurfaceDesc((LPDDSURFACEDESC)lpddsd);
2013-07-21 12:38:09 -04:00
break ;
default :
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetSurfaceDesc: ASSERT - bad dwSize=%d lpdds=%x at %d \n " , lpddsd - > dwSize , lpdds , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
return DDERR_INVALIDOBJECT ;
break ;
}
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetSurfaceDesc: ASSERT - missing hook lpdds=%x dwSize=%d(%s) at %d \n " ,
2013-07-21 12:38:09 -04:00
lpdds , lpddsd - > dwSize , lpddsd - > dwSize = = sizeof ( DDSURFACEDESC ) ? " DDSURFACEDESC " : " DDSURFACEDESC2 " , __LINE__ ) ;
return DDERR_INVALIDOBJECT ;
}
HRESULT WINAPI extGetSurfaceDesc2 ( LPDIRECTDRAWSURFACE2 lpdds , LPDDSURFACEDESC2 lpddsd )
{
if ( ! lpddsd - > dwSize ) lpddsd - > dwSize = sizeof ( DDSURFACEDESC2 ) ; // enforce correct dwSize value
switch ( lpddsd - > dwSize ) {
case sizeof ( DDSURFACEDESC ) :
if ( pGetSurfaceDesc1 ) return extGetSurfaceDesc ( pGetSurfaceDesc1 , ( LPDIRECTDRAWSURFACE ) lpdds , ( LPDDSURFACEDESC ) lpddsd ) ;
2014-12-10 11:39:52 -05:00
//else return lpdds->GetSurfaceDesc((LPDDSURFACEDESC)lpddsd);
2013-07-21 12:38:09 -04:00
break ;
case sizeof ( DDSURFACEDESC2 ) :
if ( pGetSurfaceDesc4 ) return extGetSurfaceDesc ( ( GetSurfaceDesc_Type ) pGetSurfaceDesc4 , ( LPDIRECTDRAWSURFACE ) lpdds , ( LPDDSURFACEDESC ) lpddsd ) ;
2014-12-10 11:39:52 -05:00
//else return lpdds->GetSurfaceDesc((LPDDSURFACEDESC)lpddsd);
2013-07-21 12:38:09 -04:00
break ;
default :
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetSurfaceDesc: ASSERT - bad dwSize=%d lpdds=%x at %d \n " , lpddsd - > dwSize , lpdds , __LINE__ ) ;
2013-07-21 12:38:09 -04:00
return DDERR_INVALIDOBJECT ;
}
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetSurfaceDesc: ASSERT - missing hook lpdds=%x dwSize=%d(%s) at %d \n " ,
2013-07-21 12:38:09 -04:00
lpdds , lpddsd - > dwSize , lpddsd - > dwSize = = sizeof ( DDSURFACEDESC ) ? " DDSURFACEDESC " : " DDSURFACEDESC2 " , __LINE__ ) ;
return DDERR_INVALIDOBJECT ;
}
2014-02-02 11:38:46 -05:00
HRESULT WINAPI extGetSurfaceDesc7 ( LPDIRECTDRAWSURFACE2 lpdds , LPDDSURFACEDESC2 lpddsd )
{
if ( ! lpddsd - > dwSize ) lpddsd - > dwSize = sizeof ( DDSURFACEDESC2 ) ; // enforce correct dwSize value
switch ( lpddsd - > dwSize ) {
case sizeof ( DDSURFACEDESC ) :
if ( pGetSurfaceDesc1 ) return extGetSurfaceDesc ( pGetSurfaceDesc1 , ( LPDIRECTDRAWSURFACE ) lpdds , ( LPDDSURFACEDESC ) lpddsd ) ;
break ;
case sizeof ( DDSURFACEDESC2 ) :
if ( pGetSurfaceDesc7 ) return extGetSurfaceDesc ( ( GetSurfaceDesc_Type ) pGetSurfaceDesc7 , ( LPDIRECTDRAWSURFACE ) lpdds , ( LPDDSURFACEDESC ) lpddsd ) ;
break ;
default :
OutTraceDW ( " GetSurfaceDesc: ASSERT - bad dwSize=%d lpdds=%x at %d \n " , lpddsd - > dwSize , lpdds , __LINE__ ) ;
return DDERR_INVALIDOBJECT ;
}
OutTraceDW ( " GetSurfaceDesc: ASSERT - missing hook lpdds=%x dwSize=%d(%s) at %d \n " ,
lpdds , lpddsd - > dwSize , lpddsd - > dwSize = = sizeof ( DDSURFACEDESC ) ? " DDSURFACEDESC " : " DDSURFACEDESC2 " , __LINE__ ) ;
return DDERR_INVALIDOBJECT ;
}
2013-07-21 12:38:09 -04:00
HRESULT WINAPI extReleaseP ( LPDIRECTDRAWPALETTE lpddPalette )
{
ULONG ref ;
2013-11-10 11:38:21 -05:00
ref = ( * pReleaseP ) ( lpddPalette ) ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " Release(P): lpddPalette=%x ref=%x \n " , lpddPalette , ref ) ;
2013-07-21 12:38:09 -04:00
if ( lpddPalette = = lpDDP & & ref = = 0 ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " Release(P): clearing lpDDP=%x->NULL \n " , lpDDP ) ;
2013-07-21 12:38:09 -04:00
lpDDP = NULL ;
}
return ref ;
}
BOOL WINAPI DDEnumerateCallbackFilter ( GUID * lpGuid , LPSTR lpDriverDescription , LPSTR lpDriverName , LPVOID lpContext )
{
BOOL res ;
typedef struct { LPDDENUMCALLBACK lpCallback ; LPVOID lpContext ; } Context_Type ;
Context_Type * p = ( Context_Type * ) lpContext ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " DDEnumerateCallback: guid=%x DriverDescription= \" %s \" DriverName= \" %s \" Context=%x \n " ,
2013-07-21 12:38:09 -04:00
lpGuid , lpDriverDescription , lpDriverName , p - > lpContext ) ;
if ( ( lpGuid = = NULL ) | | ! ( dxw . dwFlags2 & HIDEMULTIMONITOR ) ) res = ( * p - > lpCallback ) ( lpGuid , lpDriverDescription , lpDriverName , p - > lpContext ) ;
if ( ( lpGuid = = NULL ) & & ( dxw . dwFlags2 & HIDEMULTIMONITOR ) ) res = FALSE ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " DDEnumerateCallback: res=%x(%s) \n " , res , res ? " continue " : " break " ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
BOOL WINAPI DDEnumerateCallbackExFilter ( GUID * 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 ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " DDEnumerateCallbackEx: guid=%x DriverDescription= \" %s \" DriverName= \" %s \" Context=%x hm=%x \n " ,
2013-07-21 12:38:09 -04:00
lpGuid , lpDriverDescription , lpDriverName , lpContext , hm ) ;
res = TRUE ;
if ( ( lpGuid = = NULL ) | | ! ( dxw . dwFlags2 & HIDEMULTIMONITOR ) ) res = ( * p - > lpCallback ) ( lpGuid , lpDriverDescription , lpDriverName , p - > lpContext , hm ) ;
if ( ( lpGuid = = NULL ) & & ( dxw . dwFlags2 & HIDEMULTIMONITOR ) ) res = FALSE ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " DDEnumerateCallbackEx: res=%x(%s) \n " , res , res ? " continue " : " break " ) ;
2013-07-21 12:38:09 -04:00
return res ;
}
HRESULT WINAPI extDirectDrawEnumerate ( LPDDENUMCALLBACK lpCallback , LPVOID lpContext )
{
HRESULT ret ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " DirectDrawEnumerate: lpCallback=%x lpContext=%x \n " , lpCallback , lpContext ) ;
2013-07-21 12:38:09 -04:00
if ( ( dxw . dwFlags2 & HIDEMULTIMONITOR ) | | ( dxw . dwTFlags & OUTDEBUG ) ) {
struct { LPDDENUMCALLBACK lpCallback ; LPVOID lpContext ; } myContext ;
myContext . lpCallback = lpCallback ;
myContext . lpContext = lpContext ;
ret = ( * pDirectDrawEnumerate ) ( DDEnumerateCallbackFilter , ( LPVOID ) & myContext ) ;
}
else
ret = ( * pDirectDrawEnumerate ) ( lpCallback , lpContext ) ;
2013-11-16 11:38:27 -05:00
if ( ret ) OutTraceE ( " DirectDrawEnumerate: ERROR res=%x(%s) \n " , ret , ExplainDDError ( ret ) ) ;
2013-07-21 12:38:09 -04:00
return ret ;
}
HRESULT WINAPI extDirectDrawEnumerateEx ( LPDDENUMCALLBACKEX lpCallback , LPVOID lpContext , DWORD dwFlags )
{
HRESULT ret ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " DirectDrawEnumerateEx: lpCallback=%x lpContext=%x Flags=%x(%s) \n " ,
2013-07-21 12:38:09 -04:00
lpCallback , lpContext , dxw . dwFlags1 , ExplainDDEnumerateFlags ( dwFlags ) ) ;
if ( ( dxw . dwFlags2 & HIDEMULTIMONITOR ) | | ( dxw . dwTFlags & OUTDEBUG ) ) {
struct { LPDDENUMCALLBACKEX lpCallback ; LPVOID lpContext ; } myContext ;
myContext . lpCallback = lpCallback ;
myContext . lpContext = lpContext ;
ret = ( * pDirectDrawEnumerateEx ) ( DDEnumerateCallbackExFilter , ( LPVOID ) & myContext , dwFlags ) ;
}
else
ret = ( * pDirectDrawEnumerateEx ) ( lpCallback , lpContext , dwFlags ) ;
2013-12-22 11:38:36 -05:00
if ( ret ) OutTraceE ( " DirectDrawEnumerateEx: ERROR res=%x(%s) \n " , ret , ExplainDDError ( ret ) ) ;
2014-01-19 11:38:43 -05:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) ret = 0 ;
2013-07-21 12:38:09 -04:00
return ret ;
}
2013-11-10 11:38:21 -05:00
HRESULT WINAPI extDDGetGammaRamp ( LPDIRECTDRAWSURFACE lpdds , DWORD dwFlags , LPDDGAMMARAMP lpgr )
{
HRESULT ret ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetGammaRamp: dds=%x dwFlags=%x \n " , lpdds , dwFlags ) ;
2014-04-12 12:40:05 -04:00
if ( dxw . IsAPrimarySurface ( lpdds ) ) lpdds = lpDDSEmu_Prim ;
2013-11-10 11:38:21 -05:00
ret = ( * pDDGetGammaRamp ) ( lpdds , dwFlags , lpgr ) ;
2014-04-12 12:40:05 -04:00
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 " ) ;
}
}
2013-11-10 11:38:21 -05:00
return ret ;
}
HRESULT WINAPI extDDSetGammaRamp ( LPDIRECTDRAWSURFACE lpdds , DWORD dwFlags , LPDDGAMMARAMP lpgr )
{
HRESULT ret ;
2014-04-12 12:40:05 -04:00
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 " ) ;
}
2013-11-10 11:38:21 -05:00
if ( dxw . dwFlags2 & DISABLEGAMMARAMP ) return DD_OK ;
ret = ( * pDDSetGammaRamp ) ( lpdds , dwFlags , lpgr ) ;
2014-02-02 11:38:46 -05:00
if ( ret ) OutTraceE ( " SetGammaRamp: ERROR res=%x(%s) \n " , ret , ExplainDDError ( ret ) ) ;
2014-04-12 12:40:05 -04:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) ret = DD_OK ;
2013-11-10 11:38:21 -05:00
return ret ;
}
2013-12-22 11:38:36 -05:00
HRESULT WINAPI extGetAvailableVidMem ( LPDIRECTDRAW lpdd , LPDDSCAPS lpDDSCaps , LPDWORD lpdwTotal , LPDWORD lpdwFree , GetAvailableVidMem_Type pGetAvailableVidMem )
{
2014-08-29 12:39:42 -04:00
HRESULT res ;
2014-11-28 11:40:02 -05:00
//const DWORD dwMaxMem = 0x7FFFF000;
// v03.01.01: limit to smaller value to allow "Breath of Fire IV" card detection
const DWORD dwMaxMem = 0x70000000 ;
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " GetAvailableVidMem(D): lpdd=%x \n " , lpdd ) ;
res = ( * pGetAvailableVidMem ) ( lpdd , lpDDSCaps , lpdwTotal , lpdwFree ) ;
if ( res ) {
2014-01-03 11:38:52 -05:00
if ( ( dxw . dwFlags3 & FORCESHEL ) & & ( res = = DDERR_NODIRECTDRAWHW ) ) {
// fake some video memory....
OutTraceDW ( " GetAvailableVidMem(D): FORCESHEL mode Total=Free=%x \n " , dwMaxMem ) ;
2014-08-29 12:39:42 -04:00
* lpdwTotal = dwMaxMem ;
2014-01-03 11:38:52 -05:00
* lpdwFree = dwMaxMem ;
return DD_OK ;
}
2014-01-24 11:38:44 -05:00
OutTraceE ( " GetAvailableVidMem(D): ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-12-22 11:38:36 -05:00
}
else {
OutTraceDW ( " GetAvailableVidMem(D): DDSCaps=%x(%s) Total=%x Free=%x \n " ,
2014-01-19 11:38:43 -05:00
* lpDDSCaps , ExplainDDSCaps ( lpDDSCaps - > dwCaps ) , lpdwTotal ? * lpdwTotal : 0 , lpdwFree ? * lpdwFree : 0 ) ;
2013-12-22 11:38:36 -05:00
if ( dxw . dwFlags2 & LIMITRESOURCES ) { // check for memory value overflow - see "Mageslayer" and "Take no Prisoners"
DWORD dwLocalTotal ;
2014-01-19 11:38:43 -05:00
if ( lpdwTotal = = NULL ) {
lpdwTotal = & dwLocalTotal ; // point to usable memory....
res = ( * pGetAvailableVidMem ) ( lpdd , lpDDSCaps , lpdwTotal , lpdwFree ) ; // do it again to get total memory
}
2013-12-22 11:38:36 -05:00
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 ( lpdd , lpDDSCaps , lpdwTotal , lpdwFree , pGetAvailableVidMem2 ) ;
}
HRESULT WINAPI extGetAvailableVidMem4 ( LPDIRECTDRAW lpdd , LPDDSCAPS lpDDSCaps , LPDWORD lpdwTotal , LPDWORD lpdwFree )
{
return extGetAvailableVidMem ( lpdd , lpDDSCaps , lpdwTotal , lpdwFree , pGetAvailableVidMem4 ) ;
}
2014-01-24 11:38:44 -05:00
HRESULT WINAPI extSetSurfaceDesc ( LPDIRECTDRAWSURFACE lpdds , LPDDSURFACEDESC lpDDsd2 , DWORD dwFlags )
{
HRESULT res ;
OutTrace ( " SetSurfaceDesc: REACHED \n " ) ;
res = ( * pSetSurfaceDesc ) ( lpdds , lpDDsd2 , dwFlags ) ;
OutTraceE ( " SetSurfaceDesc: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
return res ;
}