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

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
                    232:                return TRUE;
                    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: 
                    298: - (IBAction)chooseKeyboardMappingFile:(id)sender
                    299: {
                    300:        [self choosePathForControl: keyboardMappingFile chooseDirectories:FALSE defaultInitialDir:@"~"];
                    301: }
                    302: 
                    303: - (IBAction)chooseMidiOutputFile:(id)sender
                    304: {
                    305:        [self choosePathForControl: writeMidiToFile chooseDirectories:FALSE defaultInitialDir:@"~"];
                    306: }
                    307: 
                    308: - (IBAction)choosePrintToFile:(id)sender
                    309: {
                    310:        [self choosePathForControl: printToFile chooseDirectories:FALSE defaultInitialDir:@"~"];
                    311: }
                    312: 
                    313: - (IBAction)chooseRS232InputFile:(id)sender
                    314: {
                    315:        [self choosePathForControl: readRS232FromFile chooseDirectories:FALSE defaultInitialDir:@"~"];
                    316: }
                    317: 
                    318: - (IBAction)chooseRS232OutputFile:(id)sender
                    319: {
                    320:        [self choosePathForControl: writeRS232ToFile chooseDirectories:FALSE defaultInitialDir:@"~"];
                    321: }
                    322: 
                    323: - (IBAction)chooseTosImage:(id)sender;
                    324: {
                    325:        [self choosePathForControl: tosImage chooseDirectories:FALSE defaultInitialDir:@"~"];
                    326: }
                    327: 
                    328: 
                    329: /*-----------------------------------------------------------------------*/
                    330: /*
                    331:   Methods for the "Eject" buttons
                    332: */
                    333: - (IBAction)ejectFloppyA:(id)sender
                    334: {
1.1.1.3 ! root      335:        Floppy_SetDiskFileNameNone(0);
1.1       root      336:        
                    337:        // Refresh the control
                    338:        [floppyImageA setStringValue:@""];
                    339: }
                    340: 
                    341: - (IBAction)ejectFloppyB:(id)sender
                    342: {
1.1.1.3 ! root      343:        Floppy_SetDiskFileNameNone(1);
1.1       root      344: 
                    345:        // Refresh the control
                    346:        [floppyImageB setStringValue:@""];
                    347: }
                    348: 
                    349: - (IBAction)ejectGemdosImage:(id)sender
                    350: {
1.1.1.3 ! root      351:        // Clear the control. Later. saveAllControls will set the ConfigureParams accordingly to signal this is ejected
1.1       root      352:        [gemdosImage setStringValue:@""];
                    353: }
                    354: 
                    355: - (IBAction)ejectHdImage:(id)sender
                    356: {
1.1.1.3 ! root      357:        // Clear the control. Later. saveAllControls will set the ConfigureParams accordingly to signal this is ejected
1.1       root      358:        [hdImage setStringValue:@""];
                    359: }
                    360: 
                    361: 
                    362: /*-----------------------------------------------------------------------*/
1.1.1.3 ! root      363: /**
        !           364:  * Methods for the "Load Config" button
        !           365:  */
        !           366: 
        !           367: - (IBAction)loadConfigFrom:(id)sender
        !           368: {
        !           369:     NSString *ConfigFile = [NSString stringWithCString:(sConfigFileName)];
        !           370:     NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
        !           371:     
        !           372:     if ( [ openPanel runModalForDirectory:nil file:ConfigFile types:nil ] )
        !           373:        {
        !           374:         ConfigFile = [ [ openPanel filenames ] objectAtIndex:0 ];
        !           375:     }
        !           376:        else
        !           377:        {
        !           378:                ConfigFile = nil;
        !           379:        }
        !           380: 
        !           381:        if (ConfigFile != nil)
        !           382:        {
        !           383:                // Make a non-const C string out of it
        !           384:                const char* constSzPath = [ConfigFile cString];
        !           385:                size_t cbPath = strlen(constSzPath) + 1;
        !           386:                char szPath[cbPath];
        !           387:                strncpy(szPath, constSzPath, cbPath);   
        !           388: 
        !           389:                // Load the config into ConfigureParams
        !           390:                Configuration_Load(szPath);
        !           391:                strcpy(sConfigFileName,szPath);
        !           392:                // Refresh all the controls to match ConfigureParams
        !           393:                [self setAllControls];
        !           394:        }
1.1       root      395: }
                    396: 
1.1.1.3 ! root      397: /**
        !           398:  * Methods for the "Load Config" button
        !           399:  */
        !           400: - (IBAction)saveConfigAs:(id)sender
1.1       root      401: {
1.1.1.3 ! root      402:        char splitpath[FILENAME_MAX], splitname[FILENAME_MAX];
        !           403: 
        !           404:        // Update the ConfigureParams from the controls
1.1       root      405:        [self saveAllControls];
                    406: 
1.1.1.3 ! root      407:        File_SplitPath(sConfigFileName, splitpath, splitname, NULL);
        !           408: 
        !           409:     NSSavePanel *savePanel = [ NSSavePanel savePanel ];
        !           410: 
        !           411:        NSString* defaultDir = [NSString stringWithCString:splitpath];
        !           412:     NSString *ConfigFile = [NSString stringWithCString:splitname];
        !           413:     
        !           414:     if ( ![ savePanel runModalForDirectory:defaultDir file:ConfigFile ] )
        !           415:        {
        !           416:                return;
        !           417:        }
        !           418: 
        !           419:     ConfigFile = [ savePanel filename ];
        !           420:     
        !           421:        if (ConfigFile != nil)
        !           422:        {
        !           423:                // Make a non-const C string out of it
        !           424:                const char* constSzPath = [ConfigFile cString];
        !           425:                size_t cbPath = strlen(constSzPath) + 1;
        !           426:                char szPath[cbPath];
        !           427:                strncpy(szPath, constSzPath, cbPath);   
        !           428: 
        !           429:                // Save the config from ConfigureParams
        !           430:                strcpy(sConfigFileName, szPath);
        !           431:                Configuration_Save();
        !           432:        }
1.1       root      433: }
                    434: 
                    435: 
                    436: /*-----------------------------------------------------------------------*/
                    437: /*
                    438:   Commits and closes
                    439: */
                    440: - (IBAction)commitAndClose:(id)sender
                    441: {
                    442:        BOOL applyChanges = TRUE;
                    443: 
                    444:        // The user clicked OK
                    445:        [self saveAllControls];
                    446:        
                    447:        // If a reset is required, ask the user first
1.1.1.3 ! root      448:        if (Change_DoNeedReset(&CurrentParams, &ConfigureParams))
1.1       root      449:        {
                    450:                applyChanges = ( 0 == NSRunAlertPanel (@"Reset the emulator?", 
                    451:                @"The emulator must be reset in order to apply your changes.\nAll current work will be lost.",
                    452:                @"Don't reset", @"Reset", nil) );
                    453:        }
                    454:        
                    455:        // Commit the new configuration
                    456:        if (applyChanges)
                    457:        {
1.1.1.3 ! root      458:                Change_CopyChangedParamsToConfiguration(&CurrentParams, &ConfigureParams, FALSE);
        !           459:        }
        !           460:        else
        !           461:        {
        !           462:                ConfigureParams = CurrentParams;
1.1       root      463:        }
                    464: 
                    465:        // Close the window
                    466:        [window close]; 
                    467: }
                    468: 
                    469: - (void)initKeysDropDown:(NSPopUpButton*)dropDown
                    470: {
                    471:        [dropDown removeAllItems];
                    472:        int i;
                    473:        for (i = 0; i < Preferences_cKeysForJoysticks; i++)
                    474:        {
                    475:                SDLKey key = Preferences_KeysForJoysticks[i];
                    476:                const char* szKeyName = SDL_GetKeyName(key);
                    477:                [dropDown addItemWithTitle:[[NSString stringWithCString:szKeyName] capitalizedString]]; 
                    478:                [[dropDown lastItem] setTag:key];
                    479:        }
                    480: }
                    481: 
                    482: 
                    483: /*-----------------------------------------------------------------------*/
                    484: /*
                    485:   Displays the Preferences dialog
                    486: */
                    487: - (IBAction)loadPrefs:(id)sender
                    488: {
                    489:        if (!bInitialized)
                    490:        {
                    491:                // Note: These inits cannot be done in awakeFromNib as by this time SDL is not yet initialized.
                    492: 
                    493:                // Fill the keyboard dropdowns
                    494:                [self initKeysDropDown:joystickUp];
                    495:                [self initKeysDropDown:joystickRight];
                    496:                [self initKeysDropDown:joystickDown];
                    497:                [self initKeysDropDown:joystickLeft];           
                    498:                [self initKeysDropDown:joystickFire];
                    499:                
                    500:                // Get and store the number of real joysticks
                    501:                cRealJoysticks = SDL_NumJoysticks();
                    502: 
                    503:                // Fill the real joysticks dropdown, if any are available
                    504:                if (cRealJoysticks > 0)
                    505:                {
                    506:                        [realJoystick removeAllItems];
                    507:                        int i;
                    508:                        for (i = 0; i < cRealJoysticks; i++)
                    509:                        {
                    510:                                const char* szJoystickName = SDL_JoystickName(i);
                    511:                                [realJoystick addItemWithTitle:[[NSString stringWithCString:szJoystickName] capitalizedString]];        
                    512:                                [[realJoystick lastItem] setTag:i];     
                    513:                        }
                    514:                }
                    515:                else    // No real joysticks: Disable the controls
                    516:                {
                    517:                        [[joystickMode cellWithTag:1] setEnabled:FALSE];
                    518:                        [realJoystick setEnabled:FALSE];
                    519:                }
                    520:                
                    521:                bInitialized = TRUE;
                    522:        }
                    523: 
                    524: 
1.1.1.3 ! root      525:        // Backup of configuration settings to CurrentParams (which we will only
        !           526:        // commit back to the configuration settings if choosing OK)
        !           527:        CurrentParams = ConfigureParams;
1.1       root      528: 
                    529:        [self setAllControls];
                    530: 
                    531:        // Display the window
                    532:        [[ModalWrapper alloc] runModal:window];
                    533: }
                    534: 
                    535: 
                    536: /*-----------------------------------------------------------------------*/
                    537: /*
                    538:   Updates the controls following a change in the joystick selection
                    539: */
                    540: - (IBAction)changeViewedJoystick:(id)sender
                    541: {
                    542:        // Save the pre-joystick controls, as we are about to change them
                    543:        [self saveJoystickControls];
                    544:        
                    545:        // Refresh the per-joystick controls
                    546:        [self setJoystickControls];
                    547:        
                    548:        // Update the controls' enabled states
                    549:        [self updateEnabledStates:self];
                    550: }
                    551: 
                    552: 
                    553: /*-----------------------------------------------------------------------*/
                    554: /*
                    555:   Initializes all controls
                    556: */
                    557: - (void)setAllControls
                    558: {
                    559:        // Import the floppy paths into their controls.
1.1.1.3 ! root      560:        IMPORT_TEXTFIELD(floppyImageA, ConfigureParams.DiskImage.szDiskFileName[0]); 
        !           561:        IMPORT_TEXTFIELD(floppyImageB, ConfigureParams.DiskImage.szDiskFileName[1]); 
1.1       root      562:        
                    563:        // Import all the preferences into their controls
1.1.1.3 ! root      564:        IMPORT_SWITCH(autoInsertB, ConfigureParams.DiskImage.bAutoInsertDiskB);
        !           565:     IMPORT_SWITCH(blitter, ConfigureParams.System.bBlitter);
        !           566:        IMPORT_SWITCH(bootFromHD, ConfigureParams.HardDisk.bBootFromHardDisk);  
        !           567:     IMPORT_SWITCH(captureOnChange, ConfigureParams.Screen.bCaptureChange);
        !           568:     IMPORT_TEXTFIELD(cartridgeImage, ConfigureParams.Rom.szCartridgeImageFileName);
        !           569:     IMPORT_RADIO(colorDepth, ConfigureParams.Screen.nVdiColors);
        !           570:     IMPORT_SWITCH(compatibleCpu, ConfigureParams.System.bCompatibleCpu);
        !           571:     IMPORT_RADIO(cpuClock, ConfigureParams.System.nCpuFreq);
        !           572:     IMPORT_RADIO(cpuType, ConfigureParams.System.nCpuLevel);
        !           573:        IMPORT_TEXTFIELD(defaultImagesLocation, ConfigureParams.DiskImage.szDiskImageDirectory);
        !           574:     IMPORT_SWITCH(enableMidi, ConfigureParams.Midi.bEnableMidi);
        !           575:     IMPORT_SWITCH(enablePrinter, ConfigureParams.Printer.bEnablePrinting);
        !           576:     IMPORT_SWITCH(enableRS232, ConfigureParams.RS232.bEnableRS232);
        !           577:     IMPORT_SWITCH(enableSound, ConfigureParams.Sound.bEnableSound);
        !           578:     IMPORT_DROPDOWN(frameSkip, ConfigureParams.Screen.nFrameSkips);
        !           579:     IMPORT_RADIO(keyboardMapping, ConfigureParams.Keyboard.nKeymapType);
        !           580:     IMPORT_TEXTFIELD(keyboardMappingFile, ConfigureParams.Keyboard.szMappingFileName);
        !           581:     IMPORT_RADIO(machineType, ConfigureParams.System.nMachineType);
        !           582:     IMPORT_RADIO(monitor, ConfigureParams.Screen.nMonitorType);
        !           583:     IMPORT_SWITCH(patchTimerD, ConfigureParams.System.bPatchTimerD);
        !           584:     IMPORT_RADIO(playbackQuality, ConfigureParams.Sound.nPlaybackQuality);
        !           585:     IMPORT_TEXTFIELD(printToFile, ConfigureParams.Printer.szPrintToFileName);
        !           586:     IMPORT_RADIO(ramSize, ConfigureParams.Memory.nMemorySize);
        !           587:     IMPORT_TEXTFIELD(readRS232FromFile, ConfigureParams.RS232.szInFileName);
        !           588:     IMPORT_SWITCH(realTime, ConfigureParams.System.bRealTimeClock);
        !           589:     IMPORT_SWITCH(slowFDC, ConfigureParams.System.bSlowFDC);
        !           590:     IMPORT_TEXTFIELD(tosImage, ConfigureParams.Rom.szTosImageFileName);
        !           591:     IMPORT_SWITCH(useBorders, ConfigureParams.Screen.bAllowOverscan);
        !           592:     IMPORT_SWITCH(useVDIResolution, ConfigureParams.Screen.bUseExtVdiResolutions);
        !           593:     IMPORT_TEXTFIELD(writeMidiToFile, ConfigureParams.Midi.szMidiOutFileName);
        !           594:        IMPORT_RADIO(writeProtection, ConfigureParams.DiskImage.nWriteProtection);
        !           595:     IMPORT_TEXTFIELD(writeRS232ToFile, ConfigureParams.RS232.szOutFileName);
        !           596:     IMPORT_SWITCH(zoomSTLowRes, ConfigureParams.Screen.bZoomLowRes);
        !           597:        IMPORT_SWITCH(showStatusBar, ConfigureParams.Screen.bShowStatusbar);
        !           598:        IMPORT_DROPDOWN(enableDSP,ConfigureParams.System.nDSPType);
        !           599:        IMPORT_TEXTFIELD(configFile, sConfigFileName);
1.1.1.2   root      600: 
1.1.1.3 ! root      601:        [(force8bpp) setState:((ConfigureParams.Screen.nForceBpp==8))? NSOnState : NSOffState];
1.1.1.2   root      602: 
1.1.1.3 ! root      603:        if (ConfigureParams.Screen.nVdiWidth >= 1024)
1.1.1.2   root      604:                [resolution selectCellWithTag:(2)];
1.1.1.3 ! root      605:        else if (ConfigureParams.Screen.nVdiWidth >= 768)
1.1.1.2   root      606:                [resolution selectCellWithTag:(1)];
                    607:        else
                    608:                [resolution selectCellWithTag:(0)];
                    609: 
1.1       root      610:        // If the HD flag is set, load the HD path, otherwise make it blank
1.1.1.3 ! root      611:        if (ConfigureParams.HardDisk.bUseHardDiskImage)
1.1       root      612:        {
1.1.1.3 ! root      613:                IMPORT_TEXTFIELD(hdImage, ConfigureParams.HardDisk.szHardDiskImage);    
1.1       root      614:        }
                    615:        else
                    616:        {
                    617:                [hdImage setStringValue:@""];
                    618:        }
                    619:        
                    620:        // If the Gemdos flag is set, load the Gemdos path, otherwise make it blank
1.1.1.3 ! root      621:        if (ConfigureParams.HardDisk.bUseHardDiskDirectories)
1.1       root      622:        {
1.1.1.3 ! root      623:                IMPORT_TEXTFIELD(gemdosImage, ConfigureParams.HardDisk.szHardDiskDirectories[0]);
1.1       root      624:        }
                    625:        else
                    626:        {
                    627:                [gemdosImage setStringValue:@""];
                    628:        }
                    629:        
                    630:        // Set the per-joystick controls                
                    631:        [self setJoystickControls];
                    632:        
                    633:        // Update the controls' enabled states
                    634:        [self updateEnabledStates:self];        
                    635: }
                    636: 
                    637: 
                    638: /*-----------------------------------------------------------------------*/
                    639: /*
                    640:   Updates the enabled states of controls who depend on other controls
                    641: */
                    642: - (IBAction)updateEnabledStates:(id)sender
                    643: {
                    644:        // Joystick key controls are only enabled if "Use keyboard" is selected
                    645:        int nJoystickMode;
                    646:        EXPORT_RADIO(joystickMode, nJoystickMode);
                    647:        BOOL bUsingKeyboard = (nJoystickMode == JOYSTICK_KEYBOARD);
                    648:        [joystickUp setEnabled:bUsingKeyboard];         
                    649:        [joystickRight setEnabled:bUsingKeyboard];              
                    650:        [joystickDown setEnabled:bUsingKeyboard];               
                    651:        [joystickLeft setEnabled:bUsingKeyboard];               
                    652:        [joystickFire setEnabled:bUsingKeyboard];               
                    653: 
                    654:        // Resolution and colour depth depend on Extended GEM VDI resolution
                    655:        BOOL bUsingVDI;
                    656:        EXPORT_SWITCH(useVDIResolution, bUsingVDI);
                    657:        [resolution setEnabled:bUsingVDI];              
                    658:        [colorDepth setEnabled:bUsingVDI];
                    659:        
                    660:        // Playback quality depends on enable sound
                    661:        BOOL bSoundEnabled;
                    662:     EXPORT_SWITCH(enableSound, bSoundEnabled);
                    663:        [playbackQuality setEnabled:bSoundEnabled];
                    664: }
                    665: 
                    666: 
                    667: /*-----------------------------------------------------------------------*/
                    668: /*
                    669:   Updates the joystick controls to match the new joystick selection
                    670: */
                    671: - (void)setJoystickControls
                    672: {
                    673:        // Get and persist the ID of the newly selected joystick
                    674:        EXPORT_DROPDOWN(currentJoystick, nCurrentJoystick);
                    675: 
                    676:        // 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      677:        if ( (ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoyId < 0)
        !           678:        || (ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoyId >= cRealJoysticks) )
1.1       root      679:        {
1.1.1.3 ! root      680:                ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoyId = 0;
        !           681:                if (ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoystickMode == JOYSTICK_REALSTICK)
1.1       root      682:                {
1.1.1.3 ! root      683:                        ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoystickMode = JOYSTICK_DISABLED;
1.1       root      684:                }       
                    685:        }
                    686: 
                    687:        // Don't change the realJoystick dropdown if none is available (to keep "(None available)" selected)
                    688:        if (cRealJoysticks > 0)
                    689:        {
1.1.1.3 ! root      690:                IMPORT_DROPDOWN(realJoystick, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoyId);
1.1       root      691:        }
                    692: 
1.1.1.3 ! root      693:        IMPORT_RADIO(joystickMode, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoystickMode);
        !           694:        IMPORT_DROPDOWN(joystickUp, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeUp);
        !           695:        IMPORT_DROPDOWN(joystickRight, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeRight);
        !           696:        IMPORT_DROPDOWN(joystickDown, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeDown);
        !           697:        IMPORT_DROPDOWN(joystickLeft, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeLeft);
        !           698:        IMPORT_DROPDOWN(joystickFire, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeFire);
        !           699:        IMPORT_SWITCH(enableAutoFire, ConfigureParams.Joysticks.Joy[nCurrentJoystick].bEnableAutoFire);
1.1       root      700: }
                    701: 
                    702: 
                    703: /*-----------------------------------------------------------------------*/
                    704: /*
                    705:   Saves the setting for the joystick currently being viewed
                    706: */
                    707: - (void)saveJoystickControls
                    708: {
1.1.1.3 ! root      709:        EXPORT_RADIO(joystickMode, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoystickMode);      
        !           710:        EXPORT_DROPDOWN(realJoystick, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nJoyId);
        !           711:        EXPORT_DROPDOWN(joystickUp, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeUp);
        !           712:        EXPORT_DROPDOWN(joystickRight, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeRight);
        !           713:        EXPORT_DROPDOWN(joystickDown, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeDown);
        !           714:        EXPORT_DROPDOWN(joystickLeft, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeLeft);
        !           715:        EXPORT_DROPDOWN(joystickFire, ConfigureParams.Joysticks.Joy[nCurrentJoystick].nKeyCodeFire);
        !           716:        EXPORT_SWITCH(enableAutoFire, ConfigureParams.Joysticks.Joy[nCurrentJoystick].bEnableAutoFire);
1.1       root      717: }
                    718: 
                    719: 
                    720: /*-----------------------------------------------------------------------*/
                    721: /*
                    722:   Saves the settings for all controls
                    723: */
                    724: - (void)saveAllControls
                    725: {
                    726:        // Export the preference controls into their vars
1.1.1.3 ! root      727:        EXPORT_SWITCH(autoInsertB, ConfigureParams.DiskImage.bAutoInsertDiskB);
        !           728:     EXPORT_SWITCH(blitter, ConfigureParams.System.bBlitter);
        !           729:        EXPORT_SWITCH(bootFromHD, ConfigureParams.HardDisk.bBootFromHardDisk);
        !           730:     EXPORT_SWITCH(captureOnChange, ConfigureParams.Screen.bCaptureChange);
        !           731:     EXPORT_TEXTFIELD(cartridgeImage, ConfigureParams.Rom.szCartridgeImageFileName);
        !           732:     EXPORT_RADIO(colorDepth, ConfigureParams.Screen.nVdiColors);
        !           733:     EXPORT_SWITCH(compatibleCpu, ConfigureParams.System.bCompatibleCpu);
        !           734:     EXPORT_RADIO(cpuClock, ConfigureParams.System.nCpuFreq);
        !           735:     EXPORT_RADIO(cpuType, ConfigureParams.System.nCpuLevel);
        !           736:        EXPORT_TEXTFIELD(defaultImagesLocation, ConfigureParams.DiskImage.szDiskImageDirectory);
        !           737:     EXPORT_SWITCH(enableMidi, ConfigureParams.Midi.bEnableMidi);
        !           738:     EXPORT_SWITCH(enablePrinter, ConfigureParams.Printer.bEnablePrinting);
        !           739:     EXPORT_SWITCH(enableRS232, ConfigureParams.RS232.bEnableRS232);
        !           740:     EXPORT_SWITCH(enableSound, ConfigureParams.Sound.bEnableSound);
        !           741:     EXPORT_DROPDOWN(frameSkip, ConfigureParams.Screen.nFrameSkips);
        !           742:     EXPORT_RADIO(keyboardMapping, ConfigureParams.Keyboard.nKeymapType);
        !           743:     EXPORT_TEXTFIELD(keyboardMappingFile, ConfigureParams.Keyboard.szMappingFileName);
        !           744:     EXPORT_RADIO(machineType, ConfigureParams.System.nMachineType);
        !           745:     EXPORT_RADIO(monitor, ConfigureParams.Screen.nMonitorType);
        !           746:     EXPORT_SWITCH(patchTimerD, ConfigureParams.System.bPatchTimerD);
        !           747:     EXPORT_RADIO(playbackQuality, ConfigureParams.Sound.nPlaybackQuality);
        !           748:     EXPORT_TEXTFIELD(printToFile, ConfigureParams.Printer.szPrintToFileName);
        !           749:     EXPORT_RADIO(ramSize, ConfigureParams.Memory.nMemorySize);
        !           750:     EXPORT_TEXTFIELD(readRS232FromFile, ConfigureParams.RS232.szInFileName);
        !           751:     EXPORT_SWITCH(realTime, ConfigureParams.System.bRealTimeClock);
        !           752:     EXPORT_SWITCH(slowFDC, ConfigureParams.System.bSlowFDC);
        !           753:     EXPORT_TEXTFIELD(tosImage, ConfigureParams.Rom.szTosImageFileName);
        !           754:     EXPORT_SWITCH(useBorders, ConfigureParams.Screen.bAllowOverscan);
        !           755:     EXPORT_SWITCH(useVDIResolution, ConfigureParams.Screen.bUseExtVdiResolutions);
        !           756:     EXPORT_TEXTFIELD(writeMidiToFile, ConfigureParams.Midi.szMidiOutFileName);
        !           757:        EXPORT_RADIO(writeProtection, ConfigureParams.DiskImage.nWriteProtection);
        !           758:     EXPORT_TEXTFIELD(writeRS232ToFile, ConfigureParams.RS232.szOutFileName);
        !           759:     EXPORT_SWITCH(zoomSTLowRes, ConfigureParams.Screen.bZoomLowRes);
        !           760:        EXPORT_SWITCH(showStatusBar,ConfigureParams.Screen.bShowStatusbar);
        !           761:        EXPORT_DROPDOWN(enableDSP,ConfigureParams.System.nDSPType);
1.1.1.2   root      762: 
1.1.1.3 ! root      763:        ConfigureParams.Screen.nForceBpp = ([force8bpp state] == NSOnState) ? 8 : 16;
1.1.1.2   root      764: 
                    765:        switch ([[resolution selectedCell] tag])
                    766:        {
                    767:         case 0:
1.1.1.3 ! root      768:                ConfigureParams.Screen.nVdiWidth = 640;
        !           769:                ConfigureParams.Screen.nVdiHeight = 480;
1.1.1.2   root      770:                break;
                    771:         case 1:
1.1.1.3 ! root      772:                ConfigureParams.Screen.nVdiWidth = 800;
        !           773:                ConfigureParams.Screen.nVdiHeight = 600;
1.1.1.2   root      774:                break;
                    775:         case 2:
1.1.1.3 ! root      776:                ConfigureParams.Screen.nVdiWidth = 1024;
        !           777:                ConfigureParams.Screen.nVdiHeight = 768;
1.1.1.2   root      778:                break;
                    779:        }
1.1       root      780: 
                    781:        // Define the HD flag, and export the HD path if one is selected
                    782:        if ([[hdImage stringValue] length] > 0)
                    783:        {
1.1.1.3 ! root      784:                EXPORT_TEXTFIELD(hdImage, ConfigureParams.HardDisk.szHardDiskImage);
        !           785:                ConfigureParams.HardDisk.bUseHardDiskImage = TRUE;
1.1       root      786:        }
                    787:        else
                    788:        {
1.1.1.3 ! root      789:                ConfigureParams.HardDisk.bUseHardDiskImage = FALSE;
1.1       root      790:        }
                    791:        
                    792:        // Define the Gemdos flag, and export the Gemdos path if one is selected
                    793:        if ([[gemdosImage stringValue] length] > 0)
                    794:        {
1.1.1.3 ! root      795:                EXPORT_TEXTFIELD(gemdosImage, ConfigureParams.HardDisk.szHardDiskDirectories[0]);
        !           796:                ConfigureParams.HardDisk.bUseHardDiskDirectories = TRUE;
1.1       root      797:        }
                    798:        else
                    799:        {
1.1.1.3 ! root      800:                ConfigureParams.HardDisk.bUseHardDiskDirectories = FALSE;
1.1       root      801:        }
                    802:        
                    803:        // Save the per-joystick controls               
                    804:        [self saveJoystickControls];    
                    805: }
                    806: 
                    807: @end

unix.superglobalmegacorp.com

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