OSDN Git Service

v3.0.0 Alpha5 OSDN最終版
[hengband/hengband.git] / src / main-gcu.c
index f505a9f..20ba0bf 100644 (file)
  * XXX XXX XXX Consider the use of "savetty()" and "resetty()".
  */
 
-#include "angband.h"
-#include "files.h"
-#include "term.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
  */
-# include <curses.h>
+#include <curses.h>
+#include <iconv.h>
 
 typedef struct term_data term_data;
 
 struct term_data
 {
-   term t;
+   term_type t;
 
    WINDOW *win;
 };
@@ -185,7 +193,8 @@ struct term_data
 #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
@@ -193,25 +202,16 @@ static term_data data[MAX_TERM_DATA];
  * Mega-Hack -- try to guess when "POSIX" is available.
  * If the user defines two of these, we will probably crash.
  */
-# 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(linux)
-#    define USE_TERMIO
-#   else
-#    define USE_TCHARS
-#   endif
+#   define USE_TCHARS
 #  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
 
 /*
@@ -219,8 +219,6 @@ static term_data data[MAX_TERM_DATA];
  */
 #define REDEFINE_COLORS
 
-
-
 /*
  * POSIX stuff
  */
@@ -248,10 +246,8 @@ static term_data data[MAX_TERM_DATA];
 # include <sys/types.h>
 #endif
 
-
 #include <locale.h>
 
-
 /*
  * XXX XXX Hack -- POSIX uses "O_NONBLOCK" instead of "O_NDELAY"
  *
@@ -261,14 +257,12 @@ static term_data data[MAX_TERM_DATA];
 # 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.
@@ -276,84 +270,10 @@ static term_data data[MAX_TERM_DATA];
 /* #define nonl() */
 /* #define nl() */
 
-
- /*
-  * Standard sound names
-  */
-static const concptr angband_sound_name[SOUND_MAX] =
-{
-       "dummy",
-       "hit",
-       "miss",
-       "flee",
-       "drop",
-       "kill",
-       "level",
-       "death",
-       "study",
-       "teleport",
-       "shoot",
-       "quaff",
-       "zap",
-       "walk",
-       "tpother",
-       "hitwall",
-       "eat",
-       "store1",
-       "store2",
-       "store3",
-       "store4",
-       "dig",
-       "opendoor",
-       "shutdoor",
-       "tplevel",
-       "scroll",
-       "buy",
-       "sell",
-       "warn",
-       "rocket",
-       "n_kill",
-       "u_kill",
-       "quest",
-       "heal",
-       "x_heal",
-       "bite",
-       "claw",
-       "m_spell",
-       "summon",
-       "breath",
-       "ball",
-       "m_heal",
-       "atkspell",
-       "evil",
-       "touch",
-       "sting",
-       "crush",
-       "slime",
-       "wail",
-       "winner",
-       "fire",
-       "acid",
-       "elec",
-       "cold",
-       "illegal",
-       "fail",
-       "wakeup",
-       "invuln",
-       "fall",
-       "pain",
-       "destitem",
-       "moan",
-       "show",
-       "unused",
-       "explode",
-       "glass",
-       "reflect",
-};
-
 static concptr ANGBAND_DIR_XTRA_SOUND;
 
 /*
+ * todo 有効活用されていない疑惑
  * Flag set once "sound" has been initialized
  */
 static bool can_use_sound = FALSE;
@@ -363,7 +283,6 @@ static bool can_use_sound = FALSE;
  */
 static concptr sound_file[SOUND_MAX];
 
-
 /*
  * Save the "normal" and "angband" terminal settings
  */
@@ -385,7 +304,6 @@ static struct termio  game_termio;
 #endif
 
 #ifdef USE_TCHARS
-
 static struct ltchars norm_speciax_chars;
 static struct sgttyb  norm_ttyb;
 static struct tchars  norm_tchars;
@@ -395,20 +313,14 @@ static struct ltchars game_speciax_chars;
 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.
@@ -431,41 +343,30 @@ static int can_fix_color = FALSE;
  * 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
-
 }
 
 
@@ -474,31 +375,23 @@ static void keymap_norm(void)
  */
 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
-
 }
 
 
@@ -507,31 +400,23 @@ static void keymap_game(void)
  */
 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
-
 }
 
 
@@ -540,9 +425,7 @@ static void keymap_norm_prepare(void)
  */
 static void keymap_game_prepare(void)
 {
-
 #ifdef USE_TPOSIX
-
    /* Acquire the current mapping */
    tcgetattr(0, &game_termios);
 
@@ -564,11 +447,9 @@ static void keymap_game_prepare(void)
    /* 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);
 
@@ -578,8 +459,6 @@ static void keymap_game_prepare(void)
    /* 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;
@@ -590,11 +469,9 @@ static void keymap_game_prepare(void)
    /* 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);
@@ -622,20 +499,16 @@ static void keymap_game_prepare(void)
    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 */
@@ -647,7 +520,7 @@ static errr Term_xtra_gcu_alive(int v)
       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();
@@ -661,14 +534,8 @@ static errr Term_xtra_gcu_alive(int v)
       /* Flush the output */
       (void)fflush(stdout);
    }
-
-   /* Resume */
    else
    {
-      /* Refresh */
-      /* (void)touchwin(curscr); */
-      /* (void)wrefresh(curscr); */
-
       /* Restore the settings */
       cbreak();
       noecho();
@@ -678,17 +545,16 @@ static errr Term_xtra_gcu_alive(int v)
       keymap_game();
    }
 
-   /* Success */
    return (0);
 }
 
+
 /*
  * Check for existance of a file
  */
 static bool check_file(concptr s)
 {
    FILE *fff;
-
    fff = fopen(s, "r");
    if (!fff) return (FALSE);
 
@@ -703,39 +569,35 @@ static bool check_file(concptr s)
 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];
-
-      /* Prepare the sounds */
-      for (i = 1; i < SOUND_MAX; i++)
-      {
-        /* Extract name of sound file */
-        sprintf(wav, "%s.wav", angband_sound_name[i]);
+       int i;
+       char wav[128];
+       char buf[1024];
 
-        /* Access the sound */
-        path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_SOUND, wav);
+       /* Prepare the sounds */
+       for (i = 1; i < SOUND_MAX; i++)
+       {
+               /* Extract name of sound file */
+               sprintf(wav, "%s.wav", angband_sound_name[i]);
 
-        /* Save the sound filename, if it exists */
-        if (check_file(buf)) sound_file[i] = string_make(buf);
-      }
+               /* Access the sound */
+               path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_SOUND, wav);
 
-      /* 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);
 }
 
 
 /*
  * 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);
 
@@ -759,7 +621,7 @@ static void Term_init_gcu(term *t)
 /*
  * 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);
 
@@ -770,7 +632,7 @@ static void Term_nuke_gcu(term *t)
    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 */
@@ -793,6 +655,39 @@ static void Term_nuke_gcu(term *t)
    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
 
 /*
@@ -805,18 +700,37 @@ static errr Term_xtra_gcu_event(int v)
    /* 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(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 */
@@ -834,10 +748,10 @@ static errr Term_xtra_gcu_event(int v)
       /* 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);
@@ -852,16 +766,40 @@ static errr Term_xtra_gcu_event(int v)
 {
    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(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 */
@@ -881,13 +819,13 @@ static errr Term_xtra_gcu_event(int v)
 
       /* 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);
@@ -1098,9 +1036,13 @@ 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 ? */
@@ -1112,8 +1054,19 @@ static errr Term_text_gcu(int x, int y, int n, byte a, concptr s)
    }
 #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);
@@ -1134,7 +1087,7 @@ static errr Term_text_gcu(int x, int y, int n, byte a, concptr s)
 
 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);
@@ -1173,7 +1126,7 @@ static errr term_data_init(term_data *td, int rows, int cols, int y, int x)
    t->data = td;
 
    /* Activate it */
-   Term_activate(t);
+   term_activate(t);
 
 
    /* Success */
@@ -1186,8 +1139,11 @@ static void hook_quit(concptr str)
        /* Unused */
        (void)str;
 
-       /* Exit curses */
-       endwin();
+   /* Exit curses */
+   endwin();
+
+   iconv_close(iconv_to_sys);
+   iconv_close(iconv_to_gui);
 }
 
 
@@ -1212,6 +1168,10 @@ errr init_gcu(int argc, char *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");
@@ -1252,23 +1212,16 @@ errr init_gcu(int argc, char *argv[])
    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)
@@ -1402,7 +1355,7 @@ errr init_gcu(int argc, char *argv[])
    }
 
    /* Activate the "Angband" window screen */
-   Term_activate(&data[0].t);
+   term_activate(&data[0].t);
 
    /* Store */
    term_screen = &data[0].t;
@@ -1413,5 +1366,3 @@ errr init_gcu(int argc, char *argv[])
 
 
 #endif /* USE_GCU */
-
-