Browse Source

Added level loader test driver and fixed parsing bug

Thomas Buck 10 years ago
parent
commit
8b3cd134e0
6 changed files with 106 additions and 37 deletions
  1. 4
    0
      ChangeLog.md
  2. 1
    0
      include/Log.h
  3. 11
    37
      src/loader/LoaderTR2.cpp
  4. 9
    0
      src/utils/binary.cpp
  5. 10
    0
      test/CMakeLists.txt
  6. 71
    0
      test/Loader.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
+    [ 20141011 ]
6
+    * Added simple level loader unit test driver
7
+    * Fixed the parsing bug in the new loader that sometimes caused strange hangs on level load
8
+
5
     [ 20141010 ]
9
     [ 20141010 ]
6
     * Added CPack packaging to the CMake script
10
     * Added CPack packaging to the CMake script
7
     * Added suitable install target for the Mac App Bundle
11
     * Added suitable install target for the Mac App Bundle

+ 1
- 0
include/Log.h View File

43
 Log &getLog();
43
 Log &getLog();
44
 
44
 
45
 #endif
45
 #endif
46
+

+ 11
- 37
src/loader/LoaderTR2.cpp View File

29
     }
29
     }
30
 
30
 
31
     loadPaletteTextiles();
31
     loadPaletteTextiles();
32
-    getLog() << "->loaded palette" << Log::endl;
33
 
32
 
34
     file.seek(file.tell() + 4); // Unused value?
33
     file.seek(file.tell() + 4); // Unused value?
35
 
34
 
36
     loadRooms();
35
     loadRooms();
37
-    getLog() << "->loaded rooms" << Log::endl;
38
-
39
     loadFloorData();
36
     loadFloorData();
40
-    getLog() << "->loaded floor data" << Log::endl;
41
-
42
     loadMeshes();
37
     loadMeshes();
43
-    getLog() << "->loaded meshes" << Log::endl;
44
-
45
     loadMoveables();
38
     loadMoveables();
46
-    getLog() << "->loaded moveables" << Log::endl;
47
-
48
     loadStaticMeshes();
39
     loadStaticMeshes();
49
-    getLog() << "->loaded static meshes" << Log::endl;
50
-
51
     loadTextures();
40
     loadTextures();
52
-    getLog() << "->loaded textures" << Log::endl;
53
-
54
     loadSprites();
41
     loadSprites();
55
-    getLog() << "->loaded sprites" << Log::endl;
56
-
57
     loadCameras();
42
     loadCameras();
58
-    getLog() << "->loaded cameras" << Log::endl;
59
-
60
     loadSoundSources();
43
     loadSoundSources();
61
-    getLog() << "->loaded sound sources" << Log::endl;
62
-
63
     loadBoxesOverlapsZones();
44
     loadBoxesOverlapsZones();
64
-    getLog() << "->loaded boxes overlaps zones" << Log::endl;
65
-
66
     loadAnimatedTextures();
45
     loadAnimatedTextures();
67
-    getLog() << "->loaded animated textures" << Log::endl;
68
-
69
     loadItems();
46
     loadItems();
70
-    getLog() << "->loaded items" << Log::endl;
71
 
47
 
72
     file.seek(file.tell() + 8192); // Skip Light map, only for 8bit coloring
48
     file.seek(file.tell() + 8192); // Skip Light map, only for 8bit coloring
73
 
49
 
74
     loadCinematicFrames();
50
     loadCinematicFrames();
75
-    getLog() << "->loaded cinematic frames" << Log::endl;
76
-
77
     loadDemoData();
51
     loadDemoData();
78
-    getLog() << "->loaded demo data" << Log::endl;
79
-
80
     loadSoundMap();
52
     loadSoundMap();
81
-    getLog() << "->loaded sound map" << Log::endl;
82
-
83
     loadSoundDetails();
53
     loadSoundDetails();
84
-    getLog() << "->loaded sound details" << Log::endl;
85
-
86
     loadSampleIndices();
54
     loadSampleIndices();
87
-    getLog() << "->loaded sample indices" << Log::endl;
88
 
55
 
89
     return 0;
56
     return 0;
90
 }
57
 }
116
 
83
 
117
 void LoaderTR2::loadRooms() {
84
 void LoaderTR2::loadRooms() {
118
     uint16_t numRooms = file.readU16();
85
     uint16_t numRooms = file.readU16();
86
+
119
     for (unsigned int i = 0; i < numRooms; i++) {
87
     for (unsigned int i = 0; i < numRooms; i++) {
120
         // Room Header
88
         // Room Header
121
         int32_t xOffset = file.read32();
89
         int32_t xOffset = file.read32();
142
             // 0x0010 - Normal?
110
             // 0x0010 - Normal?
143
             uint16_t attributes = file.readU16();
111
             uint16_t attributes = file.readU16();
144
 
112
 
145
-            int16_t lighting2; // Almost always equal to lighting1
113
+            int16_t lighting2 = file.read16(); // Almost always equal to lighting1
146
 
114
 
147
             // TODO store vertex somewhere
115
             // TODO store vertex somewhere
148
         }
116
         }
205
             int16_t xCorner3 = file.read16();
173
             int16_t xCorner3 = file.read16();
206
             int16_t yCorner3 = file.read16();
174
             int16_t yCorner3 = file.read16();
207
             int16_t zCorner3 = file.read16();
175
             int16_t zCorner3 = file.read16();
176
+            int16_t xCorner4 = file.read16();
177
+            int16_t yCorner4 = file.read16();
178
+            int16_t zCorner4 = file.read16();
208
 
179
 
209
             // TODO store portals somewhere
180
             // TODO store portals somewhere
210
         }
181
         }
293
     // only afterward we can read the number of meshes
264
     // only afterward we can read the number of meshes
294
     // in this data block
265
     // in this data block
295
     uint32_t numMeshData = file.readU32();
266
     uint32_t numMeshData = file.readU32();
296
-
297
     std::vector<uint16_t> buffer;
267
     std::vector<uint16_t> buffer;
298
     for (unsigned int i = 0; i < numMeshData; i++) {
268
     for (unsigned int i = 0; i < numMeshData; i++) {
299
         buffer.push_back(file.readU16());
269
         buffer.push_back(file.readU16());
332
         uint16_t nextFrame = file.readU16();
302
         uint16_t nextFrame = file.readU16();
333
         uint16_t numStateChanges = file.readU16();
303
         uint16_t numStateChanges = file.readU16();
334
         uint16_t stateChangeOffset = file.readU16(); // Index into StateChanges[]
304
         uint16_t stateChangeOffset = file.readU16(); // Index into StateChanges[]
335
-        uint16_t numAnimCommands; // How many animation commands to use
336
-        uint16_t animCommandOffset; // Index into AnimCommand[]
305
+        uint16_t numAnimCommands = file.readU16(); // How many animation commands to use
306
+        uint16_t animCommandOffset = file.readU16(); // Index into AnimCommand[]
337
 
307
 
338
         // TODO store animations somewhere
308
         // TODO store animations somewhere
339
     }
309
     }
372
         // reading the stack but not changing it
342
         // reading the stack but not changing it
373
         uint32_t flags = file.readU32();
343
         uint32_t flags = file.readU32();
374
 
344
 
345
+
375
         // Offset of mesh origin from the parent mesh origin
346
         // Offset of mesh origin from the parent mesh origin
347
+
348
+        /* Where the hell does this come from?!
376
         int32_t x = file.read32();
349
         int32_t x = file.read32();
377
         int32_t y = file.read32();
350
         int32_t y = file.read32();
378
         int32_t z = file.read32();
351
         int32_t z = file.read32();
352
+        */
379
 
353
 
380
         // TODO store mesh trees somewhere
354
         // TODO store mesh trees somewhere
381
     }
355
     }

+ 9
- 0
src/utils/binary.cpp View File

34
 
34
 
35
 uint8_t BinaryFile::readU8() {
35
 uint8_t BinaryFile::readU8() {
36
     assert(file.is_open());
36
     assert(file.is_open());
37
+    assert(file.good());
37
     uint8_t ret;
38
     uint8_t ret;
38
     char *c = reinterpret_cast<char *>(&ret);
39
     char *c = reinterpret_cast<char *>(&ret);
39
     file.read(c, 1);
40
     file.read(c, 1);
42
 
43
 
43
 uint16_t BinaryFile::readU16() {
44
 uint16_t BinaryFile::readU16() {
44
     assert(file.is_open());
45
     assert(file.is_open());
46
+    assert(file.good());
45
     uint8_t a = readU8();
47
     uint8_t a = readU8();
46
     uint8_t b = readU8();
48
     uint8_t b = readU8();
47
     return ((uint16_t)a | (uint16_t)(b << 8));
49
     return ((uint16_t)a | (uint16_t)(b << 8));
49
 
51
 
50
 uint32_t BinaryFile::readU32() {
52
 uint32_t BinaryFile::readU32() {
51
     assert(file.is_open());
53
     assert(file.is_open());
54
+    assert(file.good());
52
     uint16_t a = readU16();
55
     uint16_t a = readU16();
53
     uint16_t b = readU16();
56
     uint16_t b = readU16();
54
     return ((uint32_t)a | (uint32_t)(b << 16));
57
     return ((uint32_t)a | (uint32_t)(b << 16));
56
 
59
 
57
 uint64_t BinaryFile::readU64() {
60
 uint64_t BinaryFile::readU64() {
58
     assert(file.is_open());
61
     assert(file.is_open());
62
+    assert(file.good());
59
     uint32_t a = readU32();
63
     uint32_t a = readU32();
60
     uint32_t b = readU32();
64
     uint32_t b = readU32();
61
     return ((uint64_t)a | ((uint64_t)b << 32));
65
     return ((uint64_t)a | ((uint64_t)b << 32));
63
 
67
 
64
 float BinaryFile::readFloat() {
68
 float BinaryFile::readFloat() {
65
     assert(file.is_open());
69
     assert(file.is_open());
70
+    assert(file.good());
66
     uint32_t val = readU32();
71
     uint32_t val = readU32();
67
     char *a = reinterpret_cast<char *>(&val);
72
     char *a = reinterpret_cast<char *>(&val);
68
 
73
 
97
 
102
 
98
 int8_t BinaryFile::read8() {
103
 int8_t BinaryFile::read8() {
99
     assert(file.is_open());
104
     assert(file.is_open());
105
+    assert(file.good());
100
     int8_t ret;
106
     int8_t ret;
101
     char *p = reinterpret_cast<char *>(&ret);
107
     char *p = reinterpret_cast<char *>(&ret);
102
     file.read(p, sizeof(ret));
108
     file.read(p, sizeof(ret));
105
 
111
 
106
 int16_t BinaryFile::read16() {
112
 int16_t BinaryFile::read16() {
107
     assert(file.is_open());
113
     assert(file.is_open());
114
+    assert(file.good());
108
     int16_t ret;
115
     int16_t ret;
109
     char *p = reinterpret_cast<char *>(&ret);
116
     char *p = reinterpret_cast<char *>(&ret);
110
     file.read(p, sizeof(ret));
117
     file.read(p, sizeof(ret));
114
 
121
 
115
 int32_t BinaryFile::read32() {
122
 int32_t BinaryFile::read32() {
116
     assert(file.is_open());
123
     assert(file.is_open());
124
+    assert(file.good());
117
     int32_t ret;
125
     int32_t ret;
118
     char *p = reinterpret_cast<char *>(&ret);
126
     char *p = reinterpret_cast<char *>(&ret);
119
     file.read(p, sizeof(ret));
127
     file.read(p, sizeof(ret));
123
 
131
 
124
 int64_t BinaryFile::read64() {
132
 int64_t BinaryFile::read64() {
125
     assert(file.is_open());
133
     assert(file.is_open());
134
+    assert(file.good());
126
     int64_t ret;
135
     int64_t ret;
127
     char *p = reinterpret_cast<char *>(&ret);
136
     char *p = reinterpret_cast<char *>(&ret);
128
     file.read(p, sizeof(ret));
137
     file.read(p, sizeof(ret));

+ 10
- 0
test/CMakeLists.txt View File

15
 
15
 
16
 #################################################################
16
 #################################################################
17
 
17
 
18
+add_executable (tester_loader EXCLUDE_FROM_ALL
19
+    "Loader.cpp" "../src/utils/binary.cpp"
20
+    "../src/loader/Loader.cpp" "../src/loader/LoaderTR1.cpp"
21
+    "../src/loader/LoaderTR2.cpp" "../src/loader/LoaderTR3.cpp"
22
+)
23
+add_dependencies (check tester_loader)
24
+add_test (NAME test_loader COMMAND tester_loader)
25
+
26
+#################################################################
27
+
18
 add_executable (tester_script EXCLUDE_FROM_ALL
28
 add_executable (tester_script EXCLUDE_FROM_ALL
19
     "Script.cpp" "../src/Script.cpp" "../src/main.cpp"
29
     "Script.cpp" "../src/Script.cpp" "../src/main.cpp"
20
     "../src/utils/binary.cpp" "../src/Exception.cpp"
30
     "../src/utils/binary.cpp" "../src/Exception.cpp"

+ 71
- 0
test/Loader.cpp View File

1
+/*!
2
+ * \file test/Loader.cpp
3
+ * \brief Level Loader Unit Test
4
+ *
5
+ * \author xythobuz
6
+ */
7
+
8
+#include "global.h"
9
+#include "loader/Loader.h"
10
+
11
+int main(int argc, char *argv[]) {
12
+    if (argc != 2) {
13
+        std::cout << "Usage:" << std::endl;
14
+        std::cout << "\t" << argv[0] << " /path/to/level.tr2" << std::endl;
15
+        return 0; // Don't fail when just running this test...
16
+    }
17
+
18
+    // Print file engine version
19
+    std::cout << "Loading \"" << argv[1] << "\"" << std::endl;
20
+    std::cout << "Trying to detect engine version... ";
21
+    Loader::LoaderVersion v = Loader::checkFile(argv[1]);
22
+    switch (v) {
23
+        case Loader::TR_1:
24
+            std::cout << "TR 1";
25
+            break;
26
+
27
+        case Loader::TR_2:
28
+            std::cout << "TR 2";
29
+            break;
30
+
31
+        case Loader::TR_3:
32
+            std::cout << "TR 3";
33
+            break;
34
+
35
+        case Loader::TR_4:
36
+            std::cout << "TR 4";
37
+            break;
38
+
39
+        case Loader::TR_5:
40
+            std::cout << "TR 5";
41
+            break;
42
+
43
+        case Loader::TR_UNKNOWN:
44
+            std::cout << "Unknown version!" << std::endl;
45
+            return 2;
46
+    }
47
+    std::cout << " detected!" << std::endl;
48
+
49
+    // Create matching loader
50
+    std::cout << std::endl << "Creating level loader... ";
51
+    std::unique_ptr<Loader> loader = Loader::createLoader(argv[1]);
52
+    if (!loader) {
53
+        std::cout << "Failed!" << std::endl;
54
+        return 3;
55
+    } else {
56
+        std::cout << "Success!" << std::endl;
57
+    }
58
+
59
+    // Try to load the level
60
+    std::cout << "Trying to load level... ";
61
+    int error = loader->load(argv[1]);
62
+    if (error != 0) {
63
+        std::cout << "Failure!" << std::endl;
64
+        std::cout << "Error code: " << error << std::endl;
65
+    } else {
66
+        std::cout << "Success!" << std::endl;
67
+    }
68
+
69
+    return error;
70
+}
71
+

Loading…
Cancel
Save