home *** CD-ROM | disk | FTP | other *** search
- // HodgePodge.m --
-
- // PAK 7/31/88 -- coded on Aari ST
- // PAK 4/26/92 -- ported to NeXT
- // PAK 11/1/92 -- trying 4-bit Color-station format
-
- #import "math.h"
- #import <appkit/NXBitmapImageRep.h>
- #import "HodgePodge.h"
-
- @implementation HodgePodge
-
- long random();
- void wrap_cell_edges();
- HodgePodge *Self;
-
- - init
- { [super init];
- Cf = &z1;
- Ct = &z2;
- return [self Randomize :nil];
- }
-
- - Randomize :sender;
- { int i, j;
- for (i=1; i<=c_yh; i++)
- for (j=1; j<=c_xw; j++)
- (*Cf)[i][j] = random() % (n);
- wrap_cell_edges(Cf);
- return self;
- }
-
- - drawSelf:(const NXRect *)rects :(int)rectCount
- { n = rint([NumStates floatValue]);
- force = [DrivingForce floatValue]*n;
- Healthy2Sick = [HealthysAffectOnSick floatValue]*n/8;
- Recover2Sick = [RecoveringsAffectOnSick floatValue]*n/8;
- cellsHorizontally = [CellsHorizontally floatValue];
- cellsVertically = [CellsVertically floatValue];
- intiTimedEntry([MaxFramesPsecond floatValue]);
- initTable([DisplayColorPhase floatValue], [DisplayColorDir floatValue]);
- if (bitmap == 0)
- { bitmap = [[NXBitmapImageRep alloc] initData:(unsigned char *)image
- pixelsWide :c_xw pixelsHigh :c_yh
- bitsPerSample:4 samplesPerPixel:Ncolors+1
- hasAlpha:YES isPlanar:NO
- colorSpace:Ncolors>1? NX_RGBColorSpace:NX_OneIsWhiteColorSpace
- bytesPerRow:0 bitsPerPixel:0];
- [self setOpaque:YES];
- [self compute];
- }
- [bitmap drawIn :&bounds];
- return self;
- }
-
- /*
- * Each cell has a Health h, an integer from 0 to N.
- * If the cell is recovering (0 < h < N), its new health is the average of
- * its 8 neighbors plus a Curing Force f, expressed as a fraction of N.
- * If the cell is sick (h = 0), its new health is A * the number of healthy
- * neighbors plus B * the number of recovering neighbors.
- * If the cell is healthy (h = N), it becomes sick (presumably from
- * complacency).
- */
- - (void)compute
- { register int j;
- register cell_image *pCf; // Pointer to Cell_image, From buffer
- register cell_image *pCt, *tmp; // Pointer to Cell_image, To buffer
- register colorStationPixel *pS; // Pointer to Screen_image
- register int x, y;
- register int s;
- register int a, b;
- register int sick=0, healthy=n;
-
- Self = self;
- if (Cf == 0)
- [self init];
- for (y=1; y<=c_yh; y++) //iterate over Y (except edges)
- { pCf = (cell_image *)&(*Cf)[y][1];
- pCt = (cell_image *)&(*Ct)[y][1];
- pS = (colorStationPixel *)&image[y-1][0];
- for (x=1; x<=c_xw; x++) //iterate over X (except edges)
- { j = (*pCf)[0][0];
- if (j <= sick) // SICK: look at 8 neighbors
- { a = 0; // count of sick neighbors
- b = 0; // count of recovering neighbors
- (j=(*pCf)[-1][-1])? (j>=healthy? a++: b++): 0;
- (j=(*pCf)[-1][ 0])? (j>=healthy? a++: b++): 0;
- (j=(*pCf)[-1][ 1])? (j>=healthy? a++: b++): 0;
- (j=(*pCf)[ 0][-1])? (j>=healthy? a++: b++): 0;
- (j=(*pCf)[ 0][ 1])? (j>=healthy? a++: b++): 0;
- (j=(*pCf)[ 1][-1])? (j>=healthy? a++: b++): 0;
- (j=(*pCf)[ 1][ 0])? (j>=healthy? a++: b++): 0;
- (j=(*pCf)[ 1][ 1])? (j>=healthy? a++: b++): 0;
- s = a * Healthy2Sick + b * Recover2Sick;
- }
- else if (j < healthy) // RECOVERING: average neighbors, + force
- s= ((*pCf)[-1][-1]+(*pCf)[-1][0]+(*pCf)[-1][1]
- +(*pCf)[0][-1] +(*pCf)[0][1]
- +(*pCf)[1][-1] +(*pCf)[1][0] +(*pCf)[1][1])/8.0 + force;
- else // HEALTHY: become sick again
- s = 0;
-
- (*pCt)[0][0] = s = s>n? n: s;
-
- s = s*255/n;
- pS->alpha = -1;
- pS->red = redTable[s];
- pS->green = greenTable[s];
- pS->blue = blueTable[s];
- pS++;
-
- pCf = (cell_image *)&(*pCf)[0][1];
- pCt = (cell_image *)&(*pCt)[0][1];
- } }
-
- tmp = Cf; Cf = Ct; Ct = tmp;
- wrap_cell_edges(Cf);
- }
-
- // makes the area conform to a torus:
- // row/col 0 and row/col N+1 are replicated
- void wrap_cell_edges(Cf)
- register cell_image *Cf;
- { register int x, y;
- int w = Self->c_xw, h = Self->c_yh;
- for (x=1; x<=w; x++)
- { (*Cf)[h+1][x] = (*Cf)[1][x];
- (*Cf)[0 ][x] = (*Cf)[h][x];
- }
- for (y=1; y<=h; y++)
- { (*Cf)[y][w+1] = (*Cf)[y][1];
- (*Cf)[y][0 ] = (*Cf)[y][w];
- }
- (*Cf)[0 ][0 ] = (*Cf)[h][w];
- (*Cf)[h+1][w+1] = (*Cf)[1][1];
- (*Cf)[0 ][w+1] = (*Cf)[h][1];
- (*Cf)[h+1][0 ] = (*Cf)[1][w];
- }
-
- @end
-