📄 windraw2.cpp
字号:
{ CHXSimpleList* pList = (CHXSimpleList*) Context; CModesDesc* pDesc = new CModesDesc; pDesc->m_nWidth = pddsd->dwWidth; pDesc->m_nHeight = pddsd->dwHeight; pDesc->m_nBitCount = pddsd->ddpfPixelFormat.dwRGBBitCount; pDesc->m_fourCC = pddsd->ddpfPixelFormat.dwFourCC; pList->AddTail(pDesc); return DDENUMRET_OK;} /** Initialize WinDraw engine.* Use:* HRESULT WinDraw2_Open (LPWINDRAW lpwd, HWND hWnd, DWORD fMode,* LPSTR lpszDisplay, LPBMI lpbiDisplayFormat);* Input:* lpwd - pointer to a WINDRAW structure to initialize* hWnd - a window handle to use* fMode - WinDraw mode to set (e.g. WINDRAW_FULLSCREEN)* lpszDisplay - monitor to use (NULL or zero string = use all monitors)* lpbiDisplayFormat - preferred display mode in full screen* Returns:* NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.*/HRESULT WinDraw2_Open (LPWINDRAW lpwd, HWND hWnd, DWORD fMode, LPSTR lpszDisplay, LPBMI lpbiDisplayFormat){ /* check parameters: */ if (lpwd == NULL || hWnd == NULL || (lpwd->fMode & WINDRAW_OPENED)) return E_INVALIDARG; HRESULT hrFail = E_FAIL; if (!g_ehandlerMutexCnt) { InitializeCriticalSection(&g_ehandlerMutex); } InterlockedIncrement(&g_ehandlerMutexCnt); z_hHxColor = LoadLibrary("colorcvt.dll"); if (!z_hHxColor) z_hHxColor = LoadLibrary("hxltcolor.dll"); if (z_hHxColor) { pfInitColorConverter = (INITCOLORCONVERTERFN) GetProcAddress(z_hHxColor,"InitColorConverter"); pfSetRGB8Palette = (SETRGB8PALETTEFN) GetProcAddress(z_hHxColor,"SetRGB8Palette"); } /* initialize WinDraw structure: */ memset (lpwd, 0, sizeof (WINDRAW)); lpwd->hWnd = hWnd; lpwd->m_pModesList = new CHXSimpleList; lpwd->m_pSurfaceList = new CHXSimpleList; lpwd->nSchedulerResolution = 0; InitializeCriticalSection(&lpwd->csPrimary); /* check if want to use DirectDraw: */ if (fMode & WINDRAW_DIRECTDRAW) { lpwd->fMode |= WINDRAW_DIRECTDRAW; /* initialize DirectDraw objects: */ LPDIRECTDRAW pDirectDraw = NULL; try { if (LoadDirectDraw (lpszDisplay, &pDirectDraw, & (lpwd->dd.hDD)) != NOERROR) goto dd_fail; } catch (...) { DumpDDInfo(lpwd, NULL, "WinDraw2_Open"); goto dd_fail; } pDirectDraw->QueryInterface(IID_IDirectDraw2, (void**)&lpwd->dd.lpDD2); pDirectDraw->Release(); pDirectDraw = 0; /* * DirectX 1.0 installed (e.g. boxes with the original (Aug 95) release of Win95). * don't support that! */ if (!lpwd->dd.lpDD2) { goto dd_fail; } /* initialize our color conversion engine: */ if (pfInitColorConverter) (*pfInitColorConverter)(); /* get display format: */ lpwd->lpszDisplayDevice = lpszDisplay; lpwd->cidDisplayColor = CID_UNKNOWN; if (GetDisplayFormat (&lpwd->bmiDisplayFormat, lpwd->lpszDisplayDevice) != NOERROR || (lpwd->cidDisplayColor = GetBitmapColor ((LPBITMAPINFO)&lpwd->bmiDisplayFormat)) == CID_UNKNOWN) { /* this is very bad... */ #ifdef _DEBUG OutputDebugString ("WinDraw: cannot obtain display pixel format.\n"); #endif goto dd_fail; } /* find out what FourCC codes are supported */ lpwd->dd.lpDD2->GetFourCCCodes(&(lpwd->numCodes), lpwd->lpCodes); if (lpwd->numCodes) { lpwd->lpCodes = (LPDWORD) malloc (lpwd->numCodes*4); lpwd->lpCID = (LPDWORD) malloc (lpwd->numCodes*4); lpwd->dd.lpDD2->GetFourCCCodes(&(lpwd->numCodes), lpwd->lpCodes); for(unsigned int i = 0; i<lpwd->numCodes; i++) { lpwd->lpCID[i] = MapFourCCtoCID(lpwd->lpCodes[i]); } } /* Get the device caps */ memset(&lpwd->dd.m_caps, 0, sizeof(DDCAPS)); lpwd->dd.m_caps.dwSize = sizeof(DDCAPS_DX3); lpwd->dd.lpDD2->GetCaps(&(lpwd->dd.m_caps), 0); /* * If we have neither overlay nor streatching then we will use DibEngine (good call? time will tell) */ if (! ( (lpwd->dd.m_caps.dwCaps & DDCAPS_OVERLAY) || (lpwd->dd.m_caps.dwCaps & DDCAPS_BLTSTRETCH) )) { goto dd_fail; } /* set normal cooperative level */ if (DD_OK != lpwd->dd.lpDD2->SetCooperativeLevel(lpwd->hWnd, DDSCL_NORMAL)) { goto dd_fail; } try { if (DD_OK == WindrawSurface_CreatePrimarySurface(lpwd)) { /* DirectDraw profile/mode masks: */ DWORD dwOverlayMask, dwBltMask; DDPIXELFORMAT ddpf; /* color formats: */ int cidOut = CID_UNKNOWN; /* get pixel format of the primary surface: */ memset (&ddpf, 0, sizeof (DDPIXELFORMAT)); ddpf.dwSize = sizeof (DDPIXELFORMAT); ddpf.dwFlags = DDPF_RGB | DDPF_FOURCC; if (lpwd->dd.lpDDSPrimary->GetPixelFormat(&ddpf) != DD_OK) goto dd_fail; /* convert it to our color ID: */ cidOut = GetDirectDrawColor (&ddpf); if (cidOut < CID_RGB32 || cidOut > CID_RGB8) goto dd_fail; /* check if DirectDraw profile needs to be loaded: */ if (!lpddprofDirectDrawProfile || DDPDB_IsNewProfile ()) { /* get DirectDraw device profile: */ lpwd->dd.lpDD2->QueryInterface(IID_IDirectDraw, (void**)&pDirectDraw); HX_ASSERT(pDirectDraw); lpddprofDirectDrawProfile = DDPDB_GetDeviceProfile(pDirectDraw); pDirectDraw->Release(); pDirectDraw = 0; } /* get mode masks: */ dwOverlayMask = lpddprofDirectDrawProfile->fOverlays [cidOut-CID_RGB32]; dwBltMask = lpddprofDirectDrawProfile->fBlts [cidOut-CID_RGB32]; // if (dwOverlayMask == 0 || dwBltMask == 0) /* We currently disable DirectDraw if bltMask is 0. * Need to add support for selecting DirectDraw features based on * the info in the database. */ if (dwOverlayMask == 0) goto dd_fail; /* Enum the display modes */ zm_DisplaySettings.GetSettings(lpwd->m_pModesList); /* * For SOME reason EnumDisplayModes is causing a number of cards to go CRAZY. * So we now we call a function which calls enum display modes early and caches * the results. For some reason this does not cause things to go INSANE. Who knows why. */ // lpwd->dd.lpDD2->EnumDisplayModes(0, NULL, lpwd->m_pModesList, DisplayModeEnumeratorCallback); } else { goto dd_fail; } } catch(...) { DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "WinDraw2_Open"); goto dd_fail; } goto success; dd_fail: /* release DirectDraw library, if loaded: */ if (lpwd->dd.lpDD2 != NULL && lpwd->dd.hDD != NULL) ReleaseDirectDraw(&(lpwd->dd.lpDD), &(lpwd->dd.lpDD2), & (lpwd->dd.hDD)); /* exit with error: */ return hrFail; } else { /* use GDI: */ /* grab DCs: */ if ((lpwd->gdi.hDC = GetDC (lpwd->hWnd)) == NULL || (lpwd->gdi.hMemoryDC = CreateCompatibleDC (lpwd->gdi.hDC)) == NULL || (lpwd->gdi.hMemoryDC2 = CreateCompatibleDC (lpwd->gdi.hDC)) == NULL) goto gdi_fail; /* set default StretchBlt () mode: */ SetStretchBltMode (lpwd->gdi.hDC, COLORONCOLOR); SetStretchBltMode (lpwd->gdi.hMemoryDC,COLORONCOLOR); SetStretchBltMode (lpwd->gdi.hMemoryDC2,COLORONCOLOR); /* get display format: */ lpwd->lpszDisplayDevice = lpszDisplay; lpwd->cidDisplayColor = CID_UNKNOWN; if (GetDisplayFormat (&lpwd->bmiDisplayFormat, lpwd->lpszDisplayDevice) != NOERROR || (lpwd->cidDisplayColor = GetBitmapColor ((LPBITMAPINFO)&lpwd->bmiDisplayFormat)) == CID_UNKNOWN) { /* this is very bad... */ #ifdef _DEBUG OutputDebugString ("WinDraw: cannot obtain display pixel format.\n"); #endif goto gdi_fail; } /* initialize our color conversion engine: */ if (pfInitColorConverter) (*pfInitColorConverter)(); goto success; /* something really bad has happened... */gdi_fail: /* delete palette: */ if (lpwd->gdi.hPalette) { DeleteObject (lpwd->gdi.hPalette); lpwd->gdi.hPalette = NULL; } /* release DCs, if taken: */ if (lpwd->gdi.hDC != NULL) { ReleaseDC (lpwd->hWnd, lpwd->gdi.hDC); lpwd->gdi.hDC = NULL; } if (lpwd->gdi.hMemoryDC != NULL) { DeleteDC (lpwd->gdi.hMemoryDC); lpwd->gdi.hMemoryDC = NULL; } if (lpwd->gdi.hMemoryDC2 != NULL) { DeleteDC (lpwd->gdi.hMemoryDC2); lpwd->gdi.hMemoryDC2 = NULL; } /* exit with error: */ return E_FAIL; } success: /* activate WinDraw & exit: */ lpwd->fMode |= WINDRAW_OPENED; WinDraw2_OnPaletteChange(lpwd, lpwd->hWnd, WM_PALETTECHANGED); return NOERROR;}void DeleteDisplayModes(LPWINDRAW lpwd){ CHXSimpleList::Iterator i; if (!lpwd->m_pModesList || !lpwd->m_pModesList->GetCount()) return; for(i=lpwd->m_pModesList->Begin(); i!= lpwd->m_pModesList->End(); ++i) { CModesDesc* pDesc = (CModesDesc*) *i; HX_DELETE(pDesc); } lpwd->m_pModesList->RemoveAll();}/** Close WinDraw library.* Use:* HRESULT WinDrawClose (LPWINDRAW lpwd);* Input:* lpwd - pointer to a WINDRAW engine to deactivate* Returns:* NOERROR if OK, or E_FAIL.*/HRESULT WinDraw2_Close (LPWINDRAW lpwd){ /* check parameters: */ if (lpwd == NULL || !(lpwd->fMode & WINDRAW_OPENED)) // return E_INVALIDARG; goto cleanup; if (z_hHxColor) { FreeLibrary(z_hHxColor); z_hHxColor = 0; pfInitColorConverter = 0; pfSetRGB8Palette = 0; } /* check mode: */ if (lpwd->fMode & WINDRAW_DIRECTDRAW) { free(lpwd->lpCodes); free(lpwd->lpCID); /* * Release the Primary Surface */ if (lpwd->dd.lpDDSPrimary) { int rel = lpwd->dd.lpDDSPrimary->Release(); lpwd->dd.lpDDSPrimary = NULL; } /* release DirectDraw library, if loaded: */ if (lpwd->dd.lpDD2 != NULL && lpwd->dd.hDD != NULL) ReleaseDirectDraw (&(lpwd->dd.lpDD), &(lpwd->dd.lpDD2), &(lpwd->dd.hDD)); } else { /* GDI: */ /* delete palette: */ if (lpwd->gdi.hPalette) { DeleteObject (lpwd->gdi.hPalette); lpwd->gdi.hPalette = NULL; } /* release DCs, if taken: */ if (lpwd->gdi.hDC != NULL) { ReleaseDC (lpwd->hWnd, lpwd->gdi.hDC); lpwd->gdi.hDC = NULL; } if (lpwd->gdi.hMemoryDC != NULL) { DeleteDC (lpwd->gdi.hMemoryDC); lpwd->gdi.hMemoryDC = NULL; } if (lpwd->gdi.hMemoryDC2 != NULL) { DeleteDC (lpwd->gdi.hMemoryDC2); lpwd->gdi.hMemoryDC2 = NULL; } } cleanup: /* deactivate WinDraw & exit: */ lpwd->fMode = 0; /* remove display mode data */ DeleteDisplayModes(lpwd); HX_DELETE(lpwd->m_pModesList); HX_DELETE(lpwd->m_pSurfaceList); DeleteCriticalSection(&lpwd->csPrimary); InterlockedDecrement(&g_ehandlerMutexCnt);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -