Exemple #1
0
static int save_restore( const char *file_name, int flag )
{
   FILE *tfp = NULL;

#if defined BUFFER_FILES        
   char tfpbuffer[BUFSIZ];      
#endif 
   int scripting_flag = 0, status = 0;

#if !defined(USE_QUETZAL)
   zword_t zw;
   int little_endian = 0;

   /* Find out if we are big-endian */
   zw = 0x0001;
   if ( *( zbyte_t * ) & zw )
   {                            /* We are little-endian, like an Intel 80x86 chip. */
      little_endian = 1;
   }
#endif

   /* Open the save file and disable scripting */

   if ( flag == GAME_SAVE || flag == GAME_RESTORE )
   {
      if ( ( tfp = fopen( file_name, ( flag == GAME_SAVE ) ? "wb" : "rb" ) ) == NULL )
      {
         output_line( "Cannot open SAVE file" );
         return ( 1 );
      }
#if defined BUFFER_FILES        
      setbuf( tfp, tfpbuffer ); 
#endif 
      scripting_flag = get_word( H_FLAGS ) & SCRIPTING_FLAG;
      set_word( H_FLAGS, get_word( H_FLAGS ) & ( ~SCRIPTING_FLAG ) );
   }

#if defined(USE_QUETZAL)
   if ( flag == GAME_SAVE )
   {
      status = !save_quetzal( tfp, gfp );
   }
   else if ( flag == GAME_RESTORE )
   {
      status = !restore_quetzal( tfp, gfp );
   }
   else
   {
#endif /* defined(USE_QUETZAL) */
      /* Push PC, FP, version and store SP in special location */

      stack[--sp] = ( zword_t ) ( pc / PAGE_SIZE );
      stack[--sp] = ( zword_t ) ( pc % PAGE_SIZE );
      stack[--sp] = fp;
      stack[--sp] = h_version;
      stack[0] = sp;

      /* Save or restore stack */

#if !defined(USE_QUETZAL)
      if ( flag == GAME_SAVE )
      {
         if ( little_endian )
            swap_bytes( stack, sizeof ( stack ) );
         if ( status == 0 && fwrite( stack, sizeof ( stack ), 1, tfp ) != 1 )
            status = 1;
         if ( little_endian )
            swap_bytes( stack, sizeof ( stack ) );
      }
      else if ( flag == GAME_RESTORE )
      {
         if ( little_endian )
            swap_bytes( stack, sizeof ( stack ) );
         if ( status == 0 && fread( stack, sizeof ( stack ), 1, tfp ) != 1 )
            status = 1;
         if ( little_endian )
            swap_bytes( stack, sizeof ( stack ) );
      }
      else
#endif /* !defined(USE_QUETZAL) */
      {
         if ( flag == UNDO_SAVE )
         {
            memmove( undo_stack, stack, sizeof ( stack ) );
         }
         else                   /* if (flag == UNDO_RESTORE) */
         {
            memmove( stack, undo_stack, sizeof ( stack ) );
         }
      }

      /* Restore SP, check version, restore FP and PC */

      sp = stack[0];

      if ( stack[sp++] != h_version )
      {
         fatal( "save_restore(): Wrong game or version" );
      }

      fp = stack[sp++];
      pc = stack[sp++];
      pc += ( unsigned long ) stack[sp++] * PAGE_SIZE;

      /* Save or restore writeable game data area */

#if !defined(USE_QUETZAL)
      if ( flag == GAME_SAVE )
      {
         if ( status == 0 && fwrite( datap, h_restart_size, 1, tfp ) != 1 )
            status = 1;
      }
      else if ( flag == GAME_RESTORE )
      {
         if ( status == 0 && fread( datap, h_restart_size, 1, tfp ) != 1 )
            status = 1;
      }
      else
#endif /* !defined(USE_QUETZAL) */
      {
         if ( flag == UNDO_SAVE )
         {
            memmove( undo_datap, datap, h_restart_size );
         }
         else                   /* if (flag == UNDO_RESTORE) */
         {
            memmove( datap, undo_datap, h_restart_size );
         }
      }

#if defined(USE_QUETZAL)
   }
#endif /* defined(USE_QUETZAL) */


   /* Close the save file and restore scripting */

   if ( flag == GAME_SAVE )
   {
      fclose( tfp );
      if ( scripting_flag )
      {
         set_word( H_FLAGS, get_word( H_FLAGS ) | SCRIPTING_FLAG );
      }
   }
   else if ( flag == GAME_RESTORE )
   {
      fclose( tfp );
      restart_screen(  );
      restart_interp( scripting_flag );
   }

   /* Handle read or write errors */

   if ( status )
   {
      if ( flag == GAME_SAVE )
      {
         output_line( "Write to SAVE file failed" );
         remove( file_name );
      }
      else
      {
         fatal( "save_restore(): Read from SAVE file failed" );
      }
   }

   return ( status );

}                               /* save_restore */
Exemple #2
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 */