|
|
1.1 root 1: /*
2: Hatari - PrefsController.m
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
7: Preferences window controller implementation file
8:
9: Feb-Mar 2006, Sébastien Molines - Created
1.1.1.2 root 10: Jan 2006, Sébastien Molines - Updated for recent emulator updates
1.1 root 11: */
12:
13: // TODO: Set the default paths to MacOS-friendly values
14: // TODO: Move hardcoded string to localizable resources (e.g. string "Reset the emulator?")
15:
16:
17: #import "PrefsController.h"
18: #import "Shared.h"
19:
20: #include "main.h"
21: #include "configuration.h"
1.1.1.3 root 22: #include "change.h"
1.1 root 23: #include "dialog.h"
24: #include "file.h"
25: #include "floppy.h"
26: #include "screen.h"
27: #include "sdlgui.h"
28:
29: // Macros to transfer data between Cocoa controls and Hatari data structures
30: #define EXPORT_TEXTFIELD(nstextfield, target) GuiOsx_ExportPathString([nstextfield stringValue], target, sizeof((target)))
31: #define EXPORT_SWITCH(nsbutton, target) target = ([(nsbutton) state] == NSOnState)
32: #define EXPORT_RADIO(nsmatrix, target) target = [[(nsmatrix) selectedCell] tag]
33: #define EXPORT_DROPDOWN(nspopupbutton, target) target = [[(nspopupbutton) selectedItem] tag]
1.1.1.3 root 34: #define EXPORT_SLIDER(nsslider, target) target = [(nsslider) intValue]
35:
1.1 root 36: #define IMPORT_TEXTFIELD(nstextfield, source) [(nstextfield) setStringValue:[[NSString stringWithCString:(source)] stringByAbbreviatingWithTildeInPath]]
37: #define IMPORT_SWITCH(nsbutton, source) [(nsbutton) setState:((source))? NSOnState : NSOffState]
38: #define IMPORT_RADIO(nsmatrix, source) [(nsmatrix) selectCellWithTag:(source)]
39: #define IMPORT_DROPDOWN(nspopupbutton, source) [(nspopupbutton) selectItemAtIndex:[(nspopupbutton) indexOfItemWithTag:(source)]]
1.1.1.3 root 40: #define IMPORT_SLIDER(nsslider,source) [(nsslider) setIntValue:source]
41:
42:
43: // Back up of the current configuration parameters
44: CNF_PARAMS CurrentParams;
45:
1.1 root 46:
47: // Keys to be listed in the Joysticks dropdowns
48: SDLKey Preferences_KeysForJoysticks[] =
49: {
50: SDLK_BACKSPACE,
51: SDLK_TAB,
52: SDLK_CLEAR,
53: SDLK_RETURN,
54: SDLK_PAUSE,
55: SDLK_ESCAPE,
56: SDLK_SPACE,
57: SDLK_EXCLAIM,
58: SDLK_QUOTEDBL,
59: SDLK_HASH,
60: SDLK_DOLLAR,
61: SDLK_AMPERSAND,
62: SDLK_QUOTE,
63: SDLK_LEFTPAREN,
64: SDLK_RIGHTPAREN,
65: SDLK_ASTERISK,
66: SDLK_PLUS,
67: SDLK_COMMA,
68: SDLK_MINUS,
69: SDLK_PERIOD,
70: SDLK_SLASH,
71: SDLK_0,
72: SDLK_1,
73: SDLK_2,
74: SDLK_3,
75: SDLK_4,
76: SDLK_5,
77: SDLK_6,
78: SDLK_7,
79: SDLK_8,
80: SDLK_9,
81: SDLK_COLON,
82: SDLK_SEMICOLON,
83: SDLK_LESS,
84: SDLK_EQUALS,
85: SDLK_GREATER,
86: SDLK_QUESTION,
87: SDLK_AT,
88: SDLK_LEFTBRACKET,
89: SDLK_BACKSLASH,
90: SDLK_RIGHTBRACKET,
91: SDLK_CARET,
92: SDLK_UNDERSCORE,
93: SDLK_BACKQUOTE,
94: SDLK_a,
95: SDLK_b,
96: SDLK_c,
97: SDLK_d,
98: SDLK_e,
99: SDLK_f,
100: SDLK_g,
101: SDLK_h,
102: SDLK_i,
103: SDLK_j,
104: SDLK_k,
105: SDLK_l,
106: SDLK_m,
107: SDLK_n,
108: SDLK_o,
109: SDLK_p,
110: SDLK_q,
111: SDLK_r,
112: SDLK_s,
113: SDLK_t,
114: SDLK_u,
115: SDLK_v,
116: SDLK_w,
117: SDLK_x,
118: SDLK_y,
119: SDLK_z,
120: SDLK_DELETE,
121: SDLK_KP0,
122: SDLK_KP1,
123: SDLK_KP2,
124: SDLK_KP3,
125: SDLK_KP4,
126: SDLK_KP5,
127: SDLK_KP6,
128: SDLK_KP7,
129: SDLK_KP8,
130: SDLK_KP9,
131: SDLK_KP_PERIOD,
132: SDLK_KP_DIVIDE,
133: SDLK_KP_MULTIPLY,
134: SDLK_KP_MINUS,
135: SDLK_KP_PLUS,
136: SDLK_KP_ENTER,
137: SDLK_KP_EQUALS,
138: SDLK_UP,
139: SDLK_DOWN,
140: SDLK_RIGHT,
141: SDLK_LEFT,
142: SDLK_INSERT,
143: SDLK_HOME,
144: SDLK_END,
145: SDLK_PAGEUP,
146: SDLK_PAGEDOWN,
147: SDLK_F1,
148: SDLK_F2,
149: SDLK_F3,
150: SDLK_F4,
151: SDLK_F5,
152: SDLK_F6,
153: SDLK_F7,
154: SDLK_F8,
155: SDLK_F9,
156: SDLK_F10,
157: SDLK_F11,
158: SDLK_F12,
159: SDLK_F13,
160: SDLK_F14,
161: SDLK_F15,
162: SDLK_NUMLOCK,
163: SDLK_CAPSLOCK,
164: SDLK_SCROLLOCK,
165: SDLK_RSHIFT,
166: SDLK_LSHIFT,
167: SDLK_RCTRL,
168: SDLK_LCTRL,
169: SDLK_RALT,
170: SDLK_LALT,
171: SDLK_RMETA,
172: SDLK_LMETA,
173: SDLK_LSUPER,
174: SDLK_RSUPER,
175: SDLK_MODE,
176: SDLK_COMPOSE,
177: SDLK_HELP,
178: SDLK_PRINT,
179: SDLK_SYSREQ,
180: SDLK_BREAK,
181: SDLK_MENU,
182: SDLK_POWER,
183: SDLK_EURO,
184: SDLK_UNDO
185: };
186:
187: size_t Preferences_cKeysForJoysticks = sizeof(Preferences_KeysForJoysticks) / sizeof(Preferences_KeysForJoysticks[0]);
188:
189:
190: @implementation PrefsController
191:
192:
193: /*-----------------------------------------------------------------------*/
194: /*
195: Helper method for Choose buttons
196: Returns: TRUE is the user selected a path, FALSE if he/she aborted
197: */
198: - (BOOL)choosePathForControl:(NSTextField*)textField chooseDirectories:(bool)chooseDirectories defaultInitialDir:(NSString*)defaultInitialDir
199: {
200: // Create and configure an OpenPanel
201: NSOpenPanel *openPanel = [NSOpenPanel openPanel];
202: [openPanel setCanChooseDirectories: chooseDirectories];
203: [openPanel setCanChooseFiles: !chooseDirectories];
204:
205: NSString *directoryToOpen;
206: NSString *fileToPreselect;
207: NSString *oldPath = [textField stringValue];
208: if ((oldPath != nil) && ([oldPath length] > 0))
209: {
210: // There is existing path: we will open its directory with its file pre-selected.
211: directoryToOpen = [oldPath stringByDeletingLastPathComponent];
212: fileToPreselect = [oldPath lastPathComponent];
213: }
214: else
215: {
216: // Currently no path: we will open the user's directory with no file selected.
217: directoryToOpen = [defaultInitialDir stringByExpandingTildeInPath];
218: fileToPreselect = nil;
219: }
220:
221: // Run the OpenPanel, then check if the user clicked OK and selected at least one file
222: if ( (NSOKButton == [openPanel runModalForDirectory:directoryToOpen file:fileToPreselect types:nil] )
223: && ([[openPanel filenames] count] > 0) )
224: {
225: // Get the path to the selected file
226: NSString *path = [[openPanel filenames] objectAtIndex:0];
227:
228: // Set the control to it (abbreviated if possible)
229: [textField setStringValue:[path stringByAbbreviatingWithTildeInPath]];
230:
231: // Signal completion
1.1.1.5 ! root 232: return true;
1.1 root 233: }
234:
235: // Signal that the selection was aborted
236: return FALSE;
237: }
238:
239:
240: /*-----------------------------------------------------------------------*/
241: /*
242: Helper method to insert a floppy image
243: TODO: Add code to restrict to known file types
244: */
245: - (void)insertFloppyImageIntoDrive:(int)drive forTextField:(NSTextField*)floppyTextField
246: {
247: if ([self choosePathForControl:floppyTextField chooseDirectories:FALSE defaultInitialDir:[defaultImagesLocation stringValue]])
248: {
249: // Get the full path to the selected file
250: NSString *path = [[floppyTextField stringValue] stringByExpandingTildeInPath];
251:
252: // Make a non-const C string out of it
253: const char* constSzPath = [path cString];
254: size_t cbPath = strlen(constSzPath) + 1;
255: char szPath[cbPath];
256: strncpy(szPath, constSzPath, cbPath);
257:
258: // Insert the floppy image at this path
1.1.1.3 root 259: Floppy_SetDiskFileName(drive, szPath, NULL);
1.1 root 260: }
261: }
262:
263:
264: /*-----------------------------------------------------------------------*/
265: /*
266: Methods for all the "Choose" buttons
267: */
268: - (IBAction)chooseCartridgeImage:(id)sender;
269: {
270: [self choosePathForControl: cartridgeImage chooseDirectories:FALSE defaultInitialDir:@"~"];
271: }
272:
273: - (IBAction)chooseDefaultImagesLocation:(id)sender
274: {
275: [self choosePathForControl: defaultImagesLocation chooseDirectories:TRUE defaultInitialDir:@"~"];
276: }
277:
278: - (IBAction)chooseFloppyImageA:(id)sender
279: {
280: [self insertFloppyImageIntoDrive:0 forTextField: floppyImageA];
281: }
282:
283: - (IBAction)chooseFloppyImageB:(id)sender
284: {
285: [self insertFloppyImageIntoDrive:1 forTextField: floppyImageB];
286: }
287:
288: - (IBAction)chooseGemdosImage:(id)sender
289: {
290: [self choosePathForControl: gemdosImage chooseDirectories:TRUE defaultInitialDir:@"~"];
291: }
292:
293: - (IBAction)chooseHdImage:(id)sender
294: {
295: [self choosePathForControl: hdImage chooseDirectories:FALSE defaultInitialDir:@"~"];
296: }
297:
1.1.1.5 ! root 298: - (IBAction)chooseIdeHdImage:(id)sender
! 299: {
! 300: [self choosePathForControl: ideHdImage chooseDirectories:FALSE defaultInitialDir:@"~"];
! 301: }
! 302:
1.1 root 303: - (IBAction)chooseKeyboardMappingFile:(id)sender
304: {
305: [self choosePathForControl: keyboardMappingFile chooseDirectories:FALSE defaultInitialDir:@"~"];
306: }
307:
308: - (IBAction)chooseMidiOutputFile:(id)sender
309: {
310: [self choosePathForControl: writeMidiToFile chooseDirectories:FALSE defaultInitialDir:@"~"];
311: }
312:
313: - (IBAction)choosePrintToFile:(id)sender
314: {
315: [self choosePathForControl: printToFile chooseDirectories:FALSE defaultInitialDir:@"~"];
316: }
317:
318: - (IBAction)chooseRS232InputFile:(id)sender
319: {
320: [self choosePathForControl: readRS232FromFile chooseDirectories:FALSE defaultInitialDir:@"~"];
321: }
322:
323: - (IBAction)chooseRS232OutputFile:(id)sender
324: {
325: [self choosePathForControl: writeRS232ToFile chooseDirectories:FALSE defaultInitialDir:@"~"];
326: }
327:
328: - (IBAction)chooseTosImage:(id)sender;
329: {
330: [self choosePathForControl: tosImage chooseDirectories:FALSE defaultInitialDir:@"~"];
331: }
332:
333:
334: /*-----------------------------------------------------------------------*/
335: /*
336: Methods for the "Eject" buttons
337: */
338: - (IBAction)ejectFloppyA:(id)sender
339: {
1.1.1.3 root 340: Floppy_SetDiskFileNameNone(0);
1.1 root 341:
342: // Refresh the control
343: [floppyImageA setStringValue:@""];
344: }
345:
346: - (IBAction)ejectFloppyB:(id)sender
347: {
1.1.1.3 root 348: Floppy_SetDiskFileNameNone(1);
1.1 root 349:
350: // Refresh the control
351: [floppyImageB setStringValue:@""];
352: }
353:
354: - (IBAction)ejectGemdosImage:(id)sender
355: {
1.1.1.3 root 356: // Clear the control. Later. saveAllControls will set the ConfigureParams accordingly to signal this is ejected
1.1 root 357: [gemdosImage setStringValue:@""];
358: }
359:
360: - (IBAction)ejectHdImage:(id)sender
361: {
1.1.1.3 root 362: // Clear the control. Later. saveAllControls will set the ConfigureParams accordingly to signal this is ejected
1.1 root 363: [hdImage setStringValue:@""];
364: }
365:
1.1.1.5 ! root 366: - (IBAction)ejectIdeHdImage:(id)sender
! 367: {
! 368: // Clear the control. Later. saveAllControls will set the ConfigureParams accordingly to signal this is ejected
! 369: [ideHdImage setStringValue:@""];
! 370: }
! 371:
1.1 root 372:
373: /*-----------------------------------------------------------------------*/
1.1.1.3 root 374: /**
375: * Methods for the "Load Config" button
376: */
377:
378: - (IBAction)loadConfigFrom:(id)sender
379: {
380: NSString *ConfigFile = [NSString stringWithCString:(sConfigFileName)];
381: NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
382:
383: if ( [ openPanel runModalForDirectory:nil file:ConfigFile types:nil ] )
384: {
385: ConfigFile = [ [ openPanel filenames ] objectAtIndex:0 ];
386: }
387: else
388: {
389: ConfigFile = nil;
390: }
391:
392: if (ConfigFile != nil)
393: {
394: // Make a non-const C string out of it
395: const char* constSzPath = [ConfigFile cString];
396: size_t cbPath = strlen(constSzPath) + 1;
397: char szPath[cbPath];
398: strncpy(szPath, constSzPath, cbPath);
399:
400: // Load the config into ConfigureParams
401: Configuration_Load(szPath);
402: strcpy(sConfigFileName,szPath);
403: // Refresh all the controls to match ConfigureParams
404: [self setAllControls];
405: }
1.1 root 406: }
407:
1.1.1.3 root 408: /**
409: * Methods for the "Load Config" button
410: */
411: - (IBAction)saveConfigAs:(id)sender
1.1 root 412: {
1.1.1.3 root 413: char splitpath[FILENAME_MAX], splitname[FILENAME_MAX];
414:
415: // Update the ConfigureParams from the controls
1.1 root 416: [self saveAllControls];
417:
1.1.1.3 root 418: File_SplitPath(sConfigFileName, splitpath, splitname, NULL);
419:
420: NSSavePanel *savePanel = [ NSSavePanel savePanel ];
421:
422: NSString* defaultDir = [NSString stringWithCString:splitpath];
423: NSString *ConfigFile = [NSString stringWithCString:splitname];
424:
425: if ( ![ savePanel runModalForDirectory:defaultDir file:ConfigFile ] )
426: {
427: return;
428: }
429:
430: ConfigFile = [ savePanel filename ];
431:
432: if (ConfigFile != nil)
433: {
434: // Make a non-const C string out of it
435: const char* constSzPath = [ConfigFile cString];
436: size_t cbPath = strlen(constSzPath) + 1;
437: char szPath[cbPath];
438: strncpy(szPath, constSzPath, cbPath);
439:
440: // Save the config from ConfigureParams
441: strcpy(sConfigFileName, szPath);
442: Configuration_Save();
443: }
1.1 root 444: }
445:
446:
447: /*-----------------------------------------------------------------------*/
448: /*
449: Commits and closes
450: */
451: - (IBAction)commitAndClose:(id)sender
452: {
1.1.1.5 ! root 453: BOOL applyChanges = true;
1.1 root 454:
455: // The user clicked OK
456: [self saveAllControls];
457:
458: // If a reset is required, ask the user first
1.1.1.3 root 459: if (Change_DoNeedReset(&CurrentParams, &ConfigureParams))
1.1 root 460: {
461: applyChanges = ( 0 == NSRunAlertPanel (@"Reset the emulator?",
462: @"The emulator must be reset in order to apply your changes.\nAll current work will be lost.",
463: @"Don't reset", @"Reset", nil) );
464: }
465:
466: // Commit the new configuration
467: if (applyChanges)
468: {
1.1.1.5 ! root 469: Change_CopyChangedParamsToConfiguration(&CurrentParams, &ConfigureParams, false);
1.1.1.3 root 470: }
471: else
472: {
473: ConfigureParams = CurrentParams;
1.1 root 474: }
475:
476: // Close the window
477: [window close];
478: }
479:
480: - (void)initKeysDropDown:(NSPopUpButton*)dropDown
481: {
482: [dropDown removeAllItems];
483: int i;
484: for (i = 0; i < Preferences_cKeysForJoysticks; i++)
485: {
486: SDLKey key = Preferences_KeysForJoysticks[i];
487: const char* szKeyName = SDL_GetKeyName(key);
488: [dropDown addItemWithTitle:[[NSString stringWithCString:szKeyName] capitalizedString]];
489: [[dropDown lastItem] setTag:key];
490: }
491: }
492:
493:
494: /*-----------------------------------------------------------------------*/
495: /*
496: Displays the Preferences dialog
497: */
498: - (IBAction)loadPrefs:(id)sender
499: {
500: if (!bInitialized)
501: {
502: // Note: These inits cannot be done in awakeFromNib as by this time SDL is not yet initialized.
503:
504: // Fill the keyboard dropdowns
505: [self initKeysDropDown:joystickUp];
506: [self initKeysDropDown:joystickRight];
507: [self initKeysDropDown:joystickDown];
508: [self initKeysDropDown:joystickLeft];
509: [self initKeysDropDown:joystickFire];
510:
511: // Get and store the number of real joysticks
512: cRealJoysticks = SDL_NumJoysticks();
513:
514: // Fill the real joysticks dropdown, if any are available
515: if (cRealJoysticks > 0)
516: {
517: [realJoystick removeAllItems];
518: int i;
519: for (i = 0; i < cRealJoysticks; i++)
520: {
521: const char* szJoystickName = SDL_JoystickName(i);
522: [realJoystick addItemWithTitle:[[NSString stringWithCString:szJoystickName] capitalizedString]];
523: [[realJoystick lastItem] setTag:i];
524: }
525: }
526: else // No real joysticks: Disable the controls
527: {
528: [[joystickMode cellWithTag:1] setEnabled:FALSE];
529: [realJoystick setEnabled:FALSE];
530: }
531:
1.1.1.5 ! root 532: bInitialized = true;
1.1 root 533: }
534:
535:
1.1.1.3 root 536: // Backup of configuration settings to CurrentParams (which we will only
537: // commit back to the configuration settings if choosing OK)
538: CurrentParams = ConfigureParams;
1.1 root 539:
540: [self setAllControls];
541:
542: // Display the window
543: [[ModalWrapper alloc] runModal:window];
544: }
545:
546:
547: /*-----------------------------------------------------------------------*/
548: /*
549: Updates the controls following a change in the joystick selection
550: */
551: - (IBAction)changeViewedJoystick:(id)sender
552: {
553: // Save the pre-joystick controls, as we are about to change them
554: [self saveJoystickControls];
555:
556: // Refresh the per-joystick controls
557: [self setJoystickControls];
558:
559: // Update the controls' enabled states
560: [self updateEnabledStates:self];
561: }
562:
563:
564: /*-----------------------------------------------------------------------*/
565: /*
566: Initializes all controls
567: */
568: - (void)setAllControls
569: {
570: // Import the floppy paths into their controls.
1.1.1.3 root 571: IMPORT_TEXTFIELD(floppyImageA, ConfigureParams.DiskImage.szDiskFileName[0]);
572: IMPORT_TEXTFIELD(floppyImageB, ConfigureParams.DiskImage.szDiskFileName[1]);
1.1 root 573:
574: // Import all the preferences into their controls
1.1.1.3 root 575: IMPORT_SWITCH(autoInsertB, ConfigureParams.DiskImage.bAutoInsertDiskB);
576: IMPORT_SWITCH(blitter, ConfigureParams.System.bBlitter);
577: IMPORT_SWITCH(bootFromHD, ConfigureParams.HardDisk.bBootFromHardDisk);
578: IMPORT_SWITCH(captureOnChange, ConfigureParams.Screen.bCaptureChange);
579: IMPORT_TEXTFIELD(cartridgeImage, ConfigureParams.Rom.szCartridgeImageFileName);
580: IMPORT_RADIO(colorDepth, ConfigureParams.Screen.nVdiColors);
581: IMPORT_SWITCH(compatibleCpu, ConfigureParams.System.bCompatibleCpu);
582: IMPORT_RADIO(cpuClock, ConfigureParams.System.nCpuFreq);
583: IMPORT_RADIO(cpuType, ConfigureParams.System.nCpuLevel);
584: IMPORT_TEXTFIELD(defaultImagesLocation, ConfigureParams.DiskImage.szDiskImageDirectory);
585: IMPORT_SWITCH(enableMidi, ConfigureParams.Midi.bEnableMidi);
586: IMPORT_SWITCH(enablePrinter, ConfigureParams.Printer.bEnablePrinting);
587: IMPORT_SWITCH(enableRS232, ConfigureParams.RS232.bEnableRS232);
588: IMPORT_SWITCH(enableSound, ConfigureParams.Sound.bEnableSound);
589: IMPORT_DROPDOWN(frameSkip, ConfigureParams.Screen.nFrameSkips);
590: IMPORT_RADIO(keyboardMapping, ConfigureParams.Keyboard.nKeymapType);
591: IMPORT_TEXTFIELD(keyboardMappingFile, ConfigureParams.Keyboard.szMappingFileName);
592: IMPORT_RADIO(machineType, ConfigureParams.System.nMachineType);
593: IMPORT_RADIO(monitor, ConfigureParams.Screen.nMonitorType);
594: IMPORT_SWITCH(patchTimerD, ConfigureParams.System.bPatchTimerD);
595: IMPORT_TEXTFIELD(printToFile, ConfigureParams.Printer.szPrintToFileName);
596: IMPORT_RADIO(ramSize, ConfigureParams.Memory.nMemorySize);
597: IMPORT_TEXTFIELD(readRS232FromFile, ConfigureParams.RS232.szInFileName);
598: IMPORT_SWITCH(realTime, ConfigureParams.System.bRealTimeClock);
1.1.1.5 ! root 599: IMPORT_SWITCH(slowFDC, ConfigureParams.DiskImage.bSlowFloppy);
1.1.1.3 root 600: IMPORT_TEXTFIELD(tosImage, ConfigureParams.Rom.szTosImageFileName);
601: IMPORT_SWITCH(useBorders, ConfigureParams.Screen.bAllowOverscan);
602: IMPORT_SWITCH(useVDIResolution, ConfigureParams.Screen.bUseExtVdiResolutions);
1.1.1.4 root 603: IMPORT_TEXTFIELD(writeMidiToFile, ConfigureParams.Midi.sMidiOutFileName);
1.1.1.3 root 604: IMPORT_RADIO(writeProtection, ConfigureParams.DiskImage.nWriteProtection);
605: IMPORT_TEXTFIELD(writeRS232ToFile, ConfigureParams.RS232.szOutFileName);
606: IMPORT_SWITCH(zoomSTLowRes, ConfigureParams.Screen.bZoomLowRes);
607: IMPORT_SWITCH(showStatusBar, ConfigureParams.Screen.bShowStatusbar);
608: IMPORT_DROPDOWN(enableDSP,ConfigureParams.System.nDSPType);
609: IMPORT_TEXTFIELD(configFile, sConfigFileName);
1.1.1.2 root 610:
1.1.1.3 root 611: [(force8bpp) setState:((ConfigureParams.Screen.nForceBpp==8))? NSOnState : NSOffState];
1.1.1.2 root 612:
1.1.1.5 ! root 613: if (ConfigureParams.Sound.nPlaybackFreq >= 44100)
! 614: [playbackQuality selectCellWithTag:(2)];
! 615: else if (ConfigureParams.Sound.nPlaybackFreq >= 22050)
! 616: [playbackQuality selectCellWithTag:(1)];
! 617: else
! 618: [playbackQuality selectCellWithTag:(0)];
! 619:
1.1.1.3 root 620: if (ConfigureParams.Screen.nVdiWidth >= 1024)
1.1.1.2 root 621: [resolution selectCellWithTag:(2)];
1.1.1.3 root 622: else if (ConfigureParams.Screen.nVdiWidth >= 768)
1.1.1.2 root 623: [resolution selectCellWithTag:(1)];
624: else
625: [resolution selectCellWithTag:(0)];
626:
1.1 root 627: // If the HD flag is set, load the HD path, otherwise make it blank
1.1.1.3 root 628: if (ConfigureParams.HardDisk.bUseHardDiskImage)
1.1 root 629: {
1.1.1.3 root 630: IMPORT_TEXTFIELD(hdImage, ConfigureParams.HardDisk.szHardDiskImage);
1.1 root 631: }
632: else
633: {
634: [hdImage setStringValue:@""];
635: }
636:
1.1.1.5 ! root 637: // If the IDE HD flag is set, load the IDE HD path, otherwise make it blank
! 638: if (ConfigureParams.HardDisk.bUseIdeHardDiskImage)
! 639: {
! 640: IMPORT_TEXTFIELD(ideHdImage, ConfigureParams.HardDisk.szIdeHardDiskImage);
! 641: }
! 642: else
! 643: {
! 644: [ideHdImage setStringValue:@""];
! 645: }
! 646:
1.1 root 647: // If the Gemdos flag is set, load the Gemdos path, otherwise make it blank
1.1.1.3 root 648: if (ConfigureParams.HardDisk.bUseHardDiskDirectories)
1.1 root 649: {
1.1.1.3 root 650: IMPORT_TEXTFIELD(gemdosImage, ConfigureParams.HardDisk.szHardDiskDirectories[0]);
1.1 root 651: }
652: else
653: {
654: [gemdosImage setStringValue:@""];
655: }
656:
657: // Set the per-joystick controls
658: [self setJoystickControls];
659:
660: // Update the controls' enabled states
661: [self updateEnabledStates:self];
662: }
663:
664:
665: /*-----------------------------------------------------------------------*/
666: /*
667: Updates the enabled states of controls who depend on other controls
668: */
669: - (IBAction)updateEnabledStates:(id)sender
670: {
671: // Joystick key controls are only enabled if "Use keyboard" is selected
672: int nJoystickMode;
673: EXPORT_RADIO(joystickMode, nJoystickMode);
674: BOOL bUsingKeyboard = (nJoystickMode == JOYSTICK_KEYBOARD);
675: [joystickUp setEnabled:bUsingKeyboard];
676: [joystickRight setEnabled:bUsingKeyboard];
677: [joystickDown setEnabled:bUsingKeyboard];
678: [joystickLeft setEnabled:bUsingKeyboard];
679: [joystickFire setEnabled:bUsingKeyboard];
680:
681: // Resolution and colour depth depend on Extended GEM VDI resolution
682: BOOL bUsingVDI;
683: EXPORT_SWITCH(useVDIResolution, bUsingVDI);
684: [resolution setEnabled:bUsingVDI];
685: [colorDepth setEnabled:bUsingVDI];
686:
687: // Playback quality depends on enable sound
688: BOOL bSoundEnabled;
689: EXPORT_SWITCH(enableSound, bSoundEnabled);
690: [playbackQuality setEnabled:bSoundEnabled];
691: }
692:
693:
694: /*-----------------------------------------------------------------------*/
695: /*
696: Updates the joystick controls to match the new joystick selection
697: */
698: - (void)setJoystickControls
699: {
700: // Get and persist the ID of the newly selected joystick
701: EXPORT_DROPDOWN(currentJoystick, nCurrentJoystick);
702:
703: // Data validation: If the JoyID is out of bounds, correct it and, if set to use real joystick, change to disabled
1.1.1.3 root 704: if ( (ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoyId < 0)
705: || (ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoyId >= cRealJoysticks) )
1.1 root 706: {
1.1.1.3 root 707: ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoyId = 0;
708: if (ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoystickMode == JOYSTICK_REALSTICK)
1.1 root 709: {
1.1.1.3 root 710: ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoystickMode = JOYSTICK_DISABLED;
1.1 root 711: }
712: }
713:
714: // Don't change the realJoystick dropdown if none is available (to keep "(None available)" selected)
715: if (cRealJoysticks > 0)
716: {
1.1.1.3 root 717: IMPORT_DROPDOWN(realJoystick, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoyId);
1.1 root 718: }
719:
1.1.1.3 root 720: IMPORT_RADIO(joystickMode, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoystickMode);
721: IMPORT_DROPDOWN(joystickUp, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeUp);
722: IMPORT_DROPDOWN(joystickRight, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeRight);
723: IMPORT_DROPDOWN(joystickDown, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeDown);
724: IMPORT_DROPDOWN(joystickLeft, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeLeft);
725: IMPORT_DROPDOWN(joystickFire, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeFire);
726: IMPORT_SWITCH(enableAutoFire, ConfigureParams.Joysticks.Joy[nCurrentJoystick].bEnableAutoFire);
1.1 root 727: }
728:
729:
730: /*-----------------------------------------------------------------------*/
731: /*
732: Saves the setting for the joystick currently being viewed
733: */
734: - (void)saveJoystickControls
735: {
1.1.1.3 root 736: EXPORT_RADIO(joystickMode, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoystickMode);
737: EXPORT_DROPDOWN(realJoystick, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoyId);
738: EXPORT_DROPDOWN(joystickUp, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeUp);
739: EXPORT_DROPDOWN(joystickRight, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeRight);
740: EXPORT_DROPDOWN(joystickDown, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeDown);
741: EXPORT_DROPDOWN(joystickLeft, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeLeft);
742: EXPORT_DROPDOWN(joystickFire, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeFire);
743: EXPORT_SWITCH(enableAutoFire, ConfigureParams.Joysticks.Joy[nCurrentJoystick].bEnableAutoFire);
1.1 root 744: }
745:
746:
747: /*-----------------------------------------------------------------------*/
748: /*
749: Saves the settings for all controls
750: */
751: - (void)saveAllControls
752: {
753: // Export the preference controls into their vars
1.1.1.3 root 754: EXPORT_SWITCH(autoInsertB, ConfigureParams.DiskImage.bAutoInsertDiskB);
755: EXPORT_SWITCH(blitter, ConfigureParams.System.bBlitter);
756: EXPORT_SWITCH(bootFromHD, ConfigureParams.HardDisk.bBootFromHardDisk);
757: EXPORT_SWITCH(captureOnChange, ConfigureParams.Screen.bCaptureChange);
758: EXPORT_TEXTFIELD(cartridgeImage, ConfigureParams.Rom.szCartridgeImageFileName);
759: EXPORT_RADIO(colorDepth, ConfigureParams.Screen.nVdiColors);
760: EXPORT_SWITCH(compatibleCpu, ConfigureParams.System.bCompatibleCpu);
761: EXPORT_RADIO(cpuClock, ConfigureParams.System.nCpuFreq);
762: EXPORT_RADIO(cpuType, ConfigureParams.System.nCpuLevel);
763: EXPORT_TEXTFIELD(defaultImagesLocation, ConfigureParams.DiskImage.szDiskImageDirectory);
764: EXPORT_SWITCH(enableMidi, ConfigureParams.Midi.bEnableMidi);
765: EXPORT_SWITCH(enablePrinter, ConfigureParams.Printer.bEnablePrinting);
766: EXPORT_SWITCH(enableRS232, ConfigureParams.RS232.bEnableRS232);
767: EXPORT_SWITCH(enableSound, ConfigureParams.Sound.bEnableSound);
768: EXPORT_DROPDOWN(frameSkip, ConfigureParams.Screen.nFrameSkips);
769: EXPORT_RADIO(keyboardMapping, ConfigureParams.Keyboard.nKeymapType);
770: EXPORT_TEXTFIELD(keyboardMappingFile, ConfigureParams.Keyboard.szMappingFileName);
771: EXPORT_RADIO(machineType, ConfigureParams.System.nMachineType);
772: EXPORT_RADIO(monitor, ConfigureParams.Screen.nMonitorType);
773: EXPORT_SWITCH(patchTimerD, ConfigureParams.System.bPatchTimerD);
774: EXPORT_TEXTFIELD(printToFile, ConfigureParams.Printer.szPrintToFileName);
775: EXPORT_RADIO(ramSize, ConfigureParams.Memory.nMemorySize);
776: EXPORT_TEXTFIELD(readRS232FromFile, ConfigureParams.RS232.szInFileName);
777: EXPORT_SWITCH(realTime, ConfigureParams.System.bRealTimeClock);
1.1.1.5 ! root 778: EXPORT_SWITCH(slowFDC, ConfigureParams.DiskImage.bSlowFloppy);
1.1.1.3 root 779: EXPORT_TEXTFIELD(tosImage, ConfigureParams.Rom.szTosImageFileName);
780: EXPORT_SWITCH(useBorders, ConfigureParams.Screen.bAllowOverscan);
781: EXPORT_SWITCH(useVDIResolution, ConfigureParams.Screen.bUseExtVdiResolutions);
1.1.1.4 root 782: EXPORT_TEXTFIELD(writeMidiToFile, ConfigureParams.Midi.sMidiOutFileName);
1.1.1.3 root 783: EXPORT_RADIO(writeProtection, ConfigureParams.DiskImage.nWriteProtection);
784: EXPORT_TEXTFIELD(writeRS232ToFile, ConfigureParams.RS232.szOutFileName);
785: EXPORT_SWITCH(zoomSTLowRes, ConfigureParams.Screen.bZoomLowRes);
786: EXPORT_SWITCH(showStatusBar,ConfigureParams.Screen.bShowStatusbar);
787: EXPORT_DROPDOWN(enableDSP,ConfigureParams.System.nDSPType);
1.1.1.2 root 788:
1.1.1.3 root 789: ConfigureParams.Screen.nForceBpp = ([force8bpp state] == NSOnState) ? 8 : 16;
1.1.1.2 root 790:
1.1.1.5 ! root 791: switch ([[playbackQuality selectedCell] tag])
! 792: {
! 793: case 0:
! 794: ConfigureParams.Sound.nPlaybackFreq = 11025;
! 795: break;
! 796: case 1:
! 797: ConfigureParams.Sound.nPlaybackFreq = 22050;
! 798: break;
! 799: case 2:
! 800: ConfigureParams.Sound.nPlaybackFreq = 44100;
! 801: break;
! 802: }
! 803:
1.1.1.2 root 804: switch ([[resolution selectedCell] tag])
805: {
806: case 0:
1.1.1.3 root 807: ConfigureParams.Screen.nVdiWidth = 640;
808: ConfigureParams.Screen.nVdiHeight = 480;
1.1.1.2 root 809: break;
810: case 1:
1.1.1.3 root 811: ConfigureParams.Screen.nVdiWidth = 800;
812: ConfigureParams.Screen.nVdiHeight = 600;
1.1.1.2 root 813: break;
814: case 2:
1.1.1.3 root 815: ConfigureParams.Screen.nVdiWidth = 1024;
816: ConfigureParams.Screen.nVdiHeight = 768;
1.1.1.2 root 817: break;
818: }
1.1 root 819:
820: // Define the HD flag, and export the HD path if one is selected
821: if ([[hdImage stringValue] length] > 0)
822: {
1.1.1.3 root 823: EXPORT_TEXTFIELD(hdImage, ConfigureParams.HardDisk.szHardDiskImage);
1.1.1.5 ! root 824: ConfigureParams.HardDisk.bUseHardDiskImage = true;
! 825: }
! 826: else
! 827: {
! 828: ConfigureParams.HardDisk.bUseHardDiskImage = false;
! 829: }
! 830:
! 831: // Define the IDE HD flag, and export the IDE HD path if one is selected
! 832: if ([[ideHdImage stringValue] length] > 0)
! 833: {
! 834: EXPORT_TEXTFIELD(ideHdImage, ConfigureParams.HardDisk.szIdeHardDiskImage);
! 835: ConfigureParams.HardDisk.bUseIdeHardDiskImage = true;
1.1 root 836: }
837: else
838: {
1.1.1.5 ! root 839: ConfigureParams.HardDisk.bUseIdeHardDiskImage = false;
1.1 root 840: }
841:
842: // Define the Gemdos flag, and export the Gemdos path if one is selected
843: if ([[gemdosImage stringValue] length] > 0)
844: {
1.1.1.3 root 845: EXPORT_TEXTFIELD(gemdosImage, ConfigureParams.HardDisk.szHardDiskDirectories[0]);
1.1.1.5 ! root 846: ConfigureParams.HardDisk.bUseHardDiskDirectories = true;
1.1 root 847: }
848: else
849: {
1.1.1.5 ! root 850: ConfigureParams.HardDisk.bUseHardDiskDirectories = false;
1.1 root 851: }
852:
853: // Save the per-joystick controls
854: [self saveJoystickControls];
855: }
856:
857: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.