« 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!