mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-08 01:10:23 +00:00
114 lines
2.6 KiB
C
114 lines
2.6 KiB
C
#include "demo.h"
|
|
|
|
// lame as fuck lol
|
|
static bool done;
|
|
static uint32_t pixel;
|
|
static int y, x, dy, dx;
|
|
|
|
static int
|
|
dragonmayer(struct ncvisual* ncv, const char* str, int iters){
|
|
int total = 0;
|
|
char c;
|
|
int r;
|
|
while( (c = *str++) ){
|
|
switch(c){
|
|
case 'X':
|
|
if(iters > 1){
|
|
if((r = dragonmayer(ncv, "X+YF+", iters - 1)) < 0){
|
|
return r;
|
|
}
|
|
total += r;
|
|
}
|
|
break;
|
|
case 'Y':
|
|
if(iters > 1){
|
|
if((r = dragonmayer(ncv, "-FX-Y", iters - 1)) < 0){
|
|
return r;
|
|
}
|
|
total += r;
|
|
}
|
|
break;
|
|
case '+': { int tmp = dy; dy = -dx; dx = tmp; break; }
|
|
case '-': { int tmp = -dy; dy = dx; dx = tmp; break; }
|
|
case 'F': // FIXME want a line
|
|
ncpixel_set_r(&pixel, 0xb0 - (iters * 0x10));
|
|
ncpixel_set_a(&pixel, 0xff);
|
|
if(ncvisual_set_yx(ncv, y, x, pixel) == 0){
|
|
++total;
|
|
}
|
|
pixel = 0;
|
|
x += dx;
|
|
y += dy;
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
return total;
|
|
}
|
|
|
|
int dragon_demo(struct notcurses* nc){
|
|
done = false;
|
|
int dimy, dimx;
|
|
struct ncplane* n = notcurses_stddim_yx(nc, &dimy, &dimx);
|
|
--dimy; // don't disturb the menu bar
|
|
// we use a Lindenmayer string rewriting system. the classic dragon curve
|
|
// system is X -> X+YF+, Y -> -FX-Y, where F is forward, - is turn left, and
|
|
// + is turn right.
|
|
const char LINDENSTART[] = "FX";
|
|
const int vscale = 3;
|
|
dimy *= vscale;
|
|
dimy += (vscale - 1);
|
|
dimx *= 2;
|
|
int dxstart, dystart;
|
|
if(dimy > dimx){
|
|
dystart = 0;
|
|
dxstart = 1;
|
|
}else{
|
|
dystart = 1;
|
|
dxstart = 0;
|
|
}
|
|
size_t fbbytes = sizeof(uint32_t) * dimy * dimx;
|
|
uint32_t* rgba = malloc(fbbytes);
|
|
if(rgba == NULL){
|
|
return -1;
|
|
}
|
|
memset(rgba, 0, fbbytes);
|
|
struct ncvisual* ncv = ncvisual_from_rgba(rgba, dimy, dimx * sizeof(uint32_t), dimx);
|
|
free(rgba);
|
|
if(ncv == NULL){
|
|
return -1;
|
|
}
|
|
struct timespec scaled;
|
|
timespec_div(&demodelay, 8, &scaled);
|
|
int lasttotal = 0;
|
|
int iters = 0;
|
|
int r = 0;
|
|
do{
|
|
++iters;
|
|
lasttotal = r;
|
|
dx = dxstart;
|
|
dy = dystart;
|
|
x = dimx / 2;
|
|
y = dimy / vscale;
|
|
r = dragonmayer(ncv, LINDENSTART, iters);
|
|
if(r < 0){
|
|
ncvisual_destroy(ncv);
|
|
return r;
|
|
}
|
|
struct ncvisual_options vopts = {
|
|
.n = n,
|
|
.y = 1,
|
|
.scaling = NCSCALE_STRETCH,
|
|
};
|
|
if(ncvisual_render(nc, ncv, &vopts) == NULL){
|
|
ncvisual_destroy(ncv);
|
|
return -1;
|
|
}
|
|
DEMO_RENDER(nc);
|
|
demo_nanosleep(nc, &scaled);
|
|
}while(lasttotal != r);
|
|
ncvisual_destroy(ncv);
|
|
return 0;
|
|
}
|