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

unix.superglobalmegacorp.com

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