Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Script.cpp 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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. assertEqual(gameflowSize, 128);
  24. firstOption = f.readU32();
  25. titleReplace = f.read32();
  26. onDeathDemoMode = f.readU32();
  27. onDeathInGame = f.readU32();
  28. noInputTime = f.readU32(); // Scaled *100 in TR3
  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. // Filler 3 (6 bytes)
  45. f.seek(f.tell() + 6);
  46. cypherCode = f.readU8();
  47. language = f.readU8();
  48. secretTrack = f.readU16(); // Zero in TR3, Part of filler or real number?
  49. // Filler 4 (4 bytes)
  50. f.seek(f.tell() + 4);
  51. // Strings
  52. readStringPackage(f, levelNames, numLevels);
  53. readStringPackage(f, pictureFilenames, numPictures);
  54. readStringPackage(f, titleFilenames, numTitles);
  55. readStringPackage(f, fmvFilenames, numFMVs);
  56. readStringPackage(f, levelFilenames, numLevels);
  57. readStringPackage(f, cutsceneFilenames, numCutscenes);
  58. // Level Scripts
  59. readScriptPackage(f, script, numLevels + 1);
  60. numGameStrings = f.readU16();
  61. // More strings...
  62. readStringPackage(f, gameStrings, numGameStrings);
  63. readStringPackage(f, pcStrings, 41);
  64. readStringPackage(f, puzzles[0], numLevels);
  65. readStringPackage(f, puzzles[1], numLevels);
  66. readStringPackage(f, puzzles[2], numLevels);
  67. readStringPackage(f, puzzles[3], numLevels);
  68. readStringPackage(f, pickups[0], numLevels);
  69. readStringPackage(f, pickups[1], numLevels);
  70. readStringPackage(f, keys[0], numLevels);
  71. readStringPackage(f, keys[1], numLevels);
  72. readStringPackage(f, keys[2], numLevels);
  73. readStringPackage(f, keys[3], numLevels);
  74. return 0;
  75. }
  76. void Script::readStringPackage(BinaryFile &f, std::vector<std::string> &v, unsigned int n) {
  77. uint16_t *offset = new uint16_t[n];
  78. for (unsigned int i = 0; i < n; i++)
  79. offset[i] = f.readU16();
  80. uint16_t numBytes = f.readU16();
  81. char *list = new char[numBytes];
  82. for (uint16_t i = 0; i < numBytes; i++) {
  83. list[i] = f.read8();
  84. if (flags & S_UseSecurityTag) {
  85. list[i] ^= cypherCode;
  86. }
  87. }
  88. for (unsigned int i = 0; i < n; i++) {
  89. std::string tmp(list + offset[i]);
  90. v.push_back(tmp);
  91. }
  92. delete [] list;
  93. delete [] offset;
  94. }
  95. void Script::readScriptPackage(BinaryFile &f, std::vector<std::vector<uint16_t>> &v, unsigned int n) {
  96. uint16_t *offset = new uint16_t[n];
  97. for (unsigned int i = 0; i < n; i++) {
  98. offset[i] = f.readU16();
  99. assertEqual(offset[i] % 2, 0);
  100. }
  101. uint16_t numBytes = f.readU16();
  102. assertEqual(numBytes % 2, 0); // 16 bit opcodes and operands
  103. // Only TR2, not TR3, has 6 "filler bytes" hex 13 00 14 00 15 00 here
  104. // We need to skip these
  105. uint16_t hack1 = f.readU16();
  106. uint16_t hack2 = f.readU16();
  107. uint16_t hack3 = f.readU16();
  108. uint16_t hackStart = 0;
  109. uint16_t *list = new uint16_t[(numBytes + 6) / 2];
  110. if ((hack1 == 19) && (hack2 == 20) && (hack3 == 21)) {
  111. numBytes += 6;
  112. } else {
  113. list[0] = hack1;
  114. list[1] = hack2;
  115. list[2] = hack3;
  116. hackStart = 3;
  117. }
  118. for (uint16_t i = hackStart; i < (numBytes / 2); i++) {
  119. list[i] = f.readU16();
  120. }
  121. for (unsigned int i = 0; i < n; i++) {
  122. unsigned int end = offset[i] / 2;
  123. bool readingOperand = false;
  124. while (readingOperand || (list[end] != OP_END)) {
  125. if (readingOperand) {
  126. readingOperand = false;
  127. end++;
  128. } else {
  129. if (opcodeHasOperand[list[end]]) {
  130. readingOperand = true;
  131. }
  132. end++;
  133. }
  134. }
  135. end++;
  136. std::vector<uint16_t> tmp;
  137. for (unsigned int a = (offset[i] / 2); a < end; a++)
  138. tmp.push_back(list[a]);
  139. v.push_back(tmp);
  140. }
  141. delete [] list;
  142. delete [] offset;
  143. }
  144. unsigned int Script::levelCount() {
  145. return numLevels;
  146. }
  147. std::string Script::getLevelName(unsigned int i) {
  148. assert(i < numLevels);
  149. return levelNames.at(i);
  150. }
  151. std::string Script::getLevelFilename(unsigned int i) {
  152. assert(i < numLevels);
  153. return levelFilenames.at(i);
  154. }
  155. unsigned int Script::cutsceneCount() {
  156. return numCutscenes;
  157. }
  158. std::string Script::getCutsceneFilename(unsigned int i) {
  159. assert(i < numCutscenes);
  160. return cutsceneFilenames.at(i);
  161. }
  162. unsigned int Script::titleCount() {
  163. return numTitles;
  164. }
  165. std::string Script::getTitleFilename(unsigned int i) {
  166. assert(i < numTitles);
  167. return titleFilenames.at(i);
  168. }
  169. unsigned int Script::videoCount() {
  170. return numFMVs;
  171. }
  172. std::string Script::getVideoFilename(unsigned int i) {
  173. assert(i < numFMVs);
  174. return fmvFilenames.at(i);
  175. }
  176. unsigned int Script::gameStringCount() {
  177. return numGameStrings;
  178. }
  179. std::string Script::getGameString(unsigned int i) {
  180. assert(i < numGameStrings);
  181. return gameStrings.at(i);
  182. }
  183. unsigned int Script::pcStringCount() {
  184. return 41;
  185. }
  186. std::string Script::getPCString(unsigned int i) {
  187. assert(i < 41);
  188. return pcStrings.at(i);
  189. }
  190. std::string Script::getPuzzleString(unsigned int i, unsigned int j) {
  191. assert(i < 4);
  192. assert(j < numLevels);
  193. return puzzles.at(i).at(j);
  194. }
  195. std::string Script::getPickupString(unsigned int i, unsigned int j) {
  196. assert(i < 2);
  197. assert(j < numLevels);
  198. return pickups.at(i).at(j);
  199. }
  200. std::string Script::getKeyString(unsigned int i, unsigned int j) {
  201. assert(i < 4);
  202. assert(j < numLevels);
  203. return keys.at(i).at(j);
  204. }
  205. void Script::registerScriptHandler(ScriptOpCode op, std::function<int (bool, uint16_t)> func) {
  206. assert(op < OP_UNKNOWN);
  207. scriptHandlers[op] = func;
  208. }
  209. int Script::runScript(unsigned int level) {
  210. assert(level < (numLevels + 1));
  211. std::vector<uint16_t> s = script.at(level);
  212. for (unsigned int i = 0; i < s.size(); i++) {
  213. uint16_t opcode = s.at(i);
  214. if (opcode >= OP_UNKNOWN) {
  215. return 1;
  216. }
  217. uint16_t operand = 0;
  218. if (opcodeHasOperand[opcode]) {
  219. if ((i + 1) >= s.size())
  220. return 2; // Can't read operand!
  221. operand = s.at(++i);
  222. }
  223. if (scriptHandlers[opcode]) {
  224. int error = scriptHandlers[opcode](opcodeHasOperand[opcode], operand);
  225. if (error != 0)
  226. return error;
  227. } else {
  228. return 3;
  229. }
  230. }
  231. return 0;
  232. }