add beginnings of yield demo

This commit is contained in:
nick black 2020-06-05 15:14:07 -04:00
parent 787e66a4c8
commit 633ef1f76c
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
11 changed files with 91 additions and 32 deletions

View File

@ -420,6 +420,8 @@ up someday **FIXME**.
make the Internet great. It probably violates any number of copyrights. C'est la vie. make the Internet great. It probably violates any number of copyrights. C'est la vie.
* Mark Ferrari, master of the pixel, for no good reason allowed me to reproduce * Mark Ferrari, master of the pixel, for no good reason allowed me to reproduce
his incredible and groundbreaking color-cycling artwork. Thanks Mark! his incredible and groundbreaking color-cycling artwork. Thanks Mark!
* The world map image was made by [Vecteezy](https://www.vecteezy.com/free-vector/world-map),
and is used according to the terms of their License.
* Finally, the [demoscene](https://en.wikipedia.org/wiki/Demoscene) and general * Finally, the [demoscene](https://en.wikipedia.org/wiki/Demoscene) and general
l33t scene of the 90s and early twenty-first century endlessly inspired a l33t scene of the 90s and early twenty-first century endlessly inspired a
young hax0r. There is great joy in computing; no one will drive us from young hax0r. There is great joy in computing; no one will drive us from

View File

@ -1130,11 +1130,11 @@ ncplane_double_box_sized(struct ncplane* n, uint32_t attr, uint64_t channels,
Similarly, areas can be filled with a cell. Similarly, areas can be filled with a cell.
```c ```c
// Starting at the specified coordinate, if it has no glyph, 'c' is copied into // Starting at the specified coordinate, if its glyph is different from that of
// it. We do the same to all cardinally-connected glyphless cells, filling in // 'c', 'c' is copied into it, and the original glyph is considered the fill
// everything behind a boundary. Returns the number of cells polyfilled. An // target. We do the same to all cardinally-connected cells having this same
// invalid initial y, x is an error. Returns the number of cells filled, or // fill target. Returns the number of cells polyfilled. An invalid initial y, x
// -1 on error. // is an error. Returns the number of cells filled, or -1 on error.
int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c); int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c);
// Draw a gradient with its upper-left corner at the current cursor position, // Draw a gradient with its upper-left corner at the current cursor position,

BIN
data/worldmap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

View File

@ -22,17 +22,18 @@ a way that is going to prevent notcurses from working.
The demonstrations include (see NOTES below): The demonstrations include (see NOTES below):
* (i)ntro—a setting of tone * (a)ll—scroll all the glyphs of your font
* (b)oxes—pulsating boxes with a transparent center * (b)oxes—pulsating boxes with a transparent center
* (c)hunli—the strongest woman in the world * (c)hunli—the strongest woman in the world
* (e)agle—they took some time off my life, back in the day * (e)agle—they took some time off my life, back in the day
* (a)ll—scroll all the glyphs of your font
* (f)allin'—the screen falls apart under heavy blows * (f)allin'—the screen falls apart under heavy blows
* (g)rid—a gradient of color lain atop a great grid * (g)rid—a gradient of color lain atop a great grid
* (h)ighcon—high contrast text atop various colors * (h)ighcon—high contrast text atop various colors
* (i)ntro—a setting of tone
* (j)ungle—low-bandwidth color cycling reveals ancient ruins * (j)ungle—low-bandwidth color cycling reveals ancient ruins
* (l)uigi—a dashing Apennine plumber in a world of fire * (l)uigi—a dashing Apennine plumber in a world of fire
* (n)ormal—a normal map of a friend, with effects * (n)ormal—a normal map of a friend, with effects
* (o)utro—a message of hope from the library's author
* (q)rcode—quick response codes (from ISO/IEC 18004:2015) * (q)rcode—quick response codes (from ISO/IEC 18004:2015)
* (r)eel—demonstration of the ncreel high-level widget * (r)eel—demonstration of the ncreel high-level widget
* (s)liders—a missing-piece puzzle made up of colorful blocks * (s)liders—a missing-piece puzzle made up of colorful blocks
@ -41,7 +42,7 @@ The demonstrations include (see NOTES below):
* (v)iew—images and a video are rendered as text * (v)iew—images and a video are rendered as text
* (w)hiteout—a great Nothing slowly robs the world of color * (w)hiteout—a great Nothing slowly robs the world of color
* (x)ray—stimulate a logo with energy * (x)ray—stimulate a logo with energy
* (o)utro—a message of hope from the library's author * (y)ield—the best laid schemes o' mice an'men gang aft agley
At any time, press 'q' to quit. The demo is best run in at least an 80x45 terminal. At any time, press 'q' to quit. The demo is best run in at least an 80x45 terminal.
@ -70,7 +71,7 @@ At any time, press 'q' to quit. The demo is best run in at least an 80x45 termin
**-V**: Print the program name and version, and exit with success. **-V**: Print the program name and version, and exit with success.
demospec: Select which demos to run, and what order to run them in. The demospec: Select which demos to run, and what order to run them in. The
default is **ixeathnbcgrwuvlsfjqo**. See above for a list of demos. default is **ixeaythnbcgrwuvlsfjqo**. See above for a list of demos.
Default margins are all 0, and thus the full screen will be rendered. Using Default margins are all 0, and thus the full screen will be rendered. Using
**-m**, margins can be supplied. Provide a single number to set all four margins **-m**, margins can be supplied. Provide a single number to set all four margins
@ -91,7 +92,7 @@ non-free under the Debian Free Software Guidelines. As a result, the
are unavailable through the Debian package. are unavailable through the Debian package.
If notcurses is built without multimedia support, the **chunli**, **eagle**, If notcurses is built without multimedia support, the **chunli**, **eagle**,
**outro**, **view**, and **xray** demos will be partially or wholly **outro**, **view**, **xray**, and **yield** demos will be partially or wholly
unavailable. If notcurses is built without libqrcodegen, the **qrcode** demo unavailable. If notcurses is built without libqrcodegen, the **qrcode** demo
will be unavailable. will be unavailable.

View File

@ -1574,11 +1574,11 @@ ncplane_perimeter(struct ncplane* n, const cell* ul, const cell* ur,
return ncplane_box_sized(n, ul, ur, ll, lr, hline, vline, dimy, dimx, ctlword); return ncplane_box_sized(n, ul, ur, ll, lr, hline, vline, dimy, dimx, ctlword);
} }
// Starting at the specified coordinate, if it has no glyph, 'c' is copied into // Starting at the specified coordinate, if its glyph is different from that of
// it. We do the same to all cardinally-connected glyphless cells, filling in // 'c', 'c' is copied into it, and the original glyph is considered the fill
// everything behind a boundary. Returns the number of cells polyfilled. An // target. We do the same to all cardinally-connected cells having this same
// invalid initial y, x is an error. Returns the number of cells filled, or // fill target. Returns the number of cells polyfilled. An invalid initial y, x
// -1 on error. // is an error. Returns the number of cells filled, or -1 on error.
API int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c); API int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c);
// Draw a gradient with its upper-left corner at the current cursor position, // Draw a gradient with its upper-left corner at the current cursor position,

View File

@ -19,7 +19,7 @@ static int democount;
static demoresult* results; static demoresult* results;
static char *datadir = NOTCURSES_SHARE; static char *datadir = NOTCURSES_SHARE;
static const char DEFAULT_DEMO[] = "ixeathnbcgrwuvlsfjqo"; static const char DEFAULT_DEMO[] = "ixeaythnbcgrwuvlsfjqo";
atomic_bool interrupted = ATOMIC_VAR_INIT(false); atomic_bool interrupted = ATOMIC_VAR_INIT(false);
// checked following demos, whether aborted, failed, or otherwise // checked following demos, whether aborted, failed, or otherwise
@ -96,8 +96,8 @@ static struct {
{ "uniblock", unicodeblocks_demo, false, }, { "uniblock", unicodeblocks_demo, false, },
{ "view", view_demo, true, }, { "view", view_demo, true, },
{ "whiteout", witherworm_demo, false, }, { "whiteout", witherworm_demo, false, },
{"xray", xray_demo, false, }, { "xray", xray_demo, false, },
{ NULL, NULL, false, }, { "yield", yield_demo, false, },
{ NULL, NULL, false, }, { NULL, NULL, false, },
}; };

View File

@ -43,6 +43,7 @@ int grid_demo(struct notcurses* nc);
int fallin_demo(struct notcurses* nc); int fallin_demo(struct notcurses* nc);
int highcontrast_demo(struct notcurses* nc); int highcontrast_demo(struct notcurses* nc);
int jungle_demo(struct notcurses* nc); int jungle_demo(struct notcurses* nc);
int yield_demo(struct notcurses* nc);
int normal_demo(struct notcurses* nc); int normal_demo(struct notcurses* nc);
int sliding_puzzle_demo(struct notcurses* nc); int sliding_puzzle_demo(struct notcurses* nc);
int view_demo(struct notcurses* nc); int view_demo(struct notcurses* nc);

39
src/demo/yield.c Normal file
View File

@ -0,0 +1,39 @@
#include "demo.h"
int yield_demo(struct notcurses* nc){
if(!notcurses_canopen_images(nc)){
return 0;
}
int dimy, dimx;
struct ncplane* std = notcurses_stddim_yx(nc, &dimy, &dimx);
char* pic = find_data("worldmap.png");
nc_err_e err;
struct ncvisual* wmv = ncvisual_from_file(pic, &err);
free(pic);
if(wmv == NULL){
return -1;
}
struct ncvisual_options vopts = {
.n = std,
.scaling = NCSCALE_STRETCH,
.blitter = NCBLIT_2x2,
};
if(ncvisual_render(nc, wmv, &vopts) == NULL){
ncvisual_destroy(wmv);
return -1;
}
DEMO_RENDER(nc);
demo_nanosleep(nc, &demodelay);
cell c = CELL_SIMPLE_INITIALIZER('*');
cell_set_fg_rgb(&c, 0xff, 0, 0);
cell_set_bg_rgb(&c, 0xff, 0, 0);
for(int i = 0 ; i < 128 ; ++i){
// FIXME
// don't try to use polyfill; work directly on the ncvisual instead
}
cell_release(std, &c);
ncvisual_destroy(wmv);
return 0;
}

View File

@ -20,7 +20,7 @@ void ncplane_greyscale(ncplane *n){
// success. so a return of 0 means there's no work to be done here, and N means // success. so a return of 0 means there's no work to be done here, and N means
// we did some work here, filling everything we could reach. out-of-plane is 0. // we did some work here, filling everything we could reach. out-of-plane is 0.
static int static int
ncplane_polyfill_recurse(ncplane* n, int y, int x, const cell* c){ ncplane_polyfill_recurse(ncplane* n, int y, int x, const cell* c, const char* targ){
if(y >= n->leny || x >= n->lenx){ if(y >= n->leny || x >= n->lenx){
return 0; // not fillable return 0; // not fillable
} }
@ -28,26 +28,29 @@ ncplane_polyfill_recurse(ncplane* n, int y, int x, const cell* c){
return 0; // not fillable return 0; // not fillable
} }
cell* cur = &n->fb[nfbcellidx(n, y, x)]; cell* cur = &n->fb[nfbcellidx(n, y, x)];
if(cur->gcluster){ char* glust = cell_strdup(n, cur);
return 0; // glyph, not polyfillable if(strcmp(glust, targ)){
free(glust);
return 0;
} }
free(glust);
if(cell_duplicate(n, cur, c) < 0){ if(cell_duplicate(n, cur, c) < 0){
return -1; return -1;
} }
int r, ret = 1; int r, ret = 1;
if((r = ncplane_polyfill_recurse(n, y - 1, x, c)) < 0){ if((r = ncplane_polyfill_recurse(n, y - 1, x, c, targ)) < 0){
return -1; return -1;
} }
ret += r; ret += r;
if((r = ncplane_polyfill_recurse(n, y + 1, x, c)) < 0){ if((r = ncplane_polyfill_recurse(n, y + 1, x, c, targ)) < 0){
return -1; return -1;
} }
ret += r; ret += r;
if((r = ncplane_polyfill_recurse(n, y, x - 1, c)) < 0){ if((r = ncplane_polyfill_recurse(n, y, x - 1, c, targ)) < 0){
return -1; return -1;
} }
ret += r; ret += r;
if((r = ncplane_polyfill_recurse(n, y, x + 1, c)) < 0){ if((r = ncplane_polyfill_recurse(n, y, x + 1, c, targ)) < 0){
return -1; return -1;
} }
ret += r; ret += r;
@ -57,11 +60,25 @@ ncplane_polyfill_recurse(ncplane* n, int y, int x, const cell* c){
// at the initial step only, invalid y, x is an error, so explicitly check. // at the initial step only, invalid y, x is an error, so explicitly check.
int ncplane_polyfill_yx(ncplane* n, int y, int x, const cell* c){ int ncplane_polyfill_yx(ncplane* n, int y, int x, const cell* c){
int ret = -1; int ret = -1;
if(c->gcluster){ // can't polyfill with a null EGC if(y < n->leny && x < n->lenx){
if(y < n->leny && x < n->lenx){ if(y >= 0 && x >= 0){
if(y >= 0 && x >= 0){ if(y >= n->leny || x >= n->lenx){
ret = ncplane_polyfill_recurse(n, y, x, c); return -1; // not fillable
} }
if(y < 0 || x < 0){
return -1; // not fillable
}
cell* cur = &n->fb[nfbcellidx(n, y, x)];
char* targ = cell_strdup(n, cur);
char* fillegc = cell_strdup(n, c);
if(strcmp(fillegc, targ) == 0){
free(targ);
free(fillegc);
return 0;
}
free(fillegc);
ret = ncplane_polyfill_recurse(n, y, x, c, targ);
free(targ);
} }
} }
return ret; return ret;

View File

@ -99,7 +99,6 @@ auto perframe(struct ncvisual* ncv, struct ncvisual_options* vopts,
clock_gettime(CLOCK_MONOTONIC, &interval); clock_gettime(CLOCK_MONOTONIC, &interval);
uint64_t nsnow = timespec_to_ns(&interval); uint64_t nsnow = timespec_to_ns(&interval);
uint64_t absnow = timespec_to_ns(abstime); uint64_t absnow = timespec_to_ns(abstime);
bool paused = false;
if(absnow > nsnow){ if(absnow > nsnow){
ns_to_timespec(absnow - nsnow, &interval); ns_to_timespec(absnow - nsnow, &interval);
char32_t keyp; char32_t keyp;

View File

@ -40,8 +40,8 @@ TEST_CASE("Fills") {
REQUIRE(nullptr != pfn); REQUIRE(nullptr != pfn);
CHECK(16 == ncplane_polyfill_yx(pfn, 0, 0, &c)); CHECK(16 == ncplane_polyfill_yx(pfn, 0, 0, &c));
CHECK(0 < ncplane_putc_yx(pfn, 0, 0, &c)); CHECK(0 < ncplane_putc_yx(pfn, 0, 0, &c));
// Trying to fill the origin ought fill zero cells // Trying to fill the origin ought now be rejected
CHECK(0 == ncplane_polyfill_yx(pfn, 0, 0, &c)); CHECK(0 > ncplane_polyfill_yx(pfn, 0, 0, &c));
CHECK(0 == notcurses_render(nc_)); CHECK(0 == notcurses_render(nc_));
CHECK(0 == ncplane_destroy(pfn)); CHECK(0 == ncplane_destroy(pfn));
} }