Annotation of Examples/AppKit/BackspaceViews/WorldSpace/WorldSpaceView.m, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.