This is GameModule.m in view mode; [Download] [Up]
/* indent:4 tabsize:8 font:fixed-width */
#import <Solitaire/GameModule.h>
#import <Solitaire/GamePref.h>
#import "localstrings.h"
#import <Solitaire/SmallCard.h>
#import <Solitaire/Card.h>
//static id _SolEngine;
#if 0
id SolEngine(void)
/*
* called by game modules to get access to game engine
*/
{
return nil; //_SolEngine;
}
void setSolEngine(id engine)
{
// _SolEngine = engine;
}
id SolGameController(void)
/*
* shortcut to current game controller
*/
{
return [_SolEngine gameController];
}
#endif
@implementation GameModule
/*"
GameModule is an abstract superclass providing a generic framework for
#{.solitaire} game modules. It contains a number of methods which can be
overridden to provide game-specific behavior.
The methods #startGame:, #restartGame:, and #checkForWin: should always be
overridden.
"*/
- initFromBundle:(NSBundle*)aBundle withName:(NSString*)name
/*"
Designated initializer for the GameModule class. If this method is
overridden in a subclass, always pass message back to this class via super.
"*/
{
NSString* path;
[super init];
bundle = aBundle;
gameName = [name copy];
if (path = [bundle pathForResource:@"Engine" ofType:@"nib"])
{
[NSBundle loadNibFile:path externalNameTable:
[NSDictionary dictionaryWithObjectsAndKeys:self,
@"NSOwner", nil] withZone:[self zone]];
}
[prefs setGameName:gameName];
return self;
}
- (NSView*) inspector:sender
/*"
Returns the module's inspector view.
"*/
{
return inspector;
}
- (void) inspectorWillBeRemoved
/*"
Sent just before the module's inspector is removed; i.e. before switching
to a new game. The default implementation does nothing.
"*/
{
}
- (void) inspectorInstalled
/*"
Sent immediately after this module's inspector view has been installed in
the Game Selection Panel. Override as needed. The default implementation
does nothing.
"*/
{
}
- (void) showRules:(id)sender
/*"
Displays the rules panel.
"*/
{
if (!rulesWindow)
{
NSString* path;
if (path = [bundle pathForResource:@"Rules" ofType:@"nib"])
{
[NSBundle loadNibFile:path externalNameTable:
[NSDictionary dictionaryWithObjectsAndKeys:self,
@"NSOwner", nil] withZone:[self zone]];
}
path = [NSString stringWithFormat:@"%@Rules",gameName];
[rulesWindow setFrameAutosaveName:path];
}
[rulesWindow makeKeyAndOrderFront:sender];
}
- (void) startGame:(id)sender
/*"
Start a new game; i.e. shuffle the deck and deal. If overridden, always
send the message back to the GameModule class via super.
"*/
{
[self commonGameSetup];
}
- (void) restartGame:(id)sender
/*"
Sent when user selects "Restart Game" option. The game should start over,
without shuffling the deck. If overridden, always send the message back to
the GameModule class via super.
"*/
{
[self commonGameSetup];
}
- (void) endGame:(id)sender
/*"
Sent when the game engine is about to switch to a different game. Default
implementation hides the game window and rules window.
"*/
{
if (gameWindow) [gameWindow performClose:self];
if (rulesWindow) [rulesWindow performClose:self];
}
- (void) win
/*"
Called when the game has been won. By default, invokes the generic "win"
routine. Override to create custom "game won" behaviour.
"*/
{
// This is currently declared in a category in the Solitaire app, though it
// probably doesn't need to be since I moved SolEngine to the framework.
// [SolEngine() win];
}
- (void) lose
/*"
Called when the game has been lost. Override to create new "lost"
behaviour. Most games will not bother to detect losing situations.
"*/
{
}
- (void) checkForWin
/*"
Determine if the game has been won. Always override (unless your game is
impossible to win). If you determine that the game has been won, then
call [self win].
"*/
{
}
- (BOOL) windowShouldClose:(id)sender
/*"
If the closing window is the game window we set our outlet to
nil and set it's delegate to nil too.
"*/
{
if (sender == gameWindow)
{
gameWindow = nil;
[sender setDelegate:nil];
}
return YES;
}
- (NSString*) nibPathForCardSize:(CardSize)aCardSize realSize:(CardSize *)realSize
/*"
Attempt to find the NIB containing the indicated CardSize. If not
found, try to find *any* game NIB. Returns the actual size found in
'realSize'.
"*/
{
NSString *path;
NSString *nibname;
*realSize = aCardSize;
if (aCardSize == CS_SMALL)
nibname = @"SmallGame";
else
nibname = @"LargeGame";
if ((path = [bundle pathForResource:nibname ofType:@"nib"]) == nil)
{
if (aCardSize == CS_SMALL)
{
nibname = @"LargeGame";
*realSize = CS_LARGE;
}
else
{
nibname = @"SmallGame";
*realSize = CS_SMALL;
}
if ((path = [bundle pathForResource:nibname ofType:@"nib"]) == nil)
{
NSRunAlertPanel(gameName,LOCALIZED_NONIB_MSG, @"",
nil, nil);
return nil;
}
}
return path;
}
- (void) loadGameWindow:(NSString*)path ofSize:(CardSize)size
/*"
Load the specified NIB file containing the game window.
"*/
{
[NSBundle loadNibFile:path externalNameTable:
[NSDictionary dictionaryWithObjectsAndKeys:self, @"NSOwner", nil]
withZone:[self zone]];
frameName = [[NSString alloc] initWithFormat:@"%@%@Window", gameName, ((size == CS_SMALL) ? @"Small" : @"Large")];
[gameWindow setFrameAutosaveName:frameName];
}
- (void) commonGameSetup
/*"
HELPER METHOD. DO NOT OVERRIDE. We load the correct game nib after
rescanning our generic preferences.
"*/
{
// This is currently declared in a categpry in the Soltiare app.
#if 0
int depth;
CardSize lastCardSize = cardSize;
// if game only supports one size of card, don't bother trying to
// load the missing size
if (!ignoreSizePref)
cardSize = [SolEngine() cardSize];
// generic information used in all games
desktopColor = [SolEngine() backgroundColor];
cardBack = [SolEngine() cardBack];
// load the preferred card size
if ((cardSize != lastCardSize) || !gameWindow)
{
NSString* path = nil;
CardSize realSize;
if ((path = [self nibPathForCardSize:cardSize realSize:&realSize]) == nil)
{
NSRunAlertPanel(gameName,LOCALIZED_NIBGONE_MSG,
@"", nil, nil);
return;
}
if (realSize != cardSize)
{
cardSize = realSize;
ignoreSizePref = YES;
}
if (cardSize != lastCardSize || !gameWindow)
{
if (gameWindow) [gameWindow performClose:self];
[self loadGameWindow:path ofSize:cardSize];
}
}
// Cards need to know what background to use
if (cardSize == CS_SMALL){
if(cardBack == CS_CUSTOM)
[[SmallCard class] setCardBackImage:
[SolEngine() imageForSize:cardSize]];
else
[[SmallCard class] setCardBack:cardBack];
}
else{
if(cardBack == CS_CUSTOM)
[[Card class] setCardBackImage:
[SolEngine() imageForSize:cardSize]];
else
[[Card class] setCardBack:cardBack];
}
// Support added for a color background if using a
// color or 8-bit gray machine
if ((depth = [gameWindow depthLimit]) == 0)
{
depth = [NSWindow defaultDepthLimit];
}
if (depth != NSBestDepth(NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
{
if (depth == NSBestDepth(NSCalibratedWhiteColorSpace, 8, 8, YES, NULL))
{
float grayLevel;
[[desktopColor colorUsingColorSpaceName:NSCalibratedWhiteColorSpace] getWhite:&grayLevel alpha:NULL];
[gameWindow setBackgroundColor:[NSColor colorWithCalibratedWhite:grayLevel alpha:1.0]];
}
else
{
[gameWindow setBackgroundColor:desktopColor];
}
}
#endif
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.