-/* File: main-gcu.c */
+/* File: main-gcu.c */
/*
* Copyright (c) 1997 Ben Harrison, and others
* XXX XXX XXX Consider the use of "savetty()" and "resetty()".
*/
-#include "angband.h"
-
+#include "system/angband.h"
+#include "game-option/runtime-arguments.h"
+#include "game-option/special-options.h"
+#include "io/exit-panic.h"
+#include "io/files-util.h"
+#include "main/sound-definitions-table.h"
+#include "main/sound-of-music.h"
+#include "term/gameterm.h"
+#include "term/term-color-types.h"
+#include "util/angband-files.h"
+#include "view/display-map.h"
#ifdef USE_GCU
/*
* Include the proper "header" file
*/
-#ifdef USE_NCURSES
-# undef bool
-# include <ncurses.h>
-#else
-# include <curses.h>
-#endif
+#include <curses.h>
+#include <iconv.h>
typedef struct term_data term_data;
struct term_data
{
- term t;
+ term_type t;
WINDOW *win;
};
#define MAX_TERM_DATA 4
static term_data data[MAX_TERM_DATA];
-
+static iconv_t iconv_to_sys;
+static iconv_t iconv_to_gui;
/*
* Hack -- try to guess which systems use what commands
* Mega-Hack -- try to guess when "POSIX" is available.
* If the user defines two of these, we will probably crash.
*/
-#if !defined(USE_TPOSIX)
-# if !defined(USE_TERMIO) && !defined(USE_TCHARS)
-# if defined(_POSIX_VERSION)
-# define USE_TPOSIX
+#if !defined(USE_TCHARS)
+# if defined(_POSIX_VERSION)
+# define USE_TPOSIX
+# else
+# if defined(linux)
+# define USE_TERMIO
# else
-# if defined(USG) || defined(linux) || defined(SOLARIS)
-# define USE_TERMIO
-# else
-# define USE_TCHARS
-# endif
+# define USE_TCHARS
# endif
# endif
#endif
/*
- * Hack -- Amiga uses "fake curses" and cannot do any of this stuff
- */
-#if defined(AMIGA)
-# undef USE_TPOSIX
-# undef USE_TERMIO
-# undef USE_TCHARS
-#endif
-
-/*
* Try redefining the colors at startup.
*/
#define REDEFINE_COLORS
-
-
/*
* POSIX stuff
*/
# include <sys/types.h>
#endif
+#include <locale.h>
/*
* XXX XXX Hack -- POSIX uses "O_NONBLOCK" instead of "O_NDELAY"
# define O_NDELAY O_NONBLOCK
#endif
-
/*
* OPTION: some machines lack "cbreak()"
* On these machines, we use an older definition
*/
/* #define cbreak() crmode() */
-
/*
* OPTION: some machines cannot handle "nonl()" and "nl()"
* On these machines, we can simply ignore those commands.
/* #define nonl() */
/* #define nl() */
-
-#ifdef USE_SOUND
-
-static cptr ANGBAND_DIR_XTRA_SOUND;
+static concptr ANGBAND_DIR_XTRA_SOUND;
/*
+ * todo 有効活用されていない疑惑
* Flag set once "sound" has been initialized
*/
static bool can_use_sound = FALSE;
/*
* An array of sound file names
*/
-static cptr sound_file[SOUND_MAX];
-
-#endif /* USE_SOUND */
+static concptr sound_file[SOUND_MAX];
/*
* Save the "normal" and "angband" terminal settings
#endif
#ifdef USE_TCHARS
-
static struct ltchars norm_speciax_chars;
static struct sgttyb norm_ttyb;
static struct tchars norm_tchars;
static struct sgttyb game_ttyb;
static struct tchars game_tchars;
static int game_locax_chars;
-
#endif
-
-
/*
* Hack -- Number of initialized "term" structures
*/
static int active = 0;
-
-
#ifdef A_COLOR
-
/*
* Hack -- define "A_BRIGHT" to be "A_BOLD", because on many
* machines, "A_BRIGHT" produces ugly "inverse" video.
* Simple Angband to Curses color conversion table
*/
static int colortable[16];
-
#endif
-
-
/*
* Place the "keymap" into its "normal" state
*/
static void keymap_norm(void)
{
-
#ifdef USE_TPOSIX
-
/* restore the saved values of the special chars */
(void)tcsetattr(0, TCSAFLUSH, &norm_termios);
-
#endif
#ifdef USE_TERMIO
-
/* restore the saved values of the special chars */
(void)ioctl(0, TCSETA, (char *)&norm_termio);
-
#endif
#ifdef USE_TCHARS
-
/* restore the saved values of the special chars */
(void)ioctl(0, TIOCSLTC, (char *)&norm_speciax_chars);
(void)ioctl(0, TIOCSETP, (char *)&norm_ttyb);
(void)ioctl(0, TIOCSETC, (char *)&norm_tchars);
(void)ioctl(0, TIOCLSET, (char *)&norm_locax_chars);
-
#endif
-
}
*/
static void keymap_game(void)
{
-
#ifdef USE_TPOSIX
-
/* restore the saved values of the special chars */
(void)tcsetattr(0, TCSAFLUSH, &game_termios);
-
#endif
#ifdef USE_TERMIO
-
/* restore the saved values of the special chars */
(void)ioctl(0, TCSETA, (char *)&game_termio);
-
#endif
#ifdef USE_TCHARS
-
/* restore the saved values of the special chars */
(void)ioctl(0, TIOCSLTC, (char *)&game_speciax_chars);
(void)ioctl(0, TIOCSETP, (char *)&game_ttyb);
(void)ioctl(0, TIOCSETC, (char *)&game_tchars);
(void)ioctl(0, TIOCLSET, (char *)&game_locax_chars);
-
#endif
-
}
*/
static void keymap_norm_prepare(void)
{
-
#ifdef USE_TPOSIX
-
/* Get the normal keymap */
tcgetattr(0, &norm_termios);
-
#endif
#ifdef USE_TERMIO
-
/* Get the normal keymap */
(void)ioctl(0, TCGETA, (char *)&norm_termio);
-
#endif
#ifdef USE_TCHARS
-
/* Get the normal keymap */
(void)ioctl(0, TIOCGETP, (char *)&norm_ttyb);
(void)ioctl(0, TIOCGLTC, (char *)&norm_speciax_chars);
(void)ioctl(0, TIOCGETC, (char *)&norm_tchars);
(void)ioctl(0, TIOCLGET, (char *)&norm_locax_chars);
-
#endif
-
}
*/
static void keymap_game_prepare(void)
{
-
#ifdef USE_TPOSIX
-
/* Acquire the current mapping */
tcgetattr(0, &game_termios);
/* Normally, block until a character is read */
game_termios.c_cc[VMIN] = 1;
game_termios.c_cc[VTIME] = 0;
-
#endif
#ifdef USE_TERMIO
-
/* Acquire the current mapping */
(void)ioctl(0, TCGETA, (char *)&game_termio);
/* Force "Ctrl-Z" to suspend */
game_termio.c_cc[VSUSP] = (char)26;
- /* Hack -- Leave "VSTART/VSTOP" alone */
-
/* Disable the standard control characters */
game_termio.c_cc[VQUIT] = (char)-1;
game_termio.c_cc[VERASE] = (char)-1;
game_termio.c_cc[VEOF] = (char)-1;
game_termio.c_cc[VEOL] = (char)-1;
-#if 0
- /* Disable the non-posix control characters */
- game_termio.c_cc[VEOL2] = (char)-1;
- game_termio.c_cc[VSWTCH] = (char)-1;
- game_termio.c_cc[VDSUSP] = (char)-1;
- game_termio.c_cc[VREPRINT] = (char)-1;
- game_termio.c_cc[VDISCARD] = (char)-1;
- game_termio.c_cc[VWERASE] = (char)-1;
- game_termio.c_cc[VLNEXT] = (char)-1;
- game_termio.c_cc[VSTATUS] = (char)-1;
-#endif
-
/* Normally, block until a character is read */
game_termio.c_cc[VMIN] = 1;
game_termio.c_cc[VTIME] = 0;
-
#endif
#ifdef USE_TCHARS
-
/* Get the default game characters */
(void)ioctl(0, TIOCGETP, (char *)&game_ttyb);
(void)ioctl(0, TIOCGLTC, (char *)&game_speciax_chars);
game_tchars.t_quitc = (char)-1;
game_tchars.t_eofc = (char)-1;
game_tchars.t_brkc = (char)-1;
-
#endif
-
}
-
/*
* Suspend/Resume
*/
static errr Term_xtra_gcu_alive(int v)
{
- /* Suspend */
if (!v)
{
/* Go to normal keymap mode */
nl();
/* Hack -- make sure the cursor is visible */
- Term_xtra(TERM_XTRA_SHAPE, 1);
+ term_xtra(TERM_XTRA_SHAPE, 1);
/* Flush the curses buffer */
(void)refresh();
-#ifdef SPECIAL_BSD
- /* this moves curses to bottom right corner */
- mvcur(curscr->cury, curscr->curx, LINES - 1, 0);
-#else
/* this moves curses to bottom right corner */
- mvcur(curscr->_cury, curscr->_curx, LINES - 1, 0);
-#endif
+ mvcur(getcury(curscr), getcurx(curscr), LINES - 1, 0);
/* Exit curses */
endwin();
/* Flush the output */
(void)fflush(stdout);
}
-
- /* Resume */
else
{
- /* Refresh */
- /* (void)touchwin(curscr); */
- /* (void)wrefresh(curscr); */
-
/* Restore the settings */
cbreak();
noecho();
keymap_game();
}
- /* Success */
return (0);
}
+
/*
* Check for existance of a file
*/
-static bool check_file(cptr s)
+static bool check_file(concptr s)
{
FILE *fff;
-
fff = fopen(s, "r");
if (!fff) return (FALSE);
}
-
-#ifdef USE_SOUND
-
/*
* Initialize sound
*/
static bool init_sound(void)
{
/* Initialize once */
- if (!can_use_sound)
- {
- int i;
+ if (can_use_sound) return can_use_sound;
- char wav[128];
- char buf[1024];
+ int i;
+ char wav[128];
+ char buf[1024];
- /* Prepare the sounds */
- for (i = 1; i < SOUND_MAX; i++)
- {
- /* Extract name of sound file */
- sprintf(wav, "%s.wav", angband_sound_name[i]);
+ /* Prepare the sounds */
+ for (i = 1; i < SOUND_MAX; i++)
+ {
+ /* Extract name of sound file */
+ sprintf(wav, "%s.wav", angband_sound_name[i]);
- /* Access the sound */
- path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_SOUND, wav);
+ /* Access the sound */
+ path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_SOUND, wav);
- /* Save the sound filename, if it exists */
- if (check_file(buf)) sound_file[i] = string_make(buf);
- }
-
- /* Sound available */
- can_use_sound = TRUE;
- }
+ /* Save the sound filename, if it exists */
+ if (check_file(buf)) sound_file[i] = string_make(buf);
+ }
- /* Result */
- return (can_use_sound);
+ /* Sound available */
+ can_use_sound = TRUE;
+ return (can_use_sound);
}
-#endif /* USE_SOUND */
-
-
/*
* Init the "curses" system
*/
-static void Term_init_gcu(term *t)
+static void Term_init_gcu(term_type *t)
{
term_data *td = (term_data *)(t->data);
/*
* Nuke the "curses" system
*/
-static void Term_nuke_gcu(term *t)
+static void Term_nuke_gcu(term_type *t)
{
term_data *td = (term_data *)(t->data);
if (--active != 0) return;
/* Hack -- make sure the cursor is visible */
- Term_xtra(TERM_XTRA_SHAPE, 1);
+ term_xtra(TERM_XTRA_SHAPE, 1);
#ifdef A_COLOR
/* Reset colors to defaults */
start_color();
#endif
-#ifdef SPECIAL_BSD
/* This moves curses to bottom right corner */
- mvcur(curscr->cury, curscr->curx, LINES - 1, 0);
-#else
- /* This moves curses to bottom right corner */
- mvcur(curscr->_cury, curscr->_curx, LINES - 1, 0);
-#endif
+ mvcur(getcury(curscr), getcurx(curscr), LINES - 1, 0);
/* Flush the curses buffer */
(void)refresh();
keymap_norm();
}
+/*
+ * Convert to EUC-JP
+ */
+static void convert_to_sys(char *buf)
+{
+ size_t inlen = strlen(buf);
+ size_t outlen = inlen;
+ char tmp[outlen + 1];
+
+ char *inbuf = buf;
+ char *outbuf = tmp;
+ size_t res;
+ res = iconv(iconv_to_sys, 0, 0, 0, 0);
+ if(res == (size_t)-1) return;
+ res = iconv(iconv_to_sys, &inbuf, &inlen, &outbuf, &outlen);
+ if(res == (size_t)-1) return;
+ res = iconv(iconv_to_sys, 0, 0, &outbuf, &outlen);
+ if(res == (size_t)-1) return;
+
+ outbuf[0] = '\0';
+ strcpy(buf, tmp);
+}
+
+/*
+ * Push multiple keys reversal
+ */
+static void term_string_push(char *buf)
+{
+ int i, l = strlen(buf);
+ for (i = l; i >= 0; i--)
+ term_key_push(buf[i]);
+}
+
#ifdef USE_GETCH
/*
/* Wait */
if (v)
{
+ char buf[256];
+ char *bp = buf;
+
/* Paranoia -- Wait for it */
nodelay(stdscr, FALSE);
/* Get a keypress */
i = getch();
- /* Mega-Hack -- allow graceful "suspend" */
- for (k = 0; (k < 10) && (i == ERR); k++) i = getch();
-
/* Broken input is special */
- if (i == ERR) exit_game_panic();
- if (i == EOF) exit_game_panic();
+ if (i == ERR) exit_game_panic(p_ptr);
+ if (i == EOF) exit_game_panic(p_ptr);
+
+ *bp++ = (char)i;
+
+ /* Do not wait for it */
+ nodelay(stdscr, TRUE);
+
+ while((i = getch()) != EOF)
+ {
+ if (i == ERR) exit_game_panic(p_ptr);
+ *bp++ = (char)i;
+ if (bp == &buf[255]) break;
+ }
+
+ /* Wait for it next time */
+ nodelay(stdscr, FALSE);
+
+ *bp = '\0';
+ convert_to_sys(buf);
+ term_string_push(buf);
}
/* Do not wait */
/* None ready */
if (i == ERR) return (1);
if (i == EOF) return (1);
- }
- /* Enqueue the keypress */
- Term_keypress(i);
+ /* Enqueue the keypress */
+ term_key_push(i);
+ }
/* Success */
return (0);
{
int i, k;
- char buf[2];
+ char buf[256];
/* Wait */
if (v)
{
+ char *bp = buf;
+
/* Wait for one byte */
- i = read(0, buf, 1);
+ i = read(0, bp++, 1);
/* Hack -- Handle bizarre "errors" */
- if ((i <= 0) && (errno != EINTR)) exit_game_panic();
+ 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);
+
+ /* Tell stdin not to block */
+ if (fcntl(0, F_SETFL, k | O_NDELAY) >= 0)
+ {
+ if ((i = read(0, bp, 254)) > 0)
+ {
+ bp += i;
+ }
+
+ /* Replace the flags for stdin */
+ if (fcntl(0, F_SETFL, k)) return (1);
+ }
+
+ bp[0] = '\0';
+ convert_to_sys(buf);
+ term_string_push(buf);
}
/* Do not wait */
/* Replace the flags for stdin */
if (fcntl(0, F_SETFL, k)) return (1);
- }
- /* Ignore "invalid" keys */
- if ((i != 1) || (!buf[0])) return (1);
+ /* Ignore "invalid" keys */
+ if ((i != 1) || (!buf[0])) return (1);
- /* Enqueue the keypress */
- Term_keypress(buf[0]);
+ /* Enqueue the keypress */
+ term_key_push(buf[0]);
+ }
/* Success */
return (0);
#endif /* USE_GETCH */
-#ifdef USE_SOUND
-
/*
* Hack -- make a sound
*/
if (!sound_file[v]) return (1);
sprintf(buf,"./gcusound.sh %s\n", sound_file[v]);
- system(buf);
- return (0);
-
-#if 0
- char *argv[4];
- pid_t pid;
-
- /* Sound disabled */
- if (!use_sound) return (1);
-
- /* Illegal sound */
- if ((v < 0) || (v >= SOUND_MAX)) return (1);
+ return (system(buf) < 0);
- /* Unknown sound */
- if (!sound_file[v]) return (1);
-
- pid=fork();
-
- /* cannot fork? */
- if (pid==-1) return (1);
-
- if (pid==0)
- {
- char *argv[4];
- argv[0]="sh";
- argv[1]="-c";
- argv[2]="./gcusound.sh";
- strcpy(argv[3],sound_file[v]);
- execvp(argv[0], argv);
- exit(0);
- }
-#endif
return (0);
}
-#endif
+
/*
* React to changes
/* Make a noise */
case TERM_XTRA_NOISE:
- (void)write(1, "\007", 1);
- return (0);
+ return write(1, "\007", 1) != 1;
-#ifdef USE_SOUND
/* Make a special sound */
case TERM_XTRA_SOUND:
return (Term_xtra_gcu_sound(v));
-#endif
/* Flush the Curses buffer */
case TERM_XTRA_FRESH:
* 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, cptr s)
+static void Term_acs_text_gcu(int x, int y, int n, byte a, concptr s)
{
term_data *td = (term_data *)(Term->data);
int i;
/*
* Place some text on the screen using an attribute
*/
-static errr Term_text_gcu(int x, int y, int n, byte a, cptr s)
+static errr Term_text_gcu(int x, int y, int n, byte a, concptr s)
{
term_data *td = (term_data *)(Term->data);
- int i;
-
- char text[81];
+ char intext[n];
+ char text[80 * 3 + 1];
+ size_t inlen = n;
+ size_t outlen = sizeof(text);
+ char *inbuf = intext;
+ char *outbuf = text;
+ size_t res;
#ifdef USE_NCURSES_ACS
/* do we have colors + 16 ? */
}
#endif
+ /* Copy to char array because of iconv's warning by const char pointer */
+ memcpy(intext, s, (size_t)n);
+
/* Obtain a copy of the text */
- for (i = 0; i < n; i++) text[i] = s[i]; text[n] = 0;
+ res = iconv(iconv_to_gui, 0, 0, 0, 0);
+ if(res == (size_t)-1) return (-1);
+ res = iconv(iconv_to_gui, &inbuf, &inlen, &outbuf, &outlen);
+ if(res == (size_t)-1) return (-1);
+ res = iconv(iconv_to_gui, 0, 0, &outbuf, &outlen);
+ if(res == (size_t)-1) return (-1);
+
+ if(outlen == 0) return (-1);
+ *outbuf = '\0';
/* Move the cursor and dump the string */
wmove(td->win, y, x);
static errr term_data_init(term_data *td, int rows, int cols, int y, int x)
{
- term *t = &td->t;
+ term_type *t = &td->t;
/* Make sure the window has a positive size */
if (rows <= 0 || cols <= 0) return (0);
t->data = td;
/* Activate it */
- Term_activate(t);
+ term_activate(t);
/* Success */
}
-static void hook_quit(cptr str)
+static void hook_quit(concptr str)
{
- /* Exit curses */
- endwin();
+ /* Unused */
+ (void)str;
+
+ /* Exit curses */
+ endwin();
+
+ iconv_close(iconv_to_sys);
+ iconv_close(iconv_to_gui);
}
int num_term = 4, next_win = 0;
char path[1024];
-#ifdef USE_SOUND
+ /* Unused */
+ (void)argc;
+ (void)argv;
+
+
+ setlocale(LC_ALL, "");
+ iconv_to_sys = iconv_open("EUC-JP", "");
+ if(iconv_to_sys == (iconv_t)-1) return (-1);
+ iconv_to_gui = iconv_open("", "EUC-JP");
+ if(iconv_to_gui == (iconv_t)-1) return (-1);
/* Build the "sound" path */
path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "sound");
/* Allocate the path */
ANGBAND_DIR_XTRA_SOUND = string_make(path);
-#endif
-
/* Extract the normal keymap */
keymap_norm_prepare();
-#if defined(USG)
- /* Initialize for USG Unix */
- if (initscr() == NULL) return (-1);
-#else
/* Initialize for others systems */
if (initscr() == (WINDOW*)ERR) return (-1);
-#endif
/* Activate hooks */
quit_aux = hook_quit;
if (can_fix_color)
{
/* Prepare the color pairs */
- for (i = 1; i <= 63; i++)
- {
- /* Reset the color */
- if (init_pair(i, (i - 1) % 8, (i - 1) / 8) == ERR)
- {
- quit("Color pair init failed");
- }
-
- /* Set up the colormap */
- colortable[i - 1] = (COLOR_PAIR(i) | A_NORMAL);
- colortable[i + 7] = (COLOR_PAIR(i) | A_BRIGHT);
-
- /* XXX XXX XXX Take account of "gamma correction" */
-
- /* Prepare the "Angband Colors" */
- Term_xtra_gcu_react();
- }
+ for (i = 1; i <= 15; i++)
+ {
+ if (init_pair(i, i, 0) == ERR)
+ {
+ quit("Color pair init failed");
+ }
+
+ colortable[i] = COLOR_PAIR(i);
+ Term_xtra_gcu_react();
+ }
}
/* Attempt to use colors */
else if (can_use_color)
colortable[3] = (COLOR_PAIR(1) | A_BRIGHT); /* Orange XXX */
colortable[4] = (COLOR_PAIR(1) | A_NORMAL); /* Red */
colortable[5] = (COLOR_PAIR(2) | A_NORMAL); /* Green */
- colortable[6] = (COLOR_PAIR(4) | A_NORMAL); /* Blue */
+ colortable[6] = (COLOR_PAIR(4) | A_BRIGHT); /* Blue */
colortable[7] = (COLOR_PAIR(3) | A_NORMAL); /* Umber */
colortable[8] = (COLOR_PAIR(7) | A_BRIGHT); /* Dark-grey XXX */
colortable[9] = (COLOR_PAIR(0) | A_NORMAL); /* Light-grey XXX */
- colortable[10] = (COLOR_PAIR(5) | A_NORMAL); /* Purple */
+ colortable[10] = (COLOR_PAIR(5) | A_BRIGHT); /* Purple */
colortable[11] = (COLOR_PAIR(3) | A_BRIGHT); /* Yellow */
- colortable[12] = (COLOR_PAIR(5) | A_BRIGHT); /* Light Red XXX */
+ colortable[12] = (COLOR_PAIR(5) | A_NORMAL); /* Light Red XXX */
colortable[13] = (COLOR_PAIR(2) | A_BRIGHT); /* Light Green */
- colortable[14] = (COLOR_PAIR(4) | A_BRIGHT); /* Light Blue */
+ colortable[14] = (COLOR_PAIR(6) | A_BRIGHT); /* Light Blue */
colortable[15] = (COLOR_PAIR(3) | A_NORMAL); /* Light Umber XXX */
}
#endif
-#ifdef USE_SOUND
/* Handle "arg_sound" */
if (use_sound != arg_sound)
{
/* Change setting */
use_sound = arg_sound;
}
-#endif
-
-#ifdef USE_GRAPHICS
/* Try graphics */
if (arg_graphics)
#endif
}
-#endif /* USE_GRAPHICS */
-
-
-
/*** Low level preparation ***/
#ifdef USE_GETCH
}
/* Activate the "Angband" window screen */
- Term_activate(&data[0].t);
+ term_activate(&data[0].t);
/* Store */
term_screen = &data[0].t;
#endif /* USE_GCU */
-
-