Skip to content

Instantly share code, notes, and snippets.

@takkaria
Created July 1, 2017 20:39
Show Gist options
  • Save takkaria/bc2a975ceddf27199672129b066f8f24 to your computer and use it in GitHub Desktop.
Save takkaria/bc2a975ceddf27199672129b066f8f24 to your computer and use it in GitHub Desktop.
#include <fcntl.h>
#include "angband.h"
#include "buildid.h"
#include "cmds.h"
#include "cave.h"
#include "ui-command.h"
#include "ui-display.h"
#include "ui-prefs.h"
#include "main.h"
#ifdef USE_WEB
/*** Constants, structures etc. ***/
/**
* Information about a term
*/
struct webterm_data {
term t; /* The Angband term */
};
/*
* Max number of windows on screen
*/
#define MAX_TERMS 1
/*
* Information about our windows
*/
static struct webterm_data data[MAX_TERMS];
/*
* Help text for the commandline
*/
const char help_web[] = "JSON mode";
/*** The required bits of the Angband term implementation ***/
static void webterm_init(term *t)
{
printf("init %d %d '%s %s'\n", t->wid, t->hgt, VERSION_NAME, VERSION_STRING);
}
static void webterm_nuke(term *t)
{
printf("end\n");
}
static errr webterm_xtra_clear(int v)
{
printf("clear\n");
return 0;
}
static errr webterm_xtra_noise(int v)
{
printf("beep\n");
return 0;
}
static errr webterm_xtra_fresh(int v)
{
printf("xtra-fresh %d\n", v);
return 0;
}
static errr webterm_xtra_shape(int v)
{
printf("xtra-shape %d\n", v);
return 0;
}
static void process_keypress(const char *key)
{
size_t len = strlen(key);
/* Single characters are straightforward */
if (len == 1) {
Term_keypress(key[0], 0);
return;
}
if (key[0] == '[') {
/* We -1 to ignore the closing bracket */
keycode_t kc = keycode_find_code(key + 1, len - 2);
if (kc != 0) {
Term_keypress(kc, 0);
}
}
}
static errr webterm_xtra_event(int wait)
{
char input[256];
char keypress[256];
/* If we're not waiting, turn on non-blocking read */
if (!wait) {
fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
}
int n_chars = read(0, input, sizeof(input));
if (n_chars > 0) {
input[n_chars] = 0;
// printf("++ term-input: %s\n", input);
if (sscanf(input, "keypress %s\n", keypress) == 1) {
process_keypress(keypress);
}
}
/* Turn blocking back on */
if (!wait) {
fcntl(0, F_SETFL, fcntl(0, F_GETFL) & ~O_NONBLOCK);
}
return 0;
}
static errr webterm_xtra_flush(int v)
{
printf("flush %d\n", v);
return 0;
}
static errr webterm_xtra_delay(int v)
{
printf("xtra-delay %d\n", v);
return 0;
}
struct {
int key;
errr (*func)(int v);
} xtras[] = {
{ TERM_XTRA_CLEAR, webterm_xtra_clear },
{ TERM_XTRA_NOISE, webterm_xtra_noise },
{ TERM_XTRA_FRESH, webterm_xtra_fresh },
{ TERM_XTRA_SHAPE, webterm_xtra_shape },
{ TERM_XTRA_EVENT, webterm_xtra_event },
{ TERM_XTRA_FLUSH, webterm_xtra_flush },
{ TERM_XTRA_DELAY, webterm_xtra_delay },
{ 0, NULL },
};
static errr webterm_xtra(int n, int v)
{
int i;
for (i = 0; xtras[i].func; i++) {
if (xtras[i].key == n) {
return xtras[i].func(v);
}
}
// printf("xtra-unknown %d %d\n", n, v);
return 0;
}
/**
* Display the cursor at (x, y)
*/
static errr webterm_curs(int x, int y)
{
printf("curs %d %d\n", x, y);
return 0;
}
/**
* Erase n grids from (x,y)
*/
static errr webterm_wipe(int x, int y, int n)
{
printf("wipe %d %d %d\n", x, y, n);
return 0;
}
/**
* Render a maximum of 'n' characters of 's', at location (x, y), with attr 'a'
*/
static errr webterm_text(int x, int y, int n, int a, const wchar_t *s)
{
char str[256];
wcstombs(str, s, 256);
printf("text %d %d %d %d '%.*s'\n", x, y, n, a, n, str);
return 0;
}
/*** Other stuff that isn't part of the term implementation ***/
/**
* Create a window for the given "webterm_data" argument.
*/
static void webterm_data_init(struct webterm_data *td, int i, int rows, int cols)
{
term *t = &td->t;
/* Initialize the term */
term_init(t, cols, rows, 256);
/* Avoid bottom right corner */
t->icky_corner = false;
t->never_frosh = true;
t->soft_cursor = true;
/* Erase with "white space" */
t->attr_blank = COLOUR_WHITE;
t->char_blank = ' ';
/* Differentiate between BS/^h, Tab/^i, etc. */
t->complex_input = true;
/* Set some hooks */
t->init_hook = webterm_init;
t->nuke_hook = webterm_nuke;
t->text_hook = webterm_text;
t->wipe_hook = webterm_wipe;
t->curs_hook = webterm_curs;
t->xtra_hook = webterm_xtra;
/* Save the data */
t->data = td;
angband_term[i] = t;
/* Activate it */
Term_activate(t);
}
/**
* ...
*/
errr init_web(int argc, char **argv)
{
int term_count = 1;
/* Turn off buffering */
setvbuf(stdout, NULL, _IONBF, 0);
/* Inform the client of colour options */
for (int i = 0; i < BASIC_COLORS; i++) {
printf("color %d %d %d %d\n",
i,
angband_color_table[i][1],
angband_color_table[i][2],
angband_color_table[i][3]);
}
/* Now prepare the term(s) */
for (int i = 0; i < term_count; i++) {
webterm_data_init(&data[i], i, 24, 80);
}
/* Success */
return (0);
}
#endif /* USE_WEB */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment