This is StarShipView.m in view mode; [Download] [Up]
#import "StarShipView.h" #import "NewSpaceView.h" #import "Thinker.h" #import <stdio.h> #import "StarShipProtocol.h" #import <dpsclient/wraps.h> #define sliderDelay 2000 @implementation StarShipView static char **bundleFilenameList; + initialize { if ( self == [StarShipView class] ) { static NXDefaultsVector starShipDefs = { {"StarShipObjectSpeed", "180"}, {"StarShipIntervalTime", "5"}, {"StarShipAnimationSpeed", "500"}, {"StarShipCycleCount", "250"}, {"StarShipSound", "1"}, {"StarShipStarSpeed", "1"}, {NULL} }; NXRegisterDefaults([NXApp appName], starShipDefs); } return self; } - oneStep { if (viewScreenResized){ //tell everybody about it if(controllerTypeCount > 0){ [spaceTypeController setBoundsRect: &newViewScreenSize]; //set new clip area NXSetRect(&clipRect,newViewScreenSize.origin.x, newViewScreenSize.origin.y,newViewScreenSize.size.width, newViewScreenSize.size.height); // numbers have to do with size of the viewscreen border clipRect.origin.x += 3.0; clipRect.origin.y += 3.0;; clipRect.size.width -= 6.0; clipRect.size.height -= 6.0; rectPtr = &clipRect; } viewScreenResized = NO; } if (controllerTypeCount > 0){ // they exist NXRectClip(rectPtr); //clip to screen border if ([spaceTypeController doUntilDone]){ [spaceTypeController freeResources]; controllerIndex++; if (controllerIndex >= controllerTypeCount) controllerIndex = 0; spaceTypeController = [controllerList objectAt:controllerIndex]; if(soundGood){ [spaceTypeController setPwrDownSnd:pwrDownSnd]; [spaceTypeController setPwrUpSnd:pwrUpSnd]; } [self setModuleBox]; //update module info in inspector window [viewScreen setBodyControllerOutlet:spaceTypeController]; [spaceTypeController setStarsOutlet:viewScreen]; //send module all slider values firstTimeSound = 1; //don't want to play sound at startup [self setSound:soundMatrix]; [self setStarSpeed:starSpeedSlider]; [self setAnimationSpeed:animationSlider]; [self setObjectInterval:objectIntervalSlider]; [self setObjectSpeed:objectSpeedSlider]; [self setCycleCount:cycleCountSlider]; [spaceTypeController setBoundsRect: &newViewScreenSize]; [spaceTypeController setFirstState]; } PSinitclip(); //turn off clipping } [viewScreen oneStep]; if(frameRate > 1) xmach_sleep(port, frameRate); return self; } - (BOOL)makeSndObjects: (char *)directory { char buf[MAXPATHLEN + 1]; soundGood = YES; sprintf(buf,"%s/pwrDown.snd",directory); pwrDownSnd = [[Sound alloc] initFromSoundfile:buf]; if(pwrDownSnd == nil){ soundGood = NO; printf("unable to create sound object %s\n",buf); } sprintf(buf,"%s/pwrUp.snd",directory); pwrUpSnd = [[Sound alloc] initFromSoundfile:buf]; if(pwrUpSnd == nil){ soundGood = NO; printf("unable to create sound object %s\n",buf); } sprintf(buf,"%s/sound.snd",directory); sound = [[Sound alloc] initFromSoundfile:buf]; if(sound == nil){ soundGood = NO; printf("unable to create sound object %s\n",buf); } return soundGood; } //********************************* // this builds a list of bundles in the StarShipView.BackModule bundle // and instantiates first bundle object // there must be a class object that is same as bundle name // The idea here is build a list of space object controllers // like celestial body controllers, ship controllers, etc - buildControllerList: (char *)directory { NXBundle * tmpBundle; char buf[MAXPATHLEN + 1]; short ii,successCount; controllerTypeCount = [self searchDirectory: directory]; controllerList = [[List alloc] initCount:controllerTypeCount]; successCount = 0; if(controllerTypeCount > 0){//there are some successCount = 0; for(ii = 0; ii < controllerTypeCount; ii++){ sprintf(buf,"%s/%s.bundle",directory,bundleFilenameList[ii]); if((tmpBundle = [[NXBundle alloc] initForDirectory:buf]) == nil) printf("could not create bundle object for %s\n",buf); else { if((spaceTypeController = [[[tmpBundle classNamed:bundleFilenameList[ii]]alloc]init])){ successCount++; [controllerList addObject:spaceTypeController]; } } } controllerTypeCount = successCount; } return self; } static BOOL isOk(const char *filename) /* checks to make sure the filename is .bundle */ { char *suffix; suffix = rindex(filename,'.'); if (suffix == 0) return NO; else if(strlen(suffix) != 7) return NO; else return(strncmp(suffix,".bundle",7)) ? NO : YES; } #define CHUNK 127 static char **addFile(const char *file, int length, char **list, int count) /* Adds the specified filename to the list of filenames. It allocates * more memory in chunks as needed. */ { char *suffix; if (!list) list = (char **)malloc(CHUNK*sizeof(char *)); if (suffix = rindex(file,'.')) *suffix = '\0'; /* strip .bundle suffix */ list[count] = (char *)malloc((length+1)*sizeof(char)); strcpy(list[count], file); count++; if (!(count% CHUNK)) { list = (char **)realloc(list,(((count/CHUNK)+1)*CHUNK)*sizeof(char *)); } list[count] = NULL; return list; } static void freeList(char **list) /* Frees the array of filenames */ { char **strings; if (list) { strings = list; while (*strings) free(*strings++); free(list); } } // look in the right bundle directory for all the space object bundles // create a list called bundleFilenameList - (int)searchDirectory: (char *)directory { long basep; char *buf; struct direct *dp; char **list = NULL; int cc, fd, fileCount = 0; char dirbuf[8192]; if ((fd = open(directory, O_RDONLY, 0644)) > 0) { cc = getdirentries(fd, (buf = dirbuf), 8192, &basep); while (cc) { dp = (struct direct *)buf; if (isOk(dp->d_name)) { list = addFile(dp->d_name, dp->d_namlen, list, fileCount++); } buf += dp->d_reclen; if (buf >= dirbuf + cc) { cc = getdirentries(fd, (buf = dirbuf), 8192, &basep); } } close(fd); } freeList(bundleFilenameList); bundleFilenameList = list; return fileCount; } - sizeTo:(NXCoord)width :(NXCoord)height { [super sizeTo:width :height]; [viewScreen sizeTo:width :height];//send original size to space if(controllerTypeCount > 0){ [spaceTypeController setBoundsRect:&newViewScreenSize]; NXSetRect(&clipRect,newViewScreenSize.origin.x, newViewScreenSize.origin.y, newViewScreenSize.size.width,newViewScreenSize.size.height); clipRect.origin.x += 3.0; clipRect.origin.y += 3.0;; clipRect.size.width -= 6.0; clipRect.size.height -= 6.0; rectPtr = &clipRect; [spaceTypeController windowSizeChanged]; } return self; } - initFrame:(const NXRect *)frameRect { char buf[MAXPATHLEN + 1]; [super initFrame:frameRect]; [self allocateGState]; // For faster lock/unlockFocus [self inspector:self]; //this guarantees that sliders exist when I //set them moduleDir = [[NXApp delegate] moduleDirectory:"StarShip"]; strcpy(buf, moduleDir); viewScreen = [[NewSpaceView alloc] initFrame:frameRect]; [viewScreen setStarShipOutlet:self]; NXSetRect(&clipRect,newViewScreenSize.origin.x, newViewScreenSize.origin.y, newViewScreenSize.size.width,newViewScreenSize.size.height); clipRect.origin.x += 3.0; clipRect.origin.y += 3.0;; clipRect.size.width -= 6.0; clipRect.size.height -= 6.0; rectPtr = &clipRect; // builds list of bundle objects [self buildControllerList:buf]; controllerIndex = 0; spaceTypeController = [controllerList objectAt:controllerIndex]; if([self makeSndObjects:buf]){ [spaceTypeController setPwrDownSnd:pwrDownSnd]; [spaceTypeController setPwrUpSnd:pwrUpSnd]; } [self setModuleBox]; //update module info in inspector window [spaceTypeController setBoundsRect: (NXRect *)frameRect]; [spaceTypeController setStarsOutlet:viewScreen]; [viewScreen setBodyControllerOutlet:spaceTypeController]; [self getDefaults:self]; firstTimeSound = 1; //don't want to play sound at startup [self setSound:soundMatrix]; [self setStarSpeed:starSpeedSlider]; [self setAnimationSpeed:animationSlider]; [self setObjectInterval:objectIntervalSlider]; [self setObjectSpeed:objectSpeedSlider]; [self setCycleCount:cycleCountSlider]; [spaceTypeController setFirstState]; port = xmach_sleep_install(); viewScreenResized = NO; return self; } - setCycleCount:(Slider *)sender { int multiplier,value;; // real slider value min is 0 //I show a min of 1 cycle in the cycleCountBox value = [sender intValue]; multiplier = (int)[spaceTypeController setCycleValue:value]; if (value == 0) value = 1; else value *= multiplier; [cycleCountBox setIntValue:value]; [self delayedDefaults:self]; return self; } - setStarSpeed:(Slider *)sender { [viewScreen setStarSpeed:sender]; [spaceTypeController setStarSpeed:sender]; [self delayedDefaults:self]; return self; } - setAnimationSpeed:(Slider *)sender { frameRate = ([sender maxValue] + [sender minValue]) - [sender intValue]; [self delayedDefaults:self]; return self; } - setObjectSpeed:(Slider *)sender { [spaceTypeController setObjectSpeed:sender]; [self delayedDefaults:self]; return self; } - setObjectInterval:(Slider *)sender { [spaceTypeController setStartInterval: sender];//send slider to current [self delayedDefaults:self]; //space object return self; } - setSound:sender { if(soundGood){ //there are valid sound files if(!firstTimeSound) [sound play]; firstTimeSound = 0; soundEnabled = (BOOL)[[sender selectedCell] tag]; [spaceTypeController setSoundEnabled:soundEnabled]; } else{ //set all sound off permanently soundEnabled = NO; [spaceTypeController setSoundEnabled:soundEnabled]; } [self delayedDefaults:self]; return self; } - setModuleBox { [moduleBox setStringValue:bundleFilenameList[controllerIndex]]; return self; } - didLockFocus { [viewScreen didLockFocus]; return self; } - (const char *) windowTitle { return("StarShip!"); } - inspector:sender { char buf[MAXPATHLEN]; if (!inspectorPanel) { sprintf(buf,"%s/English.lproj/StarShip.nib",[[NXApp delegate] moduleDirectory:"StarShip"]); if([NXApp loadNibFile:buf owner:self withNames:NO] == nil) printf ("inspector not loaded %s\n",buf); } return inspectorPanel; } - inspectorWillBeRemoved { [[infoText window] orderOut:self]; return self; } // The module is never freed // but it's here in case backSpace ever wants to ;-) - free { //This is untested!!!! [controllerList freeObjects]; [controllerList free]; [pwrDownSnd free]; [pwrUpSnd free]; [sound free]; freeList(bundleFilenameList); xmach_sleep_remove(port); return [super free]; } // I left this in in case some of the modules wanted to do //something cool with mouse //down events - it is not functional right now /*- mouseDown:(NXEvent *)theEvent; { NXRect r; NXPoint p; unsigned int i; p = theEvent->location; [self convertPoint:&p fromView:nil]; [self lockFocus]; [spaceTypeController doSomethingNow]; [self unlockFocus]; return self; }*/ //needed for mouse down events /*- newWindow { shipWindow = [self window]; [shipWindow addToEventMask:NX_LMOUSEDOWNMASK]; return self; }*/ - delayedDefaults:sender { [self perform:@selector(writeDefaults:) with:self afterDelay:sliderDelay cancelPrevious:YES]; return self; } - getDefaults:sender { int cell; [animationSlider setIntValue:atoi(NXGetDefaultValue([NXApp appName], "StarShipAnimationSpeed"))]; [objectSpeedSlider setIntValue:atoi(NXGetDefaultValue([NXApp appName], "StarShipObjectSpeed"))]; [starSpeedSlider setFloatValue:atof(NXGetDefaultValue([NXApp appName], "StarShipStarSpeed"))]; [objectIntervalSlider setIntValue:atoi(NXGetDefaultValue([NXApp appName], "StarShipIntervalTime"))]; [cycleCountSlider setIntValue:atoi(NXGetDefaultValue([NXApp appName], "StarShipCycleCount"))]; [cycleCountBox setIntValue:atoi(NXGetDefaultValue([NXApp appName], "StarShipCycleCount"))]; cell = atoi(NXGetDefaultValue([NXApp appName], "StarShipSound")); if(cell) [soundMatrix selectCellAt:0:0]; else [soundMatrix selectCellAt:1:0]; return self; } - writeDefaults:sender { int tag; char ctag[2]; NXWriteDefault([NXApp appName], "StarShipAnimationSpeed", [animationSlider stringValue]); NXWriteDefault([NXApp appName], "StarShipObjectSpeed", [objectSpeedSlider stringValue]); NXWriteDefault([NXApp appName], "StarShipStarSpeed", [starSpeedSlider stringValue]); NXWriteDefault([NXApp appName], "StarShipIntervalTime", [objectIntervalSlider stringValue]); NXWriteDefault([NXApp appName], "StarShipCycleCount", [cycleCountSlider stringValue]); tag = [[soundMatrix selectedCell] tag]; sprintf(ctag,"%d",tag); NXWriteDefault([NXApp appName], "StarShipSound",ctag); return self; } port_t *xmach_sleep_install(void) { port_t *port; NX_MALLOC(port, port_t, sizeof(port_t)); port_allocate(task_self(), port); return(port); } void xmach_sleep_remove(port_t *port) { port_deallocate(task_self(), *port); NX_FREE(port); } void xmach_sleep(port_t *port, msg_timeout_t msecs) { msg_header_t h; h.msg_size = sizeof(h); h.msg_local_port = *port; msg_receive(&h, RCV_TIMEOUT, msecs); } - viewScreenResized:(NXRect *)screenRect { viewScreenResized = YES; NXSetRect(&newViewScreenSize,screenRect->origin.x, screenRect->origin.y,screenRect->size.width, screenRect->size.height); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.