diff --git a/Avara.msvc/Avara.vcxproj b/Avara.msvc/Avara.vcxproj
index b022293d..471f78e9 100644
--- a/Avara.msvc/Avara.vcxproj
+++ b/Avara.msvc/Avara.vcxproj
@@ -143,7 +143,7 @@
_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;NANOGUI_GLAD;%(PreprocessorDefinitions)
true
stdcpp17
- ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories)
+ ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories)
false
true
stdc17
@@ -171,7 +171,7 @@
true
NDEBUG;_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;NANOGUI_GLAD;%(PreprocessorDefinitions)
true
- ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;
+ ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;
true
stdcpp17
stdc17
@@ -211,4 +211,4 @@
-
\ No newline at end of file
+
diff --git a/Avara.msvc/AvaraCore.vcxproj b/Avara.msvc/AvaraCore.vcxproj
index 9117ed44..1bdee7f7 100644
--- a/Avara.msvc/AvaraCore.vcxproj
+++ b/Avara.msvc/AvaraCore.vcxproj
@@ -123,7 +123,7 @@
_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;_DEBUG;NANOGUI_GLAD;%(PreprocessorDefinitions)
true
stdcpp17
- ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories)
+ ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories)
false
true
@@ -148,7 +148,7 @@
true
_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;NDEBUG;NANOGUI_GLAD;%(PreprocessorDefinitions)
true
- ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories)
+ ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories)
stdcpp17
stdc17
true
@@ -180,7 +180,6 @@
-
@@ -315,9 +314,6 @@
-
-
-
@@ -391,7 +387,6 @@
-
@@ -507,9 +502,6 @@
-
-
-
@@ -546,4 +538,4 @@
-
\ No newline at end of file
+
diff --git a/Avara.msvc/AvaraCore.vcxproj.filters b/Avara.msvc/AvaraCore.vcxproj.filters
index e12ef1b1..a7b11584 100644
--- a/Avara.msvc/AvaraCore.vcxproj.filters
+++ b/Avara.msvc/AvaraCore.vcxproj.filters
@@ -66,9 +66,6 @@
Header Files
-
- Header Files
-
Header Files
@@ -165,21 +162,12 @@
Header Files
-
- Header Files
-
-
- Header Files
-
Header Files
Header Files
-
- Header Files
-
Header Files
@@ -959,9 +947,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -1007,15 +992,6 @@
Source Files
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
Source Files
@@ -1140,4 +1116,4 @@
Source Files
-
\ No newline at end of file
+
diff --git a/Avara.msvc/Tests.vcxproj b/Avara.msvc/Tests.vcxproj
index 5bdbfac0..97377b77 100644
--- a/Avara.msvc/Tests.vcxproj
+++ b/Avara.msvc/Tests.vcxproj
@@ -115,7 +115,7 @@
_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;_DEBUG;NANOGUI_GLAD;%(PreprocessorDefinitions)
true
stdcpp17
- ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories)
+ ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories)
false
true
@@ -140,7 +140,7 @@
true
_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;NDEBUG;NANOGUI_GLAD;%(PreprocessorDefinitions)
true
- ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories)
+ ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories)
true
stdcpp17
stdc17
@@ -167,4 +167,4 @@
-
\ No newline at end of file
+
diff --git a/Avara.xcodeproj/project.pbxproj b/Avara.xcodeproj/project.pbxproj
index 091dc9b5..a5483250 100644
--- a/Avara.xcodeproj/project.pbxproj
+++ b/Avara.xcodeproj/project.pbxproj
@@ -58,7 +58,6 @@
E517F056299713DB0036B206 /* CSoundHub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C7329895118007A875D /* CSoundHub.cpp */; };
E517F057299713DB0036B206 /* CSoundMixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C7729895118007A875D /* CSoundMixer.cpp */; };
E517F058299713DB0036B206 /* DopplerPlug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C7429895118007A875D /* DopplerPlug.cpp */; };
- E517F05A299713DB0036B206 /* CDirectObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9D29895118007A875D /* CDirectObject.cpp */; };
E517F05B299713DB0036B206 /* CTagBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9A29895118007A875D /* CTagBase.cpp */; };
E517F05C299713DB0036B206 /* CBSPPart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C6829895118007A875D /* CBSPPart.cpp */; };
E517F05D299713DB0036B206 /* CBSPWorld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C6129895118007A875D /* CBSPWorld.cpp */; };
@@ -162,9 +161,6 @@
E517F0C2299713DB0036B206 /* CStringDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BC029895118007A875D /* CStringDictionary.cpp */; };
E517F0C3299713DB0036B206 /* Debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBF29895118007A875D /* Debug.cpp */; };
E517F0C4299713DB0036B206 /* FastMat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBD29895118007A875D /* FastMat.cpp */; };
- E517F0C5299713DB0036B206 /* CHuffProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB529895118007A875D /* CHuffProcessor.cpp */; };
- E517F0C6299713DB0036B206 /* CAbstractPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB629895118007A875D /* CAbstractPipe.cpp */; };
- E517F0C7299713DB0036B206 /* CAbstractHuffPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB729895118007A875D /* CAbstractHuffPipe.cpp */; };
E517F0CA299713DB0036B206 /* RamFiles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BC129895118007A875D /* RamFiles.cpp */; };
E517F0CB299713DB0036B206 /* csscolorparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D3F29895123007A875D /* csscolorparser.cpp */; };
E517F0CC299713DB0036B206 /* glm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890E0D29895123007A875D /* glm.cpp */; };
@@ -213,9 +209,6 @@
E5890CA629895118007A875D /* CProtoControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BA729895118007A875D /* CProtoControl.cpp */; };
E5890CA729895118007A875D /* CRC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BAA29895118007A875D /* CRC.cpp */; };
E5890CA829895118007A875D /* Beeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB329895118007A875D /* Beeper.cpp */; };
- E5890CA929895118007A875D /* CHuffProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB529895118007A875D /* CHuffProcessor.cpp */; };
- E5890CAA29895118007A875D /* CAbstractPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB629895118007A875D /* CAbstractPipe.cpp */; };
- E5890CAB29895118007A875D /* CAbstractHuffPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB729895118007A875D /* CAbstractHuffPipe.cpp */; };
E5890CAD29895118007A875D /* FastMat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBD29895118007A875D /* FastMat.cpp */; };
E5890CAE29895118007A875D /* Debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBF29895118007A875D /* Debug.cpp */; };
E5890CAF29895118007A875D /* CStringDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BC029895118007A875D /* CStringDictionary.cpp */; };
@@ -315,7 +308,6 @@
E5890D1129895118007A875D /* LevelLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9329895118007A875D /* LevelLoader.cpp */; };
E5890D1229895118007A875D /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9629895118007A875D /* Parser.cpp */; };
E5890D1429895118007A875D /* CTagBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9A29895118007A875D /* CTagBase.cpp */; };
- E5890D1529895118007A875D /* CDirectObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9D29895118007A875D /* CDirectObject.cpp */; };
E5890EEB29895124007A875D /* csscolorparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D3F29895123007A875D /* csscolorparser.cpp */; };
E5890EEC29895124007A875D /* widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D4729895123007A875D /* widget.cpp */; };
E5890EED29895124007A875D /* colorcombobox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D4829895123007A875D /* colorcombobox.cpp */; };
@@ -366,7 +358,6 @@
E5A219C32DC59135007D54FF /* CSoundMixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C7729895118007A875D /* CSoundMixer.cpp */; };
E5A219C42DC59135007D54FF /* DopplerPlug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C7429895118007A875D /* DopplerPlug.cpp */; };
E5A219C52DC59135007D54FF /* OggFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94924EAE2B3A894900197378 /* OggFile.cpp */; };
- E5A219C72DC59135007D54FF /* CDirectObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9D29895118007A875D /* CDirectObject.cpp */; };
E5A219C82DC59135007D54FF /* CTagBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9A29895118007A875D /* CTagBase.cpp */; };
E5A219C92DC59135007D54FF /* CCompoundShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 948DF4152DA365CB007FEFDE /* CCompoundShape.cpp */; };
E5A219CA2DC59135007D54FF /* CBSPPart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C6829895118007A875D /* CBSPPart.cpp */; };
@@ -480,9 +471,6 @@
E5A21A372DC59135007D54FF /* CStringDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BC029895118007A875D /* CStringDictionary.cpp */; };
E5A21A382DC59135007D54FF /* Debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBF29895118007A875D /* Debug.cpp */; };
E5A21A392DC59135007D54FF /* FastMat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBD29895118007A875D /* FastMat.cpp */; };
- E5A21A3A2DC59135007D54FF /* CHuffProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB529895118007A875D /* CHuffProcessor.cpp */; };
- E5A21A3B2DC59135007D54FF /* CAbstractPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB629895118007A875D /* CAbstractPipe.cpp */; };
- E5A21A3C2DC59135007D54FF /* CAbstractHuffPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB729895118007A875D /* CAbstractHuffPipe.cpp */; };
E5A21A3F2DC59135007D54FF /* RamFiles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BC129895118007A875D /* RamFiles.cpp */; };
E5A21A402DC59135007D54FF /* csscolorparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D3F29895123007A875D /* csscolorparser.cpp */; };
E5A21A412DC59135007D54FF /* button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D4C29895123007A875D /* button.cpp */; };
@@ -658,12 +646,6 @@
E5890BB129895118007A875D /* SlidingHistogram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlidingHistogram.h; sourceTree = ""; };
E5890BB229895118007A875D /* CRC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CRC.h; sourceTree = ""; };
E5890BB329895118007A875D /* Beeper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Beeper.cpp; sourceTree = ""; };
- E5890BB529895118007A875D /* CHuffProcessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CHuffProcessor.cpp; sourceTree = ""; };
- E5890BB629895118007A875D /* CAbstractPipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAbstractPipe.cpp; sourceTree = ""; };
- E5890BB729895118007A875D /* CAbstractHuffPipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAbstractHuffPipe.cpp; sourceTree = ""; };
- E5890BB829895118007A875D /* CHuffProcessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHuffProcessor.h; sourceTree = ""; };
- E5890BBA29895118007A875D /* CAbstractPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAbstractPipe.h; sourceTree = ""; };
- E5890BBC29895118007A875D /* CAbstractHuffPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAbstractHuffPipe.h; sourceTree = ""; };
E5890BBD29895118007A875D /* FastMat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FastMat.cpp; sourceTree = ""; };
E5890BBF29895118007A875D /* Debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Debug.cpp; sourceTree = ""; };
E5890BC029895118007A875D /* CStringDictionary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CStringDictionary.cpp; sourceTree = ""; };
@@ -870,10 +852,8 @@
E5890C9429895118007A875D /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = ""; };
E5890C9529895118007A875D /* LevelLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LevelLoader.h; sourceTree = ""; };
E5890C9629895118007A875D /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Parser.cpp; sourceTree = ""; };
- E5890C9829895118007A875D /* CDirectObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDirectObject.h; sourceTree = ""; };
E5890C9A29895118007A875D /* CTagBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTagBase.cpp; sourceTree = ""; };
E5890C9B29895118007A875D /* CTagBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CTagBase.h; sourceTree = ""; };
- E5890C9D29895118007A875D /* CDirectObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDirectObject.cpp; sourceTree = ""; };
E5890D1729895123007A875D /* httplib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = httplib.h; sourceTree = ""; };
E5890D1829895123007A875D /* cute_files.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cute_files.h; sourceTree = ""; };
E5890D1929895123007A875D /* json.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = json.hpp; sourceTree = ""; };
@@ -1219,7 +1199,6 @@
E5890ED429895124007A875D /* fontstash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontstash.h; sourceTree = ""; };
E5890ED529895124007A875D /* nanovg_gl_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nanovg_gl_utils.h; sourceTree = ""; };
E5890ED729895124007A875D /* nanovg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nanovg.c; sourceTree = ""; };
- E5890ED829895124007A875D /* AudioFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioFile.h; sourceTree = ""; };
E5890ED929895124007A875D /* stb_vorbis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stb_vorbis.h; sourceTree = ""; };
E5890EDA29895124007A875D /* utf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf8.h; sourceTree = ""; };
E5890EDB29895124007A875D /* csscolorparser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = csscolorparser.hpp; sourceTree = ""; };
@@ -1419,7 +1398,6 @@
E5890BBD29895118007A875D /* FastMat.cpp */,
E5890BAF29895118007A875D /* FastMat.h */,
E5890BAE29895118007A875D /* GitVersion.h */,
- E5890BB429895118007A875D /* huffman */,
E5890BC129895118007A875D /* RamFiles.cpp */,
E5890BAD29895118007A875D /* RamFiles.h */,
E5890BC229895118007A875D /* RayHit.h */,
@@ -1432,19 +1410,6 @@
path = util;
sourceTree = "";
};
- E5890BB429895118007A875D /* huffman */ = {
- isa = PBXGroup;
- children = (
- E5890BBC29895118007A875D /* CAbstractHuffPipe.h */,
- E5890BB729895118007A875D /* CAbstractHuffPipe.cpp */,
- E5890BBA29895118007A875D /* CAbstractPipe.h */,
- E5890BB629895118007A875D /* CAbstractPipe.cpp */,
- E5890BB829895118007A875D /* CHuffProcessor.h */,
- E5890BB529895118007A875D /* CHuffProcessor.cpp */,
- );
- path = huffman;
- sourceTree = "";
- };
E5890BC729895118007A875D /* tui */ = {
isa = PBXGroup;
children = (
@@ -1706,8 +1671,6 @@
E5890C9729895118007A875D /* base */ = {
isa = PBXGroup;
children = (
- E5890C9D29895118007A875D /* CDirectObject.cpp */,
- E5890C9829895118007A875D /* CDirectObject.h */,
E5890C9A29895118007A875D /* CTagBase.cpp */,
E5890C9B29895118007A875D /* CTagBase.h */,
);
@@ -2390,7 +2353,6 @@
E517F057299713DB0036B206 /* CSoundMixer.cpp in Sources */,
E517F058299713DB0036B206 /* DopplerPlug.cpp in Sources */,
948CBF152B335A1400147E80 /* BaseAssetStorage.cpp in Sources */,
- E517F05A299713DB0036B206 /* CDirectObject.cpp in Sources */,
E517F05B299713DB0036B206 /* CTagBase.cpp in Sources */,
E517F05C299713DB0036B206 /* CBSPPart.cpp in Sources */,
E517F05D299713DB0036B206 /* CBSPWorld.cpp in Sources */,
@@ -2506,9 +2468,6 @@
E517F0C2299713DB0036B206 /* CStringDictionary.cpp in Sources */,
E517F0C3299713DB0036B206 /* Debug.cpp in Sources */,
E517F0C4299713DB0036B206 /* FastMat.cpp in Sources */,
- E517F0C5299713DB0036B206 /* CHuffProcessor.cpp in Sources */,
- E517F0C6299713DB0036B206 /* CAbstractPipe.cpp in Sources */,
- E517F0C7299713DB0036B206 /* CAbstractHuffPipe.cpp in Sources */,
E2CF30032DA88F4D002DD786 /* LegacyOpenGLRenderer.cpp in Sources */,
E517F0CA299713DB0036B206 /* RamFiles.cpp in Sources */,
E517F0CB299713DB0036B206 /* csscolorparser.cpp in Sources */,
@@ -2573,7 +2532,6 @@
E5890CBB29895118007A875D /* CDome.cpp in Sources */,
E5890F1929895124007A875D /* glad.c in Sources */,
E5890CFA29895118007A875D /* CSmartBox.cpp in Sources */,
- E5890D1529895118007A875D /* CDirectObject.cpp in Sources */,
E2CD7FAC2DB5BE1D00C3665F /* LevelInfo.cpp in Sources */,
E5890CC729895118007A875D /* LinkLoose.cpp in Sources */,
E5890F0329895124007A875D /* textbox.cpp in Sources */,
@@ -2642,7 +2600,6 @@
E5890F0729895124007A875D /* desccombobox.cpp in Sources */,
E5890CDF29895118007A875D /* CLogicDistributor.cpp in Sources */,
E5890CC029895118007A875D /* CGoal.cpp in Sources */,
- E5890CA929895118007A875D /* CHuffProcessor.cpp in Sources */,
E5890EF729895124007A875D /* popup.cpp in Sources */,
9465BFD72B30EF680050681C /* PackageManifest.cpp in Sources */,
E5890CBA29895118007A875D /* CWeapon.cpp in Sources */,
@@ -2674,12 +2631,10 @@
E5890EF029895124007A875D /* vscrollpanel.cpp in Sources */,
E5890CCF29895118007A875D /* CAbstractPlayer.cpp in Sources */,
E5890CE329895118007A875D /* CGrenade.cpp in Sources */,
- E5890CAB29895118007A875D /* CAbstractHuffPipe.cpp in Sources */,
E5890CAD29895118007A875D /* FastMat.cpp in Sources */,
E5890EFC29895124007A875D /* tabwidget.cpp in Sources */,
E5890CD829895118007A875D /* CWallDoor.cpp in Sources */,
E5890CBF29895118007A875D /* CAbstractActor.cpp in Sources */,
- E5890CAA29895118007A875D /* CAbstractPipe.cpp in Sources */,
E5890F0929895124007A875D /* stb_vorbis.c in Sources */,
6025AE4E2C255E6A00A57EFB /* LegacyOpenGLRenderer.cpp in Sources */,
E5890D0529895118007A875D /* CSoundMixer.cpp in Sources */,
@@ -2739,7 +2694,6 @@
E5A219C32DC59135007D54FF /* CSoundMixer.cpp in Sources */,
E5A219C42DC59135007D54FF /* DopplerPlug.cpp in Sources */,
E5A219C52DC59135007D54FF /* OggFile.cpp in Sources */,
- E5A219C72DC59135007D54FF /* CDirectObject.cpp in Sources */,
E5A219C82DC59135007D54FF /* CTagBase.cpp in Sources */,
E5A219C92DC59135007D54FF /* CCompoundShape.cpp in Sources */,
E5A219CA2DC59135007D54FF /* CBSPPart.cpp in Sources */,
@@ -2855,9 +2809,6 @@
E5A21A372DC59135007D54FF /* CStringDictionary.cpp in Sources */,
E5A21A382DC59135007D54FF /* Debug.cpp in Sources */,
E5A21A392DC59135007D54FF /* FastMat.cpp in Sources */,
- E5A21A3A2DC59135007D54FF /* CHuffProcessor.cpp in Sources */,
- E5A21A3B2DC59135007D54FF /* CAbstractPipe.cpp in Sources */,
- E5A21A3C2DC59135007D54FF /* CAbstractHuffPipe.cpp in Sources */,
E5A21A3F2DC59135007D54FF /* RamFiles.cpp in Sources */,
E5A21A402DC59135007D54FF /* csscolorparser.cpp in Sources */,
E5A21A412DC59135007D54FF /* button.cpp in Sources */,
diff --git a/src/audio/CBasicSound.h b/src/audio/CBasicSound.h
index c8d47f2a..ea7a99bf 100644
--- a/src/audio/CBasicSound.h
+++ b/src/audio/CBasicSound.h
@@ -8,7 +8,6 @@
*/
#pragma once
-#include "CDirectObject.h"
#include "OggFile.h"
#include "SoundSystemDefines.h"
@@ -17,7 +16,7 @@
class CSoundMixer;
class CSoundHub;
-class CBasicSound : public CDirectObject {
+class CBasicSound {
public:
Fixed masterVolume;
int16_t volumes[2];
@@ -46,6 +45,8 @@ class CBasicSound : public CDirectObject {
Boolean stopNow; // Flag to make the sound stop.
Boolean distanceDelay; // Delay sound depending on position.
+ virtual ~CBasicSound() {}
+
// The following four functions will usually be overridden:
virtual int16_t CalcVolume(int16_t theChannel); // Return volume
virtual void WriteFrame(int16_t theChannel, int16_t volumeAllowed);
diff --git a/src/audio/CSoundHub.cpp b/src/audio/CSoundHub.cpp
index 36399712..fd64c237 100644
--- a/src/audio/CSoundHub.cpp
+++ b/src/audio/CSoundHub.cpp
@@ -11,7 +11,6 @@
#include "AssetManager.h"
#include "CBasicSound.h"
-#include "CHuffProcessor.h"
#include "CRateSound.h"
#include "CSoundMixer.h"
#include "Memory.h"
@@ -62,7 +61,7 @@ CBasicSound *CSoundHubImpl::Acquire(short kind) {
return aSound;
}
-void CSoundHubImpl::ISoundHub(short numOfEachKind, short initialLinks) {
+CSoundHubImpl::CSoundHubImpl(short numOfEachKind, short initialLinks) {
short i, j;
itsMixer = NULL;
@@ -77,9 +76,6 @@ void CSoundHubImpl::ISoundHub(short numOfEachKind, short initialLinks) {
muteFlag = false;
- itsCompressor = new CHuffProcessor;
- itsCompressor->Open();
-
soundLinkStorage = NULL;
firstFreeLink = NULL;
@@ -87,31 +83,30 @@ void CSoundHubImpl::ISoundHub(short numOfEachKind, short initialLinks) {
CreateSoundLinks(initialLinks);
}
-void CSoundHubImpl::AttachMixer(CSoundMixer *aMixer) {
- itsMixer = aMixer;
- muteFlag = itsMixer->maxChannels == 0;
-}
-
-void CSoundHubImpl::Dispose() {
+CSoundHubImpl::~CSoundHubImpl() {
CBasicSound *aSound, *nextSound;
short i;
if (itsMixer) {
- itsMixer->Dispose();
+ delete itsMixer;
+ itsMixer = nullptr;
}
for (i = 0; i < hubSoundKinds; i++) {
aSound = soundList[i];
while (aSound) {
nextSound = aSound->nextSound;
- aSound->Dispose();
+ delete aSound;
aSound = nextSound;
}
}
- delete itsCompressor;
DisposeSoundLinks();
- CDirectObject::Dispose();
+}
+
+void CSoundHubImpl::AttachMixer(CSoundMixer *aMixer) {
+ itsMixer = aMixer;
+ muteFlag = itsMixer->maxChannels == 0;
}
CBasicSound *CSoundHubImpl::GetSoundSampler(short kind, short resId) {
@@ -243,7 +238,8 @@ Fixed* CSoundHubImpl::EarLocation() {
}
void CSoundHubImpl::MixerDispose() {
if (itsMixer) {
- itsMixer->Dispose();
+ delete itsMixer;
+ itsMixer = nullptr;
}
}
diff --git a/src/audio/CSoundHub.h b/src/audio/CSoundHub.h
index 2b1430b8..abbe822f 100644
--- a/src/audio/CSoundHub.h
+++ b/src/audio/CSoundHub.h
@@ -9,7 +9,6 @@
#pragma once
#include "CBasicSound.h"
-#include "CDirectObject.h"
#include "OggFile.h"
#include "SoundSystemDefines.h"
@@ -20,10 +19,11 @@
enum { hubBasic, hubRate, hubSoundKinds };
class CSoundMixer;
-class CHuffProcessor;
class CSoundHub {
public:
+ virtual ~CSoundHub() {};
+
virtual Fixed* EarLocation() = 0;
virtual Fixed DistanceToLevelOne() = 0;
virtual void MuteFlag(Boolean) = 0;
@@ -45,15 +45,13 @@ class CSoundHub {
virtual int ReadTime() = 0;
virtual void HouseKeep() = 0;
- virtual void Dispose() = 0;
virtual void MixerDispose() = 0;
virtual void HushFlag(bool) = 0;
virtual bool Stereo() = 0;
virtual bool AudioEnabled() { return true; };
};
-class CSoundHubImpl : public CDirectObject, public CSoundHub {
+class CSoundHubImpl : public CSoundHub {
public:
- CHuffProcessor *itsCompressor;
CSoundMixer *itsMixer;
CBasicSound *soundList[hubSoundKinds];
@@ -61,7 +59,9 @@ class CSoundHubImpl : public CDirectObject, public CSoundHub {
SoundLink *firstFreeLink;
Boolean muteFlag;
- virtual void ISoundHub(short numOfEachKind, short initialLinks);
+ CSoundHubImpl(short numOfEachKind, short initialLinks);
+ virtual ~CSoundHubImpl();
+
virtual void AttachMixer(CSoundMixer *aMixer);
virtual void CreateSound(short kind);
@@ -81,7 +81,6 @@ class CSoundHubImpl : public CDirectObject, public CSoundHub {
virtual void HouseKeep();
virtual void MuteFlag(Boolean);
- virtual void Dispose();
virtual Fixed* EarLocation();
virtual Fixed DistanceToLevelOne();
virtual void MixerDispose();
diff --git a/src/audio/CSoundMixer.cpp b/src/audio/CSoundMixer.cpp
index d2611912..c071ad89 100644
--- a/src/audio/CSoundMixer.cpp
+++ b/src/audio/CSoundMixer.cpp
@@ -93,7 +93,7 @@ void CSoundMixer::UpdateRightVector(Fixed *right) {
newRightMeta = true;
}
-void CSoundMixer::ISoundMixer(Fixed sampRate,
+CSoundMixer::CSoundMixer(Fixed sampRate,
short maxChannelCount,
short maxMixCount,
Boolean stereoEnable,
@@ -221,6 +221,52 @@ void CSoundMixer::ISoundMixer(Fixed sampRate,
SDL_PauseAudioDevice(outputDevice, 0);
}
+CSoundMixer::~CSoundMixer() {
+ //OSErr iErr;
+ short i;
+ MixerInfo *mix;
+
+ SDL_PauseAudioDevice(outputDevice, 1);
+ SDL_CloseAudioDevice(outputDevice);
+
+ if (motionLink) {
+ altLink = NULL;
+ useAltLink = true;
+ motionHub->ReleaseLink(motionLink);
+ motionLink = NULL;
+ }
+
+ mix = infoTable;
+ for (i = 0; i < maxChannels; i++) {
+ if (mix->active)
+ mix->active->Release();
+ else if (mix->release)
+ mix->release->Release();
+ else if (mix->intro)
+ mix->intro->Release();
+
+ mix++;
+ }
+
+ if (mixBuffers[0]) {
+ DisposePtr((Ptr)mixBuffers[0]);
+ mixBuffers[0] = NULL;
+ }
+
+#define OBLITERATE(pointer) \
+ if (pointer) { \
+ DisposePtr((Ptr)pointer); \
+ pointer = NULL; \
+ }
+
+ OBLITERATE(doubleBuffers[0])
+ OBLITERATE(doubleBuffers[1])
+ OBLITERATE(infoTable)
+ OBLITERATE(volumeLookup)
+ OBLITERATE(scaleLookup)
+ OBLITERATE(sortSpace[0])
+}
+
void CSoundMixer::PrepareScaleLookup() {
int i;
int value;
@@ -254,7 +300,10 @@ void CSoundMixer::PrepareVolumeLookup(uint8_t mixerVolume /* 0-100 */) {
if (sample16flag) {
for (vol = 1; vol <= VOLUMERANGE; vol++) {
for (samp = -SAMPLERANGE / 2; samp < SAMPLERANGE / 2; samp++) {
- *dest++ = (samp * vol * mixerVolume / 100) << (16 - BITSPERSAMPLE - VOLUMEBITS);
+ // the below line was causing problems when samp is negative.
+ // each left shift is a multiplication by two. This might have saved cpu time on 68k.
+ //*dest++ = (samp * vol * mixerVolume / 100) << (16 - BITSPERSAMPLE - VOLUMEBITS);
+ *dest++ = (samp * vol * mixerVolume / 100) * (2 * (16 - BITSPERSAMPLE - VOLUMEBITS));
}
}
} else {
@@ -277,52 +326,6 @@ void CSoundMixer::SilenceBuffers() {
}
}
-void CSoundMixer::Dispose() {
- //OSErr iErr;
- short i;
- MixerInfo *mix;
-
- SDL_PauseAudioDevice(outputDevice, 1);
- SDL_CloseAudioDevice(outputDevice);
-
- if (motionLink) {
- altLink = NULL;
- useAltLink = true;
- motionHub->ReleaseLink(motionLink);
- motionLink = NULL;
- }
-
- mix = infoTable;
- for (i = 0; i < maxChannels; i++) {
- if (mix->active)
- mix->active->Release();
- else if (mix->release)
- mix->release->Release();
- else if (mix->intro)
- mix->intro->Release();
-
- mix++;
- }
-
- if (mixBuffers[0]) {
- DisposePtr((Ptr)mixBuffers[0]);
- mixBuffers[0] = NULL;
- }
-
-#define OBLITERATE(pointer) \
- if (pointer) { \
- DisposePtr((Ptr)pointer); \
- pointer = NULL; \
- }
-
- OBLITERATE(doubleBuffers[0])
- OBLITERATE(doubleBuffers[1])
- OBLITERATE(infoTable)
- OBLITERATE(volumeLookup)
- OBLITERATE(scaleLookup)
- OBLITERATE(sortSpace[0])
-}
-
void CSoundMixer::HouseKeep() {
short i;
MixerInfo *mix;
diff --git a/src/audio/CSoundMixer.h b/src/audio/CSoundMixer.h
index 11d4265a..29746a50 100644
--- a/src/audio/CSoundMixer.h
+++ b/src/audio/CSoundMixer.h
@@ -8,7 +8,6 @@
*/
#pragma once
-#include "CDirectObject.h"
#include "FastMat.h"
#include "SoundSystemDefines.h"
@@ -47,7 +46,7 @@ typedef struct {
Vector speed; // Linear motion
} SoundMotionInfo;
-class CSoundMixer : public CDirectObject {
+class CSoundMixer {
public:
int32_t globRegister = 0;
int32_t volumeMax = 0;
@@ -106,13 +105,15 @@ class CSoundMixer : public CDirectObject {
Boolean stereo = false;
Boolean strongStereo = false;
- void ISoundMixer(Fixed sampRate,
+
+ CSoundMixer(Fixed sampRate,
int16_t maxChannelCount,
int16_t maxMixCount,
Boolean stereoEnable,
Boolean sample16Enable,
Boolean interpolateEnable,
Boolean openAudioDevice);
+ virtual ~CSoundMixer();
void SetSoundEnvironment(Fixed speedOfSound, Fixed distanceToLevelOne, int timeUnit);
void SetStereoSeparation(Boolean strongFlag);
@@ -130,7 +131,6 @@ class CSoundMixer : public CDirectObject {
void DoubleBack(uint8_t *stream, int size);
- virtual void Dispose() override;
void HouseKeep();
void AddSound(CBasicSound *theSound);
};
diff --git a/src/base/CDirectObject.cpp b/src/base/CDirectObject.cpp
deleted file mode 100644
index fa6f2fd7..00000000
--- a/src/base/CDirectObject.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- Copyright ©1994-1996, Juri Munkki
- All rights reserved.
-
- File: CDirectObject.c
- Created: Friday, March 11, 1994, 17:15
- Modified: Sunday, September 15, 1996, 21:38
-*/
-
-#include "CDirectObject.h"
-
-void CDirectObject::Dispose() { delete this; }
diff --git a/src/base/CDirectObject.h b/src/base/CDirectObject.h
deleted file mode 100644
index ca606987..00000000
--- a/src/base/CDirectObject.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- Copyright ©1994-1996, Juri Munkki
- All rights reserved.
-
- File: CDirectObject.h
- Created: Friday, March 11, 1994, 17:14
- Modified: Tuesday, February 20, 1996, 07:20
-*/
-
-#pragma once
-
-class CDirectObject {
-public:
- CDirectObject() {}
- virtual ~CDirectObject() {}
-
- virtual void Dispose();
-};
diff --git a/src/bsp/CBSPPart.h b/src/bsp/CBSPPart.h
index 33767199..191df117 100644
--- a/src/bsp/CBSPPart.h
+++ b/src/bsp/CBSPPart.h
@@ -9,7 +9,6 @@
#pragma once
#include "ARGBColor.h"
-#include "CDirectObject.h"
#include "ColorManager.h"
#include "FastMat.h"
#include "Material.h"
diff --git a/src/bsp/CBSPWorld.h b/src/bsp/CBSPWorld.h
index 66d8c5d5..8768d7d3 100644
--- a/src/bsp/CBSPWorld.h
+++ b/src/bsp/CBSPWorld.h
@@ -10,7 +10,6 @@
#pragma once
#include "CCompoundShape.h"
-#include "CDirectObject.h"
#include "Types.h"
#include
diff --git a/src/bsp/CViewParameters.h b/src/bsp/CViewParameters.h
index ef75b19d..5aca56f1 100644
--- a/src/bsp/CViewParameters.h
+++ b/src/bsp/CViewParameters.h
@@ -11,7 +11,6 @@
#include "ARGBColor.h"
#include "CBSPPart.h"
-#include "CDirectObject.h"
#define DEFAULT_LIGHT_COLOR 0xffffffff
#define DIR_LIGHT_DISTANCE 1000.0f
diff --git a/src/game/AvaraScoreInterface.h b/src/game/AvaraScoreInterface.h
index 4b6ff578..b7ad86c1 100644
--- a/src/game/AvaraScoreInterface.h
+++ b/src/game/AvaraScoreInterface.h
@@ -77,7 +77,7 @@ typedef struct {
long command; // One of ScoreInterfaceMessages
long result; // Reserved for future calls that may return results.
long capabilities; // Your capabilities.
- Handle plugIn; // Your plug-in code handle
+ //Handle plugIn; // Your plug-in code handle
long maxPlayers; // ksiInit sets this. (current default is 6)
long maxTeams; // ksiInit sets this. (current default is 6) Doesn't include neutral team!!
@@ -100,20 +100,8 @@ typedef struct {
** forever unless you are carelessly setting the resultsChanged flag
** even when the text has not changed.
*/
- Handle resultsHandle;
- long resultsChanged;
-
- /*
- ** Alternatively, you can draw the results yourself when you receive a
- ** ksiResultsDraw call. If you add any controls to the window, you have
- ** to remove them when you are closed and you have to hide them when you
- ** receive a ksiResultsHide call.
- */
- /*
- WindowPtr resultsWindow; // Guaranteed to be valid only for hide/draw/click
- Rect resultsRect; // Valid only for draw/click calls
- EventRecord *theEvent;
- */
+ //Handle resultsHandle;
+ //long resultsChanged;
/*
** The following parameters are valid for all calls and usually change
diff --git a/src/game/CAbstractActor.h b/src/game/CAbstractActor.h
index 861db8b3..6b644d9f 100644
--- a/src/game/CAbstractActor.h
+++ b/src/game/CAbstractActor.h
@@ -10,7 +10,6 @@
#pragma once
#include "AssetManager.h"
#include "CAvaraGame.h"
-#include "CDirectObject.h"
#include "ColorManager.h"
#include "CSoundHub.h"
#include "FastMat.h"
diff --git a/src/game/CAbstractPlayer.h b/src/game/CAbstractPlayer.h
index 1ab4488b..b2b0b18b 100644
--- a/src/game/CAbstractPlayer.h
+++ b/src/game/CAbstractPlayer.h
@@ -161,8 +161,8 @@ class CAbstractPlayer : public CRealMovers {
// Winning/loosing:
FrameNumber winFrame = 0;
- Quaternion winStart = {0};
- Quaternion winEnd = {0};
+ Quaternion winStart = {0, 0, 0, 0};
+ Quaternion winEnd = {0, 0, 0, 0};
Boolean isOut = 0;
short lives = 0;
diff --git a/src/game/CAvaraGame.cpp b/src/game/CAvaraGame.cpp
index b859dd82..a26d8555 100755
--- a/src/game/CAvaraGame.cpp
+++ b/src/game/CAvaraGame.cpp
@@ -55,8 +55,7 @@ void CAvaraGame::InitMixer(Boolean silentFlag) {
soundHub->MixerDispose();
- aMixer = new CSoundMixer;
- aMixer->ISoundMixer(rate22khz, 64, 8, true, true, false, soundHub->AudioEnabled());
+ aMixer = new CSoundMixer(rate22khz, 64, 8, true, true, false, soundHub->AudioEnabled());
aMixer->SetStereoSeparation(true);
aMixer->SetSoundEnvironment(FIX(400), FIX(5), CLASSICFRAMETIME);
aMixer->SetVolume(gApplication ? gApplication->Get(kSoundVolume) : 0);
@@ -85,7 +84,7 @@ void CAvaraGame::IncrementGameCounter() {
}
std::unique_ptr CAvaraGame::CreateNetManager() {
- return std::make_unique();
+ return std::make_unique(this);
}
CAvaraGame::CAvaraGame(FrameTime frameTime) {
@@ -96,7 +95,7 @@ void CAvaraGame::IAvaraGame(CAvaraApp *theApp) {
itsApp = theApp;
itsNet = CreateNetManager();
- itsNet->INetManager(this);
+ itsNet->InitializePlayers();
itsApp->SetNet(itsNet.get());
searchCount = 0;
@@ -119,11 +118,9 @@ void CAvaraGame::IAvaraGame(CAvaraApp *theApp) {
InitMixer(true);
- scoreKeeper = new CScoreKeeper;
- scoreKeeper->IScoreKeeper(this);
+ scoreKeeper = new CScoreKeeper(this);
- itsDepot = new CDepot;
- itsDepot->IDepot(this);
+ itsDepot = new CDepot(this);
// mapRes = GetResource(FUNMAPTYPE, FUNMAPID);
@@ -151,9 +148,7 @@ void CAvaraGame::IAvaraGame(CAvaraApp *theApp) {
}
CSoundHub* CAvaraGame::CreateSoundHub() {
- CSoundHubImpl *soundHub = new CSoundHubImpl;
- soundHub->ISoundHub(32, 32);
- return soundHub;
+ return new CSoundHubImpl(32, 32);
}
CAvaraGame::~CAvaraGame() {
@@ -162,8 +157,8 @@ CAvaraGame::~CAvaraGame() {
spectatePlayer = NULL;
LevelReset(false);
- scoreKeeper->Dispose();
- itsDepot->Dispose();
+ delete scoreKeeper;
+ delete itsDepot;
while (actorList) {
nextActor = actorList->nextActor;
@@ -178,12 +173,8 @@ CAvaraGame::~CAvaraGame() {
}
if (soundHub)
- soundHub->Dispose();
-// if (itsNet)
-// itsNet->Dispose();
- // ReleaseResource(mapRes);
+ delete soundHub;
- // DisposePolyWorld(&itsPolyWorld);
DisposePtr((Ptr)locatorTable);
}
diff --git a/src/game/CAvaraGame.h b/src/game/CAvaraGame.h
index be07505c..d70f59e4 100644
--- a/src/game/CAvaraGame.h
+++ b/src/game/CAvaraGame.h
@@ -11,7 +11,6 @@
#include "AvaraDefines.h"
#include "AvaraScoreInterface.h"
#include "AvaraTypes.h"
-#include "CDirectObject.h"
#include "Types.h"
#include "CNetManager.h"
#include "LevelInfo.h"
diff --git a/src/game/CDepot.cpp b/src/game/CDepot.cpp
index 8bee74b2..db8e6244 100644
--- a/src/game/CDepot.cpp
+++ b/src/game/CDepot.cpp
@@ -23,7 +23,7 @@
#include "CSmartPart.h"
#include "CViewParameters.h"
-void CDepot::IDepot(CAvaraGame *theGame) {
+CDepot::CDepot(CAvaraGame *theGame) {
itsGame = theGame;
ReloadParts();
@@ -35,7 +35,7 @@ void CDepot::IDepot(CAvaraGame *theGame) {
CreateSlivers();
}
-void CDepot::Dispose() {
+CDepot::~CDepot() {
short i;
CSliverPart *nextSliver, *slivers;
@@ -55,8 +55,6 @@ void CDepot::Dispose() {
delete smartSight;
delete grenadeSight;
delete grenadeTop;
-
- CDirectObject::Dispose();
}
void CDepot::EndScript() {
diff --git a/src/game/CDepot.h b/src/game/CDepot.h
index b0339480..331005e1 100644
--- a/src/game/CDepot.h
+++ b/src/game/CDepot.h
@@ -9,7 +9,6 @@
#pragma once
#include "AvaraDefines.h"
-#include "CDirectObject.h"
#include "FastMat.h"
#include "RayHit.h"
@@ -31,7 +30,7 @@ class CWeapon;
enum { kmiFlat, kmiTurning, kmiShuriken };
enum { kweGrenade, kweSmart };
-class CDepot : public CDirectObject {
+class CDepot {
public:
CAvaraGame *itsGame;
@@ -52,8 +51,9 @@ class CDepot : public CDirectObject {
Fixed missileTurnRate;
Fixed missileAcceleration;
- virtual void IDepot(CAvaraGame *theGame);
- virtual void Dispose();
+ CDepot(CAvaraGame *theGame);
+ virtual ~CDepot();
+
virtual void EndScript();
virtual void CreateSlivers();
diff --git a/src/game/CHUD.h b/src/game/CHUD.h
index ca386344..654e8b0d 100644
--- a/src/game/CHUD.h
+++ b/src/game/CHUD.h
@@ -1,6 +1,5 @@
#pragma once
-#include "CDirectObject.h"
#include
#include "CViewParameters.h"
#include "CPlayerManager.h"
@@ -8,7 +7,7 @@
class CAvaraGame;
-class CHUD : CDirectObject {
+class CHUD {
public:
CAvaraGame *itsGame;
int images;
diff --git a/src/game/CNetManager.cpp b/src/game/CNetManager.cpp
index efafe7cd..09e7c00e 100644
--- a/src/game/CNetManager.cpp
+++ b/src/game/CNetManager.cpp
@@ -48,35 +48,22 @@
extern Fixed FRandSeed;
extern Fixed NewFRandSeed();
-void CNetManager::INetManager(CAvaraGame *theGame) {
- short i;
-
+CNetManager::CNetManager(CAvaraGame *theGame) {
itsGame = theGame;
readyPlayers = 0;
netStatus = kNullNet;
itsCommManager = std::make_unique();
- itsCommManager->ICommManager(NULLNETPACKETS);
-
- itsProtoControl = new CProtoControl;
- itsProtoControl->IProtoControl(itsCommManager.get(), itsGame);
- // theRoster = ((CAvaraApp *)gApplication)->theRosterWind;
-
- for (i = 0; i < kMaxAvaraPlayers; i++) {
- playerTable[i] = CreatePlayerManager(i);
- slotToPosition[i] = i;
- positionToSlot[i] = i;
- teamColors[i] = i; //(i/3) * 2;
- }
+ itsProtoControl = new CProtoControl(itsCommManager.get(), itsGame);
+ activePlayersDistribution = 0;
totalDistribution = 0;
playerCount = 0;
isConnected = false;
isPlaying = false;
startingGame = false;
- netOwner = NULL;
loaderSlot = 0;
serverOptions = theGame->itsApp->Number(kServerOptionsTag);
@@ -89,38 +76,34 @@ void CNetManager::INetManager(CAvaraGame *theGame) {
lastLoginRefusal = 0;
}
-std::shared_ptr CNetManager::CreatePlayerManager(short id) {
- std::shared_ptr pm = std::make_shared();
- pm->IPlayerManager(itsGame, id, this);
- return pm;
-}
-
-void CNetManager::LevelReset() {
- playerCount = 0;
-}
-void CNetManager::Dispose() {
+CNetManager::~CNetManager() {
short i;
for (i = 0; i < kMaxAvaraPlayers; i++) {
- playerTable[i]->Dispose();
+ playerTable[i] = nullptr;
}
- itsProtoControl->Dispose();
- itsCommManager->Dispose();
+ delete itsProtoControl;
+ itsCommManager = nullptr;
}
-Boolean CNetManager::ConfirmNetChange() {
- /*
- CCommander *theActive;
- short dItem;
+std::shared_ptr CNetManager::CreatePlayerManager(short id) {
+ return std::make_shared(itsGame, id, this);
+}
- theActive = gApplication->BeginDialog();
- dItem = CautionAlert(402, NULL);
- gApplication->EndDialog(theActive);
+// This cannot be called from the constructor because CreatePlayerManager is virtual; the test
+// implementation ends up calling the CNetManager instead.
+void CNetManager::InitializePlayers() {
+ for (int i = 0; i < kMaxAvaraPlayers; i++) {
+ playerTable[i] = CreatePlayerManager(i);
+ slotToPosition[i] = i;
+ positionToSlot[i] = i;
+ teamColors[i] = i; //(i/3) * 2;
+ }
+}
- return dItem == 1;
- */
- return true;
+void CNetManager::LevelReset() {
+ playerCount = 0;
}
void CNetManager::ChangeNet(short netKind, std::string address) {
@@ -133,38 +116,27 @@ void CNetManager::ChangeNet(short netKind, std::string address, std::string pass
//CAvaraApp *theApp = itsGame->itsApp;
if (netKind != netStatus || !isConnected) {
- if (netStatus != kNullNet || !isConnected) {
- if (isConnected) {
- confirm = ConfirmNetChange();
- }
- }
-
- if (confirm) {
- switch (netKind) {
- case kNullNet:
- newManager = std::make_unique();
- newManager->ICommManager(NULLNETPACKETS);
- break;
- case kServerNet: {
- newManager = std::make_unique();
- CUDPComm *theServer = (CUDPComm*)(newManager.get());
- theServer->IUDPComm(kMaxAvaraPlayers - 1, TCPNETPACKETS, kAvaraNetVersion, itsGame->frameTime);
- theServer->StartServing();
- confirm = theServer->isConnected;
- } break;
- case kClientNet:
- newManager = std::make_unique();
- CUDPComm *theClient = (CUDPComm *)(newManager.get());
- theClient->IUDPComm(kMaxAvaraPlayers - 1, TCPNETPACKETS, kAvaraNetVersion, itsGame->frameTime);
- theClient->Connect(address, password);
- confirm = theClient->isConnected;
- break;
- }
+ switch (netKind) {
+ case kNullNet:
+ newManager = std::make_unique();
+ break;
+ case kServerNet: {
+ newManager = std::make_unique(kMaxAvaraPlayers - 1, TCPNETPACKETS, kAvaraNetVersion, itsGame->frameTime);
+ CUDPComm *theServer = (CUDPComm*)(newManager.get());
+ theServer->StartServing();
+ confirm = theServer->isConnected;
+ } break;
+ case kClientNet:
+ newManager = std::make_unique(kMaxAvaraPlayers - 1, TCPNETPACKETS, kAvaraNetVersion, itsGame->frameTime);
+ CUDPComm *theClient = (CUDPComm *)(newManager.get());
+ theClient->Connect(address, password);
+ confirm = theClient->isConnected;
+ break;
}
if (confirm && newManager) {
PresenceType keepPresence = playerTable[itsCommManager->myId]->Presence();
- itsCommManager->Dispose(); // send kpPacketProtocolLogout message before being destroyed
+ itsCommManager->Finalize(); // send kpPacketProtocolLogout message before being destroyed
itsProtoControl->Detach();
itsCommManager.swap(newManager); // newManager takes place existing CCommManager which gets deleted when out of scope
playerTable[itsCommManager->myId]->SetPresence(keepPresence);
@@ -412,7 +384,6 @@ void CNetManager::HandleDisconnect(short slotId, short why) {
if (slotId == itsCommManager->myId) {
isConnected = false;
- netOwner = NULL;
DisconnectSome(kdEveryone);
itsCommManager->SendPacket(1 << slotId, kpKillNet, 0, 0, 0, 0, 0);
} else {
@@ -715,6 +686,7 @@ void CNetManager::ResumeGame() {
// process packets until we receive all the kpStartSynch messages (with kLActive status)
ProcessQueue();
+
// Do we need this?
// itsGame->itsApp->DoUpdate();
diff --git a/src/game/CNetManager.h b/src/game/CNetManager.h
index 79232e96..57913087 100644
--- a/src/game/CNetManager.h
+++ b/src/game/CNetManager.h
@@ -11,7 +11,6 @@
#include "AvaraDefines.h"
#include "ColorManager.h"
#include "CCommManager.h"
-#include "CDirectObject.h"
#include "KeyFuncs.h"
//#include "LevelScoreRecord.h"
#include "PlayerConfig.h"
@@ -68,12 +67,11 @@ typedef union
} BlockAndValue;
*/
-class CNetManager : public CDirectObject {
+class CNetManager {
public:
CAvaraGame *itsGame;
std::unique_ptr itsCommManager;
CProtoControl *itsProtoControl;
- // CRosterWindow *theRoster;
short playerCount;
std::shared_ptr playerTable[kMaxAvaraPlayers];
@@ -88,7 +86,6 @@ class CNetManager : public CDirectObject {
uint16_t startPlayersDistribution;
uint16_t totalDistribution;
short netStatus;
- CDirectObject *netOwner;
short deadOrDonePlayers;
Boolean isConnected;
Boolean isPlaying;
@@ -126,12 +123,12 @@ class CNetManager : public CDirectObject {
//char msgBuffer[kMaxChatMessageBufferLen];
std::vector msgBuffer;
- virtual ~CNetManager() { Dispose(); };
- virtual void INetManager(CAvaraGame *theGame);
+ CNetManager(CAvaraGame *theGame);
+ virtual ~CNetManager();
+
virtual std::shared_ptr CreatePlayerManager(short);
+ virtual void InitializePlayers();
virtual void LevelReset();
- virtual void Dispose();
- virtual Boolean ConfirmNetChange();
virtual void ChangeNet(short netKind, std::string address);
virtual void ChangeNet(short netKind, std::string address, std::string password);
diff --git a/src/game/CPlayerManager.cpp b/src/game/CPlayerManager.cpp
index 55de91c0..9b8cac3c 100644
--- a/src/game/CPlayerManager.cpp
+++ b/src/game/CPlayerManager.cpp
@@ -36,7 +36,7 @@
CPlayerManager* CPlayerManager::theLocalPlayer;
CPlayerManager* CPlayerManager::theServerPlayer;
-void CPlayerManagerImpl::IPlayerManager(CAvaraGame *theGame, short id, CNetManager *aNetManager) {
+CPlayerManagerImpl::CPlayerManagerImpl(CAvaraGame *theGame, short id, CNetManager *aNetManager) {
// Rect *mainScreenRect;
itsGame = theGame;
@@ -587,10 +587,6 @@ void CPlayerManagerImpl::ViewControl() {
itsPlayer->ControlViewPoint();
}
-void CPlayerManagerImpl::Dispose() {
- CDirectObject::Dispose();
-}
-
void CPlayerManagerImpl::SendResendRequest(short askCount) {
if (/* theNetManager->fastTrack.addr.value || */ askCount >= 0) {
theNetManager->playerTable[theNetManager->itsCommManager->myId]->ResendFrame(
diff --git a/src/game/CPlayerManager.h b/src/game/CPlayerManager.h
index f89f5c05..24a1463b 100644
--- a/src/game/CPlayerManager.h
+++ b/src/game/CPlayerManager.h
@@ -8,7 +8,6 @@
*/
#pragma once
-#include "CDirectObject.h"
#include "ColorManager.h"
#include "KeyFuncs.h"
#include "PlayerConfig.h"
@@ -88,7 +87,6 @@ class CPlayerManager {
virtual Str255& PlayerName() = 0;
virtual std::string GetPlayerName() = 0;
virtual std::deque& LineBuffer() = 0;
- virtual void Dispose() = 0;
virtual void NetDisconnect() = 0;
virtual short IsRegistered() = 0;
virtual void IsRegistered(short) = 0;
@@ -149,12 +147,11 @@ class CPlayerManager {
virtual bool GetShowScoreboard() = 0;
};
-class CPlayerManagerImpl : public CDirectObject, public CPlayerManager, public std::enable_shared_from_this {
+class CPlayerManagerImpl : public CPlayerManager, public std::enable_shared_from_this {
private:
CAbstractPlayer *itsPlayer;
CAvaraGame *itsGame;
- // CRosterWindow *theRoster;
CNetManager *theNetManager;
Fixed randomKey;
@@ -215,8 +212,9 @@ class CPlayerManagerImpl : public CDirectObject, public CPlayerManager, public s
float controllerCurveExp, controllerMaxMove, controllerMultiplyX, controllerMultiplyY, controllerStickThreshold, controllerTriggerThreshold, controllerDamper;
public:
- virtual void IPlayerManager(CAvaraGame *theGame, short id, CNetManager *aNetManager);
-
+ CPlayerManagerImpl(CAvaraGame *theGame, short id, CNetManager *aNetManager);
+ virtual ~CPlayerManagerImpl() {}
+
virtual void SetPlayer(CAbstractPlayer *thePlayer);
virtual bool CalculateIsLocalPlayer();
@@ -235,11 +233,8 @@ class CPlayerManagerImpl : public CDirectObject, public CPlayerManager, public s
virtual FunctionTable *GetFunctions();
virtual void SendResendRequest(short askCount);
- virtual void Dispose();
-
virtual Boolean TestKeyPressed(short funcCode);
- // virtual void FlushMessageText(Boolean forceAll);
virtual void RosterMessageText(short len, const char *c);
virtual std::string GetChatString(int maxChars);
virtual std::string GetChatLine();
@@ -277,8 +272,6 @@ class CPlayerManagerImpl : public CDirectObject, public CPlayerManager, public s
virtual void StoreMugShot(Handle mugHandle);
virtual Handle GetMugShot();
- // virtual void GetLoadingStatusString(StringPtr theStr);
-
virtual void SpecialColorControl();
virtual short Slot();
virtual void SetLocal();
diff --git a/src/game/CScoreKeeper.cpp b/src/game/CScoreKeeper.cpp
index af564858..45660186 100644
--- a/src/game/CScoreKeeper.cpp
+++ b/src/game/CScoreKeeper.cpp
@@ -45,7 +45,7 @@ enum { // For personal pages:
kTeamNames
};
-void CScoreKeeper::IScoreKeeper(CAvaraGame *theGame) {
+CScoreKeeper::CScoreKeeper(CAvaraGame *theGame) {
itsGame = theGame;
// resRefNum = 0;
// appResRefNum = CurResFile();
@@ -53,16 +53,16 @@ void CScoreKeeper::IScoreKeeper(CAvaraGame *theGame) {
iface.command = 0;
iface.result = 0;
iface.capabilities = 0;
- iface.plugIn = NULL;
+ // iface.plugIn = NULL;
iface.maxPlayers = kMaxAvaraPlayers;
iface.maxTeams = kMaxTeamColors;
iface.frameTime = itsGame->frameTime;
iface.frameNumber = -1;
- iface.resultsHandle = NULL; //GetResource('TEXT', 300);
+ // iface.resultsHandle = NULL; //GetResource('TEXT', 300);
// DetachResource(iface.resultsHandle);
- iface.resultsChanged = false;
+ // iface.resultsChanged = false;
// iface.resultsWindow = ((CAvaraApp *)gApplication)->theRosterWind->itsWindow;
// SetRect(&iface.resultsRect, 0,0, 0,0);
// iface.theEvent = NULL;
@@ -95,11 +95,9 @@ void CScoreKeeper::IScoreKeeper(CAvaraGame *theGame) {
playerRatings = std::make_unique();
}
-void CScoreKeeper::Dispose() {
- DisposeHandle(iface.resultsHandle);
- iface.resultsHandle = NULL;
-
- CDirectObject::Dispose();
+CScoreKeeper::~CScoreKeeper() {
+ //DisposeHandle(iface.resultsHandle);
+ //iface.resultsHandle = NULL;
}
void CScoreKeeper::EndScript() {
diff --git a/src/game/CScoreKeeper.h b/src/game/CScoreKeeper.h
index 31c08159..ca68d106 100644
--- a/src/game/CScoreKeeper.h
+++ b/src/game/CScoreKeeper.h
@@ -10,7 +10,6 @@
#pragma once
#include "AvaraDefines.h"
#include "AvaraScoreInterface.h"
-#include "CDirectObject.h"
#include "PlayerRatingsSimpleElo.h"
#define PLAYER_SCORE_FIELD_COUNT 6
@@ -42,7 +41,7 @@ struct FinishRecord {
};
-class CScoreKeeper : public CDirectObject {
+class CScoreKeeper {
public:
CAvaraGame *itsGame;
ScoreInterfaceRecord iface;
@@ -61,12 +60,8 @@ class CScoreKeeper : public CDirectObject {
// player ratings stuff
std::unique_ptr playerRatings;
- virtual void IScoreKeeper(CAvaraGame *theGame);
- virtual void Dispose();
-
- // virtual OSErr OpenPlugIn(FSSpec *theFile);
- // virtual void ClosePlugIn();
- // virtual void CallPlugIn();
+ CScoreKeeper(CAvaraGame *theGame);
+ virtual ~CScoreKeeper();
virtual void EndScript();
virtual void StartResume(Boolean didStart);
@@ -77,13 +72,6 @@ class CScoreKeeper : public CDirectObject {
virtual void PlayerLeft();
virtual void PlayerJoined();
-
- /*
- virtual void Click(EventRecord *theEvent, Rect *theRect);
- virtual Handle GetCustomText();
- virtual void DrawCustomWindow(Rect *theRect);
- virtual void HideShow(Boolean doHide);
- */
virtual void Score(ScoreInterfaceReasons reason,
short team,
short player,
@@ -94,11 +82,6 @@ class CScoreKeeper : public CDirectObject {
virtual void ResetScores();
virtual void ReceiveResults(int32_t *newResults);
- // virtual void DrawOnePlayerResults(short slot, Rect *toRect);
- // virtual void DrawResultsSummary(Rect *toRect);
- // virtual void RegularClick(EventRecord *theEvent, Rect *theRect);
-
- // virtual void FilterConsoleLine(StringPtr theString, short align);
std::vector DetermineFinishOrder();
void UpdatePlayerRatings(std::vector);
diff --git a/src/game/CSmart.cpp b/src/game/CSmart.cpp
index 6e5bdebd..e7e157b1 100644
--- a/src/game/CSmart.cpp
+++ b/src/game/CSmart.cpp
@@ -248,9 +248,9 @@ void CSmart::TurnTowardsTarget() {
RayTestWithGround(&rayHit, kSolidBit);
if (rayHit.closestHit && rayHit.closestHit->theOwner == targetActor) {
- toTarget[0] -= speed[0] << 1;
- toTarget[1] -= speed[1] << 1;
- toTarget[2] -= speed[2] << 1;
+ toTarget[0] -= speed[0] * 2;
+ toTarget[1] -= speed[1] * 2;
+ toTarget[2] -= speed[2] * 2;
FindSpaceAngle(toTarget, &goodYaw, &goodPitch);
diff --git a/src/hsnd2wav.cpp b/src/hsnd2wav.cpp
deleted file mode 100644
index 2ac0f5c9..00000000
--- a/src/hsnd2wav.cpp
+++ /dev/null
@@ -1,319 +0,0 @@
-#define USE_LEGACY_HSND
-#include "AudioFile.h"
-#include "CHuffProcessor.h"
-#include "FastMat.h"
-#include "SDL2/SDL.h"
-#include "SoundSystemDefines.h"
-#include "BasePath.h"
-
-#include
-
-typedef struct {
- uint32_t versNum;
- uint32_t loopStart;
- uint32_t loopEnd;
- uint32_t loopCount;
- uint32_t dataOffset;
- UnsignedFixed baseRate;
-} LegacyHSNDRecord;
-
-struct SampleHeader {
- int16_t resId;
- int16_t refCount;
- uint32_t len;
- uint32_t loopStart;
- uint32_t loopEnd;
- uint32_t loopCount;
- UnsignedFixed baseRate;
- struct SampleHeader **nextSample;
- int16_t flags;
-};
-
-enum { kOldSampleFlag = 1 };
-
-typedef struct SampleHeader SampleHeader;
-typedef SampleHeader *SampleHeaderPtr;
-typedef SampleHeaderPtr *SampleHeaderHandle;
-
-static SampleHeaderHandle sampleList = NULL;
-static CHuffProcessor *itsCompressor = new CHuffProcessor;
-
-static std::string defaultResource(GetBasePath() + "rsrc/Avara.r");
-
-static std::string currentResource("");
-
-bool IsEquals(const std::string& str1, const std::string& str2) {
- return str1.length() == str2.length() &&
- std::equal(str1.begin(), str1.end(), str2.begin(),
- [](char a, char b) {
- return tolower(a) == tolower(b);
- });
-}
-
-void UseResFile(std::string filename) {
- currentResource.assign(GetBasePath() + filename);
-}
-
-Handle FindResource(SDL_RWops *file, OSType theType, short theID, std::string name) {
- uint32_t dataOffset = SDL_ReadBE32(file);
- uint32_t mapOffset = SDL_ReadBE32(file);
- // uint32_t dataLen =
- SDL_ReadBE32(file);
- // uint32_t mapLen =
- SDL_ReadBE32(file);
-
- SDL_RWseek(file, mapOffset + 22, 0);
-
- //uint16_t forkAttrs =
- SDL_ReadBE16(file);
-
- uint16_t typeListOffset = SDL_ReadBE16(file);
- uint16_t nameListOffset = SDL_ReadBE16(file);
- int16_t numTypes = SDL_ReadBE16(file);
-
- uint32_t offset = mapOffset + typeListOffset + 2;
- while (numTypes >= 0) {
- SDL_RWseek(file, offset, 0); // already read num_types above
-
- uint32_t rsrcType = SDL_ReadBE32(file);
- int16_t numResources = SDL_ReadBE16(file);
- uint16_t rsrcListOffset = SDL_ReadBE16(file);
-
- uint32_t rsrcOffset = mapOffset + typeListOffset + rsrcListOffset;
- while (numResources >= 0) {
- SDL_RWseek(file, rsrcOffset, 0);
-
- uint16_t rsrcId = SDL_ReadBE16(file);
- int16_t nameOffset = SDL_ReadBE16(file);
- uint32_t rsrcInfo = SDL_ReadBE32(file);
- uint32_t rsrcDataOffset = dataOffset + (rsrcInfo & 0x00FFFFFF);
- std::string rsrcName;
-
- bool nameMatch = false;
- if (nameOffset >= 0 && name != "") {
- // Only read the resource name if we're looking up by name.
- uint32_t rsrcNameOffset = mapOffset + nameListOffset + nameOffset;
- SDL_RWseek(file, rsrcNameOffset, 0);
- const uint8_t nameLen = SDL_ReadU8(file);
- char* cName = new char[nameLen];
- SDL_RWread(file, cName, nameLen, 1);
- std::string rsrcName(cName, nameLen);
- nameMatch = IsEquals(rsrcName, name);
- delete[] cName;
- }
-
- if (rsrcType == theType && ((rsrcId == theID) || nameMatch)) {
- SDL_RWseek(file, rsrcDataOffset, 0);
- uint32_t rsrcDataLen = SDL_ReadBE32(file);
- Handle h = NewHandle(rsrcDataLen);
- SDL_RWread(file, *h, rsrcDataLen, 1);
- return h;
- }
-
- rsrcOffset += 12;
- numResources--;
- }
-
- offset += 8;
- numTypes--;
- }
-
- return NULL;
-}
-
-Handle _GetResource(OSType theType, short theID, std::string theName) {
- /*
- // TODO: handle TEXT, BSPT (bsp templates)
- // everything else is just checking if it's there and not using the data
- std::string typeString = OSTypeString(theType);
- std::string idString = std::to_string(theID);
-
- nlohmann::json result = GetKeyFromSetJSON(typeString, idString, 0);
- if (result == -1) return NULL;
- else return NewHandle(0);
- */
- SDL_RWops *file;
- Handle data = NULL;
-
- // If there is a "current" resource file, look there first.
- if (currentResource.size() > 0) {
- //SDL_Log("Loading %i : %s from %s", theID, theName.c_str(), currentResource.c_str());
- if ((file = SDL_RWFromFile(currentResource.c_str(), "rb"))) {
- data = FindResource(file, theType, theID, theName);
- SDL_RWclose(file);
- }
- }
-
- // If there is no current resource file, or the resource wasn't found there, look in the default file.
- if (data == NULL) {
- //SDL_Log("Loading %i : %s from Avara resource", theID, theName.c_str());
- if ((file = SDL_RWFromFile(defaultResource.c_str(), "rb"))) {
- data = FindResource(file, theType, theID, theName);
- SDL_RWclose(file);
- }
- }
-
- return data;
-
-}
-
-Handle GetResource(OSType theType, short theID) {
- return _GetResource(theType, theID, "");
-}
-
-void ReleaseResource(Handle theResource) {
- DisposeHandle(theResource);
-}
-
-SampleHeaderHandle LoadSampleLegacy(short resId) {
- SampleHeaderHandle aSample;
- SampleHeaderPtr sampP;
-
- aSample = sampleList;
-
- while (aSample) {
- sampP = *aSample;
- if (sampP->resId == resId) {
- sampP->flags = 0;
- break;
- }
- aSample = sampP->nextSample;
- }
-
- if (!aSample) {
- Handle compressedData;
-
- compressedData = GetResource(HSOUNDRESTYPE, resId);
- if (compressedData) {
- int len;
- //short tryCount;
- Ptr soundData;
- //float base;
- LegacyHSNDRecord *ir;
-
- // MoveHHi(compressedData);
- HLock(compressedData);
-
- ir = (LegacyHSNDRecord *)*compressedData;
-
- ir->versNum = ntohl(ir->versNum);
- ir->loopStart = ntohl(ir->loopStart);
- ir->loopEnd = ntohl(ir->loopEnd);
- ir->loopCount = ntohl(ir->loopCount);
- ir->dataOffset = ntohl(ir->dataOffset);
- if (ir->versNum >= 2) {
- ir->baseRate = ntohl(ir->baseRate);
- //base = ir->baseRate / 65536.0;
- }
- //else {
- // base = 1.0;
- //}
-
- soundData = ir->dataOffset + *compressedData;
- len = itsCompressor->GetUncompressedLen(soundData);
-
- //SDL_Log("LegacyHSNDRecord versNum=%d, loopStart=%d, loopEnd=%d, loopCount=%d, dataOffset=%d, baseRate=%f, len=%i\n",
- //ir->versNum, ir->loopStart, ir->loopEnd, ir->loopCount, ir->dataOffset, base, len);
-
- aSample = (SampleHeaderHandle)NewHandle(sizeof(SampleHeader) + len);
-
- if (aSample) {
- uint8_t value;
- uint8_t *p;
- size_t i;
-
- sampP = *aSample;
- sampP->resId = resId;
- sampP->refCount = 0;
- sampP->flags = 0;
- sampP->len = len;
- sampP->loopStart = ir->loopStart;
- sampP->loopEnd = ir->loopEnd;
- sampP->loopCount = ir->loopCount;
- sampP->nextSample = sampleList;
-
- if (ir->versNum < 2) {
- sampP->baseRate = FIX1;
- } else {
- sampP->baseRate = ir->baseRate;
- }
-
- sampleList = aSample;
-
- HLock((Handle)aSample);
- p = sizeof(SampleHeader) + (unsigned char *)sampP;
- itsCompressor->Uncompress(soundData, (Ptr)p);
- HUnlock((Handle)aSample);
-
- value = 128 >> (8 - BITSPERSAMPLE);
- for (i = 0; i < len; i++) {
- value += *p;
- *p++ = value & (0xFF >> (8 - BITSPERSAMPLE));
- }
- }
-
- ReleaseResource(compressedData);
- }
- }
-
- return aSample;
-}
-
-void DisposeSamples() {
- SampleHeaderHandle aSample, nextSample, *prevP;
-
- prevP = &sampleList;
-
- aSample = sampleList;
- while (aSample) {
- nextSample = (*aSample)->nextSample;
- GetHandleSize((Handle)aSample);
- DisposeHandle((Handle)aSample);
- *prevP = nextSample;
- aSample = nextSample;
- }
-}
-
-int main(int argc, char *argv[]) {
- if (argc < 3) {
- printf("Usage: hsnd2wav [hsnd_num] [outfile] [rsrc]\n");
- return 1;
- }
-
- if (argc > 3) {
- SDL_Log("UseResFile: %s", argv[3]);
- UseResFile(argv[3]);
- }
-
- char *file_name = argv[2];
-
- InitMatrix();
- itsCompressor->Open();
-
- int resId = std::stoi(argv[1]);
- SampleHeaderHandle header = LoadSampleLegacy(resId);
-
- if (header) {
- SampleHeaderPtr sp = *header;
- int len = sp->len;
- unsigned char *p = sizeof(SampleHeader) + (unsigned char *)sp;
-
- AudioFile audioFile;
- audioFile.setSampleRate(ToFloat(sp->baseRate) * 22254.54545);
- audioFile.setAudioBufferSize(1, len); // 1 channel, num samples
- for (int i = 0; i < len; i++) {
- // Avara samples were 7-bit (0-127), introduce some range for The Tools.
- audioFile.samples[0][i] = p[i] * 2;
- }
- SDL_Log("Saving %s", file_name);
- audioFile.printSummary();
- audioFile.save(file_name);
- } else {
- SDL_Log("HSND resource not found");
- }
-
- itsCompressor->Dispose();
- DisposeSamples();
-
- return 0;
-}
diff --git a/src/level/Parser.cpp b/src/level/Parser.cpp
index 122b851a..5322d70b 100644
--- a/src/level/Parser.cpp
+++ b/src/level/Parser.cpp
@@ -1106,10 +1106,11 @@ const std::optional ReadColorVar(const char *s) {
return ReadColorVar(IndexForEntry(s));
}
-const Fixed ReadFixedMaterialVar(short index) {
+Fixed ReadFixedMaterialVar(short index) {
return ToFixed(EvalVariable(index + firstVariable, true)); // eager evaluation!
}
-const Fixed ReadFixedMaterialVar(const char *s) {
+
+Fixed ReadFixedMaterialVar(const char *s) {
return ReadFixedMaterialVar(IndexForEntry(s));
}
diff --git a/src/level/Parser.h b/src/level/Parser.h
index 8fa0ae92..a42a04a0 100644
--- a/src/level/Parser.h
+++ b/src/level/Parser.h
@@ -125,8 +125,8 @@ short ReadShortVar(short index);
short ReadShortVar(const char *s);
const std::optional ReadColorVar(short index);
const std::optional ReadColorVar(const char *);
-const Fixed ReadFixedMaterialVar(short index);
-const Fixed ReadFixedMaterialVar(const char *s);
+Fixed ReadFixedMaterialVar(short index);
+Fixed ReadFixedMaterialVar(const char *s);
std::string ReadStringVar(short index);
std::string ReadStringVar(const char *);
diff --git a/src/net/CCommManager.cpp b/src/net/CCommManager.cpp
index 65caa623..d3a8dcbf 100644
--- a/src/net/CCommManager.cpp
+++ b/src/net/CCommManager.cpp
@@ -19,22 +19,17 @@
** Initialize the packet buffer queues and allocate space
** for buffers.
*/
-void CCommManager::ICommManager(short packetSpace) {
- // base class creates PacketInfo buffers/queues
- InitializePacketQueues(packetSpace, sizeof(PacketInfo));
-}
-
-void CCommManager::InitializePacketQueues(int numPackets, std::size_t pSize) {
+CCommManager::CCommManager(short packetSpace, size_t pSize) {
packetSize = pSize;
- myId = 0; // Default to server.
+ myId = 0; // Default to server.
InitQueue(&freeQ);
InitQueue(&inQ);
-
+
firstReceivers[0] = NULL;
firstReceivers[1] = NULL;
- AllocatePacketBuffers(numPackets);
+ AllocatePacketBuffers(packetSpace);
}
void CCommManager::AllocatePacketBuffers(int numPackets) {
@@ -49,12 +44,6 @@ void CCommManager::AllocatePacketBuffers(int numPackets) {
}
}
-/*
-** Release allocated packet buffer storage and then dispose of self.
-*/
-void CCommManager::Dispose() {
-}
-
/*
** Move parameters to a new packet buffer and use WriteAndSignPacket method to
** send the packet.
diff --git a/src/net/CCommManager.h b/src/net/CCommManager.h
index feb5421c..c8fa1fb5 100644
--- a/src/net/CCommManager.h
+++ b/src/net/CCommManager.h
@@ -8,7 +8,6 @@
*/
#pragma once
-#include "CDirectObject.h"
#include "Memory.h"
#include
#include
@@ -53,7 +52,7 @@ typedef struct ReceiverRecord ReceiverRecord;
** functionality.
*/
-class CCommManager : public CDirectObject {
+class CCommManager {
public:
short myId; // Required/accessed publicly
@@ -69,18 +68,19 @@ class CCommManager : public CDirectObject {
RolloverCounter totalPacketsSent = 0;
// For method documentation, see .c-file:
- ~CCommManager() { Dispose(); }
- virtual void ICommManager(short packetSpace);
+ CCommManager() : CCommManager(MINIMUMBUFFERRESERVE, sizeof(PacketInfo)) {}
+ CCommManager(short packetSpace, size_t pSize);
+ virtual ~CCommManager() {}
+
+ virtual void Finalize() {}
- void InitializePacketQueues(int numPackets, size_t packetSize);
void AllocatePacketBuffers(int numPackets);
virtual void AddReceiver(ReceiverRecord *aReceiver, Boolean delayed);
virtual void RemoveReceiver(ReceiverRecord *aReceiver, Boolean delayed);
virtual OSErr SendPacket(short distribution, int8_t command, int8_t p1, int16_t p2, int32_t p3, int16_t dataLen, Ptr dataPtr, int16_t flags = 0);
virtual OSErr SendUrgentPacket(short distribution, int8_t command, int8_t p1, int16_t p2, int32_t p3, int16_t dataLen, Ptr dataPtr);
- virtual void Dispose();
virtual PacketInfo *GetPacket();
virtual PacketInfo *DuplicatePacket(PacketInfo *original);
diff --git a/src/net/CProtoControl.cpp b/src/net/CProtoControl.cpp
index 0cda6232..cd43178c 100644
--- a/src/net/CProtoControl.cpp
+++ b/src/net/CProtoControl.cpp
@@ -40,7 +40,7 @@ static Boolean DelayedProtoHandler(PacketInfo *thePacket, Ptr userData) {
return theControl->DelayedPacketHandler(thePacket);
}
-void CProtoControl::IProtoControl(CCommManager *aManager, CAvaraGame *aGame) {
+CProtoControl::CProtoControl(CCommManager *aManager, CAvaraGame *aGame) {
theGame = aGame;
immedReceiverRecord.handler = ImmedProtoHandler;
@@ -264,7 +264,3 @@ void CProtoControl::Detach() {
itsManager = NULL;
}
}
-
-void CProtoControl::Dispose() {
- CDirectObject::Dispose();
-}
diff --git a/src/net/CProtoControl.h b/src/net/CProtoControl.h
index b2c2a6a5..14a60833 100644
--- a/src/net/CProtoControl.h
+++ b/src/net/CProtoControl.h
@@ -9,19 +9,19 @@
#pragma once
#include "CCommManager.h"
-#include "CDirectObject.h"
-class CProtoControl : public CDirectObject {
+class CProtoControl {
public:
CCommManager *itsManager;
class CAvaraGame *theGame;
ReceiverRecord immedReceiverRecord;
ReceiverRecord delayedReceiverRecord;
- virtual void IProtoControl(CCommManager *aManager, CAvaraGame *aGame);
+ CProtoControl(CCommManager *aManager, CAvaraGame *aGame);
+ virtual ~CProtoControl() {}
+
virtual Boolean PacketHandler(PacketInfo *thePacket);
virtual Boolean DelayedPacketHandler(PacketInfo *thePacket);
- virtual void Dispose();
virtual void Attach(CCommManager *aManager);
virtual void Detach();
diff --git a/src/net/CUDPComm.cpp b/src/net/CUDPComm.cpp
index 4ab7069e..2b46257f 100755
--- a/src/net/CUDPComm.cpp
+++ b/src/net/CUDPComm.cpp
@@ -1257,10 +1257,8 @@ ClockTick CUDPComm::GetClock() {
** more urgent data. If not, any data marked urgent will be resent even if there
** no other data to send within twice that period.
*/
-void CUDPComm::IUDPComm(short clientCount, short bufferCount, uint16_t version, ClockTick urgentTimePeriod) {
- // create queues big enough to hold UDPPacketInfo packets
- InitializePacketQueues(bufferCount, sizeof(UDPPacketInfo));
-
+CUDPComm::CUDPComm(short clientCount, short bufferCount, uint16_t version, ClockTick urgentTimePeriod) : CCommManager(bufferCount, sizeof(UDPPacketInfo))
+{
inviteString[0] = 0;
softwareVersion = version;
@@ -1273,11 +1271,6 @@ void CUDPComm::IUDPComm(short clientCount, short bufferCount, uint16_t version,
// latencyConvert = urgentTimePeriod * 2; // no longer being used
- /*
- prefs = new CTagBase;
- prefs->ITagBase();
- prefs->ConvertFromHandle(gApplication->prefsBase->ReadHandle(kUDPCommPrefsTag));
- */
retransmitToRoundTripRatio = 192 + (gApplication->Number(kUDPResendPrefTag) << 5);
isConnected = false;
@@ -1295,22 +1288,13 @@ void CUDPComm::IUDPComm(short clientCount, short bufferCount, uint16_t version,
maxClients = clientCount;
while (clientCount--) {
- CUDPConnection *newConn;
-
- newConn = new CUDPConnection;
- newConn->IUDPConnection(this);
+ CUDPConnection *newConn = new CUDPConnection(this);
newConn->next = connections;
connections = newConn;
}
nextSender = connections;
- /*
- writeComplete = NewUDPIOCompletionProc(UDPWriteComplete);
- readComplete = NewUDPIOCompletionProc(UDPReadComplete);
- bufferReturnComplete = NewUDPIOCompletionProc(UDPBufferReturnComplete);
- */
-
receiverRecord.handler = ImmedProtoHandler;
receiverRecord.userData = (Ptr)this;
AddReceiver(&receiverRecord, kUDPProtoHandlerIsAsync);
@@ -1341,6 +1325,32 @@ void CUDPComm::IUDPComm(short clientCount, short bufferCount, uint16_t version,
password[0] = 0;
}
+CUDPComm::~CUDPComm() {
+ CUDPConnection *nextConn;
+
+ Finalize();
+
+ while (connections) {
+ nextConn = connections->next;
+
+ delete connections;
+ connections = nextConn;
+ }
+}
+
+void CUDPComm::Finalize() {
+ if (isConnected && !isClosed) {
+ if (myId == 0)
+ SendPacket(kdEveryone, kpPacketProtocolLogout, 0, 0, 0, 0, 0);
+ else
+ SendPacket(kdServerOnly, kpPacketProtocolLogout, myId, 0, 0, 0, 0);
+
+ Disconnect();
+ }
+
+ RemoveReceiver(&receiverRecord, kUDPProtoHandlerIsAsync);
+}
+
void CUDPComm::Disconnect() {
long startTicks;
long delta;
@@ -1383,30 +1393,6 @@ void CUDPComm::Disconnect() {
isClosed = true;
}
-void CUDPComm::Dispose() {
- CUDPConnection *nextConn;
-
- if (isConnected && !isClosed) {
- if (myId == 0)
- SendPacket(kdEveryone, kpPacketProtocolLogout, 0, 0, 0, 0, 0);
- else
- SendPacket(kdServerOnly, kpPacketProtocolLogout, myId, 0, 0, 0, 0);
-
- Disconnect();
- }
-
- RemoveReceiver(&receiverRecord, kUDPProtoHandlerIsAsync);
-
- while (connections) {
- nextConn = connections->next;
-
- connections->Dispose();
- connections = nextConn;
- }
-
- CCommManager::Dispose();
-}
-
void CUDPComm::CreateServer() {
localPort = gApplication->Number(kDefaultUDPPort);
diff --git a/src/net/CUDPComm.h b/src/net/CUDPComm.h
index 669493c8..d4db562d 100644
--- a/src/net/CUDPComm.h
+++ b/src/net/CUDPComm.h
@@ -44,12 +44,8 @@ class CUDPComm : public CCommManager {
// OSErr writeErr;
// OSErr readErr;
- // class CTagBase *prefs;
class CUDPConnection *connections;
class CUDPConnection *nextSender;
- /*
- class CTracker *tracker;
- */
long retransmitToRoundTripRatio; // In fixed point 24.8 format
@@ -62,8 +58,6 @@ class CUDPComm : public CCommManager {
ip_addr localIP; // Just a guess, but that's all we need for the tracker.
port_num localPort;
int stream;
- // char streamBuffer[UDPSTREAMBUFFERSIZE];
- // char sendBuffer[UDPSENDBUFFERSIZE];
short cramData;
@@ -76,17 +70,14 @@ class CUDPComm : public CCommManager {
Boolean turboMode;
long turboCount;
- // Boolean readIsComplete;
- // Boolean writeIsComplete;
- // Boolean blockReadComplete;
- // Boolean blockWriteComplete;
Boolean specialWakeup;
Str255 inviteString;
- virtual void IUDPComm(short clientCount, short bufferCount, uint16_t version, ClockTick urgentTimePeriod);
+ CUDPComm(short clientCount, short bufferCount, uint16_t version, ClockTick urgentTimePeriod);
+ virtual ~CUDPComm();
+ virtual void Finalize();
virtual void Disconnect();
- virtual void Dispose();
ClockTick GetClock();
diff --git a/src/net/CUDPConnection.cpp b/src/net/CUDPConnection.cpp
index 742ee36d..efdc6ddf 100644
--- a/src/net/CUDPConnection.cpp
+++ b/src/net/CUDPConnection.cpp
@@ -56,7 +56,7 @@ void CUDPConnection::DebugPacket(char eType, UDPPacketInfo *p) {
}
#endif
-void CUDPConnection::IUDPConnection(CUDPComm *theOwner) {
+CUDPConnection::CUDPConnection(CUDPComm *theOwner) {
short i;
killed = false;
@@ -111,6 +111,11 @@ void CUDPConnection::IUDPConnection(CUDPComm *theOwner) {
recentResendRate = 0;
}
+CUDPConnection::~CUDPConnection() {
+ FlushQueues();
+ delete latencyHistogram;
+}
+
void CUDPConnection::FlushQueues() {
QElemPtr elem;
QHdr *head;
@@ -586,12 +591,6 @@ void CUDPConnection::ResendNonValidatedPackets() {
}
}
-void CUDPConnection::Dispose() {
- FlushQueues();
- delete latencyHistogram;
- CDirectObject::Dispose();
-}
-
static short receiveSerialStorage[512];
size_t CUDPConnection::ReceivedPacket(UDPPacketInfo *thePacket) {
diff --git a/src/net/CUDPConnection.h b/src/net/CUDPConnection.h
index 8f3abad6..ca60dc98 100644
--- a/src/net/CUDPConnection.h
+++ b/src/net/CUDPConnection.h
@@ -9,7 +9,6 @@
#pragma once
#include "CCommManager.h"
-#include "CDirectObject.h"
#include "CommDefs.h"
#include "RolloverCounter.h"
#include "SlidingHistogram.h"
@@ -57,7 +56,7 @@ typedef struct {
enum { kReceiveQ, kTransmitQ, kBusyQ, kQueueCount };
-class CUDPConnection : public CDirectObject {
+class CUDPConnection {
public:
class CUDPConnection *next;
class CUDPComm *itsOwner;
@@ -113,7 +112,9 @@ class CUDPConnection : public CDirectObject {
Boolean killed;
- virtual void IUDPConnection(CUDPComm *theMaster);
+ CUDPConnection(CUDPComm *theMaster);
+ virtual ~CUDPConnection();
+
virtual void SendQueuePacket(UDPPacketInfo *thePacket, short theDistribution);
virtual void RoutePacket(UDPPacketInfo *thePacket);
virtual UDPPacketInfo *GetOutPacket(int32_t curTime, int32_t cramTime, int32_t urgencyAdjust);
@@ -132,7 +133,6 @@ class CUDPConnection : public CDirectObject {
virtual bool ReceiveQueuedPackets();
virtual void FlushQueues();
- virtual void Dispose();
virtual void MarkOpenConnections(CompleteAddress *table);
virtual void RewriteConnections(CompleteAddress *table, const CompleteAddress &myAddressInTOC);
diff --git a/src/tests.cpp b/src/tests.cpp
index cedde7fa..cee147ef 100644
--- a/src/tests.cpp
+++ b/src/tests.cpp
@@ -31,6 +31,8 @@ using namespace std;
class TestSoundHub : public CSoundHubImpl {
public:
+ TestSoundHub(short numOfEachKind, short initialLinks) : CSoundHubImpl(numOfEachKind,
+ initialLinks) {}
virtual Fixed* EarLocation() { return ear; }
virtual bool AudioEnabled() { return false; }
private:
@@ -132,6 +134,8 @@ class TestPlayerManager : public CPlayerManager {
class TestNetManager : public CNetManager {
public:
+ TestNetManager(CAvaraGame *theGame) : CNetManager(theGame) {}
+
std::shared_ptr CreatePlayerManager(short id) {
return std::make_shared(itsGame);
}
@@ -188,8 +192,8 @@ class TestApp : public CAvaraApp {
class TestGame : public CAvaraGame {
public:
TestGame(int frameTime) : CAvaraGame(frameTime) {}
- virtual std::unique_ptr CreateNetManager() { return std::make_unique(); }
- virtual CSoundHub* CreateSoundHub() { TestSoundHub *t = new TestSoundHub(); t->ISoundHub(64,64); return t;}
+ virtual std::unique_ptr CreateNetManager() { return std::make_unique(this); }
+ virtual CSoundHub* CreateSoundHub() { return new TestSoundHub(64,64); }
bool GameTick() {
// force tick to happen by resetting nextScheduledFrame
nextScheduledFrame = 0;
@@ -1169,11 +1173,13 @@ TEST(SERIAL_NUMBER, Rollover) {
UDPPacketInfo packet1, packet2;
test_rollover("UDPPacketInfo::serialNumber", packet1, packet2, &UDPPacketInfo::serialNumber);
- CUDPConnection conn1, conn2;
+ /* TODO: CUDPConnection relies on having gCurrentGame set up
+ CUDPConnection conn1(nullptr), conn2(nullptr);
test_rollover("CUDPConnection::serialNumber", conn1, conn2, &CUDPConnection::serialNumber);
test_rollover("CUDPConnection::receiveSerial", conn1, conn2, &CUDPConnection::receiveSerial);
test_rollover("CUDPConnection::maxValid", conn1, conn2, &CUDPConnection::maxValid);
test_rollover("CUDPConnection::ackBase", conn1, conn2, &CUDPConnection::ackBase);
+ */
}
TEST(MATERIALS, Manipulation) {
diff --git a/src/tui/TextCommand.cpp b/src/tui/TextCommand.cpp
index def3def2..4b7cce01 100644
--- a/src/tui/TextCommand.cpp
+++ b/src/tui/TextCommand.cpp
@@ -67,7 +67,7 @@ bool TextCommand::FindMatchingCommands(std::string& fullText,
return success;
}
-const bool TextCommand::ExecuteMatchingCallbacks(std::string& fullCommand) {
+bool TextCommand::ExecuteMatchingCallbacks(std::string& fullCommand) {
return FindMatchingCommands(fullCommand,
[](TextCommand* command, std::string& cmd, VectorOfArgs vargs) -> bool {
diff --git a/src/tui/TextCommand.h b/src/tui/TextCommand.h
index e707c7cb..94874b73 100644
--- a/src/tui/TextCommand.h
+++ b/src/tui/TextCommand.h
@@ -38,7 +38,7 @@ class TextCommand {
static void Register(TextCommand* command);
static bool FindMatchingCommands(std::string& fullCommand,
std::function matchCb);
- static const bool ExecuteMatchingCallbacks(std::string& fullCommand);
+ static bool ExecuteMatchingCallbacks(std::string& fullCommand);
static const std::string ListOfCommands(std::string delimeter = ", ");
static std::string UsageForCommand(std::string& fullCommand);
diff --git a/src/util/huffman/CAbstractHuffPipe.cpp b/src/util/huffman/CAbstractHuffPipe.cpp
deleted file mode 100644
index 8e028e59..00000000
--- a/src/util/huffman/CAbstractHuffPipe.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "CAbstractHuffPipe.h"
-
-/**
- Initialize counters for each symbol (ASCII chars).
- Initialize data counter to 0.
- */
-OSErr CAbstractHuffPipe::Open() {
- short i;
- for (i = 0; i < NUMSYMBOLS; i++) {
- symbCounters[i] = 1;
- }
- dataCount = 0;
- return CAbstractPipe::Open();
-}
-
-/**
- Shell sorts the first NUMSYMBOLS nodes.
- */
-void CAbstractHuffPipe::SortNodes(HuffTreeNode **table) {
- short h;
- HuffTreeNode **ip, **jp, *vp;
- HuffTreeNode **lastP;
- HuffTreeNode **hp;
-
- h = 1;
- lastP = table + NUMSYMBOLS;
-
- do {
- h += h + h + 1;
- } while (h <= NUMSYMBOLS);
-
- do {
- h /= 3;
- hp = table + h;
- for (ip = hp; ip < lastP; ip++) {
- vp = *ip;
- jp = ip;
- while (jp[-h]->count > vp->count) {
- *jp = jp[-h];
- jp -= h;
- if (jp < hp) {
- break;
- }
- }
- *jp = vp;
- }
- } while (h != 1);
-}
-
-/**
- Builds a Huffman tree using the given symbol distribution.
- The root node of the tree is returned.
- */
-HuffTreeNode *CAbstractHuffPipe::BuildTree() {
- HuffTreeNode *subTrees[NUMSYMBOLS + 1];
- HuffTreeNode **treeList;
- HuffTreeNode *freshNode;
- HuffTreeNode markerNode;
- short i;
-
- // Place symbols into the first NUMSYMBOLS places in the tree array.
- for (i = 0; i < NUMSYMBOLS; i++) {
- nodes[i].count = symbCounters[i];
- nodes[i].left = -1;
- nodes[i].right = i;
- }
-
- // Put pointers to the tree array into the subTrees array.
- for (i = 0; i < NUMSYMBOLS; i++) {
- subTrees[i] = &(nodes[i]);
- }
-
- // Sort pointers in the subTree array so that the symbol with the lowest count is first, etc.
- SortNodes(subTrees);
-
- // freshNode points to a free tree node:
- freshNode = &(nodes[NUMSYMBOLS]);
-
- // Pointer to current list of subtrees:
- treeList = subTrees;
-
- // Create a marker node to stop insertion sorts:
- markerNode.count = dataCount + NUMSYMBOLS + 1;
- subTrees[NUMSYMBOLS] = &markerNode;
-
- i = 1;
- while ((*treeList)->count == 0) {
- i++;
- treeList++;
- }
-
- // Reduce tree into a root node. Requires NUMSYMBOLS-1 steps:
- for (; i < NUMSYMBOLS; i++) {
- HuffTreeNode *aNode, *bNode;
- HuffTreeNode **sorter;
- int count;
-
- // Combine the two subtrees with the lowest counts:
- aNode = treeList[0];
- bNode = treeList[1];
- treeList++;
-
- count = aNode->count + bNode->count;
-
- freshNode->count = count;
- freshNode->left = aNode - nodes;
- freshNode->right = bNode - nodes;
-
- // Sort the new subtree into the list of subtrees:
- sorter = treeList + 1;
-
- // >= is used to keep order in the equal distribution case. > could be used as well.
- while (count >= (*sorter)->count) {
- sorter[-1] = sorter[0];
- sorter++;
- }
-
- sorter[-1] = freshNode;
-
- freshNode++;
- }
-
- return treeList[0];
-}
-
-/**
- This abstract class doesn't pass any data forward. This method was used to test the tree
- creation code.
- */
-OSErr CAbstractHuffPipe::PipeData(Ptr dataPtr, long len) {
- dataCount += len;
- while (len--) {
- symbCounters[*(unsigned char *)(dataPtr++)]++;
- }
- return noErr;
-}
diff --git a/src/util/huffman/CAbstractHuffPipe.h b/src/util/huffman/CAbstractHuffPipe.h
deleted file mode 100644
index 8fd30091..00000000
--- a/src/util/huffman/CAbstractHuffPipe.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-#include "CAbstractPipe.h"
-
-// Number of symbols in the compressed data. Don't change this unless you know what you are doing.
-#define NUMSYMBOLS 256
-
-// Defines a condition for when the tree should change.
-#define CHANGEOFPATTERNS (dataCount == 256 || (dataCount & 2047) == 0)
-
-typedef struct {
- int count;
- short left; // If negative, this is a leaf node and right is the value.
- short right;
-} HuffTreeNode;
-
-class CAbstractHuffPipe : public CAbstractPipe {
-public:
- int dataCount;
- int symbCounters[NUMSYMBOLS];
- HuffTreeNode nodes[NUMSYMBOLS * 2 - 1];
-
- CAbstractHuffPipe() {}
- virtual ~CAbstractHuffPipe() {}
-
- virtual OSErr Open();
- virtual void SortNodes(HuffTreeNode **table);
- virtual HuffTreeNode *BuildTree();
- virtual OSErr PipeData(Ptr dataPtr, long len);
-};
diff --git a/src/util/huffman/CAbstractPipe.cpp b/src/util/huffman/CAbstractPipe.cpp
deleted file mode 100644
index e9e774ac..00000000
--- a/src/util/huffman/CAbstractPipe.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "CAbstractPipe.h"
-
-/**
- Open a null pipe that does nothing. Basically a /dev/null kind of device.
- */
-OSErr CAbstractPipe::Open() {
- outputStream = NULL;
- return noErr;
-}
-
-/**
- Set the next pipe in chain.
- */
-OSErr CAbstractPipe::PipeTo(CAbstractPipe *output) {
- outputStream = output;
- return noErr;
-}
-
-/**
- In essence, this is the Write command for a pipe. Whatever is written with this command is
- processed and then output to the output pipe, if there is one or the use of one is allowed.
- */
-OSErr CAbstractPipe::PipeData(Ptr dataPtr, long len) {
- if (outputStream) {
- return outputStream->PipeData(dataPtr, len);
- } else {
- return noErr;
- }
-}
-
-/**
- Closes the pipe. Subclasses can flush any data they have buffered and then close their output
- pipe. It's probably not a good idea to close the output pipe at this point, since the user might
- want to use it for more data. Maybe a separate flush command and then a close could be in order?
- */
-OSErr CAbstractPipe::Close() {
- if (outputStream) {
- return outputStream->Close();
- } else {
- return noErr;
- }
-}
diff --git a/src/util/huffman/CAbstractPipe.h b/src/util/huffman/CAbstractPipe.h
deleted file mode 100644
index a4fe7832..00000000
--- a/src/util/huffman/CAbstractPipe.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include "Types.h"
-
-class CAbstractPipe {
-public:
- class CAbstractPipe *outputStream;
-
- CAbstractPipe() {}
- virtual ~CAbstractPipe() {}
-
- // In general, pipe methods are used in this order:
- virtual OSErr Open();
- virtual OSErr PipeTo(CAbstractPipe *output);
- virtual OSErr PipeData(Ptr dataPtr, long len);
- virtual OSErr Close();
-};
diff --git a/src/util/huffman/CHuffProcessor.cpp b/src/util/huffman/CHuffProcessor.cpp
deleted file mode 100644
index 13a4912e..00000000
--- a/src/util/huffman/CHuffProcessor.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-#include "CHuffProcessor.h"
-
-#ifndef INTEL_ARCH
-#define MEM_LONG(val) val
-#define MEM_SHORT(val) val
-#else
-#define MEM_LONG(val) ((val << 24) | ((val << 8) & 0xFF0000) | ((val >> 8) & 0xFF00) | ((val >> 24) & 0xFF))
-#define MEM_SHORT(val) (short)((val << 8) | ((val >> 8) & 0xFF))
-#endif
-
-/**
- Decoding the data is a bit more complicated than writing it, since we have to walk the tree to
- find what maps to what. We can, however, take a shortcut by reading HUFFHANDLELOOKUPBITS bits at
- a time. If the code we reach is shorter than this, all we need to do is back up a few bits. If
- we did not reach a leaf node with the lookup, we continue bit by bit until we reach a leaf.
-
- This routine creates the lookup table for HUFFHANDLELOOKUPBITS bits and it creates a table of
- lengths so that we can find out how many bits were needed for the last char.
-
- Recursion has been eliminated with a stack and the routine is a modified version of the one used
- to create the tables in the encoder object.
-
- The routine goes through the patterns in order starting with 000... and ending at 111...
- Because of this, the "holes" in the lookup table can be filled as we go. The last pointer
- written to the table has to be replicated until the end of the table.
-
- If BuildTree returns a leaf node, then the tree can only have one symbol in it and using huffman
- compression doesn't make any sense (since the code consists of only one repeated symbol).
- */
-void CHuffProcessor::CreateLookupBuffer() {
- short lastLookup;
- short walkerStack[33];
- short *stackPtr, *endPtr;
- short codeLen = 1;
- int codeString = 0;
- HuffTreeNode *theNode;
- HuffTreeNode *lastNode;
-
- theNode = BuildTree();
-
- singleSymbolData = (theNode->left < 0);
- theSingleSymbol = theNode->right;
-
- // Must be branch node.
- if (!singleSymbolData) {
- stackPtr = walkerStack + 1;
- endPtr = walkerStack + 32;
- *stackPtr++ = theNode->right;
- theNode = &nodes[theNode->left];
- lastLookup = 0;
-
- do {
- if (codeLen == HUFFHANDLELOOKUPBITS || (theNode->left < 0 && codeLen < HUFFHANDLELOOKUPBITS)) {
- int codeIndex;
- codeIndex = codeString << (HUFFHANDLELOOKUPBITS - codeLen);
- lastNode = lookupBuf[lastLookup];
- while (lastLookup < codeIndex) {
- lookupBuf[lastLookup++] = lastNode;
- }
- lookupBuf[codeIndex] = theNode;
- }
-
- if (theNode->left < 0) {
- codeLengths[theNode->right] = codeLen;
- theNode = &nodes[*--stackPtr];
- while (codeString & 1) {
- codeLen--;
- codeString >>= 1;
- };
- codeString |= 1;
- } else {
- *stackPtr++ = theNode->right;
- theNode = &nodes[theNode->left];
- codeLen++;
- codeString += codeString;
- }
- } while (stackPtr <= endPtr && stackPtr != walkerStack);
-
- lastNode = lookupBuf[lastLookup];
- while (lastLookup < HUFFHANDLELOOKUPSIZE) {
- lookupBuf[lastLookup++] = lastNode;
- }
- }
-}
-
-/**
- Create a mapping from characters to bit patterns. Lengths are stored in a different array. Bit
- patterns may be up to 24 bits int (the limitation comes from the output code).
-
- A stack is used to eliminate recursion while walking the tree.
-
- If BuildTree returns a leaf node, then the tree can only have one symbol in it and using huffman
- compression doesn't make any sense (since the code consists of only one repeated symbol).
- */
-void CHuffProcessor::CreateSymbolTable() {
- short walkerStack[33];
- short *stackPtr;
- short codeLen = 1;
- int codeString = 0;
- HuffTreeNode *theNode;
-
- theNode = BuildTree();
-
- singleSymbolData = (theNode->left < 0);
-
- // Must be branch node.
- if (!singleSymbolData) {
- stackPtr = walkerStack + 1;
- *stackPtr++ = theNode->right;
- theNode = &nodes[theNode->left];
-
- do {
- if (theNode->left < 0) {
- codeStrings[theNode->right] = codeString;
- codeLengths[theNode->right] = codeLen;
- theNode = &nodes[*--stackPtr];
- while (codeString & 1) {
- codeLen--;
- codeString >>= 1;
- };
- codeString |= 1;
- } else {
- *stackPtr++ = theNode->right;
- theNode = &nodes[theNode->left];
- codeLen++;
- codeString += codeString;
- }
- } while (stackPtr != walkerStack);
- }
-}
-
-void CHuffProcessor::DecodeAll(unsigned char *source, unsigned char *dest) {
- int i;
- int bitData;
- int *bitPointer;
- int bitPosition = 0;
- HuffTreeNode *theNode;
- short theCode;
-
- i = dataCount;
- while (i--) {
- // Read in some bits into bitData.
- bitPointer = (int *)(source + (bitPosition >> 3));
-#ifdef INTEL_ARCH
- {
- unsigned char *charPointer = (unsigned char *)bitPointer;
-
- bitData = (((unsigned int)charPointer[0] << 24) | ((unsigned int)charPointer[1] << 16) |
- ((unsigned int)charPointer[2] << 8) | (unsigned int)charPointer[3])
- << (bitPosition & 7);
- }
-#else
- bitData = (*bitPointer) << (bitPosition & 7);
-#endif
-
- // Use the lookup table to see what these bits decode to:
- theNode = lookupBuf[(bitData >> (32 - HUFFHANDLELOOKUPBITS)) & (HUFFHANDLELOOKUPSIZE - 1)];
-
- // If we didn't reach a leaf node, proceed bit by bit.
- if (theNode->left >= 0) {
- int mask = 1L << (31 - HUFFHANDLELOOKUPBITS);
-
- // Decode one bit at a time and walk the tree.
- do {
- if (mask & bitData) {
- theNode = nodes + theNode->right;
- } else {
- theNode = nodes + theNode->left;
- }
- mask >>= 1;
- } while (theNode->left >= 0);
- }
-
- // Move the decoded symbol to theCode
- theCode = theNode->right;
- *dest++ = theCode;
-
- // Mark n bits as read.
- bitPosition += codeLengths[theCode];
- }
-}
-
-int CHuffProcessor::GetUncompressedLen(Ptr compressedData) {
- HuffDataHeader *inHeader;
- inHeader = (HuffDataHeader *)compressedData;
- dataCount = MEM_LONG(inHeader->decodedSize);
- return dataCount;
-}
-
-void CHuffProcessor::Uncompress(Ptr fromPtr, Ptr destPtr) {
- HuffDataHeader *inHeader;
- unsigned int *freqCounts;
- unsigned short *freqCountsShort;
- short i, j, k;
- HuffTreeNode *lookupMem[HUFFHANDLELOOKUPSIZE];
-
- lookupBuf = lookupMem;
- inHeader = (HuffDataHeader *)fromPtr;
- dataCount = MEM_LONG(inHeader->decodedSize);
- outPointer = destPtr;
-
- if (destPtr && dataCount) {
- freqCounts = (unsigned int *)(sizeof(HuffDataHeader) + fromPtr);
-
- k = 0;
-
- freqCountsShort = (unsigned short *)freqCounts;
-
- for (i = 0; i < (NUMSYMBOLS >> 5); i++) {
- int flags;
- flags = MEM_LONG(inHeader->countBitmap[i]);
-
- for (j = 0; j < 32; j++) {
- if (dataCount > 65535) {
- int temp = (flags < 0) ? *freqCounts++ : 0;
- symbCounters[k++] = MEM_LONG(temp);
- } else {
- short temp = (flags < 0) ? *freqCountsShort++ : 0;
- symbCounters[k++] = MEM_SHORT(temp);
- }
- flags += flags;
- }
- }
-
- if (dataCount <= 65535) {
- freqCounts = (unsigned int *)freqCountsShort;
- }
-
- CreateLookupBuffer();
-
- if (singleSymbolData) {
- Ptr p = destPtr;
- while (dataCount--) {
- *p++ = theSingleSymbol;
- }
- } else {
- DecodeAll((unsigned char *)freqCounts, (unsigned char *)destPtr);
- }
- }
-}
-
-int CHuffProcessor::GetCompressedLen(Ptr sourceData, int sourceLen) {
- int outSize;
- int outputBits = 0;
- short countDataSize;
- short nonZero = 0;
- int i;
-
- dataCount = sourceLen;
-
- if (dataCount) {
- unsigned char *p;
- int *t;
- t = symbCounters;
- for (i = 0; i < NUMSYMBOLS; i++) {
- t[i] = 0;
- }
-
- i = sourceLen;
- p = (unsigned char *)sourceData;
- while (i--) {
- (t[*p++])++;
- }
-
- CreateSymbolTable();
-
- if (singleSymbolData) {
- outputBits = 0;
- nonZero = 1;
- } else {
- // Count how many bits are needed for output.
- for (i = 0; i < NUMSYMBOLS; i++) {
- if (symbCounters[i]) {
- nonZero++;
- outputBits += symbCounters[i] * codeLengths[i];
- }
- }
- }
-
- countDataSize = dataCount > 65535 ? sizeof(int) : sizeof(short);
- outCount = ((outputBits + 7) >> 3);
- outSize = nonZero * countDataSize + // Stored counts
- sizeof(HuffDataHeader) + // Header size
- outCount; // Number of encoded bytes
- } else {
- outSize = sizeof(int);
- outCount = 0;
- }
-
- return outSize;
-}
-
-void CHuffProcessor::Compress(Ptr fromPtr, Ptr destPtr) {
- short i, j, k;
- HuffDataHeader *outHeader;
-
- int count;
- int *zeroL;
- char *zeroC;
-
- zeroL = (int *)destPtr;
- count = outCount >> 2;
- while (count--) {
- *zeroL++ = 0;
- }
-
- zeroC = (char *)zeroL;
- count = outCount & 3;
- while (count--) {
- *zeroC++ = 0;
- }
-
- outHeader = (HuffDataHeader *)destPtr;
- outHeader->decodedSize = MEM_LONG(dataCount);
-
- if (dataCount) {
- unsigned char *inData, *endData;
- int outBits;
- int outLen;
- int bitOffset;
- unsigned int *countTable;
- unsigned short *countTableShort;
-
- k = 0;
- for (i = 0; i < (NUMSYMBOLS >> 5); i++) {
- int flags = 0;
- for (j = 0; j < 32; j++) {
- flags += flags;
- flags |= (symbCounters[k++] != 0);
- }
- outHeader->countBitmap[i] = MEM_LONG(flags);
- }
-
- if (dataCount > 65535) {
- countTable = (unsigned int *)(sizeof(HuffDataHeader) + destPtr);
- for (i = 0; i < NUMSYMBOLS; i++) {
- if (symbCounters[i]) {
- *countTable++ = MEM_LONG(symbCounters[i]);
- }
- }
- } else {
- countTableShort = (unsigned short *)(sizeof(HuffDataHeader) + destPtr);
- for (i = 0; i < NUMSYMBOLS; i++) {
- if (symbCounters[i]) {
- *countTableShort++ = MEM_SHORT(symbCounters[i]);
- }
- }
- countTable = (unsigned int *)countTableShort;
- }
-
- if (!singleSymbolData) {
- bitOffset = 0;
- inData = (unsigned char *)fromPtr;
- endData = inData + dataCount;
-
- while (inData < endData) {
- int *tempBitP;
-
- outBits = codeStrings[*inData];
- outLen = codeLengths[*inData++];
-
- tempBitP = (int *)((char *)countTable + (bitOffset >> 3));
-#ifdef INTEL_ARCH
- {
- unsigned char *destP = (unsigned char *)tempBitP;
- unsigned int orData;
-
- orData = outBits << (32 - ((bitOffset & 7) + outLen));
- *destP++ |= orData >> 24;
- *destP++ |= orData >> 16;
- *destP++ |= orData >> 8;
- *destP |= orData;
- }
-#else
- *tempBitP |= outBits << (32 - ((bitOffset & 7) + outLen));
-#endif
- bitOffset += outLen;
- }
- }
- }
-}
diff --git a/src/util/huffman/CHuffProcessor.h b/src/util/huffman/CHuffProcessor.h
deleted file mode 100644
index 9346cb73..00000000
--- a/src/util/huffman/CHuffProcessor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-#include "CAbstractHuffPipe.h"
-
-typedef struct {
- uint32_t decodedSize;
- uint32_t countBitmap[NUMSYMBOLS >> 5];
-} HuffDataHeader;
-
-#define HUFFHANDLELOOKUPBITS 10
-#define HUFFHANDLELOOKUPSIZE (1 << HUFFHANDLELOOKUPBITS)
-
-class CHuffProcessor : public CAbstractHuffPipe {
-public:
- Ptr outPointer;
- int outCount;
-
- HuffTreeNode **lookupBuf;
- Boolean singleSymbolData;
- unsigned char theSingleSymbol;
- int codeStrings[NUMSYMBOLS];
- short codeLengths[NUMSYMBOLS];
-
- CHuffProcessor() {}
- virtual ~CHuffProcessor() {}
-
- virtual void CreateLookupBuffer();
- virtual void CreateSymbolTable();
- virtual void DecodeAll(unsigned char *source, unsigned char *dest);
-
- virtual int GetUncompressedLen(Ptr compressedData);
- virtual int GetCompressedLen(Ptr sourceData, int sourceLen);
-
- virtual void Compress(Ptr fromPtr, Ptr destPtr);
- virtual void Uncompress(Ptr fromPtr, Ptr destPtr);
-};
diff --git a/vendor/AudioFile.h b/vendor/AudioFile.h
deleted file mode 100644
index 375f4b90..00000000
--- a/vendor/AudioFile.h
+++ /dev/null
@@ -1,1302 +0,0 @@
-//=======================================================================
-/** @file AudioFile.h
- * @author Adam Stark
- * @copyright Copyright (C) 2017 Adam Stark
- *
- * This file is part of the 'AudioFile' library
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-//=======================================================================
-
-#ifndef _AS_AudioFile_h
-#define _AS_AudioFile_h
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-// disable some warnings on Windows
-#if defined (_MSC_VER)
- __pragma(warning (push))
- __pragma(warning (disable : 4244))
- __pragma(warning (disable : 4457))
- __pragma(warning (disable : 4458))
- __pragma(warning (disable : 4389))
- __pragma(warning (disable : 4996))
-#elif defined (__GNUC__)
- _Pragma("GCC diagnostic push")
- _Pragma("GCC diagnostic ignored \"-Wconversion\"")
- _Pragma("GCC diagnostic ignored \"-Wsign-compare\"")
- _Pragma("GCC diagnostic ignored \"-Wshadow\"")
-#endif
-
-//=============================================================
-/** The different types of audio file, plus some other types to
- * indicate a failure to load a file, or that one hasn't been
- * loaded yet
- */
-enum class AudioFileFormat
-{
- Error,
- NotLoaded,
- Wave,
- Aiff
-};
-
-//=============================================================
-template
-class AudioFile
-{
-public:
-
- //=============================================================
- typedef std::vector > AudioBuffer;
-
- //=============================================================
- /** Constructor */
- AudioFile();
-
- /** Constructor, using a given file path to load a file */
- AudioFile (std::string filePath);
-
- //=============================================================
- /** Loads an audio file from a given file path.
- * @Returns true if the file was successfully loaded
- */
- bool load (std::string filePath);
-
- /** Saves an audio file to a given file path.
- * @Returns true if the file was successfully saved
- */
- bool save (std::string filePath, AudioFileFormat format = AudioFileFormat::Wave);
-
- //=============================================================
- /** @Returns the sample rate */
- uint32_t getSampleRate() const;
-
- /** @Returns the number of audio channels in the buffer */
- int getNumChannels() const;
-
- /** @Returns true if the audio file is mono */
- bool isMono() const;
-
- /** @Returns true if the audio file is stereo */
- bool isStereo() const;
-
- /** @Returns the bit depth of each sample */
- int getBitDepth() const;
-
- /** @Returns the number of samples per channel */
- int getNumSamplesPerChannel() const;
-
- /** @Returns the length in seconds of the audio file based on the number of samples and sample rate */
- double getLengthInSeconds() const;
-
- /** Prints a summary of the audio file to the console */
- void printSummary() const;
-
- //=============================================================
-
- /** Set the audio buffer for this AudioFile by copying samples from another buffer.
- * @Returns true if the buffer was copied successfully.
- */
- bool setAudioBuffer (AudioBuffer& newBuffer);
-
- /** Sets the audio buffer to a given number of channels and number of samples per channel. This will try to preserve
- * the existing audio, adding zeros to any new channels or new samples in a given channel.
- */
- void setAudioBufferSize (int numChannels, int numSamples);
-
- /** Sets the number of samples per channel in the audio buffer. This will try to preserve
- * the existing audio, adding zeros to new samples in a given channel if the number of samples is increased.
- */
- void setNumSamplesPerChannel (int numSamples);
-
- /** Sets the number of channels. New channels will have the correct number of samples and be initialised to zero */
- void setNumChannels (int numChannels);
-
- /** Sets the bit depth for the audio file. If you use the save() function, this bit depth rate will be used */
- void setBitDepth (int numBitsPerSample);
-
- /** Sets the sample rate for the audio file. If you use the save() function, this sample rate will be used */
- void setSampleRate (uint32_t newSampleRate);
-
- //=============================================================
- /** Sets whether the library should log error messages to the console. By default this is true */
- void shouldLogErrorsToConsole (bool logErrors);
-
- //=============================================================
- /** A vector of vectors holding the audio samples for the AudioFile. You can
- * access the samples by channel and then by sample index, i.e:
- *
- * samples[channel][sampleIndex]
- */
- AudioBuffer samples;
-
- //=============================================================
- /** An optional iXML chunk that can be added to the AudioFile.
- */
- std::string iXMLChunk;
-
-private:
-
- //=============================================================
- enum class Endianness
- {
- LittleEndian,
- BigEndian
- };
-
- //=============================================================
- AudioFileFormat determineAudioFileFormat (std::vector& fileData);
- bool decodeWaveFile (std::vector& fileData);
- bool decodeAiffFile (std::vector& fileData);
-
- //=============================================================
- bool saveToWaveFile (std::string filePath);
- bool saveToAiffFile (std::string filePath);
-
- //=============================================================
- void clearAudioBuffer();
-
- //=============================================================
- int32_t fourBytesToInt (std::vector& source, int startIndex, Endianness endianness = Endianness::LittleEndian);
- int16_t twoBytesToInt (std::vector& source, int startIndex, Endianness endianness = Endianness::LittleEndian);
- int getIndexOfString (std::vector& source, std::string s);
- int getIndexOfChunk (std::vector& source, const std::string& chunkHeaderID, int startIndex, Endianness endianness = Endianness::LittleEndian);
-
- //=============================================================
- T sixteenBitIntToSample (int16_t sample);
- int16_t sampleToSixteenBitInt (T sample);
-
- //=============================================================
- uint8_t sampleToSingleByte (T sample);
- T singleByteToSample (uint8_t sample);
-
- uint32_t getAiffSampleRate (std::vector& fileData, int sampleRateStartIndex);
- bool tenByteMatch (std::vector& v1, int startIndex1, std::vector& v2, int startIndex2);
- void addSampleRateToAiffData (std::vector& fileData, uint32_t sampleRate);
- T clamp (T v1, T minValue, T maxValue);
-
- //=============================================================
- void addStringToFileData (std::vector& fileData, std::string s);
- void addInt32ToFileData (std::vector& fileData, int32_t i, Endianness endianness = Endianness::LittleEndian);
- void addInt16ToFileData (std::vector& fileData, int16_t i, Endianness endianness = Endianness::LittleEndian);
-
- //=============================================================
- bool writeDataToFile (std::vector& fileData, std::string filePath);
-
- //=============================================================
- void reportError (std::string errorMessage);
-
- //=============================================================
- AudioFileFormat audioFileFormat;
- uint32_t sampleRate;
- int bitDepth;
- bool logErrorsToConsole {true};
- bool rawSamples;
-};
-
-
-//=============================================================
-// Pre-defined 10-byte representations of common sample rates
-static std::unordered_map > aiffSampleRateTable = {
- {8000, {64, 11, 250, 0, 0, 0, 0, 0, 0, 0}},
- {11025, {64, 12, 172, 68, 0, 0, 0, 0, 0, 0}},
- {16000, {64, 12, 250, 0, 0, 0, 0, 0, 0, 0}},
- {22050, {64, 13, 172, 68, 0, 0, 0, 0, 0, 0}},
- {32000, {64, 13, 250, 0, 0, 0, 0, 0, 0, 0}},
- {37800, {64, 14, 147, 168, 0, 0, 0, 0, 0, 0}},
- {44056, {64, 14, 172, 24, 0, 0, 0, 0, 0, 0}},
- {44100, {64, 14, 172, 68, 0, 0, 0, 0, 0, 0}},
- {47250, {64, 14, 184, 146, 0, 0, 0, 0, 0, 0}},
- {48000, {64, 14, 187, 128, 0, 0, 0, 0, 0, 0}},
- {50000, {64, 14, 195, 80, 0, 0, 0, 0, 0, 0}},
- {50400, {64, 14, 196, 224, 0, 0, 0, 0, 0, 0}},
- {88200, {64, 15, 172, 68, 0, 0, 0, 0, 0, 0}},
- {96000, {64, 15, 187, 128, 0, 0, 0, 0, 0, 0}},
- {176400, {64, 16, 172, 68, 0, 0, 0, 0, 0, 0}},
- {192000, {64, 16, 187, 128, 0, 0, 0, 0, 0, 0}},
- {352800, {64, 17, 172, 68, 0, 0, 0, 0, 0, 0}},
- {2822400, {64, 20, 172, 68, 0, 0, 0, 0, 0, 0}},
- {5644800, {64, 21, 172, 68, 0, 0, 0, 0, 0, 0}}
-};
-
-//=============================================================
-enum WavAudioFormat
-{
- PCM = 0x0001,
- IEEEFloat = 0x0003,
- ALaw = 0x0006,
- MULaw = 0x0007,
- Extensible = 0xFFFE
-};
-
-//=============================================================
-enum AIFFAudioFormat
-{
- Uncompressed,
- Compressed,
- Error
-};
-
-//=============================================================
-/* IMPLEMENTATION */
-//=============================================================
-
-//=============================================================
-template
-AudioFile::AudioFile()
-{
- // static_assert(std::is_floating_point::value, "ERROR: This version of AudioFile only supports floating point sample formats");
- if (std::is_floating_point::value) {
- rawSamples = false;
- bitDepth = 16;
- }
- else {
- rawSamples = true;
- bitDepth = sizeof(T) * 8;
- }
-
- sampleRate = 44100;
- samples.resize (1);
- samples[0].resize (0);
- audioFileFormat = AudioFileFormat::NotLoaded;
-}
-
-//=============================================================
-template
-AudioFile::AudioFile (std::string filePath)
- : AudioFile()
-{
- load (filePath);
-}
-
-//=============================================================
-template
-uint32_t AudioFile::getSampleRate() const
-{
- return sampleRate;
-}
-
-//=============================================================
-template
-int AudioFile::getNumChannels() const
-{
- return (int)samples.size();
-}
-
-//=============================================================
-template
-bool AudioFile::isMono() const
-{
- return getNumChannels() == 1;
-}
-
-//=============================================================
-template
-bool AudioFile::isStereo() const
-{
- return getNumChannels() == 2;
-}
-
-//=============================================================
-template
-int AudioFile::getBitDepth() const
-{
- return bitDepth;
-}
-
-//=============================================================
-template
-int AudioFile::getNumSamplesPerChannel() const
-{
- if (samples.size() > 0)
- return (int) samples[0].size();
- else
- return 0;
-}
-
-//=============================================================
-template
-double AudioFile::getLengthInSeconds() const
-{
- return (double)getNumSamplesPerChannel() / (double)sampleRate;
-}
-
-//=============================================================
-template
-void AudioFile::printSummary() const
-{
- std::cout << "|======================================|" << std::endl;
- std::cout << "Num Channels: " << getNumChannels() << std::endl;
- std::cout << "Num Samples Per Channel: " << getNumSamplesPerChannel() << std::endl;
- std::cout << "Sample Rate: " << sampleRate << std::endl;
- std::cout << "Bit Depth: " << bitDepth << std::endl;
- std::cout << "Length in Seconds: " << getLengthInSeconds() << std::endl;
- std::cout << "|======================================|" << std::endl;
-}
-
-//=============================================================
-template
-bool AudioFile::setAudioBuffer (AudioBuffer& newBuffer)
-{
- int numChannels = (int)newBuffer.size();
-
- if (numChannels <= 0)
- {
- assert (false && "The buffer your are trying to use has no channels");
- return false;
- }
-
- size_t numSamples = newBuffer[0].size();
-
- // set the number of channels
- samples.resize (newBuffer.size());
-
- for (int k = 0; k < getNumChannels(); k++)
- {
- assert (newBuffer[k].size() == numSamples);
-
- samples[k].resize (numSamples);
-
- for (size_t i = 0; i < numSamples; i++)
- {
- samples[k][i] = newBuffer[k][i];
- }
- }
-
- return true;
-}
-
-//=============================================================
-template
-void AudioFile::setAudioBufferSize (int numChannels, int numSamples)
-{
- samples.resize (numChannels);
- setNumSamplesPerChannel (numSamples);
-}
-
-//=============================================================
-template
-void AudioFile::setNumSamplesPerChannel (int numSamples)
-{
- int originalSize = getNumSamplesPerChannel();
-
- for (int i = 0; i < getNumChannels();i++)
- {
- samples[i].resize (numSamples);
-
- // set any new samples to zero
- if (numSamples > originalSize)
- std::fill (samples[i].begin() + originalSize, samples[i].end(), (T)0.);
- }
-}
-
-//=============================================================
-template
-void AudioFile::setNumChannels (int numChannels)
-{
- int originalNumChannels = getNumChannels();
- int originalNumSamplesPerChannel = getNumSamplesPerChannel();
-
- samples.resize (numChannels);
-
- // make sure any new channels are set to the right size
- // and filled with zeros
- if (numChannels > originalNumChannels)
- {
- for (int i = originalNumChannels; i < numChannels; i++)
- {
- samples[i].resize (originalNumSamplesPerChannel);
- std::fill (samples[i].begin(), samples[i].end(), (T)0.);
- }
- }
-}
-
-//=============================================================
-template
-void AudioFile::setBitDepth (int numBitsPerSample)
-{
- bitDepth = numBitsPerSample;
-}
-
-//=============================================================
-template
-void AudioFile::setSampleRate (uint32_t newSampleRate)
-{
- sampleRate = newSampleRate;
-}
-
-//=============================================================
-template
-void AudioFile::shouldLogErrorsToConsole (bool logErrors)
-{
- logErrorsToConsole = logErrors;
-}
-
-//=============================================================
-template
-bool AudioFile::load (std::string filePath)
-{
- std::ifstream file (filePath, std::ios::binary);
-
- // check the file exists
- if (! file.good())
- {
- reportError ("ERROR: File doesn't exist or otherwise can't load file\n" + filePath);
- return false;
- }
-
- std::vector fileData;
-
- file.unsetf (std::ios::skipws);
-
- file.seekg (0, std::ios::end);
- size_t length = file.tellg();
- file.seekg (0, std::ios::beg);
-
- // allocate
- fileData.resize (length);
-
- file.read(reinterpret_cast (fileData.data()), length);
- file.close();
-
- if (file.gcount() != length)
- {
- reportError ("ERROR: Couldn't read entire file\n" + filePath);
- return false;
- }
-
- // get audio file format
- audioFileFormat = determineAudioFileFormat (fileData);
-
- if (audioFileFormat == AudioFileFormat::Wave)
- {
- return decodeWaveFile (fileData);
- }
- else if (audioFileFormat == AudioFileFormat::Aiff)
- {
- return decodeAiffFile (fileData);
- }
- else
- {
- reportError ("Audio File Type: Error");
- return false;
- }
-}
-
-//=============================================================
-template
-bool AudioFile::decodeWaveFile (std::vector& fileData)
-{
- // -----------------------------------------------------------
- // HEADER CHUNK
- std::string headerChunkID (fileData.begin(), fileData.begin() + 4);
- //int32_t fileSizeInBytes = fourBytesToInt (fileData, 4) + 8;
- std::string format (fileData.begin() + 8, fileData.begin() + 12);
-
- // -----------------------------------------------------------
- // try and find the start points of key chunks
- int indexOfDataChunk = getIndexOfChunk (fileData, "data", 12);
- int indexOfFormatChunk = getIndexOfChunk (fileData, "fmt ", 12);
- int indexOfXMLChunk = getIndexOfChunk (fileData, "iXML", 12);
-
- // if we can't find the data or format chunks, or the IDs/formats don't seem to be as expected
- // then it is unlikely we'll able to read this file, so abort
- if (indexOfDataChunk == -1 || indexOfFormatChunk == -1 || headerChunkID != "RIFF" || format != "WAVE")
- {
- reportError ("ERROR: this doesn't seem to be a valid .WAV file");
- return false;
- }
-
- // -----------------------------------------------------------
- // FORMAT CHUNK
- int f = indexOfFormatChunk;
- std::string formatChunkID (fileData.begin() + f, fileData.begin() + f + 4);
- //int32_t formatChunkSize = fourBytesToInt (fileData, f + 4);
- uint16_t audioFormat = twoBytesToInt (fileData, f + 8);
- uint16_t numChannels = twoBytesToInt (fileData, f + 10);
- sampleRate = (uint32_t) fourBytesToInt (fileData, f + 12);
- uint32_t numBytesPerSecond = fourBytesToInt (fileData, f + 16);
- uint16_t numBytesPerBlock = twoBytesToInt (fileData, f + 20);
- bitDepth = (int) twoBytesToInt (fileData, f + 22);
-
- uint16_t numBytesPerSample = static_cast (bitDepth) / 8;
-
- // check that the audio format is PCM or Float or extensible
- if (audioFormat != WavAudioFormat::PCM && audioFormat != WavAudioFormat::IEEEFloat && audioFormat != WavAudioFormat::Extensible)
- {
- reportError ("ERROR: this .WAV file is encoded in a format that this library does not support at present");
- return false;
- }
-
- // check the number of channels is mono or stereo
- if (numChannels < 1 || numChannels > 128)
- {
- reportError ("ERROR: this WAV file seems to be an invalid number of channels (or corrupted?)");
- return false;
- }
-
- // check header data is consistent
- if (numBytesPerSecond != static_cast ((numChannels * sampleRate * bitDepth) / 8) || numBytesPerBlock != (numChannels * numBytesPerSample))
- {
- reportError ("ERROR: the header data in this WAV file seems to be inconsistent");
- return false;
- }
-
- // check bit depth is either 8, 16, 24 or 32 bit
- if (bitDepth != 8 && bitDepth != 16 && bitDepth != 24 && bitDepth != 32)
- {
- reportError ("ERROR: this file has a bit depth that is not 8, 16, 24 or 32 bits");
- return false;
- }
-
- // -----------------------------------------------------------
- // DATA CHUNK
- int d = indexOfDataChunk;
- std::string dataChunkID (fileData.begin() + d, fileData.begin() + d + 4);
- int32_t dataChunkSize = fourBytesToInt (fileData, d + 4);
-
- int numSamples = dataChunkSize / (numChannels * bitDepth / 8);
- int samplesStartIndex = indexOfDataChunk + 8;
-
- clearAudioBuffer();
- samples.resize (numChannels);
-
- for (int i = 0; i < numSamples; i++)
- {
- for (int channel = 0; channel < numChannels; channel++)
- {
- int sampleIndex = samplesStartIndex + (numBytesPerBlock * i) + channel * numBytesPerSample;
-
- if ((sampleIndex + (bitDepth / 8) - 1) >= fileData.size())
- {
- reportError ("ERROR: read file error as the metadata indicates more samples than there are in the file data");
- return false;
- }
-
- if (bitDepth == 8)
- {
- T sample = singleByteToSample (fileData[sampleIndex]);
- samples[channel].push_back (sample);
- }
- else if (bitDepth == 16)
- {
- int16_t sampleAsInt = twoBytesToInt (fileData, sampleIndex);
- T sample = sixteenBitIntToSample (sampleAsInt);
- samples[channel].push_back (sample);
- }
- else if (bitDepth == 24)
- {
- int32_t sampleAsInt = 0;
- sampleAsInt = (fileData[sampleIndex + 2] << 16) | (fileData[sampleIndex + 1] << 8) | fileData[sampleIndex];
-
- if (sampleAsInt & 0x800000) // if the 24th bit is set, this is a negative number in 24-bit world
- sampleAsInt = sampleAsInt | ~0xFFFFFF; // so make sure sign is extended to the 32 bit float
-
- T sample = (T)sampleAsInt / (T)8388608.;
- samples[channel].push_back (sample);
- }
- else if (bitDepth == 32)
- {
- int32_t sampleAsInt = fourBytesToInt (fileData, sampleIndex);
- T sample;
-
- if (audioFormat == WavAudioFormat::IEEEFloat)
- sample = (T)reinterpret_cast (sampleAsInt);
- else // assume PCM
- sample = (T) sampleAsInt / static_cast (std::numeric_limits::max());
-
- samples[channel].push_back (sample);
- }
- else
- {
- assert (false);
- }
- }
- }
-
- // -----------------------------------------------------------
- // iXML CHUNK
- if (indexOfXMLChunk != -1)
- {
- int32_t chunkSize = fourBytesToInt (fileData, indexOfXMLChunk + 4);
- iXMLChunk = std::string ((const char*) &fileData[indexOfXMLChunk + 8], chunkSize);
- }
-
- return true;
-}
-
-//=============================================================
-template
-bool AudioFile::decodeAiffFile (std::vector& fileData)
-{
- // -----------------------------------------------------------
- // HEADER CHUNK
- std::string headerChunkID (fileData.begin(), fileData.begin() + 4);
- //int32_t fileSizeInBytes = fourBytesToInt (fileData, 4, Endianness::BigEndian) + 8;
- std::string format (fileData.begin() + 8, fileData.begin() + 12);
-
- int audioFormat = format == "AIFF" ? AIFFAudioFormat::Uncompressed : format == "AIFC" ? AIFFAudioFormat::Compressed : AIFFAudioFormat::Error;
-
- // -----------------------------------------------------------
- // try and find the start points of key chunks
- int indexOfCommChunk = getIndexOfChunk (fileData, "COMM", 12, Endianness::BigEndian);
- int indexOfSoundDataChunk = getIndexOfChunk (fileData, "SSND", 12, Endianness::BigEndian);
- int indexOfXMLChunk = getIndexOfChunk (fileData, "iXML", 12, Endianness::BigEndian);
-
- // if we can't find the data or format chunks, or the IDs/formats don't seem to be as expected
- // then it is unlikely we'll able to read this file, so abort
- if (indexOfSoundDataChunk == -1 || indexOfCommChunk == -1 || headerChunkID != "FORM" || audioFormat == AIFFAudioFormat::Error)
- {
- reportError ("ERROR: this doesn't seem to be a valid AIFF file");
- return false;
- }
-
- // -----------------------------------------------------------
- // COMM CHUNK
- int p = indexOfCommChunk;
- std::string commChunkID (fileData.begin() + p, fileData.begin() + p + 4);
- //int32_t commChunkSize = fourBytesToInt (fileData, p + 4, Endianness::BigEndian);
- int16_t numChannels = twoBytesToInt (fileData, p + 8, Endianness::BigEndian);
- int32_t numSamplesPerChannel = fourBytesToInt (fileData, p + 10, Endianness::BigEndian);
- bitDepth = (int) twoBytesToInt (fileData, p + 14, Endianness::BigEndian);
- sampleRate = getAiffSampleRate (fileData, p + 16);
-
- // check the sample rate was properly decoded
- if (sampleRate == 0)
- {
- reportError ("ERROR: this AIFF file has an unsupported sample rate");
- return false;
- }
-
- // check the number of channels is mono or stereo
- if (numChannels < 1 ||numChannels > 2)
- {
- reportError ("ERROR: this AIFF file seems to be neither mono nor stereo (perhaps multi-track, or corrupted?)");
- return false;
- }
-
- // check bit depth is either 8, 16, 24 or 32-bit
- if (bitDepth != 8 && bitDepth != 16 && bitDepth != 24 && bitDepth != 32)
- {
- reportError ("ERROR: this file has a bit depth that is not 8, 16, 24 or 32 bits");
- return false;
- }
-
- // -----------------------------------------------------------
- // SSND CHUNK
- int s = indexOfSoundDataChunk;
- std::string soundDataChunkID (fileData.begin() + s, fileData.begin() + s + 4);
- int32_t soundDataChunkSize = fourBytesToInt (fileData, s + 4, Endianness::BigEndian);
- int32_t offset = fourBytesToInt (fileData, s + 8, Endianness::BigEndian);
- //int32_t blockSize = fourBytesToInt (fileData, s + 12, Endianness::BigEndian);
-
- int numBytesPerSample = bitDepth / 8;
- int numBytesPerFrame = numBytesPerSample * numChannels;
- int totalNumAudioSampleBytes = numSamplesPerChannel * numBytesPerFrame;
- int samplesStartIndex = s + 16 + (int)offset;
-
- // sanity check the data
- if ((soundDataChunkSize - 8) != totalNumAudioSampleBytes || totalNumAudioSampleBytes > static_cast(fileData.size() - samplesStartIndex))
- {
- reportError ("ERROR: the metadatafor this file doesn't seem right");
- return false;
- }
-
- clearAudioBuffer();
- samples.resize (numChannels);
-
- for (int i = 0; i < numSamplesPerChannel; i++)
- {
- for (int channel = 0; channel < numChannels; channel++)
- {
- int sampleIndex = samplesStartIndex + (numBytesPerFrame * i) + channel * numBytesPerSample;
-
- if ((sampleIndex + (bitDepth / 8) - 1) >= fileData.size())
- {
- reportError ("ERROR: read file error as the metadata indicates more samples than there are in the file data");
- return false;
- }
-
- if (bitDepth == 8)
- {
- int8_t sampleAsSigned8Bit = (int8_t)fileData[sampleIndex];
- T sample = (T)sampleAsSigned8Bit / (T)128.;
- samples[channel].push_back (sample);
- }
- else if (bitDepth == 16)
- {
- int16_t sampleAsInt = twoBytesToInt (fileData, sampleIndex, Endianness::BigEndian);
- T sample = sixteenBitIntToSample (sampleAsInt);
- samples[channel].push_back (sample);
- }
- else if (bitDepth == 24)
- {
- int32_t sampleAsInt = 0;
- sampleAsInt = (fileData[sampleIndex] << 16) | (fileData[sampleIndex + 1] << 8) | fileData[sampleIndex + 2];
-
- if (sampleAsInt & 0x800000) // if the 24th bit is set, this is a negative number in 24-bit world
- sampleAsInt = sampleAsInt | ~0xFFFFFF; // so make sure sign is extended to the 32 bit float
-
- T sample = (T)sampleAsInt / (T)8388608.;
- samples[channel].push_back (sample);
- }
- else if (bitDepth == 32)
- {
- int32_t sampleAsInt = fourBytesToInt (fileData, sampleIndex, Endianness::BigEndian);
- T sample;
-
- if (audioFormat == AIFFAudioFormat::Compressed)
- sample = (T)reinterpret_cast (sampleAsInt);
- else // assume uncompressed
- sample = (T) sampleAsInt / static_cast (std::numeric_limits::max());
-
- samples[channel].push_back (sample);
- }
- else
- {
- assert (false);
- }
- }
- }
-
- // -----------------------------------------------------------
- // iXML CHUNK
- if (indexOfXMLChunk != -1)
- {
- int32_t chunkSize = fourBytesToInt (fileData, indexOfXMLChunk + 4);
- iXMLChunk = std::string ((const char*) &fileData[indexOfXMLChunk + 8], chunkSize);
- }
-
- return true;
-}
-
-//=============================================================
-template
-uint32_t AudioFile::getAiffSampleRate (std::vector& fileData, int sampleRateStartIndex)
-{
- for (auto it : aiffSampleRateTable)
- {
- if (tenByteMatch (fileData, sampleRateStartIndex, it.second, 0))
- return it.first;
- }
-
- return 0;
-}
-
-//=============================================================
-template
-bool AudioFile::tenByteMatch (std::vector& v1, int startIndex1, std::vector& v2, int startIndex2)
-{
- for (int i = 0; i < 10; i++)
- {
- if (v1[startIndex1 + i] != v2[startIndex2 + i])
- return false;
- }
-
- return true;
-}
-
-//=============================================================
-template
-void AudioFile::addSampleRateToAiffData (std::vector& fileData, uint32_t sampleRate)
-{
- if (aiffSampleRateTable.count (sampleRate) > 0)
- {
- for (int i = 0; i < 10; i++)
- fileData.push_back (aiffSampleRateTable[sampleRate][i]);
- }
-}
-
-//=============================================================
-template
-bool AudioFile::save (std::string filePath, AudioFileFormat format)
-{
- if (format == AudioFileFormat::Wave)
- {
- return saveToWaveFile (filePath);
- }
- else if (format == AudioFileFormat::Aiff)
- {
- return saveToAiffFile (filePath);
- }
-
- return false;
-}
-
-//=============================================================
-template
-bool AudioFile::saveToWaveFile (std::string filePath)
-{
- std::vector fileData;
-
- int32_t dataChunkSize = getNumSamplesPerChannel() * (getNumChannels() * bitDepth / 8);
- int16_t audioFormat = bitDepth == 32 ? WavAudioFormat::IEEEFloat : WavAudioFormat::PCM;
- int32_t formatChunkSize = audioFormat == WavAudioFormat::PCM ? 16 : 18;
- int32_t iXMLChunkSize = static_cast (iXMLChunk.size());
-
- // -----------------------------------------------------------
- // HEADER CHUNK
- addStringToFileData (fileData, "RIFF");
-
- // The file size in bytes is the header chunk size (4, not counting RIFF and WAVE) + the format
- // chunk size (24) + the metadata part of the data chunk plus the actual data chunk size
- int32_t fileSizeInBytes = 4 + formatChunkSize + 8 + 8 + dataChunkSize;
- if (iXMLChunkSize > 0)
- {
- fileSizeInBytes += (8 + iXMLChunkSize);
- }
-
- addInt32ToFileData (fileData, fileSizeInBytes);
-
- addStringToFileData (fileData, "WAVE");
-
- // -----------------------------------------------------------
- // FORMAT CHUNK
- addStringToFileData (fileData, "fmt ");
- addInt32ToFileData (fileData, formatChunkSize); // format chunk size (16 for PCM)
- addInt16ToFileData (fileData, audioFormat); // audio format
- addInt16ToFileData (fileData, (int16_t)getNumChannels()); // num channels
- addInt32ToFileData (fileData, (int32_t)sampleRate); // sample rate
-
- int32_t numBytesPerSecond = (int32_t) ((getNumChannels() * sampleRate * bitDepth) / 8);
- addInt32ToFileData (fileData, numBytesPerSecond);
-
- int16_t numBytesPerBlock = getNumChannels() * (bitDepth / 8);
- addInt16ToFileData (fileData, numBytesPerBlock);
-
- addInt16ToFileData (fileData, (int16_t)bitDepth);
-
- if (audioFormat == WavAudioFormat::IEEEFloat)
- addInt16ToFileData (fileData, 0); // extension size
-
- // -----------------------------------------------------------
- // DATA CHUNK
- addStringToFileData (fileData, "data");
- addInt32ToFileData (fileData, dataChunkSize);
-
- for (int i = 0; i < getNumSamplesPerChannel(); i++)
- {
- for (int channel = 0; channel < getNumChannels(); channel++)
- {
- if (bitDepth == 8)
- {
- uint8_t byte = rawSamples ? samples[channel][i] : sampleToSingleByte (samples[channel][i]);
- fileData.push_back (byte);
- }
- else if (bitDepth == 16)
- {
- int16_t sampleAsInt = rawSamples ? samples[channel][i] : sampleToSixteenBitInt (samples[channel][i]);
- addInt16ToFileData (fileData, sampleAsInt);
- }
- else if (bitDepth == 24)
- {
- int32_t sampleAsIntAgain = rawSamples ? samples[channel][i] : (int32_t) (samples[channel][i] * (T)8388608.);
-
- uint8_t bytes[3];
- bytes[2] = (uint8_t) (sampleAsIntAgain >> 16) & 0xFF;
- bytes[1] = (uint8_t) (sampleAsIntAgain >> 8) & 0xFF;
- bytes[0] = (uint8_t) sampleAsIntAgain & 0xFF;
-
- fileData.push_back (bytes[0]);
- fileData.push_back (bytes[1]);
- fileData.push_back (bytes[2]);
- }
- else if (bitDepth == 32)
- {
- int32_t sampleAsInt;
-
- if (audioFormat == WavAudioFormat::IEEEFloat)
- sampleAsInt = (int32_t) reinterpret_cast (samples[channel][i]);
- else // assume PCM
- sampleAsInt = rawSamples ? samples[channel][i] : (int32_t) (samples[channel][i] * std::numeric_limits::max());
-
- addInt32ToFileData (fileData, sampleAsInt, Endianness::LittleEndian);
- }
- else
- {
- assert (false && "Trying to write a file with unsupported bit depth");
- return false;
- }
- }
- }
-
- // -----------------------------------------------------------
- // iXML CHUNK
- if (iXMLChunkSize > 0)
- {
- addStringToFileData (fileData, "iXML");
- addInt32ToFileData (fileData, iXMLChunkSize);
- addStringToFileData (fileData, iXMLChunk);
- }
-
- // check that the various sizes we put in the metadata are correct
- if (fileSizeInBytes != static_cast (fileData.size() - 8) || dataChunkSize != (getNumSamplesPerChannel() * getNumChannels() * (bitDepth / 8)))
- {
- reportError ("ERROR: couldn't save file to " + filePath);
- return false;
- }
-
- // try to write the file
- return writeDataToFile (fileData, filePath);
-}
-
-//=============================================================
-template
-bool AudioFile::saveToAiffFile (std::string filePath)
-{
- std::vector fileData;
-
- int32_t numBytesPerSample = bitDepth / 8;
- int32_t numBytesPerFrame = numBytesPerSample * getNumChannels();
- int32_t totalNumAudioSampleBytes = getNumSamplesPerChannel() * numBytesPerFrame;
- int32_t soundDataChunkSize = totalNumAudioSampleBytes + 8;
- int32_t iXMLChunkSize = static_cast (iXMLChunk.size());
-
- // -----------------------------------------------------------
- // HEADER CHUNK
- addStringToFileData (fileData, "FORM");
-
- // The file size in bytes is the header chunk size (4, not counting FORM and AIFF) + the COMM
- // chunk size (26) + the metadata part of the SSND chunk plus the actual data chunk size
- int32_t fileSizeInBytes = 4 + 26 + 16 + totalNumAudioSampleBytes;
- if (iXMLChunkSize > 0)
- {
- fileSizeInBytes += (8 + iXMLChunkSize);
- }
-
- addInt32ToFileData (fileData, fileSizeInBytes, Endianness::BigEndian);
-
- addStringToFileData (fileData, "AIFF");
-
- // -----------------------------------------------------------
- // COMM CHUNK
- addStringToFileData (fileData, "COMM");
- addInt32ToFileData (fileData, 18, Endianness::BigEndian); // commChunkSize
- addInt16ToFileData (fileData, getNumChannels(), Endianness::BigEndian); // num channels
- addInt32ToFileData (fileData, getNumSamplesPerChannel(), Endianness::BigEndian); // num samples per channel
- addInt16ToFileData (fileData, bitDepth, Endianness::BigEndian); // bit depth
- addSampleRateToAiffData (fileData, sampleRate);
-
- // -----------------------------------------------------------
- // SSND CHUNK
- addStringToFileData (fileData, "SSND");
- addInt32ToFileData (fileData, soundDataChunkSize, Endianness::BigEndian);
- addInt32ToFileData (fileData, 0, Endianness::BigEndian); // offset
- addInt32ToFileData (fileData, 0, Endianness::BigEndian); // block size
-
- for (int i = 0; i < getNumSamplesPerChannel(); i++)
- {
- for (int channel = 0; channel < getNumChannels(); channel++)
- {
- if (bitDepth == 8)
- {
- uint8_t byte = sampleToSingleByte (samples[channel][i]);
- fileData.push_back (byte);
- }
- else if (bitDepth == 16)
- {
- int16_t sampleAsInt = sampleToSixteenBitInt (samples[channel][i]);
- addInt16ToFileData (fileData, sampleAsInt, Endianness::BigEndian);
- }
- else if (bitDepth == 24)
- {
- int32_t sampleAsIntAgain = (int32_t) (samples[channel][i] * (T)8388608.);
-
- uint8_t bytes[3];
- bytes[0] = (uint8_t) (sampleAsIntAgain >> 16) & 0xFF;
- bytes[1] = (uint8_t) (sampleAsIntAgain >> 8) & 0xFF;
- bytes[2] = (uint8_t) sampleAsIntAgain & 0xFF;
-
- fileData.push_back (bytes[0]);
- fileData.push_back (bytes[1]);
- fileData.push_back (bytes[2]);
- }
- else if (bitDepth == 32)
- {
- // write samples as signed integers (no implementation yet for floating point, but looking at WAV implementation should help)
- int32_t sampleAsInt = (int32_t) (samples[channel][i] * std::numeric_limits::max());
- addInt32ToFileData (fileData, sampleAsInt, Endianness::BigEndian);
- }
- else
- {
- assert (false && "Trying to write a file with unsupported bit depth");
- return false;
- }
- }
- }
-
- // -----------------------------------------------------------
- // iXML CHUNK
- if (iXMLChunkSize > 0)
- {
- addStringToFileData (fileData, "iXML");
- addInt32ToFileData (fileData, iXMLChunkSize, Endianness::BigEndian);
- addStringToFileData (fileData, iXMLChunk);
- }
-
- // check that the various sizes we put in the metadata are correct
- if (fileSizeInBytes != static_cast (fileData.size() - 8) || soundDataChunkSize != getNumSamplesPerChannel() * numBytesPerFrame + 8)
- {
- reportError ("ERROR: couldn't save file to " + filePath);
- return false;
- }
-
- // try to write the file
- return writeDataToFile (fileData, filePath);
-}
-
-//=============================================================
-template
-bool AudioFile::writeDataToFile (std::vector& fileData, std::string filePath)
-{
- std::ofstream outputFile (filePath, std::ios::binary);
-
- if (outputFile.is_open())
- {
- for (size_t i = 0; i < fileData.size(); i++)
- {
- char value = (char) fileData[i];
- outputFile.write (&value, sizeof (char));
- }
-
- outputFile.close();
-
- return true;
- }
-
- return false;
-}
-
-//=============================================================
-template
-void AudioFile::addStringToFileData (std::vector& fileData, std::string s)
-{
- for (size_t i = 0; i < s.length();i++)
- fileData.push_back ((uint8_t) s[i]);
-}
-
-//=============================================================
-template
-void AudioFile::addInt32ToFileData (std::vector& fileData, int32_t i, Endianness endianness)
-{
- uint8_t bytes[4];
-
- if (endianness == Endianness::LittleEndian)
- {
- bytes[3] = (i >> 24) & 0xFF;
- bytes[2] = (i >> 16) & 0xFF;
- bytes[1] = (i >> 8) & 0xFF;
- bytes[0] = i & 0xFF;
- }
- else
- {
- bytes[0] = (i >> 24) & 0xFF;
- bytes[1] = (i >> 16) & 0xFF;
- bytes[2] = (i >> 8) & 0xFF;
- bytes[3] = i & 0xFF;
- }
-
- for (int i = 0; i < 4; i++)
- fileData.push_back (bytes[i]);
-}
-
-//=============================================================
-template
-void AudioFile::addInt16ToFileData (std::vector& fileData, int16_t i, Endianness endianness)
-{
- uint8_t bytes[2];
-
- if (endianness == Endianness::LittleEndian)
- {
- bytes[1] = (i >> 8) & 0xFF;
- bytes[0] = i & 0xFF;
- }
- else
- {
- bytes[0] = (i >> 8) & 0xFF;
- bytes[1] = i & 0xFF;
- }
-
- fileData.push_back (bytes[0]);
- fileData.push_back (bytes[1]);
-}
-
-//=============================================================
-template
-void AudioFile::clearAudioBuffer()
-{
- for (size_t i = 0; i < samples.size();i++)
- {
- samples[i].clear();
- }
-
- samples.clear();
-}
-
-//=============================================================
-template
-AudioFileFormat AudioFile::determineAudioFileFormat (std::vector& fileData)
-{
- std::string header (fileData.begin(), fileData.begin() + 4);
-
- if (header == "RIFF")
- return AudioFileFormat::Wave;
- else if (header == "FORM")
- return AudioFileFormat::Aiff;
- else
- return AudioFileFormat::Error;
-}
-
-//=============================================================
-template
-int32_t AudioFile::fourBytesToInt (std::vector& source, int startIndex, Endianness endianness)
-{
- int32_t result;
-
- if (endianness == Endianness::LittleEndian)
- result = (source[startIndex + 3] << 24) | (source[startIndex + 2] << 16) | (source[startIndex + 1] << 8) | source[startIndex];
- else
- result = (source[startIndex] << 24) | (source[startIndex + 1] << 16) | (source[startIndex + 2] << 8) | source[startIndex + 3];
-
- return result;
-}
-
-//=============================================================
-template
-int16_t AudioFile::twoBytesToInt (std::vector& source, int startIndex, Endianness endianness)
-{
- int16_t result;
-
- if (endianness == Endianness::LittleEndian)
- result = (source[startIndex + 1] << 8) | source[startIndex];
- else
- result = (source[startIndex] << 8) | source[startIndex + 1];
-
- return result;
-}
-
-//=============================================================
-template
-int AudioFile::getIndexOfString (std::vector& source, std::string stringToSearchFor)
-{
- int index = -1;
- int stringLength = (int)stringToSearchFor.length();
-
- for (size_t i = 0; i < source.size() - stringLength;i++)
- {
- std::string section (source.begin() + i, source.begin() + i + stringLength);
-
- if (section == stringToSearchFor)
- {
- index = static_cast (i);
- break;
- }
- }
-
- return index;
-}
-
-//=============================================================
-template
-int AudioFile::getIndexOfChunk (std::vector& source, const std::string& chunkHeaderID, int startIndex, Endianness endianness)
-{
- constexpr int dataLen = 4;
- if (chunkHeaderID.size() != dataLen)
- {
- assert (false && "Invalid chunk header ID string");
- return -1;
- }
-
- int i = startIndex;
- while (i < source.size() - dataLen)
- {
- if (memcmp (&source[i], chunkHeaderID.data(), dataLen) == 0)
- {
- return i;
- }
-
- i += dataLen;
- auto chunkSize = fourBytesToInt (source, i, endianness);
- i += (dataLen + chunkSize);
- }
-
- return -1;
-}
-
-//=============================================================
-template
-T AudioFile::sixteenBitIntToSample (int16_t sample)
-{
- return static_cast (sample) / static_cast (32768.);
-}
-
-//=============================================================
-template
-int16_t AudioFile::sampleToSixteenBitInt (T sample)
-{
- sample = clamp (sample, -1., 1.);
- return static_cast (sample * 32767.);
-}
-
-//=============================================================
-template
-uint8_t AudioFile::sampleToSingleByte (T sample)
-{
- sample = clamp (sample, -1., 1.);
- sample = (sample + 1.) / 2.;
- return static_cast (sample * 255.);
-}
-
-//=============================================================
-template
-T AudioFile::singleByteToSample (uint8_t sample)
-{
- return static_cast (sample - 128) / static_cast (128.);
-}
-
-//=============================================================
-template
-T AudioFile::clamp (T value, T minValue, T maxValue)
-{
- value = std::min (value, maxValue);
- value = std::max (value, minValue);
- return value;
-}
-
-//=============================================================
-template
-void AudioFile::reportError (std::string errorMessage)
-{
- if (logErrorsToConsole)
- std::cout << errorMessage << std::endl;
-}
-
-#if defined (_MSC_VER)
- __pragma(warning (pop))
-#elif defined (__GNUC__)
- _Pragma("GCC diagnostic pop")
-#endif
-
-#endif /* AudioFile_h */