#include "locale/japanese.h"
#include "main/sound-definitions-table.h"
#include "main/sound-of-music.h"
+#include "system/angband-version.h"
#include "system/angband.h"
#include "system/player-type-definition.h"
#include "term/gameterm.h"
#include "term/term-color-types.h"
+#include "term/z-form.h"
#include "util/angband-files.h"
#include "view/display-map.h"
/**
* Simple rectangle type
*/
-struct rect_s {
+struct rect_t {
int x, y;
int cx, cy;
};
-typedef struct rect_s rect_t, *rect_ptr;
/* Trivial rectangle utility to make code a bit more readable */
static rect_t rect(int x, int y, int cx, int cy)
};
/* Max number of windows on screen */
-#define MAX_TERM_DATA 4
+#define MAX_TERM_DATA 8
/* Minimum main term size */
#define MIN_TERM0_LINES 24
/*
* Suspend/Resume
*/
-static errr Term_xtra_gcu_alive(int v)
+static errr game_term_xtra_gcu_alive(int v)
{
if (!v) {
/* Go to normal keymap mode */
keymap_game();
}
- return (0);
+ return 0;
}
/*
{
FILE *fff;
fff = fopen(s, "r");
- if (!fff)
+ if (!fff) {
return false;
+ }
fclose(fff);
return true;
static bool init_sound(void)
{
/* Initialize once */
- if (can_use_sound)
+ if (can_use_sound) {
return can_use_sound;
+ }
int i;
char wav[128];
path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_SOUND, wav);
/* Save the sound filename, if it exists */
- if (check_file(buf))
+ if (check_file(buf)) {
sound_file[i] = string_make(buf);
+ }
}
/* Sound available */
can_use_sound = true;
- return (can_use_sound);
+ return can_use_sound;
}
/*
* Init the "curses" system
*/
-static void Term_init_gcu(term_type *t)
+static void game_term_init_gcu(term_type *t)
{
term_data *td = (term_data *)(t->data);
/* Count init's, handle first */
- if (active++ != 0)
+ if (active++ != 0) {
return;
+ }
/* Erase the screen */
(void)wclear(td->win);
/*
* Nuke the "curses" system
*/
-static void Term_nuke_gcu(term_type *t)
+static void game_term_nuke_gcu(term_type *t)
{
term_data *td = (term_data *)(t->data);
delwin(td->win);
/* Count nuke's, handle last */
- if (--active != 0)
+ if (--active != 0) {
return;
+ }
/* Hack -- make sure the cursor is visible */
term_xtra(TERM_XTRA_SHAPE, 1);
static void term_string_push(char *buf)
{
int i, l = strlen(buf);
- for (i = l; i >= 0; i--)
+ for (i = l; i >= 0; i--) {
term_key_push(buf[i]);
+ }
}
#ifdef USE_GETCH
/*
* Process events, with optional wait
*/
-static errr Term_xtra_gcu_event(int v)
+static errr game_term_xtra_gcu_event(int v)
{
int i, k;
i = getch();
/* Broken input is special */
- if (i == ERR)
+ if (i == ERR) {
exit_game_panic(p_ptr);
- if (i == EOF)
+ }
+ if (i == EOF) {
exit_game_panic(p_ptr);
+ }
*bp++ = (char)i;
nodelay(stdscr, true);
while ((i = getch()) != EOF) {
- if (i == ERR)
+ if (i == ERR) {
exit_game_panic(p_ptr);
+ }
*bp++ = (char)i;
- if (bp == &buf[255])
+ if (bp == &buf[255]) {
break;
+ }
}
/* Wait for it next time */
char eucbuf[sizeof(buf)];
/* strlen + 1 を渡して文字列終端('\0')を含めて変換する */
if (utf8_to_euc(buf, strlen(buf) + 1, eucbuf, sizeof(eucbuf)) < 0) {
- return (-1);
+ return -1;
}
#endif
term_string_push(_(eucbuf, buf));
nodelay(stdscr, false);
/* None ready */
- if (i == ERR)
- return (1);
- if (i == EOF)
- return (1);
+ if (i == ERR) {
+ return 1;
+ }
+ if (i == EOF) {
+ return 1;
+ }
/* Enqueue the keypress */
term_key_push(i);
}
/* Success */
- return (0);
+ return 0;
}
#else /* USE_GETCH */
/*
* Process events (with optional wait)
*/
-static errr Term_xtra_gcu_event(int v)
+static errr game_term_xtra_gcu_event(int v)
{
int i, k;
i = read(0, bp++, 1);
/* Hack -- Handle bizarre "errors" */
- if ((i <= 0) && (errno != EINTR))
+ if ((i <= 0) && (errno != EINTR)) {
exit_game_panic(p_ptr);
+ }
/* Get the current flags for stdin */
k = fcntl(0, F_GETFL, 0);
/* Oops */
- if (k < 0)
- return (1);
+ if (k < 0) {
+ return 1;
+ }
/* Tell stdin not to block */
if (fcntl(0, F_SETFL, k | O_NDELAY) >= 0) {
}
/* Replace the flags for stdin */
- if (fcntl(0, F_SETFL, k))
- return (1);
+ if (fcntl(0, F_SETFL, k)) {
+ return 1;
+ }
}
bp[0] = '\0';
char eucbuf[sizeof(buf)];
/* strlen + 1 を渡して文字列終端('\0')を含めて変換する */
if (utf8_to_euc(buf, strlen(buf) + 1, eucbuf, sizeof(eucbuf)) < 0) {
- return (-1);
+ return -1;
}
#endif
term_string_push(_(eucbuf, buf));
k = fcntl(0, F_GETFL, 0);
/* Oops */
- if (k < 0)
- return (1);
+ if (k < 0) {
+ return 1;
+ }
/* Tell stdin not to block */
- if (fcntl(0, F_SETFL, k | O_NDELAY) < 0)
- return (1);
+ if (fcntl(0, F_SETFL, k | O_NDELAY) < 0) {
+ return 1;
+ }
/* Read one byte, if possible */
i = read(0, buf, 1);
/* Replace the flags for stdin */
- if (fcntl(0, F_SETFL, k))
- return (1);
+ if (fcntl(0, F_SETFL, k)) {
+ return 1;
+ }
/* Ignore "invalid" keys */
- if ((i != 1) || (!buf[0]))
- return (1);
+ if ((i != 1) || (!buf[0])) {
+ return 1;
+ }
/* Enqueue the keypress */
term_key_push(buf[0]);
}
/* Success */
- return (0);
+ return 0;
}
#endif /* USE_GETCH */
/*
* Hack -- make a sound
*/
-static errr Term_xtra_gcu_sound(int v)
+static errr game_term_xtra_gcu_sound(int v)
{
char buf[1024];
/* Sound disabled */
- if (!use_sound)
- return (1);
+ if (!use_sound) {
+ return 1;
+ }
/* Illegal sound */
- if ((v < 0) || (v >= SOUND_MAX))
- return (1);
+ if ((v < 0) || (v >= SOUND_MAX)) {
+ return 1;
+ }
/* Unknown sound */
- if (!sound_file[v])
- return (1);
+ if (!sound_file[v]) {
+ return 1;
+ }
sprintf(buf, "./gcusound.sh %s\n", sound_file[v]);
- return (system(buf) < 0);
+ return system(buf) < 0;
- return (0);
+ return 0;
}
static int scale_color(int i, int j, int scale)
int rgb = 16 + scale * scale * r + scale * g + b;
/* In the case of white and black we need to use the ANSI colors */
if (r == g && g == b) {
- if (b == 0)
+ if (b == 0) {
rgb = 0;
- if (b == scale)
+ }
+ if (b == scale) {
rgb = 15;
+ }
}
return rgb;
}
/*
* React to changes
*/
-static errr Term_xtra_gcu_react(void)
+static errr game_term_xtra_gcu_react(void)
{
#ifdef A_COLOR
- if (COLORS == 256 || COLORS == 88) {
- /* If we have more than 16 colors, find the best matches. These numbers
- * correspond to xterm/rxvt's builtin color numbers--they do not
- * correspond to curses' constants OR with curses' color pairs.
- *
- * XTerm has 216 (6*6*6) RGB colors, with each RGB setting 0-5.
- * RXVT has 64 (4*4*4) RGB colors, with each RGB setting 0-3.
- *
- * Both also have the basic 16 ANSI colors, plus some extra grayscale
- * colors which we do not use.
- */
- int scale = COLORS == 256 ? 6 : 4;
- for (int i = 0; i < 16; i++) {
- int fg = create_color(i, scale);
- init_pair(i + 1, fg, bg_color);
- colortable[i] = COLOR_PAIR(i + 1) | A_NORMAL;
+ if (!can_change_color()) {
+ if (COLORS == 256 || COLORS == 88) {
+ /* If we have more than 16 colors, find the best matches. These numbers
+ * correspond to xterm/rxvt's builtin color numbers--they do not
+ * correspond to curses' constants OR with curses' color pairs.
+ *
+ * XTerm has 216 (6*6*6) RGB colors, with each RGB setting 0-5.
+ * RXVT has 64 (4*4*4) RGB colors, with each RGB setting 0-3.
+ *
+ * Both also have the basic 16 ANSI colors, plus some extra grayscale
+ * colors which we do not use.
+ */
+ int scale = COLORS == 256 ? 6 : 4;
+ for (int i = 0; i < 16; i++) {
+ int fg = create_color(i, scale);
+ init_pair(i + 1, fg, bg_color);
+ colortable[i] = COLOR_PAIR(i + 1) | A_NORMAL;
+ }
+ }
+ } else {
+ for (int i = 0; i < 16; ++i) {
+ init_color(i,
+ (angband_color_table[i][1] * 1000) / 255,
+ (angband_color_table[i][2] * 1000) / 255,
+ (angband_color_table[i][3] * 1000) / 255);
}
}
#endif
/* Success */
- return (0);
+ return 0;
}
/*
* Handle a "special request"
*/
-static errr Term_xtra_gcu(int n, int v)
+static errr game_term_xtra_gcu(int n, int v)
{
- term_data *td = (term_data *)(Term->data);
+ term_data *td = (term_data *)(game_term->data);
/* Analyze the request */
switch (n) {
/* Clear screen */
case TERM_XTRA_CLEAR:
touchwin(td->win);
- (void)wclear(td->win);
- return (0);
+ (void)werase(td->win);
+ return 0;
/* Make a noise */
case TERM_XTRA_NOISE:
/* Make a special sound */
case TERM_XTRA_SOUND:
- return (Term_xtra_gcu_sound(v));
+ return game_term_xtra_gcu_sound(v);
/* Flush the Curses buffer */
case TERM_XTRA_FRESH:
(void)wrefresh(td->win);
- return (0);
+ return 0;
/* Change the cursor visibility */
case TERM_XTRA_SHAPE:
curs_set(v);
- return (0);
+ return 0;
/* Suspend/Resume curses */
case TERM_XTRA_ALIVE:
- return (Term_xtra_gcu_alive(v));
+ return game_term_xtra_gcu_alive(v);
/* Process events */
case TERM_XTRA_EVENT:
- return (Term_xtra_gcu_event(v));
+ return game_term_xtra_gcu_event(v);
/* Flush events */
case TERM_XTRA_FLUSH:
- while (!Term_xtra_gcu_event(false))
+ while (!game_term_xtra_gcu_event(false)) {
;
- return (0);
+ }
+ return 0;
/* Delay */
case TERM_XTRA_DELAY:
usleep(1000 * v);
- return (0);
+ return 0;
/* React to events */
case TERM_XTRA_REACT:
- Term_xtra_gcu_react();
- return (0);
+ game_term_xtra_gcu_react();
+ return 0;
}
/* Unknown */
- return (1);
+ return 1;
}
/*
* Actually MOVE the hardware cursor
*/
-static errr Term_curs_gcu(int x, int y)
+static errr game_term_curs_gcu(int x, int y)
{
- term_data *td = (term_data *)(Term->data);
+ term_data *td = (term_data *)(game_term->data);
/* Literally move the cursor */
wmove(td->win, y, x);
/* Success */
- return (0);
+ return 0;
}
/*
* Erase a grid of space
* Hack -- try to be "semi-efficient".
*/
-static errr Term_wipe_gcu(int x, int y, int n)
+static errr game_term_wipe_gcu(int x, int y, int n)
{
- term_data *td = (term_data *)(Term->data);
+ term_data *td = (term_data *)(game_term->data);
/* Place cursor */
wmove(td->win, y, x);
/* Clear to end of line */
- if (x + n >= 80) {
+ if (x + n >= td->t.wid) {
wclrtoeol(td->win);
}
/* Clear some characters */
else {
- while (n-- > 0)
+ while (n-- > 0) {
waddch(td->win, ' ');
+ }
}
/* Success */
- return (0);
+ return 0;
}
#ifdef USE_NCURSES_ACS
* think hard about how map_info() in cave.c should handle the color
* of something that we here draw in reverse. It's not so simple, alas.
*/
-static void Term_acs_text_gcu(int x, int y, int n, byte a, concptr s)
+static void game_term_acs_text_gcu(int x, int y, int n, byte a, concptr s)
{
- term_data *td = (term_data *)(Term->data);
+ term_data *td = (term_data *)(game_term->data);
int i;
/* position the cursor */
/*
* Place some text on the screen using an attribute
*/
-static errr Term_text_gcu(int x, int y, int n, byte a, concptr s)
+static errr game_term_text_gcu(int x, int y, int n, byte a, concptr s)
{
- term_data *td = (term_data *)(Term->data);
+ term_data *td = (term_data *)(game_term->data);
#ifdef USE_NCURSES_ACS
/* do we have colors + 16 ? */
/* then call special routine for drawing special characters */
if (a & 0x10) {
- Term_acs_text_gcu(x, y, n, a, s);
- return (0);
+ game_term_acs_text_gcu(x, y, n, a, s);
+ return 0;
}
#endif
#ifdef A_COLOR
/* Set the color */
- if (can_use_color)
+ if (can_use_color) {
wattrset(td->win, colortable[a & 0x0F]);
+ }
#endif
#ifdef JP
char text[1024];
int text_len = euc_to_utf8(s, n, text, sizeof(text));
if (text_len < 0) {
- return (-1);
+ return -1;
}
#endif
/* Add the text */
waddnstr(td->win, _(text, s), _(text_len, n));
/* Success */
- return (0);
+ return 0;
}
/**
term_type *t = &td->t;
/* Make sure the window has a positive size */
- if (rows <= 0 || cols <= 0)
- return (0);
+ if (rows <= 0 || cols <= 0) {
+ return 0;
+ }
/* Create a window */
td->win = newwin(rows, cols, y, x);
/* Make sure we succeed */
if (!td->win) {
plog("Failed to setup curses window.");
- return (-1);
+ return -1;
}
/* Initialize the term */
t->char_blank = ' ';
/* Set some hooks */
- t->init_hook = Term_init_gcu;
- t->nuke_hook = Term_nuke_gcu;
+ t->init_hook = game_term_init_gcu;
+ t->nuke_hook = game_term_nuke_gcu;
/* Set some more hooks */
- t->text_hook = Term_text_gcu;
- t->wipe_hook = Term_wipe_gcu;
- t->curs_hook = Term_curs_gcu;
- t->xtra_hook = Term_xtra_gcu;
+ t->text_hook = game_term_text_gcu;
+ t->wipe_hook = game_term_wipe_gcu;
+ t->curs_hook = game_term_curs_gcu;
+ t->xtra_hook = game_term_xtra_gcu;
/* Save the data */
t->data = td;
term_activate(t);
/* Success */
- return (0);
+ return 0;
}
/**
for (;;) {
if (!*stop || !isdigit(*stop)) {
- if (i >= max)
+ if (i >= max) {
break;
- if (*start == '*')
+ }
+ if (*start == '*') {
sizes[i] = 255;
- else {
+ } else {
/* rely on atoi("23,34,*") -> 23
otherwise, copy [start, stop) into a new buffer first.*/
sizes[i] = atoi(start);
}
i++;
- if (!*stop || *stop != ',')
+ if (!*stop || *stop != ',') {
break;
+ }
stop++;
start = stop;
- } else
+ } else {
stop++;
+ }
}
return i;
}
/* Extract the normal keymap */
keymap_norm_prepare();
- bool nobigscreen = FALSE;
+ bool nobigscreen = false;
/* Parse args */
for (i = 1; i < argc; i++) {
if (prefix(argv[i], "-o")) {
- nobigscreen = TRUE;
+ nobigscreen = true;
}
-
- plog_fmt("Ignoring option: %s", argv[i]);
}
/* Initialize for others systems */
- if (initscr() == (WINDOW *)ERR)
- return (-1);
+ if (initscr() == (WINDOW *)ERR) {
+ return -1;
+ }
/* Activate hooks */
quit_aux = hook_quit;
/* Hack -- Require large screen, or Quit with message */
i = ((LINES < 24) || (COLS < 80));
- if (i)
- quit("Angband needs an 80x24 'curses' screen");
+ if (i) {
+ quit_fmt("%s needs an 80x24 'curses' screen", std::string(VARIANT_NAME).data());
+ }
#ifdef A_COLOR
}
colortable[i] = COLOR_PAIR(i);
- Term_xtra_gcu_react();
+ game_term_xtra_gcu_react();
}
}
/* Attempt to use colors */
}
/* Skip non-existant windows */
- if (rows <= 0 || cols <= 0)
+ if (rows <= 0 || cols <= 0) {
continue;
+ }
/* Create a term */
term_data_init_gcu(&data[next_win], rows, cols, y, x);
EDIT: Added support for -left and -top.
*/
{
- rect_t remaining = rect(0, 0, COLS - 1, LINES - 1);
+ rect_t remaining = rect(0, 0, COLS, LINES);
int spacer_cx = 1;
int spacer_cy = 1;
int next_term = 1;
for (i = 1; i < argc; i++) {
if (streq(argv[i], "-spacer")) {
i++;
- if (i >= argc)
+ if (i >= argc) {
quit("Missing size specifier for -spacer");
+ }
sscanf(argv[i], "%dx%d", &spacer_cx, &spacer_cy);
} else if (streq(argv[i], "-right") || streq(argv[i], "-left")) {
const char *arg, *tmp;
int cx, cys[MAX_TERM_DATA] = { 0 }, ct, j, x, y;
i++;
- if (i >= argc)
+ if (i >= argc) {
quit(format("Missing size specifier for -%s", left ? "left" : "right"));
+ }
arg = argv[i];
tmp = strchr(arg, 'x');
- if (!tmp)
+ if (!tmp) {
quit(format("Expected something like -%s 60x27,* for two %s hand terminals of 60 columns, the first 27 lines and the second whatever is left.", left ? "left" : "right", left ? "left" : "right"));
+ }
cx = atoi(arg);
remaining.cx -= cx;
if (left) {
y = remaining.y;
}
remaining.cx -= spacer_cx;
- if (left)
+ if (left) {
remaining.x += spacer_cx;
+ }
tmp++;
ct = _parse_size_list(tmp, cys, MAX_TERM_DATA);
for (j = 0; j < ct; j++) {
int cy = cys[j];
- if (y + cy > remaining.y + remaining.cy)
+ if (y + cy > remaining.y + remaining.cy) {
cy = remaining.y + remaining.cy - y;
- if (next_term >= MAX_TERM_DATA)
+ }
+ if (next_term >= MAX_TERM_DATA) {
quit(format("Too many terminals. Only %d are allowed.", MAX_TERM_DATA));
+ }
if (cy <= 0) {
quit(format("Out of bounds in -%s: %d is too large (%d rows max for this strip)",
left ? "left" : "right", cys[j], remaining.cy));
int cy, cxs[MAX_TERM_DATA] = { 0 }, ct, j, x, y;
i++;
- if (i >= argc)
+ if (i >= argc) {
quit(format("Missing size specifier for -%s", top ? "top" : "bottom"));
+ }
arg = argv[i];
tmp = strchr(arg, 'x');
- if (!tmp)
+ if (!tmp) {
quit(format("Expected something like -%s *x7 for a single %s terminal of 7 lines using as many columns as are available.", top ? "top" : "bottom", top ? "top" : "bottom"));
+ }
tmp++;
cy = atoi(tmp);
ct = _parse_size_list(arg, cxs, MAX_TERM_DATA);
y = remaining.y + remaining.cy;
}
remaining.cy -= spacer_cy;
- if (top)
+ if (top) {
remaining.y += spacer_cy;
+ }
tmp++;
for (j = 0; j < ct; j++) {
int cx = cxs[j];
- if (x + cx > remaining.x + remaining.cx)
+ if (x + cx > remaining.x + remaining.cx) {
cx = remaining.x + remaining.cx - x;
- if (next_term >= MAX_TERM_DATA)
+ }
+ if (next_term >= MAX_TERM_DATA) {
quit(format("Too many terminals. Only %d are allowed.", MAX_TERM_DATA));
+ }
if (cx <= 0) {
quit(format("Out of bounds in -%s: %d is too large (%d cols max for this strip)",
top ? "top" : "bottom", cxs[j], remaining.cx));
}
/* Map Terminal */
- if (remaining.cx < MIN_TERM0_COLS || remaining.cy < MIN_TERM0_LINES)
- quit(format("Failed: angband needs an %dx%d map screen, not %dx%d", MIN_TERM0_COLS, MIN_TERM0_LINES, remaining.cx, remaining.cy));
+ if (remaining.cx < MIN_TERM0_COLS || remaining.cy < MIN_TERM0_LINES) {
+ quit_fmt("Failed: %s needs an %dx%d map screen, not %dx%d", std::string(VARIANT_NAME).data(), MIN_TERM0_COLS, MIN_TERM0_LINES, remaining.cx, remaining.cy);
+ }
data[0].r = remaining;
term_data_init(&data[0]);
- angband_term[0] = Term;
+ angband_term[0] = game_term;
/* Child Terminals */
for (next_term = 1; next_term < term_ct; next_term++) {
term_data_init(&data[next_term]);
- angband_term[next_term] = Term;
+ angband_term[next_term] = game_term;
}
}
term_screen = &data[0].t;
/* Success */
- return (0);
+ return 0;
}
#endif /* USE_GCU */