This is StefView.m in view mode; [Download] [Up]
#import "StefView.h" // this code is copyright Darcy Brockbank, 1993 // // You may freely reuse and distribute this code in any way shape or // form, provided that this notice stays intact. // // darcy@hasc.ca, samurai@cs.mcgill.ca // StefView was implemented out of WorldSpaceView and retains some of the // movement properties... // // The code for WorldSpaceView was written by Sam Streeper at NeXT, I think, // and there were two other contributors, but I can't find their names in the // source for it. // // StefView is the common "Spotlight" screen saver you see on Macs and Windows // all the time. This is just a quick hack, and can do with vast amounts of // improvement I'm sure. // // If you do improve this thing, send me a copy! // // - darcy @implementation StefView #define X_PERIOD 15000.0 #define Y_PERIOD 12000.0 #define DEFAULT_FPS 20 #define PI 3.1415926535 #define MAX_IMAGE_WIDTH 256 #define MAX_IMAGE_HEIGHT 256 #define MAX_X_SPEED (26) #define MAX_Y_SPEED (26) #define BUFFER_WIDTH (MAX_IMAGE_WIDTH + MAX_X_SPEED + 1) #define BUFFER_HEIGHT (MAX_IMAGE_HEIGHT + MAX_Y_SPEED + 1) #define PRINT(a) printf(a) #define MINX 0.0 #define MINY 50.0 - takeSpot:(float)x:(float)y; { NXRect r = {{0.0,0.0},{0.0,0.0}}; NXPoint p = {0.0,0.0}; [spot lockFocus]; [spot getSize:&r.size]; r.origin.x = x; r.origin.y = y; [clearSpot composite:NX_COPY toPoint:&p]; [sbuffer composite:NX_DOVER fromRect:&r toPoint:&p]; [spot unlockFocus]; return self; } - takeSnapshot; { id snapShot; NXSize screen; static NXRect imageRect = {{0.0,0.0},{0.0,0.0}}; // NXColor transBlack = NXChangeAlphaComponent(NX_COLORBLACK,0.33); [NXApp getScreenSize:&screen]; imageRect.size = screen; snapShot =[[Window alloc] initContent:&imageRect style:NX_PLAINSTYLE backing:NX_NONRETAINED buttonMask:0 defer:NO]; PSsetwindowlevel(NX_MAINMENULEVEL+1,[snapShot windowNum]); PSsetautofill(NO,[snapShot windowNum]); [snapShot orderFront:self]; NXPing(); if (!sbuffer) { sbuffer = [[NXImage alloc] initSize:&screen]; } [sbuffer lockFocus]; // NXSetColor(transBlack); // NXRectFill(&imageRect); PScomposite(0.0,0.0,screen.width,screen.height,[snapShot gState], 0.0,0.0,NX_COPY); [sbuffer unlockFocus]; snapShot = [snapShot free]; return self; } - oneStep { NXRect black = {0,0,0,0}; NXRect ballRect; BRECT new; then = now; now = currentTimeInMs(); xpos = ((1 + sin(((float)now) / X_PERIOD * 2. * PI))/2.0) * maxCoord.x + MINX; ypos = ((1 + sin(((float)now) / Y_PERIOD * 2. * PI))/2.0) * maxCoord.y + MINY; if (xpos < (old.l - MAX_X_SPEED)) xpos = old.l - MAX_X_SPEED; else if (xpos > (old.l + MAX_X_SPEED)) xpos = old.l + MAX_X_SPEED; if (ypos < (old.b - MAX_Y_SPEED)) ypos = old.b - MAX_Y_SPEED; else if (ypos > (old.b + MAX_Y_SPEED)) ypos = old.b + MAX_Y_SPEED; new.l = floor(xpos); new.b = floor(ypos); new.r = new.l + imageSize.width; new.t = new.b + imageSize.height; [self takeSpot:new.l :new.b]; ballRect.origin.x = 0; ballRect.origin.y = 0; ballRect.size.width = imageSize.width; ballRect.size.height = imageSize.height; redrawTo.x = MIN(new.l, old.l); redrawTo.y = MIN(new.b, old.b); redraw.origin.x = 0; redraw.origin.y = 0; redraw.size.width = (MAX(new.r, old.r)) - redrawTo.x + 1; redraw.size.height = (MAX(new.t, old.t)) - redrawTo.y + 1; black.size= redraw.size; [buffer lockFocus]; PSsetgray(0); NXRectFill(&black); ballTo.x = new.l - redrawTo.x; ballTo.y = new.b - redrawTo.y; [spot composite:NX_SOVER fromRect:&ballRect toPoint:&ballTo]; [buffer unlockFocus]; [buffer composite:NX_COPY fromRect:&redraw toPoint:&redrawTo]; old = new; return self; } - initFrame:(const NXRect *)frameRect { const char *animSpeed; NXRect black = {0, 0, BUFFER_WIDTH, BUFFER_HEIGHT }; [super initFrame:frameRect]; [self allocateGState]; // For faster lock/unlockFocus [self setClipping:NO]; // even faster... //in this case, I only need one buffer for several Views if (!(buffer = [NXImage findImageNamed:"worldBuffer"])) { buffer = [[NXImage alloc] initSize:&black.size]; [((NXImage *)buffer) setName:"worldBuffer"]; } if ([buffer lockFocus]) { PSsetgray(0); NXRectFill(&black); [buffer unlockFocus]; } animSpeed = NXGetDefaultValue([NXApp appName], "animSpeed"); if (animSpeed == NULL) framesPerSecond = DEFAULT_FPS; else framesPerSecond = atoi(animSpeed); nextRotationTime = 0; [self newViewSize]; return self; } - sizeTo:(NXCoord)width :(NXCoord)height { [super sizeTo:width :height]; [self newViewSize]; return self; } - drawSelf:(const NXRect *)rects :(int)count { // [sbuffer composite:NX_COPY fromRect:rects toPoint:&(rects->origin)]; return self; } - newViewSize { //this is called every time View size changes NXRect black = {0, 0, BUFFER_WIDTH, BUFFER_HEIGHT }; then = now = currentTimeInMs(); if (oldSize.width == bounds.size.width && oldSize.height == bounds.size.height) return self; else { oldSize.width = bounds.size.width; oldSize.height = bounds.size.height; } maxCoord.x = bounds.size.width - imageSize.width - MINX; maxCoord.y = bounds.size.height - imageSize.height - MINY; if (maxCoord.x < 0) maxCoord.x = 0; if (maxCoord.y < 0) maxCoord.y = 0; old.l = old.r = maxCoord.x/2 + MINX; old.b = old.t = maxCoord.y/2 + MINY; ballTo.x = ballTo.y = 0; if ([buffer lockFocus]) { PSsetgray(0); NXRectFill(&black); [buffer unlockFocus]; } return self; } - (const char *)windowTitle { return "StefView"; } - inspector:sender { char buf[MAXPATHLEN]; if (!sharedInspectorPanel){ sprintf(buf,"%s/StefView.nib",[sender moduleDirectory:"Stef"]); [NXApp loadNibFile:buf owner:self withNames:NO]; if (!spot) { sprintf(buf,"%s/Spot.tiff",[sender moduleDirectory:"Stef"]); spot = [[NXImage alloc] initFromFile:buf]; [spot lockFocus]; [spot unlockFocus]; clearSpot = [[NXImage alloc] initFromFile:buf]; [clearSpot lockFocus]; [clearSpot unlockFocus]; [spot getSize:&imageSize]; } } [self takeSnapshot]; return sharedInspectorPanel; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.