Пример #1
0
void z_restart (void)
{
    static bool first_restart = TRUE;

    flush_buffer ();

    os_restart_game (RESTART_BEGIN);

    seed_random (0);

    if (!first_restart) {

        fseek (story_fp, blorb_ofs, SEEK_SET);

        if (fread (zmp, 1, h_dynamic_size, story_fp) != h_dynamic_size)
            os_fatal ("Story file read error");

    } else first_restart = FALSE;

    restart_header ();
    restart_screen ();

    sp = fp = stack + STACK_SIZE;
    frame_count = 0;

    if (h_version != V6) {

        long pc = (long) h_start_pc;
        SET_PC (pc);

    } else call (h_start_pc, 0, NULL, 0);

    os_restart_game (RESTART_END);

}/* z_restart */
Пример #2
0
/* 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;
}
Пример #3
0
static void bt_sighandler(int sig, siginfo_t *info,
                                   void *secret) {

  void *trace[16];
  char *nam;
  int i, trace_size = 0;
//  ucontext_t *uc = (ucontext_t *)secret;

  if (sig == SIGINT)
    os_fatal("Emergency exit!\n\n(Signal SIGINT received)");

  /* Do something useful with siginfo_t */

  printf("\nInterpreter bug!\nSignal %d ", sig);
  if ((nam = getsigname(sig))) printf("[%s] ",nam);
//  printf("from %p", (void *)uc->uc_mcontext.gregs[_PROG_COUNTER]);

  if (sig == SIGSEGV)
        printf(" [faulty address is %p]",info->si_addr);

  printf("\n");

  trace_size = backtrace(trace, 16);
  /* overwrite sigaction with caller's address */
//  trace[1] = (void *) uc->uc_mcontext.gregs[_PROG_COUNTER];

  /* skip first stack frame (points here) */
  printf("Backtrace:\n");
//   messages = backtrace_symbols(trace, trace_size);
//   for (i=1; i<trace_size; ++i)
//         printf("[bt] %s\n", messages[i]);

  for (i=1;i<trace_size;i++)
    {
    printf("  "); fflush(stdout);
    backtrace_symbols_fd(trace+i, 1,fileno(stdout));
    }

  exit(0);
  }
Пример #4
0
void runtime_error (int errnum)
{
    int wasfirst;
    
    if (errnum <= 0 || errnum > ERR_NUM_ERRORS)
	return;

    if (f_setup.err_report_mode == ERR_REPORT_FATAL
	|| (!f_setup.ignore_errors && errnum <= ERR_MAX_FATAL)) {
	flush_buffer ();
	os_fatal (err_messages[errnum - 1]);
	return;
    }

    wasfirst = (error_count[errnum - 1] == 0);
    error_count[errnum - 1]++;
    
    if ((f_setup.err_report_mode == ERR_REPORT_ALWAYS)
	|| (f_setup.err_report_mode == ERR_REPORT_ONCE && wasfirst)) {
	long pc;

	GET_PC (pc);
	print_string ("Warning: ");
	print_string (err_messages[errnum - 1]);
	print_string (" (PC = ");
	print_long (pc, 16);
	print_char (')');
        
	if (f_setup.err_report_mode == ERR_REPORT_ONCE) {
	    print_string (" (will ignore further occurrences)");
	} else {
	    print_string (" (occurence ");
	    print_long (error_count[errnum - 1], 10);
	    print_char (')');
	}
	new_line ();
    }

} /* report_error */
Пример #5
0
void os_init_screen (void)
{

    /*trace(TRACE_CALLS);*/

    if (initscr() == NULL) {    /* Set up curses */
	os_fatal("Unable to initialize curses. Maybe your $TERM setting is bad.");
	exit(1);
    }
    u_setup.curses_active = 1;	/* Let os_fatal know curses is running */
    cbreak();			/* Raw input mode, no line processing */
    noecho();			/* No input echo */
    nonl();			/* No newline translation */
    intrflush(stdscr, TRUE);	/* Flush output on interrupt */
    keypad(stdscr, TRUE);	/* Enable the keypad and function keys */
    scrollok(stdscr, FALSE);	/* No scrolling unless explicitly asked for */

    if (h_version == V3 && u_setup.tandy_bit != 0)
        h_config |= CONFIG_TANDY;

    if (h_version == V3)
	h_config |= CONFIG_SPLITSCREEN;

    if (h_version >= V4)
	h_config |= CONFIG_BOLDFACE | CONFIG_EMPHASIS | CONFIG_FIXED | CONFIG_TIMEDINPUT;

    if (h_version >= V5)
      h_flags &= ~(GRAPHICS_FLAG | MOUSE_FLAG | MENU_FLAG);

#ifdef NO_SOUND
    if (h_version >= V5)
      h_flags &= ~SOUND_FLAG;

    if (h_version == V3)
      h_flags &= ~OLD_SOUND_FLAG;
#else
    if ((h_version >= 5) && (h_flags & SOUND_FLAG))
	h_flags |= SOUND_FLAG;

    if ((h_version == 3) && (h_flags & OLD_SOUND_FLAG))
	h_flags |= OLD_SOUND_FLAG;

    if ((h_version == 6) && (f_setup.sound != 0))
	h_config |= CONFIG_SOUND;
#endif

    if (h_version >= V5 && (h_flags & UNDO_FLAG))
        if (f_setup.undo_slots == 0)
            h_flags &= ~UNDO_FLAG;

    getmaxyx(stdscr, h_screen_rows, h_screen_cols);

    if (u_setup.screen_height != -1)
	h_screen_rows = u_setup.screen_height;
    if (u_setup.screen_width != -1)
	h_screen_cols = u_setup.screen_width;

    h_screen_width = h_screen_cols;
    h_screen_height = h_screen_rows;

    h_font_width = 1;
    h_font_height = 1;

    /* Must be after screen dimensions are computed.  */
    if (h_version == V6) {
      if (unix_init_pictures())
	h_config |= CONFIG_PICTURES;
      else
	h_flags &= ~GRAPHICS_FLAG;
    }

    /* Use the ms-dos interpreter number for v6, because that's the
     * kind of graphics files we understand.  Otherwise, use DEC.  */
    h_interpreter_number = h_version == 6 ? INTERP_MSDOS : INTERP_DEC_20;
    h_interpreter_version = 'F';

#ifdef COLOR_SUPPORT
    /* Enable colors if the terminal supports them, the user did not
     * disable colors, and the game or user requested colors.  User
     * requests them by specifying a foreground or background.
     */
    u_setup.color_enabled = (has_colors()
			&& !u_setup.disable_color
			&& (((h_version >= 5) && (h_flags & COLOUR_FLAG))
			  || (u_setup.foreground_color != -1)
			  || (u_setup.background_color != -1)));

    /* Maybe we don't want to muck about with changing $TERM to
     * xterm-color which some supposedly current Unicies still don't
     * understand.
     */
    if (u_setup.force_color)
	u_setup.color_enabled = TRUE;

    if (u_setup.color_enabled) {
        h_config |= CONFIG_COLOUR;
        h_flags |= COLOUR_FLAG; /* FIXME: beyond zork handling? */
        start_color();
	h_default_foreground =
	  (u_setup.foreground_color == -1)
	  	? FOREGROUND_DEF : u_setup.foreground_color;
	h_default_background =
	  (u_setup.background_color ==-1)
		? BACKGROUND_DEF : u_setup.background_color;
    } else
#endif /* COLOR_SUPPORT */
    {
	/* Set these per spec 8.3.2. */
	h_default_foreground = WHITE_COLOUR;
	h_default_background = BLACK_COLOUR;
	if (h_flags & COLOUR_FLAG) h_flags &= ~COLOUR_FLAG;
    }
    os_set_colour(h_default_foreground, h_default_background);
    os_erase_area(1, 1, h_screen_rows, h_screen_cols, 0);
}/* os_init_screen */
Пример #6
0
void z_restore (void)
{
    FILE *gfp;

    zword success = 0;

    if (zargc != 0) {

        /* Get the file name */

        /* Open auxilary file */

        if ((gfp = frotzopenprompt(FILE_LOAD_AUX)) == NULL)
            goto finished;

        /* Load auxilary file */

        success = fread (zmp + zargs[0], 1, zargs[1], gfp);

        /* Close auxilary file */

        fclose (gfp);

    } else {

        long pc;
        zword release;
        zword addr;
        int i;

        /* Open game file */

        if ((gfp = frotzopenprompt(FILE_RESTORE)) == NULL)
            goto finished;

        if (f_setup.save_quetzal) {
            success = restore_quetzal (gfp, story_fp, blorb_ofs);

        } else {
            /* Load game file */

            release = (unsigned) fgetc (gfp) << 8;
            release |= fgetc (gfp);

            (void) fgetc (gfp);
            (void) fgetc (gfp);

            /* Check the release number */

            if (release == h_release) {

                pc = (long) fgetc (gfp) << 16;
                pc |= (unsigned) fgetc (gfp) << 8;
                pc |= fgetc (gfp);

                SET_PC (pc);

                sp = stack + (fgetc (gfp) << 8);
                sp += fgetc (gfp);
                fp = stack + (fgetc (gfp) << 8);
                fp += fgetc (gfp);

                for (i = (int) (sp - stack); i < STACK_SIZE; i++) {
                    stack[i] = (unsigned) fgetc (gfp) << 8;
                    stack[i] |= fgetc (gfp);
                }

                fseek (story_fp, blorb_ofs, SEEK_SET);

                for (addr = 0; addr < h_dynamic_size; addr++) {
                    int skip = fgetc (gfp);
                    for (i = 0; i < skip; i++)
                        zmp[addr++] = fgetc (story_fp);
                    zmp[addr] = fgetc (gfp);
                    (void) fgetc (story_fp);
                }

                /* Check for errors */

                if (ferror (gfp) || ferror (story_fp) || addr != h_dynamic_size)
                    success = -1;
                else

                    /* Success */

                    success = 2;

            } else print_string ("Invalid save file\n");
        }

        if ((short) success >= 0) {

            /* Close game file */

            fclose (gfp);

            if ((short) success > 0) {
                zbyte old_screen_rows;
                zbyte old_screen_cols;

                /* In V3, reset the upper window. */
                if (h_version == V3)
                    split_window (0);

                LOW_BYTE (H_SCREEN_ROWS, old_screen_rows);
                LOW_BYTE (H_SCREEN_COLS, old_screen_cols);

                /* Reload cached header fields. */
                restart_header ();

                /*
                 * Since QUETZAL files may be saved on many different machines,
                 * the screen sizes may vary a lot. Erasing the status window
                 * seems to cover up most of the resulting badness.
                 */
                if (h_version > V3 && h_version != V6
                        && (h_screen_rows != old_screen_rows
                            || h_screen_cols != old_screen_cols))
                    erase_window (1);
            }
        } else
            os_fatal ("Error reading save file");
    }

finished:

    if (h_version <= V3)
        branch (success);
    else
        store (success);

}/* z_restore */
Пример #7
0
void init_memory (void)
{
    long size;
    zword addr;
    unsigned n;
    int i, j;

    static struct {
        enum story story_id;
        zword release;
        zbyte serial[6];
    } records[] = {
        {       SHERLOCK,  21, "871214" },
        {       SHERLOCK,  26, "880127" },
        {    BEYOND_ZORK,  47, "870915" },
        {    BEYOND_ZORK,  49, "870917" },
        {    BEYOND_ZORK,  51, "870923" },
        {    BEYOND_ZORK,  57, "871221" },
        {      ZORK_ZERO, 296, "881019" },
        {      ZORK_ZERO, 366, "890323" },
        {      ZORK_ZERO, 383, "890602" },
        {      ZORK_ZERO, 393, "890714" },
        {         SHOGUN, 292, "890314" },
        {         SHOGUN, 295, "890321" },
        {         SHOGUN, 311, "890510" },
        {         SHOGUN, 322, "890706" },
        {         ARTHUR,  54, "890606" },
        {         ARTHUR,  63, "890622" },
        {         ARTHUR,  74, "890714" },
        {        JOURNEY,  26, "890316" },
        {        JOURNEY,  30, "890322" },
        {        JOURNEY,  77, "890616" },
        {        JOURNEY,  83, "890706" },
        { LURKING_HORROR, 203, "870506" },
        { LURKING_HORROR, 219, "870912" },
        { LURKING_HORROR, 221, "870918" },
        {        UNKNOWN,   0, "------" }
    };

    /* Open story file */
    {
        giblorb_map_t *map;
        giblorb_result_t res;
        char magic[4] = "XXXX";
        strid_t file;

        file = game_file_stream;

        fread(magic, 1, 4, file);

        if (!memcmp(magic, "FORM", 4))
        {
            if (giblorb_set_resource_map(file))
                os_fatal("This Blorb file seems to be invalid.");

            map = giblorb_get_resource_map();

            if (giblorb_load_resource(map, giblorb_method_FilePos,
                                      &res, giblorb_ID_Exec, 0))
                os_fatal("This Blorb file does not contain an executable chunk.");
            if (res.chunktype != giblorb_make_id('Z','C','O','D'))
                os_fatal("This Blorb file contains an executable chunk, but it is not a Z-code file.");

            story_fp = file;
            blorb_ofs = res.data.startpos;
            blorb_len = res.length;
        }
        else
        {
            story_fp = file;
            blorb_ofs = 0;
            fseek(story_fp, 0, SEEK_END);
            blorb_len = ftell(story_fp);
        }

    }

    if (blorb_len < 64)
        os_fatal("This file is too small to be a Z-code file.");

    /* Allocate memory for story header */

    if ((zmp = (zbyte *) malloc (64)) == NULL)
        os_fatal ("Out of memory");

    /* Load header into memory */

    fseek(story_fp, blorb_ofs, 0);

    if (fread (zmp, 1, 64, story_fp) != 64)
        os_fatal ("Story file read error");

    /* Copy header fields to global variables */

    LOW_BYTE (H_VERSION, h_version);

    if (h_version < V1 || h_version > V8)
        os_fatal ("Unknown Z-code version");

    if (h_version == V6)
        os_fatal ("Cannot play Z-code version 6");

    LOW_BYTE (H_CONFIG, h_config);

    if (h_version == V3 && (h_config & CONFIG_BYTE_SWAPPED))
        os_fatal ("Byte swapped story file");

    LOW_WORD (H_RELEASE, h_release);
    LOW_WORD (H_RESIDENT_SIZE, h_resident_size);
    LOW_WORD (H_START_PC, h_start_pc);
    LOW_WORD (H_DICTIONARY, h_dictionary);
    LOW_WORD (H_OBJECTS, h_objects);
    LOW_WORD (H_GLOBALS, h_globals);
    LOW_WORD (H_DYNAMIC_SIZE, h_dynamic_size);
    LOW_WORD (H_FLAGS, h_flags);

    for (i = 0, addr = H_SERIAL; i < 6; i++, addr++)
        LOW_BYTE (addr, h_serial[i]);

    /* Auto-detect buggy story files that need special fixes */

    story_id = UNKNOWN;

    for (i = 0; records[i].story_id != UNKNOWN; i++) {

        if (h_release == records[i].release) {

            for (j = 0; j < 6; j++)
                if (h_serial[j] != records[i].serial[j])
                    goto no_match;

            story_id = records[i].story_id;

        }

no_match: ; /* null statement */

    }

    LOW_WORD (H_ABBREVIATIONS, h_abbreviations);
    LOW_WORD (H_FILE_SIZE, h_file_size);

    /* Calculate story file size in bytes */

    if (h_file_size != 0) {

        story_size = (long) 2 * h_file_size;

        if (h_version >= V4)
            story_size *= 2;
        if (h_version >= V6)
            story_size *= 2;

    } else {		/* some old games lack the file size entry */

        story_size = blorb_len;
    }

    LOW_WORD (H_CHECKSUM, h_checksum);
    LOW_WORD (H_ALPHABET, h_alphabet);
    LOW_WORD (H_FUNCTIONS_OFFSET, h_functions_offset);
    LOW_WORD (H_STRINGS_OFFSET, h_strings_offset);
    LOW_WORD (H_TERMINATING_KEYS, h_terminating_keys);
    LOW_WORD (H_EXTENSION_TABLE, h_extension_table);

    /* Zork Zero Macintosh doesn't have the graphics flag set */

    if (story_id == ZORK_ZERO && h_release == 296)
        h_flags |= GRAPHICS_FLAG;

    /* Adjust opcode tables */

    if (h_version <= V4) {
        op0_opcodes[0x09] = z_pop;
        op1_opcodes[0x0f] = z_not;
    } else {
        op0_opcodes[0x09] = z_catch;
        op1_opcodes[0x0f] = z_call_n;
    }

    /* Allocate memory for story data */

    if ((zmp = (zbyte *) realloc (zmp, story_size)) == NULL)
        os_fatal ("Out of memory");

    /* Load story file in chunks of 32KB */

    n = 0x8000;

    for (size = 64; size < story_size; size += n) {

        if (story_size - size < 0x8000)
            n = (unsigned) (story_size - size);

        SET_PC (size);

        if (fread (pcp, 1, n, story_fp) != n)
            os_fatal ("Story file read error");

    }

    /* Read header extension table */

    hx_table_size = get_header_extension (HX_TABLE_SIZE);
    hx_unicode_table = get_header_extension (HX_UNICODE_TABLE);

}/* init_memory */
Пример #8
0
static void myhandler( int s)
  {
  resethandlers();
  os_fatal("Signal %d received %s",s,signame(s));
  }
Пример #9
0
void __stack_chk_fail(void)
{ 
    os_fatal("stack_chk_fail");
}
Пример #10
0
void abort()
{
    os_fatal("abort()");
}