Переглянути джерело

LoaderTR2 tries to load external SFX file

Thomas Buck 9 роки тому
джерело
коміт
8d3b675c4b

+ 4
- 0
ChangeLog.md Переглянути файл

@@ -2,6 +2,10 @@
2 2
 
3 3
 ## OpenRaider (0.1.3) xythobuz <xythobuz@xythobuz.de>
4 4
 
5
+    [ 20141126 ]
6
+    * Reduced code duplication for BinaryFile/BinaryMemory
7
+    * LoaderTR2 tries to load an external SFX file
8
+
5 9
     [ 20141124 ]
6 10
     * LoaderTR2 is starting to populate Room structures
7 11
     * Added BinaryMemory reader

+ 1
- 2
include/Exception.h Переглянути файл

@@ -14,8 +14,7 @@
14 14
 
15 15
 class Exception : std::runtime_error {
16 16
   public:
17
-    Exception(const char* what);
18
-    Exception(const std::string& what);
17
+    Exception(std::string what);
19 18
 
20 19
     static std::string getLastException();
21 20
 

+ 2
- 0
include/loader/LoaderTR2.h Переглянути файл

@@ -36,6 +36,8 @@ class LoaderTR2 : public Loader {
36 36
     void loadSoundMap();
37 37
     void loadSoundDetails();
38 38
     void loadSampleIndices();
39
+
40
+    void loadExternalSoundFile(std::string f);
39 41
 };
40 42
 
41 43
 #endif

+ 38
- 33
include/utils/binary.h Переглянути файл

@@ -9,63 +9,68 @@
9 9
 #define _UTILS_BINARY_H_
10 10
 
11 11
 #include <fstream>
12
+#include <string>
12 13
 
13
-class BinaryFile {
14
+class BinaryReader {
14 15
   public:
15
-    BinaryFile(const char* f = nullptr);
16
-    ~BinaryFile();
16
+    virtual ~BinaryReader();
17 17
 
18
-    int open(const char* f = nullptr);
18
+    virtual long long tell() = 0;
19
+    virtual void seek(long long pos = 0) = 0;
20
+    virtual bool eof() = 0;
19 21
 
20
-    long long tell();
21
-    void seek(long long pos = 0);
22
+    virtual int8_t read8();
23
+    virtual uint8_t readU8();
22 24
 
23
-    int8_t read8();
24
-    uint8_t readU8();
25
+    virtual int16_t read16();
26
+    virtual uint16_t readU16();
25 27
 
26
-    int16_t read16();
27
-    uint16_t readU16();
28
+    virtual int32_t read32();
29
+    virtual uint32_t readU32();
28 30
 
29
-    int32_t read32();
30
-    uint32_t readU32();
31
+    virtual int64_t read64();
32
+    virtual uint64_t readU64();
31 33
 
32
-    int64_t read64();
33
-    uint64_t readU64();
34
-
35
-    float readFloat();
34
+    virtual float readFloat();
36 35
 
37 36
   private:
38
-    std::ifstream file;
37
+    virtual void read(char* d, int c) = 0;
39 38
 };
40 39
 
41
-class BinaryMemory {
40
+class BinaryFile : public BinaryReader {
42 41
   public:
43
-    BinaryMemory(char* d = nullptr);
42
+    BinaryFile(std::string f = "");
43
+    virtual ~BinaryFile();
44 44
 
45
-    int open(char* d = nullptr);
45
+    int open(std::string f = "");
46 46
 
47
-    long long tell();
48
-    void seek(long long pos = 0);
47
+    virtual long long tell();
48
+    virtual void seek(long long pos = 0);
49
+    virtual bool eof();
49 50
 
50
-    int8_t read8();
51
-    uint8_t readU8();
51
+  private:
52
+    virtual void read(char* d, int c);
52 53
 
53
-    int16_t read16();
54
-    uint16_t readU16();
54
+    std::ifstream file;
55
+};
55 56
 
56
-    int32_t read32();
57
-    uint32_t readU32();
57
+class BinaryMemory : public BinaryReader {
58
+  public:
59
+    BinaryMemory(const char* d = nullptr, long long max = -1);
60
+    virtual ~BinaryMemory();
58 61
 
59
-    int64_t read64();
60
-    uint64_t readU64();
62
+    int open(const char* d = nullptr, long long max = -1);
61 63
 
62
-    float readFloat();
64
+    virtual long long tell();
65
+    virtual void seek(long long pos = 0);
66
+    virtual bool eof();
63 67
 
64 68
   private:
65
-    void read(char* d, int c);
69
+    virtual void read(char* d, int c);
66 70
 
67
-    char* data;
71
+    const char* data;
68 72
     long long offset;
73
+    long long max;
69 74
 };
70 75
 
71 76
 #endif

+ 1
- 5
src/Exception.cpp Переглянути файл

@@ -10,11 +10,7 @@
10 10
 
11 11
 std::string Exception::lastException("No custom exception since start!");
12 12
 
13
-Exception::Exception(const char* what) : runtime_error(what) {
14
-    lastException = what;
15
-}
16
-
17
-Exception::Exception(const std::string& what) : runtime_error(what) {
13
+Exception::Exception(std::string what) : runtime_error(what) {
18 14
     lastException = what;
19 15
 }
20 16
 

+ 75
- 5
src/loader/LoaderTR2.cpp Переглянути файл

@@ -24,7 +24,7 @@ LoaderTR2::~LoaderTR2() {
24 24
 }
25 25
 
26 26
 int LoaderTR2::load(std::string f) {
27
-    if (file.open(f.c_str()) != 0) {
27
+    if (file.open(f) != 0) {
28 28
         return 1; // Could not open file
29 29
     }
30 30
 
@@ -57,6 +57,8 @@ int LoaderTR2::load(std::string f) {
57 57
     loadSoundDetails();
58 58
     loadSampleIndices();
59 59
 
60
+    loadExternalSoundFile(f);
61
+
60 62
     return 0; // TODO Not finished with implementation!
61 63
 }
62 64
 
@@ -287,12 +289,20 @@ void LoaderTR2::loadMeshes() {
287 289
     }
288 290
 
289 291
     uint32_t numMeshPointers = file.readU32();
290
-    std::vector<uint32_t> meshPointers;
291
-    for (unsigned int i = 0; i < numMeshPointers; i++) {
292
-        meshPointers.push_back(file.readU32());
292
+
293
+    if ((numMeshData == 0) || (numMeshPointers == 0)) {
294
+        //! \fixme debug level regulating output?
295
+        getLog() << "LoaderTR2: No mesh data found!" << Log::endl;
296
+        return;
293 297
     }
294 298
 
295
-    // TODO interpret the buffered mesh data
299
+    for (unsigned int i = 0; i < numMeshPointers; i++) {
300
+        uint32_t meshPointer = file.readU32();
301
+        char* tmpPtr = reinterpret_cast<char*>(&buffer[meshPointer]);
302
+        BinaryMemory mem(tmpPtr, numMeshData - meshPointer);
303
+
304
+        // TODO interpret the buffered mesh data
305
+    }
296 306
 }
297 307
 
298 308
 void LoaderTR2::loadMoveables() {
@@ -561,6 +571,9 @@ void LoaderTR2::loadBoxesOverlapsZones() {
561 571
     }
562 572
 
563 573
     // TODO store zones somewhere
574
+
575
+    if ((numBoxes > 0) || (numOverlaps > 0))
576
+        getLog() << "LoaderTR2: Found NPC NavigationHints, not yet implemented!" << Log::endl;
564 577
 }
565 578
 
566 579
 void LoaderTR2::loadAnimatedTextures() {
@@ -610,6 +623,9 @@ void LoaderTR2::loadCinematicFrames() {
610 623
 
611 624
         // TODO store cinematic frames somewhere
612 625
     }
626
+
627
+    if (numCinematicFrames > 0)
628
+        getLog() << "LoaderTR2: Found CinematicFrames, not yet implemented!" << Log::endl;
613 629
 }
614 630
 
615 631
 void LoaderTR2::loadDemoData() {
@@ -618,6 +634,8 @@ void LoaderTR2::loadDemoData() {
618 634
         file.readU8();
619 635
 
620 636
     // TODO store demo data somewhere, find out meaning
637
+    if (numDemoData > 0)
638
+        getLog() << "LoaderTR2: Found DemoData, not yet implemented!" << Log::endl;
621 639
 }
622 640
 
623 641
 void LoaderTR2::loadSoundMap() {
@@ -657,3 +675,55 @@ void LoaderTR2::loadSampleIndices() {
657 675
     // TODO store sample indices somewhere
658 676
 }
659 677
 
678
+void LoaderTR2::loadExternalSoundFile(std::string f) {
679
+    size_t dir = f.find_last_of("/\\");
680
+    if (dir != std::string::npos) {
681
+        f.replace(dir + 1, std::string::npos, "MAIN.SFX");
682
+    } else {
683
+        f = "MAIN.SFX";
684
+    }
685
+
686
+    BinaryFile sfx;
687
+    if (sfx.open(f) != 0) {
688
+        getLog() << "LoaderTR2: Can't open \"" << f << "\"!" << Log::endl;
689
+        return;
690
+    }
691
+
692
+    int riffCount = 0;
693
+    bool done = false;
694
+    while (!done) {
695
+        char test[5];
696
+        test[4] = '\0';
697
+        for (int i = 0; i < 4; i++)
698
+            test[i] = sfx.read8();
699
+
700
+        if (std::string("RIFF") != std::string(test)) {
701
+            getLog() << "LoaderTR2: External SFX invalid! (" << riffCount
702
+                << ", \"" << test << "\" != \"RIFF\")" << Log::endl;
703
+            return;
704
+        }
705
+
706
+        uint32_t riffSize = sfx.readU32();
707
+
708
+        for (int i = 0; i < 4; i++)
709
+            test[i] = sfx.read8();
710
+
711
+        if (std::string("WAVE") != std::string(test)) {
712
+            getLog() << "LoaderTR2: External SFX invalid! (" << riffCount
713
+                << ", \"" << test << "\" != \"WAVE\")" << Log::endl;
714
+            return;
715
+        }
716
+
717
+        // TODO load riff somehow somewhere
718
+
719
+        // riffSize is (fileLength - 8)
720
+        sfx.seek(sfx.tell() + riffSize - 4);
721
+        riffCount++;
722
+
723
+        if (sfx.eof()) {
724
+            done = true;
725
+            getLog() << "LoaderTR2: Found " << riffCount << " SoundSamples" << Log::endl;
726
+        }
727
+    }
728
+}
729
+

+ 90
- 151
src/utils/binary.cpp Переглянути файл

@@ -5,77 +5,41 @@
5 5
  * \author xythobuz
6 6
  */
7 7
 
8
+#include <sstream>
9
+
8 10
 #include "global.h"
11
+#include "Exception.h"
9 12
 #include "utils/binary.h"
10 13
 
11
-BinaryFile::BinaryFile(const char* f) {
12
-    int r = open(f);
13
-    if (r != 0)
14
-        throw r;
15
-}
16
-
17
-BinaryFile::~BinaryFile() {
18
-    if (file.is_open())
19
-        file.close();
20
-}
21
-
22
-int BinaryFile::open(const char* f) {
23
-    if (file.is_open()) {
24
-        return 1;
25
-    } else {
26
-        if (f == nullptr)
27
-            return 0;
28
-        file.open(f, std::ios_base::in | std::ios_base::binary);
29
-        return (file ? 0 : 1);
30
-    }
31
-}
32
-
33
-long long BinaryFile::tell() {
34
-    assert(file.is_open());
35
-    return file.tellg();
36
-}
37
-
38
-void BinaryFile::seek(long long pos) {
39
-    assert(file.is_open());
40
-    file.seekg(pos);
14
+BinaryReader::~BinaryReader() {
41 15
 }
42 16
 
43
-uint8_t BinaryFile::readU8() {
44
-    assert(file.is_open());
45
-    assert(file.good());
17
+uint8_t BinaryReader::readU8() {
46 18
     uint8_t ret;
47 19
     char* c = reinterpret_cast<char*>(&ret);
48
-    file.read(c, 1);
20
+    read(c, 1);
49 21
     return ret;
50 22
 }
51 23
 
52
-uint16_t BinaryFile::readU16() {
53
-    assert(file.is_open());
54
-    assert(file.good());
55
-    uint8_t a = readU8();
56
-    uint8_t b = readU8();
57
-    return ((uint16_t)a | (uint16_t)(b << 8));
24
+uint16_t BinaryReader::readU16() {
25
+    uint16_t a = readU8();
26
+    uint16_t b = readU8();
27
+    return (a | (b << 8));
58 28
 }
59 29
 
60
-uint32_t BinaryFile::readU32() {
61
-    assert(file.is_open());
62
-    assert(file.good());
63
-    uint16_t a = readU16();
64
-    uint16_t b = readU16();
65
-    return ((uint32_t)a | (uint32_t)(b << 16));
30
+uint32_t BinaryReader::readU32() {
31
+    uint32_t a = readU16();
32
+    uint32_t b = readU16();
33
+    return (a | (b << 16));
66 34
 }
67 35
 
68
-uint64_t BinaryFile::readU64() {
69
-    assert(file.is_open());
70
-    assert(file.good());
71
-    uint32_t a = readU32();
72
-    uint32_t b = readU32();
73
-    return ((uint64_t)a | ((uint64_t)b << 32));
36
+uint64_t BinaryReader::readU64() {
37
+    uint64_t a = readU32();
38
+    uint64_t b = readU32();
39
+    return (a | (b << 32));
74 40
 }
75 41
 
76
-float BinaryFile::readFloat() {
77
-    assert(file.is_open());
78
-    assert(file.good());
42
+float BinaryReader::readFloat() {
79 43
     uint32_t val = readU32();
80 44
     char* a = reinterpret_cast<char*>(&val);
81 45
 
@@ -95,7 +59,7 @@ namespace {
95 59
      *  without having to detect the endianness at run-time?
96 60
      */
97 61
     const int bigendiandetection = 1;
98
-#define ISBIGENDIAN() ((*(char *)&bigendiandetection) == 0)
62
+#define ISBIGENDIAN() ((*reinterpret_cast<const char *>(&bigendiandetection)) == 0)
99 63
 
100 64
     void swapByteOrder(char* d, unsigned int n) {
101 65
         if (ISBIGENDIAN()) {
@@ -108,158 +72,133 @@ namespace {
108 72
     }
109 73
 }
110 74
 
111
-int8_t BinaryFile::read8() {
112
-    assert(file.is_open());
113
-    assert(file.good());
75
+int8_t BinaryReader::read8() {
114 76
     int8_t ret;
115 77
     char* p = reinterpret_cast<char*>(&ret);
116
-    file.read(p, sizeof(ret));
78
+    read(p, sizeof(ret));
117 79
     return ret;
118 80
 }
119 81
 
120
-int16_t BinaryFile::read16() {
121
-    assert(file.is_open());
122
-    assert(file.good());
82
+int16_t BinaryReader::read16() {
123 83
     int16_t ret;
124 84
     char* p = reinterpret_cast<char*>(&ret);
125
-    file.read(p, sizeof(ret));
85
+    read(p, sizeof(ret));
126 86
     swapByteOrder(p, 2);
127 87
     return ret;
128 88
 }
129 89
 
130
-int32_t BinaryFile::read32() {
131
-    assert(file.is_open());
132
-    assert(file.good());
90
+int32_t BinaryReader::read32() {
133 91
     int32_t ret;
134 92
     char* p = reinterpret_cast<char*>(&ret);
135
-    file.read(p, sizeof(ret));
93
+    read(p, sizeof(ret));
136 94
     swapByteOrder(p, 4);
137 95
     return ret;
138 96
 }
139 97
 
140
-int64_t BinaryFile::read64() {
141
-    assert(file.is_open());
142
-    assert(file.good());
98
+int64_t BinaryReader::read64() {
143 99
     int64_t ret;
144 100
     char* p = reinterpret_cast<char*>(&ret);
145
-    file.read(p, sizeof(ret));
101
+    read(p, sizeof(ret));
146 102
     swapByteOrder(p, 8);
147 103
     return ret;
148 104
 }
149 105
 
150 106
 // ----------------------------------------------------------------------------
151 107
 
152
-BinaryMemory::BinaryMemory(char* d) : data(nullptr), offset(0) {
153
-    int r = open(d);
108
+BinaryFile::BinaryFile(std::string f) {
109
+    int r = open(f);
154 110
     if (r != 0)
155 111
         throw r;
156 112
 }
157 113
 
158
-int BinaryMemory::open(char* d) {
159
-    if (data != nullptr)
160
-        return 1;
114
+BinaryFile::~BinaryFile() {
115
+    if (file.is_open())
116
+        file.close();
117
+}
161 118
 
162
-    if (d != nullptr) {
163
-        data = d;
164
-        offset = 0;
119
+int BinaryFile::open(std::string f) {
120
+    if (file.is_open()) {
121
+        return 1;
122
+    } else {
123
+        if (f == "")
124
+            return 0;
125
+        file.open(f, std::ios_base::in | std::ios_base::binary);
126
+        return (file ? 0 : 1);
165 127
     }
166
-
167
-    return 0;
168 128
 }
169 129
 
170
-long long BinaryMemory::tell() {
171
-    assert(offset >= 0);
172
-    return offset;
130
+long long BinaryFile::tell() {
131
+    assert(file.is_open());
132
+    return file.tellg();
173 133
 }
174 134
 
175
-void BinaryMemory::seek(long long pos) {
176
-    assert(pos >= 0);
177
-    offset = pos;
135
+void BinaryFile::seek(long long pos) {
136
+    assert(file.is_open());
137
+    file.seekg(pos);
178 138
 }
179 139
 
180
-void BinaryMemory::read(char* d, int c) {
181
-    for (int i = 0; i < c; i++) {
182
-        d[i] = data[offset + i];
183
-    }
184
-    offset += c;
140
+bool BinaryFile::eof() {
141
+    file.peek();
142
+    return file.eof();
185 143
 }
186 144
 
187
-uint8_t BinaryMemory::readU8() {
188
-    assert(offset >= 0);
189
-    uint8_t ret;
190
-    char* c = reinterpret_cast<char*>(&ret);
191
-    read(c, 1);
192
-    return ret;
145
+void BinaryFile::read(char* d, int c) {
146
+    assert(file.is_open());
147
+    assert(file.good());
148
+    file.read(d, c);
193 149
 }
194 150
 
195
-uint16_t BinaryMemory::readU16() {
196
-    assert(offset >= 0);
197
-    uint8_t a = readU8();
198
-    uint8_t b = readU8();
199
-    return ((uint16_t)a | (uint16_t)(b << 8));
200
-}
151
+// ----------------------------------------------------------------------------
201 152
 
202
-uint32_t BinaryMemory::readU32() {
203
-    assert(offset >= 0);
204
-    uint16_t a = readU16();
205
-    uint16_t b = readU16();
206
-    return ((uint32_t)a | (uint32_t)(b << 16));
153
+BinaryMemory::BinaryMemory(const char* d, long long m) : data(nullptr), offset(0), max(-1) {
154
+    int r = open(d, m);
155
+    if (r != 0)
156
+        throw r;
207 157
 }
208 158
 
209
-uint64_t BinaryMemory::readU64() {
210
-    assert(offset >= 0);
211
-    uint32_t a = readU32();
212
-    uint32_t b = readU32();
213
-    return ((uint64_t)a | (uint64_t)(b << 32));
159
+BinaryMemory::~BinaryMemory() {
214 160
 }
215 161
 
216
-float BinaryMemory::readFloat() {
217
-    assert(offset >= 0);
218
-    uint32_t val = readU32();
219
-    char* a = reinterpret_cast<char*>(&val);
220
-
221
-    float ret;
222
-    char* b = reinterpret_cast<char*>(&ret);
162
+int BinaryMemory::open(const char* d, long long m) {
163
+    if (data != nullptr)
164
+        return 1;
223 165
 
224
-    for (int i = 0; i < 4; i++)
225
-        b[i] = a[i];
166
+    if (d != nullptr) {
167
+        data = d;
168
+        offset = 0;
169
+        max = m;
170
+    }
226 171
 
227
-    return ret;
172
+    return 0;
228 173
 }
229 174
 
230
-int8_t BinaryMemory::read8() {
175
+long long BinaryMemory::tell() {
231 176
     assert(offset >= 0);
232
-    int8_t ret;
233
-    char* p = reinterpret_cast<char*>(&ret);
234
-    read(p, sizeof(ret));
235
-    return ret;
177
+    return offset;
236 178
 }
237 179
 
238
-int16_t BinaryMemory::read16() {
239
-    assert(offset >= 0);
240
-    int16_t ret;
241
-    char* p = reinterpret_cast<char*>(&ret);
242
-    read(p, sizeof(ret));
243
-    swapByteOrder(p, 2);
244
-    return ret;
180
+void BinaryMemory::seek(long long pos) {
181
+    assert(pos >= 0);
182
+    offset = pos;
245 183
 }
246 184
 
247
-int32_t BinaryMemory::read32() {
248
-    assert(offset >= 0);
249
-    int32_t ret;
250
-    char* p = reinterpret_cast<char*>(&ret);
251
-    read(p, sizeof(ret));
252
-    swapByteOrder(p, 4);
253
-    return ret;
185
+bool BinaryMemory::eof() {
186
+    return (offset > max);
254 187
 }
255 188
 
256
-int64_t BinaryMemory::read64() {
257
-    assert(offset >= 0);
189
+void BinaryMemory::read(char* d, int c) {
258 190
     assert(offset >= 0);
259
-    int64_t ret;
260
-    char* p = reinterpret_cast<char*>(&ret);
261
-    read(p, sizeof(ret));
262
-    swapByteOrder(p, 8);
263
-    return ret;
191
+    assert(c > 0);
192
+    if ((offset + c) > max) {
193
+        std::ostringstream ss;
194
+        ss << "BinaryMemory read out of bounds ("
195
+            << offset << " + " << c << " > " << max;
196
+        throw new Exception(ss.str());
197
+    }
198
+
199
+    for (int i = 0; i < c; i++) {
200
+        d[i] = data[offset + i];
201
+    }
202
+    offset += c;
264 203
 }
265 204
 

Завантаження…
Відмінити
Зберегти