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