Showing preview only (1,304K chars total). Download the full file or copy to clipboard to get everything.
Repository: utopia-rise/fmod-gdnative
Branch: master
Commit: a3c2dc9a72b0
Files: 560
Total size: 21.7 MB
Directory structure:
gitextract_oki6utj3/
├── .clang-format
├── .gitattributes
├── .github/
│ ├── actions/
│ │ ├── create-android-plugin/
│ │ │ └── action.yaml
│ │ └── create-native-build/
│ │ └── action.yaml
│ └── workflows/
│ ├── check_pr.yml
│ └── release.yml
├── .gitignore
├── .gitmodules
├── .readthedocs.yml
├── Android.mk
├── LICENSE
├── README.md
├── SConstruct
├── android-plugin/
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── library/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── utopiarise/
│ │ │ └── godot/
│ │ │ └── fmod/
│ │ │ └── android/
│ │ │ └── plugin/
│ │ │ └── FmodPlugin.kt
│ │ └── resources/
│ │ └── fmod-android-license.txt
│ └── settings.gradle.kts
├── demo/
│ ├── .gitattributes
│ ├── .gitignore
│ ├── .gutconfig.json
│ ├── addons/
│ │ ├── fmod/
│ │ │ ├── .gitignore
│ │ │ ├── FmodAndroidExportPlugin.gd
│ │ │ ├── FmodAndroidExportPlugin.gd.uid
│ │ │ ├── FmodManager.gd
│ │ │ ├── FmodManager.gd.uid
│ │ │ ├── FmodPlugin.gd
│ │ │ ├── FmodPlugin.gd.uid
│ │ │ ├── fmod.gdextension
│ │ │ ├── fmod.gdextension.uid
│ │ │ ├── icons/
│ │ │ │ ├── bank_icon.svg.import
│ │ │ │ ├── bus_icon.svg.import
│ │ │ │ ├── c_parameter_icon.svg.import
│ │ │ │ ├── d_parameter_icon.svg.import
│ │ │ │ ├── event_icon.svg.import
│ │ │ │ ├── fmod_emitter.png.import
│ │ │ │ ├── fmod_icon.svg.import
│ │ │ │ ├── snapshot_icon.svg.import
│ │ │ │ └── vca_icon.svg.import
│ │ │ ├── libs/
│ │ │ │ ├── android/
│ │ │ │ │ └── arm64/
│ │ │ │ │ └── CopyPast_Fmod_Libs_Here.txt
│ │ │ │ ├── iOS/
│ │ │ │ │ └── CopyPast_Fmod_Libs_Here.txt
│ │ │ │ ├── linux/
│ │ │ │ │ └── CopyPast_Fmod_Libs_Here.txt
│ │ │ │ ├── macos/
│ │ │ │ │ ├── CopyPast_Fmod_Libs_Here.txt
│ │ │ │ │ ├── libGodotFmod.macos.editor.framework/
│ │ │ │ │ │ └── Info.plist
│ │ │ │ │ ├── libGodotFmod.macos.template_debug.framework/
│ │ │ │ │ │ └── Info.plist
│ │ │ │ │ └── libGodotFmod.macos.template_release.framework/
│ │ │ │ │ └── Info.plist
│ │ │ │ └── windows/
│ │ │ │ └── CopyPast_Fmod_Libs_Here.txt
│ │ │ ├── plugin.cfg
│ │ │ └── tool/
│ │ │ ├── FmodBankDatabase.gd
│ │ │ ├── FmodBankDatabase.gd.uid
│ │ │ ├── inspectors/
│ │ │ │ ├── FmodBankLoaderPropertyInspectorPlugin.gd
│ │ │ │ ├── FmodBankLoaderPropertyInspectorPlugin.gd.uid
│ │ │ │ ├── FmodEmitterPropertyInspectorPlugin.gd
│ │ │ │ └── FmodEmitterPropertyInspectorPlugin.gd.uid
│ │ │ ├── performances/
│ │ │ │ ├── PerformancesDisplay.gd
│ │ │ │ └── PerformancesDisplay.gd.uid
│ │ │ ├── property_editors/
│ │ │ │ ├── FmodBankPathEditorProperty.gd
│ │ │ │ ├── FmodBankPathEditorProperty.gd.uid
│ │ │ │ ├── FmodBankPathsPropertyEditorUi.tscn
│ │ │ │ ├── FmodEventEditorProperty.gd
│ │ │ │ ├── FmodEventEditorProperty.gd.uid
│ │ │ │ ├── FmodEventEditorProperty.tscn
│ │ │ │ ├── FmodGuidAndPathPropertyEditorUi.gd
│ │ │ │ ├── FmodGuidAndPathPropertyEditorUi.gd.uid
│ │ │ │ ├── FmodGuidAndPathPropertyEditorUi.tscn
│ │ │ │ ├── FmodPathEditorProperty.gd
│ │ │ │ ├── FmodPathEditorProperty.gd.uid
│ │ │ │ └── FmodPathEditorProperty.tscn
│ │ │ └── ui/
│ │ │ ├── EventParametersDisplay.gd
│ │ │ ├── EventParametersDisplay.gd.uid
│ │ │ ├── EventParametersDisplay.tscn
│ │ │ ├── EventParametersWindow.tscn
│ │ │ ├── EventPlayControls.gd
│ │ │ ├── EventPlayControls.gd.uid
│ │ │ ├── FmodBankExplorer.gd
│ │ │ ├── FmodBankExplorer.gd.uid
│ │ │ ├── FmodBankExplorer.tscn
│ │ │ ├── ParameterDisplay.gd
│ │ │ ├── ParameterDisplay.gd.uid
│ │ │ ├── ParameterDisplay.tscn
│ │ │ └── TestFmodBankExplorer.tscn
│ │ └── gut/
│ │ ├── GutScene.gd
│ │ ├── GutScene.gd.uid
│ │ ├── GutScene.tscn
│ │ ├── LICENSE.md
│ │ ├── UserFileViewer.gd
│ │ ├── UserFileViewer.gd.uid
│ │ ├── UserFileViewer.tscn
│ │ ├── autofree.gd
│ │ ├── autofree.gd.uid
│ │ ├── awaiter.gd
│ │ ├── awaiter.gd.uid
│ │ ├── cli/
│ │ │ ├── change_project_warnings.gd
│ │ │ ├── change_project_warnings.gd.uid
│ │ │ ├── gut_cli.gd
│ │ │ ├── gut_cli.gd.uid
│ │ │ ├── optparse.gd
│ │ │ └── optparse.gd.uid
│ │ ├── collected_script.gd
│ │ ├── collected_script.gd.uid
│ │ ├── collected_test.gd
│ │ ├── collected_test.gd.uid
│ │ ├── comparator.gd
│ │ ├── comparator.gd.uid
│ │ ├── compare_result.gd
│ │ ├── compare_result.gd.uid
│ │ ├── diff_formatter.gd
│ │ ├── diff_formatter.gd.uid
│ │ ├── diff_tool.gd
│ │ ├── diff_tool.gd.uid
│ │ ├── double_templates/
│ │ │ ├── function_template.txt
│ │ │ ├── init_template.txt
│ │ │ └── script_template.txt
│ │ ├── double_tools.gd
│ │ ├── double_tools.gd.uid
│ │ ├── doubler.gd
│ │ ├── doubler.gd.uid
│ │ ├── dynamic_gdscript.gd
│ │ ├── dynamic_gdscript.gd.uid
│ │ ├── editor_caret_context_notifier.gd
│ │ ├── editor_caret_context_notifier.gd.uid
│ │ ├── error_tracker.gd
│ │ ├── error_tracker.gd.uid
│ │ ├── fonts/
│ │ │ └── OFL.txt
│ │ ├── gui/
│ │ │ ├── EditorRadioButton.tres
│ │ │ ├── GutBottomPanel.gd
│ │ │ ├── GutBottomPanel.gd.uid
│ │ │ ├── GutBottomPanel.tscn
│ │ │ ├── GutControl.gd
│ │ │ ├── GutControl.gd.uid
│ │ │ ├── GutControl.tscn
│ │ │ ├── GutEditorWindow.gd
│ │ │ ├── GutEditorWindow.gd.uid
│ │ │ ├── GutEditorWindow.tscn
│ │ │ ├── GutLogo.tscn
│ │ │ ├── GutRunner.gd
│ │ │ ├── GutRunner.gd.uid
│ │ │ ├── GutRunner.tscn
│ │ │ ├── GutSceneTheme.tres
│ │ │ ├── MinGui.tscn
│ │ │ ├── NormalGui.tscn
│ │ │ ├── OutputText.gd
│ │ │ ├── OutputText.gd.uid
│ │ │ ├── OutputText.tscn
│ │ │ ├── ResizeHandle.gd
│ │ │ ├── ResizeHandle.gd.uid
│ │ │ ├── ResizeHandle.tscn
│ │ │ ├── ResultsTree.gd
│ │ │ ├── ResultsTree.gd.uid
│ │ │ ├── ResultsTree.tscn
│ │ │ ├── RunAtCursor.gd
│ │ │ ├── RunAtCursor.gd.uid
│ │ │ ├── RunAtCursor.tscn
│ │ │ ├── RunExternally.gd
│ │ │ ├── RunExternally.gd.uid
│ │ │ ├── RunExternally.tscn
│ │ │ ├── RunResults.gd
│ │ │ ├── RunResults.gd.uid
│ │ │ ├── RunResults.tscn
│ │ │ ├── Settings.tscn
│ │ │ ├── ShellOutOptions.gd
│ │ │ ├── ShellOutOptions.gd.uid
│ │ │ ├── ShellOutOptions.tscn
│ │ │ ├── ShortcutButton.gd
│ │ │ ├── ShortcutButton.gd.uid
│ │ │ ├── ShortcutButton.tscn
│ │ │ ├── ShortcutDialog.gd
│ │ │ ├── ShortcutDialog.gd.uid
│ │ │ ├── ShortcutDialog.tscn
│ │ │ ├── about.gd
│ │ │ ├── about.gd.uid
│ │ │ ├── about.tscn
│ │ │ ├── editor_globals.gd
│ │ │ ├── editor_globals.gd.uid
│ │ │ ├── gut_config_gui.gd
│ │ │ ├── gut_config_gui.gd.uid
│ │ │ ├── gut_gui.gd
│ │ │ ├── gut_gui.gd.uid
│ │ │ ├── gut_logo.gd
│ │ │ ├── gut_logo.gd.uid
│ │ │ ├── gut_user_preferences.gd
│ │ │ ├── gut_user_preferences.gd.uid
│ │ │ ├── option_maker.gd
│ │ │ ├── option_maker.gd.uid
│ │ │ ├── panel_controls.gd
│ │ │ ├── panel_controls.gd.uid
│ │ │ ├── run_from_editor.gd
│ │ │ ├── run_from_editor.gd.uid
│ │ │ └── run_from_editor.tscn
│ │ ├── gut.gd
│ │ ├── gut.gd.uid
│ │ ├── gut_cmdln.gd
│ │ ├── gut_cmdln.gd.uid
│ │ ├── gut_config.gd
│ │ ├── gut_config.gd.uid
│ │ ├── gut_fonts.gd
│ │ ├── gut_fonts.gd.uid
│ │ ├── gut_loader.gd
│ │ ├── gut_loader.gd.uid
│ │ ├── gut_loader_the_scene.tscn
│ │ ├── gut_menu.gd
│ │ ├── gut_menu.gd.uid
│ │ ├── gut_plugin.gd
│ │ ├── gut_plugin.gd.uid
│ │ ├── gut_to_move.gd
│ │ ├── gut_to_move.gd.uid
│ │ ├── gut_tracked_error.gd
│ │ ├── gut_tracked_error.gd.uid
│ │ ├── gut_vscode_debugger.gd
│ │ ├── gut_vscode_debugger.gd.uid
│ │ ├── hook_script.gd
│ │ ├── hook_script.gd.uid
│ │ ├── inner_class_registry.gd
│ │ ├── inner_class_registry.gd.uid
│ │ ├── input_factory.gd
│ │ ├── input_factory.gd.uid
│ │ ├── input_sender.gd
│ │ ├── input_sender.gd.uid
│ │ ├── junit_xml_export.gd
│ │ ├── junit_xml_export.gd.uid
│ │ ├── lazy_loader.gd
│ │ ├── lazy_loader.gd.uid
│ │ ├── logger.gd
│ │ ├── logger.gd.uid
│ │ ├── menu_manager.gd.uid
│ │ ├── method_maker.gd
│ │ ├── method_maker.gd.uid
│ │ ├── one_to_many.gd
│ │ ├── one_to_many.gd.uid
│ │ ├── orphan_counter.gd
│ │ ├── orphan_counter.gd.uid
│ │ ├── parameter_factory.gd
│ │ ├── parameter_factory.gd.uid
│ │ ├── parameter_handler.gd
│ │ ├── parameter_handler.gd.uid
│ │ ├── plugin.cfg
│ │ ├── printers.gd
│ │ ├── printers.gd.uid
│ │ ├── result_exporter.gd
│ │ ├── result_exporter.gd.uid
│ │ ├── script_parser.gd
│ │ ├── script_parser.gd.uid
│ │ ├── signal_watcher.gd
│ │ ├── signal_watcher.gd.uid
│ │ ├── source_code_pro.fnt
│ │ ├── spy.gd
│ │ ├── spy.gd.uid
│ │ ├── strutils.gd
│ │ ├── strutils.gd.uid
│ │ ├── stub_params.gd
│ │ ├── stub_params.gd.uid
│ │ ├── stubber.gd
│ │ ├── stubber.gd.uid
│ │ ├── summary.gd
│ │ ├── summary.gd.uid
│ │ ├── test.gd
│ │ ├── test.gd.uid
│ │ ├── test_collector.gd
│ │ ├── test_collector.gd.uid
│ │ ├── thing_counter.gd
│ │ ├── thing_counter.gd.uid
│ │ ├── utils.gd
│ │ ├── utils.gd.uid
│ │ ├── version_conversion.gd
│ │ ├── version_conversion.gd.uid
│ │ ├── version_numbers.gd
│ │ ├── version_numbers.gd.uid
│ │ ├── warnings_manager.gd
│ │ └── warnings_manager.gd.uid
│ ├── appstore.png.import
│ ├── assets/
│ │ ├── Banks/
│ │ │ ├── Dialogue_CN.bank
│ │ │ ├── Dialogue_EN.bank
│ │ │ ├── Dialogue_JP.bank
│ │ │ ├── Master.bank
│ │ │ ├── Master.strings.bank
│ │ │ ├── Music.bank
│ │ │ ├── SFX.bank
│ │ │ └── Vehicles.bank
│ │ ├── Music/
│ │ │ ├── License.txt
│ │ │ ├── jingles_SAX07.ogg
│ │ │ └── jingles_SAX07.ogg.import
│ │ └── Sounds/
│ │ ├── beltHandle1.ogg
│ │ ├── beltHandle1.ogg.import
│ │ ├── beltHandle2.ogg
│ │ ├── beltHandle2.ogg.import
│ │ ├── bookClose.ogg
│ │ ├── bookClose.ogg.import
│ │ ├── bookFlip1.ogg
│ │ ├── bookFlip1.ogg.import
│ │ ├── bookFlip2.ogg
│ │ ├── bookFlip2.ogg.import
│ │ ├── bookFlip3.ogg
│ │ ├── bookFlip3.ogg.import
│ │ ├── bookOpen.ogg
│ │ ├── bookOpen.ogg.import
│ │ ├── bookPlace1.ogg
│ │ ├── bookPlace1.ogg.import
│ │ ├── bookPlace2.ogg
│ │ ├── bookPlace2.ogg.import
│ │ ├── bookPlace3.ogg
│ │ ├── bookPlace3.ogg.import
│ │ ├── chop.ogg
│ │ ├── chop.ogg.import
│ │ ├── cloth1.ogg
│ │ ├── cloth1.ogg.import
│ │ ├── cloth2.ogg
│ │ ├── cloth2.ogg.import
│ │ ├── cloth3.ogg
│ │ ├── cloth3.ogg.import
│ │ ├── cloth4.ogg
│ │ ├── cloth4.ogg.import
│ │ ├── clothBelt.ogg
│ │ ├── clothBelt.ogg.import
│ │ ├── clothBelt2.ogg
│ │ ├── clothBelt2.ogg.import
│ │ ├── creak1.ogg
│ │ ├── creak1.ogg.import
│ │ ├── creak2.ogg
│ │ ├── creak2.ogg.import
│ │ ├── creak3.ogg
│ │ ├── creak3.ogg.import
│ │ ├── doorClose_1.ogg
│ │ ├── doorClose_1.ogg.import
│ │ ├── doorClose_2.ogg
│ │ ├── doorClose_2.ogg.import
│ │ ├── doorClose_3.ogg
│ │ ├── doorClose_3.ogg.import
│ │ ├── doorClose_4.ogg
│ │ ├── doorClose_4.ogg.import
│ │ ├── doorOpen_1.ogg
│ │ ├── doorOpen_1.ogg.import
│ │ ├── doorOpen_2.ogg
│ │ ├── doorOpen_2.ogg.import
│ │ ├── drawKnife1.ogg
│ │ ├── drawKnife1.ogg.import
│ │ ├── drawKnife2.ogg
│ │ ├── drawKnife2.ogg.import
│ │ ├── drawKnife3.ogg
│ │ ├── drawKnife3.ogg.import
│ │ ├── dropLeather.ogg
│ │ ├── dropLeather.ogg.import
│ │ ├── footstep00.ogg
│ │ ├── footstep00.ogg.import
│ │ ├── footstep01.ogg
│ │ ├── footstep01.ogg.import
│ │ ├── footstep02.ogg
│ │ ├── footstep02.ogg.import
│ │ ├── footstep03.ogg
│ │ ├── footstep03.ogg.import
│ │ ├── footstep04.ogg
│ │ ├── footstep04.ogg.import
│ │ ├── footstep05.ogg
│ │ ├── footstep05.ogg.import
│ │ ├── footstep06.ogg
│ │ ├── footstep06.ogg.import
│ │ ├── footstep07.ogg
│ │ ├── footstep07.ogg.import
│ │ ├── footstep08.ogg
│ │ ├── footstep08.ogg.import
│ │ ├── footstep09.ogg
│ │ ├── footstep09.ogg.import
│ │ ├── handleCoins.ogg
│ │ ├── handleCoins.ogg.import
│ │ ├── handleCoins2.ogg
│ │ ├── handleCoins2.ogg.import
│ │ ├── handleSmallLeather.ogg
│ │ ├── handleSmallLeather.ogg.import
│ │ ├── handleSmallLeather2.ogg
│ │ ├── handleSmallLeather2.ogg.import
│ │ ├── knifeSlice.ogg
│ │ ├── knifeSlice.ogg.import
│ │ ├── knifeSlice2.ogg
│ │ ├── knifeSlice2.ogg.import
│ │ ├── licence.txt
│ │ ├── metalClick.ogg
│ │ ├── metalClick.ogg.import
│ │ ├── metalLatch.ogg
│ │ ├── metalLatch.ogg.import
│ │ ├── metalPot1.ogg
│ │ ├── metalPot1.ogg.import
│ │ ├── metalPot2.ogg
│ │ ├── metalPot2.ogg.import
│ │ ├── metalPot3.ogg
│ │ └── metalPot3.ogg.import
│ ├── default_env.tres
│ ├── export_presets.cfg
│ ├── high_level_2D/
│ │ ├── ChangeColor.gd
│ │ ├── ChangeColor.gd.uid
│ │ ├── ChooseLanguageButton.gd
│ │ ├── ChooseLanguageButton.gd.uid
│ │ ├── Emitter.gd
│ │ ├── Emitter.gd.uid
│ │ ├── FmodNodesTest.tscn
│ │ ├── Kinematic.gd
│ │ ├── Kinematic.gd.uid
│ │ ├── SayWelcomeButton.gd
│ │ ├── SayWelcomeButton.gd.uid
│ │ ├── footstep.tscn
│ │ ├── sin_move.gd
│ │ └── sin_move.gd.uid
│ ├── high_level_3D/
│ │ ├── FPSCounter.gd
│ │ ├── FPSCounter.gd.uid
│ │ ├── World.tscn
│ │ ├── environment/
│ │ │ ├── 1x1.png.import
│ │ │ ├── Ball.tscn
│ │ │ ├── Floor.tscn
│ │ │ ├── Wall.tscn
│ │ │ ├── ball_material.tres
│ │ │ ├── box.tscn
│ │ │ ├── sin_move.gd
│ │ │ ├── sin_move.gd.uid
│ │ │ ├── soundcollider.gd
│ │ │ ├── soundcollider.gd.uid
│ │ │ └── wall_material.tres
│ │ ├── player/
│ │ │ ├── Camera.gd
│ │ │ ├── Camera.gd.uid
│ │ │ ├── Player.gd
│ │ │ ├── Player.gd.uid
│ │ │ └── Player.tscn
│ │ ├── rollingball.gd
│ │ ├── rollingball.gd.uid
│ │ ├── selfdestroy.gd
│ │ └── selfdestroy.gd.uid
│ ├── icon.png.import
│ ├── icon.svg.import
│ ├── low_level_2D/
│ │ ├── ChangeColor.gd
│ │ ├── ChangeColor.gd.uid
│ │ ├── Emitter.gd
│ │ ├── Emitter.gd.uid
│ │ ├── EnterAndLeave.gd
│ │ ├── EnterAndLeave.gd.uid
│ │ ├── EnterandLeave2.gd
│ │ ├── EnterandLeave2.gd.uid
│ │ ├── FmodScriptTest.tscn
│ │ ├── FmodTest.gd
│ │ ├── FmodTest.gd.uid
│ │ ├── LangChooseButton.gd
│ │ ├── LangChooseButton.gd.uid
│ │ ├── Listener.gd
│ │ ├── Listener.gd.uid
│ │ ├── Listener2.gd
│ │ ├── Listener2.gd.uid
│ │ ├── WelcomeButton.gd
│ │ └── WelcomeButton.gd.uid
│ ├── project.godot
│ ├── run_tests.sh
│ └── test/
│ ├── integration/
│ │ └── init
│ ├── tests.tscn
│ └── unit/
│ ├── test_bank.gd
│ ├── test_bank.gd.uid
│ ├── test_bus.gd
│ ├── test_bus.gd.uid
│ ├── test_callbacks.gd
│ ├── test_callbacks.gd.uid
│ ├── test_desc_event.gd
│ ├── test_desc_event.gd.uid
│ ├── test_event.gd
│ ├── test_event.gd.uid
│ ├── test_global.gd
│ ├── test_global.gd.uid
│ ├── test_listener.gd
│ ├── test_listener.gd.uid
│ ├── test_sound.gd
│ ├── test_sound.gd.uid
│ ├── test_vca.gd
│ └── test_vca.gd.uid
├── docs/
│ ├── .gitignore
│ ├── build.sh
│ ├── mkdocs.yml
│ ├── requirements.txt
│ ├── run.sh
│ └── src/
│ └── doc/
│ ├── advanced/
│ │ └── 1-compiling.md
│ ├── index.md
│ └── user-guide/
│ ├── 1-install.md
│ ├── 2-initialization.md
│ ├── 3-using-fmod-plugin.md
│ ├── 4-loading-banks.md
│ ├── 5-playing-events.md
│ ├── 6-listeners.md
│ ├── 7-playing-sounds.md
│ ├── 8-other-low-level-examples.md
│ └── 9-plugins.md
├── get_fmod.py
├── jni/
│ └── Application.mk
└── src/
├── callback/
│ ├── event_callbacks.cpp
│ ├── event_callbacks.h
│ ├── file_callbacks.cpp
│ └── file_callbacks.h
├── constants.h
├── core/
│ ├── fmod_file.cpp
│ ├── fmod_file.h
│ ├── fmod_sound.cpp
│ └── fmod_sound.h
├── data/
│ ├── performance_data.cpp
│ └── performance_data.h
├── fmod_cache.cpp
├── fmod_cache.h
├── fmod_logging.cpp
├── fmod_logging.h
├── fmod_server.cpp
├── fmod_server.h
├── fmod_string_names.cpp
├── fmod_string_names.h
├── helpers/
│ ├── common.h
│ ├── constants.h
│ ├── current_function.h
│ ├── files.h
│ └── maths.h
├── nodes/
│ ├── fmod_bank_loader.cpp
│ ├── fmod_bank_loader.h
│ ├── fmod_event_emitter.h
│ ├── fmod_event_emitter_2d.cpp
│ ├── fmod_event_emitter_2d.h
│ ├── fmod_event_emitter_3d.cpp
│ ├── fmod_event_emitter_3d.h
│ ├── fmod_listener.h
│ ├── fmod_listener_2d.cpp
│ ├── fmod_listener_2d.h
│ ├── fmod_listener_3d.cpp
│ └── fmod_listener_3d.h
├── plugins/
│ ├── ios_plugins_loader.h
│ └── plugins_helper.h
├── register_types.cpp
├── register_types.h
├── resources/
│ ├── fmod_dsp_settings.cpp
│ ├── fmod_dsp_settings.h
│ ├── fmod_logging_settings.cpp
│ ├── fmod_logging_settings.h
│ ├── fmod_plugins_settings.cpp
│ ├── fmod_plugins_settings.h
│ ├── fmod_settings.cpp
│ ├── fmod_settings.h
│ ├── fmod_software_format_settings.cpp
│ ├── fmod_software_format_settings.h
│ ├── fmod_sound_3d_settings.cpp
│ └── fmod_sound_3d_settings.h
├── studio/
│ ├── fmod_bank.cpp
│ ├── fmod_bank.h
│ ├── fmod_bus.cpp
│ ├── fmod_bus.h
│ ├── fmod_event.cpp
│ ├── fmod_event.h
│ ├── fmod_event_description.cpp
│ ├── fmod_event_description.h
│ ├── fmod_parameter_description.cpp
│ ├── fmod_parameter_description.h
│ ├── fmod_vca.cpp
│ └── fmod_vca.h
└── tools/
├── fmod_editor_export_plugin.cpp
├── fmod_editor_export_plugin.h
├── fmod_editor_plugin.cpp
└── fmod_editor_plugin.h
================================================
FILE CONTENTS
================================================
================================================
FILE: .clang-format
================================================
---
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: BlockIndent
AlignEscapedNewlines: Left
AlignOperands: AlignAfterOperator
AlignTrailingComments: false
#Allow
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortEnumsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
#Brace`
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterComma
BreakStringLiterals: true
ColumnLimit: 120
CompactNamespaces: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: Always
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '".*"'
Priority: 1
- Regex: '^<.*\.h>'
Priority: 2
- Regex: '^<.*'
Priority: 3
IndentAccessModifiers: false
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
PackConstructorInitializers: CurrentLine
#Penalty
PenaltyBreakAssignment: 40
PenaltyBreakBeforeFirstCallParameter: 0
PenaltyBreakComment: 100
PenaltyBreakFirstLessLess: 0
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 100
PenaltyBreakTemplateDeclaration: 0
PenaltyExcessCharacter: 1
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 10000
PointerAlignment: Left
ReferenceAlignment: Left
ReflowComments: true
SeparateDefinitionBlocks: Always
ShortNamespaceLines: 0
SortIncludes: CaseInsensitive
SortUsingDeclarations: false
#Space
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: 1
SpacesInParentheses: false
SpacesInSquareBrackets: false
#Tab
TabWidth: 4
UseTab: Never
---
Language: Cpp
Standard: c++17
...
================================================
FILE: .gitattributes
================================================
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf
# Ignore some files when exporting to a ZIP.
# Only include the addons folder when downloading from the Asset Library.
/** export-ignore
/addons/fmod !export-ignore
/addons/fmod/** !export-ignore
================================================
FILE: .github/actions/create-android-plugin/action.yaml
================================================
name: Create Fmod native build
description: Creates fmod native build for a specific platform
runs:
using: composite
steps:
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
java-version: 17
- name: Download fmod jar
uses: actions/download-artifact@v4
with:
name: fmod-jar
path: android-plugin/library/libraries/
- name: Build android plugin
uses: eskatos/gradle-command-action@v1
with:
wrapper-directory: android-plugin/
build-root-directory: android-plugin/
arguments: :library:build
================================================
FILE: .github/actions/create-native-build/action.yaml
================================================
name: Create Fmod native build
description: Creates fmod native build for a specific platform
inputs:
platform:
description: The platform to build for.
target:
description: The target to build.
additional-python-packages:
description: Additional python package to install.
flags:
description: Additional compilation scons flags.
fmod-executable-suffix:
description: The suffix of fmod executable to install fmod libraries.
fmod-user:
description: The FMOD user used to download fmod binaries
fmod-password:
description: The password for fmod account used to download fmod binaries.
shell:
description: The shell used by the runner.
runs:
using: composite
steps:
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v4
with:
# Semantic version range syntax or exact version of a Python version
python-version: "3.x"
# Optional - x64 or x86 architecture, defaults to x64
architecture: "x64"
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
#TODO: remove hardcoded scons version when https://github.com/godotengine/godot-cpp/pull/1526 is released
- name: Configuring Python packages
shell: ${{ inputs.shell }}
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons==4.7.0 requests ${{ inputs.additional-python-packages }}
python --version
scons --version
- name: Installing FMOD on Windows
shell: ${{ inputs.shell }}
if: runner.os == 'Windows'
run: |
cd ..
New-Item -ItemType directory -Path libs; cd libs
New-Item -ItemType directory -Path fmod; cd fmod
python ../../fmod-gdextension/get_fmod.py ${{inputs.fmod-user}} ${{inputs.fmod-password}} ${{inputs.platform}} ${{env.FMOD_VERSION}}
7z x fmodstudioapi${{env.FMOD_VERSION}}${{inputs.fmod-executable-suffix}}
ls
mv api/ windows
cd ../../
- name: Installing FMOD on Linux & Android
if: runner.os == 'Linux'
shell: ${{ inputs.shell }}
run: |
cd ..
mkdir libs && cd libs
mkdir fmod && cd fmod
python ../../fmod-gdextension/get_fmod.py ${{inputs.fmod-user}} ${{inputs.fmod-password}} ${{inputs.platform}} ${{env.FMOD_VERSION}}
tar -xvf fmodstudioapi${{env.FMOD_VERSION}}${{inputs.fmod-executable-suffix}}
mv fmodstudioapi${{env.FMOD_VERSION}}${{inputs.platform}}/api ${{inputs.platform}}
cd ../../
- name: Installing FMOD on MacOS & iOS
if: runner.os == 'MacOS'
shell: ${{ inputs.shell }}
run: |
cd ..
mkdir libs && cd libs
mkdir fmod && cd fmod
python ../../fmod-gdextension/get_fmod.py ${{inputs.fmod-user}} ${{inputs.fmod-password}} ${{inputs.platform}} ${{env.FMOD_VERSION}}
hdiutil attach fmodstudioapi${{env.FMOD_VERSION}}${{inputs.fmod-executable-suffix}}
[[ ${{inputs.platform}} = "macos" ]] && cp -r "/Volumes/FMOD Programmers API Mac/FMOD Programmers API/api" osx
[[ ${{inputs.platform}} = "ios" ]] && cp -r "/Volumes/FMOD Programmers API iOS/FMOD Programmers API/api" ios
cd ../../
- name: create android fmod artifact
if: inputs.platform == 'android' && inputs.target == 'template_release'
shell: ${{ inputs.shell }}
run: |
mkdir android-fmod-artifact
cp ../libs/fmod/android/core/lib/fmod.jar android-fmod-artifact/
cp android-plugin/library/src/main/resources/fmod-android-license.txt android-fmod-artifact/
- name: Upload fmod jar
if: inputs.platform == 'android' && inputs.target == 'template_release'
uses: actions/upload-artifact@v4
with:
name: fmod-jar
path: android-fmod-artifact
if-no-files-found: error
- name: Get number of CPU cores
id: cpu-cores
uses: SimenB/github-actions-cpu-cores@v1
- name: Compilation
shell: ${{ inputs.shell }}
run: |
cd ../fmod-gdextension
scons platform=${{ inputs.platform }} generate_bindings=yes target=${{ inputs.target }} target_path=${{ env.TARGET_PATH }} target_name=${{ env.TARGET_NAME }} -j${{ steps.cpu-cores.outputs.count }} ${{ inputs.flags }}
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.platform }}-${{ inputs.target }}
path: ${{ env.TARGET_PATH }}${{ inputs.platform }}/**/*.*
if-no-files-found: error
================================================
FILE: .github/workflows/check_pr.yml
================================================
name: 🌈 Check Pull Request
on:
pull_request:
types: [opened, synchronize, reopened]
pull_request_target:
types: [opened, synchronize, reopened]
# Global Settings
env:
GODOT_VERSION: 4.5
NDK_VERSION: 27.3.13750724
TARGET_PATH: demo/addons/fmod/libs/
TARGET_NAME: libGodotFmod
FMOD_VERSION: 20306
jobs:
gate:
runs-on: ubuntu-latest
# EXCLUSIVE PATHS:
# - In-repo PRs use pull_request
# - External PRs use pull_request_target, so secrets are available, but only after the run is approved
if: >
(
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository
) || (
github.event_name == 'pull_request_target' &&
github.event.pull_request.head.repo.full_name != github.repository
)
environment: ${{ github.event_name == 'pull_request_target' && 'external-pr' || '' }}
steps:
- run: echo "Run Approved"
build:
name: ${{ matrix.name }}
needs: gate
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: Windows Editor Compilation
os: "windows-2022"
platform: windows
target: editor
additional-python-packages: pywin32
fmod-executable-suffix: win-installer.exe
shell: pwsh
- name: Windows Debug Compilation
os: "windows-2022"
platform: windows
target: template_debug
additional-python-packages: pywin32
fmod-executable-suffix: win-installer.exe
shell: pwsh
- name: Windows Release Compilation
os: "windows-2022"
platform: windows
target: template_release
additional-python-packages: pywin32
fmod-executable-suffix: win-installer.exe
shell: pwsh
- name: Ubuntu Editor Compilation
os: "ubuntu-22.04"
platform: linux
target: editor
fmod-executable-suffix: linux.tar.gz
fmod-core-platform-folder: linux/core/lib/x86_64
fmod-studio-platform-folder: linux/studio/lib/x86_64
fmod-library-suffix: so
godot-executable-download-suffix: linux.x86_64.zip
godot-executable: Godot_v$GODOT_VERSION-stable_linux.x86_64
shell: bash
- name: Ubuntu Debug Compilation
os: "ubuntu-22.04"
platform: linux
target: template_debug
fmod-executable-suffix: linux.tar.gz
shell: bash
- name: Ubuntu Release Compilation
os: "ubuntu-22.04"
platform: linux
target: template_release
fmod-executable-suffix: linux.tar.gz
shell: bash
- name: MacOS Editor Compilation
os: "macos-14"
platform: macos
target: editor
fmod-executable-suffix: osx.dmg
fmod-core-platform-folder: osx/core/lib
fmod-studio-platform-folder: osx/studio/lib
fmod-library-suffix: dylib
godot-executable-download-suffix: macos.universal.zip
godot-executable: Godot.app/Contents/MacOs/Godot
shell: bash
- name: MacOS Debug Compilation
os: "macos-14"
platform: macos
target: template_debug
fmod-executable-suffix: osx.dmg
shell: bash
- name: MacOS Release Compilation
os: "macos-14"
platform: macos
target: template_release
fmod-executable-suffix: osx.dmg
shell: bash
- name: Android Editor Compilation
os: "ubuntu-22.04"
platform: android
target: editor
fmod-executable-suffix: android.tar.gz
flags: ndk_version=$NDK_VERSION arch=arm64
shell: bash
- name: Android Debug Compilation
os: "ubuntu-22.04"
platform: android
target: template_debug
fmod-executable-suffix: android.tar.gz
flags: ndk_version=$NDK_VERSION arch=arm64
shell: bash
- name: Android Release Compilation
os: "ubuntu-22.04"
platform: android
target: template_release
fmod-executable-suffix: android.tar.gz
flags: ndk_version=$NDK_VERSION arch=arm64
shell: bash
- name: iOS Debug Compilation
os: "macos-14"
platform: ios
target: template_debug
fmod-executable-suffix: ios.dmg
shell: bash
- name: iOS Release Compilation
os: "macos-14"
platform: ios
target: template_release
fmod-executable-suffix: ios.dmg
shell: bash
steps:
- name: Checkout (in-repo PR)
if: github.event_name == 'pull_request'
uses: actions/checkout@v4
with:
lfs: true
submodules: recursive
- name: Checkout (external PR via target)
if: github.event_name == 'pull_request_target'
uses: actions/checkout@v4
with:
lfs: true
submodules: recursive
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false
- name: Android dependencies
if: ${{ matrix.platform == 'android' }}
uses: nttld/setup-ndk@v1
with:
ndk-version: r23c
link-to-sdk: true
- name: Compile native plugin
uses: ./.github/actions/create-native-build
with:
platform: ${{ matrix.platform }}
target: ${{ matrix.target }}
additional-python-packages: ${{ matrix.additional-python-packages }}
flags: ${{ matrix.flags }}
fmod-executable-suffix: ${{ matrix.fmod-executable-suffix }}
fmod-user: ${{ secrets.FMODUSER }}
fmod-password: ${{ secrets.FMODPASS }}
shell: ${{ matrix.shell }}
- name: Download godot engine
if: matrix.platform != 'android' && matrix.platform != 'ios' && matrix.platform != 'windows' && matrix.target == 'editor'
run: |
wget https://github.com/godotengine/godot-builds/releases/download/${{env.GODOT_VERSION}}-stable/Godot_v${{env.GODOT_VERSION}}-stable_${{ matrix.godot-executable-download-suffix }}
unzip Godot_v${{env.GODOT_VERSION}}-stable_${{ matrix.godot-executable-download-suffix }}
rm Godot_v${{env.GODOT_VERSION}}-stable_${{ matrix.godot-executable-download-suffix }}
- name: Run tests
if: matrix.platform != 'android' && matrix.platform != 'ios' && matrix.platform != 'windows' && matrix.target == 'editor'
run: |
cd demo
chmod +x run_tests.sh
chmod +x ../${{ matrix.godot-executable }}
./run_tests.sh ../${{ matrix.godot-executable }}
create-android-plugin:
needs: [build]
strategy:
matrix:
include:
- os: "ubuntu-22.04"
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
lfs: true
submodules: recursive
- name: Create android plugin
uses: ./.github/actions/create-android-plugin
================================================
FILE: .github/workflows/release.yml
================================================
name: 🌈 Release
on:
push:
tags:
- '\d+.\d+.\d+-\d+.\d+.\d+'
# Global Settings
env:
GODOT_VERSION: 4.5
NDK_VERSION: 27.3.13750724
TARGET_PATH: demo/addons/fmod/libs/
TARGET_NAME: libGodotFmod
FMOD_VERSION: 20306
jobs:
build:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: Windows Editor Compilation
os: "windows-2022"
platform: windows
target: editor
additional-python-packages: pywin32
fmod-executable-suffix: win-installer.exe
shell: pwsh
- name: Windows Debug Compilation
os: "windows-2022"
platform: windows
target: template_debug
additional-python-packages: pywin32
fmod-executable-suffix: win-installer.exe
shell: pwsh
- name: Windows Release Compilation
os: "windows-2022"
platform: windows
target: template_release
additional-python-packages: pywin32
fmod-executable-suffix: win-installer.exe
shell: pwsh
- name: Ubuntu Editor Compilation
os: "ubuntu-22.04"
platform: linux
target: editor
fmod-executable-suffix: linux.tar.gz
fmod-core-platform-folder: linux/core/lib/x86_64
fmod-studio-platform-folder: linux/studio/lib/x86_64
fmod-library-suffix: so
godot-executable-download-suffix: linux.x86_64.zip
godot-executable: Godot_v$GODOT_VERSION-stable_linux.x86_64
shell: bash
- name: Ubuntu Debug Compilation
os: "ubuntu-22.04"
platform: linux
target: template_debug
fmod-executable-suffix: linux.tar.gz
shell: bash
- name: Ubuntu Release Compilation
os: "ubuntu-22.04"
platform: linux
target: template_release
fmod-executable-suffix: linux.tar.gz
shell: bash
- name: MacOS Editor Compilation
os: "macos-14"
platform: macos
target: editor
fmod-executable-suffix: osx.dmg
fmod-core-platform-folder: osx/core/lib
fmod-studio-platform-folder: osx/studio/lib
fmod-library-suffix: dylib
godot-executable-download-suffix: macos.universal.zip
godot-executable: Godot.app/Contents/MacOs/Godot
shell: bash
- name: MacOS Debug Compilation
os: "macos-14"
platform: macos
target: template_debug
fmod-executable-suffix: osx.dmg
shell: bash
- name: MacOS Release Compilation
os: "macos-14"
platform: macos
target: template_release
fmod-executable-suffix: osx.dmg
shell: bash
- name: Android Editor Compilation
os: "ubuntu-22.04"
platform: android
target: editor
fmod-executable-suffix: android.tar.gz
flags: ndk_version=$NDK_VERSION arch=arm64
shell: bash
- name: Android Debug Compilation
os: "ubuntu-22.04"
platform: android
target: template_debug
fmod-executable-suffix: android.tar.gz
flags: ndk_version=$NDK_VERSION arch=arm64
shell: bash
- name: Android Release Compilation
os: "ubuntu-22.04"
platform: android
target: template_release
fmod-executable-suffix: android.tar.gz
flags: ndk_version=$NDK_VERSION arch=arm64
shell: bash
- name: iOS Debug Compilation
os: "macos-14"
platform: ios
target: template_debug
fmod-executable-suffix: ios.dmg
shell: bash
- name: iOS Release Compilation
os: "macos-14"
platform: ios
target: template_release
fmod-executable-suffix: ios.dmg
shell: bash
steps:
- name: Checkout
uses: actions/checkout@v4
with:
lfs: true
submodules: recursive
- name: Android dependencies
if: ${{ matrix.platform == 'android' }}
uses: nttld/setup-ndk@v1
with:
ndk-version: r23c
link-to-sdk: true
- name: Compile native plugin
uses: ./.github/actions/create-native-build
with:
platform: ${{ matrix.platform }}
target: ${{ matrix.target }}
additional-python-packages: ${{ matrix.additional-python-packages }}
flags: ${{ matrix.flags }}
fmod-executable-suffix: ${{ matrix.fmod-executable-suffix }}
fmod-user: ${{ secrets.FMODUSER }}
fmod-password: ${{ secrets.FMODPASS }}
shell: ${{ matrix.shell }}
package-godot-addon:
needs: [build]
strategy:
matrix:
include:
- os: "ubuntu-22.04"
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
lfs: true
submodules: recursive
- name: Create android plugin
uses: ./.github/actions/create-android-plugin
with:
godot-version: ${{ env.GODOT_VERSION }}
- name: Download linux editor libraries
uses: actions/download-artifact@v4
with:
name: linux-editor
path: demo/addons/fmod/libs/linux/
- name: Download linux template_debug libraries
uses: actions/download-artifact@v4
with:
name: linux-template_debug
path: demo/addons/fmod/libs/linux/
- name: Download linux template_release libraries
uses: actions/download-artifact@v4
with:
name: linux-template_release
path: demo/addons/fmod/libs/linux/
- name: Download windows editor libraries
uses: actions/download-artifact@v4
with:
name: windows-editor
path: demo/addons/fmod/libs/windows/
- name: Download windows template_debug libraries
uses: actions/download-artifact@v4
with:
name: windows-template_debug
path: demo/addons/fmod/libs/windows/
- name: Download windows template_release libraries
uses: actions/download-artifact@v4
with:
name: windows-template_release
path: demo/addons/fmod/libs/windows/
- name: Download macos editor libraries
uses: actions/download-artifact@v4
with:
name: macos-editor
path: demo/addons/fmod/libs/macos/
- name: Download macos template_debug libraries
uses: actions/download-artifact@v4
with:
name: macos-template_debug
path: demo/addons/fmod/libs/macos/
- name: Download macos template_release libraries
uses: actions/download-artifact@v4
with:
name: macos-template_release
path: demo/addons/fmod/libs/macos/
- name: Download iOS template_debug libraries
uses: actions/download-artifact@v4
with:
name: ios-template_debug
path: demo/addons/fmod/libs/iOS/
- name: Download iOS template_release libraries
uses: actions/download-artifact@v4
with:
name: ios-template_release
path: demo/addons/fmod/libs/iOS/
- name: Download android editor libraries
uses: actions/download-artifact@v4
with:
name: android-editor
path: demo/addons/fmod/libs/android/
- name: Download android template_debug libraries
uses: actions/download-artifact@v4
with:
name: android-template_debug
path: demo/addons/fmod/libs/android/
- name: Download android template_release libraries
uses: actions/download-artifact@v4
with:
name: android-template_release
path: demo/addons/fmod/libs/android/
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false
- name: Zip fmod addon
run: |
cd demo/addons/
zip -r addons.zip fmod -x '*/.gitignore'
- name: Zip demo project (without .godot and GUT)
run: |
cd demo
zip -r demo.zip . \
-x '*/.gitignore' \
'*.zip' \
'.godot/*' '.godot/**' \
'addons/gut/*' 'addons/gut/**' 'addons/gut' \
'.gut*' \
'run_tests.sh' \
'test/' 'test/*' 'test/**' \
- name: Upload Addon Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./demo/addons/addons.zip
asset_name: addons.zip
asset_content_type: application/zip
- name: Upload Demo Project Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./demo/demo.zip
asset_name: demo.zip
asset_content_type: application/zip
================================================
FILE: .gitignore
================================================
# Created by https://www.gitignore.io/api/clion,cmake,scons
# Edit at https://www.gitignore.io/?templates=clion,cmake,scons
### OSX ###
.DS_Store
### Android ###
libs/
obj/
### CLion ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
CMakeLists.txt
bin/
*.os
*.o
*.obj
*.exp
*.lib
# Clion specific
.idea/*
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### CLion Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
.idea/sonarlint
### CMake ###
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
### CMake Patch ###
# External projects
*-prefix/
### Visual Studio Generated Files ###
*.vcxproj
*.vcxproj.filters
*.sln
### SCons ###
# for projects that use SCons for building: http://http://www.scons.org/
.sconsign.dblite
# When configure fails, SCons outputs these
config.log
.sconf_temp
# End of https://www.gitignore.io/api/clion,cmake,scons
# uncomment when https://github.com/godotengine/godot/issues/71521 fix is in release.
#demo/.godot
**/*.editor
demo/addons/fmod/libs/android/aar/
*.pdb
.vs
================================================
FILE: .gitmodules
================================================
[submodule "godot-cpp"]
path = godot-cpp
url = https://github.com/godotengine/godot-cpp
================================================
FILE: .readthedocs.yml
================================================
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# Build documentation with MkDocs
mkdocs:
configuration: docs/mkdocs.yml
# Optionally set the version of Python and requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt
================================================
FILE: Android.mk
================================================
# Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := fmod-core-prebuilt
LOCAL_SRC_FILES := ../libs/fmod/android/core/lib/$(TARGET_ARCH_ABI)/libfmod.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := fmod-studio-prebuilt
LOCAL_SRC_FILES := ../libs/fmod/android/studio/lib/$(TARGET_ARCH_ABI)/libfmodstudio.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := godot-prebuilt
ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_SRC_FILES := ../godot-cpp/bin/libgodot-cpp.android.release.x86.a
endif
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_SRC_FILES := ../godot-cpp/bin/libgodot-cpp.android.release.armv7.a
endif
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
LOCAL_SRC_FILES := ../godot-cpp/bin/libgodot-cpp.android.release.arm64v8.a
endif
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libGodotFmod.android.release.$(TARGET_ARCH_ABI)
LOCAL_CPPFLAGS := -std=c++14
LOCAL_CPP_FEATURES := rtti exceptions
LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := \
src/godot_fmod.cpp \
src/gdlibrary.cpp \
src/callback/file_callbacks.cpp \
src/callback/event_callbacks.cpp \
LOCAL_SHARED_LIBRARIES := \
fmod-core-prebuilt \
fmod-studio-prebuilt
LOCAL_C_INCLUDES := \
../godot-cpp/godot-headers \
../godot-cpp/include/ \
../godot-cpp/include/core \
../godot-cpp/include/gen \
../libs/fmod/android/studio/inc \
../libs/fmod/android/core/inc
LOCAL_STATIC_LIBRARIES := godot-prebuilt
include $(BUILD_SHARED_LIBRARY)
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2019 Utopia-Rise and Alex Fonseka
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================

[](https://github.com/utopia-rise/fmod-gdextension/actions/workflows/release.yml)
[](https://discord.com/invite/u2NM2vTGMn)
---
**Godot 4 GDExtension that integrates with the FMOD Studio API.** [FMOD is an audio engine and middleware solution](https://www.fmod.com/) for interactive audio in games. It has been the audio engine behind many
titles such as **Transistor**, **Into the Breach** and **Celeste**. This Godot extension is used by games such as [Koira](https://dont-nod.com/en/games/koira/).
If you need any help, you can join our [Discord Server](https://discord.com/invite/u2NM2vTGMn).
# Installation
1. [Download Latest Release](https://github.com/utopia-rise/fmod-gdextension/releases/latest)
2. Unpack the `addons/fmod` folder into your `/addons` folder within the Godot project
3. Enable this addon within the Godot settings: `Project > Project Settings > Plugins`
#### Read the [official docs](https://fmod-gdextension.readthedocs.io/en/latest/) to get started with this addon.
# Features
## 🔉 Seamless integration with FMOD
Use FMOD Studio to create bank files this addon will auto-load all events for you inside Godot Engine. Live updating works out of the box.

## 🔉 Dedicated Godot nodes
This GDExtension provides nodes such as `FmodEventEmitter2D`, `FmodEventEmitter3D`, `FmodEventListener2D` and `FmodEventListener3D` that can be used in any Godot scene or GDScript code.

# Contributing
In order to be able to PR this repo from a fork, you need to add `FMODUSER` and `FMODPASS` secrets to your fork repo.
This enables CI to download FMOD api.
Feel free to raise pull requests. We hope you'll enjoy this addon!
## How this extension works
This GDExtension exposes most of the Studio API functions to Godot's GDScript and also provides helpers for performing
common functions like attaching Studio events to Godot nodes and playing 3D/positional audio.
> **Note:** This plugin doesn't provide C# bindings to FMOD. There is technically a C# FMOD API but we choose to develop it as a C++ GDExtension. Any language binding with a auto-binding feature for extensions should be able to use this plugin, which is the case for GDScript. C# doesn't offer this feature yet.
## Continuous Delivery
This project uses [Github Actions](https://github.com/features/actions) to continuously deploy released drivers. If you do not want to use those releases, you
can compile from sources by looking to [compile from sources section](./docs/src/doc/advanced/1-compiling.md). This project uses [SEMVER](https://semver.org/).
# Special Thanks
This project is a forked from [godot-fmod-integration](https://github.com/alexfonseka/godot-fmod-integration)
from [alexfonseka](https://github.com/alexfonseka). We'd like to thank him for the work he did, we simply adapted his
work to GDNative.
# Tested Versions
- **Godot Version:** 4.4 stable
- **FMOD Version:** 2.03
[fmodsingleton]: .README/fmodsingleton.png
[usecustombuild]: .README/usecustombuild.png
================================================
FILE: SConstruct
================================================
#!/usr/bin/env python
import os
import shutil
import subprocess
from SCons.Script import SConscript, ARGUMENTS, Action, Copy
target_path = ARGUMENTS.pop("target_path", "demo/addons/fmod/libs/")
target_name = ARGUMENTS.pop("target_name", "libGodotFmod")
fmod_lib_dir = ARGUMENTS.pop("fmod_lib_dir", "../libs/fmod/")
env = SConscript("godot-cpp/SConstruct")
# Add those directory manually, so we can skip the godot_cpp directory when including headers in C++ files
source_path = [
os.path.join("godot-cpp", "include","godot_cpp"),
os.path.join("godot-cpp", "gen", "include","godot_cpp")
]
env.Append(CPPPATH=[env.Dir(d) for d in source_path])
env.Replace(fmod_lib_dir = fmod_lib_dir)
# For the reference:
# - CCFLAGS are compilation flags shared between C and C++
# - CFLAGS are for C-specific compilation flags
# - CXXFLAGS are for C++-specific compilation flags
# - CPPFLAGS are for pre-processor flags
# - CPPDEFINES are for pre-processor defines
# - LINKFLAGS are for linking flags
# tweak this if you want to use different folders, or more folders, to store your source code in.
env.Append(CPPPATH=["src/"])
sources = [
Glob('src/*.cpp'),
Glob('src/callback/*.cpp'),
Glob('src/core/*.cpp'),
Glob('src/data/*.cpp'),
Glob('src/tools/*.cpp'),
Glob('src/helpers/*.cpp'),
Glob('src/nodes/*.cpp'),
Glob('src/resources/*.cpp'),
Glob('src/studio/*.cpp'),
Glob('src/plugins/*.cpp')
]
lfix = ""
debug = False
if env["target"] == "template_debug" or env["target"] == "editor":
lfix = "L"
debug = True
if env["platform"] == "macos":
libfmod = 'libfmod%s.dylib' % lfix
libfmodstudio = 'libfmodstudio%s.dylib' % lfix
env.Append(CPPPATH=[env['fmod_lib_dir'] + 'osx/core/inc/', env['fmod_lib_dir'] + 'osx/studio/inc/'])
env.Append(LIBPATH=[env['fmod_lib_dir'] + 'osx/core/lib/', env['fmod_lib_dir'] + 'osx/studio/lib/'])
env.Append(LIBS=[libfmod, libfmodstudio])
env.Append(
LINKFLAGS=[
"-framework",
"Cocoa",
"-Wl,-undefined,dynamic_lookup",
"-rpath", "@loader_path/.."
]
)
elif env["platform"] == "linux":
libfmod = 'libfmod%s.so'% lfix
libfmodstudio = 'libfmodstudio%s.so'% lfix
env.Append(CPPPATH=[env['fmod_lib_dir'] + 'linux/core/inc/', env['fmod_lib_dir'] + 'linux/studio/inc/'])
env.Append(LIBPATH=[env['fmod_lib_dir'] + 'linux/core/lib/' + env["arch"], env['fmod_lib_dir'] + 'linux/studio/lib/' + env["arch"]])
env.Append(LIBS=[libfmod, libfmodstudio])
env.Append(CCFLAGS=["-fPIC", "-Wwrite-strings"])
env.Append(LINKFLAGS=["-Wl,-R,'$$ORIGIN'"])
env.Append(LINKFLAGS=["-m64", "-fuse-ld=gold"])
elif env["platform"] == "windows":
libfmod = 'fmod%s_vc'% lfix
libfmodstudio = 'fmodstudio%s_vc'% lfix
fmod_info_table = {
"x86_64" : "x64",
"x86_32" : "x86",
}
arch_suffix_override = fmod_info_table[env["arch"]]
env.Append(CPPPATH=[env['fmod_lib_dir'] + 'windows/core/inc/', env['fmod_lib_dir'] + 'windows/studio/inc/'])
env.Append(LIBPATH=[env['fmod_lib_dir'] + 'windows/core/lib/' + arch_suffix_override, env['fmod_lib_dir'] + 'windows/studio/lib/' + arch_suffix_override])
env.Append(LIBS=[libfmod, libfmodstudio])
env.Append(LINKFLAGS=["/WX"])
if debug:
env.Append(CCFLAGS=["/FS", "/Zi"])
elif env["platform"] == "ios":
libfmod = 'libfmod%s_iphoneos.a' % lfix
libfmodstudio = 'libfmodstudio%s_iphoneos.a' % lfix
env.Append(CPPPATH=[env['fmod_lib_dir'] + 'ios/core/inc/', env['fmod_lib_dir'] + 'ios/studio/inc/'])
env.Append(LIBPATH=[env['fmod_lib_dir'] + 'ios/core/lib/', env['fmod_lib_dir'] + 'ios/studio/lib/'])
env.Append(LIBS=[libfmod, libfmodstudio])
env.Append(LINKFLAGS=[
'-Wl,-undefined,dynamic_lookup', "-miphoneos-version-min=" + env["ios_min_version"]
])
elif env["platform"] == "android":
libfmod = 'libfmod%s.so' % lfix
libfmodstudio = 'libfmodstudio%s.so' % lfix
fmod_info_table = {
"armv7": "armeabi-v7a",
"arm64": "arm64-v8a",
"x86": "x86",
"x86_64": "x86_64"
}
arch_dir = fmod_info_table[env["arch"]]
env.Append(CPPPATH=[env['fmod_lib_dir'] + 'android/core/inc/', env['fmod_lib_dir'] + 'android/studio/inc/'])
env.Append(LIBPATH=[env['fmod_lib_dir'] + 'android/core/lib/' + arch_dir, env['fmod_lib_dir'] + 'android/studio/lib/' + arch_dir])
env.Append(LIBS=[libfmod, libfmodstudio])
#Output is placed in the addons directory of the demo project directly
target = "{}{}/{}.{}.{}".format(
target_path, env["platform"], target_name, env["platform"], env["target"]
) if env["platform"] != "android" else "{}{}/{}/{}.{}.{}".format(
target_path, env["platform"], env["arch"], target_name, env["platform"], env["target"]
)
if env["platform"] == "macos":
target = "{}.framework/{}.{}.{}".format(
target,
target_name,
env["platform"],
env["target"]
)
else:
target = "{}.{}{}".format(
target,
env["arch"],
env["SHLIBSUFFIX"]
)
library = env.SharedLibrary(target=target, source=sources)
def sys_exec(args):
proc = subprocess.Popen(args, stdout=subprocess.PIPE, text=True)
(out, err) = proc.communicate()
return out.rstrip("\r\n").lstrip()
if env["platform"] == "ios":
xcframework_path = "{}{}/{}.{}.{}.xcframework".format(
target_path,
env["platform"],
target_name,
env["platform"],
env["target"]
)
def create_xcframework(self, arg, env, executor = None):
sys_exec(["xcodebuild", "-create-xcframework", "-library", target, "-output", xcframework_path])
sys_exec(["rm", target])
sys_exec(["/usr/libexec/PlistBuddy", "-c", "Add :MinimumOSVersion string " + env["ios_min_version"], "{}/Info.plist".format(xcframework_path)])
create_xcframework_action = Action('', create_xcframework)
AddPostAction(library, create_xcframework_action)
def copy_fmod_libraries(self, arg, env, executor = None):
fmod_core_lib_dir = ""
fmod_studio_lib_dir = ""
addon_fmod_libs_output = "{}{}/".format(
target_path, env["platform"]
) if env["platform"] != "android" else "{}{}/{}/".format(
target_path, env["platform"], env["arch"]
)
if env["platform"] == "macos":
fmod_core_lib_dir = env['fmod_lib_dir'] + 'osx/core/lib/'
fmod_studio_lib_dir = env['fmod_lib_dir'] + 'osx/studio/lib/'
elif env["platform"] == "linux":
fmod_core_lib_dir = env['fmod_lib_dir'] + 'linux/core/lib/' + env["arch"]
fmod_studio_lib_dir = env['fmod_lib_dir'] + 'linux/studio/lib/' + env["arch"]
elif env["platform"] == "windows":
fmod_core_lib_dir = env['fmod_lib_dir'] + 'windows/core/lib/' + arch_suffix_override + '/'
fmod_studio_lib_dir = env['fmod_lib_dir'] + 'windows/studio/lib/' + arch_suffix_override + '/'
elif env["platform"] == "ios":
fmod_core_lib_dir = env['fmod_lib_dir'] + 'ios/core/lib/'
fmod_studio_lib_dir = env['fmod_lib_dir'] + 'ios/studio/lib/'
elif env["platform"] == "android":
fmod_core_lib_dir = env['fmod_lib_dir'] + 'android/core/lib/' + arch_dir
fmod_studio_lib_dir = env['fmod_lib_dir'] + 'android/studio/lib/' + arch_dir
source_files = [env.Glob(os.path.join(source_dir, '*.*')) for source_dir in [fmod_core_lib_dir, fmod_studio_lib_dir]]
[[shutil.copy(str(file), addon_fmod_libs_output) for file in files] for files in source_files]
copy_fmod_libraries_action = Action('', copy_fmod_libraries)
AddPostAction(library, copy_fmod_libraries_action)
Default(library)
================================================
FILE: android-plugin/.gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
library/libraries/
================================================
FILE: android-plugin/build.gradle.kts
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.library") version "8.0.0" apply false
id("org.jetbrains.kotlin.android") version "2.1.20" apply false
}
================================================
FILE: android-plugin/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: android-plugin/gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
================================================
FILE: android-plugin/gradlew
================================================
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
================================================
FILE: android-plugin/gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: android-plugin/library/.gitignore
================================================
/build
================================================
FILE: android-plugin/library/build.gradle.kts
================================================
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
}
val pluginName = "fmod"
val pluginPackageName = "com.utopiarise.godot.fmod.android.plugin"
android {
namespace = pluginPackageName
compileSdk = 33
defaultConfig {
minSdk = 24
targetSdk = 33
manifestPlaceholders["godotPluginName"] = pluginName
manifestPlaceholders["godotPluginPackageName"] = pluginPackageName
buildConfigField("String", "GODOT_PLUGIN_NAME", "\"${pluginName}\"")
setProperty("archivesBaseName", pluginName)
}
buildFeatures {
buildConfig = true
}
buildTypes {
release {
isMinifyEnabled = false
buildConfigField("boolean", "DEBUG", "false")
}
debug {
buildConfigField("boolean", "DEBUG", "true")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
val copyDebugAARToDemoAddons by tasks.registering(Copy::class) {
description = "Copies the generated debug AAR binary to the plugin's addons directory"
from("build/outputs/aar")
include("$pluginName-debug.aar")
into("../../demo/addons/$pluginName/libs/android")
}
val copyReleaseAARToDemoAddons by tasks.registering(Copy::class) {
description = "Copies the generated release AAR binary to the plugin's addons directory"
from("build/outputs/aar")
include("$pluginName-release.aar")
into("../../demo/addons/$pluginName/libs/android")
}
tasks.named("assemble").configure {
finalizedBy(copyDebugAARToDemoAddons)
finalizedBy(copyReleaseAARToDemoAddons)
}
dependencies {
implementation(files("libraries/fmod.jar"))
implementation("org.godotengine:godot:4.5.0.stable")
}
================================================
FILE: android-plugin/library/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
>
<application>
<meta-data
android:name="org.godotengine.plugin.v2.FmodPlugin"
android:value="com.utopiarise.godot.fmod.android.plugin.FmodPlugin" />
</application>
</manifest>
================================================
FILE: android-plugin/library/src/main/kotlin/com/utopiarise/godot/fmod/android/plugin/FmodPlugin.kt
================================================
package com.utopiarise.godot.fmod.android.plugin
import android.app.Activity
import android.view.View
import org.fmod.FMOD
import org.godotengine.godot.Godot
import org.godotengine.godot.plugin.GodotPlugin
class FmodPlugin(godot: Godot) : GodotPlugin(godot) {
override fun getPluginName() = "Godot Fmod Android Plugin"
override fun onMainCreate(activity: Activity?): View? {
FMOD.init(activity)
return super.onMainCreate(activity)
}
override fun onMainDestroy() {
FMOD.close()
}
companion object {
init {
if (BuildConfig.DEBUG) {
System.loadLibrary("fmodL")
System.loadLibrary("fmodstudioL")
} else {
System.loadLibrary("fmod")
System.loadLibrary("fmodstudio")
}
}
}
}
================================================
FILE: android-plugin/library/src/main/resources/fmod-android-license.txt
================================================
Copyright (C) 2010 The Android Open Source Project All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following
disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: android-plugin/settings.gradle.kts
================================================
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "Godot Fmod Android Plugin"
include(":library")
================================================
FILE: demo/.gitattributes
================================================
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf
================================================
FILE: demo/.gitignore
================================================
# Godot 4+ specific ignores
.godot/
# Godot-specific ignores
.import/
export.cfg
export_credentials.cfg
# Imported translations (automatically generated from CSV files)
*.translation
# Mono-specific ignores
.mono/
data_*/
mono_crash.*.json
.vscode/
logs/
**/*.aar
android/build
android/
================================================
FILE: demo/.gutconfig.json
================================================
{
"background_color": "262626ff",
"compact_mode": false,
"configured_dirs": [
"res://test/unit"
],
"dirs": [
"res://test/unit"
],
"disable_colors": false,
"double_strategy": 1,
"failure_error_types": [
"gut"
],
"font_color": "ccccccff",
"font_name": "CourierPrime",
"font_size": 16.0,
"gut_on_top": true,
"hide_orphans": false,
"ignore_pause": false,
"include_subdirs": false,
"junit_xml_file": "",
"junit_xml_timestamp": false,
"log_level": 1.0,
"no_error_tracking": false,
"opacity": 100.0,
"paint_after": 0.1,
"post_run_script": "",
"pre_run_script": "",
"prefix": "test_",
"should_exit": true,
"should_exit_on_success": false,
"should_maximize": false,
"suffix": ".gd",
"wait_log_delay": 0.5
}
================================================
FILE: demo/addons/fmod/.gitignore
================================================
*.dll
*.a
*.dylib
*.so
*.so.*
*.xcframework
!libs/
================================================
FILE: demo/addons/fmod/FmodAndroidExportPlugin.gd
================================================
@tool
class_name FmodAndroidExportPlugin extends EditorExportPlugin
var plugin_name: String = "fmod"
func _supports_platform(platform):
if platform is EditorExportPlatformAndroid:
return true
return false
func _get_android_libraries(platform, debug):
if debug:
return PackedStringArray([plugin_name + "/libs/android/" + plugin_name + "-debug.aar"])
else:
return PackedStringArray([plugin_name + "/libs/android/" + plugin_name + "-release.aar"])
func _get_name():
return plugin_name
================================================
FILE: demo/addons/fmod/FmodAndroidExportPlugin.gd.uid
================================================
uid://cle6f2srp4yun
================================================
FILE: demo/addons/fmod/FmodManager.gd
================================================
@tool
extends Node
var performance_display: PerformancesDisplay
func _ready():
process_mode = PROCESS_MODE_ALWAYS
performance_display = PerformancesDisplay.new()
add_child(performance_display)
func _exit_tree() -> void:
remove_child(performance_display)
performance_display.free()
func _process(delta):
FmodServer.update()
func _notification(what):
FmodServer.notification(what)
if OS.has_feature("mobile"):
match what:
NOTIFICATION_APPLICATION_FOCUS_OUT: FmodServer.mixer_suspend()
NOTIFICATION_APPLICATION_FOCUS_IN: FmodServer.mixer_resume()
================================================
FILE: demo/addons/fmod/FmodManager.gd.uid
================================================
uid://cds10pm7hwn3p
================================================
FILE: demo/addons/fmod/FmodPlugin.gd
================================================
@tool
class_name FmodPlugin extends EditorPlugin
const ADDON_PATH: StringName = &"res://addons/fmod"
const FmodManager_Autoload_Name: StringName = &"FmodManager"
@onready var theme: Theme = get_editor_interface().get_base_control().get_theme()
var fmod_bank_explorer_window: PackedScene = load("res://addons/fmod/tool/ui/FmodBankExplorer.tscn")
var bank_explorer: FmodBankExplorer
var fmod_button: Button
var export_plugin: FmodEditorExportPlugin = FmodEditorExportPlugin.new()
var android_export_plugin: FmodAndroidExportPlugin = FmodAndroidExportPlugin.new()
var emitter_inspector_plugin: FmodEmitterPropertyInspectorPlugin = FmodEmitterPropertyInspectorPlugin.new(self)
var bank_loader_inspector_plugin: FmodBankLoaderPropertyInspectorPlugin = FmodBankLoaderPropertyInspectorPlugin.new(self)
func _init() -> void:
FmodBankDatabase.reload_all_banks()
func _enable_plugin() -> void:
add_autoload_singleton(FmodManager_Autoload_Name, "res://addons/fmod/FmodManager.gd")
func _disable_plugin() -> void:
remove_autoload_singleton(FmodManager_Autoload_Name)
func _enter_tree() -> void:
_add_explorer_button()
_add_bank_explorer_window()
add_inspector_plugin(bank_loader_inspector_plugin)
add_inspector_plugin(emitter_inspector_plugin)
add_export_plugin(export_plugin)
add_export_plugin(android_export_plugin)
func _exit_tree() -> void:
remove_control_from_container(EditorPlugin.CONTAINER_TOOLBAR, fmod_button)
fmod_button.queue_free()
bank_explorer.queue_free()
remove_inspector_plugin(emitter_inspector_plugin)
remove_inspector_plugin(bank_loader_inspector_plugin)
remove_export_plugin(android_export_plugin)
remove_export_plugin(export_plugin)
func _add_explorer_button() -> void:
fmod_button = Button.new()
fmod_button.icon = load("res://addons/fmod/icons/fmod_icon.svg")
fmod_button.text = "Fmod Explorer"
fmod_button.pressed.connect(_on_project_explorer_button_clicked)
add_control_to_container(EditorPlugin.CONTAINER_TOOLBAR, fmod_button)
func _add_bank_explorer_window() -> void:
bank_explorer = fmod_bank_explorer_window.instantiate()
bank_explorer.theme = get_editor_interface().get_base_control().get_theme()
bank_explorer.visible = false
add_child(bank_explorer)
func _on_project_explorer_button_clicked() -> void:
bank_explorer.should_display_copy_buttons = true
bank_explorer.should_display_select_button = false
_popup_project_explorer(FmodBankExplorer.ToDisplayFlags.BUSES | FmodBankExplorer.ToDisplayFlags.VCA | FmodBankExplorer.ToDisplayFlags.EVENTS)
func open_project_explorer_events(on_select_callable: Callable) -> void:
_open_project_explorer(FmodBankExplorer.ToDisplayFlags.EVENTS, on_select_callable)
func open_project_explorer_bank(on_select_callable: Callable) -> void:
_open_project_explorer(0, on_select_callable)
func _open_project_explorer(display_flag: int, on_select_callable: Callable) -> void:
bank_explorer.should_display_copy_buttons = false
bank_explorer.should_display_select_button = true
_popup_project_explorer(display_flag, on_select_callable)
func _popup_project_explorer(to_display: int, callable: Callable = Callable()) -> void:
if bank_explorer.visible == true:
bank_explorer.close_window()
return
bank_explorer.flags = to_display
bank_explorer.reset_search()
bank_explorer.regenerate_tree(callable)
bank_explorer.popup_centered()
================================================
FILE: demo/addons/fmod/FmodPlugin.gd.uid
================================================
uid://cwsif6rhp50p5
================================================
FILE: demo/addons/fmod/fmod.gdextension
================================================
[configuration]
entry_symbol = "fmod_library_init"
compatibility_minimum = 4.5
[libraries]
windows.editor.x86_64 = "res://addons/fmod/libs/windows/libGodotFmod.windows.editor.x86_64.dll"
windows.debug.x86_64 = "res://addons/fmod/libs/windows/libGodotFmod.windows.template_debug.x86_64.dll"
windows.release.x86_64 = "res://addons/fmod/libs/windows/libGodotFmod.windows.template_release.x86_64.dll"
macos.editor = "res://addons/fmod/libs/macos/libGodotFmod.macos.editor.framework"
macos.debug = "res://addons/fmod/libs/macos/libGodotFmod.macos.template_debug.framework"
macos.release = "res://addons/fmod/libs/macos/libGodotFmod.macos.template_release.framework"
linux.editor.x86_64 = "res://addons/fmod/libs/linux/libGodotFmod.linux.editor.x86_64.so"
linux.debug.x86_64 = "res://addons/fmod/libs/linux/libGodotFmod.linux.template_debug.x86_64.so"
linux.release.x86_64 = "res://addons/fmod/libs/linux/libGodotFmod.linux.template_release.x86_64.so"
android.debug.x86_64 = "res://addons/fmod/libs/android/x86_64/libGodotFmod.android.template_debug.x86_64.so"
android.release.x86_64 = "res://addons/fmod/libs/android/x86_64/libGodotFmod.android.template_release.x86_64.so"
android.debug.arm64 = "res://addons/fmod/libs/android/arm64/libGodotFmod.android.template_debug.arm64.so"
android.release.arm64 = "res://addons/fmod/libs/android/arm64/libGodotFmod.android.template_release.arm64.so"
ios.debug = "res://addons/fmod/libs/ios/libGodotFmod.ios.template_debug.xcframework"
ios.release = "res://addons/fmod/libs/ios/libGodotFmod.ios.template_release.xcframework"
[icons]
FmodEventEmitter2D = "res://addons/fmod/icons/fmod_icon.svg"
FmodEventEmitter3D = "res://addons/fmod/icons/fmod_icon.svg"
FmodListener2D = "res://addons/fmod/icons/fmod_icon.svg"
FmodListener3D = "res://addons/fmod/icons/fmod_icon.svg"
FmodBankLoader = "res://addons/fmod/icons/fmod_icon.svg"
[dependencies]
windows.editor.x86_64 = {
"libs/windows/fmodL.dll": "",
"libs/windows/fmodstudioL.dll": ""
}
windows.debug.x86_64 = {
"libs/windows/fmodL.dll": "",
"libs/windows/fmodstudioL.dll": ""
}
windows.release.x86_64 = {
"libs/windows/fmod.dll": "",
"libs/windows/fmodstudio.dll": ""
}
linux.editor.x86_64 = {
"libs/linux/libfmodL.so": "",
"libs/linux/libfmodL.so.14": "",
"libs/linux/libfmodL.so.14.6": "",
"libs/linux/libfmodstudioL.so": "",
"libs/linux/libfmodstudioL.so.14": "",
"libs/linux/libfmodstudioL.so.14.6": ""
}
linux.debug.x86_64 = {
"libs/linux/libfmodL.so": "",
"libs/linux/libfmodL.so.14": "",
"libs/linux/libfmodL.so.14.6": "",
"libs/linux/libfmodstudioL.so": "",
"libs/linux/libfmodstudioL.so.14": "",
"libs/linux/libfmodstudioL.so.14.6": ""
}
linux.release.x86_64 = {
"libs/linux/libfmod.so": "",
"libs/linux/libfmod.so.14": "",
"libs/linux/libfmod.so.14.6": "",
"libs/linux/libfmodstudio.so": "",
"libs/linux/libfmodstudio.so.14": "",
"libs/linux/libfmodstudio.so.14.6": ""
}
macos.editor = {
"libs/macos/libfmodL.dylib": "",
"libs/macos/libfmodstudioL.dylib": ""
}
macos.debug = {
"libs/macos/libfmodL.dylib": "",
"libs/macos/libfmodstudioL.dylib": ""
}
macos.release = {
"libs/macos/libfmod.dylib": "",
"libs/macos/libfmodstudio.dylib": ""
}
android.debug.x86_64 = {
"libs/android/x86_64/libfmodL.so": "",
"libs/android/x86_64/libfmodstudioL.so": "",
}
android.release.x86_64 = {
"libs/android/x86_64/libfmod.so": "",
"libs/android/x86_64/libfmodstudio.so": "",
}
android.debug.arm64 = {
"libs/android/arm64/libfmodL.so": "",
"libs/android/arm64/libfmodstudioL.so": "",
}
android.release.arm64 = {
"libs/android/arm64/libfmod.so": "",
"libs/android/arm64/libfmodstudio.so": "",
}
ios.debug = {
"libs/ios/libfmodL_iphoneos.a": "",
"libs/ios/libfmodstudioL_iphoneos.a": ""
}
ios.release = {
"libs/ios/libfmod_iphoneos.a": "",
"libs/ios/libfmodstudio_iphoneos.a": ""
}
================================================
FILE: demo/addons/fmod/fmod.gdextension.uid
================================================
uid://dq17s7r52klxe
================================================
FILE: demo/addons/fmod/icons/bank_icon.svg.import
================================================
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://o2chsr07oeqs"
path="res://.godot/imported/bank_icon.svg-8de6c7bff09a67352e162b3c61b601de.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/fmod/icons/bank_icon.svg"
dest_files=["res://.godot/imported/bank_icon.svg-8de6c7bff09a67352e162b3c61b601de.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
================================================
FILE: demo/addons/fmod/icons/bus_icon.svg.import
================================================
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dj1kag4aeg58t"
path="res://.godot/imported/bus_icon.svg-f536ffd3c4893e79a9d3cb9a1b4fb50c.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/fmod/icons/bus_icon.svg"
dest_files=["res://.godot/imported/bus_icon.svg-f536ffd3c4893e79a9d3cb9a1b4fb50c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
================================================
FILE: demo/addons/fmod/icons/c_parameter_icon.svg.import
================================================
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cmvcqfsl167te"
path="res://.godot/imported/c_parameter_icon.svg-04115c2482c9a6874356ffdc09c41db0.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/fmod/icons/c_parameter_icon.svg"
dest_files=["res://.godot/imported/c_parameter_icon.svg-04115c2482c9a6874356ffdc09c41db0.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
================================================
FILE: demo/addons/fmod/icons/d_parameter_icon.svg.import
================================================
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dgna04txtwnyb"
path="res://.godot/imported/d_parameter_icon.svg-d339e4e3f950ae8593b999ef51579136.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/fmod/icons/d_parameter_icon.svg"
dest_files=["res://.godot/imported/d_parameter_icon.svg-d339e4e3f950ae8593b999ef51579136.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
================================================
FILE: demo/addons/fmod/icons/event_icon.svg.import
================================================
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cmpgmbn3y4svl"
path="res://.godot/imported/event_icon.svg-4e6e2103d076f95b7bef82f079e433e6.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/fmod/icons/event_icon.svg"
dest_files=["res://.godot/imported/event_icon.svg-4e6e2103d076f95b7bef82f079e433e6.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
================================================
FILE: demo/addons/fmod/icons/fmod_emitter.png.import
================================================
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cotpb54utx6d6"
path="res://.godot/imported/fmod_emitter.png-6783a287e298e2a04e64a6deaa6fe366.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/fmod/icons/fmod_emitter.png"
dest_files=["res://.godot/imported/fmod_emitter.png-6783a287e298e2a04e64a6deaa6fe366.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
================================================
FILE: demo/addons/fmod/icons/fmod_icon.svg.import
================================================
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bwqq5q7kodk40"
path="res://.godot/imported/fmod_icon.svg-cca7eb13231881fafaea0d598d407ea3.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/fmod/icons/fmod_icon.svg"
dest_files=["res://.godot/imported/fmod_icon.svg-cca7eb13231881fafaea0d598d407ea3.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
================================================
FILE: demo/addons/fmod/icons/snapshot_icon.svg.import
================================================
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b4jxbh86chubi"
path="res://.godot/imported/snapshot_icon.svg-7b517248819b3685844766808fbce2a5.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/fmod/icons/snapshot_icon.svg"
dest_files=["res://.godot/imported/snapshot_icon.svg-7b517248819b3685844766808fbce2a5.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
================================================
FILE: demo/addons/fmod/icons/vca_icon.svg.import
================================================
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://crsj4jjaeq87a"
path="res://.godot/imported/vca_icon.svg-def43f27fe148a7a0b18c7dcaab20c79.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/fmod/icons/vca_icon.svg"
dest_files=["res://.godot/imported/vca_icon.svg-def43f27fe148a7a0b18c7dcaab20c79.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
================================================
FILE: demo/addons/fmod/libs/android/arm64/CopyPast_Fmod_Libs_Here.txt
================================================
================================================
FILE: demo/addons/fmod/libs/iOS/CopyPast_Fmod_Libs_Here.txt
================================================
================================================
FILE: demo/addons/fmod/libs/linux/CopyPast_Fmod_Libs_Here.txt
================================================
================================================
FILE: demo/addons/fmod/libs/macos/CopyPast_Fmod_Libs_Here.txt
================================================
================================================
FILE: demo/addons/fmod/libs/macos/libGodotFmod.macos.editor.framework/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>libGodotFmod.macos.editor</string>
<key>CFBundleIdentifier</key>
<string>com.utopia-rise.fmod-gdextension</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>libGodotFmod.macos.editor</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.12</string>
</dict>
</plist>
================================================
FILE: demo/addons/fmod/libs/macos/libGodotFmod.macos.template_debug.framework/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>libGodotFmod.macos.template_debug</string>
<key>CFBundleIdentifier</key>
<string>com.utopiarise.fmod-gdextension</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>libGodotFmod.macos.template_debug</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.12</string>
</dict>
</plist>
================================================
FILE: demo/addons/fmod/libs/macos/libGodotFmod.macos.template_release.framework/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>libGodotFmod.macos.template_release</string>
<key>CFBundleIdentifier</key>
<string>com.utopiarise.fmod-gdextension</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>libGodotFmod.macos.template_release</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.12</string>
</dict>
</plist>
================================================
FILE: demo/addons/fmod/libs/windows/CopyPast_Fmod_Libs_Here.txt
================================================
================================================
FILE: demo/addons/fmod/plugin.cfg
================================================
[plugin]
name="FMOD GDExtension"
description="FMOD GDExtension for Godot Engine 4.5"
author="Utopia-rise, Tristan Grespinet, Pierre-Thomas Meisels"
version="6.1.0"
script="FmodPlugin.gd"
================================================
FILE: demo/addons/fmod/tool/FmodBankDatabase.gd
================================================
extends Node
class_name FmodBankDatabase
static var banks := Array()
const MASTER_STRINGS_BANK_NAME = "Master.strings.bank"
const MASTER_BANK_NAME = "Master.bank"
static func reload_all_banks():
banks.clear()
var banks_root = ProjectSettings.get_setting("Fmod/General/banks_path", "")
var master_strings_bank_path = "%s/%s" % [banks_root, MASTER_STRINGS_BANK_NAME]
var master_bank_path = "%s/%s" % [banks_root, MASTER_BANK_NAME]
if not FileAccess.file_exists(master_strings_bank_path):
push_warning("Cannot find master strings bank at %s" % master_strings_bank_path)
return
if not FileAccess.file_exists(master_bank_path):
push_warning("Cannot find master bank at %s" % master_bank_path)
return
banks.append(
FmodServer.load_bank(master_strings_bank_path, FmodServer.FMOD_STUDIO_LOAD_BANK_NORMAL)
)
banks.append(
FmodServer.load_bank(master_bank_path, FmodServer.FMOD_STUDIO_LOAD_BANK_NORMAL)
)
var dir: DirAccess = DirAccess.open(banks_root)
if dir:
dir.list_dir_begin()
var file_name : String = dir.get_next()
while file_name != "":
if dir.current_is_dir():
pass # the found item is a directory
elif file_name.ends_with(".bank") and file_name != MASTER_STRINGS_BANK_NAME and file_name != MASTER_BANK_NAME:
banks.append(
FmodServer.load_bank("%s/%s" % [banks_root, file_name], FmodServer.FMOD_STUDIO_LOAD_BANK_NORMAL)
)
file_name = dir.get_next()
================================================
FILE: demo/addons/fmod/tool/FmodBankDatabase.gd.uid
================================================
uid://dovuikgbkylhi
================================================
FILE: demo/addons/fmod/tool/inspectors/FmodBankLoaderPropertyInspectorPlugin.gd
================================================
class_name FmodBankLoaderPropertyInspectorPlugin extends EditorInspectorPlugin
static var bank_icon = load("res://addons/fmod/icons/bank_icon.svg")
var _open_project_explorer_callable: Callable
func _init(plugin: FmodPlugin):
_open_project_explorer_callable = plugin.open_project_explorer_bank
func _can_handle(object: Object):
return object is FmodBankLoader
func _parse_property(object: Object, type: Variant.Type, name: String, hint_type: PropertyHint, hint_string: String, usage_flags: int, wide: bool):
return name == "bank_paths"
func _parse_category(object: Object, category: String):
if category != "FmodBankLoader":
return
var editor_property := FmodBankPathEditorProperty.new(_open_project_explorer_callable)
add_property_editor("bank_paths", editor_property, false, "Fmod banks")
================================================
FILE: demo/addons/fmod/tool/inspectors/FmodBankLoaderPropertyInspectorPlugin.gd.uid
================================================
uid://tnljjxahubam
================================================
FILE: demo/addons/fmod/tool/inspectors/FmodEmitterPropertyInspectorPlugin.gd
================================================
class_name FmodEmitterPropertyInspectorPlugin extends EditorInspectorPlugin
var _open_project_explorer_callable: Callable
var _event_editor_property_scene: PackedScene = load("res://addons/fmod/tool/property_editors/FmodEventEditorProperty.tscn")
func _init(plugin: FmodPlugin):
_open_project_explorer_callable = plugin.open_project_explorer_events
func _can_handle(object: Object):
return object is FmodEventEmitter2D or \
object is FmodEventEmitter3D
func _parse_property(object: Object, type: Variant.Type, name: String, hint_type: PropertyHint, hint_string: String, usage_flags: int, wide: bool):
return name == "event_name" || name == "event_guid"
func _parse_category(object: Object, category: String):
if category != "FmodEventEmitter2D" and category != "FmodEventEmitter3D":
return
var editor_property := _event_editor_property_scene.instantiate()
editor_property.initialize(_open_project_explorer_callable, "event_name", "event_guid")
add_property_editor_for_multiple_properties("Fmod event", PackedStringArray(["event_name", "event_guid"]), editor_property)
================================================
FILE: demo/addons/fmod/tool/inspectors/FmodEmitterPropertyInspectorPlugin.gd.uid
================================================
uid://co1ktq45h26wx
================================================
FILE: demo/addons/fmod/tool/performances/PerformancesDisplay.gd
================================================
class_name PerformancesDisplay extends Node
const CORE_CPU_DSP_CATEGORY = "FMOD [Core]/Cpu DSP"
const CORE_CPU_GEOMETRY_CATEGORY = "FMOD [Core]/Cpu Geometry"
const CORE_CPU_STREAM_CATEGORY = "FMOD [Core]/Cpu Stream"
const CORE_CPU_UPDATE_CATEGORY = "FMOD/[Core] Cpu Update"
const CORE_CPU_CONVOLUTION_THREAD1_CATEGORY = "FMOD/[Core] Cpu convolution Thread 1"
const CORE_CPU_CONVOLUTION_THREAD2_CATEGORY = "FMOD/[Core] Cpu convolution Thread 2"
const STUDIO_CPU_UPDATE_CATEGORY = "FMOD/[Studio] Cpu Update"
const MEMORY_CURRENTLY_ALLOCATED_CATEGORY = "FMOD/[Memory] Currently allocated"
const MEMORY_MAX_ALLOCATED_CATEGORY = "FMOD/[Memory] Max allocated"
const FILE_SAMPLE_CATEGORY = "FMOD/[File] Sample bytes read"
const FILE_STREAM_CATEGORY = "FMOD/[File] Stream bytes read"
const FILE_OTHER_CATEGORY = "FMOD/[File] Other bytes read"
func _enter_tree():
var performance_data: FmodPerformanceData = FmodServer.get_performance_data()
add_monitor(CORE_CPU_DSP_CATEGORY, func(): return performance_data.dsp)
add_monitor(CORE_CPU_GEOMETRY_CATEGORY, func(): return performance_data.geometry)
add_monitor(CORE_CPU_STREAM_CATEGORY, func(): return performance_data.stream)
add_monitor(CORE_CPU_UPDATE_CATEGORY, func(): return performance_data.update)
add_monitor(CORE_CPU_CONVOLUTION_THREAD1_CATEGORY, func(): return performance_data.convolution1)
add_monitor(CORE_CPU_CONVOLUTION_THREAD2_CATEGORY, func(): return performance_data.convolution2)
add_monitor(STUDIO_CPU_UPDATE_CATEGORY, func(): return performance_data.studio)
add_monitor(MEMORY_CURRENTLY_ALLOCATED_CATEGORY, func(): return performance_data.currently_allocated)
add_monitor(MEMORY_MAX_ALLOCATED_CATEGORY, func(): return performance_data.max_allocated)
add_monitor(FILE_SAMPLE_CATEGORY, func(): return performance_data.sample_bytes_read)
add_monitor(FILE_STREAM_CATEGORY, func(): return performance_data.stream_bytes_read)
add_monitor(FILE_OTHER_CATEGORY, func(): return performance_data.other_bytes_read)
func _exit_tree() -> void:
remove_monitor(CORE_CPU_DSP_CATEGORY)
remove_monitor(CORE_CPU_GEOMETRY_CATEGORY)
remove_monitor(CORE_CPU_STREAM_CATEGORY)
remove_monitor(CORE_CPU_UPDATE_CATEGORY)
remove_monitor(CORE_CPU_CONVOLUTION_THREAD1_CATEGORY)
remove_monitor(CORE_CPU_CONVOLUTION_THREAD2_CATEGORY)
remove_monitor(STUDIO_CPU_UPDATE_CATEGORY)
remove_monitor(MEMORY_CURRENTLY_ALLOCATED_CATEGORY)
remove_monitor(MEMORY_MAX_ALLOCATED_CATEGORY)
remove_monitor(FILE_SAMPLE_CATEGORY)
remove_monitor(FILE_STREAM_CATEGORY)
remove_monitor(FILE_OTHER_CATEGORY)
func add_monitor(title: String, callable: Callable) -> void:
if not Performance.has_custom_monitor(title):
Performance.add_custom_monitor(title, callable)
func remove_monitor(title: String) -> void:
if Performance.has_custom_monitor(title):
Performance.remove_custom_monitor(title)
================================================
FILE: demo/addons/fmod/tool/performances/PerformancesDisplay.gd.uid
================================================
uid://bc0uajlvc0u00
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodBankPathEditorProperty.gd
================================================
class_name FmodBankPathEditorProperty extends EditorProperty
var path_property_name := "bank_paths"
var ui: Control
var last_selected_index := -1
func _init(open_project_explorer_callable: Callable):
ui = load("res://addons/fmod/tool/property_editors/FmodBankPathsPropertyEditorUi.tscn").instantiate()
add_child(ui)
var add_button: Button = ui.get_node("%AddButton")
var open_project_explorer_event = func open_project_explorer_event():
open_project_explorer_callable.call(self._set_path_and_guid)
add_button.pressed.connect(open_project_explorer_event)
var remove_button: Button = ui.get_node("%RemoveButton")
remove_button.pressed.connect(_on_remove_button)
var manual_add_button: Button = ui.get_node("%ManualAddButton")
manual_add_button.pressed.connect(_on_manual_add_button)
var up_button: Button = ui.get_node("%UpButton")
up_button.pressed.connect(_on_move_button.bind(false))
var down_button: Button = ui.get_node("%DownButton")
down_button.pressed.connect(_on_move_button.bind(true))
func _update_property():
var bank_list: ItemList = ui.get_node("%BankList")
bank_list.clear()
var bank_paths: Array = get_edited_object()[path_property_name]
for path in bank_paths:
bank_list.add_item(path)
if last_selected_index == -1:
return
bank_list.select(last_selected_index)
last_selected_index = -1
func _set_path_and_guid(path: String, _cancel: String):
var current_bank_paths: Array = get_edited_object()[path_property_name]
if current_bank_paths.has(path):
return
var bank_paths := Array(current_bank_paths)
bank_paths.append(path)
emit_changed(path_property_name, bank_paths)
func _on_remove_button():
var bank_list: ItemList = ui.get_node("%BankList")
var current_bank_paths: Array = get_edited_object()[path_property_name]
var bank_paths := Array(current_bank_paths)
var selected_items_indexes: PackedInt32Array = bank_list.get_selected_items()
if selected_items_indexes.is_empty():
return
var item = bank_list.get_item_text(selected_items_indexes[0])
var in_list_index = bank_paths.find(item)
bank_paths.remove_at(in_list_index)
last_selected_index = in_list_index if in_list_index < bank_paths.size() else in_list_index - 1
emit_changed(path_property_name, bank_paths)
func _on_manual_add_button():
var manual_add_line_edit: LineEdit = ui.get_node("%ManualAddLineEdit")
var to_add: String = manual_add_line_edit.text
if not to_add.begins_with("res://") || not to_add.ends_with(".bank"):
return
_set_path_and_guid(to_add, "")
manual_add_line_edit.text = ""
func _on_move_button(is_down: bool):
var bank_list: ItemList = ui.get_node("%BankList")
var current_bank_paths: Array = get_edited_object()[path_property_name]
var bank_paths := Array(current_bank_paths)
var selected_items_indexes: PackedInt32Array = bank_list.get_selected_items()
if selected_items_indexes.is_empty():
return
var item = bank_list.get_item_text(selected_items_indexes[0])
var in_list_index = bank_paths.find(item)
var boundary = current_bank_paths.size() - 1 if is_down else 0
if in_list_index == boundary:
return
var new_index = in_list_index + 1 if is_down else in_list_index - 1
bank_paths.remove_at(in_list_index)
bank_paths.insert(new_index, item)
last_selected_index = new_index
emit_changed(path_property_name, bank_paths)
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodBankPathEditorProperty.gd.uid
================================================
uid://cxyd4qioylvgr
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodBankPathsPropertyEditorUi.tscn
================================================
[gd_scene load_steps=2 format=3 uid="uid://dtlwk8wdeal3h"]
[ext_resource type="Texture2D" uid="uid://o2chsr07oeqs" path="res://addons/fmod/icons/bank_icon.svg" id="1_11c48"]
[node name="FmodBankPathsPropertyEditorUi" type="VBoxContainer"]
offset_right = 92.0
offset_bottom = 43.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="HBoxContainer" type="HBoxContainer" parent="."]
layout_mode = 2
[node name="AddButton" type="Button" parent="HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
text = "+"
icon = ExtResource("1_11c48")
icon_alignment = 2
[node name="RemoveButton" type="Button" parent="HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
text = "-"
[node name="VSeparator" type="VSeparator" parent="HBoxContainer"]
layout_mode = 2
[node name="UpButton" type="Button" parent="HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
text = "↑"
[node name="DownButton" type="Button" parent="HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
text = "↓"
[node name="BankList" type="ItemList" parent="."]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
auto_height = true
[node name="HBoxContainer2" type="HBoxContainer" parent="."]
layout_mode = 2
[node name="ManualAddLineEdit" type="LineEdit" parent="HBoxContainer2"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
[node name="ManualAddButton" type="Button" parent="HBoxContainer2"]
unique_name_in_owner = true
layout_mode = 2
text = "+"
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodEventEditorProperty.gd
================================================
@tool class_name FmodEventEditorProperty extends FmodPathEditorProperty
static var EVENT_PARAMETER_PREFIX_FOR_PROPERTIES = "fmod_parameters"
var former_event_description: FmodEventDescription
func _update_property():
super()
if get_edited_object().event_name == "":
return
_update_parameters()
var event_description: FmodEventDescription = FmodServer.get_event_from_guid(get_edited_object().event_guid)
if event_description == null:
event_description = FmodServer.get_event(get_edited_object().event_name)
former_event_description = event_description
func _set_path_and_guid(path: String, guid: String):
super(path, guid)
if get_edited_object().event_name == "":
return
_update_parameters()
former_event_description = FmodServer.get_event_from_guid(get_edited_object().event_guid)
func _update_parameters():
var event_description: FmodEventDescription = FmodServer.get_event_from_guid(get_edited_object().event_guid)
if event_description == null:
return
if former_event_description != null and event_description != former_event_description:
get_edited_object().tool_remove_all_parameters()
var map_to_property_name = func map_to_property_name(dict: Dictionary):
return dict["name"]
var filter_fmod_parameter_property = func filter_fmod_parameter_property(parameter_name: String):
return parameter_name.begins_with(EVENT_PARAMETER_PREFIX_FOR_PROPERTIES)
var filter_property_id = func filter_property_id(property: String):
return property.ends_with("/id")
var existing_property_ids = get_edited_object().get_property_list().map(map_to_property_name).filter(filter_fmod_parameter_property).filter(filter_property_id)
var map_property_name_to_parameter_name = func map_property_name_to_parameter_name(parameter: String):
return parameter.split("/")[1]
var existing_parameter_names = existing_property_ids.map(map_property_name_to_parameter_name)
var map_property_id_to_parameter_id_value = func map_property_id_to_parameter_id_value(property: String):
return get_edited_object()[property]
var existing_parameter_ids = existing_property_ids.map(map_property_id_to_parameter_id_value)
var property_matching = existing_parameter_ids.map(func(id): return false)
for param: FmodParameterDescription in event_description.get_parameters():
if param.is_global() or param.is_automatic() or param.is_read_only():
continue
var parameter_name = param.get_name()
var parameter_id_param = "%s/%s/id" % [EVENT_PARAMETER_PREFIX_FOR_PROPERTIES, parameter_name]
var parameter_value_param = "%s/%s" % [EVENT_PARAMETER_PREFIX_FOR_PROPERTIES, parameter_name]
var parameter_variant_type = "%s/%s/variant_type" % [EVENT_PARAMETER_PREFIX_FOR_PROPERTIES, parameter_name]
var parameter_labels = "%s/%s/labels" % [EVENT_PARAMETER_PREFIX_FOR_PROPERTIES, parameter_name]
var existing_property_name_index = existing_property_ids.find(parameter_id_param)
var are_properties_already_in_node = existing_property_name_index != -1
var parameter_id = param.get_id()
var variant_type: Variant.Type = TYPE_FLOAT
var default_value = param.get_default_value()
var minimum_value = param.get_minimum()
var maximum_value = param.get_maximum()
if param.is_labeled():
variant_type = TYPE_STRING
default_value = event_description.get_parameter_label_by_id(parameter_id, default_value)
minimum_value = event_description.get_parameter_label_by_id(parameter_id, minimum_value)
maximum_value = event_description.get_parameter_label_by_id(parameter_id, maximum_value)
elif param.is_discrete():
variant_type = TYPE_INT
default_value = int(default_value)
minimum_value = int(minimum_value)
maximum_value = int(maximum_value)
if are_properties_already_in_node:
property_matching[existing_property_name_index] = existing_parameter_ids[existing_property_name_index] == parameter_id
if not are_properties_already_in_node or get_edited_object()[parameter_id_param] == null:
get_edited_object()[parameter_id_param] = parameter_id
if not are_properties_already_in_node or get_edited_object()[parameter_value_param] == null:
get_edited_object()[parameter_value_param] = default_value
if not are_properties_already_in_node or get_edited_object()[parameter_variant_type] == null:
get_edited_object()[parameter_variant_type] = variant_type
if param.is_labeled() and (not are_properties_already_in_node or get_edited_object()[parameter_labels] == null):
get_edited_object()[parameter_labels] = event_description.get_parameter_labels_by_id(parameter_id)
for i in property_matching.size():
if not property_matching[i]:
get_edited_object().tool_remove_parameter(existing_parameter_ids[i])
get_edited_object().notify_property_list_changed()
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodEventEditorProperty.gd.uid
================================================
uid://b32x60k0th8td
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodEventEditorProperty.tscn
================================================
[gd_scene load_steps=3 format=3 uid="uid://cowfthogh1n7i"]
[ext_resource type="PackedScene" uid="uid://cujo3xq0erren" path="res://addons/fmod/tool/property_editors/FmodPathEditorProperty.tscn" id="1_xvpec"]
[ext_resource type="Script" uid="uid://b32x60k0th8td" path="res://addons/fmod/tool/property_editors/FmodEventEditorProperty.gd" id="2_nkhkm"]
[node name="FmodEventEditorProperty" instance=ExtResource("1_xvpec")]
script = ExtResource("2_nkhkm")
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodGuidAndPathPropertyEditorUi.gd
================================================
@tool class_name FmodGuidAndPathPropertyEditorUi extends HBoxContainer
func set_callables(window_callable: Callable, path_callable: Callable, guid_callable: Callable):
%EventExplorerButton.pressed.connect(window_callable)
%PathLineEdit.text_changed.connect(path_callable)
%GuidLineEdit.text_changed.connect(guid_callable)
func set_icon(icon: Texture2D):
%EventExplorerButton.icon = icon
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodGuidAndPathPropertyEditorUi.gd.uid
================================================
uid://3xn18ci172v4
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodGuidAndPathPropertyEditorUi.tscn
================================================
[gd_scene load_steps=3 format=3 uid="uid://hy04frgfhtgu"]
[ext_resource type="Script" uid="uid://3xn18ci172v4" path="res://addons/fmod/tool/property_editors/FmodGuidAndPathPropertyEditorUi.gd" id="1_eao7t"]
[ext_resource type="Texture2D" uid="uid://cmpgmbn3y4svl" path="res://addons/fmod/icons/event_icon.svg" id="1_kuu6i"]
[node name="FmodGuidAndPathPropertyEditorUi" type="HBoxContainer"]
offset_right = 1152.0
offset_bottom = 66.0
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource("1_eao7t")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3
[node name="PathLineEdit" type="LineEdit" parent="VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="GuidLineEdit" type="LineEdit" parent="VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="EventExplorerButton" type="Button" parent="."]
unique_name_in_owner = true
layout_mode = 2
icon = ExtResource("1_kuu6i")
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodPathEditorProperty.gd
================================================
@tool class_name FmodPathEditorProperty extends EditorProperty
var ui: Control
var guid_property: String
var path_property: String
var regex := RegEx.new()
var default_line_edit_modulate: Color
func initialize(open_project_explorer_callable: Callable, path_prop: String, guid_prop: String):
regex.compile("{\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}}")
guid_property = guid_prop
path_property = path_prop
var guid_and_path_ui: FmodGuidAndPathPropertyEditorUi = %FmodGuidAndPathPropertyEditorUi
default_line_edit_modulate = guid_and_path_ui.get_node("%GuidLineEdit").modulate
var open_project_explorer_event = func open_project_explorer_event():
open_project_explorer_callable.call(self._set_path_and_guid)
guid_and_path_ui.set_callables(open_project_explorer_event, _set_path, _set_guid)
func _update_property():
var guid_and_path_ui = %FmodGuidAndPathPropertyEditorUi
guid_and_path_ui.get_node("%PathLineEdit").text = get_edited_object()[path_property]
guid_and_path_ui.get_node("%GuidLineEdit").text = get_edited_object()[guid_property]
func _set_path(path: String):
emit_changed(path_property, path)
func _set_guid(guid: String):
var line_edit := %FmodGuidAndPathPropertyEditorUi.get_node("%GuidLineEdit") as LineEdit
if not regex.search(guid):
line_edit.modulate = Color.RED
return
line_edit.modulate = default_line_edit_modulate
emit_changed(guid_property, guid)
func _set_path_and_guid(path: String, guid: String):
_set_path(path)
_set_guid(guid)
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodPathEditorProperty.gd.uid
================================================
uid://qshng8csi2fr
================================================
FILE: demo/addons/fmod/tool/property_editors/FmodPathEditorProperty.tscn
================================================
[gd_scene load_steps=3 format=3 uid="uid://cujo3xq0erren"]
[ext_resource type="Script" uid="uid://qshng8csi2fr" path="res://addons/fmod/tool/property_editors/FmodPathEditorProperty.gd" id="1_4e4vx"]
[ext_resource type="PackedScene" uid="uid://hy04frgfhtgu" path="res://addons/fmod/tool/property_editors/FmodGuidAndPathPropertyEditorUi.tscn" id="2_nvtqg"]
[node name="FmodPathEditorProperty" type="EditorProperty"]
script = ExtResource("1_4e4vx")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
[node name="FmodGuidAndPathPropertyEditorUi" parent="VBoxContainer" instance=ExtResource("2_nvtqg")]
unique_name_in_owner = true
layout_mode = 2
================================================
FILE: demo/addons/fmod/tool/ui/EventParametersDisplay.gd
================================================
@tool class_name EventParametersDisplay extends ScrollContainer
static var parameter_display_scene: PackedScene = load("res://addons/fmod/tool/ui/ParameterDisplay.tscn")
func set_fmod_event(event: FmodEventDescription) -> bool: # returns false if there were no parameters
for child in %ParameterDisplaysContainer.get_children():
%ParameterDisplaysContainer.remove_child(child)
child.queue_free()
var event_parameters: Array = event.get_parameters()
if event_parameters:
show()
for parameter : FmodParameterDescription in event_parameters:
var parameter_display: ParameterDisplay = parameter_display_scene.instantiate()
parameter_display.set_event_description(event)
parameter_display.set_parameter(parameter)
if %ParameterDisplaysContainer.get_child_count() > 0:
%ParameterDisplaysContainer.add_child(HSeparator.new())
%ParameterDisplaysContainer.add_child(parameter_display)
return true # we had parameters to show!
else:
return false # no parameters to visualise
================================================
FILE: demo/addons/fmod/tool/ui/EventParametersDisplay.gd.uid
================================================
uid://7relkis52fsu
================================================
FILE: demo/addons/fmod/tool/ui/EventParametersDisplay.tscn
================================================
[gd_scene load_steps=2 format=3 uid="uid://cppeyr1ke5wre"]
[ext_resource type="Script" uid="uid://7relkis52fsu" path="res://addons/fmod/tool/ui/EventParametersDisplay.gd" id="1_2l58q"]
[node name="EventParametersDisplay" type="ScrollContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource("1_2l58q")
[node name="ParameterDisplaysContainer" type="VBoxContainer" parent="."]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
================================================
FILE: demo/addons/fmod/tool/ui/EventParametersWindow.tscn
================================================
[gd_scene load_steps=2 format=3 uid="uid://skp8awewyl85"]
[ext_resource type="PackedScene" uid="uid://cppeyr1ke5wre" path="res://addons/fmod/tool/ui/EventParametersDisplay.tscn" id="1_clkxg"]
[node name="EventParametersWindow" type="Window"]
[node name="EventParametersDisplay" parent="." instance=ExtResource("1_clkxg")]
================================================
FILE: demo/addons/fmod/tool/ui/EventPlayControls.gd
================================================
@tool
extends PanelContainer
@export var play_button : Button
@export var stop_button : Button
@export var fade_out_toggle : CheckButton
var event_instance : FmodEvent
func _ready() -> void:
hide()
play_button.icon = EditorInterface.get_editor_theme().get_icon("Play", "EditorIcons")
stop_button.icon = EditorInterface.get_editor_theme().get_icon("Stop", "EditorIcons")
play_button.pressed.connect(on_play_button_pressed)
stop_button.pressed.connect(on_stop_button_pressed)
func set_fmod_event(_event_description : FmodEventDescription) -> void:
stop_and_release_instance() # always stop and release if a previous one is active
event_instance = FmodServer.create_event_instance_with_guid(_event_description.get_guid())
show()
func play_event() -> void:
if event_instance:
event_instance.start()
func stop_event() -> void:
if event_instance:
var stop_mode : int = FmodServer.FMOD_STUDIO_STOP_IMMEDIATE
if fade_out_toggle.button_pressed:
stop_mode = FmodServer.FMOD_STUDIO_STOP_ALLOWFADEOUT
event_instance.stop(stop_mode)
func _exit_tree() -> void:
stop_and_release_instance()
func stop_and_release_instance() -> void:
if event_instance:
event_instance.stop(0)
event_instance.release()
func on_play_button_pressed() -> void:
play_event()
func on_stop_button_pressed() -> void:
stop_event()
================================================
FILE: demo/addons/fmod/tool/ui/EventPlayControls.gd.uid
================================================
uid://vgmq7hfrbddw
================================================
FILE: demo/addons/fmod/tool/ui/FmodBankExplorer.gd
================================================
@tool class_name FmodBankExplorer extends Window
enum ToDisplayFlags {
BUSES = 1,
VCA = 2,
EVENTS = 4
}
static var _fmod_icon = load("res://addons/fmod/icons/fmod_icon.svg")
static var _vca_icon = load("res://addons/fmod/icons/vca_icon.svg")
static var _bank_icon = load("res://addons/fmod/icons/bank_icon.svg")
static var _event_icon = load("res://addons/fmod/icons/event_icon.svg")
static var _bus_icon = load("res://addons/fmod/icons/bus_icon.svg")
static var _snapshot_icon = load("res://addons/fmod/icons/snapshot_icon.svg")
signal emit_path_and_guid(path: String, guid: String)
var tree: Tree
@onready var copy_path_button := %PathLabel.get_child(0)
@onready var copy_guid_button := %GuidLabel.get_child(0)
var should_display_copy_buttons = true
var should_display_select_button = false
var _current_select_callable: Callable
var base_color: Color
var contrast: float
var background_color: Color
var banks: Array = Array()
var flags: int = 0
var search: String = ""
func reset_search():
%SearchField.text = ""
search = ""
func _ready():
var main_window_size = get_parent().get_window().size
size = main_window_size * 0.5
var copy_texture : Texture = EditorInterface.get_editor_theme().get_icon("ActionCopy", "EditorIcons")
copy_guid_button.icon = copy_texture
copy_path_button.icon = copy_texture
copy_guid_button.visible = false
copy_path_button.visible = false
copy_path_button.pressed.connect(_on_copy_path_button)
copy_guid_button.pressed.connect(_on_copy_guid_button)
var emit_path_and_guid_callable = func emit_path_and_guid_callable():
var selected_item = tree.get_selected()
if selected_item == null:
return
var selected_fmod_element = selected_item.get_metadata(0)
if selected_fmod_element == null:
return
var path = selected_fmod_element.get_godot_res_path() if selected_fmod_element is FmodBank else selected_fmod_element.get_path()
emit_path_and_guid.emit(path, selected_fmod_element.get_guid())
%SelectButton.pressed.connect(emit_path_and_guid_callable)
%SelectButton.pressed.connect(close_window)
%CloseButton.pressed.connect(close_window)
close_requested.connect(close_window)
tree = %Tree
tree.item_selected.connect(_on_item_selected)
tree.columns = 1
generate_tree()
%RefreshBanksButton.pressed.connect(on_refresh_banks_button_pressed)
func regenerate_tree(callable: Callable = Callable()):
tree.clear()
generate_tree(callable)
func generate_tree(callable: Callable = Callable()):
%SelectButton.visible = should_display_select_button
if _current_select_callable != Callable() && _current_select_callable.get_object() != null:
emit_path_and_guid.disconnect(_current_select_callable)
_current_select_callable = callable
var root_item := tree.create_item()
root_item.set_text(0, "Fmod objects")
root_item.set_icon(0, _fmod_icon)
var has_many_flags = (flags & (flags - 1)) != 0
for bank in FmodServer.get_all_banks():
var fmod_bank := bank as FmodBank
var buses := fmod_bank.get_bus_list()
var vcas := fmod_bank.get_vca_list()
var events := fmod_bank.get_description_list()
if search.is_empty():
var bank_item := tree.create_item(root_item)
bank_item.set_text(0, fmod_bank.get_godot_res_path())
bank_item.set_icon(0, _bank_icon)
bank_item.set_metadata(0, bank)
if flags & ToDisplayFlags.BUSES and buses.size() != 0:
buses.sort_custom(sort_by_path)
if has_many_flags:
var buses_item := tree.create_item(bank_item)
buses_item.set_text(0, "Buses")
buses_item.set_icon(0, _bus_icon)
_add_elements_as_tree(buses, buses_item)
else:
_add_elements_as_tree(buses, bank_item)
if flags & ToDisplayFlags.VCA and vcas.size() != 0:
vcas.sort_custom(sort_by_path)
if has_many_flags:
var vca_item := tree.create_item(bank_item)
vca_item.set_text(0, "VCAs")
vca_item.set_icon(0, _vca_icon)
_add_elements_as_tree(vcas, vca_item)
else:
_add_elements_as_tree(vcas, bank_item)
if flags & ToDisplayFlags.EVENTS and events.size() != 0:
events.sort_custom(sort_by_path)
if has_many_flags:
var events_item := tree.create_item(bank_item)
events_item.set_text(0, "Events")
events_item.set_icon(0, _event_icon)
_add_elements_as_tree(events, events_item)
else:
_add_elements_as_tree(events, bank_item)
else:
if flags & ToDisplayFlags.BUSES:
_add_elements_as_items(buses, root_item)
if flags & ToDisplayFlags.VCA:
_add_elements_as_items(vcas, root_item)
if flags & ToDisplayFlags.EVENTS:
_add_elements_as_items(events, root_item)
if copy_path_button.visible:
copy_path_button.visible = should_display_copy_buttons
if copy_guid_button.visible:
copy_guid_button.visible = should_display_copy_buttons
if _current_select_callable != Callable():
print(_current_select_callable)
emit_path_and_guid.connect(_current_select_callable)
%SelectButton.visible = should_display_select_button and %GuidLabel.text != ""
func _add_elements_as_items(elements: Array, parent: TreeItem):
for element in elements:
var full_path: String = element.get_path()
if not full_path.containsn(search):
continue
var child := tree.create_item(parent)
var name := full_path.rsplit("/")[-1]
child.set_text(0, name)
child.set_metadata(0, element)
child.set_icon(0, _get_icon_for_fmod_path(full_path))
func _add_elements_as_tree(elements: Array, parent: TreeItem):
var nodes := { "": parent }
for element in elements:
var full_path: String = element.get_path()
var parts := full_path.split("/")
# Drop the “type:” prefix
if parts.size() > 0:
parts.remove_at(0)
# Walk each segment in turn, building a running “key”
var key := ""
for i in range(parts.size()):
var name = parts[i]
if full_path == "bus:/":
name = "Master"
if key == "":
key = name
else:
key = key + "/" + name
# If we haven’t created this node yet, do so now
if not nodes.has(key):
var root_and_name := key.rsplit("/", false, 1)
var parent_key: String = ""
if root_and_name.size() == 2:
parent_key = root_and_name[0]
var parent_item = nodes[parent_key]
var child := tree.create_item(parent_item)
child.set_text(0, name)
nodes[key] = child
# If this is the final segment, attach the metadata & icon
if i == parts.size() - 1:
var leaf = nodes[key]
leaf.set_metadata(0, element)
leaf.set_icon(0, _get_icon_for_fmod_path(full_path))
func _on_item_selected():
var metadata = tree.get_selected().get_metadata(0)
if metadata == null or !metadata.get_guid():
%PathsBG.hide()
%EventPlayControls.hide()
copy_path_button.visible = false
copy_guid_button.visible = false
%SelectButton.visible = false
%ParametersLabel.visible = false
%ParametersContainer.visible = false
return
%GuidLabel.set_text(metadata.get_guid())
%PathLabel.set_text(metadata.get_path())
%PathsBG.show()
if should_display_copy_buttons:
copy_path_button.visible = true
copy_guid_button.visible = true
if should_display_select_button:
%SelectButton.visible = true
if metadata is FmodEventDescription:
%EventPlayControls.set_fmod_event(metadata)
var _show_parameter_controls : bool = %EventParametersDisplay.set_fmod_event(metadata)
%ParametersLabel.visible = _show_parameter_controls
%ParametersContainer.visible = _show_parameter_controls
return
%EventPlayControls.hide()
%EventParametersDisplay.hide()
%ParametersLabel.visible = false
%ParametersContainer.visible = false
func _on_copy_path_button():
DisplayServer.clipboard_set(%PathLabel.text)
func _on_copy_guid_button():
DisplayServer.clipboard_set(%GuidLabel.text)
func on_refresh_banks_button_pressed() -> void:
# unload banks
banks.clear()
tree.clear()
FmodBankDatabase.reload_all_banks()
generate_tree()
func close_window():
%EventPlayControls.stop_event()
visible = false
static func _get_icon_for_fmod_path(fmod_path: String) -> Texture2D:
var icon: Texture2D = null
if fmod_path.begins_with("bus:/"):
icon = _bus_icon
elif fmod_path.begins_with("event:/"):
icon = _event_icon
elif fmod_path.begins_with("vca:/"):
icon = _vca_icon
elif fmod_path.begins_with("snapshot:/"):
icon = _snapshot_icon
return icon
static func sort_by_path(a, b):
return a.get_path().casecmp_to(b.get_path()) < 0
func _on_text_edit_text_submitted(new_text: String) -> void:
search = new_text
regenerate_tree()
================================================
FILE: demo/addons/fmod/tool/ui/FmodBankExplorer.gd.uid
================================================
uid://b5xgbibc3amtk
================================================
FILE: demo/addons/fmod/tool/ui/FmodBankExplorer.tscn
================================================
[gd_scene load_steps=17 format=3 uid="uid://nr38urn226al"]
[ext_resource type="Script" uid="uid://b5xgbibc3amtk" path="res://addons/fmod/tool/ui/FmodBankExplorer.gd" id="1_ekqus"]
[ext_resource type="Script" uid="uid://vgmq7hfrbddw" path="res://addons/fmod/tool/ui/EventPlayControls.gd" id="2_mleop"]
[ext_resource type="PackedScene" uid="uid://cppeyr1ke5wre" path="res://addons/fmod/tool/ui/EventParametersDisplay.tscn" id="2_uoyg8"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_potss"]
bg_color = Color(0.21176471, 0.23921569, 0.2901961, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_piloo"]
bg_color = Color(0.21176471, 0.23921569, 0.2901961, 1)
[sub_resource type="Theme" id="Theme_02ixt"]
Button/styles/normal = SubResource("StyleBoxFlat_potss")
LineEdit/styles/normal = SubResource("StyleBoxFlat_piloo")
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wrr0m"]
bg_color = Color(0, 0, 0, 0.247059)
border_width_left = 1
border_width_top = 1
border_width_right = 1
border_width_bottom = 1
border_color = Color(1, 1, 1, 0.207843)
corner_radius_top_left = 5
corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_2pbsy"]
[sub_resource type="LabelSettings" id="LabelSettings_3jkpq"]
font_size = 18
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0awfk"]
bg_color = Color(0, 0, 0, 0.14902)
border_width_left = 1
border_width_top = 1
border_width_right = 1
border_width_bottom = 1
border_color = Color(0.8, 0.8, 0.8, 0.145098)
corner_radius_top_left = 5
corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5
[sub_resource type="LabelSettings" id="LabelSettings_d4isr"]
[sub_resource type="DPITexture" id="DPITexture_potss"]
_source = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"><path fill=\"#e0e0e0\" d=\"M2 1a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h1V3h9V2a1 1 0 0 0-1-1zm3 3a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1zm1 2h7v7H6z\"/></svg>
"
base_scale = 1.25
color_map = {
Color(1, 0.37254903, 0.37254903, 1): Color(1, 0.47, 0.42, 1),
Color(0.37254903, 1, 0.5921569, 1): Color(0.45, 0.95, 0.5, 1),
Color(1, 0.8666667, 0.39607844, 1): Color(1, 0.87, 0.4, 1)
}
[sub_resource type="DPITexture" id="DPITexture_piloo"]
_source = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"><path fill=\"#e0e0e0\" d=\"M4 12a1 1 0 0 0 1.555.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 4 4z\"/></svg>
"
base_scale = 1.25
color_map = {
Color(1, 0.37254903, 0.37254903, 1): Color(1, 0.47, 0.42, 1),
Color(0.37254903, 1, 0.5921569, 1): Color(0.45, 0.95, 0.5, 1),
Color(1, 0.8666667, 0.39607844, 1): Color(1, 0.87, 0.4, 1)
}
[sub_resource type="DPITexture" id="DPITexture_02ixt"]
_source = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"><rect width=\"10\" height=\"10\" x=\"3\" y=\"3\" fill=\"#e0e0e0\" rx=\"1\"/></svg>
"
base_scale = 1.25
color_map = {
Color(1, 0.37254903, 0.37254903, 1): Color(1, 0.47, 0.42, 1),
Color(0.37254903, 1, 0.5921569, 1): Color(0.45, 0.95, 0.5, 1),
Color(1, 0.8666667, 0.39607844, 1): Color(1, 0.87, 0.4, 1)
}
[sub_resource type="InputEventKey" id="InputEventKey_w47tf"]
device = -1
keycode = 4194305
[sub_resource type="Shortcut" id="Shortcut_rarey"]
events = [SubResource("InputEventKey_w47tf")]
[node name="FmodBankExplorer" type="Window"]
oversampling_override = 1.0
title = "Fmod banks explorer"
initial_position = 2
size = Vector2i(1280, 673)
script = ExtResource("1_ekqus")
[node name="BGPanel" type="Panel" parent="."]
unique_name_in_owner = true
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="WindowMargin" type="MarginContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = SubResource("Theme_02ixt")
theme_override_constants/margin_left = 16
theme_override_constants/margin_top = 16
theme_override_constants/margin_right = 16
theme_override_constants/margin_bottom = 16
[node name="VBoxContainer" type="VBoxContainer" parent="WindowMargin"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="TopPanel" type="PanelContainer" parent="WindowMargin/VBoxContainer"]
custom_minimum_size = Vector2(0, 42.315)
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="WindowMargin/VBoxContainer/TopPanel"]
layout_mode = 2
alignment = 2
[node name="SearchField" type="LineEdit" parent="WindowMargin/VBoxContainer/TopPanel/HBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
size_flags_horizontal = 2
placeholder_text = "Search.."
context_menu_enabled = false
[node name="RefreshBanksButton" type="Button" parent="WindowMargin/VBoxContainer/TopPanel/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "Refresh Banks"
[node name="BaseColorPanel" type="PanelContainer" parent="WindowMargin/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
theme_override_styles/panel = SubResource("StyleBoxFlat_wrr0m")
[node name="MarginContainer" type="MarginContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel"]
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
[node name="HSplitContainer" type="HSplitContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer"]
layout_mode = 2
[node name="Tree" type="Tree" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
size_flags_stretch_ratio = 0.54
theme_override_styles/panel = SubResource("StyleBoxEmpty_2pbsy")
hide_root = true
[node name="MarginContainer" type="MarginContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
[node name="RightPanelContent" type="VBoxContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="PathsLabel" type="Label" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent"]
visible = false
layout_mode = 2
size_flags_vertical = 1
text = "ID:"
label_settings = SubResource("LabelSettings_3jkpq")
justification_flags = 35
[node name="PathsBG" type="PanelContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/panel = SubResource("StyleBoxFlat_0awfk")
[node name="MarginContainer" type="MarginContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/PathsBG"]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="PathContainer" type="HBoxContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/PathsBG/MarginContainer"]
layout_mode = 2
[node name="TitleLabelContainer" type="VBoxContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/PathsBG/MarginContainer/PathContainer"]
layout_mode = 2
[node name="PathTitleLabel" type="Label" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/PathsBG/MarginContainer/PathContainer/TitleLabelContainer"]
layout_mode = 2
size_flags_vertical = 6
text = "Path:"
label_settings = SubResource("LabelSettings_d4isr")
[node name="GuidTitleLabel" type="Label" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/PathsBG/MarginContainer/PathContainer/TitleLabelContainer"]
layout_mode = 2
size_flags_vertical = 6
text = "GUID: "
label_settings = SubResource("LabelSettings_d4isr")
[node name="ValueContainer" type="VBoxContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/PathsBG/MarginContainer/PathContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="PathLabel" type="Label" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/PathsBG/MarginContainer/PathContainer/ValueContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 6
text = "asdfasdfasdfasdf"
[node name="CopyPathLabel" type="Button" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/PathsBG/MarginContainer/PathContainer/ValueContainer/PathLabel"]
visible = false
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = 5.57001
offset_top = -15.5
offset_right = 36.57
offset_bottom = 15.5
grow_horizontal = 0
grow_vertical = 2
icon = SubResource("DPITexture_potss")
[node name="GuidLabel" type="Label" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/PathsBG/MarginContainer/PathContainer/ValueContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 6
text = "asdfasdf"
vertical_alignment = 1
[node name="CopyGuidLabel" type="Button" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/PathsBG/MarginContainer/PathContainer/ValueContainer/GuidLabel"]
visible = false
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = 6.095
offset_top = -15.5
offset_right = 37.095
offset_bottom = 15.5
grow_horizontal = 0
grow_vertical = 2
icon = SubResource("DPITexture_potss")
[node name="ParametersLabel" type="Label" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent"]
unique_name_in_owner = true
visible = false
custom_minimum_size = Vector2(0, 45)
layout_mode = 2
text = "Parameters:"
label_settings = SubResource("LabelSettings_3jkpq")
vertical_alignment = 2
[node name="ParametersContainer" type="PanelContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_vertical = 3
theme_override_styles/panel = SubResource("StyleBoxFlat_0awfk")
[node name="MarginContainer" type="MarginContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/ParametersContainer"]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="EventParametersDisplay" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/ParametersContainer/MarginContainer" instance=ExtResource("2_uoyg8")]
unique_name_in_owner = true
layout_mode = 2
[node name="EventPlayControls" type="PanelContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent" node_paths=PackedStringArray("play_button", "stop_button", "fade_out_toggle")]
unique_name_in_owner = true
visible = false
custom_minimum_size = Vector2(0, 55.44)
layout_mode = 2
size_flags_vertical = 10
size_flags_stretch_ratio = 0.1
theme_override_styles/panel = SubResource("StyleBoxFlat_0awfk")
script = ExtResource("2_mleop")
play_button = NodePath("MarginContainer/HBoxContainer/PlayEventButton")
stop_button = NodePath("MarginContainer/HBoxContainer/StopEventButton")
fade_out_toggle = NodePath("MarginContainer/HBoxContainer/FadeoutToggle")
[node name="MarginContainer" type="MarginContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/EventPlayControls"]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="HBoxContainer" type="HBoxContainer" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/EventPlayControls/MarginContainer"]
layout_mode = 2
[node name="PlayEventButton" type="Button" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/EventPlayControls/MarginContainer/HBoxContainer"]
layout_mode = 2
text = "Play"
icon = SubResource("DPITexture_piloo")
[node name="StopEventButton" type="Button" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/EventPlayControls/MarginContainer/HBoxContainer"]
layout_mode = 2
text = "Stop"
icon = SubResource("DPITexture_02ixt")
[node name="FadeoutToggle" type="CheckButton" parent="WindowMargin/VBoxContainer/BaseColorPanel/MarginContainer/HSplitContainer/MarginContainer/RightPanelContent/EventPlayControls/MarginContainer/HBoxContainer"]
layout_mode = 2
text = "Allow fade out"
[node name="MarginContainer" type="MarginContainer" parent="WindowMargin/VBoxContainer"]
layout_mode = 2
theme_override_constants/margin_top = 8
[node name="HBoxContainer" type="HBoxContainer" parent="WindowMargin/VBoxContainer/MarginContainer"]
layout_mode = 2
alignment = 1
[node name="MarginContainer2" type="MarginContainer" parent="WindowMargin/VBoxContainer/MarginContainer/HBoxContainer"]
layout_mode = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_right = 8
[node name="SelectButton" type="Button" parent="WindowMargin/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer2"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_horizontal = 4
text = "Select"
[node name="MarginContainer" type="MarginContainer" parent="WindowMargin/VBoxContainer/MarginContainer/HBoxContainer"]
layout_mode = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_right = 8
[node name="CloseButton" type="Button" parent="WindowMargin/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
shortcut = SubResource("Shortcut_rarey")
text = "Close"
[connection signal="text_submitted" from="WindowMargin/VBoxContainer/TopPanel/HBoxContainer/SearchField" to="." method="_on_text_edit_text_submitted"]
================================================
FILE: demo/addons/fmod/tool/ui/ParameterDisplay.gd
================================================
@tool class_name ParameterDisplay extends MarginContainer
var event_description: FmodEventDescription
var parameter: FmodParameterDescription
func set_event_description(p_event_description: FmodEventDescription):
event_description = p_event_description
func set_parameter(p_parameter: FmodParameterDescription):
show()
parameter = p_parameter
func display_value_selector(should: bool):
%ValueSetterContainer.visible = should
func _ready():
if parameter == null:
hide()
return
var minimum_value = parameter.get_minimum()
var maximum_value = parameter.get_maximum()
var default_value = parameter.get_default_value()
var copy_icon : Texture = EditorInterface.get_editor_theme().get_icon("ActionCopy", "EditorIcons")
%NameCopyButton.icon = copy_icon
%IdCopyButton.icon = copy_icon
%NameLabel.text = parameter.get_name()
%IdLabel.text = str(parameter.get_id())
if parameter.is_labeled():
%RangeTitle.text = "Values"
var values_text = "["
var is_first: bool = true
for label: String in event_description.get_parameter_labels_by_id(parameter.get_id()):
if not is_first:
values_text += ", "
values_text += label
is_first = false
values_text += "]"
%RangeLabel.text = values_text
else:
%RangeLabel.text = "[%s, %s]" % [minimum_value, maximum_value]
%DefaultValueLabel.text = str(default_value)
%NameCopyButton.pressed.connect(_on_copy_name_button)
%IdCopyButton.pressed.connect(_on_copy_id_button)
%BackToDefaultButton.pressed.connect(_on_default_value_button)
%ValueSlider.min_value = minimum_value
%ValueSlider.max_value = maximum_value
%ValueSlider.value = default_value
_on_slider_value_changed(%ValueSlider.value)
%ValueSlider.value_changed.connect(_on_slider_value_changed)
func _on_copy_name_button():
DisplayServer.clipboard_set(%NameLabel.text)
func _on_copy_id_button():
DisplayServer.clipboard_set(%IdLabel.text)
func _on_default_value_button():
%ValueSlider.value = parameter.get_default_value()
func _on_slider_value_changed(value: float):
%CurrentValueLabel.text = str(value)
================================================
FILE: demo/addons/fmod/tool/ui/ParameterDisplay.gd.uid
================================================
uid://ve6g43nb1hdd
================================================
FILE: demo/addons/fmod/tool/ui/ParameterDisplay.tscn
================================================
[gd_scene load_steps=2 format=3 uid="uid://bfdldojk5i6u3"]
[ext_resource type="Script" uid="uid://ve6g43nb1hdd" path="res://addons/fmod/tool/ui/ParameterDisplay.gd" id="1_fxyw8"]
[node name="ParameterDisplay" type="MarginContainer"]
visible = false
offset_right = 168.0
offset_bottom = 160.0
size_flags_horizontal = 3
theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 4
script = ExtResource("1_fxyw8")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
[node name="VBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
layout_mode = 2
[node name="TitleContainer" type="VBoxContainer" parent="VBoxContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 20
[node name="NameTitle" type="Label" parent="VBoxContainer/VBoxContainer/TitleContainer"]
layout_mode = 2
size_flags_vertical = 10
text = "Name: "
[node name="IdTitle" type="Label" parent="VBoxContainer/VBoxContainer/TitleContainer"]
layout_mode = 2
size_flags_vertical = 10
text = "ID: "
[node name="RangeTitle" type="Label" parent="VBoxContainer/VBoxContainer/TitleContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 10
text = "Range: "
[node name="DefaultValueTitle" type="Label" parent="VBoxContainer/VBoxContainer/TitleContainer"]
layout_mode = 2
size_flags_vertical = 10
text = "Default value: "
[node name="ContentContainer" type="VBoxContainer" parent="VBoxContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 20
[node name="NameLabel" type="Label" parent="VBoxContainer/VBoxContainer/ContentContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 10
[node name="NameCopyButton" type="Button" parent="VBoxContainer/VBoxContainer/ContentContainer/NameLabel"]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = 9.0
offset_top = -15.5
offset_right = 40.0
offset_bottom = 15.5
grow_horizontal = 0
grow_vertical = 2
size_flags_vertical = 10
[node name="IdLabel" type="Label" parent="VBoxContainer/VBoxContainer/ContentContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 10
[node name="IdCopyButton" type="Button" parent="VBoxContainer/VBoxContainer/ContentContainer/IdLabel"]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = 9.0
offset_top = -15.5
offset_right = 40.0
offset_bottom = 15.5
grow_horizontal = 0
grow_vertical = 2
size_flags_vertical = 10
[node name="RangeLabel" type="Label" parent="VBoxContainer/VBoxContainer/ContentContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 10
[node name="DefaultValueLabel" type="Label" parent="VBoxContainer/VBoxContainer/ContentContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 10
[node name="ValueSetterContainer" type="VBoxContainer" parent="VBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/ValueSetterContainer"]
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/ValueSetterContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/ValueSetterContainer/HBoxContainer"]
layout_mode = 2
text = "Set value: "
[node name="ValueSlider" type="HSlider" parent="VBoxContainer/ValueSetterContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
[node name="BackToDefaultButton" type="Button" parent="VBoxContainer/ValueSetterContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "Default"
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/ValueSetterContainer"]
layout_mode = 2
[node name="CurrentValueTitleLabel" type="Label" parent="VBoxContainer/ValueSetterContainer/HBoxContainer2"]
layout_mode = 2
text = "Current value: "
[node name="CurrentValueLabel" type="Label" parent="VBoxContainer/ValueSetterContainer/HBoxContainer2"]
unique_name_in_owner = true
layout_mode = 2
[node name="Button" type="Button" parent="VBoxContainer/ValueSetterContainer"]
layout_mode = 2
text = "Select"
================================================
FILE: demo/addons/fmod/tool/ui/TestFmodBankExplorer.tscn
================================================
[gd_scene load_steps=2 format=3 uid="uid://f4i35731qm63"]
[ext_resource type="PackedScene" uid="uid://nr38urn226al" path="res://addons/fmod/tool/ui/FmodBankExplorer.tscn" id="1_0ul6h"]
[node name="TestFmodBankExplorer" type="Node2D"]
[node name="FmodBankLoader" type="FmodBankLoader" parent="."]
bank_paths = ["res://assets/Banks/Master.strings.bank", "res://assets/Banks/Master.bank", "res://assets/Banks/Music.bank", "res://assets/Banks/Vehicles.bank"]
[node name="FmodBankExplorer" parent="FmodBankLoader" instance=ExtResource("1_0ul6h")]
initial_position = 0
position = Vector2i(0, 36)
================================================
FILE: demo/addons/gut/GutScene.gd
================================================
extends Node2D
# ##############################################################################
# This is a wrapper around the normal and compact gui controls and serves as
# the interface between gut.gd and the gui. The GutRunner creates an instance
# of this and then this takes care of managing the different GUI controls.
# ##############################################################################
@onready var _normal_gui = $Normal
@onready var _compact_gui = $Compact
var gut = null :
set(val):
gut = val
_set_gut(val)
func _ready():
_normal_gui.switch_modes.connect(use_compact_mode.bind(true))
_compact_gui.switch_modes.connect(use_compact_mode.bind(false))
_normal_gui.set_title("GUT")
_compact_gui.set_title("GUT")
_normal_gui.align_right()
_compact_gui.to_bottom_right()
use_compact_mode(false)
if(get_parent() == get_tree().root):
_test_running_setup()
func _test_running_setup():
set_font_size(100)
_normal_gui.get_textbox().text = "hello world, how are you doing?"
# ------------------------
# Private
# ------------------------
func _set_gut(val):
if(_normal_gui.get_gut() == val):
return
_normal_gui.set_gut(val)
_compact_gui.set_gut(val)
val.start_run.connect(_on_gut_start_run)
val.end_run.connect(_on_gut_end_run)
val.start_pause_before_teardown.connect(_on_gut_pause)
val.end_pause_before_teardown.connect(_on_pause_end)
func _set_both_titles(text):
_normal_gui.set_title(text)
_compact_gui.set_title(text)
# ------------------------
# Events
# ------------------------
func _on_gut_start_run():
_set_both_titles('Running')
func _on_gut_end_run():
_set_both_titles('Finished')
func _on_gut_pause():
_set_both_titles('-- Paused --')
func _on_pause_end():
_set_both_titles('Running')
# ------------------------
# Public
# ------------------------
func get_textbox():
return _normal_gui.get_textbox()
func set_font_size(new_size):
var rtl = _normal_gui.get_textbox()
rtl.set('theme_override_font_sizes/bold_italics_font_size', new_size)
rtl.set('theme_override_font_sizes/bold_font_size', new_size)
rtl.set('theme_override_font_sizes/italics_font_size', new_size)
rtl.set('theme_override_font_sizes/normal_font_size', new_size)
func set_font(font_name):
_set_all_fonts_in_rtl(_normal_gui.get_textbox(), font_name)
func _set_font(rtl, font_name, custom_name):
if(font_name == null):
rtl.remove_theme_font_override(custom_name)
else:
var font_path = 'res://addons/gut/fonts/' + font_name + '.ttf'
if(FileAccess.file_exists(font_path)):
var dyn_font = FontFile.new()
dyn_font.load_dynamic_font('res://addons/gut/fonts/' + font_name + '.ttf')
rtl.add_theme_font_override(custom_name, dyn_font)
func _set_all_fonts_in_rtl(rtl, base_name):
if(base_name == 'Default'):
_set_font(rtl, null, 'normal_font')
_set_font(rtl, null, 'bold_font')
_set_font(rtl, null, 'italics_font')
_set_font(rtl, null, 'bold_italics_font')
else:
_set_font(rtl, base_name + '-Regular', 'normal_font')
_set_font(rtl, base_name + '-Bold', 'bold_font')
_set_font(rtl, base_name + '-Italic', 'italics_font')
_set_font(rtl, base_name + '-BoldItalic', 'bold_italics_font')
func set_default_font_color(color):
_normal_gui.get_textbox().set('custom_colors/default_color', color)
func set_background_color(color):
_normal_gui.set_bg_color(color)
func use_compact_mode(should=true):
_compact_gui.visible = should
_normal_gui.visible = !should
func set_opacity(val):
_normal_gui.modulate.a = val
_compact_gui.modulate.a = val
func set_title(text):
_set_both_titles(text)
================================================
FILE: demo/addons/gut/GutScene.gd.uid
================================================
uid://bw7tukh738kw1
================================================
FILE: demo/addons/gut/GutScene.tscn
================================================
[gd_scene load_steps=4 format=3 uid="uid://m28heqtswbuq"]
[ext_resource type="Script" uid="uid://bw7tukh738kw1" path="res://addons/gut/GutScene.gd" id="1_b4m8y"]
[ext_resource type="PackedScene" uid="uid://duxblir3vu8x7" path="res://addons/gut/gui/NormalGui.tscn" id="2_j6ywb"]
[ext_resource type="PackedScene" uid="uid://cnqqdfsn80ise" path="res://addons/gut/gui/MinGui.tscn" id="3_3glw1"]
[node name="GutScene" type="Node2D"]
script = ExtResource("1_b4m8y")
[node name="Normal" parent="." instance=ExtResource("2_j6ywb")]
[node name="Compact" parent="." instance=ExtResource("3_3glw1")]
offset_left = 5.0
offset_top = 273.0
offset_right = 265.0
offset_bottom = 403.0
================================================
FILE: demo/addons/gut/LICENSE.md
================================================
The MIT License (MIT)
=====================
Copyright (c) 2018 Tom "Butch" Wesley
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: demo/addons/gut/UserFileViewer.gd
================================================
extends Window
@onready var rtl = $TextDisplay/RichTextLabel
func _get_file_as_text(path):
var to_return = null
var f = FileAccess.open(path, FileAccess.READ)
if(f != null):
to_return = f.get_as_text()
else:
to_return = str('ERROR: Could not open file. Error code ', FileAccess.get_open_error())
return to_return
func _ready():
rtl.clear()
func _on_OpenFile_pressed():
$FileDialog.popup_centered()
func _on_FileDialog_file_selected(path):
show_file(path)
func _on_Close_pressed():
self.hide()
func show_file(path):
var text = _get_file_as_text(path)
if(text == ''):
text = '<Empty File>'
rtl.set_text(text)
self.window_title = path
func show_open():
self.popup_centered()
$FileDialog.popup_centered()
func get_rich_text_label():
return $TextDisplay/RichTextLabel
func _on_Home_pressed():
rtl.scroll_to_line(0)
func _on_End_pressed():
rtl.scroll_to_line(rtl.get_line_count() -1)
func _on_Copy_pressed():
return
# OS.clipboard = rtl.text
func _on_file_dialog_visibility_changed():
if rtl.text.length() == 0 and not $FileDialog.visible:
self.hide()
================================================
FILE: demo/addons/gut/UserFileViewer.gd.uid
================================================
uid://x51wilphva3d
================================================
FILE: demo/addons/gut/UserFileViewer.tscn
================================================
[gd_scene load_steps=2 format=3 uid="uid://bsm7wtt1gie4v"]
[ext_resource type="Script" uid="uid://x51wilphva3d" path="res://addons/gut/UserFileViewer.gd" id="1"]
[node name="UserFileViewer" type="Window"]
exclusive = true
script = ExtResource("1")
[node name="FileDialog" type="FileDialog" parent="."]
access = 1
show_hidden_files = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TextDisplay" type="ColorRect" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 8.0
offset_right = -10.0
offset_bottom = -65.0
color = Color(0.2, 0.188235, 0.188235, 1)
[node name="RichTextLabel" type="RichTextLabel" parent="TextDisplay"]
anchor_right = 1.0
anchor_bottom = 1.0
focus_mode = 2
text = "In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content. Lorem ipsum may be used before final copy is available, but it may also be used to temporarily replace copy in a process called greeking, which allows designers to consider form without the meaning of the text influencing the design.
Lorem ipsum is typically a corrupted version of De finibus bonorum et malorum, a first-century BCE text by the Roman statesman and philosopher Cicero, with words altered, added, and removed to make it nonsensical, improper Latin.
Versions of the Lorem ipsum text have been used in typesetting at least since the 1960s, when it was popularized by advertisements for Letraset transfer sheets. Lorem ipsum was introduced to the digital world in the mid-1980s when Aldus employed it in graphic and word-processing templates for its desktop publishing program PageMaker. Other popular word processors including Pages and Microsoft Word have since adopted Lorem ipsum as well."
selection_enabled = true
[node name="OpenFile" type="Button" parent="."]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -158.0
offset_top = -50.0
offset_right = -84.0
offset_bottom = -30.0
text = "Open File"
[node name="Home" type="Button" parent="."]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -478.0
offset_top = -50.0
offset_right = -404.0
offset_bottom = -30.0
text = "Home"
[node name="Copy" type="Button" parent="."]
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 160.0
offset_top = -50.0
offset_right = 234.0
offset_bottom = -30.0
text = "Copy"
[node name="End" type="Button" parent="."]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -318.0
offset_top = -50.0
offset_right = -244.0
offset_bottom = -30.0
text = "End"
[node name="Close" type="Button" parent="."]
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 10.0
offset_top = -50.0
offset_right = 80.0
offset_bottom = -30.0
text = "Close"
[connection signal="file_selected" from="FileDialog" to="." method="_on_FileDialog_file_selected"]
[connection signal="visibility_changed" from="FileDialog" to="." method="_on_file_dialog_visibility_changed"]
[connection signal="pressed" from="OpenFile" to="." method="_on_OpenFile_pressed"]
[connection signal="pressed" from="Home" to="." method="_on_Home_pressed"]
[connection signal="pressed" from="Copy" to="." method="_on_Copy_pressed"]
[connection signal="pressed" from="End" to="." method="_on_End_pressed"]
[connection signal="pressed" from="Close" to="." method="_on_Close_pressed"]
================================================
FILE: demo/addons/gut/autofree.gd
================================================
# ##############################################################################
#(G)odot (U)nit (T)est class
#
# ##############################################################################
# The MIT License (MIT)
# =====================
#
# Copyright (c) 2025 Tom "Butch" Wesley
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ##############################################################################
# Class used to keep track of objects to be freed and utilities to free them.
# ##############################################################################
var _to_free = []
var _to_queue_free = []
var _ref_counted_doubles = []
var _all_instance_ids = []
func _add_instance_id(thing):
if(thing.has_method("get_instance_id")):
_all_instance_ids.append(thing.get_instance_id())
func add_free(thing):
if(typeof(thing) == TYPE_OBJECT):
_add_instance_id(thing)
if(!thing is RefCounted):
_to_free.append(thing)
elif(GutUtils.is_double(thing)):
_ref_counted_doubles.append(thing)
func add_queue_free(thing):
if(typeof(thing) == TYPE_OBJECT):
_add_instance_id(thing)
_to_queue_free.append(thing)
func get_queue_free_count():
return _to_queue_free.size()
func get_free_count():
return _to_free.size()
func free_all():
for node in _to_free:
if(is_instance_valid(node)):
if(GutUtils.is_double(node)):
node.__gutdbl_done()
node.free()
_to_free.clear()
for i in range(_to_queue_free.size()):
if(is_instance_valid(_to_queue_free[i])):
_to_queue_free[i].queue_free()
_to_queue_free.clear()
for ref_dbl in _ref_counted_doubles:
ref_dbl.__gutdbl_done()
_ref_counted_doubles.clear()
_all_instance_ids.clear()
func has_instance_id(id):
return _all_instance_ids.has(id)
================================================
FILE: demo/addons/gut/autofree.gd.uid
================================================
uid://bxjfriqxgwe0r
================================================
FILE: demo/addons/gut/awaiter.gd
================================================
extends Node
class AwaitLogger:
var _time_waited = 0.0
var logger = GutUtils.get_logger()
var waiting_on = "nothing"
var logged_initial_message = false
var wait_log_delay := 1.0
var disabled = false
func waited(x):
_time_waited += x
if(!logged_initial_message and _time_waited >= wait_log_delay):
log_it()
logged_initial_message = true
func reset():
_time_waited = 0.0
logged_initial_message = false
func log_it():
if(!disabled):
var msg = str("--- Awaiting ", waiting_on, " ---")
logger.wait_msg(msg)
signal timeout
signal wait_started
var await_logger = AwaitLogger.new()
var _wait_time := 0.0
var _wait_process_frames := 0
var _wait_physics_frames := 0
var _signal_to_wait_on = null
var _predicate_method = null
var _waiting_for_predicate_to_be = null
var _predicate_time_between := 0.0
var _predicate_time_between_elpased := 0.0
var _elapsed_time := 0.0
var _elapsed_frames := 0
var _did_last_wait_timeout = false
var did_last_wait_timeout = false :
get: return _did_last_wait_timeout
set(val): push_error("Cannot set did_last_wait_timeout")
func _ready() -> void:
get_tree().process_frame.connect(_on_tree_process_frame)
get_tree().physics_frame.connect(_on_tree_physics_frame)
func _on_tree_process_frame():
# Count frames here instead of in _process so that tree order never
# makes a difference and the count/signaling happens outside of
# _process being called.
if(_wait_process_frames > 0):
_elapsed_frames += 1
if(_elapsed_frames > _wait_process_frames):
_end_wait()
func _on_tree_physics_frame():
# Count frames here instead of in _physics_process so that tree order never
# makes a difference and the count/signaling happens outside of
# _physics_process being called.
if(_wait_physics_frames != 0):
_elapsed_frames += 1
if(_elapsed_frames > _wait_physics_frames):
_end_wait()
func _physics_process(delta):
if(is_waiting()):
await_logger.waited(delta)
if(_wait_time != 0.0):
_elapsed_time += delta
if(_elapsed_time >= _wait_time):
_end_wait()
if(_predicate_method != null):
_predicate_time_between_elpased += delta
if(_predicate_time_between_elpased >= _predicate_time_between):
_predicate_time_between_elpased = 0.0
var result = _predicate_method.call()
if(_waiting_for_predicate_to_be == false):
if(typeof(result) != TYPE_BOOL or result != true):
_end_wait()
else:
if(typeof(result) == TYPE_BOOL and result == _waiting_for_predicate_to_be):
_end_wait()
func _end_wait():
await_logger.reset()
# Check for time before checking for frames so that the extra frames added
# when waiting on a signal do not cause a false negative for timing out.
if(_wait_time > 0):
_did_last_wait_timeout = _elapsed_time >= _wait_time
elif(_wait_physics_frames > 0):
_did_last_wait_timeout = _elapsed_frames >= _wait_physics_frames
elif(_wait_process_frames > 0):
_did_last_wait_timeout = _elapsed_frames >= _wait_process_frames
if(_signal_to_wait_on != null and \
is_instance_valid(_signal_to_wait_on.get_object()) and \
_signal_to_wait_on.is_connected(_signal_callback)):
_signal_to_wait_on.disconnect(_signal_callback)
_wait_process_frames = 0
_wait_time = 0.0
_wait_physics_frames = 0
_signal_to_wait_on = null
_predicate_method = null
_elapsed_time = 0.0
_elapsed_frames = 0
timeout.emit()
const ARG_NOT_SET = '_*_argument_*_is_*_not_set_*_'
func _signal_callback(
_arg1=ARG_NOT_SET, _arg2=ARG_NOT_SET, _arg3=ARG_NOT_SET,
_arg4=ARG_NOT_SET, _arg5=ARG_NOT_SET, _arg6=ARG_NOT_SET,
_arg7=ARG_NOT_SET, _arg8=ARG_NOT_SET, _arg9=ARG_NOT_SET):
_signal_to_wait_on.disconnect(_signal_callback)
# DO NOT _end_wait here. For other parts of the test to get the signal that
# was waited on, we have to wait for another frames. For example, the
# signal_watcher doesn't get the signal in time if we don't do this.
_wait_process_frames = 1
func wait_seconds(x, msg=''):
await_logger.waiting_on = str(x, " seconds ", msg)
_did_last_wait_timeout = false
_wait_time = x
wait_started.emit()
func wait_process_frames(x, msg=''):
await_logger.waiting_on = str(x, " idle frames ", msg)
_did_last_wait_timeout = false
_wait_process_frames = x
wait_started.emit()
func wait_physics_frames(x, msg=''):
await_logger.waiting_on = str(x, " physics frames ", msg)
_did_last_wait_timeout = false
_wait_physics_frames = x
wait_started.emit()
func wait_for_signal(the_signal : Signal, max_time, msg=''):
await_logger.waiting_on = str("signal ", the_signal.get_name(), " or ", max_time, "s ", msg)
_did_last_wait_timeout = false
the_signal.connect(_signal_callback)
_signal_to_wait_on = the_signal
_wait_time = max_time
wait_started.emit()
func wait_until(predicate_function: Callable, max_time, time_between_calls:=0.0, msg=''):
await_logger.waiting_on = str("callable to return TRUE or ", max_time, "s. ", msg)
_predicate_time_between = time_between_calls
_predicate_method = predicate_function
_wait_time = max_time
_waiting_for_predicate_to_be = true
_predicate_time_between_elpased = 0.0
_did_last_wait_timeout = false
wait_started.emit()
func wait_while(predicate_function: Callable, max_time, time_between_calls:=0.0, msg=''):
await_logger.waiting_on = str("callable to return FALSE or ", max_time, "s. ", msg)
_predicate_time_between = time_between_calls
_predicate_method = predicate_function
_wait_time = max_time
_waiting_for_predicate_to_be = false
_predicate_time_between_elpased = 0.0
_did_last_wait_timeout = false
wait_started.emit()
func is_waiting():
return _wait_time != 0.0 || \
_wait_physics_frames != 0 || \
_wait_process_frames != 0
================================================
FILE: demo/addons/gut/awaiter.gd.uid
================================================
uid://ccu4ww35edtdi
================================================
FILE: demo/addons/gut/cli/change_project_warnings.gd
================================================
extends SceneTree
var Optparse = load('res://addons/gut/cli/optparse.gd')
var WarningsManager = load("res://addons/gut/warnings_manager.gd")
const WARN_VALUE_PRINT_POSITION = 36
var godot_default_warnings = {
"assert_always_false": 1, "assert_always_true": 1, "confusable_identifier": 1,
"confusable_local_declaration": 1, "confusable_local_usage": 1, "constant_used_as_function": 1,
"deprecated_keyword": 1, "empty_file": 1, "enable": true,
"exclude_addons": true, "function_used_as_property": 1, "get_node_default_without_onready": 2,
"incompatible_ternary": 1, "inference_on_variant": 2, "inferred_declaration": 0,
"int_as_enum_without_cast": 1, "int_as_enum_without_match": 1, "integer_division": 1,
"narrowing_conversion": 1, "native_method_override": 2, "onready_with_export": 2,
"property_used_as_function": 1, "redundant_await": 1, "redundant_static_unload": 1,
"renamed_in_godot_4_hint": 1, "return_value_discarded": 0, "shadowed_global_identifier": 1,
"shadowed_variable": 1, "shadowed_variable_base_class": 1, "standalone_expression": 1,
"standalone_ternary": 1, "static_called_on_instance": 1, "unassigned_variable": 1,
"unassigned_variable_op_assign": 1, "unreachable_code": 1, "unreachable_pattern": 1,
"unsafe_call_argument": 0, "unsafe_cast": 0, "unsafe_method_access": 0,
"unsafe_property_access": 0, "unsafe_void_return": 1, "untyped_declaration": 0,
"unused_local_constant": 1, "unused_parameter": 1, "unused_private_class_variable": 1,
"unused_signal": 1, "unused_variable": 1
}
var gut_default_changes = {
"exclude_addons": false, "redundant_await": 0,
}
var warning_settings = {}
func _setup_warning_settings():
warning_settings["godot_default"] = godot_default_warnings
warning_settings["current"] = WarningsManager.create_warnings_dictionary_from_project_settings()
warning_settings["all_warn"] = WarningsManager.create_warn_all_warnings_dictionary()
var gut_default = godot_default_warnings.duplicate()
gut_default.merge(gut_default_changes, true)
warning_settings["gut_default"] = gut_default
func _warn_value_to_s(value):
var readable = str(value).capitalize()
if(typeof(value) == TYPE_INT):
readable = WarningsManager.WARNING_LOOKUP.get(value, str(readable, ' ???'))
readable = readable.capitalize()
return readable
func _human_readable(warnings):
var to_return = ""
for key in warnings:
var readable = _warn_value_to_s(warnings[key])
to_return += str(key.capitalize().rpad(35, ' '), readable, "\n")
return to_return
func _dump_settings(which):
if(warning_settings.has(which)):
GutUtils.pretty_print(warning_settings[which])
else:
print("UNKNOWN print option ", which)
func _print_settings(which):
if(warning_settings.has(which)):
print(_human_readable(warning_settings[which]))
else:
print("UNKNOWN print option ", which)
func _apply_settings(which):
if(!warning_settings.has(which)):
print("UNKNOWN set option ", which)
return
var pre_settings = warning_settings["current"]
var new_settings = warning_settings[which]
if(new_settings == pre_settings):
print("-- Settings are the same, no changes were made --")
return
WarningsManager.apply_warnings_dictionary(new_settings)
ProjectSettings.save()
print("-- Project Warning Settings have been updated --")
print(_diff_changes_text(pre_settings))
func _diff_text(w1, w2, diff_col_pad=10):
var to_return = ""
for key in w1:
var v1_text = _warn_value_to_s(w1[key])
var v2_text = _warn_value_to_s(w2[key])
var diff_text = v1_text
var prefix = " "
if(v1_text != v2_text):
var diff_prefix = " "
if(w1[key] > w2[key]):
diff_prefix = "-"
else:
diff_prefix = "+"
prefix = "* "
diff_text = str(v1_text.rpad(diff_col_pad, ' '), diff_prefix, v2_text)
to_return += str(str(prefix, key.capitalize()).rpad(WARN_VALUE_PRINT_POSITION, ' '), diff_text, "\n")
return to_return.rstrip("\n")
func _diff_changes_text(pre_settings):
var orig_diff_text = _diff_text(
pre_settings,
WarningsManager.create_warnings_dictionary_from_project_settings(),
0)
# these next two lines are fragile and brute force...enjoy
var diff_text = orig_diff_text.replace("-", " -> ")
diff_text = diff_text.replace("+", " -> ")
if(orig_diff_text == diff_text):
diff_text += "\n-- No changes were made --"
else:
diff_text += "\nChanges will not be visible in Godot until it is restarted.\n"
diff_text += "Even if it asks you to reload...Maybe. Probably."
return diff_text
func _diff(name_1, name_2):
if(warning_settings.has(name_1) and warning_settings.has(name_2)):
var c2_pad = name_1.length() + 2
var heading = str(" ".repeat(WARN_VALUE_PRINT_POSITION), name_1.rpad(c2_pad, ' '), name_2, "\n")
heading += str(
" ".repeat(WARN_VALUE_PRINT_POSITION),
"-".repeat(name_1.length()).rpad(c2_pad, " "),
"-".repeat(name_2.length()),
"\n")
var text = _diff_text(warning_settings[name_1], warning_settings[name_2], c2_pad)
print(heading)
print(text)
var diff_count = 0
for line in text.split("\n"):
if(!line.begins_with(" ")):
diff_count += 1
if(diff_count == 0):
print('-- [', name_1, "] and [", name_2, "] are the same --")
else:
print('-- There are ', diff_count, ' differences between [', name_1, "] and [", name_2, "] --")
else:
print("One or more unknown Warning Level Names:, [", name_1, "] [", name_2, "]")
func _set_settings(nvps):
var pre_settings = warning_settings["current"]
for i in range(nvps.size()/2):
var s_name = nvps[i * 2]
var s_value = nvps[i * 2 + 1]
if(godot_default_warnings.has(s_name)):
var t = typeof(godot_default_warnings[s_name])
if(t == TYPE_INT):
s_value = s_value.to_int()
elif(t == TYPE_BOOL):
s_value = s_value.to_lower() == 'true'
WarningsManager.set_project_setting_warning(s_name, s_value)
ProjectSettings.save()
print(_diff_changes_text(pre_settings))
func _setup_options():
var opts = Optparse.new()
opts.banner = """
This script prints info about or sets the warning settings for the project.
Each action requires one or more Warning Level Names.
Warning Level Names:
* current The current settings for the project.
* godot_default The default settings for Godot.
* gut_default The warning settings that is used when developing GUT.
* all_warn Everything set to warn.
""".dedent()
opts.add('-h', false, 'Print this help')
opts.add('-set', [], "Sets a single setting in the project settings and saves.\n" +
"Use -dump to see a list of setting names and values.\n" +
"Example: -set enabled,true -set unsafe_cast,2 -set unreachable_code,0")
opts.add_heading(" Actions (require Warning Level Name)")
opts.add('-diff', [], "Shows the difference between two Warning Level Names.\n" +
"Example: -diff current,all_warn")
opts.add('-dump', 'none', "Prints a dictionary of the warning values.")
opts.add('-print', 'none', "Print human readable warning values.")
opts.add('-apply', 'none', "Applys one of the Warning Level Names to the project settings. You should restart after using this")
return opts
func _print_help(opts):
opts.print_help()
func _init():
# Testing might set this flag but it should never be disabled for this tool
# or it cannot save project settings, but says it did. Sneakily use the
# private property to get around this property being read-only. Don't
# try this at home.
WarningsManager._disabled = false
_setup_warning_settings()
var opts = _setup_options()
opts.parse()
if(opts.unused.size() != 0):
opts.print_help()
print("Unknown arguments ", opts.unused)
if(opts.values.h):
opts.print_help()
elif(opts.values.print != 'none'):
_print_settings(opts.values.print)
elif(opts.values.dump != 'none'):
_dump_settings(opts.values.dump)
elif(opts.values.apply != 'none'):
_apply_settings(opts.values.apply )
elif(opts.values.diff.size() == 2):
_diff(opts.values.diff[0], opts.values.diff[1])
elif(opts.values.set.size() % 2 == 0):
_set_settings(opts.values.set)
else:
opts.print_help()
print("You didn't specify any options or too many or not the right size or something invalid. I don't know what you want to do.")
quit()
================================================
FILE: demo/addons/gut/cli/change_project_warnings.gd.uid
================================================
uid://1pauyfnd1cre
================================================
FILE: demo/addons/gut/cli/gut_cli.gd
================================================
extends Node
var Optparse = load('res://addons/gut/cli/optparse.gd')
var Gut = load('res://addons/gut/gut.gd')
var GutRunner = load('res://addons/gut/gui/GutRunner.tscn')
# ------------------------------------------------------------------------------
# Helper class to resolve the various different places where an option can
# be set. Using the get_value method will enforce the order of precedence of:
# 1. command line value
# 2. config file value
# 3. default value
#
# The idea is that you set the base_opts. That will get you a copies of the
# hash with null values for the other types of values. Lower precedented hashes
# will punch through null values of higher precedented hashes.
# ------------------------------------------------------------------------------
class OptionResolver:
var base_opts = {}
var cmd_opts = {}
var config_opts = {}
func get_value(key):
return _nvl(cmd_opts[key], _nvl(config_opts[key], base_opts[key]))
func set_base_opts(opts):
base_opts = opts
cmd_opts = _null_copy(opts)
config_opts = _null_copy(opts)
# creates a copy of a hash with all values null.
func _null_copy(h):
var new_hash = {}
for key in h:
new_hash[key] = null
return new_hash
func _nvl(a, b):
if(a == null):
return b
else:
return a
func _string_it(h):
var to_return = ''
for key in h:
to_return += str('(',key, ':', _nvl(h[key], 'NULL'), ')')
return to_return
func to_s():
return str("base:\n", _string_it(base_opts), "\n", \
"config:\n", _string_it(config_opts), "\n", \
"cmd:\n", _string_it(cmd_opts), "\n", \
"resolved:\n", _string_it(get_resolved_values()))
func get_resolved_values():
var to_return = {}
for key in base_opts:
to_return[key] = get_value(key)
return to_return
func to_s_verbose():
var to_return = ''
var resolved = get_resolved_values()
for key in base_opts:
to_return += str(key, "\n")
to_return += str(' default: ', _nvl(base_opts[key], 'NULL'), "\n")
to_return += str(' config: ', _nvl(config_opts[key], ' --'), "\n")
to_return += str(' cmd: ', _nvl(cmd_opts[key], ' --'), "\n")
to_return += str(' final: ', _nvl(resolved[key], 'NULL'), "\n")
return to_return
# ------------------------------------------------------------------------------
# Here starts the actual script that uses the Options class to kick off Gut
# and run your tests.
# ------------------------------------------------------------------------------
var _gut_config = load('res://addons/gut/gut_config.gd').new()
# array of command line options specified
var _final_opts = []
func setup_options(options, font_names):
var opts = Optparse.new()
opts.banner =\
"""
The GUT CLI
-----------
The default behavior for GUT is to load options from a res://.gutconfig.json if
it exists. Any options specified on the command line will take precedence over
options specified in the gutconfig file. You can specify a different gutconfig
file with the -gconfig option.
To generate a .gutconfig.json file you can use -gprint_gutconfig_sample
To see the effective values of a CLI command and a gutconfig use -gpo
Values for options can be supplied using:
option=value # no space around "="
option value # a space between option and value w/o =
Options whose values are lists/arrays can be specified multiple times:
-gdir=a,b
-gdir c,d
-gdir e
# results in -gdir equaling [a, b, c, d, e]
To not use an empty value instead of a default value, specifiy the option with
an immediate "=":
-gconfig=
"""
opts.add_heading("Test Config:")
opts.add('-gdir', options.dirs, 'List of directories to search for test scripts in.')
opts.add('-ginclude_subdirs', false, 'Flag to include all subdirectories specified with -gdir.')
opts.add('-gtest', [], 'List of full paths to test scripts to run.')
opts.add('-gprefix', options.prefix, 'Prefix used to find tests when specifying -gdir. Default "[default]".')
opts.add('-gsuffix', options.suffix, 'Test script suffix, including .gd extension. Default "[default]".')
opts.add('-gconfig', 'res://.gutconfig.json', 'The config file to load options from. The default is [default]. Use "-gconfig=" to not use a config file.')
opts.add('-gpre_run_script', '', 'pre-run hook script path')
opts.add('-gpost_run_script', '', 'post-run hook script path')
opts.add('-gerrors_do_not_cause_failure', false, 'When an internal GUT error occurs tests will fail. With this option set, that does not happen.')
opts.add('-gdouble_strategy', 'SCRIPT_ONLY', 'Default strategy to use when doubling. Valid values are [INCLUDE_NATIVE, SCRIPT_ONLY]. Default "[default]"')
opts.add_heading("Run Options:")
opts.add('-gselect', '', 'All scripts that contain the specified string in their filename will be ran')
opts.add('-ginner_class', '', 'Only run inner classes that contain the specified string in their name.')
opts.add('-gunit_test_name', '', 'Any test that contains the specified text will be run, all others will be skipped.')
opts.add('-gexit', false, 'Exit after running tests. If not specified you have to manually close the window.')
opts.add('-gexit_on_success', false, 'Only exit if zero tests fail.')
opts.add('-gignore_pause', false, 'Ignores any calls to pause_before_teardown.')
opts.add('-gno_error_tracking', false, 'Disable error tracking.')
opts.add('-gfailure_error_types', options.failure_error_types, 'Error types that will cause tests to fail if the are encountered during the execution of a test. Default "[default]"')
opts.add_heading("Display Settings:")
opts.add('-glog', options.log_level, 'Log level [0-3]. Default [default]')
opts.add('-ghide_orphans', false, 'Display orphan counts for tests and scripts. Default [default].')
opts.add('-gmaximize', false, 'Maximizes test runner window to fit the viewport.')
opts.add('-gcompact_mode', false, 'The runner will be in compact mode. This overrides -gmaximize.')
opts.add('-gopacity', options.opacity, 'Set opacity of test runner window. Use range 0 - 100. 0 = transparent, 100 = opaque.')
opts.add('-gdisable_colors', false, 'Disable command line colors.')
opts.add('-gfont_name', options.font_name, str('Valid values are: ', font_names, '. Default "[default]"'))
opts.add('-gfont_size', options.font_size, 'Font size, default "[default]"')
opts.add('-gbackground_color', options.background_color, 'Background color as an html color, default "[default]"')
opts.add('-gfont_color',options.font_color, 'Font color as an html color, default "[default]"')
opts.add('-gpaint_after', options.paint_after, 'Delay before GUT will add a 1 frame pause to paint the screen/GUI. default [default]')
opts.add('-gwait_log_delay', options.wait_log_delay, 'Delay before GUT will print a message to indicate a test is awaiting one of the wait_* methods. Default [default]')
opts.add_heading("Result Export:")
opts.add('-gjunit_xml_file', options.junit_xml_file, 'Export results of run to this file in the Junit XML format.')
opts.add('-gjunit_xml_timestamp', options.junit_xml_timestamp, 'Include a timestamp in the -gjunit_xml_file, default [default]')
opts.add_heading("Help:")
opts.add('-gh', false, 'Print this help. You did this to see this, so you probably understand.')
opts.add('-gpo', false, 'Print option values from all sources and the value used.')
opts.add('-gprint_gutconfig_sample', false, 'Print out json that can be used to make a gutconfig file.')
# run as in editor, for shelling out purposes through Editor.
var o = opts.add('-graie', false, 'do not use')
o.show_in_help = false
return opts
# Parses options, applying them to the _tester or setting values
# in the options struct.
func extract_command_line_options(from, to):
to.compact_mode = from.get_value_or_null('-gcompact_mode')
to.config_file = from.get_value_or_null('-gconfig')
to.dirs = from.get_value_or_null('-gdir')
to.disable_colors = from.get_value_or_null('-gdisable_colors')
to.double_strategy = from.get_value_or_null('-gdouble_strategy')
to.errors_do_not_cause_failure = from.get_value_or_null('-gerrors_do_not_cause_failure')
to.hide_orphans = from.get_value_or_null('-ghide_orphans')
to.ignore_pause = from.get_value_or_null('-gignore_pause')
to.include_subdirs = from.get_value_or_null('-ginclude_subdirs')
to.inner_class = from.get_value_or_null('-ginner_class')
to.log_level = from.get_value_or_null('-glog')
to.opacity = from.get_value_or_null('-gopacity')
to.post_run_script = from.get_value_or_null('-gpost_run_script')
to.pre_run_script = from.get_value_or_null('-gpre_run_script')
to.prefix = from.get_value_or_null('-gprefix')
to.selected = from.get_value_or_null('-gselect')
to.should_exit = from.get_value_or_null('-gexit')
to.should_exit_on_success = from.get_value_or_null('-gexit_on_success')
to.should_maximize = from.get_value_or_null('-gmaximize')
to.suffix = from.get_value_or_null('-gsuffix')
to.tests = from.get_value_or_null('-gtest')
to.unit_test_name = from.get_value_or_null('-gunit_test_name')
to.wait_log_delay = from.get_value_or_null('-gwait_log_delay')
to.background_color = from.get_value_or_null('-gbackground_color')
to.font_color = from.get_value_or_null('-gfont_color')
to.font_name = from.get_value_or_null('-gfont_name')
to.font_size = from.get_value_or_null('-gfont_size')
to.paint_after = from.get_value_or_null('-gpaint_after')
to.junit_xml_file = from.get_value_or_null('-gjunit_xml_file')
to.junit_xml_timestamp = from.get_value_or_null('-gjunit_xml_timestamp')
to.failure_error_types = from.get_value_or_null('-gfailure_error_types')
to.no_error_tracking = from.get_value_or_null('-gno_error_tracking')
to.raie = from.get_value_or_null('-graie')
func _print_gutconfigs(values):
var header = """Here is a sample of a full .gutconfig.json file.
You do not need to specify all values in your own file. The values supplied in
this sample are what would be used if you ran gut w/o the -gprint_gutconfig_sample
option. Option priority is: command-line, .gutconfig, default)."""
print("\n", header.replace("\n", ' '), "\n")
var resolved = values
# remove_at some options that don't make sense to be in config
resolved.erase("config_file")
resolved.erase("show_help")
print(JSON.stringify(resolved, ' '))
for key in resolved:
resolved[key] = null
print("\n\nAnd here's an empty config for you fill in what you want.")
print(JSON.stringify(resolved, ' '))
func _run_tests(opt_resolver):
_final_opts = opt_resolver.get_resolved_values();
_gut_config.options = _final_opts
var runner = GutRunner.instantiate()
runner.set_gut_config(_gut_config)
get_tree().root.add_child(runner)
if(opt_resolver.cmd_opts.raie):
runner.run_from_editor()
else:
runner.run_tests()
# parse options and run Gut
func main():
var opt_resolver = OptionResolver.new()
opt_resolver.set_base_opts(_gut_config.default_options)
var cli_opts = setup_options(_gut_config.default_options, _gut_config.valid_fonts)
cli_opts.parse()
var all_options_valid = cli_opts.unused.size() == 0
extract_command_line_options(cli_opts, opt_resolver.cmd_opts)
var config_path = opt_resolver.get_value('config_file')
var load_result = 1
# Checking for an empty config path allows us to not use a config file via
# the -gconfig_file option since using "-gconfig_file=" or -gconfig_file=''"
# will result in an empty string.
if(config_path != ''):
load_result = _gut_config.load_options_no_defaults(config_path)
# SHORTCIRCUIT
if(!all_options_valid):
print('Unknown arguments: ', cli_opts.unused)
get_tree().quit(1)
elif(load_result == -1):
print('Invalid gutconfig ', load_result)
get_tree().quit(1)
else:
opt_resolver.config_opts = _gut_config.options
if(cli_opts.get_value('-gh')):
print(GutUtils.version_numbers.get_version_text())
cli_opts.print_help()
get_tree().quit(0)
elif(cli_opts.get_value('-gpo')):
print('All config options and where they are specified. ' +
'The "final" value shows which value will actually be used ' +
'based on order of precedence (default < .gutconfig < cmd line).' + "\n")
print(opt_resolver.to_s_verbose())
get_tree().quit(0)
elif(cli_opts.get_value('-gprint_gutconfig_sample')):
_print_gutconfigs(opt_resolver.get_resolved_values())
get_tree().quit(0)
else:
_run_tests(opt_resolver)
# ##############################################################################
#(G)odot (U)nit (T)est class
#
# ##############################################################################
# The MIT License (MIT)
# =====================
#
# Copyright (c) 2025 Tom "Butch" Wesley
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ##############################################################################
================================================
FILE: demo/addons/gut/cli/gut_cli.gd.uid
================================================
uid://bhuudqinp4bth
================================================
FILE: demo/addons/gut/cli/optparse.gd
================================================
## Parses command line arguments, as one might expect.
##
## Parses command line arguments with a bunch of options including generating
## text that displays all the arguments your script accepts. This
## is included in the GUT ClassRef since it might be usable by others and is
## portable (everything it needs is in this one file).
## [br]
## This does alot, if you want to see it in action have a look at
## [url=https://github.com/bitwes/Gut/blob/main/scratch/optparse_example.gd]scratch/optparse_example.gd[/url]
## [codeblock lang=text]
##
## Godot Argument Lists
## -------------------------
## There are two sets of command line arguments that Godot populates:
## OS.get_cmdline_args
## OS.get_cmdline_user_args.
##
## OS.get_cmdline_args contains any arguments that are not used by the engine
## itself. This means options like --help and -d will never appear in this list
## since these are used by the engine. The one exception is the -s option which
## is always included as the first entry and the script path as the second.
## Optparse ignores these values for argument processing but can be accessed
## with my_optparse.options.script_option. This list does not contain any
## arguments that appear in OS.get_cmdline_user_args.
##
## OS.get_cmdline_user_args contains any arguments that appear on the command
## line AFTER " -- " or " ++ ". This list CAN contain options that the engine
## would otherwise use, and are ignored completely by the engine.
##
## The parse method, by default, includes arguments from OS.get_cmdline_args and
## OS.get_cmdline_user_args. You can optionally pass one of these to the parse
## method to limit which arguments are parsed. You can also conjure up your own
## array of arguments and pass that to parse.
##
## See Godot's documentation for get_cmdline_args and get_cmdline_user_args for
## more information.
##
##
## Adding Options
## --------------
## Use the following to add options to be parsed. These methods return the
## created Option instance. See that class above for more info. You can use
## the returned instance to get values, or use get_value/get_value_or_null.
## add("--name", "default", "Description goes here")
## add(["--name", "--aliases"], "default", "Description goes here")
## add_required(["--name", "--aliases"], "default", "Description goes here")
## add_positional("--name", "default", "Description goes here")
## add_positional_required("--name", "default", "Description goes here")
##
## get_value will return the value of the option or the default if it was not
## set. get_value_or_null will return the value of the option or null if it was
## not set.
##
## The Datatype for an option is determined from the default value supplied to
## the various add methods. Supported types are
## String
## Int
## Float
## Array of strings
## Boolean
##
##
## Value Parsing
## -------------
## optparse uses option_name_prefix to differentiate between option names and
## values. Any argument that starts with this value will be treated as an
## argument name. The default is "-". Set this before calling parse if you want
## to change it.
##
## Values for options can be supplied on the command line with or without an "=":
## option=value # no space around "="
## option value # a space between option and value w/o =
## There is no way to escape "=" at this time.
##
## Array options can be specified multiple times and/or set from a comma delimited
## list.
## -gdir=a,b
## -gdir c,d
## -gdir e
## Results in -gdir equaling [a, b, c, d, e]. There is no way to escape commas
## at this time.
##
## To specify an empty list via the command line follow the option with an equal
## sign
## -gdir=
##
## Boolean options will have thier value set to !default when they are supplied
## on the command line. Boolean options cannot have a value on the command line.
## They are either supplied or not.
##
## If a value is not an array and is specified multiple times on the command line
## then the last entry will be used as the value.
##
## Positional argument values are parsed after all named arguments are parsed.
## This means that other options can appear before, between, and after positional
## arguments.
## --foo=bar positional_0_value --disabled --bar foo positional_1_value --a_flag
##
## Anything that is not used by named or positional arguments will appear in the
## unused property. You can use this to detect unrecognized arguments or treat
## everything else provided as a list of things, or whatever you want. You can
## use is_option on the elements of unused (or whatever you want really) to see
## if optparse would treat it as an option name.
##
## Use get_missing_required_options to get an array of Option with all required
## options that were not found when parsing.
##
## The parsed_args property holds the list of arguments that were parsed.
##
##
## Help Generation
## ---------------
## You can call get_help to generate help text, or you can just call print_help
## and this will print it for you.
##
## Set the banner property to any text you want to appear before the usage and
## options sections.
##
## Options are printed in the order they are added. You can add a heading for
## different options sections with add_heading.
## add("--asdf", 1, "This will have no heading")
## add_heading("foo")
## add("--foo", false, "This will have the foo heading")
## add("--another_foo", 1.5, "This too.")
## add_heading("This is after foo")
## add("--bar", true, "You probably get it by now.")
##
## If you include "[default]" in the description of a option, then the help will
## substitue it with the default value.
## [/codeblock]
#-------------------------------------------------------------------------------
# Holds all the properties of a command line option
#
# value will return the default when it has not been set.
#-------------------------------------------------------------------------------
class Option:
var _has_been_set = false
var _value = null
# REMEMBER that when this option is an array, you have to set the value
# before you alter the contents of the array (append etc) or has_been_set
# will return false and it might not be used right. For example
# get_value_or_null will return null when you've actually changed the value.
var value = _value:
get:
return _value
set(val):
_has_been_set = true
_value = val
var option_name = ''
var default = null
var description = ''
var required = false
var aliases: Array[String] = []
var show_in_help = true
func _init(name,default_value,desc=''):
option_name = name
default = default_value
description = desc
_value = default
func wrap_text(text, left_indent, max_length, wiggle_room=15):
var line_indent = str("\n", " ".repeat(left_indent + 1))
var wrapped = ''
var position = 0
var split_length = max_length
while(position < text.length()):
if(position > 0):
wrapped += line_indent
var split_by = split_length
if(position + split_by + wiggle_room >= text.length()):
split_by = text.length() - position
else:
var min_space = text.rfind(' ', position + split_length)
var max_space = text.find(' ', position + split_length)
if(max_space <= position + split_length + wiggle_room):
split_by = max_space - position
else:
split_by = min_space - position
wrapped += text.substr(position, split_by).lstrip(' ')
if(position == 0):
split_length = max_length - left_indent
gitextract_oki6utj3/
├── .clang-format
├── .gitattributes
├── .github/
│ ├── actions/
│ │ ├── create-android-plugin/
│ │ │ └── action.yaml
│ │ └── create-native-build/
│ │ └── action.yaml
│ └── workflows/
│ ├── check_pr.yml
│ └── release.yml
├── .gitignore
├── .gitmodules
├── .readthedocs.yml
├── Android.mk
├── LICENSE
├── README.md
├── SConstruct
├── android-plugin/
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── library/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── utopiarise/
│ │ │ └── godot/
│ │ │ └── fmod/
│ │ │ └── android/
│ │ │ └── plugin/
│ │ │ └── FmodPlugin.kt
│ │ └── resources/
│ │ └── fmod-android-license.txt
│ └── settings.gradle.kts
├── demo/
│ ├── .gitattributes
│ ├── .gitignore
│ ├── .gutconfig.json
│ ├── addons/
│ │ ├── fmod/
│ │ │ ├── .gitignore
│ │ │ ├── FmodAndroidExportPlugin.gd
│ │ │ ├── FmodAndroidExportPlugin.gd.uid
│ │ │ ├── FmodManager.gd
│ │ │ ├── FmodManager.gd.uid
│ │ │ ├── FmodPlugin.gd
│ │ │ ├── FmodPlugin.gd.uid
│ │ │ ├── fmod.gdextension
│ │ │ ├── fmod.gdextension.uid
│ │ │ ├── icons/
│ │ │ │ ├── bank_icon.svg.import
│ │ │ │ ├── bus_icon.svg.import
│ │ │ │ ├── c_parameter_icon.svg.import
│ │ │ │ ├── d_parameter_icon.svg.import
│ │ │ │ ├── event_icon.svg.import
│ │ │ │ ├── fmod_emitter.png.import
│ │ │ │ ├── fmod_icon.svg.import
│ │ │ │ ├── snapshot_icon.svg.import
│ │ │ │ └── vca_icon.svg.import
│ │ │ ├── libs/
│ │ │ │ ├── android/
│ │ │ │ │ └── arm64/
│ │ │ │ │ └── CopyPast_Fmod_Libs_Here.txt
│ │ │ │ ├── iOS/
│ │ │ │ │ └── CopyPast_Fmod_Libs_Here.txt
│ │ │ │ ├── linux/
│ │ │ │ │ └── CopyPast_Fmod_Libs_Here.txt
│ │ │ │ ├── macos/
│ │ │ │ │ ├── CopyPast_Fmod_Libs_Here.txt
│ │ │ │ │ ├── libGodotFmod.macos.editor.framework/
│ │ │ │ │ │ └── Info.plist
│ │ │ │ │ ├── libGodotFmod.macos.template_debug.framework/
│ │ │ │ │ │ └── Info.plist
│ │ │ │ │ └── libGodotFmod.macos.template_release.framework/
│ │ │ │ │ └── Info.plist
│ │ │ │ └── windows/
│ │ │ │ └── CopyPast_Fmod_Libs_Here.txt
│ │ │ ├── plugin.cfg
│ │ │ └── tool/
│ │ │ ├── FmodBankDatabase.gd
│ │ │ ├── FmodBankDatabase.gd.uid
│ │ │ ├── inspectors/
│ │ │ │ ├── FmodBankLoaderPropertyInspectorPlugin.gd
│ │ │ │ ├── FmodBankLoaderPropertyInspectorPlugin.gd.uid
│ │ │ │ ├── FmodEmitterPropertyInspectorPlugin.gd
│ │ │ │ └── FmodEmitterPropertyInspectorPlugin.gd.uid
│ │ │ ├── performances/
│ │ │ │ ├── PerformancesDisplay.gd
│ │ │ │ └── PerformancesDisplay.gd.uid
│ │ │ ├── property_editors/
│ │ │ │ ├── FmodBankPathEditorProperty.gd
│ │ │ │ ├── FmodBankPathEditorProperty.gd.uid
│ │ │ │ ├── FmodBankPathsPropertyEditorUi.tscn
│ │ │ │ ├── FmodEventEditorProperty.gd
│ │ │ │ ├── FmodEventEditorProperty.gd.uid
│ │ │ │ ├── FmodEventEditorProperty.tscn
│ │ │ │ ├── FmodGuidAndPathPropertyEditorUi.gd
│ │ │ │ ├── FmodGuidAndPathPropertyEditorUi.gd.uid
│ │ │ │ ├── FmodGuidAndPathPropertyEditorUi.tscn
│ │ │ │ ├── FmodPathEditorProperty.gd
│ │ │ │ ├── FmodPathEditorProperty.gd.uid
│ │ │ │ └── FmodPathEditorProperty.tscn
│ │ │ └── ui/
│ │ │ ├── EventParametersDisplay.gd
│ │ │ ├── EventParametersDisplay.gd.uid
│ │ │ ├── EventParametersDisplay.tscn
│ │ │ ├── EventParametersWindow.tscn
│ │ │ ├── EventPlayControls.gd
│ │ │ ├── EventPlayControls.gd.uid
│ │ │ ├── FmodBankExplorer.gd
│ │ │ ├── FmodBankExplorer.gd.uid
│ │ │ ├── FmodBankExplorer.tscn
│ │ │ ├── ParameterDisplay.gd
│ │ │ ├── ParameterDisplay.gd.uid
│ │ │ ├── ParameterDisplay.tscn
│ │ │ └── TestFmodBankExplorer.tscn
│ │ └── gut/
│ │ ├── GutScene.gd
│ │ ├── GutScene.gd.uid
│ │ ├── GutScene.tscn
│ │ ├── LICENSE.md
│ │ ├── UserFileViewer.gd
│ │ ├── UserFileViewer.gd.uid
│ │ ├── UserFileViewer.tscn
│ │ ├── autofree.gd
│ │ ├── autofree.gd.uid
│ │ ├── awaiter.gd
│ │ ├── awaiter.gd.uid
│ │ ├── cli/
│ │ │ ├── change_project_warnings.gd
│ │ │ ├── change_project_warnings.gd.uid
│ │ │ ├── gut_cli.gd
│ │ │ ├── gut_cli.gd.uid
│ │ │ ├── optparse.gd
│ │ │ └── optparse.gd.uid
│ │ ├── collected_script.gd
│ │ ├── collected_script.gd.uid
│ │ ├── collected_test.gd
│ │ ├── collected_test.gd.uid
│ │ ├── comparator.gd
│ │ ├── comparator.gd.uid
│ │ ├── compare_result.gd
│ │ ├── compare_result.gd.uid
│ │ ├── diff_formatter.gd
│ │ ├── diff_formatter.gd.uid
│ │ ├── diff_tool.gd
│ │ ├── diff_tool.gd.uid
│ │ ├── double_templates/
│ │ │ ├── function_template.txt
│ │ │ ├── init_template.txt
│ │ │ └── script_template.txt
│ │ ├── double_tools.gd
│ │ ├── double_tools.gd.uid
│ │ ├── doubler.gd
│ │ ├── doubler.gd.uid
│ │ ├── dynamic_gdscript.gd
│ │ ├── dynamic_gdscript.gd.uid
│ │ ├── editor_caret_context_notifier.gd
│ │ ├── editor_caret_context_notifier.gd.uid
│ │ ├── error_tracker.gd
│ │ ├── error_tracker.gd.uid
│ │ ├── fonts/
│ │ │ └── OFL.txt
│ │ ├── gui/
│ │ │ ├── EditorRadioButton.tres
│ │ │ ├── GutBottomPanel.gd
│ │ │ ├── GutBottomPanel.gd.uid
│ │ │ ├── GutBottomPanel.tscn
│ │ │ ├── GutControl.gd
│ │ │ ├── GutControl.gd.uid
│ │ │ ├── GutControl.tscn
│ │ │ ├── GutEditorWindow.gd
│ │ │ ├── GutEditorWindow.gd.uid
│ │ │ ├── GutEditorWindow.tscn
│ │ │ ├── GutLogo.tscn
│ │ │ ├── GutRunner.gd
│ │ │ ├── GutRunner.gd.uid
│ │ │ ├── GutRunner.tscn
│ │ │ ├── GutSceneTheme.tres
│ │ │ ├── MinGui.tscn
│ │ │ ├── NormalGui.tscn
│ │ │ ├── OutputText.gd
│ │ │ ├── OutputText.gd.uid
│ │ │ ├── OutputText.tscn
│ │ │ ├── ResizeHandle.gd
│ │ │ ├── ResizeHandle.gd.uid
│ │ │ ├── ResizeHandle.tscn
│ │ │ ├── ResultsTree.gd
│ │ │ ├── ResultsTree.gd.uid
│ │ │ ├── ResultsTree.tscn
│ │ │ ├── RunAtCursor.gd
│ │ │ ├── RunAtCursor.gd.uid
│ │ │ ├── RunAtCursor.tscn
│ │ │ ├── RunExternally.gd
│ │ │ ├── RunExternally.gd.uid
│ │ │ ├── RunExternally.tscn
│ │ │ ├── RunResults.gd
│ │ │ ├── RunResults.gd.uid
│ │ │ ├── RunResults.tscn
│ │ │ ├── Settings.tscn
│ │ │ ├── ShellOutOptions.gd
│ │ │ ├── ShellOutOptions.gd.uid
│ │ │ ├── ShellOutOptions.tscn
│ │ │ ├── ShortcutButton.gd
│ │ │ ├── ShortcutButton.gd.uid
│ │ │ ├── ShortcutButton.tscn
│ │ │ ├── ShortcutDialog.gd
│ │ │ ├── ShortcutDialog.gd.uid
│ │ │ ├── ShortcutDialog.tscn
│ │ │ ├── about.gd
│ │ │ ├── about.gd.uid
│ │ │ ├── about.tscn
│ │ │ ├── editor_globals.gd
│ │ │ ├── editor_globals.gd.uid
│ │ │ ├── gut_config_gui.gd
│ │ │ ├── gut_config_gui.gd.uid
│ │ │ ├── gut_gui.gd
│ │ │ ├── gut_gui.gd.uid
│ │ │ ├── gut_logo.gd
│ │ │ ├── gut_logo.gd.uid
│ │ │ ├── gut_user_preferences.gd
│ │ │ ├── gut_user_preferences.gd.uid
│ │ │ ├── option_maker.gd
│ │ │ ├── option_maker.gd.uid
│ │ │ ├── panel_controls.gd
│ │ │ ├── panel_controls.gd.uid
│ │ │ ├── run_from_editor.gd
│ │ │ ├── run_from_editor.gd.uid
│ │ │ └── run_from_editor.tscn
│ │ ├── gut.gd
│ │ ├── gut.gd.uid
│ │ ├── gut_cmdln.gd
│ │ ├── gut_cmdln.gd.uid
│ │ ├── gut_config.gd
│ │ ├── gut_config.gd.uid
│ │ ├── gut_fonts.gd
│ │ ├── gut_fonts.gd.uid
│ │ ├── gut_loader.gd
│ │ ├── gut_loader.gd.uid
│ │ ├── gut_loader_the_scene.tscn
│ │ ├── gut_menu.gd
│ │ ├── gut_menu.gd.uid
│ │ ├── gut_plugin.gd
│ │ ├── gut_plugin.gd.uid
│ │ ├── gut_to_move.gd
│ │ ├── gut_to_move.gd.uid
│ │ ├── gut_tracked_error.gd
│ │ ├── gut_tracked_error.gd.uid
│ │ ├── gut_vscode_debugger.gd
│ │ ├── gut_vscode_debugger.gd.uid
│ │ ├── hook_script.gd
│ │ ├── hook_script.gd.uid
│ │ ├── inner_class_registry.gd
│ │ ├── inner_class_registry.gd.uid
│ │ ├── input_factory.gd
│ │ ├── input_factory.gd.uid
│ │ ├── input_sender.gd
│ │ ├── input_sender.gd.uid
│ │ ├── junit_xml_export.gd
│ │ ├── junit_xml_export.gd.uid
│ │ ├── lazy_loader.gd
│ │ ├── lazy_loader.gd.uid
│ │ ├── logger.gd
│ │ ├── logger.gd.uid
│ │ ├── menu_manager.gd.uid
│ │ ├── method_maker.gd
│ │ ├── method_maker.gd.uid
│ │ ├── one_to_many.gd
│ │ ├── one_to_many.gd.uid
│ │ ├── orphan_counter.gd
│ │ ├── orphan_counter.gd.uid
│ │ ├── parameter_factory.gd
│ │ ├── parameter_factory.gd.uid
│ │ ├── parameter_handler.gd
│ │ ├── parameter_handler.gd.uid
│ │ ├── plugin.cfg
│ │ ├── printers.gd
│ │ ├── printers.gd.uid
│ │ ├── result_exporter.gd
│ │ ├── result_exporter.gd.uid
│ │ ├── script_parser.gd
│ │ ├── script_parser.gd.uid
│ │ ├── signal_watcher.gd
│ │ ├── signal_watcher.gd.uid
│ │ ├── source_code_pro.fnt
│ │ ├── spy.gd
│ │ ├── spy.gd.uid
│ │ ├── strutils.gd
│ │ ├── strutils.gd.uid
│ │ ├── stub_params.gd
│ │ ├── stub_params.gd.uid
│ │ ├── stubber.gd
│ │ ├── stubber.gd.uid
│ │ ├── summary.gd
│ │ ├── summary.gd.uid
│ │ ├── test.gd
│ │ ├── test.gd.uid
│ │ ├── test_collector.gd
│ │ ├── test_collector.gd.uid
│ │ ├── thing_counter.gd
│ │ ├── thing_counter.gd.uid
│ │ ├── utils.gd
│ │ ├── utils.gd.uid
│ │ ├── version_conversion.gd
│ │ ├── version_conversion.gd.uid
│ │ ├── version_numbers.gd
│ │ ├── version_numbers.gd.uid
│ │ ├── warnings_manager.gd
│ │ └── warnings_manager.gd.uid
│ ├── appstore.png.import
│ ├── assets/
│ │ ├── Banks/
│ │ │ ├── Dialogue_CN.bank
│ │ │ ├── Dialogue_EN.bank
│ │ │ ├── Dialogue_JP.bank
│ │ │ ├── Master.bank
│ │ │ ├── Master.strings.bank
│ │ │ ├── Music.bank
│ │ │ ├── SFX.bank
│ │ │ └── Vehicles.bank
│ │ ├── Music/
│ │ │ ├── License.txt
│ │ │ ├── jingles_SAX07.ogg
│ │ │ └── jingles_SAX07.ogg.import
│ │ └── Sounds/
│ │ ├── beltHandle1.ogg
│ │ ├── beltHandle1.ogg.import
│ │ ├── beltHandle2.ogg
│ │ ├── beltHandle2.ogg.import
│ │ ├── bookClose.ogg
│ │ ├── bookClose.ogg.import
│ │ ├── bookFlip1.ogg
│ │ ├── bookFlip1.ogg.import
│ │ ├── bookFlip2.ogg
│ │ ├── bookFlip2.ogg.import
│ │ ├── bookFlip3.ogg
│ │ ├── bookFlip3.ogg.import
│ │ ├── bookOpen.ogg
│ │ ├── bookOpen.ogg.import
│ │ ├── bookPlace1.ogg
│ │ ├── bookPlace1.ogg.import
│ │ ├── bookPlace2.ogg
│ │ ├── bookPlace2.ogg.import
│ │ ├── bookPlace3.ogg
│ │ ├── bookPlace3.ogg.import
│ │ ├── chop.ogg
│ │ ├── chop.ogg.import
│ │ ├── cloth1.ogg
│ │ ├── cloth1.ogg.import
│ │ ├── cloth2.ogg
│ │ ├── cloth2.ogg.import
│ │ ├── cloth3.ogg
│ │ ├── cloth3.ogg.import
│ │ ├── cloth4.ogg
│ │ ├── cloth4.ogg.import
│ │ ├── clothBelt.ogg
│ │ ├── clothBelt.ogg.import
│ │ ├── clothBelt2.ogg
│ │ ├── clothBelt2.ogg.import
│ │ ├── creak1.ogg
│ │ ├── creak1.ogg.import
│ │ ├── creak2.ogg
│ │ ├── creak2.ogg.import
│ │ ├── creak3.ogg
│ │ ├── creak3.ogg.import
│ │ ├── doorClose_1.ogg
│ │ ├── doorClose_1.ogg.import
│ │ ├── doorClose_2.ogg
│ │ ├── doorClose_2.ogg.import
│ │ ├── doorClose_3.ogg
│ │ ├── doorClose_3.ogg.import
│ │ ├── doorClose_4.ogg
│ │ ├── doorClose_4.ogg.import
│ │ ├── doorOpen_1.ogg
│ │ ├── doorOpen_1.ogg.import
│ │ ├── doorOpen_2.ogg
│ │ ├── doorOpen_2.ogg.import
│ │ ├── drawKnife1.ogg
│ │ ├── drawKnife1.ogg.import
│ │ ├── drawKnife2.ogg
│ │ ├── drawKnife2.ogg.import
│ │ ├── drawKnife3.ogg
│ │ ├── drawKnife3.ogg.import
│ │ ├── dropLeather.ogg
│ │ ├── dropLeather.ogg.import
│ │ ├── footstep00.ogg
│ │ ├── footstep00.ogg.import
│ │ ├── footstep01.ogg
│ │ ├── footstep01.ogg.import
│ │ ├── footstep02.ogg
│ │ ├── footstep02.ogg.import
│ │ ├── footstep03.ogg
│ │ ├── footstep03.ogg.import
│ │ ├── footstep04.ogg
│ │ ├── footstep04.ogg.import
│ │ ├── footstep05.ogg
│ │ ├── footstep05.ogg.import
│ │ ├── footstep06.ogg
│ │ ├── footstep06.ogg.import
│ │ ├── footstep07.ogg
│ │ ├── footstep07.ogg.import
│ │ ├── footstep08.ogg
│ │ ├── footstep08.ogg.import
│ │ ├── footstep09.ogg
│ │ ├── footstep09.ogg.import
│ │ ├── handleCoins.ogg
│ │ ├── handleCoins.ogg.import
│ │ ├── handleCoins2.ogg
│ │ ├── handleCoins2.ogg.import
│ │ ├── handleSmallLeather.ogg
│ │ ├── handleSmallLeather.ogg.import
│ │ ├── handleSmallLeather2.ogg
│ │ ├── handleSmallLeather2.ogg.import
│ │ ├── knifeSlice.ogg
│ │ ├── knifeSlice.ogg.import
│ │ ├── knifeSlice2.ogg
│ │ ├── knifeSlice2.ogg.import
│ │ ├── licence.txt
│ │ ├── metalClick.ogg
│ │ ├── metalClick.ogg.import
│ │ ├── metalLatch.ogg
│ │ ├── metalLatch.ogg.import
│ │ ├── metalPot1.ogg
│ │ ├── metalPot1.ogg.import
│ │ ├── metalPot2.ogg
│ │ ├── metalPot2.ogg.import
│ │ ├── metalPot3.ogg
│ │ └── metalPot3.ogg.import
│ ├── default_env.tres
│ ├── export_presets.cfg
│ ├── high_level_2D/
│ │ ├── ChangeColor.gd
│ │ ├── ChangeColor.gd.uid
│ │ ├── ChooseLanguageButton.gd
│ │ ├── ChooseLanguageButton.gd.uid
│ │ ├── Emitter.gd
│ │ ├── Emitter.gd.uid
│ │ ├── FmodNodesTest.tscn
│ │ ├── Kinematic.gd
│ │ ├── Kinematic.gd.uid
│ │ ├── SayWelcomeButton.gd
│ │ ├── SayWelcomeButton.gd.uid
│ │ ├── footstep.tscn
│ │ ├── sin_move.gd
│ │ └── sin_move.gd.uid
│ ├── high_level_3D/
│ │ ├── FPSCounter.gd
│ │ ├── FPSCounter.gd.uid
│ │ ├── World.tscn
│ │ ├── environment/
│ │ │ ├── 1x1.png.import
│ │ │ ├── Ball.tscn
│ │ │ ├── Floor.tscn
│ │ │ ├── Wall.tscn
│ │ │ ├── ball_material.tres
│ │ │ ├── box.tscn
│ │ │ ├── sin_move.gd
│ │ │ ├── sin_move.gd.uid
│ │ │ ├── soundcollider.gd
│ │ │ ├── soundcollider.gd.uid
│ │ │ └── wall_material.tres
│ │ ├── player/
│ │ │ ├── Camera.gd
│ │ │ ├── Camera.gd.uid
│ │ │ ├── Player.gd
│ │ │ ├── Player.gd.uid
│ │ │ └── Player.tscn
│ │ ├── rollingball.gd
│ │ ├── rollingball.gd.uid
│ │ ├── selfdestroy.gd
│ │ └── selfdestroy.gd.uid
│ ├── icon.png.import
│ ├── icon.svg.import
│ ├── low_level_2D/
│ │ ├── ChangeColor.gd
│ │ ├── ChangeColor.gd.uid
│ │ ├── Emitter.gd
│ │ ├── Emitter.gd.uid
│ │ ├── EnterAndLeave.gd
│ │ ├── EnterAndLeave.gd.uid
│ │ ├── EnterandLeave2.gd
│ │ ├── EnterandLeave2.gd.uid
│ │ ├── FmodScriptTest.tscn
│ │ ├── FmodTest.gd
│ │ ├── FmodTest.gd.uid
│ │ ├── LangChooseButton.gd
│ │ ├── LangChooseButton.gd.uid
│ │ ├── Listener.gd
│ │ ├── Listener.gd.uid
│ │ ├── Listener2.gd
│ │ ├── Listener2.gd.uid
│ │ ├── WelcomeButton.gd
│ │ └── WelcomeButton.gd.uid
│ ├── project.godot
│ ├── run_tests.sh
│ └── test/
│ ├── integration/
│ │ └── init
│ ├── tests.tscn
│ └── unit/
│ ├── test_bank.gd
│ ├── test_bank.gd.uid
│ ├── test_bus.gd
│ ├── test_bus.gd.uid
│ ├── test_callbacks.gd
│ ├── test_callbacks.gd.uid
│ ├── test_desc_event.gd
│ ├── test_desc_event.gd.uid
│ ├── test_event.gd
│ ├── test_event.gd.uid
│ ├── test_global.gd
│ ├── test_global.gd.uid
│ ├── test_listener.gd
│ ├── test_listener.gd.uid
│ ├── test_sound.gd
│ ├── test_sound.gd.uid
│ ├── test_vca.gd
│ └── test_vca.gd.uid
├── docs/
│ ├── .gitignore
│ ├── build.sh
│ ├── mkdocs.yml
│ ├── requirements.txt
│ ├── run.sh
│ └── src/
│ └── doc/
│ ├── advanced/
│ │ └── 1-compiling.md
│ ├── index.md
│ └── user-guide/
│ ├── 1-install.md
│ ├── 2-initialization.md
│ ├── 3-using-fmod-plugin.md
│ ├── 4-loading-banks.md
│ ├── 5-playing-events.md
│ ├── 6-listeners.md
│ ├── 7-playing-sounds.md
│ ├── 8-other-low-level-examples.md
│ └── 9-plugins.md
├── get_fmod.py
├── jni/
│ └── Application.mk
└── src/
├── callback/
│ ├── event_callbacks.cpp
│ ├── event_callbacks.h
│ ├── file_callbacks.cpp
│ └── file_callbacks.h
├── constants.h
├── core/
│ ├── fmod_file.cpp
│ ├── fmod_file.h
│ ├── fmod_sound.cpp
│ └── fmod_sound.h
├── data/
│ ├── performance_data.cpp
│ └── performance_data.h
├── fmod_cache.cpp
├── fmod_cache.h
├── fmod_logging.cpp
├── fmod_logging.h
├── fmod_server.cpp
├── fmod_server.h
├── fmod_string_names.cpp
├── fmod_string_names.h
├── helpers/
│ ├── common.h
│ ├── constants.h
│ ├── current_function.h
│ ├── files.h
│ └── maths.h
├── nodes/
│ ├── fmod_bank_loader.cpp
│ ├── fmod_bank_loader.h
│ ├── fmod_event_emitter.h
│ ├── fmod_event_emitter_2d.cpp
│ ├── fmod_event_emitter_2d.h
│ ├── fmod_event_emitter_3d.cpp
│ ├── fmod_event_emitter_3d.h
│ ├── fmod_listener.h
│ ├── fmod_listener_2d.cpp
│ ├── fmod_listener_2d.h
│ ├── fmod_listener_3d.cpp
│ └── fmod_listener_3d.h
├── plugins/
│ ├── ios_plugins_loader.h
│ └── plugins_helper.h
├── register_types.cpp
├── register_types.h
├── resources/
│ ├── fmod_dsp_settings.cpp
│ ├── fmod_dsp_settings.h
│ ├── fmod_logging_settings.cpp
│ ├── fmod_logging_settings.h
│ ├── fmod_plugins_settings.cpp
│ ├── fmod_plugins_settings.h
│ ├── fmod_settings.cpp
│ ├── fmod_settings.h
│ ├── fmod_software_format_settings.cpp
│ ├── fmod_software_format_settings.h
│ ├── fmod_sound_3d_settings.cpp
│ └── fmod_sound_3d_settings.h
├── studio/
│ ├── fmod_bank.cpp
│ ├── fmod_bank.h
│ ├── fmod_bus.cpp
│ ├── fmod_bus.h
│ ├── fmod_event.cpp
│ ├── fmod_event.h
│ ├── fmod_event_description.cpp
│ ├── fmod_event_description.h
│ ├── fmod_parameter_description.cpp
│ ├── fmod_parameter_description.h
│ ├── fmod_vca.cpp
│ └── fmod_vca.h
└── tools/
├── fmod_editor_export_plugin.cpp
├── fmod_editor_export_plugin.h
├── fmod_editor_plugin.cpp
└── fmod_editor_plugin.h
SYMBOL INDEX (126 symbols across 51 files)
FILE: src/callback/event_callbacks.cpp
type Callbacks (line 10) | namespace Callbacks {
function FMOD_RESULT (line 12) | FMOD_RESULT F_CALL event_callback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type...
FILE: src/callback/event_callbacks.h
function namespace (line 7) | namespace Callbacks {
FILE: src/callback/file_callbacks.cpp
type Callbacks (line 3) | namespace Callbacks {
function GodotFileRunner (line 5) | GodotFileRunner* GodotFileRunner::get_singleton() {
function FMOD_RESULT (line 24) | FMOD_RESULT GodotFileRunner::cancelReadRequest(FMOD_ASYNCREADINFO* req...
function FMOD_RESULT (line 104) | FMOD_RESULT F_CALL godotFileOpen(const char* name, unsigned int* files...
function FMOD_RESULT (line 116) | FMOD_RESULT F_CALL godotFileClose(void* handle, void* userdata) {
function FMOD_RESULT (line 122) | FMOD_RESULT F_CALL godotSyncRead(FMOD_ASYNCREADINFO* info, void* userd...
function FMOD_RESULT (line 136) | FMOD_RESULT F_CALL godotSyncCancel(FMOD_ASYNCREADINFO* info, void* use...
FILE: src/callback/file_callbacks.h
function namespace (line 13) | namespace Callbacks {
FILE: src/core/fmod_file.h
function namespace (line 7) | namespace godot {
FILE: src/core/fmod_sound.h
function namespace (line 7) | namespace godot {
FILE: src/data/performance_data.h
function namespace (line 6) | namespace godot {
FILE: src/fmod_cache.cpp
function FMOD_GUID (line 254) | FMOD_GUID FmodCache::get_event_guid(const String& event_path) {
function String (line 262) | String FmodCache::get_event_path(const FMOD_GUID& guid) {
FILE: src/fmod_cache.h
function namespace (line 12) | namespace godot {
FILE: src/fmod_logging.cpp
type godot (line 10) | namespace godot {
function logging_init (line 13) | void logging_init() {
function log_fmod_message (line 57) | void log_fmod_message(FMODLogLevel level, const String& message) {
function FMOD_RESULT (line 76) | FMOD_RESULT fmod_debug_callback(FMOD_DEBUG_FLAGS flags, const char* fi...
FILE: src/fmod_logging.h
function namespace (line 9) | namespace godot {
FILE: src/fmod_server.cpp
function FmodServer (line 163) | FmodServer* FmodServer::get_singleton() {
function Transform3D (line 382) | Transform3D FmodServer::get_listener_transform3d(int index) {
function Transform2D (line 394) | Transform2D FmodServer::get_listener_transform2d(int index) {
function Vector3 (line 406) | Vector3 FmodServer::get_listener_3d_velocity(int index) {
function Vector2 (line 418) | Vector2 FmodServer::get_listener_2d_velocity(int index) {
function Object (line 465) | Object* FmodServer::get_object_attached_to_listener(const int index) {
function register_ios_dsp (line 515) | uint32_t register_ios_dsp(FMOD_SYSTEM_PTR system, FMOD_DSP_DESCRIPTION* ...
function register_ios_codec (line 519) | uint32_t register_ios_codec(FMOD_SYSTEM_PTR system, FMOD_CODEC_DESCRIPTI...
function register_ios_output (line 523) | uint32_t register_ios_output(FMOD_SYSTEM_PTR system, FMOD_OUTPUT_DESCRIP...
function FMOD_GUID (line 625) | FMOD_GUID FmodServer::get_event_guid_internal(const String& event_path) {
function String (line 629) | String FmodServer::get_event_guid(const String& event_path) {
function String (line 633) | String FmodServer::get_event_path_internal(const FMOD_GUID& guid) {
function String (line 637) | String FmodServer::get_event_path(const String& guid) {
function Array (line 641) | Array FmodServer::get_all_vca() {
function Array (line 649) | Array FmodServer::get_all_buses() {
function Array (line 657) | Array FmodServer::get_all_event_descriptions() {
function Array (line 665) | Array FmodServer::get_all_banks() {
function FMOD_STUDIO_SOUND_INFO (line 896) | FMOD_STUDIO_SOUND_INFO FmodServer::get_sound_info(const String& sound_ke...
function Array (line 928) | Array FmodServer::get_available_drivers() {
function Dictionary (line 1040) | Dictionary FmodServer::get_global_parameter_desc_by_name(const String& p...
function Dictionary (line 1059) | Dictionary FmodServer::get_global_parameter_desc_by_id(uint64_t paramete...
function Array (line 1083) | Array FmodServer::get_global_parameter_desc_list() {
FILE: src/fmod_server.h
type OneShot (line 39) | struct OneShot {
type Listener (line 44) | struct Listener {
type Callback (line 50) | struct Callback {
function class (line 56) | class FmodServer : public Object {
FILE: src/fmod_string_names.cpp
function FmodStringNames (line 16) | FmodStringNames* FmodStringNames::get_instance() {
FILE: src/fmod_string_names.h
function class (line 10) | class FmodStringNames {
FILE: src/helpers/common.h
function Node (line 103) | Node* node {nullptr};
function FMOD_GUID (line 144) | static inline FMOD_GUID string_to_fmod_guid(const char* guid) {
function String (line 154) | static inline String fmod_guid_to_string(const FMOD_GUID& guid) {
function fmod_parameter_id_to_ulong (line 163) | static inline uint64_t fmod_parameter_id_to_ulong(const FMOD_STUDIO_PARA...
FILE: src/helpers/current_function.h
function namespace (line 22) | namespace boost {
FILE: src/helpers/files.h
function namespace (line 7) | namespace godot {
FILE: src/helpers/maths.h
function namespace (line 11) | namespace godot {
FILE: src/nodes/fmod_bank_loader.cpp
function Array (line 27) | const Array& FmodBankLoader::get_bank_paths() const {
FILE: src/nodes/fmod_bank_loader.h
function namespace (line 7) | namespace godot {
FILE: src/nodes/fmod_event_emitter.h
function namespace (line 20) | namespace godot {
function Parameter (line 283) | Parameter* parameter {_find_parameter(p_name)};
function Parameter (line 309) | Parameter* parameter {_find_parameter(p_id)};
function FMOD_GUID (line 442) | FMOD_GUID event_guid {FmodServer::get_singleton()->get_event_guid_intern...
function FMOD_GUID (line 461) | FMOD_GUID event_guid {string_to_fmod_guid(guid.utf8().get_data())};
function should_load_by_name (line 617) | bool should_load_by_name {ProjectSettings::get_singleton()->get_setting(
function String (line 630) | const String& parameter_name {parts[0]};
function PackedStringArray (line 682) | PackedStringArray parts {p_name.trim_prefix(vformat("%s/", FmodStringNam...
function PackedStringArray (line 717) | PackedStringArray parts {p_name.trim_prefix(vformat("%s/", FmodStringNam...
function Parameter (line 731) | Parameter* parameter {_find_parameter(parts[0])}
function parameter_min_value (line 766) | const float parameter_min_value {parameter_description->get_minimum()};
function Parameter (line 837) | const Parameter& parameter {_parameters[i]};
FILE: src/nodes/fmod_event_emitter_2d.h
function namespace (line 9) | namespace godot {
FILE: src/nodes/fmod_event_emitter_3d.h
function namespace (line 8) | namespace godot {
FILE: src/nodes/fmod_listener.h
function namespace (line 8) | namespace godot {
FILE: src/nodes/fmod_listener_2d.h
function namespace (line 8) | namespace godot {
FILE: src/nodes/fmod_listener_3d.h
function namespace (line 8) | namespace godot {
FILE: src/plugins/ios_plugins_loader.h
type FMOD_IOS_INTERFACE (line 11) | typedef struct {
FILE: src/plugins/plugins_helper.h
function String (line 9) | static String get_fmod_plugins_base_path(const Ref<FmodPluginsSettings>&...
function String (line 24) | static String get_plugins_os_directory(const Ref<FmodPluginsSettings>& p...
FILE: src/register_types.cpp
function initialize_fmod_with_settings (line 35) | void initialize_fmod_with_settings() {
function initialize_fmod (line 50) | void initialize_fmod() {
function initialize_fmod_module (line 68) | void initialize_fmod_module(ModuleInitializationLevel p_level) {
function uninitialize_fmod_module (line 122) | void uninitialize_fmod_module(ModuleInitializationLevel p_level) {
function GDExtensionBool (line 139) | GDExtensionBool GDE_EXPORT
FILE: src/resources/fmod_dsp_settings.h
function namespace (line 6) | namespace godot {
FILE: src/resources/fmod_logging_settings.cpp
function String (line 53) | const String& FmodLoggingSettings::get_log_file_path() const {
FILE: src/resources/fmod_logging_settings.h
type DebugLevel (line 14) | enum DebugLevel {
FILE: src/resources/fmod_plugins_settings.cpp
function String (line 17) | const String& FmodPluginsSettings::get_plugins_base_path() const {
function PackedStringArray (line 25) | const PackedStringArray& FmodPluginsSettings::get_dynamic_plugin_list() ...
function Array (line 105) | const Array& FmodPluginsSettings::get_static_plugins_methods() const {
function String (line 121) | const String& FmodStaticPluginMethod::get_method_name() const {
FILE: src/resources/fmod_plugins_settings.h
type Type (line 12) | enum Type {
FILE: src/resources/fmod_settings.cpp
function String (line 45) | const String& FmodGeneralSettings::get_banks_path() const {
FILE: src/resources/fmod_settings.h
function namespace (line 8) | namespace godot {
FILE: src/resources/fmod_software_format_settings.h
function namespace (line 8) | namespace godot {
FILE: src/resources/fmod_sound_3d_settings.h
function namespace (line 6) | namespace godot {
FILE: src/studio/fmod_bank.cpp
function Array (line 48) | Array FmodBank::get_description_list() const {
function Array (line 56) | Array FmodBank::get_bus_list() const {
function Array (line 64) | Array FmodBank::get_vca_list() const {
function String (line 153) | const String& FmodBank::get_godot_res_path() const {
FILE: src/studio/fmod_bank.h
function namespace (line 11) | namespace godot {
FILE: src/studio/fmod_bus.h
function namespace (line 7) | namespace godot {
FILE: src/studio/fmod_event.cpp
function FMOD_STUDIO_PLAYBACK_STATE (line 122) | FMOD_STUDIO_PLAYBACK_STATE FmodEvent::get_playback_state() const {
function Transform2D (line 199) | Transform2D FmodEvent::get_2d_attributes() const {
function Transform3D (line 212) | Transform3D FmodEvent::get_3d_attributes() const {
function Callable (line 247) | const Callable& FmodEvent::get_callback() const {
function String (line 251) | const String& FmodEvent::get_programmers_callback_sound_key() const {
FILE: src/studio/fmod_event_description.cpp
function Array (line 59) | Array FmodEventDescription::get_instance_list() {
function Array (line 133) | Array FmodEventDescription::get_min_max_distance() {
function Array (line 187) | Array FmodEventDescription::get_parameters() const {
function String (line 195) | String FmodEventDescription::get_parameter_label_by_id(uint64_t id, int ...
function String (line 208) | String FmodEventDescription::get_parameter_label_by_name(const String& p...
function String (line 221) | String FmodEventDescription::get_parameter_label_by_index(int index, int...
function PackedStringArray (line 234) | PackedStringArray FmodEventDescription::get_parameter_labels_by_id(uint6...
function PackedStringArray (line 249) | PackedStringArray FmodEventDescription::get_parameter_labels_by_name(con...
function PackedStringArray (line 264) | PackedStringArray FmodEventDescription::get_parameter_labels_by_index(in...
function Dictionary (line 279) | Dictionary FmodEventDescription::get_user_property(const String& name) {
function Dictionary (line 304) | Dictionary FmodEventDescription::user_property_by_index(int index) {
FILE: src/studio/fmod_event_description.h
function namespace (line 9) | namespace godot {
FILE: src/studio/fmod_parameter_description.cpp
function String (line 7) | const String& FmodParameterDescription::get_name() const {
FILE: src/studio/fmod_parameter_description.h
function namespace (line 7) | namespace godot {
FILE: src/studio/fmod_vca.h
function namespace (line 8) | namespace godot {
FILE: src/tools/fmod_editor_export_plugin.cpp
function String (line 182) | String FmodEditorExportPlugin::_get_name() const {
function PackedStringArray (line 207) | PackedStringArray FmodEditorExportPlugin::_get_libraries_to_export(const...
FILE: src/tools/fmod_editor_export_plugin.h
function namespace (line 10) | namespace godot {
FILE: src/tools/fmod_editor_plugin.h
function namespace (line 11) | namespace godot {
Condensed preview — 560 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,305K chars).
[
{
"path": ".clang-format",
"chars": 3144,
"preview": "---\nBasedOnStyle: LLVM\nAccessModifierOffset: -4\nAlignAfterOpenBracket: BlockIndent\nAlignEscapedNewlines: Left\nAlignOpera"
},
{
"path": ".gitattributes",
"chars": 306,
"preview": "# Normalize EOL for all files that Git considers text files.\n* text=auto eol=lf\n\n# Ignore some files when exporting to a"
},
{
"path": ".github/actions/create-android-plugin/action.yaml",
"chars": 593,
"preview": "name: Create Fmod native build\ndescription: Creates fmod native build for a specific platform\nruns:\n using: composite\n "
},
{
"path": ".github/actions/create-native-build/action.yaml",
"chars": 4624,
"preview": "name: Create Fmod native build\ndescription: Creates fmod native build for a specific platform\ninputs:\n platform:\n de"
},
{
"path": ".github/workflows/check_pr.yml",
"chars": 7371,
"preview": "name: 🌈 Check Pull Request\non:\n pull_request:\n types: [opened, synchronize, reopened]\n pull_request_target:\n typ"
},
{
"path": ".github/workflows/release.yml",
"chars": 9907,
"preview": "name: 🌈 Release\non:\n push:\n tags:\n - '\\d+.\\d+.\\d+-\\d+.\\d+.\\d+'\n\n# Global Settings\nenv:\n GODOT_VERSION: 4.5\n N"
},
{
"path": ".gitignore",
"chars": 2584,
"preview": "\n# Created by https://www.gitignore.io/api/clion,cmake,scons\n# Edit at https://www.gitignore.io/?templates=clion,cmake,s"
},
{
"path": ".gitmodules",
"chars": 90,
"preview": "[submodule \"godot-cpp\"]\n\tpath = godot-cpp\n\turl = https://github.com/godotengine/godot-cpp\n"
},
{
"path": ".readthedocs.yml",
"chars": 489,
"preview": "# .readthedocs.yml\n# Read the Docs configuration file\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html fo"
},
{
"path": "Android.mk",
"chars": 1487,
"preview": "# Android.mk\nLOCAL_PATH := $(call my-dir)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := fmod-core-prebuilt\nLOCAL_SRC_FILES := ."
},
{
"path": "LICENSE",
"chars": 1085,
"preview": "MIT License\n\nCopyright (c) 2019 Utopia-Rise and Alex Fonseka\n\nPermission is hereby granted, free of charge, to any perso"
},
{
"path": "README.md",
"chars": 3369,
"preview": "\n\n[ users:\n# Gradle settings configured through the IDE *will ov"
},
{
"path": "android-plugin/gradlew",
"chars": 8472,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "android-plugin/gradlew.bat",
"chars": 2776,
"preview": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \""
},
{
"path": "android-plugin/library/.gitignore",
"chars": 6,
"preview": "/build"
},
{
"path": "android-plugin/library/build.gradle.kts",
"chars": 1861,
"preview": "\nplugins {\n id(\"com.android.library\")\n id(\"org.jetbrains.kotlin.android\")\n}\n\nval pluginName = \"fmod\"\nval pluginPac"
},
{
"path": "android-plugin/library/src/main/AndroidManifest.xml",
"chars": 391,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xm"
},
{
"path": "android-plugin/library/src/main/kotlin/com/utopiarise/godot/fmod/android/plugin/FmodPlugin.kt",
"chars": 841,
"preview": "package com.utopiarise.godot.fmod.android.plugin\n\nimport android.app.Activity\nimport android.view.View\nimport org.fmod.F"
},
{
"path": "android-plugin/library/src/main/resources/fmod-android-license.txt",
"chars": 1303,
"preview": "Copyright (C) 2010 The Android Open Source Project All rights reserved.\n\nRedistribution and use in source and binary for"
},
{
"path": "android-plugin/settings.gradle.kts",
"chars": 349,
"preview": "pluginManagement {\n repositories {\n google()\n mavenCentral()\n gradlePluginPortal()\n }\n}\ndepen"
},
{
"path": "demo/.gitattributes",
"chars": 80,
"preview": "# Normalize EOL for all files that Git considers text files.\n* text=auto eol=lf\n"
},
{
"path": "demo/.gitignore",
"chars": 291,
"preview": "\n# Godot 4+ specific ignores\n.godot/\n\n# Godot-specific ignores\n.import/\nexport.cfg\nexport_credentials.cfg\n\n# Imported tr"
},
{
"path": "demo/.gutconfig.json",
"chars": 735,
"preview": "{\n \"background_color\": \"262626ff\",\n \"compact_mode\": false,\n \"configured_dirs\": [\n \"res://test/unit\"\n ],\n \"dirs\": [\n \"r"
},
{
"path": "demo/addons/fmod/.gitignore",
"chars": 50,
"preview": "*.dll\n*.a\n*.dylib\n*.so\n*.so.*\n*.xcframework\n!libs/"
},
{
"path": "demo/addons/fmod/FmodAndroidExportPlugin.gd",
"chars": 498,
"preview": "@tool\nclass_name FmodAndroidExportPlugin extends EditorExportPlugin\n\nvar plugin_name: String = \"fmod\"\n\nfunc _supports_pl"
},
{
"path": "demo/addons/fmod/FmodAndroidExportPlugin.gd.uid",
"chars": 20,
"preview": "uid://cle6f2srp4yun\n"
},
{
"path": "demo/addons/fmod/FmodManager.gd",
"chars": 567,
"preview": "@tool\nextends Node\n\nvar performance_display: PerformancesDisplay\n\nfunc _ready():\n\tprocess_mode = PROCESS_MODE_ALWAYS\n\tpe"
},
{
"path": "demo/addons/fmod/FmodManager.gd.uid",
"chars": 20,
"preview": "uid://cds10pm7hwn3p\n"
},
{
"path": "demo/addons/fmod/FmodPlugin.gd",
"chars": 3351,
"preview": "@tool\nclass_name FmodPlugin extends EditorPlugin\n\n\nconst ADDON_PATH: StringName = &\"res://addons/fmod\"\nconst FmodManager"
},
{
"path": "demo/addons/fmod/FmodPlugin.gd.uid",
"chars": 20,
"preview": "uid://cwsif6rhp50p5\n"
},
{
"path": "demo/addons/fmod/fmod.gdextension",
"chars": 3767,
"preview": "[configuration]\nentry_symbol = \"fmod_library_init\"\ncompatibility_minimum = 4.5\n\n[libraries]\nwindows.editor.x86_64 = \"res"
},
{
"path": "demo/addons/fmod/fmod.gdextension.uid",
"chars": 20,
"preview": "uid://dq17s7r52klxe\n"
},
{
"path": "demo/addons/fmod/icons/bank_icon.svg.import",
"chars": 1071,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://o2chsr07oeqs\"\npath=\"res://.godot/imported/bank_icon.sv"
},
{
"path": "demo/addons/fmod/icons/bus_icon.svg.import",
"chars": 1069,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dj1kag4aeg58t\"\npath=\"res://.godot/imported/bus_icon.sv"
},
{
"path": "demo/addons/fmod/icons/c_parameter_icon.svg.import",
"chars": 1093,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cmvcqfsl167te\"\npath=\"res://.godot/imported/c_parameter"
},
{
"path": "demo/addons/fmod/icons/d_parameter_icon.svg.import",
"chars": 1093,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dgna04txtwnyb\"\npath=\"res://.godot/imported/d_parameter"
},
{
"path": "demo/addons/fmod/icons/event_icon.svg.import",
"chars": 1075,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cmpgmbn3y4svl\"\npath=\"res://.godot/imported/event_icon."
},
{
"path": "demo/addons/fmod/icons/fmod_emitter.png.import",
"chars": 958,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cotpb54utx6d6\"\npath=\"res://.godot/imported/fmod_emitte"
},
{
"path": "demo/addons/fmod/icons/fmod_icon.svg.import",
"chars": 1072,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bwqq5q7kodk40\"\npath=\"res://.godot/imported/fmod_icon.s"
},
{
"path": "demo/addons/fmod/icons/snapshot_icon.svg.import",
"chars": 1084,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://b4jxbh86chubi\"\npath=\"res://.godot/imported/snapshot_ic"
},
{
"path": "demo/addons/fmod/icons/vca_icon.svg.import",
"chars": 1069,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://crsj4jjaeq87a\"\npath=\"res://.godot/imported/vca_icon.sv"
},
{
"path": "demo/addons/fmod/libs/android/arm64/CopyPast_Fmod_Libs_Here.txt",
"chars": 0,
"preview": ""
},
{
"path": "demo/addons/fmod/libs/iOS/CopyPast_Fmod_Libs_Here.txt",
"chars": 0,
"preview": ""
},
{
"path": "demo/addons/fmod/libs/linux/CopyPast_Fmod_Libs_Here.txt",
"chars": 0,
"preview": ""
},
{
"path": "demo/addons/fmod/libs/macos/CopyPast_Fmod_Libs_Here.txt",
"chars": 0,
"preview": ""
},
{
"path": "demo/addons/fmod/libs/macos/libGodotFmod.macos.editor.framework/Info.plist",
"chars": 790,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "demo/addons/fmod/libs/macos/libGodotFmod.macos.template_debug.framework/Info.plist",
"chars": 805,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "demo/addons/fmod/libs/macos/libGodotFmod.macos.template_release.framework/Info.plist",
"chars": 809,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "demo/addons/fmod/libs/windows/CopyPast_Fmod_Libs_Here.txt",
"chars": 0,
"preview": ""
},
{
"path": "demo/addons/fmod/plugin.cfg",
"chars": 188,
"preview": "[plugin]\n\nname=\"FMOD GDExtension\"\ndescription=\"FMOD GDExtension for Godot Engine 4.5\"\nauthor=\"Utopia-rise, Tristan Gresp"
},
{
"path": "demo/addons/fmod/tool/FmodBankDatabase.gd",
"chars": 1420,
"preview": "extends Node\n\nclass_name FmodBankDatabase\n\n\nstatic var banks := Array()\nconst MASTER_STRINGS_BANK_NAME = \"Master.strings"
},
{
"path": "demo/addons/fmod/tool/FmodBankDatabase.gd.uid",
"chars": 20,
"preview": "uid://dovuikgbkylhi\n"
},
{
"path": "demo/addons/fmod/tool/inspectors/FmodBankLoaderPropertyInspectorPlugin.gd",
"chars": 805,
"preview": "class_name FmodBankLoaderPropertyInspectorPlugin extends EditorInspectorPlugin\n\nstatic var bank_icon = load(\"res://addon"
},
{
"path": "demo/addons/fmod/tool/inspectors/FmodBankLoaderPropertyInspectorPlugin.gd.uid",
"chars": 19,
"preview": "uid://tnljjxahubam\n"
},
{
"path": "demo/addons/fmod/tool/inspectors/FmodEmitterPropertyInspectorPlugin.gd",
"chars": 1083,
"preview": "class_name FmodEmitterPropertyInspectorPlugin extends EditorInspectorPlugin\n\nvar _open_project_explorer_callable: Callab"
},
{
"path": "demo/addons/fmod/tool/inspectors/FmodEmitterPropertyInspectorPlugin.gd.uid",
"chars": 20,
"preview": "uid://co1ktq45h26wx\n"
},
{
"path": "demo/addons/fmod/tool/performances/PerformancesDisplay.gd",
"chars": 2845,
"preview": "class_name PerformancesDisplay extends Node\n\n\nconst CORE_CPU_DSP_CATEGORY = \"FMOD [Core]/Cpu DSP\"\nconst CORE_CPU_GEOMETR"
},
{
"path": "demo/addons/fmod/tool/performances/PerformancesDisplay.gd.uid",
"chars": 20,
"preview": "uid://bc0uajlvc0u00\n"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodBankPathEditorProperty.gd",
"chars": 3307,
"preview": "class_name FmodBankPathEditorProperty extends EditorProperty\n\nvar path_property_name := \"bank_paths\"\n\nvar ui: Control\nva"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodBankPathEditorProperty.gd.uid",
"chars": 20,
"preview": "uid://cxyd4qioylvgr\n"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodBankPathsPropertyEditorUi.tscn",
"chars": 1599,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://dtlwk8wdeal3h\"]\n\n[ext_resource type=\"Texture2D\" uid=\"uid://o2chsr07oeqs\" path"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodEventEditorProperty.gd",
"chars": 4749,
"preview": "@tool class_name FmodEventEditorProperty extends FmodPathEditorProperty\n\n\nstatic var EVENT_PARAMETER_PREFIX_FOR_PROPERTI"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodEventEditorProperty.gd.uid",
"chars": 20,
"preview": "uid://b32x60k0th8td\n"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodEventEditorProperty.tscn",
"chars": 453,
"preview": "[gd_scene load_steps=3 format=3 uid=\"uid://cowfthogh1n7i\"]\n\n[ext_resource type=\"PackedScene\" uid=\"uid://cujo3xq0erren\" p"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodGuidAndPathPropertyEditorUi.gd",
"chars": 394,
"preview": "@tool class_name FmodGuidAndPathPropertyEditorUi extends HBoxContainer\n\n\nfunc set_callables(window_callable: Callable, p"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodGuidAndPathPropertyEditorUi.gd.uid",
"chars": 19,
"preview": "uid://3xn18ci172v4\n"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodGuidAndPathPropertyEditorUi.tscn",
"chars": 977,
"preview": "[gd_scene load_steps=3 format=3 uid=\"uid://hy04frgfhtgu\"]\n\n[ext_resource type=\"Script\" uid=\"uid://3xn18ci172v4\" path=\"re"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodPathEditorProperty.gd",
"chars": 1480,
"preview": "@tool class_name FmodPathEditorProperty extends EditorProperty\n\nvar ui: Control\nvar guid_property: String\nvar path_prope"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodPathEditorProperty.gd.uid",
"chars": 19,
"preview": "uid://qshng8csi2fr\n"
},
{
"path": "demo/addons/fmod/tool/property_editors/FmodPathEditorProperty.tscn",
"chars": 671,
"preview": "[gd_scene load_steps=3 format=3 uid=\"uid://cujo3xq0erren\"]\n\n[ext_resource type=\"Script\" uid=\"uid://qshng8csi2fr\" path=\"r"
},
{
"path": "demo/addons/fmod/tool/ui/EventParametersDisplay.gd",
"chars": 1004,
"preview": "@tool class_name EventParametersDisplay extends ScrollContainer\n\nstatic var parameter_display_scene: PackedScene = load("
},
{
"path": "demo/addons/fmod/tool/ui/EventParametersDisplay.gd.uid",
"chars": 19,
"preview": "uid://7relkis52fsu\n"
},
{
"path": "demo/addons/fmod/tool/ui/EventParametersDisplay.tscn",
"chars": 594,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://cppeyr1ke5wre\"]\n\n[ext_resource type=\"Script\" uid=\"uid://7relkis52fsu\" path=\"r"
},
{
"path": "demo/addons/fmod/tool/ui/EventParametersWindow.tscn",
"chars": 325,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://skp8awewyl85\"]\n\n[ext_resource type=\"PackedScene\" uid=\"uid://cppeyr1ke5wre\" pa"
},
{
"path": "demo/addons/fmod/tool/ui/EventPlayControls.gd",
"chars": 1347,
"preview": "@tool\nextends PanelContainer\n\n@export var play_button : Button\n@export var stop_button : Button\n@export var fade_out_tog"
},
{
"path": "demo/addons/fmod/tool/ui/EventPlayControls.gd.uid",
"chars": 19,
"preview": "uid://vgmq7hfrbddw\n"
},
{
"path": "demo/addons/fmod/tool/ui/FmodBankExplorer.gd",
"chars": 8401,
"preview": "@tool class_name FmodBankExplorer extends Window\n\nenum ToDisplayFlags {\n\tBUSES = 1,\n\tVCA = 2,\n\tEVENTS = 4\n}\n\nstatic var "
},
{
"path": "demo/addons/fmod/tool/ui/FmodBankExplorer.gd.uid",
"chars": 20,
"preview": "uid://b5xgbibc3amtk\n"
},
{
"path": "demo/addons/fmod/tool/ui/FmodBankExplorer.tscn",
"chars": 15243,
"preview": "[gd_scene load_steps=17 format=3 uid=\"uid://nr38urn226al\"]\n\n[ext_resource type=\"Script\" uid=\"uid://b5xgbibc3amtk\" path=\""
},
{
"path": "demo/addons/fmod/tool/ui/ParameterDisplay.gd",
"chars": 2059,
"preview": "@tool class_name ParameterDisplay extends MarginContainer\n\nvar event_description: FmodEventDescription\nvar parameter: Fm"
},
{
"path": "demo/addons/fmod/tool/ui/ParameterDisplay.gd.uid",
"chars": 19,
"preview": "uid://ve6g43nb1hdd\n"
},
{
"path": "demo/addons/fmod/tool/ui/ParameterDisplay.tscn",
"chars": 4498,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://bfdldojk5i6u3\"]\n\n[ext_resource type=\"Script\" uid=\"uid://ve6g43nb1hdd\" path=\"r"
},
{
"path": "demo/addons/fmod/tool/ui/TestFmodBankExplorer.tscn",
"chars": 594,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://f4i35731qm63\"]\n\n[ext_resource type=\"PackedScene\" uid=\"uid://nr38urn226al\" pat"
},
{
"path": "demo/addons/gut/GutScene.gd",
"chars": 3570,
"preview": "extends Node2D\n# ##############################################################################\n# This is a wrapper arou"
},
{
"path": "demo/addons/gut/GutScene.gd.uid",
"chars": 20,
"preview": "uid://bw7tukh738kw1\n"
},
{
"path": "demo/addons/gut/GutScene.tscn",
"chars": 673,
"preview": "[gd_scene load_steps=4 format=3 uid=\"uid://m28heqtswbuq\"]\n\n[ext_resource type=\"Script\" uid=\"uid://bw7tukh738kw1\" path=\"r"
},
{
"path": "demo/addons/gut/LICENSE.md",
"chars": 1107,
"preview": "The MIT License (MIT)\n=====================\n\nCopyright (c) 2018 Tom \"Butch\" Wesley\n\nPermission is hereby granted, free o"
},
{
"path": "demo/addons/gut/UserFileViewer.gd",
"chars": 1090,
"preview": "extends Window\n\n@onready var rtl = $TextDisplay/RichTextLabel\n\nfunc _get_file_as_text(path):\n\tvar to_return = null\n\tvar "
},
{
"path": "demo/addons/gut/UserFileViewer.gd.uid",
"chars": 19,
"preview": "uid://x51wilphva3d\n"
},
{
"path": "demo/addons/gut/UserFileViewer.tscn",
"chars": 3433,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://bsm7wtt1gie4v\"]\n\n[ext_resource type=\"Script\" uid=\"uid://x51wilphva3d\" path=\"r"
},
{
"path": "demo/addons/gut/autofree.gd",
"chars": 2742,
"preview": "# ##############################################################################\n#(G)odot (U)nit (T)est class\n#\n# ######"
},
{
"path": "demo/addons/gut/autofree.gd.uid",
"chars": 20,
"preview": "uid://bxjfriqxgwe0r\n"
},
{
"path": "demo/addons/gut/awaiter.gd",
"chars": 5660,
"preview": "extends Node\n\nclass AwaitLogger:\n\tvar _time_waited = 0.0\n\tvar logger = GutUtils.get_logger()\n\tvar waiting_on = \"nothing\""
},
{
"path": "demo/addons/gut/awaiter.gd.uid",
"chars": 20,
"preview": "uid://ccu4ww35edtdi\n"
},
{
"path": "demo/addons/gut/cli/change_project_warnings.gd",
"chars": 8325,
"preview": "extends SceneTree\n\nvar Optparse = load('res://addons/gut/cli/optparse.gd')\nvar WarningsManager = load(\"res://addons/gut/"
},
{
"path": "demo/addons/gut/cli/change_project_warnings.gd.uid",
"chars": 19,
"preview": "uid://1pauyfnd1cre\n"
},
{
"path": "demo/addons/gut/cli/gut_cli.gd",
"chars": 13748,
"preview": "extends Node\n\nvar Optparse = load('res://addons/gut/cli/optparse.gd')\nvar Gut = load('res://addons/gut/gut.gd')\nvar GutR"
},
{
"path": "demo/addons/gut/cli/gut_cli.gd.uid",
"chars": 20,
"preview": "uid://bhuudqinp4bth\n"
},
{
"path": "demo/addons/gut/cli/optparse.gd",
"chars": 23678,
"preview": "## Parses command line arguments, as one might expect.\n##\n## Parses command line arguments with a bunch of options inclu"
},
{
"path": "demo/addons/gut/cli/optparse.gd.uid",
"chars": 20,
"preview": "uid://c8m4fojwln6bq\n"
},
{
"path": "demo/addons/gut/collected_script.gd",
"chars": 5399,
"preview": "# ------------------------------------------------------------------------------\n# This holds all the meta information f"
},
{
"path": "demo/addons/gut/collected_script.gd.uid",
"chars": 20,
"preview": "uid://bjjcnr1oqvag6\n"
},
{
"path": "demo/addons/gut/collected_test.gd",
"chars": 3103,
"preview": "# ------------------------------------------------------------------------------\n# Used to keep track of info about each"
},
{
"path": "demo/addons/gut/collected_test.gd.uid",
"chars": 20,
"preview": "uid://cl854f1m26a2a\n"
},
{
"path": "demo/addons/gut/comparator.gd",
"chars": 3315,
"preview": "var _strutils = GutUtils.Strutils.new()\nvar _max_length = 100\nvar _should_compare_int_to_float = true\n\nconst MISSING = '"
},
{
"path": "demo/addons/gut/comparator.gd.uid",
"chars": 20,
"preview": "uid://bohry7fhscy7y\n"
},
{
"path": "demo/addons/gut/compare_result.gd",
"chars": 1169,
"preview": "var _are_equal = false\nvar are_equal = false :\n\tget:\n\t\treturn get_are_equal()\n\tset(val):\n\t\tset_are_equal(val)\n\nvar _summ"
},
{
"path": "demo/addons/gut/compare_result.gd.uid",
"chars": 20,
"preview": "uid://cow1xqmqqvn4e\n"
},
{
"path": "demo/addons/gut/diff_formatter.gd",
"chars": 1533,
"preview": "var _strutils = GutUtils.Strutils.new()\nconst INDENT = ' '\nvar _max_to_display = 30\nconst ABSOLUTE_MAX_DISPLAYED = 10"
},
{
"path": "demo/addons/gut/diff_formatter.gd.uid",
"chars": 20,
"preview": "uid://ch2km05phxacd\n"
},
{
"path": "demo/addons/gut/diff_tool.gd",
"chars": 3562,
"preview": "extends 'res://addons/gut/compare_result.gd'\nconst INDENT = ' '\nenum {\n\tDEEP,\n\tSIMPLE\n}\n\nvar _strutils = GutUtils.Str"
},
{
"path": "demo/addons/gut/diff_tool.gd.uid",
"chars": 20,
"preview": "uid://beoxokvl1hjs8\n"
},
{
"path": "demo/addons/gut/double_templates/function_template.txt",
"chars": 277,
"preview": "{func_decleration}\n\tif(__gutdbl == null):\n\t\treturn\n\n\t__gutdbl.spy_on('{method_name}', {param_array})\n\tif(__gutdbl.is_stu"
},
{
"path": "demo/addons/gut/double_templates/init_template.txt",
"chars": 93,
"preview": "{func_decleration}:\n\tsuper({super_params})\n\t__gutdbl.spy_on('{method_name}', {param_array})\n\n"
},
{
"path": "demo/addons/gut/double_templates/script_template.txt",
"chars": 1204,
"preview": "# ##############################################################################\n# Gut Doubled Script\n# ################"
},
{
"path": "demo/addons/gut/double_tools.gd",
"chars": 1985,
"preview": "var thepath = ''\nvar subpath = ''\nvar from_singleton = null\nvar is_partial = null\n\nvar double_ref : WeakRef = null\nvar s"
},
{
"path": "demo/addons/gut/double_tools.gd.uid",
"chars": 19,
"preview": "uid://tr4khoco1hef\n"
},
{
"path": "demo/addons/gut/doubler.gd",
"chars": 9322,
"preview": "extends RefCounted\n\n\nvar _base_script_text = GutUtils.get_file_as_text('res://addons/gut/double_templates/script_templat"
},
{
"path": "demo/addons/gut/doubler.gd.uid",
"chars": 20,
"preview": "uid://cpy013l0wqwmg\n"
},
{
"path": "demo/addons/gut/dynamic_gdscript.gd",
"chars": 1154,
"preview": "@tool\nvar default_script_name_no_extension = 'gut_dynamic_script'\nvar default_script_resource_path = 'res://addons/gut/n"
},
{
"path": "demo/addons/gut/dynamic_gdscript.gd.uid",
"chars": 20,
"preview": "uid://cnbjsrik0p5uf\n"
},
{
"path": "demo/addons/gut/editor_caret_context_notifier.gd",
"chars": 7616,
"preview": "@tool\nextends Node\n# ##############################################################################\n#\n# Watches script e"
},
{
"path": "demo/addons/gut/editor_caret_context_notifier.gd.uid",
"chars": 20,
"preview": "uid://c110s7a32x4su\n"
},
{
"path": "demo/addons/gut/error_tracker.gd",
"chars": 5238,
"preview": "extends Logger\nclass_name GutErrorTracker\n\n# ---------------------------------------------------------------------------"
},
{
"path": "demo/addons/gut/error_tracker.gd.uid",
"chars": 19,
"preview": "uid://35kxgqotjmlu\n"
},
{
"path": "demo/addons/gut/fonts/OFL.txt",
"chars": 4426,
"preview": "Copyright (c) 2009, Mark Simonson (http://www.ms-studio.com, mark@marksimonson.com),\nwith Reserved Font Name Anonymous P"
},
{
"path": "demo/addons/gut/gui/EditorRadioButton.tres",
"chars": 542,
"preview": "[gd_resource type=\"Theme\" load_steps=3 format=3 uid=\"uid://dssgvu257o1si\"]\n\n[sub_resource type=\"StyleBoxFlat\" id=\"StyleB"
},
{
"path": "demo/addons/gut/gui/GutBottomPanel.gd",
"chars": 15155,
"preview": "@tool\nextends Control\n\nvar GutEditorGlobals = load('res://addons/gut/gui/editor_globals.gd')\nvar GutConfigGui = load('re"
},
{
"path": "demo/addons/gut/gui/GutBottomPanel.gd.uid",
"chars": 20,
"preview": "uid://dtvnb0xatk0my\n"
},
{
"path": "demo/addons/gut/gui/GutBottomPanel.tscn",
"chars": 10099,
"preview": "[gd_scene load_steps=10 format=3 uid=\"uid://b3bostcslstem\"]\n\n[ext_resource type=\"Script\" uid=\"uid://dtvnb0xatk0my\" path="
},
{
"path": "demo/addons/gut/gui/GutControl.gd",
"chars": 8935,
"preview": "@tool\nextends Control\n\nconst RUNNER_JSON_PATH = 'res://.gut_editor_config.json'\n\nvar GutConfig = load('res://addons/gut/"
},
{
"path": "demo/addons/gut/gui/GutControl.gd.uid",
"chars": 20,
"preview": "uid://cqlvpwidawld6\n"
},
{
"path": "demo/addons/gut/gui/GutControl.tscn",
"chars": 1777,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://4jb53yqktyfg\"]\n\n[ext_resource type=\"Script\" uid=\"uid://cqlvpwidawld6\" path=\"r"
},
{
"path": "demo/addons/gut/gui/GutEditorWindow.gd",
"chars": 2054,
"preview": "@tool\nextends Window\n\n\nvar GutEditorGlobals = load('res://addons/gut/gui/editor_globals.gd')\n\n@onready var _chk_always_o"
},
{
"path": "demo/addons/gut/gui/GutEditorWindow.gd.uid",
"chars": 20,
"preview": "uid://crp2af6k4nmf5\n"
},
{
"path": "demo/addons/gut/gui/GutEditorWindow.tscn",
"chars": 4351,
"preview": "[gd_scene load_steps=10 format=3 uid=\"uid://dnnvwlplf1km7\"]\n\n[ext_resource type=\"Script\" uid=\"uid://crp2af6k4nmf5\" path="
},
{
"path": "demo/addons/gut/gui/GutLogo.tscn",
"chars": 1269,
"preview": "[gd_scene load_steps=4 format=3 uid=\"uid://bjkn8mhx2fmt1\"]\n\n[ext_resource type=\"Script\" uid=\"uid://b8lvgepb64m8t\" path=\""
},
{
"path": "demo/addons/gut/gui/GutRunner.gd",
"chars": 7604,
"preview": "# ##############################################################################\n# This class joins together GUT, GUT Gu"
},
{
"path": "demo/addons/gut/gui/GutRunner.gd.uid",
"chars": 19,
"preview": "uid://eg8k46gd42a4\n"
},
{
"path": "demo/addons/gut/gui/GutRunner.tscn",
"chars": 477,
"preview": "[gd_scene load_steps=3 format=3 uid=\"uid://bqy3ikt6vu4b5\"]\n\n[ext_resource type=\"Script\" uid=\"uid://eg8k46gd42a4\" path=\"r"
},
{
"path": "demo/addons/gut/gui/GutSceneTheme.tres",
"chars": 293,
"preview": "[gd_resource type=\"Theme\" load_steps=2 format=3 uid=\"uid://cstkhwkpajvqu\"]\n\n[ext_resource type=\"FontFile\" uid=\"uid://c6c"
},
{
"path": "demo/addons/gut/gui/MinGui.tscn",
"chars": 5218,
"preview": "[gd_scene load_steps=5 format=3 uid=\"uid://cnqqdfsn80ise\"]\n\n[ext_resource type=\"Theme\" uid=\"uid://cstkhwkpajvqu\" path=\"r"
},
{
"path": "demo/addons/gut/gui/NormalGui.tscn",
"chars": 7392,
"preview": "[gd_scene load_steps=5 format=3 uid=\"uid://duxblir3vu8x7\"]\n\n[ext_resource type=\"Theme\" uid=\"uid://cstkhwkpajvqu\" path=\"r"
},
{
"path": "demo/addons/gut/gui/OutputText.gd",
"chars": 9128,
"preview": "@tool\nextends VBoxContainer\n\nvar GutEditorGlobals = load('res://addons/gut/gui/editor_globals.gd')\nvar PanelControls = l"
},
{
"path": "demo/addons/gut/gui/OutputText.gd.uid",
"chars": 20,
"preview": "uid://cax5phqs8acmu\n"
},
{
"path": "demo/addons/gut/gui/OutputText.tscn",
"chars": 4428,
"preview": "[gd_scene load_steps=5 format=3 uid=\"uid://bqmo4dj64c7yl\"]\n\n[ext_resource type=\"Script\" uid=\"uid://cax5phqs8acmu\" path=\""
},
{
"path": "demo/addons/gut/gui/ResizeHandle.gd",
"chars": 2934,
"preview": "@tool\nextends ColorRect\n# #############################################################################\n# Resize Handle "
},
{
"path": "demo/addons/gut/gui/ResizeHandle.gd.uid",
"chars": 20,
"preview": "uid://duf6rfdqr6yoc\n"
},
{
"path": "demo/addons/gut/gui/ResizeHandle.tscn",
"chars": 313,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://bvrqqgjpyouse\"]\n\n[ext_resource type=\"Script\" uid=\"uid://duf6rfdqr6yoc\" path=\""
},
{
"path": "demo/addons/gut/gui/ResultsTree.gd",
"chars": 9106,
"preview": "@tool\nextends Tree\n\nvar _show_orphans = true\nvar show_orphans = true :\n\tget: return _show_orphans\n\tset(val): _show_orpha"
},
{
"path": "demo/addons/gut/gui/ResultsTree.gd.uid",
"chars": 20,
"preview": "uid://dehdhn78qv5tr\n"
},
{
"path": "demo/addons/gut/gui/ResultsTree.tscn",
"chars": 849,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://dls5r5f6157nq\"]\n\n[ext_resource type=\"Script\" uid=\"uid://dehdhn78qv5tr\" path=\""
},
{
"path": "demo/addons/gut/gui/RunAtCursor.gd",
"chars": 4445,
"preview": "@tool\nextends Control\n\nvar EditorCaretContextNotifier = load('res://addons/gut/editor_caret_context_notifier.gd')\n\n@onre"
},
{
"path": "demo/addons/gut/gui/RunAtCursor.gd.uid",
"chars": 20,
"preview": "uid://c4gmgdl1xwflw\n"
},
{
"path": "demo/addons/gut/gui/RunAtCursor.tscn",
"chars": 1884,
"preview": "[gd_scene load_steps=3 format=3 uid=\"uid://0yunjxtaa8iw\"]\n\n[ext_resource type=\"Script\" uid=\"uid://c4gmgdl1xwflw\" path=\"r"
},
{
"path": "demo/addons/gut/gui/RunExternally.gd",
"chars": 4982,
"preview": "@tool\nextends Control\n\n# I'm probably going to put this back in later and I don't want to create it\n# again. Yeah, yeah"
},
{
"path": "demo/addons/gut/gui/RunExternally.gd.uid",
"chars": 20,
"preview": "uid://bi8pg352un4om\n"
},
{
"path": "demo/addons/gut/gui/RunExternally.tscn",
"chars": 1880,
"preview": "[gd_scene load_steps=3 format=3 uid=\"uid://cftcb0e6g7tu1\"]\n\n[ext_resource type=\"Script\" uid=\"uid://bi8pg352un4om\" path=\""
},
{
"path": "demo/addons/gut/gui/RunResults.gd",
"chars": 6068,
"preview": "@tool\nextends Control\n\nvar GutEditorGlobals = load('res://addons/gut/gui/editor_globals.gd')\n\nvar _interface = null\nvar "
},
{
"path": "demo/addons/gut/gui/RunResults.gd.uid",
"chars": 20,
"preview": "uid://chnko3073tkcv\n"
},
{
"path": "demo/addons/gut/gui/RunResults.tscn",
"chars": 3271,
"preview": "[gd_scene load_steps=4 format=3 uid=\"uid://4gyyn12um08h\"]\n\n[ext_resource type=\"Script\" uid=\"uid://chnko3073tkcv\" path=\"r"
},
{
"path": "demo/addons/gut/gui/Settings.tscn",
"chars": 184,
"preview": "[gd_scene format=3 uid=\"uid://cvvvtsah38l0e\"]\n\n[node name=\"Settings\" type=\"VBoxContainer\"]\noffset_right = 388.0\noffset_b"
},
{
"path": "demo/addons/gut/gui/ShellOutOptions.gd",
"chars": 10577,
"preview": "@tool\nextends ConfirmationDialog\n\nconst RUN_MODE_EDITOR = 'Editor'\nconst RUN_MODE_BLOCKING = 'Blocking'\nconst RUN_MODE_N"
},
{
"path": "demo/addons/gut/gui/ShellOutOptions.gd.uid",
"chars": 20,
"preview": "uid://c64u22kybimgi\n"
},
{
"path": "demo/addons/gut/gui/ShellOutOptions.tscn",
"chars": 1020,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://ckv5eh8xyrwbk\"]\n\n[ext_resource type=\"Script\" uid=\"uid://c64u22kybimgi\" path=\""
},
{
"path": "demo/addons/gut/gui/ShortcutButton.gd",
"chars": 3312,
"preview": "@tool\nextends Control\n\n\n@onready var _ctrls = {\n\tshortcut_label = $Layout/lblShortcut,\n\tset_button = $Layout/SetButton,\n"
},
{
"path": "demo/addons/gut/gui/ShortcutButton.gd.uid",
"chars": 19,
"preview": "uid://k6hvvpekp0xw\n"
},
{
"path": "demo/addons/gut/gui/ShortcutButton.tscn",
"chars": 1681,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://sfb1fw8j6ufu\"]\n\n[ext_resource type=\"Script\" uid=\"uid://k6hvvpekp0xw\" path=\"re"
},
{
"path": "demo/addons/gut/gui/ShortcutDialog.gd",
"chars": 3874,
"preview": "@tool\nextends ConfirmationDialog\n\nvar GutEditorGlobals = load('res://addons/gut/gui/editor_globals.gd')\nvar default_path"
},
{
"path": "demo/addons/gut/gui/ShortcutDialog.gd.uid",
"chars": 20,
"preview": "uid://dc5jgemxslgvl\n"
},
{
"path": "demo/addons/gut/gui/ShortcutDialog.tscn",
"chars": 6560,
"preview": "[gd_scene load_steps=3 format=3 uid=\"uid://dj5ve0bq7xa5j\"]\n\n[ext_resource type=\"Script\" uid=\"uid://dc5jgemxslgvl\" path=\""
},
{
"path": "demo/addons/gut/gui/about.gd",
"chars": 3072,
"preview": "@tool\nextends AcceptDialog\n\nvar GutEditorGlobals = load('res://addons/gut/gui/editor_globals.gd')\n\nvar _bbcode = \\\n\"\"\"\n["
},
{
"path": "demo/addons/gut/gui/about.gd.uid",
"chars": 19,
"preview": "uid://g7qu8ihdt3pd\n"
},
{
"path": "demo/addons/gut/gui/about.tscn",
"chars": 2141,
"preview": "[gd_scene load_steps=5 format=3 uid=\"uid://dqbkylpsatcqm\"]\n\n[ext_resource type=\"Script\" uid=\"uid://g7qu8ihdt3pd\" path=\"r"
},
{
"path": "demo/addons/gut/gui/editor_globals.gd",
"chars": 2485,
"preview": "@tool\n\nstatic var GutUserPreferences = load(\"res://addons/gut/gui/gut_user_preferences.gd\")\nstatic var temp_directory = "
},
{
"path": "demo/addons/gut/gui/editor_globals.gd.uid",
"chars": 20,
"preview": "uid://cbi00ubn046c2\n"
},
{
"path": "demo/addons/gut/gui/gut_config_gui.gd",
"chars": 10800,
"preview": "var PanelControls = load(\"res://addons/gut/gui/panel_controls.gd\")\nvar GutConfig = load('res://addons/gut/gut_config.gd'"
},
{
"path": "demo/addons/gut/gui/gut_config_gui.gd.uid",
"chars": 20,
"preview": "uid://chosc1tvfaduq\n"
},
{
"path": "demo/addons/gut/gui/gut_gui.gd",
"chars": 5954,
"preview": "extends Control\n# ##############################################################################\n# This is the decoupled"
},
{
"path": "demo/addons/gut/gui/gut_gui.gd.uid",
"chars": 20,
"preview": "uid://blvhsbnsvfyow\n"
},
{
"path": "demo/addons/gut/gui/gut_logo.gd",
"chars": 6090,
"preview": "@tool\nextends Node2D\n\nclass Eyeball:\n\textends Node2D\n\n\tvar _should_draw_laser = false\n\tvar _laser_end_pos = Vector2.ZERO"
},
{
"path": "demo/addons/gut/gui/gut_logo.gd.uid",
"chars": 20,
"preview": "uid://b8lvgepb64m8t\n"
},
{
"path": "demo/addons/gut/gui/gut_user_preferences.gd",
"chars": 2327,
"preview": "class GutEditorPref:\n\tvar gut_pref_prefix = 'gut/'\n\tvar pname = '__not_set__'\n\tvar default = null\n\tvar value = '__not_se"
},
{
"path": "demo/addons/gut/gui/gut_user_preferences.gd.uid",
"chars": 20,
"preview": "uid://dsndkn6whyiov\n"
},
{
"path": "demo/addons/gut/gui/option_maker.gd",
"chars": 3078,
"preview": "var PanelControls = load(\"res://addons/gut/gui/panel_controls.gd\")\n\n# All titles so we can free them when we want.\nvar _"
},
{
"path": "demo/addons/gut/gui/option_maker.gd.uid",
"chars": 20,
"preview": "uid://bjahqsqo645sf\n"
},
{
"path": "demo/addons/gut/gui/panel_controls.gd",
"chars": 12389,
"preview": "# ------------------------------------------------------------------------------\n# -------------------------------------"
},
{
"path": "demo/addons/gut/gui/panel_controls.gd.uid",
"chars": 20,
"preview": "uid://db54jy04d8w7p\n"
},
{
"path": "demo/addons/gut/gui/run_from_editor.gd",
"chars": 640,
"preview": "# ------------------------------------------------------------------------------\n# This is the entry point when running "
},
{
"path": "demo/addons/gut/gui/run_from_editor.gd.uid",
"chars": 20,
"preview": "uid://bwf2iuidqfkpl\n"
},
{
"path": "demo/addons/gut/gui/run_from_editor.tscn",
"chars": 250,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://bgj3fm5d8yvjw\"]\n\n[ext_resource type=\"Script\" uid=\"uid://bwf2iuidqfkpl\" path=\""
},
{
"path": "demo/addons/gut/gut.gd",
"chars": 46322,
"preview": "extends 'res://addons/gut/gut_to_move.gd'\nclass_name GutMain\n## The GUT brains.\n##\n## Most of this class is for internal"
},
{
"path": "demo/addons/gut/gut.gd.uid",
"chars": 20,
"preview": "uid://duvvxvj18c04d\n"
},
{
"path": "demo/addons/gut/gut_cmdln.gd",
"chars": 2564,
"preview": "# ------------------------------------------------------------------------------\n# Description\n# -----------\n# Entry poi"
},
{
"path": "demo/addons/gut/gut_cmdln.gd.uid",
"chars": 20,
"preview": "uid://bxw30gwbwnh55\n"
}
]
// ... and 360 more files (download for full content)
About this extraction
This page contains the full source code of the utopia-rise/fmod-gdnative GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 560 files (21.7 MB), approximately 323.4k tokens, and a symbol index with 126 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.