+++ /dev/null
-/*!
- @file chuukei.c
- @brief 中継機能の実装
- @date 2014/01/02
- @author
- 2014 Deskull rearranged comment for Doxygen.
- */
-
-#include "angband.h"
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <ctype.h>
-#ifdef WINDOWS
-#include <windows.h>
-#endif
-
-#ifdef CHUUKEI
-#if defined(WINDOWS)
-#include <winsock.h>
-#elif defined(MACINTOSH)
-#include <OpenTransport.h>
-#include <OpenTptInternet.h>
-#else
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include <arpa/inet.h>
-
-#include <setjmp.h>
-#include <signal.h>
-#endif
-
-#define MAX_HOSTNAME 256
-#endif
-
-#define RINGBUF_SIZE 1024*1024
-#define FRESH_QUEUE_SIZE 4096
-#ifdef WINDOWS
-#define WAIT 100
-#else
-#define WAIT 100*1000 /* ブラウズ側のウエイト(us単位) */
-#endif
-#define DEFAULT_DELAY 50
-#define RECVBUF_SIZE 1024
-
-static long epoch_time; /* バッファ開始時刻 */
-static int browse_delay; /* 表示するまでの時間(100ms単位)(この間にラグを吸収する) */
-#ifdef CHUUKEI
-static int sd; /* ソケットのファイルディスクリプタ */
-static long time_diff; /* プレイ側との時間のずれ(これを見ながらディレイを調整していく) */
-static int server_port;
-static char server_name[MAX_HOSTNAME];
-#endif
-
-static int movie_fd;
-static int movie_mode;
-
-#ifdef CHUUKEI
-#ifdef WINDOWS
-#define close closesocket
-#endif
-
-#ifdef MACINTOSH
-static InetSvcRef inet_services = nil;
-static EndpointRef ep = kOTInvalidEndpointRef;
-#endif
-#endif
-/* 描画する時刻を覚えておくキュー構造体 */
-static struct
-{
- int time[FRESH_QUEUE_SIZE];
- int next;
- int tail;
-}fresh_queue;
-
-
-/* リングバッファ構造体 */
-static struct
-{
- char *buf;
- int wptr;
- int rptr;
- int inlen;
-}ring;
-
-#ifdef MACINTOSH
-int recv(int s, char *buffer, size_t buflen, int flags)
-{
- OTFlags junkFlags;
- int n = OTRcv(ep, (void *) buffer, buflen, &junkFlags);
- if( n <= 0 )
- return n;
- return n;
-}
-#endif
-
-/*
- * Original hooks
- */
-static errr (*old_xtra_hook)(int n, int v);
-static errr (*old_curs_hook)(int x, int y);
-static errr (*old_bigcurs_hook)(int x, int y);
-static errr (*old_wipe_hook)(int x, int y, int n);
-static errr (*old_text_hook)(int x, int y, int n, byte a, cptr s);
-
-static void disable_chuukei_server(void)
-{
- term *t = angband_term[0];
-#ifdef CHUUKEI
- chuukei_server = FALSE;
-#endif /* CHUUKEI */
- t->xtra_hook = old_xtra_hook;
- t->curs_hook = old_curs_hook;
- t->bigcurs_hook = old_bigcurs_hook;
- t->wipe_hook = old_wipe_hook;
- t->text_hook = old_text_hook;
-}
-
-/* ANSI Cによればstatic変数は0で初期化されるが一応初期化する */
-static errr init_buffer(void)
-{
- fresh_queue.next = fresh_queue.tail = 0;
- ring.wptr = ring.rptr = ring.inlen = 0;
- fresh_queue.time[0] = 0;
- ring.buf = malloc(RINGBUF_SIZE);
- if (ring.buf == NULL) return (-1);
-
- return (0);
-}
-
-/* 現在の時間を100ms単位で取得する */
-static long get_current_time(void)
-{
-#ifdef WINDOWS
- return timeGetTime() / 100;
-#elif defined(MACINTOSH)
- return TickCount();
-#else
- struct timeval tv;
- gettimeofday(&tv, NULL);
-
- return (tv.tv_sec * 10 + tv.tv_usec / 100000);
-#endif
-}
-
-
-/* リングバッファ構造体に buf の内容を加える */
-static errr insert_ringbuf(char *buf)
-{
- int len;
- len = strlen(buf) + 1; /* +1は終端文字分 */
-
- if (movie_mode)
- {
- fd_write(movie_fd, buf, len);
-#ifdef CHUUKEI
- if (!chuukei_server) return 0;
-#else
- return 0;
-#endif
- }
-
- /* バッファをオーバー */
- if (ring.inlen + len >= RINGBUF_SIZE)
- {
-#ifdef CHUUKEI
- if (chuukei_server) disable_chuukei_server();
- else chuukei_client = FALSE;
-
- prt("送受信バッファが溢れました。サーバとの接続を切断します。", 0, 0);
- inkey();
-
- close(sd);
-#endif
- return (-1);
- }
-
- /* バッファの終端までに収まる */
- if (ring.wptr + len < RINGBUF_SIZE)
- {
- memcpy(ring.buf + ring.wptr, buf, len);
- ring.wptr += len;
- }
- /* バッファの終端までに収まらない(ピッタリ収まる場合も含む) */
- else
- {
- int head = RINGBUF_SIZE - ring.wptr; /* 前半 */
- int tail = len - head; /* 後半 */
-
- memcpy(ring.buf + ring.wptr, buf, head);
- memcpy(ring.buf, buf + head, tail);
- ring.wptr = tail;
- }
-
- ring.inlen += len;
-
- /* Success */
- return (0);
-}
-
-#ifdef CHUUKEI
-void flush_ringbuf(void)
-{
-#ifndef MACINTOSH
- fd_set fdset;
- struct timeval tv;
-
- if (!chuukei_server) return;
-
- if (ring.inlen == 0) return;
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- FD_ZERO(&fdset);
- FD_SET(sd, &fdset);
-
- while (1)
- {
- fd_set tmp_fdset;
- int result;
-
- tmp_fdset = fdset;
-
- /* ソケットにデータを書き込めるかどうか調べる */
- select(sd+1, (fd_set *)NULL, &tmp_fdset, (fd_set *)NULL, &tv);
-
- /* 書き込めなければ戻る */
- if (FD_ISSET(sd, &tmp_fdset) == 0) break;
-
- result = send(sd, ring.buf + ring.rptr, ((ring.wptr > ring.rptr ) ? ring.wptr : RINGBUF_SIZE) - ring.rptr, 0);
-
- if (result <= 0)
- {
- /* サーバとの接続断? */
- if (chuukei_server) disable_chuukei_server();
-
- prt("サーバとの接続が切断されました。", 0, 0);
- inkey();
- close(sd);
-
- return;
- }
-
- ring.rptr += result;
- ring.inlen -= result;
-
- if (ring.rptr == RINGBUF_SIZE) ring.rptr = 0;
- if (ring.inlen == 0) break;
- }
-#else
- if (!chuukei_server) return;
-
- if (ring.inlen == 0) return;
-
- while (1)
- {
- int result;
-
- /* ソケットにデータを書き込めるかどうか調べる */
- result = OTSnd(ep, ring.buf + ring.rptr, ((ring.wptr > ring.rptr ) ? ring.wptr : RINGBUF_SIZE) - ring.rptr, 0);
-
- if (result <= 0)
- {
- /* サーバとの接続断? */
- if (chuukei_server) disable_chuukei_server();
-
- prt("サーバとの接続が切断されました。", 0, 0);
- inkey();
- close(sd);
-
- return;
- }
-
- ring.rptr += result;
- ring.inlen -= result;
-
- if (ring.rptr == RINGBUF_SIZE) ring.rptr = 0;
- if (ring.inlen == 0) break;
- }
-#endif
-}
-
-
-static int read_chuukei_prf(cptr prf_name)
-{
- char buf[1024];
- FILE *fp;
-
- path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA, prf_name);
- fp = my_fopen(buf, "r");
-
- if (!fp) return (-1);
-
- /* 初期化 */
- server_port = -1;
- server_name[0] = 0;
- browse_delay = DEFAULT_DELAY;
-
- while (0 == my_fgets(fp, buf, sizeof(buf)))
- {
- /* サーバ名 */
- if (!strncmp(buf, "server:", 7))
- {
- strncpy(server_name, buf + 7, MAX_HOSTNAME - 1);
- server_name[MAX_HOSTNAME - 1] = '\0';
- }
-
- /* ポート番号 */
- if (!strncmp(buf, "port:", 5))
- {
- server_port = atoi(buf + 5);
- }
-
- /* ディレイ */
- if (!strncmp(buf, "delay:", 6))
- {
- browse_delay = atoi(buf + 6);
- }
- }
-
- my_fclose(fp);
-
- /* prfファイルが完全でない */
- if (server_port == -1 || server_name[0] == 0) return (-1);
-
- return (0);
-}
-
-int connect_chuukei_server(char *prf_name)
-{
-#ifndef MACINTOSH
-
-#ifdef WINDOWS
- WSADATA wsaData;
- WORD wVersionRequested = (WORD) (( 1) | ( 1 << 8));
-#endif
-
- struct sockaddr_in ask;
- struct hostent *hp;
-
- if (read_chuukei_prf(prf_name) < 0)
- {
- printf("Wrong prf file\n");
- return (-1);
- }
-
- if (init_buffer() < 0)
- {
- printf("Malloc error\n");
- return (-1);
- }
-
-#ifdef WINDOWS
- if (WSAStartup(wVersionRequested, &wsaData))
- {
- msg_print("Report: WSAStartup failed.");
- return (-1);
- }
-#endif
-
- printf("server = %s\nport = %d\n", server_name, server_port);
-
- if ((hp = gethostbyname(server_name)) != NULL)
- {
- memset(&ask, 0, sizeof(ask));
- memcpy(&ask.sin_addr, hp->h_addr_list[0], hp->h_length);
- }
- else
- {
- if ((ask.sin_addr.s_addr=inet_addr(server_name)) == 0)
- {
- printf("Bad hostname\n");
- return (-1);
- }
- }
-
- ask.sin_family = AF_INET;
- ask.sin_port = htons((unsigned short)server_port);
-
-#ifndef WINDOWS
- if ((sd=socket(PF_INET,SOCK_STREAM, 0)) < 0)
-#else
- if ((sd=socket(PF_INET,SOCK_STREAM, 0)) == INVALID_SOCKET)
-#endif
- {
- printf("Can't create socket\n");
- return (-1);
- }
-
- if (connect(sd, (struct sockaddr *)&ask, sizeof(ask)) < 0)
- {
- close(sd);
- printf("Can't connect %s port %d\n", server_name, server_port);
- return (-1);
- }
-
- return (0);
-#else /* MACINTOSH */
- OSStatus err;
- InetHostInfo response;
- InetHost host_addr;
- InetAddress inAddr;
- TCall sndCall;
- Boolean bind = false;
- OSStatus junk;
-
- if (read_chuukei_prf(prf_name) < 0){
- printf("Wrong prf file\n");
- return (-1);
- }
-
- init_buffer();
-
- printf("server = %s\nport = %d\n", server_name, server_port);
-
-
-#if TARGET_API_MAC_CARBON
- err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL);
-#else
- err = InitOpenTransport();
-#endif
-
- memset(&response, 0, sizeof(response));
-
-
-#if TARGET_API_MAC_CARBON
- inet_services = OTOpenInternetServicesInContext(kDefaultInternetServicesPath, 0, &err, NULL);
-#else
- inet_services = OTOpenInternetServices(kDefaultInternetServicesPath, 0, &err);
-#endif
-
- if (err == noErr) {
- err = OTInetStringToAddress(inet_services, (char *)server_name, &response);
-
- if (err == noErr) {
- host_addr = response.addrs[0];
- } else {
- printf("Bad hostname\n");
- }
-
-#if TARGET_API_MAC_CARBON
- ep = (void *)OTOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0, nil, &err, NULL);
-#else
- ep = (void *)OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err);
-#endif
-
- if (err == noErr) {
- err = OTBind(ep, nil, nil);
- bind = (err == noErr);
- }
- if (err == noErr){
- OTInitInetAddress(&inAddr, server_port, host_addr);
-
- sndCall.addr.len = sizeof(InetAddress);
- sndCall.addr.buf = (unsigned char*) &inAddr;
- sndCall.opt.buf = nil; /* no connection options */
- sndCall.opt.len = 0;
- sndCall.udata.buf = nil; /* no connection data */
- sndCall.udata.len = 0;
- sndCall.sequence = 0; /* ignored by OTConnect */
-
- err = OTConnect(ep, &sndCall, NULL);
-
- if( err != noErr ){
- printf("Can't connect %s port %d\n", server_name, server_port);
- }
- }
-
- err = OTSetSynchronous(ep);
- if (err == noErr)
- err = OTSetBlocking(ep);
-
- }
-
- if( err != noErr ){
- if( bind ){
- OTUnbind(ep);
- }
- /* Clean up. */
- if (ep != kOTInvalidEndpointRef) {
- OTCloseProvider(ep);
- ep = nil;
- }
- if (inet_services != nil) {
- OTCloseProvider(inet_services);
- inet_services = nil;
- }
-
- return -1;
- }
-
- return 0;
-
-#endif
-}
-#endif /* CHUUKEI */
-
-/* strが同じ文字の繰り返しかどうか調べる */
-static bool string_is_repeat(char *str, int len)
-{
- char c = str[0];
- int i;
-
- if (len < 2) return (FALSE);
-#ifdef JP
- if (iskanji(c)) return (FALSE);
-#endif
-
- for (i = 1; i < len; i++)
- {
-#ifdef JP
- if(c != str[i] || iskanji(str[i])) return (FALSE);
-#else
- if(c != str[i]) return (FALSE);
-#endif
- }
-
- return (TRUE);
-}
-
-static errr send_text_to_chuukei_server(int x, int y, int len, byte col, cptr str)
-{
- char buf[1024];
- char buf2[1024];
-
- strncpy(buf2, str, len);
- buf2[len] = '\0';
-
- if (len == 1)
- {
- sprintf(buf, "s%c%c%c%c", x+1, y+1, col, buf2[0]);
- }
- else if(string_is_repeat(buf2, len))
- {
- int i;
- for (i = len; i > 0; i -= 127)
- {
- sprintf(buf, "n%c%c%c%c%c", x+1, y+1, MIN(i, 127), col, buf2[0]);
- }
- }
- else
- {
-#ifdef SJIS
- sjis2euc(buf2);
-#endif
- sprintf(buf, "t%c%c%c%c%s", x+1, y+1, len, col, buf2);
- }
-
- insert_ringbuf(buf);
-
- return (*old_text_hook)(x, y, len, col, str);
-}
-
-static errr send_wipe_to_chuukei_server(int x, int y, int len)
-{
- char buf[1024];
-
- sprintf(buf, "w%c%c%c", x+1, y+1, len);
-
- insert_ringbuf(buf);
-
- return (*old_wipe_hook)(x, y, len);
-}
-
-static errr send_xtra_to_chuukei_server(int n, int v)
-{
- char buf[1024];
-
- if (n == TERM_XTRA_CLEAR || n == TERM_XTRA_FRESH || n == TERM_XTRA_SHAPE)
- {
- sprintf(buf, "x%c", n+1);
-
- insert_ringbuf(buf);
-
- if (n == TERM_XTRA_FRESH)
- {
- sprintf(buf, "d%ld", get_current_time() - epoch_time);
- insert_ringbuf(buf);
- }
- }
-
- /* Verify the hook */
- if (!old_xtra_hook) return -1;
-
- return (*old_xtra_hook)(n, v);
-}
-
-static errr send_curs_to_chuukei_server(int x, int y)
-{
- char buf[1024];
-
- sprintf(buf, "c%c%c", x+1, y+1);
-
- insert_ringbuf(buf);
-
- return (*old_curs_hook)(x, y);
-}
-
-static errr send_bigcurs_to_chuukei_server(int x, int y)
-{
- char buf[1024];
-
- sprintf(buf, "C%c%c", x+1, y+1);
-
- insert_ringbuf(buf);
-
- return (*old_bigcurs_hook)(x, y);
-}
-
-
-/*
- * Prepare z-term hooks to call send_*_to_chuukei_server()'s
- */
-void prepare_chuukei_hooks(void)
-{
- term *t0 = angband_term[0];
-
- /* Save original z-term hooks */
- old_xtra_hook = t0->xtra_hook;
- old_curs_hook = t0->curs_hook;
- old_bigcurs_hook = t0->bigcurs_hook;
- old_wipe_hook = t0->wipe_hook;
- old_text_hook = t0->text_hook;
-
- /* Prepare z-term hooks */
- t0->xtra_hook = send_xtra_to_chuukei_server;
- t0->curs_hook = send_curs_to_chuukei_server;
- t0->bigcurs_hook = send_bigcurs_to_chuukei_server;
- t0->wipe_hook = send_wipe_to_chuukei_server;
- t0->text_hook = send_text_to_chuukei_server;
-}
-
-
-/*
- * Prepare z-term hooks to call send_*_to_chuukei_server()'s
- */
-void prepare_movie_hooks(void)
-{
- char buf[1024];
- char tmp[80];
-
- if (movie_mode)
- {
- movie_mode = 0;
-#ifdef CHUUKEI
- if (!chuukei_server) disable_chuukei_server();
-#else
- disable_chuukei_server();
-#endif
- fd_close(movie_fd);
-#ifdef JP
- msg_print("録画を終了しました。");
-#else
- msg_print("Stopped recording.");
-#endif
- }
- else
- {
- sprintf(tmp, "%s.amv", player_base);
-#ifdef JP
- if (get_string("ムービー記録ファイル: ", tmp, 80))
-#else
- if (get_string("Movie file name: ", tmp, 80))
-#endif
- {
- int fd;
-
- path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
-
- fd = fd_open(buf, O_RDONLY);
-
- /* Existing file */
- if (fd >= 0)
- {
- char out_val[160];
-
- /* Close the file */
- (void)fd_close(fd);
-
- /* Build query */
-#ifdef JP
- (void)sprintf(out_val, "現存するファイルに上書きしますか? (%s)", buf);
-#else
- (void)sprintf(out_val, "Replace existing file %s? ", buf);
-#endif
-
- /* Ask */
- if (!get_check(out_val)) return;
-
- movie_fd = fd_open(buf, O_WRONLY | O_TRUNC);
- }
- else
- {
- movie_fd = fd_make(buf, 0644);
- }
-
- if (!movie_fd)
- {
-#ifdef JP
- msg_print("ファイルを開けません!");
-#else
- msg_print("Can not open file.");
-#endif
- return;
- }
-
- movie_mode = 1;
-#ifdef CHUUKEI
- if (!chuukei_server) prepare_chuukei_hooks();
-#else
- prepare_chuukei_hooks();
-#endif
- do_cmd_redraw();
- }
- }
-}
-
-#ifdef CHUUKEI
-static int handle_timestamp_data(int timestamp)
-{
- long current_time = get_current_time();
-
- /* 描画キューは空かどうか? */
- if (fresh_queue.tail == fresh_queue.next)
- {
- /* バッファリングし始めの時間を保存しておく */
- epoch_time = current_time;
- epoch_time += browse_delay;
- epoch_time -= timestamp;
- time_diff = current_time - timestamp;
- }
-
- /* 描画キューに保存し、保存位置を進める */
- fresh_queue.time[fresh_queue.tail] = timestamp;
- fresh_queue.tail ++;
-
- /* キューの最後尾に到達したら先頭に戻す */
- fresh_queue.tail %= FRESH_QUEUE_SIZE;
-
- if (fresh_queue.tail == fresh_queue.next)
- {
- /* 描画キュー溢れ */
- prt("描画タイミングキューが溢れました。サーバとの接続を切断します。", 0, 0);
- inkey();
- close(sd);
-
- return -1;
- }
-
- /* プレイ側とのディレイを調整 */
- if (time_diff != current_time - timestamp)
- {
- long old_time_diff = time_diff;
- time_diff = current_time - timestamp;
- epoch_time -= (old_time_diff - time_diff);
- }
-
- /* Success */
- return 0;
-}
-#endif /* CHUUKEI */
-
-static int handle_movie_timestamp_data(int timestamp)
-{
- static int initialized = FALSE;
-
- /* 描画キューは空かどうか? */
- if (!initialized)
- {
- /* バッファリングし始めの時間を保存しておく */
- epoch_time = get_current_time();
- epoch_time += browse_delay;
- epoch_time -= timestamp;
- //time_diff = current_time - timestamp;
- initialized = TRUE;
- }
-
- /* 描画キューに保存し、保存位置を進める */
- fresh_queue.time[fresh_queue.tail] = timestamp;
- fresh_queue.tail ++;
-
- /* キューの最後尾に到達したら先頭に戻す */
- fresh_queue.tail %= FRESH_QUEUE_SIZE;
-
- /* Success */
- return 0;
-}
-
-#ifdef CHUUKEI
-static int read_sock(void)
-{
- static char recv_buf[RECVBUF_SIZE];
- static int remain_bytes = 0;
- int recv_bytes;
- int i;
-
- /* 前回残ったデータの後につづけて配信サーバからデータ受信 */
- recv_bytes = recv(sd, recv_buf + remain_bytes, RECVBUF_SIZE - remain_bytes, 0);
-
- if (recv_bytes <= 0)
- return -1;
-
- /* 前回残ったデータ量に今回読んだデータ量を追加 */
- remain_bytes += recv_bytes;
-
- for (i = 0; i < remain_bytes; i ++)
- {
- /* データのくぎり('\0')を探す */
- if (recv_buf[i] == '\0')
- {
- /* 'd'で始まるデータ(タイムスタンプ)の場合は
- 描画キューに保存する処理を呼ぶ */
- if ((recv_buf[0] == 'd') &&
- (handle_timestamp_data(atoi(recv_buf + 1)) < 0))
- return -1;
-
- /* 受信データを保存 */
- if (insert_ringbuf(recv_buf) < 0)
- return -1;
-
- /* 次のデータ移行をrecv_bufの先頭に移動 */
- memmove(recv_buf, recv_buf + i + 1, remain_bytes - i - 1);
-
- remain_bytes -= (i+1);
- i = 0;
- }
- }
-
- return 0;
-}
-#endif
-
-static int read_movie_file(void)
-{
- static char recv_buf[RECVBUF_SIZE];
- static int remain_bytes = 0;
- int recv_bytes;
- int i;
-
- recv_bytes = read(movie_fd, recv_buf + remain_bytes, RECVBUF_SIZE - remain_bytes);
-
- if (recv_bytes <= 0)
- return -1;
-
- /* 前回残ったデータ量に今回読んだデータ量を追加 */
- remain_bytes += recv_bytes;
-
- for (i = 0; i < remain_bytes; i ++)
- {
- /* データのくぎり('\0')を探す */
- if (recv_buf[i] == '\0')
- {
- /* 'd'で始まるデータ(タイムスタンプ)の場合は
- 描画キューに保存する処理を呼ぶ */
- if ((recv_buf[0] == 'd') &&
- (handle_movie_timestamp_data(atoi(recv_buf + 1)) < 0))
- return -1;
-
- /* 受信データを保存 */
- if (insert_ringbuf(recv_buf) < 0)
- return -1;
-
- /* 次のデータ移行をrecv_bufの先頭に移動 */
- memmove(recv_buf, recv_buf + i + 1, remain_bytes - i - 1);
-
- remain_bytes -= (i+1);
- i = 0;
- }
- }
-
- return 0;
-}
-
-
-#ifndef WINDOWS
-/* Win版の床の中点と壁の豆腐をピリオドとシャープにする。*/
-static void win2unix(int col, char *buf)
-{
- char kabe;
- if ( col == 9 ) kabe = '%';
- else kabe = '#';
-
- while (*buf)
- {
-#ifdef JP
- if (iskanji(*buf))
- {
- buf += 2;
- continue;
- }
-#endif
- if (*buf == 127) *buf = kabe;
- else if(*buf == 31) *buf = '.';
- buf++;
- }
-}
-#endif
-
-static bool get_nextbuf(char *buf)
-{
- char *ptr = buf;
-
- while (1)
- {
- *ptr = ring.buf[ring.rptr ++];
- ring.inlen --;
- if (ring.rptr == RINGBUF_SIZE) ring.rptr = 0;
- if (*ptr++ == '\0') break;
- }
-
- if (buf[0] == 'd') return (FALSE);
-
- return (TRUE);
-}
-
-/* プレイホストのマップが大きいときクライアントのマップもリサイズする */
-static void update_term_size(int x, int y, int len)
-{
- int ox, oy;
- int nx, ny;
- Term_get_size(&ox, &oy);
- nx = ox;
- ny = oy;
-
- /* 横方向のチェック */
- if (x + len > ox) nx = x + len;
- /* 縦方向のチェック */
- if (y + 1 > oy) ny = y + 1;
-
- if (nx != ox || ny != oy) Term_resize(nx, ny);
-}
-
-static bool flush_ringbuf_client(void)
-{
- char buf[1024];
-
- /* 書くデータなし */
- if (fresh_queue.next == fresh_queue.tail) return (FALSE);
-
- /* まだ書くべき時でない */
- if (fresh_queue.time[fresh_queue.next] > get_current_time() - epoch_time) return (FALSE);
-
- /* 時間情報(区切り)が得られるまで書く */
- while (get_nextbuf(buf))
- {
- char id;
- int x, y, len, col;
- int i;
- unsigned char tmp1, tmp2, tmp3, tmp4;
- char *mesg;
-
- sscanf(buf, "%c%c%c%c%c", &id, &tmp1, &tmp2, &tmp3, &tmp4);
- x = tmp1-1; y = tmp2-1; len = tmp3; col = tmp4;
- if (id == 's')
- {
- col = tmp3;
- mesg = &buf[4];
- }
- else mesg = &buf[5];
-#ifndef WINDOWS
- win2unix(col, mesg);
-#endif
-
- switch (id)
- {
- case 't': /* 通常 */
-#ifdef SJIS
- euc2sjis(mesg);
-#endif
- update_term_size(x, y, len);
- (void)((*angband_term[0]->text_hook)(x, y, len, (byte)col, mesg));
- strncpy(&Term->scr->c[y][x], mesg, len);
- for (i = x; i < x+len; i++)
- {
- Term->scr->a[y][i] = col;
- }
- break;
-
- case 'n': /* 繰り返し */
- for (i = 1; i < len; i++)
- {
- mesg[i] = mesg[0];
- }
- mesg[i] = '\0';
- update_term_size(x, y, len);
- (void)((*angband_term[0]->text_hook)(x, y, len, (byte)col, mesg));
- strncpy(&Term->scr->c[y][x], mesg, len);
- for (i = x; i < x+len; i++)
- {
- Term->scr->a[y][i] = col;
- }
- break;
-
- case 's': /* 一文字 */
- update_term_size(x, y, 1);
- (void)((*angband_term[0]->text_hook)(x, y, 1, (byte)col, mesg));
- strncpy(&Term->scr->c[y][x], mesg, 1);
- Term->scr->a[y][x] = col;
- break;
-
- case 'w':
- update_term_size(x, y, len);
- (void)((*angband_term[0]->wipe_hook)(x, y, len));
- break;
-
- case 'x':
- if (x == TERM_XTRA_CLEAR) Term_clear();
- (void)((*angband_term[0]->xtra_hook)(x, 0));
- break;
-
- case 'c':
- update_term_size(x, y, 1);
- (void)((*angband_term[0]->curs_hook)(x, y));
- break;
- case 'C':
- update_term_size(x, y, 1);
- (void)((*angband_term[0]->bigcurs_hook)(x, y));
- break;
- }
- }
-
- fresh_queue.next++;
- if (fresh_queue.next == FRESH_QUEUE_SIZE) fresh_queue.next = 0;
- return (TRUE);
-}
-
-#ifdef CHUUKEI
-void browse_chuukei()
-{
-#ifndef MACINTOSH
- fd_set fdset;
- struct timeval tv;
-
- tv.tv_sec = 0;
- tv.tv_usec = WAIT;
-
- FD_ZERO(&fdset);
- FD_SET(sd, &fdset);
-
- Term_clear();
- Term_fresh();
- Term_xtra(TERM_XTRA_REACT, 0);
-
- while (1)
- {
- fd_set tmp_fdset;
- struct timeval tmp_tv;
-
- if (flush_ringbuf_client()) continue;
-
- tmp_fdset = fdset;
- tmp_tv = tv;
-
- /* ソケットにデータが来ているかどうか調べる */
- select(sd+1, &tmp_fdset, (fd_set *)NULL, (fd_set *)NULL, &tmp_tv);
- if (FD_ISSET(sd, &tmp_fdset) == 0)
- {
- Term_xtra(TERM_XTRA_FLUSH, 0);
- continue;
- }
-
- if (read_sock() < 0)
- {
- chuukei_client = FALSE;
- }
-
- /* 接続が切れた状態で書くべきデータがなくなっていたら終了 */
- if (!chuukei_client && fresh_queue.next == fresh_queue.tail ) break;
- }
-#else
- Term_clear();
- Term_fresh();
- Term_xtra(TERM_XTRA_REACT, 0);
-
- while (1)
- {
- UInt32 unreadData = 0;
- int n;
-
- if (flush_ringbuf_client()) continue;
-
- /* ソケットにデータが来ているかどうか調べる */
-
- OTCountDataBytes(ep, &unreadData);
- if(unreadData <= 0 ){
- Term_xtra(TERM_XTRA_FLUSH, 0);
- continue;
- }
- if (read_sock() < 0)
- {
- chuukei_client = FALSE;
- }
-
- /* 接続が切れた状態で書くべきデータがなくなっていたら終了 */
- if (!chuukei_client && fresh_queue.next == fresh_queue.tail ) break;
- }
-#endif /*MACINTOSH*/
-}
-#endif /* CHUUKEI */
-
-void prepare_browse_movie_aux(cptr filename)
-{
- movie_fd = fd_open(filename, O_RDONLY);
-
- browsing_movie = TRUE;
-
- init_buffer();
-}
-
-void prepare_browse_movie(cptr filename)
-{
- char buf[1024];
- path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
-
- prepare_browse_movie_aux(buf);
-}
-
-void browse_movie(void)
-{
- Term_clear();
- Term_fresh();
- Term_xtra(TERM_XTRA_REACT, 0);
-
- while (read_movie_file() == 0)
- {
- while (fresh_queue.next != fresh_queue.tail)
- {
- if (!flush_ringbuf_client())
- {
- Term_xtra(TERM_XTRA_FLUSH, 0);
-
- /* ソケットにデータが来ているかどうか調べる */
-#ifdef WINDOWS
- Sleep(WAIT);
-#else
- usleep(WAIT);
-#endif
- }
- }
- }
-}