home *** CD-ROM | disk | FTP | other *** search
-
- /* Generated by Interface Builder */
-
- #import <daymisckit/daymisckit.h>
- #import <gamekit/gamekit.h>
- #import <stdio.h>
- #import <stdlib.h> /* malloc */
-
- BOOL getBOOLPreference(const char *name, BOOL def)
- {
- const char *tmpstr = NXGetDefaultValue ([NXApp appName], name);
- int temp = def;
- if (tmpstr) sscanf(tmpstr, "%d", &temp);
- if (temp) return YES;
- return NO;
- }
-
- int getIntPreference(const char *name, int min, int max, int def)
- {
- int tempInt;
- const char *tmpstr = NXGetDefaultValue ([NXApp appName], name);
- if (!tmpstr) return def;
- else {
- sscanf(tmpstr, "%d", &tempInt);
- if (tempInt < min) return min;
- if (tempInt > max) return max;
- }
- return tempInt;
- }
-
- const char *getStringPreference(const char *name, const char *def)
- {
- const char *tmpstr = NXGetDefaultValue ([NXApp appName], name);
- if (tmpstr == NULL) return def;
- return tmpstr;
- }
-
- void putIntPreference(const char *name, int value)
- {
- char str[16];
- sprintf(str, "%d", value);
- NXWriteDefault ([NXApp appName], name, str);
- }
-
- void putBOOLPreference(const char *name, BOOL value)
- {
- char str[16];
- int tempInt = 0;
- if (value) tempInt = 1;
- sprintf(str, "%d", tempInt);
- NXWriteDefault ([NXApp appName], name, str);
- }
-
- void putStringPreference(const char *name, const char *value)
- {
- NXWriteDefault ([NXApp appName], name, value);
- }
-
- @implementation PreferencesBrain
-
- static char *defaultServer = "*"; // very slow -- subclass should override!
-
- - init // designated initializer sets up game variables
- { // to sensible values.
- int i;
-
- [super init];
- for (i=0; i<MAXKEYS; i++) { // get space to store default keypresses in
- keys[i] = malloc(8);
- defkey[i] = malloc(8);
- }
- numKeys = 5;
- strcpy(defkey[0], "a");
- strcpy(defkey[1], "z");
- strcpy(defkey[2], "l");
- strcpy(defkey[3], ";");
- strcpy(defkey[4], " ");
- defaultPlayerName = [[DAYString alloc] init];
- version = malloc(8);
- serverName = NXCopyStringBufferFromZone(defaultServer, [self zone]);
- firstLoad = YES;
-
- return self;
- }
-
- - appDidInit:sender // forwarded by GameBrain
- { // Do all our basic init here
- if (!gameBrain) gameBrain = [NXApp delegate];
- if (!info) info = [gameBrain infoController];
- if (!scorePlayer) scorePlayer = [gameBrain scorePlayer];
- if (!soundPlayer) soundPlayer = [gameBrain soundPlayer];
- if (!highScoreTable)
- highScoreTable = [gameBrain highScoreController];
- if (!strings) strings = [gameBrain mainStrings];
- if (!gameScreen) gameScreen = [gameBrain gameScreen];
- [self readDefaults:self];
- [gameScreen getPreferences];
- return self;
- }
-
- // methods to get at instance variables
- - (int)startLevel { return level; } // returns starting level
- - (int)speed { return speed; }
- - (BOOL)border { return border; } // return YES if gray border is on
- - (BOOL)effects { return effects; }
- - (BOOL)music { return music; }
- - (BOOL)alert { return alert; }
- - (BOOL)autoUnPause { return autoUnPause; }
- - (BOOL)autoStart { return autoStart; }
- - (BOOL)demoSound { return demoSound; }
- - (BOOL)useServer { return useServer; }
- - setAlert:(BOOL)al { alert = al; return self; }
- - setAutoUnPause:(BOOL)al { autoUnPause = al; return self; }
- - setAutoStart:(BOOL)al { autoStart = al; return self; }
- - (const char *)serverName { return serverName; }
- - setNumKeys:(int)num { numKeys = num; return self; }
-
- - readDefaults:sender // get preferences from defaults database
- {
- char *tmpstr = malloc(16);
- int i;
-
- if (serverName) free(serverName);
- useServer = getBOOLPreference("UseServer", NO);
- effects = getBOOLPreference("SoundOn", YES);
- alert = getBOOLPreference("Alerts", YES);
- autoUnPause = getBOOLPreference("AutoUnPause", YES);
- autoStart = getBOOLPreference("AutoStart", YES);
- border = getBOOLPreference("Border", YES);
- demoSound = getBOOLPreference("DemoSound", YES);
- music = getBOOLPreference("MusicOn", YES);
- level = getIntPreference("StartLevel", 1, 20, 1);
- speed = getIntPreference("GameSpeed", 0, 2, 1);
-
- serverName = NXCopyStringBufferFromZone(
- getStringPreference("ServerName", defaultServer), [self zone]);
- strcpy(version, getStringPreference("Version", "0.0"));
- [self setDefaultPlayerName:getStringPreference(
- "PlayerName", [NXApp userRealName])];
- for (i=0; i < numKeys; i++) {
- sprintf(tmpstr, "Key%d", i);
- strcpy(keys[i], getStringPreference(tmpstr, defkey[i]));
- [gameScreen setKey:i val:keys[i][0]];
- }
-
- [gameScreen getPreferences];
- [highScoreTable setServerHost:serverName];
- if (useServer) [highScoreTable setLocalScores:NO];
- else [highScoreTable setLocalScores:YES];
- // if couldn't locate the server, go local.
- if (useServer && [highScoreTable localScores]) useServer = NO;
- free(tmpstr);
- [soundPlayer turnOn:effects];
- return self;
- }
-
- - writeDefaults:sender // save preferences in defaults database
- {
- char str[32]; int i;
-
- putBOOLPreference ("Border", border);
- putBOOLPreference ("Alerts", alert);
- putBOOLPreference ("AutoStart", autoStart);
- putBOOLPreference ("AutoUnPause", autoUnPause);
- putBOOLPreference ("DemoSound", demoSound);
- putBOOLPreference ("MusicOn", music);
- putBOOLPreference ("SoundOn", effects);
- putBOOLPreference ("UseServer", useServer);
- putIntPreference ("GameSpeed", speed);
- putIntPreference ("StartLevel", level);
- putStringPreference ("Version", version);
- putStringPreference ("ServerName", serverName);
- putStringPreference ("PlayerName", [defaultPlayerName stringValue]);
-
- for (i=0; i<numKeys; i++) { // ***** it would be better to make a single
- // string for all the keys; in the future I might make this adjustment.
- // This method leaves quite a few defaults...
- sprintf(str, "Key%d", i);
- putStringPreference(str, keys[i]);
- }
- return self;
- }
-
- - (BOOL)firstTimeCheck // first time running this version?
- {
- if (!version || ![info versionString]) return NO; // if NULL, then this
- // mechanism is disabled, so it's NEVER the first time running...
- if (strcmp(version, [info versionString])) { // first time if !=
- strcpy(version, [info versionString]);
- return YES; // when the Prefs are saved (exit, etc.) the version
- // # will be stored in defaults and then next time we'll return a NO
- }
- return NO;
- }
-
- - revert:sender // return to default values
- {
- int tempInt;
-
- speed = 1; effects = YES; alert = YES;
- autoUnPause = YES; autoStart = YES; border = YES;
- demoSound = YES; music = YES; useServer = NO;
- if (serverName) free(serverName);
- serverName = NXCopyStringBufferFromZone(defaultServer, [self zone]);
- if (![highScoreTable localScores]) [highScoreTable closeServers];
- [highScoreTable setServerHost:serverName];
- [gameScreen revertBackground:sender];
- for (tempInt=0; tempInt<numKeys; tempInt++) {
- strcpy(keys[tempInt], defkey[tempInt]);
- }
- // I'm not reverting defaultPlayerName; doesn't seem necessary
-
- for (tempInt=0; tempInt<4; tempInt++)
- [gameScreen setKey:tempInt val:keys[tempInt][0]];
- [gameScreen getPreferences]; // make sure that the gameScreen is aware
- return [self preferences:self]; // update the panel
- }
-
- - takeKey:sender // used by below (keyChange) to get new keys
- { // This is klunky; there's a better way to fill up the matrix; I'll
- // fix it eventually ***** (See how the GKHighScorePanel does it; it's
- // much cleaner than this.)
- strcpy(keys[[sender tag]],[sender stringValue]); // store internally
- [gameScreen setKey:[sender tag] val:keys[[sender tag]][0]]; // send to view
- return self;
- }
-
- - (char)keyVal:(int)keyIndex // returns default key for action (0-4)
- { return keys[keyIndex][0]; }
-
- - keyChange:sender // accept changes in keys
- {
- [keyMatrix sendAction:@selector(takeKey:) to:self forAllCells:YES];
- // ***** I should check here to be sure that the new keys don't
- // conflict with each other or with the 'p' and 'n' keys...
- return self;
- }
-
- - changeLevel:sender
- {
- level = [sender intValue];
- if (sender != levelSlider) [levelSlider setIntValue:level];
- else [levelText setIntValue:level];
- return self;
- }
-
- - speedChange:sender // accept changes in speed
- {
- speed = [sender selectedTag];
- return self;
- }
-
-
- - findKeyFor:sender // used by below to set keys in pref. matrix
- {
- [sender setStringValue:keys[[sender tag]]];
- return self;
- }
-
- - setUpViews
- { // here is where we hook up the views to be switched around in the panel
- // you should override this to add extra panes besides the three basic
- // ones expected here; you can use Columns as an example of how you
- // would go about doing this.
- [inspectorBox getFrame:&inspectFrame];
- [viewPlayer getFrame:&view[0]];
- [viewScreen getFrame:&view[1]];
- [viewSound getFrame:&view[2]];
- ViewsList = [[List alloc] init];
- thePopUpList = [thePopUpListButton target];
- [thePopUpList setTarget:self];
- [thePopUpList setAction:@selector(toggleInspectorPanels:)];
- [thePopUpList removeItemAt:0];
- [thePopUpList removeItemAt:0];
- [thePopUpList removeItemAt:0];
- [[[[self
- addView:viewPlayer withName:[strings valueForStringKey:"Player"]]
- addView:viewScreen withName:[strings valueForStringKey:"Screen"]]
- addView:viewSound withName:[strings valueForStringKey:"Sound" ]]
- show:[strings valueForStringKey:"Player"]];
- [preferencesPanel orderFront:self];
- [inspectorBox display];
- return self;
- }
-
- - preferences:sender // sets controls on pref panel & brings it up
- {
- [self preferencesPanel]; // be sure panel is loaded; throw away return val.
- if (firstLoad) {
- [self setUpViews];
- [preferencesPanel orderFront:self];
- [inspectorBox display];
- firstLoad = NO;
- }
- [self refresh];
- [[self preferencesPanel] orderFront:self];
- return self;
- }
-
- - refresh // refresh all controls -- set them to display the current state
- {
- [speedButtons selectCellWithTag:speed];
- [musicButtons selectCellWithTag:music];
- [effectButtons selectCellWithTag:effects];
- [levelText setIntValue:level];
- [levelSlider setIntValue:level];
- [alertSwitch setState:alert];
- [borderSwitch setState:border];
- [serverButton setState:useServer];
- [serverText setStringValue:serverName];
- [autoStartSwitch setState:autoStart];
- [autoUnPauseSwitch setState:autoUnPause];
- [demoSwitch setState:demoSound];
- [keyMatrix sendAction:@selector(findKeyFor:) to:self forAllCells:YES];
- return self;
- }
-
- //
- // Methods to handle inspectors and swapping views around...
- // (Very much adapted from NewInspector.m)
- //
-
- - free
- {
- [ViewsList free];
- [preferencesPanel orderOut:self];
- return [super free];
- }
-
- - addView:(id)aView withName:(const char *)name
- {
- [ViewsList addObject:aView];
- [thePopUpList addItem:name];
- return self;
- }
-
- - show:(const char *)name
- {
- [self turnOnView:[thePopUpList indexOfItem:name]];
- [thePopUpListButton setTitle:name];
- return self;
- }
-
- - toggleInspectorPanels:sender
- { // from pop-up list; we display the appropriate view.
- return [self turnOnView:[sender selectedRow]];
- }
-
- - turnOnView:(int)i
- {
- NXRect newFrame;
-
- [preferencesPanel disableFlushWindow];
- // get the right view
- [inspectorBox setContentView:[ViewsList objectAt:i]];
-
- // resize and move to the right place
- newFrame.size.width = view[i].size.width;
- newFrame.size.height = view[i].size.height;
- newFrame.origin.x = inspectFrame.origin.x +
- (inspectFrame.size.width - view[i].size.width)/2;
- newFrame.origin.y = inspectFrame.origin.y +
- (inspectFrame.size.height - view[i].size.height)/2;
- [inspectorBox setFrameFromContentFrame:&newFrame];
-
- // erase junk around it -- this wouldn't be necessary if I
- // properly added/removed the Views from the respective hierarchies.
- // sometime I'll get around to fixing this.
- newFrame.size.width = view[i].size.width;
- newFrame.size.height = view[i].size.height;
- newFrame.origin.x = inspectFrame.origin.x +
- (inspectFrame.size.width - view[i].size.width)/2;
- newFrame.origin.y = inspectFrame.origin.y +
- (inspectFrame.size.height - view[i].size.height)/2;
- [grayView aroundFrame:&newFrame :inspectFrame.origin.y];
-
- // finally, display the new view
- [inspectorBox display];
- [self refresh];
- [preferencesPanel reenableFlushWindow];
- [preferencesPanel flushWindowIfNeeded];
- return self;
- }
-
- - preferencesPanel // return the preferencesPanel, load it if needed.
- {
- if( !preferencesPanel) {
- [NXApp loadNibSection:"PreferencesPanel.nib" owner:self withNames:NO];
- [preferencesPanel setFrameUsingName:"Prefs"];
- [preferencesPanel setFrameAutosaveName:"Prefs"];
- }
- return preferencesPanel;
- }
-
- - musicChange:sender // turn music on/off
- {
- music = [[sender selectedCell] tag];
- // music runs independently, so we just turn it on or off at the
- // appropriate times. *****Maybe I should have the score playback
- // pause when you pause a game; right now it doesn't.
- #ifdef GK_USE_MUSICKIT
- if ((music) && ([gameScreen gameState] != GAMEOVER))
- [scorePlayer play:self];
- else [scorePlayer stop:self];
- #endif
- return self;
- }
-
- - setScore:sender
- { // sent by "Set Score File..." button; we forward to the ScorePlayer
- #ifdef GK_USE_MUSICKIT
- [scorePlayer selectFile:sender];
- #endif
- return self;
- }
-
- - effectsChange:sender // turn sound effects on/off
- {
- effects = [[sender selectedCell] tag];
- [soundPlayer turnOn:effects];
- return self;
- }
-
- - setDefaultPlayerName:(const char *)aString // change default player name
- {
- if (aString) [defaultPlayerName setStringValue:aString];
- else [defaultPlayerName setStringValue:"Mystery Player"];
- return self;
- }
-
- - (const char *)defaultPlayerName // return ptr to defaultPlayerName string
- {
- return [defaultPlayerName stringValue];
- }
-
- - alertChange:sender
- {
- alert = NO;
- if ([sender state]) alert = YES;
- return self;
- }
-
- - unPauseChange:sender
- {
- autoUnPause = NO;
- if ([sender state]) autoUnPause = YES;
- return self;
- }
-
- - autoStartChange:sender
- {
- autoStart = NO;
- if ([sender state]) autoStart = YES;
- return self;
- }
-
- - demoSoundChange:sender // New turn off sound only in demo
- {
- demoSound = NO;
- if ([sender state]) demoSound = YES;
- return self;
- }
-
- - setBack:sender // set the background image
- { // forward the message to the game screen
- return [gameScreen changeBackground:sender];
- }
-
- - revertBack:sender // revert to default background image
- { // forward the message to the game screen
- return [gameScreen revertBackground:sender];
- }
-
- - (BOOL)borderOn { return border; }
- - setBorder:(BOOL)newBord
- { // turn gray border on/off
- if (border == newBord) return self;
- border = newBord;
- [gameScreen changeBorder:border]; // inform the GameView to adjust things.
- return self;
- }
-
- - borderChange:sender
- { // turn gray border on/off -- sent by control on the panel
- // this is a cover for the above method
- return [self setBorder:[sender state]];
- }
-
- - setUseServer:(BOOL)useIt
- { // This allows the high score controlling object to turn things off
- // if it can't connect or it loses the connection to the server
- useServer = useIt;
- [serverButton setState:useIt];
- return [self refresh];
- }
-
- - changeServer:sender
- { // The main if block handles the button/check box, while the else
- // block handles changing the server name (and also automatically
- // checks the server box)
- if (sender != serverText) { // user changed the button state
- BOOL newUse = NO;
- // get the state of the check box
- if ([serverButton state]) newUse = YES;
- if (useServer != newUse) { // turn local on/off
- // attempt to connect to the servers if we aren't already
- // note that this call only will happen if we're going local
- // to network; if going the other way, we're already connected
- // so we pass through...
- if (![highScoreTable connected]) [highScoreTable connectToServers];
- // before finishing, make sure there were no problems connecting;
- // we can't assume all is OK. (The -connected handles that; the
- // 0 is in the case of going to a local table...)
- useServer = (newUse ? [highScoreTable connected] : 0);
- [highScoreTable setLocalScores:!useServer];
- }
- } else {
- // check to see if the name is changing
- if (strcmp(serverName, [serverText stringValue])) {
- // make note of the new name (it has changed)
- if (serverName) free(serverName);
- serverName = NXCopyStringBufferFromZone([serverText stringValue],
- [self zone]);
- [highScoreTable setServerHost:serverName];
- // close current servers if already connected
- // because we need to switch to a different server
- if ([highScoreTable connected]) [highScoreTable closeServers];
- }
- // force us to use the server (i.e. return in server field will cause
- // the check box to be checked automatically, enabling the server.)
- useServer = YES;
- [serverButton setState:useServer];
- if (![highScoreTable connected]) [highScoreTable connectToServers];
- // refresh the high score panel amongst other things.
- [highScoreTable setLocalScores:![highScoreTable connected]];
- }
- // Note that if we couldn't locate the server, we go local.
- // (The HighScoreController did that automatically for us above.)
- // Finally, refresh the prefs panel to reflect any changes of internal
- // state, in particular the state of the check box, which may have
- // changed due to what happened above. (No connection, etc.)
- [self refresh];
- return self;
- }
-
- // if the Prefs are "unfair" then a game cannot be saved on a network server.
- // it is up to you to add methods that set unfair when the prefs become
- // unfair. Also, in -startingGame, you should set unfair if any prefs are
- // unfair to begin with. As it stands here, any game is fair... Note that
- // the only way to clear the unfair variable is by starting a new game with
- // fair prefs; once a pref is made unfair, the game is unfair even if you
- // change it back.
- - (BOOL)unfair { return unfair; }
- - setUnfair { unfair = YES; return self; }
- - startingGame // reset the unfair variable
- {
- unfair = NO;
- return self;
- }
-
-
- @end
-