2019-11-26 12:50:51 +00:00
|
|
|
#include <wchar.h>
|
2019-11-17 15:25:40 +00:00
|
|
|
#include <stdio.h>
|
2019-11-23 23:34:06 +00:00
|
|
|
#include <string.h>
|
2019-11-21 13:19:57 +00:00
|
|
|
#include <locale.h>
|
2019-11-19 14:10:28 +00:00
|
|
|
#include <unistd.h>
|
2019-11-24 01:52:14 +00:00
|
|
|
#include <getopt.h>
|
2019-11-17 10:04:41 +00:00
|
|
|
#include <stdlib.h>
|
2019-11-17 14:53:59 +00:00
|
|
|
#include <notcurses.h>
|
2019-11-24 17:36:46 +00:00
|
|
|
#include "demo.h"
|
2019-11-17 10:04:41 +00:00
|
|
|
|
2019-12-01 03:53:24 +00:00
|
|
|
static const unsigned long GIG = 1000000000;
|
|
|
|
|
2019-11-28 20:33:26 +00:00
|
|
|
struct timespec demodelay = {
|
|
|
|
.tv_sec = 1,
|
|
|
|
.tv_nsec = 0,
|
|
|
|
};
|
|
|
|
|
2019-11-24 01:52:14 +00:00
|
|
|
static void
|
|
|
|
usage(const char* exe, int status){
|
|
|
|
FILE* out = status == EXIT_SUCCESS ? stdout : stderr;
|
2019-11-29 09:06:02 +00:00
|
|
|
fprintf(out, "usage: %s [ -h ] [ -k ] [ -d ns ] [ -f renderfile ] demospec\n", exe);
|
2019-11-29 03:08:26 +00:00
|
|
|
fprintf(out, " -h: this message\n");
|
|
|
|
fprintf(out, " -k: keep screen; do not switch to alternate\n");
|
2019-12-01 03:53:24 +00:00
|
|
|
fprintf(out, " -d: delay multiplier (float)\n");
|
2019-11-29 09:06:02 +00:00
|
|
|
fprintf(out, " -f: render to file in addition to stdout\n");
|
2019-11-29 03:08:26 +00:00
|
|
|
fprintf(out, "all demos are run if no specification is provided\n");
|
|
|
|
fprintf(out, " i: run intro\n");
|
|
|
|
fprintf(out, " s: run shuffle\n");
|
|
|
|
fprintf(out, " u: run uniblock\n");
|
|
|
|
fprintf(out, " m: run maxcolor\n");
|
|
|
|
fprintf(out, " b: run box\n");
|
|
|
|
fprintf(out, " g: run grid\n");
|
|
|
|
fprintf(out, " w: run widecolors\n");
|
2019-11-24 01:52:14 +00:00
|
|
|
exit(status);
|
|
|
|
}
|
|
|
|
|
2019-11-25 02:54:00 +00:00
|
|
|
static int
|
2019-11-29 03:08:26 +00:00
|
|
|
intro(struct notcurses* nc){
|
2019-11-21 11:38:21 +00:00
|
|
|
struct ncplane* ncp;
|
|
|
|
if((ncp = notcurses_stdplane(nc)) == NULL){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-21 11:38:21 +00:00
|
|
|
}
|
2019-11-29 03:08:26 +00:00
|
|
|
ncplane_erase(ncp);
|
2019-11-23 14:05:32 +00:00
|
|
|
int x, y, rows, cols;
|
2019-11-29 03:08:26 +00:00
|
|
|
ncplane_dim_yx(ncp, &rows, &cols);
|
2019-11-23 14:05:32 +00:00
|
|
|
cell c;
|
2019-11-25 02:54:00 +00:00
|
|
|
cell_init(&c);
|
2019-11-26 02:34:47 +00:00
|
|
|
const char* cstr = "Δ";
|
2019-11-24 00:24:29 +00:00
|
|
|
cell_load(ncp, &c, cstr);
|
2019-11-23 14:05:32 +00:00
|
|
|
cell_set_fg(&c, 200, 0, 200);
|
2019-11-25 09:54:40 +00:00
|
|
|
int ys = 200 / (rows - 2);
|
2019-11-27 19:49:01 +00:00
|
|
|
for(y = 5 ; y < rows - 6 ; ++y){
|
2019-11-25 09:54:40 +00:00
|
|
|
cell_set_bg(&c, 0, y * ys , 0);
|
2019-11-27 19:49:01 +00:00
|
|
|
for(x = 5 ; x < cols - 6 ; ++x){
|
|
|
|
if(ncplane_cursor_move_yx(ncp, y, x)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-27 19:49:01 +00:00
|
|
|
}
|
2019-11-24 20:33:22 +00:00
|
|
|
if(ncplane_putc(ncp, &c) != (int)strlen(cstr)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-23 14:05:32 +00:00
|
|
|
}
|
2019-11-21 13:19:57 +00:00
|
|
|
}
|
|
|
|
}
|
2019-11-24 20:33:22 +00:00
|
|
|
cell_release(ncp, &c);
|
2019-11-26 02:34:47 +00:00
|
|
|
cell ul = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
cell ur = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
cell ll = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
cell lr = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
cell vl = CELL_TRIVIAL_INITIALIZER;
|
|
|
|
cell hl = CELL_TRIVIAL_INITIALIZER;
|
2019-11-27 02:30:08 +00:00
|
|
|
if(ncplane_rounded_box_cells(ncp, &ul, &ur, &ll, &lr, &hl, &vl)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-26 02:34:47 +00:00
|
|
|
}
|
|
|
|
cell_set_fg(&ul, 90, 0, 90);
|
|
|
|
cell_set_fg(&ur, 90, 0, 90);
|
|
|
|
cell_set_fg(&ll, 90, 0, 90);
|
|
|
|
cell_set_fg(&lr, 90, 0, 90);
|
|
|
|
cell_set_fg(&vl, 90, 0, 90);
|
|
|
|
cell_set_fg(&hl, 90, 0, 90);
|
|
|
|
cell_set_bg(&ul, 0, 0, 180);
|
|
|
|
cell_set_bg(&ur, 0, 0, 180);
|
|
|
|
cell_set_bg(&ll, 0, 0, 180);
|
|
|
|
cell_set_bg(&lr, 0, 0, 180);
|
|
|
|
cell_set_bg(&vl, 0, 0, 180);
|
|
|
|
cell_set_bg(&hl, 0, 0, 180);
|
2019-11-27 19:49:01 +00:00
|
|
|
if(ncplane_cursor_move_yx(ncp, 4, 4)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-27 02:30:08 +00:00
|
|
|
}
|
2019-11-27 19:49:01 +00:00
|
|
|
if(ncplane_box(ncp, &ul, &ur, &ll, &lr, &hl, &vl, rows - 6, cols - 6)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-26 02:34:47 +00:00
|
|
|
}
|
2019-11-26 02:11:27 +00:00
|
|
|
const char s1[] = " Die Welt ist alles, was der Fall ist. ";
|
2019-11-24 00:24:29 +00:00
|
|
|
const char str[] = " Wovon man nicht sprechen kann, darüber muss man schweigen. ";
|
2019-11-26 02:34:47 +00:00
|
|
|
if(ncplane_fg_rgb8(ncp, 192, 192, 192)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-23 17:39:54 +00:00
|
|
|
}
|
2019-11-26 02:34:47 +00:00
|
|
|
if(ncplane_bg_rgb8(ncp, 0, 40, 0)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-23 17:28:42 +00:00
|
|
|
}
|
2019-11-26 02:34:47 +00:00
|
|
|
if(ncplane_cursor_move_yx(ncp, rows / 2 - 2, (cols - strlen(s1) + 4) / 2)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-26 02:11:27 +00:00
|
|
|
}
|
|
|
|
if(ncplane_putstr(ncp, s1) != (int)strlen(s1)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-26 02:11:27 +00:00
|
|
|
}
|
|
|
|
if(ncplane_cursor_move_yx(ncp, rows / 2, (cols - strlen(str) + 4) / 2)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-26 02:11:27 +00:00
|
|
|
}
|
2019-11-28 18:04:46 +00:00
|
|
|
ncplane_styles_on(ncp, CELL_STYLE_ITALIC);
|
2019-11-23 23:34:06 +00:00
|
|
|
if(ncplane_putstr(ncp, str) != (int)strlen(str)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-23 17:28:42 +00:00
|
|
|
}
|
2019-11-28 18:04:46 +00:00
|
|
|
ncplane_styles_off(ncp, CELL_STYLE_ITALIC);
|
2019-11-26 12:50:51 +00:00
|
|
|
const wchar_t wstr[] = L"▏▁ ▂ ▃ ▄ ▅ ▆ ▇ █ █ ▇ ▆ ▅ ▄ ▃ ▂ ▁▕";
|
|
|
|
char mbstr[128];
|
|
|
|
if(wcstombs(mbstr, wstr, sizeof(mbstr)) <= 0){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-25 12:46:11 +00:00
|
|
|
}
|
2019-11-26 12:50:51 +00:00
|
|
|
if(ncplane_cursor_move_yx(ncp, rows / 2 - 5, (cols - wcslen(wstr) + 4) / 2)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-26 12:50:51 +00:00
|
|
|
}
|
|
|
|
if(ncplane_putstr(ncp, mbstr) != (int)strlen(mbstr)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
2019-11-25 12:46:11 +00:00
|
|
|
}
|
2019-11-23 17:28:42 +00:00
|
|
|
if(notcurses_render(nc)){
|
2019-11-29 03:08:26 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
nanosleep(&demodelay, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
ext_demos(struct notcurses* nc, const char* demos){
|
|
|
|
while(*demos){
|
|
|
|
int ret = 0;
|
|
|
|
switch(*demos){
|
|
|
|
case 'i': ret = intro(nc); break;
|
|
|
|
case 's': ret = sliding_puzzle_demo(nc); break;
|
|
|
|
case 'u': ret = unicodeblocks_demo(nc); break;
|
|
|
|
case 'm': ret = maxcolor_demo(nc); break;
|
|
|
|
case 'b': ret = box_demo(nc); break;
|
|
|
|
case 'g': ret = grid_demo(nc); break;
|
|
|
|
case 'w': ret = widecolor_demo(nc); break;
|
|
|
|
}
|
|
|
|
if(ret){
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
++demos;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// returns the demos to be run as a string. on error, returns NULL. on no
|
|
|
|
// specification, also returns NULL, heh. determine this by argv[optind];
|
|
|
|
// if it's NULL, there were valid options, but no spec.
|
|
|
|
static const char*
|
|
|
|
handle_opts(int argc, char** argv, notcurses_options* opts){
|
|
|
|
int c;
|
|
|
|
memset(opts, 0, sizeof(*opts));
|
|
|
|
opts->outfp = stdout;
|
2019-11-29 09:06:02 +00:00
|
|
|
while((c = getopt(argc, argv, "hkd:f:")) != EOF){
|
2019-11-29 03:08:26 +00:00
|
|
|
switch(c){
|
|
|
|
case 'h':
|
|
|
|
usage(*argv, EXIT_SUCCESS);
|
|
|
|
break;
|
|
|
|
case 'k':
|
|
|
|
opts->inhibit_alternate_screen = true;
|
|
|
|
break;
|
2019-11-29 09:06:02 +00:00
|
|
|
case 'f':
|
|
|
|
if(opts->renderfp){
|
|
|
|
fprintf(stderr, "-f may only be supplied once\n");
|
|
|
|
usage(*argv, EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
if((opts->renderfp = fopen(optarg, "wb")) == NULL){
|
|
|
|
usage(*argv, EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
break;
|
2019-11-29 03:08:26 +00:00
|
|
|
case 'd':{
|
2019-12-01 03:53:24 +00:00
|
|
|
float f;
|
|
|
|
if(sscanf(optarg, "%f", &f) != 1){
|
|
|
|
fprintf(stderr, "Couldn't get a float from %s\n", optarg);
|
2019-11-29 03:08:26 +00:00
|
|
|
usage(*argv, EXIT_FAILURE);
|
|
|
|
}
|
2019-12-01 03:53:24 +00:00
|
|
|
uint64_t ns = f * GIG;
|
|
|
|
demodelay.tv_sec = ns / GIG;
|
|
|
|
demodelay.tv_nsec = ns % GIG;
|
2019-11-29 03:08:26 +00:00
|
|
|
break;
|
|
|
|
}default:
|
|
|
|
usage(*argv, EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const char* demos = argv[optind];
|
|
|
|
return demos;
|
|
|
|
}
|
|
|
|
|
|
|
|
// just fucking around...for now
|
|
|
|
int main(int argc, char** argv){
|
|
|
|
srandom(time(NULL)); // a classic blunder
|
|
|
|
struct notcurses* nc;
|
|
|
|
notcurses_options nopts;
|
|
|
|
struct ncplane* ncp;
|
|
|
|
if(!setlocale(LC_ALL, "")){
|
|
|
|
fprintf(stderr, "Couldn't set locale based on user preferences\n");
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
const char* demos;
|
|
|
|
if((demos = handle_opts(argc, argv, &nopts)) == NULL){
|
|
|
|
if(argv[optind] != NULL){
|
|
|
|
usage(*argv, EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
demos = "isumbgw";
|
|
|
|
}
|
|
|
|
if((nc = notcurses_init(&nopts)) == NULL){
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
if((ncp = notcurses_stdplane(nc)) == NULL){
|
|
|
|
fprintf(stderr, "Couldn't get standard plane\n");
|
2019-11-23 17:28:42 +00:00
|
|
|
goto err;
|
|
|
|
}
|
2019-11-29 10:24:48 +00:00
|
|
|
// no one cares about the leaderscreen. 1s max.
|
|
|
|
if(demodelay.tv_sec >= 1){
|
|
|
|
sleep(1);
|
|
|
|
}else{
|
|
|
|
nanosleep(&demodelay, NULL);
|
|
|
|
}
|
2019-11-29 03:08:26 +00:00
|
|
|
if(ext_demos(nc, demos)){
|
2019-11-24 17:36:46 +00:00
|
|
|
goto err;
|
2019-11-24 19:09:53 +00:00
|
|
|
}
|
2019-11-17 15:25:40 +00:00
|
|
|
if(notcurses_stop(nc)){
|
2019-11-17 14:53:59 +00:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
2019-11-17 10:04:41 +00:00
|
|
|
return EXIT_SUCCESS;
|
2019-11-19 11:44:28 +00:00
|
|
|
|
|
|
|
err:
|
|
|
|
notcurses_stop(nc);
|
|
|
|
return EXIT_FAILURE;
|
2019-11-17 10:04:41 +00:00
|
|
|
}
|