|
|
@ -1787,19 +1787,21 @@ static int
|
|
|
|
alloc_ncplane_palette(ncplane* n, planepalette* pp){
|
|
|
|
alloc_ncplane_palette(ncplane* n, planepalette* pp){
|
|
|
|
ncplane_lock(n);
|
|
|
|
ncplane_lock(n);
|
|
|
|
ncplane_dim_yx(n, &pp->rows, &pp->cols);
|
|
|
|
ncplane_dim_yx(n, &pp->rows, &pp->cols);
|
|
|
|
int size = pp->rows * pp->cols;
|
|
|
|
// add an additional element for the background cell
|
|
|
|
|
|
|
|
int size = pp->rows * pp->cols + 1;
|
|
|
|
if((pp->channels = malloc(sizeof(*pp->channels) * size)) == NULL){
|
|
|
|
if((pp->channels = malloc(sizeof(*pp->channels) * size)) == NULL){
|
|
|
|
ncplane_unlock(n);
|
|
|
|
ncplane_unlock(n);
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pp->maxr = pp->maxg = pp->maxb = 0;
|
|
|
|
pp->maxr = pp->maxg = pp->maxb = 0;
|
|
|
|
pp->maxbr = pp->maxbg = pp->maxbb = 0;
|
|
|
|
pp->maxbr = pp->maxbg = pp->maxbb = 0;
|
|
|
|
|
|
|
|
unsigned r, g, b, br, bg, bb;
|
|
|
|
|
|
|
|
uint64_t channels;
|
|
|
|
int y, x;
|
|
|
|
int y, x;
|
|
|
|
for(y = 0 ; y < pp->rows ; ++y){
|
|
|
|
for(y = 0 ; y < pp->rows ; ++y){
|
|
|
|
for(x = 0 ; x < pp->cols ; ++x){
|
|
|
|
for(x = 0 ; x < pp->cols ; ++x){
|
|
|
|
uint64_t channels = n->fb[fbcellidx(n, y, x)].channels;
|
|
|
|
channels = n->fb[fbcellidx(n, y, x)].channels;
|
|
|
|
pp->channels[y * pp->cols + x] = channels;
|
|
|
|
pp->channels[y * pp->cols + x] = channels;
|
|
|
|
unsigned r, g, b, br, bg, bb;
|
|
|
|
|
|
|
|
cell_rgb_get_fg(channels, &r, &g, &b);
|
|
|
|
cell_rgb_get_fg(channels, &r, &g, &b);
|
|
|
|
if(r > pp->maxr){
|
|
|
|
if(r > pp->maxr){
|
|
|
|
pp->maxr = r;
|
|
|
|
pp->maxr = r;
|
|
|
@ -1822,6 +1824,29 @@ alloc_ncplane_palette(ncplane* n, planepalette* pp){
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME factor this duplication out
|
|
|
|
|
|
|
|
channels = n->background.channels;
|
|
|
|
|
|
|
|
pp->channels[y * pp->cols] = channels;
|
|
|
|
|
|
|
|
cell_rgb_get_fg(channels, &r, &g, &b);
|
|
|
|
|
|
|
|
if(r > pp->maxr){
|
|
|
|
|
|
|
|
pp->maxr = r;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(g > pp->maxg){
|
|
|
|
|
|
|
|
pp->maxg = g;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(b > pp->maxb){
|
|
|
|
|
|
|
|
pp->maxb = b;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cell_rgb_get_bg(channels, &br, &bg, &bb);
|
|
|
|
|
|
|
|
if(br > pp->maxbr){
|
|
|
|
|
|
|
|
pp->maxbr = br;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(bg > pp->maxbg){
|
|
|
|
|
|
|
|
pp->maxbg = bg;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(bb > pp->maxbb){
|
|
|
|
|
|
|
|
pp->maxbb = bb;
|
|
|
|
|
|
|
|
}
|
|
|
|
ncplane_unlock(n);
|
|
|
|
ncplane_unlock(n);
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1918,6 +1943,8 @@ int ncplane_fadeout(ncplane* n, const struct timespec* ts){
|
|
|
|
// Start time in absolute nanoseconds
|
|
|
|
// Start time in absolute nanoseconds
|
|
|
|
uint64_t startns = times.tv_sec * NANOSECS_IN_SEC + times.tv_nsec;
|
|
|
|
uint64_t startns = times.tv_sec * NANOSECS_IN_SEC + times.tv_nsec;
|
|
|
|
do{
|
|
|
|
do{
|
|
|
|
|
|
|
|
unsigned br, bg, bb;
|
|
|
|
|
|
|
|
unsigned r, g, b;
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, ×);
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, ×);
|
|
|
|
uint64_t curns = times.tv_sec * NANOSECS_IN_SEC + times.tv_nsec;
|
|
|
|
uint64_t curns = times.tv_sec * NANOSECS_IN_SEC + times.tv_nsec;
|
|
|
|
int iter = (curns - startns) / nanosecs_step + 1;
|
|
|
|
int iter = (curns - startns) / nanosecs_step + 1;
|
|
|
@ -1931,18 +1958,16 @@ int ncplane_fadeout(ncplane* n, const struct timespec* ts){
|
|
|
|
ncplane_dim_yx(n, &dimy, &dimx);
|
|
|
|
ncplane_dim_yx(n, &dimy, &dimx);
|
|
|
|
for(y = 0 ; y < pp.rows && y < dimy ; ++y){
|
|
|
|
for(y = 0 ; y < pp.rows && y < dimy ; ++y){
|
|
|
|
for(x = 0 ; x < pp.cols && x < dimx; ++x){
|
|
|
|
for(x = 0 ; x < pp.cols && x < dimx; ++x){
|
|
|
|
unsigned r, g, b;
|
|
|
|
|
|
|
|
cell_rgb_get_fg(pp.channels[pp.cols * y + x], &r, &g, &b);
|
|
|
|
|
|
|
|
unsigned br, bg, bb;
|
|
|
|
|
|
|
|
cell_rgb_get_bg(pp.channels[pp.cols * y + x], &br, &bg, &bb);
|
|
|
|
|
|
|
|
cell* c = &n->fb[dimx * y + x];
|
|
|
|
cell* c = &n->fb[dimx * y + x];
|
|
|
|
if(!cell_fg_default_p(c)){
|
|
|
|
if(!cell_fg_default_p(c)){
|
|
|
|
|
|
|
|
cell_rgb_get_fg(pp.channels[pp.cols * y + x], &r, &g, &b);
|
|
|
|
r = r * (maxsteps - iter) / maxsteps;
|
|
|
|
r = r * (maxsteps - iter) / maxsteps;
|
|
|
|
g = g * (maxsteps - iter) / maxsteps;
|
|
|
|
g = g * (maxsteps - iter) / maxsteps;
|
|
|
|
b = b * (maxsteps - iter) / maxsteps;
|
|
|
|
b = b * (maxsteps - iter) / maxsteps;
|
|
|
|
cell_set_fg(c, r, g, b);
|
|
|
|
cell_set_fg(c, r, g, b);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!cell_bg_default_p(c)){
|
|
|
|
if(!cell_bg_default_p(c)){
|
|
|
|
|
|
|
|
cell_rgb_get_bg(pp.channels[pp.cols * y + x], &br, &bg, &bb);
|
|
|
|
br = br * (maxsteps - iter) / maxsteps;
|
|
|
|
br = br * (maxsteps - iter) / maxsteps;
|
|
|
|
bg = bg * (maxsteps - iter) / maxsteps;
|
|
|
|
bg = bg * (maxsteps - iter) / maxsteps;
|
|
|
|
bb = bb * (maxsteps - iter) / maxsteps;
|
|
|
|
bb = bb * (maxsteps - iter) / maxsteps;
|
|
|
@ -1950,16 +1975,31 @@ int ncplane_fadeout(ncplane* n, const struct timespec* ts){
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cell* c = &n->background;
|
|
|
|
|
|
|
|
if(!cell_fg_default_p(c)){
|
|
|
|
|
|
|
|
cell_rgb_get_fg(pp.channels[pp.cols * y], &r, &g, &b);
|
|
|
|
|
|
|
|
r = r * (maxsteps - iter) / maxsteps;
|
|
|
|
|
|
|
|
g = g * (maxsteps - iter) / maxsteps;
|
|
|
|
|
|
|
|
b = b * (maxsteps - iter) / maxsteps;
|
|
|
|
|
|
|
|
cell_set_fg(&n->background, r, g, b);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!cell_bg_default_p(c)){
|
|
|
|
|
|
|
|
cell_rgb_get_bg(pp.channels[pp.cols * y], &br, &bg, &bb);
|
|
|
|
|
|
|
|
br = br * (maxsteps - iter) / maxsteps;
|
|
|
|
|
|
|
|
bg = bg * (maxsteps - iter) / maxsteps;
|
|
|
|
|
|
|
|
bb = bb * (maxsteps - iter) / maxsteps;
|
|
|
|
|
|
|
|
cell_set_bg(&n->background, br, bg, bb);
|
|
|
|
|
|
|
|
}
|
|
|
|
notcurses_render(n->nc);
|
|
|
|
notcurses_render(n->nc);
|
|
|
|
uint64_t nextwake = (iter + 1) * nanosecs_step + startns;
|
|
|
|
uint64_t nextwake = (iter + 1) * nanosecs_step + startns;
|
|
|
|
struct timespec sleepspec;
|
|
|
|
struct timespec sleepspec;
|
|
|
|
sleepspec.tv_sec = nextwake / NANOSECS_IN_SEC;
|
|
|
|
sleepspec.tv_sec = nextwake / NANOSECS_IN_SEC;
|
|
|
|
sleepspec.tv_nsec = nextwake % NANOSECS_IN_SEC;
|
|
|
|
sleepspec.tv_nsec = nextwake % NANOSECS_IN_SEC;
|
|
|
|
int r;
|
|
|
|
int rsleep;
|
|
|
|
// clock_nanosleep() has no love for CLOCK_MONOTONIC_RAW, at least as
|
|
|
|
// clock_nanosleep() has no love for CLOCK_MONOTONIC_RAW, at least as
|
|
|
|
// of Glibc 2.29 + Linux 5.3 :/.
|
|
|
|
// of Glibc 2.29 + Linux 5.3 :/.
|
|
|
|
r = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &sleepspec, NULL);
|
|
|
|
rsleep = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &sleepspec, NULL);
|
|
|
|
if(r){
|
|
|
|
if(rsleep){
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}while(true);
|
|
|
|
}while(true);
|
|
|
|