From 0a79cf44569734437d1c9e6160a14970bd439954 Mon Sep 17 00:00:00 2001 From: Tanasart <22589759+Ttanasart-pt@users.noreply.github.com> Date: Fri, 17 Feb 2023 17:31:33 +0700 Subject: [PATCH] Colorize HSV, mask weight --- PixelComposer.yyp | 3 +- .../o_dialog_file_name_collection/Draw_64.gml | 7 +- objects/o_dialog_menubox/Create_0.gml | 19 ++-- objects/o_dialog_scrollbox/Alarm_0.gml | 11 ++- objects/o_dialog_scrollbox/Create_0.gml | 25 ++++- objects/o_dialog_scrollbox/Destroy_0.gml | 1 + objects/o_dialog_splash/Draw_64.gml | 9 +- objects/o_main/Create_0.gml | 4 +- objects/o_main/Other_69.gml | 12 ++- scripts/array_functions/array_functions.gml | 6 ++ .../dialog_management/dialog_management.gml | 7 ++ .../draw_surface_blend/draw_surface_blend.gml | 44 +++------ scripts/globals/globals.gml | 2 +- scripts/mask_function/mask_function.gml | 4 +- scripts/meta_data/meta_data.gml | 38 ++++++++ scripts/node_blend/node_blend.gml | 23 ++--- scripts/node_colorize/node_colorize.gml | 2 +- scripts/node_data/node_data.gml | 2 +- .../node_palette_sort/node_palette_sort.gml | 2 +- scripts/panel_collection/panel_collection.gml | 95 +++++++++++-------- scripts/panel_menu/panel_menu.gml | 59 +++++++----- scripts/scrollBox/scrollBox.gml | 17 ++-- .../steam_ugc_collection.gml | 6 +- .../steam_ugc_functions.gml | 12 ++- scripts/string_function/string_function.gml | 2 + .../surface_functions/surface_functions.gml | 5 + shaders/sh_colorize/sh_colorize.fsh | 89 ++++++++++++----- 27 files changed, 332 insertions(+), 174 deletions(-) diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 70335c3b2..452899212 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -1446,9 +1446,10 @@ {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"Cards flipping.pxc","CopyToMask":-1,"filePath":"datafiles/Sample Projects",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"Dice.pxc","CopyToMask":-1,"filePath":"datafiles/Sample Projects",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"Shiny gem.pxc","CopyToMask":-1,"filePath":"datafiles/Sample Projects",}, - {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"graphics x2.ai","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_sort_24.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_reverse.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, + {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"graphics x2.ai","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, + {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_workshop_download.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"default.zip","CopyToMask":-1,"filePath":"datafiles/data/themes",}, ], "MetaData": { diff --git a/objects/o_dialog_file_name_collection/Draw_64.gml b/objects/o_dialog_file_name_collection/Draw_64.gml index b2046d622..a45c79467 100644 --- a/objects/o_dialog_file_name_collection/Draw_64.gml +++ b/objects/o_dialog_file_name_collection/Draw_64.gml @@ -29,15 +29,19 @@ var txt = get_text("new_collection_create", "Create collection"); var icon = THEME.accept; + var clr = COLORS._main_value_positive; if(updating != noone) { txt = get_text("collection_update", "Update collection"); } + if(ugc == 1) { txt = get_text("workshop_upload", "Upload to Steam Workshop"); icon = THEME.workshop_upload; + clr = c_white; } else if(ugc == 2) { txt = get_text("workshop_update", "Update Steam Workshop"); icon = THEME.workshop_update; + clr = c_white; } if(ugc_loading) { @@ -48,7 +52,7 @@ if(STEAM_UGC_ITEM_UPLOADING == false) instance_destroy(); } else { - if(buttonInstant(THEME.button_hide, bx, by, bw, bh, mouse_ui, sFOCUS, sHOVER, txt, icon, 0, COLORS._main_value_positive) == 2) { + if(buttonInstant(THEME.button_hide, bx, by, bw, bh, mouse_ui, sFOCUS, sHOVER, txt, icon, 0, clr) == 2) { if(meta.author_steam_id == 0) meta.author_steam_id = STEAM_USER_ID; @@ -73,6 +77,7 @@ steam_ugc_create_collection(updating); ugc_loading = true; } else if(ugc == 2) { + PANEL_COLLECTION.saveCollection(updating.path, false, updating.meta); steam_ugc_update_collection(updating); ugc_loading = true; } else diff --git a/objects/o_dialog_menubox/Create_0.gml b/objects/o_dialog_menubox/Create_0.gml index b83f1ac75..94ae34444 100644 --- a/objects/o_dialog_menubox/Create_0.gml +++ b/objects/o_dialog_menubox/Create_0.gml @@ -28,31 +28,30 @@ event_inherited(); draw_set_text(f_p0, fa_center, fa_center, COLORS._main_text); for(var i = 0; i < array_length(menu); i++) { - if(!is_array(menu[i])) { + var menuItem = menu[i]; + if(!is_array(menuItem)) { dialog_h += ui(8); continue; } draw_set_font(f_p0); - var ww = string_width(menu[i][0]) + ui(64); + var ww = string_width(menuItem[0]) + ui(64); - if(array_length(menu[i]) > 2) { - if(menu[i][2] == ">") { - - } else if(is_array(menu[i][2])) { - var _key = find_hotkey(menu[i][2][0], menu[i][2][1]); + if(array_length(menuItem) > 2) { + if(is_array(menuItem[2])) { + var _key = find_hotkey(menuItem[2][0], menuItem[2][1]); if(_key) { draw_set_font(f_p1); var ss = key_get_name(_key.key, _key.modi); ww += string_width(ss) + ui(16); } } - } else if(is_array(menu[i][1])) { - var amo = array_length(menu[i][1]); + } else if(is_array(menuItem[1])) { + var amo = array_length(menuItem[1]); ww = max(ww, ui(16) + amo * (hght + ui(4))); } dialog_w = max(dialog_w, ww); - if(is_array(menu[i][1])) + if(is_array(menuItem[1])) dialog_h += hght; dialog_h += hght; } diff --git a/objects/o_dialog_scrollbox/Alarm_0.gml b/objects/o_dialog_scrollbox/Alarm_0.gml index 98919e16c..f63b9003b 100644 --- a/objects/o_dialog_scrollbox/Alarm_0.gml +++ b/objects/o_dialog_scrollbox/Alarm_0.gml @@ -1,7 +1,16 @@ /// @description init #region pos var hght = line_height(f_p0, 8); - var hh = array_length(scrollbox.data) * hght; + var hh = 0; + + for( var i = 0; i < array_length(scrollbox.data); i++ ) { + if(scrollbox.data[i] == -1) { + hh += ui(8); + continue; + } + + hh += hght; + } dialog_h = min(max_h, hh); sc_content.resize(dialog_w, dialog_h); diff --git a/objects/o_dialog_scrollbox/Create_0.gml b/objects/o_dialog_scrollbox/Create_0.gml index bcc7d82f4..2b1760803 100644 --- a/objects/o_dialog_scrollbox/Create_0.gml +++ b/objects/o_dialog_scrollbox/Create_0.gml @@ -9,6 +9,7 @@ event_inherited(); selecting = -1; scrollbox = noone; + initVal = 0; anchor = ANCHOR.top | ANCHOR.left; @@ -16,21 +17,31 @@ event_inherited(); draw_clear_alpha(COLORS.panel_bg_clear, 0); var hght = line_height(f_p0, 8); var data = scrollbox.data; - var _h = array_length(data) * hght; var _dw = sc_content.surface_w; + var _h = 0; + var _ly = _y; + + var hovering = -1; for(var i = 0; i < array_length(data); i++) { - var _ly = _y + i * hght; + if(data[i] == -1) { + draw_sprite_stretched(THEME.menu_separator, 0, ui(8), _ly, _dw - ui(16), ui(6)); + _ly += ui(8); + _h += ui(8); + + continue; + } if(sHOVER && sc_content.hover && point_in_rectangle(_m[0], _m[1], 0, _ly + 1, _dw, _ly + hght - 1)) { selecting = i; + hovering = i; } if(selecting == i) { draw_sprite_stretched_ext(THEME.textbox, 3, 0, _ly, _dw, hght, COLORS.dialog_menubox_highlight, 1); if(sFOCUS && (mouse_press(mb_left) || keyboard_check_pressed(vk_enter))) { - scrollbox.onModify(i); + initVal = i; instance_destroy(); } } @@ -40,8 +51,16 @@ event_inherited(); draw_text_cut(_dw / 2, _ly + hght / 2, data[i], _dw); else if(align == fa_left) draw_text_cut(ui(8), _ly + hght / 2, data[i], _dw); + + _ly += hght; + _h += hght; } + UNDO_HOLDING = true; + if(hovering > -1) scrollbox.onModify(hovering); + else scrollbox.onModify(initVal); + UNDO_HOLDING = false; + if(sFOCUS) { if(keyboard_check_pressed(vk_up)) { selecting--; diff --git a/objects/o_dialog_scrollbox/Destroy_0.gml b/objects/o_dialog_scrollbox/Destroy_0.gml index e3ab05314..a3ff85a8e 100644 --- a/objects/o_dialog_scrollbox/Destroy_0.gml +++ b/objects/o_dialog_scrollbox/Destroy_0.gml @@ -1,4 +1,5 @@ /// @description init event_inherited(); +scrollbox.onModify(initVal); scrollbox.open = false; \ No newline at end of file diff --git a/objects/o_dialog_splash/Draw_64.gml b/objects/o_dialog_splash/Draw_64.gml index db7d70a03..0c5884355 100644 --- a/objects/o_dialog_splash/Draw_64.gml +++ b/objects/o_dialog_splash/Draw_64.gml @@ -81,8 +81,11 @@ if !ready exit; var bx = x1 - ui(32); var by = y0 - ui(32); - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), mouse_ui, sFOCUS, sHOVER, "Open Steam Workshop", THEME.steam) == 2) { - steam_activate_overlay_browser("https://steamcommunity.com/app/2299510/workshop/") - } + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), mouse_ui, sFOCUS, sHOVER, "Open Steam Workshop", THEME.steam) == 2) + steam_activate_overlay_browser("https://steamcommunity.com/app/2299510/workshop/"); + + bx -= ui(36); + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), mouse_ui, sFOCUS, sHOVER, "Refresh content", THEME.refresh) == 2) + steamUCGload(); } #endregion \ No newline at end of file diff --git a/objects/o_main/Create_0.gml b/objects/o_main/Create_0.gml index 206c2aac2..407c53572 100644 --- a/objects/o_main/Create_0.gml +++ b/objects/o_main/Create_0.gml @@ -185,6 +185,7 @@ globalvar STEAM_ENABLED, STEAM_APP_ID, STEAM_USER_ID, STEAM_USERNAME; globalvar STEAM_UGC_ITEM_UPLOADING, STEAM_UGC_ITEM_ID, STEAM_UGC_ITEM_FILE, STEAM_UGC_UPDATE_HANDLE; globalvar STEAM_UGC_SUBMIT_ID, STEAM_UGC_UPDATE_MAP, STEAM_UGC_PUBLISH_ID, STEAM_UGC_UPDATE, STEAM_UGC_TYPE; + globalvar STEAM_SUB_ID; enum STEAM_UGC_FILE_TYPE { collection, @@ -193,7 +194,8 @@ } STEAM_UGC_TYPE = STEAM_UGC_FILE_TYPE.collection; - STEAM_USER_ID = 0; + STEAM_SUB_ID = 0; + STEAM_USER_ID = 0; STEAM_USERNAME = ""; STEAM_UGC_UPDATE_HANDLE = 0; diff --git a/objects/o_main/Other_69.gml b/objects/o_main/Other_69.gml index 3f7a0b354..e59589cfa 100644 --- a/objects/o_main/Other_69.gml +++ b/objects/o_main/Other_69.gml @@ -12,9 +12,9 @@ if(string(ev_id) == string(STEAM_UGC_ITEM_ID) && ev_type == "ugc_create_item") { var tgs = array_clone(STEAM_UGC_ITEM_FILE.meta.tags); switch(STEAM_UGC_TYPE) { - case STEAM_UGC_FILE_TYPE.collection : array_insert(tgs, 0, "Collection"); break; - case STEAM_UGC_FILE_TYPE.project : array_insert(tgs, 0, "Project"); break; - case STEAM_UGC_FILE_TYPE.node_preset : array_insert(tgs, 0, "Node preset"); break; + case STEAM_UGC_FILE_TYPE.collection : array_insert_unique(tgs, 0, "Collection"); break; + case STEAM_UGC_FILE_TYPE.project : array_insert_unique(tgs, 0, "Project"); break; + case STEAM_UGC_FILE_TYPE.node_preset : array_insert_unique(tgs, 0, "Node preset"); break; } steam_ugc_set_item_tags(STEAM_UGC_UPDATE_HANDLE, tgs); @@ -43,10 +43,12 @@ if(string(ev_id) == string(STEAM_UGC_SUBMIT_ID)) { log_message("WORKSHOP", type + " uploaded", THEME.workshop_upload); PANEL_MENU.setNotiIcon(THEME.workshop_upload); } + + STEAM_SUB_ID = steam_ugc_subscribe_item(STEAM_UGC_PUBLISH_ID); exit; } - switch(async_load[? "result"]) { + switch(async_load[? "result"]) { #region error case 2: log_warning("WORKSHOP", "Generic failure."); break; case 3: log_warning("WORKSHOP", "Your Steam client doesn't have a connection to the back-end."); break; case 5: log_warning("WORKSHOP", "Password/ticket is invalid."); break; @@ -153,5 +155,5 @@ if(string(ev_id) == string(STEAM_UGC_SUBMIT_ID)) { case 106: log_warning("WORKSHOP", "This Game Server Login Token (GSLT) has expired from disuse; it can be reset for use."); break; case 107: log_warning("WORKSHOP", "user doesn't have enough wallet funds to complete the action"); break; case 108: log_warning("WORKSHOP", "There are too many of this thing pending already"); break; - } + } #endregion } \ No newline at end of file diff --git a/scripts/array_functions/array_functions.gml b/scripts/array_functions/array_functions.gml index 700a205af..33f03cf2a 100644 --- a/scripts/array_functions/array_functions.gml +++ b/scripts/array_functions/array_functions.gml @@ -59,6 +59,12 @@ function array_push_unique(arr, val) { array_push(arr, val); } + +function array_insert_unique(arr, ind, val) { + if(array_exists(arr, val)) return; + array_insert(arr, ind, val); +} + function array_append(arr, arr0) { for( var i = 0; i < array_length(arr0); i++ ) array_push(arr, arr0[i]); diff --git a/scripts/dialog_management/dialog_management.gml b/scripts/dialog_management/dialog_management.gml index c9c42cc03..26ded5253 100644 --- a/scripts/dialog_management/dialog_management.gml +++ b/scripts/dialog_management/dialog_management.gml @@ -23,4 +23,11 @@ function menuCall(_x = mouse_mx, _y = mouse_my, menu = []) { var dia = dialogCall(o_dialog_menubox, _x, _y); dia.setMenu(menu); return dia; +} + +function menuItem(name, func, spr = noone, hotkey = noone) constructor { + self.name = name; + self.func = func; + self.spr = spr; + self.hotkey = hotkey; } \ No newline at end of file diff --git a/scripts/draw_surface_blend/draw_surface_blend.gml b/scripts/draw_surface_blend/draw_surface_blend.gml index 4cc44032e..764fd42f0 100644 --- a/scripts/draw_surface_blend/draw_surface_blend.gml +++ b/scripts/draw_surface_blend/draw_surface_blend.gml @@ -1,40 +1,24 @@ globalvar BLEND_TYPES; -BLEND_TYPES = [ "Normal", "Add", "Subtract", "Multiply", "Screen", "Contrast", "Overlay", "Hue", "Saturation", "Luminosity", "Maximum", "Minimum" ]; - -enum BLEND_MODE { - normal, - add, - subtract, - multiply, - screen, - contrast, - overlay, - hue, - sat, - luma, - - maxx, - minn, -} +BLEND_TYPES = [ "Normal", "Add", "Subtract", "Multiply", "Screen", "Overlay", "Hue", "Saturation", "Luminosity", "Maximum", "Minimum" ]; function draw_surface_blend(background, foreground, blend, alpha, _pre_alp = true, _mask = 0, tile = 0) { if(!is_surface(background)) return; var sh = sh_blend_normal - switch(blend) { - case BLEND_MODE.normal : sh = sh_blend_normal break; - case BLEND_MODE.add : sh = sh_blend_add; break; - case BLEND_MODE.subtract : sh = sh_blend_subtract; break; - case BLEND_MODE.multiply : sh = sh_blend_multiply; break; - case BLEND_MODE.screen : sh = sh_blend_screen; break; - case BLEND_MODE.contrast : sh = sh_blend_contrast; break; - case BLEND_MODE.overlay : sh = sh_blend_overlay; break; - case BLEND_MODE.hue : sh = sh_blend_hue; break; - case BLEND_MODE.sat : sh = sh_blend_sat; break; - case BLEND_MODE.luma : sh = sh_blend_luma; break; + switch(BLEND_TYPES[blend]) { + case "Normal" : sh = sh_blend_normal break; + case "Add" : sh = sh_blend_add; break; + case "Subtract" : sh = sh_blend_subtract; break; + case "Multiply" : sh = sh_blend_multiply; break; + case "Screen" : sh = sh_blend_screen; break; + case "Overlay" : sh = sh_blend_overlay; break; + case "Hue" : sh = sh_blend_hue; break; + case "Saturation" : sh = sh_blend_sat; break; + case "Luminosity" : sh = sh_blend_luma; break; - case BLEND_MODE.maxx : sh = sh_blend_max; break; - case BLEND_MODE.minn : sh = sh_blend_min; break; + case "Maximum" : sh = sh_blend_max; break; + case "Minimum" : sh = sh_blend_min; break; + default: return; } var uniform_foreground = shader_get_sampler_index(sh, "fore"); diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index eeff401f3..8df666b82 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.pr5"; + VERSION_STRING = "1.13.pr7"; globalvar NODES, NODE_MAP, APPEND_MAP, HOTKEYS, HOTKEY_CONTEXT; diff --git a/scripts/mask_function/mask_function.gml b/scripts/mask_function/mask_function.gml index 7fe42f41d..b0579bda8 100644 --- a/scripts/mask_function/mask_function.gml +++ b/scripts/mask_function/mask_function.gml @@ -1,5 +1,5 @@ function mask_apply(original, edited, mask, mix = 1) { - if(!is_surface(mask) || mix == 1) return edited; + if(!is_surface(mask) && mix == 1) return edited; var _s = surface_create_size(original); @@ -9,7 +9,7 @@ function mask_apply(original, edited, mask, mix = 1) { texture_set_stage(shader_get_sampler_index(sh_mask, "edited"), surface_get_texture(edited)); shader_set_uniform_i(shader_get_uniform(sh_mask, "useMask"), is_surface(mask)); - texture_set_stage(shader_get_sampler_index(sh_mask, "mask"), surface_get_texture(mask)); + texture_set_stage(shader_get_sampler_index(sh_mask, "mask"), surface_get_texture(mask)); shader_set_uniform_f(shader_get_uniform(sh_mask, "mixRatio"), mix); diff --git a/scripts/meta_data/meta_data.gml b/scripts/meta_data/meta_data.gml index bda36941d..5f4916283 100644 --- a/scripts/meta_data/meta_data.gml +++ b/scripts/meta_data/meta_data.gml @@ -103,6 +103,23 @@ function MetaDataManager() constructor { _w = max(_w, string_width_ext(_ver, -1, ww)); } + if(array_length(tags)) { + draw_set_font(f_p0); + _h += ui(8); + var tx = 0; + var hh = line_height(f_p0, ui(4)); + var th = hh; + for( var i = 0; i < array_length(tags); i++ ) { + var ww = string_width(tags[i]) + ui(16); + if(tx + ww + ui(2) > _w - ui(16)) { + tx = 0; + th += hh + ui(2); + } + tx += ww + ui(2); + } + _h += th; + } + var mx = min(mouse_mx + ui(16), WIN_W - (_w + ui(16))); var my = min(mouse_my + ui(16), WIN_H - (_h + ui(16))); @@ -146,6 +163,27 @@ function MetaDataManager() constructor { draw_text_ext(mx + ui(8), ty, _ver, -1, _w); ty += string_height_ext(_ver, -1, _w); } + + if(array_length(tags)) { + draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text); + ty += ui(8); + var tx = 0; + var hh = line_height(f_p0, ui(4)); + + for( var i = 0; i < array_length(tags); i++ ) { + var ww = string_width(tags[i]) + ui(16); + if(tx + ww + ui(2) > _w - ui(16)) { + tx = 0; + ty += hh + ui(2); + } + + draw_sprite_stretched_ext(THEME.group_label, 0, mx + ui(8) + tx, ty, ww, hh, COLORS._main_icon, 1); + draw_text(mx + ui(8) + tx + ui(8), ty + hh / 2, tags[i]); + + tx += ww + ui(2); + } + } + } } diff --git a/scripts/node_blend/node_blend.gml b/scripts/node_blend/node_blend.gml index d97c58795..81fa5aa91 100644 --- a/scripts/node_blend/node_blend.gml +++ b/scripts/node_blend/node_blend.gml @@ -1,16 +1,5 @@ function Node_create_Blend(_x, _y, _group = -1, _param = "") { var node = new Node_Blend(_x, _y, _group); - - switch(_param) { - case "normal" : node.inputs[| 2].setValue(BLEND_MODE.normal) break; - case "add" : node.inputs[| 2].setValue(BLEND_MODE.add); break; - case "subtract" : node.inputs[| 2].setValue(BLEND_MODE.subtract); break; - case "multiply" : node.inputs[| 2].setValue(BLEND_MODE.multiply); break; - case "overlay" : node.inputs[| 2].setValue(BLEND_MODE.overlay); break; - case "screen" : node.inputs[| 2].setValue(BLEND_MODE.screen); break; - case "maxx" : node.inputs[| 2].setValue(BLEND_MODE.maxx); break; - case "minn" : node.inputs[| 2].setValue(BLEND_MODE.minn); break; - } return node; } @@ -81,7 +70,7 @@ function Node_Blend(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constr inputs[| 10].setVisible(_tile == 0); inputs[| 11].setVisible(_tile == 0); - if(_tile == 0) { + if(_tile == 0 && is_surface(_fore)) { ww = surface_get_width(_back); hh = surface_get_height(_back); @@ -120,16 +109,18 @@ function Node_Blend(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constr hh = surface_get_height(_back); break; case 1 : - ww = surface_get_width(_foreDraw); - hh = surface_get_height(_foreDraw); + if(is_surface(_foreDraw)) { + ww = surface_get_width(_foreDraw); + hh = surface_get_height(_foreDraw); + } break; case 2 : ww = surface_get_width(_mask); hh = surface_get_height(_mask); break; case 3 : - ww = max(surface_get_width(_back), surface_get_width(_fore), surface_get_width(_mask)); - hh = max(surface_get_height(_back), surface_get_height(_fore), surface_get_height(_mask)); + ww = max(surface_get_width(_back), is_surface(_fore)? surface_get_width(_fore) : 1, surface_get_width(_mask)); + hh = max(surface_get_height(_back), is_surface(_fore)? surface_get_height(_fore) : 1, surface_get_height(_mask)); break; case 4 : ww = _out_dim[0]; diff --git a/scripts/node_colorize/node_colorize.gml b/scripts/node_colorize/node_colorize.gml index f09ae4877..4a34c6758 100644 --- a/scripts/node_colorize/node_colorize.gml +++ b/scripts/node_colorize/node_colorize.gml @@ -6,7 +6,7 @@ function Node_Colorize(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) con uniform_color = shader_get_uniform(shader, "gradient_color"); uniform_time = shader_get_uniform(shader, "gradient_time"); uniform_shift = shader_get_uniform(shader, "gradient_shift"); - uniform_key = shader_get_uniform(shader, "keys"); + uniform_key = shader_get_uniform(shader, "gradient_keys"); uniform_alpha = shader_get_uniform(shader, "multiply_alpha"); inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0); diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index 6253905c8..14c871d6a 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -761,7 +761,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) constructor { } static clearInputCache = function() { - for( var i = 0; i < ds_list_size(inputs); i++ ) + for( var i = 0; i < ds_list_size(inputs); i++ ) inputs[| i].cache_value[0] = false; } diff --git a/scripts/node_palette_sort/node_palette_sort.gml b/scripts/node_palette_sort/node_palette_sort.gml index 1d00a08f3..d84656d7c 100644 --- a/scripts/node_palette_sort/node_palette_sort.gml +++ b/scripts/node_palette_sort/node_palette_sort.gml @@ -9,7 +9,7 @@ function Node_Palette_Sort(_x, _y, _group = -1) : Node(_x, _y, _group) construct .setVisible(true, true); inputs[| 1] = nodeValue("Order", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) - .setDisplay(VALUE_DISPLAY.enum_button, [ "Brightness", "Hue (HSV)", "Saturation (SHV)", "Value (VHS)", "Red (RGB)", "Green (GBR)", "Blue (BRG)" ]) + .setDisplay(VALUE_DISPLAY.enum_button, [ "Brightness", -1, "Hue (HSV)", "Saturation (SHV)", "Value (VHS)", -1, "Red (RGB)", "Green (GBR)", "Blue (BRG)" ]) .rejectArray(); inputs[| 2] = nodeValue("Reverse", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); diff --git a/scripts/panel_collection/panel_collection.gml b/scripts/panel_collection/panel_collection.gml index 2eccc42d3..5ca1c6966 100644 --- a/scripts/panel_collection/panel_collection.gml +++ b/scripts/panel_collection/panel_collection.gml @@ -30,32 +30,34 @@ function Panel_Collection() : PanelContent() constructor { data_path = ""; static initMenu = function() { - contentMenu = [ - [ get_text("panel_collection_replace", "Replace with selected"), function() { - saveCollection(_menu_node.path, false, _menu_node.meta); - } ], - [ get_text("panel_collection_edit_meta", "Edit metadata") + "...", function() { - var dia = dialogCall(o_dialog_file_name_collection, mouse_mx + ui(8), mouse_my + ui(-320)); - var meta = _menu_node.getMetadata(); - if(meta != noone && meta != undefined) - dia.meta = meta; - - dia.updating = _menu_node; - dia.expand(); - } ], - -1, - [ get_text("delete", "Delete"), function() { - file_delete(_menu_node.path); - refreshContext(); - } ], - ]; - - if(DEMO) array_delete(contentMenu, 0, 3); - else if(_menu_node && STEAM_ENABLED) { - var meta = _menu_node.getMetadata(); + if(_menu_node == noone) return; + var meta = _menu_node.getMetadata(); + + contentMenu = []; + + if(meta == noone || !meta.steam) { + contentMenu = [ + [ get_text("panel_collection_replace", "Replace with selected"), function() { + saveCollection(_menu_node.path, false, _menu_node.meta); + } ], + [ get_text("panel_collection_edit_meta", "Edit metadata") + "...", function() { + var dia = dialogCall(o_dialog_file_name_collection, mouse_mx + ui(8), mouse_my + ui(-320)); + var meta = _menu_node.getMetadata(); + if(meta != noone && meta != undefined) + dia.meta = meta; + dia.updating = _menu_node; + dia.expand(); + } ], + -1, + [ get_text("delete", "Delete"), function() { + file_delete(_menu_node.path); + refreshContext(); + } ] + ]; + } else if(STEAM_ENABLED) { if(!meta.steam) { - array_insert(contentMenu, 2, [ get_text("panel_collection_workshop_upload", "Upload to Steam Workshop") + "...", function() { + array_push(contentMenu, [ get_text("panel_collection_workshop_upload", "Upload to Steam Workshop") + "...", function() { var dia = dialogCall(o_dialog_file_name_collection, mouse_mx + ui(8), mouse_my + ui(-320)); var meta = _menu_node.getMetadata(); if(meta != noone && meta != undefined) @@ -65,19 +67,33 @@ function Panel_Collection() : PanelContent() constructor { dia.updating = _menu_node; dia.expand(); } ]); - } - - if(meta.steam && meta.author_steam_id == STEAM_USER_ID && meta.file_id != 0) { - array_insert(contentMenu, 2, [get_text("panel_collection_workshop_update", "Update Steam Workshop content") + "...", function() { - var dia = dialogCall(o_dialog_file_name_collection, mouse_mx + ui(8), mouse_my + ui(-320)); - var meta = _menu_node.getMetadata(); - if(meta != noone && meta != undefined) - dia.meta = meta; + } else { + if(meta.author_steam_id == STEAM_USER_ID && meta.file_id != 0) { + array_push(contentMenu, [get_text("panel_collection_workshop_update", "Update Steam Workshop content") + "...", function() { + var dia = dialogCall(o_dialog_file_name_collection, mouse_mx + ui(8), mouse_my + ui(-320)); + var meta = _menu_node.getMetadata(); + if(meta != noone && meta != undefined) + dia.meta = meta; + + dia.ugc = 2; + dia.updating = _menu_node; + dia.expand(); + } ]); + } - dia.ugc = 2; - dia.updating = _menu_node; - dia.expand(); - } ]); + array_push(contentMenu, ["Unsubscribe", function() { + var meta = _menu_node.getMetadata(); + var del_id = meta.file_id; + + for( var i = 0; i < ds_list_size(STEAM_COLLECTION); i++ ) { + print(STEAM_COLLECTION[| i].meta.file_id); + if(STEAM_COLLECTION[| i].getMetadata().file_id == del_id) { + ds_list_delete(STEAM_COLLECTION, i); + break; + } + } + steam_ugc_unsubscribe_item(del_id); + }]); } } } @@ -146,7 +162,7 @@ function Panel_Collection() : PanelContent() constructor { if(mouse_press(mb_left, pFOCUS)) file_dragging = _node; - if(mouse_press(mb_right, pFOCUS)) { + if(!DEMO && mouse_press(mb_right, pFOCUS)) { _menu_node = _node; initMenu(); var dia = dialogCall(o_dialog_menubox, mouse_mx + 8, mouse_my + 8); @@ -220,7 +236,7 @@ function Panel_Collection() : PanelContent() constructor { if(mouse_press(mb_left, pFOCUS)) file_dragging = _node; - if(mouse_press(mb_right, pFOCUS)) { + if(!DEMO && mouse_press(mb_right, pFOCUS)) { _menu_node = _node; initMenu(); var dia = dialogCall(o_dialog_menubox, mouse_mx + ui(8), mouse_my + ui(8)); @@ -286,6 +302,9 @@ function Panel_Collection() : PanelContent() constructor { function refreshContext() { context.scan([".json", ".pxcc"]); + + if(STEAM_ENABLED) + steamUCGload(); } function saveCollection(_name, save_surface = true, metadata = noone) { diff --git a/scripts/panel_menu/panel_menu.gml b/scripts/panel_menu/panel_menu.gml index 0af2f5050..eb2ee1201 100644 --- a/scripts/panel_menu/panel_menu.gml +++ b/scripts/panel_menu/panel_menu.gml @@ -48,6 +48,36 @@ function Panel_Menu() : PanelContent() constructor { array_delete(menu_file, 1, 4); } + menu_help = [ get_text("panel_menu_help", "Help"), [ + [ get_text("panel_menu_help_video", "Tutorial videos"), function() { + url_open("https://www.youtube.com/@makhamdev"); + } ], + [ get_text("panel_menu_help_wiki", "Community Wiki"), function() { + url_open("https://pixel-composer.fandom.com/wiki/Pixel_Composer_Wiki"); + } ], + -1, + [ get_text("panel_menu_itch", "itch.io page"), function() { + url_open("https://makham.itch.io/pixel-composer"); + } ], + [ get_text("panel_menu_steam", "Steam page"), function() { + url_open("https://store.steampowered.com/app/2299510/Pixel_Composer"); + } ], + -1, + [ get_text("panel_menu_directory", "Open local directory"), function() { + shellOpenExplorer(DIRECTORY); + } ], + [ get_text("panel_menu_reset_default", "Reset default collection, assets"), function() { + zip_unzip("data/Collections.zip", DIRECTORY + "Collections"); + zip_unzip("data/Assets.zip", DIRECTORY + "Assets"); + } ], + ]]; + + menu_help_steam = array_clone(menu_help); + array_push(menu_help_steam[1], -1, + [ get_text("panel_menu_steam_workshop", "Steam Workshop"), function() { + steam_activate_overlay_browser("https://steamcommunity.com/app/2299510/workshop/"); + } ]); + menus = [ [ get_text("panel_menu_file", "File"), menu_file], [ get_text("panel_menu_edit", "Edit"), [ @@ -112,29 +142,7 @@ function Panel_Menu() : PanelContent() constructor { PREF_SAVE(); } ], ]], - [ get_text("panel_menu_help", "Help"), [ - [ get_text("panel_menu_help_video", "Tutorial videos"), function() { - url_open("https://www.youtube.com/@makhamdev"); - } ], - [ get_text("panel_menu_help_wiki", "Community Wiki"), function() { - url_open("https://pixel-composer.fandom.com/wiki/Pixel_Composer_Wiki"); - } ], - -1, - [ get_text("panel_menu_itch", "itch.io page"), function() { - url_open("https://makham.itch.io/pixel-composer"); - } ], - [ get_text("panel_menu_steam", "Steam page"), function() { - url_open("https://store.steampowered.com/app/2299510/Pixel_Composer"); - } ], - -1, - [ get_text("panel_menu_directory", "Open local directory"), function() { - shellOpenExplorer(DIRECTORY); - } ], - [ get_text("panel_menu_reset_default", "Reset default collection, assets"), function() { - zip_unzip("data/Collections.zip", DIRECTORY + "Collections"); - zip_unzip("data/Assets.zip", DIRECTORY + "Assets"); - } ], - ]], + menu_help, ] if(TESTING) { @@ -220,10 +228,11 @@ function Panel_Menu() : PanelContent() constructor { draw_sprite_ui_uniform(THEME.icon_24, 0, h / 2, h / 2, 1, c_white); var xx = h; + menus[6] = STEAM_ENABLED? menu_help_steam : menu_help; + if(pHOVER && point_in_rectangle(mx, my, 0, 0, ui(40), ui(32))) { - if(mouse_press(mb_left, pFOCUS)) { + if(mouse_press(mb_left, pFOCUS)) dialogCall(o_dialog_about); - } } for(var i = 0; i < array_length(menus); i++) { diff --git a/scripts/scrollBox/scrollBox.gml b/scripts/scrollBox/scrollBox.gml index b1c99d9ba..8ba346038 100644 --- a/scripts/scrollBox/scrollBox.gml +++ b/scripts/scrollBox/scrollBox.gml @@ -1,7 +1,8 @@ function scrollBox(_data, _onModify) : widget() constructor { onModify = _onModify; data_list = _data; - data = []; + data = []; + curr_text = 0; open = false; open_rx = 0; @@ -11,16 +12,17 @@ function scrollBox(_data, _onModify) : widget() constructor { extra_button = noone; static trigger = function() { - if(is_method(data_list)) - data = data_list(); - else - data = data_list; - + if(is_method(data_list)) data = data_list(); + else data = data_list; + + var ind = array_find(data, curr_text); + open = true; with(dialogCall(o_dialog_scrollbox, x + open_rx, y + open_ry)) { scrollbox = other; + initVal = ind; dialog_w = other.w; - align = other.align; + align = other.align; } } @@ -30,6 +32,7 @@ function scrollBox(_data, _onModify) : widget() constructor { open_rx = _rx; open_ry = _ry; h = _h; + curr_text = _text; w = _w; if(extra_button != noone) { diff --git a/scripts/steam_ugc_collection/steam_ugc_collection.gml b/scripts/steam_ugc_collection/steam_ugc_collection.gml index 1dd9e94c3..dfe5199dd 100644 --- a/scripts/steam_ugc_collection/steam_ugc_collection.gml +++ b/scripts/steam_ugc_collection/steam_ugc_collection.gml @@ -9,7 +9,8 @@ function steam_ugc_create_collection(file) { directory_destroy(DIRECTORY + "steamUGC"); directory_create(DIRECTORY + "steamUGC"); file_copy(file.path, DIRECTORY + "steamUGC/" + filename_name(file.path)); - file_copy(file.spr_path[0], DIRECTORY + "steamUGC/" + filename_name(file.spr_path[0])); + if(array_safe_get(file.spr_path, 0, 0) != 0) + file_copy(file.spr_path[0], DIRECTORY + "steamUGC/" + filename_name(file.spr_path[0])); steam_ugc_collection_generate(file); STEAM_UGC_ITEM_ID = steam_ugc_create_item(STEAM_APP_ID, ugc_filetype_community); @@ -26,7 +27,8 @@ function steam_ugc_update_collection(file, update_preview = false) { directory_destroy(DIRECTORY + "steamUGC"); directory_create(DIRECTORY + "steamUGC"); file_copy(file.path, DIRECTORY + "steamUGC/" + filename_name(file.path)); - file_copy(file.spr_path[0], DIRECTORY + "steamUGC/" + filename_name(file.spr_path[0])); + if(array_safe_get(file.spr_path, 0, 0) != 0) + file_copy(file.spr_path[0], DIRECTORY + "steamUGC/" + filename_name(file.spr_path[0])); STEAM_UGC_PUBLISH_ID = file.meta.file_id; STEAM_UGC_UPDATE_HANDLE = steam_ugc_start_item_update(STEAM_APP_ID, STEAM_UGC_PUBLISH_ID); diff --git a/scripts/steam_ugc_functions/steam_ugc_functions.gml b/scripts/steam_ugc_functions/steam_ugc_functions.gml index 5ecca7938..124f94db6 100644 --- a/scripts/steam_ugc_functions/steam_ugc_functions.gml +++ b/scripts/steam_ugc_functions/steam_ugc_functions.gml @@ -1,12 +1,20 @@ function __initSteamUGC() { globalvar STEAM_SUBS, STEAM_COLLECTION, STEAM_PROJECTS; - STEAM_SUBS = ds_list_create(); + STEAM_SUBS = ds_list_create(); STEAM_COLLECTION = ds_list_create(); STEAM_PROJECTS = ds_list_create(); if(DEMO) return; if(!STEAM_ENABLED) return; + steamUCGload(); +} + +function steamUCGload() { + ds_list_clear(STEAM_SUBS); + ds_list_clear(STEAM_COLLECTION); + ds_list_clear(STEAM_PROJECTS); + steam_ugc_get_subscribed_items(STEAM_SUBS); for( var i = 0; i < ds_list_size(STEAM_SUBS); i++ ) { @@ -56,7 +64,7 @@ function __loadSteamUGC(file_id, item_map) { } function __loadSteamUGCCollection(file_id, f, path) { - var name = string_replace(filename_name(f), ".pxc", ""); + var name = string_replace(filename_name(f), ".pxcc", ""); var file = new FileObject(name, path + "\\" + f); var icon_path = string_replace(path + "\\" + f, ".pxcc", ".png"); if(file_exists(icon_path)) { diff --git a/scripts/string_function/string_function.gml b/scripts/string_function/string_function.gml index 16367a38a..260180320 100644 --- a/scripts/string_function/string_function.gml +++ b/scripts/string_function/string_function.gml @@ -33,6 +33,8 @@ function string_partial_match(str, key) { function string_real(val) { if(is_string(val)) return val; + if(is_struct(val)) return string(val); + if(is_array(val)) { var s = "["; for( var i = 0; i < array_length(val); i++ ) diff --git a/scripts/surface_functions/surface_functions.gml b/scripts/surface_functions/surface_functions.gml index a2ee4e064..f2b7f602e 100644 --- a/scripts/surface_functions/surface_functions.gml +++ b/scripts/surface_functions/surface_functions.gml @@ -19,6 +19,11 @@ function draw_surface_part_ext_safe(surface, _l, _t, _w, _h, _x, _y, _xs = 1, _y draw_surface_part_ext(surface, _l, _t, _w, _h, _x, _y, _xs, _ys, _col, _alpha); } +function surface_create_size(surf) { + if(!is_surface(surf)) return surface_create(1, 1); + return surface_create_valid(surface_get_width(surf), surface_get_height(surf)); +} + function surface_size_to(surface, width, height) { if(!surface_exists(surface)) return false; if(width < 1 && height < 1) return false; diff --git a/shaders/sh_colorize/sh_colorize.fsh b/shaders/sh_colorize/sh_colorize.fsh index 417e1e92f..ce8683f3b 100644 --- a/shaders/sh_colorize/sh_colorize.fsh +++ b/shaders/sh_colorize/sh_colorize.fsh @@ -7,10 +7,74 @@ varying vec4 v_vColour; uniform int gradient_blend; uniform vec4 gradient_color[16]; uniform float gradient_time[16]; -uniform int keys; +uniform int gradient_keys; uniform float gradient_shift; uniform int multiply_alpha; +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 0.0000000001; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); + } + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +float hueDist(float a0, float a1, float t) { + float da = fract(a1 - a0); + float ds = fract(2. * da) - da; + return a0 + ds * t; +} + +vec3 hsvMix(vec3 c1, vec3 c2, float t) { + vec3 h1 = rgb2hsv(c1); + vec3 h2 = rgb2hsv(c2); + + vec3 h = vec3(0.); + h.x = h.x + hueDist(h1.x, h2.x, t); + h.y = mix(h1.y, h2.y, t); + h.z = mix(h1.z, h2.z, t); + + return hsv2rgb(h); +} + +vec4 gradientEval(in float prog) { + vec4 col = vec4(0.); + + for(int i = 0; i < 16; i++) { + if(gradient_time[i] == prog) { + col = gradient_color[i]; + break; + } else if(gradient_time[i] > prog) { + if(i == 0) + col = gradient_color[i]; + else { + float t = (prog - gradient_time[i - 1]) / (gradient_time[i] - gradient_time[i - 1]); + if(gradient_blend == 0) + col = mix(gradient_color[i - 1], gradient_color[i], t); + else if(gradient_blend == 1) + col = gradient_color[i - 1]; + else if(gradient_blend == 2) + col = vec4(hsvMix(gradient_color[i - 1].rgb, gradient_color[i].rgb, t), 1.); + } + break; + } + if(i >= gradient_keys - 1) { + col = gradient_color[gradient_keys - 1]; + break; + } + } + + return col; +} + void main() { vec4 _col = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord ); float prog = abs(dot(_col.rgb, vec3(0.2126, 0.7152, 0.0722)) + gradient_shift); @@ -24,28 +88,7 @@ void main() { prog = fract(prog); } - vec4 col = vec4(0.); - - for(int i = 0; i < 16; i++) { - if(gradient_time[i] == prog) { - col = gradient_color[i]; - break; - } else if(gradient_time[i] > prog) { - if(i == 0) - col = gradient_color[i]; - else { - if(gradient_blend == 0) - col = mix(gradient_color[i - 1], gradient_color[i], (prog - gradient_time[i - 1]) / (gradient_time[i] - gradient_time[i - 1])); - else if(gradient_blend == 1) - col = gradient_color[i - 1]; - } - break; - } - if(i >= keys - 1) { - col = gradient_color[keys - 1]; - break; - } - } + vec4 col = gradientEval(prog); col.a = _col.a; gl_FragColor = col;