This is SplatApp.m in view mode; [Download] [Up]
/* * SplatApp * description: subclass of EKApplication - keeps track of the main UI * components and application flow * history: * 5/1/93 [Erik Kay] - converted much of the SplatController to here * 6/8/93 [Erik Kay] - cleaned up some of the file opening code */ #import "SplatApp.h" #import "SplatGame.h" #import "SplatDefaults.h" #import "Board.h" #import "ComputerPlayer.h" #import "HumanPlayer.h" #import "NetworkPlayer.h" #import <sys/dir.h> #define COMP_EXTENSION "scplayer" @implementation SplatApp - challenge:sender { int exitValue; id panel; DPSContext newcontext, oldcontext; NXHandler handler; newcontext = DPSCreateContext("drool",0,0,0); oldcontext = context; context = newcontext; DPSSetContext(newcontext); panel = NXGetAlertPanel ("Splat Challenge", "Erik is challenging you to a game of Splat. Do you accept?", "OK","Cancel",NULL); [panel center]; [panel makeKeyAndOrderFront:self]; NX_DURING { handler.code = 0; exitValue = [NXApp runModalFor:panel]; } NX_HANDLER { handler = NXLocalHandler; if (handler.code == dps_err_ps) NXReportError((NXHandler *)(&handler)); } NX_ENDHANDLER [panel orderOut:self]; context = oldcontext; DPSSetContext([NXApp context]); return self; } /* * setup and new game initialization */ + new { self = [super new]; [self setDelegate:self]; //? we're our own delegate... duh! // setup resources that I want to be preloaded [self addImageResource:"one"]; [self addImageResource:"two"]; [self addImageResource:"obstruction"]; [self addImageResource:"smallone"]; [self addImageResource:"smalltwo"]; [self addSoundResource:"move"]; [self addSoundResource:"change"]; [self addSoundResource:"bigChange"]; [self addSoundResource:"wowChange"]; [self addSoundResource:"gameOver"]; [self addSoundResource:"win"]; return self; } - appDidInit:sender { NXRect f1, f2; int i; id button, matrix, popup; char path[MAXPATHLEN], boardPath[MAXPATHLEN]; const char *tmp; [defaultsManager loadDefaults]; // load the computer players [self loadComputerStrategies]; // board file initialization tmp = [[NXBundle mainBundle] directory]; sprintf(path,"%s/boards",tmp); boardBundle = [[NXBundle alloc] initForDirectory:path]; strcpy(boardPath,[defaultsManager boardPath]); // initialize the mini board [miniSplatBoard setScalable:YES]; [miniSplatBoard setBoard:[Board newFromFile:boardPath]]; // games games = [[List alloc] init]; // load resources [self loadResources]; // setup the "new game setup" panel player1CurrentView = player1NewHuman; player2CurrentView = player2NewComputer; [player1NewGame getFrame:&f1]; [player2NewGame getFrame:&f2]; [player1CurrentView setFrame:&f1]; [player2CurrentView setFrame:&f2]; [[player1NewGame superview] replaceSubview:player1NewGame with:player1CurrentView]; [[player2NewGame superview] replaceSubview:player2NewGame with:player2CurrentView]; [player1CurrentView display]; [player2CurrentView display]; [newGamePanel flushWindow]; //? initialize all of the popups properly //? This is a hack to workaround bug #35247 //? basically, popup matrices aren't initialized properly (they don't have //? a selected cell unless the user selects something), so the we have to //? do the initialization manually. Note that all popup connections are //? also being set equal to their matrices since all future operations will //? be with the matrices themselves. the variable name is a little //? confusing for this and perhaps we should have additional variables for //? the matrices button = player1TypePopup; popup = [button target]; matrix = [popup itemList]; [matrix selectCellAt:[popup indexOfItem:[button title]] :0]; player1TypePopup = matrix; button = player2TypePopup; popup = [button target]; matrix = [popup itemList]; [matrix selectCellAt:[popup indexOfItem:[button title]] :0]; player2TypePopup = matrix; button = player1SearchDepth; popup = [button target]; matrix = [popup itemList]; [matrix selectCellAt:[popup indexOfItem:[button title]] :0]; player1SearchDepth = matrix; button = player2SearchDepth; popup = [button target]; matrix = [popup itemList]; [matrix selectCellAt:[popup indexOfItem:[button title]] :0]; player2SearchDepth = matrix; button = player1CompPopup; popup = [button target]; matrix = [popup itemList]; [matrix selectCellAt:[popup indexOfItem:[button title]] :0]; player1CompPopup = popup; button = player2CompPopup; popup = [button target]; matrix = [popup itemList]; [matrix selectCellAt:[popup indexOfItem:[button title]] :0]; player2CompPopup = popup; // add the different strategies to the popup list for new game selection for (i = 0; i < [computerStrategies count]; i++) { [[player1CompPopup addItem: [[computerStrategies objectAt:i] strategyName]] setTag:i]; [[player2CompPopup addItem: [[computerStrategies objectAt:i] strategyName]] setTag:i]; } player1CompPopup = [player1CompPopup itemList]; player2CompPopup = [player2CompPopup itemList]; [player1HumanName setStringValue:[defaultsManager defaultPlayerName]]; [player2HumanName setStringValue:[defaultsManager defaultPlayerName]]; [newGamePanel makeKeyAndOrderFront:self]; return self; } - initializePlayersForGame:game { id item, player, strategy, rules; int tag; rules = [game rules]; item = [player1TypePopup selectedCell]; tag = [item tag]; switch (tag) { case 0: /* Human */ player = [[HumanPlayer alloc] initWithRules:rules andPieceType:SQUARE_ONE]; [player setPlayerName:[player1HumanName stringValue]]; break; case 1: /* Computer */ strategy = [computerStrategies objectAt:[[player1CompPopup selectedCell] tag]]; player = [[strategy alloc] initWithRules:rules andPieceType:SQUARE_ONE]; [player setSearchDepth:[[player1SearchDepth selectedCell] tag]]; break; case 2: /* Network */ default: player = [[NetworkPlayer alloc] initWithRules:rules andPieceType:SQUARE_ONE]; [player setHostname:[player1NetHostname stringValue]]; break; } [game setPlayer1:player]; item = [player2TypePopup selectedCell]; tag = [item tag]; switch (tag) { case 0: /* Human */ player = [[HumanPlayer alloc] initWithRules:rules andPieceType:SQUARE_TWO]; [player setPlayerName:[player2HumanName stringValue]]; break; case 1: /* Computer */ strategy = [computerStrategies objectAt:[[player2CompPopup selectedCell] tag]]; player = [[strategy alloc] initWithRules:rules andPieceType:SQUARE_TWO]; [player setSearchDepth:[[player2SearchDepth selectedCell] tag]]; break; case 2: /* Network */ default: player = [[NetworkPlayer alloc] initWithRules:rules andPieceType:SQUARE_TWO]; [player setHostname:[player2NetHostname stringValue]]; break; } [game setPlayer2:player]; return self; } /* * dynamically loaded computer strategies */ - loadComputerStrategies { DIR *dir; struct direct *dir_entry; const char *path; char *filename, *suffix; computerStrategies = [[List alloc] init]; path = [[NXBundle mainBundle] directory]; dir = opendir(path); if (dir) { while (dir_entry = readdir(dir)) { filename = dir_entry->d_name; if ((strcmp(filename,".") == 0) || (strcmp(filename,"..") == 0)) continue; suffix = rindex(filename,'.'); if (!suffix || (strcmp(suffix,".cplayer") && strcmp(suffix,".bundle"))) continue; [self loadComputer:filename]; } closedir(dir); } return self; } - loadComputer:(const char *)name { char path[MAXPATHLEN], cname[256]; id newBundle, comp; sprintf(path,"%s/%s",[[NXBundle mainBundle] directory],name); newBundle = [[NXBundle alloc] initForDirectory:path]; strcpy(path,name); *(rindex(path,'.')) = '\0'; sprintf(cname,"%sComp",path); comp = [newBundle classNamed:cname]; if ([computerStrategies indexOf:comp] != NX_NOT_IN_LIST) return comp; // this one has already been loaded [computerStrategies addObject:comp]; return comp; } /* * the board... opening a new board file, etc. */ - openBoard:sender { static id openPanel = nil; const char *theType = BOARD_EXTENSION, *filename; char const *fileTypes[2] = {0,0}; static char boardDir[MAXPATHLEN] = {'\0'}; int opr; char *ptr; if (!boardDir[0]) strcpy(boardDir,[boardBundle directory]); if (!openPanel) openPanel = [OpenPanel new]; if (theType && *theType) fileTypes[0] = theType; [NXApp setAutoupdate:NO]; opr = [openPanel runModalForDirectory:boardDir file:NULL types:fileTypes]; if (opr) { filename = [openPanel filename]; [self loadBoard:filename]; strcpy(boardDir,filename); ptr = rindex(boardDir,'/'); if (ptr) *ptr = '\0'; } else { [NXApp setAutoupdate:YES]; return self; } return self; } - loadBoard:(const char *)path { id oldBoard, newBoard; oldBoard = [miniSplatBoard board]; newBoard = [Board newFromFile:path]; [miniSplatBoard setScalable:YES]; [miniSplatBoard setBoard:newBoard]; [oldBoard free]; [NXApp setAutoupdate:YES]; return self; } - (BOOL)appAcceptsAnotherFile:sender { return YES; } - (int)app:sender openFile:(const char *)filename type:(const char *)aType { if (!strcmp(aType,BOARD_EXTENSION)) [self loadBoard:filename]; else if (!strcmp(aType,COMP_EXTENSION)) [self loadComputer:filename]; else return NO; return YES; } /* * selecting a new game setup */ - newGame:sender { id rules, game, board; [newGamePanel close]; [newGameCancel setEnabled:YES]; rules = [[SplatRules alloc] init]; game = [[SplatGame alloc] init]; [game setRules:rules]; [game setGameState:NO_GAME]; board = [[miniSplatBoard board] trueCopy]; [game setBoard:board]; [board free]; [self initializePlayersForGame:game]; if (![game initNetPlayers]) { [game free]; return self; } //? must do this to prevent deadlock if (![[game player1] isKindOf:[NetworkPlayer class]]) [game showGame]; currentGame = game; return self; } - cancelNewGame:sender { [newGamePanel close]; return self; } - setPlayer1Type:sender { id menu, newView; NXRect f; int tag; menu = [sender selectedCell]; tag = [menu tag]; switch (tag) { case 0: /* Human */ newView = player1NewHuman; break; case 1: /* Computer */ newView = player1NewComputer; break; case 2: /* Network */ newView = player1NewNetwork; break; default: /* error */ fprintf (stderr,"Splat: unknown player type selected: %d\n",tag); return self; break; } [[player1CurrentView superview] replaceSubview:player1CurrentView with:newView]; player1CurrentView = newView; [player1NewGame getFrame:&f]; [player1CurrentView setFrame:&f]; [newView display]; return self; } - setPlayer2Type:sender { id menu, newView; NXRect f; int tag; menu = [sender selectedCell]; tag = [menu tag]; switch (tag) { case 0: /* Human */ newView = player2NewHuman; break; case 1: /* Computer */ newView = player2NewComputer; break; case 2: /* Network */ newView = player2NewNetwork; break; default: /* error */ fprintf (stderr,"Splat: unknown player type selected: %d\n",tag); return self; break; } [[player2CurrentView superview] replaceSubview:player2CurrentView with:newView]; player2CurrentView = newView; [player2NewGame getFrame:&f]; [player2CurrentView setFrame:&f]; [newView display]; return self; } // // control the current game // - pauseGame:sender { [currentGame pauseGame:sender]; return self; } - stopGame:sender { [currentGame stopGame:sender]; return self; } - startGame:sender { [currentGame stopGame:sender]; [currentGame startGame:sender]; return self; } // // delegate methods // - appWillTerminate:sender { [defaultsManager writeDefaults]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.