1 /*
2 * Prefs_WIN32.i - Global preferences, WIN32 specific stuff
3 *
4 * Frodo (C) 1994-1997,2002 Christian Bauer
5 * WIN32 code by J. Richard Sladkey <jrs@world.std.com>
6 */
7
8 #include <commctrl.h>
9 #include "resource.h"
10
11 Prefs *Prefs::edit_prefs;
12 char *Prefs::edit_prefs_name;
13 HWND Prefs::hDlg;
14
15 #define STANDARD_PAGE 0
16 #define WIN32_PAGE 1
17
ShowEditor(bool,char * prefs_name)18 bool Prefs::ShowEditor(bool /* startup */, char *prefs_name)
19 {
20 edit_prefs = this;
21 edit_prefs_name = prefs_name;
22
23 PROPSHEETPAGE psp[2];
24
25 // Set up standard preferences property page.
26 psp[0].dwSize = sizeof(PROPSHEETPAGE);
27 psp[0].dwFlags = PSP_HASHELP;
28 psp[0].hInstance = hInstance;
29 psp[0].pszTemplate = MAKEINTRESOURCE(IDD_PREFERENCES_STANDARD);
30 psp[0].pszIcon = NULL;
31 psp[0].pfnDlgProc = StandardDialogProc;
32 psp[0].pszTitle = NULL;
33 psp[0].lParam = 0;
34 psp[0].pfnCallback = NULL;
35
36 // Set up WIN32 preferences property page.
37 psp[1].dwSize = sizeof(PROPSHEETPAGE);
38 psp[1].dwFlags = PSP_HASHELP;
39 psp[1].hInstance = hInstance;
40 psp[1].pszTemplate = MAKEINTRESOURCE(IDD_PREFERENCES_WIN32);
41 psp[1].pszIcon = NULL;
42 psp[1].pfnDlgProc = WIN32DialogProc;
43 psp[1].pszTitle = NULL;
44 psp[1].lParam = 0;
45 psp[1].pfnCallback = NULL;
46
47 // Setup property sheet.
48 PROPSHEETHEADER psh;
49 psh.dwSize = sizeof(PROPSHEETHEADER);
50 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
51 psh.hwndParent = hwnd;
52 psh.hInstance = hInstance;
53 psh.pszIcon = NULL;
54 psh.pszCaption = "Preferences";
55 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
56 psh.nStartPage = 0;
57 psh.ppsp = psp;
58 psh.pfnCallback = NULL;
59
60 int result = PropertySheet(&psh);
61
62 if (result == -1)
63 return FALSE;
64 return result;
65 }
66
StandardDialogProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)67 BOOL CALLBACK Prefs::StandardDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
68 {
69 return edit_prefs->DialogProc(STANDARD_PAGE, hDlg, message, wParam, lParam);
70 }
71
WIN32DialogProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)72 BOOL CALLBACK Prefs::WIN32DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
73 {
74 return edit_prefs->DialogProc(WIN32_PAGE, hDlg, message, wParam, lParam);
75 }
76
DialogProc(int page,HWND hDlg_arg,UINT message,WPARAM wParam,LPARAM lParam)77 BOOL Prefs::DialogProc(int page, HWND hDlg_arg, UINT message, WPARAM wParam, LPARAM lParam)
78 {
79 hDlg = hDlg_arg;
80
81 switch (message) {
82
83 case WM_INITDIALOG:
84 SetupControls(page);
85 SetValues(page);
86 return TRUE;
87
88 case WM_COMMAND:
89 switch (LOWORD(wParam)) {
90
91 case IDC_BROWSE8:
92 BrowseForDevice(IDC_DEVICE8);
93 break;
94
95 case IDC_BROWSE9:
96 BrowseForDevice(IDC_DEVICE9);
97 break;
98
99 case IDC_BROWSE10:
100 BrowseForDevice(IDC_DEVICE10);
101 break;
102
103 case IDC_BROWSE11:
104 BrowseForDevice(IDC_DEVICE11);
105 break;
106
107 }
108 return TRUE;
109
110 case WM_NOTIFY:
111 {
112 NMHDR *pnmhdr = (NMHDR *) lParam;
113 switch (pnmhdr->code) {
114
115 case PSN_KILLACTIVE:
116 SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
117 break;
118
119 case PSN_APPLY:
120 GetValues(page);
121 break;
122
123 case PSN_HELP:
124 PostMessage(hwnd, WM_COMMAND, ID_HELP_SETTINGS, 0);
125 break;
126 }
127 }
128 return TRUE;
129 }
130
131 return FALSE;
132 }
133
134 #define SetupSpin(id, upper, lower) SendMessage(GetDlgItem(hDlg, id), UDM_SETRANGE, 0, MAKELONG(upper, lower))
135 #define SetupSpinIncrement(id, increment) (udaccel.nSec = 0, udaccel.nInc = increment, SendMessage(GetDlgItem(hDlg, id), UDM_SETACCEL, 1, (LPARAM) &udaccel))
136 #define SetupComboClear(id) SendMessage(GetDlgItem(hDlg, id), CB_RESETCONTENT, 0, 0)
137 #define SetupComboAdd(id, string) SendMessage(GetDlgItem(hDlg, id), CB_ADDSTRING, 0, (LPARAM) string)
138
SetupControls(int page)139 void Prefs::SetupControls(int page)
140 {
141 UDACCEL udaccel;
142 switch (page) {
143
144 case STANDARD_PAGE:
145 SetupSpin(IDC_NORMAL_SPIN, 200, 1);
146 SetupSpin(IDC_BADLINES_SPIN, 200, 1);
147 SetupSpin(IDC_CIA_SPIN, 200, 1);
148 SetupSpin(IDC_FLOPPY_SPIN, 200, 1);
149 SetupSpin(IDC_DRAWEVERY_SPIN, 10, 1);
150 SetupComboClear(IDC_REUSIZE);
151 SetupComboAdd(IDC_REUSIZE, "None");
152 SetupComboAdd(IDC_REUSIZE, "128k");
153 SetupComboAdd(IDC_REUSIZE, "256k");
154 SetupComboAdd(IDC_REUSIZE, "512k");
155 break;
156
157 case WIN32_PAGE:
158 SetupComboClear(IDC_VIEWPORT);
159 SetupComboAdd(IDC_VIEWPORT, "Default");
160 SetupComboAdd(IDC_VIEWPORT, "320x200");
161 SetupComboAdd(IDC_VIEWPORT, "336x216");
162 SetupComboAdd(IDC_VIEWPORT, "384x272");
163 SetupComboClear(IDC_DISPLAYMODE);
164 SetupComboAdd(IDC_DISPLAYMODE, "Default");
165 {
166 C64Display *TheDisplay = TheApp->TheC64->TheDisplay;
167 int n = TheDisplay->GetNumDisplayModes();
168 const C64Display::DisplayMode *modes =
169 TheDisplay->GetDisplayModes();
170 for (int i = 0; i < n; i++) {
171 char mode[64];
172 sprintf(mode, "%dx%dx%d%s",
173 modes[i].x, modes[i].y, modes[i].depth,
174 modes[i].modex ? " (ModeX)" : "");
175 SetupComboAdd(IDC_DISPLAYMODE, mode);
176 }
177 }
178 SetupSpin(IDC_SCALINGNUMERATOR_SPIN, 16, 1);
179 SetupSpin(IDC_SCALINGDENOMINATOR_SPIN, 4, 1);
180 SetupSpin(IDC_LATENCYMIN_SPIN, 1000, 20);
181 SetupSpinIncrement(IDC_LATENCYMIN_SPIN, 20);
182 SetupSpin(IDC_LATENCYMAX_SPIN, 1000, 20);
183 SetupSpinIncrement(IDC_LATENCYMAX_SPIN, 20);
184 SetupSpin(IDC_LATENCYAVG_SPIN, 1000, 20);
185 SetupSpinIncrement(IDC_LATENCYAVG_SPIN, 20);
186 break;
187 }
188 }
189
190 #define SetText(id, val) SetDlgItemText(hDlg, id, val)
191 #define SetInteger(id, val) SetDlgItemInt(hDlg, id, val, FALSE)
192 #define SetCheckBox(id, val) CheckDlgButton(hDlg, id, (val) ? BST_CHECKED : BST_UNCHECKED)
193 #define SetCombo(id, val) SendMessage(GetDlgItem(hDlg, id), CB_SELECTSTRING, 0, (LPARAM) val)
194
SetValues(int page)195 void Prefs::SetValues(int page)
196 {
197 const char *str;
198 switch (page) {
199
200 case STANDARD_PAGE:
201 SetText(IDC_DEVICE8, DrivePath[0]);
202 SetText(IDC_DEVICE9, DrivePath[1]);
203 SetText(IDC_DEVICE10, DrivePath[2]);
204 SetText(IDC_DEVICE11, DrivePath[3]);
205
206 SetInteger(IDC_NORMAL, NormalCycles);
207 SetInteger(IDC_BADLINES, BadLineCycles);
208 SetInteger(IDC_CIA, CIACycles);
209 SetInteger(IDC_FLOPPY, FloppyCycles);
210 SetInteger(IDC_DRAWEVERY, SkipFrames);
211 switch (REUSize) {
212 case REU_NONE: str = "None"; break;
213 case REU_128K: str = "128k"; break;
214 case REU_256K: str = "256k"; break;
215 case REU_512K: str = "512k"; break;
216 }
217 SetCombo(IDC_REUSIZE, str);
218
219 SetCheckBox(IDC_LIMITSPEED, LimitSpeed);
220 SetCheckBox(IDC_SPRITES, SpritesOn);
221 SetCheckBox(IDC_SPRITECOLLISIONS, SpriteCollisions);
222 SetCheckBox(IDC_JOYSTICK1, Joystick1On);
223 SetCheckBox(IDC_JOYSTICK2, Joystick2On);
224 SetCheckBox(IDC_SWAPJOYSTICKS, JoystickSwap);
225 SetCheckBox(IDC_FASTRESET, FastReset);
226 SetCheckBox(IDC_CIAIRQHACK, CIAIRQHack);
227 SetCheckBox(IDC_MAPSLASH, MapSlash);
228 SetCheckBox(IDC_SIDEMULATION, SIDType == SIDTYPE_DIGITAL);
229 SetCheckBox(IDC_SIDFILTERS, SIDFilters);
230 SetCheckBox(IDC_1541EMULATION, Emul1541Proc);
231 break;
232
233 case WIN32_PAGE:
234 SetCheckBox(IDC_FULLSCREEN, DisplayType == DISPTYPE_SCREEN);
235 SetCheckBox(IDC_SYSTEMMEMORY, SystemMemory);
236 SetCheckBox(IDC_ALWAYSCOPY, AlwaysCopy);
237 SetText(IDC_VIEWPORT, ViewPort);
238 SetText(IDC_DISPLAYMODE, DisplayMode);
239
240 SetCheckBox(IDC_HIDECURSOR, HideCursor);
241 SetCheckBox(IDC_SYSTEMKEYS, SystemKeys);
242 SetInteger(IDC_SCALINGNUMERATOR, ScalingNumerator);
243 SetInteger(IDC_SCALINGDENOMINATOR, ScalingDenominator);
244
245 SetCheckBox(IDC_DIRECTSOUND, DirectSound);
246 SetCheckBox(IDC_EXCLUSIVESOUND, ExclusiveSound);
247 SetInteger(IDC_LATENCYMIN, LatencyMin);
248 SetInteger(IDC_LATENCYMAX, LatencyMax);
249 SetInteger(IDC_LATENCYAVG, LatencyAvg);
250
251 SetCheckBox(IDC_AUTOPAUSE, AutoPause);
252 SetCheckBox(IDC_PREFSATSTARTUP, PrefsAtStartup);
253 SetCheckBox(IDC_SHOWLEDS, ShowLEDs);
254 break;
255 }
256 }
257
258 #define GetCheckBox(id, val) (val = IsDlgButtonChecked(hDlg, id) == BST_CHECKED)
259 #define GetInteger(id, val) (val = GetDlgItemInt(hDlg, id, NULL, FALSE))
260 #define GetText(id, val) GetDlgItemText(hDlg, id, val, sizeof(val))
261
GetValues(int page)262 void Prefs::GetValues(int page)
263 {
264 BOOL temp;
265 char str[256];
266 switch (page) {
267
268 case STANDARD_PAGE:
269 GetText(IDC_DEVICE8, DrivePath[0]);
270 GetText(IDC_DEVICE9, DrivePath[1]);
271 GetText(IDC_DEVICE10, DrivePath[2]);
272 GetText(IDC_DEVICE11, DrivePath[3]);
273
274 GetInteger(IDC_NORMAL, NormalCycles);
275 GetInteger(IDC_BADLINES, BadLineCycles);
276 GetInteger(IDC_CIA, CIACycles);
277 GetInteger(IDC_FLOPPY, FloppyCycles);
278 GetInteger(IDC_DRAWEVERY, SkipFrames);
279 GetText(IDC_REUSIZE, str);
280 if (strcmp(str, "None") == 0)
281 REUSize = REU_NONE;
282 else if (strcmp(str, "128k") == 0)
283 REUSize = REU_128K;
284 else if (strcmp(str, "256k") == 0)
285 REUSize = REU_256K;
286 else if (strcmp(str, "512k") == 0)
287 REUSize = REU_512K;
288
289 GetCheckBox(IDC_LIMITSPEED, LimitSpeed);
290 GetCheckBox(IDC_SPRITES, SpritesOn);
291 GetCheckBox(IDC_SPRITECOLLISIONS, SpriteCollisions);
292 GetCheckBox(IDC_JOYSTICK1, Joystick1On);
293 GetCheckBox(IDC_JOYSTICK2, Joystick2On);
294 GetCheckBox(IDC_SWAPJOYSTICKS, JoystickSwap);
295 GetCheckBox(IDC_FASTRESET, FastReset);
296 GetCheckBox(IDC_CIAIRQHACK, CIAIRQHack);
297 GetCheckBox(IDC_MAPSLASH, MapSlash);
298 GetCheckBox(IDC_SIDEMULATION, temp);
299 SIDType = temp ? SIDTYPE_DIGITAL : SIDTYPE_NONE;
300 GetCheckBox(IDC_SIDFILTERS, SIDFilters);
301 GetCheckBox(IDC_1541EMULATION, Emul1541Proc);
302 break;
303
304 case WIN32_PAGE:
305 GetCheckBox(IDC_FULLSCREEN, temp);
306 DisplayType = temp ? DISPTYPE_SCREEN : DISPTYPE_WINDOW;
307 GetCheckBox(IDC_SYSTEMMEMORY, SystemMemory);
308 GetCheckBox(IDC_ALWAYSCOPY, AlwaysCopy);
309 GetText(IDC_VIEWPORT, ViewPort);
310 GetText(IDC_DISPLAYMODE, DisplayMode);
311
312 GetCheckBox(IDC_HIDECURSOR, HideCursor);
313 GetCheckBox(IDC_SYSTEMKEYS, SystemKeys);
314 GetInteger(IDC_SCALINGNUMERATOR, ScalingNumerator);
315 GetInteger(IDC_SCALINGDENOMINATOR, ScalingDenominator);
316
317 GetCheckBox(IDC_DIRECTSOUND, DirectSound);
318 GetCheckBox(IDC_EXCLUSIVESOUND, ExclusiveSound);
319 GetInteger(IDC_LATENCYMIN, LatencyMin);
320 GetInteger(IDC_LATENCYMAX, LatencyMax);
321 GetInteger(IDC_LATENCYAVG, LatencyAvg);
322
323 GetCheckBox(IDC_AUTOPAUSE, AutoPause);
324 GetCheckBox(IDC_PREFSATSTARTUP, PrefsAtStartup);
325 GetCheckBox(IDC_SHOWLEDS, ShowLEDs);
326 break;
327 }
328
329 for (int i = 0; i < 4; i++) {
330 DriveType[i] = DRVTYPE_DIR;
331 int length = strlen(DrivePath[i]);
332 if (length >= 4) {
333 char *suffix = DrivePath[i] + length - 4;
334 if (stricmp(suffix, ".t64") == 0)
335 DriveType[i] = DRVTYPE_T64;
336 else if (stricmp(suffix, ".d64") == 0)
337 DriveType[i] = DRVTYPE_D64;
338 }
339 }
340 }
341
BrowseForDevice(int id)342 void Prefs::BrowseForDevice(int id)
343 {
344 char filename[256];
345 GetDlgItemText(hDlg, id, filename, sizeof(filename));
346 OPENFILENAME ofn;
347 memset(&ofn, 0, sizeof(ofn));
348 ofn.lStructSize = sizeof(ofn);
349 ofn.hwndOwner = hDlg;
350 ofn.hInstance = hInstance;
351 ofn.lpstrFilter =
352 "All Files (*.*)\0*.*\0"
353 "All C64 Files (*.d64;*.t64)\0*.d64;*.t64\0"
354 "D64 Files (*.d64)\0*.d64\0"
355 "T64 Files (*.t64)\0*.t64\0"
356 ;
357 ofn.lpstrCustomFilter = NULL;
358 ofn.nMaxCustFilter = 0;
359 ofn.nFilterIndex = 1;
360 ofn.lpstrFile = filename;
361 ofn.nMaxFile = sizeof(filename);
362 ofn.lpstrFileTitle = NULL;
363 ofn.nMaxFileTitle = 0;
364 ofn.lpstrInitialDir = NULL;
365 ofn.lpstrTitle = "Set Device";
366 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_NOTESTFILECREATE |
367 OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_SHAREAWARE;
368 ofn.nFileOffset = 0;
369 ofn.nFileExtension = 0;
370 ofn.lpstrDefExt = NULL;
371 ofn.lpfnHook = NULL;
372 ofn.lpTemplateName = NULL;
373 BOOL result = GetOpenFileName(&ofn);
374 if (result) {
375 const char *ext = filename + ofn.nFileExtension;
376 if (stricmp(ext, "d64") != 0 && stricmp(ext, "t64") != 0)
377 filename[ofn.nFileOffset - 1] = '\0';
378 char cwd[256];
379 GetCurrentDirectory(sizeof(cwd), cwd);
380 int cwd_len = strlen(cwd);
381 if (cwd_len > 0 && cwd[cwd_len - 1] != '\\') {
382 strcat(cwd, "\\");
383 cwd_len++;
384 }
385 if (strnicmp(filename, cwd, cwd_len) == 0)
386 SetDlgItemText(hDlg, id, filename + cwd_len);
387 else
388 SetDlgItemText(hDlg, id, filename);
389 }
390 }
391