From 11488e5c52770f7fc057c19682eed96b838ae5dd Mon Sep 17 00:00:00 2001 From: mleaf233 Date: Fri, 26 Dec 2025 23:08:20 +0800 Subject: [PATCH 1/3] fix: Compatible with non-PC platforms --- assets/shaders/brainstorm.fs | 153 +++++++++++++++++++++++------------ smods.lua | 4 +- 2 files changed, 102 insertions(+), 55 deletions(-) diff --git a/assets/shaders/brainstorm.fs b/assets/shaders/brainstorm.fs index e81f6be..eeaf239 100644 --- a/assets/shaders/brainstorm.fs +++ b/assets/shaders/brainstorm.fs @@ -4,7 +4,7 @@ #define PRECISION mediump #endif -// extern int dpi; +// extern int dpi; extern vec3 greyscale_weights; extern int blur_amount; extern ivec2 card_size; @@ -18,61 +18,97 @@ extern float red_threshold; // extern bool floating; extern vec2 texture_size; +// Love2D/GLSL Compatibility Macros +#ifndef Image +#define Image sampler2D +#endif + +#ifndef Texel +#define Texel texture2D +#endif + +// Max blur loop limit (constant required for loop unrolling in some drivers) +#define MAX_BLUR 10 + float greyscale(vec4 col) { return dot(greyscale_weights, col.rgb); } vec4 myTexelFetch(Image s, ivec2 c) { + // [Fix]: Explicit cast to vec2 for coordinate calculation // return texelFetch(s, c * dpi, l); vec2 uv = (vec2(c) + vec2(0.5)) / texture_size; return Texel(s, uv); } float gaussian_blur(Image jokers_sampler, ivec2 texture_coords) { - float col = 0.0; + float col = 0.0; float total = 0.0; - for (int x = -blur_amount; x <= blur_amount; x++) { - for (int y = -blur_amount; y <= blur_amount; y++) { + + // [Fix]: Loop bounds must be constants + for (int x = -MAX_BLUR; x <= MAX_BLUR; x++) { + // Optimization: skip iterations outside current blur_amount + if (x < -blur_amount || x > blur_amount) continue; + + for (int y = -MAX_BLUR; y <= MAX_BLUR; y++) { + if (y < -blur_amount || y > blur_amount) continue; + ivec2 offset = ivec2(x, y); float factor; - if (blur_amount == 0) + + if (blur_amount == 0) { factor = 1.0; - else { - factor = exp(-dot(offset, offset) / float(blur_amount * blur_amount)); + } else { + // [Fix]: Cast ivec2 to vec2 before dot product + vec2 offset_f = vec2(offset); + float dist_sq = dot(offset_f, offset_f); + + // [Fix]: Cast int to float for division + float blur_f = float(blur_amount); + factor = exp(-dist_sq / (blur_f * blur_f)); } + col += greyscale(myTexelFetch(jokers_sampler, texture_coords + offset)) * factor; total += factor; } } - col /= total; - return col; + + // [Fix]: Safety check for division + if (total > 0.0) { + col /= total; + } + return col; } #define sobel_kernel_length 6 -vec3 sobel_kernelx[sobel_kernel_length] = vec3[sobel_kernel_length] ( - vec3(-1, -1, -1), - vec3(-1, 0, -2), - vec3(-1, 1, -1), - vec3(1, -1, 1), - vec3(1, 0, 2), - vec3(1, 1, 1) -); - -vec3 sobel_kernely[sobel_kernel_length] = vec3[sobel_kernel_length] ( - vec3(-1, -1, -1), - vec3(0, -1, -2), - vec3(1, -1, -1), - vec3(-1, 1, 1), - vec3(0, 1, 2), - vec3(1, 1, 1) -); - vec2 sobel_filter(Image jokers_sampler, ivec2 texture_coords) { - vec2 d = vec2(0); + // [Fix]: Initialize array elements individually (No C-style initializer lists) + vec3 sobel_kernelx[6]; + sobel_kernelx[0] = vec3(-1.0, -1.0, -1.0); + sobel_kernelx[1] = vec3(-1.0, 0.0, -2.0); + sobel_kernelx[2] = vec3(-1.0, 1.0, -1.0); + sobel_kernelx[3] = vec3( 1.0, -1.0, 1.0); + sobel_kernelx[4] = vec3( 1.0, 0.0, 2.0); + sobel_kernelx[5] = vec3( 1.0, 1.0, 1.0); + + vec3 sobel_kernely[6]; + sobel_kernely[0] = vec3(-1.0, -1.0, -1.0); + sobel_kernely[1] = vec3( 0.0, -1.0, -2.0); + sobel_kernely[2] = vec3( 1.0, -1.0, -1.0); + sobel_kernely[3] = vec3(-1.0, 1.0, 1.0); + sobel_kernely[4] = vec3( 0.0, 1.0, 2.0); + sobel_kernely[5] = vec3( 1.0, 1.0, 1.0); + + vec2 d = vec2(0.0); + for (int i = 0; i < sobel_kernel_length; i++) { - d.x += gaussian_blur(jokers_sampler, texture_coords + ivec2(sobel_kernelx[i].xy)) * sobel_kernelx[i].z; - d.y += gaussian_blur(jokers_sampler, texture_coords + ivec2(sobel_kernely[i].xy)) * sobel_kernely[i].z; + // [Fix]: extract xy as float, then cast to ivec2 for texture offset + ivec2 offset_x = ivec2(sobel_kernelx[i].xy); + d.x += gaussian_blur(jokers_sampler, texture_coords + offset_x) * sobel_kernelx[i].z; + + ivec2 offset_y = ivec2(sobel_kernely[i].xy); + d.y += gaussian_blur(jokers_sampler, texture_coords + offset_y) * sobel_kernely[i].z; } return d; } @@ -82,11 +118,14 @@ vec2 sobel_filter(Image jokers_sampler, ivec2 texture_coords) { float canny_edges(Image jokers_sampler, ivec2 texture_coords) { vec2 d = sobel_filter(jokers_sampler, texture_coords); float g = length(d); - float t = atan(d.y / d.x); + + // [Fix]: Use atan(y, x) to avoid division by zero and handle quadrants correctly + float t = atan(d.y, d.x); // determine where to sample from the direction of the gradient ivec2 offset1; ivec2 offset2; + if (t < -0.375 * pi) { offset1 = ivec2(0, -1); offset2 = ivec2(0, 1); @@ -96,8 +135,7 @@ float canny_edges(Image jokers_sampler, ivec2 texture_coords) { } else if (t < 0.125 * pi) { offset1 = ivec2(-1, 0); offset2 = ivec2(1, 0); - } - else if (t < 0.375 * pi) { + } else if (t < 0.375 * pi) { offset1 = ivec2(-1, -1); offset2 = ivec2(1, 1); } else { @@ -115,22 +153,20 @@ float canny_edges(Image jokers_sampler, ivec2 texture_coords) { } } -float hash12(vec2 p) -{ - vec3 p3 = fract(vec3(p.xyx) * .1031); +float hash12(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * 0.1031); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.x + p3.y) * p3.z); } - vec4 mapcol(float v, ivec2 coords) { + // [Fix]: Cast ivec2 to vec2 for hash function if (v > blue_threshold) { - return mix(blue_low, blue_high, hash12(coords)); - } - else if (v > red_threshold) { - return mix(red_low, red_high, hash12(coords)); + return mix(blue_low, blue_high, hash12(vec2(coords))); + } else if (v > red_threshold) { + return mix(red_low, red_high, hash12(vec2(coords))); } else { - return vec4(0, 0, 0, 0); + return vec4(0.0, 0.0, 0.0, 0.0); } } @@ -148,27 +184,38 @@ vec4 mapcol(float v, ivec2 coords) { // return false; // } -vec4 effect( vec4 colour, Image jokers_sampler, vec2 texture_coords, vec2 screen_coords ) -{ +vec4 effect(vec4 colour, Image jokers_sampler, vec2 texture_coords, vec2 screen_coords) { + // float col = greyscale(texture(jokers_sampler, texture_coords)); - - ivec2 absolute_texture_coords = ivec2(texture_coords * texture_size); + // [Fix]: explicit cast to ivec2 + ivec2 absolute_texture_coords = ivec2(texture_coords * texture_size); // float col = gaussian_blur(jokers_sampler, absolute_texture_coords); // vec2 d = sobel_filter(jokers_sampler, absolute_texture_coords); + float canny = canny_edges(jokers_sampler, absolute_texture_coords); // if (floating && is_floating_edge(jokers_sampler, absolute_texture_coords)) { // canny = 100.0; // } - vec4 cannycol = mapcol(canny, absolute_texture_coords); - if (mod(absolute_texture_coords.x, card_size.x) < margin.x || mod(absolute_texture_coords.x, card_size.x) >= card_size.x - margin.x) { - cannycol = vec4(0, 0, 0, 0); + + // [Fix]: Convert all ints to floats for mod() compatibility + float abs_x = float(absolute_texture_coords.x); + float card_x = float(card_size.x); + float margin_x = float(margin.x); + + // [Fix]: Use float mod + if (mod(abs_x, card_x) < margin_x || mod(abs_x, card_x) >= card_x - margin_x) { + cannycol = vec4(0.0); } - if (mod(absolute_texture_coords.y, card_size.y) < margin.y || mod(absolute_texture_coords.y, card_size.y) >= card_size.y - margin.y) { - cannycol = vec4(0, 0, 0, 0); + + float abs_y = float(absolute_texture_coords.y); + float card_y = float(card_size.y); + float margin_y = float(margin.y); + + if (mod(abs_y, card_y) < margin_y || mod(abs_y, card_y) >= card_y - margin_y) { + cannycol = vec4(0.0); } - // if (floating) { return cannycol; // return vec4(cannycol.rgb, min(cannycol.a, myTexelFetch(jokers_sampler, absolute_texture_coords, 0).a)); // } else { @@ -176,4 +223,4 @@ vec4 effect( vec4 colour, Image jokers_sampler, vec2 texture_coords, vec2 screen // } // return texelFetch(jokers_sampler, absolute_texture_coords, 0); // return texture(jokers_sampler, texture_coords); -} +} \ No newline at end of file diff --git a/smods.lua b/smods.lua index 88da59c..251910e 100644 --- a/smods.lua +++ b/smods.lua @@ -34,7 +34,7 @@ SMODS.current_mod.config_tab = function() return {n = G.UIT.ROOT, config = {r = 0.1, align = "cm", padding = 0.1, colour = G.C.BLACK, minw = 8, minh = 6}, nodes = { {n = G.UIT.R, config = {align = "cl", padding = 0}, nodes = { {n = G.UIT.C, config = { align = "c", padding = 0 }, nodes = { - { n = G.UIT.T, config = { text = "Brainstorm", scale = 0.35, colour = G.C.UI.TEXT_LIGHT }}, + { n = G.UIT.T, config = { text = localize("brainstorm_config"), scale = 0.35, colour = G.C.UI.TEXT_LIGHT }}, }}, {n = G.UIT.C, config = { align = "cl", padding = 0.05 }, nodes = { create_toggle{ col = true, label = "", scale = 0.85, w = 0, shadow = true, ref_table = Blueprint.SETTINGS, ref_value = 'brainstorm' }, @@ -42,7 +42,7 @@ SMODS.current_mod.config_tab = function() }}, {n = G.UIT.R, config = {align = "cl", padding = 0}, nodes = { {n = G.UIT.C, config = { align = "c", padding = 0 }, nodes = { - { n = G.UIT.T, config = { text = "Blueprint", scale = 0.35, colour = G.C.UI.TEXT_LIGHT }}, + { n = G.UIT.T, config = { text = localize("blueprint_config"), scale = 0.35, colour = G.C.UI.TEXT_LIGHT }}, }}, {n = G.UIT.C, config = { align = "cl", padding = 0.05 }, nodes = { create_toggle{ col = true, label = "", scale = 0.85, w = 0, shadow = true, ref_table = Blueprint.SETTINGS, ref_value = 'blueprint' }, From d6bde326be2909c814a032532c9234b89f42410a Mon Sep 17 00:00:00 2001 From: mleaf233 Date: Fri, 26 Dec 2025 23:13:16 +0800 Subject: [PATCH 2/3] Localization Support for Simplified Chinese (zh_CN) --- localization/zh_CN.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 localization/zh_CN.lua diff --git a/localization/zh_CN.lua b/localization/zh_CN.lua new file mode 100644 index 0000000..db59963 --- /dev/null +++ b/localization/zh_CN.lua @@ -0,0 +1,12 @@ +return { + translator = { + "mleaf233" + }, + misc = { + dictionary = { + blueprint_config = "动态 蓝图", + testtesttest = "hi hello hi", + brainstorm_config = "动态 头脑风暴" + } + } +} From 05ecc8f2302ecad1c5e4a457a892e43600e4bc0a Mon Sep 17 00:00:00 2001 From: mleaf233 Date: Fri, 26 Dec 2025 23:21:35 +0800 Subject: [PATCH 3/3] fill in the missing keys --- localization/en-us.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/localization/en-us.lua b/localization/en-us.lua index 1a80e9d..ca7fdc5 100644 --- a/localization/en-us.lua +++ b/localization/en-us.lua @@ -1,7 +1,9 @@ return { - misc = { - dictionary = { - testtesttest = "hi hello hi", - } + misc = { + dictionary = { + testtesttest = "hi hello hi", + blueprint_config = "Blueprint", + brainstorm_config = "Brainstorm", } + } } \ No newline at end of file