1
0
mirror of https://github.com/DxWnd/DxWnd.reloaded synced 2024-12-30 09:25:35 +01:00
DxWnd.reloaded/dll/emulateddc.cpp

138 lines
5.0 KiB
C++
Raw Normal View History

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "dxwnd.h"
#include "dxwcore.hpp"
#include "syslibs.h"
#include "dxhelper.h"
#include "resource.h"
// SAVELASTDC: optimized mode, if the last window handle and size didn't change,
// it is not necessary to create a new VirtualHDC and attached bitmap, you can reuse
// the last one, with the further advantage of avoiding multiple scaling to and from
// the virtual image with quality loss (see "BattleZone 1998").
// Unfortunately something is wrong with Imperialism II, so better not activate ....
#ifdef DXWND_SAVELASTDC
static HWND gLasthWnd = NULL;
static RECT gLastRect = {0,0,0,0};
#endif
HDC dxwCore::AcquireEmulatedDC(HWND hwnd)
{
HDC wdc;
RECT WinRect;
HGDIOBJ PrevSelection;
//OutTrace("ACQUIRE hwnd=%x vhdc=%x pic=%x\n", hwnd, VirtualHDC, VirtualPic);
if(!(wdc=(*pGDIGetDC)(hwnd))){ // potential DC leakage
OutTraceE("AcquireEmulatedDC: GetDC ERROR hwnd=%x err=%d at=%d\n", hwnd, GetLastError(), __LINE__);
return NULL;
}
(*pGetClientRect)(hwnd, &WinRect);
VirtualPicRect = WinRect;
dxw.UnmapClient(&VirtualPicRect);
#ifdef DXWND_SAVELASTDC
if((hwnd == gLasthWnd) && (WinRect.right == gLastRect.right) && (WinRect.bottom == gLastRect.bottom)) {
if(!(*pGDIStretchBlt)(VirtualHDC, VirtualPicRect.left, VirtualPicRect.top, VirtualPicRect.right, VirtualPicRect.bottom, wdc, 0, 0, WinRect.right, WinRect.bottom, SRCCOPY))
OutTraceE("AcquireEmulatedDC: StretchBlt ERROR err=%d at=%d\n", GetLastError(), __LINE__);
if(!(pGDIReleaseDC)(hwnd, wdc))
OutTraceE("AcquireEmulatedDC: ReleaseDC ERROR hdc=%x err=%d at=%d\n", wdc, GetLastError(), __LINE__);
return VirtualHDC;
}
gLasthWnd = hwnd;
gLastRect = WinRect;
#endif
//OutTrace("WINDOW picrect=(%d,%d)-(%d,%d)\n",
// VirtualPicRect.left, VirtualPicRect.top, VirtualPicRect.right, VirtualPicRect.bottom);
OutTraceB("AcquireEmulatedDC: hwnd=%x Desktop=%x WinRect=(%d,%d)(%d,%d) VirtRect=(%d,%d)(%d,%d)\n",
hwnd, dxw.IsDesktop(hwnd),
WinRect.left, WinRect.top, WinRect.right, WinRect.bottom,
VirtualPicRect.left, VirtualPicRect.top, VirtualPicRect.right, VirtualPicRect.bottom);
// v2.03.91.fx3: loop required to eliminate resource leakage ("Yu No")
if(VirtualHDC) {
while(TRUE){
if(!DeleteObject(VirtualHDC))
OutTraceE("AcquireEmulatedDC: DeleteObject ERROR hdc=%x err=%d at=%d\n", VirtualHDC, GetLastError(), __LINE__);
else break;
(*pSleep)(1);
}
}
if(VirtualPic) {
while(TRUE){
if(!DeleteObject(VirtualPic))
OutTraceE("AcquireEmulatedDC: DeleteObject ERROR pic=%x err=%d at=%d\n", VirtualPic, GetLastError(), __LINE__);
else break;
(*pSleep)(1);
}
}
if(!(VirtualHDC=CreateCompatibleDC(wdc)))
OutTraceE("AcquireEmulatedDC: CreateCompatibleDC ERROR err=%d at=%d\n", GetLastError(), __LINE__);
if(!(VirtualPic=CreateCompatibleBitmap(wdc, dxw.GetScreenWidth(), dxw.GetScreenHeight())))
OutTraceE("AcquireEmulatedDC: CreateCompatibleBitmap ERROR err=%d at=%d\n", GetLastError(), __LINE__);
if(!(PrevSelection=(*pSelectObject)(VirtualHDC, VirtualPic)))
OutTraceE("AcquireEmulatedDC: SelectObject ERROR err=%d at=%d\n", GetLastError(), __LINE__);
else {
if(!DeleteObject(PrevSelection))
OutTraceE("AcquireEmulatedDC: DeleteObject ERROR pic=%x err=%d at=%d\n", PrevSelection, GetLastError(), __LINE__);;
}
//OutTrace("RENEW_IMAGE hdc=%x pic=%x\n", VirtualHDC, VirtualPic);
if(!(*pGDIStretchBlt)(VirtualHDC, VirtualPicRect.left, VirtualPicRect.top, VirtualPicRect.right, VirtualPicRect.bottom, wdc, 0, 0, WinRect.right, WinRect.bottom, SRCCOPY))
OutTraceE("AcquireEmulatedDC: StretchBlt ERROR err=%d at=%d\n", GetLastError(), __LINE__);
if(!(pGDIReleaseDC)(hwnd, wdc))
OutTraceE("AcquireEmulatedDC: ReleaseDC ERROR hdc=%x err=%d at=%d\n", wdc, GetLastError(), __LINE__);
return VirtualHDC;
}
BOOL dxwCore::ReleaseEmulatedDC(HWND hwnd)
{
HDC wdc;
RECT WinRect;
//OutTrace("RELEASE hwnd=%x\n", hwnd);
(*pGetClientRect)(hwnd, &WinRect);
OutTraceB("ReleaseEmulatedDC: hwnd=%x Desktop=%x WinRect=(%d,%d)(%d,%d) VirtRect=(%d,%d)(%d,%d)\n",
hwnd, dxw.IsDesktop(hwnd),
WinRect.left, WinRect.top, WinRect.right, WinRect.bottom,
VirtualPicRect.left, VirtualPicRect.top, VirtualPicRect.right, VirtualPicRect.bottom);
if(!(wdc=(*pGDIGetDC)(hwnd))) { // potential DC leakage
OutTraceE("ReleaseEmulatedDC: GetDC ERROR err=%d at=%d\n", GetLastError(), __LINE__);
return FALSE;
}
SetStretchBltMode(VirtualHDC, HALFTONE);
if(!(*pGDIStretchBlt)(wdc, 0, 0, WinRect.right, WinRect.bottom, VirtualHDC, 0, 0, VirtualPicRect.right, VirtualPicRect.bottom, SRCCOPY))
OutTraceE("ReleaseEmulatedDC: StretchBlt ERROR err=%d at=%d\n", GetLastError(), __LINE__);
if(!(*pGDIReleaseDC)(hwnd, wdc))// fixed DC leakage
OutTraceE("ReleaseEmulatedDC: ReleaseDC ERROR hwnd=%x hdc=%x err=%d at=%d\n", hwnd, wdc, GetLastError(), __LINE__);
return TRUE;
}
void dxwCore::ResetEmulatedDC()
{
//OutTrace("RESET\n");
VirtualHDC=NULL;
VirtualPic=NULL;
VirtualOffsetX=0;
VirtualOffsetY=0;
}
BOOL dxwCore::IsVirtual(HDC hdc)
{
return (hdc==VirtualHDC) && (GDIEmulationMode == GDIMODE_EMULATED);
}