home *** CD-ROM | disk | FTP | other *** search
-
- #import <gamekit/gamekit.h> // Colors
- #import <daymisckit/daymisckit.h> // ExtendedApp, etc.
- #import <dpsclient/psops.h> // PSsetgray()
- #import <dpsclient/wraps.h> // PScompositerect()
- #import <libc.h> // for random(), etc.
- #import <math.h> // for floor(), etc.
- #import <stdio.h> // for standard C file operations
-
-
- @implementation GameView
-
- #define dragdef const char *dragTypes[3] =\
- {NXFilenamePboardType, NXColorPboardType, NULL}
- #define dragNum 2
-
- - initFrame:(const NXRect *)frm // designated initializer for a view
- {
- dragdef;
-
- [super initFrame:frm];
- cycles = 0;
- srandom(time(0));
- demoMode = NO;
- grayBorder = YES;
- state = GAMEOVER;
- demoWait = 0;
- doingBorder = NO;
- grayBorder = YES;
- backColor = NXConvertRGBToColor(0.333, 0.333, 0.333); // dark gray default
- backIsColor = YES; // default bg is dark gray...
- [self registerForDraggedTypes:dragTypes count:dragNum];
- dragOperation = NX_DragOperationNone;
- return self;
- }
-
- - appDidInit:sender // forwarded by gamebrain
- {
- if (!controller) controller = [NXApp delegate];
- if (!preferences) preferences = [controller preferencesBrain];
- if (!scoreKeeper) scoreKeeper = [controller scoreKeeper];
- if (!strings) strings = [controller mainStrings];
- if (!customSound) customSound = [controller soundPlayer];
- [self loadPix];
- return self;
- }
-
- - loadPix
- {
- const char *tmpStr;
- char *okStr; float r, g, b;
-
- [self allocateGState];
-
- // set background
- okStr = malloc(8);
- tmpStr = NXGetDefaultValue([NXApp appName], "BackColor");
- if (tmpStr) {
- backIsColor = NO;
- sscanf(tmpStr, "%s %f %f %f", &okStr[0], &r, &g, &b);
- backColor = NXConvertRGBToColor(r, g, b);
- if (okStr[0] == 'Y') {
- backIsColor = YES;
- }
- }
- free(okStr);
-
- // get some buffers to hold our drawings.
- buffer = [[NXImage allocFromZone:[self zone]] initSize:&bounds.size];
- staticBuffer = [[NXImage allocFromZone:[self zone]] initSize:&bounds.size];
-
- if (!backIsColor)
- [self setBackgroundFile:
- NXGetDefaultValue([NXApp appName], "BackGround")
- andRemember:NO];
-
- return self;
- }
-
- - animate:sender
- { // method to start the animation - called by appDidInit
-
- // set up Animator: (autoUpdate) this handles moving viruses and
- // makes sure the columns fall when they should. The animator is
- // an object that handles timed entries "smartly".
- animator = [[Animator alloc] initChronon:[self speedTime]
- adaptation:0.0 target:self
- action:@selector(autoUpdate:) autoStart:YES eventMask:0];
-
- return self;
- }
-
- - (BOOL)demoMode // if last game was demo
- { return demoMode; }
-
- - (float)speedTime // returns time between animation frames
- { return GRANULARITY; // return delay between clock ticks
- } // 0.05 is about as fast as should be used.
-
- - (int)gameState // tell caller our state... if in demo, game is over
- { if (demoMode) return GAMEOVER; return state; }
-
- - (int)realGameState // tell caller our state...may need to really know...
- { return state; }
-
- - getOffset:(NXPoint *)aPoint // returns offset by reference
- {
- GK_VECTOR_X(aPoint) = offset.x; GK_VECTOR_Y(aPoint) = offset.y;
- return self;
- }
-
- - setOffset:(const NXPoint *)aPoint // change the offset
- {
- offset.x = GK_VECTOR_X(aPoint); offset.y = GK_VECTOR_Y(aPoint);
- return self;
- }
-
- - autoUpdate:sender // called by timed entry to update screen periodically
- { // ALL animation is controlled from here!!!
- cycles++;
- // you would do updates to various screen objects and
- // then do a [self updateSelf:&bounds :1];
- return self;
- }
-
- - updateSelf:(NXRect *)rects :(int)rectCount // redraws the screen.
- { // it redraws only what has changed since last redraw.
- NXPing();
- return self;
- }
-
- - mouseDown:(NXEvent *)event // handle mouseDown events.
- {
- [controller pauseGame:self]; // pause/unpause game
- return self;
- }
-
- - (BOOL)acceptsFirstMouse // let us grab activating mousedowns
- { // 1st click is to become 1st responder, NOT pause/unpause
- return NO;
- }
-
- - setKey:(int)keyIndex val:(char)keyVal // change key we respond to
- {
- keys[keyIndex] = keyVal;
- return self;
- }
-
- - pause:sender // set pause status.
- {
- paused = YES;
- return self;
- }
-
- - unpause:sender // remove paused status
- {
- paused = NO;
- return self;
- }
-
- - (BOOL)isPaused // tell caller is we're paused
- { return paused; }
-
- - keyDown:(NXEvent *)myevent // handle keyDown events.
- {
- PSobscurecursor(); // subclasses which override need to do this.
- if (myevent->data.key.charSet == NX_ASCIISET &&
- (myevent->flags&(NX_CONTROLMASK|NX_ALTERNATEMASK|NX_COMMANDMASK)) == 0)
- {
- if (GKKEYCODE == 'p') { // allow pause
- if (paused) [controller unpause];
- else [controller pause];
- } else if (GKKEYCODE == 'n') { // allow new game
- [controller startNewGame:self]; // re-start the game
- // returns nil if user changes mind...
- } else if (paused) { // any keyDown unpauses game (except 'p').
- [controller unpause];
- }
- } else return [super keyDown:myevent];
- return self;
- }
-
- - (BOOL)acceptsFirstResponder // to grab keyboard events
- { return YES; }
-
- - getPreferences
- {
- if (!preferences) preferences = [[NXApp delegate] preferencesBrain];
- return self;
- }
-
- - free // get rid of support objects
- {
- [animator free];
- return [super free];
- }
-
- - setUpScreen
- {
- if ((demoMode)||(doingBorder)) [self display];
- return self;
- }
-
- - changeBorder:(BOOL)borderOn
- { // move view about in the window & do sizing
- NXRect wFrame;
-
- if (borderOn == grayBorder) return self;
-
- if (borderOn) {
- [window getFrame:&wFrame];
- NXInsetRect(&wFrame, -BEZELSIZE, -BEZELSIZE);
- [self moveBy:BEZELSIZE :BEZELSIZE];
- [window placeWindowAndDisplay:&wFrame];
- } else {
- [window getFrame:&wFrame];
- NXInsetRect(&wFrame, BEZELSIZE, BEZELSIZE);
- [self moveBy:-BEZELSIZE :-BEZELSIZE];
- [window placeWindowAndDisplay:&wFrame];
- }
- grayBorder = borderOn;
- return self;
- }
-
- - restartGame
- {
- cycles = 0;
- state = NORMALSTATE;
- if (demoMode) {
- demoMode = NO;
- [[self window] setTitle:[strings valueForStringKey:"GameName"]];
- }
- [scoreKeeper resetScore];
- [self getPreferences]; // make sure we're up to date
- return self;
- }
-
- //// Background handling methods stolen from BreakApp:
-
- - setBackgroundFile:(const char *)fileName andRemember:(BOOL)remember
- // This methods allows changing the file used to paint the background of the
- // playing field. Set fileName to NULL to revert to the default. Set
- // remember to YES if you wish the write the value out in the defaults.
- {
- [backGround free];
-
- backGround = [[NXImage allocFromZone:[self zone]] initSize:&bounds.size];
- [backGround setBackgroundColor:backColor];
- [backGround setScalable:YES];
- if (fileName) {
- [backGround useFromFile:fileName];
- if (remember) {
- NXWriteDefault ([NXApp appName], "BackGround", fileName);
- }
- } else { // default background image
- [backGround useFromSection:"BackGround.eps"];
- if (remember) {
- NXRemoveDefault ([NXApp appName], "BackGround");
- }
- }
- backIsColor = NO;
- [self buildBackground];
- [self writeColor];
- [self display];
- return self;
- }
-
- - buildBackground { return self; } // for subclass use
-
- // The following two methods allow changing the background image from
- // menu items or buttons.
-
- - changeBackground:sender
- {
- const char *const *types = [NXImage imageFileTypes];
- if ([[OpenPanel new] runModalForTypes:types]) {
- [self setBackgroundFile:[[OpenPanel new] filename] andRemember:YES];
- [self display];
- }
- return self;
- }
-
- - revertBackground:sender
- {
- backIsColor = NO;
- [self setBackgroundFile:NULL andRemember:YES];
- [self display];
- return self;
- }
-
- - loadAnImage:(const char *)imageName
- {
- char *tempStr = (char *)malloc(MAXPATHLEN);
- sprintf(tempStr, "%s/%s", [NXApp appDirectory], imageName);
- [self setBackgroundFile:tempStr andRemember:YES];
- free(tempStr); [self display];
- return self;
- }
-
- - back1:sender { return [self loadAnImage:"Back1.eps"]; }
- - back2:sender { return [self loadAnImage:"Back2.tiff"]; }
- - back3:sender { return [self loadAnImage:"Back3.tiff"]; }
-
- - drawBackground:(NXRect *)rect
- // drawBackground: just draws the specified piece of the background by
- // compositing from the background image.
- {
- NXRect tmpRect = *rect;
-
- if (backIsColor) {
- NXSetColor(backColor);
- NXRectFill(rect);
- return self;
- }
-
- NX_X(&tmpRect) = floor(NX_X(&tmpRect));
- NX_Y(&tmpRect) = floor(NX_Y(&tmpRect));
- if (NXDrawingStatus == NX_DRAWING) {
- PSsetgray (NX_BLACK);
- PScompositerect (NX_X(&tmpRect), NX_Y(&tmpRect),
- NX_WIDTH(&tmpRect), NX_HEIGHT(&tmpRect), NX_SOVER);
- }
- [backGround composite:NX_SOVER fromRect:&tmpRect toPoint:&tmpRect.origin];
- return self;
- }
-
- - sizeTo:(NXCoord)width :(NXCoord)height
- {
- [super sizeTo:width :height];
- [backGround setSize:&bounds.size];
- return self;
- }
-
-
- // deal with drag and drop colors:
- - acceptColor:(NXColor)color atPoint:(const NXPoint *)aPoint
- {
- backIsColor = YES;
- backColor = color;
- [[self writeColor] update];
- return self;
- }
-
- - writeColor
- {
- char def[256];
- float r, g, b;
-
- NXConvertColorToRGB(backColor, &r, &g, &b);
- sprintf(def, "%s %f %f %f", (backIsColor ? "YES" : "NO"), r, g, b);
- NXWriteDefault ([NXApp appName], "BackColor", def);
- return self;
- }
-
-
- // these assume that you already locked focus. Thus, when overriding
- // these methods, the subclas should lock focus in the static buffer
- // before calling the super (this) method.
- - rebuildStaticBuffer
- {
- [self drawBackground:&bounds];
- return self;
- }
-
- - rebuildStaticAt:(NXRect *)rect
- {
- [self drawBackground:rect];
- return self;
- }
-
- // drag and drop an image into the view's background.
- // uses 3.0 drag kit stuff
-
- - (NXDragOperation)draggingEntered:sender
- {
- NXDragOperation sourceMask;
-
- // Ask the sender for its operation mask.
- sourceMask = [sender draggingSourceOperationMask];
- if (sourceMask & NX_DragOperationCopy)
- dragOperation = NX_DragOperationCopy;
- else if (sourceMask & NX_DragOperationGeneric)
- dragOperation = NX_DragOperationGeneric;
- else dragOperation = NX_DragOperationNone;
- return dragOperation;
- }
-
- - (NXDragOperation)draggingUpdated:sender { return dragOperation; }
- - draggingExited:sender { return self; }
-
- - (BOOL)prepareForDragOperation:sender
- { // We do want to accept the dragged image/color.
- return YES;
- }
-
- - (BOOL)performDragOperation:sender
- {
- Pasteboard *dragPasteboard = [Pasteboard newName:NXDragPboard];
- char *file;
- int length;
- dragdef;
- BOOL foundOne = NO;
-
- if ([dragPasteboard findAvailableTypeFrom:dragTypes num:dragNum]
- == NXFilenamePboardType) {
- if ([dragPasteboard readType:NXFilenamePboardType
- data:&file length:&length]) {
- foundOne = YES;
- [self setBackgroundFile:file andRemember:YES];
- [dragPasteboard deallocatePasteboardData:file length:length];
- [NXApp activateSelf:YES];
- [window makeKeyAndOrderFront:self];
- } }
- else if ([dragPasteboard findAvailableTypeFrom:dragTypes num:dragNum]
- == NXColorPboardType) {
- NXPoint p = [sender draggingLocation];
- NXColor c = NXReadColorFromPasteboard([sender draggingPasteboard]);
- [self acceptColor:c atPoint:&p];
- foundOne = YES;
- [NXApp activateSelf:YES];
- [window makeKeyAndOrderFront:self];
- }
- return foundOne;
- }
-
- - concludeDragOperation:sender { return self; }
-
- - gameOver // sent by GameBrain
- {
- state = GAMEOVER;
- return self;
- }
-
- @end
-