From 3cfbd33d624a3736321fd48b03dee89a7c4eff6d Mon Sep 17 00:00:00 2001 From: Tanasart Date: Fri, 26 Apr 2024 18:21:25 +0700 Subject: [PATCH] - [Feedback] Fix inline feedback not working. --- .../_node_VFX_spawner.gml.backup0 | 16 +- .../_node_VFX_spawner.gml.backup1 | 20 +- .../scripts/node_blend/node_blend.gml.backup0 | 301 ++++++++++++++ .../scripts/node_blend/node_blend.gml.backup1 | 301 ++++++++++++++ .../node_feedback_inline.gml.backup0 | 86 ++++ .../node_feedback_inline.gml.backup1 | 86 ++++ .../node_path_bridge.gml.backup0 | 3 +- .../node_path_bridge.gml.backup1 | 3 +- .../node_processor/node_processor.gml.backup0 | 386 ++++++++++++++++++ .../node_processor/node_processor.gml.backup1 | 386 ++++++++++++++++++ .../scripts/node_value/node_value.gml.backup0 | 2 +- .../scripts/node_value/node_value.gml.backup1 | 2 +- .../panel_preview/panel_preview.gml.backup0 | 2 +- .../panel_preview/panel_preview.gml.backup1 | 2 +- .../surface_functions.gml.backup0 | 10 +- .../surface_functions.gml.backup1 | 5 +- #backups/shaders/sh_FXAA/sh_FXAA.fsh.backup0 | 66 +++ .../_node_VFX_spawner/_node_VFX_spawner.gml | 14 +- scripts/node_blend/node_blend.gml | 62 +-- .../node_feedback_inline.gml | 15 +- scripts/node_path_bridge/node_path_bridge.gml | 1 + scripts/node_processor/node_processor.gml | 17 +- .../surface_functions/surface_functions.gml | 8 +- 23 files changed, 1729 insertions(+), 65 deletions(-) create mode 100644 #backups/scripts/node_blend/node_blend.gml.backup0 create mode 100644 #backups/scripts/node_blend/node_blend.gml.backup1 create mode 100644 #backups/scripts/node_feedback_inline/node_feedback_inline.gml.backup0 create mode 100644 #backups/scripts/node_feedback_inline/node_feedback_inline.gml.backup1 create mode 100644 #backups/scripts/node_processor/node_processor.gml.backup0 create mode 100644 #backups/scripts/node_processor/node_processor.gml.backup1 create mode 100644 #backups/shaders/sh_FXAA/sh_FXAA.fsh.backup0 diff --git a/#backups/scripts/_node_VFX_spawner/_node_VFX_spawner.gml.backup0 b/#backups/scripts/_node_VFX_spawner/_node_VFX_spawner.gml.backup0 index 692dd7a49..64ef24b69 100644 --- a/#backups/scripts/_node_VFX_spawner/_node_VFX_spawner.gml.backup0 +++ b/#backups/scripts/_node_VFX_spawner/_node_VFX_spawner.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-26 09:58:54 +// 2024-04-26 16:29:55 function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Spawner"; update_on_frame = true; @@ -356,8 +356,18 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co if(array_empty(surfs)) return; for( var i = 0, n = array_length(surfs); i < n; i++ ) { - if(is_surface(surface_cache[$ surfs[i]])) continue; - surface_cache[$ surfs[i]] = surface_clone(surfs[i]); + var _s = surfs[i]; + + if(is_surface(surface_cache[$ _s])) + continue; + + if(is_instanceof(_s, SurfaceAtlas)) + _s = _s.surface.get(); + + if(!surface_exists(_s)) + continue; + + surface_cache[$ surfs[i]] = surface_clone(_s); } } #endregion diff --git a/#backups/scripts/_node_VFX_spawner/_node_VFX_spawner.gml.backup1 b/#backups/scripts/_node_VFX_spawner/_node_VFX_spawner.gml.backup1 index 4f5e7a332..5c9696149 100644 --- a/#backups/scripts/_node_VFX_spawner/_node_VFX_spawner.gml.backup1 +++ b/#backups/scripts/_node_VFX_spawner/_node_VFX_spawner.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-26 09:57:25 +// 2024-04-26 16:29:54 function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Spawner"; update_on_frame = true; @@ -100,9 +100,7 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co inputs[| 30] = nodeValue("Distribution map", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone) .rejectArray() - inputs[| 31] = nodeValue("Atlas", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, [] ) - .setArrayDepth(1) - .rejectArray(); + inputs[| 31] = nodeValue("Atlas", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, [] ); inputs[| 32] = nodeValue("Seed", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, irandom_range(100000, 999999)) .rejectArray(); @@ -358,8 +356,18 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co if(array_empty(surfs)) return; for( var i = 0, n = array_length(surfs); i < n; i++ ) { - if(is_surface(surface_cache[$ surfs[i]])) continue; - surface_cache[$ surfs[i]] = surface_clone(surfs[i]); + var _s = surfs[i]; + + if(is_surface(surface_cache[$ _s])) + continue; + + if(is_instanceof(_s, SurfaceAtlas)) + _s = _s.surface.get(); + + if(!surface_exists(_s)) + continue; + + surface_cache[$ surfs[i]] = surface_clone(_s); } } #endregion diff --git a/#backups/scripts/node_blend/node_blend.gml.backup0 b/#backups/scripts/node_blend/node_blend.gml.backup0 new file mode 100644 index 000000000..f062b4c5c --- /dev/null +++ b/#backups/scripts/node_blend/node_blend.gml.backup0 @@ -0,0 +1,301 @@ +// 2024-04-26 15:43:17 +#region create + global.node_blend_keys = [ + "normal", "add", "subtract", "multiply", "screen", + "overlay", "hue", "saturation", "luminosity", "maximum", + "minimum", "replace", "difference" + ]; + + function Node_create_Blend(_x, _y, _group = noone, _param = {}) { + var node = new Node_Blend(_x, _y, _group); + var query = struct_try_get(_param, "query", ""); + + var ind = array_find(global.node_blend_keys, query); + if(ind >= 0) node.inputs[| 2].setValue(ind); + + return node; + } + + enum NODE_BLEND_OUTPUT { + background, + foreground, + mask, + maximum, + constant + } + + enum NODE_BLEND_FILL { + none, + stretch, + tile + } +#endregion + +function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Blend"; + manage_atlas = false; + + inputs[| 0] = nodeValue("Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + inputs[| 1] = nodeValue("Foreground", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 2] = nodeValue("Blend mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, BLEND_TYPES ); + + inputs[| 3] = nodeValue("Opacity", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1) + .setDisplay(VALUE_DISPLAY.slider); + + inputs[| 4] = nodeValue("Mask", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 5] = nodeValue("Fill mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "None", "Stretch", "Tile" ]); + + inputs[| 6] = nodeValue("Output dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Background", "Forground", "Mask", "Maximum", "Constant" ]) + .rejectArray(); + + inputs[| 7] = nodeValue("Constant dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF) + .setDisplay(VALUE_DISPLAY.vector); + + inputs[| 8] = nodeValue("Active", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + active_index = 8; + + inputs[| 9] = nodeValue("Preserve alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 10] = nodeValue("Horizontal Align", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_button, [ THEME.inspector_surface_halign, THEME.inspector_surface_halign, THEME.inspector_surface_halign]); + + inputs[| 11] = nodeValue("Vertical Align", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_button, [ THEME.inspector_surface_valign, THEME.inspector_surface_valign, THEME.inspector_surface_valign]); + + inputs[| 12] = nodeValue("Invert mask", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 13] = nodeValue("Mask feather", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1) + .setDisplay(VALUE_DISPLAY.slider, { range: [1, 16, 0.1] }); + + inputs[| 14] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0.5, 0.5 ]) + .setDisplay(VALUE_DISPLAY.vector); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ 8, + ["Surfaces", true], 0, 1, 4, 12, 13, 6, 7, + ["Blend", false], 2, 3, 9, + ["Transform", false], 5, 14, + ] + + attribute_surface_depth(); + + temp_surface = [ surface_create(1, 1), surface_create(1, 1) ]; + blend_temp_surface = temp_surface[1]; + + dragging = false; + drag_sx = 0; + drag_sy = 0; + drag_mx = 0; + drag_my = 0; + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + var _surf = outputs[| 0].getValue(); + if(is_array(_surf)) _surf = array_safe_get_fast(_surf, preview_index); + if(is_struct(_surf)) return; + if(!surface_exists(_surf)) return; + + var _fore = getSingleValue( 1); + var _fill = getSingleValue( 5); + var _posi = getSingleValue(14); + if(_fill) return; + + var sw = surface_get_width_safe( _surf); + var sh = surface_get_height_safe(_surf); + var fw = surface_get_width_safe( _fore); + var fh = surface_get_height_safe(_fore); + + var _rx = _posi[0] * sw - fw / 2; + var _ry = _posi[1] * sh - fh / 2; + _rx = _x + _rx * _s; + _ry = _y + _ry * _s; + var _rw = fw * _s; + var _rh = fh * _s; + + if(dragging) { + var px = drag_sx + (_mx - drag_mx) / _s; + var py = drag_sy + (_my - drag_my) / _s; + + px /= sw; + py /= sh; + + if(inputs[| 14].setValue([ px, py ])) + UNDO_HOLDING = true; + + if(mouse_release(mb_left)) { + UNDO_HOLDING = false; + dragging = false; + } + } + + draw_set_color(COLORS._main_accent); + if(dragging || (active && point_in_rectangle(_mx, _my, _rx, _ry, _rx + _rw, _ry + _rh))) { + draw_rectangle_width(_rx, _ry, _rx + _rw, _ry + _rh, 2); + + if(mouse_press(mb_left)) { + dragging = true; + drag_sx = _posi[0] * sw; + drag_sy = _posi[1] * sh; + drag_mx = _mx; + drag_my = _my; + } + } else + draw_rectangle(_rx, _ry, _rx + _rw, _ry + _rh, true); + } #endregion + + static step = function() { #region + var _back = getSingleValue(0); + var _fore = getSingleValue(1); + var _fill = getSingleValue(5); + var _outp = getSingleValue(6); + + var _atlas = is_instanceof(_fore, SurfaceAtlas); + + inputs[| 5].setVisible(!_atlas); + inputs[| 6].editWidget.data_list = _atlas? [ "Background", "Forground" ] : [ "Background", "Forground", "Mask", "Maximum", "Constant" ]; + inputs[| 7].setVisible(_outp == 4); + + inputs[| 14].setVisible(_fill == 0 && !_atlas); + } #endregion + + static processData = function(_outSurf, _data, _output_index, _array_index) { #region + var _back = _data[0]; + var _fore = _data[1]; + var _type = _data[2]; + var _opacity = _data[3]; + var _mask = _data[4]; + var _fill = _data[5]; + + var _outp = _data[6]; + var _out_dim = _data[7]; + var _pre_alp = _data[9]; + + var _halign = _data[10]; + var _valign = _data[11]; + var _posit = _data[14]; + + var _mskInv = _data[12]; + var _mskFea = _data[13]; + + var cDep = attrDepth(); + + #region dimension + var ww = 1; + var hh = 1; + var _atlas = is_instanceof(_fore, SurfaceAtlas); + + switch(_outp) { + case NODE_BLEND_OUTPUT.background : + ww = surface_get_width_safe(_back); + hh = surface_get_height_safe(_back); + break; + + case NODE_BLEND_OUTPUT.foreground : + ww = surface_get_width_safe(_fore); + hh = surface_get_height_safe(_fore); + break; + + case NODE_BLEND_OUTPUT.mask : + ww = surface_get_width_safe(_mask); + hh = surface_get_height_safe(_mask); + break; + + case NODE_BLEND_OUTPUT.maximum : + ww = max(surface_get_width_safe(_back), surface_get_width_safe(_fore), surface_get_width_safe(_mask)); + hh = max(surface_get_height_safe(_back), surface_get_height_safe(_fore), surface_get_height_safe(_mask)); + break; + + case NODE_BLEND_OUTPUT.constant : + ww = _out_dim[0]; + hh = _out_dim[1]; + break; + } + #endregion + + for( var i = 0; i < 2; i++ ) temp_surface[i] = surface_verify(temp_surface[i], ww, hh, cDep); + + var _backDraw = temp_surface[0]; + var _foreDraw = temp_surface[1]; + + surface_set_shader(_backDraw, noone,, BLEND.over); + draw_surface_safe(_back); + surface_reset_shader(); + + if(_fill == NODE_BLEND_FILL.none || _atlas) { + + if(_atlas) { + if(_outp == NODE_BLEND_OUTPUT.background) { + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_safe(_fore.getSurface(), _fore.x, _fore.y); + surface_reset_shader(); + + _backDraw = _back; + + } else if(_outp == NODE_BLEND_OUTPUT.foreground) { + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_safe(_fore, 0, 0); + surface_reset_shader(); + + surface_set_shader(_backDraw, noone,, BLEND.over); + draw_surface_safe(_back, -_fore.x, -_fore.y); + surface_reset_shader(); + } + + } else if(is_surface(_fore)) { + var sx = 0; + var sy = 0; + + var fw = surface_get_width_safe(_fore); + var fh = surface_get_height_safe(_fore); + + var px = _posit[0] * ww; + var py = _posit[1] * hh; + + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_safe(_fore, px - fw / 2, py - fh / 2); + surface_reset_shader(); + + _backDraw = _back; + } + + } else if(_fill == NODE_BLEND_FILL.stretch) { + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_stretched(_fore, 0, 0, ww, hh); + surface_reset_shader(); + + } else if(_fill == NODE_BLEND_FILL.tile) { + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_tiled(_fore, 0, 0); + surface_reset_shader(); + } + + var _osurf = is_instanceof(_outSurf, SurfaceAtlas)? _outSurf.surface.surface : _outSurf; + var _output = surface_verify(_osurf, ww, hh, cDep); + + _mask = mask_modify(_mask, _mskInv, _mskFea); + + surface_set_shader(_output, noone); + if(is_surface(_fore)) draw_surface_blend(_backDraw, _foreDraw, _type, _opacity, _pre_alp, _mask); + else draw_surface_safe(_backDraw); + surface_reset_shader(); + + if(_atlas) { + var _newAtl = _fore.clone(); + + if(_outp == NODE_BLEND_OUTPUT.background) { + _newAtl.x = 0; + _newAtl.y = 0; + } + + _newAtl.setSurface(_output); + return _newAtl; + } + + return _outSurf; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_blend/node_blend.gml.backup1 b/#backups/scripts/node_blend/node_blend.gml.backup1 new file mode 100644 index 000000000..c714310e6 --- /dev/null +++ b/#backups/scripts/node_blend/node_blend.gml.backup1 @@ -0,0 +1,301 @@ +// 2024-04-26 15:41:59 +#region create + global.node_blend_keys = [ + "normal", "add", "subtract", "multiply", "screen", + "overlay", "hue", "saturation", "luminosity", "maximum", + "minimum", "replace", "difference" + ]; + + function Node_create_Blend(_x, _y, _group = noone, _param = {}) { + var node = new Node_Blend(_x, _y, _group); + var query = struct_try_get(_param, "query", ""); + + var ind = array_find(global.node_blend_keys, query); + if(ind >= 0) node.inputs[| 2].setValue(ind); + + return node; + } + + enum NODE_BLEND_OUTPUT { + background, + foreground, + mask, + maximum, + constant + } + + enum NODE_BLEND_FILL { + none, + stretch, + tile + } +#endregion + +function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Blend"; + manage_atlas = false; + + inputs[| 0] = nodeValue("Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + inputs[| 1] = nodeValue("Foreground", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 2] = nodeValue("Blend mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, BLEND_TYPES ); + + inputs[| 3] = nodeValue("Opacity", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1) + .setDisplay(VALUE_DISPLAY.slider); + + inputs[| 4] = nodeValue("Mask", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 5] = nodeValue("Fill mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "None", "Stretch", "Tile" ]); + + inputs[| 6] = nodeValue("Output dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Background", "Forground", "Mask", "Maximum", "Constant" ]) + .rejectArray(); + + inputs[| 7] = nodeValue("Constant dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF) + .setDisplay(VALUE_DISPLAY.vector); + + inputs[| 8] = nodeValue("Active", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + active_index = 8; + + inputs[| 9] = nodeValue("Preserve alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 10] = nodeValue("Horizontal Align", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_button, [ THEME.inspector_surface_halign, THEME.inspector_surface_halign, THEME.inspector_surface_halign]); + + inputs[| 11] = nodeValue("Vertical Align", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_button, [ THEME.inspector_surface_valign, THEME.inspector_surface_valign, THEME.inspector_surface_valign]); + + inputs[| 12] = nodeValue("Invert mask", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 13] = nodeValue("Mask feather", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1) + .setDisplay(VALUE_DISPLAY.slider, { range: [1, 16, 0.1] }); + + inputs[| 14] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0.5, 0.5 ]) + .setDisplay(VALUE_DISPLAY.vector); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ 8, + ["Surfaces", true], 0, 1, 4, 12, 13, 6, 7, + ["Blend", false], 2, 3, 9, + ["Transform", false], 5, 14, + ] + + attribute_surface_depth(); + + temp_surface = [ surface_create(1, 1), surface_create(1, 1) ]; + blend_temp_surface = temp_surface[1]; + + dragging = false; + drag_sx = 0; + drag_sy = 0; + drag_mx = 0; + drag_my = 0; + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + var _surf = outputs[| 0].getValue(); + if(is_array(_surf)) _surf = array_safe_get_fast(_surf, preview_index); + if(is_struct(_surf)) return; + if(!surface_exists(_surf)) return; + + var _fore = getSingleValue( 1); + var _fill = getSingleValue( 5); + var _posi = getSingleValue(14); + if(_fill) return; + + var sw = surface_get_width_safe( _surf); + var sh = surface_get_height_safe(_surf); + var fw = surface_get_width_safe( _fore); + var fh = surface_get_height_safe(_fore); + + var _rx = _posi[0] * sw - fw / 2; + var _ry = _posi[1] * sh - fh / 2; + _rx = _x + _rx * _s; + _ry = _y + _ry * _s; + var _rw = fw * _s; + var _rh = fh * _s; + + if(dragging) { + var px = drag_sx + (_mx - drag_mx) / _s; + var py = drag_sy + (_my - drag_my) / _s; + + px /= sw; + py /= sh; + + if(inputs[| 14].setValue([ px, py ])) + UNDO_HOLDING = true; + + if(mouse_release(mb_left)) { + UNDO_HOLDING = false; + dragging = false; + } + } + + draw_set_color(COLORS._main_accent); + if(dragging || (active && point_in_rectangle(_mx, _my, _rx, _ry, _rx + _rw, _ry + _rh))) { + draw_rectangle_width(_rx, _ry, _rx + _rw, _ry + _rh, 2); + + if(mouse_press(mb_left)) { + dragging = true; + drag_sx = _posi[0] * sw; + drag_sy = _posi[1] * sh; + drag_mx = _mx; + drag_my = _my; + } + } else + draw_rectangle(_rx, _ry, _rx + _rw, _ry + _rh, true); + } #endregion + + static step = function() { #region + var _back = getSingleValue(0); + var _fore = getSingleValue(1); + var _fill = getSingleValue(5); + var _outp = getSingleValue(6); + + var _atlas = is_instanceof(_fore, SurfaceAtlas); + + inputs[| 5].setVisible(!_atlas); + inputs[| 6].editWidget.data_list = _atlas? [ "Background", "Forground" ] : [ "Background", "Forground", "Mask", "Maximum", "Constant" ]; + inputs[| 7].setVisible(_outp == 4); + + inputs[| 14].setVisible(_fill == 0 && !_atlas); + } #endregion + + static processData = function(_outSurf, _data, _output_index, _array_index) { #region + var _back = _data[0]; + var _fore = _data[1]; + var _type = _data[2]; + var _opacity = _data[3]; + var _mask = _data[4]; + var _fill = _data[5]; + + var _outp = _data[6]; + var _out_dim = _data[7]; + var _pre_alp = _data[9]; + + var _halign = _data[10]; + var _valign = _data[11]; + var _posit = _data[14]; + + var _mskInv = _data[12]; + var _mskFea = _data[13]; + + var cDep = attrDepth(); + + #region dimension + var ww = 1; + var hh = 1; + var _atlas = is_instanceof(_fore, SurfaceAtlas); + + switch(_outp) { + case NODE_BLEND_OUTPUT.background : + ww = surface_get_width_safe(_back); + hh = surface_get_height_safe(_back); + break; + + case NODE_BLEND_OUTPUT.foreground : + ww = surface_get_width_safe(_fore); + hh = surface_get_height_safe(_fore); + break; + + case NODE_BLEND_OUTPUT.mask : + ww = surface_get_width_safe(_mask); + hh = surface_get_height_safe(_mask); + break; + + case NODE_BLEND_OUTPUT.maximum : + ww = max(surface_get_width_safe(_back), surface_get_width_safe(_fore), surface_get_width_safe(_mask)); + hh = max(surface_get_height_safe(_back), surface_get_height_safe(_fore), surface_get_height_safe(_mask)); + break; + + case NODE_BLEND_OUTPUT.constant : + ww = _out_dim[0]; + hh = _out_dim[1]; + break; + } + #endregion + + for( var i = 0; i < 2; i++ ) temp_surface[i] = surface_verify(temp_surface[i], ww, hh, cDep); + + var _backDraw = temp_surface[0]; + var _foreDraw = temp_surface[1]; + + surface_set_shader(_backDraw, noone,, BLEND.over); + draw_surface_safe(_back); + surface_reset_shader(); + + if(_fill == NODE_BLEND_FILL.none || _atlas) { + + if(_atlas) { + if(_outp == NODE_BLEND_OUTPUT.background) { + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_safe(_fore.getSurface(), _fore.x, _fore.y); + surface_reset_shader(); + + _backDraw = _back; + + } else if(_outp == NODE_BLEND_OUTPUT.foreground) { + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_safe(_fore, 0, 0); + surface_reset_shader(); + + surface_set_shader(_backDraw, noone,, BLEND.over); + draw_surface_safe(_back, -_fore.x, -_fore.y); + surface_reset_shader(); + } + + } else if(is_surface(_fore)) { + var sx = 0; + var sy = 0; + + var fw = surface_get_width_safe(_fore); + var fh = surface_get_height_safe(_fore); + + var px = _posit[0] * ww; + var py = _posit[1] * hh; + + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_safe(_fore, px - fw / 2, py - fh / 2); + surface_reset_shader(); + + _backDraw = _back; + } + + } else if(_fill == NODE_BLEND_FILL.stretch) { + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_stretched(_fore, 0, 0, ww, hh); + surface_reset_shader(); + + } else if(_fill == NODE_BLEND_FILL.tile) { + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_tiled(_fore, 0, 0); + surface_reset_shader(); + } + + var _osurf = is_instanceof(_outSurf, SurfaceAtlas)? _outSurf.surface.surface : _outSurf; + var _output = surface_verify(_osurf, ww, hh, cDep); + + _mask = mask_modify(_mask, _mskInv, _mskFea); + + surface_set_shader(_output, noone); + if(is_surface(_fore)) draw_surface_blend(_backDraw, _foreDraw, _type, _opacity, _pre_alp, _mask); + else draw_surface_safe(_backDraw); + surface_reset_shader(); + + if(_atlas) { + var _newAtl = _fore.clone(); + + if(_outp == NODE_BLEND_OUTPUT.background) { + _newAtl.x = 0; + _newAtl.y = 0; + } + + _newAtl.setSurface(_output); + return _newAtl; + } + + return _outSurf; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_feedback_inline/node_feedback_inline.gml.backup0 b/#backups/scripts/node_feedback_inline/node_feedback_inline.gml.backup0 new file mode 100644 index 000000000..12727b0e1 --- /dev/null +++ b/#backups/scripts/node_feedback_inline/node_feedback_inline.gml.backup0 @@ -0,0 +1,86 @@ +// 2024-04-26 18:21:19 +function Node_Feedback_Inline(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Feedback"; + color = COLORS.node_blend_feedback; + icon = THEME.feedback; + icon_24 = THEME.feedback_24; + + w = 0; + h = 0; + + is_root = false; + selectable = false; + update_on_frame = true; + + attributes.junc_in = [ "", 0 ]; + attributes.junc_out = [ "", 0 ]; + + junc_in = noone; + junc_out = noone; + + value_buffer = noone; + + static bypassConnection = function() { return CURRENT_FRAME > 0; } + static bypassNextNode = function() { return false; } + static getNextNode = function() { return [] }; + + static scanJunc = function() { #region + var node_in = PROJECT.nodeMap[? attributes.junc_in[0]]; + var node_out = PROJECT.nodeMap[? attributes.junc_out[0]]; + + junc_in = node_in? node_in.inputs[| attributes.junc_in[1]] : noone; + junc_out = node_out? node_out.outputs[| attributes.junc_out[1]] : noone; + + if(junc_in) junc_in.value_from_loop = self; + if(junc_out) array_push(junc_out.value_to_loop, self); + } #endregion + + static updateValue = function() { #region + var type = junc_out.type; + var val = junc_out.getValue(); + + switch(type) { + case VALUE_TYPE.surface : + surface_array_free(value_buffer); + value_buffer = surface_array_clone(val); + break; + + default : + value_buffer = variable_clone(val); + break; + } + } #endregion + + static getValue = function(arr) { #region + INLINE + + arr[@ 0] = value_buffer; + arr[@ 1] = junc_out; + } #endregion + + static drawConnections = function(params = {}) { #region + if(!active) return noone; + if(!junc_in || !junc_out) return noone; + if(!junc_in.node.active || !junc_out.node.active) return noone; + + params.dashed = true; + var sel = drawJuncConnection(junc_out, junc_in, params); + params.dashed = false; + + if(sel) return self; + return noone; + } #endregion + + static drawNode = function(_x, _y, _mx, _my, _s, display_parameter = noone) {} + + static pointIn = function(_x, _y, _mx, _my, _s) { return false; } + + static postDeserialize = function() { #region + scanJunc(); + } #endregion + + static onDestroy = function() { #region + if(junc_in) junc_in.value_from_loop = noone; + if(junc_out) array_remove(junc_out.value_to_loop, self); + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_feedback_inline/node_feedback_inline.gml.backup1 b/#backups/scripts/node_feedback_inline/node_feedback_inline.gml.backup1 new file mode 100644 index 000000000..e816ad391 --- /dev/null +++ b/#backups/scripts/node_feedback_inline/node_feedback_inline.gml.backup1 @@ -0,0 +1,86 @@ +// 2024-04-26 18:21:04 +function Node_Feedback_Inline(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Feedback"; + color = COLORS.node_blend_feedback; + icon = THEME.feedback; + icon_24 = THEME.feedback_24; + + w = 0; + h = 0; + + is_root = false; + selectable = false; + update_on_frame = true; + + attributes.junc_in = [ "", 0 ]; + attributes.junc_out = [ "", 0 ]; + + junc_in = noone; + junc_out = noone; + + value_buffer = noone; + + static bypassConnection = function() { return CURRENT_FRAME > 0; } + static bypassNextNode = function() { return false; } + static getNextNode = function() { return [] }; + + static scanJunc = function() { #region + var node_in = PROJECT.nodeMap[? attributes.junc_in[0]]; + var node_out = PROJECT.nodeMap[? attributes.junc_out[0]]; + + junc_in = node_in? node_in.inputs[| attributes.junc_in[1]] : noone; + junc_out = node_out? node_out.outputs[| attributes.junc_out[1]] : noone; + + if(junc_in) junc_in.value_from_loop = self; + if(junc_out) array_push(junc_out.value_to_loop, self); + } #endregion + + static updateValue = function() { #region + var type = junc_out.type; + var val = junc_out.getValue(); + + switch(type) { + case VALUE_TYPE.surface : + surface_array_free(value_buffer); + value_buffer = surface_array_clone(val); + break; + + default : + value_buffer = variable_clone(val); + break; + } + } #endregion + + static getValue = function(arr) { #region + INLINE + + arr[@ 0] = value_buffer; + arr[@ 1] = junc_out; + } #endregion + + static drawConnections = function(params = {}) { #region + if(!active) return noone; + if(!junc_in || !junc_out) return noone; + if(!junc_in.node.active || !junc_out.node.active) return noone; + + params.dashed = true; + var sel = drawJuncConnection(junc_out, junc_in, params); + params.dashed = false; + + if(sel) return self; + return noone; + } #endregion + + static drawNode = function(_x, _y, _mx, _my, _s, display_parameter = noone) {} + + static pointIn = function(_x, _y, _mx, _my, _s) { return false; } + + static postDeserialize = function() { #region + scanJunc(); + } #endregion + + static onDestroy = function() { #region + if(junc_in) junc_in.value_from_loop = noone; + if(junc_out) array_remove(junc_out.value_to_loop, self); + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_path_bridge/node_path_bridge.gml.backup0 b/#backups/scripts/node_path_bridge/node_path_bridge.gml.backup0 index 6b2fb2c29..90ff6b225 100644 --- a/#backups/scripts/node_path_bridge/node_path_bridge.gml.backup0 +++ b/#backups/scripts/node_path_bridge/node_path_bridge.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-26 14:41:10 +// 2024-04-26 14:57:55 function Node_Path_Bridge(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Bridge Path"; w = 96; @@ -137,6 +137,7 @@ function Node_Path_Bridge(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _p = eval_bezier(_rat, p0[0], p0[1], p1[0], p1[1], _c0x, _c0y, _c1x, _c1y); out.x = _p[0]; out.y = _p[1]; + } else { out.x = lerp(p0[0], p1[0], _rat); out.y = lerp(p0[1], p1[1], _rat); diff --git a/#backups/scripts/node_path_bridge/node_path_bridge.gml.backup1 b/#backups/scripts/node_path_bridge/node_path_bridge.gml.backup1 index dbf835b8c..24c0eb074 100644 --- a/#backups/scripts/node_path_bridge/node_path_bridge.gml.backup1 +++ b/#backups/scripts/node_path_bridge/node_path_bridge.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-26 14:39:57 +// 2024-04-26 14:52:00 function Node_Path_Bridge(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Bridge Path"; w = 96; @@ -137,6 +137,7 @@ function Node_Path_Bridge(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _p = eval_bezier(_rat, p0[0], p0[1], p1[0], p1[1], _c0x, _c0y, _c1x, _c1y); out.x = _p[0]; out.y = _p[1]; + } else { out.x = lerp(p0[0], p1[0], _rat); out.y = lerp(p0[1], p1[1], _rat); diff --git a/#backups/scripts/node_processor/node_processor.gml.backup0 b/#backups/scripts/node_processor/node_processor.gml.backup0 new file mode 100644 index 000000000..420ee3cf4 --- /dev/null +++ b/#backups/scripts/node_processor/node_processor.gml.backup0 @@ -0,0 +1,386 @@ +// 2024-04-26 15:11:01 +enum ARRAY_PROCESS { + loop, + hold, + expand, + expand_inv, +} + +#macro PROCESSOR_OVERLAY_CHECK if(array_length(current_data) != ds_list_size(inputs)) return; + +function Node_Processor(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + attributes.array_process = ARRAY_PROCESS.loop; + current_data = []; + inputs_data = []; + inputs_is_array = []; + all_inputs = []; + + process_amount = 0; + process_length = []; + dimension_index = 0; + + manage_atlas = true; + atlas_index = 0; + + batch_output = false; //Run processData once with all outputs as array. + + icon = THEME.node_processor_icon; + + array_push(attributeEditors, "Array processor"); + array_push(attributeEditors, [ "Array process type", function() { return attributes.array_process; }, + new scrollBox([ "Loop", "Hold", "Expand", "Expand inverse" ], + function(val) { + attributes.array_process = val; + triggerRender(); + }, false) ]); + + static getInputData = function(index, def = 0) { INLINE return array_safe_get_fast(inputs_data, index, def); } + + static processData_prebatch = function() {} + static processData_postbatch = function() {} + + static processData = function(_outSurf, _data, _output_index, _array_index = 0) { return _outSurf; } + + static getSingleValue = function(_index, _arr = preview_index, output = false) { #region + var _l = output? outputs : inputs; + var _n = _l[| _index]; + var _in = output? _n.getValue() : getInputData(_index); + + if(!_n.isArray(_in)) return _in; + + var _aIndex = _arr; + if(!is_array(_in)) return 0; + + switch(attributes.array_process) { + case ARRAY_PROCESS.loop : _aIndex = safe_mod(_arr, array_length(_in)); break; + case ARRAY_PROCESS.hold : _aIndex = min(_arr, array_length(_in) - 1); break; + case ARRAY_PROCESS.expand : _aIndex = floor(_arr / process_length[_index][1]) % process_length[_index][0]; break; + case ARRAY_PROCESS.expand_inv : _aIndex = floor(_arr / process_length[ds_list_size(_l) - 1 - _index][1]) % process_length[_index][0]; break; + } + + return array_safe_get_fast(_in, _aIndex); + } #endregion + + static getDimension = function(arr = 0) { #region + if(dimension_index == -1) return [ 1, 1 ]; + + var _in = getSingleValue(dimension_index, arr); + + if(inputs[| dimension_index].type == VALUE_TYPE.surface && is_surface(_in)) { + var ww = surface_get_width_safe(_in); + var hh = surface_get_height_safe(_in); + return [ww, hh]; + } + + if(is_array(_in) && array_length(_in) == 2) + return _in; + + return [1, 1]; + } #endregion + + static processDataArray = function(outIndex) { #region + var _output = outputs[| outIndex]; + var _out = _output.getValue(); + var _atlas = false; + var _pAtl = noone; + var _data = array_create(ds_list_size(inputs)); + + if(process_amount == 1) { #region render single data + if(_output.type == VALUE_TYPE.d3object) //passing 3D vertex call + return _out; + + for(var i = 0; i < ds_list_size(inputs); i++) + _data[i] = inputs_data[i]; + + if(_output.type == VALUE_TYPE.surface) { // Surface preparation + if(manage_atlas) { + _pAtl = _data[atlas_index]; + _atlas = is_instanceof(_pAtl, SurfaceAtlas); + + if(_atlas) _data[atlas_index] = _pAtl.getSurface(); + } + + if(dimension_index > -1) { + var surf = _data[dimension_index]; + var _sw = 1, _sh = 1; + if(inputs[| dimension_index].type == VALUE_TYPE.surface) { + if(is_surface(surf)) { + _sw = surface_get_width_safe(surf); + _sh = surface_get_height_safe(surf); + } else + return noone; + } else if(is_array(surf)) { + _sw = array_safe_get_fast(surf, 0, 1); + _sh = array_safe_get_fast(surf, 1, 1); + } + + if(is_instanceof(_out, SurfaceAtlas)) { + if(manage_atlas) { + surface_free_safe(_out.getSurface()) + _out = surface_verify(_out.getSurface(), _sw, _sh, attrDepth()); + } + } else + _out = surface_verify(_out, _sw, _sh, attrDepth()); + } + } + + current_data = _data; + + if(active_index > -1 && !_data[active_index]) { // skip + if(inputs[| 0].type == VALUE_TYPE.surface) + return surface_clone(_data[0], _out); + else + return _data[0]; + } + + var data = processData(_out, _data, outIndex, 0); // Process data + + if(_output.type == VALUE_TYPE.surface) { + if(manage_atlas && _atlas && is_surface(data)) { // Convert back to atlas + var _atl = _pAtl.clone(); + _atl.setSurface(data); + return _atl; + } + + //data = surface_project_posterize(data); + } + + return data; + } #endregion + + #region ++++ array preparation ++++ + if(!is_array(_out)) + _out = array_create(process_amount); + else if(array_length(_out) != process_amount) + array_resize(_out, process_amount); + #endregion + + for(var l = 0; l < process_amount; l++) { + for(var i = 0; i < ds_list_size(inputs); i++) + _data[i] = all_inputs[i][l]; + + if(_output.type == VALUE_TYPE.surface) { #region // Output surface verification + if(manage_atlas) { + _pAtl = _data[atlas_index]; + _atlas = is_instanceof(_pAtl, SurfaceAtlas); + + if(_atlas) _data[atlas_index] = _pAtl.getSurface(); + } + + if(dimension_index > -1) { + var surf = _data[dimension_index]; + var _sw = 1, _sh = 1; + if(inputs[| dimension_index].type == VALUE_TYPE.surface) { + if(is_surface(surf)) { + _sw = surface_get_width_safe(surf); + _sh = surface_get_height_safe(surf); + } else + return noone; + } else if(is_array(surf)) { + _sw = surf[0]; + _sh = surf[1]; + } + + if(is_instanceof(_out[l], SurfaceAtlas)) { + if(manage_atlas) { + surface_free_safe(_out[l].surface.surface) + _out[l] = surface_verify(_out[l].getSurface(), _sw, _sh, attrDepth()); + } + + } else + _out[l] = surface_verify(_out[l], _sw, _sh, attrDepth()); + } + } #endregion + + if(l == 0 || l == preview_index) + current_data = _data; + + if(active_index > -1 && !_data[active_index]) { // skip + if(!_atlas && inputs[| 0].type == VALUE_TYPE.surface) + _out[l] = surface_clone(_data[0], _out[l]); + else + _out[l] = _data[0]; + } else { + _out[l] = processData(_out[l], _data, outIndex, l); // Process data + + if(_output.type == VALUE_TYPE.surface) { + if(manage_atlas && _atlas && is_surface(_out[l])) { // Convert back to atlas + var _atl = _pAtl.clone(); + _atl.setSurface(_out[l]); + _out[l] = _atl; + } + + //data = surface_project_posterize(data); + } + } + } + + return _out; + } #endregion + + static processBatchOutput = function() { #region + for(var i = 0; i < ds_list_size(outputs); i++) { + if(outputs[| i].type != VALUE_TYPE.surface) continue; + var _res = outputs[| i].getValue(); + surface_array_free(_res); + outputs[| i].setValue(noone); + } + + if(process_amount == 1) { + var data = processData(noone, inputs_data, 0, 0); + for(var i = 0; i < ds_list_size(outputs); i++) { + var _outp = array_safe_get_fast(data, i, undefined); + if(_outp == undefined) continue; + outputs[| i].setValue(_outp); + } + } else { + var _outputs = array_create(ds_list_size(outputs)); + for( var l = 0; l < process_amount; l++ ) { + var _data = array_create(ds_list_size(inputs)); + for(var i = 0; i < ds_list_size(inputs); i++) + _data[i] = all_inputs[i][l]; + + var data = processData(0, _data, 0, l); + for(var i = 0; i < ds_list_size(outputs); i++) { + var _outp = array_safe_get_fast(data, i, undefined); + _outputs[i][l] = _outp; + } + } + + for( var i = 0, n = ds_list_size(outputs); i < n; i++ ) + outputs[| i].setValue(_outputs[i]); + } + } #endregion + + static processOutput = function() { #region + var val; + + for(var i = 0; i < ds_list_size(outputs); i++) { + if(outputs[| i].process_array) { + val = processDataArray(i); + if(val == undefined) continue; + } else + val = processData(noone, noone, i); + outputs[| i].setValue(val); + } + } #endregion + + static preGetInputs = function() {} + + static getInputs = function() { #region + preGetInputs(); + + var _len = ds_list_size(inputs); + + process_amount = 1; + inputs_data = array_verify(inputs_data, _len); + inputs_is_array = array_verify(inputs_is_array, _len); + process_length = array_verify(process_length, _len); + all_inputs = array_verify(all_inputs, _len); + + for(var i = 0; i < _len; i++) { + var raw = inputs[| i].getValue(); + var amo = inputs[| i].arrayLength(raw); + var val = raw; + + if(amo == 0) val = noone; //empty array + else if(amo == 1) val = raw[0]; //spread single array + amo = max(1, amo); + + setInputData(i, val); + inputs_is_array[i] = inputs[| i].isArray(val); + + switch(attributes.array_process) { + case ARRAY_PROCESS.loop : + case ARRAY_PROCESS.hold : + process_amount = max(process_amount, amo); + break; + + case ARRAY_PROCESS.expand : + case ARRAY_PROCESS.expand_inv : + process_amount *= amo; + break; + } + + process_length[i] = [amo, process_amount]; + } + + var amoMax = process_amount; + for( var i = 0; i < _len; i++ ) { + amoMax /= process_length[i][0]; + process_length[i][1] = amoMax; + } + + for(var i = 0; i < _len; i++) + all_inputs[i] = array_verify(all_inputs[i], process_amount); + + for(var l = 0; l < process_amount; l++) #region input preparation + for(var i = 0; i < _len; i++) { + var _in = inputs_data[i]; + + if(!inputs_is_array[i]) { + all_inputs[i][l] = _in; + continue; + } + + if(array_length(_in) == 0) { + all_inputs[i][l] = 0; + continue; + } + + var _index = 0; + switch(attributes.array_process) { + case ARRAY_PROCESS.loop : _index = safe_mod(l, array_length(_in)); break; + case ARRAY_PROCESS.hold : _index = min(l, array_length(_in) - 1); break; + case ARRAY_PROCESS.expand : _index = floor(l / process_length[i][1]) % process_length[i][0]; break; + case ARRAY_PROCESS.expand_inv : _index = floor(l / process_length[ds_list_size(inputs) - 1 - i][1]) % process_length[i][0]; break; + } + + all_inputs[i][l] = inputs[| i].arrayBalance(_in[_index]); + } #endregion + + } #endregion + + static update = function(frame = CURRENT_FRAME) { #region + processData_prebatch(); + if(batch_output) processBatchOutput(); + else processOutput(); + processData_postbatch(); + + postProcess(); + } #endregion + + static postProcess = function() {} + + static processSerialize = function(_map) { #region + _map.array_process = attributes.array_process; + } #endregion + + static processDeserialize = function() { #region + attributes.array_process = struct_try_get(load_map, "array_process", ARRAY_PROCESS.loop); + } #endregion + + ///////////////////// CACHE ///////////////////// + + static cacheCurrentFrameIndex = function(_frame, index) { #region + cacheArrayCheck(); + if(CURRENT_FRAME < 0) return; + if(CURRENT_FRAME >= array_length(cached_output)) return; + + var prev = cached_output[CURRENT_FRAME]; + surface_array_free(array_safe_get_fast(prev, index)); + cached_output[CURRENT_FRAME][index] = surface_array_clone(_frame); + + array_safe_set(cache_result, CURRENT_FRAME, true); + + return cached_output[CURRENT_FRAME]; + } #endregion + + static getCacheFrameIndex = function(frame = CURRENT_FRAME, index = 0) { #region + if(frame < 0) return false; + if(!cacheExist(frame)) return noone; + + var surf = array_safe_get_fast(cached_output, frame); + return array_safe_get_fast(surf, index); + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_processor/node_processor.gml.backup1 b/#backups/scripts/node_processor/node_processor.gml.backup1 new file mode 100644 index 000000000..794082f08 --- /dev/null +++ b/#backups/scripts/node_processor/node_processor.gml.backup1 @@ -0,0 +1,386 @@ +// 2024-04-26 15:11:00 +enum ARRAY_PROCESS { + loop, + hold, + expand, + expand_inv, +} + +#macro PROCESSOR_OVERLAY_CHECK if(array_length(current_data) != ds_list_size(inputs)) return; + +function Node_Processor(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + attributes.array_process = ARRAY_PROCESS.loop; + current_data = []; + inputs_data = []; + inputs_is_array = []; + all_inputs = []; + + process_amount = 0; + process_length = []; + dimension_index = 0; + + manage_atlas = true; + atlas_index = 0; + + batch_output = false; //Run processData once with all outputs as array. + + icon = THEME.node_processor_icon; + + array_push(attributeEditors, "Array processor"); + array_push(attributeEditors, [ "Array process type", function() { return attributes.array_process; }, + new scrollBox([ "Loop", "Hold", "Expand", "Expand inverse" ], + function(val) { + attributes.array_process = val; + triggerRender(); + }, false) ]); + + static getInputData = function(index, def = 0) { INLINE return array_safe_get_fast(inputs_data, index, def); } + + static processData_prebatch = function() {} + static processData_postbatch = function() {} + + static processData = function(_outSurf, _data, _output_index, _array_index = 0) { return _outSurf; } + + static getSingleValue = function(_index, _arr = preview_index, output = false) { #region + var _l = output? outputs : inputs; + var _n = _l[| _index]; + var _in = output? _n.getValue() : getInputData(_index); + + if(!_n.isArray(_in)) return _in; + + var _aIndex = _arr; + if(!is_array(_in)) return 0; + + switch(attributes.array_process) { + case ARRAY_PROCESS.loop : _aIndex = safe_mod(_arr, array_length(_in)); break; + case ARRAY_PROCESS.hold : _aIndex = min(_arr, array_length(_in) - 1); break; + case ARRAY_PROCESS.expand : _aIndex = floor(_arr / process_length[_index][1]) % process_length[_index][0]; break; + case ARRAY_PROCESS.expand_inv : _aIndex = floor(_arr / process_length[ds_list_size(_l) - 1 - _index][1]) % process_length[_index][0]; break; + } + + return array_safe_get_fast(_in, _aIndex); + } #endregion + + static getDimension = function(arr = 0) { #region + if(dimension_index == -1) return [ 1, 1 ]; + + var _in = getSingleValue(dimension_index, arr); + + if(inputs[| dimension_index].type == VALUE_TYPE.surface && is_surface(_in)) { + var ww = surface_get_width_safe(_in); + var hh = surface_get_height_safe(_in); + return [ww, hh]; + } + + if(is_array(_in) && array_length(_in) == 2) + return _in; + + return [1, 1]; + } #endregion + + static processDataArray = function(outIndex) { #region + var _output = outputs[| outIndex]; + var _out = _output.getValue(); + var _atlas = false; + var _pAtl = noone; + var _data = array_create(ds_list_size(inputs)); + + if(process_amount == 1) { #region render single data + if(_output.type == VALUE_TYPE.d3object) //passing 3D vertex call + return _out; + + for(var i = 0; i < ds_list_size(inputs); i++) + _data[i] = inputs_data[i]; + + if(_output.type == VALUE_TYPE.surface) { // Surface preparation + if(manage_atlas) { + _pAtl = _data[atlas_index]; + _atlas = is_instanceof(_pAtl, SurfaceAtlas); + + if(_atlas) _data[atlas_index] = _pAtl.getSurface(); + } + + if(dimension_index > -1) { + var surf = _data[dimension_index]; + var _sw = 1, _sh = 1; + if(inputs[| dimension_index].type == VALUE_TYPE.surface) { + if(is_surface(surf)) { + _sw = surface_get_width_safe(surf); + _sh = surface_get_height_safe(surf); + } else + return noone; + } else if(is_array(surf)) { + _sw = array_safe_get_fast(surf, 0, 1); + _sh = array_safe_get_fast(surf, 1, 1); + } + + if(is_instanceof(_out, SurfaceAtlas)) { + if(manage_atlas) { + surface_free_safe(_out.getSurface()) + _out = surface_verify(_out.getSurface(), _sw, _sh, attrDepth()); + } + } else + _out = surface_verify(_out, _sw, _sh, attrDepth()); + } + } + + current_data = _data; + + if(active_index > -1 && !_data[active_index]) { // skip + if(inputs[| 0].type == VALUE_TYPE.surface) + return surface_clone(_data[0], _out); + else + return _data[0]; + } + + var data = processData(_out, _data, outIndex, 0); // Process data + + if(_output.type == VALUE_TYPE.surface) { + if(manage_atlas && _atlas && is_surface(data)) { // Convert back to atlas + var _atl = _pAtl.clone(); + _atl.setSurface(data); + return _atl; + } + + //data = surface_project_posterize(data); + } + + return data; + } #endregion + + #region ++++ array preparation ++++ + if(!is_array(_out)) + _out = array_create(process_amount); + else if(array_length(_out) != process_amount) + array_resize(_out, process_amount); + #endregion + + for(var l = 0; l < process_amount; l++) { + for(var i = 0; i < ds_list_size(inputs); i++) + _data[i] = all_inputs[i][l]; + + if(_output.type == VALUE_TYPE.surface) { #region // Output surface verification + if(manage_atlas) { + _pAtl = _data[atlas_index]; + _atlas = is_instanceof(_pAtl, SurfaceAtlas); + + if(_atlas) _data[atlas_index] = _pAtl.getSurface(); + } + + if(dimension_index > -1) { + var surf = _data[dimension_index]; + var _sw = 1, _sh = 1; + if(inputs[| dimension_index].type == VALUE_TYPE.surface) { + if(is_surface(surf)) { + _sw = surface_get_width_safe(surf); + _sh = surface_get_height_safe(surf); + } else + return noone; + } else if(is_array(surf)) { + _sw = surf[0]; + _sh = surf[1]; + } + + if(is_instanceof(_out[l], SurfaceAtlas)) { + if(manage_atlas) { + surface_free_safe(_out[l].surface.surface) + _out[l] = surface_verify(_out[l].getSurface(), _sw, _sh, attrDepth()); + } + + } else + _out[l] = surface_verify(_out[l], _sw, _sh, attrDepth()); + } + } #endregion + + if(l == 0 || l == preview_index) + current_data = _data; + + if(active_index > -1 && !_data[active_index]) { // skip + if(!_atlas && inputs[| 0].type == VALUE_TYPE.surface) + _out[l] = surface_clone(_data[0], _out[l]); + else + _out[l] = _data[0]; + } else { + _out[l] = processData(_out[l], _data, outIndex, l); // Process data + + if(_output.type == VALUE_TYPE.surface) { + if(manage_atlas && _atlas && is_surface(_out[l])) { // Convert back to atlas + var _atl = _pAtl.clone(); + _atl.setSurface(_out[l]); + _out[l] = _atl; + } + + //data = surface_project_posterize(data); + } + } + } + + return _out; + } #endregion + + static processBatchOutput = function() { #region + for(var i = 0; i < ds_list_size(outputs); i++) { + if(outputs[| i].type != VALUE_TYPE.surface) continue; + var _res = outputs[| i].getValue(); + surface_array_free(_res); + outputs[| i].setValue(noone); + } + + if(process_amount == 1) { + var data = processData(noone, inputs_data, 0, 0); + for(var i = 0; i < ds_list_size(outputs); i++) { + var _outp = array_safe_get_fast(data, i, undefined); + if(_outp == undefined) continue; + outputs[| i].setValue(_outp); + } + } else { + var _outputs = array_create(ds_list_size(outputs)); + for( var l = 0; l < process_amount; l++ ) { + var _data = array_create(ds_list_size(inputs)); + for(var i = 0; i < ds_list_size(inputs); i++) + _data[i] = all_inputs[i][l]; + + var data = processData(0, _data, 0, l); + for(var i = 0; i < ds_list_size(outputs); i++) { + var _outp = array_safe_get_fast(data, i, undefined); + _outputs[i][l] = _outp; + } + } + + for( var i = 0, n = ds_list_size(outputs); i < n; i++ ) + outputs[| i].setValue(_outputs[i]); + } + } #endregion + + static processOutput = function() { #region + var val; + + for(var i = 0; i < ds_list_size(outputs); i++) { + if(outputs[| i].process_array) { + val = processDataArray(i); + if(val == undefined) continue; + } else + val = processData(noone, noone, i); + outputs[| i].setValue(val); + } + } #endregion + + static preGetInputs = function() {} + + static getInputs = function() { #region + preGetInputs(); + + var _len = ds_list_size(inputs); + + process_amount = 1; + inputs_data = array_verify(inputs_data, _len); + inputs_is_array = array_verify(inputs_is_array, _len); + process_length = array_verify(process_length, _len); + all_inputs = array_verify(all_inputs, _len); + + for(var i = 0; i < _len; i++) { + var raw = inputs[| i].getValue(); + var amo = inputs[| i].arrayLength(raw); + var val = raw; + + if(amo == 0) val = noone; //empty array + else if(amo == 1) val = raw[0]; //spread single array + amo = max(1, amo); + + setInputData(i, val); + inputs_is_array[i] = inputs[| i].isArray(val); + + switch(attributes.array_process) { + case ARRAY_PROCESS.loop : + case ARRAY_PROCESS.hold : + process_amount = max(process_amount, amo); + break; + + case ARRAY_PROCESS.expand : + case ARRAY_PROCESS.expand_inv : + process_amount *= amo; + break; + } + + process_length[i] = [amo, process_amount]; + } + + var amoMax = process_amount; + for( var i = 0; i < _len; i++ ) { + amoMax /= process_length[i][0]; + process_length[i][1] = amoMax; + } + + for(var i = 0; i < _len; i++) + all_inputs[i] = array_verify(all_inputs[i], process_amount); + + for(var l = 0; l < process_amount; l++) #region input preparation + for(var i = 0; i < _len; i++) { + var _in = inputs_data[i]; + + if(!inputs_is_array[i]) { + all_inputs[i][l] = _in; + continue; + } + + if(array_length(_in) == 0) { + all_inputs[i][l] = 0; + continue; + } + + var _index = 0; + switch(attributes.array_process) { + case ARRAY_PROCESS.loop : _index = safe_mod(l, array_length(_in)); break; + case ARRAY_PROCESS.hold : _index = min(l, array_length(_in) - 1); break; + case ARRAY_PROCESS.expand : _index = floor(l / process_length[i][1]) % process_length[i][0]; break; + case ARRAY_PROCESS.expand_inv : _index = floor(l / process_length[ds_list_size(inputs) - 1 - i][1]) % process_length[i][0]; break; + } + + all_inputs[i][l] = inputs[| i].arrayBalance(_in[_index]); + } #endregion + + } #endregion + + static update = function(frame = CURRENT_FRAME) { #region + processData_prebatch(); + if(batch_output) processBatchOutput(); + else processOutput(); + processData_postbatch(); + + postProcess(); + } #endregion + + static postProcess = function() {} + + static processSerialize = function(_map) { #region + _map.array_process = attributes.array_process; + } #endregion + + static processDeserialize = function() { #region + attributes.array_process = struct_try_get(load_map, "array_process", ARRAY_PROCESS.loop); + } #endregion + + ///////////////////// CACHE ///////////////////// + + static cacheCurrentFrameIndex = function(_frame, index) { #region + cacheArrayCheck(); + if(CURRENT_FRAME < 0) return; + if(CURRENT_FRAME >= array_length(cached_output)) return; + + var prev = cached_output[CURRENT_FRAME]; + surface_array_free(array_safe_get_fast(prev, index)); + cached_output[CURRENT_FRAME][index] = surface_array_clone(_frame); + + array_safe_set(cache_result, CURRENT_FRAME, true); + + return cached_output[CURRENT_FRAME]; + } #endregion + + static getCacheFrameIndex = function(frame = CURRENT_FRAME, index = 0) { #region + if(frame < 0) return false; + if(!cacheExist(frame)) return noone; + + var surf = array_safe_get_fast(cached_output, frame); + return array_safe_get_fast(surf, index); + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_value/node_value.gml.backup0 b/#backups/scripts/node_value/node_value.gml.backup0 index 1025f057f..e9951dbae 100644 --- a/#backups/scripts/node_value/node_value.gml.backup0 +++ b/#backups/scripts/node_value/node_value.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-24 08:43:01 +// 2024-04-26 18:11:04 #region ---- global names ---- global.junctionEndName = [ "Hold", "Loop", "Ping pong", "Wrap" ]; diff --git a/#backups/scripts/node_value/node_value.gml.backup1 b/#backups/scripts/node_value/node_value.gml.backup1 index b0c0755dd..1025f057f 100644 --- a/#backups/scripts/node_value/node_value.gml.backup1 +++ b/#backups/scripts/node_value/node_value.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-24 08:42:22 +// 2024-04-24 08:43:01 #region ---- global names ---- global.junctionEndName = [ "Hold", "Loop", "Ping pong", "Wrap" ]; diff --git a/#backups/scripts/panel_preview/panel_preview.gml.backup0 b/#backups/scripts/panel_preview/panel_preview.gml.backup0 index ec04500e7..f47538ae4 100644 --- a/#backups/scripts/panel_preview/panel_preview.gml.backup0 +++ b/#backups/scripts/panel_preview/panel_preview.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-25 15:21:26 +// 2024-04-26 16:01:35 #region funtion calls function __fnInit_Preview() { __registerFunction("preview_focus_content", panel_preview_focus_content); diff --git a/#backups/scripts/panel_preview/panel_preview.gml.backup1 b/#backups/scripts/panel_preview/panel_preview.gml.backup1 index 752e30317..a1c3c8e49 100644 --- a/#backups/scripts/panel_preview/panel_preview.gml.backup1 +++ b/#backups/scripts/panel_preview/panel_preview.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-22 18:45:51 +// 2024-04-26 15:47:58 #region funtion calls function __fnInit_Preview() { __registerFunction("preview_focus_content", panel_preview_focus_content); diff --git a/#backups/scripts/surface_functions/surface_functions.gml.backup0 b/#backups/scripts/surface_functions/surface_functions.gml.backup0 index ef7289a84..1324b9d19 100644 --- a/#backups/scripts/surface_functions/surface_functions.gml.backup0 +++ b/#backups/scripts/surface_functions/surface_functions.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-21 15:41:41 +// 2024-04-26 15:47:55 #region ==================================== DRAW ==================================== function draw_surface_safe(surface, _x = 0, _y = 0) { #region @@ -219,8 +219,9 @@ function surface_get_pixel_ext(surface, _x, _y) { #region INLINE - - if(!is_surface(surface)) return 0; + + if(is_instanceof(surface, SurfaceAtlas)) surface = surface.surface.get(); + if(!surface_exists(surface)) return 0; var px = surface_getpixel_ext(surface, _x, _y); if(is_numeric(px)) return int64(px); @@ -559,7 +560,8 @@ } #endregion function surface_encode(surface, stringify = true) { #region - if(!is_surface(surface)) return ""; + if(is_instanceof(surface, SurfaceAtlas)) surface = surface.surface.get(); + if(!surface_exists(surface)) return ""; var buff = buffer_create(surface_get_width_safe(surface) * surface_get_height_safe(surface) * 4, buffer_fixed, 1); diff --git a/#backups/scripts/surface_functions/surface_functions.gml.backup1 b/#backups/scripts/surface_functions/surface_functions.gml.backup1 index bd610ca48..1fc3f683f 100644 --- a/#backups/scripts/surface_functions/surface_functions.gml.backup1 +++ b/#backups/scripts/surface_functions/surface_functions.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-21 15:41:27 +// 2024-04-26 15:43:13 #region ==================================== DRAW ==================================== function draw_surface_safe(surface, _x = 0, _y = 0) { #region @@ -559,7 +559,8 @@ } #endregion function surface_encode(surface, stringify = true) { #region - if(!is_surface(surface)) return ""; + if(is_instanceof(surface, SurfaceAtlas)) surface = surface.surface.get(); + if(!surface_exists(surface)) return ""; var buff = buffer_create(surface_get_width_safe(surface) * surface_get_height_safe(surface) * 4, buffer_fixed, 1); diff --git a/#backups/shaders/sh_FXAA/sh_FXAA.fsh.backup0 b/#backups/shaders/sh_FXAA/sh_FXAA.fsh.backup0 new file mode 100644 index 000000000..889e33e71 --- /dev/null +++ b/#backups/shaders/sh_FXAA/sh_FXAA.fsh.backup0 @@ -0,0 +1,66 @@ +// 2024-04-26 18:07:44 +// +// Simple passthrough fragment shader +// +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +//Texel size (1/resolution) +uniform vec2 dimension; + +#define SPAN_MAX (8.0) //Maximum texel span +//These are more technnical and probably don't need changing: +#define REDUCE_MIN (1.0 / 128.0) //Minimum "dir" reciprocal +#define REDUCE_MUL (1.0 / 32.0) //Luma multiplier for "dir" reciprocal + +vec4 textureFXAA(sampler2D tex, vec2 uv) { + vec2 u_texel = 1. / dimension; + //Sample center and 4 corners + vec3 rgbCC = texture2D(tex, uv).rgb; + vec3 rgb00 = texture2D(tex, uv + vec2( -0.5, -0.5) * u_texel).rgb; + vec3 rgb10 = texture2D(tex, uv + vec2( +0.5, -0.5) * u_texel).rgb; + vec3 rgb01 = texture2D(tex, uv + vec2( -0.5, +0.5) * u_texel).rgb; + vec3 rgb11 = texture2D(tex, uv + vec2( +0.5, +0.5) * u_texel).rgb; + + //Luma coefficients + const vec3 luma = vec3(0.299, 0.587, 0.114); + //Get luma from the 5 samples + float lumaCC = dot(rgbCC, luma); + float luma00 = dot(rgb00, luma); + float luma10 = dot(rgb10, luma); + float luma01 = dot(rgb01, luma); + float luma11 = dot(rgb11, luma); + + //Compute gradient from luma values + vec2 dir = vec2((luma01 + luma11) - (luma00 + luma10), (luma00 + luma01) - (luma10 + luma11)); + //Diminish dir length based on total luma + float dirReduce = max((luma00 + luma10 + luma01 + luma11) * REDUCE_MUL, REDUCE_MIN); + //Divide dir by the distance to nearest edge plus dirReduce + float rcpDir = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + //Multiply by reciprocal and limit to pixel span + dir = clamp(dir * rcpDir, -SPAN_MAX, SPAN_MAX) * u_texel.xy; + + //Average middle texels along dir line + vec4 A = 0.5 * ( + texture2D(tex, uv - dir * (1.0 / 6.0)) + + texture2D(tex, uv + dir * (1.0 / 6.0))); + + //Average with outer texels along dir line + vec4 B = A * 0.5 + 0.25 * ( + texture2D(tex, uv - dir * (0.5)) + + texture2D(tex, uv + dir * (0.5))); + + + //Get lowest and highest luma values + float lumaMin = min(lumaCC, min(min(luma00, luma10), min(luma01, luma11))); + float lumaMax = max(lumaCC, max(max(luma00, luma10), max(luma01, luma11))); + + //Get average luma + float lumaB = dot(B.rgb, luma); + //If the average is outside the luma range, using the middle average + return ((lumaB < lumaMin) || (lumaB > lumaMax)) ? A : B; +} + +void main() { + gl_FragColor = textureFXAA( gm_BaseTexture, v_vTexcoord ); +} diff --git a/scripts/_node_VFX_spawner/_node_VFX_spawner.gml b/scripts/_node_VFX_spawner/_node_VFX_spawner.gml index 06860795e..4c1bc6c7d 100644 --- a/scripts/_node_VFX_spawner/_node_VFX_spawner.gml +++ b/scripts/_node_VFX_spawner/_node_VFX_spawner.gml @@ -355,8 +355,18 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co if(array_empty(surfs)) return; for( var i = 0, n = array_length(surfs); i < n; i++ ) { - if(is_surface(surface_cache[$ surfs[i]])) continue; - surface_cache[$ surfs[i]] = surface_clone(surfs[i]); + var _s = surfs[i]; + + if(is_surface(surface_cache[$ _s])) + continue; + + if(is_instanceof(_s, SurfaceAtlas)) + _s = _s.surface.get(); + + if(!surface_exists(_s)) + continue; + + surface_cache[$ surfs[i]] = surface_clone(_s); } } #endregion diff --git a/scripts/node_blend/node_blend.gml b/scripts/node_blend/node_blend.gml index 88525ccd5..be4cb4465 100644 --- a/scripts/node_blend/node_blend.gml +++ b/scripts/node_blend/node_blend.gml @@ -14,11 +14,24 @@ return node; } + + enum NODE_BLEND_OUTPUT { + background, + foreground, + mask, + maximum, + constant + } + + enum NODE_BLEND_FILL { + none, + stretch, + tile + } #endregion function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { name = "Blend"; - atlas_index = 1; manage_atlas = false; inputs[| 0] = nodeValue("Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); @@ -176,48 +189,53 @@ function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con var _atlas = is_instanceof(_fore, SurfaceAtlas); switch(_outp) { - case 0 : + case NODE_BLEND_OUTPUT.background : ww = surface_get_width_safe(_back); hh = surface_get_height_safe(_back); break; - case 1 : + + case NODE_BLEND_OUTPUT.foreground : ww = surface_get_width_safe(_fore); hh = surface_get_height_safe(_fore); break; - case 2 : + + case NODE_BLEND_OUTPUT.mask : ww = surface_get_width_safe(_mask); hh = surface_get_height_safe(_mask); break; - case 3 : + + case NODE_BLEND_OUTPUT.maximum : ww = max(surface_get_width_safe(_back), surface_get_width_safe(_fore), surface_get_width_safe(_mask)); hh = max(surface_get_height_safe(_back), surface_get_height_safe(_fore), surface_get_height_safe(_mask)); break; - case 4 : + + case NODE_BLEND_OUTPUT.constant : ww = _out_dim[0]; hh = _out_dim[1]; break; } #endregion - for( var i = 0; i < 2; i++ ) - temp_surface[i] = surface_verify(temp_surface[i], ww, hh, cDep); + for( var i = 0; i < 2; i++ ) temp_surface[i] = surface_verify(temp_surface[i], ww, hh, cDep); - var _backDraw = temp_surface[0]; - var _foreDraw = temp_surface[1]; + var _backDraw = temp_surface[0]; + var _foreDraw = temp_surface[1]; surface_set_shader(_backDraw, noone,, BLEND.over); draw_surface_safe(_back); surface_reset_shader(); - if(_fill == 0 || _atlas) { + if(_fill == NODE_BLEND_FILL.none || _atlas) { + if(_atlas) { - if(_outp == 0) { + if(_outp == NODE_BLEND_OUTPUT.background) { surface_set_shader(_foreDraw, noone,, BLEND.over); draw_surface_safe(_fore.getSurface(), _fore.x, _fore.y); surface_reset_shader(); _backDraw = _back; - } else if(_outp == 1) { + + } else if(_outp == NODE_BLEND_OUTPUT.foreground) { surface_set_shader(_foreDraw, noone,, BLEND.over); draw_surface_safe(_fore, 0, 0); surface_reset_shader(); @@ -226,6 +244,7 @@ function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con draw_surface_safe(_back, -_fore.x, -_fore.y); surface_reset_shader(); } + } else if(is_surface(_fore)) { var sx = 0; var sy = 0; @@ -242,11 +261,13 @@ function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con _backDraw = _back; } - } else if(_fill == 1) { + + } else if(_fill == NODE_BLEND_FILL.stretch) { surface_set_shader(_foreDraw, noone,, BLEND.over); draw_surface_stretched(_fore, 0, 0, ww, hh); surface_reset_shader(); - } else if(_fill == 2) { + + } else if(_fill == NODE_BLEND_FILL.tile) { surface_set_shader(_foreDraw, noone,, BLEND.over); draw_surface_tiled(_fore, 0, 0); surface_reset_shader(); @@ -258,19 +279,14 @@ function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con _mask = mask_modify(_mask, _mskInv, _mskFea); surface_set_shader(_output, noone); - if(is_surface(_fore)) { - draw_surface_blend(_backDraw, _foreDraw, _type, _opacity, _pre_alp, _mask); - } else { - BLEND_OVERRIDE - draw_surface(_backDraw, 0, 0); - BLEND_NORMAL - } + if(is_surface(_fore)) draw_surface_blend(_backDraw, _foreDraw, _type, _opacity, _pre_alp, _mask); + else draw_surface_safe(_backDraw); surface_reset_shader(); if(_atlas) { var _newAtl = _fore.clone(); - if(_outp == 0) { + if(_outp == NODE_BLEND_OUTPUT.background) { _newAtl.x = 0; _newAtl.y = 0; } diff --git a/scripts/node_feedback_inline/node_feedback_inline.gml b/scripts/node_feedback_inline/node_feedback_inline.gml index 8871afd33..5d6b42af4 100644 --- a/scripts/node_feedback_inline/node_feedback_inline.gml +++ b/scripts/node_feedback_inline/node_feedback_inline.gml @@ -19,15 +19,9 @@ function Node_Feedback_Inline(_x, _y, _group = noone) : Node(_x, _y, _group) con value_buffer = noone; - static bypassConnection = function() { #region - return CURRENT_FRAME > 0; - } #endregion - - static bypassNextNode = function() { #region - return false; - } #endregion - - static getNextNode = function() { return [] }; + static bypassConnection = function() { return CURRENT_FRAME > 0; } + static bypassNextNode = function() { return false; } + static getNextNode = function() { return [] }; static scanJunc = function() { #region var node_in = PROJECT.nodeMap[? attributes.junc_in[0]]; @@ -49,13 +43,14 @@ function Node_Feedback_Inline(_x, _y, _group = noone) : Node(_x, _y, _group) con surface_array_free(value_buffer); value_buffer = surface_array_clone(val); break; + default : value_buffer = variable_clone(val); break; } } #endregion - static getValue = function() { #region + static getValue = function(arr) { #region INLINE arr[@ 0] = value_buffer; diff --git a/scripts/node_path_bridge/node_path_bridge.gml b/scripts/node_path_bridge/node_path_bridge.gml index 675dbe2bf..e464db5e1 100644 --- a/scripts/node_path_bridge/node_path_bridge.gml +++ b/scripts/node_path_bridge/node_path_bridge.gml @@ -136,6 +136,7 @@ function Node_Path_Bridge(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _p = eval_bezier(_rat, p0[0], p0[1], p1[0], p1[1], _c0x, _c0y, _c1x, _c1y); out.x = _p[0]; out.y = _p[1]; + } else { out.x = lerp(p0[0], p1[0], _rat); out.y = lerp(p0[1], p1[1], _rat); diff --git a/scripts/node_processor/node_processor.gml b/scripts/node_processor/node_processor.gml index 0bfb39803..f790c8b2f 100644 --- a/scripts/node_processor/node_processor.gml +++ b/scripts/node_processor/node_processor.gml @@ -113,9 +113,11 @@ function Node_Processor(_x, _y, _group = noone) : Node(_x, _y, _group) construct _sh = array_safe_get_fast(surf, 1, 1); } - if(manage_atlas && is_instanceof(_out, SurfaceAtlas)) { - surface_free_safe(_out.getSurface()) - _out = surface_verify(_out.getSurface(), _sw, _sh, attrDepth()); + if(is_instanceof(_out, SurfaceAtlas)) { + if(manage_atlas) { + surface_free_safe(_out.getSurface()) + _out = surface_verify(_out.getSurface(), _sw, _sh, attrDepth()); + } } else _out = surface_verify(_out, _sw, _sh, attrDepth()); } @@ -178,9 +180,12 @@ function Node_Processor(_x, _y, _group = noone) : Node(_x, _y, _group) construct _sh = surf[1]; } - if(manage_atlas && is_instanceof(_out[l], SurfaceAtlas)) { - surface_free_safe(_out[l].surface.surface) - _out[l] = surface_verify(_out[l].getSurface(), _sw, _sh, attrDepth()); + if(is_instanceof(_out[l], SurfaceAtlas)) { + if(manage_atlas) { + surface_free_safe(_out[l].surface.surface) + _out[l] = surface_verify(_out[l].getSurface(), _sw, _sh, attrDepth()); + } + } else _out[l] = surface_verify(_out[l], _sw, _sh, attrDepth()); } diff --git a/scripts/surface_functions/surface_functions.gml b/scripts/surface_functions/surface_functions.gml index 701c7232f..a8c73d581 100644 --- a/scripts/surface_functions/surface_functions.gml +++ b/scripts/surface_functions/surface_functions.gml @@ -218,8 +218,9 @@ function surface_get_pixel_ext(surface, _x, _y) { #region INLINE - - if(!is_surface(surface)) return 0; + + if(is_instanceof(surface, SurfaceAtlas)) surface = surface.surface.get(); + if(!surface_exists(surface)) return 0; var px = surface_getpixel_ext(surface, _x, _y); if(is_numeric(px)) return int64(px); @@ -558,7 +559,8 @@ } #endregion function surface_encode(surface, stringify = true) { #region - if(!is_surface(surface)) return ""; + if(is_instanceof(surface, SurfaceAtlas)) surface = surface.surface.get(); + if(!surface_exists(surface)) return ""; var buff = buffer_create(surface_get_width_safe(surface) * surface_get_height_safe(surface) * 4, buffer_fixed, 1);