home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / compress / filearchivers / zip / zip-1.00.lha / fileio.c < prev    next >
C/C++ Source or Header  |  1992-10-09  |  10KB  |  542 lines

  1. /*
  2.  * fileio.c
  3.  *
  4.  * File manipulation routines. Should be generic.
  5.  *
  6.  * Mark Howell 28-Jul-1992 V1.0
  7.  *
  8.  */
  9.  
  10. #include "ztypes.h"
  11.  
  12. /* Static data */
  13.  
  14. static FILE *gfp = NULL;
  15. static FILE *sfp = NULL;
  16. static char save_name[FILENAME_MAX + 1] = "";
  17. static char script_name[FILENAME_MAX + 1] = "";
  18.  
  19. /*
  20.  * open_story
  21.  *
  22.  * Open game file for read.
  23.  *
  24.  */
  25.  
  26. #ifdef __STDC__
  27. void open_story (const char *storyname)
  28. #else
  29. void open_story (storyname)
  30. const char *storyname;
  31. #endif
  32. {
  33.  
  34.     gfp = fopen (storyname, "rb");
  35.     if (gfp == NULL)
  36.         fatal ("Game file not found");
  37.  
  38. }/* open_story */
  39.  
  40. /*
  41.  * close_story
  42.  *
  43.  * Close game file if open.
  44.  *
  45.  */
  46.  
  47. #ifdef __STDC__
  48. void close_story (void)
  49. #else
  50. void close_story ()
  51. #endif
  52. {
  53.  
  54.     if (gfp != NULL)
  55.         fclose (gfp);
  56.  
  57. }/* close_story */
  58.  
  59. /*
  60.  * get_story_size
  61.  *
  62.  * Calculate the size of the game file. Only used for very old games that do not
  63.  * have the game file size in the header.
  64.  *
  65.  */
  66.  
  67. #ifdef __STDC__
  68. int get_story_size (void)
  69. #else
  70. int get_story_size ()
  71. #endif
  72. {
  73.     unsigned long file_length;
  74.  
  75.     /* Seek to end of file to calculate length */
  76.  
  77.     fseek (gfp, 0L, SEEK_END);
  78.     file_length = (unsigned long) ftell (gfp);
  79.     rewind (gfp);
  80.  
  81.     /* Calculate length of file in game allocation units */
  82.  
  83.     file_length = (file_length + (unsigned long) (story_scaler - 1)) / (unsigned long) story_scaler;
  84.  
  85.     return ((int) file_length);
  86.  
  87. }/* get_story_size */
  88.  
  89. /*
  90.  * read_page
  91.  *
  92.  * Read one game file page.
  93.  *
  94.  */
  95.  
  96. #ifdef __STDC__
  97. void read_page (int page, void *buffer)
  98. #else
  99. void read_page (page, buffer)
  100. int page;
  101. void *buffer;
  102. #endif
  103. {
  104.     unsigned long file_size;
  105.     unsigned int pages, offset;
  106.  
  107.     /* Seek to start of page */
  108.  
  109.     fseek (gfp, (long) page * PAGE_SIZE, SEEK_SET);
  110.  
  111.     /* Read the page */
  112.  
  113.     if (fread (buffer, PAGE_SIZE, 1, gfp) != 1) {
  114.  
  115.         /* Read failed. Are we in the last page? */
  116.  
  117.         file_size = (unsigned long) h_file_size * story_scaler;
  118.         pages = (unsigned int) ((unsigned long) file_size / PAGE_SIZE);
  119.         offset = (unsigned int) ((unsigned long) file_size & PAGE_MASK);
  120.         if ((unsigned int) page == pages) {
  121.  
  122.             /* Read partial page if this is the last page in the game file */
  123.  
  124.             fseek (gfp, (long) page * PAGE_SIZE, SEEK_SET);
  125.             if (fread (buffer, offset, 1, gfp) == 1)
  126.                 return;
  127.         }
  128.         fatal ("Game file read error");
  129.     }
  130.  
  131. }/* read_page */
  132.  
  133. /*
  134.  * verify
  135.  *
  136.  * Verify game ($verify verb). Add all bytes in game file except for bytes in
  137.  * the game file header.
  138.  *
  139.  */
  140.  
  141. #ifdef __STDC__
  142. void verify (void)
  143. #else
  144. void verify ()
  145. #endif
  146. {
  147.     unsigned long file_size;
  148.     unsigned int pages, offset;
  149.     unsigned int start, end, i, j;
  150.     zword_t checksum = 0;
  151.     zbyte_t buffer[PAGE_SIZE];
  152.  
  153.     /* Print version banner */
  154.  
  155.     if (h_type == V3) {
  156.         write_string ("ZIP Interpreter ");
  157.         print_number (get_byte (H_INTERPRETER));
  158.         write_string (", Version ");
  159.         write_char (get_byte (H_INTERPRETER_VERSION));
  160.         write_string (".");
  161.         flush_buffer (TRUE);
  162.     }
  163.  
  164.     /* Calculate game file dimensions */
  165.  
  166.     file_size = (unsigned long) h_file_size * story_scaler;
  167.     pages = (unsigned int) ((unsigned long) file_size / PAGE_SIZE);
  168.     offset = (unsigned int) file_size & PAGE_MASK;
  169.  
  170.     /* Sum all bytes in game file, except header bytes */
  171.  
  172.     for (i = 0; i <= pages; i++) {
  173.         read_page (i, buffer);
  174.         start = (i == 0) ? 64 : 0;
  175.         end = (i == pages) ? offset : PAGE_SIZE;
  176.         for (j = start; j < end; j++)
  177.             checksum += buffer[j];
  178.     }
  179.  
  180.     /* Make a conditional jump based on whether the checksum is equal */
  181.  
  182.     conditional_jump (checksum == h_checksum);
  183.  
  184. }/* verify */
  185.  
  186. /*
  187.  * save
  188.  *
  189.  * Save game state to disk.
  190.  *
  191.  */
  192.  
  193. #ifdef __STDC__
  194. int save (void)
  195. #else
  196. int save ()
  197. #endif
  198. {
  199.     char new_save_name[FILENAME_MAX + 1];
  200.     int status;
  201.  
  202.     /* Get the file name */
  203.  
  204.     if (get_file_name (new_save_name, save_name, GAME_SAVE) != TRUE)
  205.         return (1);
  206.  
  207.     /* Do save operation */
  208.  
  209.     if (status = save_restore (new_save_name, GAME_SAVE))
  210.  
  211.         /* Perform error action */
  212.  
  213.         if (h_type == V3)
  214.             conditional_jump (0);
  215.         else
  216.             store_operand (0);
  217.     else {
  218.  
  219.         /* Perform success action */
  220.  
  221.         if (h_type == V3)
  222.             conditional_jump (1);
  223.         else
  224.             store_operand (1);
  225.  
  226.         /* Cleanup and remember file name */
  227.  
  228.         file_cleanup (new_save_name, GAME_SAVE);
  229.  
  230.         strcpy (save_name, new_save_name);
  231.  
  232.     }
  233.  
  234.     return (status);
  235.  
  236. }/* save */
  237.  
  238. /*
  239.  * restore
  240.  *
  241.  * Restore game state from disk.
  242.  *
  243.  */
  244.  
  245. #ifdef __STDC__
  246. int restore (void)
  247. #else
  248. int restore ()
  249. #endif
  250. {
  251.     char new_save_name[FILENAME_MAX + 1];
  252.     int status;
  253.  
  254.     /* Get the file name */
  255.  
  256.     if (restore_name != NULL) {
  257.         strcpy (new_save_name, restore_name);
  258.         restore_name = NULL;
  259.     } else
  260.         if (get_file_name (new_save_name, save_name, GAME_RESTORE) != TRUE)
  261.             return (1);
  262.  
  263.     /* Do restore operation */
  264.  
  265.     if (status = save_restore (new_save_name, GAME_RESTORE))
  266.  
  267.         /* perform error action */
  268.  
  269.         if (h_type == V3)
  270.             conditional_jump (0);
  271.         else
  272.             store_operand (0);
  273.     else {
  274.  
  275.         /* Perform success action */
  276.  
  277.         if (h_type == V3)
  278.             conditional_jump (1);
  279.         else
  280.             store_operand (2);
  281.  
  282.         /* Cleanup and remember file name */
  283.  
  284.         file_cleanup (new_save_name, GAME_RESTORE);
  285.  
  286.         strcpy (save_name, new_save_name);
  287.  
  288.     }
  289.  
  290.     return (status);
  291.  
  292. }/* restore */
  293.  
  294. /*
  295.  * save_restore
  296.  *
  297.  * Common save and restore code. Just save or restore the game stack and the
  298.  * writeable data area.
  299.  *
  300.  */
  301.  
  302. #ifdef __STDC__
  303. int save_restore (const char *file_name, int flag)
  304. #else
  305. int save_restore (file_name, flag)
  306. const char *file_name;
  307. int flag;
  308. #endif
  309. {
  310.     FILE *tfp;
  311.     int scripting;
  312.  
  313.     /* Open the save file */
  314.  
  315.     if (flag == GAME_SAVE) {
  316.         if ((tfp = fopen (file_name, "wb")) == NULL)
  317.             output_stringnl ("Unable to access file");
  318.     } else {
  319.         if ((tfp = fopen (file_name, "rb")) == NULL)
  320.             output_stringnl ("SAVE file not found");
  321.     }
  322.     if (tfp == NULL)
  323.         return (1);
  324.  
  325.     /* Save state of scripting */
  326.  
  327.     scripting = get_word (H_FLAGS) & SCRIPTING_FLAG;
  328.  
  329.     /* Push PC, FP, version and store SP in special location */
  330.  
  331.     stack[--sp] = (zword_t) (pc / PAGE_SIZE);
  332.     stack[--sp] = (zword_t) (pc % PAGE_SIZE);
  333.     stack[--sp] = fp;
  334.     stack[--sp] = h_version;
  335.     stack[0] = sp;
  336.  
  337.     /* Save or restore stack */
  338.  
  339.     if (flag == GAME_SAVE) {
  340.         if (fwrite (stack, sizeof (stack), 1, tfp) != 1) {
  341.             fclose (tfp);
  342.             remove (file_name);
  343.             output_stringnl ("No room for SAVE file");
  344.             tfp = NULL;
  345.         }
  346.     } else {
  347.         if (fread (stack, sizeof (stack), 1, tfp) != 1) {
  348.             fclose (tfp);
  349.             output_stringnl ("Read of SAVE file failed");
  350.             tfp = NULL;
  351.         }
  352.     }
  353.  
  354.     /* Restore SP, check version, restore FP and PC */
  355.  
  356.     sp = stack[0];
  357.     if (stack[sp++] != h_version)
  358.         fatal ("Wrong game or version");
  359.     fp = stack[sp++];
  360.     pc = stack[sp++];
  361.     pc += (unsigned long) stack[sp++] * PAGE_SIZE;
  362.  
  363.     if (tfp == NULL)
  364.         return (1);
  365.  
  366.     /* Save or restore writeable game data area */
  367.  
  368.     if (flag == GAME_SAVE) {
  369.         if (fwrite (datap, h_restart_size, 1, tfp) != 1) {
  370.             fclose (tfp);
  371.             remove (file_name);
  372.             output_stringnl ("No room for SAVE file");
  373.             tfp = NULL;
  374.         }
  375.     } else {
  376.         if (fread (datap, h_restart_size, 1, tfp) != 1) {
  377.             fclose (tfp);
  378.             output_stringnl ("Read of SAVE file failed");
  379.             tfp = NULL;
  380.         }
  381.     }
  382.  
  383.     /* Restore scripting state */
  384.  
  385.     set_word (H_FLAGS, scripting);
  386.  
  387.     if (tfp == NULL)
  388.         return (1);
  389.  
  390.     fclose (tfp);
  391.  
  392.     return (0);
  393.  
  394. }/* save_restore */
  395.  
  396. /*
  397.  * open_script
  398.  *
  399.  * Open the scripting file.
  400.  *
  401.  */
  402.  
  403. #ifdef __STDC__
  404. void open_script (void)
  405. #else
  406. void open_script ()
  407. #endif
  408. {
  409.     char new_script_name[FILENAME_MAX + 1];
  410.  
  411.     /* Get scripting file name */
  412.  
  413.     if (get_file_name (new_script_name, script_name, GAME_SCRIPT) != TRUE)
  414.         return;
  415.  
  416.     /* Open scripting file */
  417.  
  418.     sfp = fopen (new_script_name, "w");
  419.  
  420.     /* Turn off scripting if open failed */
  421.  
  422.     if (sfp == NULL) {
  423.         set_word (H_FLAGS, get_word (H_FLAGS) & (~SCRIPTING_FLAG));
  424.         output_stringnl ("Script file create failed");
  425.         return;
  426.     }
  427.  
  428.     /* Remember scripting name */
  429.  
  430.     strcpy (script_name, new_script_name);
  431.  
  432. }/* open_script */
  433.  
  434. /*
  435.  * close_script
  436.  *
  437.  * Close the scripting file.
  438.  *
  439.  */
  440.  
  441. #ifdef __STDC__
  442. void close_script (void)
  443. #else
  444. void close_script ()
  445. #endif
  446. {
  447.  
  448.     /* Close scripting file */
  449.  
  450.     if (sfp != NULL) {
  451.         fclose (sfp);
  452.         sfp = NULL;
  453.  
  454.         /* Cleanup */
  455.  
  456.         file_cleanup (script_name, GAME_SCRIPT);
  457.     }
  458.     set_word (H_FLAGS, get_word (H_FLAGS) & (~SCRIPTING_FLAG));
  459.  
  460. }/* close_script */
  461.  
  462. /*
  463.  * script_char
  464.  *
  465.  * Write one character to scripting file.
  466.  *
  467.  */
  468.  
  469. #ifdef __STDC__
  470. void script_char (char c)
  471. #else
  472. void script_char (c)
  473. char c;
  474. #endif
  475. {
  476.  
  477.     /* Only write character if scripting is on */
  478.  
  479.     if (get_word (H_FLAGS) & SCRIPTING_FLAG) {
  480.  
  481.         /* If scripting file is not open then open it */
  482.  
  483.         if (h_type == V3 && sfp == NULL)
  484.             open_script ();
  485.  
  486.         /* If scripting file is open then write the character */
  487.  
  488.         if (sfp != NULL)
  489.             putc (c, sfp);
  490.     } else
  491.  
  492.         /* Close scripting file if it is open */
  493.  
  494.         if (h_type == V3 && sfp != NULL)
  495.             close_script ();
  496.  
  497. }/* script_char */
  498.  
  499. /*
  500.  * script_line
  501.  *
  502.  * Write a string followed by a new line to the scripting file.
  503.  *
  504.  */
  505.  
  506. #ifdef __STDC__
  507. void script_line (const char *s)
  508. #else
  509. void script_line (s)
  510. const char *s;
  511. #endif
  512. {
  513.  
  514.     /* Write string */
  515.  
  516.     while (*s)
  517.         script_char (*s++);
  518.  
  519.     /* Write new line */
  520.  
  521.     script_nl ();
  522.  
  523. }/* script_line */
  524.  
  525. /*
  526.  * script_nl
  527.  *
  528.  * Write a new line to the scripting file.
  529.  *
  530.  */
  531.  
  532. #ifdef __STDC__
  533. void script_nl (void)
  534. #else
  535. void script_nl ()
  536. #endif
  537. {
  538.  
  539.     script_char ('\n');
  540.  
  541. }/* script_nl */
  542.