#include "dxwnd.h" #include "dxwcore.hpp" #include "syslibs.h" #include "hddraw.h" #include "dxhook.h" #include "dxhelper.h" #include "stdio.h" static void Stopper(char *s, int line) { char sMsg[81]; sprintf_s(sMsg, 80, "break: \"%s\"", s); MessageBox(0, sMsg, "break", MB_OK | MB_ICONEXCLAMATION); } //#define STOPPER_TEST // comment out to eliminate #ifdef STOPPER_TEST #define STOPPER(s) Stopper(s, __LINE__) #else #define STOPPER(s) #endif /* dlg->m_DCEmulationMode = 0; if(t->flags2 & GDISTRETCHED) dlg->m_DCEmulationMode = 1; if(t->flags3 & GDIEMULATEDC) dlg->m_DCEmulationMode = 2; if(t->flags & MAPGDITOPRIMARY) dlg->m_DCEmulationMode = 3; */ typedef BOOL (WINAPI *ExtTextOutW_Type)(HDC, int, int, UINT, const RECT *, LPCWSTR, UINT, const INT *); typedef BOOL (WINAPI *ExtTextOutA_Type)(HDC, int, int, UINT, const RECT *, LPCSTR, UINT, const INT *); BOOL WINAPI extExtTextOutW(HDC, int, int, UINT, const RECT *, LPCWSTR, UINT, const INT *); BOOL WINAPI extExtTextOutA(HDC, int, int, UINT, const RECT *, LPCSTR, UINT, const INT *); ExtTextOutW_Type pExtTextOutW = NULL; ExtTextOutA_Type pExtTextOutA = NULL; static HookEntry_Type Hooks[]={ {HOOK_IAT_CANDIDATE, "GetDeviceCaps", (FARPROC)GetDeviceCaps, (FARPROC *)&pGDIGetDeviceCaps, (FARPROC)extGetDeviceCaps}, {HOOK_IAT_CANDIDATE, "ScaleWindowExtEx", (FARPROC)ScaleWindowExtEx, (FARPROC *)&pGDIScaleWindowExtEx, (FARPROC)extScaleWindowExtEx}, {HOOK_IAT_CANDIDATE, "SaveDC", (FARPROC)SaveDC, (FARPROC *)&pGDISaveDC, (FARPROC)extGDISaveDC}, {HOOK_IAT_CANDIDATE, "RestoreDC", (FARPROC)RestoreDC, (FARPROC *)&pGDIRestoreDC, (FARPROC)extGDIRestoreDC}, {HOOK_IAT_CANDIDATE, "AnimatePalette", (FARPROC)AnimatePalette, (FARPROC *)&pAnimatePalette, (FARPROC)extAnimatePalette}, {HOOK_IAT_CANDIDATE, "CreatePalette", (FARPROC)CreatePalette, (FARPROC *)&pGDICreatePalette, (FARPROC)extGDICreatePalette}, {HOOK_IAT_CANDIDATE, "SelectPalette", (FARPROC)SelectPalette, (FARPROC *)&pGDISelectPalette, (FARPROC)extSelectPalette}, {HOOK_IAT_CANDIDATE, "RealizePalette", (FARPROC)RealizePalette, (FARPROC *)&pGDIRealizePalette, (FARPROC)extRealizePalette}, {HOOK_IAT_CANDIDATE, "GetSystemPaletteEntries", (FARPROC)GetSystemPaletteEntries, (FARPROC *)&pGDIGetSystemPaletteEntries, (FARPROC)extGetSystemPaletteEntries}, {HOOK_IAT_CANDIDATE, "SetSystemPaletteUse", (FARPROC)SetSystemPaletteUse, (FARPROC *)&pSetSystemPaletteUse, (FARPROC)extSetSystemPaletteUse}, {HOOK_IAT_CANDIDATE, "StretchDIBits", (FARPROC)StretchDIBits, (FARPROC *)&pStretchDIBits, (FARPROC)extStretchDIBits}, //{HOOK_IAT_CANDIDATE, "SetDIBitsToDevice", (FARPROC)NULL, (FARPROC *)&pSetDIBitsToDevice, (FARPROC)extSetDIBitsToDevice}, //{HOOK_IAT_CANDIDATE, "CreateCompatibleBitmap", (FARPROC)NULL, (FARPROC *)&pCreateCompatibleBitmap, (FARPROC)extCreateCompatibleBitmap}, //{HOOK_IAT_CANDIDATE, "SetMapMode", (FARPROC)NULL, (FARPROC *)NULL, (FARPROC)extSetMapMode}, {HOOK_IAT_CANDIDATE, "SetPixelFormat", (FARPROC)NULL, (FARPROC *)&pGDISetPixelFormat, (FARPROC)extGDISetPixelFormat}, {HOOK_IAT_CANDIDATE, "GetPixelFormat", (FARPROC)NULL, (FARPROC *)&pGDIGetPixelFormat, (FARPROC)extGDIGetPixelFormat}, {HOOK_IAT_CANDIDATE, "ChoosePixelFormat", (FARPROC)NULL, (FARPROC *)&pChoosePixelFormat, (FARPROC)extChoosePixelFormat}, {HOOK_IAT_CANDIDATE, "DescribePixelFormat", (FARPROC)NULL, (FARPROC *)&pDescribePixelFormat, (FARPROC)extDescribePixelFormat}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type RemapHooks[]={ {HOOK_IAT_CANDIDATE, "SetViewportOrgEx", (FARPROC)SetViewportOrgEx, (FARPROC *)&pSetViewportOrgEx, (FARPROC)extSetViewportOrgEx}, // needed in ShowBanner {HOOK_IAT_CANDIDATE, "SetViewportExtEx", (FARPROC)NULL, (FARPROC *)&pSetViewportExtEx, (FARPROC)extSetViewportExtEx}, {HOOK_IAT_CANDIDATE, "GetViewportOrgEx", (FARPROC)NULL, (FARPROC *)&pGetViewportOrgEx, (FARPROC)extGetViewportOrgEx}, {HOOK_IAT_CANDIDATE, "GetWindowOrgEx", (FARPROC)NULL, (FARPROC *)&pGetWindowOrgEx, (FARPROC)extGetWindowOrgEx}, {HOOK_IAT_CANDIDATE, "SetWindowOrgEx", (FARPROC)NULL, (FARPROC *)&pSetWindowOrgEx, (FARPROC)extSetWindowOrgEx}, {HOOK_IAT_CANDIDATE, "GetCurrentPositionEx", (FARPROC)NULL, (FARPROC *)&pGetCurrentPositionEx, (FARPROC)extGetCurrentPositionEx}, {HOOK_IAT_CANDIDATE, "SetDIBitsToDevice", (FARPROC)NULL, (FARPROC *)&pSetDIBitsToDevice, (FARPROC)extSetDIBitsToDevice}, // does the stretching {HOOK_IAT_CANDIDATE, "GetRgnBox", (FARPROC)NULL, (FARPROC *)&pGetRgnBox, (FARPROC)extGetRgnBox}, //{HOOK_IAT_CANDIDATE, "GetRegionData", (FARPROC)NULL, (FARPROC *)&pGetRegionData, (FARPROC)extGetRegionData}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type ScaledHooks[]={ {HOOK_IAT_CANDIDATE, "Rectangle", (FARPROC)Rectangle, (FARPROC *)&pGDIRectangle, (FARPROC)extRectangle}, {HOOK_IAT_CANDIDATE, "TextOutA", (FARPROC)TextOutA, (FARPROC *)&pGDITextOutA, (FARPROC)extTextOutA}, {HOOK_IAT_CANDIDATE, "GetClipBox", (FARPROC)NULL, (FARPROC *)&pGDIGetClipBox, (FARPROC)extGetClipBox}, //{HOOK_IAT_CANDIDATE, "GetRgnBox", (FARPROC)NULL, (FARPROC *)&pGetRgnBox, (FARPROC)extGetRgnBox}, {HOOK_IAT_CANDIDATE, "Polyline", (FARPROC)NULL, (FARPROC *)&pPolyline, (FARPROC)extPolyline}, {HOOK_IAT_CANDIDATE, "PolyBezierTo", (FARPROC)NULL, (FARPROC *)&pPolyBezierTo, (FARPROC)extPolyBezierTo}, {HOOK_IAT_CANDIDATE, "PolylineTo", (FARPROC)NULL, (FARPROC *)&pPolylineTo, (FARPROC)extPolylineTo}, {HOOK_IAT_CANDIDATE, "PolyDraw", (FARPROC)NULL, (FARPROC *)&pPolyDraw, (FARPROC)extPolyDraw}, {HOOK_IAT_CANDIDATE, "MoveToEx", (FARPROC)NULL, (FARPROC *)&pMoveToEx, (FARPROC)extMoveToEx}, {HOOK_IAT_CANDIDATE, "ArcTo", (FARPROC)NULL, (FARPROC *)&pArcTo, (FARPROC)extArcTo}, {HOOK_IAT_CANDIDATE, "LineTo", (FARPROC)NULL, (FARPROC *)&pLineTo, (FARPROC)extLineTo}, {HOOK_IAT_CANDIDATE, "SetPixel", (FARPROC)NULL, (FARPROC *)&pSetPixel, (FARPROC)extSetPixel}, {HOOK_IAT_CANDIDATE, "Ellipse", (FARPROC)NULL, (FARPROC *)&pEllipse, (FARPROC)extEllipse}, {HOOK_IAT_CANDIDATE, "Polygon", (FARPROC)NULL, (FARPROC *)&pPolygon, (FARPROC)extPolygon}, {HOOK_IAT_CANDIDATE, "Arc", (FARPROC)NULL, (FARPROC *)&pArc, (FARPROC)extArc}, // commented out since they alter text on screen...... (see Imperialism II difficulty level menu) //{HOOK_IAT_CANDIDATE, "CreateEllipticRgn", (FARPROC)NULL, (FARPROC *)&pCreateEllipticRgn, (FARPROC)extCreateEllipticRgn}, //{HOOK_IAT_CANDIDATE, "CreateEllipticRgnIndirect", (FARPROC)NULL, (FARPROC *)&pCreateEllipticRgnIndirect, (FARPROC)extCreateEllipticRgnIndirect}, //{HOOK_IAT_CANDIDATE, "CreateRectRgn", (FARPROC)NULL, (FARPROC *)&pCreateRectRgn, (FARPROC)extCreateRectRgn}, //{HOOK_IAT_CANDIDATE, "CreateRectRgnIndirect", (FARPROC)NULL, (FARPROC *)&pCreateRectRgnIndirect, (FARPROC)extCreateRectRgnIndirect}, //{HOOK_IAT_CANDIDATE, "CreatePolygonRgn", (FARPROC)NULL, (FARPROC *)&pCreatePolygonRgn, (FARPROC)extCreatePolygonRgn}, // same as emulated GDI ... {HOOK_IAT_CANDIDATE, "CreateCompatibleDC", (FARPROC)CreateCompatibleDC, (FARPROC *)&pGDICreateCompatibleDC, (FARPROC)extGDICreateCompatibleDC}, {HOOK_IAT_CANDIDATE, "DeleteDC", (FARPROC)DeleteDC, (FARPROC *)&pGDIDeleteDC, (FARPROC)extGDIDeleteDC}, {HOOK_IAT_CANDIDATE, "CreateDCA", (FARPROC)CreateDCA, (FARPROC *)&pGDICreateDC, (FARPROC)extGDICreateDC}, // CreateDCW ..... {HOOK_IAT_CANDIDATE, "BitBlt", (FARPROC)BitBlt, (FARPROC *)&pGDIBitBlt, (FARPROC)extGDIBitBlt}, {HOOK_IAT_CANDIDATE, "StretchBlt", (FARPROC)StretchBlt, (FARPROC *)&pGDIStretchBlt, (FARPROC)extGDIStretchBlt}, {HOOK_IAT_CANDIDATE, "PatBlt", (FARPROC)PatBlt, (FARPROC *)&pGDIPatBlt, (FARPROC)extGDIPatBlt}, {HOOK_IAT_CANDIDATE, "MaskBlt", (FARPROC)NULL, (FARPROC *)&pMaskBlt, (FARPROC)extMaskBlt}, {HOOK_IAT_CANDIDATE, "ExtTextOutA", (FARPROC)ExtTextOutA, (FARPROC *)&pExtTextOutA, (FARPROC)extExtTextOutA}, {HOOK_IAT_CANDIDATE, "ExtTextOutW", (FARPROC)ExtTextOutW, (FARPROC *)&pExtTextOutW, (FARPROC)extExtTextOutW}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type EmulateHooks[]={ // useless CreateCompatibleDC: it maps VirtualHDC on top of VirtualHDC, then does nothing, unless when asked to operate on 0!.... //{HOOK_IAT_CANDIDATE, "CreateCompatibleDC", (FARPROC)CreateCompatibleDC, (FARPROC *)&pGDICreateCompatibleDC, (FARPROC)extEMUCreateCompatibleDC}, // useless DeleteDC: it's just a proxy //{HOOK_IAT_CANDIDATE, "DeleteDC", (FARPROC)DeleteDC, (FARPROC *)&pGDIDeleteDC, (FARPROC)extGDIDeleteDC}, {HOOK_IAT_CANDIDATE, "CreateDCA", (FARPROC)CreateDCA, (FARPROC *)&pGDICreateDC, (FARPROC)extGDICreateDC}, // CreateDCW ..... {HOOK_IAT_CANDIDATE, "GetObjectType", (FARPROC)GetObjectType, (FARPROC *)&pGetObjectType, (FARPROC)extGetObjectType}, {HOOK_IAT_CANDIDATE, "GetClipBox", (FARPROC)NULL, (FARPROC *)&pGDIGetClipBox, (FARPROC)extGetClipBox}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type DDHooks[]={ {HOOK_IAT_CANDIDATE, "CreateCompatibleDC", (FARPROC)CreateCompatibleDC, (FARPROC *)&pGDICreateCompatibleDC, (FARPROC)extDDCreateCompatibleDC}, {HOOK_IAT_CANDIDATE, "DeleteDC", (FARPROC)DeleteDC, (FARPROC *)&pGDIDeleteDC, (FARPROC)extDDDeleteDC}, {HOOK_IAT_CANDIDATE, "CreateDCA", (FARPROC)CreateDCA, (FARPROC *)&pGDICreateDC, (FARPROC)extDDCreateDC}, {HOOK_IAT_CANDIDATE, "BitBlt", (FARPROC)BitBlt, (FARPROC *)&pGDIBitBlt, (FARPROC)extDDBitBlt}, {HOOK_IAT_CANDIDATE, "StretchBlt", (FARPROC)StretchBlt, (FARPROC *)&pGDIStretchBlt, (FARPROC)extDDStretchBlt}, {HOOK_IAT_CANDIDATE, "GetClipBox", (FARPROC)NULL, (FARPROC *)&pGDIGetClipBox, (FARPROC)extGetClipBox}, // {HOOK_IAT_CANDIDATE, "PatBlt", (FARPROC)PatBlt, (FARPROC *)&pGDIPatBlt, (FARPROC)extDDPatBlt}, // missing one ... // {HOOK_IAT_CANDIDATE, "MaskBlt", (FARPROC)NULL, (FARPROC *)&pMaskBlt, (FARPROC)extDDMaskBlt}, // missing one ... {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type TextHooks[]={ {HOOK_IAT_CANDIDATE, "CreateFontA", (FARPROC)CreateFont, (FARPROC *)&pGDICreateFont, (FARPROC)extCreateFont}, {HOOK_IAT_CANDIDATE, "CreateFontIndirectA", (FARPROC)CreateFontIndirectA, (FARPROC *)&pGDICreateFontIndirect, (FARPROC)extCreateFontIndirect}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type GammaHooks[]={ {HOOK_IAT_CANDIDATE, "SetDeviceGammaRamp", (FARPROC)SetDeviceGammaRamp, (FARPROC *)&pGDISetDeviceGammaRamp, (FARPROC)extSetDeviceGammaRamp}, {HOOK_IAT_CANDIDATE, "GetDeviceGammaRamp", (FARPROC)GetDeviceGammaRamp, (FARPROC *)&pGDIGetDeviceGammaRamp, (FARPROC)extGetDeviceGammaRamp}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type FontHooks[]={ {HOOK_IAT_CANDIDATE, "CreateScalableFontResourceA", (FARPROC)NULL, (FARPROC *)&pCreateScalableFontResourceA, (FARPROC)extCreateScalableFontResourceA}, {HOOK_IAT_CANDIDATE, "CreateScalableFontResourceW", (FARPROC)NULL, (FARPROC *)&pCreateScalableFontResourceW, (FARPROC)extCreateScalableFontResourceW}, {HOOK_IAT_CANDIDATE, "AddFontResourceA", (FARPROC)NULL, (FARPROC *)&pAddFontResourceA, (FARPROC)extAddFontResourceA}, {HOOK_IAT_CANDIDATE, "AddFontResourceW", (FARPROC)NULL, (FARPROC *)&pAddFontResourceW, (FARPROC)extAddFontResourceW}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; extern HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); extern HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *, LPDIRECTDRAW FAR *, REFIID, IUnknown FAR *); static char *libname = "gdi32.dll"; void HookGDI32Init() { HookLibInit(Hooks); HookLibInit(RemapHooks); HookLibInit(DDHooks); HookLibInit(EmulateHooks); HookLibInit(TextHooks); HookLibInit(GammaHooks); } void HookGDI32(HMODULE module) { HookLibrary(module, Hooks, libname); if (dxw.dwFlags1 & CLIENTREMAPPING) HookLibrary(module, RemapHooks, libname); if (dxw.dwFlags2 & GDISTRETCHED) HookLibrary(module, ScaledHooks, libname); if (dxw.dwFlags3 & GDIEMULATEDC) HookLibrary(module, EmulateHooks, libname); if (dxw.dwFlags1 & MAPGDITOPRIMARY) HookLibrary(module, DDHooks, libname); if (dxw.dwFlags1 & FIXTEXTOUT) HookLibrary(module, TextHooks, libname); if (dxw.dwFlags2 & DISABLEGAMMARAMP) HookLibrary(module, GammaHooks, libname); // v2.02.33 - for "Stratego" compatibility option if(dxw.dwFlags3 & FONTBYPASS) HookLibrary(module, FontHooks, libname); } FARPROC Remap_GDI32_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; if(addr=RemapLibrary(proc, hModule, Hooks)) return addr; if (dxw.dwFlags1 & CLIENTREMAPPING) if(addr=RemapLibrary(proc, hModule, RemapHooks)) return addr; if (dxw.dwFlags2 & GDISTRETCHED) if (addr=RemapLibrary(proc, hModule, ScaledHooks)) return addr; if (dxw.dwFlags3 & GDIEMULATEDC) if (addr=RemapLibrary(proc, hModule, EmulateHooks)) return addr; if (dxw.dwFlags1 & MAPGDITOPRIMARY) if (addr=RemapLibrary(proc, hModule, DDHooks)) return addr; if (dxw.dwFlags1 & FIXTEXTOUT) if(addr=RemapLibrary(proc, hModule, TextHooks)) return addr; if (dxw.dwFlags2 & DISABLEGAMMARAMP) if(addr=RemapLibrary(proc, hModule, GammaHooks)) return addr; // v2.02.33 - for "Stratego" compatibility option if (dxw.dwFlags3 & FONTBYPASS) if(addr=RemapLibrary(proc, hModule, FontHooks)) return addr; return NULL; } //-------------------------------------------------------------------------------------------- // // extern and common functions // //-------------------------------------------------------------------------------------------- extern DEVMODE *pSetDevMode; extern DWORD PaletteEntries[256]; extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE); extern HRESULT WINAPI sBlt(char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL); extern GetDC_Type pGetDC; extern ReleaseDC_Type pReleaseDC; static COLORREF GetMatchingColor(COLORREF crColor) { int iDistance, iMinDistance; int iColorIndex, iMinColorIndex; COLORREF PalColor; iMinDistance=0xFFFFFF; iMinColorIndex=0; for(iColorIndex=0; iColorIndex<256; iColorIndex++){ int iDist; iDistance=0; PalColor=PaletteEntries[iColorIndex]; switch(dxw.ActualPixelFormat.dwRGBBitCount){ case 32: PalColor = ((PalColor & 0x00FF0000) >> 16) | (PalColor & 0x0000FF00) | ((PalColor & 0x000000FF) << 16); break; case 16: if(dxw.ActualPixelFormat.dwGBitMask==0x03E0){ // RGB555 screen settings PalColor = ((PalColor & 0x7C00) >> 7) | ((PalColor & 0x03E0) << 6) | ((PalColor & 0x001F) << 19); } else { // RGB565 screen settings PalColor = ((PalColor & 0xF800) >> 8) | ((PalColor & 0x07E0) << 5) | ((PalColor & 0x001F) << 19); } break; } iDist = (crColor & 0x00FF0000) - (PalColor & 0x00FF0000); iDist >>= 16; if (iDist<0) iDist=-iDist; iDist *= iDist; iDistance += iDist; iDist = (crColor & 0x0000FF00) - (PalColor & 0x0000FF00); iDist >>= 8; if (iDist<0) iDist=-iDist; iDist *= iDist; iDistance += iDist; iDist = (crColor & 0x000000FF) - (PalColor & 0x000000FF); // iDist >>= 0; if (iDist<0) iDist=-iDist; iDist *= iDist; iDistance += iDist; if (iDistance < iMinDistance) { iMinDistance = iDistance; iMinColorIndex = iColorIndex; } if (iMinDistance==0) break; // got the perfect match! } OutTraceDW("GetMatchingColor: color=%x matched with palette[%d]=%x dist=%d\n", crColor, iMinColorIndex, PaletteEntries[iMinColorIndex], iDistance); PalColor=PaletteEntries[iMinColorIndex]; switch(dxw.ActualPixelFormat.dwRGBBitCount){ case 32: crColor = ((PalColor & 0x00FF0000) >> 16) | (PalColor & 0x0000FF00) | ((PalColor & 0x000000FF) << 16); break; case 16: if(dxw.ActualPixelFormat.dwGBitMask==0x03E0){ // RGB555 screen settings crColor = ((PalColor & 0x7C00) >> 7) | ((PalColor & 0x03E0) << 6) | ((PalColor & 0x001F) << 19); } else { // RGB565 screen settings crColor = ((PalColor & 0xF800) >> 8) | ((PalColor & 0x07E0) << 5) | ((PalColor & 0x001F) << 19); } break; } return crColor; } //-------------------------------------------------------------------------------------------- // // API hookers // //-------------------------------------------------------------------------------------------- int WINAPI extGetDeviceCaps(HDC hdc, int nindex) { DWORD res; res = (*pGDIGetDeviceCaps)(hdc, nindex); if(IsTraceDDRAW){ OutTrace("GetDeviceCaps: hdc=%x index=%x(%s)", hdc, nindex, ExplainDeviceCaps(nindex)); switch(nindex){ case RASTERCAPS: OutTrace(" res=0x%04x(%s)\n",res, ExplainRasterCaps(res)); break; case BITSPIXEL: case COLORRES: case VERTRES: case SIZEPALETTE: case NUMRESERVED: OutTrace(" res=%d\n",res); break; default: OutTrace(" res=0x%04x\n",res); break; } } // if you have a bypassed setting, use it first! if(pSetDevMode){ switch(nindex){ case BITSPIXEL: case COLORRES: res = pSetDevMode->dmBitsPerPel; OutTraceDW("GetDeviceCaps: fix(1) BITSPIXEL/COLORRES cap=%x\n",res); return res; case HORZRES: res = pSetDevMode->dmPelsWidth; OutTraceDW("GetDeviceCaps: fix(1) HORZRES cap=%d\n", res); return res; case VERTRES: res = pSetDevMode->dmPelsHeight; OutTraceDW("GetDeviceCaps: fix(1) VERTRES cap=%d\n", res); return res; } } switch(nindex){ case VERTRES: res= dxw.GetScreenHeight(); OutTraceDW("GetDeviceCaps: fix(2) VERTRES cap=%d\n", res); break; case HORZRES: res= dxw.GetScreenWidth(); OutTraceDW("GetDeviceCaps: fix(2) HORZRES cap=%d\n", res); break; // WARNING: in no-emu mode, the INIT8BPP and INIT16BPP flags expose capabilities that // are NOT implemented and may cause later troubles! case RASTERCAPS: if(dxw.dwFlags2 & INIT8BPP) { res |= RC_PALETTE; // v2.02.12 OutTraceDW("GetDeviceCaps: fix(2) RASTERCAPS setting RC_PALETTE cap=%x\n",res); } break; case BITSPIXEL: case COLORRES: if(dxw.dwFlags2 & (INIT8BPP|INIT16BPP)){ // v2.02.32 fix if(dxw.dwFlags2 & INIT8BPP) res = 8; if(dxw.dwFlags2 & INIT16BPP) res = 16; OutTraceDW("GetDeviceCaps: fix(2) BITSPIXEL/COLORRES cap=%d\n",res); } break; //case NUMCOLORS: // numcolors windows bug fix.... // if(res == -1) res=1; // return res; } if(dxw.dwFlags1 & EMULATESURFACE){ switch(nindex){ case RASTERCAPS: if((dxw.VirtualPixelFormat.dwRGBBitCount==8) || (dxw.dwFlags2 & INIT8BPP)){ res |= RC_PALETTE; OutTraceDW("GetDeviceCaps: fix(3) RASTERCAPS setting RC_PALETTE cap=%x(%s)\n", res, ExplainRasterCaps(res)); } break; case BITSPIXEL: case COLORRES: int PrevRes; PrevRes=res; if(dxw.VirtualPixelFormat.dwRGBBitCount!=0) res = dxw.VirtualPixelFormat.dwRGBBitCount; if(dxw.dwFlags2 & INIT8BPP) res = 8; if(dxw.dwFlags2 & INIT16BPP) res = 16; if(PrevRes != res) OutTraceDW("GetDeviceCaps: fix(3) BITSPIXEL/COLORRES cap=%d\n",res); break; case SIZEPALETTE: res = 256; OutTraceDW("GetDeviceCaps: fix(3) SIZEPALETTE cap=%x\n",res); break; case NUMRESERVED: res = 0; OutTraceDW("GetDeviceCaps: fix(3) NUMRESERVED cap=%x\n",res); break; } } return res; } BOOL WINAPI extTextOutA(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cchString) { BOOL ret; extern BOOL gFixed; OutTraceDW("TextOut: hdc=%x xy=(%d,%d) str=(%d)\"%.*s\"\n", hdc, nXStart, nYStart, cchString, cchString, lpString); if (!gFixed && dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.MapClient(&nXStart, &nYStart); OutTraceDW("TextOut: fixed dest=(%d,%d)\n", nXStart, nYStart); } ret=(*pGDITextOutA)(hdc, nXStart, nYStart, lpString, cchString); if(!ret) OutTraceE("TextOut: ERROR ret=%x\n", ret); return ret; } BOOL WINAPI extScaleWindowExtEx(HDC hdc, int Xnum, int Xdenom, int Ynum, int Ydenom, LPSIZE lpSize) { OutTraceDW("ScaleWindowExtEx: hdc=%x num=(%d,%d) denom=(%d,%d) lpSize=%d\n", hdc, Xnum, Ynum, Xdenom, Ydenom, lpSize); MessageBox(0, "ScaleWindowExtEx", "to fix", MB_OK | MB_ICONEXCLAMATION); return (*pGDIScaleWindowExtEx)(hdc, Xnum, Xdenom, Ynum, Ydenom, lpSize); } BOOL WINAPI extRectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) { int ret; OutTraceDW("Rectangle: hdc=%x xy=(%d,%d)-(%d,%d)\n", hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.MapClient(&nLeftRect, &nTopRect, &nRightRect, &nBottomRect); OutTraceDW("Rectangle: fixed dest=(%d,%d)-(%d,%d)\n", nLeftRect, nTopRect, nRightRect, nBottomRect); } ret=(*pGDIRectangle)(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); if(!ret) OutTraceE("Rectangle: ERROR ret=%x\n", ret); return ret; } int WINAPI extGDISaveDC(HDC hdc) { int ret; ret=(*pGDISaveDC)(hdc); OutTraceDW("GDI.SaveDC: hdc=%x ret=%x\n", hdc, ret); return ret; } BOOL WINAPI extGDIRestoreDC(HDC hdc, int nSavedDC) { BOOL ret; ret=(*pGDIRestoreDC)(hdc, nSavedDC); OutTraceDW("GDI.RestoreDC: hdc=%x nSavedDC=%x ret=%x\n", hdc, nSavedDC, ret); return ret; } /* --------------------------------------------------------------------------- */ // v2.1.75: Hooking for GDI32 CreatePalette, SelectPalette, RealizePalette: // maps the GDI palette to the buffered DirectDraw one. This fixes the screen // output for "Dementia" (a.k.a. "Armed & Delirious"). HPALETTE WINAPI extGDICreatePalette(CONST LOGPALETTE *plpal) { HPALETTE ret; int idx; OutTraceDW("GDI.CreatePalette: plpal=%x version=%x NumEntries=%x\n", plpal, plpal->palVersion, plpal->palNumEntries); ret=(*pGDICreatePalette)(plpal); if(IsDebug){ OutTraceDW("PalEntry[%x]= ", plpal->palNumEntries); for(idx=0; idxpalNumEntries; idx++) OutTraceDW("(%x)", plpal->palPalEntry[idx]); OutTraceDW("\n"); } OutTraceDW("GDI.CreatePalette: hPalette=%x\n", ret); return ret; } HPALETTE hDesktopPalette=NULL; HPALETTE WINAPI extSelectPalette(HDC hdc, HPALETTE hpal, BOOL bForceBackground) { HPALETTE ret; if(hdc==dxw.RealHDC) hdc= dxw.VirtualHDC; ret=(*pGDISelectPalette)(hdc, hpal, bForceBackground); OutTraceDW("GDI.SelectPalette: hdc=%x hpal=%x ForceBackground=%x ret=%x\n", hdc, hpal, bForceBackground, ret); if((OBJ_DC == GetObjectType(hdc)) && (dxw.dwFlags1 & EMULATESURFACE)){ OutTraceDW("GDI.SelectPalette: register desktop palette hpal=%x\n", hpal); hDesktopPalette=hpal; } return ret; } BOOL WINAPI extAnimatePalette(HPALETTE hpal, UINT iStartIndex, UINT cEntries, const PALETTEENTRY *ppe) { // Invoked by "Pharaoh's Ascent 1.4" STOPPER("AnimatePalette"); return TRUE; } UINT WINAPI extRealizePalette(HDC hdc) { UINT ret; extern void mySetPalette(int, int, LPPALETTEENTRY); OutTraceDW("GDI.RealizePalette: hdc=%x\n", hdc); if((OBJ_DC == GetObjectType(hdc)) && (dxw.dwFlags1 & EMULATESURFACE)){ PALETTEENTRY PalEntries[256]; UINT nEntries; nEntries=GetPaletteEntries(hDesktopPalette, 0, 256, PalEntries); mySetPalette(0, nEntries, PalEntries); if(IsDebug) dxw.DumpPalette(nEntries, PalEntries); ret=DD_OK; } else ret=(*pGDIRealizePalette)(hdc); OutTraceDW("GDI.RealizePalette: hdc=%x ret=%x\n", hdc, ret); return ret; } // In emulated mode (when color depyth is 8BPP ?) it may happen that the game // expects to get the requested system palette entries, while the 32BPP screen // returns 0. "Mission Force Cyberstorm" is one of these. Returning the same // value as nEntries, even though lppe is untouched, fixes the problem. static PALETTEENTRY dp[256]={ // default palette, captured on my PC with video mode set to 8BPP {0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x00,0x80,0x00,0x00},{0x80,0x80,0x00,0x00}, {0x00,0x00,0x80,0x00},{0x80,0x00,0x80,0x00},{0x00,0x80,0x80,0x00},{0xc0,0xc0,0xc0,0x00}, {0xa0,0xa0,0xa0,0x00},{0xf0,0xf0,0xf0,0x00},{0xc0,0xdc,0xc0,0x00},{0xa6,0xca,0xf0,0x00}, {0x04,0x04,0x04,0x00},{0x08,0x08,0x08,0x00},{0x0c,0x0c,0x0c,0x00},{0x11,0x11,0x11,0x00}, {0x16,0x16,0x16,0x00},{0x1c,0x1c,0x1c,0x00},{0x22,0x22,0x22,0x00},{0x29,0x29,0x29,0x00}, {0x55,0x55,0x55,0x00},{0x4d,0x4d,0x4d,0x00},{0x42,0x42,0x42,0x00},{0x39,0x39,0x39,0x00}, {0xff,0x7c,0x80,0x00},{0xff,0x50,0x50,0x00},{0xd6,0x00,0x93,0x00},{0xcc,0xec,0xff,0x00}, {0xef,0xd6,0xc6,0x00},{0xe7,0xe7,0xd6,0x00},{0xad,0xa9,0x90,0x00},{0x33,0x00,0x00,0x00}, {0x66,0x00,0x00,0x00},{0x99,0x00,0x00,0x00},{0xcc,0x00,0x00,0x00},{0x00,0x33,0x00,0x00}, {0x33,0x33,0x00,0x00},{0x66,0x33,0x00,0x00},{0x99,0x33,0x00,0x00},{0xcc,0x33,0x00,0x00}, {0xff,0x33,0x00,0x00},{0x00,0x66,0x00,0x00},{0x33,0x66,0x00,0x00},{0x66,0x66,0x00,0x00}, {0x99,0x66,0x00,0x00},{0xcc,0x66,0x00,0x00},{0xff,0x66,0x00,0x00},{0x00,0x99,0x00,0x00}, {0x33,0x99,0x00,0x00},{0x66,0x99,0x00,0x00},{0x99,0x99,0x00,0x00},{0xcc,0x99,0x00,0x00}, {0xff,0x99,0x00,0x00},{0x00,0xcc,0x00,0x00},{0x33,0xcc,0x00,0x00},{0x66,0xcc,0x00,0x00}, {0x99,0xcc,0x00,0x00},{0xcc,0xcc,0x00,0x00},{0xff,0xcc,0x00,0x00},{0x66,0xff,0x00,0x00}, {0x99,0xff,0x00,0x00},{0xcc,0xff,0x00,0x00},{0x00,0x00,0x33,0x00},{0x33,0x00,0x33,0x00}, {0x66,0x00,0x33,0x00},{0x99,0x00,0x33,0x00},{0xcc,0x00,0x33,0x00},{0xff,0x00,0x33,0x00}, {0x00,0x33,0x33,0x00},{0x33,0x33,0x33,0x00},{0x66,0x33,0x33,0x00},{0x99,0x33,0x33,0x00}, {0xcc,0x33,0x33,0x00},{0xff,0x33,0x33,0x00},{0x00,0x66,0x33,0x00},{0x33,0x66,0x33,0x00}, {0x66,0x66,0x33,0x00},{0x99,0x66,0x33,0x00},{0xcc,0x66,0x33,0x00},{0xff,0x66,0x33,0x00}, {0x00,0x99,0x33,0x00},{0x33,0x99,0x33,0x00},{0x66,0x99,0x33,0x00},{0x99,0x99,0x33,0x00}, {0xcc,0x99,0x33,0x00},{0xff,0x99,0x33,0x00},{0x00,0xcc,0x33,0x00},{0x33,0xcc,0x33,0x00}, {0x66,0xcc,0x33,0x00},{0x99,0xcc,0x33,0x00},{0xcc,0xcc,0x33,0x00},{0xff,0xcc,0x33,0x00}, {0x33,0xff,0x33,0x00},{0x66,0xff,0x33,0x00},{0x99,0xff,0x33,0x00},{0xcc,0xff,0x33,0x00}, {0xff,0xff,0x33,0x00},{0x00,0x00,0x66,0x00},{0x33,0x00,0x66,0x00},{0x66,0x00,0x66,0x00}, {0x99,0x00,0x66,0x00},{0xcc,0x00,0x66,0x00},{0xff,0x00,0x66,0x00},{0x00,0x33,0x66,0x00}, {0x33,0x33,0x66,0x00},{0x66,0x33,0x66,0x00},{0x99,0x33,0x66,0x00},{0xcc,0x33,0x66,0x00}, {0xff,0x33,0x66,0x00},{0x00,0x66,0x66,0x00},{0x33,0x66,0x66,0x00},{0x66,0x66,0x66,0x00}, {0x99,0x66,0x66,0x00},{0xcc,0x66,0x66,0x00},{0x00,0x99,0x66,0x00},{0x33,0x99,0x66,0x00}, {0x66,0x99,0x66,0x00},{0x99,0x99,0x66,0x00},{0xcc,0x99,0x66,0x00},{0xff,0x99,0x66,0x00}, {0x00,0xcc,0x66,0x00},{0x33,0xcc,0x66,0x00},{0x99,0xcc,0x66,0x00},{0xcc,0xcc,0x66,0x00}, {0xff,0xcc,0x66,0x00},{0x00,0xff,0x66,0x00},{0x33,0xff,0x66,0x00},{0x99,0xff,0x66,0x00}, {0xcc,0xff,0x66,0x00},{0xff,0x00,0xcc,0x00},{0xcc,0x00,0xff,0x00},{0x00,0x99,0x99,0x00}, {0x99,0x33,0x99,0x00},{0x99,0x00,0x99,0x00},{0xcc,0x00,0x99,0x00},{0x00,0x00,0x99,0x00}, {0x33,0x33,0x99,0x00},{0x66,0x00,0x99,0x00},{0xcc,0x33,0x99,0x00},{0xff,0x00,0x99,0x00}, {0x00,0x66,0x99,0x00},{0x33,0x66,0x99,0x00},{0x66,0x33,0x99,0x00},{0x99,0x66,0x99,0x00}, {0xcc,0x66,0x99,0x00},{0xff,0x33,0x99,0x00},{0x33,0x99,0x99,0x00},{0x66,0x99,0x99,0x00}, {0x99,0x99,0x99,0x00},{0xcc,0x99,0x99,0x00},{0xff,0x99,0x99,0x00},{0x00,0xcc,0x99,0x00}, {0x33,0xcc,0x99,0x00},{0x66,0xcc,0x66,0x00},{0x99,0xcc,0x99,0x00},{0xcc,0xcc,0x99,0x00}, {0xff,0xcc,0x99,0x00},{0x00,0xff,0x99,0x00},{0x33,0xff,0x99,0x00},{0x66,0xcc,0x99,0x00}, {0x99,0xff,0x99,0x00},{0xcc,0xff,0x99,0x00},{0xff,0xff,0x99,0x00},{0x00,0x00,0xcc,0x00}, {0x33,0x00,0x99,0x00},{0x66,0x00,0xcc,0x00},{0x99,0x00,0xcc,0x00},{0xcc,0x00,0xcc,0x00}, {0x00,0x33,0x99,0x00},{0x33,0x33,0xcc,0x00},{0x66,0x33,0xcc,0x00},{0x99,0x33,0xcc,0x00}, {0xcc,0x33,0xcc,0x00},{0xff,0x33,0xcc,0x00},{0x00,0x66,0xcc,0x00},{0x33,0x66,0xcc,0x00}, {0x66,0x66,0x99,0x00},{0x99,0x66,0xcc,0x00},{0xcc,0x66,0xcc,0x00},{0xff,0x66,0x99,0x00}, {0x00,0x99,0xcc,0x00},{0x33,0x99,0xcc,0x00},{0x66,0x99,0xcc,0x00},{0x99,0x99,0xcc,0x00}, {0xcc,0x99,0xcc,0x00},{0xff,0x99,0xcc,0x00},{0x00,0xcc,0xcc,0x00},{0x33,0xcc,0xcc,0x00}, {0x66,0xcc,0xcc,0x00},{0x99,0xcc,0xcc,0x00},{0xcc,0xcc,0xcc,0x00},{0xff,0xcc,0xcc,0x00}, {0x00,0xff,0xcc,0x00},{0x33,0xff,0xcc,0x00},{0x66,0xff,0x99,0x00},{0x99,0xff,0xcc,0x00}, {0xcc,0xff,0xcc,0x00},{0xff,0xff,0xcc,0x00},{0x33,0x00,0xcc,0x00},{0x66,0x00,0xff,0x00}, {0x99,0x00,0xff,0x00},{0x00,0x33,0xcc,0x00},{0x33,0x33,0xff,0x00},{0x66,0x33,0xff,0x00}, {0x99,0x33,0xff,0x00},{0xcc,0x33,0xff,0x00},{0xff,0x33,0xff,0x00},{0x00,0x66,0xff,0x00}, {0x33,0x66,0xff,0x00},{0x66,0x66,0xcc,0x00},{0x99,0x66,0xff,0x00},{0xcc,0x66,0xff,0x00}, {0xff,0x66,0xcc,0x00},{0x00,0x99,0xff,0x00},{0x33,0x99,0xff,0x00},{0x66,0x99,0xff,0x00}, {0x99,0x99,0xff,0x00},{0xcc,0x99,0xff,0x00},{0xff,0x99,0xff,0x00},{0x00,0xcc,0xff,0x00}, {0x33,0xcc,0xff,0x00},{0x66,0xcc,0xff,0x00},{0x99,0xcc,0xff,0x00},{0xcc,0xcc,0xff,0x00}, {0xff,0xcc,0xff,0x00},{0x33,0xff,0xff,0x00},{0x66,0xff,0xcc,0x00},{0x99,0xff,0xff,0x00}, {0xcc,0xff,0xff,0x00},{0xff,0x66,0x66,0x00},{0x66,0xff,0x66,0x00},{0xff,0xff,0x66,0x00}, {0x66,0x66,0xff,0x00},{0xff,0x66,0xff,0x00},{0x66,0xff,0xff,0x00},{0xa5,0x00,0x21,0x00}, {0x5f,0x5f,0x5f,0x00},{0x77,0x77,0x77,0x00},{0x86,0x86,0x86,0x00},{0x96,0x96,0x96,0x00}, {0xcb,0xcb,0xcb,0x00},{0xb2,0xb2,0xb2,0x00},{0xd7,0xd7,0xd7,0x00},{0xdd,0xdd,0xdd,0x00}, {0xe3,0xe3,0xe3,0x00},{0xea,0xea,0xea,0x00},{0xff,0xfb,0xf0,0x00},{0xa0,0xa0,0xa4,0x00}, {0x80,0x80,0x80,0x00},{0xff,0x00,0x00,0x00},{0x00,0xff,0x00,0x00},{0xff,0xff,0x00,0x00}, {0x00,0x00,0xff,0x00},{0xff,0x00,0xff,0x00},{0x00,0xff,0xff,0x00},{0xff,0xff,0xff,0x00} }; UINT WINAPI extGetSystemPaletteEntries(HDC hdc, UINT iStartIndex, UINT nEntries, LPPALETTEENTRY lppe) { int ret; OutTraceDW("GetSystemPaletteEntries: hdc=%x start=%d num=%d\n", hdc, iStartIndex, nEntries); ret=(*pGDIGetSystemPaletteEntries)(hdc, iStartIndex, nEntries, lppe); OutTraceDW("GetSystemPaletteEntries: ret=%d\n", ret); if((ret == 0) && (dxw.dwFlags1 & EMULATESURFACE)) { // use static default data... for(UINT idx=0; idxGetDC device context, // that is a memory device type associated to NULL (desktop) window, through GDI StretchBlt api. So, you shoud compensate // by scaling and offsetting to main window. dxw.MapWindow(&nXDest, &nYDest, &nWidth, &nHeight); } } res=(*pGDIStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWSrc, nHSrc, dwRop); if (IsToScreen) dxw.ShowOverlay(hdcDest); if(!res) OutTraceE("GDI.StretchBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); return res; } BOOL WINAPI extGDIDeleteDC(HDC hdc) { BOOL res; OutTraceDW("GDI.DeleteDC: hdc=%x\n", hdc); res=(*pGDIDeleteDC)(hdc); if(!res) OutTraceE("GDI.DeleteDC: ERROR err=%d at %d\n", GetLastError(), __LINE__); return res; } HFONT WINAPI extCreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet, DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCTSTR lpszFace) { OutTraceDW("CreateFont: h=%d w=%d face=\"%s\"\n", nHeight, nWidth, lpszFace); if(dxw.dwFlags1 & FIXTEXTOUT) { if(nHeight > 0) dxw.MapClient(&nWidth, &nHeight); else { nHeight= -nHeight; dxw.MapClient(&nWidth, &nHeight); nHeight= -nHeight; } } return (*pGDICreateFont)(nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet, fdwOutputPrecision, fdwClipPrecision, NONANTIALIASED_QUALITY, fdwPitchAndFamily, lpszFace); } // CreateFontIndirect hook routine to avoid font aliasing that prevents reverse blitting working on palettized surfaces HFONT WINAPI extCreateFontIndirect(const LOGFONT* lplf) { LOGFONT lf; HFONT retHFont; OutTraceDW("CreateFontIndirect: h=%d w=%d face=\"%s\"\n", lplf->lfHeight, lplf->lfWidth, lplf->lfFaceName); memcpy((char *)&lf, (char *)lplf, sizeof(LOGFONT)); lf.lfQuality=NONANTIALIASED_QUALITY; if(dxw.dwFlags1 & FIXTEXTOUT) { if(lf.lfHeight > 0) dxw.MapClient((int *)&lf.lfWidth, (int *)&lf.lfHeight); else { lf.lfHeight= -lf.lfHeight; dxw.MapClient((int *)&lf.lfWidth, (int *)&lf.lfHeight); lf.lfHeight= -lf.lfHeight; } } retHFont=((*pGDICreateFontIndirect)(&lf)); if(retHFont) OutTraceDW("CreateFontIndirect: hfont=%x\n", retHFont); else OutTraceDW("CreateFontIndirect: error=%d at %d\n", GetLastError(), __LINE__); return retHFont; } BOOL WINAPI extSetDeviceGammaRamp(HDC hDC, LPVOID lpRamp) { BOOL ret; OutTraceDW("SetDeviceGammaRamp: hdc=%x\n", hDC); if(dxw.dwFlags2 & DISABLEGAMMARAMP) { OutTraceDW("SetDeviceGammaRamp: SUPPRESSED\n"); return TRUE; } ret=(*pGDISetDeviceGammaRamp)(hDC, lpRamp); if(!ret) OutTraceE("SetDeviceGammaRamp: ERROR err=%d\n", GetLastError()); return ret; } BOOL WINAPI extGetDeviceGammaRamp(HDC hDC, LPVOID lpRamp) { BOOL ret; OutTraceDW("GetDeviceGammaRamp: hdc=%x\n", hDC); ret=(*pGDIGetDeviceGammaRamp)(hDC, lpRamp); if(!ret) OutTraceE("GetDeviceGammaRamp: ERROR err=%d\n", GetLastError()); return ret; } int WINAPI extGetClipBox(HDC hdc, LPRECT lprc) { // v2.02.31: needed in "Imperialism II" to avoid blit clipping int ret; char *sRetCodes[4]={"ERROR", "NULLREGION", "SIMPLEREGION", "COMPLEXREGION"}; OutTraceDW("GetClipBox: hdc=%x\n", hdc); ret=(*pGDIGetClipBox)(hdc, lprc); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc)) && (ret!=ERROR)){ OutTraceDW("GetClipBox: scaling main win coordinates (%d,%d)-(%d,%d)\n", lprc->left, lprc->top, lprc->right, lprc->bottom); // current implementation is NOT accurate, since it always returns the whole // virtual desktop area as the current clipbox...!!! *lprc=dxw.GetScreenRect(); } OutTraceDW("GetClipBox: ret=%x(%s) rect=(%d,%d)-(%d,%d)\n", ret, sRetCodes[ret], lprc->left, lprc->top, lprc->right, lprc->bottom); return ret; } int WINAPI extGetRgnBox(HRGN hrgn, LPRECT lprc) { int ret; OutTraceDW("GetRgnBox: hrgn=%x\n", hrgn); ret=(*pGetRgnBox)(hrgn, lprc); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hrgn)) && (ret!=ERROR)){ OutTraceDW("GetRgnBox: scaling main win coordinates (%d,%d)-(%d,%d)\n", lprc->left, lprc->top, lprc->right, lprc->bottom); dxw.UnmapClient(lprc); } OutTraceDW("GetRgnBox: ret=%x(%s) rect=(%d,%d)-(%d,%d)\n", ret, ExplainRegionType(ret), lprc->left, lprc->top, lprc->right, lprc->bottom); return ret; } BOOL WINAPI extPolyline(HDC hdc, const POINT *lppt, int cPoints) { BOOL ret; if(IsTraceDDRAW){ int i; OutTrace("Polyline: hdc=%x cPoints=%d pt=", hdc, cPoints); for(i=0; ibmiHeader); OutTraceDW("SetDIBitsToDevice: BitmapInfo dim=(%dx%d) Planes=%d BPP=%d Compression=%x SizeImage=%x\n", bmi->biWidth, bmi->biHeight, bmi->biPlanes, bmi->biBitCount, bmi->biCompression, bmi->biSizeImage); if (dxw.IsFullScreen() && dxw.IsVirtual(hdc)){ int X, Y; X=XDest+dxw.VirtualOffsetX; Y=YDest+dxw.VirtualOffsetY; OutTraceDW("SetDIBitsToDevice: virtual pos=(%d,%d)+(%d+%d)=(%d,%d)\n", XDest, YDest, dxw.VirtualOffsetX, dxw.VirtualOffsetY, X, Y); ret=(*pSetDIBitsToDevice)(hdc, X, Y, dwWidth, dwHeight, XSrc, YSrc, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse); if(!ret || (ret==GDI_ERROR)) OutTraceE("SetDIBitsToDevice: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } //else if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ DWORD OrigWidth, OrigHeight; int OrigXDest, OrigYDest; OrigWidth=dwWidth; OrigHeight=dwHeight; OrigXDest=XDest; OrigYDest=YDest; dxw.MapClient(&XDest, &YDest, (int *)&dwWidth, (int *)&dwHeight); OutTraceDW("SetDIBitsToDevice: fixed dest=(%d,%d)-(%dx%d)\n", XDest, YDest, dwWidth, dwHeight); HDC hTempDc; HBITMAP hbmPic; if(!(hTempDc=CreateCompatibleDC(hdc))) OutTraceE("CreateCompatibleDC: ERROR err=%d at=%d\n", GetLastError(), __LINE__); // tricky part: CreateCompatibleBitmap is needed to set the dc size, but it has to be performed // against hdc to set for color depth, then selected (through SelectObject) against the temporary // dc to assign the needed size and color space to the temporary dc. if(!(hbmPic=CreateCompatibleBitmap(hdc, OrigWidth, OrigHeight))) OutTraceE("CreateCompatibleBitmap: ERROR err=%d at=%d\n", GetLastError(), __LINE__); if(!SelectObject(hTempDc, hbmPic)) OutTraceE("SelectObject: ERROR err=%d at=%d\n", GetLastError(), __LINE__); if(!(*pSetDIBitsToDevice)(hTempDc, 0, 0, OrigWidth, OrigHeight, XSrc, YSrc, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse)) OutTraceE("SetDIBitsToDevice: ERROR err=%d at=%d\n", GetLastError(), __LINE__); // v2.02.94: set HALFTONE stretching. Fixes "Celtic Kings Rage of War" SetStretchBltMode(hdc,HALFTONE); if(!(ret=(*pGDIStretchBlt)(hdc, XDest, YDest, dwWidth, dwHeight, hTempDc, 0, 0, OrigWidth, OrigHeight, SRCCOPY))) OutTraceE("StretchBlt: ERROR err=%d at=%d\n", GetLastError(), __LINE__); if(!(DeleteObject(hbmPic))) // v2.02.32 - avoid resource leakage OutTraceE("DeleteObject: ERROR err=%d at=%d\n", GetLastError(), __LINE__); if(!(DeleteDC(hTempDc))) OutTraceE("DeleteDC: ERROR err=%d at=%d\n", GetLastError(), __LINE__); } else{ ret=(*pSetDIBitsToDevice)(hdc, XDest, YDest, dwWidth, dwHeight, XSrc, YSrc, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse); } if(!ret || (ret==GDI_ERROR)) OutTraceE("SetDIBitsToDevice: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } //HBITMAP WINAPI extCreateCompatibleBitmap(HDC hdc, int nWidth, int nHeight) //{ // HBITMAP ret; // OutTraceDW("CreateCompatibleBitmap: hdc=%x size=(%d,%d)\n", // hdc, nWidth, nHeight); // // if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ // dxw.MapClient(&nWidth, &nHeight); // OutTraceDW("CreateCompatibleBitmap: fixed size=(%d,%d)\n", nWidth, nHeight); // } // // ret=(*pCreateCompatibleBitmap)(hdc, nWidth, nHeight); // if(!ret) OutTraceE("CreateCompatibleBitmap: ERROR ret=%x err=%d\n", ret, GetLastError()); // return ret; //} COLORREF WINAPI extSetPixel(HDC hdc, int X, int Y, COLORREF crColor) { COLORREF ret; OutTraceDW("SetPixel: hdc=%x color=%x point=(%d,%d)\n", hdc, crColor, X, Y); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.MapClient(&X, &Y); OutTraceDW("SetPixel: fixed pos=(%d,%d)\n", X, Y); } ret=(*pSetPixel)(hdc, X, Y, crColor); // both 0x00000000 and 0xFFFFFFFF are legitimate colors and therefore valid return codes... //if(ret==GDI_ERROR) OutTraceE("SetPixel: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } BOOL WINAPI extEllipse(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) { int ret; OutTraceDW("Ellipse: hdc=%x rect=(%d,%d)-(%d,%d)\n", hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.MapClient(&nLeftRect, &nTopRect, &nRightRect, &nBottomRect); OutTraceDW("Ellipse: fixed dest=(%d,%d)-(%d,%d)\n", nLeftRect, nTopRect, nRightRect, nBottomRect); } ret=(*pEllipse)(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); if(!ret) OutTraceE("Ellipse: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } BOOL WINAPI extPolygon(HDC hdc, const POINT *lpPoints, int cCount) { BOOL ret; if(IsTraceDDRAW){ int i; OutTrace("Polygon: hdc=%x cCount=%d pt=", hdc, cCount); for(i=0; ileft, lprc->top, lprc->right, lprc->bottom); if (dxw.IsFullScreen()){ dxw.MapClient((RECT *)lprc); OutTraceDW("CreateEllipticRgnIndirect: fixed rect=(%d,%d)-(%d,%d)\n", lprc->left, lprc->top, lprc->right, lprc->bottom); } ret=(*pCreateEllipticRgnIndirect)(lprc); if(!ret) OutTraceE("CreateEllipticRgnIndirect: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } HRGN WINAPI extCreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) { HRGN ret; OutTraceDW("CreateRectRgn: rect=(%d,%d)-(%d,%d)\n", nLeftRect, nTopRect, nRightRect, nBottomRect); if (dxw.IsFullScreen()){ dxw.MapClient(&nLeftRect, &nTopRect, &nRightRect, &nBottomRect); OutTraceDW("CreateRectRgn: fixed rect=(%d,%d)-(%d,%d)\n", nLeftRect, nTopRect, nRightRect, nBottomRect); } ret=(*pCreateRectRgn)(nLeftRect, nTopRect, nRightRect, nBottomRect); if(!ret) OutTraceE("CreateRectRgn: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } HRGN WINAPI extCreateRectRgnIndirect(const RECT *lprc) { HRGN ret; OutTraceDW("CreateRectRgnIndirect: rect=(%d,%d)-(%d,%d)\n", lprc->left, lprc->top, lprc->right, lprc->bottom); if (dxw.IsFullScreen()){ dxw.MapClient((RECT *)lprc); OutTraceDW("CreateRectRgnIndirect: fixed rect=(%d,%d)-(%d,%d)\n", lprc->left, lprc->top, lprc->right, lprc->bottom); } ret=(*pCreateRectRgnIndirect)(lprc); if(!ret) OutTraceE("CreateRectRgnIndirect: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } HRGN WINAPI extCreatePolygonRgn(const POINT *lpPoints, int cPoints, int fnPolyFillMode) { HRGN ret; if(IsTraceDDRAW){ int i; OutTrace("CreatePolygonRgn: PolyFillMode=%x cCount=%d pt=", fnPolyFillMode, cPoints); for(i=0; ix, lpPoint->y); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.UnmapClient(lpPoint); OutTraceDW("SetViewportOrgEx: fixed previous ViewPort=(%d,%d)\n", lpPoint->x, lpPoint->y); } } if(!ret) OutTraceE("SetViewportOrgEx: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } BOOL WINAPI extSetViewportExtEx(HDC hdc, int nXExtent, int nYExtent, LPSIZE lpSize) { BOOL ret; OutTraceDW("SetViewportExtEx: hdc=%x ext=(%d,%d)\n", hdc, nXExtent, nYExtent); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.MapClient(&nXExtent, &nYExtent); OutTraceDW("SetViewportExtEx: fixed ext=(%d,%d)\n", nXExtent, nYExtent); } ret=(*pSetViewportExtEx)(hdc, nXExtent, nYExtent, lpSize); if(ret && lpSize) { OutTraceDW("SetViewportExtEx: previous ext=(%d,%d)\n", lpSize->cx, lpSize->cy); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.UnmapClient((LPPOINT)lpSize); OutTraceDW("SetViewportExtEx: fixed previous ext=(%d,%d)\n", lpSize->cx, lpSize->cy); } } if(!ret) OutTraceE("SetViewportExtEx: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } BOOL WINAPI extGetViewportOrgEx(HDC hdc, LPPOINT lpPoint) { BOOL ret; OutTraceDW("GetViewportOrgEx: hdc=%x\n", hdc); if(dxw.IsVirtual(hdc)) { lpPoint->x = dxw.VirtualOffsetX; lpPoint->y = dxw.VirtualOffsetY; return TRUE; } ret=(*pGetViewportOrgEx)(hdc, lpPoint); if(ret) { OutTraceDW("GetViewportOrgEx: ViewPort=(%d,%d)\n", lpPoint->x, lpPoint->y); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.UnmapClient(lpPoint); OutTraceDW("GetViewportOrgEx: fixed ViewPort=(%d,%d)\n", lpPoint->x, lpPoint->y); } } if(!ret) OutTraceE("GetViewportOrgEx: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } BOOL WINAPI extGetWindowOrgEx(HDC hdc, LPPOINT lpPoint) { BOOL ret; OutTraceDW("GetWindowOrgEx: hdc=%x\n", hdc); ret=(*pGetWindowOrgEx)(hdc, lpPoint); if(ret) { OutTraceDW("GetWindowOrgEx: ViewPort=(%d,%d)\n", lpPoint->x, lpPoint->y); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.UnmapClient(lpPoint); OutTraceDW("GetWindowOrgEx: fixed ViewPort=(%d,%d)\n", lpPoint->x, lpPoint->y); } } if(!ret) OutTraceE("GetWindowOrgEx: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } BOOL WINAPI extSetWindowOrgEx(HDC hdc, int X, int Y, LPPOINT lpPoint) { BOOL ret; OutTraceDW("SetWindowOrgEx: hdc=%x pos=(%d,%d)\n", hdc, X, Y); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.MapClient(&X, &Y); OutTraceDW("SetWindowOrgEx: fixed pos=(%d,%d)\n", X, Y); } ret=(*pSetWindowOrgEx)(hdc, X, Y, lpPoint); if(ret && lpPoint) { OutTraceDW("SetWindowOrgEx: previous ViewPort=(%d,%d)\n", lpPoint->x, lpPoint->y); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.UnmapClient(lpPoint); OutTraceDW("SetWindowOrgEx: fixed previous ViewPort=(%d,%d)\n", lpPoint->x, lpPoint->y); } } if(!ret) OutTraceE("SetWindowOrgEx: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } BOOL WINAPI extGetCurrentPositionEx(HDC hdc, LPPOINT lpPoint) { BOOL ret; OutTraceDW("GetCurrentPositionEx: hdc=%x\n", hdc); ret=(*pGetCurrentPositionEx)(hdc, lpPoint); if(ret) { OutTraceDW("GetCurrentPositionEx: pos=(%d,%d)\n", lpPoint->x, lpPoint->y); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.UnmapClient(lpPoint); OutTraceDW("GetCurrentPositionEx: fixed pos=(%d,%d)\n", lpPoint->x, lpPoint->y); } } if(!ret) OutTraceE("GetCurrentPositionEx: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } BOOL WINAPI extCreateScalableFontResourceA(DWORD fdwHidden, LPCTSTR lpszFontRes, LPCTSTR lpszFontFile, LPCTSTR lpszCurrentPath) { BOOL res; OutTraceDW("CreateScalableFontResource: hidden=%d FontRes=\"%s\" FontFile=\"%s\" CurrentPath=\"%s\"\n", fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath); if(dxw.dwFlags3 & FONTBYPASS) return TRUE; res=(*pCreateScalableFontResourceA)(fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath); if(!res) OutTraceE("CreateScalableFontResource: ERROR err=%d at=%d\n", GetLastError(), __LINE__); return res; } BOOL WINAPI extCreateScalableFontResourceW(DWORD fdwHidden, LPCWSTR lpszFontRes, LPCWSTR lpszFontFile, LPCWSTR lpszCurrentPath) { BOOL res; OutTraceDW("CreateScalableFontResource: hidden=%d FontRes=\"%ls\" FontFile=\"%ls\" CurrentPath=\"%ls\"\n", fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath); if(dxw.dwFlags3 & FONTBYPASS) return TRUE; res=(*pCreateScalableFontResourceW)(fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath); if(!res) OutTraceE("CreateScalableFontResource: ERROR err=%d at=%d\n", GetLastError(), __LINE__); return res; } int WINAPI extAddFontResourceA(LPCTSTR lpszFontFile) { BOOL res; OutTraceDW("AddFontResource: FontFile=\"%s\"\n", lpszFontFile); if(dxw.dwFlags3 & FONTBYPASS) { OutTraceDW("AddFontResource: SUPPRESSED FontFile=\"%s\"\n", lpszFontFile); return TRUE; } res=(*pAddFontResourceA)(lpszFontFile); if(!res) OutTraceE("AddFontResource: ERROR err=%d at=%d\n", GetLastError(), __LINE__); return res; } int WINAPI extAddFontResourceW(LPCWSTR lpszFontFile) { BOOL res; OutTraceDW("AddFontResource: FontFile=\"%ls\"\n", lpszFontFile); if(dxw.dwFlags3 & FONTBYPASS) { OutTraceDW("AddFontResource: SUPPRESSED FontFile=\"%ls\"\n", lpszFontFile); return TRUE; } res=(*pAddFontResourceW)(lpszFontFile); if(!res) OutTraceE("AddFontResource: ERROR err=%d at=%d\n", GetLastError(), __LINE__); return res; } UINT WINAPI extSetSystemPaletteUse(HDC hdc, UINT uUsage) { //BOOL res; OutTraceDW("SetSystemPaletteUse: hdc=%x Usage=%x(%s)\n", hdc, uUsage, ExplainPaletteUse(uUsage)); return SYSPAL_NOSTATIC256; } //BEWARE: SetPixelFormat must be issued on the same hdc used by OpenGL wglCreateContext, otherwise // a failure err=2000 ERROR INVALID PIXEL FORMAT occurs!! BOOL WINAPI extGDISetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd) { BOOL res; OutTraceDW("SetPixelFormat: hdc=%x PixelFormat=%d Flags=%x PixelType=%x(%s) ColorBits=%d RGBdepth=(%d,%d,%d) RGBshift=(%d,%d,%d)\n", hdc, iPixelFormat, ppfd->dwFlags, ppfd->iPixelType, ppfd->iPixelType?"PFD_TYPE_COLORINDEX":"PFD_TYPE_RGBA", ppfd->cColorBits, ppfd->cRedBits, ppfd->cGreenBits, ppfd->cBlueBits, ppfd->cRedShift, ppfd->cGreenShift, ppfd->cBlueShift); //if(dxw.dwFlags1 & EMULATESURFACE) { // OutTraceDW("SetPixelFormat: prevent pixelformat change\n"); // return TRUE; //} if(dxw.IsDesktop(WindowFromDC(hdc))){ HDC oldhdc = hdc; hdc=(*pGDIGetDC)(dxw.GethWnd()); OutTraceDW("SetPixelFormat: remapped desktop hdc=%x->%x hWnd=%x\n", oldhdc, hdc, dxw.GethWnd()); } res=(*pGDISetPixelFormat)(hdc, iPixelFormat, ppfd); dxw.ActualPixelFormat.dwRGBBitCount = ppfd->cColorBits; if(!res) OutTraceE("SetPixelFormat: ERROR err=%d at=%d\n", GetLastError(), __LINE__); return res; } int WINAPI extGDIGetPixelFormat(HDC hdc) { int res; OutTraceDW("GetPixelFormat: hdc=%x\n", hdc); if(dxw.IsDesktop(WindowFromDC(hdc))){ HDC oldhdc = hdc; hdc=(*pGDIGetDC)(dxw.GethWnd()); OutTraceDW("GetPixelFormat: remapped desktop hdc=%x->%x hWnd=%x\n", oldhdc, hdc, dxw.GethWnd()); } res=(*pGDIGetPixelFormat)(hdc); if(!res) OutTraceE("GetPixelFormat: ERROR err=%d at=%d\n", GetLastError(), __LINE__); else OutTraceDW("GetPixelFormat: res=%d\n", res); return res; } int WINAPI extChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd) { int res; OutTraceDW("ChoosePixelFormat: hdc=%x Flags=%x PixelType=%x(%s) ColorBits=%d RGBdepth=(%d,%d,%d) RGBshift=(%d,%d,%d)\n", hdc, ppfd->dwFlags, ppfd->iPixelType, ppfd->iPixelType?"PFD_TYPE_COLORINDEX":"PFD_TYPE_RGBA", ppfd->cColorBits, ppfd->cRedBits, ppfd->cGreenBits, ppfd->cBlueBits, ppfd->cRedShift, ppfd->cGreenShift, ppfd->cBlueShift); //PIXELFORMATDESCRIPTOR myppfd; //memcpy(&myppfd, ppfd, sizeof(PIXELFORMATDESCRIPTOR)); //myppfd.dwFlags |= PFD_DRAW_TO_WINDOW; //res=(*pChoosePixelFormat)(hdc, &myppfd); res=(*pChoosePixelFormat)(hdc, ppfd); if(!res) OutTraceE("ChoosePixelFormat: ERROR err=%d at=%d\n", GetLastError(), __LINE__); else OutTraceDW("ChoosePixelFormat: res=%d\n", res); return res; } int WINAPI extDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd) { int res; OutTraceDW("DescribePixelFormat: hdc=%x PixelFormat=%d Bytes=%d\n", hdc, iPixelFormat, nBytes); res=(*pDescribePixelFormat)(hdc, iPixelFormat, nBytes, ppfd); if(!res){ OutTraceE("DescribePixelFormat: ERROR err=%d at=%d\n", GetLastError(), __LINE__); return res; } if (ppfd && nBytes==sizeof(PIXELFORMATDESCRIPTOR)){ OutTraceDW("DescribePixelFormat: res=%d Flags=%x PixelType=%x(%s) ColorBits=%d RGBdepth=(%d,%d,%d) RGBshift=(%d,%d,%d)\n", res, ppfd->dwFlags, ppfd->iPixelType, ppfd->iPixelType?"PFD_TYPE_COLORINDEX":"PFD_TYPE_RGBA", ppfd->cColorBits, ppfd->cRedBits, ppfd->cGreenBits, ppfd->cBlueBits, ppfd->cRedShift, ppfd->cGreenShift, ppfd->cBlueShift); } else { OutTraceDW("DescribePixelFormat: res=%d\n", res); } return res; } DWORD WINAPI extGetObjectType(HGDIOBJ h) { DWORD res; res=(*pGetObjectType)(h); OutTraceDW("GetObjectType: h=%x type=%x\n", h, res); if(h==dxw.VirtualHDC) { OutTraceDW("GetObjectType: REMAP h=%x type=%x->%x\n", h, res, OBJ_DC); res=OBJ_DC; } return res; } extern BOOL gFixed; BOOL WINAPI extExtTextOutA(HDC hdc, int X, int Y, UINT fuOptions, const RECT *lprc, LPCSTR lpString, UINT cbCount, const INT *lpDx) { RECT rc; if(IsTraceDW){ OutTrace("ExtTextOutA: hdc=%x pos=(%d,%d) String=\"%s\" rect=", hdc, X, Y, lpString); if(lprc) OutTrace("(%d,%d)-(%d,%d)\n", lprc->left, lprc->top, lprc->right, lprc->bottom); else OutTrace("NULL\n"); } if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc)) && !gFixed){ dxw.MapClient(&X, &Y); if(lprc) dxw.MapClient(&rc); OutTraceDW("ExtTextOutA: fixed pos=(%d,%d)\n", X, Y); } if(lprc) return (*pExtTextOutA)(hdc, X, Y, fuOptions, &rc, lpString, cbCount, lpDx); else return (*pExtTextOutA)(hdc, X, Y, fuOptions, NULL, lpString, cbCount, lpDx); } BOOL WINAPI extExtTextOutW(HDC hdc, int X, int Y, UINT fuOptions, const RECT *lprc, LPCWSTR lpString, UINT cbCount, const INT *lpDx) { RECT rc; if(IsTraceDW){ OutTrace("ExtTextOutW: hdc=%x pos=(%d,%d) String=\"%ls\" rect=", hdc, X, Y, lpString); if(lprc) OutTrace("(%d,%d)-(%d,%d)\n", lprc->left, lprc->top, lprc->right, lprc->bottom); else OutTrace("NULL\n"); } if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc)) && !gFixed){ dxw.MapClient(&X, &Y); if(lprc) dxw.MapClient(&rc); OutTraceDW("ExtTextOutW: fixed pos=(%d,%d)\n", X, Y); } if(lprc) return (*pExtTextOutW)(hdc, X, Y, fuOptions, &rc, lpString, cbCount, lpDx); else return (*pExtTextOutW)(hdc, X, Y, fuOptions, NULL, lpString, cbCount, lpDx); } #if 0 // unhooked, since quite surprisingly all rectangles showed properly scaled already in RollerCoaster Tycoon !! DWORD WINAPI extGetRegionData(HRGN hRgn, DWORD dwCount, LPRGNDATA lpRgnData) { DWORD ret; RECT *data; ret=(*pGetRegionData)(hRgn, dwCount, lpRgnData); if(IsDebug){ OutTrace("GetRegionData: hRgn=%x count=%d RgnData=%x ret=%d\n", hRgn, dwCount, lpRgnData, ret); if(lpRgnData && dwCount){ OutTrace("GetRegionData: size=%d type=%x(%s) count=%d size=%d rect=(%d,%d)-(%d,%d)\n", lpRgnData->rdh.dwSize, lpRgnData->rdh.iType, (lpRgnData->rdh.iType==RDH_RECTANGLES ? "RDH_RECTANGLES" : "unknown"), lpRgnData->rdh.nCount, lpRgnData->rdh.nRgnSize, lpRgnData->rdh.rcBound.left, lpRgnData->rdh.rcBound.top, lpRgnData->rdh.rcBound.right, lpRgnData->rdh.rcBound.bottom); data=(RECT *)lpRgnData->Buffer; for(DWORD i=0; irdh.nCount; i++) OutTrace("GetRegionData: item=%i rect=(%d,%d)-(%d,%d)\n", i, data[i].left, data[i].top, data[i].right, data[i].bottom); } } if(dxw.IsFullScreen() && lpRgnData && dwCount){ dxw.UnmapClient(&(lpRgnData->rdh.rcBound)); data=(RECT *)lpRgnData->Buffer; for(DWORD i=0; irdh.nCount; i++) dxw.UnmapClient(&(data[i])); if(IsDebug){ OutTrace("GetRegionData: FIXED rect=(%d,%d)-(%d,%d)\n", lpRgnData->rdh.rcBound.left, lpRgnData->rdh.rcBound.top, lpRgnData->rdh.rcBound.right, lpRgnData->rdh.rcBound.bottom); data=(RECT *)lpRgnData->Buffer; for(DWORD i=0; irdh.nCount; i++) OutTrace("GetRegionData: FIXED item=%i rect=(%d,%d)-(%d,%d)\n", i, data[i].left, data[i].top, data[i].right, data[i].bottom); } } return ret; } #endif