Introduction
Introduction Statistics Contact Development Disclaimer Help
Add sacc hackathon. - brcon2024-hackathons - Bitreichcon 2024 Hackathons
git clone git://bitreich.org/brcon2024-hackathons git://enlrupgkhuxnvlhsf6lc3fz…
Log
Files
Refs
Tags
Submodules
---
commit 14f1a3a9baed42894753c5378cd2b3eb7ead1d4d
parent 82a5bb00c21621db20f28c368d204017c6d0ec82
Author: Christoph Lohmann <[email protected]>
Date: Fri, 2 Aug 2024 15:40:33 +0200
Add sacc hackathon.
Diffstat:
A sacc/README.md | 11 +++++++++++
A sacc/ui_rogue.c | 938 +++++++++++++++++++++++++++++…
A sacc/ui_rogue.tar.gz | 0
3 files changed, 949 insertions(+), 0 deletions(-)
---
diff --git a/sacc/README.md b/sacc/README.md
@@ -0,0 +1,11 @@
+# Sacc Hackathon
+
+## Rouge Interface
+
+pazz0 created this wonderful rouge ui for sacc(1).
+
+Let us optimize it for release!
+
+Make it part of mainline sacc?
+
+
diff --git a/sacc/ui_rogue.c b/sacc/ui_rogue.c
@@ -0,0 +1,938 @@
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <term.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "common.h"
+#include "config.h"
+
+#define C(c) #c
+#define S(c) C(c)
+
+/* ncurses doesn't define those in term.h, where they're used */
+#ifndef OK
+#define OK (0)
+#endif
+#ifndef ERR
+#define ERR (-1)
+#endif
+
+static struct termios tsave;
+static struct termios tsacc;
+static Item *curentry;
+static int termset = ERR;
+static char bufout[256];
+static char bufout2[256];
+
+void drawscreen(void);
+
+uint32_t
+fnv1a(int n,...)
+{
+ int i;
+ char *s;
+ va_list l;
+ uint32_t h;
+
+ h = 0x811c9dc5;
+
+ va_start(l, n);
+ for (i = 0; i < n; i++) {
+ for (s = va_arg(l, char*); *s; s++) {
+ h ^= *s;
+ h *= 0x01000193;
+ }
+ }
+ va_end(l);
+
+ return h;
+}
+
+uint32_t
+xorshift(uint32_t *s)
+{
+ *s ^= *s << 13;
+ *s ^= *s >> 17;
+ *s ^= *s << 5;
+ return *s;
+}
+
+struct cell {
+ char c;
+ size_t nitems;
+ Item **items;
+};
+
+#define MAPHEIGHT (25)
+#define MAPWIDTH (80)
+struct cell map[MAPHEIGHT][MAPWIDTH];
+
+struct room {
+ struct room *p;
+ void *d;
+ size_t x, y;
+ size_t w, h;
+};
+
+struct rect {
+ struct rect *next, *next2;
+ struct room *room;
+ size_t x1, y1;
+ size_t x2, y2;
+ size_t d;
+};
+
+struct rect *
+randomneighbor(struct rect *x, struct rect *rs, uint32_t *prng)
+{
+ struct rect *r, *result;
+ size_t n;
+
+ n = 0;
+ result = NULL;
+ for (r = rs; r; r = r->next) {
+ if (r->y2 < x->y1 || r->y1 > x->y2 || r->x2 < x->x1 || r->x1 >…
+ continue;
+ if ((r->y2 == x->y1 || r->y1 == x->y2) && (r->x2 == x->x1 || r…
+ continue;
+ n++;
+ if (xorshift(prng) / (1. + UINT32_MAX) < 1. / n)
+ result = r;
+ }
+
+ return result;
+}
+
+#define ROOM_HEIGHT_MIN 3
+#define ROOM_WIDTH_MIN 5
+#define ROOM_MARGIN_MIN 1
+#define CELL_HEIGHT_MIN (ROOM_HEIGHT_MIN + ROOM_MARGIN_MIN + 3)
+#define CELL_WIDTH_MIN (ROOM_WIDTH_MIN + ROOM_MARGIN_MIN + 3)
+size_t
+generaterooms_gnarf(uint32_t prng, struct room *rs, size_t l)
+{
+ struct rect *queuehead, *queuetail;
+ struct rect *r, *t;
+ struct rect *rects, *walk;
+ size_t w, h, i, j, rl, n;
+ int vertical;
+ struct room *room;
+
+ r = malloc(sizeof(*r));
+ r->x1 = r->y1 = ROOM_MARGIN_MIN;
+ r->x2 = MAPWIDTH;
+ r->y2 = MAPHEIGHT;
+ r->d = 0;
+
+ queuetail = r;
+ queuetail->next = NULL;
+ queuehead = r;
+
+ rects = NULL;
+ rl = 0;
+
+ while (queuehead) {
+ r = queuehead;
+ if (queuetail == queuehead)
+ queuetail = NULL;
+ queuehead = queuehead->next;
+
+ if (r->x2 - r->x1 >= CELL_WIDTH_MIN * 2 && r->y2 - r->y1 >= CE…
+ vertical = xorshift(&prng) & 1;
+ } else if (r->x2 - r->x1 >= CELL_WIDTH_MIN * 2) {
+ vertical = 0;
+ } else if (r->y2 - r->y1 >= CELL_HEIGHT_MIN * 2) {
+ vertical = 1;
+ } else {
+ r->next = rects;
+ rects = r;
+ rl++;
+ continue;
+ }
+
+ if (vertical) {
+ w = r->x2 - r->x1;
+ h = CELL_HEIGHT_MIN + xorshift(&prng) % (1 + r->y2 - r…
+ } else {
+ w = CELL_WIDTH_MIN + xorshift(&prng) % (1 + r->x2 - r-…
+ h = r->y2 - r->y1;
+ }
+
+ t = malloc(sizeof(*t));
+ t->x1 = r->x1;
+ t->y1 = r->y1;
+ t->x2 = r->x1 + w;
+ t->y2 = r->y1 + h;
+ t->d = r->d + 1;
+ t->next = NULL;
+ t->room = NULL;
+
+ if (!queuetail) {
+ queuehead = t;
+ queuetail = t;
+ } else {
+ queuetail->next = t;
+ queuetail = t;
+ }
+
+ t = malloc(sizeof(*t));
+ if (vertical) {
+ t->x1 = r->x1;
+ t->y1 = r->y1 + h;
+ } else {
+ t->x1 = r->x1 + w;
+ t->y1 = r->y1;
+ }
+ t->x2 = r->x2;
+ t->y2 = r->y2;
+ t->d = r->d + 1;
+ t->next = NULL;
+ t->room = NULL;
+
+ queuetail->next = t;
+ queuetail = t;
+
+ free(r);
+ }
+
+ if (l > rl)
+ l = rl;
+
+ for (r = rects; r; r = r->next) {
+ if (MAPHEIGHT / 2 >= r->y1 && MAPHEIGHT / 2 < r->y2 &&
+ MAPWIDTH / 2 >= r->x1 && MAPWIDTH / 2 < r->x2)
+ break;
+ }
+
+ i = 0;
+ rs[i].w = ROOM_WIDTH_MIN + xorshift(&prng) % (1 + r->x2 - r->x1 - ROOM…
+ rs[i].h = ROOM_HEIGHT_MIN + xorshift(&prng) % (1 + r->y2 - r->y1 - ROO…
+ rs[i].x = r->x1 + xorshift(&prng) % (1 + r->x2 - r->x1 - ROOM_MARGIN_M…
+ rs[i].y = r->y1 + xorshift(&prng) % (1 + r->y2 - r->y1 - ROOM_MARGIN_M…
+ rs[i].p = NULL;
+ r->room = &rs[i];
+
+ walk = r;
+ walk->next2 = NULL;
+
+ i++;
+ for (; i < l;) {
+ t = randomneighbor(r, rects, &prng);
+ if (!t || t->room) {
+ n = 0;
+ for (t = walk; t; t = t->next2) {
+ n++;
+ if (xorshift(&prng) / (1. + UINT32_MAX) < 1. /…
+ r = t;
+
+ }
+ continue;
+ }
+ rs[i].w = ROOM_WIDTH_MIN + xorshift(&prng) % (1 + t->x2 - t->x…
+ rs[i].h = ROOM_HEIGHT_MIN + xorshift(&prng) % (1 + t->y2 - t->…
+ rs[i].x = t->x1 + xorshift(&prng) % (1 + t->x2 - t->x1 - ROOM_…
+ rs[i].y = t->y1 + xorshift(&prng) % (1 + t->y2 - t->y1 - ROOM_…
+ rs[i].p = r->room;
+ t->room = &rs[i];
+ i++;
+ r = t;
+ r->next2 = walk;
+ walk = r;
+ }
+
+ for (r = rects; r;) {
+ t = r->next;
+ free(r);
+ r = t;
+ }
+
+ return l;
+}
+
+size_t
+distance(size_t x1, size_t y1, size_t x2, size_t y2)
+{
+ size_t d;
+
+ if (y1 < y2)
+ d = y2 - y1;
+ else
+ d = y1 - y2;
+ if (x1 < x2)
+ d += x2 - x1;
+ else
+ d += x1 - x2;
+
+ return d;
+}
+
+void
+nearestpoints(struct room *a, struct room *b, size_t *ax, size_t *ay, size_t *…
+{
+ if (a->y >= b->y && a->y < b->y + b->h) {
+ *ay = *by = a->y;
+ } else if (b->y >= a->y && b->y < a->y + a->h) {
+ *ay = *by = b->y;
+ } else if (a->y >= b->y) {
+ *ay = a->y;
+ *by = b->y + b->h - 1;
+ } else if (b->y >= a->y) {
+ *ay = a->y + a->h - 1;
+ *by = b->y;
+ }
+
+ if (a->x >= b->x && a->x < b->x + b->w) {
+ *ax = *bx = a->x;
+ } else if (b->x >= a->x && b->x < a->x + a->w) {
+ *ax = *bx = b->x;
+ } else if (a->x >= b->x) {
+ *ax = a->x;
+ *bx = b->x + b->w - 1;
+ } else if (b->x >= a->x) {
+ *ax = a->x + a->w - 1;
+ *bx = b->x;
+ }
+}
+
+void
+connectrooms(struct room *a, struct room *b)
+{
+ size_t i, j;
+ ssize_t ii;
+ size_t x1, y1;
+ size_t x2, y2;
+
+ nearestpoints(a, b, &x1, &y1, &x2, &y2);
+
+ if (y1 > y2) {
+ ii = -1;
+ } else if (y2 > y1) {
+ ii = 1;
+ } else {
+ ii = 0;
+ }
+
+/*
+printf("%lu\t%lu\t%d\n", y1, y2, ii);
+*/
+ for (i = y1; i != y2; i += ii)
+ map[i][x1].c = '.';
+
+ if (x1 > x2) {
+ ii = -1;
+ } else if (x2 > x1) {
+ ii = 1;
+ } else {
+ ii = 0;
+ }
+
+ for (i = x1; i != x2; i += ii)
+ map[y2][i].c = '.';
+}
+
+void
+rendermap(void)
+{
+ size_t i, j;
+
+ for (i = 0; i < MAPHEIGHT; i++) {
+ for (j = 0; j < MAPWIDTH; j++)
+ putchar(map[i][j].c);
+ putchar('\n');
+ }
+}
+
+size_t
+placeitems_hash(Item *item, size_t *assocs, size_t k)
+{
+ Dir *dir;
+ Item *citem;
+ size_t i;
+
+ dir = item->dat;
+ for (i = 0; i < dir->nitems; i++) {
+ citem = &dir->items[i];
+ /* TODO Somewhere else */
+ if (!citem->host || !citem->port || !citem->selector)
+ continue;
+ assocs[i] = fnv1a(6, item->host, item->port, item->selector, c…
+ }
+
+ return k;
+}
+
+#define POSITIONS_LENGTH 4
+enum {
+ Portal,
+ StaircaseDown,
+ Bookshelf,
+ Back
+};
+
+size_t px, py;
+
+void
+generatemap(Item *item, int new)
+{
+ Dir *dir;
+ Item *citem;
+ size_t i, j, k, l, ir;
+ size_t x, y;
+ ssize_t n, m;
+ size_t *cassocs;
+ struct room *rooms, *r;
+ struct {
+ unsigned char x, y;
+ } positions[POSITIONS_LENGTH];
+ uint32_t prng;
+ char buffer[3];
+
+ for (i = 0; i < MAPHEIGHT; i++) {
+ for (j = 0; j < MAPWIDTH; j++) {
+ map[i][j].c = '#';
+ free(map[i][j].items);
+ map[i][j].items = NULL;
+ map[i][j].nitems = 0;
+ }
+ }
+
+ dir = item->dat;
+ for (j = l = 0; j < dir->nitems; j++) {
+ if (dir->items[j].type == '0' ||
+ dir->items[j].type == '1')
+ l++;
+ }
+
+ k = 1 + l / 10;
+ rooms = calloc(k, sizeof(*rooms));
+ if (!rooms)
+ return;
+ k = generaterooms_gnarf(fnv1a(3, item->host, item->port, item->selecto…
+
+ cassocs = calloc(dir->nitems, sizeof(*cassocs));
+ if (!cassocs)
+ goto cleanup;
+
+ k = placeitems_hash(item, cassocs, k);
+
+ /* Insert rooms */
+ for (i = 0; i < k; i++) {
+ for (y = rooms[i].y; y < rooms[i].y + rooms[i].h; y++) {
+ for (x = rooms[i].x; x < rooms[i].x + rooms[i].w; x++)
+ map[y][x].c = '.';
+ }
+ }
+
+ /* Insert connections */
+ for (i = 0; i < k; i++) {
+ if (rooms[i].p)
+ connectrooms(&rooms[i], rooms[i].p);
+ }
+
+ /*
+ Insert items
+ The placement of items affects the initial placement of the pl…
+ */
+ ir = fnv1a(4, item->host, item->port, item->selector, "initial_room") …
+
+ for (i = 0; i < k; i++) {
+ snprintf(buffer, sizeof(buffer), "%d", i);
+ prng = fnv1a(4, item->host, item->port, item->selector, buffer…
+ for (j = 0, n = 0, m = rooms[i].h * rooms[i].w; j < m; j++) {
+ if ((m - j) * (xorshift(&prng) / (double)UINT32_MAX) <…
+ positions[n].x = rooms[i].x + j % rooms[i].w;
+ positions[n].y = rooms[i].y + j / rooms[i].w;
+ n++;
+ }
+ if (n == POSITIONS_LENGTH)
+ break;
+ }
+ for (j = 0; j < dir->nitems; j++) {
+ if (cassocs[j] != i)
+ continue;
+
+ citem = &dir->items[j];
+ switch (citem->type) {
+ case '0':
+ x = positions[Bookshelf].x;
+ y = positions[Bookshelf].y;
+ if (map[y][x].nitems)
+ map[y][x].c = 'E';
+ else
+ map[y][x].c = '?';
+ break;
+ case '1':
+ if (strcmp(citem->host, item->host) || strcmp(…
+ x = positions[Portal].x;
+ y = positions[Portal].y;
+ if (map[y][x].nitems)
+ map[y][x].c = 'O';
+ else
+ map[y][x].c = '0';
+ } else {
+ x = positions[StaircaseDown].x;
+ y = positions[StaircaseDown].y;
+ if (map[y][x].nitems)
+ map[y][x].c = 'L';
+ else
+ map[y][x].c = '>';
+ }
+ break;
+ default:
+ continue;
+ }
+ map[y][x].nitems++;
+ map[y][x].items = realloc(map[y][x].items, map[y][x].n…
+ map[y][x].items[map[y][x].nitems-1] = citem;
+
+ if (new && j == dir->curline && citem->raw) {
+ px = x;
+ py = y;
+ }
+ }
+
+ if (i == ir && item->entry != item) {
+ y = positions[Back].y;
+ x = positions[Back].x;
+ if (strcmp(item->entry->host, item->host) || strcmp(it…
+ map[y][x].c = '0';
+ else
+ map[y][x].c = '<';
+ map[y][x].nitems++;
+ map[y][x].items = realloc(map[y][x].items, map[y][x].n…
+ map[y][x].items[map[y][x].nitems-1] = item->entry;
+ }
+
+ if (i == ir && new && !dir->items[dir->curline].raw) {
+ px = positions[Back].x;
+ py = positions[Back].y;
+ }
+ }
+ free(cassocs);
+
+cleanup:
+ free(rooms);
+}
+
+void
+uisetup(void)
+{
+ tcgetattr(0, &tsave);
+ tsacc = tsave;
+ tsacc.c_lflag &= ~(ECHO|ICANON);
+ tsacc.c_cc[VMIN] = 1;
+ tsacc.c_cc[VTIME] = 0;
+ tcsetattr(0, TCSANOW, &tsacc);
+
+ if (termset != OK)
+ /* setupterm call exits on error */
+ termset = setupterm(NULL, 1, NULL);
+ putp(tparm(clear_screen, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ fflush(stdout);
+}
+
+void
+uicleanup(void)
+{
+ tcsetattr(0, TCSANOW, &tsave);
+
+ if (termset != OK)
+ return;
+
+ putp(tparm(clear_screen, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ fflush(stdout);
+}
+
+char *
+uiprompt(char *fmt, ...)
+{
+ va_list ap;
+ char *input = NULL;
+ size_t n;
+ ssize_t r;
+
+ putp(tparm(save_cursor, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ putp(tparm(cursor_address, lines-1, 0, 0, 0, 0, 0, 0, 0, 0));
+ putp(tparm(clr_eol, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ va_start(ap, fmt);
+ vsnprintf(bufout, sizeof(bufout), fmt, ap);
+ va_end(ap);
+
+ n = mbsprint(bufout, columns);
+
+ putp(tparm(clr_eol, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ putp(tparm(cursor_address, lines-1, n, 0, 0, 0, 0, 0, 0, 0));
+
+ tsacc.c_lflag |= (ECHO|ICANON);
+ tcsetattr(0, TCSANOW, &tsacc);
+ fflush(stdout);
+
+ n = 0;
+ r = getline(&input, &n, stdin);
+
+ tsacc.c_lflag &= ~(ECHO|ICANON);
+ tcsetattr(0, TCSANOW, &tsacc);
+ putp(tparm(restore_cursor, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ fflush(stdout);
+
+ if (r == -1) {
+ clearerr(stdin);
+ clear(&input);
+ } else if (input[r - 1] == '\n') {
+ input[--r] = '\0';
+ }
+
+ return input;
+}
+
+void
+displaybar(char *s) {
+ size_t n;
+
+ putp(tparm(save_cursor, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ putp(tparm(cursor_address, lines-2, 0, 0, 0, 0, 0, 0, 0, 0));
+ putp(tparm(enter_standout_mode, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ n = mbsprint(s, columns);
+ for (n = columns - n; n; n--)
+ putchar(' ');
+
+ putp(tparm(exit_standout_mode, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ putp(tparm(restore_cursor, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ fflush(stdout);
+}
+
+void
+vdisplayinfoline(char *fmt, va_list ap)
+{
+ putp(tparm(save_cursor, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ putp(tparm(cursor_address, lines-1, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ vsnprintf(bufout, sizeof(bufout), fmt, ap);
+
+ mbsprint(bufout, columns);
+
+ putp(tparm(clr_eol, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ putp(tparm(restore_cursor, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ fflush(stdout);
+}
+
+void
+uistatus(char *fmt, ...)
+{
+ va_list ap;
+ size_t n;
+
+ putp(tparm(save_cursor, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ putp(tparm(cursor_address, lines-1, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ va_start(ap, fmt);
+ n = vsnprintf(bufout, sizeof(bufout), fmt, ap);
+ va_end(ap);
+
+ if (n < sizeof(bufout)-1) {
+ snprintf(bufout+n, sizeof(bufout)-n,
+ " [Press a key to continue \xe2\x98\x83]");
+ }
+
+ mbsprint(bufout, columns);
+
+ putp(tparm(clr_eol, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ putp(tparm(restore_cursor, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ fflush(stdout);
+
+ getchar();
+}
+
+void
+displayinfoline(char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vdisplayinfoline(fmt, ap);
+ va_end(ap);
+}
+
+Item *
+showmenu(char *title, Item **item, size_t l)
+{
+ size_t i;
+
+ putp(tparm(clear_screen, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+
+ putp(tparm(enter_standout_mode, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ printf("%s\n", title);
+ putp(tparm(exit_standout_mode, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ for (i = 0; i < l; i++)
+ printf("%lu\t%s\n", i, item[i]->username);
+
+ if (!scanf("%lu", &i) || i >= l)
+ return NULL;
+ fflush(stdout);
+
+ return item[i];
+}
+
+Item *
+prompt(char *text, Item *item)
+{
+ displayinfoline(text, item->username);
+ getchar();
+ return item;
+}
+
+Item *
+interact(Item *item)
+{
+ Item *selection;
+
+ selection = NULL;
+
+ switch (map[py][px].c) {
+ case '?':
+ case '0':
+ case '>':
+ case '<':
+ selection = map[py][px].items[0];
+ break;
+ case 'E':
+ selection = showmenu("Bookshelf", map[py][px].items, map[py][p…
+ break;
+ case 'O':
+ selection = showmenu("Portal machine", map[py][px].items, map[…
+ break;
+ case 'L':
+ selection = showmenu("Elevator", map[py][px].items, map[py][px…
+ break;
+ }
+
+ drawscreen();
+
+ if (selection) {
+ switch (map[py][px].c) {
+ case '?':
+ case 'E':
+ displayinfoline("A loading bar?! In a book?!");
+ break;
+ case 'O':
+ case '0':
+ displayinfoline("You are getting transported through t…
+ break;
+ case 'L':
+ displayinfoline("You hear elevator music...");
+ break;
+ case '<':
+ case '>':
+ displayinfoline("Too many stairs...");
+ break;
+ }
+ }
+
+ return selection;
+}
+
+void
+describe(size_t x, size_t y, int verbose)
+{
+ switch (map[y][x].c) {
+ case 'E':
+ displayinfoline("A bookshelf.");
+ break;
+ case 'O':
+ displayinfoline("A portal machine.");
+ break;
+ case 'L':
+ displayinfoline("An elevator.");
+ break;
+ case '?':
+ case '>':
+ case '<':
+ case '0':
+ if (*map[y][x].items[0]->username) {
+ displayinfoline("'%s'.", map[y][x].items[0]->username);
+ } else {
+ itemuri(map[y][x].items[0], bufout2, sizeof(bufout2));
+ displayinfoline("'%s'.", bufout2);
+ }
+ break;
+ default:
+ if (verbose) {
+ switch (map[y][x].c) {
+ case '.':
+ displayinfoline("Floor.");
+ break;
+ case '#':
+ displayinfoline("Wall.");
+ break;
+ }
+ } else {
+ displayinfoline("");
+ }
+ break;
+ }
+}
+
+void
+move(ssize_t dx, ssize_t dy)
+{
+ size_t x, y;
+
+ /* allow wraparound of the world for the lulz, even if it's not happen…
+ y = (MAPHEIGHT + py + dy) % MAPHEIGHT;
+ x = (MAPWIDTH + px + dx) % MAPWIDTH;
+
+ if (map[y][x].c == '#')
+ return;
+
+ putp(tparm(cursor_address, py, px, 0, 0, 0, 0, 0, 0, 0 ));
+ putchar(map[py][px].c);
+
+ py = y;
+ px = x;
+ putp(tparm(cursor_address, py, px, 0, 0, 0, 0, 0, 0, 0 ));
+ putchar('@');
+ putp(tparm(cursor_address, py, px, 0, 0, 0, 0, 0, 0, 0 ));
+
+ describe(x, y, 0);
+ putp(tparm(cursor_address, py, px, 0, 0, 0, 0, 0, 0, 0 ));
+}
+
+void
+drawscreen(void)
+{
+ Dir *dir;
+
+ putp(tparm(clear_screen, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ rendermap();
+
+ if (curentry->entry != curentry && (dir = curentry->entry->dat)) {
+ displaybar(dir->items[dir->curline].username);
+ } else {
+ itemuri(curentry, bufout, sizeof(bufout));
+ displaybar(bufout);
+ }
+
+ move(0, 0);
+
+}
+
+void
+uidisplay(Item *entry)
+{
+ if (!entry || entry->type != '1')
+ return;
+
+ generatemap(entry, curentry != entry);
+
+ curentry = entry;
+ drawscreen();
+}
+
+void
+lookmode(void)
+{
+ size_t x, y;
+
+ x = px;
+ y = py;
+
+ for (;;) {
+ switch (getchar()) {
+ case 0x1B:
+ case 'q':
+ putp(tparm(cursor_address, py, px, 0, 0, 0, 0, 0, 0, 0…
+ return;
+ case 'h':
+ x = (MAPWIDTH + x - 1) % MAPWIDTH;
+ break;
+ case 'j':
+ y = (y + 1) % MAPHEIGHT;
+ break;
+ case 'k':
+ y = (MAPHEIGHT + y - 1) % MAPHEIGHT;
+ break;
+ case 'l':
+ x = (x + 1) % MAPWIDTH;
+ break;
+ }
+ putp(tparm(cursor_address, y, x, 0, 0, 0, 0, 0, 0, 0));
+ describe(x, y, 1);
+ }
+}
+
+Item *
+uiselectitem(Item *entry)
+{
+ Dir *dir;
+ Item *e;
+ size_t i;
+
+ if (!entry || !(dir = entry->dat))
+ return NULL;
+
+ for (;;) {
+ switch (getchar()) {
+ case 'h':
+ move(-1, 0);
+ break;
+ case 'j':
+ move(0, 1);
+ break;
+ case 'k':
+ move(0, -1);
+ break;
+ case 'l':
+ move(1, 0);
+ break;
+ case 'L':
+ lookmode();
+ break;
+ case ' ':
+ /* Portals, stairs, bookshelfs */
+ if (e = interact(entry)) {
+ if (e->type == '1') {
+ for (i = 0; i < dir->nitems; i++) {
+ if (e == &dir->items[i]) {
+ dir->curline = i;
+ break;
+ }
+ }
+ }
+ return e;
+ }
+ break;
+ case 'q':
+ return NULL;
+ }
+ }
+}
+
+void
+uisigwinch(int signal)
+{
+ Dir *dir;
+
+ if (termset == OK)
+ del_curterm(cur_term);
+ termset = setupterm(NULL, 1, NULL);
+
+ if (!curentry || !(dir = curentry->dat))
+ return;
+
+ uidisplay(curentry);
+}
diff --git a/sacc/ui_rogue.tar.gz b/sacc/ui_rogue.tar.gz
Binary files differ.
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.