This is FlyView.m in view mode; [Download] [Up]
#import "FlyView.h"
#import "Thinker.h"
#import <stdio.h>
#import <string.h>
#import <sys/types.h>
@implementation FlyView
- oneStep
{
static BStimeval then = 0;
static unsigned int i;
static BOOL didSwitchState;
didSwitchState = NO;
for (i = 0; i < flyCount; i++) {
currentFly = [flyList objectAt:i];
if ([currentFly isSplat]) {
[[currentFly eraseGuts] toggleSplat:NO];
[flyLogic randomPosition:currentFly];
} else {
[currentFly eraseFly];
if ((currentTimeInMs() - then) > [currentFly statePeriod]) {
didSwitchState = YES;
[currentFly setState:![currentFly isFirstState]];
}
[[flyLogic getNewHeading:currentFly] adjustPosition:currentFly];
[[currentFly setCellRect] drawFly];
}
}
if (didSwitchState) {
then = currentTimeInMs();
}
mach_sleep(port, frameRate);
return self;
}
- initFrame:(NXRect *)frameRect
{
struct timeval tp;
char buf[MAXPATHLEN + 1];
long i;
[super initFrame:frameRect];
gettimeofday(&tp, (struct timezone *)0L);
srandom(tp.tv_sec);
moduleDir = [[NXApp delegate] moduleDirectory:"Fly"];
strcpy(buf, moduleDir);
strcat(buf, "/Fly.bundle");
flyBundle = [[NXBundle alloc] initForDirectory:buf];
[flyBundle getPath:buf forResource:"fly" ofType:"tiff"];
flyImage = [[NXImage alloc] initFromFile:buf];
[flyBundle getPath:buf forResource:"guts" ofType:"tiff"];
gutsImage = [[NXImage alloc] initFromFile:buf];
[flyBundle getPath:buf forResource:"flyMask" ofType:"tiff"];
maskImage = [[NXImage alloc] initFromFile:buf];
[flyBundle getPath:buf forResource:"splat" ofType:"snd"];
splatSnd = [[Sound alloc] initFromSoundfile:buf];
[self inspector:self];
[[infoText setEditable:NO] setSelectable:YES]; // for 3.0pr IB bug
NXRegisterDefaults([NXApp appName], defs);
[self getDefaults:self];
[self setAnimationSpeed:animationSlider];
[self setNumFlies:flyCountSlider];
flyWindow = [self window];
[flyWindow addToEventMask:NX_LMOUSEDOWNMASK];
maxFlyCount = (unsigned int)[(Slider *)flyCountSlider maxValue];
flyLogic = [[FlyLogic alloc] init];
[flyLogic setBoundsRect:&bounds];
flyList = [[List alloc] initCount:maxFlyCount];
for (i = 0; i < flyCount; i++) {
currentFly = [self createFly];
[flyList addObject:currentFly];
}
port = mach_sleep_install();
return self;
}
- (Fly *)createFly
{
Fly *fly;
fly = [[Fly alloc] init];
[fly setFlyImage:flyImage];
[fly setGutsImage:gutsImage];
[fly setMaskImage:maskImage];
[fly setSplatSnd:splatSnd];
[flyLogic randomPosition:fly];
[fly setCellRect];
[self setFlySpeed:speedSlider forFly:fly];
[flyLogic getStateAndTurn:fly];
return(fly);
}
- free
{
mach_sleep_remove(port);
[[flyList freeObjects] free];
[flyImage free];
[gutsImage free];
[splatSnd free];
[flyLogic free];
[flyBundle free];
return [super free];
}
- drawSelf:(const NXRect *)rects :(int)rectCount
{
if (!rects || !rectCount) return self;
if (kBackgroundGray != NX_BLACK) {
PSsetgray(kBackgroundGray);
NXRectFill(rects);
}
return self;
}
- mouseDown:(NXEvent *)theEvent;
{
NXRect r;
NXPoint p;
NXPoint *flyPos;
unsigned int i;
p = theEvent->location;
[self convertPoint:&p fromView:nil];
for (i = 0; i < flyCount; i++) {
currentFly = [flyList objectAt:i];
if (![currentFly isSplat]) {
flyPos = [currentFly position];
NXSetRect(&r, flyPos->x, flyPos->y, kFlyCellWidth, kFlyCellHeight);
if (NXPointInRect(&p, &r)) {
[self lockFocus];
[currentFly doSplat];
[self unlockFocus];
}
}
}
return self;
}
- newWindow
{
flyWindow = [self window];
[flyWindow addToEventMask:NX_LMOUSEDOWNMASK];
return self;
}
- sizeTo:(NXCoord)width :(NXCoord)height
{
[super sizeTo:width :height];
[flyLogic setBoundsRect:&bounds];
return self;
}
- (const char *) windowTitle
{
return("Catch the Buzz...");
}
- inspector:sender
{
char buf[MAXPATHLEN + 1];
if (!inspectorPanel) {
[flyBundle getPath:buf forResource:"FlyView" ofType:"nib"];
[NXApp loadNibFile:buf owner:self withNames:NO];
}
return inspectorPanel;
}
- inspectorWillBeRemoved
{
[[infoText window] orderOut:self];
return self;
}
- setSpeed:sender
{
unsigned int i;
for (i = 0; i < [flyList count]; i++) {
[self setFlySpeed:sender forFly:[flyList objectAt:i]];
}
return self;
}
- setFlySpeed:(Slider *)sender forFly:(Fly *)fly
{
float speed;
speed = [sender floatValue];
if (speed < 1) speed = 1;
[fly setSpeedValue:speed];
[flyLogic getStateAndTurn:fly];
[self delayedDefaults:self];
return self;
}
- setAnimationSpeed:(Slider *)sender
{
frameRate = ([sender maxValue] + [sender minValue]) - [sender intValue];
[self delayedDefaults:self];
return self;
}
- setNumFlies:sender
{
unsigned int tmpFlyCount;
int flyDiff;
tmpFlyCount = flyCount;
flyCount = [flyCountSlider intValue];
[flyCountBox setIntValue:flyCount];
flyDiff = abs(flyCount - tmpFlyCount);
if (flyCount > tmpFlyCount) {
while(flyDiff--) {
[flyList addObject:[self createFly]];
if ([self canDraw]) {
[self lockFocus];
[[flyList lastObject] drawFly];
[self unlockFocus];
}
}
} else if (flyCount < tmpFlyCount) {
if ([self canDraw]) {
[self lockFocus];
while(flyDiff--) {
[[[flyList removeLastObject] eraseFly] free];
}
[self unlockFocus];
}
}
[self delayedDefaults:self];
return self;
}
- delayedDefaults:sender
{
[self perform:@selector(writeDefaults:) with:self afterDelay:kSliderDelay cancelPrevious:YES];
return self;
}
- getDefaults:sender
{
[speedSlider setFloatValue:atof(NXGetDefaultValue([NXApp appName], "FlySpeed"))];
[animationSlider setIntValue:atoi(NXGetDefaultValue([NXApp appName], "AnimationSpeed"))];
[flyCountSlider setIntValue:atoi(NXGetDefaultValue([NXApp appName], "NumFlies"))];
[flyCountBox setIntValue:[flyCountSlider intValue]];
return self;
}
- writeDefaults:sender
{
NXWriteDefault([NXApp appName], "FlySpeed", [speedSlider stringValue]);
NXWriteDefault([NXApp appName], "AnimationSpeed", [animationSlider stringValue]);
NXWriteDefault([NXApp appName], "NumFlies", [flyCountSlider stringValue]);
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.