home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.0 / NeXTSTEP3.0.iso / NextDeveloper / Examples / AppKit / BackspaceViews / WorldSpace / WorldSpaceView.m < prev   
Encoding:
Text File  |  1992-06-11  |  6.4 KB  |  317 lines

  1.  
  2. #import "WorldSpaceView.h"
  3. #import "SpaceView.h"
  4. #import "Thinker.h"
  5. #import <appkit/NXImage.h>
  6. #import <ma    W>
  7. #import <libc.h>
  8. #import <dpsclient/wraps.h>
  9. #import <appkit/Panel.h>
  10. #import <c.h>
  11. #import <defaults/defaults.h>
  12. #import <sys/file.h>
  13.  
  14. @implementation WorldSpaceView
  15.  
  16. // x & y periods in milliseconds
  17. #define X_PERIOD 20000.0
  18. #define Y_PERIOD 19000.0
  19. #define DEFAULT_FPS 20
  20.  
  21. #define PI 3.1415926535
  22.  
  23. // #define MAX_IMAGE_WIDTH 200
  24. // #define MAX_IMAGE_HEIGHT 150
  25. #define MAX_IMAGE_WIDTH 256
  26. #define MAX_IMAGE_HEIGHT 256
  27.  
  28. #define MAX_X_SPEED (26)
  29. #define MAX_Y_SPEED (26)
  30.  
  31. #define BUFFER_WIDTH (MAX_IMAGE_WIDTH + MAX_X_SPEED + 1)
  32. #define BUFFER_HEIGHT (MAX_IMAGE_HEIGHT + MAX_Y_SPEED + 1)
  33.  
  34.  
  35.  
  36. // move the world to its new position
  37. - oneStep
  38. {
  39.     NXRect black = {0,0,0,0};
  40.     NXRect ballRect;
  41.     BRECT new;
  42.     
  43.     then = now;
  44.     now = currentTimeInMs();
  45.     // now += 30;
  46.  
  47.     // calculate new ball x & y position
  48.     xpos = ((1 + sin(((float)now) / X_PERIOD * 2. * PI))/2.0) 
  49.         * maxCoord.x;
  50.     ypos = ((1 + sin(((float)now) / Y_PERIOD * 2. * PI))/2.0) 
  51.         * maxCoord.y;
  52.     
  53.     
  54.     if (xpos < (old.l - MAX_X_SPEED)) xpos = old.l - MAX_X_SPEED;
  55.     else if (xpos > (old.l + MAX_X_SPEED)) xpos = old.l + MAX_X_SPEED;
  56.  
  57.     if (ypos < (old.b - MAX_Y_SPEED)) ypos = old.b - MAX_Y_SPEED;
  58.     else if (ypos > (old.b + MAX_Y_SPEED)) ypos = old.b + MAX_Y_SPEED;
  59.  
  60.  
  61.     /* animate by selecting a new image to blit */
  62.  
  63.     [self incrementImageNumber];
  64.     
  65.     new.l = floor(xpos);
  66.     new.b = floor(ypos);
  67.     new.r = new.l + imageSize.width;
  68.     new.t = new.b + imageSize.height;
  69.     
  70.     ballRect.origin.x = 0;
  71.     ballRect.origin.y = 0;
  72.     ballRect.size.width = imageSize.width;
  73.     ballRect.size.height = imageSize.height;
  74.     
  75.     redrawTo.x = MIN(new.l, old.l);
  76.     redrawTo.y = MIN(new.b, old.b);
  77.  
  78.     redraw.origin.x = 0;
  79.     redraw.origin.y = 0;
  80.     redraw.size.width = (MAX(new.r, old.r)) - redrawTo.x + 1;
  81.     redraw.size.height = (MAX(new.t, old.t)) - redrawTo.y + 1;
  82.     
  83.     black.size= redraw.size;
  84.  
  85.     [buffer lockFocus];
  86.     PSsetgray(0);
  87.     NXRectFill(&black);
  88.     
  89.     ballTo.x = new.l - redrawTo.x;
  90.     ballTo.y = new.b - redrawTo.y;
  91.  
  92.     [currentImage composite:NX_SOVER fromRect:&ballRect toPoint:&ballTo];
  93.     [buffer unlockFocus];
  94.     
  95.     
  96.     // Now bring it onto the screen
  97.     
  98.     [buffer composite:NX_COPY fromRect:&redraw toPoint:&redrawTo];
  99.  
  100.     old = new;
  101.  
  102.     // now put in the stars...
  103.     
  104.     avoid.origin = redrawTo;
  105.     [mySpaceView setVoidRect:&avoid];
  106.     [mySpaceView oneStep];
  107.  
  108.     return self;
  109. }
  110.  
  111.  
  112.  
  113. static char *basename(char *path, const char *suffix)
  114. {
  115.     char *begin, *end,    Xme;
  116.     int len;
  117.     
  118.     if (strlen(path) < strlen(suffix)) {
  119.         end = begin = path;
  120.     }
  121.     else {
  122.     begin = rindex(path, '/');
  123.     if (begin) begin++;
  124.         else begin = path;
  125.     
  126.     end = path+strlen(path)-strlen(suffix);
  127.     if (0 != strcmp(end, suffix))
  128.         end = path+strlen(path);
  129.     
  130.     if (end < begin) end = begin;
  131.     }
  132.     len = end-begin;
  133.     name = malloc(len+1);
  134.     strncpy(name, begin, len);
  135.     name[len] = '\0';
  136.     return name;
  137. }
  138.  
  139.  
  140. static BOOL noAnimFile = FALSE;
  141.  
  142. - initFrame:(const NXRect *)frameRect
  143. {
  144.     char moduleDirectory[1024];
  145.     const char *animSpeed, *animFile, *animName;
  146.     char animFrame[1024];
  147.     int i, f;
  148.     id local_image;
  149.  
  150.     NXRect black = {0, 0, BUFFER_WIDTH, BUFFER_HEIGHT };
  151.  
  152.     [super initFrame:frameRect];
  153.     [self allocateGState];        // For faster lock/unlockFocus
  154.     [self setClipping:NO];        // even faster...
  155.  
  156.     //in this case, I only need one buffer for several Views
  157.     if (!(buffer = [NXImage findImageNamed:"worldBuffer"]))
  158.     {
  159.         buffer = [[NXImage alloc] initSize:&black.size];
  160.         [buffer setName:"worldBuffer"];
  161.     }
  162.     
  163.     if ([buffer lockFocus])
  164.     {
  165.         PSsetgray(0);
  166.         NXRectFill(&black);
  167.         [buffer unlockFocus];
  168.     }
  169.  
  170.  
  171.     animSpeed = NXGetDefaultValue([NXApp appName], "animSpeed");
  172.     if (animSpeed == NULL) framesPerSecond = DEFAULT_FPS;
  173.     else framesPerSecond = atoi(animSpeed);
  174.  
  175.     animFile = NXGetDefaultValue([NXApp appName], "animFile");
  176.     if (animFile == NULL)
  177.     {
  178.         sprintf(moduleDirectory,"%s/Globe.anim",
  179.             [(BSThinker()) moduleDirectory:"WorldSpace"]);
  180.         animFile = moduleDirectory;
  181.     }
  182.     animName = basename((char *)animFile, ".anim");
  183.    
  184.     imageList = [[List alloc] init];
  185.  
  186.     /* construct the image list */
  187.     for (i=0; ; i++)
  188.     {
  189.         sprintf(animFrame, "%s/%s.%d.tiff", animFile, animName, i+1);
  190.         if (!(local_image = [NXImage findImageNamed:animFrame]))
  191.         {
  192.             if ((f=open(animFrame, O_RDONLY)) < 0) break;
  193.             close(f);
  194.  
  195.             local_image = [[NXImage alloc] initFromFile:animFrame];
  196.             if (local_image == NULL) break;    // never null, even if no file
  197.             [local_image setName:animFrame];
  198.         }
  199.  
  200.         [imageList addObject:local_image];
  201.         if (i == 0) [local_image getSize: &imageSize];
  202.     }
  203.     numberOfFrames = i;
  204.     currentFrame = 0;
  205.     
  206.     if (numberOfFrames == 0)
  207.     {
  208.         if (!noAnimFile)
  209.         NXRunAlertPanel([NXApp appName], "Could not open %s",
  210.                 NULL, NULL, NULL, animFile);
  211.         noAnimFile = TRUE;
  212.         return nil;
  213.     }
  214.  
  215.     nextRotationTime = 0;
  216.  
  217.     [self newViewSize];
  218.  
  219.     mySpaceView = [[SpaceView alloc] initF    Y:frameRect];
  220.     avoid.size = imageSize;
  221.  
  222.     return self;
  223. }
  224.  
  225. - sizeTo:(NXCoord)width :(NXCoord)height
  226. {
  227.     [super sizeTo:width :height];
  228.     [mySpaceView sizeTo:width :height];
  229.     [self newViewSize];
  230.     return self;
  231. }
  232.  
  233. - drawSelf:(const NXRect *)rects :(int)rectCount
  234. {
  235.     // if (!rects || !rectCount) return self;
  236.     
  237.     //PSsetgray(0);
  238.     //NXRectFill(rects);
  239.     
  240.     //NXRectClip(rects);
  241.  
  242.     return self;
  243. }
  244.  
  245. - newViewSize
  246. {
  247.     //this is called every time View size changes
  248.     NXRect black = {0, 0, BUFFER_WIDTH, BUFFER_HEIGHT };
  249.  
  250.     then = now = currentTimeInMs();
  251.  
  252.     if (oldSize.width == bounds.size.width &&
  253.             oldSize.height == bounds.size.height)
  254.         return self;
  255.     else
  256.     {
  257.         oldSize.width = bounds.size.width;
  258.         oldSize.height = bounds.size.height;
  259.     }
  260.     
  261.     maxCoord.x = bounds.size.width - imageSize.width;
  262.     maxCoord.y = bounds.size.height - imageSize.height;
  263.     if (maxCoord.x < 0) maxCoord.x = 0;
  264.     if (maxCoord.y < 0) maxCoord.y = 0;
  265.  
  266.  
  267.     old.l = old.r = maxCoord.x/2;
  268.     old.b = old.t = maxCoord.y/2;
  269.     ballTo.x = ballTo.y = 0;
  270.  
  271.     if ([buffer lockFocus])
  272.     {
  273.         PSsetgray(0);
  274.         NXRectFill(&black);
  275.         [buffer unlockFocus];
  276.     }
  277.  
  278.     return self;
  279. }
  280.  
  281. - incrementImageNumber
  282. {
  283.     if (now > nextRotationTime)
  284.     {
  285.         if (++currentFrame >= numberOfFrames) currentFrame = 0;
  286.         currentImage = [imageList objectAt:currentFrame];
  287.         nextRotationTime = now + 1000/framesPerSecond;
  288.     }
  289.  
  290.     return self;
  291. }
  292.  
  293. - (const char *)windowTitle
  294. {
  295.     return "World in Space";
  296. }
  297.  
  298. - didLockFocus
  299. {
  300.     [mySpaceView didLockFocus];
  301.     return self;
  302. }
  303.  
  304. - inspector:sender
  305. {
  306.     char buf[MAXPATHLEN];
  307.     
  308.     if (!sharedInspectorPanel)
  309.     {
  310.         sprintf(buf,"%s/WorldSpace.nib",[sender moduleDirectory:"WorldSpace"]);
  311.         [NXApp loadNibFile:buf owner:self withNames:NO];
  312.     }
  313.     return sharedInspectorPanel;
  314. }
  315.  
  316. @end
  317.