Skip to content

Instantly share code, notes, and snippets.

@lunasorcery
Created February 28, 2013 02:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lunasorcery/5053693 to your computer and use it in GitHub Desktop.
Save lunasorcery/5053693 to your computer and use it in GitHub Desktop.
The Dragon Curve created using GBDK's 2D plotter APIs. I know it's not entirely optimal code.
// Dragon Curve for Gameboy, using GBDK
// By Will Kirkby 2013
//
// Ported from Eelke Schipper's http://www.khanacademy.org/cs/dragon-curve/1414142328
//
// Use the up and down buttons to
// increase or decrease the number of folds.
//
// (1 << n) is used in place of pow(2, n) for speed purposes.
#include <gb/gb.h>
#include <gb/drawing.h>
// Is direction is the nth fold left?
// could put this in a table to optimise, considering the limited fold range we've got....
UINT8 isLeft(UINT16 n) {
return (((n & -n) << 1) & n) != 0;
}
void drawCurve(UINT8 folds, UINT8 clear) {
UINT16 segmentCount, i;
INT8 segmentSize;
INT8 segmentX, segmentY, nsegmentX, nsegmentY;
INT8 x, y, dx, dy, newX, newY;
UINT8 dir;
// The number of segments we draw
segmentCount = 1 << folds;
segmentSize = 80 / (1 << ((folds + 1) >> 1));
// The direction of the segments
segmentX = segmentSize;
segmentY = segmentSize;
if ((folds & 1) == 0)
segmentX = 0;
nsegmentX = -segmentX;
nsegmentY = -segmentY;
// Clear the previous render.
if (clear) {
color(WHITE, WHITE, SOLID);
box(0, 0, 159, 143, M_FILL);
}
color(BLACK, WHITE, SOLID);
gotogxy(0, 0);
gprintf("Folds: %d", folds);
gotogxy(0, 1);
gprintf("Segments: ");
gprintn(segmentCount, 10, UNSIGNED); // just run with it.... hacky code for a hacky library.
// Start point
x = 40;
y = 72;
// Direction should be 0, 1, 2 or 3.
dir = 0;
dir = ((folds - 1) >> 1) & 0x03;
if (dir != 0)
dir = 4 - dir;
i = 0;
// yeah... let's use labels to simulate a loop. apparently GBDK doesn't like loops with INT16s.
drawfold:
i++;
switch (dir) { // could probably optimise this too... table lookup anyone?
case 0:
dx = segmentX;
dy = segmentY;
break;
case 1:
dx = segmentY;
dy = nsegmentX;
break;
case 2:
dx = nsegmentX;
dy = nsegmentY;
break;
case 3:
dx = nsegmentY;
dy = segmentX;
break;
}
newX = x + dx;
newY = y + dy;
line(x, y, newX, newY);
x = newX;
y = newY;
// Turn dir, lots of optimisation here.
if (isLeft(i))
dir--;
else
dir++;
dir &= 0x03; // same as dir %= 4;
if (i == segmentCount)
goto afterloop; // break
goto drawfold; // loop back
afterloop:
return; // apparently I need a statement between the label and the closing brace.
}
void main() {
UINT8 folds, btns, btns_old, key_was_pressed;
folds = 1;
btns = 0;
btns_old = 0;
key_was_pressed = 0;
drawCurve(folds, 0);
// game loop
loop:
wait_vbl_done();
// Input
btns = joypad();
if ((btns & J_UP) && !(btns_old & J_UP)) {
if (folds != 7) {
key_was_pressed = 1;
folds++;
}
}
else if ((btns & J_DOWN) && !(btns_old & J_DOWN)) {
if (folds != 1) {
key_was_pressed = 1;
folds--;
}
}
if (key_was_pressed) {
drawCurve(folds, 1);
key_was_pressed = 0;
}
btns_old = btns;
goto loop;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment