« Back to the project
Source Code:
//
// Bitalizer v1.2
//
// Brian Reavis
// brianreavis@inwo.com
// http://random.inwo.com/bitalizer/
//
// This is licenced under a use-modify-and
// distribute-however-you-like license. All
// I ask is that you don't change a few lines
// and take complete credit for it. Other than
// that, have fun with it. If you make something
// with it, send me a link!
//
import processing.video.*;
//---- initial configuration ----
boolean renderVideo = false;
String filename = "shell32.dll";
color bgColor = #000000;
color color0 = #ff002a;
color color255 = #00ffea;
color subdivisionColor = #202020;
int bytesPerFrame = 128;
float walkLength = 0.5;
float angleSpan = PI/8;
//---- setup the environment ----
void setup(){
size(468, 320);
frameRate(30);
//initial positioning
startX = width/2;
startY = height/2;
camX=startX;
camY=startY;
x = startX;
y = startY;
BUFFER_WIDTH = 256;
BUFFER_HEIGHT = 256;
//strokes and fills
colorMode(HSB, 255);
strokeWeight(2);
smooth();
background(bgColor);
//initalizing the video rendering
if (renderVideo){
video = new MovieMaker(
this,
width,
height,
str(day())+"-"+str(month())+"-"+str(year())+" "+str(hour())+str(minute())+str(second()) + ".mov",
30,
MovieMaker.ANIMATION,
MovieMaker.HIGH
);
}
//set up the first buffer that we're going to render into
initalizeRenderBuffers();
}
//---- general variables & functions----
int startX, startY;
float x, y;
float theta = 0;
byte[] bytes;
MovieMaker video;
float camX,camY;
float scaleAmt = 1.0;
boolean stopRendering = false;
void keyPressed(){
switch(key){
case '-':
scaleAmt -= 0.05;
break;
case '+':
scaleAmt += 0.05;
break;
case ' ':
stopRendering = true;
break;
}
}
void draw(){
switch(frameCount){
case 1:
background(bgColor);
return;
case 2:
loadData(filename);
break;
default:
background(bgColor);
camX -= (camX-x)/30;
camY -= (camY-y)/30;
scale(scaleAmt);
translate((width/2/scaleAmt - camX), (height/2/scaleAmt - camY));
//draw to the off-screen buffers
if (!stopRendering) render();
//show the buffers
drawRenderBuffers();
drawStartpoint();
drawEndpoint();
if (renderVideo){
video.addFrame();
}
break;
}
}
//---- render buffers for out-of-window rendering ----
int currentBufferI = 0;
int currentBufferJ = 0;
int relativeX = 0;
int relativeY = 0;
int BUFFER_WIDTH;
int BUFFER_HEIGHT;
PGraphics renderBuffers[];
PGraphics currentBuffer;
int renderBuffers_iAssociations[];
int renderBuffers_jAssociations[];
void initalizeRenderBuffers(){
renderBuffers = new PGraphics[0];
renderBuffers_iAssociations = new int[0];
renderBuffers_jAssociations = new int[0];
switchRenderBuffer(0, 0);
}
PGraphics addRenderBuffer(int iIdx, int jIdx){
PGraphics newBuffer = createGraphics(BUFFER_WIDTH, BUFFER_HEIGHT, JAVA2D);
newBuffer.background(bgColor);
newBuffer.strokeWeight(0.7);
int newBufferIdx = renderBuffers.length;
renderBuffers = (PGraphics[])append(renderBuffers, newBuffer);
renderBuffers_iAssociations = append(renderBuffers_iAssociations, iIdx);
renderBuffers_jAssociations = append(renderBuffers_jAssociations, jIdx);
return newBuffer;
}
void switchRenderBuffer(int iIdx, int jIdx){
if (currentBuffer != null)
currentBuffer.endDraw();
currentBufferI = iIdx;
currentBufferJ = jIdx;
relativeX = -currentBufferI * BUFFER_WIDTH;
relativeY = -currentBufferJ * BUFFER_HEIGHT;
for (int i = 0; i < renderBuffers_iAssociations.length; i++){
if (renderBuffers_iAssociations[i] == iIdx && renderBuffers_jAssociations[i] == jIdx){
currentBuffer = renderBuffers[i];
currentBuffer.beginDraw();
return;
}
}
try {
currentBuffer = addRenderBuffer(iIdx, jIdx);
currentBuffer.beginDraw();
}catch(Exception e){
//and... we're out of memory :(
stopRendering = true;
}
}
void drawRenderBuffers(){
for (int n = 0; n < renderBuffers.length; n++){
int x = renderBuffers_iAssociations[n]*BUFFER_WIDTH;
int y = renderBuffers_jAssociations[n]*BUFFER_HEIGHT;
renderBuffers[n].endDraw();
image(renderBuffers[n], renderBuffers_iAssociations[n]*BUFFER_WIDTH, renderBuffers_jAssociations[n]*BUFFER_HEIGHT);
noFill();
stroke(subdivisionColor);
strokeWeight(1);
rect(renderBuffers_iAssociations[n]*BUFFER_WIDTH, renderBuffers_jAssociations[n]*BUFFER_HEIGHT, BUFFER_WIDTH, BUFFER_HEIGHT);
}
}
//---- draw the bits... ----
void render(){
currentBuffer.beginDraw();
strokeWeight(0.5);
float newX, newY;
int upperBound = min(bytes.length, bytesPerFrame);
for (int i = 0; i < upperBound; i++){
currentBuffer.stroke(lerpColor(color0, color255, int(bytes[i])/255f), 80);
for (int j = 0; j < 8; j++){
int bit = bitofbyte(bytes[i],j);
theta = theta + (bit==1?1:-1)*angleSpan;
newX = x + cos(theta)*walkLength;
newY = y + sin(theta)*walkLength;
float plot0x = x + relativeX;
float plot0y = y + relativeY;
float plot1x = newX + relativeX;
float plot1y = newY + relativeY;
currentBuffer.line(plot0x, plot0y, plot1x, plot1y);
int bI = plot0x >= BUFFER_WIDTH ? 1 : (plot0x < 0 ? -1 : 0);
int bJ = plot0y >= BUFFER_HEIGHT ? 1 : (plot0y < 0 ? -1 : 0);
if (bI != 0 || bJ != 0){
switchRenderBuffer(currentBufferI+bI, currentBufferJ+bJ);
currentBuffer.stroke(lerpColor(color0, color255, int(bytes[i])/255f), 80);
currentBuffer.line(plot0x - BUFFER_WIDTH*bI, plot0y - BUFFER_HEIGHT*bJ, plot1x - BUFFER_WIDTH*bI, plot1y - BUFFER_HEIGHT*bJ);
}
x = newX;
y = newY;
}
}
currentBuffer.endDraw();
bytes = subset(bytes, upperBound);
if (bytes.length == 0 && renderVideo){
video.finish();
exit();
}
}
//---- other rendering functions ----
void drawStartpoint(){
fill(0);
stroke(#d8ff00);
strokeWeight(2);
ellipseMode(CENTER);
ellipse(startX, startY, 3, 3);
}
void drawEndpoint(){
fill(0);
stroke(#d8ff00);
strokeWeight(2);
ellipseMode(CENTER);
ellipse(x, y, 3, 3);
}
//---- auxiliary functions ----
int bitofbyte(byte bite, int idx){
return (bite & 1 << (7 - idx)) != 0 ? 1 : 0;
}
void loadData(String filename){
print("Loading bytes from ");
print(filename);
print("...");
bytes = loadBytes(filename);
println(" Done.");
}
//...and that's it!