Changeset - 5e822fe9c265
[Not reviewed]
0 1 0
Vitaly Takmazov - 14 years ago 2011-10-21 08:13:46
vitalyster@gmail.com
fixed dfrotz target
1 file changed with 5 insertions and 2 deletions:
0 comments (0 inline, 0 general)
backends/frotz/dfrotz/dumb/dumb_input.c
Show inline comments
 
/* dumb-input.c
 
 * $Id: dumb-input.c,v 1.1.1.1 2002/03/26 22:38:34 feedle Exp $
 
 * Copyright 1997,1998 Alpine Petrofsky <alpine@petrofsky.berkeley.ca.us>.
 
 * Any use permitted provided this notice stays intact.
 
 */
 

	
 
#include "dumb_frotz.h"
 
f_setup_t f_setup;
 

	
 
static char runtime_usage[] =
 
  "DUMB-FROTZ runtime help:\n"
 
  "  General Commands:\n"
 
  "    \\help    Show this message.\n"
 
  "    \\set     Show the current values of runtime settings.\n"
 
  "    \\s       Show the current contents of the whole screen.\n"
 
  "    \\d       Discard the part of the input before the cursor.\n"
 
  "    \\wN      Advance clock N/10 seconds, possibly causing the current\n"
 
  "                and subsequent inputs to timeout.\n"
 
  "    \\w       Advance clock by the amount of real time since this input\n"
 
  "                started (times the current speed factor).\n"
 
  "    \\t       Advance clock just enough to timeout the current input\n"
 
  "  Reverse-Video Display Method Settings:\n"
 
  "    \\rn   none    \\rc   CAPS    \\rd   doublestrike    \\ru   underline\n"
 
  "    \\rbC  show rv blanks as char C (orthogonal to above modes)\n"
 
  "  Output Compression Settings:\n"
 
  "    \\cn      none: show whole screen before every input.\n"
 
  "    \\cm      max: show only lines that have new nonblank characters.\n"
 
  "    \\cs      spans: like max, but emit a blank line between each span of\n"
 
  "                screen lines shown.\n"
 
  "    \\chN     Hide top N lines (orthogonal to above modes).\n"
 
  "  Misc Settings:\n"
 
  "    \\sfX     Set speed factor to X.  (0 = never timeout automatically).\n"
 
  "    \\mp      Toggle use of MORE prompts\n"
 
  "    \\ln      Toggle display of line numbers.\n"
 
  "    \\lt      Toggle display of the line type identification chars.\n"
 
  "    \\vb      Toggle visual bell.\n"
 
  "    \\pb      Toggle display of picture outline boxes.\n"
 
  "    (Toggle commands can be followed by a 1 or 0 to set value ON or OFF.)\n"
 
  "  Character Escapes:\n"
 
  "    \\\\  backslash    \\#  backspace    \\[  escape    \\_  return\n"
 
  "    \\< \\> \\^ \\.  cursor motion        \\1 ..\\0  f1..f10\n"
 
  "    \\D ..\\X   Standard Frotz hotkeys.  Use \\H (help) to see the list.\n"
 
  "  Line Type Identification Characters:\n"
 
  "    Input lines:\n"
 
  "      untimed  timed\n"
 
  "      >        T      A regular line-oriented input\n"
 
  "      )        t      A single-character input\n"
 
  "      }        D      A line input with some input before the cursor.\n"
 
  "                         (Use \\d to discard it.)\n"
 
  "    Output lines:\n"
 
  "      ]     Output line that contains the cursor.\n"
 
  "      .     A blank line emitted as part of span compression.\n"
 
  "            (blank) Any other output line.\n"
 
;
 

	
 
static float speed = 1;
 
static bool do_more_prompts = FALSE;
 

	
 
enum input_type {
 
  INPUT_CHAR,
 
  INPUT_LINE,
 
  INPUT_LINE_CONTINUED,
 
};
 

	
 
/* get a character.  Exit with no fuss on EOF.  */
 
static int xgetchar(void)
 
{
 
  int c = getchar();
 
  if (c == EOF) {
 
    if (feof(stdin)) {
 
      fprintf(stderr, "\nEOT\n");
 
      exit(0);
 
    }
 
    os_fatal(strerror(errno));
 
  }
 
  return c;
 
}
 

	
 
/* Read one line, including the newline, into s.  Safely avoids buffer
 
 * overruns (but that's kind of pointless because there are several
 
 * other places where I'm not so careful).  */
 
static void getline_(char *s)
 
{
 
	fflush(stdout);
 
  int c;
 
  char *p = s;
 
  char *p;
 
	
 
  fflush(stdout);
 
  
 
  p = s;
 
  while (p < s + INPUT_BUFFER_SIZE - 1)
 
    if ((*p++ = xgetchar()) == '\n') {
 
      *p = '\0';
 
      return;
 
    }
 
  p[-1] = '\n';
 
  p[0] = '\0';
 
  while ((c = xgetchar()) != '\n')
 
    ;
 
  printf("Line too long, truncated to %s\n", s - INPUT_BUFFER_SIZE);
 
}
 

	
 
/* Translate in place all the escape characters in s.  */
 
static void translate_special_chars(char *s)
 
{
 
  char *src = s, *dest = s;
 
  while (*src)
 
    switch(*src++) {
 
    default: *dest++ = src[-1]; break;
 
    case '\n': *dest++ = ZC_RETURN; break;
 
    case '\\':
 
      switch (*src++) {
 
      case '\n': *dest++ = ZC_RETURN; break;
 
      case '\\': *dest++ = '\\'; break;
 
      case '?': *dest++ = ZC_BACKSPACE; break;
 
      case '[': *dest++ = ZC_ESCAPE; break;
 
      case '_': *dest++ = ZC_RETURN; break;
 
      case '^': *dest++ = ZC_ARROW_UP; break;
 
      case '.': *dest++ = ZC_ARROW_DOWN; break;
 
      case '<': *dest++ = ZC_ARROW_LEFT; break;
 
      case '>': *dest++ = ZC_ARROW_RIGHT; break;
 
      case 'R': *dest++ = ZC_HKEY_RECORD; break;
 
      case 'P': *dest++ = ZC_HKEY_PLAYBACK; break;
 
      case 'S': *dest++ = ZC_HKEY_SEED; break;
 
      case 'U': *dest++ = ZC_HKEY_UNDO; break;
 
      case 'N': *dest++ = ZC_HKEY_RESTART; break;
 
      case 'X': *dest++ = ZC_HKEY_QUIT; break;
 
      case 'D': *dest++ = ZC_HKEY_DEBUG; break;
 
      case 'H': *dest++ = ZC_HKEY_HELP; break;
 
      case '1': case '2': case '3': case '4':
 
      case '5': case '6': case '7': case '8': case '9':
 
	*dest++ = ZC_FKEY_MIN + src[-1] - '0' - 1; break;
 
      case '0': *dest++ = ZC_FKEY_MIN + 9; break;
 
      default:
 
	fprintf(stderr, "DUMB-FROTZ: unknown escape char: %c\n", src[-1]);
 
	fprintf(stderr, "Enter \\help to see the list\n");
 
      }
 
    }
 
  *dest = '\0';
 
}
 

	
 

	
 
/* The time in tenths of seconds that the user is ahead of z time.  */
 
static int time_ahead = 0;
 

	
 
/* Called from os_read_key and os_read_line if they have input from
 
 * a previous call to dumb_read_line.
 
 * Returns TRUE if we should timeout rather than use the read-ahead.
 
 * (because the user is further ahead than the timeout).  */
 
static bool check_timeout(int timeout)
 
{
 
  if ((timeout == 0) || (timeout > time_ahead))
 
    time_ahead = 0;
 
  else
 
    time_ahead -= timeout;
 
  return time_ahead != 0;
 
}
 

	
 
/* If val is '0' or '1', set *var accordingly, otherwise toggle it.  */
 
static void toggle(bool *var, char val)
 
{
 
  *var = val == '1' || (val != '0' && !*var);
 
}
 

	
 
/* Handle input-related user settings and call dumb_output_handle_setting.  */
 
bool dumb_handle_setting(const char *setting, bool show_cursor, bool startup)
 
{
 
  if (!strncmp(setting, "sf", 2)) {
 
    speed = atof(&setting[2]);
 
    printf("Speed Factor %g\n", speed);
 
  } else if (!strncmp(setting, "mp", 2)) {
 
    toggle(&do_more_prompts, setting[2]);
 
    printf("More prompts %s\n", do_more_prompts ? "ON" : "OFF");
 
  } else {
 
    if (!strcmp(setting, "set")) {
 
      printf("Speed Factor %g\n", speed);
 
      printf("More Prompts %s\n", do_more_prompts ? "ON" : "OFF");
 
    }
 
    return dumb_output_handle_setting(setting, show_cursor, startup);
 
  }
 
  return TRUE;
 
}
 

	
 
/* Read a line, processing commands (lines that start with a backslash
 
 * (that isn't the start of a special character)), and write the
 
 * first non-command to s.
 
 * Return true if timed-out.  */
 
static bool dumb_read_line(char *s, char *prompt, bool show_cursor,
 
			   int timeout, enum input_type type,
 
			   zchar *continued_line_chars)
 
{
 
  time_t start_time;
 

	
 
  if (timeout) {
 
    if (time_ahead >= timeout) {
 
      time_ahead -= timeout;
 
      return TRUE;
 
    }
 
    timeout -= time_ahead;
 
    start_time = time(0);
 
  }
 
  time_ahead = 0;
 

	
 
  dumb_show_screen(show_cursor);
 
  for (;;) {
 
    char *command;
 
    if (prompt)
 
      fputs(prompt, stdout);
 
    else
 
      dumb_show_prompt(show_cursor, (timeout ? "tTD" : ")>}")[type]);
 
    getline_(s);
 
    if ((s[0] != '\\') || ((s[1] != '\0') && !islower(s[1]))) {
 
      /* Is not a command line.  */
 
      translate_special_chars(s);
 
      if (timeout) {
 
	int elapsed = (time(0) - start_time) * 10 * speed;
 
	if (elapsed > timeout) {
 
	  time_ahead = elapsed - timeout;
 
	  return TRUE;
 
	}
 
      }
 
      return FALSE;
 
    }
 
    /* Commands.  */
 

	
 
    /* Remove the \ and the terminating newline.  */
 
    command = s + 1;
 
    command[strlen(command) - 1] = '\0';
 
    
 
    if (!strcmp(command, "t")) {
 
      if (timeout) {
 
	time_ahead = 0;
 
	s[0] = '\0';
 
	return TRUE;
 
      }
 
    } else if (*command == 'w') {
 
      if (timeout) {
 
	int elapsed = atoi(&command[1]);
 
	time_t now = time(0);
 
	if (elapsed == 0)
 
	  elapsed = (now - start_time) * 10 * speed;
 
	if (elapsed >= timeout) {
 
	  time_ahead = elapsed - timeout;
 
	  s[0] = '\0';
 
	  return TRUE;
 
	}
 
	timeout -= elapsed;
 
	start_time = now;
 
      }
 
    } else if (!strcmp(command, "d")) {
 
      if (type != INPUT_LINE_CONTINUED)
 
	fprintf(stderr, "DUMB-FROTZ: No input to discard\n");
 
      else {
 
	dumb_discard_old_input(strlen(continued_line_chars));
 
	continued_line_chars[0] = '\0';
 
	type = INPUT_LINE;
 
      }
 
    } else if (!strcmp(command, "help")) {
 
      if (!do_more_prompts)
 
	fputs(runtime_usage, stdout);
 
      else {
 
	char *current_page, *next_page;
 
	current_page = next_page = runtime_usage;
 
	for (;;) {
 
	  int i;
 
	  for (i = 0; (i < h_screen_rows - 2) && *next_page; i++)
 
	    next_page = strchr(next_page, '\n') + 1;
 
	  printf("%.*s", next_page - current_page, current_page);
 
	  current_page = next_page;
 
	  if (!*current_page)
 
	    break;
 
	  printf("HELP: Type <return> for more, or q <return> to stop: ");
 
	  getline_(s);
 
	  if (!strcmp(s, "q\n"))
 
	    break;
 
	}
 
      }
 
    } else if (!strcmp(command, "s")) {
 
	dumb_dump_screen();
 
    } else if (!dumb_handle_setting(command, show_cursor, FALSE)) {
 
      fprintf(stderr, "DUMB-FROTZ: unknown command: %s\n", s);
 
      fprintf(stderr, "Enter \\help to see the list of commands\n");
0 comments (0 inline, 0 general)