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.

LoaderTR2.cpp 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. /*!
  2. * \file src/loader/LoaderTR2.cpp
  3. * \brief TR2 level file loader
  4. *
  5. * \author xythobuz
  6. */
  7. #include <array>
  8. #include <cstdint>
  9. #include <vector>
  10. #include "global.h"
  11. #include "Log.h"
  12. #include "loader/LoaderTR2.h"
  13. LoaderTR2::LoaderTR2() {
  14. }
  15. LoaderTR2::~LoaderTR2() {
  16. }
  17. int LoaderTR2::load(std::string f) {
  18. if (file.open(f.c_str()) != 0) {
  19. return 1; // Could not open file
  20. }
  21. if (file.readU32() != 0x2D) {
  22. return 2; // Not a TR2 level?!
  23. }
  24. loadPaletteTextiles();
  25. getLog() << "->loaded palette" << Log::endl;
  26. file.seek(file.tell() + 4); // Unused value?
  27. loadRooms();
  28. getLog() << "->loaded rooms" << Log::endl;
  29. loadFloorData();
  30. getLog() << "->loaded floor data" << Log::endl;
  31. loadMeshes();
  32. getLog() << "->loaded meshes" << Log::endl;
  33. loadMoveables();
  34. getLog() << "->loaded moveables" << Log::endl;
  35. loadStaticMeshes();
  36. getLog() << "->loaded static meshes" << Log::endl;
  37. loadTextures();
  38. getLog() << "->loaded textures" << Log::endl;
  39. loadSprites();
  40. getLog() << "->loaded sprites" << Log::endl;
  41. loadCameras();
  42. getLog() << "->loaded cameras" << Log::endl;
  43. loadSoundSources();
  44. getLog() << "->loaded sound sources" << Log::endl;
  45. loadBoxesOverlapsZones();
  46. getLog() << "->loaded boxes overlaps zones" << Log::endl;
  47. loadAnimatedTextures();
  48. getLog() << "->loaded animated textures" << Log::endl;
  49. loadItems();
  50. getLog() << "->loaded items" << Log::endl;
  51. file.seek(file.tell() + 8192); // Skip Light map, only for 8bit coloring
  52. loadCinematicFrames();
  53. getLog() << "->loaded cinematic frames" << Log::endl;
  54. loadDemoData();
  55. getLog() << "->loaded demo data" << Log::endl;
  56. loadSoundMap();
  57. getLog() << "->loaded sound map" << Log::endl;
  58. loadSoundDetails();
  59. getLog() << "->loaded sound details" << Log::endl;
  60. loadSampleIndices();
  61. getLog() << "->loaded sample indices" << Log::endl;
  62. return 0;
  63. }
  64. void LoaderTR2::loadPaletteTextiles() {
  65. file.seek(file.tell() + 768); // Skip 8bit palette, 256 * 3 bytes
  66. // Read the 16bit palette, 256 * 4 bytes, RGBA, A unused
  67. std::array<uint32_t, 256> palette; //!< RGBA, A unused
  68. for (auto &x : palette)
  69. x = file.readU32();
  70. uint32_t numTextiles = file.readU32();
  71. file.seek(file.tell() + (numTextiles * 256 * 256)); // Skip 8bit textiles
  72. // Read the 16bit textiles, numTextiles * 256 * 256 * 2 bytes
  73. std::vector<std::array<uint16_t, 256 * 256>> textiles;
  74. for (unsigned int i = 0; i < numTextiles; i++) {
  75. std::array<uint16_t, 256 * 256> arr;
  76. for (auto &x : arr) {
  77. x = file.readU16();
  78. }
  79. textiles.push_back(arr);
  80. }
  81. // TODO store palette and textiles somewhere
  82. }
  83. void LoaderTR2::loadRooms() {
  84. uint16_t numRooms = file.readU16();
  85. for (unsigned int i = 0; i < numRooms; i++) {
  86. // Room Header
  87. int32_t xOffset = file.read32();
  88. int32_t zOffset = file.read32();
  89. int32_t yBottom = file.read32(); // lowest point == largest y value
  90. int32_t yTop = file.read32(); // highest point == smallest y value
  91. // Number of data words (2 bytes) to follow
  92. uint32_t dataToFollow = file.readU32();
  93. uint16_t numVertices = file.readU16();
  94. for (unsigned int v = 0; v < numVertices; v++) {
  95. // Vertex coordinates, relative to x/zOffset
  96. int16_t relativeX = file.read16();
  97. int16_t relativeY = file.read16();
  98. int16_t relativeZ = file.read16();
  99. int16_t lighting1 = file.read16();
  100. // Set of flags for special rendering effects
  101. // 0x8000 - Something to do with water surface?
  102. // 0x4000 - Underwater lighting modulation/movement if seen from above
  103. // 0x2000 - Water/Quicksand surface movement
  104. // 0x0010 - Normal?
  105. uint16_t attributes = file.readU16();
  106. int16_t lighting2; // Almost always equal to lighting1
  107. // TODO store vertex somewhere
  108. }
  109. uint16_t numRectangles = file.readU16();
  110. for (unsigned int r = 0; r < numRectangles; r++) {
  111. // Indices into the vertex list read just before
  112. uint16_t vertex1 = file.readU16();
  113. uint16_t vertex2 = file.readU16();
  114. uint16_t vertex3 = file.readU16();
  115. uint16_t vertex4 = file.readU16();
  116. // Index into the object-texture list
  117. uint16_t texture = file.readU16();
  118. // TODO store rectangles somewhere
  119. }
  120. uint16_t numTriangles = file.readU16();
  121. for (unsigned int t = 0; t < numTriangles; t++) {
  122. // Indices into the room vertex list
  123. uint16_t vertex1 = file.readU16();
  124. uint16_t vertex2 = file.readU16();
  125. uint16_t vertex3 = file.readU16();
  126. // Index into the object-texture list
  127. uint16_t texture = file.readU16();
  128. // TODO store triangles somewhere
  129. }
  130. uint16_t numSprites = file.readU16();
  131. for (unsigned int s = 0; s < numSprites; s++) {
  132. uint16_t vertex = file.readU16(); // Index into vertex list
  133. uint16_t texture = file.readU16(); // Index into object-texture list
  134. // TODO store sprites somewhere
  135. }
  136. uint16_t numPortals = file.readU16();
  137. for (unsigned int p = 0; p < numPortals; p++) {
  138. // Which room this portal leads to
  139. uint16_t adjoiningRoom = file.readU16();
  140. // Which way the portal faces
  141. // The normal points away from the adjacent room
  142. // To be seen through, it must point toward the viewpoint
  143. int16_t xNormal = file.read16();
  144. int16_t yNormal = file.read16();
  145. int16_t zNormal = file.read16();
  146. // The corners of this portal
  147. // The right-hand rule applies with respect to the normal
  148. int16_t xCorner1 = file.read16();
  149. int16_t yCorner1 = file.read16();
  150. int16_t zCorner1 = file.read16();
  151. int16_t xCorner2 = file.read16();
  152. int16_t yCorner2 = file.read16();
  153. int16_t zCorner2 = file.read16();
  154. int16_t xCorner3 = file.read16();
  155. int16_t yCorner3 = file.read16();
  156. int16_t zCorner3 = file.read16();
  157. // TODO store portals somewhere
  158. }
  159. uint16_t numZSectors = file.readU16();
  160. uint16_t numXSectors = file.readU16();
  161. for (unsigned int s = 0; s < (numZSectors * numXSectors); s++) {
  162. // Sectors are 1024*1024 world coordinates. Floor and Ceiling are
  163. // signed numbers of 256 units of height.
  164. // Floor/Ceiling value of 0x81 is used to indicate impenetrable
  165. // walls around the sector.
  166. // Floor values are used by the original engine to determine
  167. // what objects can be traversed and how. Relative steps of 1 (256)
  168. // can be walked up, 2..7 must be jumped up, larger than 7 is too high
  169. // If RoomAbove/Below is not none, the Ceiling/Floor is a collisional
  170. // portal to that room
  171. uint16_t indexFloorData = file.readU16();
  172. uint16_t indexBox = file.readU16(); // 0xFFFF if none
  173. uint8_t roomBelow = file.readU8(); // 0xFF if none
  174. int8_t floor = file.read8(); // Absolute height of floor (divided by 256)
  175. uint8_t roomAbove = file.readU8(); // 0xFF if none
  176. int8_t ceiling = file.read8(); // Absolute height of ceiling (/ 256)
  177. // TODO store sectors somewhere
  178. }
  179. int16_t intensity1 = file.read16();
  180. int16_t intensity2 = file.read16();
  181. int16_t lightMode = file.read16();
  182. uint16_t numLights = file.readU16();
  183. for (unsigned int l = 0; l < numLights; l++) {
  184. // Position of light, in world coordinates
  185. int32_t x = file.read32();
  186. int32_t y = file.read32();
  187. int32_t z = file.read32();
  188. uint16_t intensity1 = file.readU16();
  189. uint16_t intensity2 = file.readU16(); // Almost always equal to intensity1
  190. uint32_t fade1 = file.readU32(); // Falloff value?
  191. uint32_t fade2 = file.readU32(); // Falloff value?
  192. // TODO store light somewhere
  193. }
  194. uint16_t numStaticMeshes = file.readU16();
  195. for (unsigned int s = 0; s < numStaticMeshes; s++) {
  196. // Absolute position in world coordinates
  197. int32_t x = file.read32();
  198. int32_t y = file.read32();
  199. int32_t z = file.read32();
  200. // High two bits (0xC000) indicate steps of
  201. // 90 degrees (eg. (rotation >> 14) * 90)
  202. uint16_t rotation = file.readU16();
  203. // Constant lighting, 0xFFFF means use mesh lighting
  204. uint16_t intensity1 = file.readU16();
  205. uint16_t intensity2 = file.readU16();
  206. // Which StaticMesh item to draw
  207. uint16_t objectID = file.readU16();
  208. // TODO store static meshes somewhere
  209. }
  210. int16_t alternateRoom = file.read16();
  211. uint16_t flags = file.readU16();
  212. }
  213. }
  214. void LoaderTR2::loadFloorData() {
  215. uint32_t numFloorData = file.readU32();
  216. for (unsigned int f = 0; f < numFloorData; f++) {
  217. uint16_t unused = file.readU16();
  218. // TODO store floor data somewhere
  219. }
  220. }
  221. void LoaderTR2::loadMeshes() {
  222. // Number of bitu16s of mesh data to follow
  223. // Read all the mesh data into a buffer, because
  224. // only afterward we can read the number of meshes
  225. // in this data block
  226. uint32_t numMeshData = file.readU32();
  227. std::vector<uint16_t> buffer;
  228. for (unsigned int i = 0; i < numMeshData; i++) {
  229. buffer.push_back(file.readU16());
  230. }
  231. uint32_t numMeshPointers = file.readU32();
  232. std::vector<uint32_t> meshPointers;
  233. for (unsigned int i = 0; i < numMeshPointers; i++) {
  234. meshPointers.push_back(file.readU32());
  235. }
  236. // TODO interpret the buffered mesh data
  237. }
  238. void LoaderTR2::loadMoveables() {
  239. uint32_t numAnimations = file.readU32();
  240. for (unsigned int a = 0; a < numAnimations; a++) {
  241. // *Byte* Offset into Frames[] (so divide by 2!)
  242. uint32_t frameOffset = file.readU32();
  243. uint8_t frameRate = file.readU8(); // Engine ticks per frame
  244. // Number of bit16s in Frames[] used by this animation
  245. // Be careful when parsing frames using the FrameSize value
  246. // as the size of each frame, since an animations frame range
  247. // may extend into the next animations frame range, and that
  248. // may have a different FrameSize value.
  249. uint8_t frameSize = file.readU8();
  250. uint16_t stateID = file.readU16();
  251. file.seek(file.tell() + 8); // Skip 8 unknown bytes
  252. uint16_t frameStart = file.readU16(); // First frame in this animation
  253. uint16_t frameEnd = file.readU16(); // Last frame in this animation
  254. uint16_t nextAnimation = file.readU16();
  255. uint16_t nextFrame = file.readU16();
  256. uint16_t numStateChanges = file.readU16();
  257. uint16_t stateChangeOffset = file.readU16(); // Index into StateChanges[]
  258. uint16_t numAnimCommands; // How many animation commands to use
  259. uint16_t animCommandOffset; // Index into AnimCommand[]
  260. // TODO store animations somewhere
  261. }
  262. uint32_t numStateChanges = file.readU32();
  263. for (unsigned int s = 0; s < numStateChanges; s++) {
  264. uint16_t stateID = file.readU16();
  265. uint16_t numAnimDispatches = file.readU16();
  266. uint16_t animDispatchOffset = file.readU16(); // Index into AnimDispatches[]
  267. // TODO store state changes somewhere
  268. }
  269. uint32_t numAnimDispatches = file.readU32();
  270. for (unsigned int a = 0; a < numAnimDispatches; a++) {
  271. int16_t low = file.read16(); // Lowest frame that uses this range
  272. int16_t high = file.read16(); // Highest frame (+1?) that uses this range
  273. int16_t nextAnimation = file.read16(); // Animation to go to
  274. int16_t nextFrame = file.read16(); // Frame offset to go to
  275. // TODO store animation dispatches somewhere
  276. }
  277. uint32_t numAnimCommands = file.readU32();
  278. std::vector<int16_t> animCommands;
  279. for (unsigned int a = 0; a < numAnimCommands; a++) {
  280. animCommands.push_back(file.read16());
  281. }
  282. uint32_t numMeshTrees = file.readU32();
  283. for (unsigned int m = 0; m < numMeshTrees; m++) {
  284. // 0x0002 - Put parent mesh on the mesh stack
  285. // 0x0001 - Pop mesh from stack, use as parent mesh
  286. // When both are not set, use previous mesh as parent mesh
  287. // When both are set, do 0x0001 first, then 0x0002, thereby
  288. // reading the stack but not changing it
  289. uint32_t flags = file.readU32();
  290. // Offset of mesh origin from the parent mesh origin
  291. int32_t x = file.read32();
  292. int32_t y = file.read32();
  293. int32_t z = file.read32();
  294. // TODO store mesh trees somewhere
  295. }
  296. uint32_t numFrames = file.readU32();
  297. std::vector<uint16_t> frames;
  298. for (unsigned int f = 0; f < numFrames; f++) {
  299. frames.push_back(file.readU16());
  300. }
  301. uint32_t numMoveables = file.readU32();
  302. for (unsigned int m = 0; m < numMoveables; m++) {
  303. // Item identifier, matched in Items[]
  304. uint32_t objectID = file.readU32();
  305. uint16_t numMeshes = file.readU16();
  306. uint16_t startingMesh = file.readU16(); // Offset into MeshPointers[]
  307. uint32_t meshTree = file.readU32(); // Offset into MeshTree[]
  308. // *Byte* offset into Frames[] (divide by 2 for Frames[i])
  309. uint32_t frameOffset = file.readU32();
  310. // If animation index is 0xFFFF, the object is stationary or
  311. // animated by the engine (ponytail)
  312. uint16_t animation = file.readU16();
  313. // TODO store moveables somewhere
  314. }
  315. // TODO combine all this into moveables with their animations
  316. }
  317. void LoaderTR2::loadStaticMeshes() {
  318. uint32_t numStaticMeshes = file.readU32();
  319. for (unsigned int s = 0; s < numStaticMeshes; s++) {
  320. uint32_t objectID = file.readU32(); // Matched in Items[]
  321. uint16_t mesh = file.readU16(); // Offset into MeshPointers[]
  322. // tr2_vertex BoundingBox[2][2];
  323. // // First index is which one, second index is opposite corners
  324. int16_t x11 = file.read16();
  325. int16_t y11 = file.read16();
  326. int16_t z11 = file.read16();
  327. int16_t x12 = file.read16();
  328. int16_t y12 = file.read16();
  329. int16_t z12 = file.read16();
  330. int16_t x21 = file.read16();
  331. int16_t y21 = file.read16();
  332. int16_t z21 = file.read16();
  333. int16_t x22 = file.read16();
  334. int16_t y22 = file.read16();
  335. int16_t z22 = file.read16();
  336. // Meaning uncertain. Usually 2, and 3 for objects Lara can
  337. // travel through, like TR2s skeletons and underwater plants
  338. uint16_t flags = file.readU16();
  339. // TODO store static meshes somewhere
  340. }
  341. }
  342. void LoaderTR2::loadTextures() {
  343. uint32_t numObjectTextures = file.readU32();
  344. for (unsigned int o = 0; o < numObjectTextures; o++) {
  345. // 0 means that a texture is all-opaque, and that transparency
  346. // information is ignored.
  347. // 1 means that transparency information is used. In 8-bit color,
  348. // index 0 is the transparent color, while in 16-bit color, the
  349. // top bit (0x8000) is the alpha channel (1 = opaque, 0 = transparent)
  350. uint16_t attribute = file.readU16();
  351. // Index into the textile list
  352. uint16_t tile = file.readU16();
  353. // The four corner vertices of the texture
  354. // The Pixel values are the actual coordinates of the vertexs pixel
  355. // The Coordinate values depend on where the other vertices are in
  356. // the object texture. And if the object texture is used to specify
  357. // a triangle, then the fourth vertexs values will all be zero
  358. // Coordinate is 1 if Pixel is the low val, 255 if high val in object texture
  359. uint8_t xCoordinate1 = file.readU8();
  360. uint8_t xPixel1 = file.readU8();
  361. uint8_t yCoordinate1 = file.readU8();
  362. uint8_t yPixel1 = file.readU8();
  363. uint8_t xCoordinate2 = file.readU8();
  364. uint8_t xPixel2 = file.readU8();
  365. uint8_t yCoordinate2 = file.readU8();
  366. uint8_t yPixel2 = file.readU8();
  367. uint8_t xCoordinate3 = file.readU8();
  368. uint8_t xPixel3 = file.readU8();
  369. uint8_t yCoordinate3 = file.readU8();
  370. uint8_t yPixel3 = file.readU8();
  371. uint8_t xCoordinate4 = file.readU8();
  372. uint8_t xPixel4 = file.readU8();
  373. uint8_t yCoordinate4 = file.readU8();
  374. uint8_t yPixel4 = file.readU8();
  375. // TODO store object textures somewhere
  376. }
  377. }
  378. void LoaderTR2::loadSprites() {
  379. uint32_t numSpriteTextures = file.readU32();
  380. for (unsigned int s = 0; s < numSpriteTextures; s++) {
  381. uint16_t tile = file.readU16();
  382. uint8_t x = file.readU8();
  383. uint8_t y = file.readU8();
  384. uint16_t width = file.readU16(); // Actually (width * 256) + 255
  385. uint16_t height = file.readU16(); // Actually (height * 256) + 255
  386. int16_t leftSide = file.read16();
  387. int16_t topSide = file.read16();
  388. int16_t rightSide = file.read16();
  389. int16_t bottomSide = file.read16();
  390. // TODO store sprite textures somewhere
  391. }
  392. uint32_t numSpriteSequences = file.readU32();
  393. for (unsigned int s = 0; s < numSpriteSequences; s++) {
  394. int32_t objectID = file.read32(); // Item identifier, matched in Items[]
  395. int16_t negativeLength = file.read16(); // Negative sprite count
  396. int16_t offset = file.read16(); // Where sequence starts in sprite texture list
  397. // TODO store sprite sequences somewhere
  398. }
  399. }
  400. void LoaderTR2::loadCameras() {
  401. uint32_t numCameras = file.readU32();
  402. for (unsigned int c = 0; c < numCameras; c++) {
  403. int32_t x = file.read32();
  404. int32_t y = file.read32();
  405. int32_t z = file.read32();
  406. int16_t room = file.read16();
  407. file.seek(file.tell() + 2); // Unknown, correlates to Boxes? Zones?
  408. // TODO store cameras somewhere
  409. }
  410. }
  411. void LoaderTR2::loadSoundSources() {
  412. uint32_t numSoundSources = file.readU32();
  413. for (unsigned int s = 0; s < numSoundSources; s++) {
  414. // Absolute world coordinate positions of sound source
  415. int32_t x = file.read32();
  416. int32_t y = file.read32();
  417. int32_t z = file.read32();
  418. // Internal sound index
  419. uint16_t soundID = file.readU16();
  420. // Unknown, 0x40, 0x80 or 0xC0
  421. uint16_t flags = file.readU16();
  422. // TODO store sound sources somewhere
  423. }
  424. }
  425. void LoaderTR2::loadBoxesOverlapsZones() {
  426. uint32_t numBoxes = file.readU32();
  427. for (unsigned int b = 0; b < numBoxes; b++) {
  428. // Sectors (* 1024 units)
  429. uint8_t zMin = file.readU8();
  430. uint8_t zMax = file.readU8();
  431. uint8_t xMin = file.readU8();
  432. uint8_t xMax = file.readU8();
  433. int16_t trueFloor = file.read16(); // Y value (no scaling)
  434. // Index into overlaps[]. The high bit is sometimes set
  435. // this occurs in front of swinging doors and the like
  436. int16_t overlapIndex = file.read16();
  437. // TODO store boxes somewhere
  438. }
  439. uint32_t numOverlaps = file.readU32();
  440. std::vector<uint16_t> overlaps;
  441. for (unsigned int o = 0; o < numOverlaps; o++) {
  442. overlaps.push_back(file.readU16());
  443. }
  444. // TODO store overlaps somewhere
  445. std::vector<int16_t> zones;
  446. for (unsigned int z = 0; z < numBoxes; z++) {
  447. for (unsigned int i = 0; i < 10; i++) {
  448. zones.push_back(file.read16());
  449. }
  450. }
  451. // TODO store zones somewhere
  452. }
  453. void LoaderTR2::loadAnimatedTextures() {
  454. uint32_t numAnimatedTextures = file.readU32();
  455. std::vector<uint16_t> animatedTextures;
  456. for (unsigned int a = 0; a < numAnimatedTextures; a++) {
  457. animatedTextures.push_back(file.readU16());
  458. }
  459. // TODO store animated textures somewhere. Format?
  460. }
  461. void LoaderTR2::loadItems() {
  462. uint32_t numItems = file.readU32();
  463. for (unsigned int i = 0; i < numItems; i++) {
  464. int16_t objectID = file.read16();
  465. int16_t room = file.read16();
  466. // Item position in world coordinates
  467. int32_t x = file.read32();
  468. int32_t y = file.read32();
  469. int32_t z = file.read32();
  470. int16_t angle = file.read16(); // (0xC000 >> 14) * 90deg
  471. int16_t intensity1 = file.read16(); // Constant lighting; -1 means mesh lighting
  472. int16_t intensity2 = file.read16(); // Almost always like intensity1
  473. // 0x0100 - Initially visible
  474. // 0x3E00 - Activation mask, open, can be XORed with related FloorData list fields.
  475. uint16_t flags = file.readU16();
  476. // TODO store items somewhere
  477. }
  478. }
  479. void LoaderTR2::loadCinematicFrames() {
  480. uint16_t numCinematicFrames = file.readU16();
  481. for (unsigned int c = 0; c < numCinematicFrames; c++) {
  482. int16_t rotY = file.read16(); // Y rotation, +-32767 = +-180deg
  483. int16_t rotZ = file.read16(); // Z rotation, like rotY
  484. int16_t rotZ2 = file.read16(); // Like rotZ?
  485. int16_t posZ = file.read16(); // Camera pos relative to what?
  486. int16_t posY = file.read16();
  487. int16_t posX = file.read16();
  488. int16_t unknown = file.read16(); // Changing this can cause runtime error
  489. int16_t rotX = file.read16(); // X rotation, like rotY
  490. // TODO store cinematic frames somewhere
  491. }
  492. }
  493. void LoaderTR2::loadDemoData() {
  494. uint16_t numDemoData = file.readU16();
  495. for (unsigned int d = 0; d < numDemoData; d++)
  496. file.readU8();
  497. // TODO store demo data somewhere, find out meaning
  498. }
  499. void LoaderTR2::loadSoundMap() {
  500. std::array<int16_t, 370> soundMap;
  501. for (auto &x : soundMap) {
  502. x = file.read16();
  503. }
  504. // TODO store sound map somewhere
  505. }
  506. void LoaderTR2::loadSoundDetails() {
  507. uint32_t numSoundDetails = file.readU32();
  508. for (unsigned int s = 0; s < numSoundDetails; s++) {
  509. int16_t sample = file.read16(); // Index into SampleIndices[]
  510. int16_t volume = file.read16();
  511. // sound range? distance at which this sound can be heard?
  512. int16_t unknown1 = file.read16();
  513. // Bits 8-15: priority?
  514. // Bits 2-7: number of samples in this group
  515. // Bits 0-1: channel number?
  516. int16_t unknown2 = file.read16();
  517. // TODO store sound details somewhere
  518. }
  519. }
  520. void LoaderTR2::loadSampleIndices() {
  521. uint32_t numSampleIndices = file.readU32();
  522. std::vector<uint32_t> sampleIndices;
  523. for (unsigned int i = 0; i < numSampleIndices; i++) {
  524. sampleIndices.push_back(file.readU32());
  525. }
  526. // TODO store sample indices somewhere
  527. }