浏览代码

Added support for TR1 levels

Thomas Buck 9 年前
父节点
当前提交
9e759a7937

+ 1
- 0
CMakeLists.txt 查看文件

@@ -37,6 +37,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
37 37
     set (WARNINGS "${WARNINGS} -Wno-padded -Wno-packed")
38 38
     set (WARNINGS "${WARNINGS} -Wno-global-constructors -Wno-exit-time-destructors")
39 39
     set (WARNINGS "${WARNINGS} -Wno-documentation-unknown-command -Wno-c++98-compat-pedantic")
40
+    set (WARNINGS "${WARNINGS} -Wno-shorten-64-to-32 -Wno-sign-compare -Wno-sign-conversion")
40 41
     set (OpenRaider_CXX_FLAGS "${OpenRaider_CXX_FLAGS} -std=c++11")
41 42
     set (OpenRaider_CXX_FLAGS_DEBUG "${OpenRaider_CXX_FLAGS_DEBUG} -g -O0 -ftrapv")
42 43
     set (OpenRaider_CXX_FLAGS_RELEASE "${OpenRaider_CXX_FLAGS_RELEASE} -O2 -fomit-frame-pointer")

+ 3
- 0
ChangeLog.md 查看文件

@@ -2,6 +2,9 @@
2 2
 
3 3
 ## OpenRaider (0.1.3) xythobuz <xythobuz@xythobuz.de>
4 4
 
5
+    [ 20140304 ]
6
+    * Added (more or less working) support for loading TR1 levels
7
+
5 8
     [ 20140222 ]
6 9
     * Updated imgui to version 1.33
7 10
 

+ 4
- 5
include/Mesh.h 查看文件

@@ -22,13 +22,12 @@ struct IndexedRectangle {
22 22
 };
23 23
 
24 24
 struct IndexedColoredRectangle {
25
-    unsigned int v1, v2, v3, v4;
26
-    unsigned char r, g, b;
25
+    unsigned int v1, v2, v3, v4, index;
27 26
 
28
-    IndexedColoredRectangle(unsigned char _r, unsigned char _g, unsigned char _b,
27
+    IndexedColoredRectangle(unsigned int paletteIndex,
29 28
                             unsigned int _v1, unsigned int _v2,
30 29
                             unsigned int _v3, unsigned int _v4 = 0)
31
-        : v1(_v1), v2(_v2), v3(_v3), v4(_v4), r(_r), g(_g), b(_b) { }
30
+        : v1(_v1), v2(_v2), v3(_v3), v4(_v4), index(paletteIndex) { }
32 31
 };
33 32
 
34 33
 // --------------------------------------
@@ -50,7 +49,7 @@ class Mesh {
50 49
 
51 50
     std::vector<unsigned short> indicesColorBuff;
52 51
     std::vector<glm::vec3> verticesColorBuff;
53
-    std::vector<glm::vec3> colorsBuff;
52
+    std::vector<unsigned int> colorsBuff;
54 53
 
55 54
     ShaderBuffer indices, vertices, uvs;
56 55
     ShaderBuffer indicesColor, verticesColor, colors;

+ 11
- 0
include/TextureManager.h 查看文件

@@ -9,6 +9,8 @@
9 9
 #ifndef _TEXTURE_MANAGER_H
10 10
 #define _TEXTURE_MANAGER_H
11 11
 
12
+#include <array>
13
+#include <tuple>
12 14
 #include <vector>
13 15
 
14 16
 // These are loaded into TextureStorage::SYSTEM by initialize()!
@@ -68,6 +70,7 @@ class TextureManager {
68 70
     static int initializeSplash();
69 71
     static void shutdown();
70 72
     static void clear();
73
+    static void prepare();
71 74
 
72 75
     static int numTextures(TextureStorage s = TextureStorage::GAME);
73 76
 
@@ -114,6 +117,11 @@ class TextureManager {
114 117
 
115 118
     static unsigned int getTextureID(int n, TextureStorage s);
116 119
 
120
+    static void setPalette(int index, glm::vec4 color);
121
+    static glm::vec4 getPalette(int index);
122
+
123
+    static void addIndexedTexture(unsigned char* image, unsigned int width, unsigned int height);
124
+
117 125
   private:
118 126
     static std::vector<unsigned int>& getIds(TextureStorage s);
119 127
     static std::vector<int>& getUnits(TextureStorage s);
@@ -133,6 +141,9 @@ class TextureManager {
133 141
 
134 142
     static std::vector<BufferManager> gameBuffers;
135 143
     static std::vector<BufferManager> systemBuffers;
144
+
145
+    static std::array<glm::vec4, 256> colorPalette;
146
+    static std::vector<std::tuple<unsigned char*, unsigned int, unsigned int>> indexedTextures;
136 147
 };
137 148
 
138 149
 #endif

+ 8
- 8
include/global.h 查看文件

@@ -109,7 +109,7 @@ typedef enum {
109 109
 
110 110
 template<typename T, typename U>
111 111
 [[noreturn]] void assertEqualImplementation(const char* exp, T a, U b, const char* file, int line,
112
-        bool print = false, const char* str = nullptr) {
112
+                                            const char* str = nullptr) {
113 113
     const unsigned int maxSize = 128;
114 114
     void* callstack[maxSize];
115 115
     int frames = backtrace(callstack, maxSize);
@@ -117,7 +117,7 @@ template<typename T, typename U>
117 117
 
118 118
     std::cout << std::endl << "assertion failed:" << std::endl;
119 119
     std::cout << "\t" << exp << std::endl;
120
-    if (print)
120
+    if (str != nullptr)
121 121
         std::cout << "\t(" << a << " " << str << " " << b << ")" << std::endl;
122 122
     std::cout << "in " << file << ":" << line << std::endl << std::endl;
123 123
 
@@ -142,7 +142,7 @@ template<typename T, typename U>
142 142
     auto assertEvalTemp2 = y; \
143 143
     if (assertEvalTemp != assertEvalTemp2) \
144 144
         assertEqualImplementation(#x " == " #y, assertEvalTemp, assertEvalTemp2, \
145
-                                  __FILE__, __LINE__, true, "!="); \
145
+                                  __FILE__, __LINE__, "!="); \
146 146
 }
147 147
 
148 148
 #define assertNotEqual(x, y) { \
@@ -150,7 +150,7 @@ template<typename T, typename U>
150 150
     auto assertEvalTemp2 = y; \
151 151
     if (assertEvalTemp == assertEvalTemp2) \
152 152
         assertEqualImplementation(#x " != " #y, assertEvalTemp, assertEvalTemp2, \
153
-                                  __FILE__, __LINE__, true, "=="); \
153
+                                  __FILE__, __LINE__, "=="); \
154 154
 }
155 155
 
156 156
 #define assertLessThan(x, y) { \
@@ -158,7 +158,7 @@ template<typename T, typename U>
158 158
     auto assertEvalTemp2 = y; \
159 159
     if (assertEvalTemp >= assertEvalTemp2) \
160 160
         assertEqualImplementation(#x " < " #y, assertEvalTemp, assertEvalTemp2, \
161
-                                  __FILE__, __LINE__, true, ">="); \
161
+                                  __FILE__, __LINE__, ">="); \
162 162
 }
163 163
 
164 164
 #define assertLessThanEqual(x, y) { \
@@ -166,7 +166,7 @@ template<typename T, typename U>
166 166
     auto assertEvalTemp2 = y; \
167 167
     if (assertEvalTemp > assertEvalTemp2) \
168 168
         assertEqualImplementation(#x " <= " #y, assertEvalTemp, assertEvalTemp2, \
169
-                                  __FILE__, __LINE__, true, ">"); \
169
+                                  __FILE__, __LINE__, ">"); \
170 170
 }
171 171
 
172 172
 #define assertGreaterThan(x, y) { \
@@ -174,7 +174,7 @@ template<typename T, typename U>
174 174
     auto assertEvalTemp2 = y; \
175 175
     if (assertEvalTemp <= assertEvalTemp2) \
176 176
         assertEqualImplementation(#x " > " #y, assertEvalTemp, assertEvalTemp2, \
177
-                                  __FILE__, __LINE__, true, "<="); \
177
+                                  __FILE__, __LINE__, "<="); \
178 178
 }
179 179
 
180 180
 #define assertGreaterThanEqual(x, y) { \
@@ -182,7 +182,7 @@ template<typename T, typename U>
182 182
     auto assertEvalTemp2 = y; \
183 183
     if (assertEvalTemp < assertEvalTemp2) \
184 184
         assertEqualImplementation(#x " >= " #y, assertEvalTemp, assertEvalTemp2, \
185
-                                  __FILE__, __LINE__, true, "<"); \
185
+                                  __FILE__, __LINE__, "<"); \
186 186
 }
187 187
 
188 188
 #else // NODEBUG

+ 14
- 7
include/loader/LoaderTR1.h 查看文件

@@ -8,17 +8,24 @@
8 8
 #ifndef _LOADER_LOADER_TR1_H_
9 9
 #define _LOADER_LOADER_TR1_H_
10 10
 
11
-#include "loader/Loader.h"
11
+#include "loader/LoaderTR2.h"
12 12
 
13
-class LoaderTR1 : public Loader {
13
+class LoaderTR1 : public LoaderTR2 {
14 14
   public:
15
-    LoaderTR1();
16
-    virtual ~LoaderTR1();
17
-
18 15
     virtual int load(std::string f);
19 16
 
20
-  private:
21
-
17
+  protected:
18
+    virtual void loadPalette();
19
+    virtual void loadTextures();
20
+    virtual void loadRoomLights();
21
+    virtual void loadRoomStaticMeshes(std::vector<StaticModel*>& staticModels);
22
+    virtual void loadRoomVertex(RoomVertexTR2& vert);
23
+    virtual void loadItems();
24
+    virtual void loadBoxesOverlapsZones();
25
+    virtual void loadSoundMap();
26
+    virtual void loadSoundSamples();
27
+
28
+    virtual int getPaletteIndex(uint16_t index);
22 29
 };
23 30
 
24 31
 #endif

+ 9
- 3
include/loader/LoaderTR2.h 查看文件

@@ -11,6 +11,8 @@
11 11
 #include <array>
12 12
 #include <cstdint>
13 13
 
14
+#include "RoomData.h"
15
+#include "RoomMesh.h"
14 16
 #include "loader/Loader.h"
15 17
 
16 18
 class LoaderTR2 : public Loader {
@@ -18,15 +20,18 @@ class LoaderTR2 : public Loader {
18 20
     virtual int load(std::string f);
19 21
 
20 22
   protected:
21
-    virtual void loadPaletteTextiles();
23
+    virtual void loadPalette();
24
+    virtual void loadTextures();
22 25
     virtual void loadRoomLights();
26
+    virtual void loadRoomStaticMeshes(std::vector<StaticModel*>& staticModels);
23 27
     virtual void loadRoomDataEnd(int16_t& alternateRoom, unsigned int& roomFlags);
28
+    virtual void loadRoomVertex(RoomVertexTR2& vert);
24 29
     virtual void loadRooms();
25 30
     virtual void loadFloorData();
26 31
     virtual void loadMeshes();
27 32
     virtual void loadMoveables();
28 33
     virtual void loadStaticMeshes();
29
-    virtual void loadTextures();
34
+    virtual void loadTextiles();
30 35
     virtual void loadSprites();
31 36
     virtual void loadCameras();
32 37
     virtual void loadSoundSources();
@@ -40,8 +45,9 @@ class LoaderTR2 : public Loader {
40 45
     virtual void loadSampleIndices();
41 46
 
42 47
     virtual void loadExternalSoundFile(std::string f);
48
+    virtual void loadSoundFiles(BinaryReader& sfx);
43 49
 
44
-    std::array<uint32_t, 256> palette;
50
+    virtual int getPaletteIndex(uint16_t index);
45 51
 };
46 52
 
47 53
 #endif

+ 1
- 0
include/system/Shader.h 查看文件

@@ -27,6 +27,7 @@ class ShaderBuffer {
27 27
     void bindBuffer(int location, int size);
28 28
     void unbind(int location);
29 29
 
30
+    unsigned int getBuffer() { assert(created); return buffer; }
30 31
     int getSize() { return boundSize; }
31 32
 
32 33
   private:

+ 1
- 2
src/Console.cpp 查看文件

@@ -74,8 +74,8 @@ void Console::display() {
74 74
     if (!visible)
75 75
         return;
76 76
 
77
-    static bool scrollToBottom = false;
78 77
     if (ImGui::Begin("Console", &visible, ImVec2(600, 400))) {
78
+        static bool scrollToBottom = false;
79 79
         if (lastLogLength != Log::size()) {
80 80
             lastLogLength = Log::size();
81 81
             scrollToBottom = true;
@@ -166,7 +166,6 @@ void Console::display() {
166 166
 
167 167
         if (ImGui::IsItemHovered() || focusInput) {
168 168
             ImGui::SetKeyboardFocusHere(-1);
169
-            focusInput = false;
170 169
         }
171 170
     }
172 171
     ImGui::End();

+ 1
- 0
src/Game.cpp 查看文件

@@ -59,6 +59,7 @@ int Game::loadLevel(const char* level) {
59 59
         }
60 60
 
61 61
         SoundManager::prepareSources();
62
+        TextureManager::prepare();
62 63
 
63 64
         mLoaded = true;
64 65
         Render::setMode(RenderMode::Texture);

+ 2
- 0
src/MenuFolder.cpp 查看文件

@@ -49,6 +49,8 @@ int MenuFolder::init(Folder* folder, bool filter) {
49 49
             // Filter files based on file name
50 50
             if ((f.getName().length() > 4)
51 51
                 && (f.getName().compare(f.getName().length() - 4, 4, ".phd") != 0)
52
+                && (f.getName().compare(f.getName().length() - 4, 4, ".psx") != 0)
53
+                && (f.getName().compare(f.getName().length() - 4, 4, ".tub") != 0)
52 54
                 && (f.getName().compare(f.getName().length() - 4, 4, ".tr2") != 0)
53 55
                 && (f.getName().compare(f.getName().length() - 4, 4, ".tr4") != 0)
54 56
                 && (f.getName().compare(f.getName().length() - 4, 4, ".trc") != 0)) {

+ 4
- 3
src/Mesh.cpp 查看文件

@@ -37,7 +37,7 @@ Mesh::Mesh(const std::vector<glm::vec3>& vert,
37 37
         verticesColorBuff.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
38 38
         verticesColorBuff.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
39 39
         verticesColorBuff.push_back(glm::vec3(vert.at(t.v4).x, vert.at(t.v4).y, vert.at(t.v4).z));
40
-        colorsBuff.push_back(glm::vec3(t.r, t.g, t.b));
40
+        colorsBuff.push_back(t.index);
41 41
     }
42 42
 
43 43
     for (auto& t : coloredTri) {
@@ -45,7 +45,7 @@ Mesh::Mesh(const std::vector<glm::vec3>& vert,
45 45
         verticesColorBuff.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
46 46
         verticesColorBuff.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
47 47
         verticesColorBuff.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
48
-        colorsBuff.push_back(glm::vec3(t.r, t.g, t.b));
48
+        colorsBuff.push_back(t.index);
49 49
     }
50 50
 }
51 51
 
@@ -101,7 +101,8 @@ void Mesh::prepare() {
101 101
                 v = 0;
102 102
             indCol.push_back(vertCol.size());
103 103
             vertCol.push_back(verticesColorBuff.at(vertIndex + v));
104
-            cols.push_back(colorsBuff.at(i));
104
+            glm::vec4 c = TextureManager::getPalette(colorsBuff.at(i));
105
+            cols.push_back(glm::vec3(c.x, c.y, c.z));
105 106
         }
106 107
 
107 108
         if (indicesColorBuff.at(i) == 0) {

+ 44
- 0
src/TextureManager.cpp 查看文件

@@ -45,6 +45,8 @@ glm::vec2 TextureTile::getUV(unsigned int i) {
45 45
 
46 46
 // ----------------------------------------------------------------------------
47 47
 
48
+#define COLOR_PALETTE_SIZE 256
49
+
48 50
 std::vector<unsigned int> TextureManager::mTextureIdsGame;
49 51
 std::vector<unsigned int> TextureManager::mTextureIdsSystem;
50 52
 std::vector<TextureTile*> TextureManager::tiles;
@@ -54,6 +56,8 @@ std::vector<int> TextureManager::systemUnits;
54 56
 unsigned int TextureManager::nextFreeTextureUnit = 0;
55 57
 std::vector<BufferManager> TextureManager::gameBuffers;
56 58
 std::vector<BufferManager> TextureManager::systemBuffers;
59
+std::array<glm::vec4, 256> TextureManager::colorPalette;
60
+std::vector<std::tuple<unsigned char*, unsigned int, unsigned int>> TextureManager::indexedTextures;
57 61
 
58 62
 int TextureManager::initialize() {
59 63
     assertEqual(mTextureIdsGame.size(), 0);
@@ -126,6 +130,8 @@ void TextureManager::clear() {
126 130
     gameUnits.clear();
127 131
     systemUnits.clear();
128 132
     nextFreeTextureUnit = 0;
133
+
134
+    indexedTextures.clear();
129 135
 }
130 136
 
131 137
 int TextureManager::loadBufferSlot(unsigned char* image,
@@ -279,6 +285,44 @@ BufferManager* TextureManager::getBufferManager(int tex, TextureStorage store) {
279 285
     return &(v.at(tex));
280 286
 }
281 287
 
288
+void TextureManager::setPalette(int index, glm::vec4 color) {
289
+    assertGreaterThanEqual(index, 0);
290
+    assertLessThan(index, COLOR_PALETTE_SIZE);
291
+    colorPalette[index] = color;
292
+}
293
+
294
+glm::vec4 TextureManager::getPalette(int index) {
295
+    assertGreaterThanEqual(index, 0);
296
+    assertLessThan(index, COLOR_PALETTE_SIZE);
297
+    return colorPalette[index];
298
+}
299
+
300
+void TextureManager::addIndexedTexture(unsigned char* image, unsigned int width, unsigned int height) {
301
+    unsigned char* img = new unsigned char[width * height];
302
+    for (unsigned int i = 0; i < (width * height); i++)
303
+        img[i] = image[i];
304
+    indexedTextures.emplace_back(img, width, height);
305
+}
306
+
307
+void TextureManager::prepare() {
308
+    for (int i = 0; i < indexedTextures.size(); i++) {
309
+        auto tex = indexedTextures.at(i);
310
+        unsigned char* img = std::get<0>(tex);
311
+        unsigned int width = std::get<1>(tex);
312
+        unsigned int height = std::get<2>(tex);
313
+        unsigned char* image = new unsigned char[width * height * 4];
314
+        for (unsigned int i = 0; i < (width * height); i++) {
315
+            auto col = getPalette(img[i]);
316
+            image[i * 4] = col.x * 255;
317
+            image[(i * 4) + 1] = col.y * 255;
318
+            image[(i * 4) + 2] = col.z * 255;
319
+            image[(i * 4) + 3] = col.w * 255;
320
+        }
321
+        delete [] img;
322
+        loadBufferSlot(image, width, height, ColorMode::RGBA, 32, TextureStorage::GAME, i, true);
323
+    }
324
+}
325
+
282 326
 int TextureManager::loadImage(std::string filename, TextureStorage s, int slot) {
283 327
     if (stringEndsWith(filename, ".pcx")) {
284 328
         return loadPCX(filename, s, slot);

+ 8
- 7
src/UI.cpp 查看文件

@@ -304,26 +304,27 @@ void UI::display() {
304 304
             static float rot[3];
305 305
 
306 306
             if (ImGui::SliderFloat3("Position", pos, -100.0f, 100.0f)) {
307
-                dirty = true;
307
+                //dirty = true;
308 308
             }
309 309
             if (ImGui::SliderFloat3("Rotation", rot, -6.0f, 6.0f)) {
310
-                dirty = true;
310
+                //dirty = true;
311 311
             }
312 312
             if (ImGui::SliderFloat("Zoom", &zoom, -1.0f, 2.0f)) {
313
-                dirty = true;
313
+                //dirty = true;
314 314
             }
315 315
 
316 316
             if (dirty) {
317 317
                 static glm::mat4 projection = glm::perspective(45.0f, 1.0f, 0.1f, 2000.0f);
318 318
 
319
-                glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(zoom, zoom, zoom));
320 319
                 glm::mat4 rotateX = glm::rotate(glm::mat4(1.0f), rot[0], glm::vec3(1.0f, 0.0f, 0.0f));
321 320
                 glm::mat4 rotateY = glm::rotate(glm::mat4(1.0f), rot[1], glm::vec3(0.0f, 1.0f, 0.0f));
322 321
                 glm::mat4 rotateZ = glm::rotate(glm::mat4(1.0f), rot[2], glm::vec3(0.0f, 0.0f, 1.0f));
323
-                glm::mat4 rotate = rotateZ * rotateY * rotateX;
322
+                glm::mat4 rotate = rotateZ * rotateX * rotateY;
324 323
                 glm::mat4 translate = glm::translate(glm::mat4(1.0f), glm::vec3(pos[0], pos[1], pos[2]));
325
-                glm::mat4 view = glm::inverse(scale * rotate * translate);
326
-                MVP = projection * view;
324
+                //glm::mat4 view = glm::inverse(rotate * translate);
325
+                glm::mat4 view = rotate * translate;
326
+                glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(zoom, zoom, zoom));
327
+                MVP = projection * view * scale;
327 328
 
328 329
                 redraw = true;
329 330
                 dirty = false;

+ 4
- 1
src/loader/Loader.cpp 查看文件

@@ -7,6 +7,7 @@
7 7
 
8 8
 #include "global.h"
9 9
 #include "loader/Loader.h"
10
+#include "loader/LoaderTR1.h"
10 11
 #include "loader/LoaderTR2.h"
11 12
 #include "loader/LoaderTR3.h"
12 13
 
@@ -38,12 +39,14 @@ Loader::LoaderVersion Loader::checkFile(std::string f) {
38 39
 std::unique_ptr<Loader> Loader::createLoader(std::string f) {
39 40
     LoaderVersion v = checkFile(f);
40 41
     switch (v) {
41
-        case TR_1:
42 42
         case TR_4:
43 43
         case TR_5:
44 44
         case TR_UNKNOWN:
45 45
             return nullptr;
46 46
 
47
+        case TR_1:
48
+            return std::unique_ptr<Loader>(new LoaderTR1());
49
+
47 50
         case TR_2:
48 51
             return std::unique_ptr<Loader>(new LoaderTR2());
49 52
 

+ 253
- 6
src/loader/LoaderTR1.cpp 查看文件

@@ -6,21 +6,268 @@
6 6
  */
7 7
 
8 8
 #include "global.h"
9
+#include "Game.h"
10
+#include "Log.h"
11
+#include "SoundManager.h"
12
+#include "World.h"
9 13
 #include "loader/LoaderTR1.h"
10 14
 
11
-LoaderTR1::LoaderTR1() {
15
+int LoaderTR1::load(std::string f) {
16
+    if (file.open(f) != 0) {
17
+        return 1; // Could not open file
18
+    }
19
+
20
+    uint32_t version = file.readU32();
21
+    if (version != 0x20) {
22
+        return 2; // Not a TR1 level?!
23
+    }
24
+
25
+    loadTextures();
26
+
27
+    file.seek(file.tell() + 4); // Unused value?
28
+
29
+    loadRooms();
30
+    loadFloorData();
31
+    loadMeshes();
32
+    loadMoveables();
33
+    loadStaticMeshes();
34
+    loadTextiles();
35
+    loadSprites();
36
+    loadCameras();
37
+    loadSoundSources();
38
+    loadBoxesOverlapsZones();
39
+    loadAnimatedTextures();
40
+    loadItems();
41
+
42
+    file.seek(file.tell() + 8192); // TODO light map!
43
+
44
+    loadPalette();
45
+    loadCinematicFrames();
46
+    loadDemoData();
47
+    loadSoundMap();
48
+    loadSoundDetails();
49
+    loadSoundSamples();
50
+    loadSampleIndices();
51
+
52
+    return 0;
12 53
 }
13 54
 
14
-LoaderTR1::~LoaderTR1() {
55
+void LoaderTR1::loadPalette() {
56
+    // Read the 8bit palette, 256 * 3 bytes, RGB
57
+    for (int i = 0; i < 256; i++) {
58
+        uint8_t r = file.readU8();
59
+        uint8_t g = file.readU8();
60
+        uint8_t b = file.readU8();
61
+
62
+        //! \fixme Hack to make everything brighter
63
+        static const uint8_t lightHackFactor = 3;
64
+        r *= lightHackFactor;
65
+        if (r > 255)
66
+            r = 255;
67
+        g *= lightHackFactor;
68
+        if (g > 255)
69
+            g = 255;
70
+        b *= lightHackFactor;
71
+        if (b > 255)
72
+            b = 255;
73
+
74
+        glm::vec4 c(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
75
+        TextureManager::setPalette(i, c);
76
+    }
15 77
 }
16 78
 
17
-int LoaderTR1::load(std::string f) {
18
-    if (file.open(f.c_str()) != 0) {
19
-        return 1; // Could not open file
79
+void LoaderTR1::loadTextures() {
80
+    uint32_t numTextures = file.readU32();
81
+    for (unsigned int i = 0; i < numTextures; i++) {
82
+        std::array<uint8_t, 256 * 256> arr;
83
+        for (auto& x : arr) {
84
+            x = file.readU8(); // Palette index
85
+        }
86
+
87
+        TextureManager::addIndexedTexture(&arr[0], 256, 256);
88
+    }
89
+
90
+    if (numTextures > 0)
91
+        Log::get(LOG_INFO) << "LoaderTR1: Found " << numTextures << " Textures!" << Log::endl;
92
+    else
93
+        Log::get(LOG_INFO) << "LoaderTR1: No Textures in this level?!" << Log::endl;
94
+}
95
+
96
+void LoaderTR1::loadRoomLights() {
97
+    int16_t intensity = file.read16();
98
+
99
+    uint16_t numLights = file.readU16();
100
+    for (unsigned int l = 0; l < numLights; l++) {
101
+        // Position of light, in world coordinates
102
+        int32_t x = file.read32();
103
+        int32_t y = file.read32();
104
+        int32_t z = file.read32();
105
+
106
+        uint16_t intensity1 = file.readU16();
107
+        uint32_t fade = file.readU32(); // Falloff value?
108
+
109
+        // TODO store light somewhere
110
+    }
111
+}
112
+
113
+void LoaderTR1::loadRoomStaticMeshes(std::vector<StaticModel*>& staticModels) {
114
+    uint16_t numStaticMeshes = file.readU16();
115
+    for (unsigned int s = 0; s < numStaticMeshes; s++) {
116
+        // Absolute position in world coordinates
117
+        int32_t x = file.read32();
118
+        int32_t y = file.read32();
119
+        int32_t z = file.read32();
120
+
121
+        // High two bits (0xC000) indicate steps of
122
+        // 90 degrees (eg. (rotation >> 14) * 90)
123
+        uint16_t rotation = file.readU16();
124
+
125
+        // Constant lighting, 0xFFFF means use mesh lighting
126
+        //! \todo Use static mesh lighting information
127
+        uint16_t intensity1 = file.readU16();
128
+
129
+        // Which StaticMesh item to draw
130
+        uint16_t objectID = file.readU16();
131
+
132
+        staticModels.push_back(new StaticModel(glm::vec3(x, y, z),
133
+                                               glm::radians((rotation >> 14) * 90.0f),
134
+                                               objectID));
135
+    }
136
+}
137
+
138
+void LoaderTR1::loadRoomVertex(RoomVertexTR2& vert) {
139
+    vert.x = file.read16();
140
+    vert.y = file.read16();
141
+    vert.z = file.read16();
142
+    vert.light1 = file.read16();
143
+    vert.attributes = 0;
144
+    vert.light2 = vert.light1;
145
+}
146
+
147
+void LoaderTR1::loadItems() {
148
+    uint32_t numItems = file.readU32();
149
+    for (unsigned int i = 0; i < numItems; i++) {
150
+        int16_t objectID = file.read16();
151
+        int16_t room = file.read16();
152
+
153
+        // Item position in world coordinates
154
+        int32_t x = file.read32();
155
+        int32_t y = file.read32();
156
+        int32_t z = file.read32();
157
+
158
+        uint16_t angle = file.readU16(); // (0xC000 >> 14) * 90deg
159
+        int16_t intensity = file.read16(); // Constant lighting; -1 means mesh lighting
160
+
161
+        // 0x0100 - Initially visible
162
+        // 0x3E00 - Activation mask, open, can be XORed with related FloorData list fields.
163
+        uint16_t flags = file.readU16();
164
+
165
+        glm::vec3 pos(
166
+            static_cast<float>(x),
167
+            static_cast<float>(y),
168
+            static_cast<float>(z)
169
+        );
170
+
171
+        glm::vec3 rot(
172
+            0.0f,
173
+            glm::radians(((angle >> 14) & 0x03) * 90.0f),
174
+            0.0f
175
+        );
176
+
177
+        Entity* e = new Entity(objectID, room, pos, rot);
178
+        getWorld().addEntity(e);
179
+
180
+        if (objectID == 0) {
181
+            Game::setLara(getWorld().sizeEntity() - 1);
182
+        }
20 183
     }
21 184
 
185
+    if (numItems > 0)
186
+        Log::get(LOG_INFO) << "LoaderTR1: Found " << numItems << " Items!" << Log::endl;
187
+    else
188
+        Log::get(LOG_INFO) << "LoaderTR1: No Items in this level?!" << Log::endl;
189
+}
190
+
191
+void LoaderTR1::loadBoxesOverlapsZones() {
192
+    uint32_t numBoxes = file.readU32();
193
+    for (unsigned int b = 0; b < numBoxes; b++) {
194
+        // Sectors (not scaled!)
195
+        int32_t zMin = file.read32();
196
+        int32_t zMax = file.read32();
197
+        int32_t xMin = file.read32();
198
+        int32_t xMax = file.read32();
199
+
200
+        int16_t trueFloor = file.read16(); // Y value (no scaling)
22 201
 
202
+        // Index into overlaps[]. The high bit is sometimes set
203
+        // this occurs in front of swinging doors and the like
204
+        uint16_t overlapIndex = file.readU16();
205
+
206
+        // TODO store boxes somewhere
207
+    }
208
+
209
+    uint32_t numOverlaps = file.readU32();
210
+    std::vector<std::vector<uint16_t>> overlaps;
211
+    overlaps.emplace_back();
212
+    unsigned int list = 0;
213
+    for (unsigned int o = 0; o < numOverlaps; o++) {
214
+        // Apparently used by NPCs to decide where to go next.
215
+        // List of neighboring boxes for each box.
216
+        // Each entry is a uint16, 0x8000 set marks end of list.
217
+        uint16_t e = file.readU16();
218
+        overlaps.at(list).push_back(e);
219
+        if (e & 0x8000) {
220
+            overlaps.emplace_back();
221
+            list++;
222
+        }
223
+    }
224
+
225
+    // TODO store overlaps somewhere
226
+
227
+    for (unsigned int z = 0; z < numBoxes; z++) {
228
+        // Normal room state
229
+        int16_t ground1 = file.read16();
230
+        int16_t ground2 = file.read16();
231
+        int16_t fly = file.read16();
232
+
233
+        // Alternate room state
234
+        int16_t ground1alt = file.read16();
235
+        int16_t ground2alt = file.read16();
236
+        int16_t flyAlt = file.read16();
237
+
238
+        // TODO store zones somewhere
239
+    }
240
+
241
+    if ((numBoxes > 0) || (numOverlaps > 0))
242
+        Log::get(LOG_INFO) << "LoaderTR1: Found NPC NavigationHints (" << numBoxes
243
+                           << ", " << numOverlaps << ", " << list << "), unimplemented!" << Log::endl;
244
+    else
245
+        Log::get(LOG_INFO) << "LoaderTR1: No NPC NavigationHints in this level?!" << Log::endl;
246
+}
247
+
248
+void LoaderTR1::loadSoundMap() {
249
+    for (int i = 0; i < 256; i++) {
250
+        SoundManager::addSoundMapEntry(file.read16());
251
+    }
252
+}
253
+
254
+void LoaderTR1::loadSoundSamples() {
255
+    uint32_t soundSampleSize = file.readU32();
256
+    if (soundSampleSize <= 0) {
257
+        return;
258
+    }
259
+
260
+    std::vector<uint8_t> buffer;
261
+    for (int i = 0; i < soundSampleSize; i++) {
262
+        buffer.push_back(file.readU8());
263
+    }
264
+
265
+    char* tmpPtr = reinterpret_cast<char*>(&buffer[0]);
266
+    BinaryMemory sfx(tmpPtr, soundSampleSize);
267
+    loadSoundFiles(sfx);
268
+}
23 269
 
24
-    return 1; // stub
270
+int LoaderTR1::getPaletteIndex(uint16_t index) {
271
+    return index;
25 272
 }
26 273
 

+ 76
- 56
src/loader/LoaderTR2.cpp 查看文件

@@ -30,7 +30,8 @@ int LoaderTR2::load(std::string f) {
30 30
         return 2; // Not a TR2 level?!
31 31
     }
32 32
 
33
-    loadPaletteTextiles();
33
+    loadPalette();
34
+    loadTextures();
34 35
 
35 36
     file.seek(file.tell() + 4); // Unused value?
36 37
 
@@ -39,7 +40,7 @@ int LoaderTR2::load(std::string f) {
39 40
     loadMeshes();
40 41
     loadMoveables();
41 42
     loadStaticMeshes();
42
-    loadTextures();
43
+    loadTextiles();
43 44
     loadSprites();
44 45
     loadCameras();
45 46
     loadSoundSources();
@@ -62,25 +63,34 @@ int LoaderTR2::load(std::string f) {
62 63
 
63 64
 // ---- Textures ----
64 65
 
65
-void LoaderTR2::loadPaletteTextiles() {
66
+void LoaderTR2::loadPalette() {
66 67
     file.seek(file.tell() + 768); // Skip 8bit palette, 256 * 3 bytes
67 68
 
68 69
     // Read the 16bit palette, 256 * 4 bytes, RGBA, A unused
69
-    for (auto& x : palette)
70
-        x = file.readU32();
70
+    for (int i = 0; i < 256; i++) {
71
+        uint8_t r = file.readU8();
72
+        uint8_t g = file.readU8();
73
+        uint8_t b = file.readU8();
74
+        uint8_t a = file.readU8();
75
+
76
+        glm::vec4 c(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
77
+        TextureManager::setPalette(i, c);
78
+    }
79
+}
71 80
 
72
-    uint32_t numTextiles = file.readU32();
81
+void LoaderTR2::loadTextures() {
82
+    uint32_t numTextures = file.readU32();
73 83
 
74
-    file.seek(file.tell() + (numTextiles * 256 * 256)); // Skip 8bit textiles
84
+    file.seek(file.tell() + (numTextures * 256 * 256)); // Skip 8bit textures
75 85
 
76
-    // Read the 16bit textiles, numTextiles * 256 * 256 * 2 bytes
77
-    for (unsigned int i = 0; i < numTextiles; i++) {
86
+    // Read the 16bit textures, numTextures * 256 * 256 * 2 bytes
87
+    for (unsigned int i = 0; i < numTextures; i++) {
78 88
         std::array<uint8_t, 256 * 256 * 2> arr;
79 89
         for (auto& x : arr) {
80 90
             x = file.readU8();
81 91
         }
82 92
 
83
-        // Convert 16bit textile to 32bit textile
93
+        // Convert 16bit textures to 32bit textures
84 94
         unsigned char* img = argb16to32(&arr[0], 256, 256);
85 95
         int r = TextureManager::loadBufferSlot(img, 256, 256,
86 96
                                                ColorMode::ARGB, 32,
@@ -89,13 +99,13 @@ void LoaderTR2::loadPaletteTextiles() {
89 99
         delete [] img;
90 100
     }
91 101
 
92
-    if (numTextiles > 0)
93
-        Log::get(LOG_INFO) << "LoaderTR2: Found " << numTextiles << " Textures!" << Log::endl;
102
+    if (numTextures > 0)
103
+        Log::get(LOG_INFO) << "LoaderTR2: Found " << numTextures << " Textures!" << Log::endl;
94 104
     else
95 105
         Log::get(LOG_INFO) << "LoaderTR2: No Textures in this level?!" << Log::endl;
96 106
 }
97 107
 
98
-void LoaderTR2::loadTextures() {
108
+void LoaderTR2::loadTextiles() {
99 109
     uint32_t numObjectTextures = file.readU32();
100 110
     for (unsigned int o = 0; o < numObjectTextures; o++) {
101 111
         // 0 means that a texture is all-opaque, and that transparency
@@ -110,7 +120,7 @@ void LoaderTR2::loadTextures() {
110 120
         // calculated as the maximum of the individual color values.
111 121
         uint16_t attribute = file.readU16();
112 122
 
113
-        // Index into the textile list
123
+        // Index into the texture list
114 124
         uint16_t tile = file.readU16();
115 125
 
116 126
         TextureTile* t = new TextureTile(attribute, tile);
@@ -200,6 +210,32 @@ void LoaderTR2::loadRoomLights() {
200 210
     }
201 211
 }
202 212
 
213
+void LoaderTR2::loadRoomStaticMeshes(std::vector<StaticModel*>& staticModels) {
214
+    uint16_t numStaticMeshes = file.readU16();
215
+    for (unsigned int s = 0; s < numStaticMeshes; s++) {
216
+        // Absolute position in world coordinates
217
+        int32_t x = file.read32();
218
+        int32_t y = file.read32();
219
+        int32_t z = file.read32();
220
+
221
+        // High two bits (0xC000) indicate steps of
222
+        // 90 degrees (eg. (rotation >> 14) * 90)
223
+        uint16_t rotation = file.readU16();
224
+
225
+        // Constant lighting, 0xFFFF means use mesh lighting
226
+        //! \todo Use static mesh lighting information
227
+        uint16_t intensity1 = file.readU16();
228
+        uint16_t intensity2 = file.readU16();
229
+
230
+        // Which StaticMesh item to draw
231
+        uint16_t objectID = file.readU16();
232
+
233
+        staticModels.push_back(new StaticModel(glm::vec3(x, y, z),
234
+                                               glm::radians((rotation >> 14) * 90.0f),
235
+                                               objectID));
236
+    }
237
+}
238
+
203 239
 void LoaderTR2::loadRoomDataEnd(int16_t& alternateRoom, unsigned int& roomFlags) {
204 240
     alternateRoom = file.read16();
205 241
 
@@ -210,6 +246,15 @@ void LoaderTR2::loadRoomDataEnd(int16_t& alternateRoom, unsigned int& roomFlags)
210 246
     }
211 247
 }
212 248
 
249
+void LoaderTR2::loadRoomVertex(RoomVertexTR2& vert) {
250
+    vert.x = file.read16();
251
+    vert.y = file.read16();
252
+    vert.z = file.read16();
253
+    vert.light1 = file.read16();
254
+    vert.attributes = file.readU16();
255
+    vert.light2 = file.read16();
256
+}
257
+
213 258
 void LoaderTR2::loadRooms() {
214 259
     uint16_t numRooms = file.readU16();
215 260
     for (unsigned int i = 0; i < numRooms; i++) {
@@ -233,12 +278,7 @@ void LoaderTR2::loadRooms() {
233 278
         std::vector<RoomVertexTR2> vertices;
234 279
         for (unsigned int v = 0; v < numVertices; v++) {
235 280
             RoomVertexTR2 vert;
236
-            vert.x = file.read16();
237
-            vert.y = file.read16();
238
-            vert.z = file.read16();
239
-            vert.light1 = file.read16();
240
-            vert.attributes = file.readU16();
241
-            vert.light2 = file.read16();
281
+            loadRoomVertex(vert);
242 282
             vertices.push_back(vert);
243 283
 
244 284
             // Fill bounding box
@@ -378,29 +418,8 @@ void LoaderTR2::loadRooms() {
378 418
 
379 419
         loadRoomLights();
380 420
 
381
-        uint16_t numStaticMeshes = file.readU16();
382 421
         std::vector<StaticModel*> staticModels;
383
-        for (unsigned int s = 0; s < numStaticMeshes; s++) {
384
-            // Absolute position in world coordinates
385
-            int32_t x = file.read32();
386
-            int32_t y = file.read32();
387
-            int32_t z = file.read32();
388
-
389
-            // High two bits (0xC000) indicate steps of
390
-            // 90 degrees (eg. (rotation >> 14) * 90)
391
-            uint16_t rotation = file.readU16();
392
-
393
-            // Constant lighting, 0xFFFF means use mesh lighting
394
-            uint16_t intensity1 = file.readU16();
395
-            uint16_t intensity2 = file.readU16();
396
-
397
-            // Which StaticMesh item to draw
398
-            uint16_t objectID = file.readU16();
399
-
400
-            staticModels.push_back(new StaticModel(glm::vec3(x, y, z),
401
-                                                   glm::radians((rotation >> 14) * 90.0f),
402
-                                                   objectID));
403
-        }
422
+        loadRoomStaticMeshes(staticModels);
404 423
 
405 424
         int16_t alternateRoom = -1;
406 425
         unsigned int roomFlags = 0;
@@ -494,6 +513,10 @@ void LoaderTR2::loadSprites() {
494 513
 
495 514
 // ---- Meshes ----
496 515
 
516
+int LoaderTR2::getPaletteIndex(uint16_t index) {
517
+    return (index & 0xFF00) >> 8; // Use index into 16bit palette
518
+}
519
+
497 520
 void LoaderTR2::loadMeshes() {
498 521
     // Number of bitu16s of mesh data to follow
499 522
     // Read all the mesh data into a buffer, because
@@ -588,12 +611,8 @@ void LoaderTR2::loadMeshes() {
588 611
             uint16_t vertex4 = mem.readU16();
589 612
             uint16_t texture = mem.readU16();
590 613
 
591
-            int index = (texture & 0xFF00) >> 8;
592
-            uint8_t red = (palette.at(index) & 0xFF000000) >> 24,
593
-                    green = (palette.at(index) & 0x00FF0000) >> 16,
594
-                    blue = (palette.at(index) & 0x0000FF00) >> 8;
595
-
596
-            coloredRectangles.emplace_back(red, green, blue, vertex1, vertex2, vertex3, vertex4);
614
+            int index = getPaletteIndex(texture);
615
+            coloredRectangles.emplace_back(index, vertex1, vertex2, vertex3, vertex4);
597 616
         }
598 617
 
599 618
         int16_t numColoredTriangles = mem.read16();
@@ -604,12 +623,8 @@ void LoaderTR2::loadMeshes() {
604 623
             uint16_t vertex3 = mem.readU16();
605 624
             uint16_t texture = mem.readU16();
606 625
 
607
-            int index = (texture & 0xFF00) >> 8;
608
-            uint8_t red = (palette.at(index) & 0xFF000000) >> 24,
609
-                    green = (palette.at(index) & 0x00FF0000) >> 16,
610
-                    blue = (palette.at(index) & 0x0000FF00) >> 8;
611
-
612
-            coloredTriangles.emplace_back(red, green, blue, vertex1, vertex2, vertex3);
626
+            int index = getPaletteIndex(texture);
627
+            coloredTriangles.emplace_back(index, vertex1, vertex2, vertex3);
613 628
         }
614 629
 
615 630
         Mesh* mesh = new Mesh(vertices, texturedRectangles, texturedTriangles,
@@ -850,6 +865,7 @@ void LoaderTR2::loadMoveables() {
850 865
         pos.x = frame.read16();
851 866
         pos.y = frame.read16();
852 867
         pos.z = frame.read16();
868
+        // TODO frame data format different for TR1!
853 869
         BoneFrame* bf = new BoneFrame(pos);
854 870
 
855 871
         for (int i = 0; i < numMeshes; i++) {
@@ -1097,6 +1113,10 @@ void LoaderTR2::loadExternalSoundFile(std::string f) {
1097 1113
         return;
1098 1114
     }
1099 1115
 
1116
+    loadSoundFiles(sfx);
1117
+}
1118
+
1119
+void LoaderTR2::loadSoundFiles(BinaryReader& sfx) {
1100 1120
     int riffCount = 0;
1101 1121
     while (!sfx.eof()) {
1102 1122
         char test[5];
@@ -1126,9 +1146,9 @@ void LoaderTR2::loadExternalSoundFile(std::string f) {
1126 1146
     }
1127 1147
 
1128 1148
     if (riffCount > 0)
1129
-        Log::get(LOG_INFO) << "LoaderTR2: Found " << riffCount << " SoundSamples in SFX" << Log::endl;
1149
+        Log::get(LOG_INFO) << "LoaderTR2: Loaded " << riffCount << " SoundSamples" << Log::endl;
1130 1150
     else
1131
-        Log::get(LOG_INFO) << "LoaderTR2: No SoundSamples in SFX?!" << Log::endl;
1151
+        Log::get(LOG_INFO) << "LoaderTR2: No SoundSamples found!" << Log::endl;
1132 1152
 }
1133 1153
 
1134 1154
 // ---- Stuff ----

+ 3
- 2
src/loader/LoaderTR3.cpp 查看文件

@@ -18,7 +18,8 @@ int LoaderTR3::load(std::string f) {
18 18
         return 2; // Not a TR3 level?!
19 19
     }
20 20
 
21
-    loadPaletteTextiles();
21
+    loadPalette();
22
+    loadTextures();
22 23
 
23 24
     file.seek(file.tell() + 4); // Unused value?
24 25
 
@@ -32,7 +33,7 @@ int LoaderTR3::load(std::string f) {
32 33
     loadSoundSources();
33 34
     loadBoxesOverlapsZones();
34 35
     loadAnimatedTextures();
35
-    loadTextures();
36
+    loadTextiles();
36 37
     loadItems();
37 38
 
38 39
     file.seek(file.tell() + 8192); // Skip Light map, only for 8bit coloring

+ 15
- 6
src/system/Shader.cpp 查看文件

@@ -53,12 +53,6 @@ void ShaderBuffer::unbind(int location) {
53 53
 
54 54
 // ----------------------------------------------------------------------------
55 55
 
56
-static int loadBufferSlot(unsigned char* image = nullptr,
57
-                          unsigned int width = 256, unsigned int height = 256,
58
-                          ColorMode mode = ColorMode::RGBA, unsigned int bpp = 32,
59
-                          TextureStorage s = TextureStorage::GAME,
60
-                          int slot = -1, bool filter = true);
61
-
62 56
 ShaderTexture::ShaderTexture(int w, int h) : width(w), height(h) {
63 57
     glGenFramebuffers(1, &framebuffer);
64 58
     bind();
@@ -346,6 +340,21 @@ void Shader::drawGL(ShaderBuffer& vertices, ShaderBuffer& uvs, ShaderBuffer& ind
346 340
         glViewport(0, 0, Window::getSize().x, Window::getSize().y);
347 341
     } else {
348 342
         target->bind();
343
+
344
+        unsigned int sz = vertices.getSize();
345
+        glm::vec3* buffer = new glm::vec3[sz];
346
+    glBindBuffer(GL_ARRAY_BUFFER, vertices.getBuffer());
347
+        glGetBufferSubData(GL_ARRAY_BUFFER, 0, sz * sizeof(glm::vec3), buffer);
348
+
349
+        Log::get(LOG_DEBUG) << "drawGL Vertex dump:" << Log::endl;
350
+        for (unsigned int i = 0; i < sz; i++) {
351
+            glm::vec4 tmp(buffer[i], 1.0f);
352
+            tmp = MVP * tmp;
353
+            glm::vec3 res(tmp.x, tmp.y, tmp.z);
354
+            Log::get(LOG_DEBUG) << buffer[i] << " -> " << res << Log::endl;
355
+        }
356
+
357
+        delete [] buffer;
349 358
     }
350 359
 
351 360
     shader.use();

+ 8
- 8
src/utils/binary.cpp 查看文件

@@ -101,7 +101,7 @@ int64_t BinaryReader::read64() {
101 101
 // ----------------------------------------------------------------------------
102 102
 
103 103
 BinaryFile::BinaryFile(std::string f) {
104
-    assert(open(f) == 0);
104
+    assertEqual(open(f), 0);
105 105
 }
106 106
 
107 107
 BinaryFile::~BinaryFile() {
@@ -144,7 +144,7 @@ void BinaryFile::read(char* d, int c) {
144 144
 // ----------------------------------------------------------------------------
145 145
 
146 146
 BinaryMemory::BinaryMemory(const char* d, long long m) : data(nullptr), offset(0), max(-1) {
147
-    assert(open(d, m) == 0);
147
+    assertEqual(open(d, m), 0);
148 148
 }
149 149
 
150 150
 BinaryMemory::~BinaryMemory() {
@@ -164,23 +164,23 @@ int BinaryMemory::open(const char* d, long long m) {
164 164
 }
165 165
 
166 166
 long long BinaryMemory::tell() {
167
-    assert(offset >= 0);
167
+    assertGreaterThanEqual(offset, 0);
168 168
     return offset;
169 169
 }
170 170
 
171 171
 void BinaryMemory::seek(long long pos) {
172
-    assert(pos >= 0);
172
+    assertGreaterThanEqual(pos, 0);
173 173
     offset = pos;
174 174
 }
175 175
 
176 176
 bool BinaryMemory::eof() {
177
-    return (offset > max);
177
+    return (offset >= max);
178 178
 }
179 179
 
180 180
 void BinaryMemory::read(char* d, int c) {
181
-    assert(offset >= 0);
182
-    assert(c > 0);
183
-    assert((offset + c) <= max);
181
+    assertGreaterThanEqual(offset, 0);
182
+    assertGreaterThan(c, 0);
183
+    assertLessThanEqual(offset + c, max);
184 184
     for (int i = 0; i < c; i++) {
185 185
         d[i] = data[offset + i];
186 186
     }

正在加载...
取消
保存