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.