This is AnimView.m in view mode; [Download] [Up]
// AnimView.m // 1993 Christoph Marquardt // You may freely copy, distribute, and reuse the code in this program. // the author disclaims any warranty of any kind, expressed or implied, as to its // fitness for any particular use. #import <strings.h> #import "AnimView.h" void getFileFromPath(const char *thePath, char *thefile) { int i,x,n,t=0,l; l = strlen(thePath)-1; for(i=l;i>=0;i--) if(thePath[i] == '/') { i++; break; } for(x=i;x<l;x++) if(thePath[x] == '.') break; for (n=i;n<x;n++) thefile[t++]=thePath[n]; thefile[t] = 0; } @implementation AnimView :View - initFrame:(NXRect *)theFrame { [super initFrame:(NXRect *)theFrame]; Status = STOPPED; Frames = NULL; frameN = 0; numFrames = 0; fps = 25.0; return self; } - openAnim:(const char *)filename { BOOL GoOn = YES; int n=10; int i=0; char theFile[300], name[100]; NXSize theSize; const NXPoint thePoint = { 0.0, 0.0 }; if (Status != STOPPED) [self stopAnim:self]; if (Frames != NULL) { for(i=0;i<numFrames;i++) [ Frames[i] free]; free(Frames); i=0; } Frames = (id *)malloc(n*sizeof(id)); numFrames = 0; getFileFromPath(filename, name); [window setTitle:name]; while(GoOn == YES) { sprintf(theFile, "%s/%s.%d.tiff", filename, name, i+1); if (i == n) { n = n*2; Frames = realloc(Frames, n*sizeof(id)); } Frames[i] = [NXImage allocFromZone:[self zone]]; [Frames[i] initFromFile:theFile]; if ( ![Frames[i] lockFocus] ) { GoOn = NO; numFrames = i; } else { [Frames[i] unlockFocus]; i++; } } if (numFrames == 0) { [Frames[0] free]; free(Frames); NXRunAlertPanel(NULL,"Couldn't open %s.", NULL, NULL, NULL, theFile); return self; } [ Frames[0] getSize:&theSize]; if (theSize.width != 0.0) [window sizeWindow:theSize.width :theSize.height]; // Showing first image of anim ... [self lockFocus]; [Frames[0] composite:NX_COPY toPoint:&thePoint]; [self unlockFocus]; [window flushWindow]; return self; } - playAnim:sender { if (numFrames == 0) return self; if ( [sender respondsTo:@selector(setState:)] ) playbutton = sender; else playbutton = nil; if (Status == RUNNING) [self stopAnim:self]; if (Status == STOPPED) frameN = 0; Status = RUNNING; timer = DPSAddTimedEntry(1/fps, &runOneStep, self, NX_BASETHRESHOLD); return self; } - stopAnim:sender { if (Status == RUNNING) { if (playbutton != nil) [playbutton setState:NO]; DPSRemoveTimedEntry(timer); Status = STOPPED; } if (Status == PAUSED) { if (playbutton != nil) [playbutton setState:NO]; if (pausebutton != nil) [pausebutton setState:NO]; Status = STOPPED; } return self; } - pauseAnim:sender { if ( [sender respondsTo:@selector(setState:)] ) pausebutton = sender; else pausebutton = nil; if (Status == PAUSED) { Status = RUNNING; timer = DPSAddTimedEntry(1/fps, &runOneStep, self, NX_BASETHRESHOLD); return self; } if (Status == RUNNING) { DPSRemoveTimedEntry(timer); Status = PAUSED; } if (Status == STOPPED) if ( [sender respondsTo:@selector(setState:)] ) [sender setState:NO]; return self; } - step:(double)timeNow; { const NXPoint thePoint = { 0.0, 0.0 }; if (frameN == numFrames) frameN = 0; [self lockFocus]; [Frames[frameN++] composite:NX_COPY toPoint:&thePoint]; [self unlockFocus]; [window flushWindow]; return self; } - takeFramesPerSecond:sender { fps = [sender floatValue]; return self; } - setFramesPerSecond:(float)thefps { fps = thefps; return self; } - (float)framesPerSecond { return fps; } - free { int i; if (Status == RUNNING) DPSRemoveTimedEntry(timer); for(i=0;i<numFrames;i++) [ Frames[i] free]; free(Frames); return [super free]; } // Delegate methods of window. - windowWillMiniaturize:theW toMiniwindow:theMW { if (numFrames != 0) [window setMiniwindowImage:Frames[0]]; if(Status == RUNNING) { DPSRemoveTimedEntry(timer); Status = PAUSED; } return self; } // Pretty much a dummy function to invoke the step method. void runOneStep (DPSTimedEntry timedEntry, double timeNow, void *data) { [(id)data step:timeNow]; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.