#include "dxwnd.h" #include "dxwcore.hpp" #include "syslibs.h" #include "hddraw.h" #include "dxhook.h" #include "dxhelper.h" static HookEntry_Type Hooks[]={ {"GetDeviceCaps", (FARPROC)GetDeviceCaps, (FARPROC *)&pGDIGetDeviceCaps, (FARPROC)extGetDeviceCaps}, {"TextOutA", (FARPROC)TextOutA, (FARPROC *)&pGDITextOutA, (FARPROC)extTextOutA}, {"ScaleWindowExtEx", (FARPROC)ScaleWindowExtEx, (FARPROC *)&pGDIScaleWindowExtEx, (FARPROC)extScaleWindowExtEx}, {"Rectangle", (FARPROC)Rectangle, (FARPROC *)&pGDIRectangle, (FARPROC)extRectangle}, {"SaveDC", (FARPROC)SaveDC, (FARPROC *)&pGDISaveDC, (FARPROC)extGDISaveDC}, {"RestoreDC", (FARPROC)RestoreDC, (FARPROC *)&pGDIRestoreDC, (FARPROC)extGDIRestoreDC}, {"CreatePalette", (FARPROC)CreatePalette, (FARPROC *)&pGDICreatePalette, (FARPROC)extGDICreatePalette}, {"SelectPalette", (FARPROC)SelectPalette, (FARPROC *)&pGDISelectPalette, (FARPROC)extSelectPalette}, {"RealizePalette", (FARPROC)RealizePalette, (FARPROC *)&pGDIRealizePalette, (FARPROC)extRealizePalette}, {"GetSystemPaletteEntries", (FARPROC)GetSystemPaletteEntries, (FARPROC *)&pGDIGetSystemPaletteEntries, (FARPROC)extGetSystemPaletteEntries}, {"GetClipBox", (FARPROC)NULL, (FARPROC *)&pGDIGetClipBox, (FARPROC)extGetClipBox}, {"Polyline", (FARPROC)NULL, (FARPROC *)&pPolyline, (FARPROC)extPolyline}, {"PolyBezierTo", (FARPROC)NULL, (FARPROC *)&pPolyBezierTo, (FARPROC)extPolyBezierTo}, {"PolylineTo", (FARPROC)NULL, (FARPROC *)&pPolylineTo, (FARPROC)extPolylineTo}, {"PolyDraw", (FARPROC)NULL, (FARPROC *)&pPolyDraw, (FARPROC)extPolyDraw}, {"MoveToEx", (FARPROC)NULL, (FARPROC *)&pMoveToEx, (FARPROC)extMoveToEx}, {"ArcTo", (FARPROC)NULL, (FARPROC *)&pArcTo, (FARPROC)extArcTo}, {"LineTo", (FARPROC)NULL, (FARPROC *)&pLineTo, (FARPROC)extLineTo}, {"StretchDIBits", (FARPROC)StretchDIBits, (FARPROC *)&pStretchDIBits, (FARPROC)extStretchDIBits}, {"SetDIBitsToDevice", (FARPROC)NULL, (FARPROC *)&pSetDIBitsToDevice, (FARPROC)extSetDIBitsToDevice}, //{"CreateCompatibleBitmap", (FARPROC)NULL, (FARPROC *)&pCreateCompatibleBitmap, (FARPROC)extCreateCompatibleBitmap}, {"SetPixel", (FARPROC)NULL, (FARPROC *)&pSetPixel, (FARPROC)extSetPixel}, {"Ellipse", (FARPROC)NULL, (FARPROC *)&pEllipse, (FARPROC)extEllipse}, {"Polygon", (FARPROC)NULL, (FARPROC *)&pPolygon, (FARPROC)extPolygon}, {"Arc", (FARPROC)NULL, (FARPROC *)&pArc, (FARPROC)extArc}, {"CreateEllipticRgn", (FARPROC)NULL, (FARPROC *)&pCreateEllipticRgn, (FARPROC)extCreateEllipticRgn}, {"CreateEllipticRgnIndirect", (FARPROC)NULL, (FARPROC *)&pCreateEllipticRgnIndirect, (FARPROC)extCreateEllipticRgnIndirect}, {"CreateRectRgn", (FARPROC)NULL, (FARPROC *)&pCreateRectRgn, (FARPROC)extCreateRectRgn}, {"CreateRectRgnIndirect", (FARPROC)NULL, (FARPROC *)&pCreateRectRgnIndirect, (FARPROC)extCreateRectRgnIndirect}, {"CreatePolygonRgn", (FARPROC)NULL, (FARPROC *)&pCreatePolygonRgn, (FARPROC)extCreatePolygonRgn}, {"DrawTextA", (FARPROC)NULL, (FARPROC *)&pDrawText, (FARPROC)extDrawText}, {"DrawTextExA", (FARPROC)NULL, (FARPROC *)&pDrawTextEx, (FARPROC)extDrawTextEx}, {"MaskBlt", (FARPROC)NULL, (FARPROC *)&pMaskBlt, (FARPROC)extMaskBlt}, {0, NULL, 0, 0} // terminator }; static HookEntry_Type DDHooks[]={ {"CreateCompatibleDC", (FARPROC)CreateCompatibleDC, (FARPROC *)&pGDICreateCompatibleDC, (FARPROC)extDDCreateCompatibleDC}, {"DeleteDC", (FARPROC)DeleteDC, (FARPROC *)&pGDIDeleteDC, (FARPROC)extDDDeleteDC}, {"CreateDCA", (FARPROC)CreateDCA, (FARPROC *)&pGDICreateDC, (FARPROC)extDDCreateDC}, {"BitBlt", (FARPROC)BitBlt, (FARPROC *)&pGDIBitBlt, (FARPROC)extDDBitBlt}, {"StretchBlt", (FARPROC)StretchBlt, (FARPROC *)&pGDIStretchBlt, (FARPROC)extDDStretchBlt}, // {"PatBlt", (FARPROC)PatBlt, (FARPROC *)&pGDIPatBlt, (FARPROC)extDDPatBlt}, // missing one ... {0, NULL, 0, 0} // terminator }; static HookEntry_Type GDIHooks[]={ {"CreateCompatibleDC", (FARPROC)CreateCompatibleDC, (FARPROC *)&pGDICreateCompatibleDC, (FARPROC)extGDICreateCompatibleDC}, {"DeleteDC", (FARPROC)DeleteDC, (FARPROC *)&pGDIDeleteDC, (FARPROC)extGDIDeleteDC}, {"CreateDCA", (FARPROC)CreateDCA, (FARPROC *)&pGDICreateDC, (FARPROC)extGDICreateDC}, {"BitBlt", (FARPROC)BitBlt, (FARPROC *)&pGDIBitBlt, (FARPROC)extGDIBitBlt}, {"StretchBlt", (FARPROC)StretchBlt, (FARPROC *)&pGDIStretchBlt, (FARPROC)extGDIStretchBlt}, {"PatBlt", (FARPROC)PatBlt, (FARPROC *)&pGDIPatBlt, (FARPROC)extGDIPatBlt}, {0, NULL, 0, 0} // terminator }; static HookEntry_Type EmuHooks[]={ //{"SetTextColor", (FARPROC)SetTextColor, (FARPROC *)&pGDISetTextColor, (FARPROC)extSetTextColor}, //{"SetBkColor", (FARPROC)SetBkColor, (FARPROC *)&pGDISetBkColor, (FARPROC)extSetBkColor}, {"CreateFontA", (FARPROC)CreateFont, (FARPROC *)&pGDICreateFont, (FARPROC)extCreateFont}, {"CreateFontIndirectA", (FARPROC)CreateFontIndirectA, (FARPROC *)&pGDICreateFontIndirect, (FARPROC)extCreateFontIndirect}, {0, NULL, 0, 0} // terminator }; static HookEntry_Type GammaHooks[]={ {"SetDeviceGammaRamp", (FARPROC)SetDeviceGammaRamp, (FARPROC *)&pGDISetDeviceGammaRamp, (FARPROC)extSetDeviceGammaRamp}, {"GetDeviceGammaRamp", (FARPROC)GetDeviceGammaRamp, (FARPROC *)&pGDIGetDeviceGammaRamp, (FARPROC)extGetDeviceGammaRamp}, {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 HookGDI32(HMODULE module) { HookLibrary(module, Hooks, libname); if(dxw.dwFlags1 & MAPGDITOPRIMARY) HookLibrary(module, DDHooks, libname); else HookLibrary(module, GDIHooks, libname); if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC)) HookLibrary(module, EmuHooks, libname); if(dxw.dwFlags2 & DISABLEGAMMARAMP) HookLibrary(module, GammaHooks, libname); } void HookGDI32Init() { HookLibInit(Hooks); HookLibInit(DDHooks); HookLibInit(EmuHooks); HookLibInit(GammaHooks); } FARPROC Remap_GDI32_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; if (addr=RemapLibrary(proc, hModule, Hooks)) return addr; if(dxw.dwFlags1 & MAPGDITOPRIMARY) if(addr=RemapLibrary(proc, hModule, DDHooks)) return addr; else if(addr=RemapLibrary(proc, hModule, GDIHooks)) return addr; if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC)) if(addr=RemapLibrary(proc, hModule, EmuHooks)) return addr; if(dxw.dwFlags2 & DISABLEGAMMARAMP) if(addr=RemapLibrary(proc, hModule, GammaHooks)) 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! } OutTraceD("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); OutTraceD("GetDeviceCaps: hdc=%x index=%x(%s) res=%x\n", hdc, nindex, ExplainDeviceCaps(nindex), res); // if you have a bypassed setting, use it first! if(pSetDevMode){ switch(nindex){ case BITSPIXEL: case COLORRES: res = pSetDevMode->dmBitsPerPel; OutTraceD("GetDeviceCaps: fix BITSPIXEL/COLORRES cap=%x\n",res); return res; case HORZRES: res = pSetDevMode->dmPelsWidth; OutTraceD("GetDeviceCaps: fix HORZRES cap=%d\n", res); return res; case VERTRES: res = pSetDevMode->dmPelsHeight; OutTraceD("GetDeviceCaps: fix VERTRES cap=%d\n", res); return res; } } switch(nindex){ case VERTRES: res= dxw.GetScreenHeight(); OutTraceD("GetDeviceCaps: fix VERTRES cap=%d\n", res); break; case HORZRES: res= dxw.GetScreenWidth(); OutTraceD("GetDeviceCaps: fix 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 OutTraceD("GetDeviceCaps: fix RASTERCAPS setting RC_PALETTE cap=%x\n",res); } break; case BITSPIXEL: case COLORRES: if(dxw.dwFlags2 & INIT8BPP|INIT16BPP){ if(dxw.dwFlags2 & INIT8BPP) res = 8; if(dxw.dwFlags2 & INIT16BPP) res = 16; OutTraceD("GetDeviceCaps: fix BITSPIXEL/COLORRES cap=%d\n",res); } break; } if(dxw.dwFlags1 & EMULATESURFACE){ switch(nindex){ case RASTERCAPS: if((dxw.VirtualPixelFormat.dwRGBBitCount==8) || (dxw.dwFlags2 & INIT8BPP)){ res = RC_PALETTE; OutTraceD("GetDeviceCaps: fix RASTERCAPS setting RC_PALETTE cap=%x\n",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) OutTraceD("GetDeviceCaps: fix BITSPIXEL/COLORRES cap=%d\n",res); break; case SIZEPALETTE: res = 256; OutTraceD("GetDeviceCaps: fix SIZEPALETTE cap=%x\n",res); break; case NUMRESERVED: res = 0; OutTraceD("GetDeviceCaps: fix NUMRESERVED cap=%x\n",res); break; } } return res; } BOOL WINAPI extTextOutA(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cchString) { BOOL ret; OutTraceD("TextOut: hdc=%x xy=(%d,%d) str=(%d)\"%s\"\n", hdc, nXStart, nYStart, cchString, lpString); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.MapClient(&nXStart, &nYStart); OutTraceD("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) { OutTraceD("ScaleWindowExtEx: hdc=%x num=(%d,%d) denom=(%d,%d) lpSize=%d\n", hdc, Xnum, Ynum, Xdenom, Ydenom, lpSize); if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen()) return 1; return (*pGDIScaleWindowExtEx)(hdc, Xnum, Xdenom, Ynum, Ydenom, lpSize); } BOOL WINAPI extRectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) { int ret; OutTraceD("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); OutTraceD("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); OutTraceD("GDI.SaveDC: hdc=%x ret=%x\n", hdc, ret); //AutoRefreshThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AutoRefresh, (LPVOID)hdc, 0, &dwThrdId); return ret; } BOOL WINAPI extGDIRestoreDC(HDC hdc, int nSavedDC) { BOOL ret; ret=(*pGDIRestoreDC)(hdc, nSavedDC); OutTraceD("GDI.RestoreDC: hdc=%x nSavedDC=%x ret=%x\n", hdc, nSavedDC, ret); //TerminateThread(AutoRefreshThread, 0); 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; dxw.IsGDIPalette=TRUE; OutTraceD("GDI.CreatePalette: plpal=%x version=%x NumEntries=%x\n", plpal, plpal->palVersion, plpal->palNumEntries); ret=(*pGDICreatePalette)(plpal); if(IsDebug){ OutTraceD("PalEntry[%x]= ", plpal->palNumEntries); for(idx=0; idxpalNumEntries; idx++) OutTraceD("(%x)", plpal->palPalEntry[idx]); OutTraceD("\n"); } dxw.palVersion=plpal->palVersion; dxw.palNumEntries=plpal->palNumEntries; if(dxw.palNumEntries>256) dxw.palNumEntries=256; for(idx=0; idxpalPalEntry[idx]; OutTraceD("GDI.CreatePalette: hPalette=%x\n", ret); return ret; } HPALETTE WINAPI extSelectPalette(HDC hdc, HPALETTE hpal, BOOL bForceBackground) { HPALETTE ret; ret=(*pGDISelectPalette)(hdc, hpal, bForceBackground); OutTraceD("GDI.SelectPalette: hdc=%x hpal=%x ForceBackground=%x ret=%x\n", hdc, hpal, bForceBackground, ret); return ret; } UINT WINAPI extRealizePalette(HDC hdc) { UINT ret; extern void mySetPalette(int, int, LPPALETTEENTRY); ret=(*pGDIRealizePalette)(hdc); OutTraceD("GDI.RealizePalette: hdc=%x ret=%x\n", hdc, ret); if(!dxw.IsGDIPalette) return ret; // quick & dirty implementation through a nasty global: // if the SelectPalette didn't force to the background (arg bForceBackground==FALSE) // then don't override the current palette set by the DirectDrawPalette class. // should be cleaned up a little.... // maybe not: now both Diablo & Dementia colors are working... if(dxw.dwFlags1 & EMULATESURFACE) mySetPalette(0, dxw.palNumEntries, dxw.palPalEntry); // DEBUGGING if(IsDebug){ int idx; OutTraceD("PaletteEntries[%x]= ", dxw.palNumEntries); for(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); if (dxw.dwFlags2 & SHOWFPSOVERLAY) dxw.ShowFPS(hdcDest); } res=(*pGDIStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWSrc, nHSrc, dwRop); if(!res) OutTraceE("GDI.StretchBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); return res; } BOOL WINAPI extGDIDeleteDC(HDC hdc) { BOOL res; OutTraceD("GDI.DeleteDC: hdc=%x\n", hdc); res=(*pGDIDeleteDC)(hdc); if(!res) OutTraceE("GDI.DeleteDC: ERROR err=%d at %d\n", GetLastError(), __LINE__); return res; } COLORREF WINAPI extSetTextColor(HDC hdc, COLORREF crColor) { COLORREF res; if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC) && (dxw.VirtualPixelFormat.dwRGBBitCount==8)) crColor=GetMatchingColor(crColor); res=(*pGDISetTextColor)(hdc, crColor); OutTraceD("SetTextColor: color=%x res=%x%s\n", crColor, res, (res==CLR_INVALID)?"(CLR_INVALID)":""); return res; } COLORREF WINAPI extSetBkColor(HDC hdc, COLORREF crColor) { COLORREF res; if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC) && (dxw.VirtualPixelFormat.dwRGBBitCount==8)) crColor=GetMatchingColor(crColor); res=(*pGDISetBkColor)(hdc, crColor); OutTraceD("SetBkColor: color=%x res=%x%s\n", crColor, res, (res==CLR_INVALID)?"(CLR_INVALID)":""); 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) { OutTraceD("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; OutTraceD("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) OutTraceD("CreateFontIndirect: hfont=%x\n", retHFont); else OutTraceD("CreateFontIndirect: error=%d at %d\n", GetLastError(), __LINE__); return retHFont; } BOOL WINAPI extSetDeviceGammaRamp(HDC hDC, LPVOID lpRamp) { BOOL ret; OutTraceD("SetDeviceGammaRamp: hdc=%x\n", hDC); if(dxw.dwFlags2 & DISABLEGAMMARAMP) { OutTraceD("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; OutTraceD("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"}; OutTraceD("GetClipBox: hdc=%x\n", hdc); ret=(*pGDIGetClipBox)(hdc, lprc); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc)) && (ret!=ERROR)){ OutTraceD("GetClipBox: scaling main win coordinates (%d,%d)-(%d,%d)\n", lprc->left, lprc->top, lprc->right, lprc->bottom); *lprc=dxw.GetScreenRect(); } OutTraceD("GetClipBox: ret=%x(%s)\n", ret, sRetCodes[ret]); return ret; } BOOL WINAPI extPolyline(HDC hdc, const POINT *lppt, int cPoints) { BOOL ret; if(IsTraceD){ int i; OutTrace("Polyline: hdc=%x cPoints=%d pt=", hdc, cPoints); for(i=0; ibmiHeader); OutTraceD("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() && (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); OutTraceD("SetDIBitsToDevice: fixed dest=(%d,%d)-(%d,%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__); if(!(ret=(*pGDIStretchBlt)(hdc, XDest, YDest, dwWidth, dwHeight, hTempDc, 0, 0, OrigWidth, OrigHeight, SRCCOPY))) OutTraceE("StretchBlt: ERROR err=%d at=%d\n", GetLastError(), __LINE__); DeleteDC(hTempDc); } 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; // OutTraceD("CreateCompatibleBitmap: hdc=%x size=(%d,%d)\n", // hdc, nWidth, nHeight); // // if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ // dxw.MapClient(&nWidth, &nHeight); // OutTraceD("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; OutTraceD("SetPixel: hdc=%x color=%x point=(%d,%d)\n", hdc, crColor, X, Y); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.MapClient(&X, &Y); OutTraceD("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; OutTraceD("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); OutTraceD("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(IsTraceD){ 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); OutTraceD("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; OutTraceD("CreateRectRgn: rect=(%d,%d)-(%d,%d)\n", nLeftRect, nTopRect, nRightRect, nBottomRect); if (dxw.IsFullScreen()){ dxw.MapClient(&nLeftRect, &nTopRect, &nRightRect, &nBottomRect); OutTraceD("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; OutTraceD("CreateRectRgnIndirect: rect=(%d,%d)-(%d,%d)\n", lprc->left, lprc->top, lprc->right, lprc->bottom); if (dxw.IsFullScreen()){ dxw.MapClient((RECT *)lprc); OutTraceD("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(IsTraceD){ int i; OutTrace("CreatePolygonRgn: PolyFillMode=%x cCount=%d pt=", fnPolyFillMode, cPoints); for(i=0; ileft, lpRect->top, lpRect->right, lpRect->bottom, uFormat, nCount, lpchText); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.MapClient((RECT *)lpRect); OutTraceD("DrawText: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); } ret=(*pDrawText)(hdc, lpchText, nCount, lpRect, uFormat); if(!ret) OutTraceE("DrawText: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } int WINAPI extDrawTextEx(HDC hdc, LPTSTR lpchText, int nCount, LPRECT lpRect, UINT dwDTFormat, LPDRAWTEXTPARAMS lpDTParams) { int ret; OutTraceD("DrawTextEx: hdc=%x rect=(%d,%d)-(%d,%d) DTFormat=%x Text=(%d)\"%s\"\n", hdc, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, dwDTFormat, nCount, lpchText); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ dxw.MapClient((RECT *)lpRect); OutTraceD("DrawTextEx: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); } ret=(*pDrawTextEx)(hdc, lpchText, nCount, lpRect, dwDTFormat, lpDTParams); if(!ret) OutTraceE("DrawTextEx: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } BOOL WINAPI extMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask, DWORD dwRop) { BOOL ret; OutTraceD("MaskBlt: hdcDest=%x pos=(%d,%d) size=(%dx%d) hdcSrc=%x pos=(%d,%d) hbmMask=%x Mask=(%d,%d) dwRop=%x\n", hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, hbmMask, xMask, yMask, dwRop); if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdcDest))){ dxw.MapClient(&nXDest, &nYDest, &nWidth, &nHeight); OutTraceD("MaskBlt: fixed pos=(%d,%d) size=(%dx%d)\n", nXDest, nYDest, nWidth, nHeight); } ret=(*pMaskBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, hbmMask, xMask, yMask, dwRop); if(!ret) OutTraceE("MaskBlt: ERROR ret=%x err=%d\n", ret, GetLastError()); return ret; } #if 0 // to map: // GetCurrentPositionEx // GetViewportExtEx // DPtoLP // GetWindowOrgEx // LPtoDP // OffsetViewportOrgEx // OffsetWindowOrgEx // TransparentBlt // to do: eliminate FIXTEXTOUT handling BOOL SetTextJustification( _In_ HDC hdc, _In_ int nBreakExtra, <---- _In_ int nBreakCount ); #endif