diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 344534c..0e698fd 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14919d03fd4ec468005183e338af3f4734eeed9ec11ef6aaf2540c1f9bb00872 -size 691712 +oid sha256:e28f7cec6d5eae185c1bdf2c27ab49e1357051f487c243b60f5d25b11172c21f +size 694784 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 6a033f1..3dd268f 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:145095298932076ccdb75aec0627b07f05ad61d9559ed3481a57de4d8a58ea21 -size 662016 +oid sha256:46c4384a402e3f5d23af6b3f6f9649833e7aefedf0c46bfd7eee282d8029f6ff +size 664576 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 92701ad..87d28d4 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -1309,4 +1309,14 @@ fix: added reference to Palette object to allow final Release() without crash - fix: fix RECT structure passed to ddraw::Unlock method in case it points to bad coordinates. Fixes FIFA2000 in D3D mode fix: wrapped all OpenGL GetString methods and inserted proper logging. For diagnostic purposes. fix: fix ddraw::SetPalette wrapper in case lppd is NULL. Fixes Adrenix sw mode crash. -fix: better way to manage extra modules to be hooked (Glide ddls, SmackW32) \ No newline at end of file +fix: better way to manage extra modules to be hooked (Glide ddls, SmackW32) + +v2.03.93: +add: GUI game icon extracted also form separated *.ico icon file +add: GUI definition of default values for window position +fix: ddrawsurface::Unlock lprect usage: doesn't use the input value but refers to rect passed in Lock operation. Fixes "fifa 2000" crash. +fix: avoid issuing a GetPalette method against a deallocated object +fix: automatic creation of Clipper object if needed for emulated ddraw blit to primary surface - fixes the well known black blitting problem +fix: proper handling of dinput DirectInputDevice::GetDeviceData() DI_BUFFEROVERFLOW error condition +fix: user32 GetCursorPos() wrapper +fix: user32 mouse_event() wrapper \ No newline at end of file diff --git a/dll/ddblit.cpp b/dll/ddblit.cpp index a515a73..ca0d914 100644 --- a/dll/ddblit.cpp +++ b/dll/ddblit.cpp @@ -169,10 +169,12 @@ static HRESULT sBltToPrimary(int dxversion, Blt_Type pBlt, char *api, LPDIRECTDR #if FIXBIGGERRECT // seems necessary to "cure" the "FIFA 2000" soccer game in hw accelerated graphics, when the Unlock() method - // receives RECT coordinates with big negative numbers! + // receives RECT coordinates with big positive or negative numbers! if(lpdestrect){ if(lpdestrect->top < 0) lpdestrect->top = 0; + if(lpdestrect->top > (LONG)dxw.GetScreenWidth()) lpdestrect->top = 0; if(lpdestrect->left < 0) lpdestrect->left = 0; + if(lpdestrect->left > (LONG)dxw.GetScreenHeight()) lpdestrect->left = 0; if(lpdestrect->bottom > (LONG)dxw.GetScreenHeight()) lpdestrect->bottom = dxw.GetScreenHeight(); if(lpdestrect->right > (LONG)dxw.GetScreenWidth()) lpdestrect->right = dxw.GetScreenWidth(); if(lpdestrect->bottom < lpdestrect->top) lpdestrect->bottom = (LONG)dxw.GetScreenHeight(); diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index 70f9f84..d31d507 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -415,6 +415,7 @@ LPDIRECTDRAWSURFACE lpDDZBuffer=NULL; // the service objects (emulated backbuffer, emulater primary, ....) are attached. LPDIRECTDRAW lpPrimaryDD=NULL; int iBakBufferVersion; +int iDirectDrawVersion; LPDIRECTDRAWPALETTE lpDDP=NULL; LPDIRECTDRAWCLIPPER lpddC=NULL; int iDDPExtraRefCounter=0; @@ -532,6 +533,7 @@ static CHAR *LogSurfaceAttributes(LPDDSURFACEDESC lpddsd, char *label, int line) if (lpddsd->dwFlags & DDSD_LPSURFACE) sprintf(sInfo, "%s Surface=%x", sInfo, lpddsd->lpSurface); if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) sprintf(sInfo, "%s ZBufferBitDepth=%d", sInfo, lpddsd->dwZBufferBitDepth); if (lpddsd->dwFlags & DDSD_ALPHABITDEPTH) sprintf(sInfo, "%s AlphaBitDepth=%d", sInfo, lpddsd->dwAlphaBitDepth); + if (lpddsd->dwReserved) sprintf(sInfo, "%s Reserved=%d", sInfo, lpddsd->dwReserved); if (lpddsd->dwFlags & DDSD_REFRESHRATE) sprintf(sInfo, "%s RefreshRate=%d", sInfo, lpddsd->dwRefreshRate); if (lpddsd->dwFlags & DDSD_LINEARSIZE) sprintf(sInfo, "%s LinearSize=%d", sInfo, lpddsd->dwLinearSize); if (lpddsd->dwSize == sizeof(DDSURFACEDESC2)){ @@ -1142,6 +1144,8 @@ void HookDDSession(LPDIRECTDRAW *lplpdd, int dxversion) OutTraceDW("Hooking directdraw session dd=%x dxversion=%d thread_id=%x\n", *lplpdd, dxversion, GetCurrentThreadId()); + iDirectDrawVersion = dxversion; // save for ddraw session operations + // unimplemented, but better not hook it with a single wrapper //SetHook((void *)(**(DWORD **)lplpdd + 12), extCompact, (void **)&pCompact, "Compact"); switch(dxversion) { @@ -1575,7 +1579,7 @@ static void HandleCapsD(char *sLabel, LPDDCAPS c) static HRESULT WINAPI extGetCapsD(int dxversion, GetCapsD_Type pGetCapsD, LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2) { HRESULT res; - OutTraceDDRAW("GetCaps(D): lpdd=%x %s %s\n", lpdd, c1?"c1":"NULL", c2?"c2":"NULL"); + OutTraceDDRAW("GetCaps(D%d): lpdd=%x %s %s\n", dxversion, lpdd, c1?"c1":"NULL", c2?"c2":"NULL"); res=(*pGetCapsD)(lpdd, c1, c2); if(res) OutTraceE("GetCaps(D): ERROR res=%x(%s)\n", res, ExplainDDError(res)); @@ -2256,9 +2260,9 @@ HRESULT WINAPI extSetDisplayMode4(LPDIRECTDRAW lpdd, DWORD dwwidth, DWORD dwheig HRESULT WINAPI extSetDisplayMode7(LPDIRECTDRAW lpdd, DWORD dwwidth, DWORD dwheight, DWORD dwbpp, DWORD dwrefreshrate, DWORD dwflags) { return extSetDisplayMode(7, lpdd, dwwidth, dwheight, dwbpp, dwrefreshrate, dwflags);} -HRESULT WINAPI extGetDisplayMode(GetDisplayMode_Type pGetDisplayMode, LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd) +HRESULT WINAPI extGetDisplayMode(int dxversion, GetDisplayMode_Type pGetDisplayMode, LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd) { - OutTraceDDRAW("GetDisplayMode(D1): lpdd=%x lpddsd=%x\n", lpdd, lpddsd); + OutTraceDDRAW("GetDisplayMode(D%d): lpdd=%x lpddsd=%x\n", dxversion, lpdd, lpddsd); (*pGetDisplayMode)(lpdd, lpddsd); if(dxw.dwFlags1 & EMULATESURFACE) { @@ -2294,15 +2298,15 @@ HRESULT WINAPI extGetDisplayMode(GetDisplayMode_Type pGetDisplayMode, LPDIRECTDR } HRESULT WINAPI extGetDisplayMode1(LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd) -{ return extGetDisplayMode(pGetDisplayMode1, lpdd, lpddsd); } +{ return extGetDisplayMode(1, pGetDisplayMode1, lpdd, lpddsd); } HRESULT WINAPI extGetDisplayMode2(LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd) -{ return extGetDisplayMode(pGetDisplayMode2, lpdd, lpddsd); } +{ return extGetDisplayMode(2, pGetDisplayMode2, lpdd, lpddsd); } HRESULT WINAPI extGetDisplayMode3(LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd) -{ return extGetDisplayMode(pGetDisplayMode3, lpdd, lpddsd); } +{ return extGetDisplayMode(3, pGetDisplayMode3, lpdd, lpddsd); } HRESULT WINAPI extGetDisplayMode4(LPDIRECTDRAW lpdd, LPDDSURFACEDESC2 lpddsd) -{ return extGetDisplayMode((GetDisplayMode_Type)pGetDisplayMode4, lpdd, (LPDDSURFACEDESC)lpddsd); } +{ return extGetDisplayMode(4, (GetDisplayMode_Type)pGetDisplayMode4, lpdd, (LPDDSURFACEDESC)lpddsd); } HRESULT WINAPI extGetDisplayMode7(LPDIRECTDRAW lpdd, LPDDSURFACEDESC2 lpddsd) -{ return extGetDisplayMode((GetDisplayMode_Type)pGetDisplayMode7, lpdd, (LPDDSURFACEDESC)lpddsd); } +{ return extGetDisplayMode(7, (GetDisplayMode_Type)pGetDisplayMode7, lpdd, (LPDDSURFACEDESC)lpddsd); } HRESULT WINAPI extSetCooperativeLevel(int dxversion, SetCooperativeLevel_Type pSetCooperativeLevel, LPDIRECTDRAW lpdd, HWND hwnd, DWORD dwflags) { @@ -3570,8 +3574,11 @@ HRESULT WINAPI PrimaryStretchBlt(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFA LPDIRECTDRAWSURFACE lpddsBak; DDSCAPS caps; CreateSurface1_Type pCreateSurface; + CreateClipper_Type pCreateClipper; + SetClipper_Type pSetClipper; BltFast_Type pBltFast; int dwSize; + static BOOL bUseFastBlt = !(dxw.dwFlags3 & FORCECLIPPER); switch(iBakBufferVersion){ default: @@ -3617,15 +3624,42 @@ HRESULT WINAPI PrimaryStretchBlt(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFA } else { while(TRUE) { - // fast-blit to primary - if(dxw.dwFlags3 & FORCECLIPPER){ - res= (*pBlt)(lpdds, lpdestrect, lpddsTmp, &TmpRect, DDBLT_WAIT, 0); - if(res) OutTraceE("PrimaryStretchBlt: Blt ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + if(bUseFastBlt){ + res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, DDBLTFAST_WAIT); } else{ - res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, DDBLTFAST_WAIT); - if(res) OutTraceE("PrimaryStretchBlt: BltFast ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + res= (*pBlt)(lpdds, lpdestrect, lpddsTmp, &TmpRect, DDBLT_WAIT, 0); } + if(res == DDERR_INVALIDRECT){ + OutTraceDW("PrimaryStretchBlt: adding clipper ddversion=%x at %d\n", iDirectDrawVersion, __LINE__); + bUseFastBlt = FALSE; + switch(iDirectDrawVersion){ + case 1: pCreateClipper = pCreateClipper1; break; + case 2: pCreateClipper = pCreateClipper2; break; + case 3: pCreateClipper = pCreateClipper3; break; + case 4: pCreateClipper = pCreateClipper4; break; + case 7: pCreateClipper = pCreateClipper7; break; + } + switch(iBakBufferVersion){ + case 1: pSetClipper = pSetClipper1; break; + case 2: pSetClipper = pSetClipper2; break; + case 3: pSetClipper = pSetClipper3; break; + case 4: pSetClipper = pSetClipper4; break; + case 7: pSetClipper = pSetClipper7; break; + } + if(!lpddC){ + res=(*pCreateClipper)(lpPrimaryDD, 0, &lpddC, NULL); + if(res) OutTraceE("CreateClipper ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + } + //res=(*pSetHWnd)(lpddC, 0, dxw.GethWnd()); // no good, cliper object could be unhooked yet! "Settlers III" would crash! + res=lpddC->SetHWnd(0, dxw.GethWnd()); + if(res) OutTraceE("SetHWnd ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + res=(*pSetClipper)(lpdds, lpddC); + if(res) OutTraceE("SetClipper ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceDW("PrimaryStretchBlt: added clipper lpddc=%x at %d\n", lpddC, __LINE__); + res= (*pBlt)(lpdds, lpdestrect, lpddsTmp, &TmpRect, DDBLT_WAIT, 0); + } + if(res) OutTraceE("PrimaryStretchBlt: BltFast ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); if(res == DDERR_SURFACELOST){ res = lpdds->Restore(); if(res) { @@ -4221,7 +4255,9 @@ HRESULT WINAPI extGetPalette(int dxversion, GetPalette_Type pGetPalette, LPDIREC isBack=dxwss.IsABackBufferSurface(lpdds); OutTraceDDRAW("GetPalette(%d): lpdds=%x%s%s\n", dxversion, lpdds, isPrim?"(PRIM)":"", isBack?"(BACK)":""); - res=(*pGetPalette)(lpdds, lplpddp); + res = DD_OK; + lpdds->AddRef(); + if(lpdds->Release()) res=(*pGetPalette)(lpdds, lplpddp); // v2.03.07: in "Die Hard Trilogy" the backbuffer surface is queryed for the palette // v2.03.08: in "Viper Racing" lpDDP is still NULL (how could it be?) @@ -4396,6 +4432,8 @@ HRESULT WINAPI extSetClipper7(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWCLIPPER lpd DDSURFACEDESC SaveSurfaceDesc; LPDIRECTDRAWSURFACE SaveSurface = NULL; +LPRECT SaveLockedlpRect = NULL; +RECT SaveLockedRect; static HRESULT WINAPI extLock(int dxversion, Lock_Type pLock, LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent) { @@ -4412,6 +4450,9 @@ static HRESULT WINAPI extLock(int dxversion, Lock_Type pLock, LPDIRECTDRAWSURFAC dxversion, lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpDDSurfaceDesc, sRect); } + SaveLockedlpRect = lprect; + if(SaveLockedlpRect) SaveLockedRect = *lprect; + res=(*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); if(res==DDERR_SURFACEBUSY){ // v70: fix for "Ancient Evil" (*pUnlockMethod(dxversion))(lpdds, NULL); @@ -4476,6 +4517,9 @@ static HRESULT WINAPI extLockDir(int dxversion, Lock_Type pLock, LPDIRECTDRAWSUR dxversion, lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpDDSurfaceDesc, sRect); } + SaveLockedlpRect = lprect; + if(SaveLockedlpRect) SaveLockedRect = *lprect; + switch(dxversion){ case 1: pBlt=pBlt1; pGetGDISurface=pGetGDISurface1; break; case 2: pBlt=pBlt2; pGetGDISurface=pGetGDISurface2; break; @@ -4567,7 +4611,6 @@ static HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRA HRESULT res; BOOL IsPrim; BOOL IsBack; - RECT rect; Blt_Type pBlt; IsPrim=dxwss.IsAPrimarySurface(lpdds); @@ -4599,15 +4642,12 @@ static HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRA } if(dxversion >= 4){ - // make lprect point elsewhere, so that the original values are not altered - if(lprect){ - CleanRect(&lprect,__LINE__); - rect = *lprect; - lprect = ▭ - // v2.03.20: apparently, it seems that in ddraw 7 you can set an empty rectangle to mean the whole area .... - // this fixes the black screen otherwise present in "Arcanum". - if(IsPrim && ((lprect->right - lprect->left) == 0) && ((lprect->bottom - lprect->top) == 0)) lprect = NULL; - } + // v2.03.20: apparently, it seems that in ddraw 7 you can set an empty rectangle to mean the whole area .... + // this fixes the black screen otherwise present in "Arcanum". + // v2.02.92: found in Fifa 2000: lpRect is completely ignored, receiving bogus values like (-1, -1, -1, -1} + // or {0, 0, 0, 0}, or {-109119151, -109119151, -109119151, -109119151}. + // better use the Lock-ed rect + if(IsPrim) lprect = SaveLockedlpRect; } if((dxw.dwFlags6 & FIXPITCH) && !(IsPrim||IsBack) && (lpdds == SaveSurface)){ @@ -4693,7 +4733,14 @@ static HRESULT WINAPI extUnlockDir(int dxversion, Unlock4_Type pUnlock, LPDIRECT IsPrim=dxwss.IsAPrimarySurface(lpdds); IsBack=dxwss.IsABackBufferSurface(lpdds); - if ((dxversion >= 4) && lprect) CleanRect(&lprect,__LINE__); + if(dxversion >= 4){ + // v2.03.20: apparently, it seems that in ddraw 7 you can set an empty rectangle to mean the whole area .... + // this fixes the black screen otherwise present in "Arcanum". + // v2.02.92: found in Fifa 2000: lpRect is completely ignored, receiving bogus values like (-1, -1, -1, -1} + // or {0, 0, 0, 0}, or {-109119151, -109119151, -109119151, -109119151}. + // better use the Lock-ed rect + if(IsPrim) lprect = SaveLockedlpRect; + } if(IsTraceDDRAW){ char sRect[81]; @@ -5695,6 +5742,7 @@ static HRESULT WINAPI extGetSurfaceDesc(int dxversion, GetSurfaceDesc_Type pGetS #define FIXSURFACEDESCSIZE TRUE if(FIXSURFACEDESCSIZE){ + int prevsize = lpddsd->dwSize; switch(dxversion){ case 1: case 2: @@ -5706,21 +5754,18 @@ static HRESULT WINAPI extGetSurfaceDesc(int dxversion, GetSurfaceDesc_Type pGetS lpddsd->dwSize = sizeof(DDSURFACEDESC2); break; } + if(prevsize != lpddsd->dwSize) OutTraceDW("GetSurfaceDesc(%d): FIXED dwSize=%d->%d\n", dxversion, prevsize, lpddsd->dwSize); } res=(*pGetSurfaceDesc)(lpdds, lpddsd); - OutTraceDDRAW("GetSurfaceDesc: %slpdds=%x%s res=%x(%s)\n", - res?"ERROR ":"", lpdds, IsPrim?"(PRIM)":(IsBack?"(BACK)":""), res, ExplainDDError(res)); if(res) { - OutTraceE("GetSurfaceDesc: ERROR err=%x(%s) dxversion=%d s->len=%d at %d\n", res, ExplainDDError(res), dxversion, lpddsd->dwSize, __LINE__); + OutTraceE("GetSurfaceDesc(%d): ERROR err=%x(%s)\n", dxversion, res, ExplainDDError(res)); return res; } - OutTraceDDRAW("GetSurfaceDesc: lpdds=%x %s\n", lpdds, LogSurfaceAttributes(lpddsd, "GetSurfaceDesc", __LINE__)); + OutTraceDDRAW("GetSurfaceDesc(%d): lpdds=%x%s %s\n", dxversion, lpdds, IsPrim?"(PRIM)":(IsBack?"(BACK)":""), LogSurfaceAttributes(lpddsd, "GetSurfaceDesc", __LINE__)); if (IsPrim) { - OutTraceDW("GetSurfaceDesc: fixing PRIMARY surface\n"); - IsFixed=TRUE; if (dxw.dwFlags1 & EMULATESURFACE) lpddsd->ddpfPixelFormat = dxw.VirtualPixelFormat; lpddsd->ddsCaps.dwCaps |= DDSD_Prim.ddsCaps.dwCaps; lpddsd->ddsCaps.dwCaps |= (DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_VISIBLE); // primary surfaces must be this way @@ -5729,21 +5774,21 @@ static HRESULT WINAPI extGetSurfaceDesc(int dxversion, GetSurfaceDesc_Type pGetS lpddsd->dwBackBufferCount=DDSD_Prim.dwBackBufferCount; lpddsd->dwHeight=dxw.GetScreenHeight(); lpddsd->dwWidth=dxw.GetScreenWidth(); + OutTraceDW("GetSurfaceDesc: FIXED lpdds=%x %s\n", lpdds, LogSurfaceAttributes(lpddsd, "PRIMARY", __LINE__)); } if (IsBack) { - OutTraceDW("GetSurfaceDesc: fixing BACKBUFFER surface\n"); - IsFixed=TRUE; // flags that backbuffer surfaces must have set lpddsd->ddsCaps.dwCaps |= (DDSCAPS_3DDEVICE|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); // flags that backbuffer surfaces can't have set lpddsd->ddsCaps.dwCaps &= ~(DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN|DDSCAPS_COMPLEX|DDSCAPS_FLIP); + OutTraceDW("GetSurfaceDesc: FIXED lpdds=%x %s\n", lpdds, LogSurfaceAttributes(lpddsd, "BACKBUFFER", __LINE__)); } // v2.03.82: fixed logic for ZBUFFER capabilities: "The Creed" may have two, in SYSTEMMEMORY or in VIDEOMEMORY ... if(lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) { lpddsd->ddsCaps.dwCaps = dxwcdb.GetCaps(lpdds); - OutTraceDW("GetSurfaceDesc: lpdds=%x %s\n", lpdds, LogSurfaceAttributes(lpddsd, "GetSurfaceDesc [FIXED]", __LINE__)); + OutTraceDW("GetSurfaceDesc: FIXED lpdds=%x %s\n", lpdds, LogSurfaceAttributes(lpddsd, "ZBUFFER", __LINE__)); } return DD_OK; diff --git a/dll/dinput.cpp b/dll/dinput.cpp index eb1ea3a..b2d1482 100644 --- a/dll/dinput.cpp +++ b/dll/dinput.cpp @@ -551,6 +551,40 @@ dwFlags Normally, data is removed from the buffer after it is read. */ +/* Mind the following scenarios! +Your application can query for the number of elements in the device buffer by setting the rgdod parameter to NULL, setting pdwInOut to INFINITE +and setting dwFlags to DIGDD_PEEK. The following code example illustrates how this can be done. + +dwItems = INFINITE; +hres = idirectinputdevice9_GetDeviceData( + pdid, + sizeof(DIDEVICEOBJECTDATA), + NULL, + &dwItems, + DIGDD_PEEK); +if (SUCCEEDED(hres)) { + // dwItems = Number of elements in buffer. + if (hres == DI_BUFFEROVERFLOW) { + // Buffer overflow occurred; not all data + // was successfully captured. + } +} + +To query about whether a buffer overflow has occurred, set the rgdod parameter to NULL and the pdwInOut parameter to 0. +The following code example illustrates how this can be done. + +dwItems = 0; +hres = idirectinputdevice9_GetDeviceData( + pdid, + sizeof(DIDEVICEOBJECTDATA), + NULL, + &dwItems, + 0); +if (hres == DI_BUFFEROVERFLOW) { + // Buffer overflow occurred. +} +*/ + HRESULT WINAPI extGetDeviceData(LPDIRECTINPUTDEVICE lpdid, DWORD cbdata, LPVOID rgdod, LPDWORD pdwinout, DWORD dwflags) { HRESULT res; @@ -577,6 +611,7 @@ HRESULT WINAPI extGetDeviceData(LPDIRECTINPUTDEVICE lpdid, DWORD cbdata, LPVOID switch(res){ case DI_OK: + case DI_BUFFEROVERFLOW: break; case DIERR_NOTACQUIRED: case DIERR_INPUTLOST: @@ -611,9 +646,11 @@ HRESULT WINAPI extGetDeviceData(LPDIRECTINPUTDEVICE lpdid, DWORD cbdata, LPVOID } tmp = (BYTE *)rgdod; + if(!tmp) return res; + if(dxw.bDInputAbs){ GetMousePosition((int *)&p.x, (int *)&p.y); - for(i = 0; i < *pdwinout; i ++){ + for(i = 0; (i < *pdwinout) && ((LPDIDEVICEOBJECTDATA)tmp)->dwOfs; i ++){ if(((LPDIDEVICEOBJECTDATA)tmp)->dwOfs == DIMOFS_X)((LPDIDEVICEOBJECTDATA)tmp)->dwData = p.x; if(((LPDIDEVICEOBJECTDATA)tmp)->dwOfs == DIMOFS_Y)((LPDIDEVICEOBJECTDATA)tmp)->dwData = p.y; tmp += cbdata; @@ -621,14 +658,14 @@ HRESULT WINAPI extGetDeviceData(LPDIRECTINPUTDEVICE lpdid, DWORD cbdata, LPVOID OutTraceB("GetDeviceData(I): ABS mousedata=(%d,%d)\n", p.x, p.y); } else{ - for(i = 0; i < *pdwinout; i ++){ + for(i = 0; (i < *pdwinout) && ((LPDIDEVICEOBJECTDATA)tmp)->dwOfs; i ++){ if(((LPDIDEVICEOBJECTDATA)tmp)->dwOfs == DIMOFS_X) OutTraceB("GetDeviceData(I): REL mousedata X=%d\n", ((LPDIDEVICEOBJECTDATA)tmp)->dwData); if(((LPDIDEVICEOBJECTDATA)tmp)->dwOfs == DIMOFS_Y) OutTraceB("GetDeviceData(I): REL mousedata Y=%d\n", ((LPDIDEVICEOBJECTDATA)tmp)->dwData); tmp += cbdata; } } } - return DI_OK; + return res; } HRESULT WINAPI extGetDeviceState(LPDIRECTINPUTDEVICE lpdid, DWORD cbdata, LPDIMOUSESTATE lpvdata) diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 9b19676..8e0f06b 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -27,7 +27,7 @@ along with this program. If not, see . #include "TlHelp32.h" -#define VERSION "2.03.92.fx2" +#define VERSION "2.03.93" #define DDTHREADLOCK 1 //#define LOCKTHREADS diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index cd0afb6..3d2b464 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/user32.cpp b/dll/user32.cpp index c59265e..71ee4ca 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -307,7 +307,7 @@ static HookEntryEx_Type MouseHooks[]={ {HOOK_IAT_CANDIDATE, 0, "SetCursor", (FARPROC)SetCursor, (FARPROC *)&pSetCursor, (FARPROC)extSetCursor}, {HOOK_IAT_CANDIDATE, 0, "SendMessageA", (FARPROC)SendMessageA, (FARPROC *)&pSendMessageA, (FARPROC)extSendMessageA}, {HOOK_IAT_CANDIDATE, 0, "SendMessageW", (FARPROC)SendMessageW, (FARPROC *)&pSendMessageW, (FARPROC)extSendMessageW}, - //{HOOK_IAT_CANDIDATE, 0, "mouse_event", (FARPROC)NULL, (FARPROC *)&pmouse_event, (FARPROC)extmouse_event}, + {HOOK_IAT_CANDIDATE, 0, "mouse_event", (FARPROC)mouse_event, (FARPROC *)&pmouse_event, (FARPROC)extmouse_event}, //{HOOK_IAT_CANDIDATE, 0, "SetPhysicalCursorPos", NULL, (FARPROC *)&pSetCursor, (FARPROC)extSetCursor}, // ??? {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator }; @@ -1131,6 +1131,7 @@ static BOOL WINAPI extPeekMessage(PeekMessage_Type pPeekMessage, LPMSG lpMsg, HW { BOOL res; + if(dxw.dwFlags3 & PEEKALLMESSAGES){ if((wMsgFilterMin==0) && (wMsgFilterMax == 0)){ // no filtering, everything is good res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F)); @@ -1152,6 +1153,14 @@ static BOOL WINAPI extPeekMessage(PeekMessage_Type pPeekMessage, LPMSG lpMsg, HW else OutTraceW("PeekMessage: ANY lpmsg=%x hwnd=%x filter=(%x-%x) remove=%x(%s) res=%x\n", lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg), res); + } + else { + res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F)); + OutTrace("PeekMessage: lpmsg=%x hwnd=%x filter=(%x-%x) remove=%x(%s) msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n", + lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg), + lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), + lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); + } return res; @@ -3805,9 +3814,44 @@ BOOL WINAPI extPaintDesktop(HDC hdc) if(!ret) OutTraceE("PaintDesktop ERROR: err=%d\n", GetLastError()); return ret; } + + +char *ExplainMouseMoveFlags(DWORD c) +{ + static char eb[256]; + unsigned int l; + strcpy(eb,"MOUSEEVENTF_"); + if (c & MOUSEEVENTF_MOVE) strcat(eb, "MOVE+"); + if (c & MOUSEEVENTF_LEFTDOWN) strcat(eb, "LEFTDOWN+"); + if (c & MOUSEEVENTF_LEFTUP) strcat(eb, "LEFTUP+"); + if (c & MOUSEEVENTF_RIGHTDOWN) strcat(eb, "RIGHTDOWN+"); + if (c & MOUSEEVENTF_RIGHTUP) strcat(eb, "RIGHTUP+"); + if (c & MOUSEEVENTF_MIDDLEDOWN) strcat(eb, "MIDDLEDOWN+"); + if (c & MOUSEEVENTF_MIDDLEUP) strcat(eb, "MIDDLEUP+"); + if (c & MOUSEEVENTF_XDOWN) strcat(eb, "XDOWN+"); + if (c & MOUSEEVENTF_XUP) strcat(eb, "XUP+"); + if (c & MOUSEEVENTF_WHEEL) strcat(eb, "WHEEL+"); + if (c & MOUSEEVENTF_HWHEEL) strcat(eb, "HWHEEL+"); + if (c & MOUSEEVENTF_ABSOLUTE) strcat(eb, "ABSOLUTE+"); + l=strlen(eb); + if (l>strlen("MOUSEEVENTF_")) eb[l-1]=0; // delete last '+' if any + else eb[0]=0; + return(eb); +} + VOID WINAPI extmouse_event(DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData, ULONG_PTR dwExtraInfo) { - OutTrace("mouse_event: flags=%x xy=(%d,%d) data=%x, extrainfo=%lx\n", dwFlags, dx, dy, dwData, dwExtraInfo); + OutTrace("mouse_event: flags=%x(%s) xy=(%d,%d) data=%x, extrainfo=%lx\n", + dwFlags, ExplainMouseMoveFlags(dwFlags), dx, dy, dwData, dwExtraInfo); + + if((dwFlags & MOUSEEVENTF_MOVE) && (dxw.dwFlags2 & KEEPCURSORFIXED)) { + OutTraceDW("mouse_event: SUPPRESS mouse move\n"); + return; + } + + if(dxw.Windowize){ + dxw.MapClient((int *)&dx, (int *)&dy); + } return (*pmouse_event)(dwFlags, dx, dy, dwData, dwExtraInfo); } diff --git a/host/CGlobalSettings.cpp b/host/CGlobalSettings.cpp index 8f87276..d876a0c 100644 --- a/host/CGlobalSettings.cpp +++ b/host/CGlobalSettings.cpp @@ -79,6 +79,23 @@ IMPLEMENT_DYNAMIC(CGlobalSettings, CDialog) CGlobalSettings::CGlobalSettings(CWnd* pParent /*=NULL*/) : CDialog(CGlobalSettings::IDD, pParent) { + m_DebugMode = GetPrivateProfileInt("window", "debug", 0, gInitPath); + m_AutoHideMode = GetPrivateProfileInt("window", "autohide", 0, gInitPath); + m_CheckAdminRights = GetPrivateProfileInt("window", "checkadmin", 0, gInitPath); + m_NameFromFolder = GetPrivateProfileInt("window", "namefromfolder", 0, gInitPath); + m_MultiHooks = GetPrivateProfileInt("window", "multiprocesshook", 0, gInitPath); + m_UpdatePaths = GetPrivateProfileInt("window", "updatepaths", 1, gInitPath); + // texture limits + m_TexMinX = GetPrivateProfileInt("texture", "MinTexX", 0, gInitPath); + m_TexMinY = GetPrivateProfileInt("texture", "MinTexY", 0, gInitPath); + m_TexMaxX = GetPrivateProfileInt("texture", "MaxTexX", 0, gInitPath); + m_TexMaxY = GetPrivateProfileInt("texture", "MaxTexY", 0, gInitPath); + // defaults + m_DefaultCoordinates = GetPrivateProfileInt("window", "defaultcoord", 0, gInitPath); + m_DefaultPosX = GetPrivateProfileInt("window", "defaultposx", 50, gInitPath); + m_DefaultPosY = GetPrivateProfileInt("window", "defaultposy", 50, gInitPath); + m_DefaultSizX = GetPrivateProfileInt("window", "defaultsizx", 800, gInitPath); + m_DefaultSizY = GetPrivateProfileInt("window", "defaultsizy", 600, gInitPath); } CGlobalSettings::~CGlobalSettings() @@ -87,7 +104,12 @@ CGlobalSettings::~CGlobalSettings() void CGlobalSettings::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); + //char msg[80]; + //sprintf(msg, "DoDataExchange(1) defposx = %d", m_DefaultPosX); + //MessageBox(msg, "debug", 0); + CString sDefaultPosX, sDefaultPosY; + sDefaultPosX.Format("%d", m_DefaultPosX); + sDefaultPosY.Format("%d", m_DefaultPosY); DDX_Check(pDX, IDC_CONFIG_DEBUGMODE, m_DebugMode); DDX_Check(pDX, IDC_CONFIG_AUTOHIDE, m_AutoHideMode); DDX_Check(pDX, IDC_CONFIG_CHECKADMIN, m_CheckAdminRights); @@ -98,34 +120,29 @@ void CGlobalSettings::DoDataExchange(CDataExchange* pDX) DDX_Text (pDX, IDC_TEX_MINY, m_TexMinY); DDX_Text (pDX, IDC_TEX_MAXX, m_TexMaxX); DDX_Text (pDX, IDC_TEX_MAXY, m_TexMaxY); + DDX_Radio(pDX, IDC_DEFAULTCOORDINATES, m_DefaultCoordinates); + DDX_Text(pDX, IDC_DEFAULTPOSX, sDefaultPosX); + DDX_Text(pDX, IDC_DEFAULTPOSY, sDefaultPosY); + DDX_Text(pDX, IDC_DEFAULTSIZX, m_DefaultSizX); + DDX_Text(pDX, IDC_DEFAULTSIZY, m_DefaultSizY); + m_DefaultPosX = atoi(sDefaultPosX); + m_DefaultPosY = atoi(sDefaultPosY); + CDialog::DoDataExchange(pDX); + //sprintf(msg, "DoDataExchange(2) defposx = %d", m_DefaultPosX); + //MessageBox(msg, "debug", 0); } BEGIN_MESSAGE_MAP(CGlobalSettings, CDialog) END_MESSAGE_MAP() -#define IDPaletteTIMER 2 - -// CPaletteDialog message handlers - -//static void SetKeys(HWND hDlg, Key_Type *FKeys, KeyCombo_Type *FKeyCombo) -//{ -// for(int i=0; FKeys[i].iLabelResourceId; i++){ -// int iCursor = 0; -// DWORD dwKey; -// dwKey = GetPrivateProfileInt("keymapping", FKeys[i].sIniLabel, -1, gInitPath); -// SetDlgItemText(hDlg,FKeys[i].iLabelResourceId,FKeys[i].sLabel); -// CComboBox *pCombo=(CComboBox *)GetDlgItem(FKeys[i].iComboResourceId); -// pCombo->Clear(); -// for(int j=0; FKeyCombo[j].dwVKeyCode; j++) { -// pCombo->AddString(FKeyCombo[j].sVKeyLabel); -// if(dwKey == FKeyCombo[j].dwVKeyCode) iCursor=j; -// } -// pCombo->SetCurSel(iCursor); -// } -//} - BOOL CGlobalSettings::OnInitDialog() { + IFormat *m_pRelIntegerFormat = new(RelIntegerFormat); + m_EditPosX.SubclassDlgItem(IDC_DEFAULTPOSX, this); + m_EditPosY.SubclassDlgItem(IDC_DEFAULTPOSY, this); + m_EditPosX.SetFormatter(m_pRelIntegerFormat); + m_EditPosY.SetFormatter(m_pRelIntegerFormat); + CDialog::OnInitDialog(); for(int i=0; FKeys[i].iLabelResourceId; i++){ int iCursor = 0; DWORD dwKey; @@ -152,22 +169,7 @@ BOOL CGlobalSettings::OnInitDialog() } pCombo->SetCurSel(iCursor); } - //SetKeys(this, FKeys, FKeyCombo); - //SetKeys(this, HKeys, HKeyCombo); - - m_DebugMode = GetPrivateProfileInt("window", "debug", 0, gInitPath); - m_AutoHideMode = GetPrivateProfileInt("window", "autohide", 0, gInitPath); - m_CheckAdminRights = GetPrivateProfileInt("window", "checkadmin", 0, gInitPath); - m_NameFromFolder = GetPrivateProfileInt("window", "namefromfolder", 0, gInitPath); - m_MultiHooks = GetPrivateProfileInt("window", "multiprocesshook", 0, gInitPath); - m_UpdatePaths = GetPrivateProfileInt("window", "updatepaths", 1, gInitPath); - m_TexMinX = GetPrivateProfileInt("texture", "MinTexX", 0, gInitPath); - m_TexMinY = GetPrivateProfileInt("texture", "MinTexY", 0, gInitPath); - m_TexMaxX = GetPrivateProfileInt("texture", "MaxTexX", 0, gInitPath); - m_TexMaxY = GetPrivateProfileInt("texture", "MaxTexY", 0, gInitPath); - CDialog::OnInitDialog(); return TRUE; // return TRUE unless you set the focus to a control - // EXCEPTION: OCX Property Pages should return FALSE } void CGlobalSettings::OnOK() @@ -196,6 +198,18 @@ void CGlobalSettings::OnOK() WritePrivateProfileString("texture", "MaxTexX", val, gInitPath); sprintf_s(val, sizeof(val), "%i", m_TexMaxY); WritePrivateProfileString("texture", "MaxTexY", val, gInitPath); + // defaults + sprintf_s(val, sizeof(val), "%i", m_DefaultCoordinates); + WritePrivateProfileString("window", "defaultcoord", val, gInitPath); + sprintf_s(val, sizeof(val), "%i", m_DefaultPosX); + WritePrivateProfileString("window", "defaultposx", val, gInitPath); + sprintf_s(val, sizeof(val), "%i", m_DefaultPosY); + WritePrivateProfileString("window", "defaultposy", val, gInitPath); + sprintf_s(val, sizeof(val), "%i", m_DefaultSizX); + WritePrivateProfileString("window", "defaultsizx", val, gInitPath); + sprintf_s(val, sizeof(val), "%i", m_DefaultSizY); + WritePrivateProfileString("window", "defaultsizy", val, gInitPath); + // fkeys for(int i=0; FKeys[i].iLabelResourceId; i++){ int iCursor = 0; diff --git a/host/CGlobalSettings.h b/host/CGlobalSettings.h index b3839db..c81ac93 100644 --- a/host/CGlobalSettings.h +++ b/host/CGlobalSettings.h @@ -1,3 +1,5 @@ +#include "specialedit.h" + #pragma once typedef struct { @@ -39,11 +41,18 @@ protected: int m_TexMinY; int m_TexMaxX; int m_TexMaxY; + int m_DefaultCoordinates; + int m_DefaultPosX; + int m_DefaultPosY; + int m_DefaultSizX; + int m_DefaultSizY; DECLARE_MESSAGE_MAP() public: public: virtual BOOL OnInitDialog(); protected: + CSpecialEdit m_EditPosX; + CSpecialEdit m_EditPosY; virtual void OnOK(); }; diff --git a/host/TabProgram.cpp b/host/TabProgram.cpp index a48a52f..bbdfd86 100644 --- a/host/TabProgram.cpp +++ b/host/TabProgram.cpp @@ -2,6 +2,7 @@ // #include "stdafx.h" +#include "shlwapi.h" #include "TargetDlg.h" #include "TabProgram.h" #include "dxwndhost.h" @@ -229,6 +230,38 @@ void CTabProgram::OnDropFiles(HDROP dropInfo) DragFinish(dropInfo); } +#include +#include +#include + +void _tmain(int argc, TCHAR *argv[]) +{ + WIN32_FIND_DATA FindFileData; + HANDLE hFind; + + if( argc != 2 ) + { + _tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]); + return; + } + + _tprintf (TEXT("Target file is %s\n"), argv[1]); + hFind = FindFirstFile(argv[1], &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) + { + printf ("FindFirstFile failed (%d)\n", GetLastError()); + return; + } + else + { + _tprintf (TEXT("The first file found is %s\n"), + FindFileData.cFileName); + FindClose(hFind); + } +} + + + BOOL CTabProgram::OnInitDialog() { HINSTANCE Hinst; @@ -246,14 +279,38 @@ BOOL CTabProgram::OnInitDialog() //m_Launch.DragAcceptFiles(); CDialog::OnInitDialog(); CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent())); + IconBox=(CStatic *)this->GetDlgItem(IDC_STATIC_ICON); Hinst = ::LoadLibrary(cTarget->m_FilePath); if(Hinst){ Icon = ::ExtractIcon(Hinst, cTarget->m_FilePath, 0); - IconBox=(CStatic *)this->GetDlgItem(IDC_STATIC_ICON); - PrevIcon = IconBox->SetIcon(Icon); - if (IconBox->GetIcon() == NULL) - IconBox->SetIcon(::LoadIcon(NULL, IDI_ERROR)); - ::FreeLibrary(Hinst); + if(Icon){ + PrevIcon = IconBox->SetIcon(Icon); + if (IconBox->GetIcon() == NULL) + IconBox->SetIcon(::LoadIcon(NULL, IDI_ERROR)); + } + else{ + WIN32_FIND_DATA FindFileData; + HANDLE hFind; + char SearchPath[MAX_PATH]; + strcpy(SearchPath, cTarget->m_FilePath); + PathRemoveFileSpec(SearchPath); + strcat(SearchPath, "\\*.ico"); + //MessageBox(SearchPath, "debug", 0); + hFind = FindFirstFile(SearchPath, &FindFileData); + if ((hFind != INVALID_HANDLE_VALUE) && (hFind != (HANDLE)ERROR_FILE_NOT_FOUND)){ + strcpy(SearchPath, cTarget->m_FilePath); + PathRemoveFileSpec(SearchPath); + strcat(SearchPath, "\\"); + strcat(SearchPath, FindFileData.cFileName); + //MessageBox(SearchPath, "debug", 0); + Icon = ::ExtractIcon(NULL, SearchPath, 0); + PrevIcon = IconBox->SetIcon(Icon); + if (IconBox->GetIcon() == NULL) + IconBox->SetIcon(::LoadIcon(NULL, IDI_ERROR)); + FindClose(hFind); + } + ::FreeLibrary(Hinst); + } if(PrevIcon) ::DestroyIcon(PrevIcon); } diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 9c560db..53f6757 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index b02a57e..6ec6f9e 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 a7d3c4b..59b8477 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 bcc85a2..8d3a3c6 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -1962,6 +1962,12 @@ void CDxwndhostView::OnAdd(char *sInitialPath) } memset(&TargetMaps[i],0,sizeof(TARGETMAP)); // clean up, just in case.... if(sInitialPath) dlg.m_FilePath = CString(sInitialPath); + + dlg.m_Coordinates = GetPrivateProfileInt("window", "defaultcoord", 0, gInitPath); + dlg.m_PosX = GetPrivateProfileInt("window", "defaultposx", 50, gInitPath); + dlg.m_PosY = GetPrivateProfileInt("window", "defaultposy", 50, gInitPath); + dlg.m_SizX = GetPrivateProfileInt("window", "defaultsizx", 800, gInitPath); + dlg.m_SizY = GetPrivateProfileInt("window", "defaultsizy", 600, gInitPath); if(dlg.DoModal() == IDOK && dlg.m_FilePath.GetLength()){ strnncpy(PrivateMaps[i].title, (char *)dlg.m_Title.GetString(), MAX_TITLE); diff --git a/host/resource b/host/resource index 0ec0d94..c2ab1e7 100644 Binary files a/host/resource and b/host/resource differ