drop textplay PoC
parent
b87d8f15f7
commit
fb2078daa6
@ -1,231 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <notcurses/notcurses.h>
|
||||
#include "compat/compat.c"
|
||||
|
||||
#define GIG 1000000000ull
|
||||
static const uint32_t LOWCOLOR = 0x004080;
|
||||
static const uint32_t HICOLOR = 0xddffdd;
|
||||
static const uint32_t NANOSEC = GIG / 60; // 60 cps
|
||||
static const int FRAMERATIO = 2; // display 1 of every FRAMERATIO frames
|
||||
#define MARGIN 2
|
||||
|
||||
static struct notcurses*
|
||||
init(void){
|
||||
struct notcurses_options opts = {
|
||||
//.loglevel = NCLOGLEVEL_DEBUG,
|
||||
.margin_t = MARGIN / 2,
|
||||
.margin_r = MARGIN,
|
||||
.margin_b = MARGIN / 2,
|
||||
.margin_l = MARGIN,
|
||||
.flags = NCOPTION_NO_ALTERNATE_SCREEN |
|
||||
NCOPTION_SUPPRESS_BANNERS,
|
||||
};
|
||||
struct notcurses* nc = notcurses_init(&opts, stdout);
|
||||
return nc;
|
||||
}
|
||||
|
||||
// normally called with hicolor of HICOLOR, but sometimes we need to dull
|
||||
// it out (when we pause, and at the end)
|
||||
static int
|
||||
colorize(struct ncplane* n, uint32_t hicolor){
|
||||
int y, x;
|
||||
ncplane_cursor_yx(n, &y, &x);
|
||||
uint32_t c = hicolor;
|
||||
ncplane_set_bg_rgb(n, 0x222222);
|
||||
while(y >= 0){
|
||||
while(x >= 0){
|
||||
uint16_t stylemask;
|
||||
uint64_t channels;
|
||||
char* egc = ncplane_at_yx(n, y, x, &stylemask, &channels);
|
||||
if(egc == NULL){
|
||||
return -1;
|
||||
}
|
||||
if(strcmp(egc, "") == 0){
|
||||
free(egc);
|
||||
--x;
|
||||
continue;
|
||||
}
|
||||
ncplane_set_fg_rgb(n, c);
|
||||
if(ncplane_putegc_yx(n, y, x, egc, NULL) < 0){
|
||||
free(egc);
|
||||
return -1;
|
||||
}
|
||||
if(c != LOWCOLOR){
|
||||
unsigned g = (c & 0xff00) >> 8u;
|
||||
--g;
|
||||
// only the leading character gets the bright almost-white
|
||||
c = (c & 0x000080) | (g << 8u);
|
||||
}
|
||||
free(egc);
|
||||
--x;
|
||||
}
|
||||
--y;
|
||||
x = ncplane_dim_x(n) - 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// whenever the text indicates a lengthy delay, keep the frame rolling...
|
||||
static int
|
||||
longdelay(struct notcurses* nc, struct ncvisual* ncv, struct ncvisual_options* vopts){
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
uint64_t nowns, deadlinens;
|
||||
nowns = now.tv_sec * GIG + now.tv_nsec;
|
||||
deadlinens = nowns + 5ull * GIG;
|
||||
do{
|
||||
if(ncv){
|
||||
for(int i = 0 ; i < FRAMERATIO ; ++i){
|
||||
ncvisual_decode(ncv);
|
||||
}
|
||||
if(ncvisual_render(nc, ncv, vopts) == NULL){
|
||||
return -1;
|
||||
}
|
||||
if(notcurses_render(nc)){
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
// FIXME clock_nanosleep
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
nowns = now.tv_sec * GIG + now.tv_nsec;
|
||||
}while(nowns < deadlinens);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
textplay(struct notcurses* nc, struct ncplane* tplane, struct ncvisual* ncv){
|
||||
char* buf = NULL;
|
||||
size_t buflen = 1;
|
||||
struct ncplane* stdn = notcurses_stdplane(nc);
|
||||
ncplane_set_scrolling(tplane, true);
|
||||
struct ncvisual_options vopts = {
|
||||
.n = ncplane_dup(stdn, NULL),
|
||||
.scaling = NCSCALE_STRETCH,
|
||||
.blitter = NCBLIT_PIXEL,
|
||||
};
|
||||
ncplane_move_below(vopts.n, tplane);
|
||||
wint_t wc;
|
||||
while((wc = getwc(stdin)) != WEOF){
|
||||
if(ncv){
|
||||
if(ncvisual_render(nc, ncv, &vopts) == NULL){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ncplane_erase(tplane);
|
||||
char conv[7];
|
||||
mbstate_t mbs = {};
|
||||
size_t w = wcrtomb(conv, wc, &mbs);
|
||||
if(w == (size_t)-1){
|
||||
goto err;
|
||||
}
|
||||
conv[w] = '\0';
|
||||
char* tmp = realloc(buf, buflen + w);
|
||||
if(tmp == NULL){
|
||||
goto err;
|
||||
}
|
||||
buf = tmp;
|
||||
strcpy(buf + buflen - 1, conv);
|
||||
buflen += w;
|
||||
int pt = ncplane_puttext(tplane, 0, NCALIGN_LEFT, buf, NULL);
|
||||
if(pt < 0){
|
||||
goto err;
|
||||
}
|
||||
if(colorize(tplane, HICOLOR)){
|
||||
goto err;
|
||||
}
|
||||
if(notcurses_render(nc)){
|
||||
goto err;
|
||||
}
|
||||
struct timespec ts = {
|
||||
.tv_sec = 0, .tv_nsec = NANOSEC,
|
||||
};
|
||||
if(!ncv){
|
||||
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
|
||||
}else{
|
||||
for(int i = 0 ; i < FRAMERATIO ; ++i){
|
||||
ncvisual_decode(ncv);
|
||||
}
|
||||
}
|
||||
if(wc == L'…'){
|
||||
if(notcurses_render(nc)){
|
||||
goto err;
|
||||
}
|
||||
if(longdelay(nc, ncv, &vopts)){
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
// dull out the leading character for exit
|
||||
if(colorize(tplane, 0x00ff80)){
|
||||
goto err;
|
||||
}
|
||||
if(notcurses_render(nc)){
|
||||
goto err;
|
||||
}
|
||||
ncplane_destroy(vopts.n);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
ncplane_destroy(vopts.n);
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct ncplane*
|
||||
textplane(struct notcurses* nc){
|
||||
int dimy, dimx;
|
||||
struct ncplane* stdn = notcurses_stddim_yx(nc, &dimy, &dimx);
|
||||
struct ncplane_options nopts = {
|
||||
.y = MARGIN * 2 + 2,
|
||||
.x = MARGIN * 4 + 2,
|
||||
.rows = dimy - MARGIN * 4 + 1,
|
||||
.cols = dimx - MARGIN * 8,
|
||||
.name = "text",
|
||||
};
|
||||
struct ncplane* n = ncplane_create(stdn, &nopts);
|
||||
uint64_t channels = NCCHANNELS_INITIALIZER(0, 0, 0, 0x22, 0x22, 0x22);
|
||||
/*ncchannels_set_fg_alpha(&channels, NCALPHA_TRANSPARENT);
|
||||
ncchannels_set_bg_alpha(&channels, NCALPHA_TRANSPARENT);*/
|
||||
if(n){
|
||||
ncplane_set_base(n, "", 0, channels);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(FILE* fp){
|
||||
fprintf(fp, "usage: textplay [ media ]\n");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv){
|
||||
const char* media = NULL;
|
||||
if(argc > 3){
|
||||
usage(stderr);
|
||||
return EXIT_FAILURE;
|
||||
}else if(argc == 2){
|
||||
media = argv[1];
|
||||
}
|
||||
struct notcurses* nc = init();
|
||||
if(nc == NULL){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
struct ncvisual* ncv = NULL;
|
||||
if(media){
|
||||
if((ncv = ncvisual_from_file(media)) == NULL){
|
||||
notcurses_stop(nc);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
struct ncplane* tplane = textplane(nc);
|
||||
if(tplane == NULL){
|
||||
notcurses_stop(nc);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
textplay(nc, tplane, ncv);
|
||||
ncvisual_destroy(ncv);
|
||||
if(notcurses_stop(nc)){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue