diff --git a/includes/RhythmGameUtilities/Parsers.hpp b/includes/RhythmGameUtilities/Parsers.hpp index cda7e55..afd466a 100644 --- a/includes/RhythmGameUtilities/Parsers.hpp +++ b/includes/RhythmGameUtilities/Parsers.hpp @@ -91,53 +91,4 @@ std::vector ParseSectionsFromChart(const char *contents) return sections; } -extern "C" -{ - PACKAGE_API - ChartSectionInternal *ParseSectionsFromChartInternal(const char *contents, - int *outSize) - { - auto internalSections = ParseSectionsFromChart(contents); - - *outSize = internalSections.size(); - - auto sections = (ChartSectionInternal *)malloc( - internalSections.size() * sizeof(ChartSectionInternal)); - - for (auto i = 0; i < internalSections.size(); i += 1) - { - sections[i].name = - (char *)malloc(strlen(internalSections[i].name.c_str()) + 1); - strcpy(sections[i].name, internalSections[i].name.c_str()); - - sections[i].lines = (KeyValuePairInternal *)malloc( - internalSections[i].lines.size() * - sizeof(KeyValuePairInternal)); - - sections[i].lineCount = internalSections[i].lines.size(); - - for (auto j = 0; j < internalSections[i].lines.size(); j += 1) - { - sections[i].lines[j].key = (char *)malloc( - strlen(internalSections[i].lines[j].first.c_str()) + 1); - strcpy(sections[i].lines[j].key, - internalSections[i].lines[j].first.c_str()); - - auto values = internalSections[i].lines[j].second; - - for (auto k = 0; k < values.size(); k += 1) - { - sections[i].lines[j].values[k] = - (char *)malloc(strlen(values[k].c_str()) + 1); - strcpy(sections[i].lines[j].values[k], values[k].c_str()); - } - - sections[i].lines[j].valueCount = values.size(); - } - } - - return sections; - } -} - } // namespace RhythmGameUtilities diff --git a/includes/RhythmGameUtilities/ParsersInternal.hpp b/includes/RhythmGameUtilities/ParsersInternal.hpp new file mode 100644 index 0000000..91a0075 --- /dev/null +++ b/includes/RhythmGameUtilities/ParsersInternal.hpp @@ -0,0 +1,64 @@ +#pragma once + +#include "Parsers.hpp" +#include "Utilities.hpp" + +#ifdef _WIN32 +#define PACKAGE_API __declspec(dllexport) +#else +#define PACKAGE_API +#endif + +namespace RhythmGameUtilities +{ + +extern "C" +{ + PACKAGE_API + ChartSectionInternal *ParseSectionsFromChartInternal(const char *contents, + int *outSize) + { + auto internalSections = ParseSectionsFromChart(contents); + + *outSize = internalSections.size(); + + auto sections = (ChartSectionInternal *)malloc( + internalSections.size() * sizeof(ChartSectionInternal)); + + for (auto i = 0; i < internalSections.size(); i += 1) + { + sections[i].name = + (char *)malloc(strlen(internalSections[i].name.c_str()) + 1); + strcpy(sections[i].name, internalSections[i].name.c_str()); + + sections[i].lines = (KeyValuePairInternal *)malloc( + internalSections[i].lines.size() * + sizeof(KeyValuePairInternal)); + + sections[i].lineCount = internalSections[i].lines.size(); + + for (auto j = 0; j < internalSections[i].lines.size(); j += 1) + { + sections[i].lines[j].key = (char *)malloc( + strlen(internalSections[i].lines[j].first.c_str()) + 1); + strcpy(sections[i].lines[j].key, + internalSections[i].lines[j].first.c_str()); + + auto values = internalSections[i].lines[j].second; + + for (auto k = 0; k < values.size(); k += 1) + { + sections[i].lines[j].values[k] = + (char *)malloc(strlen(values[k].c_str()) + 1); + strcpy(sections[i].lines[j].values[k], values[k].c_str()); + } + + sections[i].lines[j].valueCount = values.size(); + } + } + + return sections; + } +} + +} // namespace RhythmGameUtilities diff --git a/includes/RhythmGameUtilities/RhythmGameUtilities.cpp b/includes/RhythmGameUtilities/RhythmGameUtilities.cpp index 361d35f..ec66ffe 100644 --- a/includes/RhythmGameUtilities/RhythmGameUtilities.cpp +++ b/includes/RhythmGameUtilities/RhythmGameUtilities.cpp @@ -2,4 +2,6 @@ #include "Audio.hpp" #include "Parsers.hpp" +#include "ParsersInternal.hpp" #include "Utilities.hpp" +#include "UtilitiesInternal.hpp" diff --git a/includes/RhythmGameUtilities/Utilities.hpp b/includes/RhythmGameUtilities/Utilities.hpp index 1c9350d..b2d3e7e 100644 --- a/includes/RhythmGameUtilities/Utilities.hpp +++ b/includes/RhythmGameUtilities/Utilities.hpp @@ -112,21 +112,6 @@ extern "C" return tick / resolution; } - PACKAGE_API int ConvertSecondsToTicksInternal(float seconds, int resolution, - int *bpmChangesKeys, - int *bpmChangesValues, - int bpmChangesSize) - { - std::map bpmChanges; - - for (auto i = 0; i < bpmChangesSize; i += 1) - { - bpmChanges[bpmChangesKeys[i]] = bpmChangesValues[i]; - } - - return ConvertSecondsToTicks(seconds, resolution, bpmChanges); - } - PACKAGE_API bool IsOnTheBeat(float bpm, float currentTime) { auto beatInterval = SECONDS_PER_MINUTE / bpm; @@ -154,34 +139,6 @@ extern "C" { return std::clamp(((v - a) / (b - a)), 0.0f, 1.0f); } - - PACKAGE_API BeatBar * - CalculateBeatBarsInternal(int *bpmChangesKeys, int *bpmChangesValues, - int bpmChangesSize, int resolution, int ts, - bool includeHalfNotes, int *outSize) - { - auto bpmChanges = std::map(); - - for (auto i = 0; i < bpmChangesSize; i += 1) - { - bpmChanges[bpmChangesKeys[i]] = bpmChangesValues[i]; - } - - auto internalBeatBars = - CalculateBeatBars(bpmChanges, resolution, ts, includeHalfNotes); - - *outSize = internalBeatBars.size(); - - auto beatBars = - (BeatBar *)malloc(internalBeatBars.size() * sizeof(BeatBar)); - - for (auto i = 0; i < internalBeatBars.size(); i += 1) - { - beatBars[i] = internalBeatBars[i]; - } - - return beatBars; - } } std::string Trim(const char *contents) diff --git a/includes/RhythmGameUtilities/UtilitiesInternal.hpp b/includes/RhythmGameUtilities/UtilitiesInternal.hpp new file mode 100644 index 0000000..935c5ac --- /dev/null +++ b/includes/RhythmGameUtilities/UtilitiesInternal.hpp @@ -0,0 +1,64 @@ +#pragma once + +#include + +#include "Structs/BeatBar.h" + +#include "Utilities.hpp" + +#ifdef _WIN32 +#define PACKAGE_API __declspec(dllexport) +#else +#define PACKAGE_API +#endif + +namespace RhythmGameUtilities +{ + +extern "C" +{ + PACKAGE_API int ConvertSecondsToTicksInternal(float seconds, int resolution, + int *bpmChangesKeys, + int *bpmChangesValues, + int bpmChangesSize) + { + std::map bpmChanges; + + for (auto i = 0; i < bpmChangesSize; i += 1) + { + bpmChanges[bpmChangesKeys[i]] = bpmChangesValues[i]; + } + + return ConvertSecondsToTicks(seconds, resolution, bpmChanges); + } + + PACKAGE_API BeatBar * + CalculateBeatBarsInternal(int *bpmChangesKeys, int *bpmChangesValues, + int bpmChangesSize, int resolution, int ts, + bool includeHalfNotes, int *outSize) + { + auto bpmChanges = std::map(); + + for (auto i = 0; i < bpmChangesSize; i += 1) + { + bpmChanges[bpmChangesKeys[i]] = bpmChangesValues[i]; + } + + auto internalBeatBars = + CalculateBeatBars(bpmChanges, resolution, ts, includeHalfNotes); + + *outSize = internalBeatBars.size(); + + auto beatBars = + (BeatBar *)malloc(internalBeatBars.size() * sizeof(BeatBar)); + + for (auto i = 0; i < internalBeatBars.size(); i += 1) + { + beatBars[i] = internalBeatBars[i]; + } + + return beatBars; + } +} + +} // namespace RhythmGameUtilities diff --git a/tests/RhythmGameUtilities/Parsers.cpp b/tests/RhythmGameUtilities/Parsers.cpp index eb7f8c0..38dc789 100644 --- a/tests/RhythmGameUtilities/Parsers.cpp +++ b/tests/RhythmGameUtilities/Parsers.cpp @@ -104,54 +104,10 @@ void testParseValuesFromChartSections() std::cout << "."; } -void testParseSectionsFromChartInternal() -{ - int size = 0; - - auto sections = ParseSectionsFromChartInternal(contents, &size); - - assert(size == 4); - - assert(strcmp(sections[0].name, "Song") == 0); - assert(sections[0].lineCount == 12); - assert(strcmp(sections[1].name, "SyncTrack") == 0); - assert(sections[1].lineCount == 11); - assert(strcmp(sections[2].name, "Events") == 0); - assert(sections[2].lineCount == 16); - assert(strcmp(sections[3].name, "ExpertSingle") == 0); - assert(sections[3].lineCount == 11); - - std::cout << "."; -} - -void testParseValuesFromChartSectionsInternal() -{ - int size = 0; - - auto sections = ParseSectionsFromChartInternal(contents, &size); - - assert(size == 4); - - assert(sections[0].lineCount == 12); - - assert(strcmp(sections[0].lines[0].key, "Name") == 0); - assert(strcmp(sections[0].lines[0].values[0], "Example Song") == 0); - - assert(strcmp(sections[0].lines[6].key, "Resolution") == 0); - assert(strcmp(sections[0].lines[6].values[0], "192") == 0); - - assert(strcmp(sections[0].lines[11].key, "MusicStream") == 0); - assert(strcmp(sections[0].lines[11].values[0], "Example Song.ogg") == 0); - - std::cout << "."; -} - int main() { testParseSectionsFromChart(); testParseValuesFromChartSections(); - testParseSectionsFromChartInternal(); - testParseValuesFromChartSectionsInternal(); return 0; } diff --git a/tests/RhythmGameUtilities/ParsersInternal.cpp b/tests/RhythmGameUtilities/ParsersInternal.cpp new file mode 100644 index 0000000..c53b356 --- /dev/null +++ b/tests/RhythmGameUtilities/ParsersInternal.cpp @@ -0,0 +1,120 @@ +#include +#include +#include + +#include "RhythmGameUtilities/ParsersInternal.hpp" + +using namespace RhythmGameUtilities; + +auto contents = R"([Song] +{ + Name = "Example Song" + Artist = "Example Artist" + Album = "Example Album" + Genre = "Example Genre" + Year = ", 2021" + Charter = "Example Charter" + Resolution = 192 + Difficulty = 4 + Offset = 0.56 + PreviewStart = 45.28 + PreviewEnd = 75.28 + MusicStream = "Example Song.ogg" +} +[SyncTrack] +{ + 0 = TS 4 + 0 = B 88000 + 3840 = B 112000 + 9984 = TS 2 1 + 9984 = B 89600 + 22272 = TS 4 + 22272 = B 112000 + 33792 = B 111500 + 34560 = B 112000 + 42240 = B 111980 + 69120 = TS 2 1 +} +[Events] +{ + 768 = E "section Intro" + 9984 = E "phrase_start" + 9984 = E "section Verse 1" + 10080 = E "lyric Stand" + 10208 = E "lyric in" + 10344 = E "lyric line" + 10496 = E "lyric as" + 10608 = E "lyric we" + 10736 = E "lyric march" + 10896 = E "lyric to" + 11008 = E "lyric the" + 11112 = E "lyric drums" + 11268 = E "lyric of" + 11400 = E "lyric the" + 11520 = E "lyric east" + 11904 = E "phrase_end" +} +[ExpertSingle] +{ + 768 = N 0 0 + 768 = S 64 768 + 864 = N 1 0 + 864 = N 5 0 + 960 = N 2 0 + 960 = N 6 0 + 1056 = N 3 0 + 1056 = E solo + 1152 = N 4 0 + 1248 = N 7 0 + 1248 = E soloend +})"; + +void testParseSectionsFromChartInternal() +{ + int size = 0; + + auto sections = ParseSectionsFromChartInternal(contents, &size); + + assert(size == 4); + + assert(strcmp(sections[0].name, "Song") == 0); + assert(sections[0].lineCount == 12); + assert(strcmp(sections[1].name, "SyncTrack") == 0); + assert(sections[1].lineCount == 11); + assert(strcmp(sections[2].name, "Events") == 0); + assert(sections[2].lineCount == 16); + assert(strcmp(sections[3].name, "ExpertSingle") == 0); + assert(sections[3].lineCount == 11); + + std::cout << "."; +} + +void testParseValuesFromChartSectionsInternal() +{ + int size = 0; + + auto sections = ParseSectionsFromChartInternal(contents, &size); + + assert(size == 4); + + assert(sections[0].lineCount == 12); + + assert(strcmp(sections[0].lines[0].key, "Name") == 0); + assert(strcmp(sections[0].lines[0].values[0], "Example Song") == 0); + + assert(strcmp(sections[0].lines[6].key, "Resolution") == 0); + assert(strcmp(sections[0].lines[6].values[0], "192") == 0); + + assert(strcmp(sections[0].lines[11].key, "MusicStream") == 0); + assert(strcmp(sections[0].lines[11].values[0], "Example Song.ogg") == 0); + + std::cout << "."; +} + +int main() +{ + testParseSectionsFromChartInternal(); + testParseValuesFromChartSectionsInternal(); + + return 0; +} diff --git a/tests/RhythmGameUtilities/Utilities.cpp b/tests/RhythmGameUtilities/Utilities.cpp index 0a62f0d..976bda2 100644 --- a/tests/RhythmGameUtilities/Utilities.cpp +++ b/tests/RhythmGameUtilities/Utilities.cpp @@ -105,32 +105,6 @@ void testCalculateBeatBars() std::cout << "."; } -void testCalculateBeatBarsInternal() -{ - std::map bpmChanges = { - {0, 88000}, {3840, 112000}, {9984, 89600}, {22272, 112000}, - {33792, 111500}, {34560, 112000}, {42240, 111980}}; - - std::vector bpmChangesKeys; - std::vector bpmChangesValues; - - for (const auto &[key, value] : bpmChanges) - { - bpmChangesKeys.push_back(key); - bpmChangesValues.push_back(value); - } - - int *outSize; - - auto beatBars = - CalculateBeatBarsInternal(&bpmChangesKeys[0], &bpmChangesValues[0], - size(bpmChanges), 192, 4, true, outSize); - - assert(*outSize == 446); - - std::cout << "."; -} - void testFindAllMatches() { std::regex pattern("\\w+"); @@ -166,7 +140,6 @@ int main() testSplit(); testGenerateAdjacentKeyPairs(); testCalculateBeatBars(); - testCalculateBeatBarsInternal(); testFindAllMatches(); testFindMatchGroups(); diff --git a/tests/RhythmGameUtilities/UtilitiesInternal.cpp b/tests/RhythmGameUtilities/UtilitiesInternal.cpp new file mode 100644 index 0000000..82daa35 --- /dev/null +++ b/tests/RhythmGameUtilities/UtilitiesInternal.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include "RhythmGameUtilities/UtilitiesInternal.hpp" + +using namespace RhythmGameUtilities; + +void testConvertSecondsToTicksInternal() +{ + std::map bpmChanges = { + {0, 88000}, {3840, 112000}, {9984, 89600}, {22272, 112000}, + {33792, 111500}, {34560, 112000}, {42240, 111980}}; + + std::vector bpmChangesKeys; + std::vector bpmChangesValues; + + for (const auto &[key, value] : bpmChanges) + { + bpmChangesKeys.push_back(key); + bpmChangesValues.push_back(value); + } + + assert(1408 == ConvertSecondsToTicksInternal(5, 192, &bpmChangesKeys[0], + &bpmChangesValues[0], + size(bpmChanges))); + + std::cout << "."; +} + +void testCalculateBeatBarsInternal() +{ + std::map bpmChanges = { + {0, 88000}, {3840, 112000}, {9984, 89600}, {22272, 112000}, + {33792, 111500}, {34560, 112000}, {42240, 111980}}; + + std::vector bpmChangesKeys; + std::vector bpmChangesValues; + + for (const auto &[key, value] : bpmChanges) + { + bpmChangesKeys.push_back(key); + bpmChangesValues.push_back(value); + } + + int *outSize; + + auto beatBars = + CalculateBeatBarsInternal(&bpmChangesKeys[0], &bpmChangesValues[0], + size(bpmChanges), 192, 4, true, outSize); + + assert(*outSize == 446); + + std::cout << "."; +} + +int main() +{ + testConvertSecondsToTicksInternal(); + testCalculateBeatBarsInternal(); + + return 0; +}