diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 44f23fe..6593552 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -123,7 +123,7 @@ #define DISABLEFOGGING 0x00000080 // Disable D3D fogging #define NOPOWER2FIX 0x00000100 // Handle textures whose size is not a power of 2 (32, 64, 128 ...) #define NOPERFCOUNTER 0x00000200 // Disables the GetPerfCounter performance metrics API,as if it was not supported.... -//#define ADDPROXYLIBS 0x00000400 // Add proxy libs to otherwise hook-resilient system libraries (e.g. d3d9.dll) +#define BILINEARFILTER 0x00000400 // attempt to smooth low-res graphic by applying biulinear filtering in emulation mode #define INTERCEPTRDTSC 0x00000800 // Intercapts RDTSC opcodes to hook at assembly level #define LIMITSCREENRES 0x00001000 // Limit available screen resolution up to defined maximum #define NOFILLRECT 0x00002000 // Suppress FillRect calls @@ -258,7 +258,6 @@ LRESULT CALLBACK extDialogWindowProc(HWND, UINT, WPARAM, LPARAM); #define IsAssertEnabled (dxw.dwTFlags & ASSERTDIALOG) #define STEP OutTrace("STEP at %s:%d\n", __FILE__, __LINE__) -extern void WinDBPut(HWND, WNDPROC, int, int); extern BOOL WinDBGetSize(HWND, int *, int *); extern WNDPROC WinDBGetProc(HWND); extern void WinDBPutProc(HWND, WNDPROC); diff --git a/build/Resources_CN.dll b/build/Resources_CN.dll index 97de0a0..107b622 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:f4ebe7bb2d5b4f0c2e01945a42c267f0cf4ed997b613467bb6d6765c7e8bd509 +oid sha256:c6ce831ba912fd0a77ada82ff268cc3c5cc5b143ceba47afa5e0788624735db6 size 125952 diff --git a/build/Resources_EN.dll b/build/Resources_EN.dll index cc10c2c..2db050a 100644 --- a/build/Resources_EN.dll +++ b/build/Resources_EN.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7877cda228843a7292dcc2ef71b5137b271f8b9e179d9c23e28ed8d2f4312b3 +oid sha256:e39bc9f35955a42e51eccb033dbb72b802e4e0a91c62191beef0052f7f1d3d22 size 131072 diff --git a/build/Resources_IT.dll b/build/Resources_IT.dll index 76e348d..29f7e48 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:7ef79c84347b104980862e150366e8b8a0115714151f066e4374a9bc11bb2e76 +oid sha256:e4a8fde842a309899161df48662be08b6bf37c06b73f603cd9d199224e09ff82 size 132096 diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 9f9b368..1e41ea6 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44bc7151507fb71f758117713d02a61e84ee848a109920a5e8c6820e4cfe79a2 -size 493568 +oid sha256:560b196fd41dbbde675f2e6704d3c54299dd975d272960a9cee2b7ce33ea7dc8 +size 495616 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 781ca07..2a8f0da 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5570bd89772f420d0608463f52afa594fcd539e13d51ea017829fbc0d63ed28 +oid sha256:c4f935425138f4ca43dedf590f0e046ccea571fc42e7620b6673226b6f2179f9 size 549376 diff --git a/build/dxwnd.ini b/build/dxwnd.ini index 4df1801..d060f11 100644 --- a/build/dxwnd.ini +++ b/build/dxwnd.ini @@ -1,59 +1,7 @@ [window] -posx=1074 -posy=334 sizx=320 sizy=200 lang=automatic +posx=50 +posy=50 [target] -title0=MetroLL.exe -path0=D:\Games\Metro Last Light\MetroLL.exe -launchpath0= -module0= -opengllib0= -ver0=10 -coord0=0 -flag0=679477792 -flagg0=1207959552 -flagh0=20 -flagi0=205520900 -tflag0=6147 -initx0=0 -inity0=0 -minx0=0 -miny0=0 -maxx0=0 -maxy0=0 -posx0=50 -posy0=50 -sizx0=800 -sizy0=600 -maxfps0=0 -initts0=0 -winver0=0 -maxres0=-1 -title1=MC.EXE -path1=D:\Games\Moonchld\MC.EXE -launchpath1= -module1= -opengllib1= -ver1=0 -coord1=0 -flag1=134218336 -flagg1=1207959552 -flagh1=2068 -flagi1=-2009071612 -tflag1=6147 -initx1=0 -inity1=0 -minx1=0 -miny1=0 -maxx1=0 -maxy1=0 -posx1=50 -posy1=50 -sizx1=800 -sizy1=600 -maxfps1=0 -initts1=0 -winver1=0 -maxres1=-1 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 91a90c1..1aca786 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -552,4 +552,8 @@ fix: removed extra reference to ddraw session causing window movements on fullsc v2.02.85 fix: revised handling of d3d D3DFORMAT field: fixes "Call of Cthulhu DCotE" color problems -fix: added recovery for rounded child win coordinates: fixes blitting problems in Diablo when win size is not an exact multiple of native resolution. \ No newline at end of file +fix: added recovery for rounded child win coordinates: fixes blitting problems in Diablo when win size is not an exact multiple of native resolution. + +v2.02.86 +fix: thank to aqrit's research, hooked and hanlded user32.dll GetUpdateRgn API. This fixes refresh and crash problems in Diablo & Hellfire. +added bilinear filtering to directdraw palettized 8BPP emulated mode (where it is mostly needed!). A must try is "Genocide" ! \ No newline at end of file diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index d6df995..fe3c3af 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -2488,6 +2488,11 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = dxw.GetScreenWidth(); ddsd.dwHeight = dxw.GetScreenHeight(); + if(dxw.dwFlags4 & BILINEARFILTER){ + // double backbuffer size + ddsd.dwWidth = dxw.GetScreenWidth() << 1; + ddsd.dwHeight = dxw.GetScreenHeight() << 1; + } DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[EmuBack]" , __LINE__); res=(*pCreateSurface)(lpdd, &ddsd, &lpDDSEmu_Back, 0); @@ -3709,6 +3714,7 @@ HRESULT WINAPI extLock(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC } if(res) OutTraceE("Lock ERROR: ret=%x(%s)\n", res, ExplainDDError(res)); DumpSurfaceAttributes(lpDDSurfaceDesc, "[Locked]" , __LINE__); + OutTraceB("Lock: lPitch=%d lpSurface=%x\n", lpDDSurfaceDesc->lPitch, lpDDSurfaceDesc->lpSurface); if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; // shouldn't happen.... if hooked to non primary surface, just call regular method. diff --git a/dll/dxemublt.cpp b/dll/dxemublt.cpp index 1cf9fec..6c049c7 100644 --- a/dll/dxemublt.cpp +++ b/dll/dxemublt.cpp @@ -126,31 +126,6 @@ static HRESULT WINAPI EmuBlt_8_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdest } if(dxw.dwFlags3 & MARKBLIT) MarkRect32(dest0, w, h, destpitch); -#if 0 - if(1 && IsTraceDDRAW) { - DWORD dwStats[256]; - src8 = (BYTE *)lpsurface; - src8 += lpsrcrect->top*ddsd_src.lPitch; - src8 += lpsrcrect->left; - for(x = 0; x < 256; x ++) dwStats[x]=0; - for(y = 0; y < h; y ++){ - for(x = 0; x < w; x ++){ - dwStats[*(src8 ++)]++; - } - src8 += srcpitch; - } - OutTrace("Colors: "); - for(x = 0; x < 256; x ++) { - char sElement[8]; - if (dwStats[x]) - sprintf(sElement,"%x,", dwStats[x]); - else - strcpy(sElement, "_,"); - OutTrace(sElement); - } - OutTrace("\n"); - } -#endif res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect); if (res) OutTraceE("EmuBlt8_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__); @@ -159,6 +134,112 @@ static HRESULT WINAPI EmuBlt_8_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdest return res; } +static DWORD Melt(DWORD c1, DWORD c2) +{ + DWORD ret; + register BYTE *b1 = (BYTE *)&c1; + register BYTE *b2 = (BYTE *)&c2; + register BYTE *br = (BYTE *)&ret; + //for(int i=0; i<4; i++) + *br++ = (*(b1++)>>1) + (*(b2++)>>1); + *br++ = (*(b1++)>>1) + (*(b2++)>>1); + *br++ = (*(b1++)>>1) + (*(b2++)>>1); + return ret; +} + +static HRESULT WINAPI BilinearBlt_8_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) +{ + HRESULT res; + BYTE *src8; + DWORD *dest, *dest0; + DDSURFACEDESC2 ddsd_src, ddsd_dst; + long srcpitch, destpitch; + DWORD x, y, w, h; + + w = lpdestrect->right - lpdestrect->left; + h = lpdestrect->bottom - lpdestrect->top; + + lpdestrect->left <<= 1; + lpdestrect->top <<= 1; + lpdestrect->right <<= 1; + lpdestrect->bottom <<= 1; + + memset(&ddsd_dst,0,sizeof(DDSURFACEDESC2)); + ddsd_dst.dwSize = Set_dwSize_From_Surface(lpddsdst); + ddsd_dst.dwFlags = DDSD_LPSURFACE | DDSD_PITCH; + if(res=(*pLock)(lpddsdst, 0, (LPDDSURFACEDESC)&ddsd_dst, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0)){ + OutTraceE("BilBlt8_32: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + + memset(&ddsd_src,0,sizeof(DDSURFACEDESC2)); + ddsd_src.dwSize = Set_dwSize_From_Surface(lpddssrc); + ddsd_src.dwFlags = DDSD_LPSURFACE | DDSD_PITCH; + if (lpsurface) { // already locked, just get info .... + if(res=lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd_src)) { + OutTraceE("BilBlt8_32: GetSurfaceDesc ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + (*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect); + (*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect); + return 0; + } + } + else { + if(res=(*pLock)(lpddssrc, 0, (LPDDSURFACEDESC)&ddsd_src, DDLOCK_SURFACEMEMORYPTR|DDLOCK_READONLY, 0)) { + (*pUnlockMethod(lpddsdst))(lpddsdst,0); + OutTraceE("BilBlt8_32: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return 0; + } + lpsurface=ddsd_src.lpSurface; + } + + ddsd_dst.lPitch >>= 2; + dest = (DWORD *)ddsd_dst.lpSurface; + dest += lpdestrect->top*ddsd_dst.lPitch; + dest += lpdestrect->left; + destpitch = ddsd_dst.lPitch - (2 * w); + dest0 = dest; + + src8 = (BYTE *)lpsurface; + src8 += lpsrcrect->top*ddsd_src.lPitch; + src8 += lpsrcrect->left; + srcpitch = ddsd_src.lPitch - w; + + // OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src8,dest,srcpitch,destpitch); + for(y = 0; y < h; y ++){ + BYTE *begin = src8; + for(x = 0; x < w; x ++){ + *(dest ++) = PaletteEntries[*(src8)]; + *(dest ++) = Melt(PaletteEntries[*(src8)], PaletteEntries[*(src8+1)]); + src8++; + } + src8 = begin; + dest += destpitch; + if(y+1 == h) + for(x = 0; x < w; x ++){ // last line, duplicate the line above + *(dest ++) = PaletteEntries[*(src8)]; + *(dest ++) = Melt(PaletteEntries[*(src8)], PaletteEntries[*(src8+1)]); + src8++; + } + else + for(x = 0; x < w; x ++){ + *(dest ++) = Melt(PaletteEntries[*(src8)], PaletteEntries[*(src8+w)]); + *(dest ++) = Melt(PaletteEntries[*(src8+1)], PaletteEntries[*(src8+w)]); + src8++; + } + src8 += srcpitch; + dest += destpitch; + } + + if(dxw.dwFlags3 & MARKBLIT) MarkRect32(dest0, w, h, destpitch); + + res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect); + if (res) OutTraceE("BilBlt8_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__); + res=(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect); + if (res) OutTraceE("BilBlt8_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddssrc, res, ExplainDDError(res), __LINE__); + return res; +} + static HRESULT WINAPI EmuBlt_16_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) { @@ -999,6 +1080,7 @@ void SetBltTransformations() case 8: pRevBlt=RevBlt_32_to_8; pEmuBlt=EmuBlt_8_to_32; + if(dxw.dwFlags4 & BILINEARFILTER) pEmuBlt=BilinearBlt_8_to_32; OutTraceDW("set color transformation 8<->32\n"); break; case 16: diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 38b7f79..5797968 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -82,7 +82,7 @@ static char *Flag3Names[32]={ static char *Flag4Names[32]={ "NOALPHACHANNEL", "SUPPRESSCHILD", "FIXREFCOUNTER", "SHOWTIMESTRETCH", "ZBUFFERCLEAN", "ZBUFFER0CLEAN", "ZBUFFERALWAYS", "DISABLEFOGGING", - "NOPOWER2FIX", "NOPERFCOUNTER", "ADDPROXYLIBS", "INTERCEPTRDTSC", + "NOPOWER2FIX", "NOPERFCOUNTER", "BILINEARFILTER", "INTERCEPTRDTSC", "LIMITSCREENRES", "NOFILLRECT", "HOOKGLIDE", "HIDEDESKTOP", "STRETCHTIMERS", "NOFLIPEMULATION", "NOTEXTURES", "RETURNNULLREF", "FINETIMING", "NATIVERES", "SUPPORTSVGA", "SUPPORTHDTV", diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp index 157f238..f23fd4a 100644 --- a/dll/dxwcore.cpp +++ b/dll/dxwcore.cpp @@ -594,8 +594,8 @@ POINT dxwCore::FixMessagePt(HWND hwnd, POINT point) if (curr.y < 0) curr.y=0; if (curr.x > rect.right) curr.x=rect.right; if (curr.y > rect.bottom) curr.y=rect.bottom; - if (rect.right) curr.x = (curr.x * dxw.GetScreenWidth()) / rect.right; - if (rect.bottom) curr.y = (curr.y * dxw.GetScreenHeight()) / rect.bottom; + if (rect.right) curr.x = ((curr.x * dxw.GetScreenWidth()) + (rect.right >> 1)) / rect.right; + if (rect.bottom) curr.y = ((curr.y * dxw.GetScreenHeight()) + (rect.bottom >> 1)) / rect.bottom; return curr; } @@ -607,10 +607,10 @@ void dxwCore::MapClient(LPRECT rect) if(!(*pGetClientRect)(hWnd, &client)) return; w = client.right ? client.right : iSizX; h = client.bottom ? client.bottom : iSizY; - rect->left= rect->left * w / (int)dwScreenWidth; - rect->top= rect->top * h / (int)dwScreenHeight; - rect->right= rect->right * w / (int)dwScreenWidth; - rect->bottom= rect->bottom * h / (int)dwScreenHeight; + rect->left= ((rect->left * w)+(dwScreenWidth >> 1)) / (int)dwScreenWidth; + rect->top= ((rect->top * h)+(dwScreenHeight >> 1)) / (int)dwScreenHeight; + rect->right= ((rect->right * w)+(dwScreenWidth >> 1)) / (int)dwScreenWidth; + rect->bottom= ((rect->bottom * h)+(dwScreenHeight >> 1)) / (int)dwScreenHeight; } void dxwCore::MapClient(int *nXDest, int *nYDest, int *nWDest, int *nHDest) @@ -620,10 +620,10 @@ void dxwCore::MapClient(int *nXDest, int *nYDest, int *nWDest, int *nHDest) if(!(*pGetClientRect)(hWnd, &client)) return; w = client.right ? client.right : iSizX; h = client.bottom ? client.bottom : iSizY; - *nXDest= *nXDest * w / (int)dwScreenWidth; - *nYDest= *nYDest * h / (int)dwScreenHeight; - *nWDest= *nWDest * w / (int)dwScreenWidth; - *nHDest= *nHDest * h / (int)dwScreenHeight; + *nXDest= ((*nXDest * w)+(dwScreenWidth >> 1)) / (int)dwScreenWidth; + *nYDest= ((*nYDest * h)+(dwScreenHeight >> 1)) / (int)dwScreenHeight; + *nWDest= ((*nWDest * w)+(dwScreenWidth >> 1)) / (int)dwScreenWidth; + *nHDest= ((*nHDest * h)+(dwScreenHeight >> 1)) / (int)dwScreenHeight; } void dxwCore::MapClient(LPPOINT lppoint) @@ -633,8 +633,8 @@ void dxwCore::MapClient(LPPOINT lppoint) if(!(*pGetClientRect)(hWnd, &client)) return; w = client.right ? client.right : iSizX; h = client.bottom ? client.bottom : iSizY; - lppoint->x = (lppoint->x * w) / (int)dwScreenWidth; - lppoint->y = (lppoint->y * h) / (int)dwScreenHeight; + lppoint->x= ((lppoint->x * w)+(dwScreenWidth >> 1)) / (int)dwScreenWidth; + lppoint->y= ((lppoint->y * h)+(dwScreenHeight >> 1)) / (int)dwScreenHeight; } void dxwCore::MapClient(int *nXDest, int *nYDest) @@ -644,8 +644,8 @@ void dxwCore::MapClient(int *nXDest, int *nYDest) if(!(*pGetClientRect)(hWnd, &client)) return; w = client.right ? client.right : iSizX; h = client.bottom ? client.bottom : iSizY; - *nXDest= *nXDest * w / (int)dwScreenWidth; - *nYDest= *nYDest * h / (int)dwScreenHeight; + *nXDest= ((*nXDest * w)+(dwScreenWidth >> 1)) / (int)dwScreenWidth; + *nYDest= ((*nYDest * h)+(dwScreenHeight >> 1)) / (int)dwScreenHeight; } void dxwCore::UnmapClient(LPPOINT lppoint) @@ -655,8 +655,8 @@ void dxwCore::UnmapClient(LPPOINT lppoint) if(!(*pGetClientRect)(hWnd, &client)) return; w = client.right ? client.right : iSizX; h = client.bottom ? client.bottom : iSizY; - if(w) lppoint->x = (lppoint->x * (int)dwScreenWidth) / w; - if(h) lppoint->y = (lppoint->y * (int)dwScreenHeight) / h; + if(w) lppoint->x = ((lppoint->x * (int)dwScreenWidth) + (w >> 1)) / w; + if(h) lppoint->y = ((lppoint->y * (int)dwScreenHeight) + (h >> 1)) / h; } void dxwCore::UnmapClient(int *nXDest, int *nYDest) @@ -666,8 +666,8 @@ void dxwCore::UnmapClient(int *nXDest, int *nYDest) if(!(*pGetClientRect)(hWnd, &client)) return; w = client.right ? client.right : iSizX; h = client.bottom ? client.bottom : iSizY; - if(w) *nXDest= *nXDest * (int)dwScreenWidth / w; - if(h) *nYDest= *nYDest * (int)dwScreenHeight / h; + if(w) *nXDest = ((*nXDest * (int)dwScreenWidth) + (w >> 1)) / w; + if(h) *nYDest = ((*nYDest * (int)dwScreenHeight) + (h >> 1)) / h; } void dxwCore::UnmapClient(LPRECT lpRect) @@ -678,12 +678,12 @@ void dxwCore::UnmapClient(LPRECT lpRect) w = client.right ? client.right : iSizX; h = client.bottom ? client.bottom : iSizY; if(w) { - lpRect->left = (lpRect->left * (int)dwScreenWidth) / w; - lpRect->right = (lpRect->right * (int)dwScreenWidth) / w; + lpRect->left = ((lpRect->left * (int)dwScreenWidth) + (w >> 1)) / w; + lpRect->right = ((lpRect->right * (int)dwScreenWidth) + (w >> 1)) / w; } if(h) { - lpRect->top = (lpRect->top * (int)dwScreenHeight) / h; - lpRect->bottom = (lpRect->bottom * (int)dwScreenHeight) / h; + lpRect->top = ((lpRect->top * (int)dwScreenHeight) + (h >> 1)) / h; + lpRect->bottom = ((lpRect->bottom * (int)dwScreenHeight) + (h >> 1)) / h; } } @@ -693,10 +693,10 @@ void dxwCore::MapWindow(LPRECT rect) POINT upleft = {0,0}; if(!(*pGetClientRect)(hWnd, &client)) return; (*pClientToScreen)(hWnd, &upleft); - rect->left= upleft.x + ((rect->left * client.right) / (int)dwScreenWidth); - rect->top= upleft.y + ((rect->top * client.bottom) / (int)dwScreenHeight); - rect->right= upleft.x + ((rect->right * client.right) / (int)dwScreenWidth); - rect->bottom= upleft.y + ((rect->bottom * client.bottom) / (int)dwScreenHeight); + rect->left= upleft.x + (((rect->left * client.right) + (dwScreenWidth >> 1)) / (int)dwScreenWidth); + rect->top= upleft.y + (((rect->top * client.bottom) + (dwScreenHeight >> 1)) / (int)dwScreenHeight); + rect->right= upleft.x + (((rect->right * client.right) + (dwScreenWidth >> 1)) / (int)dwScreenWidth); + rect->bottom= upleft.y + (((rect->bottom * client.bottom) + (dwScreenHeight >> 1)) / (int)dwScreenHeight); } void dxwCore::MapWindow(int *nXDest, int *nYDest, int *nWDest, int *nHDest) @@ -705,10 +705,10 @@ void dxwCore::MapWindow(int *nXDest, int *nYDest, int *nWDest, int *nHDest) POINT upleft = {0,0}; if(!(*pGetClientRect)(hWnd, &client)) return; (*pClientToScreen)(hWnd, &upleft); - *nXDest= upleft.x + ((*nXDest * client.right) / (int)dwScreenWidth); - *nYDest= upleft.y + ((*nYDest * client.bottom) / (int)dwScreenHeight); - *nWDest= (*nWDest * client.right) / (int)dwScreenWidth; - *nHDest= (*nHDest * client.bottom) / (int)dwScreenHeight; + *nXDest= upleft.x + (((*nXDest * client.right) + (dwScreenWidth >> 1)) / (int)dwScreenWidth); + *nYDest= upleft.y + (((*nYDest * client.bottom) + (dwScreenHeight >> 1)) / (int)dwScreenHeight); + *nWDest= ((*nWDest * client.right) + (dwScreenWidth >> 1)) / (int)dwScreenWidth; + *nHDest= ((*nHDest * client.bottom) + (dwScreenHeight >> 1)) / (int)dwScreenHeight; } void dxwCore::MapWindow(LPPOINT lppoint) @@ -717,8 +717,8 @@ void dxwCore::MapWindow(LPPOINT lppoint) POINT upleft = {0,0}; if(!(*pGetClientRect)(hWnd, &client)) return; (*pClientToScreen)(hWnd, &upleft); - lppoint->x = upleft.x + ((lppoint->x * client.right) / dwScreenWidth); - lppoint->y = upleft.y + ((lppoint->y * client.bottom) / dwScreenHeight); + lppoint->x = upleft.x + (((lppoint->x * client.right) + (dwScreenWidth >> 1)) / dwScreenWidth); + lppoint->y = upleft.y + (((lppoint->y * client.bottom) + (dwScreenHeight >> 1)) / dwScreenHeight); } POINT dxwCore::ClientOffset(HWND hwnd) @@ -736,8 +736,8 @@ POINT dxwCore::ClientOffset(HWND hwnd) upleft.x = upleft.y = 0; (*pClientToScreen)(hWnd, &upleft); desk0 = upleft; - if (desktop.right) ret.x = ((win0.x - desk0.x) * (LONG)dwScreenWidth) / desktop.right; - if (desktop.bottom) ret.y = ((win0.y - desk0.y) * (LONG)dwScreenHeight) / desktop.bottom; + if (desktop.right) ret.x = (((win0.x - desk0.x) * (LONG)dwScreenWidth) + (desktop.right >> 1)) / desktop.right; + if (desktop.bottom) ret.y = (((win0.y - desk0.y) * (LONG)dwScreenHeight) + (desktop.bottom >> 1)) / desktop.bottom; OutTraceB("ClientOffset: hwnd=%x offset=(%d,%d)\n", hwnd, ret.x, ret.y); return ret; } @@ -753,10 +753,10 @@ RECT dxwCore::GetWindowRect(RECT win) if(!desktop.right || !desktop.bottom) return win; - win.left = ((win.left - desk0.x) * (LONG)dwScreenWidth) / desktop.right; - win.top = ((win.top - desk0.y) * (LONG)dwScreenHeight) / desktop.bottom; - win.right = ((win.right - desk0.x) * (LONG)dwScreenWidth) / desktop.right; - win.bottom = ((win.bottom - desk0.y) * (LONG)dwScreenHeight) / desktop.bottom; + win.left = (((win.left - desk0.x) * (LONG)dwScreenWidth) + (desktop.right >> 1)) / desktop.right; + win.top = (((win.top - desk0.y) * (LONG)dwScreenHeight) + (desktop.bottom >> 1)) / desktop.bottom; + win.right = (((win.right - desk0.x) * (LONG)dwScreenWidth) + (desktop.right >> 1)) / desktop.right; + win.bottom = (((win.bottom - desk0.y) * (LONG)dwScreenHeight) + (desktop.bottom >> 1)) / desktop.bottom; return win; } @@ -768,10 +768,10 @@ RECT dxwCore::GetClientRect(RECT win) if(!desktop.right || !desktop.bottom) return win; - win.left = (win.left * dwScreenWidth) / desktop.right; - win.top = (win.top * dwScreenHeight) / desktop.bottom; - win.right = (win.right * dwScreenWidth) / desktop.right; - win.bottom = (win.bottom * dwScreenHeight) / desktop.bottom; + win.left = ((win.left * dwScreenWidth) + (desktop.right >> 1)) / desktop.right; + win.top = ((win.top * dwScreenHeight) + (desktop.bottom >> 1)) / desktop.bottom; + win.right = ((win.right * dwScreenWidth) + (desktop.right >> 1)) / desktop.right; + win.bottom = ((win.bottom * dwScreenHeight) + (desktop.bottom >> 1)) / desktop.bottom; return win; } diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index d0635d9..f297218 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -24,7 +24,7 @@ along with this program. If not, see . #include "dxwnd.h" #include "dxwcore.hpp" -#define VERSION "2.02.85" +#define VERSION "2.02.86" #define DDTHREADLOCK 1 diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index 61209d3..de13cab 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/syslibs.h b/dll/syslibs.h index f41b85c..c36431b 100644 --- a/dll/syslibs.h +++ b/dll/syslibs.h @@ -163,12 +163,14 @@ typedef BOOL (WINAPI *GetMessage_Type)(LPMSG, HWND, UINT, UINT); typedef BOOL (WINAPI *GetMonitorInfo_Type)(HMONITOR, LPMONITORINFO); typedef int (WINAPI *GetSystemMetrics_Type)(int); typedef HWND (WINAPI *GetTopWindow_Type)(HWND); +typedef int (WINAPI *GetUpdateRgn_Type)(HWND, HRGN, BOOL); typedef LONG (WINAPI *GetWindowLong_Type)(HWND, int); typedef BOOL (WINAPI *GetWindowRect_Type)(HWND, LPRECT); typedef BOOL (WINAPI *InvalidateRect_Type)(HWND, CONST RECT *, BOOL); typedef int (WINAPI *MapWindowPoints_Type)(HWND, HWND, LPPOINT, UINT); typedef BOOL (WINAPI *MoveWindow_Type)(HWND, int, int, int, int, BOOL); typedef BOOL (WINAPI *PeekMessage_Type)(LPMSG, HWND, UINT, UINT, UINT); +typedef BOOL (WINAPI *RedrawWindow_Type)(HWND, const RECT *, HRGN, UINT); typedef ATOM (WINAPI *RegisterClassExA_Type)(WNDCLASSEX *); typedef ATOM (WINAPI *RegisterClassA_Type)(WNDCLASS *); typedef int (WINAPI *GDIReleaseDC_Type)(HWND, HDC); @@ -370,6 +372,7 @@ DXWEXTERN GetMonitorInfo_Type pGetMonitorInfoW DXWINITIALIZED; DXWEXTERN GetSystemMetrics_Type pGetSystemMetrics DXWINITIALIZED; DXWEXTERN GetTopWindow_Type pGetTopWindow DXWINITIALIZED; DXWEXTERN GDIGetDC_Type pGDIGetWindowDC DXWINITIALIZED; +DXWEXTERN GetUpdateRgn_Type pGetUpdateRgn DXWINITIALIZED; DXWEXTERN GetWindowLong_Type pGetWindowLongA DXWINITIALIZED; DXWEXTERN GetWindowLong_Type pGetWindowLongW DXWINITIALIZED; DXWEXTERN GetWindowRect_Type pGetWindowRect DXWINITIALIZED; @@ -377,6 +380,7 @@ DXWEXTERN InvalidateRect_Type pInvalidateRect DXWINITIALIZED; DXWEXTERN MapWindowPoints_Type pMapWindowPoints DXWINITIALIZED; DXWEXTERN MoveWindow_Type pMoveWindow DXWINITIALIZED; DXWEXTERN PeekMessage_Type pPeekMessage DXWINITIALIZED; +DXWEXTERN RedrawWindow_Type pRedrawWindow DXWINITIALIZED; DXWEXTERN RegisterClassExA_Type pRegisterClassExA DXWINITIALIZED; DXWEXTERN RegisterClassA_Type pRegisterClassA DXWINITIALIZED; DXWEXTERN GDIReleaseDC_Type pGDIReleaseDC DXWINITIALIZED; @@ -580,6 +584,7 @@ extern BOOL WINAPI extGetMonitorInfoA(HMONITOR, LPMONITORINFO); extern BOOL WINAPI extGetMonitorInfoW(HMONITOR, LPMONITORINFO); extern int WINAPI extGetSystemMetrics(int); extern HWND WINAPI extGetTopWindow(HWND); +extern int WINAPI extGetUpdateRgn(HWND, HRGN, BOOL); extern HDC WINAPI extGDIGetWindowDC(HWND); extern HDC WINAPI extEMUGetWindowDC(HWND); extern HDC WINAPI extDDGetWindowDC(HWND); @@ -591,6 +596,7 @@ extern BOOL WINAPI extInvalidateRect(HWND, RECT *, BOOL); extern int WINAPI extMapWindowPoints(HWND, HWND, LPPOINT, UINT); extern BOOL WINAPI extMoveWindow(HWND, int, int, int, int, BOOL); extern BOOL WINAPI extPeekMessage(LPMSG, HWND, UINT, UINT, UINT); +extern BOOL WINAPI extRedrawWindow(HWND, const RECT *, HRGN, UINT); extern ATOM WINAPI extRegisterClassExA(WNDCLASSEXA *); extern ATOM WINAPI extRegisterClassA(WNDCLASSA *); extern int WINAPI extGDIReleaseDC(HWND, HDC); diff --git a/dll/user32.cpp b/dll/user32.cpp index b97a21d..c04ce68 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -108,7 +108,9 @@ static HookEntry_Type RemapHooks[]={ {HOOK_IAT_CANDIDATE, "GetClientRect", (FARPROC)GetClientRect, (FARPROC *)&pGetClientRect, (FARPROC)extGetClientRect}, {HOOK_IAT_CANDIDATE, "GetWindowRect", (FARPROC)GetWindowRect, (FARPROC *)&pGetWindowRect, (FARPROC)extGetWindowRect}, {HOOK_IAT_CANDIDATE, "MapWindowPoints", (FARPROC)MapWindowPoints, (FARPROC *)&pMapWindowPoints, (FARPROC)extMapWindowPoints}, + {HOOK_IAT_CANDIDATE, "GetUpdateRgn", (FARPROC)GetUpdateRgn, (FARPROC *)&pGetUpdateRgn, (FARPROC)extGetUpdateRgn}, //{HOOK_IAT_CANDIDATE, "GetUpdateRect", (FARPROC)GetUpdateRect, (FARPROC *)&pGetUpdateRect, (FARPROC)extGetUpdateRect}, + //{HOOK_IAT_CANDIDATE, "RedrawWindow", (FARPROC)RedrawWindow, (FARPROC *)&pRedrawWindow, (FARPROC)extRedrawWindow}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; @@ -1016,8 +1018,12 @@ BOOL WINAPI extGetWindowRect(HWND hwnd, LPRECT lpRect) // Diablo fix: it retrieves coordinates for the explorer window, that are as big as the real desktop!!! if(lpRect->left < 0) lpRect->left=0; +// if(lpRect->left > (LONG)dxw.GetScreenWidth()) lpRect->left=dxw.GetScreenWidth(); +// if(lpRect->right < 0) lpRect->right=0; if(lpRect->right > (LONG)dxw.GetScreenWidth()) lpRect->right=dxw.GetScreenWidth(); if(lpRect->top < 0) lpRect->top=0; +// if(lpRect->top > (LONG)dxw.GetScreenHeight()) lpRect->top=dxw.GetScreenHeight(); +// if(lpRect->bottom < 0) lpRect->bottom=0; if(lpRect->bottom > (LONG)dxw.GetScreenHeight()) lpRect->bottom=dxw.GetScreenHeight(); OutTraceB("GetWindowRect: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); @@ -1983,7 +1989,8 @@ HDC WINAPI extBeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint) // on CLIENTREMAPPING, resize the paint area to virtual screen size if(dxw.dwFlags1 & CLIENTREMAPPING) lpPaint->rcPaint=dxw.GetScreenRect(); - OutTraceDW("GDI.BeginPaint: hdc=%x\n", hdc); + OutTraceDW("GDI.BeginPaint: hdc=%x rcPaint=(%d,%d)-(%d,%d)\n", + hdc, lpPaint->rcPaint.left, lpPaint->rcPaint.top, lpPaint->rcPaint.right, lpPaint->rcPaint.bottom); return hdc; } @@ -2434,6 +2441,13 @@ BOOL WINAPI extUpdateWindow(HWND hwnd) return ret; } +BOOL WINAPI extRedrawWindow(HWND hWnd, const RECT *lprcUpdate, HRGN hrgnUpdate, UINT flags) +{ + OutTraceDW("RedrawWindow: hwnd=%x flags=%x\n", hWnd, flags); + return (*pRedrawWindow)(hWnd, lprcUpdate, hrgnUpdate, flags); +} + + BOOL WINAPI extGetWindowPlacement(HWND hwnd, WINDOWPLACEMENT *lpwndpl) { BOOL ret; @@ -2691,3 +2705,20 @@ BOOL WINAPI extGetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpmi) { return extGetMonitorInfo(hMonitor, lpmi, pGetMonitorInfoW); } + +int WINAPI extGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase) +{ + int regionType; + RECT rc; + regionType=(*pGetUpdateRgn)(hWnd, hRgn, bErase); + if( regionType == SIMPLEREGION ){ + regionType = GetRgnBox( hRgn, &rc ); + if( regionType == SIMPLEREGION ){ + dxw.UnmapClient(&rc); + if( SetRectRgn( hRgn, rc.left, rc.top, rc.right, rc.bottom ) ){ + ; // success + } + } + } + return regionType; +} \ No newline at end of file diff --git a/host/Resource.h b/host/Resource.h index c346f1b..8ebc3a6 100644 Binary files a/host/Resource.h and b/host/Resource.h differ diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 70096ab..752f061 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -21,6 +21,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) { //{{AFX_DATA_INIT(CTargetDlg) m_DXVersion = 0; + m_BilinearFilter = 0; m_Coordinates = 0; m_DxEmulationMode = 4; // default: AUTOMATIC m_DCEmulationMode = 0; // default: no emulation diff --git a/host/TargetDlg.h b/host/TargetDlg.h index ed98333..0b43c81 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -28,6 +28,7 @@ public: int m_Coordinates; int m_DxEmulationMode; int m_DCEmulationMode; + BOOL m_BilinearFilter; BOOL m_HookDI; BOOL m_ModifyMouse; BOOL m_OutProxyTrace; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index df724c3..74a40fb 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index cf95ace..6594334 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 fbc03c7..3fa1ea2 100644 Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ diff --git a/host/dxwndhostView.cpp b/host/dxwndhostView.cpp index 7e63ad8..3ad4c81 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -128,6 +128,10 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) case 2: t->flags |= LOCKEDSURFACE; break; case 3: t->flags |= EMULATESURFACE; break; case 4: t->flags |= AUTOMATIC; break; + case 5: + t->flags |= EMULATESURFACE; + t->flags4 |= BILINEARFILTER; + break; } t->flags2 &= ~GDISTRETCHED; t->flags &= ~MAPGDITOPRIMARY; @@ -300,10 +304,15 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_PeekAllMessages = t->flags3 & PEEKALLMESSAGES ? 1 : 0; dlg->m_DxEmulationMode = 0; + dlg->m_BilinearFilter = FALSE; if(t->flags & EMULATEBUFFER) dlg->m_DxEmulationMode = 1; if(t->flags & LOCKEDSURFACE) dlg->m_DxEmulationMode = 2; if(t->flags & EMULATESURFACE) dlg->m_DxEmulationMode = 3; if(t->flags & AUTOMATIC) dlg->m_DxEmulationMode = 4; + if(t->flags4 & BILINEARFILTER) { + dlg->m_DxEmulationMode = 5; + dlg->m_BilinearFilter = TRUE; + } dlg->m_DCEmulationMode = 0; if(t->flags2 & GDISTRETCHED) dlg->m_DCEmulationMode = 1; diff --git a/locale/cn/Resources_Cn.ncb b/locale/cn/Resources_Cn.ncb index 3e9eff4..48bdd41 100644 Binary files a/locale/cn/Resources_Cn.ncb and b/locale/cn/Resources_Cn.ncb differ diff --git a/locale/cn/Resources_Cn.rc b/locale/cn/Resources_Cn.rc index aa1e0d2..ee71530 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 fc9c29a..5c6baa9 100644 Binary files a/locale/cn/Resources_Cn.suo and b/locale/cn/Resources_Cn.suo differ diff --git a/locale/en/Resources_EN.rc b/locale/en/Resources_EN.rc index cf95ace..6594334 100644 Binary files a/locale/en/Resources_EN.rc and b/locale/en/Resources_EN.rc differ diff --git a/locale/en/Resources_En.ncb b/locale/en/Resources_En.ncb index 812fa90..f02b3ef 100644 Binary files a/locale/en/Resources_En.ncb and b/locale/en/Resources_En.ncb differ diff --git a/locale/en/Resources_En.suo b/locale/en/Resources_En.suo index 4545e7a..5133e74 100644 Binary files a/locale/en/Resources_En.suo and b/locale/en/Resources_En.suo differ diff --git a/locale/it/Resources_IT.rc b/locale/it/Resources_IT.rc index 653d27d..5f2688d 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 index d8288be..c36d64f 100644 Binary files a/locale/it/Resources_It.ncb and b/locale/it/Resources_It.ncb differ diff --git a/locale/it/Resources_It.suo b/locale/it/Resources_It.suo index f2bfdbb..92db4c4 100644 Binary files a/locale/it/Resources_It.suo and b/locale/it/Resources_It.suo differ