From 7418d7767bc9733640061dfd457df6796e236026 Mon Sep 17 00:00:00 2001 From: gho tik Date: Thu, 30 Oct 2014 12:39:54 -0400 Subject: [PATCH] v2_02_96_src Former-commit-id: ca9fa70709c4797019a40006f6a6a59b397bd08d --- Include/dxwnd.h | 2 +- build/Resources_CN.dll | 2 +- build/Resources_EN.dll | 3 - build/Resources_IT.dll | 2 +- build/Resources_RU.dll | 3 + build/dxwnd.0.ini | 10 ++ build/dxwnd.dll | 4 +- build/dxwnd.exe | 4 +- build/dxwnd.ini | 14 +- build/exports/dxwnd.ini | 8 +- build/readme-relnotes.txt | 9 ++ dll/advapi.cpp | 11 +- dll/ddraw.cpp | 4 +- dll/dxhook.cpp | 5 +- dll/dxwcore.cpp | 108 ++++++++++++-- dll/dxwcore.hpp | 2 + dll/dxwnd.cpp | 12 +- dll/dxwnd.vs2008.suo | Bin 280576 -> 280576 bytes dll/dxwnd.vs2008.vcproj | 2 +- dll/gdi32.cpp | 6 +- dll/hd3d.cpp | 8 +- dll/kernel32.cpp | 52 ++++--- dll/syslibs.h | 16 ++- dll/user32.cpp | 52 +++++-- dll/winmm.cpp | 106 +++++++++++++- dll/wndproc.cpp | 5 +- host/Resource.h | Bin 30578 -> 30644 bytes host/TabSysLibs.cpp | 3 + host/TargetDlg.cpp | 1 + host/TargetDlg.h | 1 + host/dxwndhost.aps | Bin 177980 -> 152564 bytes host/dxwndhost.rc | Bin 88730 -> 89078 bytes host/dxwndhost.vs2008.suo | Bin 110592 -> 111104 bytes host/dxwndhost.vs2008.vcproj | 4 + host/dxwndhostView.cpp | 2 + host/resource | Bin 0 -> 30714 bytes locale/cn/Resources_Cn.ncb | Bin 35840 -> 0 bytes locale/cn/Resources_Cn.rc | Bin 82246 -> 82552 bytes locale/cn/Resources_Cn.suo | Bin 7168 -> 7168 bytes locale/en/Resources_En.ncb | Bin 35840 -> 0 bytes locale/it/Resources_IT.rc | Bin 88560 -> 88910 bytes locale/it/Resources_It.ncb | Bin 35840 -> 0 bytes locale/it/Resources_It.suo | Bin 7168 -> 7168 bytes locale/ru/Resources_RU.rc | Bin 0 -> 91118 bytes locale/ru/Resources_Ru.sln | 20 +++ locale/ru/Resources_Ru.suo | Bin 0 -> 8192 bytes locale/ru/Resources_Ru.vcproj | 259 ++++++++++++++++++++++++++++++++++ 47 files changed, 664 insertions(+), 76 deletions(-) delete mode 100644 build/Resources_EN.dll create mode 100644 build/Resources_RU.dll create mode 100644 host/resource delete mode 100644 locale/cn/Resources_Cn.ncb delete mode 100644 locale/en/Resources_En.ncb delete mode 100644 locale/it/Resources_It.ncb create mode 100644 locale/ru/Resources_RU.rc create mode 100644 locale/ru/Resources_Ru.sln create mode 100644 locale/ru/Resources_Ru.suo create mode 100644 locale/ru/Resources_Ru.vcproj 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 3dbd9838b9471ef16b1fd1a9480e2420f3a839c9..b25e8f2e053c7acfc675d65d5e48999bbb2aa950 100644 GIT binary patch delta 21177 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 bV$7tDSY5-fq1Yvc-=$(sqgv}b2V?&qoL#jA delta 19891 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 G 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; StackIdx0$rnSVHyeaH GDFFcFC=ECO delta 14 Vcmdn;p7GN=#tnL*n+rl+lmIz+2A2Q; diff --git a/host/TabSysLibs.cpp b/host/TabSysLibs.cpp index e03632b..4c72038 100644 --- a/host/TabSysLibs.cpp +++ b/host/TabSysLibs.cpp @@ -37,6 +37,9 @@ void CTabSysLibs::DoDataExchange(CDataExchange* pDX) // Glide DDX_Check(pDX, IDC_HOOKGLIDE, cTarget->m_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 5cab8e8e4b80340b557559fc21584fd25ca4c479..97192aa636cfb2ad3c29b54f81d3b8ad12724dfc 100644 GIT binary patch delta 3861 zcmZu!3vg7`8UFvXo6TnPAcSP!yGZ~;1ZwsX$cAS&*$pft*)<7571;&C%OVEwL4l?e z(E&t24|sHRcvZt=Xbdb2wmO>n01Av)V5YUT4t40zqC-K^VnMh6J-asvUGB`i`Oo)% z-~ZZkA9?4h;l|#qt%0Igh(X(!nSmA4m$c1%(i3%gqSd2$>0DDh=jswOOC-c<9nRsu z`_Zrswc;xsUg6&*^2DV~ER%*=j~<29phqk3_|72O^*CIm@6+QsF)j=Br2v@#kxb}> zHmHMyJk~%xEP}=GILw1(;<1rfB;LxxE-})8`hujO9W-zh-jV{b#()!EGNXQb7wW_r z1K!%c7jwmhY^>ehiFsmZ4t9ul3&`ru!Fq8@FvIq4s#%+h!zE!{E?$*}FApd2#E-dR zQyy+sinkBIA)>edbB{F)z*sSMir?Ia6%@&>!STne75FjRz7KOs_dq+$1_N|!fl68f z%~biLgtS8mG*Vw7aoUOZc$2li0&`#!Ozv&AktiilPJ$<7(~HQON8?yT0q#BacQ-B# zBOGh_6`ps{-(frPqtXEYNSb~506Hisfn&FN@Oh7;57jGZFDFZK-uMQ+rj*jG1IU)> zWdnQ0m_iq30OU$^RVn)+pR)bj!=CQ%&6nQn5F6D$Qh`LnF?L4{g$mkRLy_cs|01ii z;HNJvwIMt7{FI_!)&Uien7gEJxx;pQZ#626mI^Ry<(se=E=bwmYxaFc*&AR6hHtQx*gvih?5 zT=3r{mP+Sy!>uIHFQ3l?w#^0~aAm#6|nBmQYE$`pOBQIN%ZOb#^g$PqKkM!w{T z5p(zev(cC<`7Qnjf=VQX?RG;RA8WQ52S`_7#`LBD)hbs#Sd95xt_|}h%#ZH#|JjP#WDo#bT#o)mTcxgzU6%@ zb0UB9eG?Y*Y^%jufVA( zv7yKx`M`?z@IzK7JsLl;nsFHam(|Y7k$?GtO>-}C2R>`kQxvxsh9h@TsIJC&RY-Yom?+P?HkR>xBu(|9HG;%EUfrs3|f{4#qnQYWm+N(DJ`rx9S#>xiEuY`Pw>v4k@nDCQBqT=xmeZ{;D&CJf5Zc*QWW` z6B0A1{_Sc0F;t&En{T{ntp`0oTdqnKY1B(ZU00;~UrzI{q%`Zz!k|NI*;^EA=n$3r zY8v+(wRL-h=&%s?9pYZAP`NwOxHW{F@rkA~wCcW~FTRo0qKoXZPKx33tGYdDx{qmW zHv{6Tn{=zm`_C!j^D448k-cuJSm~n}uTxL11|>#5otTUvugOb9xg*2k%2=ErYPy-0 zt#1(>HE7dO&7Uj)v7nndn7Li#J&abdiwN1V15TtcWdqQp}o**35l50Ixj> z;)Eh;ds;l$j@F97lxE~MMUhA6hGhPJn?ez_OTQ9PE6#RPMBi?4-)1Ua5yN3syfIx& zfdYrcn4MHxO`K(vexQ~{Q=}umUm_*eh4bQ64-H89G&EljdA}#!MWv^UmsDYv2p?uf z{8sGvf~t3ssGU9)lGSfkVnYATseCE+NWW5jwya)rGY7@Lzeme3C1nqNmL}C(($vZq zrPhh!mVsGh9YZ$J%P~3IJjwq523jjoOf6-WOr?XDX|aVCA{J-bA+eyE=!Lr`+7?9d zoJV0FVi|*{s(A+9HP5AoQ2cc=|Hxk@ff z&Zcr5iV;iIShu&SZev<3W%M7uf#U5KiQRLAX*K1YC@PLJn<(R~Ad``Qp^6xfGNWc! za^=?inT)fXsvk$3b$d~)+QuxCX3^r}UL~Q9&ZTm|{eR1Px;bL|RR6#u*)%zBJ`$q>Q|)`uC^#KYf_| t?@{D~%#o=)xgrk6qq7`C&E-^IDWm_#rb8_SNhD6umF@w0{7Zu_{{uB=;kp0- delta 20090 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 delta 875 zcmYk4Pe>GT6vyYy&aUes=B~Q9>!RZtwwao3T81Dh9a7dmJ85(YjQ)UNV&Wx>96~xR zratYb;pXaLEVD)YMRP0DOO%H6M?7kDu!1^tsSa-Mmj->|!~EX+y*KaAjQ+`{Z`$U| zES?cblG=&WL<^x27l>BgV95nrta351w2j?L7?+(#uvAg-r?O&Cqlg3vn+pQCXeXz2 zMA;z+AGD3hP>wI6nY=2w-+Dlj04SK`A!K6pQJL%e&bP!rzngqc{yBA@MNX3NxAP__ z{F63Kipxkrqd}Cr|QzNtsu+hC#y%|y;+TbFO?!|6WN{om*+ZQ zk0-z**a=gO>od|P%Y)J=|w}nenl10xm)K!9ypKH&nqSC1I{ zEt&6#_rwQco!A*VKl4-p*=M%whj=o|6U|(U#Q|rhyr|v?^3a1Pz`hiKk2M$2R3(QX z0|)9HMhPgU7KFHksSThR$G~N3r+^am{0x>6f-0jPWK#=~i>=)O7jx-QZ8SpA)N~Q% zIN@d92viuiz+q|;dJ(2Yb7-M1RyqcLV-OU~JLAL6;??+Uz&6;6Mfn{b`1qaqP(Ij!WYz`Mv-9N^y1!4dI 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 0000000000000000000000000000000000000000..bca6966533d173fe18f519015151e847836eeb53 GIT binary patch literal 30714 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 literal 0 HcmV?d00001 diff --git a/locale/cn/Resources_Cn.ncb b/locale/cn/Resources_Cn.ncb deleted file mode 100644 index 2b80c0b5cc363f4ba1e983b8c12dd2e229a0b6f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35840 zcmeI5%WvaE9LJ~SwRBmQ_hSLc3PONZjYF%p+j2l{+?0woUA5f?Ru)leJH_DGk)5RJ zjlTd1#D)I=#FYapB*Y!<1##gI0B*aS5T};!&&{hGV|?t^ z1R{AHF=lde&FGYzmA{ppOwSnOh_+%GL+Ru1N0!p35t~?1`bX8MVi$__qJ2{w45lP&L+#2}@jj9Dto2yi9H_(QY zDRUuhy1wOAZD-%*3l*KjtMqx&S)XsPEesusQWv4naIpV{4RrN*!~)QB>% zt*e~!m5q2!^{Ko{#oJ*ufOw=rWg*8?0rmy#9i%LrZ^DCpU=MI|7DGJt^=SSET*j?C@FbVjQRJ{kg1p5vq&D83$n zeGKb?F_6IV6L<=jl<)PwkgnbcFJnLXkWxd~OV5^(@IBHJmms}WOw!WRpMgnF7GF3m z9tG0lWt7MWk#po+>Ge`hMgao}kif|kkQs`B1W4dw5|C;Cs!ZBjgdTbRU0d5Chlfaj z1kMA2oyPxpXdl}^0wh2JBtQZrKmsH{0wh2JBtQZr&?eCF^I!WQV+z;mxFa<+)krjS!t1GaB4cQ= zYFLA6817dzsD=|w*)UGdloL%o@P>*(I4rqAE7z2y-AXpa!#JAj*Ba_!O}8|thc&2& zwJp@cZH;iO3)T|5DT5PQ@1&MEkU01tE;j0e*FEh|BD|ln4V5s8jsn7-gu;z7`vcdh z3*N0Szq{KfsBprAiq5K$6ZV#^2QCujEk6mdSu6+}>-gENIsJ+XT~zoZ$P;z51o?SR z#9~Jhx}nOEi*;7!NG?RDBtQbEj=<{u)%$XviElv7yU?ktB`ZV%Bybc2WXQ*M=_kea z|3HH8|7lyiILP<^c6)>HC9MX^Cr-^-d^?pq9J}7M*aUWd|=2&VpbyTzY77M-O2_hQ{G*;*1fUj(@RFW3J)Up<v^6*(y?*q`(N2gq^(^5YqT7+isx92o+DBv5{`p;s`!5m4R`2tl+ZgZbu**GjVh D!)hM; delta 18 acmey-!g{QUb;F%&lkIBcHtXE*$pQdci3te+ diff --git a/locale/cn/Resources_Cn.suo b/locale/cn/Resources_Cn.suo index 91008cbe9220b705e98dd035872a1c769fb95ea4..a2b6943a069b8523d8ca759e08faec4b1c528899 100644 GIT binary patch delta 110 zcmZp$Xt3De!@?*wS&>VDb*+{{MSx r%wjnCi(mi`6Ht;HssJRpxkShasB^L=r~Kw)VofX@Tu73WOQd@Mmysy< delta 125 zcmZp$Xt3De!@|fjS&>Da?Z8$Em&9kAi&(a?Fq&@G7jEAI6ny^4goGBxcNtC1=Ko+Bk?Fj~tJ+fz# z$&SB(RhKMS@em8PNNiZK>xTXfz_LY1h*iROJWrxLn#nu)u5|2sZQtW_f8*=x%zVC? zcC9dof?`FR&?l~5)u!ju+Hf+Jy3lvom{&-TD%FG48?c&`kzTK_xFi7*IN=2TU01)X zGm!uZoJj&ot)0nsv(Y3#0_*GYY#-Yff6Vq?N8tfXpBaF;O20X!bR(C^4x(&ijmhy_ zH<8I>i!qa%Z)T_DsQj&LW@5&eM7EVn8%m#iKeCiQjoi&urGHe7Dt4h*OMa^Kba~G4 zoI>Q7b50agL(7Tsli6h1l6^sQpNWFqEG%0isbtw+RC;bu>3-k^OM%ki|6>HZFspPY z41;jaDFXPdaz#R$&VP7gNNwDswf4M>Hopl9-@){;iJW1Nnno?>+vf5>J~faZ zxt5PY%k%=P;5nw_o2ox!jGD7yuoMXkycacVoMuV^xB1b)`^|vA^wF z$2e@)R<<68!^VSyJWjMDY_UR!hVx;Y6IR3x(_XrdGJ4G&R*IG<3rCQoE2g zv{*H)K{X8bs~S|piKc8A2dB%4rXIK>uvj=OdxO?qQ;K%0*c1|$sE0M((x4vJ zpdQvXQ4hB@!m%z`OYEc!PH6oZEwLwY@LpW}Umsle)SX1Qo4O5^FshCL!mfnEjXK?d z>(mABbS=NT(oo%0ZU#(lqe6KI@oxB7q45I+l}{{Ij@FrI=0_K|>e z{jK!Bz108iBWb!Kf#XMDyZ(RtqGd!RKmsH{0wh2JBtQZrKmsH{0wh2Jdm$j-12B;Q z37jng)c;cdyXh3c)c#O9H2h0O$YZ{J*E`ie_teLtsDV{}uh; zt1$5;I>6^)mtgX5HAG7&Ghxdd!7`8Vi?GWuCK4clqbKm%(TBhYNPq-LfCNZ@1W14c cNPq-LfCNZ@1W14cNPq-LfCNZ@1ooN0e>0R9IsgCw diff --git a/locale/it/Resources_IT.rc b/locale/it/Resources_IT.rc index 11d2c99f84dc0b4bcebb9f1a91dbfbcddbaaf8c6..5209a879c595968cd257d4c520cba757a60b56db 100644 GIT binary patch delta 161 zcmeycnf2T@)(r|TCL0{$m~7ywBuZ!H~;P%8a1R3VL1G}eJceQ*D<4QF0(F*wWm18B1)xdJ44w>13_3v41;~zP2x4#riaIg` kK;$Mb^a5CeKK(J!5BH&-^lD&%}?N z13K?eAY%7v_Jw^6SVS%Z1^8uuZR6 zWjDggUejYMTz6xyQVN>sa^Tc_cX!$j%4MtK_+F)*&+{r#?6{?t8>?0qr)8_!bmMrT zYsW#jwQ0rn=iRP#XWDe?n-$007%gT-i&NvpD6~yKur1#;z1R%hD5!`&Nb*dk0kg|Me#;_GqPXRwPf3GbQ!HV%wWEQ-N6KqE2#zZ-tyN6Y($e36VYd=r(&D8T zNDG%=Vk{L_+R=IWRPpv=KD%VhA=-)M45iO~ z7}-i+KMt0|W1)jcPmN=p*Lm_#d+$j{nhKPbegPKUtiRL%JaW5;!*m zr0ZXn$@?B*P(}ug#vXgPi3CWX7YOXv|9hc+tOE&<011!)36KB@kN^pg011!)36Q`J z0r?$(fdojPzX(L~+duAQ?|Zwu>;8P4-mr0F{R`0uXwV2~&v2Gs!EZ)s2sq}s9pd^lH4we;mU=+bZ4K%H4e9}H5B0!~Mj+7zXsLsg0V!=HuceM94mggB|LOypo{lCF zK1$w}x&c{d0O65@!mT_<1J|l`q6;{vEx&)zH>mJ|!-~#pksFRw?L%jYie8+Cls=Ki zwof#(=z?Tsfc=f`J4`puY%g-`~D3+TUdS&q+Xk zefg|y-xH87pV-jd?E&h4ssF{BVD@-$u%lb%^M4O{g7BQ4Ns_+bJ_)qy@TkxK$uob? z!{qrtnMUmO{GU8$#OMD2fq?|h5CQ4>-9I#R7mfPgZW@e}K<^RQumAU6ZCN7{AOR8} z0TLhq5+DH*AOR8}0TSqM0`fZm0|}5oe-WVmm-^p5UlC0G?;&0~P5p0woh?~g66h@g zeE>=QVN_y3Ew?{%2?5*^?b*vl|^t*&SZ<)1KKfXV*|yac-nV;}(% vIDG>0-yIAjKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2Jy+z<(GFtwb diff --git a/locale/it/Resources_It.suo b/locale/it/Resources_It.suo index e7d7b34746c19e04fe614a2535d64b619d979e38..8153fba35c9c749b53411b9025e5094f3e8fdf52 100644 GIT binary patch delta 236 zcmZp$Xt3De!@|fkS&>DaEy0nq>-(q4MJ$(i1Q-|?Sb_LI5KO+vqB8ja2g~LP)(y;z zW}7uRXEXA!10{Kp6*O?NO#Z>;J^8SZ;p78+ER!p^y?GhgfGRkURBisk?awm#u!Qa8 z1_5WVQU`vZHUXc>E&_Iwn*`lBxR6v&{vznl3w8oGvS^8rKQALEP=p6bbn_RXO+d#@ V*5s7md`zr~kwX+&vP7bX830(LR^k8v delta 240 zcmZp$Xt3De!@|flS&>Da?SWA0zJ^DWi&!r4h%zuRumkabAeelSMP>2<4wlUotQ(ja zO*U(C&SvD{07~*8D`?${`WI8XB^kfHqpdkW2JOWTbxb-E1A(K4>btZoi^yg*d1j=$FYbz1*pX|(SxcQ6F aCZGc+YjVnOJ|@=0$ial9Xmg1~4>JIktXZA_ diff --git a/locale/ru/Resources_RU.rc b/locale/ru/Resources_RU.rc new file mode 100644 index 0000000000000000000000000000000000000000..d16af362c687d149198e396e177a871c684220aa GIT binary patch literal 91118 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +