Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*!
  2. * \file src/Script.cpp
  3. * \brief Game script loader
  4. *
  5. * \author xythobuz
  6. */
  7. #include "global.h"
  8. #include "Script.h"
  9. Script::Script() : puzzles(4), pickups(2), keys(4) {
  10. }
  11. Script::~Script() {
  12. }
  13. int Script::load(const char *file) {
  14. BinaryFile f;
  15. if (f.open(file) != 0)
  16. return 1;
  17. version = f.readU32();
  18. char desc[256];
  19. for (int i = 0; i < 256; i++)
  20. desc[i] = f.read8();
  21. description = desc;
  22. uint16_t gameflowSize = f.readU16();
  23. assert(gameflowSize == 128);
  24. firstOption = f.readU32();
  25. titleReplace = f.read32();
  26. onDeathDemoMode = f.readU32();
  27. onDeathInGame = f.readU32();
  28. noInputTime = f.readU32();
  29. onDemoInterrupt = f.readU32();
  30. onDemoEnd = f.readU32();
  31. // Filler 1 (36 bytes)
  32. f.seek(f.tell() + 36);
  33. numLevels = f.readU16();
  34. numPictures = f.readU16();
  35. numTitles = f.readU16();
  36. numFMVs = f.readU16();
  37. numCutscenes = f.readU16();
  38. numDemos = f.readU16();
  39. titleTrack = f.readU16();
  40. singleLevel = f.read16();
  41. // Filler 2 (32 bytes)
  42. f.seek(f.tell() + 32);
  43. flags = f.readU16();
  44. bool tag = (flags & S_UseSecurityTag) != 0;
  45. // Filler 3 (6 bytes)
  46. f.seek(f.tell() + 6);
  47. cypherCode = f.readU8();
  48. language = f.readU8();
  49. secretTrack = f.readU16();
  50. // Filler 4 (4 bytes)
  51. f.seek(f.tell() + 4);
  52. // Strings
  53. readStringPackage(f, levelNames, numLevels, tag, 0);
  54. readStringPackage(f, pictureFilenames, numPictures, tag, 0);
  55. readStringPackage(f, titleFilenames, numTitles, tag, 0);
  56. readStringPackage(f, fmvFilenames, numFMVs, tag, 0);
  57. readStringPackage(f, levelFilenames, numLevels, tag, 0);
  58. readStringPackage(f, cutsceneFilenames, numCutscenes, tag, 0);
  59. // Offset definitely TR2 specific?!
  60. readStringPackage(f, script, numLevels + 1, false, 6);
  61. numGameStrings = f.readU16();
  62. assert(numGameStrings == 89);
  63. readStringPackage(f, gameStrings, numGameStrings, tag, 0);
  64. readStringPackage(f, pcStrings, 41, tag, 0);
  65. readStringPackage(f, puzzles[0], numLevels, tag, 0);
  66. readStringPackage(f, puzzles[1], numLevels, tag, 0);
  67. readStringPackage(f, puzzles[2], numLevels, tag, 0);
  68. readStringPackage(f, puzzles[3], numLevels, tag, 0);
  69. readStringPackage(f, pickups[0], numLevels, tag, 0);
  70. readStringPackage(f, pickups[1], numLevels, tag, 0);
  71. readStringPackage(f, keys[0], numLevels, tag, 0);
  72. readStringPackage(f, keys[1], numLevels, tag, 0);
  73. readStringPackage(f, keys[2], numLevels, tag, 0);
  74. readStringPackage(f, keys[3], numLevels, tag, 0);
  75. return 0;
  76. }
  77. void Script::readStringPackage(BinaryFile &f, std::vector<std::string> &v, unsigned int n, bool tag, uint16_t off) {
  78. uint16_t *offset = new uint16_t[n];
  79. for (unsigned int i = 0; i < n; i++)
  80. offset[i] = f.readU16();
  81. uint16_t numBytes = f.readU16() + off;
  82. char *list = new char[numBytes];
  83. for (uint16_t i = 0; i < numBytes; i++) {
  84. list[i] = f.read8();
  85. if (tag) {
  86. list[i] ^= cypherCode;
  87. }
  88. }
  89. for (unsigned int i = 0; i < n; i++) {
  90. std::string tmp(list + offset[i]);
  91. v.push_back(tmp);
  92. }
  93. delete [] list;
  94. delete [] offset;
  95. }
  96. unsigned int Script::levelCount() {
  97. return numLevels;
  98. }
  99. std::string Script::getLevelName(unsigned int i) {
  100. assert(i < numLevels);
  101. return levelNames.at(i);
  102. }
  103. std::string Script::getLevelFilename(unsigned int i) {
  104. assert(i < numLevels);
  105. return levelFilenames.at(i);
  106. }
  107. unsigned int Script::cutsceneCount() {
  108. return numCutscenes;
  109. }
  110. std::string Script::getCutsceneFilename(unsigned int i) {
  111. assert(i < numCutscenes);
  112. return cutsceneFilenames.at(i);
  113. }
  114. unsigned int Script::titleCount() {
  115. return numTitles;
  116. }
  117. std::string Script::getTitleFilename(unsigned int i) {
  118. assert(i < numTitles);
  119. return titleFilenames.at(i);
  120. }
  121. unsigned int Script::videoCount() {
  122. return numFMVs;
  123. }
  124. std::string Script::getVideoFilename(unsigned int i) {
  125. assert(i < numFMVs);
  126. return fmvFilenames.at(i);
  127. }
  128. unsigned int Script::gameStringCount() {
  129. return numGameStrings;
  130. }
  131. std::string Script::getGameString(unsigned int i) {
  132. assert(i < numGameStrings);
  133. return gameStrings.at(i);
  134. }
  135. unsigned int Script::pcStringCount() {
  136. return 41;
  137. }
  138. std::string Script::getPCString(unsigned int i) {
  139. assert(i < 41);
  140. return pcStrings.at(i);
  141. }
  142. std::string Script::getPuzzleString(unsigned int i, unsigned int j) {
  143. assert(i < 4);
  144. assert(j < numLevels);
  145. return puzzles.at(i).at(j);
  146. }
  147. std::string Script::getPickupString(unsigned int i, unsigned int j) {
  148. assert(i < 2);
  149. assert(j < numLevels);
  150. return pickups.at(i).at(j);
  151. }
  152. std::string Script::getKeyString(unsigned int i, unsigned int j) {
  153. assert(i < 4);
  154. assert(j < numLevels);
  155. return keys.at(i).at(j);
  156. }