home *** CD-ROM | disk | FTP | other *** search
-
- #import "WorldSpaceView.h"
- #import "SpaceView.h"
- #import "Thinker.h"
- #import <appkit/NXImage.h>
- #import <ma W>
- #import <libc.h>
- #import <dpsclient/wraps.h>
- #import <appkit/Panel.h>
- #import <c.h>
- #import <defaults/defaults.h>
- #import <sys/file.h>
-
- @implementation WorldSpaceView
-
- // x & y periods in milliseconds
- #define X_PERIOD 20000.0
- #define Y_PERIOD 19000.0
- #define DEFAULT_FPS 20
-
- #define PI 3.1415926535
-
- // #define MAX_IMAGE_WIDTH 200
- // #define MAX_IMAGE_HEIGHT 150
- #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)
-
-
-
- // move the world to its new position
- - oneStep
- {
- NXRect black = {0,0,0,0};
- NXRect ballRect;
- BRECT new;
-
- then = now;
- now = currentTimeInMs();
- // now += 30;
-
- // calculate new ball x & y position
- xpos = ((1 + sin(((float)now) / X_PERIOD * 2. * PI))/2.0)
- * maxCoord.x;
- ypos = ((1 + sin(((float)now) / Y_PERIOD * 2. * PI))/2.0)
- * maxCoord.y;
-
-
- 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;
-
-
- /* animate by selecting a new image to blit */
-
- [self incrementImageNumber];
-
- new.l = floor(xpos);
- new.b = floor(ypos);
- new.r = new.l + imageSize.width;
- new.t = new.b + imageSize.height;
-
- 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;
-
- [currentImage composite:NX_SOVER fromRect:&ballRect toPoint:&ballTo];
- [buffer unlockFocus];
-
-
- // Now bring it onto the screen
-
- [buffer composite:NX_COPY fromRect:&redraw toPoint:&redrawTo];
-
- old = new;
-
- // now put in the stars...
-
- avoid.origin = redrawTo;
- [mySpaceView setVoidRect:&avoid];
- [mySpaceView oneStep];
-
- return self;
- }
-
-
-
- static char *basename(char *path, const char *suffix)
- {
- char *begin, *end, Xme;
- int len;
-
- if (strlen(path) < strlen(suffix)) {
- end = begin = path;
- }
- else {
- begin = rindex(path, '/');
- if (begin) begin++;
- else begin = path;
-
- end = path+strlen(path)-strlen(suffix);
- if (0 != strcmp(end, suffix))
- end = path+strlen(path);
-
- if (end < begin) end = begin;
- }
- len = end-begin;
- name = malloc(len+1);
- strncpy(name, begin, len);
- name[len] = '\0';
- return name;
- }
-
-
- static BOOL noAnimFile = FALSE;
-
- - initFrame:(const NXRect *)frameRect
- {
- char moduleDirectory[1024];
- const char *animSpeed, *animFile, *animName;
- char animFrame[1024];
- int i, f;
- id local_image;
-
- 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];
- [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);
-
- animFile = NXGetDefaultValue([NXApp appName], "animFile");
- if (animFile == NULL)
- {
- sprintf(moduleDirectory,"%s/Globe.anim",
- [(BSThinker()) moduleDirectory:"WorldSpace"]);
- animFile = moduleDirectory;
- }
- animName = basename((char *)animFile, ".anim");
-
- imageList = [[List alloc] init];
-
- /* construct the image list */
- for (i=0; ; i++)
- {
- sprintf(animFrame, "%s/%s.%d.tiff", animFile, animName, i+1);
- if (!(local_image = [NXImage findImageNamed:animFrame]))
- {
- if ((f=open(animFrame, O_RDONLY)) < 0) break;
- close(f);
-
- local_image = [[NXImage alloc] initFromFile:animFrame];
- if (local_image == NULL) break; // never null, even if no file
- [local_image setName:animFrame];
- }
-
- [imageList addObject:local_image];
- if (i == 0) [local_image getSize: &imageSize];
- }
- numberOfFrames = i;
- currentFrame = 0;
-
- if (numberOfFrames == 0)
- {
- if (!noAnimFile)
- NXRunAlertPanel([NXApp appName], "Could not open %s",
- NULL, NULL, NULL, animFile);
- noAnimFile = TRUE;
- return nil;
- }
-
- nextRotationTime = 0;
-
- [self newViewSize];
-
- mySpaceView = [[SpaceView alloc] initF Y:frameRect];
- avoid.size = imageSize;
-
- return self;
- }
-
- - sizeTo:(NXCoord)width :(NXCoord)height
- {
- [super sizeTo:width :height];
- [mySpaceView sizeTo:width :height];
- [self newViewSize];
- return self;
- }
-
- - drawSelf:(const NXRect *)rects :(int)rectCount
- {
- // if (!rects || !rectCount) return self;
-
- //PSsetgray(0);
- //NXRectFill(rects);
-
- //NXRectClip(rects);
-
- 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;
- maxCoord.y = bounds.size.height - imageSize.height;
- if (maxCoord.x < 0) maxCoord.x = 0;
- if (maxCoord.y < 0) maxCoord.y = 0;
-
-
- old.l = old.r = maxCoord.x/2;
- old.b = old.t = maxCoord.y/2;
- ballTo.x = ballTo.y = 0;
-
- if ([buffer lockFocus])
- {
- PSsetgray(0);
- NXRectFill(&black);
- [buffer unlockFocus];
- }
-
- return self;
- }
-
- - incrementImageNumber
- {
- if (now > nextRotationTime)
- {
- if (++currentFrame >= numberOfFrames) currentFrame = 0;
- currentImage = [imageList objectAt:currentFrame];
- nextRotationTime = now + 1000/framesPerSecond;
- }
-
- return self;
- }
-
- - (const char *)windowTitle
- {
- return "World in Space";
- }
-
- - didLockFocus
- {
- [mySpaceView didLockFocus];
- return self;
- }
-
- - inspector:sender
- {
- char buf[MAXPATHLEN];
-
- if (!sharedInspectorPanel)
- {
- sprintf(buf,"%s/WorldSpace.nib",[sender moduleDirectory:"WorldSpace"]);
- [NXApp loadNibFile:buf owner:self withNames:NO];
- }
- return sharedInspectorPanel;
- }
-
- @end
-