diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 2fe946a70..0d00c0ee4 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -101,6 +101,8 @@ {"name":"strandSim","order":5,"path":"folders/nodes/data/simulation/strandSim.yy",}, {"name":"VFX","order":6,"path":"folders/nodes/data/simulation/VFX.yy",}, {"name":"generators","order":1,"path":"folders/nodes/data/simulation/VFX/generators.yy",}, + {"name":"tiler","order":31,"path":"folders/nodes/data/tiler.yy",}, + {"name":"tools","order":1,"path":"folders/nodes/data/tiler/tools.yy",}, {"name":"transform","order":28,"path":"folders/nodes/data/transform.yy",}, {"name":"value","order":29,"path":"folders/nodes/data/value.yy",}, {"name":"atlas","order":1,"path":"folders/nodes/data/value/atlas.yy",}, @@ -165,6 +167,7 @@ {"name":"color_picker","order":4,"path":"folders/shader/color_picker.yy",}, {"name":"color_selector","order":5,"path":"folders/shader/color_selector.yy",}, {"name":"draw","order":6,"path":"folders/shader/draw.yy",}, + {"name":"tiler","order":17,"path":"folders/shader/draw/tiler.yy",}, {"name":"filter","order":7,"path":"folders/shader/filter.yy",}, {"name":"blend_edge","order":40,"path":"folders/shader/filter/blend_edge.yy",}, {"name":"blur","order":50,"path":"folders/shader/filter/blur.yy",}, @@ -400,6 +403,8 @@ {"name":"__shapes","order":3,"path":"scripts/__shapes/__shapes.yy",}, {"name":"__strandSim","order":2,"path":"scripts/__strandSim/__strandSim.yy",}, {"name":"__surface","order":7,"path":"scripts/__surface/__surface.yy",}, + {"name":"__tiler_brush","order":1,"path":"scripts/__tiler_brush/__tiler_brush.yy",}, + {"name":"__tiler_tool","order":1,"path":"scripts/__tiler_tool/__tiler_tool.yy",}, {"name":"__vec2","order":7,"path":"scripts/__vec2/__vec2.yy",}, {"name":"__vec3","order":8,"path":"scripts/__vec3/__vec3.yy",}, {"name":"__vec4","order":9,"path":"scripts/__vec4/__vec4.yy",}, @@ -1371,6 +1376,8 @@ {"name":"textInput","order":3,"path":"scripts/textInput/textInput.yy",}, {"name":"texture_set_repeat","order":1,"path":"scripts/texture_set_repeat/texture_set_repeat.yy",}, {"name":"theme_definition","order":14,"path":"scripts/theme_definition/theme_definition.yy",}, + {"name":"tiler_tool_brush","order":1,"path":"scripts/tiler_tool_brush/tiler_tool_brush.yy",}, + {"name":"tiler_tool_fill","order":2,"path":"scripts/tiler_tool_fill/tiler_tool_fill.yy",}, {"name":"time_source","order":25,"path":"scripts/time_source/time_source.yy",}, {"name":"timeline_data","order":18,"path":"scripts/timeline_data/timeline_data.yy",}, {"name":"toggleGroup","order":7,"path":"scripts/toggleGroup/toggleGroup.yy",}, @@ -1542,7 +1549,10 @@ {"name":"sh_draw_surface_part_tiled","order":1,"path":"shaders/sh_draw_surface_part_tiled/sh_draw_surface_part_tiled.yy",}, {"name":"sh_draw_surface","order":52,"path":"shaders/sh_draw_surface/sh_draw_surface.yy",}, {"name":"sh_draw_texture","order":5,"path":"shaders/sh_draw_texture/sh_draw_texture.yy",}, - {"name":"sh_draw_tile","order":15,"path":"shaders/sh_draw_tile/sh_draw_tile.yy",}, + {"name":"sh_draw_tile_apply","order":2,"path":"shaders/sh_draw_tile_apply/sh_draw_tile_apply.yy",}, + {"name":"sh_draw_tile_brush","order":3,"path":"shaders/sh_draw_tile_brush/sh_draw_tile_brush.yy",}, + {"name":"sh_draw_tile_clear","order":4,"path":"shaders/sh_draw_tile_clear/sh_draw_tile_clear.yy",}, + {"name":"sh_draw_tile_map","order":1,"path":"shaders/sh_draw_tile_map/sh_draw_tile_map.yy",}, {"name":"sh_edge_detect","order":35,"path":"shaders/sh_edge_detect/sh_edge_detect.yy",}, {"name":"sh_edge_shade_apply","order":2,"path":"shaders/sh_edge_shade_apply/sh_edge_shade_apply.yy",}, {"name":"sh_edge_shade_convert","order":1,"path":"shaders/sh_edge_shade_convert/sh_edge_shade_convert.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index b441c0609..191973ceb 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -199,6 +199,8 @@ {"$GMFolder":"","%Name":"VFX","folderPath":"folders/nodes/data/simulation/VFX.yy","name":"VFX","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"affector","folderPath":"folders/nodes/data/simulation/VFX/affector.yy","name":"affector","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"generators","folderPath":"folders/nodes/data/simulation/VFX/generators.yy","name":"generators","resourceType":"GMFolder","resourceVersion":"2.0",}, + {"$GMFolder":"","%Name":"tiler","folderPath":"folders/nodes/data/tiler.yy","name":"tiler","resourceType":"GMFolder","resourceVersion":"2.0",}, + {"$GMFolder":"","%Name":"tools","folderPath":"folders/nodes/data/tiler/tools.yy","name":"tools","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"transform","folderPath":"folders/nodes/data/transform.yy","name":"transform","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"value","folderPath":"folders/nodes/data/value.yy","name":"value","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"array","folderPath":"folders/nodes/data/value/array.yy","name":"array","resourceType":"GMFolder","resourceVersion":"2.0",}, @@ -276,6 +278,7 @@ {"$GMFolder":"","%Name":"color_picker","folderPath":"folders/shader/color_picker.yy","name":"color_picker","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"color_selector","folderPath":"folders/shader/color_selector.yy","name":"color_selector","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"draw","folderPath":"folders/shader/draw.yy","name":"draw","resourceType":"GMFolder","resourceVersion":"2.0",}, + {"$GMFolder":"","%Name":"tiler","folderPath":"folders/shader/draw/tiler.yy","name":"tiler","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"filter","folderPath":"folders/shader/filter.yy","name":"filter","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"blend_edge","folderPath":"folders/shader/filter/blend_edge.yy","name":"blend_edge","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"blur","folderPath":"folders/shader/filter/blur.yy","name":"blur","resourceType":"GMFolder","resourceVersion":"2.0",}, @@ -886,6 +889,8 @@ {"id":{"name":"__shapes","path":"scripts/__shapes/__shapes.yy",},}, {"id":{"name":"__strandSim","path":"scripts/__strandSim/__strandSim.yy",},}, {"id":{"name":"__surface","path":"scripts/__surface/__surface.yy",},}, + {"id":{"name":"__tiler_brush","path":"scripts/__tiler_brush/__tiler_brush.yy",},}, + {"id":{"name":"__tiler_tool","path":"scripts/__tiler_tool/__tiler_tool.yy",},}, {"id":{"name":"__vec2","path":"scripts/__vec2/__vec2.yy",},}, {"id":{"name":"__vec3","path":"scripts/__vec3/__vec3.yy",},}, {"id":{"name":"__vec4","path":"scripts/__vec4/__vec4.yy",},}, @@ -1761,6 +1766,7 @@ {"id":{"name":"node_threshold","path":"scripts/node_threshold/node_threshold.yy",},}, {"id":{"name":"node_tile_random","path":"scripts/node_tile_random/node_tile_random.yy",},}, {"id":{"name":"node_tile","path":"scripts/node_tile/node_tile.yy",},}, + {"id":{"name":"node_tiler","path":"scripts/node_tiler/node_tiler.yy",},}, {"id":{"name":"node_time_remap","path":"scripts/node_time_remap/node_time_remap.yy",},}, {"id":{"name":"node_timeline_preview","path":"scripts/node_timeline_preview/node_timeline_preview.yy",},}, {"id":{"name":"node_to_number","path":"scripts/node_to_number/node_to_number.yy",},}, @@ -2010,6 +2016,8 @@ {"id":{"name":"texture_set_interpolation","path":"scripts/texture_set_interpolation/texture_set_interpolation.yy",},}, {"id":{"name":"texture_set_repeat","path":"scripts/texture_set_repeat/texture_set_repeat.yy",},}, {"id":{"name":"theme_definition","path":"scripts/theme_definition/theme_definition.yy",},}, + {"id":{"name":"tiler_tool_brush","path":"scripts/tiler_tool_brush/tiler_tool_brush.yy",},}, + {"id":{"name":"tiler_tool_fill","path":"scripts/tiler_tool_fill/tiler_tool_fill.yy",},}, {"id":{"name":"time_source","path":"scripts/time_source/time_source.yy",},}, {"id":{"name":"timeline_data","path":"scripts/timeline_data/timeline_data.yy",},}, {"id":{"name":"timer_function","path":"scripts/timer_function/timer_function.yy",},}, @@ -2203,6 +2211,10 @@ {"id":{"name":"sh_draw_surface_part_tiled","path":"shaders/sh_draw_surface_part_tiled/sh_draw_surface_part_tiled.yy",},}, {"id":{"name":"sh_draw_surface","path":"shaders/sh_draw_surface/sh_draw_surface.yy",},}, {"id":{"name":"sh_draw_texture","path":"shaders/sh_draw_texture/sh_draw_texture.yy",},}, + {"id":{"name":"sh_draw_tile_apply","path":"shaders/sh_draw_tile_apply/sh_draw_tile_apply.yy",},}, + {"id":{"name":"sh_draw_tile_brush","path":"shaders/sh_draw_tile_brush/sh_draw_tile_brush.yy",},}, + {"id":{"name":"sh_draw_tile_clear","path":"shaders/sh_draw_tile_clear/sh_draw_tile_clear.yy",},}, + {"id":{"name":"sh_draw_tile_map","path":"shaders/sh_draw_tile_map/sh_draw_tile_map.yy",},}, {"id":{"name":"sh_draw_tile","path":"shaders/sh_draw_tile/sh_draw_tile.yy",},}, {"id":{"name":"sh_draw_vertex_aa","path":"shaders/sh_draw_vertex_aa/sh_draw_vertex_aa.yy",},}, {"id":{"name":"sh_edge_detect","path":"shaders/sh_edge_detect/sh_edge_detect.yy",},}, diff --git a/datafiles/data/Theme.zip b/datafiles/data/Theme.zip index ef0ccd5da..170ce8b2a 100644 Binary files a/datafiles/data/Theme.zip and b/datafiles/data/Theme.zip differ diff --git a/objects/o_dialog_palette/Draw_64.gml b/objects/o_dialog_palette/Draw_64.gml index 8412611aa..a13c6d020 100644 --- a/objects/o_dialog_palette/Draw_64.gml +++ b/objects/o_dialog_palette/Draw_64.gml @@ -360,6 +360,8 @@ if palette == 0 exit; if(array_length(palette) > 1) { if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, "", THEME.minus) == 2) { array_delete(palette, index_selecting[0], index_selecting[1]); + if(array_empty(palette)) + palette = [ c_black ]; index_selecting = [ 0, 0 ]; onApply(palette); diff --git a/scripts/__canvas_brush/__canvas_brush.gml b/scripts/__canvas_brush/__canvas_brush.gml index e0efbe92a..e6b08447e 100644 --- a/scripts/__canvas_brush/__canvas_brush.gml +++ b/scripts/__canvas_brush/__canvas_brush.gml @@ -1,10 +1,4 @@ function canvas_brush() constructor { - brush_sizing = false; - brush_sizing_s = 0; - brush_sizing_mx = 0; - brush_sizing_my = 0; - brush_sizing_dx = 0; - brush_sizing_dy = 0; brush_use_surface = false; brush_surface = noone; @@ -16,6 +10,13 @@ function canvas_brush() constructor { brush_seed = irandom_range(100000, 999999); brush_next_dist = 0; + brush_sizing = false; + brush_sizing_s = 0; + brush_sizing_mx = 0; + brush_sizing_my = 0; + brush_sizing_dx = 0; + brush_sizing_dy = 0; + mouse_pre_dir_x = undefined; mouse_pre_dir_y = undefined; diff --git a/scripts/__tiler_brush/__tiler_brush.gml b/scripts/__tiler_brush/__tiler_brush.gml new file mode 100644 index 000000000..390fcce2a --- /dev/null +++ b/scripts/__tiler_brush/__tiler_brush.gml @@ -0,0 +1,122 @@ +function tiler_brush(node) constructor { + brush_size = 1; + brush_indices = [[]]; + brush_width = 0; + brush_height = 0; + + brush_surface = noone; + brush_erase = false; + + brush_sizing = false; + brush_sizing_s = 0; + brush_sizing_mx = 0; + brush_sizing_my = 0; + brush_sizing_dx = 0; + brush_sizing_dy = 0; + + self.node = node; + + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + var attr = node.tool_attribute; + var _siz = attr.size; + + brush_size = _siz; + + if(brush_size = PEN_USE && attr.pressure) + brush_size = round(lerp(attr.pressure_size[0], attr.pressure_size[1], power(PEN_PRESSURE / 1024, 2))); + } + + function sizing(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + var attr = node.tool_attribute; + var _siz = attr.size; + + if(brush_sizing) { + var s = brush_sizing_s + (_mx - brush_sizing_mx) / 16; + s = max(1, s); + attr.size = s; + + if(mouse_release(mb_right)) + brush_sizing = false; + + } else if(mouse_press(mb_right, active) && key_mod_press(SHIFT) && brush_surface == noone) { + + brush_sizing = true; + brush_sizing_s = _siz; + brush_sizing_mx = _mx; + brush_sizing_my = _my; + + brush_sizing_dx = round((_mx - _x) / _s - 0.5); + brush_sizing_dy = round((_my - _y) / _s - 0.5); + } + } +} + +function tiler_draw_point_brush(brush, _x, _y) { + if(brush.brush_height * brush.brush_width == 0) return; + + shader_set(sh_draw_tile_brush); + BLEND_OVERRIDE + + for( var i = 0, n = brush.brush_height; i < n; i++ ) + for( var j = 0, m = brush.brush_width; j < m; j++ ) { + shader_set_f("index", brush.brush_erase? -1 : brush.brush_indices[i][j]); + + var _xx = _x + j; + var _yy = _y + i; + + if(brush.brush_size <= 1) + draw_point(_xx, _yy); + + else if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + var fx = global.FIX_POINTS[brush.brush_size]; + for( var i = 0, n = array_length(fx); i < n; i++ ) + draw_point(_xx + fx[i][0], _yy + fx[i][1]); + + } else + draw_circle_prec(_xx, _yy, brush.brush_size / 2, 0); + } + + BLEND_NORMAL + shader_reset(); +} + +function tiler_draw_line_brush(brush, _x0, _y0, _x1, _y1) { + if(brush.brush_height * brush.brush_width == 0) return; + + shader_set(sh_draw_tile_brush); + BLEND_OVERRIDE + + for( var i = 0, n = brush.brush_height; i < n; i++ ) + for( var j = 0, m = brush.brush_width; j < m; j++ ) { + shader_set_f("index", brush.brush_erase? -1 : brush.brush_indices[i][j]); + + var _xx0 = _x0 + j; + var _yy0 = _y0 + i; + var _xx1 = _x1 + j; + var _yy1 = _y1 + i; + + if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + if(_xx1 > _xx0) _xx0--; + if(_xx1 < _xx0) _xx1--; + + if(_yy1 > _yy0) _yy0--; + if(_yy1 < _yy0) _yy1--; + } + + if(brush.brush_size == 1) { + draw_line(_xx0, _yy0, _xx1, _yy1); + + } else if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + + var fx = global.FIX_POINTS[brush.brush_size]; + for( var i = 0, n = array_length(fx); i < n; i++ ) + draw_line(_xx0 + fx[i][0], _yy0 + fx[i][1], _xx1 + fx[i][0], _yy1 + fx[i][1]); + + } else { + draw_line_width(_xx0, _yy0, _xx1, _yy1, brush.brush_size); + } + } + + BLEND_NORMAL + shader_reset(); +} \ No newline at end of file diff --git a/scripts/__tiler_brush/__tiler_brush.yy b/scripts/__tiler_brush/__tiler_brush.yy new file mode 100644 index 000000000..b3fecc547 --- /dev/null +++ b/scripts/__tiler_brush/__tiler_brush.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"v1", + "%Name":"__tiler_brush", + "isCompatibility":false, + "isDnD":false, + "name":"__tiler_brush", + "parent":{ + "name":"tools", + "path":"folders/nodes/data/tiler/tools.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/__tiler_tool/__tiler_tool.gml b/scripts/__tiler_tool/__tiler_tool.gml new file mode 100644 index 000000000..0954cf624 --- /dev/null +++ b/scripts/__tiler_tool/__tiler_tool.gml @@ -0,0 +1,17 @@ +function tiler_tool(node) constructor { + self.node = node; + subtool = 0; + brush_resizable = true; + + apply_draw_surface = noone; + drawing_surface = noone; + preview_draw_mask = noone; + + tile_size = [ 1, 1 ]; + + static init = function() {} + static step = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {} + + static drawPreview = function() {} + static drawMask = function() {} +} \ No newline at end of file diff --git a/scripts/__tiler_tool/__tiler_tool.yy b/scripts/__tiler_tool/__tiler_tool.yy new file mode 100644 index 000000000..e5f81612f --- /dev/null +++ b/scripts/__tiler_tool/__tiler_tool.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"v1", + "%Name":"__tiler_tool", + "isCompatibility":false, + "isDnD":false, + "name":"__tiler_tool", + "parent":{ + "name":"tools", + "path":"folders/nodes/data/tiler/tools.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/buffer_functions/buffer_functions.gml b/scripts/buffer_functions/buffer_functions.gml index 7868f6abd..2020f858b 100644 --- a/scripts/buffer_functions/buffer_functions.gml +++ b/scripts/buffer_functions/buffer_functions.gml @@ -84,13 +84,7 @@ function buffer_write_at(buffer, position, type, data) { function buffer_serialize(buffer, compress = true) { INLINE if(!buffer_exists(buffer)) return ""; - - if(compress) { - var comp = buffer_compress(buffer, 0, buffer_get_size(buffer)); - return buffer_base64_encode(comp, 0, buffer_get_size(comp)); - } - - return buffer_base64_encode(buffer, 0, buffer_get_size(buffer)); + return compress? buffer_compress_all(buffer) : buffer_base64_encode(buffer, 0, buffer_get_size(buffer)); } function buffer_deserialize(buffer, compress = true) { @@ -123,6 +117,11 @@ function buffer_compress_string(str) { return buffer_compress(buffer, 0, buffer_get_size(buffer)); } +function buffer_compress_all(buff) { + var comp = buffer_compress(buff, 0, buffer_get_size(buff)); + return buffer_base64_encode(comp, 0, buffer_get_size(comp)); +} + function buffer_to_start(buff) { INLINE buffer_seek(buff, buffer_seek_start, 0); } function buffer_delete_safe(buff) { INLINE if(buffer_exists(buff)) buffer_delete(buff); } \ No newline at end of file diff --git a/scripts/canvas_flood_fill_functions/canvas_flood_fill_functions.gml b/scripts/canvas_flood_fill_functions/canvas_flood_fill_functions.gml index fd285a557..518ee484a 100644 --- a/scripts/canvas_flood_fill_functions/canvas_flood_fill_functions.gml +++ b/scripts/canvas_flood_fill_functions/canvas_flood_fill_functions.gml @@ -1,13 +1,12 @@ function _ff_getPixel(_x, _y) { return buffer_read_at(_ff_buff, (_y * _ff_w + _x) * 4, buffer_u32); } -function canvas_ff_fillable(colorBase, colorFill, _x, _y, _thres) { #region +function canvas_ff_fillable(colorBase, colorFill, _x, _y, _thres) { var c = _ff_getPixel(_x, _y); var d = color_diff_alpha(colorBase, c); - //print($"Checking [{_x}, {_y}]: {colorBase} - {c} : {_color_get_alpha(colorBase)} - {_color_get_alpha(c)} | {d}"); return d <= _thres && c != colorFill; -} #endregion +} -function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #region +function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { var colorFill = CURRENT_COLOR; var colorBase = int64(surface_getpixel_ext(_surf, _x, _y)); @@ -95,9 +94,9 @@ function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #r draw_set_alpha(1); buffer_delete(_ff_buff); -} #endregion +} -function canvas_flood_fill_all(_surf, _x, _y, _thres) { #region +function canvas_flood_fill_all(_surf, _x, _y, _thres) { var colorBase = surface_getpixel_ext(_surf, _x, _y); var colorFill = colorBase; @@ -134,4 +133,4 @@ function canvas_flood_fill_all(_surf, _x, _y, _thres) { #region buffer_delete(_ff_buff); return [ sel_x0, sel_y0, sel_x1, sel_y1 ]; -} #endregion \ No newline at end of file +} \ No newline at end of file diff --git a/scripts/canvas_tool_fill/canvas_tool_fill.gml b/scripts/canvas_tool_fill/canvas_tool_fill.gml index d60419917..d85dcdc4f 100644 --- a/scripts/canvas_tool_fill/canvas_tool_fill.gml +++ b/scripts/canvas_tool_fill/canvas_tool_fill.gml @@ -31,8 +31,4 @@ function canvas_tool_fill(toolAttr) : canvas_tool() constructor { } } - - function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { - - } } \ No newline at end of file diff --git a/scripts/color_selector/color_selector.gml b/scripts/color_selector/color_selector.gml index d680960cb..2edfa57ae 100644 --- a/scripts/color_selector/color_selector.gml +++ b/scripts/color_selector/color_selector.gml @@ -413,6 +413,7 @@ function colorSelector(onApply = noone) constructor { draw_sprite_stretched_ext(THEME.color_picker_box, 1, cx - ui(18), cy - ui(18), ui(36), ui(36), current_color, aa); cx += ui(48); + if(interactable) if(buttonInstant(THEME.button_hide, cx - ui(18), cy - ui(18), ui(36), ui(36), mouse_ui, focus, hover, "", THEME.color_picker_dropper, 0, c_white) == 2) dropper_active = true; } diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index 765038985..bf400ebfe 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -42,7 +42,7 @@ LATEST_VERSION = 1_18_00_0; VERSION = 1_18_01_0; SAVE_VERSION = 1_18_01_0; - VERSION_STRING = MAC? "1.18.003m" : "1.18.2.005"; + VERSION_STRING = MAC? "1.18.003m" : "1.18.2.0077"; BUILD_NUMBER = 1_18_01_0; HOTKEYS = ds_map_create(); diff --git a/scripts/node_canvas/node_canvas.gml b/scripts/node_canvas/node_canvas.gml index 1554b8d95..869a91b5d 100644 --- a/scripts/node_canvas/node_canvas.gml +++ b/scripts/node_canvas/node_canvas.gml @@ -749,7 +749,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor prev_surface = surface_verify(prev_surface, _dim[0], _dim[1]); preview_draw_surface = surface_verify(preview_draw_surface, _dim[0], _dim[1]); - preview_draw_mask = surface_verify(preview_draw_mask, _sw, _sh); + preview_draw_mask = surface_verify(preview_draw_mask, _sw, _sh); #endregion #region tool diff --git a/scripts/node_collection/node_collection.gml b/scripts/node_collection/node_collection.gml index 9a22f7b2b..ca1b94871 100644 --- a/scripts/node_collection/node_collection.gml +++ b/scripts/node_collection/node_collection.gml @@ -533,7 +533,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc if(_s < 0.75) return; var _bx = (xx + w * _s) - 10; - var _by = (yy + h * _s) - 10; + var _by = previewable? (yy + h * _s) - 10 : yy + h / 2 * _s; var _hv = PANEL_GRAPH.pHOVER && PANEL_GRAPH.node_hovering == self && PANEL_GRAPH._value_focus == noone; _hv &= point_in_circle(_mx, _my, _bx, _by, 8); diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 402326a2b..d60a8fb9d 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -515,9 +515,6 @@ function __initNodes() { var input = ds_list_create(); addNodeCatagory("IO", input); ds_list_add(input, "Images"); - addNodeObject(input, "Canvas", s_node_canvas, "Node_Canvas", [1, Node_Canvas], ["draw"], "Draw on surface using brush, eraser, etc."); - addNodeObject(input, "Canvas Group", s_node_canvas_group, "Node_Canvas_Group", [1, Node_Canvas_Group],, "Create a group that combines multiple canvas nodes a layers.").setVersion(11740); - addNodeObject(input, "Active Canvas", s_node_active_canvas, "Node_Active_Canvas", [1, Node_Active_Canvas], ["draw"], "Draw using parameterized brush.").setVersion(11570); addNodeObject(input, "Image", s_node_image, "Node_Image", [0, Node_create_Image],, "Load a single image from your computer."); addNodeObject(input, "Image GIF", s_node_image_gif, "Node_Image_gif", [0, Node_create_Image_gif],, "Load animated .gif from your computer."); addNodeObject(input, "Splice Spritesheet", s_node_image_sheet, "Node_Image_Sheet", [1, Node_Image_Sheet],, "Cut up spritesheet into animation or image array."); @@ -527,6 +524,12 @@ function __initNodes() { addNodeObject(input, "SVG", s_node_svg, "Node_SVG", [1, Node_SVG],, "Load a SVG file."); if(!DEMO) addNodeObject(input, "Export", s_node_export, "Node_Export", [0, Node_create_Export],, "Export image, image array to file, image sequence, animation."); + ds_list_add(input, "Draw"); + addNodeObject(input, "Canvas", s_node_canvas, "Node_Canvas", [1, Node_Canvas], ["draw"], "Draw on surface using brush, eraser, etc."); + addNodeObject(input, "Canvas Group", s_node_canvas_group, "Node_Canvas_Group", [1, Node_Canvas_Group],, "Create a group that combines multiple canvas nodes a layers.").setVersion(11740); + addNodeObject(input, "Active Canvas", s_node_active_canvas, "Node_Active_Canvas", [1, Node_Active_Canvas], ["draw"], "Draw using parameterized brush.").setVersion(11570); + /**/ addNodeObject(input, "Tile Drawer", s_node_svg, "Node_Tile_Drawer", [1, Node_Tile_Drawer],, "Draw using tileset.").setVersion(1_18_02_0); + ds_list_add(input, "Files"); addNodeObject(input, "Text File In", s_node_text_file_read, "Node_Text_File_Read", [1, Node_Text_File_Read], ["txt"], "Load .txt in as text.").setVersion(1080); addNodeObject(input, "Text File Out", s_node_text_file_write, "Node_Text_File_Write", [1, Node_Text_File_Write], ["txt"], "Save text as a .txt file.").setVersion(1090); diff --git a/scripts/node_repeat/node_repeat.gml b/scripts/node_repeat/node_repeat.gml index 2a6c0feb4..4049280c5 100644 --- a/scripts/node_repeat/node_repeat.gml +++ b/scripts/node_repeat/node_repeat.gml @@ -34,15 +34,15 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co newInput(4, nodeValue_Vec2("Shift position", self, [ DEF_SURF_W / 2, 0 ])) .setUnitRef(function() /*=>*/ {return getDimension()}); - newInput(5, nodeValue_Rotation_Range("Repeat rotation", self, [0, 0])); + newInput(5, nodeValue_Rotation_Range("Repeat rotation", self, [ 0, 0 ])); newInput(6, nodeValue_Float("Scale multiply", self, 1)); - newInput(7, nodeValue_Rotation_Range("Angle range", self, [0, 360])); + newInput(7, nodeValue_Rotation_Range("Angle range", self, [ 0, 360 ])); newInput(8, nodeValue_Float("Radius", self, 1)); - newInput(9, nodeValue_Vec2("Start position", self, [0, 0])) + newInput(9, nodeValue_Vec2("Start position", self, [ 0, 0 ])) .setUnitRef(function(index) { return getInputData(1); }); newInput(10, nodeValue_Curve("Scale over copy", self, CURVE_DEF_11 )); @@ -105,7 +105,7 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co newInput(32, nodeValue_Rotation("Start rotation", self, 0)); - newInput(33, nodeValue_Rotation("Rotation", self, 0)); + newInput(33, nodeValue_Rotation("Base rotation", self, 0)); newInput(34, nodeValue_Enum_Scroll("Blend Mode", self, 0, [ "Normal", "Additive", "Maximum" ])); @@ -429,7 +429,7 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co scax = eval_curve_x(_msca, i / (_amo - 1)) * _rsca; scay = scax; - rot = _rots + _rrot[0] + (_rrot[1] - _rrot[0]) * i / _amo; + rot = _rots + lerp(_rrot[0], _rrot[1], i / _amo); var _surf = _iSrf; if(is_array(_iSrf)) { @@ -477,10 +477,9 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co if(_rsta == 2) runy += _sh / 2; } - array_resize(atlases, atlas_i); var __temp_p = [ 0,0 ]; - for( var i = 0, n = array_length(atlases); i < n; i++ ) { // animators + for( var i = 0, n = atlas_i; i < n; i++ ) { // animators var _a = atlases[i]; var _surf = _a.surface; @@ -591,7 +590,7 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co var sw = _sw * _a.sx; var sh = _sh * _a.sy; - var pos = point_rotate(-sw / 2, -sh / 2, 0, 0, rot); + var pos = point_rotate(-sw / 2, -sh / 2, 0, 0, _a.rot); minx = min(minx, _x + pos[0], _x - pos[0], _x + pos[1], _x - pos[1]); miny = min(miny, _y + pos[0], _y - pos[0], _y + pos[1], _y - pos[1]); @@ -646,7 +645,7 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co else if(_bld_md == 1) { BLEND_ADD } else if(_bld_md == 2) { BLEND_MAX } - for( var i = 0, n = array_length(atlases); i < n; i++ ) { + for( var i = 0, n = atlas_i; i < n; i++ ) { var _a = atlases[i]; shader_set_interpolation(_a.surface); diff --git a/scripts/node_smear/node_smear.gml b/scripts/node_smear/node_smear.gml index 41884760f..2d0232b92 100644 --- a/scripts/node_smear/node_smear.gml +++ b/scripts/node_smear/node_smear.gml @@ -41,10 +41,12 @@ function Node_Smear(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con newInput(15, nodeValue_Enum_Scroll("Blend Mode", self, 0, [ "Maximum", "Additive" ])); + newInput(16, nodeValue_Bool("Normalize", self, false)); + input_display_list = [ 5, 6, ["Surfaces", true], 0, 3, 4, 7, 8, ["Smear", false], 11, 14, 1, 9, 2, 10, 13, 12, - ["Render", false], 15, + ["Render", false], 16, 15, ] newOutput(0, nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone)); @@ -90,6 +92,7 @@ function Node_Smear(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con shader_set_i("blend", _data[15]); shader_set_i("modulateStr", _data[12]); shader_set_f("spread", _data[13]); + shader_set_i("normalized", _data[16]); draw_surface_safe(_data[0]); surface_reset_shader(); diff --git a/scripts/node_tiler/node_tiler.gml b/scripts/node_tiler/node_tiler.gml new file mode 100644 index 000000000..272917596 --- /dev/null +++ b/scripts/node_tiler/node_tiler.gml @@ -0,0 +1,480 @@ +function Node_Tile_Drawer(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Tile Drawer"; + bypass_grid = true; + + newInput( 0, nodeValue_Surface("Tileset", self, noone)); + + newInput( 1, nodeValue_IVec2("Map size", self, [ 16, 16 ])); + + newInput( 2, nodeValue_Vec2("Tile size", self, [ 16, 16 ])); + + #region tile selector + tile_selector_surface = 0; + tile_selector_mask = 0; + tile_selector_h = ui(320); + + tile_selector_x = 0; + tile_selector_y = 0; + tile_selector_s = 1; + tile_selector_s_to = 1; + + tile_dragging = false; + tile_drag_sx = 0; + tile_drag_sy = 0; + tile_drag_mx = 0; + tile_drag_my = 0; + + tile_selecting = false; + tile_select_ss = [ 0, 0 ]; + + grid_draw = true; + + tile_selector = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus, _panel = noone) { + var _h = tile_selector_h; + var _pd = ui(4); + var _tileSet = current_data[0]; + var _tileSiz = current_data[2]; + + var _sx = _x + _pd; + var _sy = _y + _pd; + var _sw = _w - _pd * 2; + var _sh = _h - _pd * 2; + + draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, _x, _y, _w, _h, c_white, 1); + tile_selector_surface = surface_verify(tile_selector_surface, _sw, _sh); + tile_selector_mask = surface_verify(tile_selector_mask, _sw, _sh); + + if(!is_surface(_tileSet)) return _h; + + var _tdim = surface_get_dimension(_tileSet); + + var _tileAmo = [ floor(_tdim[0] / _tileSiz[0]), floor(_tdim[1] / _tileSiz[1]) ]; + + var _tileSel_w =_tileSiz[0] * tile_selector_s; + var _tileSel_h =_tileSiz[1] * tile_selector_s; + + var _msx = _m[0] - _sx - tile_selector_x; + var _msy = _m[1] - _sy - tile_selector_y; + + var _mtx = floor(_msx / tile_selector_s / _tileSiz[0]); + var _mty = floor(_msy / tile_selector_s / _tileSiz[1]); + var _mid = _mtx >= 0 && _mtx < _tileAmo[0] && _mty >= 0 && _mtx < _tileAmo[1]? _mty * _tileAmo[0] + _mtx : noone; + + var _tileHov_x = tile_selector_x + _mtx * _tileSiz[0] * tile_selector_s; + var _tileHov_y = tile_selector_y + _mty * _tileSiz[1] * tile_selector_s; + + var _hov = _hover && point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h); + + surface_set_target(tile_selector_surface); + draw_clear(COLORS.panel_bg_clear); + draw_sprite_tiled_ext(s_transparent, 0, tile_selector_x, tile_selector_y, tile_selector_s, tile_selector_s, COLORS.panel_preview_transparent, 1); + + draw_surface_ext(_tileSet, tile_selector_x, tile_selector_y, tile_selector_s, tile_selector_s, 0, c_white, 1); + + if(grid_draw) { + var _gw = _tileSiz[0] * tile_selector_s; + var _gh = _tileSiz[1] * tile_selector_s; + + var gw = _tdim[0] / _tileSiz[0]; + var gh = _tdim[1] / _tileSiz[1]; + + var cx = tile_selector_x; + var cy = tile_selector_y; + + draw_set_color(PROJECT.previewGrid.color); + draw_set_alpha(PROJECT.previewGrid.opacity); + + for( var i = 1; i < gw; i++ ) { + var _xx = cx + i * _gw; + draw_line(_xx, cy, _xx, cy + _tdim[1] * tile_selector_s); + } + + for( var i = 1; i < gh; i++ ) { + var _yy = cy + i * _gh; + draw_line(cx, _yy, cx + _tdim[0] * tile_selector_s, _yy); + } + + draw_set_alpha(1); + } + + draw_set_color(COLORS.panel_preview_surface_outline); + draw_rectangle(tile_selector_x, tile_selector_y, tile_selector_x + _tdim[0] * tile_selector_s - 1, tile_selector_y + _tdim[1] * tile_selector_s - 1, true); + + draw_set_color(c_black); + draw_rectangle_width(_tileHov_x, _tileHov_y, _tileHov_x + _tileSel_w - 1, _tileHov_y + _tileSel_h - 1, 1); + + if(_hov && _mid > noone && mouse_press(mb_left, _focus)) { + tile_selecting = true; + tile_select_ss = [ _mtx, _mty ]; + } + surface_reset_target(); + + surface_set_target(tile_selector_mask); + DRAW_CLEAR + + draw_set_color(c_white); + + for( var i = 0, n = array_length(brush.brush_indices); i < n; i++ ) + for( var j = 0, m = array_length(brush.brush_indices[i]); j < m; j++ ) { + var _bindex = brush.brush_indices[i][j]; + var _tileSel_row = floor(_bindex / _tileAmo[0]); + var _tileSel_col = safe_mod(_bindex, _tileAmo[0]); + var _tileSel_x = tile_selector_x + _tileSel_col * _tileSiz[0] * tile_selector_s; + var _tileSel_y = tile_selector_y + _tileSel_row * _tileSiz[1] * tile_selector_s; + draw_rectangle(_tileSel_x, _tileSel_y, _tileSel_x + _tileSel_w, _tileSel_y + _tileSel_h, false); + } + surface_reset_target(); + + #region tile selection + if(tile_selecting) { + var _ts_sx = clamp(min(tile_select_ss[0], _mtx), 0, _tileAmo[0] - 1); + var _ts_sy = clamp(min(tile_select_ss[1], _mty), 0, _tileAmo[1] - 1); + var _ts_ex = clamp(max(tile_select_ss[0], _mtx), 0, _tileAmo[0] - 1); + var _ts_ey = clamp(max(tile_select_ss[1], _mty), 0, _tileAmo[1] - 1); + + brush.brush_indices = []; + brush.brush_width = _ts_ex - _ts_sx + 1; + brush.brush_height = _ts_ey - _ts_sy + 1; + var _ind = 0; + + for( var i = _ts_sy; i <= _ts_ey; i++ ) + for( var j = _ts_sx; j <= _ts_ex; j++ ) + brush.brush_indices[i - _ts_sy][j - _ts_sx] = i * _tileAmo[0] + j; + + if(mouse_release(mb_left)) + tile_selecting = false; + } + #endregion + + #region pan zoom + if(tile_dragging) { + var _tdx = _m[0] - tile_drag_mx; + var _tdy = _m[1] - tile_drag_my; + + tile_selector_x = tile_drag_sx + _tdx; + tile_selector_y = tile_drag_sy + _tdy; + + if(mouse_release(mb_middle)) + tile_dragging = false; + } + + if(_hov) { + if(mouse_press(mb_middle, _focus)) { + tile_dragging = true; + tile_drag_sx = tile_selector_x; + tile_drag_sy = tile_selector_y; + tile_drag_mx = _m[0]; + tile_drag_my = _m[1]; + } + + var _s = tile_selector_s; + if(mouse_wheel_up()) { tile_selector_s_to = clamp(tile_selector_s_to * 1.1, 0.5, 4); } + if(mouse_wheel_down()) { tile_selector_s_to = clamp(tile_selector_s_to / 1.1, 0.5, 4); } + tile_selector_s = lerp_float(tile_selector_s, tile_selector_s_to, 3); + + if(_s != tile_selector_s) { + var _ds = tile_selector_s - _s; + + tile_selector_x -= _msx * _ds / _s; + tile_selector_y -= _msy * _ds / _s; + } + } + + var _tdim_ws = _tdim[0] * tile_selector_s; + var _tdim_hs = _tdim[1] * tile_selector_s; + var _minx = -(_tdim_ws - _w) - 32; + var _miny = -(_tdim_hs - _h) - 32; + var _maxx = 32; + var _maxy = 32; + if(_minx > _maxx) { _minx = (_minx + _maxx) / 2; _maxx = _minx; } + if(_miny > _maxy) { _miny = (_miny + _maxy) / 2; _maxy = _miny; } + + tile_selector_x = clamp(tile_selector_x, _minx, _maxx); + tile_selector_y = clamp(tile_selector_y, _miny, _maxy); + #endregion + + draw_surface(tile_selector_surface, _sx, _sy); + + shader_set(sh_brush_outline); + shader_set_f("dimension", _sw, _sh); + draw_surface(tile_selector_mask, _sx, _sy); + shader_reset(); + + return _h; + }); + #endregion + + input_display_list = [ + ["Tileset", false], 0, 2, + ["Map", false], 1, + ["Tiles", false], tile_selector, + ] + + newOutput(0, nodeValue_Output("Tile output", self, VALUE_TYPE.surface, noone)); + + newOutput(1, nodeValue_Output("Tile map", self, VALUE_TYPE.surface, noone)); + + newOutput(2, nodeValue_Output("Index array", self, VALUE_TYPE.integer, [])) + .setArrayDepth(1); + + #region ++++ data ++++ + canvas_surface = surface_create_empty(1, 1, surface_r16float); + canvas_buffer = buffer_create(1 * 1 * 2, buffer_grow, 2); + + drawing_surface = surface_create_empty(1, 1, surface_r16float); + draw_stack = ds_list_create(); + + preview_drawing_tile = surface_create_empty(1, 1); + preview_draw_overlay = surface_create_empty(1, 1); + preview_draw_overlay_tile = surface_create_empty(1, 1); + + _preview_draw_mask = surface_create_empty(1, 1); + preview_draw_mask = surface_create_empty(1, 1); + + attributes.dimension = [ 1, 1 ]; + temp_surface = [ 0 ]; + #endregion + + #region ++++ tool object ++++ + brush = new tiler_brush(self); + + tool_brush = new tiler_tool_brush(self, brush, false); + tool_eraser = new tiler_tool_brush(self, brush, true); + tool_fill = new tiler_tool_fill( self, brush, tool_attribute); + #endregion + + #region ++++ tools ++++ + tool_attribute.size = 1; + tool_size_edit = new textBox(TEXTBOX_INPUT.number, function(val) { tool_attribute.size = max(1, round(val)); }).setSlideType(true) + .setFont(f_p3) + .setSideButton(button(function() { dialogPanelCall(new Panel_Node_Canvas_Pressure(self), mouse_mx, mouse_my, { anchor: ANCHOR.top | ANCHOR.left }) }) + .setIcon(THEME.pen_pressure, 0, COLORS._main_icon)); + tool_size = [ "Size", tool_size_edit, "size", tool_attribute ]; + + tool_attribute.fillType = 0; + tool_fil8_edit = new buttonGroup( [ THEME.canvas_fill_type, THEME.canvas_fill_type, THEME.canvas_fill_type ], function(val) { tool_attribute.fillType = val; }) + .setTooltips( [ "Edge", "Edge + Corner" ] ) + .setCollape(false); + tool_fil8 = [ "Fill", tool_fil8_edit, "fillType", tool_attribute ]; + + tools = [ + new NodeTool( "Pencil", THEME.canvas_tools_pencil) + .setSetting(tool_size) + .setToolObject(tool_brush), + + new NodeTool( "Eraser", THEME.canvas_tools_eraser) + .setSetting(tool_size) + .setToolObject(tool_eraser), + + new NodeTool( "Fill", THEME.canvas_tools_bucket) + .setSetting(tool_fil8) + .setToolObject(tool_fill), + ]; + #endregion + + function apply_draw_surface() { + if(!is_surface(canvas_surface)) return; + if(!is_surface(drawing_surface)) return; + + surface_set_shader(canvas_surface, noone, true, BLEND.over); + draw_surface(drawing_surface, 0, 0); + surface_reset_shader(); + + triggerRender(); + } + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny, params) { + var _tileSet = current_data[0]; + var _mapSize = current_data[1]; + var _tileSize = current_data[2]; + + if(!is_surface(drawing_surface)) { + drawing_surface = surface_verify(drawing_surface, _mapSize[0], _mapSize[1], surface_r16float); + + surface_set_shader(drawing_surface, noone, true, BLEND.over); + draw_surface(canvas_surface, 0, 0); + surface_reset_shader(); + } + + #region surfaces + var _dim = attributes.dimension; + var _outDim = [ _tileSize[0] * _dim[0], _tileSize[1] * _dim[1] ]; + + preview_draw_overlay = surface_verify(preview_draw_overlay, _dim[0], _dim[1], surface_r16float); + preview_drawing_tile = surface_verify(preview_drawing_tile, _dim[0] * _tileSize[0], _dim[1] * _tileSize[1]); + preview_draw_overlay_tile = surface_verify(preview_draw_overlay_tile, _dim[0] * _tileSize[0], _dim[1] * _tileSize[1]); + + var __s = surface_get_target(); + var _sw = surface_get_width(__s); + var _sh = surface_get_height(__s); + + _preview_draw_mask = surface_verify(_preview_draw_mask, _dim[0], _dim[1]); + preview_draw_mask = surface_verify( preview_draw_mask, _sw, _sh); + + #endregion + + #region tools + var _currTool = PANEL_PREVIEW.tool_current; + var _tool = _currTool == noone? noone : _currTool.getToolObject(); + + brush.brush_size = tool_attribute.size; + + if(_tool) { + _tool.subtool = _currTool.selecting; + _tool.apply_draw_surface = apply_draw_surface; + _tool.drawing_surface = drawing_surface; + _tool.tile_size = _tileSize; + + _tool.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + + surface_set_target(preview_draw_overlay); + DRAW_CLEAR + _tool.drawPreview(); + surface_reset_target(); + + surface_set_target(_preview_draw_mask); + DRAW_CLEAR + _tool.drawMask(); + surface_reset_target(); + + surface_set_target(preview_draw_mask); + DRAW_CLEAR + draw_surface_ext(_preview_draw_mask, _x, _y, _s * _tileSize[0], _s * _tileSize[1], 0, c_white, 1); + surface_reset_target(); + + if(_tool.brush_resizable) { + if(hover && key_mod_press(CTRL)) { + if(mouse_wheel_down()) tool_attribute.size = max( 1, tool_attribute.size - 1); + if(mouse_wheel_up()) tool_attribute.size = min(64, tool_attribute.size + 1); + } + + brush.sizing(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + } + } + #endregion + + #region draw preview surfaces + var _tileSetDim = surface_get_dimension(_tileSet); + + surface_set_shader(preview_drawing_tile, sh_draw_tile_map, true, BLEND.over); + shader_set_2("dimension", _outDim); + shader_set_2("tileSize", _tileSize); + shader_set_2("tileAmo", [ floor(_tileSetDim[0] / _tileSize[0]), floor(_tileSetDim[1] / _tileSize[1]) ]); + + shader_set_surface("tileTexture", _tileSet); + shader_set_2("tileTextureDim", _tileSetDim); + + shader_set_surface("indexTexture", drawing_surface); + shader_set_2("indexTextureDim", surface_get_dimension(drawing_surface)); + + draw_empty(); + surface_reset_shader(); + + draw_surface_ext(preview_drawing_tile, _x, _y, _s, _s, 0, c_white, 1); + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + surface_set_shader(preview_draw_overlay_tile, sh_draw_tile_map, true, BLEND.over); + shader_set_2("dimension", _outDim); + shader_set_2("tileSize", _tileSize); + shader_set_2("tileAmo", [ floor(_tileSetDim[0] / _tileSize[0]), floor(_tileSetDim[1] / _tileSize[1]) ]); + + shader_set_surface("tileTexture", _tileSet); + shader_set_2("tileTextureDim", _tileSetDim); + + shader_set_surface("indexTexture", preview_draw_overlay); + shader_set_2("indexTextureDim", surface_get_dimension(preview_draw_overlay)); + + draw_empty(); + surface_reset_shader(); + + draw_surface_ext(preview_draw_overlay_tile, _x, _y, _s, _s, 0, c_white, 1); + + params.panel.drawNodeGrid(); + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + shader_set(sh_brush_outline); + shader_set_f("dimension", _sw, _sh); + draw_surface(preview_draw_mask, 0, 0); + shader_reset(); + + #endregion + } + + static processData = function(_outData, _data, _output_index, _array_index) { + var _tileSet = _data[0]; + var _mapSize = _data[1]; + var _tileSize = _data[2]; + + attributes.dimension[0] = _mapSize[0]; + attributes.dimension[1] = _mapSize[1]; + + if(!is_surface(canvas_surface) && buffer_exists(canvas_buffer)) { + canvas_surface = surface_create(_mapSize[0], _mapSize[1], surface_r16float); + buffer_set_surface(canvas_buffer, canvas_surface, 0); + } else + canvas_surface = surface_verify(canvas_surface, _mapSize[0], _mapSize[1], surface_r16float); + drawing_surface = surface_verify(drawing_surface, _mapSize[0], _mapSize[1], surface_r16float); + + surface_set_shader(drawing_surface, noone, true, BLEND.over); + draw_surface(canvas_surface, 0, 0); + surface_reset_shader(); + + if(!is_surface(_tileSet)) return _outData; + + var _tileOut = _outData[0]; + var _tileMap = _outData[1]; + var _arrIndx = _outData[2]; + + var _outDim = [ _tileSize[0] * _mapSize[0], _tileSize[1] * _mapSize[1] ]; + + _tileOut = surface_verify(_tileOut, _outDim[0], _outDim[1]); + _tileMap = surface_verify(_tileMap, _mapSize[0], _mapSize[1], surface_r16float); + _arrIndx = array_verify(_arrIndx, _mapSize[0] * _mapSize[1]); + + buffer_resize(canvas_buffer, _mapSize[0] * _mapSize[1] * 2); + buffer_get_surface(canvas_buffer, canvas_surface, 0); + + surface_set_shader(_tileMap, sh_sample, true, BLEND.over); + draw_surface(canvas_surface, 0, 0); + surface_reset_shader(); + + var _tileSetDim = surface_get_dimension(_tileSet); + + surface_set_shader(_tileOut, sh_draw_tile_map, true, BLEND.over); + shader_set_2("dimension", _outDim); + shader_set_2("tileSize", _tileSize); + shader_set_2("tileAmo", [ floor(_tileSetDim[0] / _tileSize[0]), floor(_tileSetDim[1] / _tileSize[1]) ]); + + shader_set_surface("tileTexture", _tileSet); + shader_set_2("tileTextureDim", _tileSetDim); + + shader_set_surface("indexTexture", _tileMap); + shader_set_2("indexTextureDim", surface_get_dimension(_tileMap)); + + draw_empty(); + surface_reset_shader(); + + return [ _tileOut, _tileMap, _arrIndx ]; + } + + static getPreviewValues = function() { return preview_drawing_tile; } + static getGraphPreviewSurface = function() { return getSingleValue(0, preview_index, true); } + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + static doSerialize = function(_map) { + _map.surface = buffer_serialize(canvas_buffer); + } + + static doApplyDeserialize = function() { + canvas_buffer = buffer_deserialize(load_map.surface); + canvas_surface = surface_verify(canvas_surface, attributes.dimension[0], attributes.dimension[1], surface_r16float); + drawing_surface = surface_verify(drawing_surface, attributes.dimension[0], attributes.dimension[1], surface_r16float); + + buffer_set_surface(canvas_buffer, canvas_surface, 0); + buffer_set_surface(canvas_buffer, drawing_surface, 0); + } + +} \ No newline at end of file diff --git a/scripts/node_tiler/node_tiler.yy b/scripts/node_tiler/node_tiler.yy new file mode 100644 index 000000000..b93a9b64e --- /dev/null +++ b/scripts/node_tiler/node_tiler.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"v1", + "%Name":"node_tiler", + "isCompatibility":false, + "isDnD":false, + "name":"node_tiler", + "parent":{ + "name":"tiler", + "path":"folders/nodes/data/tiler.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/node_value_vec2/node_value_vec2.gml b/scripts/node_value_vec2/node_value_vec2.gml index ad8b6f56f..b4f3fdf36 100644 --- a/scripts/node_value_vec2/node_value_vec2.gml +++ b/scripts/node_value_vec2/node_value_vec2.gml @@ -1,4 +1,5 @@ -function nodeValue_Vec2(_name, _node, _value, _data = {}) { return new __NodeValue_Vec2(_name, _node, _value, _data); } +function nodeValue_Vec2( _name, _node, _value, _data = {}) { return new __NodeValue_Vec2( _name, _node, _value, _data); } +function nodeValue_IVec2(_name, _node, _value, _data = {}) { return new __NodeValue_IVec2(_name, _node, _value, _data); } function __NodeValue_Vec2(_name, _node, _value, _data = {}) : NodeValue(_name, _node, CONNECT_TYPE.input, VALUE_TYPE.float, _value, "") constructor { setDisplay(VALUE_DISPLAY.vector, _data); @@ -75,4 +76,9 @@ function __NodeValue_Vec2(_name, _node, _value, _data = {}) : NodeValue(_name, _ return animator.getValue(_time); } +} + +function __NodeValue_IVec2(_name, _node, _value, _data = {}) : NodeValue(_name, _node, CONNECT_TYPE.input, VALUE_TYPE.integer, _value, "") constructor { + setDisplay(VALUE_DISPLAY.vector, _data); + def_length = 2; } \ No newline at end of file diff --git a/scripts/panel_data/panel_data.gml b/scripts/panel_data/panel_data.gml index 3f331cdfd..5320156af 100644 --- a/scripts/panel_data/panel_data.gml +++ b/scripts/panel_data/panel_data.gml @@ -525,7 +525,7 @@ function Panel(_parent, _x, _y, _w, _h) constructor { if(i == content_index) { foc = FOCUS == self; - var cc = foc? COLORS._main_accent : COLORS.panel_tab; + var cc = foc? (PREFERENCES.panel_outline_accent? COLORS._main_accent : COLORS.panel_select_border) : COLORS.panel_tab; draw_sprite_stretched_ext(THEME.ui_panel_tab, 1 + foc, _tbx, tby, tbw, _tdh, cc, 1); if(!foc) tab_cover = BBOX().fromWH(tsx + _tbx, tsy + tby + tbh - ui(3), tbw, THEME_VALUE.panel_tab_extend); @@ -598,7 +598,7 @@ function Panel(_parent, _x, _y, _w, _h) constructor { var tbw = string_width(txt) + ui(16 + 16); if(icn != noone) tbw += ui(16 + 4); - draw_sprite_stretched_ext(THEME.ui_panel_tab, 2, _tbx, tby, tbw, tbh, COLORS._main_accent, 1); + draw_sprite_stretched_ext(THEME.ui_panel_tab, 2, _tbx, tby, tbw, tbh, PREFERENCES.panel_outline_accent? COLORS._main_accent : COLORS.panel_select_border, 1); draw_sprite_ui(THEME.tab_exit, 0, _tbx + tbw - ui(12), tab_height / 2 + 1,,,, COLORS.panel_tab_icon); if(icn != noone) { @@ -713,7 +713,7 @@ function Panel(_parent, _x, _y, _w, _h) constructor { if(tab) draw_sprite_bbox(THEME.ui_panel_tab, 3, tab_cover); if(FOCUS == self && parent != noone) { - draw_sprite_stretched_ext(THEME.ui_panel, 1, tx + padding, ty + padding, tw - padding * 2, th - padding * 2, COLORS._main_accent, 1); + draw_sprite_stretched_ext(THEME.ui_panel, 1, tx + padding, ty + padding, tw - padding * 2, th - padding * 2, PREFERENCES.panel_outline_accent? COLORS._main_accent : COLORS.panel_select_border, 1); if(hasContent() && !m_in && m_ot) { draw_sprite_stretched_ext(THEME.ui_panel, 1, tx + padding, ty + padding, tw - padding * 2, th - padding * 2, c_white, 0.4); diff --git a/scripts/panel_preview/panel_preview.gml b/scripts/panel_preview/panel_preview.gml index e1c1a7888..0164a7337 100644 --- a/scripts/panel_preview/panel_preview.gml +++ b/scripts/panel_preview/panel_preview.gml @@ -873,13 +873,18 @@ function Panel_Preview() : PanelContent() constructor { } + preview_surface_width = 0; + preview_surface_height = 0; + function drawNodePreview() { var ss = canvas_s; var psx = 0, psy = 0; var psw = 0, psh = 0; - var pswd = 0, pshd = 0; var psx1 = 0, psy1 = 0; + preview_surface_width = 0; + preview_surface_height = 0; + var ssx = 0, ssy = 0; var ssw = 0, ssh = 0; @@ -889,11 +894,11 @@ function Panel_Preview() : PanelContent() constructor { psw = surface_get_width_safe(preview_surfaces[0]); psh = surface_get_height_safe(preview_surfaces[0]); - pswd = psw * ss; - pshd = psh * ss; + preview_surface_width = psw * ss; + preview_surface_height = psh * ss; - psx1 = psx + pswd; - psy1 = psy + pshd; + psx1 = psx + preview_surface_width; + psy1 = psy + preview_surface_height; } if(is_surface(preview_surfaces[1])) { @@ -1043,8 +1048,8 @@ function Panel_Preview() : PanelContent() constructor { if(is_surface(preview_surfaces[0])) { // outline if(PROJECT.previewGrid.pixel && canvas_s >= 16) { - var gw = pswd / canvas_s; - var gh = pshd / canvas_s; + var gw = preview_surface_width / canvas_s; + var gh = preview_surface_height / canvas_s; var cx = canvas_x; var cy = canvas_y; @@ -1054,46 +1059,50 @@ function Panel_Preview() : PanelContent() constructor { for( var i = 1; i < gw; i++ ) { var _xx = cx + i * canvas_s; - draw_line(_xx, cy, _xx, cy + pshd); + draw_line(_xx, cy, _xx, cy + preview_surface_height); } for( var i = 1; i < gh; i++ ) { var _yy = cy + i * canvas_s; - draw_line(cx, _yy - 1, cx + pswd, _yy - 1); + draw_line(cx, _yy - 1, cx + preview_surface_width, _yy - 1); } draw_set_alpha(1); } - if(PROJECT.previewGrid.show) { - var _gw = PROJECT.previewGrid.size[0] * canvas_s; - var _gh = PROJECT.previewGrid.size[1] * canvas_s; - - var gw = pswd / _gw; - var gh = pshd / _gh; - - var cx = canvas_x; - var cy = canvas_y; - - draw_set_color(PROJECT.previewGrid.color); - draw_set_alpha(PROJECT.previewGrid.opacity); - - for( var i = 1; i < gw; i++ ) { - var _xx = cx + i * _gw; - draw_line(_xx, cy, _xx, cy + pshd); - } - - for( var i = 1; i < gh; i++ ) { - var _yy = cy + i * _gh; - draw_line(cx, _yy, cx + pswd, _yy); - } - - draw_set_alpha(1); - } - draw_set_color(COLORS.panel_preview_surface_outline); - draw_rectangle(psx, psy, psx + pswd - 1, psy + pshd - 1, true); + draw_rectangle(psx, psy, psx + preview_surface_width - 1, psy + preview_surface_height - 1, true); } + + if(!struct_try_get(_node, "bypass_grid", false)) drawNodeGrid(); + } + + function drawNodeGrid() { + if(!PROJECT.previewGrid.show) return; + + var _gw = PROJECT.previewGrid.size[0] * canvas_s; + var _gh = PROJECT.previewGrid.size[1] * canvas_s; + + var gw = preview_surface_width / _gw; + var gh = preview_surface_height / _gh; + + var cx = canvas_x; + var cy = canvas_y; + + draw_set_color(PROJECT.previewGrid.color); + draw_set_alpha(PROJECT.previewGrid.opacity); + + for( var i = 1; i < gw; i++ ) { + var _xx = cx + i * _gw; + draw_line(_xx, cy, _xx, cy + preview_surface_height); + } + + for( var i = 1; i < gh; i++ ) { + var _yy = cy + i * _gh; + draw_line(cx, _yy, cx + preview_surface_width, _yy); + } + + draw_set_alpha(1); } function draw3DPolygon(_node) { @@ -1696,7 +1705,9 @@ function Panel_Preview() : PanelContent() constructor { var overActive = active && overHover; - var params = { w, h, toolbar_height }; + var params = { w, h, toolbar_height }; + params.panel = self; + var mouse_free = false; if(_node.is_3D == NODE_3D.none) { @@ -1904,8 +1915,6 @@ function Panel_Preview() : PanelContent() constructor { var _sx1 = _sxx + tool_size / 2; var _sy1 = _syy + tool_size / 2; - draw_sprite_colored(stool[_sind], 0, _sxx, _syy); - if(point_in_rectangle(_mx, _my, _sx0, _sy0 + 1, _sx1, _sy1 - 1)) { TOOLTIP = tool.getDisplayName(_sind); draw_sprite_stretched(THEME.button_hide, 1, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2); @@ -1918,6 +1927,9 @@ function Panel_Preview() : PanelContent() constructor { draw_sprite_stretched_ext(THEME.button_hide, 2, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); draw_sprite_stretched_ext(THEME.button_hide, 3, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); } + + draw_sprite_colored(stool[_sind], 0, _sxx, _syy); + } if(point_in_rectangle(_mx, _my, tx, _y0 + 1, tx + s_ww, _y1 - 1)) @@ -2023,7 +2035,7 @@ function Panel_Preview() : PanelContent() constructor { break; } - var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key],, [ mx, my ]) + var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key], , [ mx, my ], x, y); params.s = tolh; params.font = _tool_font; @@ -2173,7 +2185,7 @@ function Panel_Preview() : PanelContent() constructor { } } - function drawContent(panel) { #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + function drawContent(panel) { // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< mouse_on_preview = pHOVER && point_in_rectangle(mx, my, 0, topbar_height, w, h - toolbar_height); if(do_fullView) run_in(1, fullView); @@ -2266,7 +2278,7 @@ function Panel_Preview() : PanelContent() constructor { } } - } #endregion + } ////=========== ACTION =========== diff --git a/scripts/preferences/preferences.gml b/scripts/preferences/preferences.gml index 51d22368c..5fc69a42e 100644 --- a/scripts/preferences/preferences.gml +++ b/scripts/preferences/preferences.gml @@ -117,6 +117,7 @@ PREFERENCES.palette_stretch = false; PREFERENCES.pan_mouse_key = mb_middle; + PREFERENCES.panel_outline_accent = true; #endregion #region //////////////////////////////////////////////////////////////////////// WIDGET //////////////////////////////////////////////////////////////////////// diff --git a/scripts/theme_definition/theme_definition.gml b/scripts/theme_definition/theme_definition.gml index 0fe924424..539653abe 100644 --- a/scripts/theme_definition/theme_definition.gml +++ b/scripts/theme_definition/theme_definition.gml @@ -516,6 +516,7 @@ function ThemeColor() constructor { panel_bg_clear_inner = CDEF.main_mdblack; panel_bg_clear = CDEF.main_black; + panel_select_border = CDEF.main_grey; panel_frame = CDEF.main_dkgrey; panel_prop_bg = CDEF.main_ltgrey; panel_tab = CDEF.white; diff --git a/scripts/tiler_tool_brush/tiler_tool_brush.gml b/scripts/tiler_tool_brush/tiler_tool_brush.gml new file mode 100644 index 000000000..220ceb79e --- /dev/null +++ b/scripts/tiler_tool_brush/tiler_tool_brush.gml @@ -0,0 +1,112 @@ +function tiler_tool_brush(node, _brush, eraser = false) : tiler_tool(node) constructor { + self.brush = _brush; + isEraser = eraser; + brush_resizable = true; + + mouse_cur_x = 0; + mouse_cur_y = 0; + mouse_pre_x = 0; + mouse_pre_y = 0; + mouse_pre_draw_x = undefined; + mouse_pre_draw_y = undefined; + + mouse_holding = false; + + mouse_line_drawing = false; + mouse_line_x0 = 0; + mouse_line_y0 = 0; + mouse_line_x1 = 0; + mouse_line_y1 = 0; + + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + brush.brush_erase = isEraser; + + mouse_cur_x = floor(round((_mx - _x) / _s - 0.5) / tile_size[0]); + mouse_cur_y = floor(round((_my - _y) / _s - 0.5) / tile_size[1]); + + if(mouse_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_presses(SHIFT, CTRL)) { + + var _dx = mouse_cur_x - mouse_pre_draw_x; + var _dy = mouse_cur_y - mouse_pre_draw_y; + + if(_dx != _dy) { + var _ddx = _dx; + var _ddy = _dy; + + if(abs(_dx) > abs(_dy)) { + var _rat = round(_ddx / _ddy); + _ddx = _ddy * _rat; + + } else if(abs(_dx) < abs(_dy)) { + var _rat = round(_ddy / _ddx); + _ddy = _ddx * _rat; + + } + + mouse_cur_x = mouse_pre_draw_x + _ddx - sign(_ddx); + mouse_cur_y = mouse_pre_draw_y + _ddy - sign(_ddy); + } + } + + if(mouse_press(mb_left, active)) { + + surface_set_target(drawing_surface); + tiler_draw_point_brush(brush, mouse_cur_x, mouse_cur_y); + surface_reset_target(); + + mouse_holding = true; + if(mouse_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_press(SHIFT)) { + surface_set_target(drawing_surface); + tiler_draw_line_brush(brush, mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y); + surface_reset_target(); + mouse_holding = false; + + apply_draw_surface(); + } + + mouse_pre_draw_x = mouse_cur_x; + mouse_pre_draw_y = mouse_cur_y; + } + + if(mouse_holding) { + if(mouse_pre_draw_x != mouse_cur_x || mouse_pre_draw_y != mouse_cur_y) { + surface_set_target(drawing_surface); + tiler_draw_line_brush(brush, mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y); + surface_reset_target(); + } + + mouse_pre_draw_x = mouse_cur_x; + mouse_pre_draw_y = mouse_cur_y; + + if(mouse_release(mb_left)) { + mouse_holding = false; + apply_draw_surface(); + } + } + + mouse_pre_x = mouse_cur_x; + mouse_pre_y = mouse_cur_y; + + } + + function drawPreview() { + mouse_line_drawing = false; + + if(mouse_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_press(SHIFT)) { + + tiler_draw_line_brush(brush, mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y); + mouse_line_drawing = true; + mouse_line_x0 = min(mouse_cur_x, mouse_pre_draw_x); + mouse_line_y0 = min(mouse_cur_y, mouse_pre_draw_y); + mouse_line_x1 = max(mouse_cur_x, mouse_pre_draw_x) + 1; + mouse_line_y1 = max(mouse_cur_y, mouse_pre_draw_y) + 1; + + } else + tiler_draw_point_brush(brush, mouse_cur_x, mouse_cur_y); + } + + static drawMask = function() { + draw_set_color(c_white); + tiler_draw_point_brush(brush, mouse_cur_x, mouse_cur_y); + } +} \ No newline at end of file diff --git a/scripts/tiler_tool_brush/tiler_tool_brush.yy b/scripts/tiler_tool_brush/tiler_tool_brush.yy new file mode 100644 index 000000000..df561936b --- /dev/null +++ b/scripts/tiler_tool_brush/tiler_tool_brush.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"v1", + "%Name":"tiler_tool_brush", + "isCompatibility":false, + "isDnD":false, + "name":"tiler_tool_brush", + "parent":{ + "name":"tools", + "path":"folders/nodes/data/tiler/tools.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/tiler_tool_fill/tiler_tool_fill.gml b/scripts/tiler_tool_fill/tiler_tool_fill.gml new file mode 100644 index 000000000..40e780ecb --- /dev/null +++ b/scripts/tiler_tool_fill/tiler_tool_fill.gml @@ -0,0 +1,126 @@ +function tiler_tool_fill(node, _brush, toolAttr) : tiler_tool(node) constructor { + self.brush = _brush; + self.tool_attribute = toolAttr; + + mouse_cur_x = -1; + mouse_cur_y = -1; + mouse_pre_x = -1; + mouse_pre_y = -1; + + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + mouse_cur_x = floor(round((_mx - _x) / _s - 0.5) / tile_size[0]); + mouse_cur_y = floor(round((_my - _y) / _s - 0.5) / tile_size[1]); + + surface_w = surface_get_width(drawing_surface); + surface_h = surface_get_height(drawing_surface); + + if(mouse_press(mb_left, active) && point_in_rectangle(mouse_cur_x, mouse_cur_y, 0, 0, surface_w - 1, surface_h - 1)) { + surface_set_target(drawing_surface); + tiler_flood_fill_scanline(drawing_surface, mouse_cur_x, mouse_cur_y, brush, tool_attribute.fillType); + surface_reset_target(); + + apply_draw_surface(); + } + } +} + +function _tiler_ff_getPixel(_x, _y) { return round(buffer_read_at(_ff_buff, (_y * _ff_w + _x) * 2, buffer_f16)); } + +function tiler_flood_fill_scanline(_surf, _x, _y, brush, _corner = false) { + if(brush.brush_height * brush.brush_width == 0) return; + + var _index = brush.brush_erase? -1 : brush.brush_indices[0][0]; + var colorBase = surface_getpixel(_surf, _x, _y)[0]; + +// print($"Filling {_x}, {_y} = {_index} [base: {colorBase}]") + if(_index == colorBase) return; //Clicking on the same color as the fill color + + _ff_w = surface_get_width(_surf); + _ff_h = surface_get_height(_surf); + _ff_buff = buffer_create(_ff_w * _ff_h * 2, buffer_fixed, 2); + buffer_get_surface(_ff_buff, _surf, 0); + + var x1, y1, x_start; + var spanAbove, spanBelow; + + var qx = ds_queue_create(); + var qy = ds_queue_create(); + ds_queue_enqueue(qx, _x); + ds_queue_enqueue(qy, _y); + + shader_set(sh_draw_tile_brush); + BLEND_OVERRIDE + shader_set_f("index", _index); + + while(!ds_queue_empty(qx)) { + + x1 = ds_queue_dequeue(qx); + y1 = ds_queue_dequeue(qy); + +// print($"----Checking {x1}, {y1} - {_tiler_ff_getPixel(x1, y1)}") + + if(_tiler_ff_getPixel(x1, y1) == _index) continue; //Color in queue is already filled + + while(x1 > 0 && colorBase == _tiler_ff_getPixel(x1 - 1, y1)) //Move to the leftmost connected pixel in the same row. + x1--; + x_start = x1; + + spanAbove = false; + spanBelow = false; + + while(x1 < surface_w && colorBase == _tiler_ff_getPixel(x1, y1)) { + draw_point(x1, y1); + buffer_write_at(_ff_buff, (y1 * _ff_w + x1) * 2, buffer_f16, _index); + +// print($"----Filling {x1}, {y1}") + + if(y1 > 0) { + if(_corner && x1 > 0 && colorBase == _tiler_ff_getPixel(x1 - 1, y1 - 1)) { //Check top left pixel + ds_queue_enqueue(qx, x1 - 1); + ds_queue_enqueue(qy, y1 - 1); + } + + if(colorBase == _tiler_ff_getPixel(x1, y1 - 1)) { //Check top pixel + ds_queue_enqueue(qx, x1); + ds_queue_enqueue(qy, y1 - 1); + } + } + + if(y1 < surface_h - 1) { + if(_corner && x1 > 0 && colorBase == _tiler_ff_getPixel(x1 - 1, y1 + 1)) { //Check bottom left pixel + ds_queue_enqueue(qx, x1 - 1); + ds_queue_enqueue(qy, y1 + 1); + } + + if(colorBase == _tiler_ff_getPixel(x1, y1 + 1)) { //Check bottom pixel + ds_queue_enqueue(qx, x1); + ds_queue_enqueue(qy, y1 + 1); + } + } + + if(_corner && x1 < surface_w - 1) { + if(y1 > 0 && colorBase == _tiler_ff_getPixel(x1 + 1, y1 - 1)) { //Check top right pixel + ds_queue_enqueue(qx, x1 + 1); + ds_queue_enqueue(qy, y1 - 1); + } + + if(y1 < surface_h - 1 && colorBase == _tiler_ff_getPixel(x1 + 1, y1 + 1)) { //Check bottom right pixel + ds_queue_enqueue(qx, x1 + 1); + ds_queue_enqueue(qy, y1 + 1); + } + } + + x1++; + } + } + + BLEND_NORMAL + shader_reset(); + + ds_queue_destroy(qx); + ds_queue_destroy(qy); + + draw_set_alpha(1); + buffer_delete(_ff_buff); +} \ No newline at end of file diff --git a/scripts/tiler_tool_fill/tiler_tool_fill.yy b/scripts/tiler_tool_fill/tiler_tool_fill.yy new file mode 100644 index 000000000..814a66817 --- /dev/null +++ b/scripts/tiler_tool_fill/tiler_tool_fill.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"v1", + "%Name":"tiler_tool_fill", + "isCompatibility":false, + "isDnD":false, + "name":"tiler_tool_fill", + "parent":{ + "name":"tools", + "path":"folders/nodes/data/tiler/tools.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/shaders/sh_brush_outline/sh_brush_outline.fsh b/shaders/sh_brush_outline/sh_brush_outline.fsh index a4e4768b6..5841d6f69 100644 --- a/shaders/sh_brush_outline/sh_brush_outline.fsh +++ b/shaders/sh_brush_outline/sh_brush_outline.fsh @@ -17,6 +17,8 @@ void main() { float p5 = texture2D( gm_BaseTexture, v_vTexcoord + vec2(tx.x, 0.) ).a > 0.? 1. : 0.; float p7 = texture2D( gm_BaseTexture, v_vTexcoord + vec2(0., tx.y) ).a > 0.? 1. : 0.; - if(p == 0. && (p1 != p7 || p3 != p5)) - gl_FragColor = v_vColour; + if(p1 != p7 || p3 != p5) { + if(p == 0.) gl_FragColor = v_vColour; + if(p == 1.) gl_FragColor = vec4(0., 0., 0., 1.); + } } diff --git a/shaders/sh_draw_tile/sh_draw_tile.yy b/shaders/sh_draw_tile/sh_draw_tile.yy index 7df82601b..65b2dfe88 100644 --- a/shaders/sh_draw_tile/sh_draw_tile.yy +++ b/shaders/sh_draw_tile/sh_draw_tile.yy @@ -3,8 +3,8 @@ "%Name":"sh_draw_tile", "name":"sh_draw_tile", "parent":{ - "name":"draw", - "path":"folders/shader/draw.yy", + "name":"tiler", + "path":"folders/shader/draw/tiler.yy", }, "resourceType":"GMShader", "resourceVersion":"2.0", diff --git a/shaders/sh_draw_tile_apply/sh_draw_tile_apply.fsh b/shaders/sh_draw_tile_apply/sh_draw_tile_apply.fsh new file mode 100644 index 000000000..8505efcd1 --- /dev/null +++ b/shaders/sh_draw_tile_apply/sh_draw_tile_apply.fsh @@ -0,0 +1,13 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +// uniform sampler2D canvas; +// uniform sampler2D drawing; + +void main() { + gl_FragColor = vec4(0.); + // vec4 c = texture2D( canvas, v_vTexcoord ); + // vec4 d = texture2D( drawing, v_vTexcoord ); + + // gl_FragColor = d.r > 0.? d : c; +} diff --git a/shaders/sh_draw_tile_apply/sh_draw_tile_apply.vsh b/shaders/sh_draw_tile_apply/sh_draw_tile_apply.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_draw_tile_apply/sh_draw_tile_apply.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_draw_tile_apply/sh_draw_tile_apply.yy b/shaders/sh_draw_tile_apply/sh_draw_tile_apply.yy new file mode 100644 index 000000000..4ed6721c2 --- /dev/null +++ b/shaders/sh_draw_tile_apply/sh_draw_tile_apply.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_draw_tile_apply", + "name":"sh_draw_tile_apply", + "parent":{ + "name":"tiler", + "path":"folders/shader/draw/tiler.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/shaders/sh_draw_tile_brush/sh_draw_tile_brush.fsh b/shaders/sh_draw_tile_brush/sh_draw_tile_brush.fsh new file mode 100644 index 000000000..e0c0e41de --- /dev/null +++ b/shaders/sh_draw_tile_brush/sh_draw_tile_brush.fsh @@ -0,0 +1,8 @@ +// varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform float index; + +void main() { + gl_FragColor = vec4(index + 1., 0., 0., 1.); +} diff --git a/shaders/sh_draw_tile_brush/sh_draw_tile_brush.vsh b/shaders/sh_draw_tile_brush/sh_draw_tile_brush.vsh new file mode 100644 index 000000000..b19b24c9f --- /dev/null +++ b/shaders/sh_draw_tile_brush/sh_draw_tile_brush.vsh @@ -0,0 +1,18 @@ +// +// 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_draw_tile_brush/sh_draw_tile_brush.yy b/shaders/sh_draw_tile_brush/sh_draw_tile_brush.yy new file mode 100644 index 000000000..be62594fb --- /dev/null +++ b/shaders/sh_draw_tile_brush/sh_draw_tile_brush.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_draw_tile_brush", + "name":"sh_draw_tile_brush", + "parent":{ + "name":"tiler", + "path":"folders/shader/draw/tiler.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/shaders/sh_draw_tile_clear/sh_draw_tile_clear.fsh b/shaders/sh_draw_tile_clear/sh_draw_tile_clear.fsh new file mode 100644 index 000000000..8004a8e5d --- /dev/null +++ b/shaders/sh_draw_tile_clear/sh_draw_tile_clear.fsh @@ -0,0 +1,6 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() { + gl_FragColor = vec4(-1., 0., 0., 1.); +} diff --git a/shaders/sh_draw_tile_clear/sh_draw_tile_clear.vsh b/shaders/sh_draw_tile_clear/sh_draw_tile_clear.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_draw_tile_clear/sh_draw_tile_clear.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_draw_tile_clear/sh_draw_tile_clear.yy b/shaders/sh_draw_tile_clear/sh_draw_tile_clear.yy new file mode 100644 index 000000000..bb4ca0b24 --- /dev/null +++ b/shaders/sh_draw_tile_clear/sh_draw_tile_clear.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_draw_tile_clear", + "name":"sh_draw_tile_clear", + "parent":{ + "name":"tiler", + "path":"folders/shader/draw/tiler.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/shaders/sh_draw_tile_map/sh_draw_tile_map.fsh b/shaders/sh_draw_tile_map/sh_draw_tile_map.fsh new file mode 100644 index 000000000..2b08ce475 --- /dev/null +++ b/shaders/sh_draw_tile_map/sh_draw_tile_map.fsh @@ -0,0 +1,23 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform vec2 tileSize; +uniform vec2 tileAmo; + +uniform sampler2D tileTexture; +uniform vec2 tileTextureDim; + +uniform sampler2D indexTexture; +uniform vec2 indexTextureDim; + +void main() { + vec2 px = v_vTexcoord * dimension; + vec2 tileTx = mod(px, tileSize); + + float index = texture2D( indexTexture, floor(px / tileSize) / indexTextureDim ).r - 1.; + vec2 texTx = vec2(mod(index, tileAmo.x), floor(index / tileAmo.x)) * tileSize; + + gl_FragColor = texture2D( tileTexture, (texTx + tileTx) / tileTextureDim ); + // gl_FragColor = vec4(tileTx, 0., 1.); +} diff --git a/shaders/sh_draw_tile_map/sh_draw_tile_map.vsh b/shaders/sh_draw_tile_map/sh_draw_tile_map.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_draw_tile_map/sh_draw_tile_map.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_draw_tile_map/sh_draw_tile_map.yy b/shaders/sh_draw_tile_map/sh_draw_tile_map.yy new file mode 100644 index 000000000..69fc7ab62 --- /dev/null +++ b/shaders/sh_draw_tile_map/sh_draw_tile_map.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_draw_tile_map", + "name":"sh_draw_tile_map", + "parent":{ + "name":"tiler", + "path":"folders/shader/draw/tiler.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/shaders/sh_smear/sh_smear.fsh b/shaders/sh_smear/sh_smear.fsh index 84d6f96f8..2ae6596a9 100644 --- a/shaders/sh_smear/sh_smear.fsh +++ b/shaders/sh_smear/sh_smear.fsh @@ -18,6 +18,7 @@ uniform int alpha; uniform int modulateStr; uniform int inv; uniform int blend; +uniform int normalized; vec4 sampleTexture(vec2 pos) { #region if(pos.x >= 0. && pos.y >= 0. && pos.x <= 1. && pos.y <= 1.) @@ -43,11 +44,12 @@ vec4 smear(vec2 shift) { vec4 base = sampleTexture( v_vTexcoord ); float mBri = (base.r + base.g + base.b) / 3. * base.a; - vec4 res = base; - vec4 col, rcol; + vec4 res, col, rcol; float bright, rbright, dist = 0.; if(inv == 0) { + res = base; + for(float i = 0.; i <= 1.0; i += delta) { col = sampleTexture( v_vTexcoord - shift * i); @@ -87,7 +89,9 @@ vec4 smear(vec2 shift) { } mBri = bright; - res = alpha == 0? vec4(vec3(i), 1.) : vec4(vec3(1.), i); + + float _i = normalized == 1? i / bright : i; + res = alpha == 0? vec4(vec3(_i), 1.) : vec4(vec3(1.), _i); } }