diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 45e3a186d..22403701b 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -127,6 +127,7 @@ {"id":{"name":"draw_surface_blend","path":"scripts/draw_surface_blend/draw_surface_blend.yy",},"order":1,}, {"id":{"name":"node_string_get_char","path":"scripts/node_string_get_char/node_string_get_char.yy",},"order":19,}, {"id":{"name":"_p_dialog_undo_block","path":"objects/_p_dialog_undo_block/_p_dialog_undo_block.yy",},"order":0,}, + {"id":{"name":"node_path_reverse","path":"scripts/node_path_reverse/node_path_reverse.yy",},"order":29,}, {"id":{"name":"fd_rectangle_get_acceleration_y","path":"scripts/fd_rectangle_get_acceleration_y/fd_rectangle_get_acceleration_y.yy",},"order":3,}, {"id":{"name":"sh_simplex","path":"shaders/sh_simplex/sh_simplex.yy",},"order":22,}, {"id":{"name":"node_noise_grid_tri","path":"scripts/node_noise_grid_tri/node_noise_grid_tri.yy",},"order":25,}, @@ -199,6 +200,7 @@ {"id":{"name":"node_displacement","path":"scripts/node_displacement/node_displacement.yy",},"order":1,}, {"id":{"name":"mask_function","path":"scripts/mask_function/mask_function.yy",},"order":1,}, {"id":{"name":"text_file","path":"scripts/text_file/text_file.yy",},"order":5,}, + {"id":{"name":"sh_trail_filler","path":"shaders/sh_trail_filler/sh_trail_filler.yy",},"order":49,}, {"id":{"name":"s_node_vfx_wind","path":"sprites/s_node_vfx_wind/s_node_vfx_wind.yy",},"order":3,}, {"id":{"name":"s_node_rigidSim_global","path":"sprites/s_node_rigidSim_global/s_node_rigidSim_global.yy",},"order":4,}, {"id":{"name":"sh_channel_G_grey","path":"shaders/sh_channel_G_grey/sh_channel_G_grey.yy",},"order":8,}, @@ -235,6 +237,7 @@ {"id":{"name":"sh_draw_surface_part_tiled","path":"shaders/sh_draw_surface_part_tiled/sh_draw_surface_part_tiled.yy",},"order":1,}, {"id":{"name":"o_dialog_add_node","path":"objects/o_dialog_add_node/o_dialog_add_node.yy",},"order":1,}, {"id":{"name":"s_node_curve_eval","path":"sprites/s_node_curve_eval/s_node_curve_eval.yy",},"order":0,}, + {"id":{"name":"s_node_path_reverse","path":"sprites/s_node_path_reverse/s_node_path_reverse.yy",},"order":8,}, {"id":{"name":"fd_rectangle_get_pressure_width","path":"scripts/fd_rectangle_get_pressure_width/fd_rectangle_get_pressure_width.yy",},"order":18,}, {"id":{"name":"sh_blend_normal","path":"shaders/sh_blend_normal/sh_blend_normal.yy",},"order":1,}, {"id":{"name":"node_feedback_output","path":"scripts/node_feedback_output/node_feedback_output.yy",},"order":2,}, diff --git a/objects/o_dialog_arrayBox/Create_0.gml b/objects/o_dialog_arrayBox/Create_0.gml index cf95d5152..5eca0392e 100644 --- a/objects/o_dialog_arrayBox/Create_0.gml +++ b/objects/o_dialog_arrayBox/Create_0.gml @@ -58,7 +58,7 @@ event_inherited(); } if(keyboard_check_pressed(vk_down)) - selecting = (selecting + 1) % array_length(arrayBox.data); + selecting = safe_mod(selecting + 1, array_length(arrayBox.data)); if(keyboard_check_pressed(vk_escape)) instance_destroy(); diff --git a/objects/o_dialog_fontscrollbox/Create_0.gml b/objects/o_dialog_fontscrollbox/Create_0.gml index 0e492ce83..9785d5a6c 100644 --- a/objects/o_dialog_fontscrollbox/Create_0.gml +++ b/objects/o_dialog_fontscrollbox/Create_0.gml @@ -59,7 +59,7 @@ event_inherited(); } if(keyboard_check_pressed(vk_down)) - selecting = (selecting + 1) % array_length(data); + selecting = safe_mod(selecting + 1, array_length(data)); if(keyboard_check_pressed(vk_escape)) instance_destroy(); diff --git a/objects/o_dialog_menubox/Draw_64.gml b/objects/o_dialog_menubox/Draw_64.gml index 094c64610..c1854d6af 100644 --- a/objects/o_dialog_menubox/Draw_64.gml +++ b/objects/o_dialog_menubox/Draw_64.gml @@ -113,7 +113,7 @@ } if(keyboard_check_pressed(vk_down)) - selecting = (selecting + 1) % array_length(menu); + selecting = safe_mod(selecting + 1, array_length(menu)); if(keyboard_check_pressed(vk_escape)) instance_destroy(); diff --git a/objects/o_dialog_scrollbox/Create_0.gml b/objects/o_dialog_scrollbox/Create_0.gml index 10554face..eacf05e89 100644 --- a/objects/o_dialog_scrollbox/Create_0.gml +++ b/objects/o_dialog_scrollbox/Create_0.gml @@ -71,7 +71,7 @@ event_inherited(); } if(keyboard_check_pressed(vk_down)) - selecting = (selecting + 1) % array_length(data); + selecting = safe_mod(selecting + 1, array_length(data)); if(keyboard_check_pressed(vk_escape)) instance_destroy(); diff --git a/objects/o_main/Step_0.gml b/objects/o_main/Step_0.gml index d0ab546fd..339ebfe11 100644 --- a/objects/o_main/Step_0.gml +++ b/objects/o_main/Step_0.gml @@ -16,7 +16,7 @@ #endregion #region step - VARIABLE.step(); + //VARIABLE.step(); try { if(PANEL_MAIN != 0) diff --git a/scripts/ase_object/ase_object.gml b/scripts/ase_object/ase_object.gml index ad1c2a1cd..f7c2affa4 100644 --- a/scripts/ase_object/ase_object.gml +++ b/scripts/ase_object/ase_object.gml @@ -78,9 +78,9 @@ function ase_layer(name) constructor { if(tag != noone) { var st = tag[? "Frame start"]; var ed = tag[? "Frame end"]; - ind = st + index % (ed - st + 1); + ind = st + safe_mod(index, ed - st + 1); } else - ind = index % array_length(cels); + ind = safe_mod(index, array_length(cels)); return array_safe_get(cels, ind); } diff --git a/scripts/buttonGroup/buttonGroup.gml b/scripts/buttonGroup/buttonGroup.gml index fcddbfce3..eaa6a0706 100644 --- a/scripts/buttonGroup/buttonGroup.gml +++ b/scripts/buttonGroup/buttonGroup.gml @@ -80,8 +80,8 @@ function buttonGroupClass(_data, _onClick) : widget() constructor { if(is_array(data) && key_mod_press(SHIFT)) { var len = array_length(data); if(len) { - if(mouse_wheel_down()) onClick((_selecting + 1 + len) % len); - if(mouse_wheel_up()) onClick((_selecting - 1 + len) % len); + if(mouse_wheel_down()) onClick(safe_mod(_selecting + 1 + len, len)); + if(mouse_wheel_up()) onClick(safe_mod(_selecting - 1 + len, len)); } } } diff --git a/scripts/buttonPalette/buttonPalette.gml b/scripts/buttonPalette/buttonPalette.gml index 002058ec7..0deb19a00 100644 --- a/scripts/buttonPalette/buttonPalette.gml +++ b/scripts/buttonPalette/buttonPalette.gml @@ -63,7 +63,7 @@ function drawPaletteGrid(_pal, _x, _y, _w, _gs = 24, c_color = -1) { for(var i = 0; i < array_length(_pal); i++) { draw_set_color(_pal[i]); - var _x0 = _x + (i % col) * _gs; + var _x0 = _x + safe_mod(i, col) * _gs; var _y0 = _y + floor(i / col) * _gs; draw_rectangle(_x0, _y0 + 1, _x0 + _gs, _y0 + _gs, false); } @@ -71,7 +71,7 @@ function drawPaletteGrid(_pal, _x, _y, _w, _gs = 24, c_color = -1) { if(c_color > -1) { for(var i = 0; i < array_length(_pal); i++) { if(c_color == _pal[i]) { - var _x0 = _x + (i % col) * _gs; + var _x0 = _x + safe_mod(i, col) * _gs; var _y0 = _y + floor(i / col) * _gs; draw_set_color(c_white); diff --git a/scripts/directory_object/directory_object.gml b/scripts/directory_object/directory_object.gml index f7a182fc6..e2b5791c6 100644 --- a/scripts/directory_object/directory_object.gml +++ b/scripts/directory_object/directory_object.gml @@ -102,7 +102,7 @@ function DirectoryObject(name, path) constructor { var _temp = sprite_add(icon_path, 0, false, false, 0, 0); var ww = sprite_get_width(_temp); var hh = sprite_get_height(_temp); - var amo = ww % hh == 0? ww / hh : 1; + var amo = safe_mod(ww, hh) == 0? ww / hh : 1; sprite_delete(_temp); f.spr_path = [icon_path, amo, true]; diff --git a/scripts/draw_line_width2/draw_line_width2.gml b/scripts/draw_line_width2/draw_line_width2.gml index 611762e19..0fd7ffae6 100644 --- a/scripts/draw_line_width2/draw_line_width2.gml +++ b/scripts/draw_line_width2/draw_line_width2.gml @@ -23,7 +23,7 @@ function draw_line_width2(x0, y0, x1, y1, w0, w1, cap = false) { } } -function draw_line_width2_angle(x0, y0, x1, y1, w0, w1, a0 = 0, a1 = 0, _oc = c_white, _nc = c_white) { +function draw_line_width2_angle(x0, y0, x1, y1, w0, w1, a0 = 0, a1 = 0, _oc = c_white, _nc = c_white, widColor = false) { var _x0 = x0 + lengthdir_x(w0 / 2, a0); var _y0 = y0 + lengthdir_y(w0 / 2, a0); var _x1 = x1 + lengthdir_x(w1 / 2, a1); @@ -31,10 +31,10 @@ function draw_line_width2_angle(x0, y0, x1, y1, w0, w1, a0 = 0, a1 = 0, _oc = c_ //draw_set_color(c_red); draw_primitive_begin(pr_trianglestrip); - draw_vertex_color( x0, y0, _oc, 1); - draw_vertex_color( x1, y1, _nc, 1); - draw_vertex_color(_x0, _y0, _oc, 1); - draw_vertex_color(_x1, _y1, _nc, 1); + draw_vertex_color( x0, y0, widColor? merge_color(_oc, c_black, 0.5) : _oc, 1); + draw_vertex_color( x1, y1, widColor? merge_color(_nc, c_black, 0.5) : _nc, 1); + draw_vertex_color(_x0, _y0, widColor? merge_color(_oc, c_black, 0.0) : _oc, 1); + draw_vertex_color(_x1, _y1, widColor? merge_color(_nc, c_black, 0.0) : _nc, 1); draw_primitive_end(); var _x0 = x0 + lengthdir_x(w0 / 2, a0 + 180); @@ -44,9 +44,9 @@ function draw_line_width2_angle(x0, y0, x1, y1, w0, w1, a0 = 0, a1 = 0, _oc = c_ //draw_set_color(c_blue); draw_primitive_begin(pr_trianglestrip); - draw_vertex_color( x0, y0, _oc, 1); - draw_vertex_color( x1, y1, _nc, 1); - draw_vertex_color(_x0, _y0, _oc, 1); - draw_vertex_color(_x1, _y1, _nc, 1); + draw_vertex_color( x0, y0, widColor? merge_color(_oc, c_black, 0.5) : _oc, 1); + draw_vertex_color( x1, y1, widColor? merge_color(_nc, c_black, 0.5) : _nc, 1); + draw_vertex_color(_x0, _y0, widColor? merge_color(_oc, c_black, 1.0) : _oc, 1); + draw_vertex_color(_x1, _y1, widColor? merge_color(_nc, c_black, 1.0) : _nc, 1); draw_primitive_end(); } \ No newline at end of file diff --git a/scripts/draw_tooltip/draw_tooltip.gml b/scripts/draw_tooltip/draw_tooltip.gml index 54ca22365..c36ffa257 100644 --- a/scripts/draw_tooltip/draw_tooltip.gml +++ b/scripts/draw_tooltip/draw_tooltip.gml @@ -66,7 +66,7 @@ function draw_tooltip_surface_array(surf) { if(!is_surface(surf[ind])) continue; var i = floor(ind / col); - var j = ind % col; + var j = safe_mod(ind, col); var sw = surface_get_width(surf[ind]); var sh = surface_get_height(surf[ind]); diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index 61329d3a9..9782c27a4 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -30,7 +30,7 @@ globalvar VERSION, SAVEFILE_VERSION, VERSION_STRING; VERSION = 1130; SAVEFILE_VERSION = 1300; - VERSION_STRING = "1.13.pr11"; + VERSION_STRING = "1.13.pr13"; globalvar NODES, NODE_MAP, APPEND_MAP, HOTKEYS, HOTKEY_CONTEXT; diff --git a/scripts/node_2d_light/node_2d_light.gml b/scripts/node_2d_light/node_2d_light.gml index f4b39aa7f..b54b29933 100644 --- a/scripts/node_2d_light/node_2d_light.gml +++ b/scripts/node_2d_light/node_2d_light.gml @@ -185,7 +185,7 @@ function Node_2D_light(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) con nx = _pos[0] + lengthdir_x(_range, dir); ny = _pos[1] + lengthdir_y(_range, dir); - if((i % bnd_amo) / bnd_amo < _rbnr && i) { + if(safe_mod(i, bnd_amo) / bnd_amo < _rbnr && i) { draw_vertex_color(_pos[0], _pos[1], c_white, 1); draw_vertex_color(ox, oy, c_black, 1); draw_vertex_color(nx, ny, c_black, 1); diff --git a/scripts/node_3d_repeat/node_3d_repeat.gml b/scripts/node_3d_repeat/node_3d_repeat.gml index bafb188e8..03197745e 100644 --- a/scripts/node_3d_repeat/node_3d_repeat.gml +++ b/scripts/node_3d_repeat/node_3d_repeat.gml @@ -143,7 +143,7 @@ function Node_3D_Repeat(_x, _y, _group = -1) : Node(_x, _y, _group) constructor matrix_set(matrix_world, matrix_stack_top()); if(is_array(sv)) { - var index = i % array_length(sv); + var index = safe_mod(i, array_length(sv)); var _sv = sv[index]; _sv(index); } else diff --git a/scripts/node_ase_file_read/node_ase_file_read.gml b/scripts/node_ase_file_read/node_ase_file_read.gml index 090f5e119..8bba5d421 100644 --- a/scripts/node_ase_file_read/node_ase_file_read.gml +++ b/scripts/node_ase_file_read/node_ase_file_read.gml @@ -120,7 +120,7 @@ function Node_ASE_File_Read(_x, _y, _group = -1) : Node(_x, _y, _group) construc var st = tag[? "Frame start"]; var ed = tag[? "Frame end"]; var rn = ed - st + 1; - var progFr = (ANIMATOR.current_frame - _tag_delay) % rn + 1; + var progFr = safe_mod(ANIMATOR.current_frame - _tag_delay, rn) + 1; var prog = progFr / rn; var txt = ""; diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index 7b411d630..c0ce84037 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -541,8 +541,10 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) constructor { static drawPreview = function(xx, yy, _s) { if(!active) return; + var _node = outputs[| preview_channel]; if(_node.type != VALUE_TYPE.surface) return; + var surf = _node.getValue(); preview_amount = 0; if(is_array(surf)) { diff --git a/scripts/node_equation/node_equation.gml b/scripts/node_equation/node_equation.gml index baacbfcff..23cae42b0 100644 --- a/scripts/node_equation/node_equation.gml +++ b/scripts/node_equation/node_equation.gml @@ -104,7 +104,7 @@ function Node_Equation(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) con if(index < input_fix_len) return; if(LOADING || APPENDING) return; - if((index - input_fix_len) % data_length == 0) { //Variable name + if(safe_mod(index - input_fix_len, data_length) == 0) { //Variable name inputs[| index + 1].name = inputs[| index].getValue(); } diff --git a/scripts/node_json_file_write/node_json_file_write.gml b/scripts/node_json_file_write/node_json_file_write.gml index ed78789c7..fffe9be52 100644 --- a/scripts/node_json_file_write/node_json_file_write.gml +++ b/scripts/node_json_file_write/node_json_file_write.gml @@ -64,7 +64,7 @@ function Node_Json_File_Write(_x, _y, _group = -1) : Node(_x, _y, _group) constr if(index < input_fix_len) return; if(LOADING || APPENDING) return; - if((index - input_fix_len) % data_length == 0) { //Variable name + if(safe_mod(index - input_fix_len, data_length) == 0) { //Variable name inputs[| index + 1].name = inputs[| index].getValue() + " value"; } diff --git a/scripts/node_line/node_line.gml b/scripts/node_line/node_line.gml index cb5a0020e..eb955ee55 100644 --- a/scripts/node_line/node_line.gml +++ b/scripts/node_line/node_line.gml @@ -29,7 +29,7 @@ function Node_Line(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constru inputs[| 9] = nodeValue("Shift", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) .setDisplay(VALUE_DISPLAY._default, 1 / 64); - inputs[| 10] = nodeValue("Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, [ new gradientKey(0, c_white) ] ) + inputs[| 10] = nodeValue("Color over length", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, [ new gradientKey(0, c_white) ] ) .setDisplay(VALUE_DISPLAY.gradient); inputs[| 11] = nodeValue("Width over length", self, JUNCTION_CONNECT.input, VALUE_TYPE.curve, CURVE_DEF_11); @@ -41,12 +41,16 @@ function Node_Line(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constru inputs[| 14] = nodeValue("Round segment", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 4) .setDisplay(VALUE_DISPLAY.slider, [2, 16, 1]); + inputs[| 15] = nodeValue("Span color over path", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false, "Apply the full 'color over length' to the trimmed path."); + + inputs[| 16] = nodeValue("Greyscale over width", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + input_display_list = [ ["Output", true], 0, 1, ["Line data", false], 6, 7, 2, ["Line settings", false], 3, 11, 12, 8, 9, 13, 14, ["Wiggle", false], 4, 5, - ["Render", false], 10 + ["Render", false], 10, 15, 16, ]; outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); @@ -70,6 +74,8 @@ function Node_Line(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constru var _cap = _data[13]; var _capP = _data[14]; + var _colP = _data[15]; + var _colW = _data[16]; inputs[| 14].setVisible(_cap); @@ -108,6 +114,9 @@ function Node_Line(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constru var step = 0; while(_total > 0) { + if(_rtLen == 0) break; + if(ww <= 0.001) break; + if(_prog_curr >= 1) _prog_curr = frac(_prog_curr); else @@ -138,7 +147,7 @@ function Node_Line(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constru _na = point_direction(n0[0], n0[1], n1[0], n1[1]) + 90; } - _nc = gradient_eval(_color, _prog_eli / _rtLen, ds_list_get(_col_data, 0)); + _nc = gradient_eval(_color, _colP? _prog_eli / _rtLen : _prog_curr, ds_list_get(_col_data, 0)); if(_prog_curr > _prog) { if(_cap) { @@ -152,7 +161,7 @@ function Node_Line(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constru } } - draw_line_width2_angle(_ox, _oy, _nx, _ny, _ow, _nw, _oa, _na, _oc, _nc); + draw_line_width2_angle(_ox, _oy, _nx, _ny, _ow, _nw, _oa, _na, _oc, _nc, _colW); _total -= _prog_curr - _prog; } @@ -201,7 +210,7 @@ function Node_Line(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constru _nw = random_range(_wid[0], _wid[1]); _nw *= eval_curve_x(_widc, _widap? _prog_eli / _rtLen : _prog_curr); - _nc = gradient_eval(_color, _prog_eli / _rtLen, ds_list_get(_col_data, 0)); + _nc = gradient_eval(_color, _colP? _prog_eli / _rtLen : _prog_curr, ds_list_get(_col_data, 0)); if(_prog_curr > _prog) { if(_cap) { @@ -215,7 +224,7 @@ function Node_Line(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constru } } - draw_line_width2_angle(_ox, _oy, _nx, _ny, _ow, _nw, _d + 90, _d + 90, _oc, _nc); + draw_line_width2_angle(_ox, _oy, _nx, _ny, _ow, _nw, _d + 90, _d + 90, _oc, _nc, _colW); _total -= (_prog_curr - _prog); } diff --git a/scripts/node_lua_compute/node_lua_compute.gml b/scripts/node_lua_compute/node_lua_compute.gml index 64b0666c9..bffe9ceea 100644 --- a/scripts/node_lua_compute/node_lua_compute.gml +++ b/scripts/node_lua_compute/node_lua_compute.gml @@ -143,7 +143,7 @@ function Node_Lua_Compute(_x, _y, _group = -1) : Node(_x, _y, _group) constructo compiled = false; - if((index - input_fix_len) % data_length == 1) { //Variable type + if(safe_mod(index - input_fix_len, data_length) == 1) { //Variable type var type = inputs[| index].getValue(); switch(type) { diff --git a/scripts/node_lua_surface/node_lua_surface.gml b/scripts/node_lua_surface/node_lua_surface.gml index 3fb4fbe39..0716e564e 100644 --- a/scripts/node_lua_surface/node_lua_surface.gml +++ b/scripts/node_lua_surface/node_lua_surface.gml @@ -147,7 +147,7 @@ function Node_Lua_Surface(_x, _y, _group = -1) : Node(_x, _y, _group) constructo compiled = false; - if((index - input_fix_len) % data_length == 1) { //Variable type + if(safe_mod(index - input_fix_len, data_length) == 1) { //Variable type var type = inputs[| index].getValue(); switch(type) { diff --git a/scripts/node_path_reverse/node_path_reverse.gml b/scripts/node_path_reverse/node_path_reverse.gml new file mode 100644 index 000000000..e7be4945b --- /dev/null +++ b/scripts/node_path_reverse/node_path_reverse.gml @@ -0,0 +1,30 @@ +function Node_Path_Reverse(_x, _y, _group = -1) : Node(_x, _y, _group) constructor { + name = "Reverse Path"; + previewable = false; + + w = 96; + + inputs[| 0] = nodeValue("Path", self, JUNCTION_CONNECT.input, VALUE_TYPE.pathnode, noone) + .setVisible(true, true); + + outputs[| 0] = nodeValue("Path", self, JUNCTION_CONNECT.output, VALUE_TYPE.pathnode, self); + + static getPointRatio = function(_rat) { + var _path = inputs[| 0].getValue(); + + if(!is_struct(_path) || !struct_has(_path, "getPointRatio")) + return [ 0, 0 ]; + + var _p = _path.getPointRatio(1 - _rat); + return _p; + } + + function update() { + outputs[| 0].setValue(self); + } + + static onDrawNode = function(xx, yy, _mx, _my, _s) { + var bbox = drawGetBbox(xx, yy, _s); + draw_sprite_fit(s_node_path_trim, 0, bbox.xc, bbox.yc, bbox.w, bbox.h); + } +} \ No newline at end of file diff --git a/scripts/node_path_reverse/node_path_reverse.yy b/scripts/node_path_reverse/node_path_reverse.yy new file mode 100644 index 000000000..0e7844e65 --- /dev/null +++ b/scripts/node_path_reverse/node_path_reverse.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "node_path_reverse", + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "path", + "path": "folders/nodes/data/value/path.yy", + }, +} \ No newline at end of file diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 5f17332f9..32a8e1eaf 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -221,7 +221,7 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { addNodeObject(filter, "Glow", s_node_glow, "Node_Glow", [1, Node_Glow]); addNodeObject(filter, "Shadow", s_node_shadow, "Node_Shadow", [1, Node_Shadow]); addNodeObject(filter, "Bloom", s_node_bloom, "Node_Bloom", [1, Node_Bloom]); - addNodeObject(filter, "Trail", s_node_trail, "Node_Trail", [1, Node_Trail]); + addNodeObject(filter, "Trail", s_node_trail, "Node_Trail", [1, Node_Trail]).set_version(1130); addNodeObject(filter, "Erode", s_node_erode, "Node_Erode", [1, Node_Erode]); addNodeObject(filter, "Corner", s_node_corner, "Node_Corner", [1, Node_Corner], ["round corner"]).set_version(1110); addNodeObject(filter, "2D Light", s_node_2d_light, "Node_2D_light", [1, Node_2D_light]); @@ -398,6 +398,7 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { addNodeObject(values, "Shift Path", s_node_path_shift, "Node_Path_Shift", [1, Node_Path_Shift]).set_version(1130); addNodeObject(values, "Trim Path", s_node_path_trim, "Node_Path_Trim", [1, Node_Path_Trim]).set_version(1130); addNodeObject(values, "Wave Path", s_node_path_wave, "Node_Path_Wave", [1, Node_Path_Wave], ["zigzag path"]).set_version(1130); + addNodeObject(values, "Reverse Path", s_node_path_reverse, "Node_Path_Reverse", [1, Node_Path_Reverse]).set_version(1130); ds_list_add(values, "Boolean"); addNodeObject(values, "Boolean", s_node_boolean, "Node_Boolean", [1, Node_Boolean]); diff --git a/scripts/node_repeat/node_repeat.gml b/scripts/node_repeat/node_repeat.gml index 42056f895..9b69f1413 100644 --- a/scripts/node_repeat/node_repeat.gml +++ b/scripts/node_repeat/node_repeat.gml @@ -190,7 +190,7 @@ function Node_Repeat(_x, _y, _group = -1) : Node(_x, _y, _group) constructor { } } else if(_pat == 1) { var row = floor(i / _col); - var col = i % _col; + var col = safe_mod(i, _col); posx = _spos[0] + _rpos[0] * col + _cls[0] * row; posy = _spos[1] + _rpos[1] * col + _cls[1] * row; @@ -218,7 +218,7 @@ function Node_Repeat(_x, _y, _group = -1) : Node(_x, _y, _group) constructor { var _surf = _inSurf; if(is_array(_inSurf)) - _surf = array_safe_get(_inSurf, _arr? irandom(array_length(_inSurf) - 1) : i % array_length(_inSurf)); + _surf = array_safe_get(_inSurf, _arr? irandom(array_length(_inSurf) - 1) : safe_mod(i, array_length(_inSurf))); var _sw = surface_get_width(_surf); var _sh = surface_get_height(_surf); diff --git a/scripts/node_rigid_object_spawner/node_rigid_object_spawner.gml b/scripts/node_rigid_object_spawner/node_rigid_object_spawner.gml index 61c637cac..912aa9c80 100644 --- a/scripts/node_rigid_object_spawner/node_rigid_object_spawner.gml +++ b/scripts/node_rigid_object_spawner/node_rigid_object_spawner.gml @@ -81,7 +81,7 @@ function Node_Rigid_Object_Spawner(_x, _y, _group = -1) : Node(_x, _y, _group) c var _spw = inputs[| 6].getValue(); if(_spw) { - if(_typ == 0 && (ANIMATOR.current_frame % _del == 0)) + if(_typ == 0 && (safe_mod(ANIMATOR.current_frame, _del) == 0)) spawn(); if(_typ == 1 && ANIMATOR.current_frame == _frm) spawn(); diff --git a/scripts/node_switch/node_switch.gml b/scripts/node_switch/node_switch.gml index b6b1dee8e..991f954ce 100644 --- a/scripts/node_switch/node_switch.gml +++ b/scripts/node_switch/node_switch.gml @@ -81,7 +81,7 @@ function Node_Switch(_x, _y, _group = -1) : Node(_x, _y, _group) constructor { if(index < input_fix_len) return; if(LOADING || APPENDING) return; - if((index - input_fix_len) % data_length == 0) { //Variable name + if(safe_mod(index - input_fix_len, data_length) == 0) { //Variable name inputs[| index + 1].name = inputs[| index].getValue() + " value"; } diff --git a/scripts/node_trail/node_trail.gml b/scripts/node_trail/node_trail.gml index 87800ab80..b23faf41a 100644 --- a/scripts/node_trail/node_trail.gml +++ b/scripts/node_trail/node_trail.gml @@ -2,21 +2,25 @@ function Node_Trail(_x, _y, _group = -1) : Node(_x, _y, _group) constructor { name = "Trail"; use_cache = true; - inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0); - inputs[| 1] = nodeValue("Max life", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 5); - inputs[| 2] = nodeValue("Alpha fade", self, JUNCTION_CONNECT.input, VALUE_TYPE.curve, CURVE_DEF_11); + shader = sh_trail_filler; + uni_dimension = shader_get_uniform(shader, "dimension"); + uni_range = shader_get_uniform(shader, "range"); + uni_sam_prev = shader_get_sampler_index(shader, "prevFrame"); - inputs[| 3] = nodeValue("Blend mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) - .setDisplay(VALUE_DISPLAY.enum_scroll, BLEND_TYPES ); + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0); + + inputs[| 1] = nodeValue("Max life", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 5); + + inputs[| 2] = nodeValue("Loop", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); input_display_list = [ ["Surface", true], 0, - ["Trail settings", false], 1, 3, 2 + ["Trail settings", false], 1, 2, ]; - temp_surf = [ surface_create(1, 1), surface_create(1, 1) ]; + output_surf = surface_create(1, 1); static update = function() { if(!inputs[| 0].value_from) return; @@ -24,47 +28,56 @@ function Node_Trail(_x, _y, _group = -1) : Node(_x, _y, _group) constructor { var _surf = inputs[| 0].getValue(); var _life = inputs[| 1].getValue(); - var _alpha = inputs[| 2].getValue(); - var _blend = inputs[| 3].getValue(); + var _loop = inputs[| 2].getValue(); if(!is_surface(_surf)) return; cacheCurrentFrame(_surf); - for(var i = 0; i < 2; i++) { - temp_surf[i] = surface_verify(temp_surf[i], surface_get_width(_surf), surface_get_height(_surf)); + output_surf = surface_verify(output_surf, surface_get_width(_surf), surface_get_height(_surf)); + surface_set_target(output_surf); + draw_clear_alpha(0, 0); + surface_reset_target(); - surface_set_target(temp_surf[i]); - draw_clear_alpha(0, 0); - surface_reset_target(); - } - var _outSurf = outputs[| 0].getValue(); _outSurf = surface_verify(_outSurf, surface_get_width(_surf), surface_get_height(_surf)); outputs[| 0].setValue(_outSurf); var curf = ANIMATOR.current_frame; - var aa = 1; - var frame_amo = min(_life, curf); + var frame_amo = _loop? _life : min(_life, curf); var st_frame = curf - frame_amo; - var bg = 0; + print("====="); for(var i = 0; i <= frame_amo; i++) { var frame_idx = st_frame + i; var prog = (frame_idx - (curf - _life)) / _life; - var aa = eval_curve_x(_alpha, prog); - aa = power(aa, 2); - bg = !bg; + if(_loop && frame_idx < 0) frame_idx = ANIMATOR.frames_total + frame_idx; - surface_set_target(temp_surf[bg]); - draw_surface_blend(temp_surf[!bg], getCacheFrame(frame_idx), _blend, aa, false); + var prev = _loop? safe_mod(frame_idx - 1 + ANIMATOR.frames_total, ANIMATOR.frames_total) : frame_idx - 1; + if(!is_surface(getCacheFrame(frame_idx))) continue; + + if(!is_surface(getCacheFrame(prev))) { + surface_set_target(output_surf); + draw_surface(getCacheFrame(frame_idx), 0, 0); + surface_reset_target(); + continue; + } + + surface_set_target(output_surf); + shader_set(sh_trail_filler); + shader_set_uniform_f(uni_dimension, surface_get_width(_surf), surface_get_height(_surf)); + shader_set_uniform_f(uni_range, surface_get_width(_surf) / 2); + texture_set_stage(uni_sam_prev, surface_get_texture(getCacheFrame(prev))); + + draw_surface(getCacheFrame(frame_idx), 0, 0); + shader_reset(); surface_reset_target(); } surface_set_target(_outSurf); draw_clear_alpha(0, 0); BLEND_OVERRIDE; - draw_surface_safe(temp_surf[bg], 0, 0); + draw_surface_safe(output_surf, 0, 0); BLEND_NORMAL; surface_reset_target(); } diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index cb378615e..41234162f 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -825,7 +825,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } static _getValue = function(_time = ANIMATOR.current_frame, applyUnit = true, arrIndex = 0) { - //__count("getValue") var _val = getValueRecursive(_time); var val = _val[0]; var nod = _val[1]; diff --git a/scripts/panel_preview/panel_preview.gml b/scripts/panel_preview/panel_preview.gml index e56210510..3e0a23561 100644 --- a/scripts/panel_preview/panel_preview.gml +++ b/scripts/panel_preview/panel_preview.gml @@ -594,7 +594,7 @@ function Panel_Preview() : PanelContent() constructor { draw_sprite_stretched(THEME.button, 2, xx, yy, ui(40), ui(40)); if(is_array(_node.tools[i][1])) { - var _ind = tool_sub_index % array_length(_node.tools[i][1]); + var _ind = safe_mod(tool_sub_index, array_length(_node.tools[i][1])); draw_sprite_ui_uniform(_node.tools[i][1][_ind], 0, xx + ui(20), yy + ui(20)); } else draw_sprite_ui_uniform(_node.tools[i][1], 0, xx + ui(20), yy + ui(20)); diff --git a/scripts/polygon/polygon.gml b/scripts/polygon/polygon.gml index e19f79fc5..4f963f381 100644 --- a/scripts/polygon/polygon.gml +++ b/scripts/polygon/polygon.gml @@ -44,10 +44,10 @@ function polygon_points_classify(points) { var side, _side = 0; var convexs = []; var reflects = []; - var startindex = (maxindex - 1 + len) % len; + var startindex = safe_mod(maxindex - 1 + len, len); for( var i = 0; i < len; i++ ) { - var index = (startindex + i) % len; + var index = safe_mod(startindex + i, len); var _px0 = points[index][0]; var _py0 = points[index][1]; var _px1 = points[safe_mod(index + 1, len)][0]; @@ -106,8 +106,8 @@ function polygon_triangulate(points, tolerance = 4) { var len = array_length(pointInd); var c0 = convexes[0]; var c0i = array_find(pointInd, c0); - var c1 = pointInd[(c0i - 1 + len) % len]; - var c2 = pointInd[(c0i + 1) % len]; + var c1 = pointInd[safe_mod(c0i - 1 + len, len)]; + var c2 = pointInd[safe_mod(c0i + 1, len)]; var p0 = points[c0]; var p1 = points[c1]; @@ -137,8 +137,8 @@ function polygon_triangulate(points, tolerance = 4) { if(array_exists(reflected, c1)) { var c1i = array_find(pointInd, c1); - var c1b = (c1i - 1 + len) % len; - var c1a = (c1i + 1) % len; + var c1b = safe_mod(c1i - 1 + len, len); + var c1a = safe_mod(c1i + 1, len); var p1b = points[pointInd[c1b]]; var p1a = points[pointInd[c1a]]; @@ -152,8 +152,8 @@ function polygon_triangulate(points, tolerance = 4) { if(array_exists(reflected, c2)) { var c2i = array_find(pointInd, c2); - var c2b = (c2i - 1 + len) % len; - var c2a = (c2i + 1) % len; + var c2b = safe_mod(c2i - 1 + len, len); + var c2a = safe_mod(c2i + 1, len); var p2b = points[pointInd[c2b]]; var p2a = points[pointInd[c2a]]; diff --git a/scripts/safe_operation/safe_operation.gml b/scripts/safe_operation/safe_operation.gml index 9de068509..ea5931911 100644 --- a/scripts/safe_operation/safe_operation.gml +++ b/scripts/safe_operation/safe_operation.gml @@ -1,3 +1,3 @@ function safe_mod(numb, modd) { - return modd == 0? numb : numb % modd; + return modd == 0? 0 : numb % modd; } \ No newline at end of file diff --git a/scripts/scrollBox/scrollBox.gml b/scripts/scrollBox/scrollBox.gml index ffd98c400..2159ba730 100644 --- a/scripts/scrollBox/scrollBox.gml +++ b/scripts/scrollBox/scrollBox.gml @@ -62,8 +62,8 @@ function scrollBox(_data, _onModify) : widget() constructor { var ind = array_find(data_list, _text); var len = array_length(data_list); if(len) { - if(mouse_wheel_down()) onModify((ind + 1 + len) % len); - if(mouse_wheel_up()) onModify((ind - 1 + len) % len); + if(mouse_wheel_down()) onModify(safe_mod(ind + 1 + len, len)); + if(mouse_wheel_up()) onModify(safe_mod(ind - 1 + len, len)); } } } else { diff --git a/scripts/steam_ugc_functions/steam_ugc_functions.gml b/scripts/steam_ugc_functions/steam_ugc_functions.gml index 124f94db6..c306a0d69 100644 --- a/scripts/steam_ugc_functions/steam_ugc_functions.gml +++ b/scripts/steam_ugc_functions/steam_ugc_functions.gml @@ -71,7 +71,7 @@ function __loadSteamUGCCollection(file_id, f, path) { var _temp = sprite_add(icon_path, 0, false, false, 0, 0); var ww = sprite_get_width(_temp); var hh = sprite_get_height(_temp); - var amo = ww % hh == 0? ww / hh : 1; + var amo = safe_mod(ww, hh) == 0? ww / hh : 1; sprite_delete(_temp); file.spr_path = [icon_path, amo, false]; } diff --git a/scripts/surfaceBox/surfaceBox.gml b/scripts/surfaceBox/surfaceBox.gml index df0335f30..83770268a 100644 --- a/scripts/surfaceBox/surfaceBox.gml +++ b/scripts/surfaceBox/surfaceBox.gml @@ -52,7 +52,7 @@ function surfaceBox(_onModify, def_path = "") : widget() constructor { draw_rectangle(sx0, sy0, sx1, sy1, true); if(is_array(_surface) && array_length(_surface)) - _surface = _surface[round(current_time / 250) % array_length(_surface)]; + _surface = _surface[safe_mod(round(current_time / 250), array_length(_surface))]; if(is_surface(_surface)) { var sfw = surface_get_width(_surface); diff --git a/shaders/sh_trail_filler/sh_trail_filler.fsh b/shaders/sh_trail_filler/sh_trail_filler.fsh new file mode 100644 index 000000000..99c75c4a5 --- /dev/null +++ b/shaders/sh_trail_filler/sh_trail_filler.fsh @@ -0,0 +1,48 @@ +// +// Simple passthrough fragment shader +// +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +#define PI 3.14159265359 + +uniform sampler2D prevFrame; +uniform vec2 dimension; +uniform float range; + +void main() { + vec4 colCur = texture2D( gm_BaseTexture, v_vTexcoord ); + vec4 colPre = texture2D( prevFrame, v_vTexcoord ); + + if(colCur.a > 0.) { + gl_FragColor = colCur; + return; + } + + gl_FragColor = vec4(0.); + float piStep = PI / 64.; + + for(float i = 0.; i <= range; i++) + for(float j = 0.; j <= PI * 2.; j += piStep) { + vec2 shift = vec2(cos(j), sin(j)) * i / dimension; + vec2 pos0 = v_vTexcoord + shift; + vec2 pos1 = v_vTexcoord - shift; + + if(pos0.x < 0. || pos0.y < 0. || pos0.x > 1. || pos0.y > 1.) continue; + vec4 col0 = texture2D( prevFrame, pos0 ); + if(col0.a == 0.) continue; + + vec2 norm = normalize(shift); + + for(float k = 0.; k <= range; k++) { + vec2 posS = v_vTexcoord - norm * k / dimension; + if(posS.x < 0. || posS.y < 0. || posS.x > 1. || posS.y > 1.) continue; + + vec4 colS = texture2D( gm_BaseTexture, posS ); + if(colS.a == 0.) continue; + + gl_FragColor = colS; + return; + } + } +} diff --git a/shaders/sh_trail_filler/sh_trail_filler.vsh b/shaders/sh_trail_filler/sh_trail_filler.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_trail_filler/sh_trail_filler.vsh @@ -0,0 +1,19 @@ +// +// Simple passthrough vertex shader +// +attribute vec3 in_Position; // (x,y,z) +//attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() +{ + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + v_vTexcoord = in_TextureCoord; +} diff --git a/shaders/sh_trail_filler/sh_trail_filler.yy b/shaders/sh_trail_filler/sh_trail_filler.yy new file mode 100644 index 000000000..f46c9c7e8 --- /dev/null +++ b/shaders/sh_trail_filler/sh_trail_filler.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "sh_trail_filler", + "type": 1, + "parent": { + "name": "filter", + "path": "folders/shader/filter.yy", + }, +} \ No newline at end of file diff --git a/sprites/s_node_path_reverse/68b1a5ac-6d57-4e04-92b9-2fe61390b460.png b/sprites/s_node_path_reverse/68b1a5ac-6d57-4e04-92b9-2fe61390b460.png new file mode 100644 index 000000000..b66a6a58f Binary files /dev/null and b/sprites/s_node_path_reverse/68b1a5ac-6d57-4e04-92b9-2fe61390b460.png differ diff --git a/sprites/s_node_path_reverse/layers/68b1a5ac-6d57-4e04-92b9-2fe61390b460/01c1d19d-3467-4f55-8479-4e72ca8ad153.png b/sprites/s_node_path_reverse/layers/68b1a5ac-6d57-4e04-92b9-2fe61390b460/01c1d19d-3467-4f55-8479-4e72ca8ad153.png new file mode 100644 index 000000000..b66a6a58f Binary files /dev/null and b/sprites/s_node_path_reverse/layers/68b1a5ac-6d57-4e04-92b9-2fe61390b460/01c1d19d-3467-4f55-8479-4e72ca8ad153.png differ diff --git a/sprites/s_node_path_reverse/s_node_path_reverse.yy b/sprites/s_node_path_reverse/s_node_path_reverse.yy new file mode 100644 index 000000000..aff279acf --- /dev/null +++ b/sprites/s_node_path_reverse/s_node_path_reverse.yy @@ -0,0 +1,74 @@ +{ + "resourceType": "GMSprite", + "resourceVersion": "1.0", + "name": "s_node_path_reverse", + "bboxMode": 0, + "collisionKind": 1, + "type": 0, + "origin": 4, + "preMultiplyAlpha": false, + "edgeFiltering": false, + "collisionTolerance": 0, + "swfPrecision": 2.525, + "bbox_left": 3, + "bbox_right": 60, + "bbox_top": 14, + "bbox_bottom": 53, + "HTile": false, + "VTile": false, + "For3D": false, + "DynamicTexturePage": false, + "width": 64, + "height": 64, + "textureGroupId": { + "name": "Default", + "path": "texturegroups/Default", + }, + "swatchColours": null, + "gridX": 0, + "gridY": 0, + "frames": [ + {"resourceType":"GMSpriteFrame","resourceVersion":"1.1","name":"68b1a5ac-6d57-4e04-92b9-2fe61390b460",}, + ], + "sequence": { + "resourceType": "GMSequence", + "resourceVersion": "1.4", + "name": "s_node_path_reverse", + "timeUnits": 1, + "playback": 1, + "playbackSpeed": 30.0, + "playbackSpeedType": 0, + "autoRecord": true, + "volume": 1.0, + "length": 1.0, + "events": {"Keyframes":[],"resourceVersion":"1.0","resourceType":"KeyframeStore",}, + "moments": {"Keyframes":[],"resourceVersion":"1.0","resourceType":"KeyframeStore",}, + "tracks": [ + {"resourceType":"GMSpriteFramesTrack","resourceVersion":"1.0","name":"frames","spriteId":null,"keyframes":{"Keyframes":[ + {"id":"5ba3f760-c155-4936-80f8-7c7261057bfc","Key":0.0,"Length":1.0,"Stretch":false,"Disabled":false,"IsCreationKey":false,"Channels":{"0":{"Id":{"name":"68b1a5ac-6d57-4e04-92b9-2fe61390b460","path":"sprites/s_node_path_reverse/s_node_path_reverse.yy",},"resourceVersion":"1.0","resourceType":"SpriteFrameKeyframe",},},"resourceVersion":"1.0","resourceType":"Keyframe",}, + ],"resourceVersion":"1.0","resourceType":"KeyframeStore",},"trackColour":0,"inheritsTrackColour":true,"builtinName":0,"traits":0,"interpolation":1,"tracks":[],"events":[],"isCreationTrack":false,"modifiers":[],}, + ], + "visibleRange": null, + "lockOrigin": false, + "showBackdrop": true, + "showBackdropImage": false, + "backdropImagePath": "", + "backdropImageOpacity": 0.5, + "backdropWidth": 1366, + "backdropHeight": 768, + "backdropXOffset": 0.0, + "backdropYOffset": 0.0, + "xorigin": 32, + "yorigin": 32, + "eventToFunction": {}, + "eventStubScript": null, + }, + "layers": [ + {"resourceType":"GMImageLayer","resourceVersion":"1.0","name":"01c1d19d-3467-4f55-8479-4e72ca8ad153","visible":true,"isLocked":false,"blendMode":0,"opacity":100.0,"displayName":"default",}, + ], + "nineSlice": null, + "parent": { + "name": "path", + "path": "folders/nodes/icons/value/path.yy", + }, +} \ No newline at end of file