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
# 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"
// 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 [ ] = {
{ " DirectDrawCreate " , ( FARPROC ) NULL , ( FARPROC * ) & pDirectDrawCreate , ( FARPROC ) extDirectDrawCreate } ,
{ " DirectDrawCreateEx " , ( FARPROC ) NULL , ( FARPROC * ) & pDirectDrawCreateEx , ( FARPROC ) extDirectDrawCreateEx } ,
2013-11-16 11:38:27 -05:00
{ " DirectDrawEnumerateA " , ( FARPROC ) NULL , ( FARPROC * ) & pDirectDrawEnumerate , ( FARPROC ) extDirectDrawEnumerate } ,
{ " DirectDrawEnumerateExA " , ( FARPROC ) NULL , ( FARPROC * ) & pDirectDrawEnumerateEx , ( FARPROC ) extDirectDrawEnumerateEx } ,
//{"DirectDrawEnumerateW", (FARPROC)NULL, (FARPROC *)&pDirectDrawEnumerateW, (FARPROC)extDirectDrawCreate},
//{"DirectDrawEnumerateExW", (FARPROC)NULL, (FARPROC *)&pDirectDrawEnumerateExW, (FARPROC)extDirectDrawCreate},
2013-11-10 11:38:26 -05:00
{ 0 , NULL , 0 , 0 } // terminator
} ;
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 )
{
DDSURFACEDESC ddsdRefreshRate ;
int Reminder ;
memset ( & ddsdRefreshRate , 0 , sizeof ( ddsdRefreshRate ) ) ;
ddsdRefreshRate . dwSize = sizeof ( ddsdRefreshRate ) ;
( * pGetDisplayMode ) ( lpdd , & ddsdRefreshRate ) ;
gdwRefreshRate = ddsdRefreshRate . dwRefreshRate ;
if ( ! gdwRefreshRate ) return ;
iRefreshDelayCount = 0 ;
Reminder = 0 ;
do {
iRefreshDelays [ iRefreshDelayCount ] = ( 1000 + Reminder ) / gdwRefreshRate ;
Reminder = ( 1000 + Reminder ) - ( iRefreshDelays [ iRefreshDelayCount ] * gdwRefreshRate ) ;
iRefreshDelayCount + + ;
} while ( Reminder & & ( iRefreshDelayCount < MAXREFRESHDELAYCOUNT ) ) ;
OutTraceDW ( " Refresh rate=%d: delay= " , gdwRefreshRate ) ;
for ( int i = 0 ; i < iRefreshDelayCount ; i + + ) OutTraceDW ( " %d " , iRefreshDelays [ i ] ) ;
OutTraceDW ( " \n " ) ;
}
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 ) ;
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 ;
DDSURFACEDESC ddsd ;
ddsd . dwSize = sizeof ( DDSURFACEDESC ) ;
if ( res = ( * pGetDisplayMode ) ( lpdd , & ddsd ) ) {
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 ) ;
if ( ! EnumDisplaySettings ( NULL , ENUM_CURRENT_SETTINGS , & CurrDevMode ) ) {
OutTraceE ( " EnumDisplaySettings: ERROR err=%d at %d \n " , GetLastError ( ) , __LINE__ ) ;
return ;
}
memset ( & dxw . ActualPixelFormat , 0 , sizeof ( DDPIXELFORMAT ) ) ;
// initialize to default null values, but dwRGBBitCount
dxw . ActualPixelFormat . dwRGBBitCount = CurrDevMode . dmBitsPerPel ;
dxw . VirtualPixelFormat . dwRGBBitCount = CurrDevMode . dmBitsPerPel ; // until set differently
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 ;
}
}
int HookDirectDraw ( HMODULE module , int version )
{
HINSTANCE hinst ;
void * tmp ;
const GUID dd7 = { 0x15e65ec0 , 0x3b9c , 0x11d2 , 0xb9 , 0x2f , 0x00 , 0x60 , 0x97 , 0x97 , 0xea , 0x5b } ;
if ( dxw . dwFlags2 & SETCOMPATIBILITY ) {
typedef HRESULT ( WINAPI * SetAppCompatData_Type ) ( DWORD , DWORD ) ;
SetAppCompatData_Type pSetAppCompatData ;
HRESULT res ;
hinst = LoadLibrary ( " ddraw.dll " ) ;
pSetAppCompatData = ( SetAppCompatData_Type ) ( * pGetProcAddress ) ( hinst , " SetAppCompatData " ) ;
if ( pSetAppCompatData ) {
res = ( * pSetAppCompatData ) ( 2 , 0 ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " HookDirectDraw: SetAppCompatData(2,0) ret=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
2013-07-21 12:38:09 -04:00
}
FreeLibrary ( hinst ) ;
}
OutTraceB ( " HookDirectDraw version=%d \n " , version ) ; //GHO
switch ( version ) {
case 0 : // automatic
tmp = HookAPI ( module , " ddraw.dll " , NULL , " DirectDrawCreate " , extDirectDrawCreate ) ;
if ( tmp ) pDirectDrawCreate = ( DirectDrawCreate_Type ) tmp ;
tmp = HookAPI ( module , " ddraw.dll " , NULL , " DirectDrawCreateEx " , extDirectDrawCreateEx ) ;
if ( tmp ) pDirectDrawCreateEx = ( DirectDrawCreateEx_Type ) tmp ;
tmp = HookAPI ( module , " ddraw.dll " , NULL , " DirectDrawEnumerateA " , extDirectDrawEnumerate ) ;
if ( tmp ) pDirectDrawEnumerate = ( DirectDrawEnumerate_Type ) tmp ;
tmp = HookAPI ( module , " ddraw.dll " , NULL , " DirectDrawEnumerateExA " , extDirectDrawEnumerateEx ) ;
if ( tmp ) pDirectDrawEnumerateEx = ( DirectDrawEnumerateEx_Type ) tmp ;
break ;
case 1 :
case 2 :
case 3 :
case 5 :
case 6 :
hinst = LoadLibrary ( " ddraw.dll " ) ;
pDirectDrawEnumerate =
( DirectDrawEnumerate_Type ) GetProcAddress ( hinst , " DirectDrawEnumerateA " ) ;
pDirectDrawCreate =
( DirectDrawCreate_Type ) GetProcAddress ( hinst , " DirectDrawCreate " ) ;
if ( pDirectDrawCreate ) {
LPDIRECTDRAW lpdd ;
BOOL res ;
HookAPI ( module , " ddraw.dll " , pDirectDrawCreate , " DirectDrawCreate " , extDirectDrawCreate ) ;
HookAPI ( module , " ddraw.dll " , pDirectDrawEnumerate , " DirectDrawEnumerateA " , extDirectDrawEnumerate ) ;
res = extDirectDrawCreate ( 0 , & lpdd , 0 ) ;
if ( res ) {
OutTraceE ( " DirectDrawCreate: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
}
lpdd - > Release ( ) ;
}
break ;
case 7 :
hinst = LoadLibrary ( " ddraw.dll " ) ;
pDirectDrawEnumerate =
( DirectDrawEnumerate_Type ) GetProcAddress ( hinst , " DirectDrawEnumerateA " ) ;
pDirectDrawEnumerateEx =
( DirectDrawEnumerateEx_Type ) GetProcAddress ( hinst , " DirectDrawEnumerateExA " ) ;
pDirectDrawCreate =
( DirectDrawCreate_Type ) GetProcAddress ( hinst , " DirectDrawCreate " ) ;
if ( pDirectDrawCreate ) {
LPDIRECTDRAW lpdd ;
BOOL res ;
HookAPI ( module , " ddraw.dll " , pDirectDrawCreate , " DirectDrawCreate " , extDirectDrawCreate ) ;
HookAPI ( module , " ddraw.dll " , pDirectDrawEnumerate , " DirectDrawEnumerateA " , extDirectDrawEnumerate ) ;
HookAPI ( module , " ddraw.dll " , pDirectDrawEnumerateEx , " DirectDrawEnumerateExA " , extDirectDrawEnumerateEx ) ;
res = extDirectDrawCreate ( 0 , & lpdd , 0 ) ;
if ( res ) OutTraceE ( " DirectDrawCreate: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
lpdd - > Release ( ) ;
}
pDirectDrawCreateEx =
( DirectDrawCreateEx_Type ) GetProcAddress ( hinst , " DirectDrawCreateEx " ) ;
if ( pDirectDrawCreateEx ) {
LPDIRECTDRAW lpdd ;
BOOL res ;
HookAPI ( module , " ddraw.dll " , pDirectDrawCreateEx , " DirectDrawCreateEx " , extDirectDrawCreateEx ) ;
res = extDirectDrawCreateEx ( 0 , & lpdd , dd7 , 0 ) ;
if ( res ) OutTraceE ( " DirectDrawCreateEx: ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
lpdd - > Release ( ) ;
}
break ;
}
if ( pDirectDrawCreate | | pDirectDrawCreateEx ) return 1 ;
return 0 ;
}
Unlock4_Type pUnlockMethod ( LPDIRECTDRAWSURFACE lpdds )
{
char sMsg [ 81 ] ;
void * extUnlock ;
2013-08-25 12:38:13 -04:00
__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__ ) ;
return ( Unlock4_Type ) pUnlock1 ;
} ;
2013-07-21 12:38:09 -04:00
if ( extUnlock = = ( void * ) extUnlock1 ) return ( Unlock4_Type ) pUnlock1 ;
if ( extUnlock = = ( void * ) extUnlock4 ) return ( Unlock4_Type ) pUnlock4 ;
2013-07-30 12:38:11 -04:00
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 ;
}
CreateSurface2_Type pCreateSurfaceMethod ( LPDIRECTDRAWSURFACE lpdds )
{
char sMsg [ 81 ] ;
void * extUnlock ;
extUnlock = ( void * ) * ( DWORD * ) ( * ( DWORD * ) lpdds + 128 ) ;
if ( extUnlock = = ( void * ) extUnlock1 ) return ( CreateSurface2_Type ) pCreateSurface1 ;
2014-03-21 12:38:57 -04:00
if ( extUnlock = = ( void * ) extUnlock4 ) return pCreateSurface7 ? ( CreateSurface2_Type ) pCreateSurface7 : ( CreateSurface2_Type ) pCreateSurface4 ;
2013-07-30 12:38:11 -04:00
if ( extUnlock = = ( void * ) extUnlockDir1 ) return ( CreateSurface2_Type ) pCreateSurface1 ;
2014-03-21 12:38:57 -04:00
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 ) ;
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 ] ;
void * extGetCaps ;
__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 ;
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 ] ;
void * extCreateSurface ;
__try {
extCreateSurface = ( void * ) * ( DWORD * ) ( * ( DWORD * ) lpdd + 24 ) ;
}
__except ( EXCEPTION_EXECUTE_HANDLER ) {
extCreateSurface = NULL ;
} ;
if ( extCreateSurface = = ( void * ) extCreateSurface7 ) return 7 ;
2013-08-25 12:38:13 -04:00
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 ;
}
/* ------------------------------------------------------------------ */
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) " ) ;
}
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
2014-09-02 12:38:49 -04:00
if ( dxw . dwFlags1 & AUTOMATIC ) dxw . dwFlags1 | = EMULATESURFACE ;
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
2013-07-21 12:38:09 -04:00
return 0 ;
}
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
2014-09-02 12:38:49 -04:00
if ( dxw . dwFlags1 & AUTOMATIC ) dxw . dwFlags1 | = EMULATESURFACE ;
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 ) ;
2014-03-21 12:38:57 -04:00
lpPrimaryDD = * lplpdd ;
2013-07-21 12:38:09 -04:00
return 0 ;
}
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 ;
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 ;
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 " ) ;
2014-01-19 11:38:43 -05:00
# ifdef COMMENTED_OUT
2013-08-25 12:38:13 -04:00
if ( dxw . dwFlags3 & DISABLEHAL ) { // IID_IDirect3DHALDevice - Dark Vengeance
// this is odd: this piece of code returns the very same error code returned by the actual
// QueryInterface call, but avoid a memory corruption and makes the game working....
// there must be something wrong behind it.
2014-01-19 11:38:43 -05:00
// SEEMS FIXED NOW, NO MORE CRASHES, THIS OPTION IS USELESS
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface: suppress IID_IDirect3DHALDevice interface res=DDERR_GENERIC \n " ) ;
2013-08-25 12:38:13 -04:00
return DDERR_GENERIC ;
2014-01-19 11:38:43 -05:00
//GUID IID_IDirect3DRGBDevice = {0xA4665C60,0x2673,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56};
//res = (*pQueryInterfaceS)(lpdds, IID_IDirect3DRGBDevice, obp);
//OutTraceDW("QueryInterface: redirect IID_IDirect3DHALDevice to RGB interface res=%x(%s)\n", res, ExplainDDError(res));
//return res;
//return DD_OK;
2013-08-25 12:38:13 -04:00
}
2014-01-19 11:38:43 -05:00
# endif
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 ;
}
2013-07-21 12:38:09 -04:00
if ( dwLocalDDVersion > dxw . dwMaxDDVersion ) {
* obp = NULL ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface(S): DDVersion=%d SUPPRESSED 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 ) ;
}
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 ) ;
2013-07-21 12:38:09 -04:00
return ( 0 ) ;
}
// added trace
2013-12-22 11:38:36 -05:00
OutTraceDDRAW ( " QueryInterface(S): lpdds=%x%s REFIID=%x obp=%x DDVersion=%d ret=0 \n " ,
2013-07-21 12:38:09 -04:00
lpdds , IsPrim ? " (PRIM) " : " " , riid . Data1 , * obp , dwLocalDDVersion ) ;
switch ( dwLocalDDVersion ) {
case 1 : // added for The Sims
case 2 :
case 3 :
case 4 :
case 7 :
dxw . dwDDVersion = dwLocalDDVersion ;
if ( IsPrim ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface(S): primary=%x new=%x \n " , lpdds , * obp ) ;
2013-07-21 12:38:09 -04:00
dxw . MarkPrimarySurface ( ( LPDIRECTDRAWSURFACE ) * obp ) ;
HookDDSurfacePrim ( ( LPDIRECTDRAWSURFACE * ) obp , dxw . dwDDVersion ) ;
}
else {
2013-11-10 11:38:21 -05:00
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 ) ;
2013-07-21 12:38:09 -04:00
}
break ;
}
2013-11-10 11:38:21 -05:00
if ( IsGammaRamp ) {
// 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-07-21 12:38:09 -04:00
}
2013-11-10 11:38:21 -05:00
if ( ( lpdds = = lpDDSBack ) & & dwLocalDDVersion ) {
// assume that you always use the newer interface version, if available.
if ( dwLocalDDVersion > ( UINT ) iBakBufferVersion ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " QueryInterface(S): switching backbuffer %x -> %x \n " , lpDDSBack , * obp ) ;
2013-11-10 11:38:21 -05:00
lpDDSBack = ( LPDIRECTDRAWSURFACE ) * obp ;
iBakBufferVersion = dwLocalDDVersion ;
}
}
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 ( ) ;
AdjustWindowFrame ( dxw . GethWnd ( ) , dwwidth , dwheight ) ;
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 ( ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " SetDisplayMode: mode=EMULATE %s ret=OK \n " , DumpPixelFormat ( & ddsd ) ) ;
2013-11-10 11:38:26 -05:00
return DD_OK ;
2013-07-21 12:38:09 -04:00
}
2013-12-22 11:38:36 -05:00
OutTraceDW ( " SetDisplayMode: mode=STANDARD BPP=%d \n " , dwbpp ) ;
2013-11-10 11:38:26 -05:00
dxw . ActualPixelFormat . dwRGBBitCount = dwbpp ;
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 ;
( * pGetDisplayMode ) ( lpdd , ( LPDDSURFACEDESC ) & ddsd ) ;
2013-11-10 11:38:26 -05:00
if ( version = = 1 )
res = ( * pSetDisplayMode1 ) ( lpdd , ddsd . dwWidth , ddsd . dwHeight , dwbpp ) ;
else
res = ( * pSetDisplayMode2 ) ( lpdd , ddsd . dwWidth , ddsd . dwHeight , dwbpp , ddsd . dwRefreshRate , 0 ) ;
2013-12-22 11:38:36 -05:00
OutTraceDW ( " SetDisplayMode: fixing colordepth current=%d required=%d size=(%dx%d) \n " ,
2013-07-21 12:38:09 -04:00
ddsd . ddpfPixelFormat . dwRGBBitCount , dwbpp , ddsd . dwWidth , ddsd . dwHeight ) ;
2014-03-23 12:38:58 -04:00
SetVSyncDelays ( lpdd ) ;
2013-07-21 12:38:09 -04:00
return 0 ;
}
HRESULT WINAPI extSetDisplayMode2 ( LPDIRECTDRAW lpdd ,
DWORD dwwidth , DWORD dwheight , DWORD dwbpp , DWORD dwrefreshrate , DWORD dwflags )
{
return extSetDisplayMode ( 2 , lpdd , dwwidth , dwheight , dwbpp , dwrefreshrate , dwflags ) ;
}
HRESULT WINAPI 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
lpddsd - > dwWidth = dxw . GetScreenWidth ( ) ;
lpddsd - > dwHeight = dxw . GetScreenHeight ( ) ;
// v2.1.96: fake screen color depth
2013-08-30 12:38:14 -04:00
if ( dxw . dwFlags2 & ( INIT8BPP | INIT16BPP ) ) { // v2.02.32 fix
2013-07-21 12:38:09 -04:00
if ( dxw . dwFlags2 & INIT8BPP ) FixPixelFormat ( 8 , & lpddsd - > ddpfPixelFormat ) ;
if ( dxw . dwFlags2 & INIT16BPP ) FixPixelFormat ( 16 , & lpddsd - > ddpfPixelFormat ) ;
2013-12-22 11:38:36 -05:00
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 ) ;
if ( dwflags & DDSCL_FULLSCREEN ) {
2013-08-25 12:38:13 -04:00
// 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 ) ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " SetCooperativeLevel: desktop hwnd=%x -> %x \n " , hwnd , dxw . GethWnd ( ) ) ;
2013-08-25 12:38:13 -04:00
hwnd = dxw . GethWnd ( ) ;
}
2013-07-21 12:38:09 -04:00
dxw . SetFullScreen ( TRUE ) ;
dwflags & = ~ ( DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWMODEX ) ;
dwflags | = DDSCL_NORMAL ;
res = ( * pSetCooperativeLevel ) ( lpdd , hwnd , dwflags ) ;
AdjustWindowFrame ( hwnd , dxw . GetScreenWidth ( ) , dxw . GetScreenHeight ( ) ) ;
2014-04-01 12:38:40 -04:00
if ( dxw . dwFlags1 & FIXWINFRAME ) dxw . FixWindowFrame ( hwnd ) ;
2013-07-21 12:38:09 -04:00
}
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 ) ;
}
if ( res )
OutTraceE ( " SetCooperativeLevel: ERROR err=%x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
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-10-21 12:38:23 -04:00
# define FIX_FLAGSMASK (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_PIXELFORMAT|DDSD_ZBUFFERBITDEPTH|DDSD_TEXTURESTAGE)
2013-11-10 11:38:21 -05:00
2013-10-21 12:38:23 -04:00
void FixSurfaceCapsAnalytic ( LPDDSURFACEDESC2 lpddsd , int dxversion )
{
2013-11-10 11:38:21 -05:00
switch ( lpddsd - > dwFlags & FIX_FLAGSMASK ) {
2013-10-21 12:38:23 -04:00
//case 0:
// switch (lpddsd->ddsCaps.dwCaps){
// case 0:
// // Star Force Deluxe
// lpddsd->dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
// lpddsd->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
// lpddsd->dwHeight = dxw.GetScreenHeight();
// lpddsd->dwWidth = dxw.GetScreenWidth();
2013-11-10 11:38:26 -05:00
// GetPixFmt(lpddsd);
2013-10-21 12:38:23 -04:00
// return;
// break;
// }
// break;
case DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_TEXTURESTAGE :
// Ancient Evil:
// dwFlags: DDSD_CAPS+HEIGHT+WIDTH+PIXELFORMAT+TEXTURESTAGE
// dwCaps1: DDSCAPS_OFFSCREENPLAIN+SYSTEMMEMORY+TEXTURE
// dwCaps2: DDSCAPS2_TEXTUREMANAGE
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-10-21 12:38:23 -04:00
return ;
break ;
2013-11-10 11:38:21 -05:00
case DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_ZBUFFERBITDEPTH :
2013-07-21 12:38:09 -04:00
switch ( lpddsd - > ddsCaps . dwCaps ) {
2013-11-10 11:38:21 -05:00
case DDSCAPS_VIDEOMEMORY | DDSCAPS_ZBUFFER :
// Dungeon Keeper II
return ;
2013-07-21 12:38:09 -04:00
break ;
2013-10-21 12:38:23 -04:00
case DDSCAPS_SYSTEMMEMORY | DDSCAPS_ZBUFFER :
// "Star Wars Shadows of the Empire" through d3d
return ;
break ;
2013-07-21 12:38:09 -04:00
}
2013-08-25 12:38:13 -04:00
break ;
2013-11-10 11:38:21 -05:00
case DDSD_CAPS | DDSD_WIDTH :
2013-08-25 12:38:13 -04:00
switch ( lpddsd - > ddsCaps . dwCaps ) {
2013-11-10 11:38:21 -05:00
case DDSCAPS_SYSTEMMEMORY :
return ;
2013-07-09 12:38:16 -04:00
break ;
2013-11-10 11:38:21 -05:00
case DDSCAPS_VIDEOMEMORY :
return ;
2013-08-25 12:38:13 -04:00
break ;
2013-11-10 11:38:21 -05:00
case DDSCAPS_SYSTEMMEMORY | DDSCAPS_RESERVED2 :
// Martian Gothic
return ;
break ;
case DDSCAPS_VIDEOMEMORY | DDSCAPS_RESERVED2 :
// Martian Gothic
return ;
2013-08-25 12:38:13 -04:00
break ;
2013-10-21 12:38:23 -04:00
case DDSCAPS_VIDEOMEMORY | DDSCAPS_WRITEONLY | DDSCAPS_RESERVED2 :
// Empire Earth
return ;
break ;
2013-08-25 12:38:13 -04:00
}
break ;
2013-07-30 12:38:11 -04:00
case DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH :
switch ( lpddsd - > ddsCaps . dwCaps ) {
2013-09-16 12:38:17 -04:00
case DDSCAPS_BACKBUFFER | DDSCAPS_SYSTEMMEMORY :
// Vangers
lpddsd - > ddsCaps . dwCaps = DDSCAPS_SYSTEMMEMORY ;
2013-11-10 11:38:21 -05:00
return ;
break ;
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY :
// Bunnies must die
lpddsd - > ddsCaps . dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_SYSTEMMEMORY ; // NOT WORKING
return ;
2013-09-16 12:38:17 -04:00
break ;
2013-07-30 12:38:11 -04:00
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY :
2013-11-10 11:38:21 -05:00
// Alien Nations, Heroes of Might & Magic IV --- troublesome!!!!
2013-11-10 11:38:26 -05:00
lpddsd - > dwFlags = ( DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT ) ;
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY ) ;
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
break ;
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY :
// Cave Story, HoMM3
2013-07-30 12:38:11 -04:00
lpddsd - > dwFlags | = DDSD_PIXELFORMAT ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
break ;
case DDSCAPS_SYSTEMMEMORY :
// Magic & Mayhem
lpddsd - > dwFlags | = DDSD_PIXELFORMAT ;
lpddsd - > ddsCaps . dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
break ;
case DDSCAPS_OFFSCREENPLAIN :
// Cave Story, Magic & Mayhem
lpddsd - > dwFlags | = DDSD_PIXELFORMAT ;
lpddsd - > ddsCaps . dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
2013-07-30 12:38:11 -04:00
break ;
2013-08-30 12:38:14 -04:00
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE :
// Nightmare Ned
lpddsd - > dwFlags | = DDSD_PIXELFORMAT ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
break ;
case DDSCAPS_SYSTEMMEMORY | DDSCAPS_3DDEVICE :
// Actua Soccer 3
lpddsd - > dwFlags | = DDSD_PIXELFORMAT ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
break ;
case DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE :
// Actua Soccer 3
lpddsd - > dwFlags | = DDSD_PIXELFORMAT ;
lpddsd - > ddsCaps . dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_3DDEVICE ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
2013-08-30 12:38:14 -04:00
break ;
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_SYSTEMMEMORY :
2013-11-10 11:38:21 -05:00
// Nightmare Ned, The Sims ???
2013-08-30 12:38:14 -04:00
lpddsd - > dwFlags | = DDSD_PIXELFORMAT ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
2013-08-30 12:38:14 -04:00
break ;
2013-11-10 11:38:21 -05:00
}
break ;
case DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH :
switch ( lpddsd - > ddsCaps . dwCaps ) {
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY :
// Airline Tycoon Evolution
return ;
2013-07-30 12:38:11 -04:00
break ;
2013-11-10 11:38:21 -05:00
//case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY|DDSCAPS_3DDEVICE:
// OutTrace("FixSurfaceCaps: ??? (Dungeon Keeper D3D)\n");
// break;
2013-07-30 12:38:11 -04:00
}
2013-08-25 12:38:13 -04:00
break ;
2013-11-10 11:38:21 -05:00
case DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT :
switch ( lpddsd - > ddsCaps . dwCaps ) {
2013-10-21 12:38:23 -04:00
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM :
// Empire Earth
// tbd
// try
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_SYSTEMMEMORY ) ;
// eotry
return ;
2013-11-10 11:38:26 -05:00
break ;
case DDSCAPS_OFFSCREENPLAIN :
2013-11-10 11:38:21 -05:00
// Submarine titans (8BPP)
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
break ;
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY :
2013-11-10 11:38:26 -05:00
// Duckman, HoM&M4, Beavis & Butthead do U.
// unsetting the Pixel Format may cause the backbuffer to be created with DDPF_ALPHAPIXELS flag on
// and some generic surface with DDPF_ALPHAPIXELS off, so that blitting is unsupported.
// But it seems impossible to get HOMM4 to cope with Beavis & Butthead!!!
if ( ! ( dxw . dwFlags3 & NOPIXELFORMAT ) ) GetPixFmt ( lpddsd ) ;
return ;
break ;
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY :
// Dungeon Keeper II GOG release (intro screen): doesn't like calling GetPixFmt!!!
2013-11-16 11:38:27 -05:00
// it requests a DDPF_FOURCC surface with fourcc="YYYY" that should not be overridden?
//
2013-11-10 11:38:26 -05:00
// need not to be configurable until we get a different case.
// it works both on VIDEOMEMORY or SYSTEMMEMORY. The latter should be more stable.
2013-11-16 11:38:27 -05:00
// v2.02.41: don't alter FOURCC pixel formats
if ( lpddsd - > ddpfPixelFormat . dwFlags & DDPF_FOURCC ) return ;
2013-11-10 11:38:26 -05:00
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ;
2013-11-10 11:38:21 -05:00
return ;
break ;
2013-11-23 11:38:29 -05:00
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM :
// Empire Earth
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ;
return ;
break ;
case DDSCAPS_COMPLEX | DDSCAPS_TEXTURE | DDSCAPS_MIPMAP :
// Empire Earth: flags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_MIPMAPCOUNT
return ;
break ;
2013-11-10 11:38:21 -05:00
case DDSCAPS_SYSTEMMEMORY | DDSCAPS_ZBUFFER :
// the Sims
return ;
break ;
case DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE :
2013-11-10 11:38:26 -05:00
// Wargames Direct3D hw acceleration
2013-11-10 11:38:24 -05:00
// Star Wars Shadows of the Empire in RGB HEL mode
2013-11-10 11:38:21 -05:00
return ;
break ;
2013-10-21 12:38:23 -04:00
case DDSCAPS_TEXTURE :
// Empire Earth
return ;
break ;
2013-11-10 11:38:21 -05:00
case DDSCAPS_VIDEOMEMORY | DDSCAPS_ZBUFFER :
// Martian Gothic
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_ZBUFFER ) ; // working ????
return ;
break ;
case DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ZBUFFER :
// Rayman 2
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_ZBUFFER ) ; // working ????
return ;
break ;
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY | DDSCAPS_3DDEVICE :
// Premier Manager 98
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
break ;
case DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY : // NOT WORKING
// Bunnies must die (not the horny ones!)
lpddsd - > ddsCaps . dwCaps = DDSCAPS_OVERLAY | DDSCAPS_SYSTEMMEMORY ;
return ;
break ;
2013-10-21 12:38:23 -04:00
case DDSCAPS_SYSTEMMEMORY :
// Star Force Deluxe
lpddsd - > ddsCaps . dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY ;
2013-11-10 11:38:26 -05:00
// GetPixFmt(lpddsd);
2013-10-21 12:38:23 -04:00
return ;
break ;
case DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_ALLOCONLOAD :
// Star Wars Shadows of the Empire
2013-11-10 11:38:26 -05:00
// seems to work both with/without GetPixFmt, but doesn't like DDSCAPS_SYSTEMMEMORY textures.
// Setting GetPixFmt makes bad alpha transparencies!
2013-11-10 11:38:24 -05:00
// DDSCAPS_VIDEOMEMORY doesn't work with HEL only! Better switch to DDSCAPS_SYSTEMMEMORY.
if ( dxw . dwFlags3 & FORCESHEL ) lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_ALLOCONLOAD ) ;
2013-10-21 12:38:23 -04:00
return ;
break ;
2013-11-10 11:38:21 -05:00
}
break ;
case DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT :
switch ( lpddsd - > ddsCaps . dwCaps ) {
case DDSCAPS_SYSTEMMEMORY :
// Wargames
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ;
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
//lpddsd->dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH; // turn DDSD_PIXELFORMAT off
return ;
break ;
case DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY :
// A10 Cuba
lpddsd - > ddsCaps . dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY ; // DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY working as well...
return ;
break ;
}
2013-07-21 12:38:09 -04:00
break ;
2013-11-10 11:38:21 -05:00
}
if ( dxw . dwFlags3 & SURFACEWARN ) {
char sMsg [ 512 ] ;
sprintf ( sMsg , " Flags=%x(%s) Caps=%x(%s) " , lpddsd - > dwFlags , ExplainFlags ( lpddsd - > dwFlags ) , lpddsd - > ddsCaps . dwCaps , ExplainDDSCaps ( lpddsd - > ddsCaps . dwCaps ) ) ;
MessageBox ( 0 , sMsg , " FixSurfaceCaps unmanaged setting " , MB_OK | MB_ICONEXCLAMATION ) ;
}
2013-10-21 12:38:23 -04:00
}
2013-11-10 11:38:21 -05:00
2013-10-21 12:38:23 -04:00
static void FixSurfaceCaps ( LPDDSURFACEDESC2 lpddsd , int dxversion )
{
// To do: fix Dungeon Keeper II
// rules of thumb:
2013-11-23 11:38:29 -05:00
// 1) always get rid of DDSCAPS_VIDEOMEMORY & DDSCAPS_LOCALVIDMEM caps
2013-10-21 12:38:23 -04:00
// 2) always add DDSCAPS_SYSTEMMEMORY caps
// 3) DDSCAPS_SYSTEMMEMORY is supported from dxversion 4
// 4) if DDSD_CAPS is not set, ignore caps
// 5) ignore DDSD_CKSRCBLT, ....
// 6) setting a different pixel format in memory requires DDSCAPS_OFFSCREENPLAIN capability
2013-12-27 11:38:38 -05:00
// 7) DDSD_TEXTURESTAGE surfaces may need to adjust pixel format (....???)
2013-11-10 11:38:26 -05:00
// 8) Generic surfaces are mapped to SYSTEMMEMORY and set to primary surface PixelFormat
// 9) When pixelformat is unspecified, be sure to pick the right one (with or without alphapixels?)
2013-12-27 11:38:38 -05:00
// 10) Don't alter surfaces with a color depth different from primary surface (Lords of Magic Special Edition)
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 ) ) ;
if ( dxw . dwFlags3 & ANALYTICMODE ) return FixSurfaceCapsAnalytic ( lpddsd , dxversion ) ;
if ( ( lpddsd - > dwFlags & ( DDSD_WIDTH | DDSD_HEIGHT ) ) = = DDSD_WIDTH ) {
// buffer surface - no changes
return ;
}
if ( ( lpddsd - > dwFlags & ( DDSD_PIXELFORMAT | DDSD_TEXTURESTAGE ) ) = = ( DDSD_PIXELFORMAT | DDSD_TEXTURESTAGE ) ) {
// textures, set proper color depth and make no further changes
2013-11-10 11:38:26 -05:00
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
}
if ( ( lpddsd - > dwFlags & DDSD_CAPS ) & & ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_ZBUFFER ) ) { // z-buffer surface - set to memory
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_ZBUFFER ) ;
return ;
}
if ( ( lpddsd - > dwFlags & DDSD_CAPS ) & & ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_3DDEVICE ) ) { // 3DDEVICE: enforce PIXELFORMAT on MEMORY
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-11-10 11:38:24 -05:00
//// DDSCAPS_ALLOCONLOAD on VIDEOMEMORY can't be done when HAL is disabled - it returns DDERR_NODIRECTDRAWHW error
//if((lpddsd->dwFlags & DDSD_CAPS) &&
// ((lpddsd->ddsCaps.dwCaps & (DDSCAPS_TEXTURE|DDSCAPS_ALLOCONLOAD))==(DDSCAPS_TEXTURE|DDSCAPS_ALLOCONLOAD))) {
// if (dxw.dwFlags3 & FORCESHEL) lpddsd->ddsCaps.dwCaps = (DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY|DDSCAPS_ALLOCONLOAD);
// return;
//}
// 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 ;
}
// no further changes...
return ;
}
2013-11-16 11:38:27 -05:00
2013-11-10 11:38:21 -05:00
if ( lpddsd - > dwFlags & DDSD_ZBUFFERBITDEPTH ) {
lpddsd - > dwFlags & = ~ DDSD_PIXELFORMAT ;
}
2013-11-16 11:38:27 -05:00
// v2.02.41: don't alter FOURCC pixel formats
if ( ( lpddsd - > dwFlags & DDSD_PIXELFORMAT ) & & ( lpddsd - > ddpfPixelFormat . dwFlags & DDPF_FOURCC ) ) return ;
2013-12-27 11:38:38 -05:00
// v2.02.50: don't alter surfaces with different color depth
if ( ( lpddsd - > dwFlags & DDSD_PIXELFORMAT ) & & ( lpddsd - > ddpfPixelFormat . dwRGBBitCount ! = dxw . VirtualPixelFormat . dwRGBBitCount ) ) return ;
2013-11-23 11:38:29 -05:00
#if 0
// v2.02.43: don't alter MIPMAP surfaces
if ( ( lpddsd - > dwFlags & DDSD_MIPMAPCOUNT ) & & ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_MIPMAP ) ) {
//GetPixFmt(lpddsd);
return ;
}
# endif
2013-11-10 11:38:26 -05:00
#if 0
2013-11-10 11:38:21 -05:00
// HoM&M3/4 fix....
if ( ( ( lpddsd - > dwFlags & ( DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT ) ) = = ( DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH ) ) & &
2013-11-10 11:38:26 -05:00
( ( lpddsd - > ddsCaps . dwCaps & ~ ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY ) = = DDSCAPS_OFFSCREENPLAIN ) ) {
//lpddsd->ddsCaps.dwCaps = 0;
lpddsd - > dwFlags = ( DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT ) ;
lpddsd - > ddsCaps . dwCaps = ( DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY ) ;
GetPixFmt ( lpddsd ) ;
2013-11-10 11:38:21 -05:00
return ;
2013-07-21 12:38:09 -04:00
}
2013-11-10 11:38:26 -05:00
# endif
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
ddsd . ddsCaps . dwCaps | = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ;
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 " ) ;
2013-09-16 12:38:17 -04:00
res = ( * pGetGDISurface ) ( lpdd , & lpDDSEmu_Prim ) ; // ok only if the previous surface has the good properties!!!
( * pReleaseS ) ( lpDDSEmu_Prim ) ;
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 ;
ddsd . ddsCaps . dwCaps = DDSCAPS_OFFSCREENPLAIN ;
2013-07-21 12:38:09 -04:00
ddsd . dwWidth = dxw . GetScreenWidth ( ) ;
ddsd . dwHeight = dxw . GetScreenHeight ( ) ;
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
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 ) ;
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
ddsd . ddsCaps . dwCaps | = ( DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ) ;
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 ) ;
//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__ ) ;
2013-09-18 12:38:18 -04:00
ddsd . ddsCaps . dwCaps & = ~ DDSCAPS_VIDEOMEMORY ; // try ...
ddsd . ddsCaps . dwCaps | = DDSCAPS_SYSTEMMEMORY ; // try ...
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 ) ;
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 ;
ddsd . ddsCaps . dwCaps | = DDSCAPS_SYSTEMMEMORY ;
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 ;
lpddsd - > ddsCaps . dwCaps | = DDSCAPS_SYSTEMMEMORY ;
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 ) ;
2013-07-21 12:38:09 -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.
if ( dxw . dwDDVersion = = 1 ) lpdd - > AddRef ( ) ;
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-08-25 12:38:13 -04:00
#if 0
2013-10-21 12:38:23 -04:00
if ( lpddsc - > dwCaps & DDSCAPS_MIPMAP ) {
2013-12-22 11:38:36 -05:00
OutTraceDW ( " GetAttachedSurface: emulate MIPMAP capability \n " ) ;
2013-08-25 12:38:13 -04:00
lpddsc - > dwCaps & = ~ DDSCAPS_MIPMAP ;
}
# endif
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 ) ;
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 ;
}
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 ;
//CkArg arg;
ToPrim = dxw . IsAPrimarySurface ( lpdds ) ;
FromPrim = dxw . IsAPrimarySurface ( lpddssrc ) ;
ToScreen = ToPrim & & ! ( dxw . dwFlags1 & EMULATESURFACE ) ;
FromScreen = FromPrim & & ! ( dxw . dwFlags1 & EMULATESURFACE ) ;
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 ;
return res ;
}
// Blit to primary surface
if ( dxw . HandleFPS ( ) ) return DD_OK ;
2013-08-25 12:38:13 -04:00
2013-07-21 12:38:09 -04:00
destrect = dxw . MapWindowRect ( lpdestrect ) ;
2013-11-16 11:38:27 -05:00
//OutTrace("DESTRECT=(%d,%d)-(%d,%d)\n", destrect.left, destrect.top, destrect.right, destrect.bottom);
2013-07-21 12:38:09 -04:00
if ( ! ( dxw . dwFlags1 & ( EMULATESURFACE | EMULATEBUFFER ) ) ) {
res = 0 ;
// 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__ ) ;
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
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
// Blit/Flip to emulated primary surface
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__ ) ;
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
work on my PC .
*/
if ( res = = DDERR_UNSUPPORTED ) {
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__ ) ;
}
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = 0 ;
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 ) {
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__ ) ;
2013-07-21 12:38:09 -04:00
res = ( * pBlt ) ( lpDDSEmu_Prim , & destrect , lpDDSSource , & emurect , DDBLT_WAIT , 0 ) ;
if ( res ) BlitError ( res , & emurect , & destrect , __LINE__ ) ;
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = 0 ;
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-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 ) ;
( * pGetSurfaceDescMethod ( lpdds ) ) ( ( LPDIRECTDRAWSURFACE2 ) lpDDSBack , & ddsd ) ;
ddsd . dwFlags & = ~ DDSD_PITCH ;
res = ( * pCreateSurfaceMethod ( lpdds ) ) ( lpPrimaryDD , & ddsd , & lpddsTmp , NULL ) ;
if ( res ) OutTraceE ( " CreateSurface: ERROR %x(%s) at %d \n " , res , ExplainDDError ( res ) , __LINE__ ) ;
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"
res = ( * pBlt ) ( lpddsTmp , NULL , lpdds , NULL , DDBLT_WAIT , NULL ) ;
}
else {
// in no-emulated mode, the primary surface is the whole screen, so you have to pick...
// needed for "Black Thorn"
RECT clip ;
clip = dxw . GetUnmappedScreenRect ( ) ;
res = ( * pBlt ) ( lpddsTmp , NULL , lpdds , & clip , DDBLT_WAIT , NULL ) ;
}
2014-02-03 11:38:53 -05:00
if ( res ) OutTraceE ( " Blt: ERROR %x(%s) at %d " , res , ExplainDDError ( res ) , __LINE__ ) ;
}
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-03-23 12:38:58 -04:00
// restore flipped backbuffer and delete temporary surface
2014-02-03 11:38:53 -05:00
res = ( * pBlt ) ( lpddssrc , NULL , lpddsTmp , NULL , DDBLT_WAIT , NULL ) ;
if ( res ) OutTraceE ( " Blt: ERROR %x(%s) at %d " , res , ExplainDDError ( res ) , __LINE__ ) ;
( * 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 ;
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!
2013-07-21 12:38:09 -04:00
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 ;
2014-09-02 12:38:49 -04:00
ret = sBlt ( " BltFast " , lpdds , & destrect , lpddssrc , NULL , flags , NULL , FALSE ) ;
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 )
{
static DWORD time = 0 ;
static BOOL step = 0 ;
DWORD tmp ;
if ( ! ( dxw . dwFlags1 & SAVELOAD ) ) return ( * pWaitForVerticalBlank ) ( lpdd , dwflags , hevent ) ;
tmp = ( * pGetTickCount ) ( ) ;
if ( ( time - tmp ) > 32 ) time = tmp ;
( * pSleep ) ( time - tmp ) ;
2014-03-23 12:38:58 -04:00
time + = iRefreshDelays [ step + + ] ;
if ( step > = iRefreshDelayCount ) step = 0 ;
2013-11-10 11:38:26 -05:00
return 0 ;
}
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 ) ) ;
2013-11-28 11:38:31 -05:00
//mySetPalette(0, 256, lpentries);
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
2013-12-22 11:38:36 -05:00
if ( IsTraceDDRAW ) {
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__ ) ;
2013-07-21 12:38:09 -04:00
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = DD_OK ;
// shouldn't happen.... if hooked to non primary surface, just call regular method.
// it happens in "Deadlock 2" backbuffer surface!!!
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 ) {
2013-07-21 12:38:09 -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 ) ;
}
res = ( * pUnlock ) ( lpdds , lprect ) ;
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 ) ;
if ( dxw . dwFlags1 & SUPPRESSDXERRORS ) res = 0 ;
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 ) {
2013-08-25 12:38:13 -04:00
( * pGetGDISurface ) ( lpPrimaryDD , & lpDDSPrim ) ;
2013-09-16 12:38:17 -04:00
if ( lpdds = = lpDDSPrim ) {
2013-07-30 12:38:11 -04:00
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 ) ;
if ( lpDDSBuffer ) ( * 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 ) ;
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 ) ) ;
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 ;
static SupportedRes_Type SupportedSVGARes [ 9 ] = {
2014-02-04 11:39:01 -05:00
{ 320 , 200 } ,
{ 320 , 240 } ,
{ 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 ;
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-04-04 12:39:03 -04:00
if ( ( dxw . dwFlags4 & NATIVERES ) ) {
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 ;
EmuDesc . dwRefreshRate = 0 ;
EmuDesc . ddpfPixelFormat . dwFlags = DDPF_RGB ;
if ( lpddsd ) EmuDesc . dwSize = lpddsd - > dwSize ; // sizeof either DDSURFACEDESC or DDSURFACEDESC2 !!!
else EmuDesc . dwSize = sizeof ( DDSURFACEDESC2 ) ;
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 ] ;
FixPixelFormat ( EmuDesc . ddpfPixelFormat . dwRGBBitCount , & ( EmuDesc . ddpfPixelFormat ) ) ;
2013-07-21 12:38:09 -04:00
res = ( * cb ) ( ( LPDDSURFACEDESC ) & EmuDesc , lpContext ) ;
2014-02-04 11:39:01 -05:00
OutTraceDW ( " EnumDisplayModes(D): proposed depth[%d]=%d size[%d]=(%d,%d) res=%x \n " ,
DepthIdx , SupportedDepths [ DepthIdx ] , ResIdx , SupportedRes [ ResIdx ] . w , SupportedRes [ ResIdx ] . h , res ) ;
2013-07-21 12:38:09 -04:00
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 ) ;
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 ;
}
2013-11-23 11:38:29 -05:00
#if 0
static HRESULT WINAPI RestoreAll ( LPDIRECTDRAWSURFACE7 lpDDSurface , LPDDSURFACEDESC2 lpDDSurfaceDesc , LPVOID lpContext )
{
HRESULT res ;
//res=lpDDSurface->Restore();
res = ( * pRestore ) ( ( LPDIRECTDRAWSURFACE ) lpDDSurface ) ;
OutTraceB ( " TestCooperativeLevel: Restore lpdds=%x res=%x(%s) \n " , lpDDSurface , res , ExplainDDError ( res ) ) ;
( * pReleaseS ) ( ( LPDIRECTDRAWSURFACE ) lpDDSurface ) ;
if ( res ) return DDENUMRET_CANCEL ;
return DDENUMRET_OK ;
}
# endif
2013-07-21 12:38:09 -04:00
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 ) {
#if 0
( * pEnumSurfaces4 ) ( lpdd , DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL , NULL , NULL , ( LPDDENUMSURFACESCALLBACK2 ) RestoreAll ) ;
//lpDDSEmu_Prim->Restore();
//res=(*pEnumSurfaces4)(lpdd, dwflags, lpddsd, lpContext, cb);
# else
res = ( ( LPDIRECTDRAW7 ) lpdd ) - > RestoreAllSurfaces ( ) ;
if ( res ) OutTraceE ( " TestCooperativeLevel: RestoreAllSurfaces ERROR res=%x(%s) \n " , res , ExplainDDError ( res ) ) ;
# endif
}
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 ) ;
2013-07-21 12:38:09 -04:00
2013-11-10 11:38:21 -05:00
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
# ifdef EXPERIMENTAL_1
if ( 1 ) {
IsFixed = TRUE ;
if ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_BACKBUFFER ) {
lpddsd - > dwSize = sizeof ( DDSURFACEDESC2 ) ;
lpddsd - > ddsCaps . dwCaps | = DDSCAPS_RESERVED2 ;
( ( LPDDSURFACEDESC2 ) lpddsd ) - > ddsCaps . dwCaps2 = DDSCAPS2_RESERVED2 ;
( ( LPDDSURFACEDESC2 ) lpddsd ) - > ddsCaps . dwCaps3 = 0 ;
}
else
if ( lpddsd - > ddsCaps . dwCaps & DDSCAPS_BACKBUFFER ) {
}
else {
lpddsd - > ddsCaps . dwCaps | = DDSCAPS_RESERVED2 ;
( ( LPDDSURFACEDESC2 ) lpddsd ) - > ddsCaps . dwCaps2 | = DDSCAPS2_RESERVED2 ;
}
}
# endif
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 ) ;
2013-11-10 11:38:21 -05:00
/**/ 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 ) ;
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 ) ;
break ;
case sizeof ( DDSURFACEDESC2 ) :
if ( pGetSurfaceDesc4 ) return extGetSurfaceDesc ( ( GetSurfaceDesc_Type ) pGetSurfaceDesc4 , ( LPDIRECTDRAWSURFACE ) lpdds , ( LPDDSURFACEDESC ) lpddsd ) ;
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 ) ;
2013-11-10 11:38:21 -05:00
ret = ( * pDDGetGammaRamp ) ( lpdds , dwFlags , lpgr ) ;
if ( ret ) OutTraceE ( " GetGammaRamp: ERROR res=%x(%s) \n " , ret , ExplainDDError ( ret ) ) ;
2013-12-22 11:38:36 -05:00
else OutTraceDDRAW ( " GetGammaRamp: RGB=(%x,%x,%x) \ n " , lpgr->red, lpgr->green, lpgr->blue) ;
2013-11-10 11:38:21 -05:00
return ret ;
}
HRESULT WINAPI extDDSetGammaRamp ( LPDIRECTDRAWSURFACE lpdds , DWORD dwFlags , LPDDGAMMARAMP lpgr )
{
HRESULT ret ;
2014-02-02 11:38:46 -05:00
OutTraceDDRAW ( " SetGammaRamp: dds=%x dwFlags=%x RGB=(%x,%x,%x) \n " , lpdds , dwFlags , lpgr - > red , lpgr - > green , lpgr - > blue ) ;
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 ) ) ;
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 )
{
HRESULT res ;
2014-01-03 11:38:52 -05:00
const DWORD dwMaxMem = 0x7FFFF000 ;
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 ) ;
* lpdwTotal = dwMaxMem ;
* 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 ;
}