diff options
| author | Louis Burda <quent.burda@gmail.com> | 2023-07-26 17:59:43 +0200 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2023-07-26 17:59:43 +0200 |
| commit | ed666b4fd98ad168f735b814cf74e77ef5c52794 (patch) | |
| tree | 1a9e0f4920060f193d5add588503253a2635a19a /tis-curses.c | |
| parent | ce2b644f251d5b22dc2228a0ffc8479408c49c38 (diff) | |
| download | tis100-ed666b4fd98ad168f735b814cf74e77ef5c52794.tar.gz tis100-ed666b4fd98ad168f735b814cf74e77ef5c52794.zip | |
Fork tis256 to create version like game
Diffstat (limited to 'tis-curses.c')
| -rw-r--r-- | tis-curses.c | 565 |
1 files changed, 0 insertions, 565 deletions
diff --git a/tis-curses.c b/tis-curses.c deleted file mode 100644 index 157b102..0000000 --- a/tis-curses.c +++ /dev/null @@ -1,565 +0,0 @@ -#define NCURSES_WIDECHAR 1 - -#include "tpu.h" -#include "util.h" -#include "asm.h" - -#include <curses.h> -#include <sys/inotify.h> -#include <unistd.h> -#include <locale.h> -#include <errno.h> -#include <stdarg.h> -#include <string.h> -#include <stdio.h> -#include <stdbool.h> -#include <stdlib.h> - -#define KEY_ESC 0x1b -#define KEY_CTRL(c) ((c) & ~0x60) - -#define TPU_INPUT_ROWS 14 -#define TPU_INPUT_COLS 20 -#define TPU_INFO_W 6 -#define TPU_INFO_H 4 -#define TPU_CNT 6 -#define TPU_W (TPU_INPUT_COLS + 2 + 6) -#define TPU_H (TPU_INPUT_ROWS + 2) - -#define TIMEOUT 50 - -enum input_mode { - MAIN, - TPU_NAV -}; - -enum { - NONE, MIN, MAX, MID -}; - -enum { - COLOR_HEADING, - COLOR_VAL -}; - -static const char *mode_repr[] = { - "IDL", "RUN", "REA", "WRI" -}; - -static int scrx = 0; -static int scry = 0; -static int scrw = 80; -static int scrh = 40; - -static struct tis tis; -static FILE *tis_stdin = NULL; -static FILE *tis_stdout = NULL; - -static int show_reloaded = 0; - -static enum input_mode input_mode = MAIN; - -static struct tpu *tpu_sel = NULL; - -int (*cleanup)(void) = endwin; -const char *progname = "tis-curses"; - -static enum tpu_port_dir -key_to_dir(int key) -{ - switch (key) { - case KEY_LEFT: - return DIR_LEFT; - case KEY_RIGHT: - return DIR_RIGHT; - case KEY_UP: - return DIR_UP; - case KEY_DOWN: - return DIR_DOWN; - default: - abort(); - } -} - -static const cchar_t * -dir_to_arrow(enum tpu_port_dir dir) -{ - switch (dir) { - case DIR_UP: - return WACS_UARROW; - case DIR_DOWN: - return WACS_DARROW; - case DIR_LEFT: - return WACS_LARROW; - case DIR_RIGHT: - return WACS_RARROW; - } -} - -static int -tpu_pos_x(struct tpu *tpu) -{ - return 2 + (int) tpu->x * (TPU_W + 4); -} - -static int -tpu_pos_y(struct tpu *tpu) -{ - return 2 + (int) tpu->y * (TPU_H + 2); -} - -static void -tui_draw_box(int sx, int sy, int w, int h, attr_t attr, - const cchar_t *ul, const cchar_t *ur, - const cchar_t *ll, const cchar_t *lr) -{ - int x, y; - - if (sx + w < scrx || sx >= scrx + scrw) return; - if (sy + h < scry || sy >= scry + scrh) return; - - sx -= scrx; - sy -= scry; - - attron(attr); - mvadd_wch(sy, sx, ul); - mvadd_wch(sy, sx + w - 1, ur); - mvadd_wch(sy + h - 1, sx, ll); - mvadd_wch(sy + h - 1, sx + w - 1, lr); - for (x = sx + 1; x < sx + w - 1; x++) - mvadd_wch(sy, x, WACS_D_HLINE); - for (x = sx + 1; x < sx + w - 1; x++) - mvadd_wch(sy + h - 1, x, WACS_D_HLINE); - for (y = sy + 1; y < sy + h - 1; y++) - mvadd_wch(y, sx, WACS_D_VLINE); - for (y = sy + 1; y < sy + h - 1; y++) - mvadd_wch(y, sx + w - 1, WACS_D_VLINE); - attroff(attr); -} - -static void -__attribute__((format(printf, 4, 5))) -tui_draw_text(int x, int y, attr_t attr, const char *fmt, ...) -{ - char buf[256]; - va_list ap; - int i; - - va_start(ap, fmt); - vsnprintf(buf, 256, fmt, ap); - va_end(ap); - - attron(attr); - for (i = 0; i < strlen(buf) && x + i < scrx + scrw; i++) - mvaddch(y - scry, x + i - scrx, (chtype) buf[i]); - attroff(attr); -} - -static void -tui_draw_wch(int x, int y, attr_t attr, const cchar_t *c) -{ - attron(attr); - mvadd_wch(y - scry, x - scrx, c); - attroff(attr); -} - -static void -tui_draw_tpu(struct tpu *tpu) -{ - char linebuf[TPU_INPUT_COLS + 1]; - struct tpu_port *port; - int sx, sy, x, y, w, h; - int off, start, inst; - size_t len; - attr_t attr; - int idle; - - attr = (tpu_sel == tpu && input_mode == TPU_NAV) ? A_BOLD : 0; - - sx = tpu_pos_x(tpu); - sy = tpu_pos_y(tpu); - tui_draw_box(sx, sy, TPU_W, TPU_H, attr, - WACS_D_ULCORNER, WACS_D_URCORNER, - WACS_D_LLCORNER, WACS_D_LRCORNER); - - if (tpu->inst_cnt > 0) { - start = MAX(0, MIN(tpu->pc - 4, (int) tpu->inst_cnt - TPU_INPUT_ROWS)); - inst = start; - for (off = 0; off < TPU_INPUT_ROWS && inst < tpu->inst_cnt; ) { - if (tpu->label_map.labels[inst]) { - len = strlen(tpu->label_map.labels[inst]); - if (len > TPU_INPUT_COLS - 1) { - tui_draw_text(sx + 2, sy + 1 + off, A_DIM, - "%.*s..:", TPU_INPUT_COLS - 3, - tpu->label_map.labels[inst]); - } else { - tui_draw_text(sx + 2, sy + 1 + off, A_DIM, - "%s:", tpu->label_map.labels[inst]); - } - off++; - } - asm_print_inst(linebuf, sizeof(linebuf), &tpu->insts[inst]); - tui_draw_text(sx + 2, sy + 1 + off, - inst == tpu->pc ? A_STANDOUT : 0, "%-*.*s", - TPU_INPUT_COLS, TPU_INPUT_COLS, linebuf); - inst++; off++; - } - } - - x = sx + TPU_W - TPU_INFO_W; - y = sy; - w = TPU_INFO_W; - h = TPU_INFO_H; - tui_draw_box(x, y, w, h, attr, - WACS_D_TTEE, WACS_D_URCORNER, WACS_D_LTEE, WACS_D_RTEE); - tui_draw_text(x + 2, y + 1, A_BOLD, "ACC"); - tui_draw_text(x + 2, y + 2, 0, "%03i", tpu->acc); - - tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr, - WACS_D_LTEE, WACS_D_RTEE, WACS_D_LTEE, WACS_D_RTEE); - tui_draw_text(x + 2, y + 1, A_BOLD, "BAK"); - tui_draw_text(x + 2, y + 2, 0, "%03i", tpu->bak); - - tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr, - WACS_D_LTEE, WACS_D_RTEE, WACS_D_LTEE, WACS_D_RTEE); - tui_draw_text(x + 2, y + 1, A_BOLD, "LST"); - if (tpu->last < 0) { - tui_draw_text(x + 2, y + 2, 0, "N/A"); - } else { - tui_draw_wch(x + 2, y + 2, 0, - dir_to_arrow((enum tpu_port_dir) tpu->last)); - tui_draw_wch(x + 3, y + 2, 0, - dir_to_arrow((enum tpu_port_dir) tpu->last)); - tui_draw_wch(x + 4, y + 2, 0, - dir_to_arrow((enum tpu_port_dir) tpu->last)); - } - - tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr, - WACS_D_LTEE, WACS_D_RTEE, WACS_D_LTEE, WACS_D_RTEE); - tui_draw_text(x + 2, y + 1, A_BOLD, "MOD"); - tui_draw_text(x + 2, y + 2, 0, "%s", mode_repr[tpu->status]); - - tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr, - WACS_D_LTEE, WACS_D_RTEE, WACS_D_BTEE, WACS_D_LRCORNER); - tui_draw_text(x + 2, y + 1, A_BOLD, "IDL"); - if (tpu->steps > 0) - idle = (int) ((double) tpu->idle_steps * 100 / (double) tpu->steps); - else - idle = 100; - tui_draw_text(x + 2, y + 2, 0, "%03i", idle); - - if (tpu->ports[DIR_LEFT].attached) { - port = &tpu->ports[DIR_LEFT]; - if (port->in >= 0) - tui_draw_text(sx - 3, sy + 6, - A_BOLD, "%03i", port->in); - if (port->type & PORT_IN) - tui_draw_wch(sx - 1, sy + 7, - port->in >= 0 ? A_BOLD : 0, WACS_RARROW); - if (port->type & PORT_OUT) - tui_draw_wch(sx - 1, sy + 8, - port->out >= 0 ? A_BOLD : 0, WACS_LARROW); - if (port->out >= 0) - tui_draw_text(sx - 3, sy + 10, - A_BOLD, "%03i", port->out); - } - - if (tpu->ports[DIR_RIGHT].attached) { - port = &tpu->ports[DIR_RIGHT]; - if (port->out >= 0) - tui_draw_text(sx + TPU_W + 1, sy + 5, - A_BOLD, "%03i", port->out); - if (port->type & PORT_OUT) - tui_draw_wch(sx + TPU_W + 1, sy + 7, - port->out >= 0 ? A_BOLD : 0, WACS_RARROW); - if (port->type & PORT_IN) - tui_draw_wch(sx + TPU_W + 1, sy + 8, - port->in >= 0 ? A_BOLD : 0, WACS_LARROW); - if (port->in >= 0) - tui_draw_text(sx + TPU_W + 1, sy + 9, - A_BOLD, "%03i", port->in); - } - - if (tpu->ports[DIR_UP].attached) { - port = &tpu->ports[DIR_UP]; - if (port->out >= 0) - tui_draw_text(sx + 9, sy - 1, - A_BOLD, "%03i", port->out); - if (port->type & PORT_OUT) - tui_draw_wch(sx + 13, sy - 1, - port->out >= 0 ? A_BOLD : 0, WACS_UARROW); - if (port->type & PORT_IN) - tui_draw_wch(sx + 15, sy - 1, - port->in >= 0 ? A_BOLD : 0, WACS_DARROW); - if (port->in >= 0) - tui_draw_text(sx + 17, sy - 1, - A_BOLD, "%03i", port->in); - } - - if (tpu->ports[DIR_DOWN].attached) { - port = &tpu->ports[DIR_DOWN]; - if (port->in >= 0) - tui_draw_text(sx + 9, sy + TPU_H, - A_BOLD, "%03i", port->in); - if (port->type & PORT_IN) - tui_draw_wch(sx + 13, sy + TPU_H, - port->in >= 0 ? A_BOLD : 0, WACS_UARROW); - if (port->type & PORT_OUT) - tui_draw_wch(sx + 15, sy + TPU_H, - port->out >= 0 ? A_BOLD : 0, WACS_DARROW); - if (port->out >= 0) - tui_draw_text(sx + 17, sy + TPU_H, - A_BOLD, "%03i", port->out); - } -} - -static void -tui_draw(void) -{ - struct tpu_map_link *link; - size_t i; - int tx; - - clear(); - for (i = 0; i < TPU_MAP_BUCKETS; i++) { - for (link = tis.tpu_map.buckets[i]; link; link = link->next) - tui_draw_tpu(link->tpu); - } - if (show_reloaded > 0) { - tx = MAX(0, scrx + scrw / 2 - 4); - tui_draw_text(scrx, scry, A_STANDOUT, "%-*s", scrw, ""); - tui_draw_text(tx, scry, A_STANDOUT, "RELOADED"); - show_reloaded--; - } - refresh(); -} - -static void -tui_resize(void) -{ - scrw = getmaxx(stdscr); - scrh = getmaxy(stdscr); -} - -static void -tui_seek(struct tpu *tpu, int dx, int dy) -{ - struct tpu_map_link *link; - int minx, miny, maxx, maxy; - int x, y; - size_t i; - - if (tpu) { - minx = maxx = tpu_pos_x(tpu); - miny = maxy = tpu_pos_y(tpu); - } else { - minx = miny = maxx = maxy = -1; - for (i = 0; i < TPU_MAP_BUCKETS; i++) { - link = tis.tpu_map.buckets[i]; - for (; link; link = link->next) { - if (tpu && tpu != link->tpu) - continue; - x = tpu_pos_x(link->tpu); - if (minx == -1 || x < minx) minx = x; - if (maxx == -1 || x > maxx) maxx = x; - y = tpu_pos_y(link->tpu); - if (miny == -1 || y < miny) miny = y; - if (maxy == -1 || y > maxy) maxy = y; - } - } - if (minx == -1 || miny == -1) return; - } - - if (dx == MIN) scrx = minx - 2; - else if (dx == MAX) scrx = maxx + TPU_W + 2 - scrw; - else if (dx == MID) scrx = (minx + maxx + TPU_W - scrw) / 2; - - if (dy == MIN) scry = miny - 2; - else if (dy == MAX) scry = maxy + TPU_H + 2 - scrh; - else if (dy == MID) scry = (miny + maxy + TPU_H - scrh) / 2; -} - -static void -handlekey(int key) -{ - enum tpu_port_dir dir; - int c; - - if (input_mode == MAIN) { - switch (key) { - case 'I': - input_mode = TPU_NAV; - break; - case KEY_UP: - scry -= 2; - break; - case KEY_DOWN: - scry += 2; - break; - case KEY_LEFT: - scrx -= 4; - break; - case KEY_RIGHT: - scrx += 4; - break; - case 's': - if (tis_stdin && tis.stdin_port.attached - && tis.stdin_port.out < 0) { - c = getc(tis_stdin); - if (c >= 0) tis.stdin_port.out = c; - } - - if (tis.stdout_port.attached && tis.stdout_port.in >= 0) { - if (tis_stdout) - putc(tis.stdout_port.in, tis_stdout); - tis.stdout_port.in = -1; - } - - tis_step(&tis); - break; - } - } else { - switch (key) { - case KEY_ESC: - input_mode = MAIN; - break; - case KEY_UP: - case KEY_DOWN: - case KEY_LEFT: - case KEY_RIGHT: - dir = key_to_dir(key); - if (tpu_sel && tpu_sel->ports[dir].dst_tpu) - tpu_sel = tpu_sel->ports[dir].dst_tpu; - tui_seek(tpu_sel, MID, MID); - break; - } - } -} - -static struct tpu * -first_tpu(void) -{ - size_t i; - - for (i = 0; i < TPU_MAP_BUCKETS; i++) { - if (tis.tpu_map.buckets[i]) - return tis.tpu_map.buckets[i]->tpu; - } - - return NULL; -} - -static void -reset(int ifd, int argc, char **argv, bool watch) -{ - tis_load(&tis, argv[1]); - - if (watch) - if (inotify_add_watch(ifd, argv[1], IN_MODIFY) < 0) - die("inotify_add_watch '%s':", argv[1]); - - if (argc >= 3) { - if (tis_stdin) fclose(tis_stdin); - tis_stdin = fopen(argv[2], "r"); - if (!tis_stdin) die("fopen '%s':", argv[2]); - } - - if (argc >= 4) { - if (tis_stdout) fclose(tis_stdout); - tis_stdout = fopen(argv[3], "w+"); - if (!tis_stdout) die("fopen '%s':", argv[3]); - } - - if (tis.stdin_port.attached) { - tpu_sel = tis.stdin_port.dst_tpu; - } else { - tpu_sel = first_tpu(); - } - tui_seek(NULL, MID, MID); - -} - -int -main(int argc, char **argv) -{ - struct inotify_event event; - ssize_t len; - bool quit; - int key; - int ifd; - - if (argc < 2 || argc > 4) { - fprintf(stderr, "Usage: tis-curses FILE [STDIN] [STDOUT]\n"); - exit(1); - } - - setlocale(LC_ALL, ""); - - initscr(); - - raw(); - noecho(); - keypad(stdscr, TRUE); - start_color(); - curs_set(0); - tui_resize(); - timeout(TIMEOUT); - ESCDELAY = 0; - - tis_init(&tis); - - ifd = inotify_init1(IN_NONBLOCK); - - reset(ifd, argc, argv, true); - - quit = false; - while (!quit) { - len = read(ifd, &event, sizeof(event)); - if (len < 0 && errno != EAGAIN) - die("inotify_read:"); - if (len >= 0) { - reset(ifd, argc, argv, true); - show_reloaded = 1000 / TIMEOUT; - } - - tui_draw(); - key = getch(); - switch (key) { - case KEY_RESIZE: - tui_resize(); - break; - case 'g': - tui_seek(tpu_sel, MID, MID); - break; - case 'h': - tui_seek(NULL, MID, MID); - break; - case 'i': - if (tis.stdin_port.attached) - tui_seek(tis.stdin_port.dst_tpu, MID, MID); - break; - case 'o': - if (tis.stdout_port.attached) - tui_seek(tis.stdout_port.dst_tpu, MID, MID); - break; - case 'r': - reset(ifd, argc, argv, false); - break; - case KEY_CTRL('c'): - quit = true; - break; - default: - handlekey(key); - break; - } - } - - tis_deinit(&tis); - - close(ifd); - - if (tis_stdin) fclose(tis_stdin); - if (tis_stdout) fclose(tis_stdout); - - endwin(); -} |
