view src/win32/VideoMode.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line source
1 // VideoMode.cpp : implementation file
2 //
4 #include "stdafx.h"
5 #include "resource.h"
7 /// #define _AFXDLL /// EVIL
8 /// #include "afxwin.h" /// EVIL
9 /// #include "afxdll_.h" /// EVIL
11 #define DIRECTDRAW_VERSION 0x0700
12 #include "ddraw.h"
14 #include "VideoMode.h"
16 #include "../common/System.h" // for system messages
18 #define MAX_DRIVERS 32 // 32 drivers maximum
20 //-----------------------------------------------------------------------------
21 // Local structures
22 //-----------------------------------------------------------------------------
23 // Keeps data on the available DDraw drivers
24 struct
25 {
26 char szDescription[128];
27 char szName[128];
28 GUID * pGUID;
29 GUID GUIDcopy;
30 HMONITOR hm;
31 } Drivers[MAX_DRIVERS];
33 //-----------------------------------------------------------------------------
34 // Local data
35 //-----------------------------------------------------------------------------
36 static int gDriverCnt = 0; // Total number of drivers
37 static GUID *gpSelectedDriverGUID;
39 //-----------------------------------------------------------------------------
40 // Name: DDEnumCallbackEx()
41 // Desc: This call back is used to determine the existing available DDraw
42 // devices, so the user can pick which one to run on.
43 //-----------------------------------------------------------------------------
44 BOOL WINAPI
45 DDEnumCallbackEx(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID pContext, HMONITOR hm)
46 {
47 if (pGUID)
48 {
49 Drivers[gDriverCnt].GUIDcopy = *pGUID;
50 Drivers[gDriverCnt].pGUID = &Drivers[gDriverCnt].GUIDcopy;
51 }
52 else
53 Drivers[gDriverCnt].pGUID = NULL;
54 Drivers[gDriverCnt].szDescription[127] = '\0';
55 Drivers[gDriverCnt].szName[127] = '\0';
56 strncpy(Drivers[gDriverCnt].szDescription, pDescription, 127);
57 strncpy(Drivers[gDriverCnt].szName, pName, 127);
58 Drivers[gDriverCnt].hm = hm;
59 if (gDriverCnt < MAX_DRIVERS)
60 gDriverCnt++;
61 else
62 return DDENUMRET_CANCEL;
63 return DDENUMRET_OK;
64 }
66 //-----------------------------------------------------------------------------
67 // Name: DDEnumCallback()
68 // Desc: This callback is used only with old versions of DDraw.
69 //-----------------------------------------------------------------------------
70 BOOL WINAPI
71 DDEnumCallback(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID context)
72 {
73 return (DDEnumCallbackEx(pGUID, pDescription, pName, context, NULL));
74 }
76 static HRESULT WINAPI addVideoMode(LPDDSURFACEDESC2 surf, LPVOID lpContext)
77 {
78 HWND h = (HWND)lpContext;
79 char buffer[50];
81 switch (surf->ddpfPixelFormat.dwRGBBitCount)
82 {
83 case 16:
84 case 24:
85 case 32:
86 if (surf->dwWidth >= 640 && surf->dwHeight >= 480)
87 {
88 sprintf(buffer, "%4dx%4dx%2d", surf->dwWidth, surf->dwHeight,
89 surf->ddpfPixelFormat.dwRGBBitCount);
90 int pos = ::SendMessage(h, LB_ADDSTRING, 0, (LPARAM)buffer);
91 ::SendMessage(h, LB_SETITEMDATA, pos,
92 (surf->ddpfPixelFormat.dwRGBBitCount << 24) |
93 ((surf->dwWidth & 4095) << 12) |
94 (surf->dwHeight & 4095));
95 }
96 }
98 return DDENUMRET_OK;
99 }
101 int winVideoModeSelect(CWnd *pWnd, GUID **guid)
102 {
103 HINSTANCE h = /**/ ::LoadLibrary("ddraw.dll");
105 // If ddraw.dll doesn't exist in the search path,
106 // then DirectX probably isn't installed, so fail.
107 if (!h)
108 return -1;
110 gDriverCnt = 0;
112 // Note that you must know which version of the
113 // function to retrieve (see the following text).
114 // For this example, we use the ANSI version.
115 LPDIRECTDRAWENUMERATEEX lpDDEnumEx;
116 lpDDEnumEx = (LPDIRECTDRAWENUMERATEEX)
117 GetProcAddress(h, "DirectDrawEnumerateExA");
119 // If the function is there, call it to enumerate all display
120 // devices attached to the desktop, and any non-display DirectDraw
121 // devices.
122 if (lpDDEnumEx)
123 lpDDEnumEx(DDEnumCallbackEx, NULL,
124 DDENUM_ATTACHEDSECONDARYDEVICES |
125 DDENUM_NONDISPLAYDEVICES
126 );
127 else
128 {
129 /*
130 * We must be running on an old version of DirectDraw.
131 * Therefore MultiMon isn't supported. Fall back on
132 * DirectDrawEnumerate to enumerate standard devices on a
133 * single-monitor system.
134 */
135 BOOL (WINAPI *lpDDEnum)(LPDDENUMCALLBACK, LPVOID);
137 lpDDEnum = (BOOL (WINAPI *)(LPDDENUMCALLBACK, LPVOID))
138 GetProcAddress(h, "DirectDrawEnumerateA");
139 if (lpDDEnum)
140 lpDDEnum(DDEnumCallback, NULL);
142 /* Note that it could be handy to let the OldCallback function
143 * be a wrapper for a DDEnumCallbackEx.
144 *
145 * Such a function would look like:
146 * BOOL FAR PASCAL OldCallback(GUID FAR *lpGUID,
147 * LPSTR pDesc,
148 * LPSTR pName,
149 * LPVOID pContext)
150 * {
151 * return Callback(lpGUID,pDesc,pName,pContext,NULL);
152 * }
153 */
154 }
156 int selected = 0;
158 if (gDriverCnt > 1)
159 {
160 VideoDriverSelect d(pWnd);
162 selected = d.DoModal();
164 if (selected == -1)
165 {
166 // If the library was loaded by calling LoadLibrary(),
167 // then you must use FreeLibrary() to let go of it.
168 /**/ ::FreeLibrary(h);
170 return -1;
171 }
172 }
174 HRESULT (WINAPI *DDrawCreateEx)(GUID *, LPVOID *, REFIID, IUnknown *);
175 DDrawCreateEx = (HRESULT (WINAPI *)(GUID *, LPVOID *, REFIID, IUnknown *))
176 GetProcAddress(h, "DirectDrawCreateEx");
178 LPDIRECTDRAW7 ddraw = NULL;
179 if (DDrawCreateEx)
180 {
181 HRESULT hret = DDrawCreateEx(Drivers[selected].pGUID,
182 (void * *)&ddraw,
183 IID_IDirectDraw7,
184 NULL);
185 if (hret != DD_OK)
186 {
187 systemMessage(0, "Error during DirectDrawCreateEx: %08x", hret);
188 /**/ ::FreeLibrary(h);
189 return -1;
190 }
191 }
192 else
193 {
194 // should not happen....
195 systemMessage(0, "Error getting DirectDrawCreateEx");
196 /**/ ::FreeLibrary(h);
197 return -1;
198 }
200 VideoMode dlg(ddraw, pWnd);
202 int res = dlg.DoModal();
204 if (res != -1)
205 {
206 *guid = Drivers[selected].pGUID;
207 }
208 ddraw->Release();
209 ddraw = NULL;
211 // If the library was loaded by calling LoadLibrary(),
212 // then you must use FreeLibrary() to let go of it.
213 /**/ ::FreeLibrary(h);
215 return res;
216 }
218 /////////////////////////////////////////////////////////////////////////////
219 // VideoMode dialog
221 VideoMode::VideoMode(LPDIRECTDRAW7 pDraw, CWnd*pParent /*=NULL*/)
222 : CDialog(VideoMode::IDD, pParent)
223 {
224 //{{AFX_DATA_INIT(VideoMode)
225 // NOTE: the ClassWizard will add member initialization here
226 //}}AFX_DATA_INIT
227 pDirectDraw = pDraw;
228 }
230 void VideoMode::DoDataExchange(CDataExchange*pDX)
231 {
232 CDialog::DoDataExchange(pDX);
233 //{{AFX_DATA_MAP(VideoMode)
234 DDX_Control(pDX, IDC_MODES, m_modes);
235 //}}AFX_DATA_MAP
236 }
238 BEGIN_MESSAGE_MAP(VideoMode, CDialog)
239 //{{AFX_MSG_MAP(VideoMode)
240 ON_LBN_SELCHANGE(IDC_MODES, OnSelchangeModes)
241 ON_BN_CLICKED(ID_CANCEL, OnCancel)
242 ON_BN_CLICKED(ID_OK, OnOk)
243 //}}AFX_MSG_MAP
244 END_MESSAGE_MAP()
246 /////////////////////////////////////////////////////////////////////////////
247 // VideoMode message handlers
249 void VideoMode::OnSelchangeModes()
250 {
251 int item = m_modes.GetCurSel();
253 GetDlgItem(ID_OK)->EnableWindow(item != -1);
254 }
256 void VideoMode::OnCancel()
257 {
258 EndDialog(-1);
259 }
261 void VideoMode::OnOk()
262 {
263 int cur = m_modes.GetCurSel();
265 if (cur != -1)
266 {
267 cur = m_modes.GetItemData(cur);
268 }
269 EndDialog(cur);
270 }
272 BOOL VideoMode::OnInitDialog()
273 {
274 CDialog::OnInitDialog();
276 // check for available fullscreen modes
277 pDirectDraw->EnumDisplayModes(DDEDM_STANDARDVGAMODES, NULL, m_modes.m_hWnd,
278 addVideoMode);
280 GetDlgItem(ID_OK)->EnableWindow(FALSE);
281 CenterWindow();
283 return TRUE; // return TRUE unless you set the focus to a control
284 // EXCEPTION: OCX Property Pages should return FALSE
285 }
287 /////////////////////////////////////////////////////////////////////////////
288 // VideoDriverSelect dialog
290 VideoDriverSelect::VideoDriverSelect(CWnd*pParent /*=NULL*/)
291 : CDialog(VideoDriverSelect::IDD, pParent)
292 {
293 //{{AFX_DATA_INIT(VideoDriverSelect)
294 // NOTE: the ClassWizard will add member initialization here
295 //}}AFX_DATA_INIT
296 }
298 void VideoDriverSelect::DoDataExchange(CDataExchange*pDX)
299 {
300 CDialog::DoDataExchange(pDX);
301 //{{AFX_DATA_MAP(VideoDriverSelect)
302 DDX_Control(pDX, IDC_DRIVERS, m_drivers);
303 //}}AFX_DATA_MAP
304 }
306 BEGIN_MESSAGE_MAP(VideoDriverSelect, CDialog)
307 //{{AFX_MSG_MAP(VideoDriverSelect)
308 ON_BN_CLICKED(ID_OK, OnOk)
309 ON_BN_CLICKED(ID_CANCEL, OnCancel)
310 ON_LBN_SELCHANGE(IDC_DRIVERS, OnSelchangeDrivers)
311 //}}AFX_MSG_MAP
312 END_MESSAGE_MAP()
314 /////////////////////////////////////////////////////////////////////////////
315 // VideoDriverSelect message handlers
317 void VideoDriverSelect::OnCancel()
318 {
319 EndDialog(-1);
320 }
322 void VideoDriverSelect::OnOk()
323 {
324 EndDialog(m_drivers.GetCurSel());
325 }
327 BOOL VideoDriverSelect::OnInitDialog()
328 {
329 CDialog::OnInitDialog();
331 for (int i = 0; i < gDriverCnt; i++)
332 {
333 m_drivers.AddString(Drivers[i].szDescription);
334 }
336 GetDlgItem(ID_OK)->EnableWindow(FALSE);
337 CenterWindow();
339 return TRUE; // return TRUE unless you set the focus to a control
340 // EXCEPTION: OCX Property Pages should return FALSE
341 }
343 void VideoDriverSelect::OnSelchangeDrivers()
344 {
345 GetDlgItem(ID_OK)->EnableWindow(m_drivers.GetCurSel() != -1);
346 }