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.

script.bfft 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * script.bfft - Tomb Raider 1 - 3 Engine Script Format Description
  3. * 2014, Thomas Buck <xythobuz@xythobuz.de>
  4. *
  5. * Based on the TR Rosetta Stone (http://www.tnlc.com/eep/tr/TRosettaStone.html),
  6. * this document (http://xythobuz.de/tr_docs/TombPC_TR2.pdf),
  7. * and my own reverse-engineering efforts.
  8. * Developed for Binspector (https://github.com/binspector/binspector)
  9. */
  10. // ########## General data structures ##########
  11. struct strings_t {
  12. unsigned 16 little stringOffsets[stringsInPackage];
  13. unsigned 16 little stringDataSize;
  14. unsigned 8 little stringData[stringDataSize];
  15. }
  16. struct script_t {
  17. unsigned 16 little sciprOffsets[stringsInPackage];
  18. unsigned 16 little scriptDataSize;
  19. unsigned 16 little scriptData[scriptDataSize / 2];
  20. }
  21. struct hack_t {
  22. signal isTR2 = 0;
  23. signal isPCVersion = 1;
  24. if ((peek() == 0x13) || (peek() == 0x15)) {
  25. // TR2 for PC and PSX has 6 "filler bytes" hex 13 00 14 00 15 00
  26. // (for TR3 for PSX, the filler is hex 15 00 16 00 17 00 instead)
  27. // at the end of the script block. We need to skip these...
  28. if (peek() == 0x13) {
  29. signal isTR2 = 1;
  30. } else {
  31. signal isTR2 = 0;
  32. signal isPCVersion = 0;
  33. }
  34. skip hack[6];
  35. }
  36. if (peek() == 0x01) {
  37. // TR2 for PSX has 64 bytes with unknown content (not zero!) here,
  38. // TR3 for PSX has 40 bytes. We try to identify and skip them (both start with 1)...
  39. // This is also currently used to set the platform specific string count
  40. if (isTR2 == 1) {
  41. signal isPCVersion = 0;
  42. skip hackPSX[64];
  43. } else {
  44. skip hackPSX[40];
  45. }
  46. }
  47. if (isTR2 == 1) {
  48. if (isPCVersion == 1) {
  49. notify "TR2 PC Version detected!";
  50. signal numPCStrings = 41;
  51. } else {
  52. notify "TR2 PSX Version detected!";
  53. signal numPCStrings = 80;
  54. }
  55. } else {
  56. if (isPCVersion == 1) {
  57. notify "TR3 PC Version detected!";
  58. signal numPCStrings = 41;
  59. } else {
  60. notify "TR3 PSX Version detected!";
  61. signal numPCStrings = 80;
  62. }
  63. }
  64. }
  65. // ########## Main file layout ##########
  66. struct main {
  67. unsigned 32 little version;
  68. unsigned 8 little description[256];
  69. unsigned 16 little gameflowSize;
  70. if (gameflowSize != 128)
  71. die "Invalid gameflow size!";
  72. unsigned 32 little firstOption;
  73. signed 32 little titleReplace;
  74. unsigned 32 little onDeathDemoMode;
  75. unsigned 32 little onDeathInGame;
  76. // Scaled * 100 in TR3
  77. unsigned 32 little noInputTime;
  78. unsigned 32 little onDemoInterrupt;
  79. unsigned 32 little onDemoEnd;
  80. skip filler1[36];
  81. unsigned 16 little numLevels;
  82. unsigned 16 little numPictures;
  83. unsigned 16 little numTitles;
  84. unsigned 16 little numFMVs;
  85. unsigned 16 little numCutscenes;
  86. unsigned 16 little numDemos;
  87. unsigned 16 little titleTrack;
  88. signed 16 little singleLevel;
  89. skip filler2[32];
  90. unsigned 16 little flags;
  91. skip filler3[6];
  92. unsigned 8 little cypherCode;
  93. unsigned 8 little language;
  94. // Zero in TR3, Part of filler or real number?
  95. unsigned 16 little secretTrack;
  96. skip filler4[4];
  97. slot stringsInPackage = numLevels;
  98. strings_t levelDisplayNames;
  99. signal stringsInPackage = numPictures;
  100. strings_t pictures;
  101. signal stringsInPackage = numTitles;
  102. strings_t titleFilenames;
  103. signal stringsInPackage = numFMVs;
  104. strings_t fmvFilenames;
  105. signal stringsInPackage = numLevels;
  106. strings_t levelFilenames;
  107. signal stringsInPackage = numCutscenes;
  108. strings_t cutsceneFilenames;
  109. signal stringsInPackage = numLevels + 1;
  110. script_t script;
  111. slot numPCStrings = 41; // PC Version has 41 pcStrings
  112. slot isPCVersion = 1;
  113. slot isTR2 = 1;
  114. hack_t hack;
  115. unsigned 16 little numGameStrings;
  116. signal stringsInPackage = numGameStrings;
  117. strings_t gameStrings;
  118. signal stringsInPackage = numPCStrings;
  119. strings_t pcStrings;
  120. signal stringsInPackage = numLevels;
  121. strings_t puzzles[4];
  122. strings_t pickups[2];
  123. strings_t keys[4];
  124. }