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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+