|
@@ -12,14 +12,11 @@
|
12
|
12
|
#include "loader/LoaderTR2.h"
|
13
|
13
|
|
14
|
14
|
LoaderTR2::LoaderTR2() {
|
15
|
|
- palette = new uint32_t[256];
|
16
|
15
|
numTextiles = 0;
|
17
|
16
|
textiles = nullptr;
|
18
|
17
|
}
|
19
|
18
|
|
20
|
19
|
LoaderTR2::~LoaderTR2() {
|
21
|
|
- delete [] palette;
|
22
|
|
-
|
23
|
20
|
if (textiles != nullptr) {
|
24
|
21
|
for (unsigned int i = 0; i < numTextiles; i++)
|
25
|
22
|
delete [] textiles[i];
|
|
@@ -27,8 +24,6 @@ LoaderTR2::~LoaderTR2() {
|
27
|
24
|
}
|
28
|
25
|
}
|
29
|
26
|
|
30
|
|
-#define HEISENBUG
|
31
|
|
-
|
32
|
27
|
int LoaderTR2::load(std::string f) {
|
33
|
28
|
if (file.open(f.c_str()) != 0) {
|
34
|
29
|
return 1; // Could not open file
|
|
@@ -39,101 +34,62 @@ int LoaderTR2::load(std::string f) {
|
39
|
34
|
}
|
40
|
35
|
|
41
|
36
|
loadPaletteTextiles();
|
42
|
|
-#ifdef HEISENBUG
|
43
|
37
|
getConsole() << "->loaded palette" << Console::endl;
|
44
|
|
-#endif
|
45
|
38
|
|
46
|
39
|
file.seek(file.tell() + 4); // Unused value?
|
47
|
40
|
|
48
|
41
|
loadRooms();
|
49
|
|
-#ifdef HEISENBUG
|
50
|
42
|
getConsole() << "->loaded rooms" << Console::endl;
|
51
|
|
-#endif
|
52
|
43
|
|
53
|
44
|
loadFloorData();
|
54
|
|
-#ifdef HEISENBUG
|
55
|
45
|
getConsole() << "->loaded floor data" << Console::endl;
|
56
|
|
-#endif
|
57
|
46
|
|
58
|
47
|
loadMeshes();
|
59
|
|
-#ifdef HEISENBUG
|
60
|
48
|
getConsole() << "->loaded meshes" << Console::endl;
|
61
|
|
-#endif
|
62
|
49
|
|
63
|
50
|
loadMoveables();
|
64
|
|
-#ifdef HEISENBUG
|
65
|
51
|
getConsole() << "->loaded moveables" << Console::endl;
|
66
|
|
-#endif
|
67
|
52
|
|
68
|
53
|
loadStaticMeshes();
|
69
|
|
-#ifdef HEISENBUG
|
70
|
54
|
getConsole() << "->loaded static meshes" << Console::endl;
|
71
|
|
-#endif
|
72
|
55
|
|
73
|
56
|
loadTextures();
|
74
|
|
-#ifdef HEISENBUG
|
75
|
57
|
getConsole() << "->loaded textures" << Console::endl;
|
76
|
|
-#endif
|
77
|
58
|
|
78
|
59
|
loadSprites();
|
79
|
|
-#ifdef HEISENBUG
|
80
|
60
|
getConsole() << "->loaded sprites" << Console::endl;
|
81
|
|
-#endif
|
82
|
61
|
|
83
|
62
|
loadCameras();
|
84
|
|
-#ifdef HEISENBUG
|
85
|
63
|
getConsole() << "->loaded cameras" << Console::endl;
|
86
|
|
-#endif
|
87
|
64
|
|
88
|
65
|
loadSoundSources();
|
89
|
|
-#ifdef HEISENBUG
|
90
|
66
|
getConsole() << "->loaded sound sources" << Console::endl;
|
91
|
|
-#endif
|
92
|
67
|
|
93
|
68
|
loadBoxesOverlapsZones();
|
94
|
|
-#ifdef HEISENBUG
|
95
|
69
|
getConsole() << "->loaded boxes overlaps zones" << Console::endl;
|
96
|
|
-#endif
|
97
|
70
|
|
98
|
71
|
loadAnimatedTextures();
|
99
|
|
-#ifdef HEISENBUG
|
100
|
72
|
getConsole() << "->loaded animated textures" << Console::endl;
|
101
|
|
-#endif
|
102
|
73
|
|
103
|
74
|
loadItems();
|
104
|
|
-#ifdef HEISENBUG
|
105
|
75
|
getConsole() << "->loaded items" << Console::endl;
|
106
|
|
-#endif
|
107
|
76
|
|
108
|
|
- loadLightMap();
|
109
|
|
-#ifdef HEISENBUG
|
110
|
|
- getConsole() << "->loaded light map" << Console::endl;
|
111
|
|
-#endif
|
|
77
|
+ file.seek(file.tell() + 8192); // Skip Light map, only for 8bit coloring
|
112
|
78
|
|
113
|
79
|
loadCinematicFrames();
|
114
|
|
-#ifdef HEISENBUG
|
115
|
80
|
getConsole() << "->loaded cinematic frames" << Console::endl;
|
116
|
|
-#endif
|
117
|
81
|
|
118
|
82
|
loadDemoData();
|
119
|
|
-#ifdef HEISENBUG
|
120
|
83
|
getConsole() << "->loaded demo data" << Console::endl;
|
121
|
|
-#endif
|
122
|
84
|
|
123
|
85
|
loadSoundMap();
|
124
|
|
-#ifdef HEISENBUG
|
125
|
86
|
getConsole() << "->loaded sound map" << Console::endl;
|
126
|
|
-#endif
|
127
|
87
|
|
128
|
88
|
loadSoundDetails();
|
129
|
|
-#ifdef HEISENBUG
|
130
|
89
|
getConsole() << "->loaded sound details" << Console::endl;
|
131
|
|
-#endif
|
132
|
90
|
|
133
|
91
|
loadSampleIndices();
|
134
|
|
-#ifdef HEISENBUG
|
135
|
92
|
getConsole() << "->loaded sample indices" << Console::endl;
|
136
|
|
-#endif
|
137
|
93
|
|
138
|
94
|
return 0;
|
139
|
95
|
}
|
|
@@ -142,8 +98,8 @@ void LoaderTR2::loadPaletteTextiles() {
|
142
|
98
|
file.seek(file.tell() + 768); // Skip 8bit palette, 256 * 3 bytes
|
143
|
99
|
|
144
|
100
|
// Read the 16bit palette, 256 * 4 bytes, RGBA, A unused
|
145
|
|
- for (unsigned int i = 0; i < 256; i++)
|
146
|
|
- palette[i] = file.readU32();
|
|
101
|
+ for (auto &x : palette)
|
|
102
|
+ x = file.readU32();
|
147
|
103
|
|
148
|
104
|
numTextiles = file.readU32();
|
149
|
105
|
|
|
@@ -160,7 +116,7 @@ void LoaderTR2::loadPaletteTextiles() {
|
160
|
116
|
}
|
161
|
117
|
|
162
|
118
|
void LoaderTR2::loadRooms() {
|
163
|
|
- numRooms = file.readU16();
|
|
119
|
+ uint16_t numRooms = file.readU16();
|
164
|
120
|
for (unsigned int i = 0; i < numRooms; i++) {
|
165
|
121
|
// Room Header
|
166
|
122
|
int32_t xOffset = file.read32();
|
|
@@ -564,42 +520,150 @@ void LoaderTR2::loadCameras() {
|
564
|
520
|
}
|
565
|
521
|
|
566
|
522
|
void LoaderTR2::loadSoundSources() {
|
|
523
|
+ uint32_t numSoundSources = file.readU32();
|
|
524
|
+ for (unsigned int s = 0; s < numSoundSources; s++) {
|
|
525
|
+ // Absolute world coordinate positions of sound source
|
|
526
|
+ int32_t x = file.read32();
|
|
527
|
+ int32_t y = file.read32();
|
|
528
|
+ int32_t z = file.read32();
|
567
|
529
|
|
|
530
|
+ // Internal sound index
|
|
531
|
+ uint16_t soundID = file.readU16();
|
|
532
|
+
|
|
533
|
+ // Unknown, 0x40, 0x80 or 0xC0
|
|
534
|
+ uint16_t flags = file.readU16();
|
|
535
|
+
|
|
536
|
+ // TODO store sound sources somewhere
|
|
537
|
+ }
|
568
|
538
|
}
|
569
|
539
|
|
570
|
540
|
void LoaderTR2::loadBoxesOverlapsZones() {
|
|
541
|
+ uint32_t numBoxes = file.readU32();
|
|
542
|
+ for (unsigned int b = 0; b < numBoxes; b++) {
|
|
543
|
+ // Sectors (* 1024 units)
|
|
544
|
+ uint8_t zMin = file.readU8();
|
|
545
|
+ uint8_t zMax = file.readU8();
|
|
546
|
+ uint8_t xMin = file.readU8();
|
|
547
|
+ uint8_t xMax = file.readU8();
|
571
|
548
|
|
|
549
|
+ int16_t trueFloor = file.read16(); // Y value (no scaling)
|
|
550
|
+
|
|
551
|
+ // Index into overlaps[]. The high bit is sometimes set
|
|
552
|
+ // this occurs in front of swinging doors and the like
|
|
553
|
+ int16_t overlapIndex = file.read16();
|
|
554
|
+
|
|
555
|
+ // TODO store boxes somewhere
|
|
556
|
+ }
|
|
557
|
+
|
|
558
|
+ uint32_t numOverlaps = file.readU32();
|
|
559
|
+ std::vector<uint16_t> overlaps;
|
|
560
|
+ for (unsigned int o = 0; o < numOverlaps; o++) {
|
|
561
|
+ overlaps.push_back(file.readU16());
|
|
562
|
+ }
|
|
563
|
+
|
|
564
|
+ // TODO store overlaps somewhere
|
|
565
|
+
|
|
566
|
+ std::vector<int16_t> zones;
|
|
567
|
+ for (unsigned int z = 0; z < numBoxes; z++) {
|
|
568
|
+ for (unsigned int i = 0; i < 10; i++) {
|
|
569
|
+ zones.push_back(file.read16());
|
|
570
|
+ }
|
|
571
|
+ }
|
|
572
|
+
|
|
573
|
+ // TODO store zones somewhere
|
572
|
574
|
}
|
573
|
575
|
|
574
|
576
|
void LoaderTR2::loadAnimatedTextures() {
|
|
577
|
+ uint32_t numAnimatedTextures = file.readU32();
|
|
578
|
+ std::vector<uint16_t> animatedTextures;
|
|
579
|
+ for (unsigned int a = 0; a < numAnimatedTextures; a++) {
|
|
580
|
+ animatedTextures.push_back(file.readU16());
|
|
581
|
+ }
|
575
|
582
|
|
|
583
|
+ // TODO store animated textures somewhere. Format?
|
576
|
584
|
}
|
577
|
585
|
|
578
|
586
|
void LoaderTR2::loadItems() {
|
|
587
|
+ uint32_t numItems = file.readU32();
|
|
588
|
+ for (unsigned int i = 0; i < numItems; i++) {
|
|
589
|
+ int16_t objectID = file.read16();
|
|
590
|
+ int16_t room = file.read16();
|
579
|
591
|
|
580
|
|
-}
|
|
592
|
+ // Item position in world coordinates
|
|
593
|
+ int32_t x = file.read32();
|
|
594
|
+ int32_t y = file.read32();
|
|
595
|
+ int32_t z = file.read32();
|
581
|
596
|
|
582
|
|
-void LoaderTR2::loadLightMap() {
|
|
597
|
+ int16_t angle = file.read16(); // (0xC000 >> 14) * 90deg
|
|
598
|
+ int16_t intensity1 = file.read16(); // Constant lighting; -1 means mesh lighting
|
|
599
|
+ int16_t intensity2 = file.read16(); // Almost always like intensity1
|
|
600
|
+
|
|
601
|
+ // 0x0100 - Initially visible
|
|
602
|
+ // 0x3E00 - Activation mask, open, can be XORed with related FloorData list fields.
|
|
603
|
+ uint16_t flags = file.readU16();
|
583
|
604
|
|
|
605
|
+ // TODO store items somewhere
|
|
606
|
+ }
|
584
|
607
|
}
|
585
|
608
|
|
586
|
609
|
void LoaderTR2::loadCinematicFrames() {
|
587
|
|
-
|
|
610
|
+ uint16_t numCinematicFrames = file.readU16();
|
|
611
|
+ for (unsigned int c = 0; c < numCinematicFrames; c++) {
|
|
612
|
+ int16_t rotY = file.read16(); // Y rotation, +-32767 = +-180deg
|
|
613
|
+ int16_t rotZ = file.read16(); // Z rotation, like rotY
|
|
614
|
+ int16_t rotZ2 = file.read16(); // Like rotZ?
|
|
615
|
+ int16_t posZ = file.read16(); // Camera pos relative to what?
|
|
616
|
+ int16_t posY = file.read16();
|
|
617
|
+ int16_t posX = file.read16();
|
|
618
|
+ int16_t unknown = file.read16(); // Changing this can cause runtime error
|
|
619
|
+ int16_t rotX = file.read16(); // X rotation, like rotY
|
|
620
|
+
|
|
621
|
+ // TODO store cinematic frames somewhere
|
|
622
|
+ }
|
588
|
623
|
}
|
589
|
624
|
|
590
|
625
|
void LoaderTR2::loadDemoData() {
|
|
626
|
+ uint16_t numDemoData = file.readU16();
|
|
627
|
+ for (unsigned int d = 0; d < numDemoData; d++)
|
|
628
|
+ file.readU8();
|
591
|
629
|
|
|
630
|
+ // TODO store demo data somewhere, find out meaning
|
592
|
631
|
}
|
593
|
632
|
|
594
|
633
|
void LoaderTR2::loadSoundMap() {
|
|
634
|
+ std::array<int16_t, 370> soundMap;
|
|
635
|
+ for (auto &x : soundMap) {
|
|
636
|
+ x = file.read16();
|
|
637
|
+ }
|
595
|
638
|
|
|
639
|
+ // TODO store sound map somewhere
|
596
|
640
|
}
|
597
|
641
|
|
598
|
642
|
void LoaderTR2::loadSoundDetails() {
|
|
643
|
+ uint32_t numSoundDetails = file.readU32();
|
|
644
|
+ for (unsigned int s = 0; s < numSoundDetails; s++) {
|
|
645
|
+ int16_t sample = file.read16(); // Index into SampleIndices[]
|
|
646
|
+ int16_t volume = file.read16();
|
599
|
647
|
|
|
648
|
+ // sound range? distance at which this sound can be heard?
|
|
649
|
+ int16_t unknown1 = file.read16();
|
|
650
|
+
|
|
651
|
+ // Bits 8-15: priority?
|
|
652
|
+ // Bits 2-7: number of samples in this group
|
|
653
|
+ // Bits 0-1: channel number?
|
|
654
|
+ int16_t unknown2 = file.read16();
|
|
655
|
+
|
|
656
|
+ // TODO store sound details somewhere
|
|
657
|
+ }
|
600
|
658
|
}
|
601
|
659
|
|
602
|
660
|
void LoaderTR2::loadSampleIndices() {
|
|
661
|
+ uint32_t numSampleIndices = file.readU32();
|
|
662
|
+ std::vector<uint32_t> sampleIndices;
|
|
663
|
+ for (unsigned int i = 0; i < numSampleIndices; i++) {
|
|
664
|
+ sampleIndices.push_back(file.readU32());
|
|
665
|
+ }
|
603
|
666
|
|
|
667
|
+ // TODO store sample indices somewhere
|
604
|
668
|
}
|
605
|
669
|
|