Created
February 28, 2013 02:28
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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