mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
bleachworm replaces widechomper #177
This commit is contained in:
parent
dbb74ea8c4
commit
c3fa7ea664
@ -45,7 +45,7 @@ contains a set of text-based demonstrations of capabilities from the notcurses l
|
||||
.P
|
||||
(s)liders—a missing-piece puzzle made up of colorful blocks
|
||||
.P
|
||||
(w)idechomper—a gremlin feasts upon wide characters
|
||||
(b)leachworm—a great Nothing slowly robs the world of color
|
||||
.P
|
||||
(v)iew—images and a video are rendered as text
|
||||
.P
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "demo.h"
|
||||
|
||||
// Fill up the screen with as much crazy Unicode as we can, and then set a
|
||||
// gremlin loose, looking to eat up all the wide characters.
|
||||
// gremlin loose, looking to brighten up the world.
|
||||
|
||||
// FIXME throw this in there somehow
|
||||
// ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫
|
||||
@ -25,6 +25,42 @@
|
||||
// the upper left: 012
|
||||
// 7 3
|
||||
// 654
|
||||
// is the provided cell part of the wall (i.e. a box-drawing character)?
|
||||
static bool
|
||||
wall_p(const struct ncplane* n, const cell* c){
|
||||
if(cell_simple_p(c)){ // any simple cell is fine to consume
|
||||
return false;
|
||||
}
|
||||
const char* egc = cell_extended_gcluster(n, c);
|
||||
wchar_t w;
|
||||
if(mbtowc(&w, egc, strlen(egc)) > 0){
|
||||
if(w >= 0x2500 && w <= 0x257f){ // no room in the inn, little snake!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// the closer the coordinate is (lower distance), the more we lighten the cell
|
||||
static inline int
|
||||
lighten(struct ncplane* n, cell* c, int distance){
|
||||
if(c->gcluster == 0){ // don't blow away wide characters
|
||||
return 0;
|
||||
}
|
||||
unsigned r, g, b;
|
||||
cell_get_fg_rgb(c, &r, &g, &b);
|
||||
r += rand() % (75 - distance * 25);
|
||||
b += rand() % (75 - distance * 25);
|
||||
g += rand() % (75 - distance * 25);
|
||||
if(r > 255) r = 255;
|
||||
if(g > 255) g = 255;
|
||||
if(b > 255) b = 255;
|
||||
if(cell_set_fg_rgb(c, r, g, b)){
|
||||
return -1;
|
||||
}
|
||||
return ncplane_putc(n, c);
|
||||
}
|
||||
|
||||
static void
|
||||
get_surrounding_cells(struct ncplane* n, cell* cells, int y, int x){
|
||||
if(ncplane_cursor_move_yx(n, y - 1, x - 1) == 0){
|
||||
@ -65,149 +101,74 @@ get_surrounding_cells(struct ncplane* n, cell* cells, int y, int x){
|
||||
}
|
||||
}
|
||||
|
||||
// is the provided cell part of the wall (i.e. a box-drawing character)?
|
||||
static bool
|
||||
wall_p(const struct ncplane* n, const cell* c){
|
||||
if(cell_simple_p(c)){ // any simple cell is fine to consume
|
||||
return false;
|
||||
}
|
||||
const char* egc = cell_extended_gcluster(n, c);
|
||||
wchar_t w;
|
||||
if(mbtowc(&w, egc, strlen(egc)) > 0){
|
||||
if(w >= 0x2500 && w <= 0x257f){ // no room in the inn, little snake!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void
|
||||
lighten(cell* c){
|
||||
unsigned r, g, b;
|
||||
cell_get_fg_rgb(c, &r, &g, &b);
|
||||
r += (255 - r) / 3;
|
||||
g += (255 - g) / 3;
|
||||
b += (255 - b) / 3;
|
||||
cell_set_fg_rgb(c, r, g, b);
|
||||
}
|
||||
|
||||
static int
|
||||
lightup_surrounding_cells(struct ncplane* n, const cell* cells, int y, int x){
|
||||
cell c = CELL_TRIVIAL_INITIALIZER;
|
||||
if(ncplane_cursor_move_yx(n, y - 1, x - 1) == 0){
|
||||
cell_duplicate(n, &c, &cells[0]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 2);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y - 1, x) == 0){
|
||||
cell_duplicate(n, &c, &cells[1]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 1);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y - 1, x + 1) == 0){
|
||||
cell_duplicate(n, &c, &cells[2]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 2);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y, x - 1) == 0){
|
||||
cell_duplicate(n, &c, &cells[7]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 1);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y, x + 1) == 0){
|
||||
cell_duplicate(n, &c, &cells[3]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 1);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y + 1, x - 1) == 0){
|
||||
cell_duplicate(n, &c, &cells[6]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 2);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y + 1, x) == 0){
|
||||
cell_duplicate(n, &c, &cells[5]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 1);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y + 1, x + 1) == 0){
|
||||
cell_duplicate(n, &c, &cells[4]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 2);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y - 2, x) == 0){
|
||||
cell_duplicate(n, &c, &cells[8]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 2);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y + 2, x) == 0){
|
||||
cell_duplicate(n, &c, &cells[9]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 2);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y, x - 2) == 0){
|
||||
cell_duplicate(n, &c, &cells[10]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 2);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y, x + 2) == 0){
|
||||
cell_duplicate(n, &c, &cells[11]);
|
||||
lighten(&c);
|
||||
ncplane_putc(n, &c);
|
||||
lighten(n, &c, 2);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y, x) == 0){
|
||||
cell_duplicate(n, &c, &cells[12]);
|
||||
lighten(n, &c, 0);
|
||||
}
|
||||
cell_release(n, &c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
restore_surrounding_cells(struct ncplane* n, const cell* cells, int y, int x){
|
||||
if(ncplane_cursor_move_yx(n, y - 1, x - 1) == 0){
|
||||
ncplane_putc(n, &cells[0]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y - 1, x) == 0){
|
||||
ncplane_putc(n, &cells[1]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y - 1, x + 1) == 0){
|
||||
ncplane_putc(n, &cells[2]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y, x - 1) == 0){
|
||||
ncplane_putc(n, &cells[7]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y, x + 1) == 0){
|
||||
ncplane_putc(n, &cells[3]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y + 1, x - 1) == 0){
|
||||
ncplane_putc(n, &cells[6]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y + 1, x) == 0){
|
||||
ncplane_putc(n, &cells[5]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y + 1, x + 1) == 0){
|
||||
ncplane_putc(n, &cells[4]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y - 2, x) == 0){
|
||||
ncplane_putc(n, &cells[8]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y + 2, x) == 0){
|
||||
ncplane_putc(n, &cells[9]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y, x - 2) == 0){
|
||||
ncplane_putc(n, &cells[10]);
|
||||
}
|
||||
if(ncplane_cursor_move_yx(n, y, x + 2) == 0){
|
||||
ncplane_putc(n, &cells[11]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// each snake wanders around aimlessly, prohibited from entering the summary
|
||||
// section. it ought light up the cells around it; to do this, we keep an array
|
||||
// of 12 cells with the original colors, which we tune up for the duration of
|
||||
// of 13 cells with the original colors, which we tune up for the duration of
|
||||
// our colocality (unless they're summary area walls).
|
||||
static void *
|
||||
snake_thread(void* vnc){
|
||||
struct notcurses* nc = vnc;
|
||||
struct ncplane* n = notcurses_stdplane(nc);
|
||||
cell lightup[12];
|
||||
cell lightup[13];
|
||||
size_t i;
|
||||
for(i = 0 ; i < sizeof(lightup) / sizeof(*lightup) ; ++i){
|
||||
cell_init(&lightup[i]);
|
||||
@ -225,24 +186,22 @@ snake_thread(void* vnc){
|
||||
cell_prime(n, &head, "א", 0, channels);
|
||||
cell c = CELL_TRIVIAL_INITIALIZER;
|
||||
struct timespec iterdelay = { .tv_sec = 0, .tv_nsec = 1000000000ul / 20, };
|
||||
int prevx = 0, prevy = 0;
|
||||
while(true){
|
||||
pthread_testcancel();
|
||||
get_surrounding_cells(n, lightup, y, x);
|
||||
ncplane_cursor_move_yx(n, y, x);
|
||||
ncplane_at_cursor(n, &c);
|
||||
// FIXME should be a whole body
|
||||
ncplane_putc(n, &head);
|
||||
if(lightup_surrounding_cells(n, lightup, y, x)){
|
||||
return NULL;
|
||||
}
|
||||
notcurses_render(nc);
|
||||
ncplane_cursor_move_yx(n, y, x);
|
||||
ncplane_putc(n, &c);
|
||||
int oldy, oldx;
|
||||
clock_nanosleep(CLOCK_MONOTONIC, 0, &iterdelay, NULL);
|
||||
do{ // force a move
|
||||
oldy = y;
|
||||
oldx = x;
|
||||
// FIXME he ought be weighted to avoid light; he's a snake after all
|
||||
int direction = random() % 4;
|
||||
switch(direction){
|
||||
case 0: --y; break;
|
||||
@ -268,10 +227,9 @@ snake_thread(void* vnc){
|
||||
x = oldx;
|
||||
y = oldy;
|
||||
}
|
||||
}while(oldx == x && oldy == y);
|
||||
if(restore_surrounding_cells(n, lightup, oldy, oldx)){
|
||||
return NULL;
|
||||
}
|
||||
}while((oldx == x && oldy == y) || (x == prevx && y == prevy));
|
||||
prevy = oldy;
|
||||
prevx = oldx;
|
||||
}
|
||||
cell_release(n, &head); // FIXME won't be released when cancelled
|
||||
cell_release(n, &c); // FIXME won't be released when cancelled
|
||||
@ -348,7 +306,7 @@ message(struct ncplane* n, int maxy, int maxx, int num, int total,
|
||||
}
|
||||
|
||||
// Much of this text comes from http://kermitproject.org/utf8.html
|
||||
int widechomper_demo(struct notcurses* nc){
|
||||
int bleachworm_demo(struct notcurses* nc){
|
||||
static const char* strs[] = {
|
||||
"Война и мир",
|
||||
"Бра́тья Карама́зовы",
|
||||
@ -670,9 +628,12 @@ int widechomper_demo(struct notcurses* nc){
|
||||
if(i){
|
||||
uint64_t delay = demodelay.tv_sec * 1000000000 + demodelay.tv_nsec;
|
||||
delay /= screens;
|
||||
struct timespec tv = {
|
||||
.tv_sec = delay / 1000000000, .tv_nsec = delay % 1000000000,
|
||||
};
|
||||
struct timespec tv;
|
||||
if(delay > GIG){
|
||||
ns_to_timespec(GIG, &tv);
|
||||
}else{
|
||||
ns_to_timespec(delay, &tv);
|
||||
}
|
||||
ncplane_fadein(n, &tv);
|
||||
}
|
||||
pthread_t tid;
|
@ -63,7 +63,7 @@ usage(const char* exe, int status){
|
||||
fprintf(out, " s: run shuffle\n");
|
||||
fprintf(out, " u: run uniblock\n");
|
||||
fprintf(out, " v: run view\n");
|
||||
fprintf(out, " w: run widechomper\n");
|
||||
fprintf(out, " w: run bleachworm\n");
|
||||
exit(status);
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ ext_demos(struct notcurses* nc, const char* demos){
|
||||
case 'l': ret = luigi_demo(nc); break;
|
||||
case 'v': ret = view_demo(nc); break;
|
||||
case 'e': ret = eagle_demo(nc); break;
|
||||
case 'w': ret = widechomper_demo(nc); break;
|
||||
case 'w': ret = bleachworm_demo(nc); break;
|
||||
case 'p': ret = panelreel_demo(nc); break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown demo specification: %c\n", *demos);
|
||||
|
@ -16,7 +16,7 @@ extern struct timespec demodelay;
|
||||
char* find_data(const char* datum);
|
||||
|
||||
int unicodeblocks_demo(struct notcurses* nc);
|
||||
int widechomper_demo(struct notcurses* nc);
|
||||
int bleachworm_demo(struct notcurses* nc);
|
||||
int box_demo(struct notcurses* nc);
|
||||
int maxcolor_demo(struct notcurses* nc);
|
||||
int grid_demo(struct notcurses* nc);
|
||||
|
@ -1126,6 +1126,7 @@ int ncplane_putc(ncplane* n, const cell* c){
|
||||
}
|
||||
}
|
||||
cell_set_wide(candidate);
|
||||
cell_release(n, candidate);
|
||||
}
|
||||
}
|
||||
n->damage[n->y] = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user