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.