ULTRAMEGAOK: mouse-moveable HUD #162

This commit is contained in:
nick black 2019-12-24 23:13:43 -05:00 committed by Nick Black
parent 6ffbe195cc
commit 7f82ac6f16
17 changed files with 203 additions and 36 deletions

View File

@ -82,7 +82,7 @@ int box_demo(struct notcurses* nc){
++y;
++x;
}
if(notcurses_render(nc)){
if(demo_render(nc)){
return -1;
}
nanosleep(&iterdelay, NULL);

View File

@ -15,6 +15,8 @@
static const int MIN_SUPPORTED_ROWS = 24;
static const int MIN_SUPPORTED_COLS = 80;
static int democount;
static demoresult* results;
static atomic_bool interrupted = ATOMIC_VAR_INIT(false);
static const char DEFAULT_DEMO[] = "ixemlubgswvpo";
@ -24,6 +26,13 @@ void interrupt_demo(void){
atomic_store(&interrupted, true);
}
const demoresult* demoresult_lookup(int idx){
if(idx < 0 || idx >= democount){
return NULL;
}
return &results[idx];
}
char* find_data(const char* datum){
char* path = malloc(strlen(datadir) + 1 + strlen(datum) + 1);
strcpy(path, datadir);
@ -171,7 +180,7 @@ intro(struct notcurses* nc){
}
ncplane_styles_off(ncp, CELL_STYLE_BLINK); // heh FIXME replace with pulse
}
if(notcurses_render(nc)){
if(demo_render(nc)){
return -1;
}
nanosleep(&demodelay, NULL);
@ -180,21 +189,15 @@ intro(struct notcurses* nc){
return 0;
}
typedef struct demoresult {
char selector;
struct ncstats stats;
uint64_t timens;
bool failed;
} demoresult;
static demoresult*
ext_demos(struct notcurses* nc, const char* demos){
int ret = 0;
demoresult* results = malloc(sizeof(*results) * strlen(demos));
results = malloc(sizeof(*results) * strlen(demos));
if(results == NULL){
return NULL;
}
memset(results, 0, sizeof(*results) * strlen(demos));
democount = strlen(demos);
struct timespec start, now;
clock_gettime(CLOCK_MONOTONIC, &start);
uint64_t prevns = timespec_to_ns(&start);
@ -311,6 +314,9 @@ int main(int argc, char** argv){
if(notcurses_mouse_enable(nc)){
goto err;
}
if(hud_create(nc) == NULL){
goto err;
}
if(input_dispatcher(nc)){
goto err;
}
@ -325,7 +331,9 @@ int main(int argc, char** argv){
}else{
nanosleep(&demodelay, NULL);
}
demoresult* results = ext_demos(nc, demos);
if(ext_demos(nc, demos)){
goto err;
}
if(results == NULL){
goto err;
}

View File

@ -57,6 +57,7 @@ demo_getc_blocking(ncinput* ni){
}
/*----------------------------- end demo input API -------------------------*/
/*-------------------------------time helpers----------------------------*/
int timespec_subtract(struct timespec *result, const struct timespec *time1,
struct timespec *time0);
@ -98,6 +99,39 @@ timespec_mul(const struct timespec* ts, unsigned multiplier, struct timespec* pr
product->tv_nsec = ns % GIG;
product->tv_sec = ns / GIG;
}
/*-------------------------------time helpers----------------------------*/
/*----------------------------------HUD----------------------------------*/
extern struct ncplane* hud;
struct ncplane* hud_create(struct notcurses* nc);
int hud_destroy(struct ncplane* hud);
// let the HUD know about an upcoming demo
int hud_schedule(const char* demoname);
// demos should not call notcurses_render() themselves, but instead call
// demo_render(), which will ensure the HUD stays on the top of the z-stack.
int demo_render(struct notcurses* nc);
// grab the hud with the mouse
int hud_grab(int y, int x);
// release the hud
int hud_release(void);
typedef struct demoresult {
char selector;
struct ncstats stats;
uint64_t timens;
bool failed;
} demoresult;
// let the HUD know that a demo has completed, reporting the stats
int hud_completion_notify(int idx, const demoresult* result);
// HUD retrieves results on demand from core
const demoresult* demoresult_lookup(int idx);
/*----------------------------------HUD----------------------------------*/
#ifdef __cplusplus
}

View File

@ -38,7 +38,7 @@ outzoomed_map(struct notcurses* nc, const char* map){
if(ncvisual_render(ncv, 0, 0, 0, 0)){
return NULL;
}
if(notcurses_render(nc)){
if(demo_render(nc)){
return NULL;
}
return ncv;
@ -100,7 +100,7 @@ zoom_map(struct notcurses* nc, const char* map){
ncplane_destroy(zncp);
return NULL;
}
if(notcurses_render(nc)){
if(demo_render(nc)){
ncvisual_destroy(zncv);
ncplane_destroy(zncp);
return NULL;
@ -173,7 +173,7 @@ eagles(struct notcurses* nc){
int eaglesmoved;
do{
eaglesmoved = 0;
notcurses_render(nc);
demo_render(nc);
for(size_t i = 0 ; i < sizeof(e) / sizeof(*e) ; ++i){
if(e[i].xoff >= truex){
continue;

View File

@ -174,7 +174,7 @@ gridswitch_demo(struct notcurses* nc, struct ncplane *n){
ncplane_putc(n, &lr);
// render!
notcurses_render(nc);
demo_render(nc);
release_cells(n, &ul, &uc, &ur, &cl, &cc, &cr, &ll, &lc, &lr);
nanosleep(&demodelay, NULL);
return ret;
@ -245,7 +245,7 @@ gridinv_demo(struct notcurses* nc, struct ncplane *n){
ncplane_putc(n, &lr);
// render!
notcurses_render(nc);
demo_render(nc);
release_cells(n, &ul, &uc, &ur, &cl, &cc, &cr, &ll, &lc, &lr);
nanosleep(&demodelay, NULL);
return gridswitch_demo(nc, n);
@ -317,7 +317,7 @@ int grid_demo(struct notcurses* nc){
ncplane_putc(n, &lr);
// render!
notcurses_render(nc);
demo_render(nc);
release_cells(n, &ul, &uc, &ur, &cl, &cc, &cr, &ll, &lc, &lr);
nanosleep(&demodelay, NULL);
return gridinv_demo(nc, n);

105
src/demo/hud.c Normal file
View File

@ -0,0 +1,105 @@
#include "demo.h"
// we provide a heads-up display throughout the demo, detailing the demos we're
// about to run, running, and just runned. the user can move this HUD with
// their mouse. it should always be on the top of the z-stack.
struct ncplane* hud = NULL;
// while the HUD is grabbed by the mouse, these are set to the position where
// the grab started. they are reset once the HUD is released.
static int hud_grab_x = -1;
static int hud_grab_y = -1;
// position of the HUD *when grab started*
static int hud_pos_x;
static int hud_pos_y;
static const int hud_rows = 5;
static const int hud_cols = 54;
static int
hud_standard_bg(struct ncplane* n){
cell c = CELL_SIMPLE_INITIALIZER(' ');
cell_set_bg_rgb(&c, 0, 0x20, 0);
ncplane_set_default(n, &c);
cell_release(n, &c);
return 0;
}
static int
hud_grabbed_bg(struct ncplane* n){
cell c = CELL_SIMPLE_INITIALIZER(' ');
cell_set_bg_rgb(&c, 0x40, 0x90, 0x40);
ncplane_set_default(n, &c);
cell_release(n, &c);
return 0;
}
struct ncplane* hud_create(struct notcurses* nc){
int dimx, dimy;
notcurses_term_dim_yx(nc, &dimy, &dimx);
//int xoffset = (dimx - hud_cols) / 2;
int xoffset = dimx - hud_cols;
//int yoffset = (dimy - hud_rows);
int yoffset = 0;
struct ncplane* n = notcurses_newplane(nc, hud_rows, hud_cols, yoffset, xoffset, NULL);
if(n == NULL){
return NULL;
}
hud_standard_bg(n);
return (hud = n);
}
int hud_destroy(struct ncplane* h){
hud = NULL;
return ncplane_destroy(h);
}
// mouse has been pressed on the hud. the caller is responsible for rerendering.
int hud_grab(int y, int x){
int ret;
if(hud == NULL){
return -1;
}
// are we in the middle of a grab?
if(hud_grab_x >= 0 && hud_grab_y >= 0){
int delty = y - hud_grab_y;
int deltx = x - hud_grab_x;
ret = ncplane_move_yx(hud, hud_pos_y + delty, hud_pos_x + deltx);
}else{
// new grab. stash point of original grab, and location of HUD at original
// grab. any delta while grabbed (relative to the original grab point)
// will see the HUD moved by delta (relative to the original HUD location).
hud_grab_x = x;
hud_grab_y = y;
ncplane_yx(hud, &hud_pos_y, &hud_pos_x);
ret = hud_grabbed_bg(hud);
}
return ret;
}
int hud_release(void){
if(hud == NULL){
return -1;
}
hud_grab_x = -1;
hud_grab_y = -1;
return hud_standard_bg(hud);
}
int hud_completion_notify(int idx, const demoresult* result){
// FIXME
return 0;
}
// inform the HUD of an upcoming demo
int hud_schedule(const char* demoname){
// FIXME
return 0;
}
int demo_render(struct notcurses* nc){
if(hud){
ncplane_move_top(hud);
}
return notcurses_render(nc);
}

View File

@ -57,6 +57,23 @@ pass_along(const ncinput* ni){
return 0;
}
static int
handle_mouse(struct notcurses* nc, const ncinput* ni){
if(ni->id != NCKEY_BUTTON1 && ni->id != NCKEY_RELEASE){
return 0;
}
int ret;
if(ni->id == NCKEY_RELEASE){
ret = hud_release();
}else{
ret = hud_grab(ni->y, ni->x);
}
if(ret == 0){
ret = demo_render(nc);
}
return ret;
}
static void *
ultramegaok_demo(void* vnc){
ncinput ni;
@ -67,7 +84,7 @@ ultramegaok_demo(void* vnc){
continue;
}
if(nckey_mouse_p(ni.id)){
// FIXME
handle_mouse(nc, &ni);
}else{
if(ni.id == 'q'){
interrupt_demo();

View File

@ -191,7 +191,7 @@ int luigi_demo(struct notcurses* nc){
ncplane_move_top(lastseen);
}
ncplane_move_yx(lastseen, yoff, i);
notcurses_render(nc);
demo_render(nc);
nanosleep(&stepdelay, NULL);
}
for(i = 0 ; i < 3 ; ++i){

View File

@ -207,7 +207,7 @@ int maxcolor_demo(struct notcurses* nc){
++x;
}
}
if(notcurses_render(nc)){
if(demo_render(nc)){
return -1;
}
nanosleep(&demodelay, NULL);

View File

@ -10,7 +10,7 @@ static struct ncvisual* chncv;
static int
perframe(struct notcurses* nc, struct ncvisual* ncv __attribute__ ((unused))){
static int three = 3; // move up one every three callbacks
notcurses_render(nc);
demo_render(nc);
if(y < targy){
return 0;
}
@ -127,7 +127,7 @@ outro_message(struct notcurses* nc, int* rows, int* cols){
return NULL;
}
ncplane_styles_off(non, CELL_STYLE_ITALIC);
if(notcurses_render(nc)){
if(demo_render(nc)){
return NULL;
}
cell_release(non, &bgcell);

View File

@ -218,7 +218,7 @@ handle_input(struct notcurses* nc, struct panelreel* pr, int efd,
sigemptyset(&sset);
wchar_t key = -1;
int pret;
notcurses_render(nc);
demo_render(nc);
do{
struct timespec pollspec, cur;
clock_gettime(CLOCK_MONOTONIC, &cur);
@ -241,7 +241,7 @@ handle_input(struct notcurses* nc, struct panelreel* pr, int efd,
if(read(efd, &val, sizeof(val)) != sizeof(val)){
fprintf(stderr, "Error reading from eventfd %d (%s)\n", efd, strerror(errno)); }else if(key < 0){
panelreel_redraw(pr);
notcurses_render(nc);
demo_render(nc);
}
}
}
@ -381,7 +381,7 @@ int panelreel_demo(struct notcurses* nc){
return -1;
}
close(efd);
if(notcurses_render(nc)){
if(demo_render(nc)){
return -1;
}
return 0;

View File

@ -32,7 +32,7 @@ move_square(struct notcurses* nc, struct ncplane* chunk, int* holey, int* holex,
targy += deltay;
targx += deltax;
ncplane_move_yx(chunk, targy, targx);
if(notcurses_render(nc)){
if(demo_render(nc)){
return -1;
}
nanosleep(&movetime, NULL);
@ -199,7 +199,7 @@ int sliding_puzzle_demo(struct notcurses* nc){
if(draw_bounding_box(n, wastey, wastex, chunky, chunkx)){
return -1;
}
if(notcurses_render(nc)){
if(demo_render(nc)){
goto done;
}
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000000, };
@ -230,7 +230,7 @@ int sliding_puzzle_demo(struct notcurses* nc){
chunks[i0] = chunks[i1];
ncplane_move_yx(chunks[i0], targy0, targx0);
chunks[i1] = t;
if(notcurses_render(nc)){
if(demo_render(nc)){
goto done;
}
}

View File

@ -188,6 +188,9 @@ int unicodeblocks_demo(struct notcurses* nc){
if((nn = notcurses_newplane(nc, BLOCKSIZE / CHUNKSIZE + 2, (CHUNKSIZE * 2) + 2, 3, xstart, NULL)) == NULL){
return -1;
}
if(hud){
ncplane_move_below_unsafe(nn, hud);
}
if(draw_block(nn, blockstart)){
return -1;
}

View File

@ -12,7 +12,7 @@ watch_for_keystroke(struct notcurses* nc, struct ncvisual* ncv __attribute__ ((u
return 1;
}
}
return notcurses_render(nc);
return demo_render(nc);
}
static int
@ -113,7 +113,7 @@ int view_demo(struct notcurses* nc){
ncplane_destroy(dsplane);
return -1;
}
notcurses_render(nc);
demo_render(nc);
ncplane_move_bottom(dsplane);
nanosleep(&demodelay, NULL);
if(ncvisual_render(ncv, 0, 0, 0, 0)){
@ -124,10 +124,10 @@ int view_demo(struct notcurses* nc){
}
ncvisual_destroy(ncv);
ncvisual_destroy(ncv2);
notcurses_render(nc);
demo_render(nc);
nanosleep(&demodelay, NULL);
ncplane_move_top(dsplane);
notcurses_render(nc);
demo_render(nc);
ncplane_destroy(dsplane);
nanosleep(&demodelay, NULL);
struct ncplane* ncpl = legend(nc, dimy, dimx);

View File

@ -257,7 +257,7 @@ snake_thread(void* vnc){
return NULL;
}
}
if(notcurses_render(nc)){
if(demo_render(nc)){
return NULL;
}
for(int s = 0 ; s < snakecount ; ++s){
@ -653,7 +653,7 @@ int witherworm_demo(struct notcurses* nc){
bytes_out, egcs_out, cols_out)){
return -1;
}
if(notcurses_render(nc)){
if(demo_render(nc)){
return -1;
}
if(i){

View File

@ -84,7 +84,7 @@ perframecb(struct notcurses* nc, struct ncvisual* ncv __attribute__ ((unused))){
}while(xoff < dimx);
}
++frameno;
notcurses_render(nc);
demo_render(nc);
// FIXME we'll need some delay here
return 0;
}

View File

@ -22,7 +22,7 @@ int main(void){
r = 0;
g = 0x80;
b = 0;
ncplane_set_fg_rgb(n, 0x80, 0x80, 0x80);
ncplane_set_fg_rgb(n, 0x40, 0x20, 0x40);
for(y = 0 ; y < dimy ; ++y){
for(x = 0 ; x < dimx ; ++x){
if(ncplane_set_bg_rgb(n, r, g, b)){