Annotation of hatari/src/gui-osx/PrefsController.m, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.