diff --git a/Include/dxwnd.h b/Include/dxwnd.h index b3c834e..52918e5 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -122,7 +122,7 @@ #define DISABLEFOGGING 0x00000080 // Disable D3D fogging #define NOPOWER2FIX 0x00000100 // Handle textures whose size is not a power of 2 (32, 64, 128 ...) #define NOPERFCOUNTER 0x00000200 // Disables the GetPerfCounter performance metrics API,as if it was not supported.... -#define BILINEAR2XFILTER 0x00000400 // attempt to smooth low-res graphic by applying biulinear filtering in emulation mode +#define BILINEAR2XFILTER 0x00000400 // attempt to smooth low-res graphic by applying simplified bilinear filtering in emulation mode #define INTERCEPTRDTSC 0x00000800 // Intercapts RDTSC opcodes to hook at assembly level #define LIMITSCREENRES 0x00001000 // Limit available screen resolution up to defined maximum #define NOFILLRECT 0x00002000 // Suppress FillRect calls @@ -173,6 +173,7 @@ #define CENTERTOWIN 0x01000000 // do NOT stretch the image to the whole window client area, but center to it. #define STRESSRESOURCES 0x02000000 // simulates a lack of resources condition, for testing (debug opt.) #define MESSAGEPUMP 0x04000000 // inserts a "message pump" loop between repeated operation that may stop the task on Win7 and greater +#define TEXTUREFORMAT 0x08000000 // Apply virtual pixel format to texture surfaces without DDSD_PIXELFORMAT attribute // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general diff --git a/build/dxwnd.dll b/build/dxwnd.dll index cfac4c1..7b88cf6 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c798c0cff917a4dfb846882ff9d9ffc9cc2fcd747228487da1f88b8e58c5b74 -size 563712 +oid sha256:09c3405b326eb5eff358f5713b62cd1107c84ce64625529de44283cab2b64c9a +size 564224 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index f7130d7..fcfb1b7 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3a88f64a7bf93e63942698c78c94a1b57ab660eea0e6b2eaf8fdd2774c0ca0e3 -size 536576 +oid sha256:be381f4fba85d8c7dcb13682c470713728dd133b38e6d4d1ed65fc6ceb74e771 +size 536064 diff --git a/build/dxwnd.ini b/build/dxwnd.ini index 14a8117..b278890 100644 --- a/build/dxwnd.ini +++ b/build/dxwnd.ini @@ -1,11 +1,11 @@ [window] -posx=1227 -posy=471 +posx=50 +posy=50 sizx=320 sizy=200 lang=default ;lang=automatic -;debug=1 +debug=1 ;multiprocesshook=0 ;checkadmin=0 [texture] diff --git a/build/exports/Black & White.dxw b/build/exports/Black & White.dxw index 7f54bff..8cc344b 100644 --- a/build/exports/Black & White.dxw +++ b/build/exports/Black & White.dxw @@ -5,11 +5,11 @@ module0= opengllib0= ver0=0 coord0=0 -flag0=679477280 +flag0=679477282 flagg0=1207959568 flagh0=20 -flagi0=4 -tflag0=259 +flagi0=4194308 +tflag0=0 initx0=0 inity0=0 minx0=0 @@ -24,3 +24,6 @@ maxfps0=0 initts0=0 winver0=0 maxres0=0 +launchpath0= +notes0= +flagj0=128 diff --git a/build/exports/Doom 3.dxw b/build/exports/Doom 3.dxw index 9147f33..809d3ce 100644 --- a/build/exports/Doom 3.dxw +++ b/build/exports/Doom 3.dxw @@ -10,7 +10,7 @@ flag0=134217760 flagg0=1207959552 flagh0=65557 flagi0=69206020 -tflag0=6211 +tflag0=64 initx0=0 inity0=0 minx0=0 @@ -25,3 +25,5 @@ maxfps0=0 initts0=0 winver0=0 maxres0=-1 +notes0= +flagj0=0 diff --git a/build/exports/Hitchcock the Final Cut.dxw b/build/exports/Hitchcock the Final Cut.dxw new file mode 100644 index 0000000..7d0cfcb --- /dev/null +++ b/build/exports/Hitchcock the Final Cut.dxw @@ -0,0 +1,29 @@ +[target] +title0=Hitchcock the Final Cut +path0=D:\Games\Hitchcock\Hitchcock_Kyro.exe +launchpath0= +module0= +opengllib0= +notes0= +ver0=1 +coord0=0 +flag0=134217762 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=67113088 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 diff --git a/build/exports/Moon Tycoon.dxw b/build/exports/Moon Tycoon.dxw new file mode 100644 index 0000000..f0372d8 --- /dev/null +++ b/build/exports/Moon Tycoon.dxw @@ -0,0 +1,142 @@ + + + + + + + + Wikisend: free file sharing service + + + + + + +
+
+
+ + +
+
+ +
+ +
+ +
+
+
+ +
+
+
+
+ + +
+
+ + + + + + + + + +
+
Upload
+
Download
+
+ +
+ + +
+ Moon Tycoon.dxw
+ +
+
+ +
    +
  • File ID: 271650
  • +
  • File size: 512 B
  • +
  • Time to live: 28 days
+
+
+
+ +
+ + + + +
+ + +
+
+ + +
+ + + + + + + +
+

Why our site?

+ +
+

Simple & Free

+Upload and download lots of  files, big files, small files, data files, +media files, archives or backups - any files. With Wikisend it`s simple and +free. + +

Share with Friends

+Share files with your friends using E-mail, MySpace page, your blog, forums +and so on. With Wikisend sharing files, photos, videos or documents is easy, +fast, and reliable. + +

Start now

+No need to register, activate, install or read manuals - use our uploading +form, you`re ready to go. + +
+ +
+ + + + +
+ + + + + + + \ No newline at end of file diff --git a/build/exports/Tomb Raider III (SW emulation).dxw b/build/exports/Tomb Raider III (SW emulation).dxw index 6e36eee..e3fd3e8 100644 --- a/build/exports/Tomb Raider III (SW emulation).dxw +++ b/build/exports/Tomb Raider III (SW emulation).dxw @@ -7,9 +7,9 @@ ver0=0 coord0=0 flag0=134217762 flagg0=1241513984 -flagh0=25165844 -flagi0=0 -tflag0=323 +flagh0=20 +flagi0=4194304 +tflag0=0 initx0=0 inity0=0 minx0=0 @@ -22,5 +22,10 @@ sizx0=800 sizy0=600 maxfps0=0 initts0=0 +launchpath0= +notes0= +flagj0=0 +winver0=0 +maxres0=0 ; remember to set SW emulated mode in game setup panel diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 7c8e92d..e5eaa01 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -719,3 +719,9 @@ add: made check for admin rights configurable in dxwnd.ini add: "portable" capability to configure relative pathnames fix: small bug in game menu string width - now game titles should not be trunked any longer. +v2.03.09 +code reorganization & reuse +add: "Set texture pixel format" flag, makes "Jeff Gordon XS Racing" working on emulated mode and 32BPP desktop +add: "GDI mode" emulation uses HALFTONE to activate GDI bilinear stretching when "Full Bilinear" filter is activated: slower, but better quality +add: preliminary hooking for EnumZBufferFormats ddraw7 method +fix: eliminated some handle leakage when injecting launched processes diff --git a/dll/Inject.cpp b/dll/Inject.cpp index 3d018c5..d15cb0f 100644 --- a/dll/Inject.cpp +++ b/dll/Inject.cpp @@ -15,62 +15,41 @@ BOOL Inject(DWORD pID, const char * DLL_NAME) { - HANDLE Proc; + HANDLE hProc, hThread; + HMODULE hLib; char buf[50] = {0}; LPVOID RemoteString, LoadLibAddy; if(!pID) return false; - //Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // not working on Win XP - Proc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pID); - if(!Proc) + //hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // not working on Win XP + hProc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pID); + if(!hProc) { sprintf(buf, "OpenProcess() failed: pid=%x err=%d", pID, GetLastError()); MessageBox(NULL, buf, "Loader", MB_OK); - printf(buf); return false; } - LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); - // Allocate space in the process for our DLL - RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - // Write the string name of our DLL in the memory allocated - WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL); - // Load our DLL - if(!CreateRemoteThread(Proc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, 0, NULL)){ + hLib=GetModuleHandle("kernel32.dll"); + LoadLibAddy = (LPVOID)GetProcAddress(hLib, "LoadLibraryA"); + // Allocate space in the process for the DLL + RemoteString = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + // Write the string name of the DLL in the memory allocated + WriteProcessMemory(hProc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL); + // Load the DLL + hThread=CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, 0, NULL); + // Free/Release/Close everything + VirtualFreeEx(hProc, RemoteString, strlen(DLL_NAME), MEM_RELEASE); + if(!hThread){ sprintf(buf, "CreateRemoteThread() failed: pid=%x err=%d", pID, GetLastError()); MessageBox(NULL, buf, "Loader", MB_OK); - printf(buf); + CloseHandle(hProc); return false; } - CloseHandle(Proc); + CloseHandle(hThread); + CloseHandle(hProc); + CloseHandle(hLib); return true; } -#if 0 -DWORD GetTargetThreadIDFromProcName(const char * ProcName) -{ - PROCESSENTRY32 pe; - HANDLE thSnapShot; - BOOL retval, ProcFound = false; - thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if(thSnapShot == INVALID_HANDLE_VALUE) - { - MessageBox(NULL, "Error: Unable to create toolhelp snapshot!", "2MLoader", MB_OK); - //printf("Error: Unable to create toolhelp snapshot!"); - return false; - } - pe.dwSize = sizeof(PROCESSENTRY32); - retval = Process32First(thSnapShot, &pe); - while(retval) - { - if(StrStrI(pe.szExeFile, ProcName)) - { - return pe.th32ProcessID; - } - retval = Process32Next(thSnapShot, &pe); - } - return 0; -} -#endif - #define STATUS_SUCCESS ((NTSTATUS)0x000 00000L) #define ThreadQuerySetWin32StartAddress 9 diff --git a/dll/ddblit.cpp b/dll/ddblit.cpp new file mode 100644 index 0000000..a0f0234 --- /dev/null +++ b/dll/ddblit.cpp @@ -0,0 +1,366 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "stdio.h" +#include "hddraw.h" +#include "dxhelper.h" + +extern LPDIRECTDRAWSURFACE lpDDSBack; +extern LPDIRECTDRAWSURFACE lpDDSEmu_Prim; +extern LPDIRECTDRAWSURFACE lpDDSEmu_Back; +extern LPDIRECTDRAW lpPrimaryDD; +extern Blt_Type pBlt; +extern ReleaseS_Type pReleaseS; +extern CreateSurface1_Type pCreateSurface1; +extern CreateSurface1_Type pCreateSurface2; +extern CreateSurface1_Type pCreateSurface3; +extern CreateSurface2_Type pCreateSurface4; +extern CreateSurface2_Type pCreateSurface7; +extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE); + +extern void BlitError(HRESULT, LPRECT, LPRECT, int); +extern void BlitTrace(char *, LPRECT, LPRECT, int); +extern void DescribeSurface(LPDIRECTDRAWSURFACE, int, char *, int); +extern void TextureHandling(LPDIRECTDRAWSURFACE); + +static HRESULT sBltNoPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx) +{ + RECT srcrect; + HRESULT res; + BOOL FromScreen; + //extern PrimaryBlt_Type pPrimaryBlt; + //CkArg arg; + + FromScreen=dxw.IsAPrimarySurface(lpddssrc) && !(dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags1 & EMULATEBUFFER); // v2.02.77 + + // 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); + } + } + + if (IsDebug) BlitTrace("NOPRIM", lpsrcrect, lpdestrect, __LINE__); + 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. + // Wrong guess!!! The cause was not compression, but simply a pixelformat mismatch. Better + // configure things properly and avoid this branch. + switch(res){ + case DDERR_UNSUPPORTED: + if (dxw.dwFlags1 & EMULATESURFACE){ + RECT targetrect; + if (IsDebug) BlitTrace("UNSUPP", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__); + targetrect=*lpdestrect; + dxw.MapWindowRect(&targetrect); + res=(*pBlt)(lpDDSEmu_Prim, &targetrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx); + } + break; + case DDERR_SURFACEBUSY: + (*pUnlockMethod(lpdds))(lpdds, NULL); + if (lpddssrc) (*pUnlockMethod(lpddssrc))(lpddssrc, NULL); + if (IsDebug) BlitTrace("BUSY", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__); + res=(*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags|DDBLT_WAIT, lpddbltfx); + break; + default: + break; + } + if (res) BlitError(res, &srcrect, lpdestrect, __LINE__); + if(IsDebug) { + DescribeSurface(lpdds, 0, "[DST]" , __LINE__); + if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!! + } + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; + if(dxw.dwFlags5 & TEXTUREMASK) { + // Texture Handling on Blt + TextureHandling(lpdds); + } + return res; +} + +static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping) +{ + HRESULT res; + RECT destrect, emurect; + extern PrimaryBlt_Type pPrimaryBlt; + + // debug suppressions + if(isFlipping){ + if(dxw.dwFlags3 & NODDRAWFLIP) return DD_OK; + } + else { + if(dxw.dwFlags3 & NODDRAWBLT) return DD_OK; + } + +#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 +#if FIXBIGGERRECT + if(lpdestrect){ + if((DWORD)lpdestrect->top < 0) lpdestrect->top = 0; + if((DWORD)lpdestrect->left < 0) lpdestrect->left = 0; + if((DWORD)lpdestrect->bottom > dxw.GetScreenHeight()) lpdestrect->bottom = dxw.GetScreenHeight(); + if((DWORD)lpdestrect->right > dxw.GetScreenWidth()) lpdestrect->right = dxw.GetScreenWidth(); + } +#endif + + if(dxw.dwFlags5 & QUARTERBLT){ + BOOL QuarterUpdate; + QuarterUpdate = lpdestrect ? + (((lpdestrect->bottom - lpdestrect->top) * (lpdestrect->right - lpdestrect->left)) > ((LONG)(dxw.GetScreenHeight() * dxw.GetScreenWidth()) >> 2)) + : + TRUE; + if(QuarterUpdate) if(dxw.HandleFPS()) return DD_OK; + } + else + if(dxw.HandleFPS()) return DD_OK; + if(dxw.dwFlags5 & NOBLT) return DD_OK; + + destrect=dxw.MapWindowRect(lpdestrect); + OutTraceB("DESTRECT=(%d,%d)-(%d,%d) Screen=(%dx%d)\n", + destrect.left, destrect.top, destrect.right, destrect.bottom, + dxw.GetScreenWidth(), dxw.GetScreenHeight()); + + if(!lpddssrc) { + if (isFlipping){ + // handle the flipping chain ... + lpddssrc=lpDDSBack; + OutTraceDW("Flip: setting flip chain to lpdds=%x\n", lpddssrc); + } + } + + // ========================= + // Blit to primary direct surface + // ========================= + + if(!(dxw.dwFlags1 & (EMULATESURFACE|EMULATEBUFFER))){ + res=DD_OK; + + // blit only when source and dest surface are different. Should make ScreenRefresh faster. + if (lpdds != lpddssrc) { + dxw.ShowOverlay(lpddssrc); + if (IsDebug) BlitTrace("PRIM-NOEMU", lpsrcrect, &destrect, __LINE__); + res=(*pPrimaryBlt)(lpdds, &destrect, lpddssrc, lpsrcrect); + } + if(res){ + BlitError(res, lpsrcrect, &destrect, __LINE__); + if(IsDebug) { + DescribeSurface(lpdds, 0, "[DST]" , __LINE__); + if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!! + } + // Try to handle HDC lock concurrency.... + if(res==DDERR_SURFACEBUSY){ + (*pUnlockMethod(lpdds))(lpdds, NULL); + if (IsDebug) BlitTrace("BUSY", lpsrcrect, &destrect, __LINE__); + res= (*pBlt)(lpdds, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); + if (res) BlitError(res, lpsrcrect, &destrect, __LINE__); + } + // 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; + } + + return res; + } + + // ... else blitting on emulated surface + + // ========================= + // Blit/Flip to emulated primary surface + // ========================= + + if(dxw.dwFlags5 & GDIMODE){ + extern void BlitToWindow(HWND, LPDIRECTDRAWSURFACE); + //if (lpdds != lpddssrc) + BlitToWindow(dxw.GethWnd(), lpddssrc); + return DD_OK; + } + + 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){ + if (IsDebug) BlitTrace("SRC2EMU", &emurect, &destrect, __LINE__); + if(destrect.top == -32000) return DD_OK; // happens when window is minimized & do not notify on task switch ... + res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); + } + + if (res) { + BlitError(res, lpsrcrect, &emurect, __LINE__); + DescribeSurface(lpdds, 0, "[DST]" , __LINE__); + if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!! + /* + 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. The error code is DDERR_UNSUPPORTED. + v2.02.98 update.... + The same thing happens with New York Racer, but with DDERR_EXCEPTION error code. + */ + if((res==DDERR_UNSUPPORTED) || (res==DDERR_EXCEPTION)){ + dxw.ShowOverlay(lpddssrc); + if (IsDebug) BlitTrace("UNSUPP", &emurect, &destrect, __LINE__); + 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)); + if (IsDebug) BlitTrace("BUSY", &emurect, &destrect, __LINE__); + res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); + if (res) BlitError(res, lpsrcrect, &destrect, __LINE__); + } + + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; + return res; + } + + LPDIRECTDRAWSURFACE lpDDSSource; + if (res=(*pColorConversion)(lpdds, emurect, &lpDDSSource)) { + OutTraceE("sBlt ERROR: Color conversion failed res=%d(%s)\n", res, ExplainDDError(res)); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; + return res; + } + + dxw.ShowOverlay(lpDDSSource); + if (IsDebug) BlitTrace("BACK2PRIM", &emurect, &destrect, __LINE__); + res=(*pPrimaryBlt)(lpDDSEmu_Prim, &destrect, lpDDSSource, &emurect); + + if (res) BlitError(res, &emurect, &destrect, __LINE__); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; + if (IsDebug) OutTrace("%s: done ret=%x at %d\n", api, res, __LINE__); + return res; +} + +HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping) +{ + POINT p = {0, 0}; + HRESULT res; + BOOL ToPrim, FromPrim, ToScreen, FromScreen; + + if(dxw.dwFlags5 & MESSAGEPUMP){ + MSG msg; + while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){ + OutTraceW("MESSAGEPUMP: msg=%x l-wParam=(%x,%x)\n", msg.message, msg.lParam, msg.wParam); + if((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST)) break; // do not consume keyboard inputs + PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + ToPrim=dxw.IsAPrimarySurface(lpdds); + FromPrim=dxw.IsAPrimarySurface(lpddssrc); + ToScreen=ToPrim && !(dxw.dwFlags1 & EMULATESURFACE); + FromScreen=FromPrim && !(dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags1 & EMULATEBUFFER); // v2.02.77 + + // log + if(IsTraceDW){ + char sLog[256]; + char sInfo[128]; + sprintf(sLog, "%s: dest=%x%s src=%x%s dwFlags=%x(%s)", + api, lpdds, (ToPrim ? "(PRIM)":""), lpddssrc, (FromPrim ? "(PRIM)":""), dwflags, ExplainBltFlags(dwflags)); + if (lpdestrect) + sprintf(sInfo, " destrect=(%d,%d)-(%d,%d)", lpdestrect->left, lpdestrect->top, lpdestrect->right, lpdestrect->bottom); + else + sprintf(sInfo, " destrect=(NULL)"); + strcat(sLog, sInfo); + if (lpsrcrect) + sprintf(sInfo, " srcrect=(%d,%d)-(%d,%d)", lpsrcrect->left, lpsrcrect->top, lpsrcrect->right, lpsrcrect->bottom); + else + 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); + } + if (dwflags & DDBLT_DEPTHFILL){ + sprintf(sInfo, " ddbltfx.FillDepth=%x", lpddbltfx->dwFillDepth); + strcat(sLog, sInfo); + } + } + strcat(sLog,"\n"); + OutTrace(sLog); + } + + if(ToPrim) + res = sBltToPrimary(api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx, isFlipping); + else + res = sBltNoPrimary(api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); + + return res; +} \ No newline at end of file diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index 51cfd67..7114c21 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -286,6 +286,8 @@ FARPROC Remap_ddraw_ProcAddress(LPCSTR proc, HMODULE hModule) return NULL; } +extern HRESULT WINAPI sBlt(char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL); + /* ------------------------------------------------------------------------------ */ // auxiliary (static) functions /* ------------------------------------------------------------------------------ */ @@ -456,7 +458,7 @@ static void DumpSurfaceAttributes(LPDDSURFACEDESC lpddsd, char *label, int line) LogSurfaceAttributes(lpddsd, label, line); } -static void DescribeSurface(LPDIRECTDRAWSURFACE lpdds, int dxversion, char *label, int line) +void DescribeSurface(LPDIRECTDRAWSURFACE lpdds, int dxversion, char *label, int line) { DDSURFACEDESC2 ddsd; HRESULT res; @@ -1515,7 +1517,7 @@ static void HandleCapsD(char *sLabel, LPDDCAPS c) HRESULT WINAPI extGetCapsD(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2) { HRESULT res; - OutTraceDDRAW("GetCaps(D): lpdd=%x\n", lpdd); + OutTraceDDRAW("GetCaps(D): lpdd=%x %s %s\n", lpdd, c1?"c1":"NULL", c2?"c2":"NULL"); res=(*pGetCapsD)(lpdd, c1, c2); if(res) OutTraceE("GetCaps(D): ERROR res=%x(%s)\n", res, ExplainDDError(res)); @@ -1539,6 +1541,10 @@ HRESULT WINAPI extGetCapsD(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2) memcpy((void *)c1, (void *)c2, size); if(c1->dwVidMemTotal == 0) c1->dwVidMemTotal=dwVidMemTotal; if(c1->dwVidMemFree == 0) c1->dwVidMemFree =dwVidMemFree; + if(c1->dwVidMemTotal == 0) c1->dwVidMemTotal=0x20000000; // 500 MB + if(c1->dwVidMemFree == 0) c1->dwVidMemFree =0x20000000; // 500 MB + if (c1) HandleCapsD("D-HW(fixed)", c1); + if (c2) HandleCapsD("D-SW(fixed)", c2); } if(dxw.dwFlags3 & CAPMASK) MaskCapsD(c1, c2); @@ -2127,6 +2133,7 @@ static void FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd, int dxversion) { // rules of thumb: // 1) textures should be left untouched (switching to SYSTEMMEMORY when forcing HEL may even fail!) + // 1.1) textures with no DDSD_PIXELFORMAT specification should have one when virtual color depth is not equal to real color depth? // 2) if a pixel format is specified, if DDSCAPS_SYSTEMMEMORY add DDSCAPS_OFFSCREENPLAY (if pixel formats are different?), otherwise do not touch anything. // 3) if the surface is used as a buffer (DDSD_WIDTH set, DDSD_HEIGHT unset) do not touch anything. // 4) zbuffer surfaces (DDSCAPS_ZBUFFER set) must have DDSCAPS_SYSTEMMEMORY @@ -2144,6 +2151,11 @@ static void FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd, int dxversion) lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; lpddsd->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; } + if((dxw.dwFlags5 & TEXTUREFORMAT) && !(lpddsd->dwFlags & DDSD_PIXELFORMAT)){ + // TEXTURE: enforce PIXELFORMAT on MEMORY + lpddsd->dwFlags |= DDSD_PIXELFORMAT; + GetPixFmt(lpddsd); + } return; } @@ -2375,7 +2387,7 @@ static HRESULT BuildBackBufferEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS // create BackBuffer surface memcpy(&ddsd, lpddsd, lpddsd->dwSize); - ddsd.dwFlags &= ~(DDSD_WIDTH|DDSD_HEIGHT|DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE); + ddsd.dwFlags &= ~(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 @@ -2474,9 +2486,8 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf // on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it.... if(dxw.dwFlags5 & NOSYSTEMMEMORY) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; - DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic]" , __LINE__); res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, pu); - if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && (res==DDERR_OUTOFVIDEOMEMORY)){ + if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && (res!=DD_OK)){ OutTraceDW("CreateSurface ERROR: res=%x(%s) at %d, retry\n", res, ExplainDDError(res), __LINE__); ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; @@ -2486,6 +2497,8 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf OutTraceE("CreateSurface: ERROR on Emu_Generic res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); return res; } + + DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic]" , __LINE__); OutTraceDW("CreateSurface: created Emu_Generic dds=%x\n", *lplpdds); if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSEmu_Generic", __LINE__); @@ -2691,14 +2704,16 @@ static HRESULT WINAPI extCreateSurface(int dxversion, CreateSurface_Type pCreate // if nothing else, it's a generic/zbuffer surface - if(lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) { - lpDDZBuffer=*lplpdds; - DDZBufferCaps = lpddsd->ddsCaps.dwCaps; - OutTraceDW("CreateSurface: lpDDZBuffer=%x save ZBUFFER caps=%x(%s)\n", lpDDZBuffer, DDZBufferCaps, ExplainDDSCaps(DDZBufferCaps)); + res=BuildGeneric(lpdd, pCreateSurface, lpddsd, dxversion, lplpdds, pu); + if(!res) { + dxw.MarkRegularSurface(*lplpdds); + if(lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) { + lpDDZBuffer=*lplpdds; + DDZBufferCaps = lpddsd->ddsCaps.dwCaps; + OutTraceDW("CreateSurface: lpDDZBuffer=%x save ZBUFFER caps=%x(%s)\n", lpDDZBuffer, DDZBufferCaps, ExplainDDSCaps(DDZBufferCaps)); + } } - res=BuildGeneric(lpdd, pCreateSurface, lpddsd, dxversion, lplpdds, pu); - if(!res) dxw.MarkRegularSurface(*lplpdds); return res; } @@ -2814,7 +2829,7 @@ HRESULT WINAPI extGetAttachedSurface7(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpdds return extGetAttachedSurface(7, pGetAttachedSurface7, lpdds, lpddsc, lplpddas); } -static void BlitError(HRESULT res, LPRECT lps, LPRECT lpd, int line) +void BlitError(HRESULT res, LPRECT lps, LPRECT lpd, int line) { OutTrace("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), line); if (res==DDERR_INVALIDRECT){ @@ -2831,7 +2846,7 @@ static void BlitError(HRESULT res, LPRECT lps, LPRECT lpd, int line) return; } -static void BlitTrace(char *label, LPRECT lps, LPRECT lpd, int line) +void BlitTrace(char *label, LPRECT lps, LPRECT lpd, int line) { extern HANDLE hTraceMutex; WaitForSingleObject(hTraceMutex, INFINITE); @@ -3144,347 +3159,6 @@ HRESULT WINAPI ColorConversionDDRAW(LPDIRECTDRAWSURFACE lpdds, RECT emurect, LPD return DD_OK; } -static HRESULT sBltNoPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, - LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx) -{ - RECT srcrect; - HRESULT res; - BOOL FromScreen; - //extern PrimaryBlt_Type pPrimaryBlt; - //CkArg arg; - - FromScreen=dxw.IsAPrimarySurface(lpddssrc) && !(dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags1 & EMULATEBUFFER); // v2.02.77 - - // 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); - } - } - - if (IsDebug) BlitTrace("NOPRIM", lpsrcrect, lpdestrect, __LINE__); - 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. - // Wrong guess!!! The cause was not compression, but simply a pixelformat mismatch. Better - // configure things properly and avoid this branch. - switch(res){ - case DDERR_UNSUPPORTED: - if (dxw.dwFlags1 & EMULATESURFACE){ - RECT targetrect; - if (IsDebug) BlitTrace("UNSUPP", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__); - targetrect=*lpdestrect; - dxw.MapWindowRect(&targetrect); - res=(*pBlt)(lpDDSEmu_Prim, &targetrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx); - } - break; - case DDERR_SURFACEBUSY: - (*pUnlockMethod(lpdds))(lpdds, NULL); - if (lpddssrc) (*pUnlockMethod(lpddssrc))(lpddssrc, NULL); - if (IsDebug) BlitTrace("BUSY", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__); - res=(*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags|DDBLT_WAIT, lpddbltfx); - break; - default: - break; - } - if (res) BlitError(res, &srcrect, lpdestrect, __LINE__); - if(IsDebug) { - DescribeSurface(lpdds, 0, "[DST]" , __LINE__); - if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!! - } - if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; - if(dxw.dwFlags5 & TEXTUREMASK) { - // Texture Handling on Blt - TextureHandling(lpdds); - } - return res; - } - -static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, - LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping) -{ - HRESULT res; - RECT destrect, emurect; - extern PrimaryBlt_Type pPrimaryBlt; - - // debug suppressions - if(isFlipping){ - if(dxw.dwFlags3 & NODDRAWFLIP) return DD_OK; - } - else { - if(dxw.dwFlags3 & NODDRAWBLT) return DD_OK; - } - -#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 -#if FIXBIGGERRECT - if(lpdestrect){ - if((DWORD)lpdestrect->top < 0) lpdestrect->top = 0; - if((DWORD)lpdestrect->left < 0) lpdestrect->left = 0; - if((DWORD)lpdestrect->bottom > dxw.GetScreenHeight()) lpdestrect->bottom = dxw.GetScreenHeight(); - if((DWORD)lpdestrect->right > dxw.GetScreenWidth()) lpdestrect->right = dxw.GetScreenWidth(); - } -#endif - - if(dxw.dwFlags5 & QUARTERBLT){ - BOOL QuarterUpdate; - QuarterUpdate = lpdestrect ? - (((lpdestrect->bottom - lpdestrect->top) * (lpdestrect->right - lpdestrect->left)) > ((LONG)(dxw.GetScreenHeight() * dxw.GetScreenWidth()) >> 2)) - : - TRUE; - if(QuarterUpdate) if(dxw.HandleFPS()) return DD_OK; - } - else - if(dxw.HandleFPS()) return DD_OK; - if(dxw.dwFlags5 & NOBLT) return DD_OK; - - destrect=dxw.MapWindowRect(lpdestrect); - OutTraceB("DESTRECT=(%d,%d)-(%d,%d) Screen=(%dx%d)\n", - destrect.left, destrect.top, destrect.right, destrect.bottom, - dxw.GetScreenWidth(), dxw.GetScreenHeight()); - - if(!lpddssrc) { - if (isFlipping){ - // handle the flipping chain ... - lpddssrc=lpDDSBack; - OutTraceDW("Flip: setting flip chain to lpdds=%x\n", lpddssrc); - } - } - - // ========================= - // Blit to primary direct surface - // ========================= - - if(!(dxw.dwFlags1 & (EMULATESURFACE|EMULATEBUFFER))){ - res=DD_OK; - - // blit only when source and dest surface are different. Should make ScreenRefresh faster. - if (lpdds != lpddssrc) { - dxw.ShowOverlay(lpddssrc); - if (IsDebug) BlitTrace("PRIM-NOEMU", lpsrcrect, &destrect, __LINE__); - res=(*pPrimaryBlt)(lpdds, &destrect, lpddssrc, lpsrcrect); - } - if(res){ - BlitError(res, lpsrcrect, &destrect, __LINE__); - if(IsDebug) { - DescribeSurface(lpdds, 0, "[DST]" , __LINE__); - if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!! - } - // Try to handle HDC lock concurrency.... - if(res==DDERR_SURFACEBUSY){ - (*pUnlockMethod(lpdds))(lpdds, NULL); - if (IsDebug) BlitTrace("BUSY", lpsrcrect, &destrect, __LINE__); - res= (*pBlt)(lpdds, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); - if (res) BlitError(res, lpsrcrect, &destrect, __LINE__); - } - // 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; - } - - return res; - } - - // ... else blitting on emulated surface - - // ========================= - // Blit/Flip to emulated primary surface - // ========================= - - if(dxw.dwFlags5 & GDIMODE){ - extern void BlitToWindow(HWND, LPDIRECTDRAWSURFACE); - if (lpdds != lpddssrc) BlitToWindow(dxw.GethWnd(), lpddssrc); - return DD_OK; - } - - 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){ - if (IsDebug) BlitTrace("SRC2EMU", &emurect, &destrect, __LINE__); - if(destrect.top == -32000) return DD_OK; // happens when window is minimized & do not notify on task switch ... - res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); - } - - if (res) { - BlitError(res, lpsrcrect, &emurect, __LINE__); - DescribeSurface(lpdds, 0, "[DST]" , __LINE__); - if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!! - /* - 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. The error code is DDERR_UNSUPPORTED. - v2.02.98 update.... - The same thing happens with New York Racer, but with DDERR_EXCEPTION error code. - */ - if((res==DDERR_UNSUPPORTED) || (res==DDERR_EXCEPTION)){ - dxw.ShowOverlay(lpddssrc); - if (IsDebug) BlitTrace("UNSUPP", &emurect, &destrect, __LINE__); - 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)); - if (IsDebug) BlitTrace("BUSY", &emurect, &destrect, __LINE__); - res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); - if (res) BlitError(res, lpsrcrect, &destrect, __LINE__); - } - - if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; - return res; - } - - LPDIRECTDRAWSURFACE lpDDSSource; - if (res=(*pColorConversion)(lpdds, emurect, &lpDDSSource)) { - OutTraceE("sBlt ERROR: Color conversion failed res=%d(%s)\n", res, ExplainDDError(res)); - if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; - return res; - } - - dxw.ShowOverlay(lpDDSSource); - if (IsDebug) BlitTrace("BACK2PRIM", &emurect, &destrect, __LINE__); - res=(*pPrimaryBlt)(lpDDSEmu_Prim, &destrect, lpDDSSource, &emurect); - - if (res) BlitError(res, &emurect, &destrect, __LINE__); - if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; - if (IsDebug) OutTrace("%s: done ret=%x at %d\n", api, res, __LINE__); - return res; -} - -HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, - LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping) -{ - POINT p = {0, 0}; - HRESULT res; - BOOL ToPrim, FromPrim, ToScreen, FromScreen; - - if(dxw.dwFlags5 & MESSAGEPUMP){ - MSG msg; - while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){ - OutTraceW("MESSAGEPUMP: msg=%x l-wParam=(%x,%x)\n", msg.message, msg.lParam, msg.wParam); - if((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST)) break; // do not consume keyboard inputs - PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - ToPrim=dxw.IsAPrimarySurface(lpdds); - FromPrim=dxw.IsAPrimarySurface(lpddssrc); - ToScreen=ToPrim && !(dxw.dwFlags1 & EMULATESURFACE); - FromScreen=FromPrim && !(dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags1 & EMULATEBUFFER); // v2.02.77 - - CleanRect(&lpdestrect,__LINE__); - CleanRect(&lpsrcrect,__LINE__); - - // log - if(IsTraceDW){ - char sLog[256]; - char sInfo[128]; - sprintf(sLog, "%s: dest=%x%s src=%x%s dwFlags=%x(%s)", - api, lpdds, (ToPrim ? "(PRIM)":""), lpddssrc, (FromPrim ? "(PRIM)":""), dwflags, ExplainBltFlags(dwflags)); - if (lpdestrect) - sprintf(sInfo, " destrect=(%d,%d)-(%d,%d)", lpdestrect->left, lpdestrect->top, lpdestrect->right, lpdestrect->bottom); - else - sprintf(sInfo, " destrect=(NULL)"); - strcat(sLog, sInfo); - if (lpsrcrect) - sprintf(sInfo, " srcrect=(%d,%d)-(%d,%d)", lpsrcrect->left, lpsrcrect->top, lpsrcrect->right, lpsrcrect->bottom); - else - 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); - } - if (dwflags & DDBLT_DEPTHFILL){ - sprintf(sInfo, " ddbltfx.FillDepth=%x", lpddbltfx->dwFillDepth); - strcat(sLog, sInfo); - } - } - strcat(sLog,"\n"); - OutTrace(sLog); - } - - if(ToPrim) - res = sBltToPrimary(api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx, isFlipping); - else - res = sBltNoPrimary(api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); - - return res; -} - HRESULT WINAPI extFlip(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, DWORD dwflags) { BOOL IsPrim; @@ -4582,7 +4256,7 @@ HRESULT WINAPI extEnumAttachedSurfaces(LPDIRECTDRAWSURFACE lpdds, LPVOID lpConte HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd) { HRESULT res; - BOOL IsPrim; + BOOL IsPrim, IsBack; // You can add backbuffers to primary surfaces to join the flipping chain, but you can't do that // to an emulated primary surface, and you receive a DDERR_CANNOTATTACHSURFACE error code. @@ -4591,7 +4265,9 @@ HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURF // But beware: this holds to BACKBUFFER surfaces only, and NOT for attached ZBUFFERS or similar! IsPrim=dxw.IsAPrimarySurface(lpdds); - OutTraceDDRAW("AddAttachedSurface: lpdds=%x%s lpddsadd=%x\n", lpdds, IsPrim?"(PRIM)":"", lpddsadd); + IsBack=dxw.IsABackBufferSurface(lpdds); + OutTraceDDRAW("AddAttachedSurface: lpdds=%x%s lpddsadd=%x%s\n", lpdds, IsPrim?"(PRIM)":(IsBack?"(BACK)":""), lpddsadd, (lpddsadd==lpDDZBuffer)?"(ZBUF)":""); + //if(!lpddsadd) return DDERR_CANNOTATTACHSURFACE; // to avoid a crash... res=(*pAddAttachedSurface)(lpdds, lpddsadd); if (res) { @@ -4613,7 +4289,7 @@ HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURF if (pAddRefS) (*pAddRefS)(lpdds); res=DD_OK; } - else if (lpdds == lpDDSBack) { + else if (IsBack) { // 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. diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp index b6e6f50..1aa22da 100644 --- a/dll/dxwcore.cpp +++ b/dll/dxwcore.cpp @@ -1413,6 +1413,7 @@ void dxwCore::ShowBanner(HWND hwnd) RECT client; RECT win; POINT PrevViewPort; + int StretchMode; hClientDC=(*pGDIGetDC)(hwnd); (*pGetClientRect)(hwnd, &client); @@ -1432,6 +1433,8 @@ void dxwCore::ShowBanner(HWND hwnd) //if(!pSetViewportOrgEx) pSetViewportOrgEx=SetViewportOrgEx; (*pSetViewportOrgEx)(hClientDC, 0, 0, &PrevViewPort); + StretchMode=GetStretchBltMode(hClientDC); + SetStretchBltMode(hClientDC, HALFTONE); for (int i=1; i<=16; i++){ int w, h; w=(bm.bmWidth*i)/8; @@ -1447,6 +1450,7 @@ void dxwCore::ShowBanner(HWND hwnd) (*pGDIStretchBlt)(hClientDC, (client.right-w)/2, (client.bottom-h)/2, w, h, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); Sleep(40); } + SetStretchBltMode(hClientDC, StretchMode); (*pSetViewportOrgEx)(hClientDC, PrevViewPort.x, PrevViewPort.y, NULL); SelectObject(hdcMem, hbmOld); DeleteDC(hdcMem); diff --git a/dll/dxwnd.aps b/dll/dxwnd.aps index be1bf61..e6a97c4 100644 Binary files a/dll/dxwnd.aps and b/dll/dxwnd.aps differ diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 14f8ed0..16e2f03 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -27,7 +27,7 @@ along with this program. If not, see . #include "TlHelp32.h" -#define VERSION "2.03.08" +#define VERSION "2.03.09" #define DDTHREADLOCK 1 //#define LOCKTHREADS @@ -176,7 +176,11 @@ int SetTarget(TARGETMAP *targets){ for(i = 0; targets[i].path[0]; i ++){ char *c; pMapping[i] = targets[i]; - GetFullPathName(targets[i].path, MAX_PATH, path, NULL); + c = targets[i].path; + if(*c == '*') + strcpy(path, targets[i].path); + else + GetFullPathName(targets[i].path, MAX_PATH, path, NULL); for(c = path; *c; c++) *c = tolower(*c); strcpy(pMapping[i].path, path); } diff --git a/dll/dxwnd.def b/dll/dxwnd.def index 2b4fd5a..a4d06bb 100644 --- a/dll/dxwnd.def +++ b/dll/dxwnd.def @@ -1,8 +1,10 @@ LIBRARY dxwnd EXPORTS - SetTarget @1 - StartHook @2 - EndHook @3 - GetDllVersion @4 - GetHookStatus @5 - GetHookInfo @6 + SetTarget @1 + StartHook @2 + EndHook @3 + GetDllVersion @4 + GetHookStatus @5 + GetHookInfo @6 + Inject @7 + GetThreadStartAddress @8 diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index 0154b49..0be041d 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/dxwnd.vs2008.vcproj b/dll/dxwnd.vs2008.vcproj index 6b69dfd..e0816fe 100644 --- a/dll/dxwnd.vs2008.vcproj +++ b/dll/dxwnd.vs2008.vcproj @@ -233,6 +233,10 @@ RelativePath=".\d3dtexture.cpp" > + + diff --git a/dll/gdiblt.cpp b/dll/gdiblt.cpp index 8b386f3..134994b 100644 --- a/dll/gdiblt.cpp +++ b/dll/gdiblt.cpp @@ -40,6 +40,10 @@ void BlitToWindow(HWND w, LPDIRECTDRAWSURFACE s) if(!ret) OutTrace("BitBlt error=%d\n", GetLastError()); } else{ + if(dxw.dwFlags5 & BILINEARFILTER) { + ret=SetStretchBltMode(thdc, HALFTONE); + if((!ret) || (ret==ERROR_INVALID_PARAMETER)) OutTrace("GDI SetStretchBltMode error=%d\n", GetLastError()); + } ret=(*pGDIStretchBlt)(thdc, 0, 0, client.right, client.bottom, shdc, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight(), SRCCOPY); if(!ret) OutTrace("GDI StretchBlt error=%d\n", GetLastError()); } diff --git a/dll/hd3d7.cpp b/dll/hd3d7.cpp index 8fa743c..a4513eb 100644 --- a/dll/hd3d7.cpp +++ b/dll/hd3d7.cpp @@ -1,5 +1,8 @@ +#define _CRT_SECURE_NO_WARNINGS + #include #include +#include #include "dxwnd.h" #include "dxwcore.hpp" #include "dxhook.h" @@ -32,6 +35,7 @@ typedef HRESULT (WINAPI *FindDevice_Type)(void *, LPD3DFINDDEVICESEARCH, LPD3DFI typedef HRESULT (WINAPI *CreateDevice2_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE, LPDIRECT3DDEVICE2 *); typedef HRESULT (WINAPI *CreateDevice3_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE4, LPDIRECT3DDEVICE3 *, LPUNKNOWN); typedef HRESULT (WINAPI *CreateDevice7_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE7, LPDIRECT3DDEVICE7 *); +typedef HRESULT (WINAPI *EnumZBufferFormats_Type)(void *, REFCLSID, LPD3DENUMPIXELFORMATSCALLBACK, LPVOID); QueryInterfaceD3_Type pQueryInterfaceD3 = NULL; Initialize_Type pInitialize = NULL; @@ -46,6 +50,9 @@ FindDevice_Type pFindDevice = NULL; CreateDevice2_Type pCreateDevice2 = NULL; CreateDevice3_Type pCreateDevice3 = NULL; CreateDevice7_Type pCreateDevice7 = NULL; +EnumZBufferFormats_Type pEnumZBufferFormats = NULL; + +HRESULT WINAPI extEnumZBufferFormats(void *, REFCLSID, LPD3DENUMPIXELFORMATSCALLBACK, LPVOID); // Direct3DDevice-n interfaces @@ -216,6 +223,89 @@ HRESULT WINAPI extTexUnload(void *); extern char *ExplainDDError(DWORD); int GD3DDeviceVersion; +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; +} + +char *DumpPixelFormat(LPDDPIXELFORMAT ddpfPixelFormat) +{ + static char sBuf[512]; + char sItem[256]; + DWORD flags=ddpfPixelFormat->dwFlags; + sprintf(sBuf, " PixelFormat flags=%x(%s) BPP=%d", + flags, ExplainPixelFormatFlags(flags), ddpfPixelFormat->dwRGBBitCount); + if (flags & DDPF_RGB) { + if (flags & DDPF_ALPHAPIXELS) { + sprintf(sItem, " RGBA=(%x,%x,%x,%x)", + ddpfPixelFormat->dwRBitMask, + ddpfPixelFormat->dwGBitMask, + ddpfPixelFormat->dwBBitMask, + ddpfPixelFormat->dwRGBAlphaBitMask); + } + else { + sprintf(sItem, " RGB=(%x,%x,%x)", + ddpfPixelFormat->dwRBitMask, + ddpfPixelFormat->dwGBitMask, + ddpfPixelFormat->dwBBitMask); + } + strcat(sBuf, sItem); + } + if (flags & DDPF_YUV) { + sprintf(sItem, " YUVA=(%x,%x,%x,%x)", + ddpfPixelFormat->dwYBitMask, + ddpfPixelFormat->dwUBitMask, + ddpfPixelFormat->dwVBitMask, + ddpfPixelFormat->dwYUVAlphaBitMask); + strcat(sBuf, sItem); + } + if (flags & DDPF_ZBUFFER) { + sprintf(sItem, " SdZSbL=(%x,%x,%x,%x)", + ddpfPixelFormat->dwStencilBitDepth, + ddpfPixelFormat->dwZBitMask, + ddpfPixelFormat->dwStencilBitMask, + ddpfPixelFormat->dwLuminanceAlphaBitMask); + strcat(sBuf, sItem); + } + if (flags & DDPF_ALPHA) { + sprintf(sItem, " LBdBlZ=(%x,%x,%x,%x)", + ddpfPixelFormat->dwLuminanceBitMask, + ddpfPixelFormat->dwBumpDvBitMask, + ddpfPixelFormat->dwBumpLuminanceBitMask, + ddpfPixelFormat->dwRGBZBitMask); + strcat(sBuf, sItem); + } + if (flags & DDPF_LUMINANCE) { + sprintf(sItem, " BMbMF=(%x,%x,%x,%x)", + ddpfPixelFormat->dwBumpDuBitMask, + ddpfPixelFormat->MultiSampleCaps.wBltMSTypes, + ddpfPixelFormat->MultiSampleCaps.wFlipMSTypes, + ddpfPixelFormat->dwYUVZBitMask); + strcat(sBuf, sItem); + } + if (flags & DDPF_BUMPDUDV) { + sprintf(sItem, " O=(%x)", + ddpfPixelFormat->dwOperations); + strcat(sBuf, sItem); + } + if (flags & DDPF_FOURCC) { + sprintf(sItem, " FourCC=%x(%s)", + ddpfPixelFormat->dwFourCC, sFourCC(ddpfPixelFormat->dwFourCC)); + strcat(sBuf, sItem); + } + return sBuf; +} + int HookDirect3D7(HMODULE module, int version){ void *tmp; HINSTANCE hinst; @@ -305,6 +395,7 @@ void HookDirect3DSession(LPDIRECTDRAW *lplpdd, int d3dversion) SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateViewport3, (void **)&pCreateViewport3, "CreateViewport(3)"); SetHook((void *)(**(DWORD **)lplpdd + 28), extFindDevice, (void **)&pFindDevice, "FindDevice"); SetHook((void *)(**(DWORD **)lplpdd + 32), extCreateDevice3, (void **)&pCreateDevice3, "CreateDevice(D3D3)"); + SetHook((void *)(**(DWORD **)lplpdd + 40), extEnumZBufferFormats, (void **)&pEnumZBufferFormats, "EnumZBufferFormats(D3D3)"); break; case 7: SetHook((void *)(**(DWORD **)lplpdd + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3S)"); @@ -1420,3 +1511,30 @@ HRESULT WINAPI extTexUnload(void *t) if(ret) OutTraceE("Texture::Load ERROR res=%x(%s)\n", ret, ExplainDDError(ret)); return ret; } + +typedef struct { + LPD3DENUMPIXELFORMATSCALLBACK *cb; + LPVOID arg; +} CallbackZBufArg; + +HRESULT WINAPI extZBufferProxy(LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpContext) +{ + HRESULT res; + OutTraceD3D("EnumZBufferFormats: CALLBACK PixelFormat=%x(%s) context=%x\n", lpDDPixFmt->dwFlags, lpContext); + res = (*(((CallbackZBufArg *)lpContext)->cb))(lpDDPixFmt, ((CallbackZBufArg *)lpContext)->arg); + OutTraceD3D("EnumDevices: CALLBACK ret=%x\n", res); + return res; +} + +HRESULT WINAPI extEnumZBufferFormats(void *lpd3d, REFCLSID riidDevice, LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback, LPVOID lpContext) +{ + HRESULT ret; + CallbackZBufArg Arg; + OutTrace("Direct3D::EnumZBufferFormats d3d=%x clsid=%x context=%x\n", lpd3d, riidDevice.Data1, lpContext); + Arg.cb= &lpEnumCallback; + Arg.arg=lpContext; + ret = (*pEnumZBufferFormats)(lpd3d, riidDevice, (LPD3DENUMPIXELFORMATSCALLBACK)extZBufferProxy, (LPVOID)&Arg); + OutTraceE("Direct3D::EnumZBufferFormats res=%x(%s)\n", ret, ExplainDDError(ret)); + return ret; +} + diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp index 268e46e..1247f80 100644 --- a/dll/kernel32.cpp +++ b/dll/kernel32.cpp @@ -853,6 +853,9 @@ BOOL WINAPI extCreateProcessA( } #endif OutTrace("CreateProcess: injection started\n", res); + CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hProcess); + CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hThread); + CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hFile); break; case EXIT_THREAD_DEBUG_EVENT: #ifdef LOCKINJECTIONTHREADS @@ -881,8 +884,16 @@ BOOL WINAPI extCreateProcessA( debug_event.u.Exception.dwFirstChance); // exception twice in same address, then do not continue. if(LastExceptionPtr == ei->ExceptionRecord.ExceptionAddress) bContinueDebugging = FALSE; + //if(ei->dwFirstChance == 0) bContinueDebugging = FALSE; LastExceptionPtr = ei->ExceptionRecord.ExceptionAddress; } + break; + case LOAD_DLL_DEBUG_EVENT: + CloseHandle(((LOAD_DLL_DEBUG_INFO *)&debug_event.u)->hFile); + break; + case CREATE_THREAD_DEBUG_EVENT: + CloseHandle(((CREATE_THREAD_DEBUG_INFO *)&debug_event.u)->hThread); + break; default: break; } diff --git a/host/Inject.cpp b/host/Inject.cpp deleted file mode 100644 index cca0596..0000000 --- a/host/Inject.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "stdafx.h" -#include -#include -#include -#include -#include - -#include - -#define WIN32_LEAN_AND_MEAN - -#define true 1 -#define false 0 - -BOOL Inject(DWORD pID, const char * DLL_NAME) -{ - HANDLE Proc; - char buf[50] = {0}; - LPVOID RemoteString, LoadLibAddy; - if(!pID) return false; - //Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // not working on Win XP - Proc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pID); - if(!Proc) - { - sprintf(buf, "OpenProcess() failed: pid=%x err=%d", pID, GetLastError()); - MessageBox(NULL, buf, "Loader", MB_OK); - printf(buf); - return false; - } - LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); - // Allocate space in the process for our DLL - RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - // Write the string name of our DLL in the memory allocated - WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL); - // Load our DLL - CreateRemoteThread(Proc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, 0, NULL); - CloseHandle(Proc); - return true; -} - -#define STATUS_SUCCESS ((NTSTATUS)0x000 00000L) -#define ThreadQuerySetWin32StartAddress 9 - -LPVOID GetThreadStartAddress(HANDLE hThread) -{ - NTSTATUS ntStatus; - HANDLE hDupHandle; - HMODULE hLibNTHandle; - LPVOID dwStartAddress; - - typedef NTSTATUS (WINAPI *NtQueryInformationThread_Type)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG); - hLibNTHandle = GetModuleHandle("ntdll.dll"); - if(!hLibNTHandle) return 0; - - NtQueryInformationThread_Type NtQueryInformationThread = - (NtQueryInformationThread_Type)GetProcAddress(hLibNTHandle, "NtQueryInformationThread"); - - if(NtQueryInformationThread == NULL) return 0; - - HANDLE hCurrentProcess = GetCurrentProcess(); - if(!DuplicateHandle(hCurrentProcess, hThread, hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){ - SetLastError(ERROR_ACCESS_DENIED); - return 0; - } - - ntStatus = NtQueryInformationThread(hDupHandle, (THREADINFOCLASS)ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD), NULL); - CloseHandle(hDupHandle); - CloseHandle(hLibNTHandle); - //if(ntStatus != STATUS_SUCCESS) return 0; - - return dwStartAddress; -} \ No newline at end of file diff --git a/host/Resource.h b/host/Resource.h index d7d2175..f4f11c7 100644 Binary files a/host/Resource.h and b/host/Resource.h differ diff --git a/host/TabDirectX.cpp b/host/TabDirectX.cpp index 343ac33..f419f72 100644 --- a/host/TabDirectX.cpp +++ b/host/TabDirectX.cpp @@ -32,6 +32,7 @@ void CTabDirectX::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_SUPPRESSCLIPPING, cTarget->m_SuppressClipping); DDX_Check(pDX, IDC_BLITFROMBACKBUFFER, cTarget->m_BlitFromBackBuffer); DDX_Check(pDX, IDC_AUTOREFRESH, cTarget->m_AutoRefresh); + DDX_Check(pDX, IDC_TEXTUREFORMAT, cTarget->m_TextureFormat); DDX_Check(pDX, IDC_VIDEOTOSYSTEMMEM, cTarget->m_VideoToSystemMem); DDX_Check(pDX, IDC_SUPPRESSDXERRORS, cTarget->m_SuppressDXErrors); DDX_Check(pDX, IDC_BACKBUFATTACH, cTarget->m_BackBufAttach); diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 290dc6c..8191f9f 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -96,6 +96,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_SuppressClipping = FALSE; m_DisableGammaRamp = FALSE; m_AutoRefresh = FALSE; + m_TextureFormat = FALSE; m_FixWinFrame = FALSE; m_EnableClipping = FALSE; m_CursorClipping = FALSE; diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 98db7a8..d7d5024 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -76,6 +76,7 @@ public: BOOL m_SuppressClipping; BOOL m_DisableGammaRamp; BOOL m_AutoRefresh; + BOOL m_TextureFormat; BOOL m_FixWinFrame; BOOL m_EnableClipping; BOOL m_CursorClipping; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index eb7f173..409a30b 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index f9e61af..615043a 100644 Binary files a/host/dxwndhost.rc and b/host/dxwndhost.rc differ diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index 26961b3..c0f8855 100644 Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ diff --git a/host/dxwndhost.vs2008.vcproj b/host/dxwndhost.vs2008.vcproj index 50c6eb3..16172cb 100644 --- a/host/dxwndhost.vs2008.vcproj +++ b/host/dxwndhost.vs2008.vcproj @@ -323,10 +323,6 @@ RelativePath=".\host.rc" > - - diff --git a/host/dxwndhostView.cpp b/host/dxwndhostView.cpp index 1c6afd9..2e689d1 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -35,7 +35,6 @@ TARGETMAP *pTargets; // idem. #define LOCKINJECTIONTHREADS - static char *Escape(char *s) { static char tmp[1024]; @@ -276,6 +275,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_SuppressClipping) t->flags |= SUPPRESSCLIPPING; if(dlg->m_DisableGammaRamp) t->flags2 |= DISABLEGAMMARAMP; if(dlg->m_AutoRefresh) t->flags |= AUTOREFRESH; + if(dlg->m_TextureFormat) t->flags5 |= TEXTUREFORMAT; if(dlg->m_FixWinFrame) t->flags |= FIXWINFRAME; if(dlg->m_EnableClipping) t->flags |= ENABLECLIPPING; if(dlg->m_CursorClipping) t->flags |= CLIPCURSOR; @@ -482,6 +482,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_SuppressClipping = t->flags & SUPPRESSCLIPPING ? 1 : 0; dlg->m_DisableGammaRamp = t->flags2 & DISABLEGAMMARAMP ? 1 : 0; dlg->m_AutoRefresh = t->flags & AUTOREFRESH ? 1 : 0; + dlg->m_TextureFormat = t->flags5 & TEXTUREFORMAT ? 1 : 0; dlg->m_FixWinFrame = t->flags & FIXWINFRAME ? 1 : 0; dlg->m_EnableClipping = t->flags & ENABLECLIPPING ? 1 : 0; dlg->m_CursorClipping = t->flags & CLIPCURSOR ? 1 : 0; @@ -1673,6 +1674,38 @@ void CDxwndhostView::OnRButtonDown(UINT nFlags, CPoint point) CListView::OnRButtonDown(nFlags, point); } +static char *ExceptionCaption(DWORD ec) +{ + char *c; + switch(ec){ + case EXCEPTION_ACCESS_VIOLATION: c="Access Violation"; break; + case EXCEPTION_DATATYPE_MISALIGNMENT: c="Datatype Misalignment"; break; + case EXCEPTION_BREAKPOINT: c="Breakpoint"; break; + case EXCEPTION_SINGLE_STEP: c="Single Step"; break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: c="Array Bouds Exceeded"; break; + case EXCEPTION_FLT_DENORMAL_OPERAND: c="Float Denormal Operand"; break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: c="Divide by Zero"; break; + case EXCEPTION_FLT_INEXACT_RESULT: c="Inexact Result"; break; + case EXCEPTION_FLT_INVALID_OPERATION: c="Invalid Operation"; break; + case EXCEPTION_FLT_OVERFLOW: c="Float Overflow"; break; + case EXCEPTION_FLT_STACK_CHECK: c="Float Stack Check"; break; + case EXCEPTION_FLT_UNDERFLOW: c="Float Undeflow"; break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: c="Integer Divide by Zero"; break; + case EXCEPTION_INT_OVERFLOW: c="Integer Overflow"; break; + case EXCEPTION_PRIV_INSTRUCTION: c="Priviliged Instruction"; break; + case EXCEPTION_IN_PAGE_ERROR: c="In Page Error"; break; + case EXCEPTION_ILLEGAL_INSTRUCTION: c="Illegal Instruction"; break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION:c="Non-continuable exception"; break; + case EXCEPTION_STACK_OVERFLOW: c="Stack Overflow"; break; + case EXCEPTION_INVALID_DISPOSITION: c="Invalid Disposition"; break; + case EXCEPTION_GUARD_PAGE: c="Guard Page Violation"; break; + case EXCEPTION_INVALID_HANDLE: c="Invalid Handle"; break; + //case EXCEPTION_POSSIBLE_DEADLOCK: c="Possible Deadlock"; break; + default: c="unknown"; break; + } + return c; +} + // For thread messaging #define DEBUG_EVENT_MESSAGE WM_APP + 0x100 @@ -1699,13 +1732,13 @@ DWORD WINAPI StartDebug(void *p) int res; BOOL step=TRUE; // initialize to TRUE to enable BOOL stepdll=FALSE; // initialize to TRUE to enable + extern char *GetFileNameFromHandle(HANDLE); #endif #ifdef LOCKINJECTIONTHREADS DWORD StartingCode; LPVOID StartAddress = 0; - DWORD TargetHandle = NULL; + HANDLE TargetHandle = NULL; #endif - extern char *GetFileNameFromHandle(HANDLE); bool bContinueDebugging; char DebugMessage[256+1]; @@ -1728,30 +1761,12 @@ DWORD WINAPI StartDebug(void *p) while(bContinueDebugging) { dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; - if (!WaitForDebugEvent(&debug_event, INFINITE)) return TRUE; + if (!WaitForDebugEvent(&debug_event, INFINITE)) break; // must release pinfo handles switch(debug_event.dwDebugEventCode){ case EXIT_PROCESS_DEBUG_EVENT: -#ifdef DXWDEBUGSTEPPING - if(step){ - // DXW_STRING_STEPPING - xpi=(EXIT_PROCESS_DEBUG_INFO *)&debug_event.u; - sprintf(DebugMessage, "EXIT PROCESS RetCode=%x", xpi->dwExitCode); - res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); - if(res!=IDYES) step=FALSE; - } -#endif bContinueDebugging=false; break; case CREATE_PROCESS_DEBUG_EVENT: -#ifdef DXWDEBUGSTEPPING - if(step){ - pi=(PROCESS_INFORMATION *)&debug_event.u; - sprintf(DebugMessage, "CREATE PROCESS hProcess=%x hThread=%x dwProcessId=%x dwThreadId=%x path=%s", - pi->hProcess, pi->hThread, pi->dwProcessId, pi->dwThreadId, GetFileNameFromHandle(pi->hProcess)); - res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); - if(res!=IDYES) step=FALSE; - } -#endif GetFullPathName("dxwnd.dll", MAX_PATH, path, NULL); if(!Inject(pinfo.dwProcessId, path)){ // DXW_STRING_INJECTION @@ -1763,20 +1778,14 @@ DWORD WINAPI StartDebug(void *p) DWORD EndlessLoop; EndlessLoop=0x9090FEEB; // careful: it's BIG ENDIAN: EB FE 90 90 SIZE_T BytesCount; - TargetHandle = (DWORD)OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pinfo.dwProcessId); + TargetHandle = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pinfo.dwProcessId); if(TargetHandle){ - //sprintf(DebugMessage,"OpenProcess returns=%x", TargetHandle); - //MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); StartAddress = GetThreadStartAddress(pinfo.hThread); - //sprintf(DebugMessage,"GetThreadStartAddress returns=%x", StartAddress); - //MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); if(StartAddress){ if(!ReadProcessMemory(pinfo.hProcess, StartAddress, &StartingCode, 4, &BytesCount)){ sprintf(DebugMessage,"ReadProcessMemory error=%d", GetLastError()); MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); } - //sprintf(DebugMessage,"ReadProcessMemory got=%x", StartingCode); - //MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); if(!WriteProcessMemory(pinfo.hProcess, StartAddress, &EndlessLoop, 4, &BytesCount)){ sprintf(DebugMessage,"WriteProcessMemory error=%d", GetLastError()); MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); @@ -1784,95 +1793,55 @@ DWORD WINAPI StartDebug(void *p) } } #endif + CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hProcess); + CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hThread); + CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hFile); break; case CREATE_THREAD_DEBUG_EVENT: -#ifdef DXWDEBUGSTEPPING - if(step){ - ti=(CREATE_THREAD_DEBUG_INFO *)&debug_event.u; - sprintf(DebugMessage, "CREATE THREAD hThread=%x lpThreadLocalBase=%x lpStartAddress=%x", - ti->hThread, ti->lpThreadLocalBase, ti->lpStartAddress); - res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); - if(res!=IDYES) step=FALSE; - } -#endif + CloseHandle(((CREATE_THREAD_DEBUG_INFO *)&debug_event.u)->hThread); break; case EXIT_THREAD_DEBUG_EVENT: -#ifdef DXWDEBUGSTEPPING - if(step){ - xti=(EXIT_THREAD_DEBUG_INFO *)&debug_event.u; - sprintf(DebugMessage, "EXIT THREAD RetCode=%x", xti->dwExitCode); - res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); - if(res!=IDYES) step=FALSE; - } -#endif #ifdef LOCKINJECTIONTHREADS if(TargetHandle && StartAddress){ - //sprintf(DebugMessage,"OpenProcess returns=%x", TargetHandle); - //MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); if(!WriteProcessMemory(pinfo.hProcess, StartAddress, &StartingCode, 4, &BytesCount)){ sprintf(DebugMessage,"WriteProcessMemory error=%d", GetLastError()); MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); } - //sprintf(DebugMessage,"WriteProcessMemory recovered=%x", StartingCode); - //MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); - CloseHandle((HANDLE)TargetHandle); } + if(TargetHandle) CloseHandle((HANDLE)TargetHandle); #endif bContinueDebugging=false; break; case LOAD_DLL_DEBUG_EVENT: -#ifdef DXWDEBUGSTEPPING - if(stepdll){ - li=(LOAD_DLL_DEBUG_INFO *)&debug_event.u; - sprintf(DebugMessage, "LOAD DLL hFile=%x path=%s", - li->hFile, GetFileNameFromHandle(li->hFile)); - res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); - if(res!=IDYES) stepdll=FALSE; - } -#endif + CloseHandle(((LOAD_DLL_DEBUG_INFO *)&debug_event.u)->hFile); break; case UNLOAD_DLL_DEBUG_EVENT: -#ifdef DXWDEBUGSTEPPING - if(stepdll){ - ui=(UNLOAD_DLL_DEBUG_INFO *)&debug_event.u; - sprintf(DebugMessage, "UNLOAD DLL Base=%x", ui->lpBaseOfDll); - res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); - if(res!=IDYES) stepdll=FALSE; - } -#endif break; case OUTPUT_DEBUG_STRING_EVENT: break; case EXCEPTION_DEBUG_EVENT: -#ifdef DXWDEBUGSTEPPING - if(step){ - ei=(EXCEPTION_DEBUG_INFO *)&debug_event.u; - sprintf(DebugMessage, "EXCEPTION code=%x flags=%x addr=%x firstchance=%x", - ei->ExceptionRecord.ExceptionCode, - ei->ExceptionRecord.ExceptionFlags, - ei->ExceptionRecord.ExceptionAddress, - debug_event.u.Exception.dwFirstChance); - res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); - if(res!=IDYES) step=FALSE; - } -#endif + //sprintf(DebugMessage, "Exception %x(%s) caught at addr=%x", + // debug_event.u.Exception.ExceptionRecord.ExceptionCode, + // ExceptionCaption(debug_event.u.Exception.ExceptionRecord.ExceptionCode), + // debug_event.u.Exception.ExceptionRecord.ExceptionAddress); + //MessageBoxEx(0, DebugMessage, "EXCEPTION", MB_ICONEXCLAMATION, NULL); break; default: + sprintf(DebugMessage,"Unknown eventcode=%x", debug_event.dwDebugEventCode); + MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); break; } if(bContinueDebugging){ - ContinueDebugEvent(debug_event.dwProcessId, - debug_event.dwThreadId, - dwContinueStatus); + ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, dwContinueStatus); } else{ DebugSetProcessKillOnExit(FALSE); ContinueDebugEvent(debug_event.dwProcessId,debug_event.dwThreadId, DBG_CONTINUE); DebugActiveProcessStop(debug_event.dwProcessId); - if (pinfo.hProcess) CloseHandle(pinfo.hProcess); - if (pinfo.hThread) CloseHandle(pinfo.hThread); } } + CloseHandle(pinfo.hThread); // no longer needed, avoid handle leakage + CloseHandle(pinfo.hProcess); // no longer needed, avoid handle leakage return TRUE; } @@ -1896,12 +1865,14 @@ void CDxwndhostView::OnRun() if(TargetMaps[i].flags2 & STARTDEBUG){ ThreadInfo.TM=&TargetMaps[i]; ThreadInfo.PM=&TitleMaps[i]; - CreateThread( NULL, 0, StartDebug, &ThreadInfo, 0, NULL); + CloseHandle(CreateThread( NULL, 0, StartDebug, &ThreadInfo, 0, NULL)); } else{ CreateProcess(NULL, (strlen(TitleMaps[i].launchpath)>0) ? TitleMaps[i].launchpath: TargetMaps[i].path, 0, 0, false, CREATE_DEFAULT_ERROR_MODE, NULL, path, &sinfo, &pinfo); + CloseHandle(pinfo.hProcess); // no longer needed, avoid handle leakage + CloseHandle(pinfo.hThread); // no longer needed, avoid handle leakage } } diff --git a/host/resource b/host/resource index f9e4c1b..d44c87c 100644 Binary files a/host/resource and b/host/resource differ