Explorar el Código

Extended LoaderTR2

Thomas Buck hace 9 años
padre
commit
523b60e9e5
Se han modificado 3 ficheros con 543 adiciones y 2 borrados
  1. 4
    0
      ChangeLog.md
  2. 17
    1
      include/loader/LoaderTR2.h
  3. 522
    1
      src/loader/LoaderTR2.cpp

+ 4
- 0
ChangeLog.md Ver fichero

@@ -2,6 +2,10 @@
2 2
 
3 3
 ## OpenRaider (0.1.3) xythobuz <xythobuz@xythobuz.de>
4 4
 
5
+    [ 20140816 ]
6
+    * Greatly extended LoaderTR2s reading code, but now seeing very
7
+      strange behavior in new Loader...
8
+
5 9
     [ 20140813 ]
6 10
     * Added LoaderTR1, LoaderTR3 stubs
7 11
 

+ 17
- 1
include/loader/LoaderTR2.h Ver fichero

@@ -23,8 +23,24 @@ public:
23 23
 private:
24 24
 
25 25
     void loadPaletteTextiles();
26
-
27 26
     void loadRooms();
27
+    void loadFloorData();
28
+    void loadMeshes();
29
+    void loadMoveables();
30
+    void loadStaticMeshes();
31
+    void loadTextures();
32
+    void loadSprites();
33
+    void loadCameras();
34
+    void loadSoundSources();
35
+    void loadBoxesOverlapsZones();
36
+    void loadAnimatedTextures();
37
+    void loadItems();
38
+    void loadLightMap();
39
+    void loadCinematicFrames();
40
+    void loadDemoData();
41
+    void loadSoundMap();
42
+    void loadSoundDetails();
43
+    void loadSampleIndices();
28 44
 
29 45
     uint32_t *palette; //!< 256 * 4 bytes, RGBA, A unused
30 46
     uint32_t numTextiles;

+ 522
- 1
src/loader/LoaderTR2.cpp Ver fichero

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

Loading…
Cancelar
Guardar