diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 94b800e..5e11017 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -7,7 +7,6 @@ #define MAXTARGETS 256 -#define DXWACTIVATESINGLETASK 1 // comment to allow multiple task activations #define ONEPIXELFIX 1 // first flags DWORD dwFlags1: @@ -173,6 +172,7 @@ #define TRACEHOOKS 0x00000400 // log hook operations #define OUTD3DTRACE 0x00000800 // traces DxWnd direct3d screen handling #define OUTDXWINTRACE 0x00001000 // traces DxWnd internal operations +#define REMAPMCI 0x00002000 // remap MCI calls coordinates in mciSendString #define EMULATEFLAGS (EMULATEBUFFER | EMULATESURFACE | LOCKEDSURFACE) #define HANDLEFPS (SHOWFPS | SHOWFPSOVERLAY | LIMITFPS | SKIPFPS) diff --git a/build/Resources_CN.dll b/build/Resources_CN.dll index 7337cbb..3a23f3b 100644 --- a/build/Resources_CN.dll +++ b/build/Resources_CN.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b88d6c9d24ee068087275664ae0d9082c85e8424e47e7b177fbd026763a5631 +oid sha256:441255a55dfe46ee221c48c22ab6f091ee7d0c851e900abe2d866e2837580db1 size 132608 diff --git a/build/Resources_EN.dll b/build/Resources_EN.dll deleted file mode 100644 index f535033..0000000 --- a/build/Resources_EN.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:55f9e6985c7b7f0f5a538ad93199152d964f7d8dc4a552a7bed38fb93cc760e1 -size 116224 diff --git a/build/Resources_IT.dll b/build/Resources_IT.dll index 70f8408..b54d3de 100644 --- a/build/Resources_IT.dll +++ b/build/Resources_IT.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:02e79b180737b4f5e1989026e05e6c48065de39060d977c158ab286a87a5d940 +oid sha256:aff84e4a82ca05d2e25f680d370216a871fa466b01525e1aa60d66e895fcdead size 139264 diff --git a/build/Resources_RU.dll b/build/Resources_RU.dll new file mode 100644 index 0000000..b3e0cb0 --- /dev/null +++ b/build/Resources_RU.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31953821448e01fefdb6409799a8dac114cf7ef92cfa4f5b009559403e20a7b9 +size 141312 diff --git a/build/dxwnd.0.ini b/build/dxwnd.0.ini index d259038..b09eb5f 100644 --- a/build/dxwnd.0.ini +++ b/build/dxwnd.0.ini @@ -4,3 +4,13 @@ posy=50 sizx=320 sizy=200 lang=automatic +[keymapping] +timetoggle=0x72 +altf4=0x73 +timeslow=0x74 +timefast=0x75 +cliptoggle= +refresh= +logtoggle= +plocktoggle= +fpstoggle= diff --git a/build/dxwnd.dll b/build/dxwnd.dll index afa42c5..bc79458 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:768707a31acc1f63671cfd55c5a50d061b29db777bdf61b5439a42dea27c7c6a -size 525824 +oid sha256:322d82c850c81a6f45b224d9fe22ab45a18d9d725180702c6b1f2f41e5abcdb7 +size 534528 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 3ad4a83..ff8d5a4 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d802959c3ec0c17b5e1e7d58672c91b0223a9b3285725418cb44a73bbfe5b3d4 -size 558592 +oid sha256:88397843c92ba22bd48b166a9964201ee90431f17e9c1212a3349b857c039159 +size 559104 diff --git a/build/dxwnd.ini b/build/dxwnd.ini index 6f8d080..b09eb5f 100644 --- a/build/dxwnd.ini +++ b/build/dxwnd.ini @@ -1,6 +1,16 @@ [window] -posx=1182 -posy=638 +posx=50 +posy=50 sizx=320 sizy=200 lang=automatic +[keymapping] +timetoggle=0x72 +altf4=0x73 +timeslow=0x74 +timefast=0x75 +cliptoggle= +refresh= +logtoggle= +plocktoggle= +fpstoggle= diff --git a/build/exports/dxwnd.ini b/build/exports/dxwnd.ini index 35d043b..baaa080 100644 --- a/build/exports/dxwnd.ini +++ b/build/exports/dxwnd.ini @@ -1,5 +1,5 @@ [window] -posx=1347 -posy=477 -sizx=417 -sizy=450 +posx=1182 +posy=638 +sizx=320 +sizy=200 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index aa531af..6670631 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -623,3 +623,12 @@ fix: FPS handling to screen updated made by SetDIBitsToDevice fix: PeekMessage implementation with "Peek all message in queue": fixes "Shadow Watch" fix: missing hook to CreateProcess - needed for "Suppress child process creation". fix: exception for bilinear filtering applied to certain games (e.g. "Shadow Watch") + +v2.02.96 +fix: FPS inticator on window title was causing the program to become irresponsive (partial fix) +fix: proper setting of ddraw surface capabilities will allow primary surface emulation for most D3D1-7 games +fix: missing initialization of variables in screen size limit handling +fix: processing of mouse messages +fix: GetSystemMetrics and LoadLibrary* calls hooked by hot patching to fix "Wind Fantasy SP" movie problems +fix: completed winmm multimedia api hooking to fix "Wind Fantasy SP" movie problems, and not only.... +fix: revised FPS control to assure more stable fps when a FPS limit delay is set \ No newline at end of file diff --git a/dll/advapi.cpp b/dll/advapi.cpp index af95845..3bd31bc 100644 --- a/dll/advapi.cpp +++ b/dll/advapi.cpp @@ -34,6 +34,8 @@ FARPROC Remap_AdvApi32_ProcAddress(LPCSTR proc, HMODULE hModule) #define IsFake(hKey) (((DWORD)hKey & HKEY_MASK) == HKEY_MASK) static FILE *OpenFakeRegistry(); +static char *hKey2String(HKEY); +static LONG myRegOpenKeyEx(HKEY, LPCTSTR, PHKEY); static char *hKey2String(HKEY hKey) { @@ -50,7 +52,7 @@ static char *hKey2String(HKEY hKey) while (!feof(regf)){ if(RegBuf[0]=='['){ if(hLocalKey == hKey){ - OutTrace("building fake Key=\"%s\" hKey=%x\n", sKey, hKey); + //OutTrace("building fake Key=\"%s\" hKey=%x\n", sKey, hKey); fclose(regf); strcpy(sKey, &RegBuf[1]); sKey[strlen(sKey)-2]=0; // get rid of "]" @@ -162,7 +164,7 @@ LONG WINAPI extRegQueryValueEx( { LONG res; - OutTraceR("RegQueryValueEx: hKey=%x(%s) ValueName=\"%s\" Reserved=%x\n", hKey, hKey2String(hKey), lpValueName, lpReserved); + OutTraceR("RegQueryValueEx: hKey=%x(\"%s\") ValueName=\"%s\" Reserved=%x\n", hKey, hKey2String(hKey), lpValueName, lpReserved); if (!IsFake(hKey)){ res=(*pRegQueryValueEx)(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); if(IsTraceR){ @@ -295,7 +297,10 @@ LONG WINAPI extRegSetValueEx(HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWO default: OutTrace("\n"); } } - if(IsFake(hKey) && (dxw.dwFlags3 & EMULATEREGISTRY)) return ERROR_SUCCESS; + if(IsFake(hKey) && (dxw.dwFlags3 & EMULATEREGISTRY)) { + OutTraceR("RegSetValueEx: SUPPRESS registry key set\n"); + return ERROR_SUCCESS; + } return (*pRegSetValueEx)(hKey, lpValueName, Reserved, dwType, lpData, cbData); } diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index 6d4144d..f0b170b 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -1821,7 +1821,7 @@ HRESULT WINAPI extQueryInterfaceS(void *lpdds, REFIID riid, LPVOID *obp) if (dwLocalDDVersion > dxw.dwMaxDDVersion) { *obp = NULL; - OutTraceDW("QueryInterface(S): DDVersion=%d SUPPRESSED lpdds=%x(%s) REFIID=%x obp=(NULL) ret=0 at %d\n", + OutTraceDW("QueryInterface(S): DDVersion=%d SUPPRESS lpdds=%x(%s) REFIID=%x obp=(NULL) ret=0 at %d\n", dwLocalDDVersion, lpdds, IsPrim?"":"(PRIM)", riid.Data1, __LINE__); return(0); } @@ -2617,6 +2617,7 @@ static HRESULT BuildBackBufferEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER|DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); // DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces ddsd.ddsCaps.dwCaps |= (DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN); + if(ddsd.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; // 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; ddsd.dwWidth = dxw.GetScreenWidth(); @@ -2702,6 +2703,7 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf memcpy(&ddsd, lpddsd, lpddsd->dwSize); // Copy over .... FixSurfaceCaps(&ddsd, dxversion); + if(ddsd.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE|DDSCAPS_ZBUFFER)) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; // v2.02.96 !! // 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; diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 6b250e3..49de4e2 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -1406,6 +1406,9 @@ LRESULT CALLBACK MessageHook(int code, WPARAM wParam, LPARAM lParam) } else { // fix the message point coordinates + POINT upleft={0,0}; + (*pClientToScreen)(dxw.GethWnd(), &upleft); + msg->pt = dxw.SubCoordinates(msg->pt, upleft); msg->pt=dxw.FixCursorPos(msg->pt); // beware: needs fix for mousewheel? if((msg->message <= WM_MOUSELAST) && (msg->message >= WM_MOUSEFIRST)) msg->lParam = MAKELPARAM(msg->pt.x, msg->pt.y); @@ -1719,7 +1722,7 @@ FARPROC RemapLibrary(LPCSTR proc, HMODULE hModule, HookEntry_Type *Hooks) if((((dxw.dwFlags4 & HOTPATCH) && (Hooks->HookStatus == HOOK_HOT_CANDIDATE)) || // hot patch candidate still to process - or ((dxw.dwFlags4 & HOTPATCHALWAYS) && (Hooks->HookStatus != HOOK_HOT_LINKED)))){ // force hot patch and not already hooked - if(!Hooks->OriginalAddress) { + if(!Hooks->OriginalAddress) { Hooks->OriginalAddress=(*pGetProcAddress)(hModule, Hooks->APIName); if(!Hooks->OriginalAddress) continue; } diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp index 9b12780..b6e6f50 100644 --- a/dll/dxwcore.cpp +++ b/dll/dxwcore.cpp @@ -584,6 +584,11 @@ void dxwCore::SethWnd(HWND hwnd) hwnd, RealHDC, WinRect.left, WinRect.top, WinRect.right, WinRect.bottom); } +BOOL dxwCore::ishWndFPS(HWND hwnd) +{ + return (hwnd == hWndFPS); +} + void dxwCore::FixWorkarea(LPRECT workarea) { int w, h, b; // width, height and border @@ -665,6 +670,48 @@ RECT dxwCore::MapWindowRect(LPRECT lpRect) return RetRect; } +RECT dxwCore::MapClientRect(LPRECT lpRect) +{ + // same as MapClient, but taking in proper account aspect ratio & virtual desktop position + RECT RetRect; + RECT ClientRect; + RECT NullRect={0, 0, 0, 0}; + int w, h, bx, by; // width, height and x,y borders + + if (!(*pGetClientRect)(hWnd, &ClientRect)) return NullRect; + + RetRect=ClientRect; + bx = by = 0; + if (dwFlags2 & KEEPASPECTRATIO){ + w = RetRect.right - RetRect.left; + h = RetRect.bottom - RetRect.top; + if ((w * iRatioY) > (h * iRatioX)){ + bx = (w - (h * iRatioX / iRatioY))/2; + } + else { + by = (h - (w * iRatioY / iRatioX))/2; + } + } + + if(lpRect){ // v2.02.41 - fixed coordinates for KEEPASPECTRATIO option + LONG Width, Height; + Width = ClientRect.right - (2*bx); + Height = ClientRect.bottom - (2*by); + RetRect.left = bx + (lpRect->left * Width / dwScreenWidth); + RetRect.right = (lpRect->right * Width / dwScreenWidth); + RetRect.top = by + (lpRect->top * Height / dwScreenHeight); + RetRect.bottom = (lpRect->bottom * Height / dwScreenHeight); + } + else{ + RetRect.left = ClientRect.left + bx; + RetRect.right = ClientRect.right - bx; + RetRect.top = ClientRect.top + by; + RetRect.bottom = ClientRect.bottom - by; + } + + return RetRect; +} + void dxwCore::MapClient(LPRECT rect) { RECT client; @@ -918,16 +965,26 @@ void dxwCore::DoSlow(int delay) } } +// Remarks: +// If the target window is owned by the current process, GetWindowText causes a WM_GETTEXT message +// to be sent to the specified window or control. If the target window is owned by another process +// and has a caption, GetWindowText retrieves the window caption text. If the window does not have +// a caption, the return value is a null string. This behavior is by design. It allows applications +// to call GetWindowText without becoming unresponsive if the process that owns the target window +// is not responding. However, if the target window is not responding and it belongs to the calling +// application, GetWindowText will cause the calling application to become unresponsive. + static void CountFPS(HWND hwnd) { static DWORD time = 0xFFFFFFFF; static DWORD FPSCount = 0; + static HWND LasthWnd = 0; extern void SetFPS(int); + static char sBuf[80+15+1]; // title + fps string + terminator //DXWNDSTATUS Status; DWORD tmp; tmp = (*pGetTickCount)(); if((tmp - time) > 1000) { - char sBuf[80+15+1]; // title + fps string + terminator char *fpss; // log fps count // OutTrace("FPS: Delta=%x FPSCount=%d\n", (tmp-time), FPSCount); @@ -935,7 +992,10 @@ static void CountFPS(HWND hwnd) GetHookInfo()->FPSCount = FPSCount; // for overlay display // show fps on win title bar if (dxw.dwFlags2 & SHOWFPS){ - GetWindowText(hwnd, sBuf, 80); + if(hwnd != LasthWnd){ + GetWindowText(hwnd, sBuf, 80); + LasthWnd = hwnd; + } fpss=strstr(sBuf," ~ ("); if(fpss==NULL) fpss=&sBuf[strlen(sBuf)]; sprintf_s(fpss, 15, " ~ (%d FPS)", FPSCount); @@ -953,20 +1013,24 @@ static void CountFPS(HWND hwnd) static void LimitFrameCount(DWORD delay) { - static DWORD oldtime=(*pGetTickCount)(); + static DWORD oldtime = (*pGetTickCount)(); DWORD newtime; newtime = (*pGetTickCount)(); + if(IsDebug) OutTrace("FPS limit: old=%x new=%x delay=%d sleep=%d\n", + oldtime, newtime, delay, (oldtime+delay-newtime)); // use '<' and not '<=' to avoid the risk of sleeping forever.... - if(newtime < oldtime+delay) { - if(IsDebug) OutTrace("FPS limit: old=%x new=%x delay=%d sleep=%d\n", - oldtime, newtime, delay, (oldtime+delay-newtime)); - (*pSleep)(oldtime+delay-newtime); - // no good processing messages in the meanwhile: AoE series won't work at all! - // don't use DoSlow(oldtime+delay-newtime); - oldtime += delay; // same as doing "oldtime=(*pGetTickCount)();" now + if((newtime < oldtime+delay) && (newtime >= oldtime)) { + //if(IsDebug) OutTrace("FPS limit: old=%x new=%x delay=%d sleep=%d\n", + // oldtime, newtime, delay, (oldtime+delay-newtime)); + do{ + if(IsDebug) OutTrace("FPS limit: sleep=%d\n", oldtime+delay-newtime); + (*pSleep)(oldtime+delay-newtime); + newtime = (*pGetTickCount)(); + if(IsDebug) OutTrace("FPS limit: newtime=%d\n", newtime); + } while(newtime < oldtime+delay); } - else - oldtime = newtime; + oldtime += delay; + if(oldtime < newtime-delay) oldtime = newtime-delay; } static BOOL SkipFrameCount(DWORD delay) @@ -1586,8 +1650,27 @@ BOOL dxwCore::ReleaseEmulatedDC(HWND hwnd) //OutTrace("StretchBlt: destdc=%x destrect=(0,0)-(%d,%d) srcdc=%x srcrect=(0,0)-(%d,%d)\n", wdc, client.right, client.bottom, VirtualHDC, VirtualPicRect.right, VirtualPicRect.bottom); // v2.02.94: set HALFTONE stretching. But causes problems with Imperialism II // SetStretchBltMode(wdc,HALFTONE); +#if 1 if(!(*pGDIStretchBlt)(wdc, 0, 0, client.right, client.bottom, VirtualHDC, 0, 0, VirtualPicRect.right, VirtualPicRect.bottom, SRCCOPY)) OutTraceE("StretchBlt: ERROR err=%d at=%d\n", GetLastError(), __LINE__); +#else + int w, h, bx, by; // width, height and x,y borders + RECT RetRect; + bx = by = 0; + RetRect=client; + if (dwFlags2 & KEEPASPECTRATIO){ + w = RetRect.right - RetRect.left; + h = RetRect.bottom - RetRect.top; + if ((w * iRatioY) > (h * iRatioX)){ + bx = (w - (h * iRatioX / iRatioY))/2; + } + else { + by = (h - (w * iRatioY / iRatioX))/2; + } + } + if(!(*pGDIStretchBlt)(wdc, bx, by, client.right-bx, client.bottom-by, VirtualHDC, 0, 0, VirtualPicRect.right, VirtualPicRect.bottom, SRCCOPY)) + OutTraceE("StretchBlt: ERROR err=%d at=%d\n", GetLastError(), __LINE__); +#endif //(*pInvalidateRect)(hwnd, NULL, 0); if(!DeleteObject(VirtualPic)) OutTraceE("DeleteObject: ERROR err=%d at=%d\n", GetLastError(), __LINE__); @@ -1745,6 +1828,7 @@ BOOL dxwCore::CheckScreenResolution(unsigned int w, unsigned int h) #define HUGE 100000 if(dxw.dwFlags4 & LIMITSCREENRES){ DWORD maxw, maxh; + maxw=HUGE; maxh=HUGE; // v2.02.96 switch(MaxScreenRes){ case DXW_NO_LIMIT: maxw=HUGE; maxh=HUGE; break; case DXW_LIMIT_320x200: maxw=320; maxh=200; break; diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp index acd4c92..0c3cb76 100644 --- a/dll/dxwcore.hpp +++ b/dll/dxwcore.hpp @@ -52,6 +52,7 @@ public: // methods void EraseClipCursor(void); RECT MapWindowRect(LPRECT lpRect); RECT MapWindowRect(void); + RECT MapClientRect(LPRECT lpRect); void MapClient(LPPOINT); void MapClient(LPRECT); void MapClient(int *, int *, int *, int *); @@ -74,6 +75,7 @@ public: // methods POINT ClientOffset(HWND); void ScreenRefresh(void); BOOL HandleFPS(void); + BOOL ishWndFPS(HWND); DWORD GetTickCount(void); void MarkPrimarySurface(LPDIRECTDRAWSURFACE); BOOL IsAPrimarySurface(LPDIRECTDRAWSURFACE); diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index ec92b34..6e04000 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -24,7 +24,8 @@ along with this program. If not, see . #include "dxwnd.h" #include "dxwcore.hpp" -#define VERSION "2.02.95" +#define VERSION "2.02.96" +#define DXWACTIVATESINGLETASK 1 // comment to allow multiple task activations #define DDTHREADLOCK 1 @@ -218,6 +219,15 @@ LRESULT CALLBACK HookProc(int ncode, WPARAM wparam, LPARAM lparam) return CallNextHookEx(hHook, ncode, wparam, lparam); } +void UnhookProc() +{ + // used to unhook DxWnd from the current process and allow another one (a son) to be managed + //ReleaseMutex(hMutex); + ReleaseMutex(hLockMutex); + UnmapViewOfFile(pMapping); + CloseHandle(hMapping); +} + void InjectHook() { char name[MAX_PATH+1]; diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index 3dbd983..b25e8f2 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 3c911f9..c2e0f4c 100644 --- a/dll/dxwnd.vs2008.vcproj +++ b/dll/dxwnd.vs2008.vcproj @@ -70,7 +70,7 @@ left, lprc->top, lprc->right, lprc->bottom); if(dxw.dwFlags4 & NOFILLRECT) { - OutTraceDW("FillRect: SUPPRESSED\n", hdc, hbr, lprc->left, lprc->top, lprc->right, lprc->bottom); + OutTraceDW("FillRect: SUPPRESS\n", hdc, hbr, lprc->left, lprc->top, lprc->right, lprc->bottom); return TRUE; } @@ -1763,6 +1770,7 @@ LONG WINAPI extEnumDisplaySettings(LPCTSTR lpszDeviceName, DWORD iModeNum, DEVMO if(dxw.dwFlags4 & LIMITSCREENRES){ #define HUGE 100000 DWORD maxw, maxh; + maxw = maxh = HUGE; switch(dxw.MaxScreenRes){ case DXW_NO_LIMIT: maxw=HUGE; maxh=HUGE; break; case DXW_LIMIT_320x200: maxw=320; maxh=200; break; @@ -2224,6 +2232,7 @@ BOOL WINAPI extDDEndPaint(HWND hwnd, const PAINTSTRUCT *lpPaint) if(dxw.IsDesktop(hwnd)) lpRect=NULL; else{ +#if 1 POINT p={0,0}; lpRect=&Rect; (*pGetClientRect)(hwnd, lpRect); @@ -2234,6 +2243,10 @@ BOOL WINAPI extDDEndPaint(HWND hwnd, const PAINTSTRUCT *lpPaint) lpRect->bottom += p.y; //dxw.AddCoordinates(lpRect, p); dxw.UnmapClient(lpRect); +#else + lpRect=&Rect; + Rect = dxw.MapClientRect(lpRect); +#endif } extBlt(dxw.lpDDSPrimHDC, lpRect, dxw.lpDDSPrimHDC, NULL, 0, NULL); return TRUE; @@ -2877,4 +2890,25 @@ BOOL WINAPI extValidateRect(HWND hWnd, const RECT *lpRect) ret = (*pValidateRect)(hWnd, lpRect); return ret; } -#endif \ No newline at end of file + +int WINAPI extGetWindowTextA(HWND hWnd, LPTSTR lpString, int nMaxCount) +{ + // purpose of this wrapped call is to clear the FPS indicator (format " ~ (%d FPS)") + // from the window title, if present. It crashes games such as "Panzer General 3 Scorched Earth" + // when FPS on window title is activated. + int ret; + OutTraceDW("GetWindowTextA: hwnd=%x MaxCount=%d\n", hWnd, nMaxCount); + ret=(*pGetWindowTextA)(hWnd, lpString, nMaxCount); + if(ret) OutTraceDW("GetWindowTextA: ret=%d String=\"%s\"\n", ret, lpString); + if (ret && (dxw.dwFlags2 & SHOWFPS) && dxw.ishWndFPS(hWnd)){ + char *p; + p=strstr(lpString, " ~ ("); + if(p){ + *p = NULL; + ret = strlen(lpString); + OutTraceDW("GetWindowTextA: FIXED ret=%d String=\"%s\"\n", ret, lpString); + } + } + return ret; +} +#endif diff --git a/dll/winmm.cpp b/dll/winmm.cpp index ab634f6..c23e5ed 100644 --- a/dll/winmm.cpp +++ b/dll/winmm.cpp @@ -1,3 +1,6 @@ +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_NON_CONFORMING_SWPRINTFS + #include "dxwnd.h" #include "dxwcore.hpp" #include "syslibs.h" @@ -5,12 +8,15 @@ #include "dxhelper.h" #include "MMSystem.h" +#include -//#undef OutTraceDW -//#define OutTraceDW OutTrace +#define SUPPRESSMCIERRORS FALSE + +BOOL IsWithinMCICall = FALSE; static HookEntry_Type Hooks[]={ - {HOOK_IAT_CANDIDATE, "mciSendCommandA", NULL, (FARPROC *)&pmciSendCommand, (FARPROC)extmciSendCommand}, + {HOOK_HOT_CANDIDATE, "mciSendCommandA", NULL, (FARPROC *)&pmciSendCommandA, (FARPROC)extmciSendCommandA}, + {HOOK_HOT_CANDIDATE, "mciSendCommandW", NULL, (FARPROC *)&pmciSendCommandW, (FARPROC)extmciSendCommandW}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; @@ -21,10 +27,17 @@ static HookEntry_Type TimeHooks[]={ {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; +static HookEntry_Type RemapHooks[]={ + {HOOK_HOT_CANDIDATE, "mciSendStringA", NULL, (FARPROC *)&pmciSendStringA, (FARPROC)extmciSendStringA}, + {HOOK_HOT_CANDIDATE, "mciSendStringW", NULL, (FARPROC *)&pmciSendStringW, (FARPROC)extmciSendStringW}, + {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator +}; + void HookWinMM(HMODULE module) { HookLibrary(module, Hooks, "winmm.dll"); if(dxw.dwFlags2 & TIMESTRETCH) HookLibrary(module, TimeHooks, "winmm.dll"); + if(dxw.dwFlags5 & REMAPMCI) HookLibrary(module, RemapHooks, "winmm.dll"); } FARPROC Remap_WinMM_ProcAddress(LPCSTR proc, HMODULE hModule) @@ -34,6 +47,8 @@ FARPROC Remap_WinMM_ProcAddress(LPCSTR proc, HMODULE hModule) if (addr=RemapLibrary(proc, hModule, Hooks)) return addr; if(dxw.dwFlags2 & TIMESTRETCH) if (addr=RemapLibrary(proc, hModule, TimeHooks)) return addr; + if(dxw.dwFlags5 & REMAPMCI) + if (addr=RemapLibrary(proc, hModule, RemapHooks)) return addr; return NULL; } @@ -81,7 +96,7 @@ MMRESULT WINAPI exttimeKillEvent(UINT uTimerID) You can use the MCI_GETDEVCAPS_CAN_STRETCH flag with the MCI_GETDEVCAPS command to determine if a device scales the image. A device returns FALSE if it cannot scale the image. */ -MCIERROR WINAPI extmciSendCommand(MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam) +MCIERROR WINAPI extmciSendCommand(mciSendCommand_Type pmciSendCommand, MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam) { RECT saverect; MCIERROR ret; @@ -126,3 +141,86 @@ MCIERROR WINAPI extmciSendCommand(MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdw if (ret) OutTraceE("mciSendCommand: ERROR res=%d\n", ret); return ret; } + +MCIERROR WINAPI extmciSendCommandA(MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam) +{ + return extmciSendCommand(pmciSendCommandA, IDDevice, uMsg, fdwCommand, dwParam); +} + +MCIERROR WINAPI extmciSendCommandW(MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam) +{ + return extmciSendCommand(pmciSendCommandW, IDDevice, uMsg, fdwCommand, dwParam); +} + +MCIERROR WINAPI extmciSendStringA(LPCTSTR lpszCommand, LPTSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback) +{ + MCIERROR ret; + if(IsWithinMCICall) return(*pmciSendStringA)(lpszCommand, lpszReturnString, cchReturn, hwndCallback); // just proxy ... + OutTraceDW("mciSendStringA: Command=\"%s\" Return=%x Callback=%x\n", lpszCommand, cchReturn, hwndCallback); +#ifdef WFSPONLY + char *target="put movie destination at "; + if(!strncmp(lpszCommand, target, strlen(target))) { + char NewCommand[256]; + RECT rect; + sscanf(&lpszCommand[strlen(target)], "%ld %ld %ld %ld", &(rect.left), &(rect.top), &(rect.right), &(rect.bottom)); + rect=dxw.MapClientRect(&rect); + sprintf(NewCommand, "put movie destination at %d %d %d %d", rect.left, rect.top, rect.right, rect.bottom); + lpszCommand=NewCommand; + OutTraceDW("mciSendStringA: replaced Command=\"%s\"\n", lpszCommand); + } +#else + char sMovieNickName[81]; + RECT rect; + if (sscanf(lpszCommand, "put %s destination at %ld %ld %ld %ld", + sMovieNickName, &(rect.left), &(rect.top), &(rect.right), &(rect.bottom))==5){ + char NewCommand[256]; + rect=dxw.MapClientRect(&rect); + sprintf(NewCommand, "put %s destination at %d %d %d %d", sMovieNickName, rect.left, rect.top, rect.right, rect.bottom); + lpszCommand=NewCommand; + OutTraceDW("mciSendStringA: replaced Command=\"%s\"\n", lpszCommand); + } +#endif + IsWithinMCICall=TRUE; + ret=(*pmciSendStringA)(lpszCommand, lpszReturnString, cchReturn, hwndCallback); + IsWithinMCICall=FALSE; + if(ret) OutTraceDW("mciSendStringA ERROR: ret=%x\n", ret); + OutTraceDW("mciSendStringA: RetString=\"%s\"\n", lpszReturnString); + return ret; +} + +MCIERROR WINAPI extmciSendStringW(LPCWSTR lpszCommand, LPWSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback) +{ + MCIERROR ret; + WCHAR *target=L"put movie destination at "; + if(IsWithinMCICall) return(*pmciSendStringW)(lpszCommand, lpszReturnString, cchReturn, hwndCallback); // just proxy ... + OutTraceDW("mciSendStringW: Command=\"%ls\" Return=%x Callback=%x\n", lpszCommand, cchReturn, hwndCallback); +#ifdef WFSPONLY + if(!wcsncmp(lpszCommand, target, wcslen(target))) { + WCHAR NewCommand[256]; + RECT rect; + swscanf(&lpszCommand[wcslen(target)], L"%ld %ld %ld %ld", &(rect.left), &(rect.top), &(rect.right), &(rect.bottom)); + rect=dxw.MapClientRect(&rect); + swprintf(NewCommand, L"put movie destination at %d %d %d %d", rect.left, rect.top, rect.right, rect.bottom); + lpszCommand=NewCommand; + OutTraceDW("mciSendStringA: replaced Command=\"%ls\"\n", lpszCommand); + } +#else + WCHAR sMovieNickName[81]; + RECT rect; + if (swscanf(lpszCommand, L"put %ls destination at %ld %ld %ld %ld", + sMovieNickName, &(rect.left), &(rect.top), &(rect.right), &(rect.bottom))==5){ + WCHAR NewCommand[256]; + rect=dxw.MapClientRect(&rect); + swprintf(NewCommand, L"put %ls destination at %d %d %d %d", sMovieNickName, rect.left, rect.top, rect.right, rect.bottom); + lpszCommand=NewCommand; + OutTraceDW("mciSendStringW: replaced Command=\"%ls\"\n", lpszCommand); + } +#endif + IsWithinMCICall=TRUE; + ret=(*pmciSendStringW)(lpszCommand, lpszReturnString, cchReturn, hwndCallback); + IsWithinMCICall=FALSE; + if(ret) OutTraceDW("mciSendStringW ERROR: ret=%x\n", ret); + OutTraceDW("mciSendStringW: RetString=\"%ls\"\n", lpszReturnString); + return ret; +} + diff --git a/dll/wndproc.cpp b/dll/wndproc.cpp index 6cb0271..3d83143 100644 --- a/dll/wndproc.cpp +++ b/dll/wndproc.cpp @@ -136,10 +136,13 @@ BOOL WinDBGetSize(HWND hwnd, int *w, int *h) WNDPROC WinDBGetProc(HWND hwnd) { int StackIdx; - for(StackIdx=0; StackIdxm_HookGlide); + + // MCI + DDX_Check(pDX, IDC_REMAPMCI, cTarget->m_RemapMCI); } BEGIN_MESSAGE_MAP(CTabSysLibs, CDialog) diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index e225961..888c77d 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -100,6 +100,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_VideoToSystemMem = FALSE; m_FixTextOut = FALSE; m_HookGlide = FALSE; + m_RemapMCI = TRUE; m_KeepCursorWithin = FALSE; m_KeepCursorFixed = FALSE; m_UseRGB565 = FALSE; diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 117b482..9427847 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -78,6 +78,7 @@ public: BOOL m_VideoToSystemMem; BOOL m_FixTextOut; BOOL m_HookGlide; + BOOL m_RemapMCI; BOOL m_KeepCursorWithin; BOOL m_KeepCursorFixed; BOOL m_UseRGB565; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 5cab8e8..97192aa 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 1a713bb..9696eea 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 a16d2df..ad01564 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 c5b14fd..16cd2ed 100644 --- a/host/dxwndhost.vs2008.vcproj +++ b/host/dxwndhost.vs2008.vcproj @@ -628,6 +628,10 @@ > + + m_VideoToSystemMem) t->flags |= SWITCHVIDEOMEMORY; if(dlg->m_FixTextOut) t->flags |= FIXTEXTOUT; if(dlg->m_HookGlide) t->flags4 |= HOOKGLIDE; + if(dlg->m_RemapMCI) t->flags5 |= REMAPMCI; if(dlg->m_KeepCursorWithin) t->flags |= KEEPCURSORWITHIN; if(dlg->m_KeepCursorFixed) t->flags2 |= KEEPCURSORFIXED; if(dlg->m_UseRGB565) t->flags |= USERGB565; @@ -411,6 +412,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_VideoToSystemMem = t->flags & SWITCHVIDEOMEMORY ? 1 : 0; dlg->m_FixTextOut = t->flags & FIXTEXTOUT ? 1 : 0; dlg->m_HookGlide = t->flags4 & HOOKGLIDE ? 1 : 0; + dlg->m_RemapMCI = t->flags5 & REMAPMCI ? 1 : 0; dlg->m_KeepCursorWithin = t->flags & KEEPCURSORWITHIN ? 1 : 0; dlg->m_KeepCursorFixed = t->flags2 & KEEPCURSORFIXED ? 1 : 0; dlg->m_UseRGB565 = t->flags & USERGB565 ? 1 : 0; diff --git a/host/resource b/host/resource new file mode 100644 index 0000000..bca6966 Binary files /dev/null and b/host/resource differ diff --git a/locale/cn/Resources_Cn.ncb b/locale/cn/Resources_Cn.ncb deleted file mode 100644 index 2b80c0b..0000000 Binary files a/locale/cn/Resources_Cn.ncb and /dev/null differ diff --git a/locale/cn/Resources_Cn.rc b/locale/cn/Resources_Cn.rc index 38041e9..17ed92c 100644 Binary files a/locale/cn/Resources_Cn.rc and b/locale/cn/Resources_Cn.rc differ diff --git a/locale/cn/Resources_Cn.suo b/locale/cn/Resources_Cn.suo index 91008cb..a2b6943 100644 Binary files a/locale/cn/Resources_Cn.suo and b/locale/cn/Resources_Cn.suo differ diff --git a/locale/en/Resources_En.ncb b/locale/en/Resources_En.ncb deleted file mode 100644 index 08ac0fb..0000000 Binary files a/locale/en/Resources_En.ncb and /dev/null differ diff --git a/locale/it/Resources_IT.rc b/locale/it/Resources_IT.rc index 11d2c99..5209a87 100644 Binary files a/locale/it/Resources_IT.rc and b/locale/it/Resources_IT.rc differ diff --git a/locale/it/Resources_It.ncb b/locale/it/Resources_It.ncb deleted file mode 100644 index 72f85de..0000000 Binary files a/locale/it/Resources_It.ncb and /dev/null differ diff --git a/locale/it/Resources_It.suo b/locale/it/Resources_It.suo index e7d7b34..8153fba 100644 Binary files a/locale/it/Resources_It.suo and b/locale/it/Resources_It.suo differ diff --git a/locale/ru/Resources_RU.rc b/locale/ru/Resources_RU.rc new file mode 100644 index 0000000..d16af36 Binary files /dev/null and b/locale/ru/Resources_RU.rc differ diff --git a/locale/ru/Resources_Ru.sln b/locale/ru/Resources_Ru.sln new file mode 100644 index 0000000..fff9e14 --- /dev/null +++ b/locale/ru/Resources_Ru.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Resources_RU", "Resources_Ru.vcproj", "{F8D07BBB-A04B-4C0C-8AF8-7F839A152456}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F8D07BBB-A04B-4C0C-8AF8-7F839A152456}.Debug|Win32.ActiveCfg = Debug|Win32 + {F8D07BBB-A04B-4C0C-8AF8-7F839A152456}.Debug|Win32.Build.0 = Debug|Win32 + {F8D07BBB-A04B-4C0C-8AF8-7F839A152456}.Release|Win32.ActiveCfg = Release|Win32 + {F8D07BBB-A04B-4C0C-8AF8-7F839A152456}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/locale/ru/Resources_Ru.suo b/locale/ru/Resources_Ru.suo new file mode 100644 index 0000000..30824f9 Binary files /dev/null and b/locale/ru/Resources_Ru.suo differ diff --git a/locale/ru/Resources_Ru.vcproj b/locale/ru/Resources_Ru.vcproj new file mode 100644 index 0000000..ec1856d --- /dev/null +++ b/locale/ru/Resources_Ru.vcproj @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +