+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