Browse Source

LoaderTR2 tries to load external SFX file

Thomas Buck 10 years ago
parent
commit
8d3b675c4b
7 changed files with 211 additions and 196 deletions
  1. 4
    0
      ChangeLog.md
  2. 1
    2
      include/Exception.h
  3. 2
    0
      include/loader/LoaderTR2.h
  4. 38
    33
      include/utils/binary.h
  5. 1
    5
      src/Exception.cpp
  6. 75
    5
      src/loader/LoaderTR2.cpp
  7. 90
    151
      src/utils/binary.cpp

+ 4
- 0
ChangeLog.md View File

2
 
2
 
3
 ## OpenRaider (0.1.3) xythobuz <xythobuz@xythobuz.de>
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
     [ 20141124 ]
9
     [ 20141124 ]
6
     * LoaderTR2 is starting to populate Room structures
10
     * LoaderTR2 is starting to populate Room structures
7
     * Added BinaryMemory reader
11
     * Added BinaryMemory reader

+ 1
- 2
include/Exception.h View File

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

+ 2
- 0
include/loader/LoaderTR2.h View File

36
     void loadSoundMap();
36
     void loadSoundMap();
37
     void loadSoundDetails();
37
     void loadSoundDetails();
38
     void loadSampleIndices();
38
     void loadSampleIndices();
39
+
40
+    void loadExternalSoundFile(std::string f);
39
 };
41
 };
40
 
42
 
41
 #endif
43
 #endif

+ 38
- 33
include/utils/binary.h View File

9
 #define _UTILS_BINARY_H_
9
 #define _UTILS_BINARY_H_
10
 
10
 
11
 #include <fstream>
11
 #include <fstream>
12
+#include <string>
12
 
13
 
13
-class BinaryFile {
14
+class BinaryReader {
14
   public:
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
   private:
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
   public:
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
   private:
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
     long long offset;
72
     long long offset;
73
+    long long max;
69
 };
74
 };
70
 
75
 
71
 #endif
76
 #endif

+ 1
- 5
src/Exception.cpp View File

10
 
10
 
11
 std::string Exception::lastException("No custom exception since start!");
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
     lastException = what;
14
     lastException = what;
19
 }
15
 }
20
 
16
 

+ 75
- 5
src/loader/LoaderTR2.cpp View File

24
 }
24
 }
25
 
25
 
26
 int LoaderTR2::load(std::string f) {
26
 int LoaderTR2::load(std::string f) {
27
-    if (file.open(f.c_str()) != 0) {
27
+    if (file.open(f) != 0) {
28
         return 1; // Could not open file
28
         return 1; // Could not open file
29
     }
29
     }
30
 
30
 
57
     loadSoundDetails();
57
     loadSoundDetails();
58
     loadSampleIndices();
58
     loadSampleIndices();
59
 
59
 
60
+    loadExternalSoundFile(f);
61
+
60
     return 0; // TODO Not finished with implementation!
62
     return 0; // TODO Not finished with implementation!
61
 }
63
 }
62
 
64
 
287
     }
289
     }
288
 
290
 
289
     uint32_t numMeshPointers = file.readU32();
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
 void LoaderTR2::loadMoveables() {
308
 void LoaderTR2::loadMoveables() {
561
     }
571
     }
562
 
572
 
563
     // TODO store zones somewhere
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
 void LoaderTR2::loadAnimatedTextures() {
579
 void LoaderTR2::loadAnimatedTextures() {
610
 
623
 
611
         // TODO store cinematic frames somewhere
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
 void LoaderTR2::loadDemoData() {
631
 void LoaderTR2::loadDemoData() {
618
         file.readU8();
634
         file.readU8();
619
 
635
 
620
     // TODO store demo data somewhere, find out meaning
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
 void LoaderTR2::loadSoundMap() {
641
 void LoaderTR2::loadSoundMap() {
657
     // TODO store sample indices somewhere
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 View File

5
  * \author xythobuz
5
  * \author xythobuz
6
  */
6
  */
7
 
7
 
8
+#include <sstream>
9
+
8
 #include "global.h"
10
 #include "global.h"
11
+#include "Exception.h"
9
 #include "utils/binary.h"
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
     uint8_t ret;
18
     uint8_t ret;
47
     char* c = reinterpret_cast<char*>(&ret);
19
     char* c = reinterpret_cast<char*>(&ret);
48
-    file.read(c, 1);
20
+    read(c, 1);
49
     return ret;
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
     uint32_t val = readU32();
43
     uint32_t val = readU32();
80
     char* a = reinterpret_cast<char*>(&val);
44
     char* a = reinterpret_cast<char*>(&val);
81
 
45
 
95
      *  without having to detect the endianness at run-time?
59
      *  without having to detect the endianness at run-time?
96
      */
60
      */
97
     const int bigendiandetection = 1;
61
     const int bigendiandetection = 1;
98
-#define ISBIGENDIAN() ((*(char *)&bigendiandetection) == 0)
62
+#define ISBIGENDIAN() ((*reinterpret_cast<const char *>(&bigendiandetection)) == 0)
99
 
63
 
100
     void swapByteOrder(char* d, unsigned int n) {
64
     void swapByteOrder(char* d, unsigned int n) {
101
         if (ISBIGENDIAN()) {
65
         if (ISBIGENDIAN()) {
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
     int8_t ret;
76
     int8_t ret;
115
     char* p = reinterpret_cast<char*>(&ret);
77
     char* p = reinterpret_cast<char*>(&ret);
116
-    file.read(p, sizeof(ret));
78
+    read(p, sizeof(ret));
117
     return ret;
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
     int16_t ret;
83
     int16_t ret;
124
     char* p = reinterpret_cast<char*>(&ret);
84
     char* p = reinterpret_cast<char*>(&ret);
125
-    file.read(p, sizeof(ret));
85
+    read(p, sizeof(ret));
126
     swapByteOrder(p, 2);
86
     swapByteOrder(p, 2);
127
     return ret;
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
     int32_t ret;
91
     int32_t ret;
134
     char* p = reinterpret_cast<char*>(&ret);
92
     char* p = reinterpret_cast<char*>(&ret);
135
-    file.read(p, sizeof(ret));
93
+    read(p, sizeof(ret));
136
     swapByteOrder(p, 4);
94
     swapByteOrder(p, 4);
137
     return ret;
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
     int64_t ret;
99
     int64_t ret;
144
     char* p = reinterpret_cast<char*>(&ret);
100
     char* p = reinterpret_cast<char*>(&ret);
145
-    file.read(p, sizeof(ret));
101
+    read(p, sizeof(ret));
146
     swapByteOrder(p, 8);
102
     swapByteOrder(p, 8);
147
     return ret;
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
     if (r != 0)
110
     if (r != 0)
155
         throw r;
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
     assert(offset >= 0);
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
     assert(offset >= 0);
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
 

Loading…
Cancel
Save