diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 6593552..f04c52c 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -146,6 +146,9 @@ #define OVERRIDEREGISTRY 0x40000000 // same as EMULATEREGISTRY, but fake keys takeprecedence #define HIDECDROMEMPTY 0x80000000 // hide empty CDROM drivers +// fifth flags DWORD dxw.dwFlags5: +#define DIABLOTWEAK 0x00000001 // ... ??? ... + // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general #define OUTDDRAWTRACE 0x00000002 // traces DxWnd directdraw screen handling @@ -176,6 +179,7 @@ typedef struct TARGETMAP int flags2; int flags3; int flags4; + int flags5; int tflags; short initx; short inity; @@ -285,3 +289,5 @@ typedef enum { TIMER_TYPE_USER32, TIMER_TYPE_WINMM } Timer_Types; + +#define CREATEDESKTOP FALSE \ No newline at end of file diff --git a/build/Resources_CN.dll b/build/Resources_CN.dll index 107b622..91c3a99 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:c6ce831ba912fd0a77ada82ff268cc3c5cc5b143ceba47afa5e0788624735db6 +oid sha256:782d53dad4046b681b15ecfbc8dd370c7a8097b7903daf63e4089c9b96916158 size 125952 diff --git a/build/Resources_EN.dll b/build/Resources_EN.dll index 2db050a..0030f75 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:e39bc9f35955a42e51eccb033dbb72b802e4e0a91c62191beef0052f7f1d3d22 +oid sha256:9ad4422aea023277c8d4310eb68782709f10d7567c8b12af62a30a32b3016c57 size 131072 diff --git a/build/Resources_IT.dll b/build/Resources_IT.dll index 29f7e48..a527ff2 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:e4a8fde842a309899161df48662be08b6bf37c06b73f603cd9d199224e09ff82 +oid sha256:ab41e49d035c39a3a88ce07e5900ea8b8e8768ad56749e8f06969b9df343374f size 132096 diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 1e41ea6..f63f5a6 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:560b196fd41dbbde675f2e6704d3c54299dd975d272960a9cee2b7ce33ea7dc8 -size 495616 +oid sha256:4f143e88ec5785fc2144af1a779b09b9e0791bf0e1e7d7050c1921d36284787e +size 501248 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 2a8f0da..78aace7 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4f935425138f4ca43dedf590f0e046ccea571fc42e7620b6673226b6f2179f9 +oid sha256:ad3ceed714b0d4f97f1187893964ff234e6c48de19bac84b66a1f25c9105088c size 549376 diff --git a/build/dxwnd.ini b/build/dxwnd.ini index d060f11..56c15db 100644 --- a/build/dxwnd.ini +++ b/build/dxwnd.ini @@ -2,6 +2,120 @@ sizx=320 sizy=200 lang=automatic -posx=50 -posy=50 +posx=1429 +posy=317 [target] +title0=Age of Empires +path0=D:\Games\Age of Empires\Empires.exe +launchpath0= +module0= +opengllib0= +ver0=0 +coord0=2 +flag0=134217762 +flagg0=1207959568 +flagh0=20 +flagi0=4195332 +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=Diablo +path1=D:\Games\Diablo\Diablo.exe +launchpath1= +module1= +opengllib1= +ver1=1 +coord1=3 +flag1=138428450 +flagg1=1242562576 +flagh1=20 +flagi1=4195328 +tflag1=0 +initx1=0 +inity1=0 +minx1=0 +miny1=0 +maxx1=0 +maxy1=0 +posx1=50 +posy1=50 +sizx1=640 +sizy1=480 +maxfps1=0 +initts1=0 +winver1=0 +maxres1=0 +title2=Dune 2000 +path2=D:\Games\Dune 2000\DUNE2000.DAT +launchpath2=D:\Games\Dune 2000\DUNE2000.EXE +module2= +opengllib2= +ver2=0 +coord2=2 +flag2=671105058 +flagg2=1207959568 +flagh2=20 +flagi2=4195332 +tflag2=64 +initx2=0 +inity2=0 +minx2=0 +miny2=0 +maxx2=0 +maxy2=0 +posx2=50 +posy2=50 +sizx2=800 +sizy2=600 +maxfps2=0 +initts2=0 +winver2=0 +maxres2=-1 +title3=Genocide (REMIXED VERSION) +path3=D:\Games\genocide\remixed version (1999)\genocide\genocide.exe +launchpath3= +module3= +opengllib3= +ver3=0 +coord3=3 +flag3=134217762 +flagg3=1207959568 +flagh3=20 +flagi3=4195332 +tflag3=6402 +initx3=0 +inity3=0 +minx3=0 +miny3=0 +maxx3=0 +maxy3=0 +posx3=50 +posy3=50 +sizx3=800 +sizy3=600 +maxfps3=0 +initts3=0 +winver3=0 +maxres3=-1 +title4=Dune 2000 +module4= +opengllib4= +title5=Genocide (REMIXED VERSION) +module5= +opengllib5= +flagj0=0 +flagj1=1 +flagj2=0 +flagj3=0 diff --git a/build/exports/dxwnd.ini b/build/exports/dxwnd.ini index e3fa042..87a33a6 100644 --- a/build/exports/dxwnd.ini +++ b/build/exports/dxwnd.ini @@ -1,5 +1,5 @@ [window] -posx=1547 -posy=779 +posx=1392 +posy=385 sizx=320 sizy=200 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 1aca786..48f1da9 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -556,4 +556,16 @@ fix: added recovery for rounded child win coordinates: fixes blitting problems i 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 +added bilinear filtering to directdraw palettized 8BPP emulated mode (where it is mostly needed!). A must try is "Genocide" ! + +v2.02.87 +attempt to fix Win8 missing support for earlier ddraw releases (Croc legend of the Gobbos, Project I.G.I., ...) +fix: optimized bilinear filtering with no horizontal / vertical sawtooth artifacts +added support for 16BPP and 32BPP desktop bilinear filtering +suppressed compatibility checking +fix: doubled default window size when bilinear filtering is active +added repositioning of control parent window when main win is moved +added debug messages about hooked window class and name +fix: ignore IME window when hooking main win, destroy it when requested +fix: ignore HWND_MESSAGE type windows +added "Diablo tweak" compatibility flag for Diablo proper screen update handling. It is a temporary tweak waiting to understand better how to properly manage it. diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index fe3c3af..abed4e1 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -293,11 +293,18 @@ int iRefreshDelayCount=2; void SetVSyncDelays(LPDIRECTDRAW lpdd) { - DDSURFACEDESC ddsdRefreshRate; + DDSURFACEDESC2 ddsdRefreshRate; int Reminder; + HRESULT res; + memset(&ddsdRefreshRate, 0, sizeof(ddsdRefreshRate)); - ddsdRefreshRate.dwSize = sizeof(ddsdRefreshRate); - (*pGetDisplayMode)(lpdd, &ddsdRefreshRate); + ddsdRefreshRate.dwSize = sizeof(DDSURFACEDESC); + res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsdRefreshRate); + if(res==DDERR_GENERIC){ // handling Win8 missing support for old ddraw interface + ddsdRefreshRate.dwSize = sizeof(DDSURFACEDESC2); + res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsdRefreshRate); + } + if(res) return; gdwRefreshRate = ddsdRefreshRate.dwRefreshRate; if(!gdwRefreshRate) return; iRefreshDelayCount=0; @@ -533,9 +540,14 @@ void mySetPalette(int dwstart, int dwcount, LPPALETTEENTRY lpentries) void InitDDScreenParameters(LPDIRECTDRAW lpdd) { HRESULT res; - DDSURFACEDESC ddsd; + DDSURFACEDESC2 ddsd; ddsd.dwSize=sizeof(DDSURFACEDESC); - if(res=(*pGetDisplayMode)(lpdd, &ddsd)){ + res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd); + if(res==DDERR_GENERIC){ // Win8 missing support for old ddraw interfaces + ddsd.dwSize=sizeof(DDSURFACEDESC2); + res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd); + } + if(res){ OutTraceE("GetDisplayMode: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); return; } @@ -1905,7 +1917,11 @@ HRESULT WINAPI extSetDisplayMode(int version, LPDIRECTDRAW lpdd, ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_REFRESHRATE; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; - (*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd); + res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd); + if(res==DDERR_GENERIC){ // handling Win8 missing support for old ddraw interface + ddsd.dwSize = sizeof(DDSURFACEDESC2); + res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd); + } if(dxw.Windowize){ if(!IsChangeDisplaySettingsHotPatched){ @@ -4176,6 +4192,10 @@ HRESULT WINAPI extEnumDisplayModes(EnumDisplayModes1_Type pEnumDisplayModes, LPD memset(&EmuDesc, 0, sizeof(EmuDesc)); EmuDesc.dwSize = sizeof(DDSURFACEDESC); // using release 1 type .... res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&EmuDesc); + if(res==DDERR_GENERIC){ // Win8 missing support for old ddraw interface + EmuDesc.dwSize = sizeof(DDSURFACEDESC2); // using release 2 type .... + res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&EmuDesc); + } if(res){ OutTraceE("GetDisplayMode(D): ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); return res; diff --git a/dll/dxemublt.cpp b/dll/dxemublt.cpp index 6c049c7..a985cc0 100644 --- a/dll/dxemublt.cpp +++ b/dll/dxemublt.cpp @@ -63,6 +63,74 @@ static void MarkRect16(SHORT *dest, int w, int h, int destpitch) return; } +static DWORD Melt32(DWORD c1, DWORD c2) +{ + DWORD ret; + ret = + ((((c1 & 0x0000FF) + (c2 & 0x0000FF)) >> 1) & 0x0000FF) | + ((((c1 & 0x00FF00) + (c2 & 0x00FF00)) >> 1) & 0x00FF00) | + ((((c1 & 0xFF0000) + (c2 & 0xFF0000)) >> 1) & 0xFF0000); + return ret; +} + +static DWORD Melt16_555(DWORD c1, DWORD c2) +{ + DWORD ret; + ret = + ((((c1 & 0x00001F) + (c2 & 0x00001F)) >> 1) & 0x00001F) | + ((((c1 & 0x0003E0) + (c2 & 0x0003E0)) >> 1) & 0x0003E0) | + ((((c1 & 0x007C00) + (c2 & 0x007C00)) >> 1) & 0x007C00); + return ret; +} + +static DWORD Melt16_565(DWORD c1, DWORD c2) +{ + DWORD ret; + ret = + ((((c1 & 0x00001F) + (c2 & 0x00001F)) >> 1) & 0x00001F) | + ((((c1 & 0x0007E0) + (c2 & 0x0007E0)) >> 1) & 0x0007E0) | + ((((c1 & 0x00F800) + (c2 & 0x00F800)) >> 1) & 0x00F800); + return ret; +} + +static void SetPalette16BPP() +{ +// OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src16,dest,srcpitch,destpitch); + unsigned int pi; + Palette16BPP = (DWORD *)malloc(0x10000 * sizeof(DWORD)); + if (dxw.dwFlags3 & BLACKWHITE){ + // actually, it should be like this: R/G/B = (red * 0.30) + (green * 0.59) + (blue * 0.11) + // (http://www.codeproject.com/Articles/66253/Converting-Colors-to-Gray-Shades) + DWORD grey; + if (dxw.dwFlags1 & USERGB565){ + for (pi=0; pi<0x10000; pi++) { + //grey = ((((pi & 0x1F)<<3) + ((pi & 0x7E0)>>3) + ((pi & 0xF800)>>8)) / 3) & 0xFF; + grey = (((((pi & 0x1F)<<3) * 30) + (((pi & 0x7E0)>>3) * 59) + (((pi & 0xF800)>>8) * 11)) / 100) & 0xFF; + Palette16BPP[pi] = (grey) + (grey<<8) + (grey<<16); + } + } + else { + for (pi=0; pi<0x10000; pi++) { + //grey = ((((pi & 0x1F)<<3) + ((pi & 0x3E0)>>2) + ((pi & 0x7C00)>>7)) / 3) & 0xFF; + grey = (((((pi & 0x1F)<<3) * 30) + (((pi & 0x3E0)>>2) * 59) + (((pi & 0x7C00)>>7) * 11)) / 100) & 0xFF; + Palette16BPP[pi] = grey + (grey<<8) + (grey<<16); + } + } + } + else { + if (dxw.dwFlags1 & USERGB565){ + for (pi=0; pi<0x10000; pi++) { + Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x7E0)<<5 | (pi & 0xF800)<<8; // RGB565 + } + } + else { + for (pi=0; pi<0x10000; pi++) { + Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x3E0)<<6 | (pi & 0x7C00)<<9; // RGB555 + } + } + } +} + static HRESULT WINAPI EmuBlt_8_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) { @@ -134,19 +202,6 @@ 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) { @@ -206,30 +261,38 @@ static HRESULT WINAPI BilinearBlt_8_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT l 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)]); + for(y = 0; y < h-1; y ++){ // first h-1 lines .... + register DWORD Q1, Q2, Q3, Q4, Q5; + Q5 = Melt32(PaletteEntries[*(src8)], PaletteEntries[*(src8+ddsd_src.lPitch)]); + for(x = 0; x < w; x ++){ + Q1 = PaletteEntries[*(src8)]; + Q2 = Melt32(Q1, PaletteEntries[*(src8+1)]); + Q3 = Q5; + Q5 = Melt32(PaletteEntries[*(src8+1)], PaletteEntries[*(src8+ddsd_src.lPitch+1)]); // to be used in next for cycle + Q4 = Melt32(Q3, Q5); + + *(dest) = Q1; + *(dest+1) = Q2; + *(dest+ddsd_dst.lPitch) = Q3; + *(dest+ddsd_dst.lPitch+1) = Q4; 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; + dest+=2; + } + src8 += srcpitch; + dest += (ddsd_dst.lPitch + destpitch); } + for(x = 0; x < w; x ++){ // last line (there's no next line to melt...) + register DWORD Q1, Q2; + Q1 = PaletteEntries[*(src8)]; + Q2 = Melt32(Q1, PaletteEntries[*(src8+1)]); + + *(dest) = Q1; + *(dest+1) = Q2; + *(dest+ddsd_dst.lPitch) = Q1; + *(dest+ddsd_dst.lPitch+1) = Q2; + src8++; + dest+=2; + } if(dxw.dwFlags3 & MARKBLIT) MarkRect32(dest0, w, h, destpitch); @@ -294,42 +357,8 @@ static HRESULT WINAPI EmuBlt_16_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes src16 += lpsrcrect->left; srcpitch = ddsd_src.lPitch - w; - // OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src16,dest,srcpitch,destpitch); - if (!Palette16BPP) { // first time through ..... - unsigned int pi; - Palette16BPP = (DWORD *)malloc(0x10000 * sizeof(DWORD)); - if (dxw.dwFlags3 & BLACKWHITE){ - // actually, it should be like this: R/G/B = (red * 0.30) + (green * 0.59) + (blue * 0.11) - // (http://www.codeproject.com/Articles/66253/Converting-Colors-to-Gray-Shades) - DWORD grey; - if (dxw.dwFlags1 & USERGB565){ - for (pi=0; pi<0x10000; pi++) { - //grey = ((((pi & 0x1F)<<3) + ((pi & 0x7E0)>>3) + ((pi & 0xF800)>>8)) / 3) & 0xFF; - grey = (((((pi & 0x1F)<<3) * 30) + (((pi & 0x7E0)>>3) * 59) + (((pi & 0xF800)>>8) * 11)) / 100) & 0xFF; - Palette16BPP[pi] = (grey) + (grey<<8) + (grey<<16); - } - } - else { - for (pi=0; pi<0x10000; pi++) { - //grey = ((((pi & 0x1F)<<3) + ((pi & 0x3E0)>>2) + ((pi & 0x7C00)>>7)) / 3) & 0xFF; - grey = (((((pi & 0x1F)<<3) * 30) + (((pi & 0x3E0)>>2) * 59) + (((pi & 0x7C00)>>7) * 11)) / 100) & 0xFF; - Palette16BPP[pi] = grey + (grey<<8) + (grey<<16); - } - } - } - else { - if (dxw.dwFlags1 & USERGB565){ - for (pi=0; pi<0x10000; pi++) { - Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x7E0)<<5 | (pi & 0xF800)<<8; // RGB565 - } - } - else { - for (pi=0; pi<0x10000; pi++) { - Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x3E0)<<6 | (pi & 0x7C00)<<9; // RGB555 - } - } - } - } + if (!Palette16BPP) SetPalette16BPP(); + for(y = 0; y < h; y ++){ for(x = 0; x < w; x ++){ //if (!(*src16 & 0x8000)) // try implement alpha bit @@ -348,6 +377,110 @@ static HRESULT WINAPI EmuBlt_16_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes return res; } +static HRESULT WINAPI BilinearBlt_16_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) +{ + HRESULT res; + WORD *src16; + 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("BilBlt16_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("BilBlt16_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|DDLOCK_WAIT, 0)) { + (*pUnlockMethod(lpddsdst))(lpddsdst,0); + OutTraceE("BilBlt16_32: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + 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; + + ddsd_src.lPitch >>= 1; + src16 = (WORD *)(lpsurface ? lpsurface:ddsd_src.lpSurface); + src16 += lpsrcrect->top*ddsd_src.lPitch; + src16 += lpsrcrect->left; + srcpitch = ddsd_src.lPitch - w; + + if (!Palette16BPP) SetPalette16BPP(); + + // 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-1; y ++){ // first h-1 lines .... + register DWORD Q1, Q2, Q3, Q4, Q5; + Q5 = Melt32(Palette16BPP[*(src16)], Palette16BPP[*(src16+ddsd_src.lPitch)]); + for(x = 0; x < w; x ++){ + Q1 = Palette16BPP[*(src16)]; + Q2 = Melt32(Q1, Palette16BPP[*(src16+1)]); + Q3 = Q5; + Q5 = Melt32(Palette16BPP[*(src16+1)], Palette16BPP[*(src16+ddsd_src.lPitch+1)]); // to be used in next for cycle + Q4 = Melt32(Q3, Q5); + + *(dest) = Q1; + *(dest+1) = Q2; + *(dest+ddsd_dst.lPitch) = Q3; + *(dest+ddsd_dst.lPitch+1) = Q4; + src16++; + dest+=2; + } + src16 += srcpitch; + dest += (ddsd_dst.lPitch + destpitch); + } + for(x = 0; x < w; x ++){ // last line (there's no next line to melt...) + register DWORD Q1, Q2; + Q1 = Palette16BPP[*(src16)]; + Q2 = Melt32(Q1, Palette16BPP[*(src16+1)]); + + *(dest) = Q1; + *(dest+1) = Q2; + *(dest+ddsd_dst.lPitch) = Q1; + *(dest+ddsd_dst.lPitch+1) = Q2; + src16++; + dest+=2; + } + + if(dxw.dwFlags3 & MARKBLIT) MarkRect32(dest0, w, h, destpitch); + + res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect); + if (res) OutTraceE("BilBlt16_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__); + res=(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect); + if (res) OutTraceE("BilBlt16_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddssrc, res, ExplainDDError(res), __LINE__); + return res; +} + static HRESULT WINAPI EmuBlt_24_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) { @@ -569,6 +702,110 @@ static HRESULT WINAPI EmuBlt_8_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdest return res; } +static HRESULT WINAPI BilinearBlt_8_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) +{ + HRESULT res; + BYTE *src8; + SHORT *dest, *dest0; + DDSURFACEDESC2 ddsd_src, ddsd_dst; + long srcpitch, destpitch; + DWORD x, y, w, h; + typedef DWORD (*Melt16_Type)(DWORD, DWORD); + Melt16_Type Melt16; + + 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_16: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + + Melt16 = (ddsd_dst.ddpfPixelFormat.dwGBitMask == 0x3E0) ? Melt16_555 : Melt16_565; + + 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_16: 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_16: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return 0; + } + lpsurface=ddsd_src.lpSurface; + } + + ddsd_dst.lPitch >>= 1; + dest = (SHORT *)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-1; y ++){ // first h-1 lines .... + register DWORD Q1, Q2, Q3, Q4, Q5; + Q5 = Melt16(PaletteEntries[*(src8)], PaletteEntries[*(src8+ddsd_src.lPitch)]); + for(x = 0; x < w; x ++){ + Q1 = PaletteEntries[*(src8)]; + Q2 = Melt16(Q1, PaletteEntries[*(src8+1)]); + Q3 = Q5; + Q5 = Melt16(PaletteEntries[*(src8+1)], PaletteEntries[*(src8+ddsd_src.lPitch+1)]); // to be used in next for cycle + Q4 = Melt16(Q3, Q5); + + *(dest) = (SHORT)Q1; + *(dest+1) = (SHORT)Q2; + *(dest+ddsd_dst.lPitch) = (SHORT)Q3; + *(dest+ddsd_dst.lPitch+1) = (SHORT)Q4; + src8++; + dest+=2; + } + src8 += srcpitch; + dest += (ddsd_dst.lPitch + destpitch); + } + for(x = 0; x < w; x ++){ // last line (there's no next line to melt...) + register DWORD Q1, Q2; + Q1 = PaletteEntries[*(src8)]; + Q2 = Melt16(Q1, PaletteEntries[*(src8+1)]); + + *(dest) = (SHORT)Q1; + *(dest+1) = (SHORT)Q2; + *(dest+ddsd_dst.lPitch) = (SHORT)Q1; + *(dest+ddsd_dst.lPitch+1) = (SHORT)Q2; + src8++; + dest+=2; + } + + if(dxw.dwFlags3 & MARKBLIT) MarkRect16(dest0, w, h, destpitch); + + res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect); + if (res) OutTraceE("BilBlt8_16: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__); + res=(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect); + if (res) OutTraceE("BilBlt8_16: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddssrc, res, ExplainDDError(res), __LINE__); + return res; +} static HRESULT WINAPI EmuBlt_16_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) @@ -581,6 +818,113 @@ static HRESULT WINAPI EmuBlt_16_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes #endif } +static HRESULT WINAPI BilinearBlt_16_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) +{ + HRESULT res; + WORD *src16; + WORD *dest, *dest0; + DDSURFACEDESC2 ddsd_src, ddsd_dst; + long srcpitch, destpitch; + DWORD x, y, w, h; + typedef DWORD (*Melt16_Type)(DWORD, DWORD); + Melt16_Type Melt16; + + 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("BilBlt16_16: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + + Melt16 = (ddsd_dst.ddpfPixelFormat.dwGBitMask == 0x3E0) ? Melt16_555 : Melt16_565; + + 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("BilBlt16_16: 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|DDLOCK_WAIT, 0)) { + (*pUnlockMethod(lpddsdst))(lpddsdst,0); + OutTraceE("BilBlt16_16: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + lpsurface=ddsd_src.lpSurface; + } + + ddsd_dst.lPitch >>= 1; + dest = (WORD *)ddsd_dst.lpSurface; + dest += lpdestrect->top*ddsd_dst.lPitch; + dest += lpdestrect->left; + destpitch = ddsd_dst.lPitch - (2 * w); + dest0 = dest; + + ddsd_src.lPitch >>= 1; + src16 = (WORD *)(lpsurface ? lpsurface:ddsd_src.lpSurface); + src16 += lpsrcrect->top*ddsd_src.lPitch; + src16 += 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-1; y ++){ // first h-1 lines .... + register DWORD Q1, Q2, Q3, Q4, Q5; + Q5 = Melt16(*(src16), *(src16+ddsd_src.lPitch)); + for(x = 0; x < w; x ++){ + Q1 = *(src16); + Q2 = Melt16(Q1, *(src16+1)); + Q3 = Q5; + Q5 = Melt16(*(src16+1), *(src16+ddsd_src.lPitch+1)); // to be used in next for cycle + Q4 = Melt16(Q3, Q5); + + *(dest) = (WORD)Q1; + *(dest+1) = (WORD)Q2; + *(dest+ddsd_dst.lPitch) = (WORD)Q3; + *(dest+ddsd_dst.lPitch+1) = (WORD)Q4; + src16++; + dest+=2; + } + src16 += srcpitch; + dest += (ddsd_dst.lPitch + destpitch); + } + for(x = 0; x < w; x ++){ // last line (there's no next line to melt...) + register DWORD Q1, Q2; + Q1 = *(src16); + Q2 = Melt16(Q1, *(src16+1)); + + *(dest) = (WORD)Q1; + *(dest+1) = (WORD)Q2; + *(dest+ddsd_dst.lPitch) = (WORD)Q1; + *(dest+ddsd_dst.lPitch+1) = (WORD)Q2; + src16++; + dest+=2; + } + + if(dxw.dwFlags3 & MARKBLIT) MarkRect16((SHORT *)dest0, w, h, destpitch); + + res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect); + if (res) OutTraceE("BilBlt16_16: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__); + res=(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect); + if (res) OutTraceE("BilBlt16_16: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddssrc, res, ExplainDDError(res), __LINE__); + return res; +} + + static HRESULT WINAPI EmuBlt_24_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) { @@ -723,6 +1067,108 @@ static HRESULT WINAPI EmuBlt_32_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes return res; } +static HRESULT WINAPI BilinearBlt_32_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) +{ + HRESULT res; + DWORD *src32; + 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("BilBlt32_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("BilBlt32_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|DDLOCK_WAIT, 0)) { + (*pUnlockMethod(lpddsdst))(lpddsdst,0); + OutTraceE("BilBlt32_32: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + 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; + + ddsd_src.lPitch >>= 2; + src32 = (DWORD *)(lpsurface ? lpsurface:ddsd_src.lpSurface); + src32 += lpsrcrect->top*ddsd_src.lPitch; + src32 += 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-1; y ++){ // first h-1 lines .... + register DWORD Q1, Q2, Q3, Q4, Q5; + Q5 = Melt32(*(src32), *(src32+ddsd_src.lPitch)); + for(x = 0; x < w; x ++){ + Q1 = *(src32); + Q2 = Melt32(Q1, *(src32+1)); + Q3 = Q5; + Q5 = Melt32(*(src32+1), *(src32+ddsd_src.lPitch+1)); // to be used in next for cycle + Q4 = Melt32(Q3, Q5); + + *(dest) = (WORD)Q1; + *(dest+1) = (WORD)Q2; + *(dest+ddsd_dst.lPitch) = (WORD)Q3; + *(dest+ddsd_dst.lPitch+1) = (WORD)Q4; + src32++; + dest+=2; + } + src32 += srcpitch; + dest += (ddsd_dst.lPitch + destpitch); + } + for(x = 0; x < w; x ++){ // last line (there's no next line to melt...) + register DWORD Q1, Q2; + Q1 = *(src32); + Q2 = Melt32(Q1, *(src32+1)); + + *(dest) = (WORD)Q1; + *(dest+1) = (WORD)Q2; + *(dest+ddsd_dst.lPitch) = (WORD)Q1; + *(dest+ddsd_dst.lPitch+1) = (WORD)Q2; + src32++; + dest+=2; + } + + if(dxw.dwFlags3 & MARKBLIT) MarkRect16((SHORT *)dest0, w, h, destpitch); + + res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect); + if (res) OutTraceE("BilBlt32_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__); + res=(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect); + if (res) OutTraceE("BilBlt32_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddssrc, res, ExplainDDError(res), __LINE__); + return res; +} + static HRESULT WINAPI EmuBlt_Null(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) { @@ -1086,6 +1532,7 @@ void SetBltTransformations() case 16: pRevBlt=RevBlt_32_to_16; pEmuBlt=EmuBlt_16_to_32; + if(dxw.dwFlags4 & BILINEARFILTER) pEmuBlt=BilinearBlt_16_to_32; OutTraceDW("set color transformation 16<->32\n"); break; case 24: @@ -1095,6 +1542,7 @@ void SetBltTransformations() break; case 32: pEmuBlt=EmuBlt_32_to_32; + if(dxw.dwFlags4 & BILINEARFILTER) pEmuBlt=BilinearBlt_32_to_32; OutTraceDW("set color transformation 32->32\n"); break; default: @@ -1107,11 +1555,13 @@ void SetBltTransformations() case 8: pRevBlt=RevBlt_16_to_8; pEmuBlt=EmuBlt_8_to_16; + if(dxw.dwFlags4 & BILINEARFILTER) pEmuBlt=BilinearBlt_8_to_16; OutTraceDW("set color transformation 8<->16\n"); break; case 16: pRevBlt=RevBlt_16_to_16; pEmuBlt=EmuBlt_16_to_16; + if(dxw.dwFlags4 & BILINEARFILTER) pEmuBlt=BilinearBlt_16_to_16; OutTraceDW("set color transformation 16<->16\n"); break; case 24: diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 5797968..4615070 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -21,6 +21,8 @@ #include "Mmsystem.h" #include "disasm.h" +#define SKIPIMEWINDOW TRUE + dxwCore dxw; typedef char *(*Geterrwarnmessage_Type)(unsigned long, unsigned long); @@ -90,6 +92,17 @@ static char *Flag4Names[32]={ "HOTPATCHALWAYS", "NOD3DRESET", "OVERRIDEREGISTRY", "HIDECDROMEMPTY", }; +static char *Flag5Names[32]={ + "DIABLOCHEAT", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", +}; + static char *TFlagNames[32]={ "OUTTRACE", "OUTDDRAWTRACE", "OUTWINMESSAGES", "OUTCURSORTRACE", "OUTPROXYTRACE", "DXPROXED", "ASSERTDIALOG", "OUTIMPORTTABLE", @@ -116,6 +129,7 @@ static void OutTraceHeader(FILE *fp) for(i=0, dword=dxw.dwFlags2; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag2Names[i]); for(i=0, dword=dxw.dwFlags3; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag3Names[i]); for(i=0, dword=dxw.dwFlags4; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag4Names[i]); + for(i=0, dword=dxw.dwFlags5; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag5Names[i]); for(i=0, dword=dxw.dwTFlags; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", TFlagNames[i]); fprintf(fp, "***\n"); } @@ -154,6 +168,7 @@ void OutTrace(const char *format, ...) fflush(fp); } +#ifdef CHECKFORCOMPATIBILITYFLAGS static BOOL CheckCompatibilityFlags() { typedef DWORD (WINAPI *GetFileVersionInfoSizeA_Type)(LPCSTR, LPDWORD); @@ -194,6 +209,7 @@ static BOOL CheckCompatibilityFlags() } return FALSE; } +#endif static void dx_ToggleLogging() { @@ -430,8 +446,14 @@ void CalculateWindowPos(HWND hwnd, DWORD width, DWORD height, LPWINDOWPOS wp) case DXW_DESKTOP_CENTER: MaxX = dxw.iSizX; MaxY = dxw.iSizY; - if (!MaxX) MaxX = width; - if (!MaxY) MaxY = height; + if (!MaxX) { + MaxX = width; + if(dxw.dwFlags4 & BILINEARFILTER) MaxX <<= 1; // double + } + if (!MaxY) { + MaxY = height; + if(dxw.dwFlags4 & BILINEARFILTER) MaxY <<= 1; // double + } //GetClientRect(0, &desktop); (*pGetClientRect)(GetDesktopWindow(), &desktop); rect.left = (desktop.right - MaxX) / 2; @@ -842,10 +864,18 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGED: if(dxw.Windowize && dxw.IsFullScreen()){ + extern HWND hControlParentWnd; LPWINDOWPOS wp; wp = (LPWINDOWPOS)lparam; dxwFixWindowPos("WindowProc", hwnd, lparam); OutTraceDW("WindowProc: WM_WINDOWPOSCHANGING fixed size=(%d,%d)\n", wp->cx, wp->cy); + // try to lock main wind & control parent together + if((message==WM_WINDOWPOSCHANGED) && hControlParentWnd){ + if(dxw.IsDesktop(hwnd)) { + POINT fo = dxw.GetFrameOffset(); + (*pMoveWindow)(hControlParentWnd, wp->x+fo.x, wp->y+fo.y, wp->cx, wp->cy, TRUE); + } + } } break; case WM_ENTERSIZEMOVE: @@ -1451,6 +1481,10 @@ static void ReplaceRDTSC() FreeLibrary(disasmlib); } +#ifdef CREATEDESKTOP +HWND hDesktopWindow = NULL; +#endif + void HookInit(TARGETMAP *target, HWND hwnd) { HMODULE base; @@ -1468,7 +1502,7 @@ void HookInit(TARGETMAP *target, HWND hwnd) if(dxw.dwFlags1 & AUTOMATIC) dxw.dwFlags1 |= EMULATESURFACE; // if AUTOMATIC, try this first! - if(hwnd){ // v2/02.32: skip this when in code injection mode. + if(hwnd){ // v2.02.32: skip this when in code injection mode. // v2.1.75: is it correct to set hWnd here? //dxw.SethWnd(hwnd); dxw.hParentWnd=GetParent(hwnd); @@ -1478,6 +1512,22 @@ void HookInit(TARGETMAP *target, HWND hwnd) if(dxw.dwFlags4 & ENABLEHOTKEYS) dxw.MapKeysInit(); } +#ifdef CREATEDESKTOP + if(CREATEDESKTOP){ + if (!hDesktopWindow){ + //hDesktopWindow=CreateWindowEx(0, "STATIC", "DxWnd Desktop", 0, + hDesktopWindow=CreateWindowEx(WS_EX_CONTROLPARENT, "STATIC", "DxWnd Desktop", 0, + target->posx, target->posy, target->sizx, target->sizy, NULL, NULL, NULL, NULL); + if(hDesktopWindow){ + OutTraceDW("created desktop emulation: hwnd=%x\n", hDesktopWindow); + } + else{ + OutTraceE("CreateWindowEx ERROR: err=%d at %d\n", GetLastError(), __LINE__); + } + } + } +#endif + if(IsTraceDW){ OutTrace("HookInit: path=\"%s\" module=\"%s\" dxversion=%s pos=(%d,%d) size=(%d,%d)", target->path, target->module, dxversions[dxw.dwTargetDDVersion], @@ -1490,16 +1540,51 @@ void HookInit(TARGETMAP *target, HWND hwnd) if (hwnd && IsDebug){ DWORD dwStyle, dwExStyle; + char ClassName[81]; + char WinText[81]; dwStyle=GetWindowLong(dxw.GethWnd(), GWL_STYLE); dwExStyle=GetWindowLong(dxw.GethWnd(), GWL_EXSTYLE); - OutTrace("HookInit: hWnd style=%x(%s) exstyle=%x(%s)\n", dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); + GetClassName(dxw.GethWnd(), ClassName, sizeof(ClassName)); + GetWindowText(dxw.GethWnd(), WinText, sizeof(WinText)); + OutTrace("HookInit: dxw.hChildWnd=%x class=\"%s\" text=\"%s\" style=%x(%s) exstyle=%x(%s)\n", + dxw.hChildWnd, ClassName, WinText, dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); dwStyle=GetWindowLong(dxw.hParentWnd, GWL_STYLE); dwExStyle=GetWindowLong(dxw.hParentWnd, GWL_EXSTYLE); - OutTrace("HookInit: dxw.hParentWnd style=%x(%s) exstyle=%x(%s)\n", dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); + GetClassName(dxw.hParentWnd, ClassName, sizeof(ClassName)); + GetWindowText(dxw.hParentWnd, WinText, sizeof(WinText)); + OutTrace("HookInit: dxw.hParentWnd=%x class=\"%s\" text=\"%s\" style=%x(%s) exstyle=%x(%s)\n", + dxw.hParentWnd, ClassName, WinText, dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); OutTrace("HookInit: target window pos=(%d,%d) size=(%d,%d)\n", dxw.iPosX, dxw.iPosY, dxw.iSizX, dxw.iSizY); } + if (SKIPIMEWINDOW) { + char ClassName[8+1]; + GetClassName(hwnd, ClassName, sizeof(ClassName)); + if(!strcmp(ClassName, "IME")){ + dxw.hChildWnd=GetParent(hwnd); + dxw.hParentWnd=GetParent(dxw.hChildWnd); + if (dxw.dwFlags2 & SUPPRESSIME) DestroyWindow(hwnd); + // v2.02.31: set main win either this one or the parent! + dxw.SethWnd((dxw.dwFlags1 & FIXPARENTWIN) ? dxw.hParentWnd : dxw.hChildWnd); + hwnd = dxw.GethWnd(); + if(hwnd) OutTraceDW("HookInit: skipped IME window. current hWnd=%x(hdc=%x) dxw.hParentWnd=%x(hdc=%x)\n", + hwnd, GetDC(hwnd), dxw.hParentWnd, GetDC(dxw.hParentWnd)); + } + } + +#ifdef CREATEDESKTOP + if(CREATEDESKTOP){ + if (hDesktopWindow){ + OutTraceDW("HookInit: set new parent=%x\n", hDesktopWindow); + SetParent(dxw.hChildWnd, hDesktopWindow); + dxw.hParentWnd = hDesktopWindow; + } + } +#endif + +#ifdef CHECKFORCOMPATIBILITYFLAGS CheckCompatibilityFlags(); // v2.02.83 Check for change of OS release +#endif HookSysLibsInit(); // this just once... @@ -1558,7 +1643,7 @@ void HookInit(TARGETMAP *target, HWND hwnd) InitScreenParameters(); if(hwnd) HookWindowProc(hwnd); // in fullscreen mode, messages seem to reach and get processed by the parent window - if(!dxw.Windowize && hwnd) HookWindowProc(GetParent(hwnd)); + if((!dxw.Windowize) && hwnd) HookWindowProc(GetParent(hwnd)); // initialize window: if // 1) not in injection mode (hwnd != 0) and diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp index f23fd4a..1688fe5 100644 --- a/dll/dxwcore.cpp +++ b/dll/dxwcore.cpp @@ -76,6 +76,7 @@ void dxwCore::InitTarget(TARGETMAP *target) dwFlags2 = target->flags2; dwFlags3 = target->flags3; dwFlags4 = target->flags4; + dwFlags5 = target->flags5; dwTFlags = target->tflags; Windowize = (dwFlags2 & WINDOWIZE) ? TRUE : FALSE; if(dwFlags3 & FULLSCREENONLY) FullScreen=TRUE; @@ -302,6 +303,17 @@ RECT dxwCore::GetUnmappedScreenRect() return Screen; } +POINT dxwCore::GetFrameOffset() +{ + RECT wrect; + POINT FrameOffset={0, 0}; + (*pGetWindowRect)(hWnd, &wrect); + (*pClientToScreen)(hWnd, &FrameOffset); + FrameOffset.x -= wrect.left; + FrameOffset.y -= wrect.top; + OutTraceB("GetFrameOffset: offset=(%d,%d)\n", FrameOffset.x, FrameOffset.y); + return FrameOffset; +} BOOL dxwCore::IsDesktop(HWND hwnd) { diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp index 3656f2c..fef7be7 100644 --- a/dll/dxwcore.hpp +++ b/dll/dxwcore.hpp @@ -68,6 +68,7 @@ public: // methods RECT GetUnmappedScreenRect(); RECT GetWindowRect(RECT); RECT GetClientRect(RECT); + POINT GetFrameOffset(); POINT AddCoordinates(POINT, POINT); RECT AddCoordinates(RECT, POINT); POINT SubCoordinates(POINT, POINT); @@ -130,6 +131,7 @@ public: // simple data variables DWORD dwFlags2; DWORD dwFlags3; DWORD dwFlags4; + DWORD dwFlags5; DWORD dwTFlags; HWND hParentWnd; HWND hChildWnd; diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index f297218..c00f7ca 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.86" +#define VERSION "2.02.87" #define DDTHREADLOCK 1 @@ -184,6 +184,8 @@ LRESULT CALLBACK HookProc(int ncode, WPARAM wparam, LPARAM lparam) // This callback is invoked per each process' thread. DoOnce = TRUE; + extern HHOOK hHook; + UnhookWindowsHookEx(hHook); // V.68: concurrency check. One game at a time, or exiting. // no good trying to insert fancy dialog boxes: the window diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index de13cab..79d498c 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/gdi32.cpp b/dll/gdi32.cpp index 2b99b2a..6a340ee 100644 --- a/dll/gdi32.cpp +++ b/dll/gdi32.cpp @@ -871,6 +871,12 @@ HDC WINAPI extGDICreateCompatibleDC(HDC hdc) OutTraceDW("GDI.CreateCompatibleDC: hdc=%x\n", hdc); if(hdc==0){ hdc=(*pGDIGetDC)(dxw.GethWnd()); +#ifdef CREATEDESKTOP + if(CREATEDESKTOP){ + extern HWND hDesktopWindow; + hdc=(*pGDIGetDC)(hDesktopWindow); + } +#endif OutTraceDW("GDI.CreateCompatibleDC: duplicating win HDC hWnd=%x\n", dxw.GethWnd()); } diff --git a/dll/user32.cpp b/dll/user32.cpp index c04ce68..ef59493 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -816,14 +816,11 @@ BOOL WINAPI extGetCursorPos(LPPOINT lppoint) if(dxw.dwFlags4 & FRAMECOMPENSATION){ static int dx, dy, todo=TRUE; if (todo){ - RECT wrect; - POINT upleft={0, 0}; - todo=FALSE; - (*pGetWindowRect)(dxw.GethWnd(), &wrect); - (*pClientToScreen)(dxw.GethWnd(), &upleft); - dx=upleft.x - wrect.left; - dy=upleft.y - wrect.top; + POINT FrameOffset = dxw.GetFrameOffset(); + dx=FrameOffset.x; + dy=FrameOffset.y; OutTraceC("GetCursorPos: frame compensation=(%d,%d)\n", dx, dy); + todo=FALSE; } lppoint->x += dx; lppoint->y += dy; @@ -1062,11 +1059,19 @@ int WINAPI extMapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT HWND WINAPI extGetDesktopWindow(void) { - // V2.1.73: correct ??? HWND res; + if((!dxw.Windowize) || (dxw.dwFlags5 & DIABLOTWEAK)) return (*pGetDesktopWindow)(); + OutTraceDW("GetDesktopWindow: FullScreen=%x\n", dxw.IsFullScreen()); if (dxw.IsFullScreen()){ +#ifdef CREATEDESKTOP + if(CREATEDESKTOP){ + extern HWND hDesktopWindow; + OutTraceDW("GetDesktopWindow: returning desktop emulated hwnd=%x\n", hDesktopWindow); + return hDesktopWindow; + } +#endif OutTraceDW("GetDesktopWindow: returning main window hwnd=%x\n", dxw.GethWnd()); return dxw.GethWnd(); } @@ -1174,6 +1179,8 @@ static void HookChildWndProc(HWND hwnd, DWORD dwStyle, LPCTSTR ApiName) if(!res) OutTraceE("%s: SetWindowLong ERROR %x\n", ApiName, GetLastError()); } +HWND hControlParentWnd = NULL; + static HWND WINAPI extCreateWindowCommon( LPCTSTR ApiName, BOOL WideChar, @@ -1196,7 +1203,7 @@ static HWND WINAPI extCreateWindowCommon( iOrigW=nWidth; iOrigH=nHeight; - if(!dxw.Windowize){ + if(!dxw.Windowize || (hWndParent == HWND_MESSAGE)){ // v2.02.87: don't process message windows (hWndParent == HWND_MESSAGE) if(WideChar) hwnd= (*pCreateWindowExW)(dwExStyle, (LPCWSTR)lpClassName, (LPCWSTR)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); else @@ -1215,6 +1222,16 @@ static HWND WINAPI extCreateWindowCommon( dwStyle &= ~WS_MAXIMIZE; } +#ifdef CREATEDESKTOP + if(CREATEDESKTOP){ + extern HWND hDesktopWindow; + if (dxw.IsRealDesktop(hWndParent)){ + OutTraceE("%s: new parent win %x->%x\n", ApiName, hWndParent, hDesktopWindow); + hWndParent=hDesktopWindow; + } + } +#endif + // v2.1.92: fixes size & position for auxiliary big window, often used // for intro movies etc. : needed for ...... // evidently, this was supposed to be a fullscreen window.... @@ -1240,7 +1257,7 @@ static HWND WINAPI extCreateWindowCommon( && !(dwStyle & WS_CHILD) // Diablo fix ) - { + { RECT screen; POINT upleft = {0,0}; @@ -1340,6 +1357,8 @@ static HWND WINAPI extCreateWindowCommon( return hwnd; } + if (dwExStyle & WS_EX_CONTROLPARENT) hControlParentWnd=hwnd; + if ((!isValidHandle) && dxw.IsFullScreen()){ dxw.SethWnd(hwnd); extern void AdjustWindowPos(HWND, DWORD, DWORD); @@ -1409,9 +1428,10 @@ HWND WINAPI extCreateWindowExW( else sprintf(wString,"%d", nWidth); if (nHeight==CW_USEDEFAULT) strcpy(hString,"CW_USEDEFAULT"); else sprintf(hString,"%d", nHeight); - OutTrace("CreateWindowExW: class=\"%ls\" wname=\"%ls\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s)\n", + OutTrace("CreateWindowExW: class=\"%ls\" wname=\"%ls\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s) hWndParent=%x%s hMenu=%x\n", ClassToWStr(lpClassName), lpWindowName, xString, yString, wString, hString, - dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); + dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle), + hWndParent, hWndParent==HWND_MESSAGE?"(HWND_MESSAGE)":"", hMenu); } if(IsDebug) OutTrace("CreateWindowExW: DEBUG screen=(%d,%d)\n", dxw.GetScreenWidth(), dxw.GetScreenHeight()); @@ -1443,9 +1463,10 @@ HWND WINAPI extCreateWindowExA( else sprintf(wString,"%d", nWidth); if (nHeight==CW_USEDEFAULT) strcpy(hString,"CW_USEDEFAULT"); else sprintf(hString,"%d", nHeight); - OutTrace("CreateWindowExA: class=\"%s\" wname=\"%s\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s)\n", + OutTrace("CreateWindowExA: class=\"%s\" wname=\"%s\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s) hWndParent=%x%s hMenu=%x\n", ClassToStr(lpClassName), lpWindowName, xString, yString, wString, hString, - dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); + dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle), + hWndParent, hWndParent==HWND_MESSAGE?"(HWND_MESSAGE)":"", hMenu); } if(IsDebug) OutTrace("CreateWindowExA: DEBUG screen=(%d,%d)\n", dxw.GetScreenWidth(), dxw.GetScreenHeight()); @@ -2317,6 +2338,10 @@ BOOL WINAPI extDestroyWindow(HWND hWnd) OutTraceDW("DestroyWindow: destroy main hwnd=%x\n", hWnd); dxw.SethWnd(NULL); } + if (hControlParentWnd && (hWnd == hControlParentWnd)) { + OutTraceDW("DestroyWindow: destroy control parent hwnd=%x\n", hWnd); + hControlParentWnd = NULL; + } res=(*pDestroyWindow)(hWnd); if(!res)OutTraceE("DestroyWindow: ERROR err=%d\n", GetLastError()); return res; @@ -2716,7 +2741,9 @@ int WINAPI extGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase) if( regionType == SIMPLEREGION ){ dxw.UnmapClient(&rc); if( SetRectRgn( hRgn, rc.left, rc.top, rc.right, rc.bottom ) ){ - ; // success + // success + OutTraceDW("GetUpdateRgn: hwnd=%x hrgn=%x update rgn=(%d,%d)-(%d,%d) erase=%x\n", + hWnd, hRgn, rc.left, rc.top, rc.right, rc.bottom, bErase); } } } diff --git a/host/MainFrm.cpp b/host/MainFrm.cpp index 7ce9e7f..bae5892 100644 --- a/host/MainFrm.cpp +++ b/host/MainFrm.cpp @@ -116,6 +116,7 @@ BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) cs.cx = GetPrivateProfileInt("window", "sizx", 320, InitPath); cs.cy = GetPrivateProfileInt("window", "sizy", 200, InitPath); + // keep window inside desktop boundaries ::GetWindowRect(::GetDesktopWindow(), &DesktopRect); if(cs.cx < 320) cs.cx = 320; diff --git a/host/Resource.h b/host/Resource.h index 8ebc3a6..e67e189 100644 Binary files a/host/Resource.h and b/host/Resource.h differ diff --git a/host/TabCompat.cpp b/host/TabCompat.cpp index fb1bfc2..9a3eb33 100644 --- a/host/TabCompat.cpp +++ b/host/TabCompat.cpp @@ -42,6 +42,7 @@ void CTabCompat::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_NOPOWER2FIX, cTarget->m_NoPower2Fix); DDX_Check(pDX, IDC_NOPERFCOUNTER, cTarget->m_NoPerfCounter); DDX_Check(pDX, IDC_HIDECDROMEMPTY, cTarget->m_HideCDROMEmpty); + DDX_Check(pDX, IDC_DIABLOTWEAK, cTarget->m_DiabloTweak); // 3D management DDX_Check(pDX, IDC_NOTEXTURES, cTarget->m_NoTextures); diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 752f061..82be5c4 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -40,6 +40,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_SuppressIME = FALSE; m_SuppressD3DExt = FALSE; m_SetCompatibility = TRUE; + m_DiabloTweak = TRUE; m_DisableHAL = FALSE; m_ForcesHEL = FALSE; m_ColorFix = FALSE; diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 0b43c81..d1a92a8 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -142,6 +142,7 @@ public: BOOL m_DisableFogging; BOOL m_SuppressIME; BOOL m_SetCompatibility; + BOOL m_DiabloTweak; BOOL m_DisableHAL; BOOL m_ForcesHEL; BOOL m_ColorFix; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 74a40fb..0934b42 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.cpp b/host/dxwndhost.cpp index b75639e..d93c908 100644 --- a/host/dxwndhost.cpp +++ b/host/dxwndhost.cpp @@ -104,6 +104,8 @@ CDxwndhostApp theApp; BOOL CDxwndhostApp::InitInstance() { + char InitPath[MAX_PATH]; + int CompatibilityMinLevel; AfxEnableControlContainer(); // standard initialization @@ -130,13 +132,15 @@ BOOL CDxwndhostApp::InitInstance() // and user-defined flags. The CCommandLine class has been replaced CNewCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); + + GetCurrentDirectory(MAX_PATH, InitPath); + strcat_s(InitPath, sizeof(InitPath), "\\dxwnd.ini"); + + //CompatibilityMinLevel = GetPrivateProfileInt("window", "compatminlevel", 0, InitPath); if(!LangSelected){ LANGID LangId; char LangString[20+1]; - char InitPath[MAX_PATH]; - GetCurrentDirectory(MAX_PATH, InitPath); - strcat_s(InitPath, sizeof(InitPath), "\\dxwnd.ini"); GetPrivateProfileString("window", "lang", "", LangString, 20+1, InitPath); if(!strcmp(LangString, "default") || !strlen(LangString)){ // if no specification, or lang=default // do nothing diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 6594334..e90125b 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 3fa1ea2..0ec922a 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 3ad4c81..74b5d41 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -107,6 +107,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) t->flags2 = 0; t->flags3 = 0; t->flags4 = 0; + t->flags5 = 0; t->tflags = 0; if(dlg->m_UnNotify) t->flags |= UNNOTIFY; if(dlg->m_Windowize) t->flags2 |= WINDOWIZE; @@ -179,6 +180,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_SuppressIME) t->flags2 |= SUPPRESSIME; if(dlg->m_SuppressD3DExt) t->flags3 |= SUPPRESSD3DEXT; if(dlg->m_SetCompatibility) t->flags2 |= SETCOMPATIBILITY; + if(dlg->m_DiabloTweak) t->flags5 |= DIABLOTWEAK; if(dlg->m_DisableHAL) t->flags3 |= DISABLEHAL; if(dlg->m_ForcesHEL) t->flags3 |= FORCESHEL; if(dlg->m_ColorFix) t->flags3 |= COLORFIX; @@ -344,6 +346,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_SuppressIME = t->flags2 & SUPPRESSIME ? 1 : 0; dlg->m_SuppressD3DExt = t->flags3 & SUPPRESSD3DEXT ? 1 : 0; dlg->m_SetCompatibility = t->flags2 & SETCOMPATIBILITY ? 1 : 0; + dlg->m_DiabloTweak = t->flags5 & DIABLOTWEAK ? 1 : 0; dlg->m_DisableHAL = t->flags3 & DISABLEHAL ? 1 : 0; dlg->m_ForcesHEL = t->flags3 & FORCESHEL ? 1 : 0; dlg->m_ColorFix = t->flags3 & COLORFIX ? 1 : 0; @@ -488,6 +491,9 @@ static void SaveConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, sprintf_s(key, sizeof(key), "flagi%i", i); sprintf_s(val, sizeof(val), "%i", TargetMap->flags4); WritePrivateProfileString("target", key, val, InitPath); + sprintf_s(key, sizeof(key), "flagj%i", i); + sprintf_s(val, sizeof(val), "%i", TargetMap->flags5); + WritePrivateProfileString("target", key, val, InitPath); sprintf_s(key, sizeof(key), "tflag%i", i); sprintf_s(val, sizeof(val), "%i", TargetMap->tflags); WritePrivateProfileString("target", key, val, InitPath); @@ -555,6 +561,8 @@ static void ClearTarget(int i, char *InitPath) WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "flagi%i", i); WritePrivateProfileString("target", key, 0, InitPath); + sprintf_s(key, sizeof(key), "flagj%i", i); + WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "tflag%i", i); WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "initx%i", i); @@ -626,6 +634,8 @@ static int LoadConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, c TargetMap->flags3 = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "flagi%i", i); TargetMap->flags4 = GetPrivateProfileInt("target", key, 0, InitPath); + sprintf_s(key, sizeof(key), "flagj%i", i); + TargetMap->flags5 = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "tflag%i", i); TargetMap->tflags = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "initx%i", i); diff --git a/locale/cn/Resources_Cn.ncb b/locale/cn/Resources_Cn.ncb index 48bdd41..293e240 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 ee71530..c95d853 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 5c6baa9..6bed9de 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 6594334..e90125b 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 f02b3ef..33ba46b 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 5133e74..955098f 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 5f2688d..23f4d59 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 c36d64f..dd9ef45 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 92db4c4..39d388b 100644 Binary files a/locale/it/Resources_It.suo and b/locale/it/Resources_It.suo differ