summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct44
-rw-r--r--core/math/audio_frame.h3
-rw-r--r--doc/classes/AudioEffectCapture.xml75
-rw-r--r--editor/editor_settings.cpp32
-rw-r--r--editor/editor_settings.h1
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp4
-rw-r--r--main/main.cpp25
-rw-r--r--modules/gdnative/include/gdnative/math_defs.h1
-rw-r--r--platform/iphone/export/export.cpp30
-rw-r--r--platform/iphone/godot_app_delegate.h24
-rw-r--r--platform/iphone/godot_app_delegate.m32
-rw-r--r--platform/iphone/godot_view.h8
-rw-r--r--platform/iphone/godot_view.mm9
-rw-r--r--platform/iphone/plugin/godot_plugin_config.h5
-rw-r--r--platform/iphone/view_controller.mm36
-rw-r--r--platform/javascript/display_server_javascript.cpp4
-rw-r--r--platform/linuxbsd/detect.py2
-rw-r--r--platform/osx/detect.py2
-rw-r--r--platform/server/detect.py4
-rw-r--r--platform/windows/detect.py2
-rw-r--r--scene/2d/cpu_particles_2d.cpp34
-rw-r--r--scene/3d/cpu_particles_3d.cpp34
-rw-r--r--scene/resources/particles_material.cpp28
-rw-r--r--scene/resources/sky_material.cpp100
-rw-r--r--servers/audio/effects/audio_effect_capture.cpp140
-rw-r--r--servers/audio/effects/audio_effect_capture.h82
-rw-r--r--servers/audio_server.cpp3
-rw-r--r--servers/audio_server.h2
-rw-r--r--servers/register_server_types.cpp3
29 files changed, 565 insertions, 204 deletions
diff --git a/SConstruct b/SConstruct
index 3795fc1c3c..065019d591 100644
--- a/SConstruct
+++ b/SConstruct
@@ -105,15 +105,14 @@ if profile:
opts = Variables(customs, ARGUMENTS)
# Target build options
-opts.Add("arch", "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", "")
-opts.Add(EnumVariable("bits", "Target platform bits", "default", ("default", "32", "64")))
opts.Add("p", "Platform (alias for 'platform')", "")
opts.Add("platform", "Target platform (%s)" % ("|".join(platform_list),), "")
+opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True))
opts.Add(EnumVariable("target", "Compilation target", "debug", ("debug", "release_debug", "release")))
+opts.Add("arch", "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", "")
+opts.Add(EnumVariable("bits", "Target platform bits", "default", ("default", "32", "64")))
opts.Add(EnumVariable("optimize", "Optimization type", "speed", ("speed", "size")))
-
-opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True))
-opts.Add(BoolVariable("tests", "Build the unit tests", False))
+opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False))
opts.Add(BoolVariable("use_lto", "Use link-time optimization", False))
# Components
@@ -123,11 +122,12 @@ opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False))
opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "")
# Advanced options
-opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
+opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False))
opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True))
+opts.Add(BoolVariable("tests", "Build the unit tests", False))
+opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
opts.Add(EnumVariable("warnings", "Level of compilation warnings", "all", ("extra", "all", "moderate", "no")))
opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", False))
-opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False))
opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all generated binary files", "")
opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False))
opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False))
@@ -317,12 +317,34 @@ if selected_platform in platform_list:
env.Tool("compilation_db")
env.Alias("compiledb", env.CompilationDatabase())
+ # 'dev' and 'production' are aliases to set default options if they haven't been set
+ # manually by the user. We use `ARGUMENTS.get()` to check if they were manually set.
if env["dev"]:
- env["verbose"] = True
- env["warnings"] = "extra"
- env["werror"] = True
+ env["verbose"] = ARGUMENTS.get("verbose", True)
+ env["warnings"] = ARGUMENTS.get("warnings", "extra")
+ env["werror"] = ARGUMENTS.get("werror", True)
if env["tools"]:
- env["tests"] = True
+ env["tests"] = ARGUMENTS.get("tests", True)
+ if env["production"]:
+ env["use_static_cpp"] = ARGUMENTS.get("use_static_cpp", True)
+ env["use_lto"] = ARGUMENTS.get("use_lto", True)
+ env["debug_symbols"] = ARGUMENTS.get("debug_symbols", False)
+ if not env["tools"] and env["target"] == "debug":
+ print(
+ "WARNING: Requested `production` build with `tools=no target=debug`, "
+ "this will give you a full debug template (use `target=release_debug` "
+ "for an optimized template with debug features)."
+ )
+ if env.msvc:
+ print(
+ "WARNING: For `production` Windows builds, you should use MinGW with GCC "
+ "or Clang instead of Visual Studio, as they can better optimize the "
+ "GDScript VM in a very significant way. MSVC LTO also doesn't work "
+ "reliably for our use case."
+ "If you want to use MSVC nevertheless for production builds, set "
+ "`debug_symbols=no use_lto=no` instead of the `production=yes` option."
+ )
+ Exit(255)
env.extra_suffix = ""
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index 5773da9211..a5616b8d79 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -47,6 +47,9 @@ static inline float undenormalise(volatile float f) {
return (v.i & 0x7f800000) < 0x08000000 ? 0.0f : f;
}
+static const float AUDIO_PEAK_OFFSET = 0.0000000001f;
+static const float AUDIO_MIN_PEAK_DB = -200.0f; // linear2db(AUDIO_PEAK_OFFSET)
+
struct AudioFrame {
//left and right samples
float l, r;
diff --git a/doc/classes/AudioEffectCapture.xml b/doc/classes/AudioEffectCapture.xml
new file mode 100644
index 0000000000..cf3d87c2e4
--- /dev/null
+++ b/doc/classes/AudioEffectCapture.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="AudioEffectCapture" inherits="AudioEffect" version="4.0">
+ <brief_description>
+ Captures audio from an audio bus in real-time.
+ </brief_description>
+ <description>
+ AudioEffectCapture is an AudioEffect which copies all audio frames from the attached audio effect bus into its internal ring buffer.
+ Application code should consume these audio frames from this ring buffer using [method get_buffer] and process it as needed, for example to capture data from a microphone, implement application defined effects, or to transmit audio over the network.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="can_get_buffer" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="frames" type="int">
+ </argument>
+ <description>
+ Returns [code]true[/code] if at least [code]frames[/code] audio frames are available to read in the internal ring buffer.
+ </description>
+ </method>
+ <method name="clear_buffer">
+ <return type="void">
+ </return>
+ <description>
+ Clears the internal ring buffer.
+ </description>
+ </method>
+ <method name="get_buffer">
+ <return type="PackedVector2Array">
+ </return>
+ <argument index="0" name="frames" type="int">
+ </argument>
+ <description>
+ Gets the next [code]frames[/code] audio samples from the internal ring buffer.
+ Returns a [PackedVector2Array] containing exactly [code]frames[/code] audio samples if available, or an empty [PackedVector2Array] if insufficient data was available.
+ </description>
+ </method>
+ <method name="get_buffer_length_frames" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the total size of the internal ring buffer in frames.
+ </description>
+ </method>
+ <method name="get_discarded_frames" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the number of audio frames discarded from the audio bus due to full buffer.
+ </description>
+ </method>
+ <method name="get_frames_available" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the number of frames available to read using [method get_buffer].
+ </description>
+ </method>
+ <method name="get_pushed_frames" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the number of audio frames inserted from the audio bus.
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="buffer_length" type="float" setter="set_buffer_length" getter="get_buffer_length" default="0.1">
+ Length of the internal ring buffer, in seconds.
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 7a602912c9..9908f5727e 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -959,27 +959,16 @@ void EditorSettings::create() {
_create_script_templates(dir->get_current_dir().plus_file("script_templates"));
- if (dir->change_dir("projects") != OK) {
- dir->make_dir("projects");
- } else {
- dir->change_dir("..");
- }
-
- // Validate/create project-specific config dir
-
- dir->change_dir("projects");
- String project_config_dir = ProjectSettings::get_singleton()->get_resource_path();
- if (project_config_dir.ends_with("/")) {
- project_config_dir = config_path.substr(0, project_config_dir.size() - 1);
- }
- project_config_dir = project_config_dir.get_file() + "-" + project_config_dir.md5_text();
-
- if (dir->change_dir(project_config_dir) != OK) {
- dir->make_dir(project_config_dir);
- } else {
- dir->change_dir("..");
+ {
+ // Validate/create project-specific editor settings dir.
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (da->change_dir(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH) != OK) {
+ Error err = da->make_dir_recursive(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH);
+ if (err || da->change_dir(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH) != OK) {
+ ERR_FAIL_MSG("Failed to create '" + EditorSettings::PROJECT_EDITOR_SETTINGS_PATH + "' folder.");
+ }
+ }
}
- dir->change_dir("..");
// Validate editor config file
@@ -1001,7 +990,6 @@ void EditorSettings::create() {
singleton->save_changed_setting = true;
singleton->config_file_path = config_file_path;
- singleton->project_config_dir = project_config_dir;
singleton->settings_dir = config_dir;
singleton->data_dir = data_dir;
singleton->cache_dir = cache_dir;
@@ -1277,7 +1265,7 @@ String EditorSettings::get_settings_dir() const {
}
String EditorSettings::get_project_settings_dir() const {
- return get_settings_dir().plus_file("projects").plus_file(project_config_dir);
+ return EditorSettings::PROJECT_EDITOR_SETTINGS_PATH;
}
String EditorSettings::get_text_editor_themes_dir() const {
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index 61ec8546aa..616a938a86 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -46,6 +46,7 @@ class EditorSettings : public Resource {
_THREAD_SAFE_CLASS_
public:
+ inline static const String PROJECT_EDITOR_SETTINGS_PATH = "res://.godot/editor";
struct Plugin {
EditorPlugin *instance = nullptr;
String path;
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 0c005e0c23..a3009731f9 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -2831,7 +2831,7 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_FRONT: {
cursor.x_rot = 0;
- cursor.y_rot = 0;
+ cursor.y_rot = Math_PI;
set_message(TTR("Front View."), 2);
name = TTR("Front");
_set_auto_orthogonal();
@@ -2840,7 +2840,7 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_REAR: {
cursor.x_rot = 0;
- cursor.y_rot = Math_PI;
+ cursor.y_rot = 0;
set_message(TTR("Rear View."), 2);
name = TTR("Rear");
_set_auto_orthogonal();
diff --git a/main/main.cpp b/main/main.cpp
index 657a6ad822..d70f0eb291 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1634,7 +1634,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
register_server_types();
- MAIN_PRINT("Main: Load Remaps");
+ MAIN_PRINT("Main: Load Boot Image");
Color clear = GLOBAL_DEF("rendering/environment/default_clear_color", Color(0.3, 0.3, 0.3));
RenderingServer::get_singleton()->set_default_clear_color(clear);
@@ -1690,7 +1690,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
MAIN_PRINT("Main: DCC");
RenderingServer::get_singleton()->set_default_clear_color(
GLOBAL_DEF("rendering/environment/default_clear_color", Color(0.3, 0.3, 0.3)));
- MAIN_PRINT("Main: END");
GLOBAL_DEF("application/config/icon", String());
ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon",
@@ -1728,7 +1727,16 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("input_devices/pointing/emulate_mouse_from_touch", true)));
}
- MAIN_PRINT("Main: Load Remaps");
+ MAIN_PRINT("Main: Load Translations and Remaps");
+
+ translation_server->setup(); //register translations, load them, etc.
+ if (locale != "") {
+ translation_server->set_locale(locale);
+ }
+ translation_server->load_translations();
+ ResourceLoader::load_translation_remaps(); //load remaps for resources
+
+ ResourceLoader::load_path_remaps();
MAIN_PRINT("Main: Load Scene Types");
@@ -1774,17 +1782,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
// This loads global classes, so it must happen before custom loaders and savers are registered
ScriptServer::init_languages();
- MAIN_PRINT("Main: Load Translations");
-
- translation_server->setup(); //register translations, load them, etc.
- if (locale != "") {
- translation_server->set_locale(locale);
- }
- translation_server->load_translations();
- ResourceLoader::load_translation_remaps(); //load remaps for resources
-
- ResourceLoader::load_path_remaps();
-
audio_server->load_default_bus_layout();
if (use_debug_profiler && EngineDebugger::is_active()) {
diff --git a/modules/gdnative/include/gdnative/math_defs.h b/modules/gdnative/include/gdnative/math_defs.h
index 05de157dd0..b5cf389506 100644
--- a/modules/gdnative/include/gdnative/math_defs.h
+++ b/modules/gdnative/include/gdnative/math_defs.h
@@ -35,6 +35,7 @@
extern "C" {
#endif
+#include <stdbool.h>
#include <stdint.h>
////// bool
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 604ad4e04b..91cecdd704 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -1351,6 +1351,8 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
Vector<String> added_embedded_dependenciy_names;
HashMap<String, String> plist_values;
+ Set<String> plugin_linker_flags;
+
Error err;
for (int i = 0; i < enabled_plugins.size(); i++) {
@@ -1417,6 +1419,13 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
p_config_data.capabilities.push_back(capability);
}
+ // Linker flags
+ // Checking duplicates
+ for (int j = 0; j < plugin.linker_flags.size(); j++) {
+ String linker_flag = plugin.linker_flags[j];
+ plugin_linker_flags.insert(linker_flag);
+ }
+
// Plist
// Using hash map container to remove duplicates
const String *K = nullptr;
@@ -1497,6 +1506,27 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
p_config_data.cpp_code += plugin_cpp_code.format(plugin_format, "$_");
}
+
+ // Update Linker Flag Values
+ {
+ String result_linker_flags = " ";
+ for (Set<String>::Element *E = plugin_linker_flags.front(); E; E = E->next()) {
+ const String &flag = E->get();
+
+ if (flag.length() == 0) {
+ continue;
+ }
+
+ if (result_linker_flags.length() > 0) {
+ result_linker_flags += ' ';
+ }
+
+ result_linker_flags += flag;
+ }
+ result_linker_flags = result_linker_flags.replace("\"", "\\\"");
+ p_config_data.linker_flags += result_linker_flags;
+ }
+
return OK;
}
diff --git a/platform/iphone/godot_app_delegate.h b/platform/iphone/godot_app_delegate.h
index 76d8aa409f..6335ada50e 100644
--- a/platform/iphone/godot_app_delegate.h
+++ b/platform/iphone/godot_app_delegate.h
@@ -31,7 +31,6 @@
#import <UIKit/UIKit.h>
typedef NSObject<UIApplicationDelegate> ApplicationDelegateService;
-typedef void (^APNSNotification)(UIBackgroundFetchResult);
@interface GodotApplicalitionDelegate : NSObject <UIApplicationDelegate>
@@ -39,27 +38,4 @@ typedef void (^APNSNotification)(UIBackgroundFetchResult);
+ (void)addService:(ApplicationDelegateService *)service;
-- (void)godot:(UIApplication *)application receivedNotificationToken:(NSData *)deviceToken;
-- (void)godot:(UIApplication *)application receivedNotificationError:(NSError *)error;
-- (void)godot:(UIApplication *)application receivedNotification:(NSDictionary *)userInfo completion:(APNSNotification)completionHandler;
-
@end
-
-#define GODOT_ENABLE_PUSH_NOTIFICATIONS \
- @interface GodotApplicalitionDelegate (PushNotifications) \
- @end \
- @implementation GodotApplicalitionDelegate (PushNotifications) \
- -(void)application : (UIApplication *)application \
- didRegisterForRemoteNotificationsWithDeviceToken : (NSData *)deviceToken { \
- [self godot:application receivedNotificationToken:deviceToken]; \
- } \
- -(void)application : (UIApplication *)application \
- didFailToRegisterForRemoteNotificationsWithError : (NSError *)error { \
- [self godot:application receivedNotificationError:error]; \
- } \
- -(void)application : (UIApplication *)application \
- didReceiveRemoteNotification : (NSDictionary *)userInfo \
- fetchCompletionHandler : (APNSNotification)completionHandler { \
- [self godot:application receivedNotification:userInfo completion:completionHandler]; \
- } \
- @end
diff --git a/platform/iphone/godot_app_delegate.m b/platform/iphone/godot_app_delegate.m
index 9d298162f3..3ce9bffc79 100644
--- a/platform/iphone/godot_app_delegate.m
+++ b/platform/iphone/godot_app_delegate.m
@@ -302,37 +302,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
// MARK: Remote Notification
-- (void)godot:(UIApplication *)application receivedNotificationToken:(NSData *)deviceToken {
- for (ApplicationDelegateService *service in services) {
- if (![service respondsToSelector:_cmd]) {
- continue;
- }
-
- [service application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
- }
-}
-
-- (void)godot:(UIApplication *)application receivedNotificationError:(NSError *)error {
- for (ApplicationDelegateService *service in services) {
- if (![service respondsToSelector:_cmd]) {
- continue;
- }
-
- [service application:application didFailToRegisterForRemoteNotificationsWithError:error];
- }
-}
-
-- (void)godot:(UIApplication *)application receivedNotification:(NSDictionary *)userInfo completion:(APNSNotification)completionHandler {
- for (ApplicationDelegateService *service in services) {
- if (![service respondsToSelector:_cmd]) {
- continue;
- }
-
- [service application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
- }
-
- completionHandler(UIBackgroundFetchResultNoData);
-}
+// Moved to the iOS Plugin
// MARK: User Activity and Handling Quick Actions
diff --git a/platform/iphone/godot_view.h b/platform/iphone/godot_view.h
index 29960c47a8..265f826173 100644
--- a/platform/iphone/godot_view.h
+++ b/platform/iphone/godot_view.h
@@ -32,12 +32,20 @@
class String;
+@class GodotView;
@protocol DisplayLayer;
@protocol GodotViewRendererProtocol;
+@protocol GodotViewDelegate
+
+- (BOOL)godotViewFinishedSetup:(GodotView *)view;
+
+@end
+
@interface GodotView : UIView
@property(assign, nonatomic) id<GodotViewRendererProtocol> renderer;
+@property(assign, nonatomic) id<GodotViewDelegate> delegate;
@property(assign, readonly, nonatomic) BOOL isActive;
diff --git a/platform/iphone/godot_view.mm b/platform/iphone/godot_view.mm
index bf073ae295..887297848e 100644
--- a/platform/iphone/godot_view.mm
+++ b/platform/iphone/godot_view.mm
@@ -120,6 +120,7 @@ static const int max_touches = 8;
[self stopRendering];
self.renderer = nil;
+ self.delegate = nil;
if (self.renderingLayer) {
[self.renderingLayer removeFromSuperlayer];
@@ -241,6 +242,14 @@ static const int max_touches = 8;
return;
}
+ if (self.delegate) {
+ BOOL delegateFinishedSetup = [self.delegate godotViewFinishedSetup:self];
+
+ if (!delegateFinishedSetup) {
+ return;
+ }
+ }
+
[self handleMotion];
[self.renderer renderOnView:self];
}
diff --git a/platform/iphone/plugin/godot_plugin_config.h b/platform/iphone/plugin/godot_plugin_config.h
index 72fab13600..f4e30c8349 100644
--- a/platform/iphone/plugin/godot_plugin_config.h
+++ b/platform/iphone/plugin/godot_plugin_config.h
@@ -66,6 +66,7 @@ struct PluginConfigIOS {
inline static const char *DEPENDENCIES_SYSTEM_KEY = "system";
inline static const char *DEPENDENCIES_CAPABILITIES_KEY = "capabilities";
inline static const char *DEPENDENCIES_FILES_KEY = "files";
+ inline static const char *DEPENDENCIES_LINKER_FLAGS = "linker_flags";
inline static const char *PLIST_SECTION = "plist";
@@ -89,6 +90,8 @@ struct PluginConfigIOS {
Vector<String> files_to_copy;
Vector<String> capabilities;
+ Vector<String> linker_flags;
+
// Optional plist section
// Supports only string types for now
HashMap<String, String> plist;
@@ -260,6 +263,8 @@ static inline PluginConfigIOS load_plugin_config(Ref<ConfigFile> config_file, co
plugin_config.files_to_copy = resolve_local_dependencies(config_base_dir, files);
plugin_config.capabilities = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_CAPABILITIES_KEY, Vector<String>());
+
+ plugin_config.linker_flags = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKER_FLAGS, Vector<String>());
}
if (config_file->has_section(PluginConfigIOS::PLIST_SECTION)) {
diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm
index c41aa13bb7..6cef244567 100644
--- a/platform/iphone/view_controller.mm
+++ b/platform/iphone/view_controller.mm
@@ -40,12 +40,14 @@
#import <AVFoundation/AVFoundation.h>
#import <GameController/GameController.h>
-@interface ViewController ()
+@interface ViewController () <GodotViewDelegate>
@property(strong, nonatomic) GodotViewRenderer *renderer;
@property(strong, nonatomic) GodotNativeVideoView *videoView;
@property(strong, nonatomic) GodotKeyboardInputView *keyboardView;
+@property(strong, nonatomic) UIView *godotLoadingOverlay;
+
@end
@implementation ViewController
@@ -62,6 +64,7 @@
self.view = view;
view.renderer = self.renderer;
+ view.delegate = self;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
@@ -97,6 +100,7 @@
[super viewDidLoad];
[self observeKeyboard];
+ [self displayLoadingOverlay];
if (@available(iOS 11.0, *)) {
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
@@ -121,6 +125,31 @@
object:nil];
}
+- (void)displayLoadingOverlay {
+ NSBundle *bundle = [NSBundle mainBundle];
+ NSString *storyboardName = @"Launch Screen";
+
+ if ([bundle pathForResource:storyboardName ofType:@"storyboardc"] == nil) {
+ return;
+ }
+
+ UIStoryboard *launchStoryboard = [UIStoryboard storyboardWithName:storyboardName bundle:bundle];
+
+ UIViewController *controller = [launchStoryboard instantiateInitialViewController];
+ self.godotLoadingOverlay = controller.view;
+ self.godotLoadingOverlay.frame = self.view.bounds;
+ self.godotLoadingOverlay.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
+
+ [self.view addSubview:self.godotLoadingOverlay];
+}
+
+- (BOOL)godotViewFinishedSetup:(GodotView *)view {
+ [self.godotLoadingOverlay removeFromSuperview];
+ self.godotLoadingOverlay = nil;
+
+ return YES;
+}
+
- (void)dealloc {
[self.videoView stopVideo];
@@ -130,6 +159,11 @@
self.renderer = nil;
+ if (self.godotLoadingOverlay) {
+ [self.godotLoadingOverlay removeFromSuperview];
+ self.godotLoadingOverlay = nil;
+ }
+
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index 915e8eeacf..cfe093693f 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -93,7 +93,7 @@ EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, co
DisplayServerJavaScript *display = get_singleton();
// Empty ID is canvas.
String target_id = String::utf8(p_event->id);
- if (target_id.is_empty() || target_id == String::utf8(display->canvas_id)) {
+ if (target_id.is_empty() || target_id == String::utf8(&(display->canvas_id[1]))) {
// This event property is the only reliable data on
// browser fullscreen state.
if (p_event->isFullscreen) {
@@ -455,7 +455,7 @@ DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const {
EmscriptenPointerlockChangeEvent ev;
emscripten_get_pointerlock_status(&ev);
- return (ev.isActive && String::utf8(ev.id) == String::utf8(canvas_id)) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE;
+ return (ev.isActive && String::utf8(ev.id) == String::utf8(&canvas_id[1])) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE;
}
// Wheel
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index c093454b0a..2141f68725 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -72,7 +72,7 @@ def get_opts():
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False),
BoolVariable("pulseaudio", "Detect and use PulseAudio", True),
BoolVariable("udev", "Use udev for gamepad connection callbacks", True),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
BoolVariable("touch", "Enable touch events", True),
BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False),
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 466f68d269..47ac609917 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -31,7 +31,7 @@ def get_opts():
False,
),
EnumVariable("macports_clang", "Build using Clang from MacPorts", "no", ("no", "5.0", "devel")),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False),
diff --git a/platform/server/detect.py b/platform/server/detect.py
index db503584d3..06042c8e17 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -32,13 +32,13 @@ def get_opts():
return [
BoolVariable("use_llvm", "Use the LLVM compiler", False),
- BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", False),
+ BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True),
BoolVariable("use_coverage", "Test Godot coverage", False),
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False),
BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False),
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False),
]
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 5216fca2ca..a675a2302f 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -64,7 +64,7 @@ def get_opts():
# XP support dropped after EOL due to missing API for IPv6 and other issues
# Vista support dropped after EOL due to GH-10243
("target_win_version", "Targeted Windows version, >= 0x0601 (Windows 7)", "0x0601"),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
EnumVariable("windows_subsystem", "Windows subsystem", "default", ("default", "console", "gui")),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
("msvc_version", "MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.", None),
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index a19347caa8..f839e8c304 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -671,6 +671,8 @@ void CPUParticles2D::_particles_process(float p_delta) {
restart = true;
}
+ float tv = 0.0;
+
if (restart) {
if (!emitting) {
p.active = false;
@@ -685,12 +687,12 @@ void CPUParticles2D::_particles_process(float p_delta) {
float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0);
+ tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0);
+ tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
p.seed = Math::rand();
@@ -765,59 +767,61 @@ void CPUParticles2D::_particles_process(float p_delta) {
continue;
} else if (p.time > p.lifetime) {
p.active = false;
+ tv = 1.0;
} else {
uint32_t alt_seed = p.seed;
p.time += local_delta;
p.custom[1] = p.time / lifetime;
+ tv = p.time / p.lifetime;
float tex_linear_velocity = 0.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]);
+ tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}
float tex_orbit_velocity = 0.0;
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
- tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]);
+ tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}
float tex_angular_velocity = 0.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
- tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]);
+ tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}
float tex_linear_accel = 0.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
- tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]);
+ tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}
float tex_tangential_accel = 0.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
- tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]);
+ tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}
float tex_radial_accel = 0.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
- tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]);
+ tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}
float tex_damping = 0.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
- tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]);
+ tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}
float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]);
+ tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_speed = 0.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
- tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]);
+ tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}
float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]);
+ tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}
Vector2 force = gravity;
@@ -869,12 +873,12 @@ void CPUParticles2D::_particles_process(float p_delta) {
float tex_scale = 1.0;
if (curve_parameters[PARAM_SCALE].is_valid()) {
- tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]);
+ tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
}
float tex_hue_variation = 0.0;
if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) {
- tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]);
+ tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
}
float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
@@ -893,7 +897,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
}
if (color_ramp.is_valid()) {
- p.color = color_ramp->get_color_at_offset(p.custom[1]) * color;
+ p.color = color_ramp->get_color_at_offset(tv) * color;
} else {
p.color = color;
}
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index c36c135fe6..85b502e7a0 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -646,6 +646,8 @@ void CPUParticles3D::_particles_process(float p_delta) {
restart = true;
}
+ float tv = 0.0;
+
if (restart) {
if (!emitting) {
p.active = false;
@@ -660,12 +662,12 @@ void CPUParticles3D::_particles_process(float p_delta) {
float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0);
+ tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0);
+ tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
p.seed = Math::rand();
@@ -772,61 +774,63 @@ void CPUParticles3D::_particles_process(float p_delta) {
continue;
} else if (p.time > p.lifetime) {
p.active = false;
+ tv = 1.0;
} else {
uint32_t alt_seed = p.seed;
p.time += local_delta;
p.custom[1] = p.time / lifetime;
+ tv = p.time / p.lifetime;
float tex_linear_velocity = 0.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]);
+ tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}
float tex_orbit_velocity = 0.0;
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
- tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]);
+ tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}
}
float tex_angular_velocity = 0.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
- tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]);
+ tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}
float tex_linear_accel = 0.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
- tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]);
+ tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}
float tex_tangential_accel = 0.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
- tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]);
+ tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}
float tex_radial_accel = 0.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
- tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]);
+ tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}
float tex_damping = 0.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
- tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]);
+ tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}
float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]);
+ tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_speed = 0.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
- tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]);
+ tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}
float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]);
+ tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}
Vector3 force = gravity;
@@ -888,12 +892,12 @@ void CPUParticles3D::_particles_process(float p_delta) {
float tex_scale = 1.0;
if (curve_parameters[PARAM_SCALE].is_valid()) {
- tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]);
+ tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
}
float tex_hue_variation = 0.0;
if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) {
- tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]);
+ tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
}
float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
@@ -912,7 +916,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
}
if (color_ramp.is_valid()) {
- p.color = color_ramp->get_color_at_offset(p.custom[1]) * color;
+ p.color = color_ramp->get_color_at_offset(tv) * color;
} else {
p.color = color;
}
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index 3aa9f9b3bc..c5a295e13f 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -305,6 +305,7 @@ void ParticlesMaterial::_update_shader() {
code += " ivec2 emission_tex_size = textureSize(emission_texture_points, 0);\n";
code += " ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);\n";
}
+ code += " float tv = 0.0;\n";
code += " if (RESTART) {\n";
if (tex_parameters[PARAM_ANGLE].is_valid()) {
@@ -407,64 +408,65 @@ void ParticlesMaterial::_update_shader() {
code += " } else {\n";
code += " CUSTOM.y += DELTA / LIFETIME;\n";
+ code += " tv = CUSTOM.y / CUSTOM.w;\n";
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_linear_velocity = 0.0;\n";
}
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
- code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_orbit_velocity = 0.0;\n";
}
}
if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
- code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_angular_velocity = 0.0;\n";
}
if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
- code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_linear_accel = 0.0;\n";
}
if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
- code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_radial_accel = 0.0;\n";
}
if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
- code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_tangent_accel = 0.0;\n";
}
if (tex_parameters[PARAM_DAMPING].is_valid()) {
- code += " float tex_damping = textureLod(damping_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_damping = textureLod(damping_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_damping = 0.0;\n";
}
if (tex_parameters[PARAM_ANGLE].is_valid()) {
- code += " float tex_angle = textureLod(angle_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_angle = textureLod(angle_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_angle = 0.0;\n";
}
if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) {
- code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_anim_speed = 0.0;\n";
}
if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
- code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_anim_offset = 0.0;\n";
}
@@ -526,13 +528,13 @@ void ParticlesMaterial::_update_shader() {
// apply color
// apply hue rotation
if (tex_parameters[PARAM_SCALE].is_valid()) {
- code += " float tex_scale = textureLod(scale_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_scale = textureLod(scale_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_scale = 1.0;\n";
}
if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) {
- code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_hue_variation = 0.0;\n";
}
@@ -553,7 +555,7 @@ void ParticlesMaterial::_update_shader() {
code += " vec4(1.250, -1.050, -0.203, 0.0),\n";
code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n";
if (color_ramp.is_valid()) {
- code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(CUSTOM.y, 0.0), 0.0);\n";
+ code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(tv, 0.0), 0.0);\n";
} else {
code += " COLOR = hue_rot_mat * color_value;\n";
}
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index 1cdabe4662..ee6a26bc65 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -522,53 +522,59 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() {
code += "}\n\n";
code += "void fragment() {\n";
- code += "\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n";
- code += "\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n";
- code += "\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n";
-
- code += "\t// rayleigh coefficients\n";
- code += "\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n";
- code += "\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n";
- code += "\t// mie coefficients from Preetham\n";
- code += "\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n";
-
- code += "\t// optical length\n";
- code += "\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n";
- code += "\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n";
- code += "\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n";
- code += "\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n";
-
- code += "\t// light extinction based on thickness of atmosphere\n";
- code += "\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n";
-
- code += "\t// in scattering\n";
- code += "\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n";
-
- code += "\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n";
- code += "\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n";
-
- code += "\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n";
- code += "\tvec3 betaMTheta = mie_beta * mie_phase;\n\n";
-
- code += "\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n";
- code += "\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n";
- code += "\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n";
-
- code += "\t// Hack in the ground color\n";
- code += "\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n";
-
- code += "\t// Solar disk and out-scattering\n";
- code += "\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n";
- code += "\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n";
- code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
- code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
- code += "\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n";
-
- code += "\tvec3 color = (Lin + L0) * 0.04;\n";
- code += "\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n";
- code += "\tCOLOR *= exposure;\n";
- code += "\t// Make optional, eliminates banding\n";
- code += "\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;\n";
+ code += "\tif (LIGHT0_ENABLED) {\n";
+ code += "\t\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n";
+ code += "\t\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n";
+ code += "\t\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n";
+
+ code += "\t\t// rayleigh coefficients\n";
+ code += "\t\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n";
+ code += "\t\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n";
+ code += "\t\t// mie coefficients from Preetham\n";
+ code += "\t\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n";
+
+ code += "\t\t// optical length\n";
+ code += "\t\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n";
+ code += "\t\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n";
+ code += "\t\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n";
+ code += "\t\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n";
+
+ code += "\t\t// light extinction based on thickness of atmosphere\n";
+ code += "\t\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n";
+
+ code += "\t\t// in scattering\n";
+ code += "\t\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n";
+
+ code += "\t\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n";
+ code += "\t\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n";
+
+ code += "\t\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n";
+ code += "\t\tvec3 betaMTheta = mie_beta * mie_phase;\n\n";
+
+ code += "\t\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n";
+ code += "\t\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n";
+ code += "\t\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n";
+
+ code += "\t\t// Hack in the ground color\n";
+ code += "\t\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n";
+
+ code += "\t\t// Solar disk and out-scattering\n";
+ code += "\t\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n";
+ code += "\t\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n";
+ code += "\t\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
+ code += "\t\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
+ code += "\t\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n";
+
+ code += "\t\tvec3 color = (Lin + L0) * 0.04;\n";
+ code += "\t\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n";
+ code += "\t\tCOLOR *= exposure;\n";
+ code += "\t\t// Make optional, eliminates banding\n";
+ code += "\t\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;\n";
+ code += "\t} else {\n";
+ code += "\t\t// There is no sun, so display night_sky and nothing else\n";
+ code += "\t\tCOLOR = texture(night_sky, SKY_COORDS).xyz * 0.04;\n";
+ code += "\t\tCOLOR *= exposure;\n";
+ code += "\t}\n";
code += "}\n";
shader = RS::get_singleton()->shader_create();
diff --git a/servers/audio/effects/audio_effect_capture.cpp b/servers/audio/effects/audio_effect_capture.cpp
new file mode 100644
index 0000000000..f37938eec8
--- /dev/null
+++ b/servers/audio/effects/audio_effect_capture.cpp
@@ -0,0 +1,140 @@
+/*************************************************************************/
+/* audio_effect_capture.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#include "audio_effect_capture.h"
+
+bool AudioEffectCapture::can_get_buffer(int p_frames) const {
+ return buffer.data_left() >= p_frames;
+}
+
+PackedVector2Array AudioEffectCapture::get_buffer(int p_frames) {
+ ERR_FAIL_COND_V(!buffer_initialized, PackedVector2Array());
+ ERR_FAIL_INDEX_V(p_frames, buffer.size(), PackedVector2Array());
+ int data_left = buffer.data_left();
+ if (data_left < p_frames || p_frames == 0) {
+ return PackedVector2Array();
+ }
+
+ PackedVector2Array ret;
+ ret.resize(p_frames);
+
+ Vector<AudioFrame> streaming_data;
+ streaming_data.resize(p_frames);
+ buffer.read(streaming_data.ptrw(), p_frames);
+ for (int32_t i = 0; i < p_frames; i++) {
+ ret.write[i] = Vector2(streaming_data[i].l, streaming_data[i].r);
+ }
+ return ret;
+}
+
+void AudioEffectCapture::clear_buffer() {
+ const int32_t data_left = buffer.data_left();
+ buffer.advance_read(data_left);
+}
+
+void AudioEffectCapture::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("can_get_buffer", "frames"), &AudioEffectCapture::can_get_buffer);
+ ClassDB::bind_method(D_METHOD("get_buffer", "frames"), &AudioEffectCapture::get_buffer);
+ ClassDB::bind_method(D_METHOD("clear_buffer"), &AudioEffectCapture::clear_buffer);
+ ClassDB::bind_method(D_METHOD("set_buffer_length", "buffer_length_seconds"), &AudioEffectCapture::set_buffer_length);
+ ClassDB::bind_method(D_METHOD("get_buffer_length"), &AudioEffectCapture::get_buffer_length);
+ ClassDB::bind_method(D_METHOD("get_frames_available"), &AudioEffectCapture::get_frames_available);
+ ClassDB::bind_method(D_METHOD("get_discarded_frames"), &AudioEffectCapture::get_discarded_frames);
+ ClassDB::bind_method(D_METHOD("get_buffer_length_frames"), &AudioEffectCapture::get_buffer_length_frames);
+ ClassDB::bind_method(D_METHOD("get_pushed_frames"), &AudioEffectCapture::get_pushed_frames);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.01,10,0.01"), "set_buffer_length", "get_buffer_length");
+}
+
+Ref<AudioEffectInstance> AudioEffectCapture::instance() {
+ if (!buffer_initialized) {
+ float target_buffer_size = AudioServer::get_singleton()->get_mix_rate() * buffer_length_seconds;
+ ERR_FAIL_COND_V(target_buffer_size <= 0 || target_buffer_size >= (1 << 27), Ref<AudioEffectInstance>());
+ buffer.resize(nearest_shift((int)target_buffer_size));
+ buffer_initialized = true;
+ }
+
+ clear_buffer();
+
+ Ref<AudioEffectCaptureInstance> ins;
+ ins.instance();
+ ins->base = Ref<AudioEffectCapture>(this);
+
+ return ins;
+}
+
+void AudioEffectCapture::set_buffer_length(float p_buffer_length_seconds) {
+ ERR_FAIL_COND(buffer_initialized);
+
+ buffer_length_seconds = p_buffer_length_seconds;
+}
+
+float AudioEffectCapture::get_buffer_length() {
+ return buffer_length_seconds;
+}
+
+int AudioEffectCapture::get_frames_available() const {
+ ERR_FAIL_COND_V(!buffer_initialized, 0);
+ return buffer.data_left();
+}
+
+int64_t AudioEffectCapture::get_discarded_frames() const {
+ return discarded_frames;
+}
+
+int AudioEffectCapture::get_buffer_length_frames() const {
+ ERR_FAIL_COND_V(!buffer_initialized, 0);
+ return buffer.size();
+}
+
+int64_t AudioEffectCapture::get_pushed_frames() const {
+ return pushed_frames;
+}
+
+void AudioEffectCaptureInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
+ RingBuffer<AudioFrame> &buffer = base->buffer;
+
+ for (int i = 0; i < p_frame_count; i++) {
+ p_dst_frames[i] = p_src_frames[i];
+ }
+
+ if (buffer.space_left() >= p_frame_count) {
+ // Add incoming audio frames to the IO ring buffer
+ int32_t ret = buffer.write(p_src_frames, p_frame_count);
+ ERR_FAIL_COND_MSG(ret != p_frame_count, "Failed to add data to effect capture ring buffer despite sufficient space.");
+ atomic_add(&base->pushed_frames, p_frame_count);
+ } else {
+ atomic_add(&base->discarded_frames, p_frame_count);
+ }
+}
+
+bool AudioEffectCaptureInstance::process_silence() const {
+ return true;
+}
diff --git a/servers/audio/effects/audio_effect_capture.h b/servers/audio/effects/audio_effect_capture.h
new file mode 100644
index 0000000000..b154be85de
--- /dev/null
+++ b/servers/audio/effects/audio_effect_capture.h
@@ -0,0 +1,82 @@
+/*************************************************************************/
+/* audio_effect_capture.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef AUDIO_EFFECT_CAPTURE_H
+#define AUDIO_EFFECT_CAPTURE_H
+
+#include "core/config/engine.h"
+#include "core/math/audio_frame.h"
+#include "core/object/reference.h"
+#include "core/templates/vector.h"
+#include "servers/audio/audio_effect.h"
+#include "servers/audio_server.h"
+
+class AudioEffectCapture;
+
+class AudioEffectCaptureInstance : public AudioEffectInstance {
+ GDCLASS(AudioEffectCaptureInstance, AudioEffectInstance);
+ friend class AudioEffectCapture;
+ Ref<AudioEffectCapture> base;
+
+public:
+ virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) override;
+ virtual bool process_silence() const override;
+};
+
+class AudioEffectCapture : public AudioEffect {
+ GDCLASS(AudioEffectCapture, AudioEffect)
+ friend class AudioEffectCaptureInstance;
+
+ RingBuffer<AudioFrame> buffer;
+ uint64_t discarded_frames = 0;
+ uint64_t pushed_frames = 0;
+ float buffer_length_seconds = 0.1f;
+ bool buffer_initialized = false;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual Ref<AudioEffectInstance> instance() override;
+
+ void set_buffer_length(float p_buffer_length_seconds);
+ float get_buffer_length();
+
+ bool can_get_buffer(int p_frames) const;
+ PackedVector2Array get_buffer(int p_len);
+ void clear_buffer();
+
+ int get_frames_available() const;
+ int64_t get_discarded_frames() const;
+ int get_buffer_length_frames() const;
+ int64_t get_pushed_frames() const;
+};
+
+#endif // AUDIO_EFFECT_CAPTURE_H
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index d4f7876b4b..16c6a26595 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -401,6 +401,7 @@ void AudioServer::_mix_step() {
for (int k = 0; k < bus->channels.size(); k++) {
if (!bus->channels[k].active) {
+ bus->channels.write[k].peak_volume = AudioFrame(AUDIO_MIN_PEAK_DB, AUDIO_MIN_PEAK_DB);
continue;
}
@@ -434,7 +435,7 @@ void AudioServer::_mix_step() {
}
}
- bus->channels.write[k].peak_volume = AudioFrame(Math::linear2db(peak.l + 0.0000000001), Math::linear2db(peak.r + 0.0000000001));
+ bus->channels.write[k].peak_volume = AudioFrame(Math::linear2db(peak.l + AUDIO_PEAK_OFFSET), Math::linear2db(peak.r + AUDIO_PEAK_OFFSET));
if (!bus->channels[k].used) {
//see if any audio is contained, because channel was not used
diff --git a/servers/audio_server.h b/servers/audio_server.h
index 51fbc59851..a1a373e1ca 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -199,7 +199,7 @@ private:
last_mix_with_audio = 0;
used = false;
active = false;
- peak_volume = AudioFrame(0, 0);
+ peak_volume = AudioFrame(AUDIO_MIN_PEAK_DB, AUDIO_MIN_PEAK_DB);
}
};
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 58bcdf5802..50efd7c554 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -36,6 +36,7 @@
#include "audio/audio_effect.h"
#include "audio/audio_stream.h"
#include "audio/effects/audio_effect_amplify.h"
+#include "audio/effects/audio_effect_capture.h"
#include "audio/effects/audio_effect_chorus.h"
#include "audio/effects/audio_effect_compressor.h"
#include "audio/effects/audio_effect_delay.h"
@@ -166,6 +167,8 @@ void register_server_types() {
ClassDB::register_class<AudioEffectRecord>();
ClassDB::register_class<AudioEffectSpectrumAnalyzer>();
ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>();
+
+ ClassDB::register_class<AudioEffectCapture>();
}
ClassDB::register_virtual_class<RenderingDevice>();