diff options
-rw-r--r-- | editor/editor_audio_buses.cpp | 2 | ||||
-rw-r--r-- | editor/editor_autoload_settings.cpp | 2 | ||||
-rw-r--r-- | editor/editor_node.cpp | 6 | ||||
-rw-r--r-- | editor/plugins/sprite_frames_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | editor/spatial_editor_gizmos.cpp | 2 | ||||
-rw-r--r-- | modules/visual_script/visual_script_editor.cpp | 2 | ||||
-rw-r--r-- | platform/x11/context_gl_x11.cpp | 14 | ||||
-rw-r--r-- | platform/x11/os_x11.cpp | 11 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 2 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 32 | ||||
-rw-r--r-- | scene/gui/tree.h | 9 | ||||
-rw-r--r-- | scene/main/scene_tree.cpp | 79 | ||||
-rw-r--r-- | scene/resources/sky_box.cpp | 63 | ||||
-rw-r--r-- | scene/resources/sky_box.h | 11 | ||||
-rw-r--r-- | scene/resources/style_box.cpp | 2 | ||||
-rw-r--r-- | servers/audio_server.cpp | 74 | ||||
-rw-r--r-- | servers/audio_server.h | 2 |
17 files changed, 182 insertions, 133 deletions
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 993429a5a4..282055be4a 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -705,8 +705,8 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses) { effects->set_drag_forwarding(this); effects->connect("item_rmb_selected", this, "_effect_rmb"); effects->set_allow_rmb_select(true); - effects->set_single_select_cell_editing_only_when_already_selected(true); effects->set_focus_mode(FOCUS_CLICK); + effects->set_allow_reselect(true); send = memnew(OptionButton); send->set_clip_text(true); diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index dde94cb334..0d7874818c 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -580,7 +580,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() { tree = memnew(Tree); tree->set_hide_root(true); tree->set_select_mode(Tree::SELECT_MULTI); - tree->set_single_select_cell_editing_only_when_already_selected(true); + tree->set_allow_reselect(true); tree->set_drag_forwarding(this); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 242648d4a9..a5f0478854 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -371,6 +371,7 @@ void EditorNode::_fs_changed() { if (preset->get_name() == export_defer.preset) { break; } + preset.unref(); } if (preset.is_null()) { String err = "Unknown export preset: " + export_defer.preset; @@ -385,7 +386,7 @@ void EditorNode::_fs_changed() { } } - export_defer.preset = ""; + get_tree()->quit(); } { @@ -3939,6 +3940,7 @@ void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) { splits[i]->hide(); } + _edit_current(); _save_docks(); } } @@ -3966,6 +3968,7 @@ void EditorNode::_dock_move_left() { dock_slot[dock_popup_selected]->move_child(current, prev->get_index()); dock_slot[dock_popup_selected]->set_current_tab(dock_slot[dock_popup_selected]->get_current_tab() - 1); dock_select->update(); + _edit_current(); _save_docks(); } @@ -3978,6 +3981,7 @@ void EditorNode::_dock_move_right() { dock_slot[dock_popup_selected]->move_child(next, current->get_index()); dock_slot[dock_popup_selected]->set_current_tab(dock_slot[dock_popup_selected]->get_current_tab() + 1); dock_select->update(); + _edit_current(); _save_docks(); } diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 0f008552d0..0608ecec58 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -747,7 +747,7 @@ SpriteFramesEditor::SpriteFramesEditor() { animations->set_hide_root(true); animations->connect("cell_selected", this, "_animation_select"); animations->connect("item_edited", this, "_animation_name_edited"); - animations->set_single_select_cell_editing_only_when_already_selected(true); + animations->set_allow_reselect(true); anim_speed = memnew(SpinBox); vbc_animlist->add_margin_child(TTR("Speed (FPS):"), anim_speed); diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 24be2095ce..0e6e7420e2 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -1150,7 +1150,7 @@ CameraSpatialGizmo::CameraSpatialGizmo(Camera *p_camera) { void MeshInstanceSpatialGizmo::redraw() { - Ref<ArrayMesh> m = mesh->get_mesh(); + Ref<Mesh> m = mesh->get_mesh(); if (!m.is_valid()) return; //none diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index a39491ef5b..9a1033e954 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -3234,7 +3234,7 @@ VisualScriptEditor::VisualScriptEditor() { members->connect("button_pressed", this, "_member_button"); members->connect("item_edited", this, "_member_edited"); members->connect("cell_selected", this, "_member_selected", varray(), CONNECT_DEFERRED); - members->set_single_select_cell_editing_only_when_already_selected(true); + members->set_allow_reselect(true); members->set_hide_folding(true); members->set_drag_forwarding(this); diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index ddf17481b1..f055d730db 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -83,6 +83,19 @@ static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) { return 0; } +static void set_class_hint(Display *p_display, Window p_window) { + XClassHint *classHint; + + /* set the name and class hints for the window manager to use */ + classHint = XAllocClassHint(); + if (classHint) { + classHint->res_name = (char *)"Godot_Engine"; + classHint->res_class = (char *)"Godot"; + } + XSetClassHint(p_display, p_window, classHint); + XFree(classHint); +} + Error ContextGL_X11::initialize() { GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = NULL; @@ -127,6 +140,7 @@ Error ContextGL_X11::initialize() { */ x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED); + set_class_hint(x11_display, x11_window); XMapWindow(x11_display, x11_window); //}; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index ade3a0a0c5..a23f2f1320 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -351,20 +351,9 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au XChangeWindowAttributes(x11_display, x11_window, CWEventMask, &new_attr); - XClassHint *classHint; - /* set the titlebar name */ XStoreName(x11_display, x11_window, "Godot"); - /* set the name and class hints for the window manager to use */ - classHint = XAllocClassHint(); - if (classHint) { - classHint->res_name = (char *)"Godot_Engine"; - classHint->res_class = (char *)"Godot"; - } - XSetClassHint(x11_display, x11_window, classHint); - XFree(classHint); - wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true); XSetWMProtocols(x11_display, x11_window, &wm_delete, 1); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 324c0cd0d1..2b111c50a6 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1028,6 +1028,8 @@ void TextEdit::_notification(int p_what) { if (cursor.column == j && cursor.line == line && block_caret && draw_caret && !insert_mode) { color = cache.caret_background_color; + } else if (!syntax_coloring && block_caret) { + color = cache.font_color; } if (str[j] >= 32) { diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index fa499ff277..3e8d8aed8a 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1455,7 +1455,7 @@ void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_c if (select_mode == SELECT_ROW) { - if (p_selected == p_current && !c.selected) { + if (p_selected == p_current && (!c.selected || allow_reselect)) { c.selected = true; selected_item = p_selected; selected_col = 0; @@ -1478,7 +1478,7 @@ void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_c if (!r_in_range && &selected_cell == &c) { - if (!selected_cell.selected || force_select_on_already_selected) { + if (!selected_cell.selected || allow_reselect) { selected_cell.selected = true; @@ -1743,7 +1743,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool /* editing */ - bool bring_up_editor = force_select_on_already_selected ? (c.selected && already_selected) : c.selected; + bool bring_up_editor = allow_reselect ? (c.selected && already_selected) : c.selected; String editor_text = c.text; switch (c.mode) { @@ -3557,16 +3557,6 @@ int Tree::get_drop_mode_flags() const { return drop_mode_flags; } -void Tree::set_single_select_cell_editing_only_when_already_selected(bool p_enable) { - - force_select_on_already_selected = p_enable; -} - -bool Tree::get_single_select_cell_editing_only_when_already_selected() const { - - return force_select_on_already_selected; -} - void Tree::set_edit_checkbox_cell_only_when_checkbox_is_pressed(bool p_enable) { force_edit_checkbox_only_on_checkbox = p_enable; @@ -3587,6 +3577,15 @@ bool Tree::get_allow_rmb_select() const { return allow_rmb_select; } +void Tree::set_allow_reselect(bool p_allow) { + allow_reselect = p_allow; +} + +bool Tree::get_allow_reselect() const { + + return allow_reselect; +} + void Tree::_bind_methods() { ClassDB::bind_method(D_METHOD("_range_click_timeout"), &Tree::_range_click_timeout); @@ -3640,8 +3639,8 @@ void Tree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_allow_rmb_select", "allow"), &Tree::set_allow_rmb_select); ClassDB::bind_method(D_METHOD("get_allow_rmb_select"), &Tree::get_allow_rmb_select); - ClassDB::bind_method(D_METHOD("set_single_select_cell_editing_only_when_already_selected", "enable"), &Tree::set_single_select_cell_editing_only_when_already_selected); - ClassDB::bind_method(D_METHOD("get_single_select_cell_editing_only_when_already_selected"), &Tree::get_single_select_cell_editing_only_when_already_selected); + ClassDB::bind_method(D_METHOD("set_allow_reselect", "allow"), &Tree::set_allow_reselect); + ClassDB::bind_method(D_METHOD("get_allow_reselect"), &Tree::get_allow_reselect); ADD_SIGNAL(MethodInfo("item_selected")); ADD_SIGNAL(MethodInfo("cell_selected")); @@ -3751,7 +3750,6 @@ Tree::Tree() { drop_mode_over = NULL; drop_mode_section = 0; single_select_defer = NULL; - force_select_on_already_selected = false; allow_rmb_select = false; force_edit_checkbox_only_on_checkbox = false; @@ -3760,6 +3758,8 @@ Tree::Tree() { cache.hover_item = NULL; cache.hover_cell = -1; + + allow_reselect = false; } Tree::~Tree() { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 81880122a9..1e46956cd9 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -490,7 +490,8 @@ private: bool allow_rmb_select; bool scrolling; - bool force_select_on_already_selected; + bool allow_reselect; + bool force_edit_checkbox_only_on_checkbox; bool hide_folding; @@ -566,15 +567,15 @@ public: void set_drop_mode_flags(int p_flags); int get_drop_mode_flags() const; - void set_single_select_cell_editing_only_when_already_selected(bool p_enable); - bool get_single_select_cell_editing_only_when_already_selected() const; - void set_edit_checkbox_cell_only_when_checkbox_is_pressed(bool p_enable); bool get_edit_checkbox_cell_only_when_checkbox_is_pressed() const; void set_allow_rmb_select(bool p_allow); bool get_allow_rmb_select() const; + void set_allow_reselect(bool p_allow); + bool get_allow_reselect() const; + void set_value_evaluator(ValueEvaluator *p_evaluator); Tree(); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 66eafa1070..2e67a1feaf 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -392,86 +392,11 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) { Ref<InputEvent> ev = p_event; ev->set_id(++last_id); //this should work better -#if 0 - switch(ev.type) { - - case InputEvent::MOUSE_BUTTON: { - - Matrix32 ai = root->get_final_transform().affine_inverse(); - Vector2 g = ai.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y)); - Vector2 l = ai.xform(Vector2(ev->get_pos().x,ev->get_pos().y)); - ev->get_pos().x=l.x; - ev->get_pos().y=l.y; - ev.mouse_button.global_x=g.x; - ev.mouse_button.global_y=g.y; - - } break; - case InputEvent::MOUSE_MOTION: { - - Matrix32 ai = root->get_final_transform().affine_inverse(); - Vector2 g = ai.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y)); - Vector2 l = ai.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y)); - Vector2 r = ai.xform(Vector2(ev->get_relative().x,ev->get_relative().y)); - ev.mouse_motion.x=l.x; - ev.mouse_motion.y=l.y; - ev.mouse_motion.global_x=g.x; - ev.mouse_motion.global_y=g.y; - ev->get_relative().x=r.x; - ev->get_relative().y=r.y; - - } break; - case InputEvent::SCREEN_TOUCH: { - - Matrix32 ai = root->get_final_transform().affine_inverse(); - Vector2 t = ai.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y)); - ev.screen_touch.x=t.x; - ev.screen_touch.y=t.y; - - } break; - case InputEvent::SCREEN_DRAG: { - - Matrix32 ai = root->get_final_transform().affine_inverse(); - Vector2 t = ai.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y)); - Vector2 r = ai.xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y)); - Vector2 s = ai.xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y)); - ev.screen_drag.x=t.x; - ev.screen_drag.y=t.y; - ev.screen_drag.relative_x=r.x; - ev.screen_drag.relative_y=r.y; - ev.screen_drag.speed_x=s.x; - ev.screen_drag.speed_y=s.y; - } break; - } - -#endif MainLoop::input_event(ev); -#if 0 - _call_input_pause("input","_input",ev); - - call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"_gui_input","_gui_input",p_event); //special one for GUI, as controls use their own process check - - //call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"input","_input",ev); - - /* - if (ev.type==InputEvent::KEY && ev->is_pressed() && !ev->is_echo() && ev->get_scancode()==KEY_F12) { - - print_line("RAM: "+itos(Memory::get_static_mem_usage())); - print_line("DRAM: "+itos(Memory::get_dynamic_mem_usage())); - } - if (ev.type==InputEvent::KEY && ev->is_pressed() && !ev->is_echo() && ev->get_scancode()==KEY_F11) { - - Memory::dump_static_mem_to_file("memdump.txt"); - } - */ - - //transform for the rest -#else call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_vp_input", ev); //special one for GUI, as controls use their own process check -#endif - if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_remote()) { //quit from game window using F8 Ref<InputEventKey> k = ev; @@ -482,7 +407,7 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) { _flush_ugc(); root_lock--; - MessageQueue::get_singleton()->flush(); //small little hack + //MessageQueue::get_singleton()->flush(); //flushing here causes UI and other places slowness root_lock++; @@ -503,7 +428,7 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) { input_handled = true; _flush_ugc(); root_lock--; - MessageQueue::get_singleton()->flush(); //small little hack + //MessageQueue::get_singleton()->flush(); //flushing here causes UI and other places slowness } else { input_handled = true; root_lock--; diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp index 5750960845..cc3cfe4dc0 100644 --- a/scene/resources/sky_box.cpp +++ b/scene/resources/sky_box.cpp @@ -128,7 +128,7 @@ void ProceduralSky::_radiance_changed() { VS::get_singleton()->sky_set_texture(sky, texture, size[get_radiance_size()]); } -void ProceduralSky::_update_sky() { +Ref<Image> ProceduralSky::_generate_sky() { update_queued = false; @@ -215,9 +215,7 @@ void ProceduralSky::_update_sky() { image.instance(); image->create(w, h, false, Image::FORMAT_RGBE9995, imgdata); - VS::get_singleton()->texture_allocate(texture, w, h, Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT); - VS::get_singleton()->texture_set_data(texture, image); - _radiance_changed(); + return image; } void ProceduralSky::set_sky_top_color(const Color &p_sky_top) { @@ -385,6 +383,33 @@ RID ProceduralSky::get_rid() const { return sky; } +void ProceduralSky::_update_sky() { + + bool use_thread = true; + if (first_time) { + use_thread = false; + first_time = false; + } +#ifdef NO_THREADS + use_thread = false; +#endif + if (use_thread) { + + if (!sky_thread) { + sky_thread = Thread::create(_thread_function, this); + regen_queued = false; + } else { + regen_queued = true; + } + + } else { + Ref<Image> image = _generate_sky(); + VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT); + VS::get_singleton()->texture_set_data(texture, image); + _radiance_changed(); + } +} + void ProceduralSky::_queue_update() { if (update_queued) @@ -394,6 +419,26 @@ void ProceduralSky::_queue_update() { call_deferred("_update_sky"); } +void ProceduralSky::_thread_done(const Ref<Image> &image) { + + VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT); + VS::get_singleton()->texture_set_data(texture, image); + _radiance_changed(); + Thread::wait_to_finish(sky_thread); + memdelete(sky_thread); + sky_thread = NULL; + if (regen_queued) { + sky_thread = Thread::create(_thread_function, this); + regen_queued = false; + } +} + +void ProceduralSky::_thread_function(void *p_ud) { + + ProceduralSky *psky = (ProceduralSky *)p_ud; + psky->call_deferred("_thread_done", psky->_generate_sky()); +} + void ProceduralSky::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_sky"), &ProceduralSky::_update_sky); @@ -446,6 +491,8 @@ void ProceduralSky::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture_size", "size"), &ProceduralSky::set_texture_size); ClassDB::bind_method(D_METHOD("get_texture_size"), &ProceduralSky::get_texture_size); + ClassDB::bind_method(D_METHOD("_thread_done", "image"), &ProceduralSky::_thread_done); + ADD_GROUP("Sky", "sky_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color"), "set_sky_top_color", "get_sky_top_color"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color"), "set_sky_horizon_color", "get_sky_horizon_color"); @@ -503,12 +550,20 @@ ProceduralSky::ProceduralSky() { sun_energy = 16; texture_size = TEXTURE_SIZE_1024; + sky_thread = NULL; + regen_queued = false; + first_time = true; _queue_update(); } ProceduralSky::~ProceduralSky() { + if (sky_thread) { + Thread::wait_to_finish(sky_thread); + memdelete(sky_thread); + sky_thread = NULL; + } VS::get_singleton()->free(sky); VS::get_singleton()->free(texture); } diff --git a/scene/resources/sky_box.h b/scene/resources/sky_box.h index 8298d1b3c0..9bd60cddaf 100644 --- a/scene/resources/sky_box.h +++ b/scene/resources/sky_box.h @@ -30,8 +30,8 @@ #ifndef Sky_H #define Sky_H +#include "os/thread.h" #include "scene/resources/texture.h" - class Sky : public Resource { GDCLASS(Sky, Resource); @@ -97,6 +97,7 @@ public: }; private: + Thread *sky_thread; Color sky_top_color; Color sky_horizon_color; float sky_curve; @@ -121,12 +122,20 @@ private: RID texture; bool update_queued; + bool regen_queued; + + bool first_time; + + void _thread_done(const Ref<Image> &p_image); + static void _thread_function(void *p_ud); protected: static void _bind_methods(); virtual void _radiance_changed(); + Ref<Image> _generate_sky(); void _update_sky(); + void _queue_update(); public: diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 48efa242e9..67bc5b30ff 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -717,7 +717,7 @@ void StyleBoxFlat::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bg_color"), &StyleBoxFlat::get_bg_color); ClassDB::bind_method(D_METHOD("set_border_color", "color"), &StyleBoxFlat::set_border_color_all); - ClassDB::bind_method(D_METHOD("get_border_color", "color"), &StyleBoxFlat::get_border_color_all); + ClassDB::bind_method(D_METHOD("get_border_color"), &StyleBoxFlat::get_border_color_all); ClassDB::bind_method(D_METHOD("set_border_width_all", "width"), &StyleBoxFlat::set_border_width_all); ClassDB::bind_method(D_METHOD("get_border_width_min"), &StyleBoxFlat::get_border_width_min); diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 3547f86eb3..f9fdd9432d 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -159,6 +159,8 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { void AudioServer::_mix_step() { + bool solo_mode = false; + for (int i = 0; i < buses.size(); i++) { Bus *bus = buses[i]; bus->index_cache = i; //might be moved around by editor, so.. @@ -166,6 +168,33 @@ void AudioServer::_mix_step() { bus->channels[k].used = false; } + + if (bus->solo) { + //solo chain + solo_mode = true; + bus->soloed = true; + do { + + if (bus != buses[0]) { + //everything has a send save for master bus + if (!bus_map.has(bus->send)) { + bus = buses[0]; //send to master + } else { + bus = bus_map[bus->send]; + if (bus->index_cache >= bus->index_cache) { //invalid, send to master + bus = buses[0]; + } + } + + bus->soloed = true; + } else { + bus = NULL; + } + + } while (bus); + } else { + bus->soloed = false; + } } //make callbacks for mixing the audio @@ -192,24 +221,26 @@ void AudioServer::_mix_step() { } //process effects - for (int j = 0; j < bus->effects.size(); j++) { + if (!bus->bypass) { + for (int j = 0; j < bus->effects.size(); j++) { - if (!bus->effects[j].enabled) - continue; + if (!bus->effects[j].enabled) + continue; - for (int k = 0; k < bus->channels.size(); k++) { + for (int k = 0; k < bus->channels.size(); k++) { - if (!bus->channels[k].active) - continue; - bus->channels[k].effect_instances[j]->process(bus->channels[k].buffer.ptr(), temp_buffer[k].ptr(), buffer_size); - } + if (!bus->channels[k].active) + continue; + bus->channels[k].effect_instances[j]->process(bus->channels[k].buffer.ptr(), temp_buffer[k].ptr(), buffer_size); + } - //swap buffers, so internal buffer always has the right data - for (int k = 0; k < bus->channels.size(); k++) { + //swap buffers, so internal buffer always has the right data + for (int k = 0; k < bus->channels.size(); k++) { - if (!buses[i]->channels[k].active) - continue; - SWAP(bus->channels[k].buffer, temp_buffer[k]); + if (!buses[i]->channels[k].active) + continue; + SWAP(bus->channels[k].buffer, temp_buffer[k]); + } } } @@ -237,7 +268,24 @@ void AudioServer::_mix_step() { AudioFrame *buf = bus->channels[k].buffer.ptr(); AudioFrame peak = AudioFrame(0, 0); + + float volume = Math::db2linear(bus->volume_db); + + if (solo_mode) { + if (!bus->soloed) { + volume = 0.0; + } + } else { + if (bus->mute) { + volume = 0.0; + } + } + + //apply volume and compute peak for (uint32_t j = 0; j < buffer_size; j++) { + + buf[j] *= volume; + float l = ABS(buf[j].l); if (l > peak.l) { peak.l = l; diff --git a/servers/audio_server.h b/servers/audio_server.h index caa07891f7..c92ff6d3a0 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -125,6 +125,8 @@ private: bool mute; bool bypass; + bool soloed; + //Each channel is a stereo pair. struct Channel { bool used; |