2022-05-13 05:57:15 -07:00
|
|
|
local modname = "texgen"
|
|
|
|
local modpath = minetest.get_modpath(modname)
|
|
|
|
|
2022-05-13 09:29:40 -07:00
|
|
|
-- Rewrite mod.conf on startup; register_on_mods_loaded does not work
|
2022-05-13 09:25:28 -07:00
|
|
|
do
|
|
|
|
local conf = Settings(modpath .. "/mod.conf")
|
|
|
|
conf:set("name", modname)
|
|
|
|
conf:set("description", "Dynamically generated texture packs")
|
|
|
|
conf:set("depends", "modlib")
|
|
|
|
local to_depend = {}
|
|
|
|
local to_dep_list = {}
|
|
|
|
for _, modname in pairs(minetest.get_modnames()) do to_depend[modname] = true end -- luacheck: ignore
|
|
|
|
local opt_dep_str = conf:get"optional_depends" or ""
|
|
|
|
for opt_depend in opt_dep_str:gmatch"[^%s,]+" do
|
|
|
|
table.insert(to_dep_list, opt_depend)
|
|
|
|
to_depend[opt_depend] = nil
|
|
|
|
end
|
|
|
|
to_depend.texgen = nil -- no circular dependency
|
|
|
|
to_depend.modlib = nil -- modlib is already a hard dependency
|
|
|
|
if next(to_depend) or not modlib then
|
|
|
|
for dep in pairs(to_depend) do table.insert(to_dep_list, dep) end
|
|
|
|
conf:set("optional_depends", table.concat(to_dep_list, ", "))
|
|
|
|
conf:write()
|
|
|
|
error"mod.conf updated to optionally depend on all enabled mods, please restart the game"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-06-08 02:22:52 -07:00
|
|
|
assert(modlib.version >= 96, "update modlib to version rolling-96 or newer")
|
2022-05-13 05:57:15 -07:00
|
|
|
|
|
|
|
local texture_path = modpath .. "/textures/"
|
|
|
|
if minetest.rmdir then
|
|
|
|
-- Clear texture directory on startup
|
|
|
|
minetest.rmdir(texture_path, true)
|
|
|
|
end
|
|
|
|
minetest.mkdir(texture_path)
|
|
|
|
|
2022-05-13 09:29:40 -07:00
|
|
|
local media = modlib.minetest.media
|
|
|
|
|
2022-05-13 05:57:15 -07:00
|
|
|
local function get_path(filename)
|
|
|
|
local path
|
2022-05-13 09:29:40 -07:00
|
|
|
local mod = media.mods[filename]
|
2022-05-13 05:57:15 -07:00
|
|
|
if mod == modname then -- media overridden by this mod
|
2022-05-13 09:29:40 -07:00
|
|
|
local overridden_paths = media.overridden_paths[filename]
|
2022-05-13 05:57:15 -07:00
|
|
|
if not overridden_paths then return end
|
|
|
|
path = overridden_paths[#overridden_paths]
|
|
|
|
else
|
2022-05-13 09:29:40 -07:00
|
|
|
path = media.paths[filename]
|
2022-05-13 05:57:15 -07:00
|
|
|
end
|
|
|
|
return path
|
|
|
|
end
|
|
|
|
|
|
|
|
texgen = {} -- HACK only use the mod namespace to expose the dithering methods to the schema...
|
2022-06-08 02:22:52 -07:00
|
|
|
|
2022-05-13 05:57:15 -07:00
|
|
|
local dithering = modlib.mod.include"dithering.lua" -- sets texgen.dithering_methods
|
2022-06-08 02:22:52 -07:00
|
|
|
|
|
|
|
local conf, schema = modlib.mod.configuration()
|
|
|
|
|
|
|
|
-- Register palette downloading command if HTTP API is available; this reloads the schema
|
|
|
|
local insecure_env, http = minetest.request_insecure_environment(), minetest.request_http_api()
|
|
|
|
if insecure_env and http then
|
|
|
|
assert(loadfile(modlib.mod.get_resource"download_palette.lua"))(insecure_env, http, schema)
|
|
|
|
end
|
|
|
|
|
2022-05-13 05:57:15 -07:00
|
|
|
texgen = nil -- ...delete it afterwards
|
|
|
|
|
|
|
|
local palette, dither
|
|
|
|
if conf.palette.name then
|
|
|
|
palette = modlib.mod.include"palette.lua"(conf.palette.name)
|
|
|
|
dither = dithering(conf.palette.dithering)
|
|
|
|
end
|
|
|
|
local saturate, monochrome, invert = conf.saturate, conf.monochrome, conf.invert
|
|
|
|
local average
|
|
|
|
if conf.average then
|
|
|
|
average = modlib.mod.include"average_color.lua"
|
|
|
|
end
|
|
|
|
|
|
|
|
local function read_convert_png(path)
|
|
|
|
local file = assert(io.open(path, "rb"))
|
|
|
|
local png = modlib.minetest.decode_png(file)
|
|
|
|
assert(not file:read(1), "EOF expected")
|
|
|
|
file:close()
|
|
|
|
modlib.minetest.convert_png_to_argb8(png)
|
|
|
|
return png
|
|
|
|
end
|
|
|
|
|
|
|
|
local clamp = modlib.math.clamp
|
|
|
|
local function transform_png(filename, path)
|
|
|
|
local png = read_convert_png(path)
|
|
|
|
if palette then
|
|
|
|
dither(png, palette)
|
|
|
|
end
|
|
|
|
modlib.table.map(png.data, function(color_num)
|
|
|
|
local color = modlib.minetest.colorspec.from_number(color_num)
|
|
|
|
if saturate ~= 1 then
|
|
|
|
-- See https://alienryderflex.com/saturation.html
|
|
|
|
local P = math.sqrt(0.299 * color.r^2 + 0.587 * color.g^2 + 0.114 * color.b^2)
|
|
|
|
local res = modlib.vector.apply({
|
|
|
|
r = clamp((color.r - P) * saturate + P + 0.5, 0, 255),
|
|
|
|
g = clamp((color.g - P) * saturate + P + 0.5, 0, 255),
|
|
|
|
b = clamp((color.b - P) * saturate + P + 0.5, 0, 255),
|
|
|
|
}, math.floor)
|
|
|
|
color.r, color.g, color.b = res.r, res.g, res.b
|
|
|
|
end
|
|
|
|
if invert then
|
|
|
|
color.r, color.g, color.b = 255 - color.r, 255 - color.g, 255 - color.b
|
|
|
|
end
|
|
|
|
if monochrome then
|
|
|
|
local brightness = math.floor(0.299 * color.r + 0.587 * color.g + 0.114 * color.b + 0.5)
|
|
|
|
color.r, color.g, color.b = brightness, brightness, brightness
|
|
|
|
end
|
|
|
|
return color:to_number()
|
|
|
|
end)
|
|
|
|
local width, height, data = png.width, png.height, png.data
|
|
|
|
if average then
|
|
|
|
width, height, data = 1, 1, {average(png):to_number()}
|
|
|
|
end
|
|
|
|
modlib.file.write(modlib.file.concat_path{modpath, "textures", filename},
|
|
|
|
modlib.minetest.encode_png(width, height, data))
|
|
|
|
end
|
|
|
|
|
2022-05-13 09:29:40 -07:00
|
|
|
for filename in pairs(media.paths) do
|
2022-05-13 09:25:28 -07:00
|
|
|
local _, ext = modlib.file.get_extension(filename)
|
|
|
|
if ext == "png" then
|
|
|
|
local path = get_path(filename)
|
|
|
|
-- May be (only) overridden media from this mod, which does not have a path (as it was deleted)
|
|
|
|
if path then transform_png(filename, path) end
|
2022-05-13 05:57:15 -07:00
|
|
|
end
|
2022-05-13 09:25:28 -07:00
|
|
|
end
|
|
|
|
-- Builtin textures aren't provided by mods and are thus unknown to modlib; provide them through this mod
|
|
|
|
for _, filename in ipairs(minetest.get_dir_list(modlib.file.concat_path{modpath, "builtin"}, false)) do
|
|
|
|
-- Don't override builtin overrides by other mods
|
2022-05-13 09:29:40 -07:00
|
|
|
if filename:match"%.png$" and not (media.paths[filename] and media.overridden_paths[filename]) then
|
2022-05-13 09:25:28 -07:00
|
|
|
transform_png(filename, modlib.file.concat_path{modpath, "builtin", filename})
|
2022-05-13 05:57:15 -07:00
|
|
|
end
|
2022-05-13 09:25:28 -07:00
|
|
|
end
|