/src/x11/x_blorb.c

https://gitlab.com/ake.forslund/frotz · C · 162 lines · 79 code · 26 blank · 57 comment · 22 complexity · 0b75f987001c5b73bea0b43d19c9306b MD5 · raw file

  1. /*
  2. * x_blorb.c - Blorb routines
  3. *
  4. * This file is part of Frotz.
  5. *
  6. * Frotz is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Frotz is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  19. * Or visit http://www.fsf.org/
  20. *
  21. */
  22. #include "x_frotz.h"
  23. #include "x_blorb.h"
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <unistd.h>
  28. #include <math.h>
  29. #ifndef NO_BLORB
  30. extern f_setup_t f_setup;
  31. FILE *blorb_fp;
  32. bb_result_t blorb_res;
  33. bb_map_t *blorb_map;
  34. static int isblorb(FILE *);
  35. #define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
  36. /*
  37. * x_blorb_init
  38. *
  39. * Check if we're opening a Blorb file directly. If not, check
  40. * to see if there's a separate Blorb file that looks like it goes
  41. * along with this Zcode file. If we have a Blorb file one way or the
  42. * other, make a Blorb map. If we opened a Blorb file directly, that
  43. * means that our executable is in that file and therefore we will look
  44. * for a ZCOD chunk and record its location so os_load_story() can find it.
  45. * Make sure the Blorb file is opened and with the file pointer blorb_fp.
  46. */
  47. bb_err_t x_blorb_init(char *filename)
  48. {
  49. FILE *fp;
  50. char *p;
  51. char *mystring;
  52. int len1;
  53. int len2;
  54. bb_err_t blorb_err;
  55. if ((fp = fopen(filename, "rb")) == NULL)
  56. return bb_err_Read;
  57. /* Is this really a Blorb file?
  58. * If not, maybe we're loading a naked zcode file
  59. * and our resources are in a separate blorb file.
  60. */
  61. if (isblorb(fp)) { /* Now we know to look */
  62. f_setup.exec_in_blorb = 1; /* for zcode in the blorb */
  63. blorb_fp = fp;
  64. } else {
  65. fclose(fp);
  66. len1 = strlen(filename) + strlen(EXT_BLORB);
  67. len2 = strlen(filename) + strlen(EXT_BLORB3);
  68. if (f_setup.blorb_file != NULL)
  69. mystring = strdup(f_setup.blorb_file);
  70. else {
  71. mystring = malloc(MAX(len1, len2) * sizeof(char) + 1);
  72. memcpy(mystring, filename, MAX(len1, len2) * sizeof(char));
  73. p = strrchr(mystring, '.');
  74. if (p != NULL) *p = '\0';
  75. strncat(mystring, EXT_BLORB, len1);
  76. }
  77. /* Check if foo.blb is there. */
  78. if ((fp = fopen(mystring, "rb")) == NULL) {
  79. p = strrchr(mystring, '.');
  80. if (p != NULL) *p = '\0';
  81. strncat(mystring, EXT_BLORB3, len2);
  82. if (!(fp = fopen(mystring, "rb")))
  83. return bb_err_NoBlorb;
  84. }
  85. if (!isblorb(fp)) {
  86. fclose(fp);
  87. return bb_err_NoBlorb;
  88. }
  89. /* At this point we know that we're using a naked zcode file */
  90. /* with resources in a separate Blorb file. */
  91. blorb_fp = fp;
  92. f_setup.use_blorb = 1;
  93. /*
  94. if (f_setup.blorb_file == NULL)
  95. printf("Found Blorb file named %s.\n", mystring);
  96. */
  97. }
  98. /* Create a Blorb map from this file.
  99. * This will fail if the file is not a valid Blorb file.
  100. * From this map, we can now pick out any resource we need.
  101. */
  102. blorb_err = bb_create_map(blorb_fp, &blorb_map);
  103. if (blorb_err != bb_err_None)
  104. return bb_err_Format;
  105. /* Locate the EXEC chunk within the blorb file and record its
  106. * location so os_load_story() can find it.
  107. */
  108. if (f_setup.exec_in_blorb) {
  109. blorb_err = bb_load_chunk_by_type(blorb_map, bb_method_FilePos,
  110. &blorb_res, bb_ID_ZCOD, 0);
  111. f_setup.exec_in_blorb = 1;
  112. /* printf("Found zcode chunk in Blorb file.\n"); */
  113. }
  114. return blorb_err;
  115. }
  116. /*
  117. * isblorb
  118. *
  119. * Returns 1 if this file is a Blorb file, 0 if not.
  120. *
  121. */
  122. static int isblorb(FILE *fp)
  123. {
  124. char mybuf[4];
  125. if (fp == NULL)
  126. return 0;
  127. fread(mybuf, 1, 4, fp);
  128. if (strncmp(mybuf, "FORM", 4))
  129. return 0;
  130. fseek(fp, 4, SEEK_CUR);
  131. fread(mybuf, 1, 4, fp);
  132. if (strncmp(mybuf, "IFRS", 4))
  133. return 0;
  134. return 1;
  135. }
  136. #endif /* NO_BLORB */