rlm@1: // VideoMode.cpp : implementation file rlm@1: // rlm@1: rlm@1: #include "stdafx.h" rlm@1: #include "resource.h" rlm@1: rlm@1: /// #define _AFXDLL /// EVIL rlm@1: /// #include "afxwin.h" /// EVIL rlm@1: /// #include "afxdll_.h" /// EVIL rlm@1: rlm@1: #define DIRECTDRAW_VERSION 0x0700 rlm@1: #include "ddraw.h" rlm@1: rlm@1: #include "VideoMode.h" rlm@1: rlm@1: #include "../common/System.h" // for system messages rlm@1: rlm@1: #define MAX_DRIVERS 32 // 32 drivers maximum rlm@1: rlm@1: //----------------------------------------------------------------------------- rlm@1: // Local structures rlm@1: //----------------------------------------------------------------------------- rlm@1: // Keeps data on the available DDraw drivers rlm@1: struct rlm@1: { rlm@1: char szDescription[128]; rlm@1: char szName[128]; rlm@1: GUID * pGUID; rlm@1: GUID GUIDcopy; rlm@1: HMONITOR hm; rlm@1: } Drivers[MAX_DRIVERS]; rlm@1: rlm@1: //----------------------------------------------------------------------------- rlm@1: // Local data rlm@1: //----------------------------------------------------------------------------- rlm@1: static int gDriverCnt = 0; // Total number of drivers rlm@1: static GUID *gpSelectedDriverGUID; rlm@1: rlm@1: //----------------------------------------------------------------------------- rlm@1: // Name: DDEnumCallbackEx() rlm@1: // Desc: This call back is used to determine the existing available DDraw rlm@1: // devices, so the user can pick which one to run on. rlm@1: //----------------------------------------------------------------------------- rlm@1: BOOL WINAPI rlm@1: DDEnumCallbackEx(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID pContext, HMONITOR hm) rlm@1: { rlm@1: if (pGUID) rlm@1: { rlm@1: Drivers[gDriverCnt].GUIDcopy = *pGUID; rlm@1: Drivers[gDriverCnt].pGUID = &Drivers[gDriverCnt].GUIDcopy; rlm@1: } rlm@1: else rlm@1: Drivers[gDriverCnt].pGUID = NULL; rlm@1: Drivers[gDriverCnt].szDescription[127] = '\0'; rlm@1: Drivers[gDriverCnt].szName[127] = '\0'; rlm@1: strncpy(Drivers[gDriverCnt].szDescription, pDescription, 127); rlm@1: strncpy(Drivers[gDriverCnt].szName, pName, 127); rlm@1: Drivers[gDriverCnt].hm = hm; rlm@1: if (gDriverCnt < MAX_DRIVERS) rlm@1: gDriverCnt++; rlm@1: else rlm@1: return DDENUMRET_CANCEL; rlm@1: return DDENUMRET_OK; rlm@1: } rlm@1: rlm@1: //----------------------------------------------------------------------------- rlm@1: // Name: DDEnumCallback() rlm@1: // Desc: This callback is used only with old versions of DDraw. rlm@1: //----------------------------------------------------------------------------- rlm@1: BOOL WINAPI rlm@1: DDEnumCallback(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID context) rlm@1: { rlm@1: return (DDEnumCallbackEx(pGUID, pDescription, pName, context, NULL)); rlm@1: } rlm@1: rlm@1: static HRESULT WINAPI addVideoMode(LPDDSURFACEDESC2 surf, LPVOID lpContext) rlm@1: { rlm@1: HWND h = (HWND)lpContext; rlm@1: char buffer[50]; rlm@1: rlm@1: switch (surf->ddpfPixelFormat.dwRGBBitCount) rlm@1: { rlm@1: case 16: rlm@1: case 24: rlm@1: case 32: rlm@1: if (surf->dwWidth >= 640 && surf->dwHeight >= 480) rlm@1: { rlm@1: sprintf(buffer, "%4dx%4dx%2d", surf->dwWidth, surf->dwHeight, rlm@1: surf->ddpfPixelFormat.dwRGBBitCount); rlm@1: int pos = ::SendMessage(h, LB_ADDSTRING, 0, (LPARAM)buffer); rlm@1: ::SendMessage(h, LB_SETITEMDATA, pos, rlm@1: (surf->ddpfPixelFormat.dwRGBBitCount << 24) | rlm@1: ((surf->dwWidth & 4095) << 12) | rlm@1: (surf->dwHeight & 4095)); rlm@1: } rlm@1: } rlm@1: rlm@1: return DDENUMRET_OK; rlm@1: } rlm@1: rlm@1: int winVideoModeSelect(CWnd *pWnd, GUID **guid) rlm@1: { rlm@1: HINSTANCE h = /**/ ::LoadLibrary("ddraw.dll"); rlm@1: rlm@1: // If ddraw.dll doesn't exist in the search path, rlm@1: // then DirectX probably isn't installed, so fail. rlm@1: if (!h) rlm@1: return -1; rlm@1: rlm@1: gDriverCnt = 0; rlm@1: rlm@1: // Note that you must know which version of the rlm@1: // function to retrieve (see the following text). rlm@1: // For this example, we use the ANSI version. rlm@1: LPDIRECTDRAWENUMERATEEX lpDDEnumEx; rlm@1: lpDDEnumEx = (LPDIRECTDRAWENUMERATEEX) rlm@1: GetProcAddress(h, "DirectDrawEnumerateExA"); rlm@1: rlm@1: // If the function is there, call it to enumerate all display rlm@1: // devices attached to the desktop, and any non-display DirectDraw rlm@1: // devices. rlm@1: if (lpDDEnumEx) rlm@1: lpDDEnumEx(DDEnumCallbackEx, NULL, rlm@1: DDENUM_ATTACHEDSECONDARYDEVICES | rlm@1: DDENUM_NONDISPLAYDEVICES rlm@1: ); rlm@1: else rlm@1: { rlm@1: /* rlm@1: * We must be running on an old version of DirectDraw. rlm@1: * Therefore MultiMon isn't supported. Fall back on rlm@1: * DirectDrawEnumerate to enumerate standard devices on a rlm@1: * single-monitor system. rlm@1: */ rlm@1: BOOL (WINAPI *lpDDEnum)(LPDDENUMCALLBACK, LPVOID); rlm@1: rlm@1: lpDDEnum = (BOOL (WINAPI *)(LPDDENUMCALLBACK, LPVOID)) rlm@1: GetProcAddress(h, "DirectDrawEnumerateA"); rlm@1: if (lpDDEnum) rlm@1: lpDDEnum(DDEnumCallback, NULL); rlm@1: rlm@1: /* Note that it could be handy to let the OldCallback function rlm@1: * be a wrapper for a DDEnumCallbackEx. rlm@1: * rlm@1: * Such a function would look like: rlm@1: * BOOL FAR PASCAL OldCallback(GUID FAR *lpGUID, rlm@1: * LPSTR pDesc, rlm@1: * LPSTR pName, rlm@1: * LPVOID pContext) rlm@1: * { rlm@1: * return Callback(lpGUID,pDesc,pName,pContext,NULL); rlm@1: * } rlm@1: */ rlm@1: } rlm@1: rlm@1: int selected = 0; rlm@1: rlm@1: if (gDriverCnt > 1) rlm@1: { rlm@1: VideoDriverSelect d(pWnd); rlm@1: rlm@1: selected = d.DoModal(); rlm@1: rlm@1: if (selected == -1) rlm@1: { rlm@1: // If the library was loaded by calling LoadLibrary(), rlm@1: // then you must use FreeLibrary() to let go of it. rlm@1: /**/ ::FreeLibrary(h); rlm@1: rlm@1: return -1; rlm@1: } rlm@1: } rlm@1: rlm@1: HRESULT (WINAPI *DDrawCreateEx)(GUID *, LPVOID *, REFIID, IUnknown *); rlm@1: DDrawCreateEx = (HRESULT (WINAPI *)(GUID *, LPVOID *, REFIID, IUnknown *)) rlm@1: GetProcAddress(h, "DirectDrawCreateEx"); rlm@1: rlm@1: LPDIRECTDRAW7 ddraw = NULL; rlm@1: if (DDrawCreateEx) rlm@1: { rlm@1: HRESULT hret = DDrawCreateEx(Drivers[selected].pGUID, rlm@1: (void * *)&ddraw, rlm@1: IID_IDirectDraw7, rlm@1: NULL); rlm@1: if (hret != DD_OK) rlm@1: { rlm@1: systemMessage(0, "Error during DirectDrawCreateEx: %08x", hret); rlm@1: /**/ ::FreeLibrary(h); rlm@1: return -1; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: // should not happen.... rlm@1: systemMessage(0, "Error getting DirectDrawCreateEx"); rlm@1: /**/ ::FreeLibrary(h); rlm@1: return -1; rlm@1: } rlm@1: rlm@1: VideoMode dlg(ddraw, pWnd); rlm@1: rlm@1: int res = dlg.DoModal(); rlm@1: rlm@1: if (res != -1) rlm@1: { rlm@1: *guid = Drivers[selected].pGUID; rlm@1: } rlm@1: ddraw->Release(); rlm@1: ddraw = NULL; rlm@1: rlm@1: // If the library was loaded by calling LoadLibrary(), rlm@1: // then you must use FreeLibrary() to let go of it. rlm@1: /**/ ::FreeLibrary(h); rlm@1: rlm@1: return res; rlm@1: } rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // VideoMode dialog rlm@1: rlm@1: VideoMode::VideoMode(LPDIRECTDRAW7 pDraw, CWnd*pParent /*=NULL*/) rlm@1: : CDialog(VideoMode::IDD, pParent) rlm@1: { rlm@1: //{{AFX_DATA_INIT(VideoMode) rlm@1: // NOTE: the ClassWizard will add member initialization here rlm@1: //}}AFX_DATA_INIT rlm@1: pDirectDraw = pDraw; rlm@1: } rlm@1: rlm@1: void VideoMode::DoDataExchange(CDataExchange*pDX) rlm@1: { rlm@1: CDialog::DoDataExchange(pDX); rlm@1: //{{AFX_DATA_MAP(VideoMode) rlm@1: DDX_Control(pDX, IDC_MODES, m_modes); rlm@1: //}}AFX_DATA_MAP rlm@1: } rlm@1: rlm@1: BEGIN_MESSAGE_MAP(VideoMode, CDialog) rlm@1: //{{AFX_MSG_MAP(VideoMode) rlm@1: ON_LBN_SELCHANGE(IDC_MODES, OnSelchangeModes) rlm@1: ON_BN_CLICKED(ID_CANCEL, OnCancel) rlm@1: ON_BN_CLICKED(ID_OK, OnOk) rlm@1: //}}AFX_MSG_MAP rlm@1: END_MESSAGE_MAP() rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // VideoMode message handlers rlm@1: rlm@1: void VideoMode::OnSelchangeModes() rlm@1: { rlm@1: int item = m_modes.GetCurSel(); rlm@1: rlm@1: GetDlgItem(ID_OK)->EnableWindow(item != -1); rlm@1: } rlm@1: rlm@1: void VideoMode::OnCancel() rlm@1: { rlm@1: EndDialog(-1); rlm@1: } rlm@1: rlm@1: void VideoMode::OnOk() rlm@1: { rlm@1: int cur = m_modes.GetCurSel(); rlm@1: rlm@1: if (cur != -1) rlm@1: { rlm@1: cur = m_modes.GetItemData(cur); rlm@1: } rlm@1: EndDialog(cur); rlm@1: } rlm@1: rlm@1: BOOL VideoMode::OnInitDialog() rlm@1: { rlm@1: CDialog::OnInitDialog(); rlm@1: rlm@1: // check for available fullscreen modes rlm@1: pDirectDraw->EnumDisplayModes(DDEDM_STANDARDVGAMODES, NULL, m_modes.m_hWnd, rlm@1: addVideoMode); rlm@1: rlm@1: GetDlgItem(ID_OK)->EnableWindow(FALSE); rlm@1: CenterWindow(); rlm@1: rlm@1: return TRUE; // return TRUE unless you set the focus to a control rlm@1: // EXCEPTION: OCX Property Pages should return FALSE rlm@1: } rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // VideoDriverSelect dialog rlm@1: rlm@1: VideoDriverSelect::VideoDriverSelect(CWnd*pParent /*=NULL*/) rlm@1: : CDialog(VideoDriverSelect::IDD, pParent) rlm@1: { rlm@1: //{{AFX_DATA_INIT(VideoDriverSelect) rlm@1: // NOTE: the ClassWizard will add member initialization here rlm@1: //}}AFX_DATA_INIT rlm@1: } rlm@1: rlm@1: void VideoDriverSelect::DoDataExchange(CDataExchange*pDX) rlm@1: { rlm@1: CDialog::DoDataExchange(pDX); rlm@1: //{{AFX_DATA_MAP(VideoDriverSelect) rlm@1: DDX_Control(pDX, IDC_DRIVERS, m_drivers); rlm@1: //}}AFX_DATA_MAP rlm@1: } rlm@1: rlm@1: BEGIN_MESSAGE_MAP(VideoDriverSelect, CDialog) rlm@1: //{{AFX_MSG_MAP(VideoDriverSelect) rlm@1: ON_BN_CLICKED(ID_OK, OnOk) rlm@1: ON_BN_CLICKED(ID_CANCEL, OnCancel) rlm@1: ON_LBN_SELCHANGE(IDC_DRIVERS, OnSelchangeDrivers) rlm@1: //}}AFX_MSG_MAP rlm@1: END_MESSAGE_MAP() rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // VideoDriverSelect message handlers rlm@1: rlm@1: void VideoDriverSelect::OnCancel() rlm@1: { rlm@1: EndDialog(-1); rlm@1: } rlm@1: rlm@1: void VideoDriverSelect::OnOk() rlm@1: { rlm@1: EndDialog(m_drivers.GetCurSel()); rlm@1: } rlm@1: rlm@1: BOOL VideoDriverSelect::OnInitDialog() rlm@1: { rlm@1: CDialog::OnInitDialog(); rlm@1: rlm@1: for (int i = 0; i < gDriverCnt; i++) rlm@1: { rlm@1: m_drivers.AddString(Drivers[i].szDescription); rlm@1: } rlm@1: rlm@1: GetDlgItem(ID_OK)->EnableWindow(FALSE); rlm@1: CenterWindow(); rlm@1: rlm@1: return TRUE; // return TRUE unless you set the focus to a control rlm@1: // EXCEPTION: OCX Property Pages should return FALSE rlm@1: } rlm@1: rlm@1: void VideoDriverSelect::OnSelchangeDrivers() rlm@1: { rlm@1: GetDlgItem(ID_OK)->EnableWindow(m_drivers.GetCurSel() != -1); rlm@1: } rlm@1: