mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-06 03:20:26 +00:00
ULTRAMEGAOK: mouse-moveable HUD #162
This commit is contained in:
parent
6ffbe195cc
commit
7f82ac6f16
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
105
src/demo/hud.c
Normal 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);
|
||||
}
|
@ -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();
|
||||
|
@ -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){
|
||||
|
@ -207,7 +207,7 @@ int maxcolor_demo(struct notcurses* nc){
|
||||
++x;
|
||||
}
|
||||
}
|
||||
if(notcurses_render(nc)){
|
||||
if(demo_render(nc)){
|
||||
return -1;
|
||||
}
|
||||
nanosleep(&demodelay, NULL);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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){
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)){
|
||||
|
Loading…
Reference in New Issue
Block a user