// Pixel Spaceships
// David Bollinger - July 2006
// http://www.davebollinger.com
// for Processing 0115 beta
// (updated for 0119 Beta)
/**
Click mouse to advance early to next pattern
*/
PixelSpaceshipFitter fitter;
PixelSpaceship ship;
miniMT rng; // want a slightly more robust rng for 32 significant bits
int currentSeed = 0;
void setup() {
size(480,480,P3D);
frameRate(30);
fitter = new PixelSpaceshipFitter(480/16, 480/16);
rng = new miniMT();
next();
}
void mousePressed() {
next();
}
void next() {
background(255);
fitter.make(++currentSeed);
}
void draw() {
fitter.drawone();
if (fitter.at00())
next();
}
// the generator
class PixelSpaceship {
static final int cols = 12;
static final int rows = 12;
static final int EMPTY = 0;
static final int AVOID = 1;
static final int SOLID = 2;
static final int COKPT = 3; // ::added to aid coloring
int seed;
int colorseed; // ::added to aid coloring
int[][] grid;
int xscale, yscale;
int xmargin, ymargin;
PixelSpaceship() {
grid = new int[rows][cols];
xscale = yscale = 1;
xmargin = ymargin = 0;
}
void recolor() { // ::added to aid coloring
colorseed = rng.generate();
}
int getHeight() {
return rows*yscale + ymargin*2;
}
int getWidth() {
return cols*xscale + xmargin*2;
}
void setMargins(int xm, int ym) {
xmargin = xm;
ymargin = ym;
}
void setScales(int xs, int ys) {
xscale = xs;
yscale = ys;
}
void setSeed(int s) {
seed = s;
}
void wipe() {
for (int r=0; r0) && (grid[r][c-1]==AVOID)) needsolid=true;
if ((c0) && (grid[r-1][c]==AVOID)) needsolid=true;
if ((r> 8;
else if (r < 9) h = (colorseed & 0xff0000) >> 16;
else h = (colorseed & 0xff000000) >> 24;
colorMode(HSB);
fill(h, mysat, mybri);
rect(x1,y1,xscale,yscale);
}
else
if (m == COKPT) {
float mysat = sats[c];
float mybri = bris[r]+40;
colorMode(HSB);
int h = (colorseed & 0xff);
fill(h, mysat, mybri);
rect(x1,y1,xscale,yscale);
}
}
}
}
}
class PixelSpaceshipFitter {
PixelSpaceship ship;
int cols, rows;
int col, row;
int seed;
// cells store the box fit pattern, contents are byte encoded as:
// (cell >> 16) & 0xff == work to do
// (cell) & 0xff == size of allocated area
// (this somewhat odd encoding scheme is a remnant of the
// fractal subdivision method used for the pixel robots t-shirt image)
int [][] cells;
// the types of work that may occur in a cell
static final int WORK_NONE = 0;
static final int WORK_DONE = 1;
PixelSpaceshipFitter(int c, int r) {
cols = c;
rows = r;
ship = new PixelSpaceship();
cells = new int[rows][cols];
}
// reset the pattern grid
void wipe() {
for (int r=0; r= cols) {
col = 0;
row++;
if (row >= rows) {
row = 0;
}
}
}
// advance through the pattern and draw the next robot
void drawone() {
boolean drawn = false;
do {
int cell = cells[row][col];
int work = (cell>>16) & 0xff;
int sizer = (cell) & 0xff;
if (work != WORK_NONE) {
int y1 = 16*row;
int x1 = 16*col;
ship.setScales( sizer, sizer );
ship.setMargins( 2*sizer, 2*sizer );
ship.setSeed(rng.generate());
ship.generate();
ship.recolor();
ship.draw( x1, y1 );
drawn = true;
}
advance(sizer);
if (at00()) return;
} while (!drawn);
}
}
// a minimal version of the Mersenne Twister
class miniMT {
private long seed;
private static final int N = 624;
private static final int M = 397;
private static final int MATRIX_A = 0x9908b0df;
private static final int UPPER_MASK = 0x80000000;
private static final int LOWER_MASK = 0x7fffffff;
private static final int TEMPERING_MASK_B = 0x9d2c5680;
private static final int TEMPERING_MASK_C = 0xefc60000;
private int mt[];
private int mti;
private int mag01[] = { 0x0, MATRIX_A };
public miniMT() {
this.setSeed(0);
}
public miniMT(long seed) {
this.setSeed(seed);
}
public void setSeed(final long _seed) {
seed=_seed;
mt = new int[N];
mt[0]= (int)(seed & 0xfffffff);
for (mti=1; mti>> 30)) + mti);
mt[mti] &= 0xffffffff;
}
}
public final int generate() {
int y;
if (mti >= N) {
int kk;
for (kk = 0; kk < N - M; kk++) {
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
mt[kk] = mt[kk+M] ^ (y >>> 1) ^ mag01[y & 0x1];
}
for (; kk < N-1; kk++) {
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
mt[kk] = mt[kk+(M-N)] ^ (y >>> 1) ^ mag01[y & 0x1];
}
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11;
y ^= (y << 7) & TEMPERING_MASK_B;
y ^= (y << 15) & TEMPERING_MASK_C;
y ^= (y >>> 18);
return y;
}
}