This is Solitaire.m in view mode; [Download] [Up]
/* indent:4 tabsize:8 font:fixed-width */ #if !defined (WIN32) #import <SoundKit/SoundKit.h> #import <libc.h> #endif #import "Solitaire.h" #import "ModuleList.h" #import "localstrings.h" #import <Solitaire/GameModule.h> #import "Preferences.h" #if defined (WIN32) #define random() rand() #define srandom(x) srand(x) #endif /* NOTE: This class is split into categories; see also SolitaireMore.m */ @implementation Solitaire /*--------------------------------------------------------------------------- | | - applicationDidFinishLaunching:notification | |---------------------------------------------------------------------------- | | Application delegate message. | \---------------------------------------------------------------------------*/ - (void) applicationDidFinishLaunching:(NSNotification *)notification { NSString *autoLaunch; NSNotificationCenter* notificationCenter; // setSolEngine(self); // get set to install the inspector inspectorFrame = [commonInspector frame]; currentInspector = nil; // make arrow keys work in game selection browser [gameSelectionBrowser setAcceptsArrowKeys:YES], [gameSelectionBrowser setSendsActionOnArrowKeys:YES]; [settingsPanel makeFirstResponder:gameSelectionBrowser]; // go find game modules, then select and load the default [self getGameType]; [self setGameIndex]; [settingsPanel setFrameAutosaveName:@"SettingsPanel"]; // hey, *somebody* might want to autolaunch Solitaire autoLaunch = [[NSUserDefaults standardUserDefaults] objectForKey:@"NXAutoLaunch"]; if (autoLaunch != nil && [autoLaunch isEqualToString:@"YES"]) { [NSApp hide:self]; } else { [settingsPanel makeKeyAndOrderFront:self]; windowHasBeenDisplayed = YES; } // We want to clean up if the power if going to be turned off. notificationCenter = [[NSWorkspace sharedWorkspace] notificationCenter]; [notificationCenter addObserver:self selector:@selector (workspaceWillPowerOff:) name:NSWorkspaceWillPowerOffNotification object:[NSWorkspace sharedWorkspace]]; srandom(time(0)); } /*--------------------------------------------------------------------------- | | - applicationDidUnhide: | |---------------------------------------------------------------------------- | | Application delegate message. Display settings panel if program is | being unhidden for the first time (normally after an autolaunch). | \---------------------------------------------------------------------------*/ - (void) applicationDidUnhide:(NSNotification *)notification { if (!windowHasBeenDisplayed) { [settingsPanel makeKeyAndOrderFront:self]; windowHasBeenDisplayed = YES; } } /*--------------------------------------------------------------------------- | | - (int)app:sender openFile:(NSString *)filename | | returns: (BOOL) YES if file was opened | NO if not | |---------------------------------------------------------------------------- | | Application delegate message requesting that a file be opened. | \---------------------------------------------------------------------------*/ - (int)application:sender openFile:(NSString *)filename { // setSolEngine(self); if ([filename pathExtension] && [[filename pathExtension] isEqualToString:@"solitaire"]) { NSString* fname = [filename lastPathComponent]; NSString* dirname = @""; [self setGameType:fname dir:dirname]; return YES; } else { NSBeep(); NSRunAlertPanel(LOCALIZED_OPEN_TITLE, LOCALIZED_OPEN_ERROR, @"", nil, nil, filename); return NO; } } /*-------------------------------------------------------------------------- | | - applicationShouldTerminate:sender | | returns: YES (it should terminate always) | |--------------------------------------------------------------------------- | | This is an Application delegate message sent just before the app | exits. | \--------------------------------------------------------------------------*/ - (BOOL) applicationShouldTerminate:(id)sender { /* kill the active game */ [[self gameController] endGame:self]; return YES; } /*-------------------------------------------------------------------------- | | - (void) workspaceWillPowerOff: | |--------------------------------------------------------------------------- | | This is an NSWorkspace notification that gets sent when the user | wants to turn off the power. | \--------------------------------------------------------------------------*/ - (void) workspaceWillPowerOff:(NSNotification*)notification { [[self gameController] endGame:self]; } /*--------------------------------------------------------------------------- | | - selectGameIndex: | |---------------------------------------------------------------------------- | | Target of game selection browser. | \---------------------------------------------------------------------------*/ - (void)selectGameIndex:sender { int index = [[gameSelectionBrowser matrixInColumn:0] selectedRow]; /* nothing to do if already selected */ if (index == realGameIndex) return; /* kill the active game */ [[self gameController] endGame:self]; realGameIndex = index; [self setGameIndex]; } /*--------------------------------------------------------------------------- | | - setGameIndex | |---------------------------------------------------------------------------- | | Load the chosen game. | \---------------------------------------------------------------------------*/ - (void) setGameIndex { GameModule* myController; NSView* newInspector; // save selected game to defaults [[NSUserDefaults standardUserDefaults] setObject:[moduleList realNameAtIndex:realGameIndex] forKey:@"gameType"]; // get the game controller (dynamically loads first time) if (!(myController = [self gameController])) { [self installInspector:nullInspector ownedBy:nil]; return; } // now plug in the inspector newInspector = [myController inspector:self]; if (!newInspector) newInspector = commonInspector; [self installInspector:newInspector ownedBy:myController]; // start a new game [myController startGame:self]; } /*--------------------------------------------------------------------------- | | - installInspector:newInspector ownedBy:myController | |---------------------------------------------------------------------------- | | Display the inspector. | \---------------------------------------------------------------------------*/ - (void)installInspector:(NSView*)newInspector ownedBy:(GameModule*)myController { if (newInspector != currentInspector) { [oldInspectorOwner inspectorWillBeRemoved]; oldInspectorOwner = myController; // don't want it to resize the box. Suboptimal technique... [newInspector setFrame:inspectorFrame]; // We don't want the old inspector to be freed and removing it [currentInspector retain]; [invisibleInspectorBox setContentView:newInspector]; currentInspector = newInspector; [myController inspectorInstalled]; [invisibleInspectorBox display]; } } /*--------------------------------------------------------------------------- | | - gameController | | returns: (GameeModule*) current game controller | |---------------------------------------------------------------------------- | | Return the game controller for the selected game. Dynamically load it | if necessary. | \---------------------------------------------------------------------------*/ - (GameModule*) gameController { GameModule* theController; if (![moduleList controllerAtIndex:realGameIndex]) { NSBundle *bundle; NSString *name; ModuleInfo *mp; NSZone *theZone; mp = [moduleList objectAtIndex:realGameIndex]; // don't try to load if it failed on a previous attempt if ([mp failed]) { return nil; } name = [mp realName]; bundle = [mp bundle]; // each module gets its own zone theZone = NSCreateZone(NSPageSize(), NSPageSize(), YES); NSSetZoneName(theZone, name); theController = [[[bundle classNamed:name] allocWithZone:theZone] initFromBundle:bundle withName:name]; if (!theController) { [mp setFailed:YES]; NSRecycleZone(theZone); NSRunAlertPanel([[NSProcessInfo processInfo] processName], LOCALIZED_LOAD_ERROR, @"", nil, nil, name); return nil; } [mp setController:theController]; } return [moduleList controllerAtIndex:realGameIndex]; } /*--------------------------------------------------------------------------- | | - (BOOL)browser:sender columnIsValid:(int)column | | returns: (BOOL) YES if browser contents are valid | NO if browser contents are not valid | |---------------------------------------------------------------------------- | | Delegate message of game selection browser. | \---------------------------------------------------------------------------*/ - (BOOL)browser:(NSBrowser *)sender isColumnValid:(int)column { return browserValid; } /*--------------------------------------------------------------------------- | | - addCellWithString:(NSString *)str at:(int)row toMatrix:matrix | |---------------------------------------------------------------------------- | | Description here. | \---------------------------------------------------------------------------*/ - (void)addCellWithString:(NSString *)str at:(int)row toMatrix:matrix { NSBrowserCell* theCell; [matrix insertRow:row]; theCell = [matrix cellAtRow:row column:0]; [theCell setStringValue:str]; [theCell setLoaded:YES]; [theCell setLeaf:YES]; } /*--------------------------------------------------------------------------- | | - browser:sender fillMatrix:matrix inColumn:(int)column | |---------------------------------------------------------------------------- | | Delegate message from game selection browser. Loads the browser. | \---------------------------------------------------------------------------*/ - (void)browser:(NSBrowser *)sender createRowsForColumn:(int)column inMatrix:(NSMatrix *)matrix { NSString *ptr; int i; // this shouldn't happen... if (browserValid) return; for (i = 0; i < [moduleList count]; i++) { [self addCellWithString:[moduleList nameAtIndex:i] at:i toMatrix:matrix]; } realGameIndex = 0; // select the active game ptr = [[NSUserDefaults standardUserDefaults] objectForKey:@"gameType"]; if (!ptr) ptr = @"Klondike"; if (ptr) { for (i = 0; i < [moduleList count]; i++) if ([ptr isEqualToString:[moduleList realNameAtIndex:i]]) { realGameIndex = i; break; } } browserValid = YES; } /*---------------------------------------------------------------------------- | | - newGame:sender | |----------------------------------------------------------------------------- | | Shuffle and deal the selected game. | \----------------------------------------------------------------------------*/ - (void) newGame:sender { [[self gameController] startGame:self]; } /*---------------------------------------------------------------------------- | | - restartGame:sender | |----------------------------------------------------------------------------- | | Restart the current game. | \----------------------------------------------------------------------------*/ - (void) restartGame:sender { [[self gameController] restartGame:self]; } /*---------------------------------------------------------------------------- | | - showRules:sender | |----------------------------------------------------------------------------- | | Show rules for the current game. | \----------------------------------------------------------------------------*/ - (void) showRules:sender { [[self gameController] showRules:self]; } /*---------------------------------------------------------------------------- | | - showInfoPanel: | |----------------------------------------------------------------------------- | | Display info panel. | \----------------------------------------------------------------------------*/ - (void) showInfoPanel:sender { if (!infoPanel) { /* NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"Info" ofType:@"nib"]; [NSBundle loadNibFile:path externalNameTable:[NSDictionary dictionaryWithObjectsAndKeys:self, @"NSOwner", nil] withZone:[self zone]]; */ [NSBundle loadNibNamed:@"Info.nib" owner:self]; [infoPanel setFrameAutosaveName:@"InfoPanel"]; } [infoPanel makeKeyAndOrderFront:nil]; } /*---------------------------------------------------------------------------- | | - windowShouldClose:sender | | returns: (BOOL) YES to close, NO otherwise | |----------------------------------------------------------------------------- | | Window delegate message. | \----------------------------------------------------------------------------*/ - (BOOL) windowShouldClose:(id)sender { if (sender == infoPanel) { infoPanel = nil; [sender setDelegate:nil]; } else if (sender == winPanel) { winPanel = nil; [sender setDelegate:nil]; } return YES; } /*---------------------------------------------------------------------------- | | - (CardSize)cardSize | | returns: (CardSize) current card size | |----------------------------------------------------------------------------- | | Request for card size. | \----------------------------------------------------------------------------*/ - (CardSize) cardSize { return [preferencesObject cardSize]; } /*---------------------------------------------------------------------------- | | - (CardBack)cardBack | | returns: (CardBack) current card back | |----------------------------------------------------------------------------- | | Request for card back. | \----------------------------------------------------------------------------*/ - (CardBack) cardBack { return [preferencesObject cardBack]; } /*---------------------------------------------------------------------------- | | - (NSColor*) backgroundColor | | returns: (NSColor*) current background color | |----------------------------------------------------------------------------- | | Request for background color. | \----------------------------------------------------------------------------*/ - (NSColor *) backgroundColor { return [preferencesObject backgroundColor]; } /*---------------------------------------------------------------------------- | | - imageForSize:(CardSize)aSize | | returns: (NSImage *) custom card back | |----------------------------------------------------------------------------- | | Request for card back custom image. | \----------------------------------------------------------------------------*/ - (NSImage*) imageForSize:(CardSize)aSize { return [preferencesObject imageForSize:aSize]; } /*---------------------------------------------------------------------------- | | - win | |----------------------------------------------------------------------------- | | Default win routine. | \----------------------------------------------------------------------------*/ - (void)win { if (!winPanel) { /* NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"Winner.nib" ofType:@"nib"]; [NSBundle loadNibFile:path externalNameTable:[NSDictionary dictionaryWithObjectsAndKeys:self, @"NSOwner", nil] withZone:[self zone]]; }; */ [NSBundle loadNibNamed:@"Winner.nib" owner:self]; } [winPanel makeKeyAndOrderFront:self]; #if !defined (WIN32) [[Sound findSoundFor:@"Trumpet.snd"] play]; #endif } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.