From 08ef08f2e6e7f0ffb275e40758c8001a1334be10 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Sun, 3 Nov 2024 10:19:27 -0500 Subject: [PATCH 01/19] Added godot-cpp submodule. --- .gitmodules | 3 +++ GodotPlugin/godot-cpp | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 GodotPlugin/godot-cpp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e0603cd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "GodotPlugin/godot-cpp"] + path = GodotPlugin/godot-cpp + url = https://github.com/godotengine/godot-cpp.git diff --git a/GodotPlugin/godot-cpp b/GodotPlugin/godot-cpp new file mode 160000 index 0000000..fbbf9ec --- /dev/null +++ b/GodotPlugin/godot-cpp @@ -0,0 +1 @@ +Subproject commit fbbf9ec4efd8f1055d00edb8d926eef8ba4c2cce From 1cb407b0a721df342cf2b5a3e5b1a23c5689f5d9 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Sun, 3 Nov 2024 10:20:26 -0500 Subject: [PATCH 02/19] Started building out Godot plugin. --- GodotPlugin/.gitignore | 4 ++ GodotPlugin/RhythmGameUtilities.gdextension | 9 ++++ GodotPlugin/SConstruct.py | 26 +++++++++++ GodotPlugin/include/register_types.cpp | 46 +++++++++++++++++++ GodotPlugin/include/register_types.h | 4 ++ GodotPlugin/include/rhythm_game_utilities.cpp | 24 ++++++++++ GodotPlugin/include/rhythm_game_utilities.h | 20 ++++++++ 7 files changed, 133 insertions(+) create mode 100644 GodotPlugin/.gitignore create mode 100644 GodotPlugin/RhythmGameUtilities.gdextension create mode 100644 GodotPlugin/SConstruct.py create mode 100644 GodotPlugin/include/register_types.cpp create mode 100644 GodotPlugin/include/register_types.h create mode 100644 GodotPlugin/include/rhythm_game_utilities.cpp create mode 100644 GodotPlugin/include/rhythm_game_utilities.h diff --git a/GodotPlugin/.gitignore b/GodotPlugin/.gitignore new file mode 100644 index 0000000..1e7ad28 --- /dev/null +++ b/GodotPlugin/.gitignore @@ -0,0 +1,4 @@ +addons/ + +*.os +*.dblite diff --git a/GodotPlugin/RhythmGameUtilities.gdextension b/GodotPlugin/RhythmGameUtilities.gdextension new file mode 100644 index 0000000..f696e2a --- /dev/null +++ b/GodotPlugin/RhythmGameUtilities.gdextension @@ -0,0 +1,9 @@ +[configuration] + +entry_symbol = "rhythm_game_utilities" +compatibility_minimum = 4.1 + +[libraries] + +macos.debug = "res://addons/RhythmGameUtilities/rhythm_game_utilities.macos.template_debug" +macos.release = "res://addons/RhythmGameUtilities/rhythm_game_utilities.macos.template_release" diff --git a/GodotPlugin/SConstruct.py b/GodotPlugin/SConstruct.py new file mode 100644 index 0000000..5dfb0d2 --- /dev/null +++ b/GodotPlugin/SConstruct.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python + +import os +import sys + +env = SConscript("godot-cpp/SConstruct") + +env.Append(CPPPATH=["include/", "../include"]) +sources = Glob("include/*.cpp") + +library = env.SharedLibrary( + "build/addons/libRhythmGameUtilities.{}.{}".format(env["platform"], env["target"]), + source=sources +) + +gdextension_copy = env.Command( + target="build/addons/RhythmGameUtilities.gdextension", + source="RhythmGameUtilities.gdextension", + action=Copy("$TARGET", "$SOURCE") +) + +env.Depends(gdextension_copy, library) + +Default(library) + +Default(gdextension_copy) diff --git a/GodotPlugin/include/register_types.cpp b/GodotPlugin/include/register_types.cpp new file mode 100644 index 0000000..65cc5a9 --- /dev/null +++ b/GodotPlugin/include/register_types.cpp @@ -0,0 +1,46 @@ +#include "register_types.h" + +#include "rhythm_game_utilities.h" + +#include +#include +#include +#include + +using namespace godot; + +void initialize_rhythm_game_utilities(ModuleInitializationLevel p_level) +{ + if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) + { + return; + } + + ClassDB::register_class(true); +} + +void terminate_rhythm_game_utilities(ModuleInitializationLevel p_level) +{ + if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) + { + return; + } +} + +extern "C" +{ + GDExtensionBool GDE_EXPORT + rhythm_game_utilities(GDExtensionInterfaceGetProcAddress p_get_proc_address, + const GDExtensionClassLibraryPtr p_library, + GDExtensionInitialization *r_initialization) + { + + godot::GDExtensionBinding::InitObject init_obj( + p_get_proc_address, p_library, r_initialization); + + init_obj.register_initializer(initialize_rhythm_game_utilities); + init_obj.register_terminator(terminate_rhythm_game_utilities); + + return init_obj.init(); + } +} diff --git a/GodotPlugin/include/register_types.h b/GodotPlugin/include/register_types.h new file mode 100644 index 0000000..bffff7b --- /dev/null +++ b/GodotPlugin/include/register_types.h @@ -0,0 +1,4 @@ +#pragma once + +void initialize_rhythm_game_utilities(); +void terminate_rhythm_game_utilities(); diff --git a/GodotPlugin/include/rhythm_game_utilities.cpp b/GodotPlugin/include/rhythm_game_utilities.cpp new file mode 100644 index 0000000..60b3bc2 --- /dev/null +++ b/GodotPlugin/include/rhythm_game_utilities.cpp @@ -0,0 +1,24 @@ +#include "rhythm_game_utilities.h" + +#include + +void rhythm_game_utilities::_bind_methods() +{ + ClassDB::bind_static_method("rhythm_game_utilities", + D_METHOD("lerp", "a", "b", "t"), + &rhythm_game_utilities::lerp); + + ClassDB::bind_static_method("rhythm_game_utilities", + D_METHOD("inverse_lerp", "a", "b", "v"), + &rhythm_game_utilities::inverse_lerp); +} + +float rhythm_game_utilities::lerp(float a, float b, float t) +{ + return RhythmGameUtilities::Lerp(a, b, t); +} + +float rhythm_game_utilities::inverse_lerp(float a, float b, float v) +{ + return RhythmGameUtilities::InverseLerp(a, b, v); +} diff --git a/GodotPlugin/include/rhythm_game_utilities.h b/GodotPlugin/include/rhythm_game_utilities.h new file mode 100644 index 0000000..8ba8c2d --- /dev/null +++ b/GodotPlugin/include/rhythm_game_utilities.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include + +using namespace godot; + +class rhythm_game_utilities : public Object +{ + GDCLASS(rhythm_game_utilities, Object) + + protected: + static void _bind_methods(); + + public: + static float lerp(float a, float b, float t); + + static float inverse_lerp(float a, float b, float v); +}; From 13b23200c4f955cdb29bb6e19781a8f480bb2350 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Sun, 3 Nov 2024 13:18:28 -0500 Subject: [PATCH 03/19] Fixed naming collision. --- GodotPlugin/RhythmGameUtilities.gdextension | 2 +- GodotPlugin/include/register_types.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/GodotPlugin/RhythmGameUtilities.gdextension b/GodotPlugin/RhythmGameUtilities.gdextension index f696e2a..a7dca5d 100644 --- a/GodotPlugin/RhythmGameUtilities.gdextension +++ b/GodotPlugin/RhythmGameUtilities.gdextension @@ -1,6 +1,6 @@ [configuration] -entry_symbol = "rhythm_game_utilities" +entry_symbol = "rhythm_game_utilities_plugin" compatibility_minimum = 4.1 [libraries] diff --git a/GodotPlugin/include/register_types.cpp b/GodotPlugin/include/register_types.cpp index 65cc5a9..d670d4c 100644 --- a/GodotPlugin/include/register_types.cpp +++ b/GodotPlugin/include/register_types.cpp @@ -29,10 +29,10 @@ void terminate_rhythm_game_utilities(ModuleInitializationLevel p_level) extern "C" { - GDExtensionBool GDE_EXPORT - rhythm_game_utilities(GDExtensionInterfaceGetProcAddress p_get_proc_address, - const GDExtensionClassLibraryPtr p_library, - GDExtensionInitialization *r_initialization) + GDExtensionBool GDE_EXPORT rhythm_game_utilities_plugin( + GDExtensionInterfaceGetProcAddress p_get_proc_address, + const GDExtensionClassLibraryPtr p_library, + GDExtensionInitialization *r_initialization) { godot::GDExtensionBinding::InitObject init_obj( From 6932d6bf42c8021eae5e85a77fbd7de9726cba34 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Sun, 3 Nov 2024 13:21:28 -0500 Subject: [PATCH 04/19] Fixed path issue with build. --- GodotPlugin/RhythmGameUtilities.gdextension | 4 ++-- GodotPlugin/SConstruct.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/GodotPlugin/RhythmGameUtilities.gdextension b/GodotPlugin/RhythmGameUtilities.gdextension index a7dca5d..7fac7bb 100644 --- a/GodotPlugin/RhythmGameUtilities.gdextension +++ b/GodotPlugin/RhythmGameUtilities.gdextension @@ -5,5 +5,5 @@ compatibility_minimum = 4.1 [libraries] -macos.debug = "res://addons/RhythmGameUtilities/rhythm_game_utilities.macos.template_debug" -macos.release = "res://addons/RhythmGameUtilities/rhythm_game_utilities.macos.template_release" +macos.debug = "res://addons/RhythmGameUtilities/libRhythmGameUtilities.macos.template_debug" +macos.release = "res://addons/RhythmGameUtilities/libRhythmGameUtilities.macos.template_release" diff --git a/GodotPlugin/SConstruct.py b/GodotPlugin/SConstruct.py index 5dfb0d2..a7f0591 100644 --- a/GodotPlugin/SConstruct.py +++ b/GodotPlugin/SConstruct.py @@ -9,12 +9,13 @@ sources = Glob("include/*.cpp") library = env.SharedLibrary( - "build/addons/libRhythmGameUtilities.{}.{}".format(env["platform"], env["target"]), + "build/addons/RhythmGameUtilities/libRhythmGameUtilities.{}.{}" + .format(env["platform"], env["target"]), source=sources ) gdextension_copy = env.Command( - target="build/addons/RhythmGameUtilities.gdextension", + target="build/addons/RhythmGameUtilities/RhythmGameUtilities.gdextension", source="RhythmGameUtilities.gdextension", action=Copy("$TARGET", "$SOURCE") ) From fd45eed3e20088882c8c44c4859564e1a153d78d Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Sun, 3 Nov 2024 13:30:32 -0500 Subject: [PATCH 05/19] Changed target min to match godot-cpp version. --- GodotPlugin/RhythmGameUtilities.gdextension | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GodotPlugin/RhythmGameUtilities.gdextension b/GodotPlugin/RhythmGameUtilities.gdextension index 7fac7bb..ff5931a 100644 --- a/GodotPlugin/RhythmGameUtilities.gdextension +++ b/GodotPlugin/RhythmGameUtilities.gdextension @@ -1,7 +1,7 @@ [configuration] entry_symbol = "rhythm_game_utilities_plugin" -compatibility_minimum = 4.1 +compatibility_minimum = 4.3 [libraries] From 4de232a77d22f6e58eeb93c5dd1bd647a6485abd Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Sun, 3 Nov 2024 13:36:04 -0500 Subject: [PATCH 06/19] Whitespace. --- GodotPlugin/include/register_types.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/GodotPlugin/include/register_types.cpp b/GodotPlugin/include/register_types.cpp index d670d4c..78ef967 100644 --- a/GodotPlugin/include/register_types.cpp +++ b/GodotPlugin/include/register_types.cpp @@ -34,7 +34,6 @@ extern "C" const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) { - godot::GDExtensionBinding::InitObject init_obj( p_get_proc_address, p_library, r_initialization); From aba2c8e11f4c6b36a8facb01812ba91592c299b7 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Sun, 3 Nov 2024 14:34:38 -0500 Subject: [PATCH 07/19] Added additional methods. --- GodotPlugin/include/rhythm_game_utilities.cpp | 56 +++++++++++++++++++ GodotPlugin/include/rhythm_game_utilities.h | 13 +++++ 2 files changed, 69 insertions(+) diff --git a/GodotPlugin/include/rhythm_game_utilities.cpp b/GodotPlugin/include/rhythm_game_utilities.cpp index 60b3bc2..93f1568 100644 --- a/GodotPlugin/include/rhythm_game_utilities.cpp +++ b/GodotPlugin/include/rhythm_game_utilities.cpp @@ -1,9 +1,12 @@ #include "rhythm_game_utilities.h" #include +#include void rhythm_game_utilities::_bind_methods() { + // Common + ClassDB::bind_static_method("rhythm_game_utilities", D_METHOD("lerp", "a", "b", "t"), &rhythm_game_utilities::lerp); @@ -11,8 +14,33 @@ void rhythm_game_utilities::_bind_methods() ClassDB::bind_static_method("rhythm_game_utilities", D_METHOD("inverse_lerp", "a", "b", "v"), &rhythm_game_utilities::inverse_lerp); + + // Utilities + + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("convert_tick_to_position", "tick", "resolution"), + &rhythm_game_utilities::convert_tick_to_position); + + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("is_on_the_beat", "bpm", "currentTime", "delta"), + &rhythm_game_utilities::is_on_the_beat); + + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("round_up_to_the_nearest_multiplier", "value", "multiplier"), + &rhythm_game_utilities::round_up_to_the_nearest_multiplier); + + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("calculate_accuracy_ratio", "position", "currentPosition", + "delta"), + &rhythm_game_utilities::calculate_accuracy_ratio); } +// Common + float rhythm_game_utilities::lerp(float a, float b, float t) { return RhythmGameUtilities::Lerp(a, b, t); @@ -22,3 +50,31 @@ float rhythm_game_utilities::inverse_lerp(float a, float b, float v) { return RhythmGameUtilities::InverseLerp(a, b, v); } + +// Utilities + +float rhythm_game_utilities::convert_tick_to_position(int tick, int resolution) +{ + return RhythmGameUtilities::ConvertTickToPosition(tick, resolution); +} + +bool rhythm_game_utilities::is_on_the_beat(int bpm, float currentTime, + float delta) +{ + return RhythmGameUtilities::IsOnTheBeat(bpm, currentTime, delta); +} + +int rhythm_game_utilities::round_up_to_the_nearest_multiplier(int value, + int multiplier) +{ + return RhythmGameUtilities::RoundUpToTheNearestMultiplier(value, + multiplier); +} + +float rhythm_game_utilities::calculate_accuracy_ratio(int position, + int currentPosition, + int delta) +{ + return RhythmGameUtilities::CalculateAccuracyRatio(position, + currentPosition, delta); +} diff --git a/GodotPlugin/include/rhythm_game_utilities.h b/GodotPlugin/include/rhythm_game_utilities.h index 8ba8c2d..0a4a4e5 100644 --- a/GodotPlugin/include/rhythm_game_utilities.h +++ b/GodotPlugin/include/rhythm_game_utilities.h @@ -14,7 +14,20 @@ class rhythm_game_utilities : public Object static void _bind_methods(); public: + // Common + static float lerp(float a, float b, float t); static float inverse_lerp(float a, float b, float v); + + // Utilities + + static float convert_tick_to_position(int tick, int resolution); + + static bool is_on_the_beat(int bpm, float currentTime, float delta = 0.05f); + + static int round_up_to_the_nearest_multiplier(int value, int multiplier); + + static float calculate_accuracy_ratio(int position, int currentPosition, + int delta = 50); }; From 2b3f9f19bf72dc3935ac55433e9eb792ce191545 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Sun, 3 Nov 2024 18:22:45 -0500 Subject: [PATCH 08/19] Added new method. --- GodotPlugin/include/rhythm_game_utilities.cpp | 26 +++++++++++++++++++ GodotPlugin/include/rhythm_game_utilities.h | 4 +++ 2 files changed, 30 insertions(+) diff --git a/GodotPlugin/include/rhythm_game_utilities.cpp b/GodotPlugin/include/rhythm_game_utilities.cpp index 93f1568..3ca8783 100644 --- a/GodotPlugin/include/rhythm_game_utilities.cpp +++ b/GodotPlugin/include/rhythm_game_utilities.cpp @@ -1,5 +1,7 @@ #include "rhythm_game_utilities.h" +#include + #include #include @@ -17,6 +19,12 @@ void rhythm_game_utilities::_bind_methods() // Utilities + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("convert_seconds_to_ticks", "seconds", "resolution", + "bpmChanges"), + &rhythm_game_utilities::convert_seconds_to_ticks); + ClassDB::bind_static_method( "rhythm_game_utilities", D_METHOD("convert_tick_to_position", "tick", "resolution"), @@ -53,6 +61,24 @@ float rhythm_game_utilities::inverse_lerp(float a, float b, float v) // Utilities +int rhythm_game_utilities::convert_seconds_to_ticks(float seconds, + int resolution, + Dictionary bpmChanges) +{ + std::map bpmChangesMap; + + auto keys = bpmChanges.keys(); + + for (auto i = 0; i < keys.size(); i += 1) + { + auto key = keys[i]; + bpmChangesMap[key] = bpmChanges[key]; + } + + return RhythmGameUtilities::ConvertSecondsToTicks(seconds, resolution, + bpmChangesMap); +} + float rhythm_game_utilities::convert_tick_to_position(int tick, int resolution) { return RhythmGameUtilities::ConvertTickToPosition(tick, resolution); diff --git a/GodotPlugin/include/rhythm_game_utilities.h b/GodotPlugin/include/rhythm_game_utilities.h index 0a4a4e5..124f956 100644 --- a/GodotPlugin/include/rhythm_game_utilities.h +++ b/GodotPlugin/include/rhythm_game_utilities.h @@ -2,6 +2,7 @@ #include #include +#include #include using namespace godot; @@ -22,6 +23,9 @@ class rhythm_game_utilities : public Object // Utilities + static int convert_seconds_to_ticks(float seconds, int resolution, + Dictionary bpmChanges); + static float convert_tick_to_position(int tick, int resolution); static bool is_on_the_beat(int bpm, float currentTime, float delta = 0.05f); From 01a01016ae1bc94596f101b2f5ff3fcbc580a574 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Sun, 3 Nov 2024 19:03:18 -0500 Subject: [PATCH 09/19] Added documentation. --- Documentation/API/Common/InverseLerp.md | 11 +++ Documentation/API/Common/Lerp.md | 11 +++ .../API/Utilities/ConvertSecondsToTicks.md | 20 +++++ .../API/Utilities/ConvertTickToPosition.md | 14 ++++ Documentation/API/Utilities/IsOnTheBeat.md | 14 ++++ .../RoundUpToTheNearestMultiplier.md | 11 +++ README.md | 81 +++++++++++++++++++ RhythmGameUtilities/README.md | 81 +++++++++++++++++++ UnityPackage/README.md | 81 +++++++++++++++++++ 9 files changed, 324 insertions(+) diff --git a/Documentation/API/Common/InverseLerp.md b/Documentation/API/Common/InverseLerp.md index 0bfeffc..ca546cb 100644 --- a/Documentation/API/Common/InverseLerp.md +++ b/Documentation/API/Common/InverseLerp.md @@ -31,3 +31,14 @@ int main() return 0; } ``` + +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.inverse_lerp(0, 10, 5) + + print(value) # 0.5 +``` diff --git a/Documentation/API/Common/Lerp.md b/Documentation/API/Common/Lerp.md index 08785a0..aa23461 100644 --- a/Documentation/API/Common/Lerp.md +++ b/Documentation/API/Common/Lerp.md @@ -31,3 +31,14 @@ int main() return 0; } ``` + +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.lerp(0, 10, 0.5) + + print(value) # 5 +``` diff --git a/Documentation/API/Utilities/ConvertSecondsToTicks.md b/Documentation/API/Utilities/ConvertSecondsToTicks.md index 188e835..533e0a8 100644 --- a/Documentation/API/Utilities/ConvertSecondsToTicks.md +++ b/Documentation/API/Utilities/ConvertSecondsToTicks.md @@ -52,3 +52,23 @@ int main() return 0; } ``` + +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var seconds = 5; + var resolution = 192; + + var bpmChanges = { + 0: 88000, 3840: 112000, 9984: 89600, + 22272: 112000, 33792: 111500, 34560: 112000, + 42240: 111980 + } + + var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpmChanges); + + print(ticks) # 1408 +``` diff --git a/Documentation/API/Utilities/ConvertTickToPosition.md b/Documentation/API/Utilities/ConvertTickToPosition.md index df36ec9..09358b1 100644 --- a/Documentation/API/Utilities/ConvertTickToPosition.md +++ b/Documentation/API/Utilities/ConvertTickToPosition.md @@ -37,3 +37,17 @@ int main() return 0; } ``` + +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var tick = 2784; + var resolution = 192; + + var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution); + + print(position) # 14.5 +``` diff --git a/Documentation/API/Utilities/IsOnTheBeat.md b/Documentation/API/Utilities/IsOnTheBeat.md index 005a42f..9d9a195 100644 --- a/Documentation/API/Utilities/IsOnTheBeat.md +++ b/Documentation/API/Utilities/IsOnTheBeat.md @@ -41,3 +41,17 @@ int main() return 0; } ``` + +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var bpm = 120; + var currentTime = 10; + var delta = 0.05; + + if rhythm_game_utilities.is_on_the_beat(bpm, currentTime, delta): + print("Is on the beat!") +``` diff --git a/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md b/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md index a6a1f58..b820a5a 100644 --- a/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md +++ b/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md @@ -31,3 +31,14 @@ int main() return 0; } ``` + +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10); + + print(value) # 20 +``` diff --git a/README.md b/README.md index c9a7a52..57f58ce 100644 --- a/README.md +++ b/README.md @@ -263,6 +263,17 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.inverse_lerp(0, 10, 5) + + print(value) # 0.5 +``` + #### `Common.Lerp` > Languages: `C#` `C++` @@ -297,6 +308,17 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.lerp(0, 10, 0.5) + + print(value) # 5 +``` + ### `Parsers` Read more about `.chart` files: @@ -724,6 +746,26 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var seconds = 5; + var resolution = 192; + + var bpmChanges = { + 0: 88000, 3840: 112000, 9984: 89600, + 22272: 112000, 33792: 111500, 34560: 112000, + 42240: 111980 + } + + var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpmChanges); + + print(ticks) # 1408 +``` + #### `Utilities.ConvertTickToPosition` > Languages: `C#` `C++` @@ -764,6 +806,20 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var tick = 2784; + var resolution = 192; + + var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution); + + print(position) # 14.5 +``` + #### `Utilities.IsOnTheBeat` > Languages: `C#` `C++` @@ -808,6 +864,20 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var bpm = 120; + var currentTime = 10; + var delta = 0.05; + + if rhythm_game_utilities.is_on_the_beat(bpm, currentTime, delta): + print("Is on the beat!") +``` + #### `Utilities.RoundUpToTheNearestMultiplier` > Languages: `C#` `C++` @@ -842,6 +912,17 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10); + + print(value) # 20 +``` + ## Architecture The current architecture for this project looks like this: diff --git a/RhythmGameUtilities/README.md b/RhythmGameUtilities/README.md index c9a7a52..57f58ce 100644 --- a/RhythmGameUtilities/README.md +++ b/RhythmGameUtilities/README.md @@ -263,6 +263,17 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.inverse_lerp(0, 10, 5) + + print(value) # 0.5 +``` + #### `Common.Lerp` > Languages: `C#` `C++` @@ -297,6 +308,17 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.lerp(0, 10, 0.5) + + print(value) # 5 +``` + ### `Parsers` Read more about `.chart` files: @@ -724,6 +746,26 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var seconds = 5; + var resolution = 192; + + var bpmChanges = { + 0: 88000, 3840: 112000, 9984: 89600, + 22272: 112000, 33792: 111500, 34560: 112000, + 42240: 111980 + } + + var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpmChanges); + + print(ticks) # 1408 +``` + #### `Utilities.ConvertTickToPosition` > Languages: `C#` `C++` @@ -764,6 +806,20 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var tick = 2784; + var resolution = 192; + + var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution); + + print(position) # 14.5 +``` + #### `Utilities.IsOnTheBeat` > Languages: `C#` `C++` @@ -808,6 +864,20 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var bpm = 120; + var currentTime = 10; + var delta = 0.05; + + if rhythm_game_utilities.is_on_the_beat(bpm, currentTime, delta): + print("Is on the beat!") +``` + #### `Utilities.RoundUpToTheNearestMultiplier` > Languages: `C#` `C++` @@ -842,6 +912,17 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10); + + print(value) # 20 +``` + ## Architecture The current architecture for this project looks like this: diff --git a/UnityPackage/README.md b/UnityPackage/README.md index c9a7a52..57f58ce 100644 --- a/UnityPackage/README.md +++ b/UnityPackage/README.md @@ -263,6 +263,17 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.inverse_lerp(0, 10, 5) + + print(value) # 0.5 +``` + #### `Common.Lerp` > Languages: `C#` `C++` @@ -297,6 +308,17 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.lerp(0, 10, 0.5) + + print(value) # 5 +``` + ### `Parsers` Read more about `.chart` files: @@ -724,6 +746,26 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var seconds = 5; + var resolution = 192; + + var bpmChanges = { + 0: 88000, 3840: 112000, 9984: 89600, + 22272: 112000, 33792: 111500, 34560: 112000, + 42240: 111980 + } + + var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpmChanges); + + print(ticks) # 1408 +``` + #### `Utilities.ConvertTickToPosition` > Languages: `C#` `C++` @@ -764,6 +806,20 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var tick = 2784; + var resolution = 192; + + var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution); + + print(position) # 14.5 +``` + #### `Utilities.IsOnTheBeat` > Languages: `C#` `C++` @@ -808,6 +864,20 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var bpm = 120; + var currentTime = 10; + var delta = 0.05; + + if rhythm_game_utilities.is_on_the_beat(bpm, currentTime, delta): + print("Is on the beat!") +``` + #### `Utilities.RoundUpToTheNearestMultiplier` > Languages: `C#` `C++` @@ -842,6 +912,17 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10); + + print(value) # 20 +``` + ## Architecture The current architecture for this project looks like this: From aa3e449d02b6528ce40a1d95391910d60b2a40df Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Mon, 4 Nov 2024 18:44:11 -0500 Subject: [PATCH 10/19] Added new method. --- .../API/Utilities/CalculateBeatBars.md | 20 +++++++++ GodotPlugin/include/rhythm_game_utilities.cpp | 45 +++++++++++++------ GodotPlugin/include/rhythm_game_utilities.h | 4 ++ GodotPlugin/include/utilities.hpp | 23 ++++++++++ README.md | 20 +++++++++ RhythmGameUtilities/README.md | 20 +++++++++ UnityPackage/README.md | 20 +++++++++ 7 files changed, 139 insertions(+), 13 deletions(-) create mode 100644 GodotPlugin/include/utilities.hpp diff --git a/Documentation/API/Utilities/CalculateBeatBars.md b/Documentation/API/Utilities/CalculateBeatBars.md index 0553abe..d3f7b55 100644 --- a/Documentation/API/Utilities/CalculateBeatBars.md +++ b/Documentation/API/Utilities/CalculateBeatBars.md @@ -50,3 +50,23 @@ int main() return 0; } ``` + +##### Godot + +```godot +extends Node + +func _ready() -> void: + var resolution = 192; + var timeSignature = 4; + + var bpmChanges = { + 0: 88000, 3840: 112000, 9984: 89600, + 22272: 112000, 33792: 111500, 34560: 112000, + 42240: 111980 + } + + var beatBars = rhythm_game_utilities.calculate_beat_bars(bpmChanges, resolution, timeSignature, true); + + print(beatBars) +``` diff --git a/GodotPlugin/include/rhythm_game_utilities.cpp b/GodotPlugin/include/rhythm_game_utilities.cpp index 3ca8783..6d812da 100644 --- a/GodotPlugin/include/rhythm_game_utilities.cpp +++ b/GodotPlugin/include/rhythm_game_utilities.cpp @@ -1,6 +1,6 @@ #include "rhythm_game_utilities.h" -#include +#include "utilities.hpp" #include #include @@ -45,6 +45,12 @@ void rhythm_game_utilities::_bind_methods() D_METHOD("calculate_accuracy_ratio", "position", "currentPosition", "delta"), &rhythm_game_utilities::calculate_accuracy_ratio); + + ClassDB::bind_static_method("rhythm_game_utilities", + D_METHOD("calculate_beat_bars", "bpmChanges", + "resolution", "ts", + "includeHalfNotes"), + &rhythm_game_utilities::calculate_beat_bars); } // Common @@ -65,18 +71,8 @@ int rhythm_game_utilities::convert_seconds_to_ticks(float seconds, int resolution, Dictionary bpmChanges) { - std::map bpmChangesMap; - - auto keys = bpmChanges.keys(); - - for (auto i = 0; i < keys.size(); i += 1) - { - auto key = keys[i]; - bpmChangesMap[key] = bpmChanges[key]; - } - - return RhythmGameUtilities::ConvertSecondsToTicks(seconds, resolution, - bpmChangesMap); + return RhythmGameUtilities::ConvertSecondsToTicks( + seconds, resolution, convert_dictionary_to_map(bpmChanges)); } float rhythm_game_utilities::convert_tick_to_position(int tick, int resolution) @@ -104,3 +100,26 @@ float rhythm_game_utilities::calculate_accuracy_ratio(int position, return RhythmGameUtilities::CalculateAccuracyRatio(position, currentPosition, delta); } + +Array rhythm_game_utilities::calculate_beat_bars(Dictionary bpmChanges, + int resolution, int ts, + bool includeHalfNotes) +{ + auto beatBars = RhythmGameUtilities::CalculateBeatBars( + convert_dictionary_to_map(bpmChanges), resolution, ts, + includeHalfNotes); + + Array beatBarsDictionaryArray; + + for (auto &beatBar : beatBars) + { + Dictionary beatBarDictionary; + + beatBarDictionary["bpm"] = beatBar.BPM; + beatBarDictionary["position"] = beatBar.Position; + + beatBarsDictionaryArray.append(beatBarDictionary); + } + + return beatBarsDictionaryArray; +} diff --git a/GodotPlugin/include/rhythm_game_utilities.h b/GodotPlugin/include/rhythm_game_utilities.h index 124f956..8a00d1d 100644 --- a/GodotPlugin/include/rhythm_game_utilities.h +++ b/GodotPlugin/include/rhythm_game_utilities.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -34,4 +35,7 @@ class rhythm_game_utilities : public Object static float calculate_accuracy_ratio(int position, int currentPosition, int delta = 50); + + static Array calculate_beat_bars(Dictionary bpmChanges, int resolution, + int ts, bool includeHalfNotes); }; diff --git a/GodotPlugin/include/utilities.hpp b/GodotPlugin/include/utilities.hpp new file mode 100644 index 0000000..6b52508 --- /dev/null +++ b/GodotPlugin/include/utilities.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include + +using namespace godot; + +template +std::map convert_dictionary_to_map(Dictionary input) +{ + std::map output; + + auto keys = input.keys(); + + for (auto i = 0; i < keys.size(); i += 1) + { + auto key = keys[i]; + output[key] = input[key]; + } + + return output; +} diff --git a/README.md b/README.md index 57f58ce..dd1a948 100644 --- a/README.md +++ b/README.md @@ -691,6 +691,26 @@ int main() } ``` +##### Godot + +```godot +extends Node + +func _ready() -> void: + var resolution = 192; + var timeSignature = 4; + + var bpmChanges = { + 0: 88000, 3840: 112000, 9984: 89600, + 22272: 112000, 33792: 111500, 34560: 112000, + 42240: 111980 + } + + var beatBars = rhythm_game_utilities.calculate_beat_bars(bpmChanges, resolution, timeSignature, true); + + print(beatBars) +``` + #### `Utilities.ConvertSecondsToTicks` > Languages: `C#` `C++` diff --git a/RhythmGameUtilities/README.md b/RhythmGameUtilities/README.md index 57f58ce..dd1a948 100644 --- a/RhythmGameUtilities/README.md +++ b/RhythmGameUtilities/README.md @@ -691,6 +691,26 @@ int main() } ``` +##### Godot + +```godot +extends Node + +func _ready() -> void: + var resolution = 192; + var timeSignature = 4; + + var bpmChanges = { + 0: 88000, 3840: 112000, 9984: 89600, + 22272: 112000, 33792: 111500, 34560: 112000, + 42240: 111980 + } + + var beatBars = rhythm_game_utilities.calculate_beat_bars(bpmChanges, resolution, timeSignature, true); + + print(beatBars) +``` + #### `Utilities.ConvertSecondsToTicks` > Languages: `C#` `C++` diff --git a/UnityPackage/README.md b/UnityPackage/README.md index 57f58ce..dd1a948 100644 --- a/UnityPackage/README.md +++ b/UnityPackage/README.md @@ -691,6 +691,26 @@ int main() } ``` +##### Godot + +```godot +extends Node + +func _ready() -> void: + var resolution = 192; + var timeSignature = 4; + + var bpmChanges = { + 0: 88000, 3840: 112000, 9984: 89600, + 22272: 112000, 33792: 111500, 34560: 112000, + 42240: 111980 + } + + var beatBars = rhythm_game_utilities.calculate_beat_bars(bpmChanges, resolution, timeSignature, true); + + print(beatBars) +``` + #### `Utilities.ConvertSecondsToTicks` > Languages: `C#` `C++` From 2f2fe33f6860154ddbbed7c7506d7a6b1e11d0f9 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Tue, 5 Nov 2024 01:31:52 -0500 Subject: [PATCH 11/19] Added new method. --- GodotPlugin/include/rhythm_game_utilities.cpp | 46 +++++++++++++++++++ GodotPlugin/include/rhythm_game_utilities.h | 4 ++ 2 files changed, 50 insertions(+) diff --git a/GodotPlugin/include/rhythm_game_utilities.cpp b/GodotPlugin/include/rhythm_game_utilities.cpp index 6d812da..501d2ec 100644 --- a/GodotPlugin/include/rhythm_game_utilities.cpp +++ b/GodotPlugin/include/rhythm_game_utilities.cpp @@ -3,6 +3,7 @@ #include "utilities.hpp" #include +#include #include void rhythm_game_utilities::_bind_methods() @@ -17,6 +18,13 @@ void rhythm_game_utilities::_bind_methods() D_METHOD("inverse_lerp", "a", "b", "v"), &rhythm_game_utilities::inverse_lerp); + // Parsers + + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("parse_sections_from_chart", "contents"), + &rhythm_game_utilities::parse_sections_from_chart); + // Utilities ClassDB::bind_static_method( @@ -65,6 +73,44 @@ float rhythm_game_utilities::inverse_lerp(float a, float b, float v) return RhythmGameUtilities::InverseLerp(a, b, v); } +// Parsers + +Dictionary rhythm_game_utilities::parse_sections_from_chart(String contents) +{ + Dictionary sections; + + auto sectionsInternal = + RhythmGameUtilities::ParseSectionsFromChart(contents.utf8().get_data()); + + for (auto sectionInternal = sectionsInternal.begin(); + sectionInternal != sectionsInternal.end(); sectionInternal++) + { + auto sectionKey = godot::String(sectionInternal->first.c_str()); + + Dictionary section; + + for (auto i = 0; i < sectionInternal->second.size(); i += 1) + { + auto temp = sectionInternal->second[i]; + + auto key = godot::Variant(temp.first.c_str()); + + Array values; + + for (auto j = 0; j < temp.second.size(); j += 1) + { + values.append(godot::Variant(temp.second[j].c_str())); + } + + section[key] = values; + } + + sections[sectionKey] = section; + } + + return sections; +} + // Utilities int rhythm_game_utilities::convert_seconds_to_ticks(float seconds, diff --git a/GodotPlugin/include/rhythm_game_utilities.h b/GodotPlugin/include/rhythm_game_utilities.h index 8a00d1d..ec39860 100644 --- a/GodotPlugin/include/rhythm_game_utilities.h +++ b/GodotPlugin/include/rhythm_game_utilities.h @@ -22,6 +22,10 @@ class rhythm_game_utilities : public Object static float inverse_lerp(float a, float b, float v); + // Parsers + + static Dictionary parse_sections_from_chart(String contents); + // Utilities static int convert_seconds_to_ticks(float seconds, int resolution, From fedab7783fb926119590f8a7308b1af0ba52c787 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Tue, 5 Nov 2024 09:55:28 -0500 Subject: [PATCH 12/19] Fixed invalid code highlighting. --- Documentation/API/Utilities/CalculateBeatBars.md | 2 +- README.md | 2 +- RhythmGameUtilities/README.md | 2 +- UnityPackage/README.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/API/Utilities/CalculateBeatBars.md b/Documentation/API/Utilities/CalculateBeatBars.md index d3f7b55..a4b2c9c 100644 --- a/Documentation/API/Utilities/CalculateBeatBars.md +++ b/Documentation/API/Utilities/CalculateBeatBars.md @@ -53,7 +53,7 @@ int main() ##### Godot -```godot +```gdscript extends Node func _ready() -> void: diff --git a/README.md b/README.md index dd1a948..e4758c7 100644 --- a/README.md +++ b/README.md @@ -693,7 +693,7 @@ int main() ##### Godot -```godot +```gdscript extends Node func _ready() -> void: diff --git a/RhythmGameUtilities/README.md b/RhythmGameUtilities/README.md index dd1a948..e4758c7 100644 --- a/RhythmGameUtilities/README.md +++ b/RhythmGameUtilities/README.md @@ -693,7 +693,7 @@ int main() ##### Godot -```godot +```gdscript extends Node func _ready() -> void: diff --git a/UnityPackage/README.md b/UnityPackage/README.md index dd1a948..e4758c7 100644 --- a/UnityPackage/README.md +++ b/UnityPackage/README.md @@ -693,7 +693,7 @@ int main() ##### Godot -```godot +```gdscript extends Node func _ready() -> void: From 1c928984620d3fc322b71149847857099c40605a Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Tue, 5 Nov 2024 09:55:45 -0500 Subject: [PATCH 13/19] Updated documentation. --- .../API/Parsers/ParseSectionsFromChart.md | 15 +++++++++++++++ README.md | 15 +++++++++++++++ RhythmGameUtilities/README.md | 15 +++++++++++++++ UnityPackage/README.md | 15 +++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/Documentation/API/Parsers/ParseSectionsFromChart.md b/Documentation/API/Parsers/ParseSectionsFromChart.md index e51ea16..e0779ac 100644 --- a/Documentation/API/Parsers/ParseSectionsFromChart.md +++ b/Documentation/API/Parsers/ParseSectionsFromChart.md @@ -34,3 +34,18 @@ int main() return 0; } ``` + +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + print(sections) +``` diff --git a/README.md b/README.md index e4758c7..c363572 100644 --- a/README.md +++ b/README.md @@ -540,6 +540,21 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + print(sections) +``` + #### `Parsers.ParseTimeSignaturesFromChartSection` > Languages: `C#` `C++` diff --git a/RhythmGameUtilities/README.md b/RhythmGameUtilities/README.md index e4758c7..c363572 100644 --- a/RhythmGameUtilities/README.md +++ b/RhythmGameUtilities/README.md @@ -540,6 +540,21 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + print(sections) +``` + #### `Parsers.ParseTimeSignaturesFromChartSection` > Languages: `C#` `C++` diff --git a/UnityPackage/README.md b/UnityPackage/README.md index e4758c7..c363572 100644 --- a/UnityPackage/README.md +++ b/UnityPackage/README.md @@ -540,6 +540,21 @@ int main() } ``` +##### Godot + +```gdscript +extends Node + +func _ready() -> void: + + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + print(sections) +``` + #### `Parsers.ParseTimeSignaturesFromChartSection` > Languages: `C#` `C++` From 03853110be46edebe892b63b19ae50571cc54f71 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Tue, 5 Nov 2024 11:34:02 -0500 Subject: [PATCH 14/19] Added GDScript to language list in README.md --- Documentation/API/Common/InverseLerp.md | 2 +- Documentation/API/Common/Lerp.md | 2 +- .../API/Parsers/ParseSectionsFromChart.md | 2 +- Documentation/API/Utilities/CalculateBeatBars.md | 2 +- .../API/Utilities/ConvertSecondsToTicks.md | 2 +- .../API/Utilities/ConvertTickToPosition.md | 2 +- Documentation/API/Utilities/IsOnTheBeat.md | 2 +- .../Utilities/RoundUpToTheNearestMultiplier.md | 2 +- README.md | 16 ++++++++-------- RhythmGameUtilities/README.md | 16 ++++++++-------- UnityPackage/README.md | 16 ++++++++-------- 11 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Documentation/API/Common/InverseLerp.md b/Documentation/API/Common/InverseLerp.md index ca546cb..7ed84d6 100644 --- a/Documentation/API/Common/InverseLerp.md +++ b/Documentation/API/Common/InverseLerp.md @@ -1,6 +1,6 @@ #### `Common.InverseLerp` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/Documentation/API/Common/Lerp.md b/Documentation/API/Common/Lerp.md index aa23461..9d59c6c 100644 --- a/Documentation/API/Common/Lerp.md +++ b/Documentation/API/Common/Lerp.md @@ -1,6 +1,6 @@ #### `Common.Lerp` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/Documentation/API/Parsers/ParseSectionsFromChart.md b/Documentation/API/Parsers/ParseSectionsFromChart.md index e0779ac..333b0d2 100644 --- a/Documentation/API/Parsers/ParseSectionsFromChart.md +++ b/Documentation/API/Parsers/ParseSectionsFromChart.md @@ -1,6 +1,6 @@ #### `Parsers.ParseSectionsFromChart` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/Documentation/API/Utilities/CalculateBeatBars.md b/Documentation/API/Utilities/CalculateBeatBars.md index a4b2c9c..66cf363 100644 --- a/Documentation/API/Utilities/CalculateBeatBars.md +++ b/Documentation/API/Utilities/CalculateBeatBars.md @@ -1,6 +1,6 @@ #### `Utilities.CalculateBeatBars` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/Documentation/API/Utilities/ConvertSecondsToTicks.md b/Documentation/API/Utilities/ConvertSecondsToTicks.md index 533e0a8..67db9f6 100644 --- a/Documentation/API/Utilities/ConvertSecondsToTicks.md +++ b/Documentation/API/Utilities/ConvertSecondsToTicks.md @@ -1,6 +1,6 @@ #### `Utilities.ConvertSecondsToTicks` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/Documentation/API/Utilities/ConvertTickToPosition.md b/Documentation/API/Utilities/ConvertTickToPosition.md index 09358b1..46b838d 100644 --- a/Documentation/API/Utilities/ConvertTickToPosition.md +++ b/Documentation/API/Utilities/ConvertTickToPosition.md @@ -1,6 +1,6 @@ #### `Utilities.ConvertTickToPosition` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/Documentation/API/Utilities/IsOnTheBeat.md b/Documentation/API/Utilities/IsOnTheBeat.md index 9d9a195..d2a8052 100644 --- a/Documentation/API/Utilities/IsOnTheBeat.md +++ b/Documentation/API/Utilities/IsOnTheBeat.md @@ -1,6 +1,6 @@ #### `Utilities.IsOnTheBeat` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md b/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md index b820a5a..379da64 100644 --- a/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md +++ b/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md @@ -1,6 +1,6 @@ #### `Utilities.RoundUpToTheNearestMultiplier` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/README.md b/README.md index c363572..ffcc067 100644 --- a/README.md +++ b/README.md @@ -231,7 +231,7 @@ _texture2D.Apply(); #### `Common.InverseLerp` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -276,7 +276,7 @@ func _ready() -> void: #### `Common.Lerp` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -505,7 +505,7 @@ int main() #### `Parsers.ParseSectionsFromChart` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -655,7 +655,7 @@ int main() #### `Utilities.CalculateBeatBars` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -728,7 +728,7 @@ func _ready() -> void: #### `Utilities.ConvertSecondsToTicks` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -803,7 +803,7 @@ func _ready() -> void: #### `Utilities.ConvertTickToPosition` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -857,7 +857,7 @@ func _ready() -> void: #### `Utilities.IsOnTheBeat` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -915,7 +915,7 @@ func _ready() -> void: #### `Utilities.RoundUpToTheNearestMultiplier` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/RhythmGameUtilities/README.md b/RhythmGameUtilities/README.md index c363572..ffcc067 100644 --- a/RhythmGameUtilities/README.md +++ b/RhythmGameUtilities/README.md @@ -231,7 +231,7 @@ _texture2D.Apply(); #### `Common.InverseLerp` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -276,7 +276,7 @@ func _ready() -> void: #### `Common.Lerp` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -505,7 +505,7 @@ int main() #### `Parsers.ParseSectionsFromChart` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -655,7 +655,7 @@ int main() #### `Utilities.CalculateBeatBars` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -728,7 +728,7 @@ func _ready() -> void: #### `Utilities.ConvertSecondsToTicks` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -803,7 +803,7 @@ func _ready() -> void: #### `Utilities.ConvertTickToPosition` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -857,7 +857,7 @@ func _ready() -> void: #### `Utilities.IsOnTheBeat` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -915,7 +915,7 @@ func _ready() -> void: #### `Utilities.RoundUpToTheNearestMultiplier` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/UnityPackage/README.md b/UnityPackage/README.md index c363572..ffcc067 100644 --- a/UnityPackage/README.md +++ b/UnityPackage/README.md @@ -231,7 +231,7 @@ _texture2D.Apply(); #### `Common.InverseLerp` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -276,7 +276,7 @@ func _ready() -> void: #### `Common.Lerp` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -505,7 +505,7 @@ int main() #### `Parsers.ParseSectionsFromChart` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -655,7 +655,7 @@ int main() #### `Utilities.CalculateBeatBars` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -728,7 +728,7 @@ func _ready() -> void: #### `Utilities.ConvertSecondsToTicks` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -803,7 +803,7 @@ func _ready() -> void: #### `Utilities.ConvertTickToPosition` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -857,7 +857,7 @@ func _ready() -> void: #### `Utilities.IsOnTheBeat` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -915,7 +915,7 @@ func _ready() -> void: #### `Utilities.RoundUpToTheNearestMultiplier` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# From 2841ab02092fba605c3826271ef2c244f120d7e9 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Wed, 6 Nov 2024 09:59:49 -0500 Subject: [PATCH 15/19] Added new methods. --- Documentation/API/Common/InverseLerp.md | 2 +- Documentation/API/Common/Lerp.md | 2 +- .../API/Parsers/ParseBpmFromChartSection.md | 18 +- .../Parsers/ParseLyricsFromChartSection.md | 16 ++ .../Parsers/ParseMetaDataFromChartSection.md | 18 +- .../API/Parsers/ParseNotesFromChartSection.md | 18 +- .../API/Parsers/ParseSectionsFromChart.md | 3 +- .../ParseTimeSignaturesFromChartSection.md | 18 +- .../API/Utilities/CalculateAccuracyRatio.md | 21 +- .../API/Utilities/CalculateBeatBars.md | 12 +- .../API/Utilities/ConvertSecondsToTicks.md | 10 +- .../API/Utilities/ConvertTickToPosition.md | 8 +- Documentation/API/Utilities/IsOnTheBeat.md | 10 +- .../RoundUpToTheNearestMultiplier.md | 4 +- GodotPlugin/include/rhythm_game_utilities.cpp | 179 ++++++++++++++---- GodotPlugin/include/rhythm_game_utilities.h | 21 +- GodotPlugin/include/utilities.hpp | 40 ++++ README.md | 160 +++++++++++++--- RhythmGameUtilities/README.md | 160 +++++++++++++--- UnityPackage/README.md | 160 +++++++++++++--- 20 files changed, 719 insertions(+), 161 deletions(-) diff --git a/Documentation/API/Common/InverseLerp.md b/Documentation/API/Common/InverseLerp.md index 7ed84d6..638d53e 100644 --- a/Documentation/API/Common/InverseLerp.md +++ b/Documentation/API/Common/InverseLerp.md @@ -32,7 +32,7 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node diff --git a/Documentation/API/Common/Lerp.md b/Documentation/API/Common/Lerp.md index 9d59c6c..6d001f7 100644 --- a/Documentation/API/Common/Lerp.md +++ b/Documentation/API/Common/Lerp.md @@ -32,7 +32,7 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node diff --git a/Documentation/API/Parsers/ParseBpmFromChartSection.md b/Documentation/API/Parsers/ParseBpmFromChartSection.md index 160db28..cdb6249 100644 --- a/Documentation/API/Parsers/ParseBpmFromChartSection.md +++ b/Documentation/API/Parsers/ParseBpmFromChartSection.md @@ -1,6 +1,6 @@ #### `Parsers.ParseBpmFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -39,3 +39,19 @@ int main() return 0; } ``` + +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var bpm = rhythm_game_utilities.parse_bpm_from_chart_section(sections["SyncTrack"]) + + print(bpm) +``` diff --git a/Documentation/API/Parsers/ParseLyricsFromChartSection.md b/Documentation/API/Parsers/ParseLyricsFromChartSection.md index 31e8746..ed6b796 100644 --- a/Documentation/API/Parsers/ParseLyricsFromChartSection.md +++ b/Documentation/API/Parsers/ParseLyricsFromChartSection.md @@ -39,3 +39,19 @@ int main() return 0; } ``` + +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var lyrics = rhythm_game_utilities.parse_lyrics_from_chart_section(sections["Events"]) + + print(lyrics) +``` diff --git a/Documentation/API/Parsers/ParseMetaDataFromChartSection.md b/Documentation/API/Parsers/ParseMetaDataFromChartSection.md index 52470c7..b2cad17 100644 --- a/Documentation/API/Parsers/ParseMetaDataFromChartSection.md +++ b/Documentation/API/Parsers/ParseMetaDataFromChartSection.md @@ -1,6 +1,6 @@ #### `Parsers.ParseMetaDataFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -43,3 +43,19 @@ int main() return 0; } ``` + +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var meta_data = rhythm_game_utilities.parse_meta_data_from_chart_section(sections["Song"]) + + print(meta_data) +``` diff --git a/Documentation/API/Parsers/ParseNotesFromChartSection.md b/Documentation/API/Parsers/ParseNotesFromChartSection.md index 7988351..35f6020 100644 --- a/Documentation/API/Parsers/ParseNotesFromChartSection.md +++ b/Documentation/API/Parsers/ParseNotesFromChartSection.md @@ -1,6 +1,6 @@ #### `Parsers.ParseNotesFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -47,3 +47,19 @@ int main() return 0; } ``` + +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var notes = rhythm_game_utilities.parse_notes_from_chart_section(sections["ExpertSingle"]) + + print(notes) +``` diff --git a/Documentation/API/Parsers/ParseSectionsFromChart.md b/Documentation/API/Parsers/ParseSectionsFromChart.md index 333b0d2..8705ad3 100644 --- a/Documentation/API/Parsers/ParseSectionsFromChart.md +++ b/Documentation/API/Parsers/ParseSectionsFromChart.md @@ -35,13 +35,12 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var file = FileAccess.open("res://song.txt", FileAccess.READ) var content = file.get_as_text() diff --git a/Documentation/API/Parsers/ParseTimeSignaturesFromChartSection.md b/Documentation/API/Parsers/ParseTimeSignaturesFromChartSection.md index b91ef84..936caba 100644 --- a/Documentation/API/Parsers/ParseTimeSignaturesFromChartSection.md +++ b/Documentation/API/Parsers/ParseTimeSignaturesFromChartSection.md @@ -1,6 +1,6 @@ #### `Parsers.ParseTimeSignaturesFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -39,3 +39,19 @@ int main() return 0; } ``` + +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var time_signatures = rhythm_game_utilities.parse_time_signatures_from_chart_section(sections["SyncTrack"]) + + print(time_signatures) +``` diff --git a/Documentation/API/Utilities/CalculateAccuracyRatio.md b/Documentation/API/Utilities/CalculateAccuracyRatio.md index 5ddbe56..be5cdce 100644 --- a/Documentation/API/Utilities/CalculateAccuracyRatio.md +++ b/Documentation/API/Utilities/CalculateAccuracyRatio.md @@ -1,6 +1,6 @@ #### `Utilities.CalculateAccuracyRatio` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -51,3 +51,22 @@ int main() return 0; } ``` + +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var seconds = 2 + var resolution = 192 + var position_delta = 50 + + var bpm_changes = { 0: 120000 } + + var current_position = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpm_changes) + + var value = rhythm_game_utilities.calculate_accuracy_ratio(750, current_position, position_delta) + + print(round(value * 100) / 100.0) # 0.64 +``` diff --git a/Documentation/API/Utilities/CalculateBeatBars.md b/Documentation/API/Utilities/CalculateBeatBars.md index 66cf363..a3da1d4 100644 --- a/Documentation/API/Utilities/CalculateBeatBars.md +++ b/Documentation/API/Utilities/CalculateBeatBars.md @@ -51,22 +51,22 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var resolution = 192; - var timeSignature = 4; + var resolution = 192 + var time_signature = 4 - var bpmChanges = { + var bpm_changes = { 0: 88000, 3840: 112000, 9984: 89600, 22272: 112000, 33792: 111500, 34560: 112000, 42240: 111980 } - var beatBars = rhythm_game_utilities.calculate_beat_bars(bpmChanges, resolution, timeSignature, true); + var beat_bars = rhythm_game_utilities.calculate_beat_bars(bpm_changes, resolution, time_signature, true) - print(beatBars) + print(beat_bars) ``` diff --git a/Documentation/API/Utilities/ConvertSecondsToTicks.md b/Documentation/API/Utilities/ConvertSecondsToTicks.md index 67db9f6..3252be4 100644 --- a/Documentation/API/Utilities/ConvertSecondsToTicks.md +++ b/Documentation/API/Utilities/ConvertSecondsToTicks.md @@ -53,22 +53,22 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var seconds = 5; - var resolution = 192; + var seconds = 5 + var resolution = 192 - var bpmChanges = { + var bpm_changes = { 0: 88000, 3840: 112000, 9984: 89600, 22272: 112000, 33792: 111500, 34560: 112000, 42240: 111980 } - var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpmChanges); + var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpm_changes) print(ticks) # 1408 ``` diff --git a/Documentation/API/Utilities/ConvertTickToPosition.md b/Documentation/API/Utilities/ConvertTickToPosition.md index 46b838d..d29a6cd 100644 --- a/Documentation/API/Utilities/ConvertTickToPosition.md +++ b/Documentation/API/Utilities/ConvertTickToPosition.md @@ -38,16 +38,16 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var tick = 2784; - var resolution = 192; + var tick = 2784 + var resolution = 192 - var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution); + var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution) print(position) # 14.5 ``` diff --git a/Documentation/API/Utilities/IsOnTheBeat.md b/Documentation/API/Utilities/IsOnTheBeat.md index d2a8052..41bf93d 100644 --- a/Documentation/API/Utilities/IsOnTheBeat.md +++ b/Documentation/API/Utilities/IsOnTheBeat.md @@ -42,16 +42,16 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var bpm = 120; - var currentTime = 10; - var delta = 0.05; + var bpm = 120 + var current_time = 10 + var delta = 0.05 - if rhythm_game_utilities.is_on_the_beat(bpm, currentTime, delta): + if rhythm_game_utilities.is_on_the_beat(bpm, current_time, delta): print("Is on the beat!") ``` diff --git a/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md b/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md index 379da64..877fe49 100644 --- a/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md +++ b/Documentation/API/Utilities/RoundUpToTheNearestMultiplier.md @@ -32,13 +32,13 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10); + var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10) print(value) # 20 ``` diff --git a/GodotPlugin/include/rhythm_game_utilities.cpp b/GodotPlugin/include/rhythm_game_utilities.cpp index 501d2ec..fa93695 100644 --- a/GodotPlugin/include/rhythm_game_utilities.cpp +++ b/GodotPlugin/include/rhythm_game_utilities.cpp @@ -25,12 +25,37 @@ void rhythm_game_utilities::_bind_methods() D_METHOD("parse_sections_from_chart", "contents"), &rhythm_game_utilities::parse_sections_from_chart); + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("parse_bpm_from_chart_section", "section"), + &rhythm_game_utilities::parse_bpm_from_chart_section); + + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("parse_lyrics_from_chart_section", "section"), + &rhythm_game_utilities::parse_lyrics_from_chart_section); + + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("parse_meta_data_from_chart_section", "section"), + &rhythm_game_utilities::parse_meta_data_from_chart_section); + + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("parse_notes_from_chart_section", "section"), + &rhythm_game_utilities::parse_notes_from_chart_section); + + ClassDB::bind_static_method( + "rhythm_game_utilities", + D_METHOD("parse_time_signatures_from_chart_section", "section"), + &rhythm_game_utilities::parse_time_signatures_from_chart_section); + // Utilities ClassDB::bind_static_method( "rhythm_game_utilities", D_METHOD("convert_seconds_to_ticks", "seconds", "resolution", - "bpmChanges"), + "bpm_changes"), &rhythm_game_utilities::convert_seconds_to_ticks); ClassDB::bind_static_method( @@ -40,7 +65,7 @@ void rhythm_game_utilities::_bind_methods() ClassDB::bind_static_method( "rhythm_game_utilities", - D_METHOD("is_on_the_beat", "bpm", "currentTime", "delta"), + D_METHOD("is_on_the_beat", "bpm", "current_time", "delta"), &rhythm_game_utilities::is_on_the_beat); ClassDB::bind_static_method( @@ -50,14 +75,14 @@ void rhythm_game_utilities::_bind_methods() ClassDB::bind_static_method( "rhythm_game_utilities", - D_METHOD("calculate_accuracy_ratio", "position", "currentPosition", + D_METHOD("calculate_accuracy_ratio", "position", "current_position", "delta"), &rhythm_game_utilities::calculate_accuracy_ratio); ClassDB::bind_static_method("rhythm_game_utilities", - D_METHOD("calculate_beat_bars", "bpmChanges", + D_METHOD("calculate_beat_bars", "bpm_changes", "resolution", "ts", - "includeHalfNotes"), + "include_half_notes"), &rhythm_game_utilities::calculate_beat_bars); } @@ -79,19 +104,21 @@ Dictionary rhythm_game_utilities::parse_sections_from_chart(String contents) { Dictionary sections; - auto sectionsInternal = + auto sections_internal = RhythmGameUtilities::ParseSectionsFromChart(contents.utf8().get_data()); - for (auto sectionInternal = sectionsInternal.begin(); - sectionInternal != sectionsInternal.end(); sectionInternal++) + for (auto section_internal = sections_internal.begin(); + section_internal != sections_internal.end(); section_internal++) { - auto sectionKey = godot::String(sectionInternal->first.c_str()); + auto section_key = godot::String(section_internal->first.c_str()); - Dictionary section; + Array section_items; - for (auto i = 0; i < sectionInternal->second.size(); i += 1) + for (auto i = 0; i < section_internal->second.size(); i += 1) { - auto temp = sectionInternal->second[i]; + Dictionary section_item; + + auto temp = section_internal->second[i]; auto key = godot::Variant(temp.first.c_str()); @@ -102,23 +129,111 @@ Dictionary rhythm_game_utilities::parse_sections_from_chart(String contents) values.append(godot::Variant(temp.second[j].c_str())); } - section[key] = values; + section_item[key] = values; + + section_items.append(section_item); } - sections[sectionKey] = section; + sections[section_key] = section_items; } return sections; } +Dictionary rhythm_game_utilities::parse_bpm_from_chart_section(Array section) +{ + auto bpm_internal = RhythmGameUtilities::ParseBpmFromChartSection( + convert_section_to_section_internal(section)); + + Dictionary bpm; + + for (auto const &[key, val] : bpm_internal) + { + bpm[key] = bpm_internal[key]; + } + + return bpm; +} + +Dictionary rhythm_game_utilities::parse_lyrics_from_chart_section(Array section) +{ + auto lyrics_internal = RhythmGameUtilities::ParseLyricsFromChartSection( + convert_section_to_section_internal(section)); + + Dictionary lyrics; + + for (auto const &[key, val] : lyrics_internal) + { + lyrics[key] = godot::String(lyrics_internal[key].c_str()); + } + + return lyrics; +} + +Dictionary +rhythm_game_utilities::parse_meta_data_from_chart_section(Array section) +{ + auto meta_data_internal = + RhythmGameUtilities::ParseMetaDataFromChartSection( + convert_section_to_section_internal(section)); + + Dictionary meta_data; + + for (auto const &[key, val] : meta_data_internal) + { + meta_data[godot::String(key.c_str())] = + godot::String(meta_data_internal[key].c_str()); + } + + return meta_data; +} + +Array rhythm_game_utilities::parse_notes_from_chart_section(Array section) +{ + auto notes_internal = RhythmGameUtilities::ParseNotesFromChartSection( + convert_section_to_section_internal(section)); + + Array notes; + + for (auto ¬e_internal : notes_internal) + { + Dictionary note; + + note["hand_position"] = note_internal.HandPosition; + note["length"] = note_internal.Length; + note["position"] = note_internal.Position; + + notes.append(note); + } + + return notes; +} + +Dictionary +rhythm_game_utilities::parse_time_signatures_from_chart_section(Array section) +{ + auto time_signatures_internal = + RhythmGameUtilities::ParseTimeSignaturesFromChartSection( + convert_section_to_section_internal(section)); + + Dictionary time_signatures; + + for (auto const &[key, val] : time_signatures_internal) + { + time_signatures[key] = time_signatures_internal[key]; + } + + return time_signatures; +} + // Utilities int rhythm_game_utilities::convert_seconds_to_ticks(float seconds, int resolution, - Dictionary bpmChanges) + Dictionary bpm_changes) { return RhythmGameUtilities::ConvertSecondsToTicks( - seconds, resolution, convert_dictionary_to_map(bpmChanges)); + seconds, resolution, convert_dictionary_to_map(bpm_changes)); } float rhythm_game_utilities::convert_tick_to_position(int tick, int resolution) @@ -126,10 +241,10 @@ float rhythm_game_utilities::convert_tick_to_position(int tick, int resolution) return RhythmGameUtilities::ConvertTickToPosition(tick, resolution); } -bool rhythm_game_utilities::is_on_the_beat(int bpm, float currentTime, +bool rhythm_game_utilities::is_on_the_beat(int bpm, float current_time, float delta) { - return RhythmGameUtilities::IsOnTheBeat(bpm, currentTime, delta); + return RhythmGameUtilities::IsOnTheBeat(bpm, current_time, delta); } int rhythm_game_utilities::round_up_to_the_nearest_multiplier(int value, @@ -140,32 +255,32 @@ int rhythm_game_utilities::round_up_to_the_nearest_multiplier(int value, } float rhythm_game_utilities::calculate_accuracy_ratio(int position, - int currentPosition, + int current_position, int delta) { return RhythmGameUtilities::CalculateAccuracyRatio(position, - currentPosition, delta); + current_position, delta); } -Array rhythm_game_utilities::calculate_beat_bars(Dictionary bpmChanges, +Array rhythm_game_utilities::calculate_beat_bars(Dictionary bpm_changes, int resolution, int ts, - bool includeHalfNotes) + bool include_half_notes) { - auto beatBars = RhythmGameUtilities::CalculateBeatBars( - convert_dictionary_to_map(bpmChanges), resolution, ts, - includeHalfNotes); + auto beat_bars = RhythmGameUtilities::CalculateBeatBars( + convert_dictionary_to_map(bpm_changes), resolution, ts, + include_half_notes); - Array beatBarsDictionaryArray; + Array beat_bars_dictionary_array; - for (auto &beatBar : beatBars) + for (auto &beat_bar : beat_bars) { - Dictionary beatBarDictionary; + Dictionary beat_bar_dictionary; - beatBarDictionary["bpm"] = beatBar.BPM; - beatBarDictionary["position"] = beatBar.Position; + beat_bar_dictionary["bpm"] = beat_bar.BPM; + beat_bar_dictionary["position"] = beat_bar.Position; - beatBarsDictionaryArray.append(beatBarDictionary); + beat_bars_dictionary_array.append(beat_bar_dictionary); } - return beatBarsDictionaryArray; + return beat_bars_dictionary_array; } diff --git a/GodotPlugin/include/rhythm_game_utilities.h b/GodotPlugin/include/rhythm_game_utilities.h index ec39860..3901c1e 100644 --- a/GodotPlugin/include/rhythm_game_utilities.h +++ b/GodotPlugin/include/rhythm_game_utilities.h @@ -26,20 +26,31 @@ class rhythm_game_utilities : public Object static Dictionary parse_sections_from_chart(String contents); + static Dictionary parse_bpm_from_chart_section(Array section); + + static Dictionary parse_lyrics_from_chart_section(Array section); + + static Dictionary parse_meta_data_from_chart_section(Array section); + + static Array parse_notes_from_chart_section(Array section); + + static Dictionary parse_time_signatures_from_chart_section(Array section); + // Utilities static int convert_seconds_to_ticks(float seconds, int resolution, - Dictionary bpmChanges); + Dictionary bpm_changes); static float convert_tick_to_position(int tick, int resolution); - static bool is_on_the_beat(int bpm, float currentTime, float delta = 0.05f); + static bool is_on_the_beat(int bpm, float current_time, + float delta = 0.05f); static int round_up_to_the_nearest_multiplier(int value, int multiplier); - static float calculate_accuracy_ratio(int position, int currentPosition, + static float calculate_accuracy_ratio(int position, int current_position, int delta = 50); - static Array calculate_beat_bars(Dictionary bpmChanges, int resolution, - int ts, bool includeHalfNotes); + static Array calculate_beat_bars(Dictionary bpm_changes, int resolution, + int ts, bool include_half_notes); }; diff --git a/GodotPlugin/include/utilities.hpp b/GodotPlugin/include/utilities.hpp index 6b52508..46e6277 100644 --- a/GodotPlugin/include/utilities.hpp +++ b/GodotPlugin/include/utilities.hpp @@ -21,3 +21,43 @@ std::map convert_dictionary_to_map(Dictionary input) return output; } + +std::vector>> +convert_section_to_section_internal(Array section) +{ + std::vector>> + sectionInternal; + + for (auto i = 0; i < section.size(); i += 1) + { + if (section[i].get_type() == Variant::DICTIONARY) + { + Dictionary variant = section[i]; + + Array keys = variant.keys(); + + for (auto j = 0; j < keys.size(); j += 1) + { + String key = keys[j]; + Array values = variant[key]; + + std::vector valuesInternal; + + for (auto k = 0; k < values.size(); k += 1) + { + if (values[k].get_type() == Variant::Type::STRING) + { + String value = values[k]; + + valuesInternal.push_back(value.utf8().get_data()); + } + } + + sectionInternal.push_back( + std::make_pair(key.utf8().get_data(), valuesInternal)); + } + } + } + + return sectionInternal; +} diff --git a/README.md b/README.md index ffcc067..be9d60e 100644 --- a/README.md +++ b/README.md @@ -263,7 +263,7 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node @@ -308,7 +308,7 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node @@ -325,7 +325,7 @@ Read more about `.chart` files: Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -365,6 +365,22 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var bpm = rhythm_game_utilities.parse_bpm_from_chart_section(sections["SyncTrack"]) + + print(bpm) +``` + #### `Parsers.ParseLyricsFromChartSection` > Languages: `C#` `C++` @@ -407,9 +423,25 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var lyrics = rhythm_game_utilities.parse_lyrics_from_chart_section(sections["Events"]) + + print(lyrics) +``` + #### `Parsers.ParseMetaDataFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -453,9 +485,25 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var meta_data = rhythm_game_utilities.parse_meta_data_from_chart_section(sections["Song"]) + + print(meta_data) +``` + #### `Parsers.ParseNotesFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -503,6 +551,22 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var notes = rhythm_game_utilities.parse_notes_from_chart_section(sections["ExpertSingle"]) + + print(notes) +``` + #### `Parsers.ParseSectionsFromChart` > Languages: `C#` `C++` `GDScript` @@ -540,13 +604,12 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var file = FileAccess.open("res://song.txt", FileAccess.READ) var content = file.get_as_text() @@ -557,7 +620,7 @@ func _ready() -> void: #### `Parsers.ParseTimeSignaturesFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -597,11 +660,27 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var time_signatures = rhythm_game_utilities.parse_time_signatures_from_chart_section(sections["SyncTrack"]) + + print(time_signatures) +``` + ### Utilities #### `Utilities.CalculateAccuracyRatio` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -653,6 +732,25 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var seconds = 2 + var resolution = 192 + var position_delta = 50 + + var bpm_changes = { 0: 120000 } + + var current_position = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpm_changes) + + var value = rhythm_game_utilities.calculate_accuracy_ratio(750, current_position, position_delta) + + print(round(value * 100) / 100.0) # 0.64 +``` + #### `Utilities.CalculateBeatBars` > Languages: `C#` `C++` `GDScript` @@ -706,24 +804,24 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var resolution = 192; - var timeSignature = 4; + var resolution = 192 + var time_signature = 4 - var bpmChanges = { + var bpm_changes = { 0: 88000, 3840: 112000, 9984: 89600, 22272: 112000, 33792: 111500, 34560: 112000, 42240: 111980 } - var beatBars = rhythm_game_utilities.calculate_beat_bars(bpmChanges, resolution, timeSignature, true); + var beat_bars = rhythm_game_utilities.calculate_beat_bars(bpm_changes, resolution, time_signature, true) - print(beatBars) + print(beat_bars) ``` #### `Utilities.ConvertSecondsToTicks` @@ -781,22 +879,22 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var seconds = 5; - var resolution = 192; + var seconds = 5 + var resolution = 192 - var bpmChanges = { + var bpm_changes = { 0: 88000, 3840: 112000, 9984: 89600, 22272: 112000, 33792: 111500, 34560: 112000, 42240: 111980 } - var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpmChanges); + var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpm_changes) print(ticks) # 1408 ``` @@ -841,16 +939,16 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var tick = 2784; - var resolution = 192; + var tick = 2784 + var resolution = 192 - var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution); + var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution) print(position) # 14.5 ``` @@ -899,17 +997,17 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var bpm = 120; - var currentTime = 10; - var delta = 0.05; + var bpm = 120 + var current_time = 10 + var delta = 0.05 - if rhythm_game_utilities.is_on_the_beat(bpm, currentTime, delta): + if rhythm_game_utilities.is_on_the_beat(bpm, current_time, delta): print("Is on the beat!") ``` @@ -947,13 +1045,13 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10); + var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10) print(value) # 20 ``` diff --git a/RhythmGameUtilities/README.md b/RhythmGameUtilities/README.md index ffcc067..be9d60e 100644 --- a/RhythmGameUtilities/README.md +++ b/RhythmGameUtilities/README.md @@ -263,7 +263,7 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node @@ -308,7 +308,7 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node @@ -325,7 +325,7 @@ Read more about `.chart` files: Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -365,6 +365,22 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var bpm = rhythm_game_utilities.parse_bpm_from_chart_section(sections["SyncTrack"]) + + print(bpm) +``` + #### `Parsers.ParseLyricsFromChartSection` > Languages: `C#` `C++` @@ -407,9 +423,25 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var lyrics = rhythm_game_utilities.parse_lyrics_from_chart_section(sections["Events"]) + + print(lyrics) +``` + #### `Parsers.ParseMetaDataFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -453,9 +485,25 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var meta_data = rhythm_game_utilities.parse_meta_data_from_chart_section(sections["Song"]) + + print(meta_data) +``` + #### `Parsers.ParseNotesFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -503,6 +551,22 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var notes = rhythm_game_utilities.parse_notes_from_chart_section(sections["ExpertSingle"]) + + print(notes) +``` + #### `Parsers.ParseSectionsFromChart` > Languages: `C#` `C++` `GDScript` @@ -540,13 +604,12 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var file = FileAccess.open("res://song.txt", FileAccess.READ) var content = file.get_as_text() @@ -557,7 +620,7 @@ func _ready() -> void: #### `Parsers.ParseTimeSignaturesFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -597,11 +660,27 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var time_signatures = rhythm_game_utilities.parse_time_signatures_from_chart_section(sections["SyncTrack"]) + + print(time_signatures) +``` + ### Utilities #### `Utilities.CalculateAccuracyRatio` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -653,6 +732,25 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var seconds = 2 + var resolution = 192 + var position_delta = 50 + + var bpm_changes = { 0: 120000 } + + var current_position = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpm_changes) + + var value = rhythm_game_utilities.calculate_accuracy_ratio(750, current_position, position_delta) + + print(round(value * 100) / 100.0) # 0.64 +``` + #### `Utilities.CalculateBeatBars` > Languages: `C#` `C++` `GDScript` @@ -706,24 +804,24 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var resolution = 192; - var timeSignature = 4; + var resolution = 192 + var time_signature = 4 - var bpmChanges = { + var bpm_changes = { 0: 88000, 3840: 112000, 9984: 89600, 22272: 112000, 33792: 111500, 34560: 112000, 42240: 111980 } - var beatBars = rhythm_game_utilities.calculate_beat_bars(bpmChanges, resolution, timeSignature, true); + var beat_bars = rhythm_game_utilities.calculate_beat_bars(bpm_changes, resolution, time_signature, true) - print(beatBars) + print(beat_bars) ``` #### `Utilities.ConvertSecondsToTicks` @@ -781,22 +879,22 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var seconds = 5; - var resolution = 192; + var seconds = 5 + var resolution = 192 - var bpmChanges = { + var bpm_changes = { 0: 88000, 3840: 112000, 9984: 89600, 22272: 112000, 33792: 111500, 34560: 112000, 42240: 111980 } - var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpmChanges); + var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpm_changes) print(ticks) # 1408 ``` @@ -841,16 +939,16 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var tick = 2784; - var resolution = 192; + var tick = 2784 + var resolution = 192 - var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution); + var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution) print(position) # 14.5 ``` @@ -899,17 +997,17 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var bpm = 120; - var currentTime = 10; - var delta = 0.05; + var bpm = 120 + var current_time = 10 + var delta = 0.05 - if rhythm_game_utilities.is_on_the_beat(bpm, currentTime, delta): + if rhythm_game_utilities.is_on_the_beat(bpm, current_time, delta): print("Is on the beat!") ``` @@ -947,13 +1045,13 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10); + var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10) print(value) # 20 ``` diff --git a/UnityPackage/README.md b/UnityPackage/README.md index ffcc067..be9d60e 100644 --- a/UnityPackage/README.md +++ b/UnityPackage/README.md @@ -263,7 +263,7 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node @@ -308,7 +308,7 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node @@ -325,7 +325,7 @@ Read more about `.chart` files: Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -365,6 +365,22 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var bpm = rhythm_game_utilities.parse_bpm_from_chart_section(sections["SyncTrack"]) + + print(bpm) +``` + #### `Parsers.ParseLyricsFromChartSection` > Languages: `C#` `C++` @@ -407,9 +423,25 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var lyrics = rhythm_game_utilities.parse_lyrics_from_chart_section(sections["Events"]) + + print(lyrics) +``` + #### `Parsers.ParseMetaDataFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -453,9 +485,25 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var meta_data = rhythm_game_utilities.parse_meta_data_from_chart_section(sections["Song"]) + + print(meta_data) +``` + #### `Parsers.ParseNotesFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -503,6 +551,22 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var notes = rhythm_game_utilities.parse_notes_from_chart_section(sections["ExpertSingle"]) + + print(notes) +``` + #### `Parsers.ParseSectionsFromChart` > Languages: `C#` `C++` `GDScript` @@ -540,13 +604,12 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var file = FileAccess.open("res://song.txt", FileAccess.READ) var content = file.get_as_text() @@ -557,7 +620,7 @@ func _ready() -> void: #### `Parsers.ParseTimeSignaturesFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -597,11 +660,27 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var file = FileAccess.open("res://song.txt", FileAccess.READ) + var content = file.get_as_text() + + var sections = rhythm_game_utilities.parse_sections_from_chart(content) + + var time_signatures = rhythm_game_utilities.parse_time_signatures_from_chart_section(sections["SyncTrack"]) + + print(time_signatures) +``` + ### Utilities #### `Utilities.CalculateAccuracyRatio` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# @@ -653,6 +732,25 @@ int main() } ``` +##### GDScript + +```gdscript +extends Node + +func _ready() -> void: + var seconds = 2 + var resolution = 192 + var position_delta = 50 + + var bpm_changes = { 0: 120000 } + + var current_position = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpm_changes) + + var value = rhythm_game_utilities.calculate_accuracy_ratio(750, current_position, position_delta) + + print(round(value * 100) / 100.0) # 0.64 +``` + #### `Utilities.CalculateBeatBars` > Languages: `C#` `C++` `GDScript` @@ -706,24 +804,24 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var resolution = 192; - var timeSignature = 4; + var resolution = 192 + var time_signature = 4 - var bpmChanges = { + var bpm_changes = { 0: 88000, 3840: 112000, 9984: 89600, 22272: 112000, 33792: 111500, 34560: 112000, 42240: 111980 } - var beatBars = rhythm_game_utilities.calculate_beat_bars(bpmChanges, resolution, timeSignature, true); + var beat_bars = rhythm_game_utilities.calculate_beat_bars(bpm_changes, resolution, time_signature, true) - print(beatBars) + print(beat_bars) ``` #### `Utilities.ConvertSecondsToTicks` @@ -781,22 +879,22 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var seconds = 5; - var resolution = 192; + var seconds = 5 + var resolution = 192 - var bpmChanges = { + var bpm_changes = { 0: 88000, 3840: 112000, 9984: 89600, 22272: 112000, 33792: 111500, 34560: 112000, 42240: 111980 } - var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpmChanges); + var ticks = rhythm_game_utilities.convert_seconds_to_ticks(seconds, resolution, bpm_changes) print(ticks) # 1408 ``` @@ -841,16 +939,16 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var tick = 2784; - var resolution = 192; + var tick = 2784 + var resolution = 192 - var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution); + var position = rhythm_game_utilities.convert_tick_to_position(tick, resolution) print(position) # 14.5 ``` @@ -899,17 +997,17 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var bpm = 120; - var currentTime = 10; - var delta = 0.05; + var bpm = 120 + var current_time = 10 + var delta = 0.05 - if rhythm_game_utilities.is_on_the_beat(bpm, currentTime, delta): + if rhythm_game_utilities.is_on_the_beat(bpm, current_time, delta): print("Is on the beat!") ``` @@ -947,13 +1045,13 @@ int main() } ``` -##### Godot +##### GDScript ```gdscript extends Node func _ready() -> void: - var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10); + var value = rhythm_game_utilities.round_up_to_the_nearest_multiplier(12, 10) print(value) # 20 ``` From 6ca879715e17eb9faa666e386700510265337652 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Thu, 7 Nov 2024 02:33:58 -0500 Subject: [PATCH 16/19] Added windows build support. --- GodotPlugin/Makefile | 16 ++++++++++++++++ GodotPlugin/RhythmGameUtilities.gdextension | 9 +++++++-- GodotPlugin/SConstruct.py | 18 +++++++++++++----- 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 GodotPlugin/Makefile diff --git a/GodotPlugin/Makefile b/GodotPlugin/Makefile new file mode 100644 index 0000000..eaa45a0 --- /dev/null +++ b/GodotPlugin/Makefile @@ -0,0 +1,16 @@ +help: + @fgrep -h "##" $(MAKEFILE_LIST) | sed -e 's/##//' | tail -n +2 + +build-debug: ## Build debug Godot plugin + scons platform=macos arch=universal target=template_debug + scons platform=windows arch=x86_32 target=template_debug + scons platform=windows arch=x86_64 target=template_debug + +build-release: ## Build release Godot plugin + scons platform=macos arch=universal target=template_release + scons platform=windows arch=x86_32 target=template_release + scons platform=windows arch=x86_64 target=template_release + +install-dependencies: ## Install Dependencies + brew install scons + brew install mingw-w64 diff --git a/GodotPlugin/RhythmGameUtilities.gdextension b/GodotPlugin/RhythmGameUtilities.gdextension index ff5931a..90522ce 100644 --- a/GodotPlugin/RhythmGameUtilities.gdextension +++ b/GodotPlugin/RhythmGameUtilities.gdextension @@ -2,8 +2,13 @@ entry_symbol = "rhythm_game_utilities_plugin" compatibility_minimum = 4.3 +reloadable = true [libraries] -macos.debug = "res://addons/RhythmGameUtilities/libRhythmGameUtilities.macos.template_debug" -macos.release = "res://addons/RhythmGameUtilities/libRhythmGameUtilities.macos.template_release" +macos.debug = "res://addons/RhythmGameUtilities/libRhythmGameUtilities.macos.template_debug.framework/libRhythmGameUtilities.macos.template_debug" +macos.release = "res://addons/RhythmGameUtilities/libRhythmGameUtilities.macos.template_release.framework/libRhythmGameUtilities.macos.template_release" +windows.debug.x86_32 = "res://addons/RhythmGameUtilities/libRhythmGameUtilities.windows.template_debug.x86_32.dll" +windows.release.x86_32 = "res://addons/RhythmGameUtilities/libRhythmGameUtilities.windows.template_release.x86_32.dll" +windows.debug.x86_64 = "res://addons/RhythmGameUtilities/libRhythmGameUtilities.windows.template_debug.x86_64.dll" +windows.release.x86_64 = "res://addons/RhythmGameUtilities/libRhythmGameUtilities.windows.template_release.x86_64.dll" diff --git a/GodotPlugin/SConstruct.py b/GodotPlugin/SConstruct.py index a7f0591..f88d54a 100644 --- a/GodotPlugin/SConstruct.py +++ b/GodotPlugin/SConstruct.py @@ -8,11 +8,19 @@ env.Append(CPPPATH=["include/", "../include"]) sources = Glob("include/*.cpp") -library = env.SharedLibrary( - "build/addons/RhythmGameUtilities/libRhythmGameUtilities.{}.{}" - .format(env["platform"], env["target"]), - source=sources -) +if env["platform"] == "macos": + file_name = "libRhythmGameUtilities.{}.{}".format(env["platform"], env["target"]) + + library = env.SharedLibrary( + "build/addons/RhythmGameUtilities/{}.framework/{}".format(file_name, file_name), + source=sources + ) +else: + library = env.SharedLibrary( + "build/addons/RhythmGameUtilities/libRhythmGameUtilities{}{}" + .format(env["suffix"], env["SHLIBSUFFIX"]), + source=sources, + ) gdextension_copy = env.Command( target="build/addons/RhythmGameUtilities/RhythmGameUtilities.gdextension", From 5ef245120153e3e9a8db02e27cd0eb4c94b8b4b1 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Thu, 7 Nov 2024 23:13:47 -0500 Subject: [PATCH 17/19] Updated README.md --- Documentation/API/Parsers/ParseLyricsFromChartSection.md | 2 +- README.md | 2 +- RhythmGameUtilities/README.md | 2 +- UnityPackage/README.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/API/Parsers/ParseLyricsFromChartSection.md b/Documentation/API/Parsers/ParseLyricsFromChartSection.md index ed6b796..f47a744 100644 --- a/Documentation/API/Parsers/ParseLyricsFromChartSection.md +++ b/Documentation/API/Parsers/ParseLyricsFromChartSection.md @@ -1,6 +1,6 @@ #### `Parsers.ParseLyricsFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/README.md b/README.md index be9d60e..3601337 100644 --- a/README.md +++ b/README.md @@ -383,7 +383,7 @@ func _ready() -> void: #### `Parsers.ParseLyricsFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/RhythmGameUtilities/README.md b/RhythmGameUtilities/README.md index be9d60e..3601337 100644 --- a/RhythmGameUtilities/README.md +++ b/RhythmGameUtilities/README.md @@ -383,7 +383,7 @@ func _ready() -> void: #### `Parsers.ParseLyricsFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# diff --git a/UnityPackage/README.md b/UnityPackage/README.md index be9d60e..3601337 100644 --- a/UnityPackage/README.md +++ b/UnityPackage/README.md @@ -383,7 +383,7 @@ func _ready() -> void: #### `Parsers.ParseLyricsFromChartSection` -> Languages: `C#` `C++` +> Languages: `C#` `C++` `GDScript` ##### C# From 58aab4b79626a52775ee3868bf841ce4e9e0347e Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Thu, 7 Nov 2024 23:35:36 -0500 Subject: [PATCH 18/19] Renamed variable. --- GodotPlugin/include/utilities.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GodotPlugin/include/utilities.hpp b/GodotPlugin/include/utilities.hpp index 46e6277..679b978 100644 --- a/GodotPlugin/include/utilities.hpp +++ b/GodotPlugin/include/utilities.hpp @@ -26,7 +26,7 @@ std::vector>> convert_section_to_section_internal(Array section) { std::vector>> - sectionInternal; + section_internal; for (auto i = 0; i < section.size(); i += 1) { @@ -53,11 +53,11 @@ convert_section_to_section_internal(Array section) } } - sectionInternal.push_back( + section_internal.push_back( std::make_pair(key.utf8().get_data(), valuesInternal)); } } } - return sectionInternal; + return section_internal; } From 92abf82cc73da639e4f2c994a5468dfd57477891 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Thu, 7 Nov 2024 23:37:03 -0500 Subject: [PATCH 19/19] Renamed variable. --- GodotPlugin/include/utilities.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GodotPlugin/include/utilities.hpp b/GodotPlugin/include/utilities.hpp index 679b978..d088064 100644 --- a/GodotPlugin/include/utilities.hpp +++ b/GodotPlugin/include/utilities.hpp @@ -41,7 +41,7 @@ convert_section_to_section_internal(Array section) String key = keys[j]; Array values = variant[key]; - std::vector valuesInternal; + std::vector values_internal; for (auto k = 0; k < values.size(); k += 1) { @@ -49,12 +49,12 @@ convert_section_to_section_internal(Array section) { String value = values[k]; - valuesInternal.push_back(value.utf8().get_data()); + values_internal.push_back(value.utf8().get_data()); } } section_internal.push_back( - std::make_pair(key.utf8().get_data(), valuesInternal)); + std::make_pair(key.utf8().get_data(), values_internal)); } } }