This is ColorBars.m in view mode; [Download] [Up]
/* * Magic Media Lab Colorbars, from the Media Lab letterhead, * with some animation tricks. c.f. License.m for an example of use. */ /* Copyright (c) 1991, 1992 by the MIT Media Laboratory This software is distributed by Michael Hawley of the MIT Media Laboratory. We hope it will be useful to you. Permission to use, copy, or modify this software for educational and research purposes only and without fee is hereby granted provided this notice appears on all copies, and provided you send us your improvements. Any other use of this software, in original or modified form, in whole or in part, requires specific permission from MIT. This software shall not be used, rewritten, or adapted for use in a commercial product without first obtaining appropriate licenses from MIT. MIT makes no representations about the suitability of this software for any purpose: it is provided "as is" without any warranty and any risk, damage, or liability incurred through your use of this software is yours alone. Michael Hawley MIT Media Laboratory 20 Ames Street, Cambridge, MA 02139 mike@media-lab.mit.edu */ #import "ColorBars.h" @implementation ColorBars #define N 8 static float pct[N] = { 0.0790, 0.1535, 0.0564, 0.2279, 0.0745, 0.2596, .1083, .0406}; static NXColor color[N]; static void initColors(){ int i = 0; #define C(r,g,b) color[i++] = NXConvertRGBToColor(r/256.0, g/256.0, b/256.0); C(77.0,17.0,93.0) C(0.0,85.0,0.0) C(255.0,255.0,255.0) C(210.0,0.0,0.0) C(255.0,90.0,0.0) C(0.0,0.0,151.0) C(255.0,248.0,0.0) C(85.0,85.0,85.0) } - initFrame:(const NXRect *)r { [super initFrame:r]; backgroundColor = NX_COLORWHITE; delay = .25; initColors(); return self; } static void drawColors(c,R) NXColor *c; NXRect R; { int i; NXCoord w = R.size.width; NXRect r; r = R; r.size.width = w * pct[0]; for (i=0; i<N; i++, r.size.width = w * pct[i]){ NXSetColor(c[i]); NXRectFill(&r); r.origin.x += r.size.width; } } - drawColors:(NXColor *)c{ drawColors(c,bounds); return self; } - (int)running { return running; } static NXColor fade(i,n,c1,c2) int i, n; NXColor c1, c2; /* return a color that's i/n of the way from c1->c2 in RGB */ { float r1, g1, b1, r2, g2, b2; float p = (float)(i)/(float)(n-1); NXConvertColorToRGB(c1,&r1,&g1,&b1); NXConvertColorToRGB(c2,&r2,&g2,&b2); #define mix(a,b) (a-p*(a-b)) r1 = mix(r1,r2); g1 = mix(g1,g2); b1 = mix(b1,b2); c1 = NXConvertRGBToColor(r1,g1,b1); return c1; } - fill:(NXColor)c { NXSetColor(c); NXRectFill(&bounds); return self; } - stopIt { running = 0; return self; } - (NXColor)backgroundColor { return backgroundColor; } - setBackgroundColor:(NXColor)c { backgroundColor = c; return self; } static void swabScramble(n) int n[N]; { int k=0,r,t[N] = {0,1,2,3,4,5,6,7}; #define pick(t,n) t[r=random()%n] #define skip(t,n) { int i,j=0; for (i=0;i<N;i++){ t[j] = t[i]; if (t[j] != n) j++; } } for (k=0;k<N;k++) n[k] = -1; k = 0; skip(t,k); n[k] = pick(t,7); skip(t,n[k]); n[n[k]] = k; while (n[k] != -1 && k < N) k++; skip(t,k); n[k] = pick(t,5); skip(t,n[k]); n[n[k]] = k; while (n[k] != -1 && k < N) k++; skip(t,k); n[k] = pick(t,3); skip(t,n[k]); n[n[k]] = k; while (n[k] != -1 && k < N) k++; skip(t,k); n[k] = pick(t,1); skip(t,n[k]); n[n[k]] = k; while (n[k] != -1 && k < N) k++; } static void swabStep(DPSTimedEntry te, double timeNow, id self) /* * Interpolate between pairs of segments */ { static int i = 0, f = 0; int j; static NXColor pc[N], cc[N]; NXColor c[N]; #define M 48 if (i==0){ /* pick random pairs of colors */ int n[8]; if (f==0){ f = 1; for (j=0;j<N;j++){ pc[j] = [self backgroundColor]; cc[j] = color[j]; } } else { if (f%3 == 0){ for (j=0;j<N;j++) cc[j] = color[j]; } else { swabScramble(n); for (j=0;j<N;j++) cc[j] = pc[n[j]]; } } } for (j=0;j<N;j++) c[j] = fade(i,M,pc[j],cc[j]); [self lockFocus]; [self drawColors:c]; i++; if (i==M || ![self running]){ i = 0; if (![self running] && te) DPSRemoveTimedEntry(te); for (j=0;j<N;j++) pc[j] = cc[j]; f++; } [self unlockFocus]; [[self window] flushWindow]; NXPing(); } static void fadeStep(DPSTimedEntry te, double timeNow, id self) { static int i = 0; int j; NXColor c[N]; #undef M #define M 64 for (j=0;j<N;j++) c[j] = fade(i,M,[self backgroundColor],color[j]); [self lockFocus]; [self drawColors:c]; i++; if (i==M || ![self running]){ i = 0; if (te) DPSRemoveTimedEntry(te); [self stopIt]; } [self unlockFocus]; [[self window] flushWindow]; NXPing(); } - fadeOn { running = 1; while (running) fadeStep(0,0.,self), usleep(2500); return self; } static void scramble(n) int *n; { int i, k, l; for (i=0; i<N; i++) n[i] = i; for (i=0; i<N; i++){ k = random()%N; l = n[k]; n[k] = n[i]; n[i] = l; } } static void scrambleStep(DPSTimedEntry te, double timeNow, id self) { static int skip = 0; int cn[N], j; NXColor c[N]; if (skip > 0) { skip--; return; } [self lockFocus]; if (random()%8 == 3){ [self drawColors:color]; skip = 3; } else { scramble(cn); for (j=0;j<N;j++) c[j] = color[cn[j]]; [self drawColors:c]; if (![self running]){ DPSRemoveTimedEntry(te); [self stopIt]; } } [self unlockFocus]; [[self window] flushWindow]; NXPing(); } - winkOff { NXRect r, a, b; r = a = b = bounds; drawColors(color,bounds); [window flushWindow]; NXPing(); NXSetColor(backgroundColor); a.size.height = b.size.height = 1; a.origin.y = r.origin.y + r.size.height; while (a.origin.y > b.origin.y){ NXRectFill(&a); NXRectFill(&b); a.origin.y -= 1; b.origin.y += 1; usleep(30000); [window flushWindow]; NXPing(); } a.origin.y += 1; b.origin.y -= 1; r = b; r.size.height = a.origin.y - b.origin.y; while (r.size.width > 2){ NXSetColor(backgroundColor); NXRectFill(&r); r.origin.x += 2; r.size.width -= 4; drawColors(color,r); [window flushWindow]; NXPing(); } r.size.width = 1; NXSetColor(NXConvertRGBToColor(.05,.05,.05)); NXRectFill(&r); [window flushWindow]; NXPing(); usleep(1000000); NXSetColor(backgroundColor); NXRectFill(&r); [window flushWindow]; NXPing(); usleep(300000); return self; } - setDrawstyle:(int)n { style = n; return [self display]; } - animate:(void (*)())f{ if (!running) running++, DPSAddTimedEntry(0.025, f, self,100); return self; } - animate:(void (*)())f :(float)t{ if (!running) running++, DPSAddTimedEntry(t, f, self,100); return self; } - drawSelf:(const NXRect *)rects :(int)n { switch (style){ case PLAIN: return [self drawColors:color]; case FADE: return [self animate:fadeStep]; case SWAB: return [self animate:swabStep]; case SCRAMBLE: return [self animate:scrambleStep:delay]; case FSCRAMBLE: [self fadeOn]; usleep(1000000); return [self animate:scrambleStep:delay]; case CLEAR: return [self fill:backgroundColor]; case WINKOFF: return [self winkOff]; } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.