This is TetApp.m in view mode; [Download] [Up]
#import <appkit/Button.h> #import <appkit/ButtonCell.h> #import <appkit/Panel.h> #import <appkit/Window.h> #import <appkit/TextField.h> #import <appkit/graphics.h> #import <string.h> #import <ctype.h> #import "TetApp.h" #import "NextMatrix.h" #import "ScoreKeeper.h" #import "TetMatrix.h" @implementation TetApp - initForColor { const NXScreen *deepestScreen; const char *str; str = NXGetDefaultValue([NXApp appName], "ColorOff"); if (str != NULL && (strcmp(str, "YES") == 0)) { colorOff = YES; gameInColor = NO; #ifdef DEBUG fprintf(stderr, "Game wants to be B&W\n"); #endif } else { colorOff = NO; deepestScreen = [NXApp colorScreen]; if ( deepestScreen->depth != NX_TwoBitGrayDepth ) { // Then 12 bit color should be more than enough [tetrisWindow setDepthLimit:NX_TwelveBitRGBDepth]; gameInColor = YES; } else { gameInColor = NO; } } return self; } + new { self = [super new]; [self setDelegate:self]; [self initForColor]; started = paused = NO; numRandomRows = 4; return self; } - setLevelLeft:anObject { levelLeft = anObject; [[levelLeft cell] setHighlightsBy:NX_CONTENTS | NX_CHANGEGRAY]; [levelLeft sendActionOn:NX_MOUSEDOWNMASK]; return self; } - setLevelRight:anObject { levelRight = anObject; [[levelRight cell] setHighlightsBy:NX_CONTENTS | NX_CHANGEGRAY]; [levelRight sendActionOn:NX_MOUSEDOWNMASK]; return self; } - (BOOL) isGameColor { return gameInColor; } - setTetrisWindow:anObject { tetrisWindow = anObject; [tetrisWindow setDelegate:self]; [tetrisWindow setMiniwindowIcon:"Tetris"]; return self; } - appDidInit:sender { const char *str; int levelValue; [controlWindow removeFromEventMask:NX_KEYDOWNMASK|NX_KEYUPMASK]; [controlWindow orderFront:self]; str = NXGetDefaultValue([NXApp appName], "CurrentLevel"); if (str != NULL) { sscanf(str, "%d", &levelValue); [level setIntValue: levelValue]; [self updateLeft: levelValue]; [self updateRight: levelValue]; #ifdef DEBUG fprintf(stderr, "Setting current level to %d\n", levelValue); #endif } str = NXGetDefaultValue([NXApp appName], "RandomRows"); if (str != NULL) { sscanf(str, "%d", &numRandomRows); [randomField setIntValue:numRandomRows]; [randomSlider setIntValue:numRandomRows]; #ifdef DEBUG fprintf(stderr, "Setting number Random rows to %d\n", numRandomRows); #endif } str = NXGetDefaultValue([NXApp appName], "ShowNext"); if (str != NULL) { if (strcmp(str, "YES") == 0) { [showNextSwitch setIntValue: YES]; [showNext showNext:showNextSwitch]; // ID is actually ignored } } [colorSwitch setIntValue: colorOff]; [tetrisWindow orderWindow:NX_ABOVE relativeTo:0]; [tetrisWindow makeKeyWindow]; return self; } - (BOOL) gamePaused { return paused; } - keyDown:(NXEvent *)theEvent { unsigned short charCode; printf("Keydown in TetApp\n"); charCode = theEvent->data.key.charCode; if (isupper(charCode)) charCode = tolower(charCode); switch (charCode) { case 13: // Pause if the user hits return [self pause:self]; } return self; } - resignActiveApp { if (started && !paused) [self pause:self]; return [super resignActiveApp]; } - updateLeft:(int) theLevel { if (theLevel <= MIN_LEVEL) { [[levelLeft setEnabled:NO] setIcon:"scrollMenuLeftD"]; } else { [[levelLeft setEnabled:YES] setIcon:"scrollMenuLeft"]; } return self; } - updateRight:(int) theLevel { if (theLevel >= MAX_LEVEL) { [[levelRight setEnabled:NO] setIcon:"scrollMenuRightD"]; } else { [[levelRight setEnabled:YES] setIcon:"scrollMenuRight"]; } return self; } - start:sender { int levelValue = [level intValue]; if (started) { if (paused) [self pause:sender]; [tetrisView stop:sender]; [[tetrisView window] disableFlushWindow]; [showNext end:self]; [startButton setTitle:"New game"]; [pauseButton setEnabled:NO]; [levelLeft setTransparent:NO]; [levelRight setTransparent:NO]; [self updateLeft: levelValue]; [self updateRight: levelValue]; [[[tetrisView window] reenableFlushWindow] flushWindow]; started = NO; } else { [[tetrisView window] disableFlushWindow]; [showNext start:self]; [startButton setTitle:"Abort"]; [pauseButton setEnabled:YES]; [scoreKeeper setZero]; [tetrisView setScoreKeeper:scoreKeeper]; [[levelLeft setTransparent:YES] setEnabled:NO]; [[levelRight setTransparent:YES] setEnabled:NO]; [[[tetrisView window] reenableFlushWindow] flushWindow]; [tetrisView newGame:levelValue]; started = YES; } return self; } - pause:sender { [[tetrisView window] disableFlushWindow]; if (paused) { [pauseButton setTitle:"Pause"]; [pauseDisplay setStringValueNoCopy:""]; [tetrisView continue:sender]; paused = NO; } else { [tetrisView pause:sender]; [pauseButton setTitle:"Continue"]; [pauseDisplay setStringValueNoCopy:"PAUSED"]; paused = YES; } [[[tetrisView window] reenableFlushWindow] flushWindow]; return self; } - gameOver { int levelValue = [level intValue]; [[tetrisView window] disableFlushWindow]; [showNext end:self]; [startButton setTitle:"New game"]; [pauseButton setEnabled:NO]; [levelLeft setTransparent:NO]; [levelRight setTransparent:NO]; [self updateLeft: levelValue]; [self updateRight: levelValue]; [[[tetrisView window] reenableFlushWindow] flushWindow]; NXPing(); started = NO; [scoreKeeper updateHighScores:levelValue]; return self; } - levelLeft:sender { int levelValue = [level intValue]; if (levelValue != MIN_LEVEL) { [level setIntValue:--levelValue]; [self updateLeft: levelValue]; [self updateRight: levelValue]; } return self; } - levelRight:sender { int levelValue = [level intValue]; if (levelValue != MAX_LEVEL) { [level setIntValue:++levelValue]; [self updateLeft: levelValue]; [self updateRight: levelValue]; } return self; } /* * Set the number of rows where random pieces will appear. */ - setRandomRows:sender { int tmp; tmp = [sender intValue]; // Will always be valid since slider is the only object that can call me!? if (tmp >= 0 && tmp <=10) { numRandomRows = tmp; [randomField setIntValue: tmp]; } else { [randomField setIntValue:numRandomRows]; } return self; } /* * Let user use monochrome blocks to get better speed. */ - adjustColor:sender { int value = [sender intValue]; colorOff = value; if ( (colorOff == NO) && ([NXApp colorScreen] != NX_TwoBitGrayDepth)) { gameInColor = YES; } if (colorOff == YES) { [tetrisWindow setDepthLimit:NX_TwoBitGrayDepth]; } else { [tetrisWindow setDepthLimit:NX_TwelveBitRGBDepth]; } if (value == YES) { fprintf(stderr, "Turing color off\n"); } else { fprintf(stderr, "Turing color on\n"); } return self; } /* * User has clicked quit. * If the game is in progress then verify the quit. * Save high scores and default values. */ - terminate:sender { char buf[20]; if (started && NXRunAlertPanel("Quit", "Game is still in progress. Really quit?", "Quit", "Cancel", NULL) == NX_ALERTALTERNATE) return self; // Clean up and die [scoreKeeper writeScores]; sprintf(buf,"%d", [level intValue]); NXWriteDefault ([NXApp appName], "CurrentLevel", buf); NXWriteDefault ([NXApp appName], "ColorOff", ([colorSwitch intValue]) ? "YES" : "NO"); sprintf(buf,"%d", numRandomRows); NXWriteDefault ([NXApp appName], "RandomRows", buf); NXWriteDefault ([NXApp appName], "ShowNext", ([showNextSwitch intValue]) ? "YES" : "NO"); return [super terminate:sender]; } /* * Allow the user to set the blocks images that make up the pieces */ - setBlocks:sender { return self; } - windowWillMiniaturize:sender toMiniwindow:miniwindow { if (started && !paused) [self pause:sender]; return self; } - windowDidMove:sender { NXRect aRect; float newX, newY; [[tetrisView window] getFrame:&aRect]; newX = aRect.origin.x + aRect.size.width + 5.; newY = aRect.origin.y; [controlWindow moveTo: newX :newY]; return self; } /* * Must bring the control panel to the front too. */ - windowDidBecomeKey:sender { [controlWindow orderFront:self]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.