mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
yield demo: punch up with polyfills
This commit is contained in:
parent
cb521e3de7
commit
2c417ddb0c
11
USAGE.md
11
USAGE.md
@ -759,8 +759,9 @@ int ncplane_at_yx_cell(struct ncplane* n, int y, int x, cell* c);
|
||||
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
|
||||
// plane), continuing for 'leny'x'lenx' cells. Either or both of 'leny' and
|
||||
// 'lenx' can be specified as -1 to go through the boundary of the plane.
|
||||
uint32_t* ncplane_rgba(const struct ncplane* nc, int begy, int begx,
|
||||
int leny, int lenx);
|
||||
// Only glyphs from the specified blitset may be present.
|
||||
uint32_t* ncplane_rgba(const struct ncplane* nc, ncblitter_e blit,
|
||||
int begy, int begx, int leny, int lenx);
|
||||
|
||||
// return a nul-terminated, heap copy of the current (UTF-8) contents.
|
||||
char* ncplane_contents(const struct ncplane* nc, int begy, int begx,
|
||||
@ -2507,6 +2508,12 @@ nc_err_e ncvisual_rotate(struct ncvisual* n, double rads);
|
||||
// transformation, unless the size is unchanged.
|
||||
nc_err_e ncvisual_resize(struct ncvisual* n, int rows, int cols);
|
||||
|
||||
// Polyfill at the specified location within the ncvisual 'n', using 'rgba'.
|
||||
int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rgba);
|
||||
|
||||
// Get the specified pixel from the specified ncvisual.
|
||||
int ncvisual_at_yx(const struct ncvisual* n, int y, int x, uint32_t* pixel);
|
||||
|
||||
// If a subtitle ought be displayed at this time, return a heap-allocated copy
|
||||
// of the UTF8 text.
|
||||
char* ncvisual_subtitle(const struct ncvisual* ncv);
|
||||
|
@ -72,6 +72,12 @@ typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
|
||||
|
||||
**int ncvisual_rotate(struct ncvisual* n, double rads);**
|
||||
|
||||
**int ncvisual_resize(struct ncvisual* n, int rows, int cols);**
|
||||
|
||||
**int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rgba);**
|
||||
|
||||
**int ncvisual_at_yx(const struct ncvisual* n, int y, int x, uint32_t* pixel);**
|
||||
|
||||
**char* ncvisual_subtitle(const struct ncvisual* ncv);**
|
||||
|
||||
# DESCRIPTION
|
||||
|
@ -621,9 +621,9 @@ namespace ncpp
|
||||
return error_guard<int> (ncplane_polyfill_yx (plane, y, x, c), -1);
|
||||
}
|
||||
|
||||
uint32_t* rgba(int begy, int begx, int leny, int lenx) const noexcept
|
||||
uint32_t* rgba(ncblitter_e blit, int begy, int begx, int leny, int lenx) const noexcept
|
||||
{
|
||||
return ncplane_rgba (plane, begy, begx, leny, lenx);
|
||||
return ncplane_rgba (plane, blit, begy, begx, leny, lenx);
|
||||
}
|
||||
|
||||
char* content(int begy, int begx, int leny, int lenx) const noexcept
|
||||
|
@ -32,10 +32,10 @@ namespace ncpp
|
||||
throw init_error ("Notcurses failed to create a new visual");
|
||||
}
|
||||
|
||||
explicit Visual (const Plane& p, int begy, int begx, int leny, int lenx)
|
||||
explicit Visual (const Plane& p, ncblitter_e blit, int begy, int begx, int leny, int lenx)
|
||||
: Root(NotCurses::get_instance())
|
||||
{
|
||||
visual = ncvisual_from_plane (p, begy, begx, leny, lenx);
|
||||
visual = ncvisual_from_plane (p, blit, begy, begx, leny, lenx);
|
||||
if (visual == nullptr)
|
||||
throw init_error ("Notcurses failed to create a new visual");
|
||||
}
|
||||
|
@ -1213,14 +1213,6 @@ ncplane_at_yx_cell(struct ncplane* n, int y, int x, cell* c){
|
||||
return r;
|
||||
}
|
||||
|
||||
// Create an RGBA flat array from the selected region of the ncplane 'nc'.
|
||||
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
|
||||
// plane), continuing for 'leny'x'lenx' cells. Either or both of 'leny' and
|
||||
// 'lenx' can be specified as -1 to go through the boundary of the plane.
|
||||
// Only spaces, half blocks, and full blocks may be present.
|
||||
API uint32_t* ncplane_rgba(const struct ncplane* nc, int begy, int begx,
|
||||
int leny, int lenx);
|
||||
|
||||
// Create a flat string from the EGCs of the selected region of the ncplane
|
||||
// 'nc'. Start at the plane's 'begy'x'begx' coordinate (which must lie on the
|
||||
// plane), continuing for 'leny'x'lenx' cells. Either or both of 'leny' and
|
||||
@ -2119,15 +2111,6 @@ API struct ncvisual* ncvisual_from_rgba(const void* rgba, int rows,
|
||||
API struct ncvisual* ncvisual_from_bgra(const void* rgba, int rows,
|
||||
int rowstride, int cols);
|
||||
|
||||
// Promote an ncplane 'n' to an ncvisual. The plane may contain only spaces,
|
||||
// half blocks, and full blocks. The latter will be checked, and any other
|
||||
// glyph will result in a NULL being returned. This function exists so that
|
||||
// planes can be subjected to ncvisual transformations. If possible, it's
|
||||
// better to create the ncvisual from memory using ncvisual_from_rgba().
|
||||
API struct ncvisual* ncvisual_from_plane(const struct ncplane* n,
|
||||
int begy, int begx,
|
||||
int leny, int lenx);
|
||||
|
||||
// each has the empty cell in addition to the product of its dimensions. i.e.
|
||||
// NCBLIT_1x1 has two states: empty and full block. NCBLIT_1x1x4 has five
|
||||
// states: empty, the three shaded blocks, and the full block.
|
||||
@ -2143,6 +2126,24 @@ typedef enum {
|
||||
NCBLIT_SIXEL, // 6 rows, 1 col (RGB), spotty support among terminals
|
||||
} ncblitter_e;
|
||||
|
||||
// Promote an ncplane 'n' to an ncvisual. The plane may contain only spaces,
|
||||
// half blocks, and full blocks. The latter will be checked, and any other
|
||||
// glyph will result in a NULL being returned. This function exists so that
|
||||
// planes can be subjected to ncvisual transformations. If possible, it's
|
||||
// better to create the ncvisual from memory using ncvisual_from_rgba().
|
||||
API struct ncvisual* ncvisual_from_plane(const struct ncplane* n,
|
||||
ncblitter_e blit,
|
||||
int begy, int begx,
|
||||
int leny, int lenx);
|
||||
|
||||
// Create an RGBA flat array from the selected region of the ncplane 'nc'.
|
||||
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
|
||||
// plane), continuing for 'leny'x'lenx' cells. Either or both of 'leny' and
|
||||
// 'lenx' can be specified as -1 to go through the boundary of the plane.
|
||||
// Only glyphs from the specified blitset may be present.
|
||||
API uint32_t* ncplane_rgba(const struct ncplane* nc, ncblitter_e blit,
|
||||
int begy, int begx, int leny, int lenx);
|
||||
|
||||
// Get the size and ratio of ncvisual pixels to output cells along the y
|
||||
// ('toy') and x ('tox') axes. A ncvisual of '*y'X'*x' pixels will require
|
||||
// ('*y' * '*toy')X('x' * 'tox') cells for full output. Returns non-zero
|
||||
@ -2166,6 +2167,12 @@ API nc_err_e ncvisual_rotate(struct ncvisual* n, double rads);
|
||||
// transformation, unless the size is unchanged.
|
||||
API nc_err_e ncvisual_resize(struct ncvisual* n, int rows, int cols);
|
||||
|
||||
// Polyfill at the specified location within the ncvisual 'n', using 'rgba'.
|
||||
API int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rgba);
|
||||
|
||||
// Get the specified pixel from the specified ncvisual.
|
||||
API int ncvisual_at_yx(const struct ncvisual* n, int y, int x, uint32_t* pixel);
|
||||
|
||||
#define NCVISUAL_OPTION_NODEGRADE 0x0001 // fail rather than degrading
|
||||
#define NCVISUAL_OPTION_BLEND 0x0002 // use CELL_ALPHA_BLEND with visual
|
||||
|
||||
|
@ -147,7 +147,17 @@ char* ncplane_at_cursor(struct ncplane* n, uint32_t* attrword, uint64_t* channel
|
||||
int ncplane_at_cursor_cell(struct ncplane* n, cell* c);
|
||||
char* ncplane_at_yx(const struct ncplane* n, int y, int x, uint32_t* attrword, uint64_t* channels);
|
||||
int ncplane_at_yx_cell(struct ncplane* n, int y, int x, cell* c);
|
||||
uint32_t* ncplane_rgba(const struct ncplane* nc, int begy, int begx, int leny, int lenx);
|
||||
typedef enum {
|
||||
NCBLIT_1x1, // full block █
|
||||
NCBLIT_2x1, // full/(upper|left) blocks ▄█
|
||||
NCBLIT_1x1x4, // shaded full blocks ▓▒░█
|
||||
NCBLIT_2x2, // quadrants ▗▐ ▖▄▟▌▙█
|
||||
NCBLIT_4x1, // four vert/horz levels █▆▄▂ / ▎▌▊█
|
||||
NCBLIT_BRAILLE, // 4 rows, 2 cols (braille) ⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿
|
||||
NCBLIT_8x1, // eight vert/horz levels █▇▆▅▄▃▂▁ / ▏▎▍▌▋▊▉█
|
||||
NCBLIT_SIXEL, // 6 rows, 1 col (RGB)
|
||||
} ncblitter_e;
|
||||
uint32_t* ncplane_rgba(const struct ncplane* nc, ncblitter_e blit, int begy, int begx, int leny, int lenx);
|
||||
char* ncplane_contents(const struct ncplane* nc, int begy, int begx, int leny, int lenx);
|
||||
void* ncplane_set_userptr(struct ncplane* n, void* opaque);
|
||||
void* ncplane_userptr(struct ncplane* n);
|
||||
@ -292,16 +302,6 @@ typedef enum {
|
||||
NCSCALE_SCALE,
|
||||
NCSCALE_STRETCH,
|
||||
} ncscale_e;
|
||||
typedef enum {
|
||||
NCBLIT_1x1, // full block █
|
||||
NCBLIT_2x1, // full/(upper|left) blocks ▄█
|
||||
NCBLIT_1x1x4, // shaded full blocks ▓▒░█
|
||||
NCBLIT_2x2, // quadrants ▗▐ ▖▄▟▌▙█
|
||||
NCBLIT_4x1, // four vert/horz levels █▆▄▂ / ▎▌▊█
|
||||
NCBLIT_BRAILLE, // 4 rows, 2 cols (braille) ⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿
|
||||
NCBLIT_8x1, // eight vert/horz levels █▇▆▅▄▃▂▁ / ▏▎▍▌▋▊▉█
|
||||
NCBLIT_SIXEL, // 6 rows, 1 col (RGB)
|
||||
} ncblitter_e;
|
||||
struct ncvisual* ncvisual_from_file(const char* file, nc_err_e* ncerr);
|
||||
struct ncvisual* ncvisual_from_rgba(const void* rgba, int rows, int rowstride, int cols);
|
||||
struct ncvisual* ncvisual_from_bgra(const void* rgba, int rows, int rowstride, int cols);
|
||||
@ -310,6 +310,8 @@ int ncvisual_geom(const struct notcurses* nc, const struct ncvisual* n, ncblitte
|
||||
void ncvisual_destroy(struct ncvisual* ncv);
|
||||
nc_err_e ncvisual_decode(struct ncvisual* nc);
|
||||
int ncvisual_rotate(struct ncvisual* n, double rads);
|
||||
int ncvisual_resize(struct ncvisual* n, int rows, int cols);
|
||||
int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rgba);
|
||||
struct ncplane* ncvisual_render(struct notcurses* nc, struct ncvisual* ncv, const struct ncvisual_options* vopts);
|
||||
char* ncvisual_subtitle(const struct ncvisual* ncv);
|
||||
typedef int (*streamcb)(struct ncvisual*, struct ncvisual_options*, const struct timespec*, void*);
|
||||
|
@ -62,7 +62,7 @@ rotate_visual(struct notcurses* nc, struct ncplane* n, int dy, int dx){
|
||||
dx = dy * 2;
|
||||
}
|
||||
//fprintf(stderr, "ASK %d/%d @ %d/%d: %p\n", dy, dx, fromy, fromx);
|
||||
struct ncvisual* ncv = ncvisual_from_plane(n, fromy, fromx, dy, dx);
|
||||
struct ncvisual* ncv = ncvisual_from_plane(n, NCBLIT_DEFAULT, fromy, fromx, dy, dx);
|
||||
//fprintf(stderr, "%d/%d @ %d/%d: %p\n", dy, dx, fromy, fromx, ncv);
|
||||
if(!ncv){
|
||||
ncvisual_destroy(ncv);
|
||||
|
@ -22,17 +22,46 @@ int yield_demo(struct notcurses* nc){
|
||||
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
|
||||
ncplane_erase(std);
|
||||
|
||||
int vy, vx, vscaley, vscalex;
|
||||
ncvisual_geom(nc, wmv, vopts.blitter, &vy, &vx, &vscaley, &vscalex);
|
||||
struct timespec scaled;
|
||||
int threshold_painted = vy * vx * 10 / 9;
|
||||
const int ITER = 128;
|
||||
timespec_div(&demodelay, ITER, &scaled);
|
||||
int tfilled = 0;
|
||||
for(int i = 0 ; i < ITER ; ++i){
|
||||
int pfilled;
|
||||
do{
|
||||
int x = random() % (vx);
|
||||
int y = random() % (vy);
|
||||
uint32_t pixel = 0;
|
||||
ncvisual_at_yx(wmv, y, x, &pixel);
|
||||
uint32_t channel = 0;
|
||||
channel_set_rgb(&channel, 0x80, channel_g(pixel), channel_b(pixel));
|
||||
//fprintf(stderr, "POLY: %d/%d\n", y, x);
|
||||
pfilled = ncvisual_polyfill_yx(wmv, y, x, channel);
|
||||
if(pfilled < 0){
|
||||
ncvisual_destroy(wmv);
|
||||
return -1;
|
||||
}
|
||||
}while(pfilled == 0);
|
||||
tfilled += pfilled;
|
||||
if(ncvisual_render(nc, wmv, &vopts) == NULL){
|
||||
ncvisual_destroy(wmv);
|
||||
return -1;
|
||||
}
|
||||
DEMO_RENDER(nc);
|
||||
demo_nanosleep(nc, &scaled);
|
||||
if(tfilled >= threshold_painted){
|
||||
break;
|
||||
}
|
||||
}
|
||||
cell_release(std, &c);
|
||||
|
||||
ncvisual_destroy(wmv);
|
||||
return 0;
|
||||
|
@ -1938,7 +1938,8 @@ int notcurses_inputready_fd(notcurses* n){
|
||||
return fileno(n->ttyinfp);
|
||||
}
|
||||
|
||||
uint32_t* ncplane_rgba(const ncplane* nc, int begy, int begx, int leny, int lenx){
|
||||
uint32_t* ncplane_rgba(const ncplane* nc, ncblitter_e blit,
|
||||
int begy, int begx, int leny, int lenx){
|
||||
if(begy < 0 || begx < 0){
|
||||
return NULL;
|
||||
}
|
||||
@ -1979,6 +1980,9 @@ uint32_t* ncplane_rgba(const ncplane* nc, int begy, int begx, int leny, int lenx
|
||||
// FIXME how do we deal with transparency?
|
||||
uint32_t frgba = (fr) + (fg << 16u) + (fb << 8u) + 0xff000000;
|
||||
uint32_t brgba = (br) + (bg << 16u) + (bb << 8u) + 0xff000000;
|
||||
// FIXME integrate 'blit'
|
||||
(void)blit;
|
||||
// FIXME need to be able to pick up quadrants!
|
||||
if((strcmp(c, " ") == 0) || (strcmp(c, "") == 0)){
|
||||
*top = *bot = brgba;
|
||||
}else if(strcmp(c, "▄") == 0){
|
||||
@ -1992,6 +1996,7 @@ uint32_t* ncplane_rgba(const ncplane* nc, int begy, int begx, int leny, int lenx
|
||||
}else{
|
||||
free(c);
|
||||
free(ret);
|
||||
//fprintf(stderr, "bad rgba character: %s\n", c);
|
||||
return NULL;
|
||||
}
|
||||
free(c);
|
||||
|
@ -473,10 +473,11 @@ auto ncvisual_render(notcurses* nc, ncvisual* ncv,
|
||||
return n;
|
||||
}
|
||||
|
||||
auto ncvisual_from_plane(const ncplane* n, int begy, int begx,
|
||||
auto ncvisual_from_plane(const ncplane* n, ncblitter_e blit, int begy, int begx,
|
||||
int leny, int lenx) -> ncvisual* {
|
||||
uint32_t* rgba = ncplane_rgba(n, begy, begx, leny, lenx);
|
||||
uint32_t* rgba = ncplane_rgba(n, blit, begy, begx, leny, lenx);
|
||||
//fprintf(stderr, "snarg: %d/%d @ %d/%d (%p)\n", leny, lenx, begy, begx, rgba);
|
||||
//fprintf(stderr, "RGBA %p\n", rgba);
|
||||
if(rgba == nullptr){
|
||||
return nullptr;
|
||||
}
|
||||
@ -490,9 +491,7 @@ auto ncvisual_from_plane(const ncplane* n, int begy, int begx,
|
||||
}
|
||||
auto* ncv = ncvisual_from_rgba(rgba, leny * 2, lenx * 4, lenx);
|
||||
free(rgba);
|
||||
if(ncv == nullptr){
|
||||
return nullptr;
|
||||
}
|
||||
//fprintf(stderr, "RETURNING %p\n", ncv);
|
||||
return ncv;
|
||||
}
|
||||
|
||||
@ -527,6 +526,50 @@ auto ncvisual_simple_streamer(ncvisual* ncv, struct ncvisual_options* vopts,
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto ncvisual_polyfill_recurse(ncvisual* n, int y, int x,
|
||||
uint32_t rgba, uint32_t match) -> int {
|
||||
if(y < 0 || y >= n->rows){
|
||||
return 0;
|
||||
}
|
||||
if(x < 0 || x >= n->cols){
|
||||
return 0;
|
||||
}
|
||||
uint32_t* pixel = &n->data[y * (n->rowstride / 4) + x];
|
||||
if(*pixel != match || *pixel == rgba){
|
||||
return 0;
|
||||
}
|
||||
//fprintf(stderr, "%d/%d: %08x -> %08x\n", y, x, *pixel, rgba);
|
||||
*pixel = rgba;
|
||||
int ret = 1;
|
||||
ret += ncvisual_polyfill_recurse(n, y - 1, x, rgba, match);
|
||||
ret += ncvisual_polyfill_recurse(n, y + 1, x, rgba, match);
|
||||
ret += ncvisual_polyfill_recurse(n, y, x - 1, rgba, match);
|
||||
ret += ncvisual_polyfill_recurse(n, y, x + 1, rgba, match);
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto ncvisual_at_yx(const ncvisual* n, int y, int x, uint32_t* pixel) -> int {
|
||||
if(y >= n->rows || y < 0){
|
||||
return -1;
|
||||
}
|
||||
if(x >= n->cols || x < 0){
|
||||
return -1;
|
||||
}
|
||||
*pixel = n->data[y * (n->rowstride / 4) + x];
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto ncvisual_polyfill_yx(ncvisual* n, int y, int x, uint32_t rgba) -> int {
|
||||
if(y >= n->rows || y < 0){
|
||||
return -1;
|
||||
}
|
||||
if(x >= n->cols || x < 0){
|
||||
return -1;
|
||||
}
|
||||
uint32_t* pixel = &n->data[y * (n->rowstride / 4) + x];
|
||||
return ncvisual_polyfill_recurse(n, y, x, rgba, *pixel);
|
||||
}
|
||||
|
||||
#ifndef USE_OIIO // built without ffmpeg or oiio
|
||||
#ifndef USE_FFMPEG
|
||||
auto ncvisual_from_file(const char* filename, nc_err_e* err) -> ncvisual* {
|
||||
|
@ -23,7 +23,7 @@ rotate_grad(struct notcurses* nc){
|
||||
}
|
||||
notcurses_render(nc);
|
||||
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
|
||||
uint32_t* rgba = ncplane_rgba(n, 0, 0, dimy, dimx);
|
||||
uint32_t* rgba = ncplane_rgba(n, NCBLIT_DEFAULT, 0, 0, dimy, dimx);
|
||||
if(rgba == NULL){
|
||||
return -1;
|
||||
}
|
||||
@ -149,7 +149,7 @@ rotate(struct notcurses* nc){
|
||||
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);;
|
||||
|
||||
// we now have 2 rows of 20 cells each, with gradients. load 'em.
|
||||
uint32_t* rgba = ncplane_rgba(n, dimy / 2, 0, 2, XSIZE);
|
||||
uint32_t* rgba = ncplane_rgba(n, NCBLIT_DEFAULT, dimy / 2, 0, 2, XSIZE);
|
||||
if(rgba == NULL){
|
||||
return -1;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ TEST_CASE("Ncpp"
|
||||
// FIXME load something onto standard plane, load it into visual, erase
|
||||
// plane, render visual, check for equivalence...
|
||||
{
|
||||
Visual v = Visual(*n, 0, 0, -1, -1);
|
||||
Visual v = Visual(*n, NCBLIT_DEFAULT, 0, 0, -1, -1);
|
||||
}
|
||||
}
|
||||
CHECK(nc.stop());
|
||||
|
@ -119,7 +119,7 @@ TEST_CASE("Rotate") {
|
||||
ncvisual_options opts{};
|
||||
auto rendered = ncvisual_render(nc_, ncv, &opts);
|
||||
REQUIRE(rendered);
|
||||
uint32_t* rgbaret = ncplane_rgba(rendered, 0, 0, -1, -1);
|
||||
uint32_t* rgbaret = ncplane_rgba(rendered, NCBLIT_DEFAULT, 0, 0, -1, -1);
|
||||
REQUIRE(rgbaret);
|
||||
for(int i = 0 ; i < height * width / 2 ; ++i){
|
||||
if(rgbaret[i] & CELL_BG_MASK){
|
||||
@ -170,7 +170,7 @@ TEST_CASE("Rotate") {
|
||||
ncvisual_options opts{};
|
||||
auto rendered = ncvisual_render(nc_, ncv, &opts);
|
||||
REQUIRE(rendered);
|
||||
uint32_t* rgbaret = ncplane_rgba(rendered, 0, 0, -1, -1);
|
||||
uint32_t* rgbaret = ncplane_rgba(rendered, NCBLIT_DEFAULT, 0, 0, -1, -1);
|
||||
REQUIRE(rgbaret);
|
||||
for(int i = 0 ; i < height * width / 2 ; ++i){
|
||||
if(rgbaret[i] & CELL_BG_MASK){
|
||||
|
Loading…
x
Reference in New Issue
Block a user