Browse Source

Fixed crashing TR3 levels. SoundSources working.

Thomas Buck 9 years ago
parent
commit
09b110bb28
12 changed files with 455 additions and 216 deletions
  1. 7
    0
      ChangeLog.md
  2. 1
    1
      include/Camera.h
  3. 24
    11
      include/SoundManager.h
  4. 5
    0
      src/Camera.cpp
  5. 13
    6
      src/Entity.cpp
  6. 1
    6
      src/RunTime.cpp
  7. 79
    26
      src/SoundManager.cpp
  8. 1
    1
      src/UI.cpp
  9. 2
    1
      src/deps/imgui/imconfig.h
  10. 301
    158
      src/deps/imgui/imgui.cpp
  11. 13
    6
      src/deps/imgui/imgui.h
  12. 8
    0
      src/system/SoundAL.cpp

+ 7
- 0
ChangeLog.md View File

@@ -2,6 +2,13 @@
2 2
 
3 3
 ## OpenRaider (0.1.3) xythobuz <xythobuz@xythobuz.de>
4 4
 
5
+    [ 20140307 ]
6
+    * Can now load all TR3 levels without crashing
7
+    * Sound Sources now working, with (more or less) proper 3D Sound
8
+    * Fixed bug that caused entities to display the wrong object
9
+    * Improved Debug UI
10
+    * Updated imgui
11
+
5 12
     [ 20140306 ]
6 13
     * Fixed LoaderTR1, can now also open the Unfinished Business levels
7 14
     * Walk key can now be used to increase free-camera movement speed

+ 1
- 1
include/Camera.h View File

@@ -23,7 +23,7 @@ class Camera {
23 23
     static void handleControllerAxis(float value, KeyboardButton axis);
24 24
 
25 25
     //! \fixme The Y axis seems to be the source of all evil?
26
-    static void setPosition(glm::vec3 p) { pos = glm::vec3(p.x, -p.y, p.z); }
26
+    static void setPosition(glm::vec3 p) { pos = glm::vec3(p.x, -p.y, p.z); dirty = true; }
27 27
     static glm::vec3 getPosition() { return glm::vec3(pos.x, -pos.y, pos.z); }
28 28
 
29 29
     static glm::vec2 getRotation() { return rot; }

+ 24
- 11
include/SoundManager.h View File

@@ -10,19 +10,32 @@
10 10
 
11 11
 #include <vector>
12 12
 
13
-struct SoundSource {
14
-    glm::vec3 pos;
15
-    int id, flags;
16
-
13
+class SoundSource {
14
+  public:
17 15
     SoundSource(glm::vec3 p, int i, int f)
18
-        : pos(p), id(i), flags(f) { }
16
+        : pos(p), id(i), flags(f), source(-1) { }
17
+    void prepare();
18
+    glm::vec3 getPos() { return pos; }
19
+    int getID() { return id; }
20
+    int getFlags() { return flags; }
21
+    int getSource() { return source; }
22
+
23
+  private:
24
+    glm::vec3 pos;
25
+    int id, flags, source;
19 26
 };
20 27
 
21
-struct SoundDetail {
22
-    int sample;
23
-    float volume;
28
+class SoundDetail {
29
+  public:
30
+    SoundDetail(int s, float v) : sample(s), source(-1), volume(v) { }
31
+    int getSample() { return sample; }
32
+    float getVolume() { return volume; }
33
+    int getSource() { return source; }
34
+    void setSource(int s) { source = s; }
24 35
 
25
-    SoundDetail(int s, float v) : sample(s), volume(v) { }
36
+  private:
37
+    int sample, source;
38
+    float volume;
26 39
 };
27 40
 
28 41
 class SoundManager {
@@ -35,11 +48,11 @@ class SoundManager {
35 48
     static void addSoundDetail(int sample, float volume);
36 49
     static void addSampleIndex(int index);
37 50
 
38
-    static int getIndex(int index, float* volume = nullptr);
39
-
40 51
     // index --> SoundMap --> SoundDetails --> SampleIndices --> play
52
+    static int getIndex(int index, float* volume = nullptr, SoundDetail** sd = nullptr);
41 53
     static int playSound(int index);
42 54
 
55
+    static void listenAt(glm::vec3 pos, glm::vec3 at, glm::vec3 up);
43 56
     static void display();
44 57
 
45 58
   private:

+ 5
- 0
src/Camera.cpp View File

@@ -13,6 +13,7 @@
13 13
 #include "global.h"
14 14
 #include "RunTime.h"
15 15
 #include "system/Shader.h"
16
+#include "system/Sound.h"
16 17
 #include "system/Window.h"
17 18
 #include "Camera.h"
18 19
 
@@ -202,6 +203,10 @@ bool Camera::update() {
202 203
     if (updateViewFrustum)
203 204
         calculateFrustumPlanes();
204 205
 
206
+    glm::vec3 at(0.0f, 0.0f, -1.0f);
207
+    glm::vec3 up(0.0f, -1.0f, 0.0f);
208
+    Sound::listenAt(pos, quaternion * at, quaternion * up);
209
+
205 210
     dirty = false;
206 211
     return updateViewFrustum;
207 212
 }

+ 13
- 6
src/Entity.cpp View File

@@ -23,10 +23,17 @@ bool Entity::showEntityModels = true;
23 23
 
24 24
 void Entity::display(glm::mat4 VP) {
25 25
     if ((cache == -1) || (cacheType == -1)) {
26
-        for (int i = 0; i < getWorld().sizeSpriteSequence(); i++) {
27
-            auto& s = getWorld().getSpriteSequence(i);
26
+        /*
27
+         * The order in which to look for matching objects with the same ID
28
+         * seems to be very important!
29
+         * If sprites and meshes are searched before models, many objects will
30
+         * be displayed wrong (eg. 'bad guy' becomes 'clothes' in tr2/boat)...
31
+         */
32
+
33
+        for (int i = 0; (i < getWorld().sizeSkeletalModel()) && (cache == -1); i++) {
34
+            auto& s = getWorld().getSkeletalModel(i);
28 35
             if (s.getID() == id) {
29
-                cacheType = CACHE_SPRITE;
36
+                cacheType = CACHE_MODEL;
30 37
                 cache = i;
31 38
                 break;
32 39
             }
@@ -41,10 +48,10 @@ void Entity::display(glm::mat4 VP) {
41 48
             }
42 49
         }
43 50
 
44
-        for (int i = 0; (i < getWorld().sizeSkeletalModel()) && (cache == -1); i++) {
45
-            auto& s = getWorld().getSkeletalModel(i);
51
+        for (int i = 0; i < getWorld().sizeSpriteSequence(); i++) {
52
+            auto& s = getWorld().getSpriteSequence(i);
46 53
             if (s.getID() == id) {
47
-                cacheType = CACHE_MODEL;
54
+                cacheType = CACHE_SPRITE;
48 55
                 cache = i;
49 56
                 break;
50 57
             }

+ 1
- 6
src/RunTime.cpp View File

@@ -100,12 +100,7 @@ void RunTime::display() {
100 100
         }
101 101
 
102 102
         float vol = Sound::getVolume();
103
-        if (ImGui::InputFloat("Volume##runtime", &vol, 0.0f, 0.0f, 3,
104
-                              ImGuiInputTextFlags_EnterReturnsTrue)) {
105
-            if (vol < 0.0f)
106
-                vol = 0.0f;
107
-            if (vol > 1.0f)
108
-                vol = 1.0f;
103
+        if (ImGui::SliderFloat("Volume##runtime", &vol, 0.0f, 1.0f)) {
109 104
             Sound::setVolume(vol);
110 105
         }
111 106
 

+ 79
- 26
src/SoundManager.cpp View File

@@ -8,9 +8,37 @@
8 8
 #include "imgui/imgui.h"
9 9
 
10 10
 #include "global.h"
11
+#include "Camera.h"
12
+#include "Log.h"
11 13
 #include "system/Sound.h"
12 14
 #include "SoundManager.h"
13 15
 
16
+void SoundSource::prepare() {
17
+    if (source != -1)
18
+        return;
19
+
20
+    float vol;
21
+    int index = SoundManager::getIndex(id, &vol);
22
+    if ((index < 0) || (index > Sound::numBuffers())) {
23
+        Log::get(LOG_ERROR) << "Invalid SoundSource ID (" << index << ", "
24
+                            << Sound::numBuffers() << ")!" << Log::endl;
25
+        source = -2;
26
+    } else {
27
+        source = Sound::addSource(index, vol, false, true);
28
+        if (source < 0) {
29
+            source = -2;
30
+        } else {
31
+            int ret = Sound::sourceAt(source, pos);
32
+            if (ret < 0) {
33
+                Log::get(LOG_ERROR) << "Error positioning SoundSource " << id << Log::endl;
34
+            }
35
+            Sound::play(source, false);
36
+        }
37
+    }
38
+}
39
+
40
+// ----------------------------------------------------------------------------
41
+
14 42
 std::vector<SoundSource> SoundManager::soundSources;
15 43
 std::vector<int> SoundManager::soundMap;
16 44
 std::vector<SoundDetail> SoundManager::soundDetails;
@@ -26,26 +54,23 @@ void SoundManager::clear() {
26 54
 }
27 55
 
28 56
 int SoundManager::prepareSources() {
29
-    for (int i = 0; i < soundSources.size(); i++) {
30
-        float vol;
31
-        int index = getIndex(soundSources.at(i).id, &vol);
32
-        int ret = Sound::addSource(index, vol, false, true);
33
-        assertEqual(ret, i);
34
-        glm::vec3 pos = soundSources.at(i).pos;
35
-        ret = Sound::sourceAt(i, pos);
36
-        assertEqual(ret, 0);
37
-        Sound::play(i, false);
38
-    }
39
-
40 57
     for (int i = 0; i < soundMap.size(); i++) {
41 58
         float vol;
42
-        int index = getIndex(i, &vol);
59
+        SoundDetail* sd;
60
+        int index = getIndex(i, &vol, &sd);
43 61
         if ((index >= 0) && (index < Sound::numBuffers())) {
44 62
             int ret = Sound::addSource(index, vol, true, false);
45
-            assertGreaterThanEqual(ret, 0);
63
+            if (ret < 0) {
64
+                Log::get(LOG_ERROR) << "Error adding SoundSource " << index << Log::endl;
65
+            }
66
+            sd->setSource(ret);
46 67
         }
47 68
     }
48 69
 
70
+    for (int i = 0; i < soundSources.size(); i++) {
71
+        soundSources.at(i).prepare();
72
+    }
73
+
49 74
     return 0;
50 75
 }
51 76
 
@@ -65,7 +90,7 @@ void SoundManager::addSampleIndex(int index) {
65 90
     sampleIndices.push_back(index);
66 91
 }
67 92
 
68
-int SoundManager::getIndex(int index, float* volume) {
93
+int SoundManager::getIndex(int index, float* volume, SoundDetail** sd) {
69 94
     if (index <= -1)
70 95
         return -1;
71 96
 
@@ -82,16 +107,19 @@ int SoundManager::getIndex(int index, float* volume) {
82 107
 
83 108
     SoundDetail s = soundDetails.at(index);
84 109
 
110
+    if (sd != nullptr)
111
+        *sd = &soundDetails.at(index);
112
+
85 113
     if (volume != nullptr)
86
-        *volume = s.volume;
114
+        *volume = s.getVolume();
87 115
 
88
-    if (s.sample <= -1)
116
+    if (s.getSample() <= -1)
89 117
         return -5; // SoundDetail has no entry here (-1)
90 118
 
91
-    if (s.sample >= sampleIndices.size())
119
+    if (s.getSample() >= sampleIndices.size())
92 120
         return -6; // SoundDetail entry is bigger than SampleIndices
93 121
 
94
-    index = sampleIndices.at(s.sample);
122
+    index = sampleIndices.at(s.getSample());
95 123
 
96 124
     if (index <= -1)
97 125
         return -7; // SampleIndices has no entry here (-1)
@@ -101,15 +129,12 @@ int SoundManager::getIndex(int index, float* volume) {
101 129
 
102 130
 int SoundManager::playSound(int index) {
103 131
     if ((index >= 0) && (index < soundMap.size())) {
104
-        if (soundMap.at(index) == -1)
105
-            return 0;
132
+        SoundDetail* sd;
133
+        int i = getIndex(index, nullptr, &sd);
134
+        if ((i < 0) || (i >= Sound::numBuffers()))
135
+            return -2;
106 136
 
107
-        int c = 1;
108
-        for (int i = 0; i < index; i++)
109
-            if (soundMap.at(i) != -1)
110
-                c++;
111
-
112
-        Sound::play(c, true);
137
+        Sound::play(sd->getSource(), true);
113 138
         return 0;
114 139
     } else {
115 140
         return -1;
@@ -117,6 +142,34 @@ int SoundManager::playSound(int index) {
117 142
 }
118 143
 
119 144
 void SoundManager::display() {
145
+    if (ImGui::CollapsingHeader("Sound Sources")) {
146
+        ImGui::Columns(5, "soundsources");
147
+        ImGui::Text("No"); ImGui::NextColumn();
148
+        ImGui::Text("ID"); ImGui::NextColumn();
149
+        ImGui::Text("Flags"); ImGui::NextColumn();
150
+        ImGui::Text("Pos"); ImGui::NextColumn();
151
+        ImGui::Text("Go"); ImGui::NextColumn();
152
+        ImGui::Separator();
153
+        for (int i = 0; i < soundSources.size(); i++) {
154
+            auto& ss = soundSources.at(i);
155
+            ImGui::Text("%03d", i);
156
+            ImGui::NextColumn();
157
+            ImGui::Text("%d", ss.getID());
158
+            ImGui::NextColumn();
159
+            ImGui::Text("%X", ss.getFlags());
160
+            ImGui::NextColumn();
161
+            ImGui::Text("%.1f %.1f %.1f", ss.getPos().x, ss.getPos().y, ss.getPos().z);
162
+            ImGui::NextColumn();
163
+            ImGui::PushID(i);
164
+            if (ImGui::Button("Go!")) {
165
+                Camera::setPosition(ss.getPos());
166
+            }
167
+            ImGui::PopID();
168
+            ImGui::NextColumn();
169
+        }
170
+        ImGui::Columns(1);
171
+    }
172
+
120 173
     if (ImGui::CollapsingHeader("Sound Player")) {
121 174
         if (!Sound::getEnabled()) {
122 175
             ImGui::Text("Please enable Sound first!");

+ 1
- 1
src/UI.cpp View File

@@ -245,7 +245,7 @@ void UI::eventsFinished() {
245 245
 }
246 246
 
247 247
 void UI::display() {
248
-    if (RunTime::getShowFPS()) {
248
+    if (RunTime::getShowFPS() && (!getMenu().isVisible())) {
249 249
         if (ImGui::Begin("Debug Overlay", nullptr, ImVec2(0, 0), -1.0f,
250 250
                          ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize
251 251
                          | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings

+ 2
- 1
src/deps/imgui/imconfig.h View File

@@ -19,8 +19,9 @@
19 19
 //#define IMGUI_API __declspec( dllexport )
20 20
 //#define IMGUI_API __declspec( dllimport )
21 21
 
22
-//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions)
22
+//---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions)
23 23
 //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS
24
+//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS
24 25
 
25 26
 //---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions.
26 27
 //#define IMGUI_INCLUDE_IMGUI_USER_INL

+ 301
- 158
src/deps/imgui/imgui.cpp
File diff suppressed because it is too large
View File


+ 13
- 6
src/deps/imgui/imgui.h View File

@@ -226,9 +226,11 @@ namespace ImGui
226 226
     IMGUI_API void          Spacing();
227 227
     IMGUI_API void          Columns(int count = 1, const char* id = NULL, bool border=true);    // setup number of columns
228 228
     IMGUI_API void          NextColumn();                                                       // next column
229
-    IMGUI_API float         GetColumnOffset(int column_index = -1);
230
-    IMGUI_API void          SetColumnOffset(int column_index, float offset);
231
-    IMGUI_API float         GetColumnWidth(int column_index = -1);
229
+    IMGUI_API int           GetColumnIndex();                                                   // get current column index
230
+    IMGUI_API float         GetColumnOffset(int column_index = -1);                             // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetcolumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this.
231
+    IMGUI_API void          SetColumnOffset(int column_index, float offset_x);                  // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column.
232
+    IMGUI_API float         GetColumnWidth(int column_index = -1);                              // column width (== GetColumnOffset(GetColumnIndex()+1) - GetColumnOffset(GetColumnOffset())
233
+    IMGUI_API int           GetColumnsCount();                                                  // number of columns (what was passed to Columns())
232 234
     IMGUI_API ImVec2        GetCursorPos();                                                     // cursor position is relative to window position
233 235
     IMGUI_API float         GetCursorPosX();                                                    // "
234 236
     IMGUI_API float         GetCursorPosY();                                                    // "
@@ -574,12 +576,15 @@ struct ImGuiIO
574 576
     const char* (*GetClipboardTextFn)();
575 577
     void        (*SetClipboardTextFn)(const char* text);
576 578
 
577
-    // Optional: override memory allocations (default to posix malloc/free). MemFreeFn() may be called with a NULL pointer.
579
+    // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer.
580
+    // (default to posix malloc/free)
578 581
     void*       (*MemAllocFn)(size_t sz);
579 582
     void        (*MemFreeFn)(void* ptr);
580 583
 
581 584
     // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows)
585
+    // (default to use native imm32 api on Windows)
582 586
     void        (*ImeSetInputScreenPosFn)(int x, int y);
587
+    void*       ImeWindowHandle;            // (Windows) Set this to your HWND to get automatic IME cursor positioning.
583 588
 
584 589
     //------------------------------------------------------------------
585 590
     // Input - Fill before calling NewFrame()
@@ -921,7 +926,7 @@ struct ImFont
921 926
     float               FontSize;           // <user set>      // Height of characters, set during loading (don't change after loading)
922 927
     float               Scale;              // = 1.0f          // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
923 928
     ImVec2              DisplayOffset;      // = (0.0f,0.0f)   // Offset font rendering by xx pixels
924
-    ImWchar             FallbackChar;       // = '?'           // Replacement glyph if one isn't found.
929
+    ImWchar             FallbackChar;       // = '?'           // Replacement glyph if one isn't found. Only set via SetFallbackChar()
925 930
 
926 931
     // Members: Runtime data
927 932
     struct Glyph
@@ -934,9 +939,10 @@ struct ImFont
934 939
     };
935 940
     ImFontAtlas*        ContainerAtlas;     // What we has been loaded into
936 941
     ImVector<Glyph>     Glyphs;
942
+    const Glyph*        FallbackGlyph;      // == FindGlyph(FontFallbackChar)
943
+    float               FallbackXAdvance;   //
937 944
     ImVector<float>     IndexXAdvance;      // Glyphs->XAdvance directly indexable (for CalcTextSize functions which are often bottleneck in large UI)
938 945
     ImVector<int>       IndexLookup;        // Index glyphs by Unicode code-point
939
-    const Glyph*        FallbackGlyph;      // == FindGlyph(FontFallbackChar)
940 946
 
941 947
     // Methods
942 948
     IMGUI_API ImFont();
@@ -944,6 +950,7 @@ struct ImFont
944 950
     IMGUI_API void                  Clear();
945 951
     IMGUI_API void                  BuildLookupTable();
946 952
     IMGUI_API const Glyph*          FindGlyph(unsigned short c) const;
953
+    IMGUI_API void                  SetFallbackChar(ImWchar c);
947 954
     IMGUI_API bool                  IsLoaded() const        { return ContainerAtlas != NULL; }
948 955
 
949 956
     // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.

+ 8
- 0
src/system/SoundAL.cpp View File

@@ -18,6 +18,10 @@
18 18
 #include "Log.h"
19 19
 #include "system/SoundAL.h"
20 20
 
21
+const static float soundTravelSectors = 15.0f;
22
+const static float referenceDistance = 1024.0f;
23
+const static float maxDistance = referenceDistance * soundTravelSectors;
24
+
21 25
 bool SoundAL::init = false;
22 26
 bool SoundAL::enabled = true;
23 27
 float SoundAL::volume = 1.0f;
@@ -44,6 +48,8 @@ int SoundAL::initialize() {
44 48
     init = true;
45 49
     setVolume(volume);
46 50
 
51
+    alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
52
+
47 53
     lastPosition = glm::vec3(0.0f, 0.0f, 0.0f);
48 54
     glm::vec3 at(0.0f, 0.0f, -1.0f);
49 55
     glm::vec3 up(0.0f, 1.0f, 0.0f);
@@ -150,6 +156,8 @@ int SoundAL::addSource(int buffer, float volume, bool atListener, bool loop) {
150 156
 
151 157
     alSourcei(id, AL_BUFFER, buffers.at(buffer));
152 158
     alSourcef(id, AL_GAIN, volume);
159
+    alSourcef(id, AL_REFERENCE_DISTANCE, referenceDistance);
160
+    alSourcef(id, AL_MAX_DISTANCE, maxDistance);
153 161
 
154 162
     if (loop)
155 163
         alSourcei(id, AL_LOOPING, AL_TRUE);

Loading…
Cancel
Save