commit 3bc0bb9e89906ec1905768db8bb43726af000e85 Author: Lars Mueller Date: Fri May 13 14:57:15 2022 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3817fe9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +textures \ No newline at end of file diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..d1d304d --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,2 @@ +globals = {"texgen"} +read_globals = {"minetest", "modlib", "Settings"} diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..9119e0f --- /dev/null +++ b/Readme.md @@ -0,0 +1,111 @@ +# Texture Generator (`texgen`) + +Dynamically generates a texture pack for your current game in the `textures` directory. + +## Features + +* Compatible with virtually all mods and games +* Easy texture pack generation, no complex installation +* Server-side (mod-based) texture pack; textures can be accessed by other mods + +## Instructions + +Just fire up the mod and configure it to your liking. It might throw an error message as it updates its `mod.conf` to depend on all enabled mods. Simply retry after that. + +### Downloading palettes + +You can use the `/download_palette ` chatcommand to download a PNG palette file, for example `/download_palette https://lospec.com/palette-list/zughy-32-1x.png`. + +See `/help download_palette` for details on its usage. + +Requires the `server` priv. Only available if `texgen` is added to `secure.http_mods`. + +**WARNING: Enabling this feature poses a minor security risk.** + +## Configuration + + +### `average` + +Replace each texture with a single pixel of its weighted average RGB color + +* Type: boolean +* Default: `false` + +### `invert` + +Invert the RGB colors + +* Type: boolean +* Default: `false` + +### `monochrome` + +Convert RGB to monochrome (greyscale) + +* Type: boolean +* Default: `false` + +### `palette` + +#### `dithering` + +Dithering method to use + +* Type: string +* Default: `floyd_steinberg` +* Possible values: + * sierra + * stucke + * sierra_lite + * jarvis_judice_ninke + * floyd_steinberg + * none + * two_row_sierra + * burkes + * atkinson + +#### `name` + +Name of the palette to use (without extension) + +* Type: string +* Default: `apollo` +* Possible values: + * soggy-newspapers + * apollo + * zughy-32 + * aap-64 + * pico-8 + * resurrect-64 + + +### `saturate` + +Increase or decrease saturation by a factor + +* Type: number +* Default: `1` +* >= `0.1` +* <= `10` + + +## Links + +* [GitHub](https://github.com/appgurueu/texgen) - sources, issue tracking, contributing +* [Discord](https://discord.gg/ysP74by) - discussion, chatting +* [Minetest Forum](https://forum.minetest.net/viewtopic.php?f=9&t=28115) - (more organized) discussion +* [ContentDB](https://content.minetest.net/packages/LMD/texgen) - releases (downloading from GitHub is recommended) + +## License + +Code written by Lars Müller (appgurueu) and licensed under the MIT license; builtin Minetest media licensed under various free Creative Commons licenses as well as the Apache 2 license (see `LICENSE.txt` in the `builtin` folder for details and attribution). + +The palettes are (for copyright reasons shuffled) versions of palettes available on [Lospec](https://lospec.com/): + +* Adigun A. Polack's "AAP-64" +* AdamCYounis' "Apollo" +* Lexaloffle Games' "PICO-8" +* Kerrie Lake's "Resurrect 64" +* Walking's "Soggy Newspapers" +* Zughy's "Zughy 32" diff --git a/average_color.lua b/average_color.lua new file mode 100644 index 0000000..dfb0a65 --- /dev/null +++ b/average_color.lua @@ -0,0 +1,18 @@ +-- Average color, weighted by alpha and calculated in linear RGB colorspace +return function(png) + -- TODO make colorspecs extend vectors + local avg_color = modlib.vector.new{r = 0, g = 0, b = 0} + local total_alpha = 0 + for _, color in ipairs(png.data) do + color = modlib.minetest.colorspec.from_number(color) + -- Squared average + avg_color = modlib.vector.add(avg_color, modlib.vector.multiply_scalar( + modlib.vector.pow_scalar({r = color.r, g = color.g, b = color.b}, 2), color.a)) + total_alpha = total_alpha + color.a + end + if total_alpha == 0 then total_alpha = 1 end -- Avoid division by zero + -- Round & convert back to colorspec + avg_color = modlib.minetest.colorspec.new(avg_color:divide_scalar(total_alpha) + :apply(math.sqrt):add_scalar(0.5):floor()) + return avg_color +end diff --git a/builtin/LICENSE.txt b/builtin/LICENSE.txt new file mode 100644 index 0000000..ab44488 --- /dev/null +++ b/builtin/LICENSE.txt @@ -0,0 +1,197 @@ + +License of Minetest textures and sounds +--------------------------------------- + +This applies to textures and sounds contained in the main Minetest +distribution. + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +http://creativecommons.org/licenses/by-sa/3.0/ + +textures/base/pack/refresh.png is under the Apache 2 license +https://www.apache.org/licenses/LICENSE-2.0.html + +Textures by Zughy are under CC BY-SA 4.0 +https://creativecommons.org/licenses/by-sa/4.0/ + +textures/base/pack/server_public.png is under CC-BY 4.0, taken from Twitter's Twemoji set +https://creativecommons.org/licenses/by/4.0/ + +Authors of media files +----------------------- +Everything not listed in here: +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +ShadowNinja: + textures/base/pack/smoke_puff.png + +paramat: + textures/base/pack/menu_header.png + textures/base/pack/next_icon.png + textures/base/pack/prev_icon.png + textures/base/pack/clear.png + textures/base/pack/search.png + +rubenwardy, paramat: + textures/base/pack/start_icon.png + textures/base/pack/end_icon.png + +erlehmann: + misc/minetest-icon-24x24.png + misc/minetest-icon.ico + misc/minetest.svg + textures/base/pack/logo.png + +JRottm: + textures/base/pack/player_marker.png + +srifqi: + textures/base/pack/chat_hide_btn.png + textures/base/pack/chat_show_btn.png + textures/base/pack/joystick_bg.png + textures/base/pack/joystick_center.png + textures/base/pack/joystick_off.png + textures/base/pack/minimap_btn.png + +Zughy: + textures/base/pack/cdb_add.png + textures/base/pack/cdb_clear.png + textures/base/pack/cdb_downloading.png + textures/base/pack/cdb_queued.png + textures/base/pack/cdb_update.png + textures/base/pack/cdb_viewonline.png + +appgurueu: + textures/base/pack/server_incompatible.png + +License of Minetest source code +------------------------------- + +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Irrlicht +--------------- + +This program uses IrrlichtMt, Minetest's fork of +the Irrlicht Engine. http://irrlicht.sourceforge.net/ + + The Irrlicht Engine License + +Copyright © 2002-2005 Nikolaus Gebhardt + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute +it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you use + this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source + distribution. + + +JThread +--------------- + +This program uses the JThread library. License for JThread follows: + +Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + +Lua +--------------- + +Lua is licensed under the terms of the MIT license reproduced below. +This means that Lua is free software and can be used for both academic +and commercial purposes at absolutely no cost. + +For details and rationale, see https://www.lua.org/license.html . + +Copyright (C) 1994-2008 Lua.org, PUC-Rio. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Fonts +--------------- + +Bitstream Vera Fonts Copyright: + + Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is + a trademark of Bitstream, Inc. + +Arimo - Apache License, version 2.0 + Digitized data copyright (c) 2010-2012 Google Corporation. + +Cousine - Apache License, version 2.0 + Digitized data copyright (c) 2010-2012 Google Corporation. + +DroidSansFallBackFull: + + Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/builtin/air.png b/builtin/air.png new file mode 100644 index 0000000..e2c4872 Binary files /dev/null and b/builtin/air.png differ diff --git a/builtin/aux1_btn.png b/builtin/aux1_btn.png new file mode 100644 index 0000000..8ceb095 Binary files /dev/null and b/builtin/aux1_btn.png differ diff --git a/builtin/blank.png b/builtin/blank.png new file mode 100644 index 0000000..85e0250 Binary files /dev/null and b/builtin/blank.png differ diff --git a/builtin/bubble.png b/builtin/bubble.png new file mode 100644 index 0000000..799327c Binary files /dev/null and b/builtin/bubble.png differ diff --git a/builtin/bubble_gone.png b/builtin/bubble_gone.png new file mode 100644 index 0000000..240ca4f Binary files /dev/null and b/builtin/bubble_gone.png differ diff --git a/builtin/camera_btn.png b/builtin/camera_btn.png new file mode 100644 index 0000000..9327dc4 Binary files /dev/null and b/builtin/camera_btn.png differ diff --git a/builtin/cdb_add.png b/builtin/cdb_add.png new file mode 100644 index 0000000..3e3d067 Binary files /dev/null and b/builtin/cdb_add.png differ diff --git a/builtin/cdb_clear.png b/builtin/cdb_clear.png new file mode 100644 index 0000000..4490d41 Binary files /dev/null and b/builtin/cdb_clear.png differ diff --git a/builtin/cdb_downloading.png b/builtin/cdb_downloading.png new file mode 100644 index 0000000..8cba383 Binary files /dev/null and b/builtin/cdb_downloading.png differ diff --git a/builtin/cdb_queued.png b/builtin/cdb_queued.png new file mode 100644 index 0000000..6972f7f Binary files /dev/null and b/builtin/cdb_queued.png differ diff --git a/builtin/cdb_update.png b/builtin/cdb_update.png new file mode 100644 index 0000000..262e42d Binary files /dev/null and b/builtin/cdb_update.png differ diff --git a/builtin/cdb_viewonline.png b/builtin/cdb_viewonline.png new file mode 100644 index 0000000..ae2a146 Binary files /dev/null and b/builtin/cdb_viewonline.png differ diff --git a/builtin/chat_btn.png b/builtin/chat_btn.png new file mode 100644 index 0000000..be4477d Binary files /dev/null and b/builtin/chat_btn.png differ diff --git a/builtin/chat_hide_btn.png b/builtin/chat_hide_btn.png new file mode 100644 index 0000000..92a8ece Binary files /dev/null and b/builtin/chat_hide_btn.png differ diff --git a/builtin/chat_show_btn.png b/builtin/chat_show_btn.png new file mode 100644 index 0000000..b260d25 Binary files /dev/null and b/builtin/chat_show_btn.png differ diff --git a/builtin/checkbox_16.png b/builtin/checkbox_16.png new file mode 100644 index 0000000..db6101f Binary files /dev/null and b/builtin/checkbox_16.png differ diff --git a/builtin/checkbox_32.png b/builtin/checkbox_32.png new file mode 100644 index 0000000..f5ff59a Binary files /dev/null and b/builtin/checkbox_32.png differ diff --git a/builtin/checkbox_64.png b/builtin/checkbox_64.png new file mode 100644 index 0000000..03eb90b Binary files /dev/null and b/builtin/checkbox_64.png differ diff --git a/builtin/clear.png b/builtin/clear.png new file mode 100644 index 0000000..9244264 Binary files /dev/null and b/builtin/clear.png differ diff --git a/builtin/crack_anylength.png b/builtin/crack_anylength.png new file mode 100644 index 0000000..d9b49f9 Binary files /dev/null and b/builtin/crack_anylength.png differ diff --git a/builtin/debug_btn.png b/builtin/debug_btn.png new file mode 100644 index 0000000..ab210a6 Binary files /dev/null and b/builtin/debug_btn.png differ diff --git a/builtin/down.png b/builtin/down.png new file mode 100644 index 0000000..c290d3a Binary files /dev/null and b/builtin/down.png differ diff --git a/builtin/drop_btn.png b/builtin/drop_btn.png new file mode 100644 index 0000000..4403ce6 Binary files /dev/null and b/builtin/drop_btn.png differ diff --git a/builtin/end_icon.png b/builtin/end_icon.png new file mode 100644 index 0000000..4fb4d52 Binary files /dev/null and b/builtin/end_icon.png differ diff --git a/builtin/error_screenshot.png b/builtin/error_screenshot.png new file mode 100644 index 0000000..e35a0a3 Binary files /dev/null and b/builtin/error_screenshot.png differ diff --git a/builtin/fast_btn.png b/builtin/fast_btn.png new file mode 100644 index 0000000..aeb4d3c Binary files /dev/null and b/builtin/fast_btn.png differ diff --git a/builtin/fly_btn.png b/builtin/fly_btn.png new file mode 100644 index 0000000..641d0fa Binary files /dev/null and b/builtin/fly_btn.png differ diff --git a/builtin/gear_icon.png b/builtin/gear_icon.png new file mode 100644 index 0000000..520e82e Binary files /dev/null and b/builtin/gear_icon.png differ diff --git a/builtin/halo.png b/builtin/halo.png new file mode 100644 index 0000000..ed3ff9d Binary files /dev/null and b/builtin/halo.png differ diff --git a/builtin/heart.png b/builtin/heart.png new file mode 100644 index 0000000..13db59b Binary files /dev/null and b/builtin/heart.png differ diff --git a/builtin/heart_gone.png b/builtin/heart_gone.png new file mode 100644 index 0000000..240ca4f Binary files /dev/null and b/builtin/heart_gone.png differ diff --git a/builtin/ignore.png b/builtin/ignore.png new file mode 100644 index 0000000..a73d222 Binary files /dev/null and b/builtin/ignore.png differ diff --git a/builtin/inventory_btn.png b/builtin/inventory_btn.png new file mode 100644 index 0000000..278ce39 Binary files /dev/null and b/builtin/inventory_btn.png differ diff --git a/builtin/joystick_bg.png b/builtin/joystick_bg.png new file mode 100644 index 0000000..4061939 Binary files /dev/null and b/builtin/joystick_bg.png differ diff --git a/builtin/joystick_center.png b/builtin/joystick_center.png new file mode 100644 index 0000000..1e4754d Binary files /dev/null and b/builtin/joystick_center.png differ diff --git a/builtin/joystick_off.png b/builtin/joystick_off.png new file mode 100644 index 0000000..6dfbc7a Binary files /dev/null and b/builtin/joystick_off.png differ diff --git a/builtin/jump_btn.png b/builtin/jump_btn.png new file mode 100644 index 0000000..d21b4a9 Binary files /dev/null and b/builtin/jump_btn.png differ diff --git a/builtin/loading_screenshot.png b/builtin/loading_screenshot.png new file mode 100644 index 0000000..4d65a5d Binary files /dev/null and b/builtin/loading_screenshot.png differ diff --git a/builtin/logo.png b/builtin/logo.png new file mode 100644 index 0000000..4879367 Binary files /dev/null and b/builtin/logo.png differ diff --git a/builtin/menu_bg.png b/builtin/menu_bg.png new file mode 100644 index 0000000..ed7e34f Binary files /dev/null and b/builtin/menu_bg.png differ diff --git a/builtin/menu_header.png b/builtin/menu_header.png new file mode 100644 index 0000000..0769a01 Binary files /dev/null and b/builtin/menu_header.png differ diff --git a/builtin/minimap_btn.png b/builtin/minimap_btn.png new file mode 100644 index 0000000..727ba1e Binary files /dev/null and b/builtin/minimap_btn.png differ diff --git a/builtin/minimap_mask_round.png b/builtin/minimap_mask_round.png new file mode 100644 index 0000000..a0c6b2d Binary files /dev/null and b/builtin/minimap_mask_round.png differ diff --git a/builtin/minimap_mask_square.png b/builtin/minimap_mask_square.png new file mode 100644 index 0000000..160b6fa Binary files /dev/null and b/builtin/minimap_mask_square.png differ diff --git a/builtin/minimap_overlay_round.png b/builtin/minimap_overlay_round.png new file mode 100644 index 0000000..16e3c41 Binary files /dev/null and b/builtin/minimap_overlay_round.png differ diff --git a/builtin/minimap_overlay_square.png b/builtin/minimap_overlay_square.png new file mode 100644 index 0000000..c971c4b Binary files /dev/null and b/builtin/minimap_overlay_square.png differ diff --git a/builtin/next_icon.png b/builtin/next_icon.png new file mode 100644 index 0000000..03f9609 Binary files /dev/null and b/builtin/next_icon.png differ diff --git a/builtin/no_screenshot.png b/builtin/no_screenshot.png new file mode 100644 index 0000000..8c70898 Binary files /dev/null and b/builtin/no_screenshot.png differ diff --git a/builtin/no_texture.png b/builtin/no_texture.png new file mode 100644 index 0000000..681b810 Binary files /dev/null and b/builtin/no_texture.png differ diff --git a/builtin/no_texture_airlike.png b/builtin/no_texture_airlike.png new file mode 100644 index 0000000..634ee8c Binary files /dev/null and b/builtin/no_texture_airlike.png differ diff --git a/builtin/noclip_btn.png b/builtin/noclip_btn.png new file mode 100644 index 0000000..5d7372d Binary files /dev/null and b/builtin/noclip_btn.png differ diff --git a/builtin/object_marker_red.png b/builtin/object_marker_red.png new file mode 100644 index 0000000..f345d03 Binary files /dev/null and b/builtin/object_marker_red.png differ diff --git a/builtin/player.png b/builtin/player.png new file mode 100644 index 0000000..6d61c43 Binary files /dev/null and b/builtin/player.png differ diff --git a/builtin/player_back.png b/builtin/player_back.png new file mode 100644 index 0000000..5e9ef05 Binary files /dev/null and b/builtin/player_back.png differ diff --git a/builtin/player_marker.png b/builtin/player_marker.png new file mode 100644 index 0000000..f2cc2c6 Binary files /dev/null and b/builtin/player_marker.png differ diff --git a/builtin/plus.png b/builtin/plus.png new file mode 100644 index 0000000..64680b5 Binary files /dev/null and b/builtin/plus.png differ diff --git a/builtin/prev_icon.png b/builtin/prev_icon.png new file mode 100644 index 0000000..71509e7 Binary files /dev/null and b/builtin/prev_icon.png differ diff --git a/builtin/progress_bar.png b/builtin/progress_bar.png new file mode 100644 index 0000000..e803671 Binary files /dev/null and b/builtin/progress_bar.png differ diff --git a/builtin/progress_bar_bg.png b/builtin/progress_bar_bg.png new file mode 100644 index 0000000..4e30ae8 Binary files /dev/null and b/builtin/progress_bar_bg.png differ diff --git a/builtin/rangeview_btn.png b/builtin/rangeview_btn.png new file mode 100644 index 0000000..e49a1b6 Binary files /dev/null and b/builtin/rangeview_btn.png differ diff --git a/builtin/rare_controls.png b/builtin/rare_controls.png new file mode 100644 index 0000000..953d9e0 Binary files /dev/null and b/builtin/rare_controls.png differ diff --git a/builtin/refresh.png b/builtin/refresh.png new file mode 100644 index 0000000..7193677 Binary files /dev/null and b/builtin/refresh.png differ diff --git a/builtin/search.png b/builtin/search.png new file mode 100644 index 0000000..aace804 Binary files /dev/null and b/builtin/search.png differ diff --git a/builtin/server_favorite.png b/builtin/server_favorite.png new file mode 100644 index 0000000..6a3fc5e Binary files /dev/null and b/builtin/server_favorite.png differ diff --git a/builtin/server_flags_creative.png b/builtin/server_flags_creative.png new file mode 100644 index 0000000..fa37a19 Binary files /dev/null and b/builtin/server_flags_creative.png differ diff --git a/builtin/server_flags_damage.png b/builtin/server_flags_damage.png new file mode 100644 index 0000000..3f0bf0d Binary files /dev/null and b/builtin/server_flags_damage.png differ diff --git a/builtin/server_flags_pvp.png b/builtin/server_flags_pvp.png new file mode 100644 index 0000000..977dfdc Binary files /dev/null and b/builtin/server_flags_pvp.png differ diff --git a/builtin/server_incompatible.png b/builtin/server_incompatible.png new file mode 100644 index 0000000..9076ab5 Binary files /dev/null and b/builtin/server_incompatible.png differ diff --git a/builtin/server_ping_1.png b/builtin/server_ping_1.png new file mode 100644 index 0000000..ba5bba1 Binary files /dev/null and b/builtin/server_ping_1.png differ diff --git a/builtin/server_ping_2.png b/builtin/server_ping_2.png new file mode 100644 index 0000000..8dca0be Binary files /dev/null and b/builtin/server_ping_2.png differ diff --git a/builtin/server_ping_3.png b/builtin/server_ping_3.png new file mode 100644 index 0000000..c2cab01 Binary files /dev/null and b/builtin/server_ping_3.png differ diff --git a/builtin/server_ping_4.png b/builtin/server_ping_4.png new file mode 100644 index 0000000..03b4b5b Binary files /dev/null and b/builtin/server_ping_4.png differ diff --git a/builtin/server_public.png b/builtin/server_public.png new file mode 100644 index 0000000..46a48fa Binary files /dev/null and b/builtin/server_public.png differ diff --git a/builtin/smoke_puff.png b/builtin/smoke_puff.png new file mode 100644 index 0000000..488b50f Binary files /dev/null and b/builtin/smoke_puff.png differ diff --git a/builtin/start_icon.png b/builtin/start_icon.png new file mode 100644 index 0000000..3830fb3 Binary files /dev/null and b/builtin/start_icon.png differ diff --git a/builtin/sunrisebg.png b/builtin/sunrisebg.png new file mode 100644 index 0000000..3352317 Binary files /dev/null and b/builtin/sunrisebg.png differ diff --git a/builtin/unknown_item.png b/builtin/unknown_item.png new file mode 100644 index 0000000..c8cf616 Binary files /dev/null and b/builtin/unknown_item.png differ diff --git a/builtin/unknown_node.png b/builtin/unknown_node.png new file mode 100644 index 0000000..cb59ff4 Binary files /dev/null and b/builtin/unknown_node.png differ diff --git a/builtin/unknown_object.png b/builtin/unknown_object.png new file mode 100644 index 0000000..c0166c3 Binary files /dev/null and b/builtin/unknown_object.png differ diff --git a/builtin/wieldhand.png b/builtin/wieldhand.png new file mode 100644 index 0000000..ff2283a Binary files /dev/null and b/builtin/wieldhand.png differ diff --git a/builtin/zoom.png b/builtin/zoom.png new file mode 100644 index 0000000..b27c8c8 Binary files /dev/null and b/builtin/zoom.png differ diff --git a/dithering.lua b/dithering.lua new file mode 100644 index 0000000..a9a5004 --- /dev/null +++ b/dithering.lua @@ -0,0 +1,102 @@ +-- Simple error diffusion dithering +-- TODO use HSV/HSL for dithering closer to human perception + +local matrices = { + none = { + fraction = 0 + }, + floyd_steinberg = { + fraction = 1/16, + {x_off = 1, 7}; + {x_off = -1, 3, 5, 1}; + }, + jarvis_judice_ninke = { + fraction = 1/48, + {x_off = 1, 7, 5}; + {x_off = -2, 3, 5, 7, 5, 3}; + {x_off = -2, 1, 3, 5, 3, 1}; + }, + stucke = { + fraction = 1/42, + {x_off = 1, 8, 4}; + {x_off = -2, 2, 4, 8, 4, 2}; + {x_off = -2, 1, 2, 4, 2, 1}; + }, + atkinson = { + fraction = 1/8, + {x_off = 1, 1, 1}; + {x_off = -1, 1, 1, 1 }; + {x_off = 0, 1 }; + }, + burkes = { + fraction = 1/42, + {x_off = 1, 8, 4}; + {x_off = -2, 2, 4, 8, 4, 2}; + }, + sierra = { + fraction = 1/16, + {x_off = 1, 4, 3}; + {x_off = -2, 1, 2, 3, 2, 1}; + }, + sierra_lite = { + fraction = 1/4, + {x_off = 1, 2}, + {x_off = -1, 1, 1 }, + }, + two_row_sierra = { + fraction = 1/32, + {x_off = 1, 5, 3}, + {x_off = -2, 2, 4, 5, 4, 2}, + {x_off = -1, 2, 3, 2 }, + }, +} +texgen.dithering_methods = matrices + +local clamp = modlib.math.clamp +return function(method) + local matrix = assert(matrices[method]) + return function(png, closest_color) + local width = png.width + local diffused_errors = {} + local zero_err = {r = 0, g = 0, b = 0} + for index, color in ipairs(png.data) do + local x, y = (index - 1) % width, math.floor((index - 1) / width) + color = modlib.minetest.colorspec.from_number(color) + local diff_err = diffused_errors[index] or zero_err + diffused_errors[index] = nil + local col_err = { + r = clamp(color.r + diff_err.r, 0, 255), + g = clamp(color.g + diff_err.g, 0, 255), + b = clamp(color.b + diff_err.b, 0, 255) + } + local new_color = closest_color(col_err) + png.data[index] = modlib.minetest.colorspec.new{ + r = new_color.r, + g = new_color.g, + b = new_color.b, + a = color.a -- keep alpha + }:to_number() + -- Diffuse error + local weight = matrix.fraction * color.a / 255 + if weight > 0 then + local err = { + r = weight * (new_color.r - col_err.r), + g = weight * (new_color.g - col_err.g), + b = weight * (new_color.b - col_err.b) + } + for y_off, row in ipairs(matrix) do + local ey = y + y_off - 1 + for x_off, factor in ipairs(row) do + local ex = x + row.x_off + x_off - 1 + local idx = ey * width + ex + local derr = diffused_errors[idx] or {r = 0, g = 0, b = 0} + derr.r = derr.r + factor * err.r + derr.g = derr.g + factor * err.g + derr.b = derr.b + factor * err.b + diffused_errors[idx] = derr + end + end + end + end + end +end diff --git a/download_palette.lua b/download_palette.lua new file mode 100644 index 0000000..ee4e083 --- /dev/null +++ b/download_palette.lua @@ -0,0 +1,39 @@ +local http = ... +local palettes = modlib.mod.get_resource"palettes" +minetest.register_chatcommand("download_palette", { + params = "", + description = "Download a palette to use for generating textures", + privs = {server = true}, + func = function(name, url) + local palette_name = url:match"/([A-Za-z0-9-_]+)%.png$" + if not (url:match"^https://" and palette_name) then + return false, "URL must be a valid HTTPS URL with a filename consisting of ASCII letters, digits, hyphens and underscores and ending in a .png extension." -- luacheck: ignore + end + http.fetch({ + url = url, + method = "GET" + }, function(res) + local failure = (res.timeout and "Timeout") or (not res.succeeded and ("HTTP Status Code %d"):format(res.code)) + if failure then + minetest.chat_send_player(name, ("Downloading from URL %s failed: %s"):format(url, failure)) + return + end + local stream = modlib.text.inputstream(res.data) + local status, res_or_err = pcall(modlib.minetest.decode_png, stream) + if stream:read(1) then + status, res_or_err = false, "EOF expected" + end + if status then + -- Rewrite & store PNG + local png = res_or_err + modlib.minetest.convert_png_to_argb8(png) + modlib.table.shuffle(png.data) -- for copyright reasons + modlib.file.write(modlib.file.concat_path{palettes, palette_name .. ".png"}, + modlib.minetest.encode_png(png.width, png.height, png.data)) + minetest.chat_send_player(name, ("Palette %s added to palettes!"):format(palette_name)) + else + minetest.chat_send_player(name, ("PNG image from URL %s is invalid: %s"):format(url, res_or_err)) + end + end) + end +}) diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..c04bfdc --- /dev/null +++ b/init.lua @@ -0,0 +1,130 @@ +local modname = "texgen" +local modpath = minetest.get_modpath(modname) + +-- Rewrite mod.conf on startup +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 + +assert(modlib.version >= 94, "update modlib to version rolling-94 or newer") + +-- Register palette downloading command if HTTP API is available +local http = minetest.request_http_api() +if http then + assert(loadfile(modlib.mod.get_resource"download_palette.lua"))(http) +end + +local texture_path = modpath .. "/textures/" +if minetest.rmdir then + -- Clear texture directory on startup + minetest.rmdir(texture_path, true) +end +minetest.mkdir(texture_path) + +local function get_path(filename) + local path + local mod = modlib.minetest.media.mods[filename] + if mod == modname then -- media overridden by this mod + local overridden_paths = modlib.minetest.media.overridden_paths[filename] + if not overridden_paths then return end + path = overridden_paths[#overridden_paths] + else + path = modlib.minetest.media.paths[filename] + end + return path +end + +texgen = {} -- HACK only use the mod namespace to expose the dithering methods to the schema... +local dithering = modlib.mod.include"dithering.lua" -- sets texgen.dithering_methods +local conf = modlib.mod.configuration() +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 + +for filename in pairs(modlib.minetest.media.paths) do + 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 + end +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 + if filename:match"%.png$" and not (modlib.minetest.media[filename] and modlib.minetest.overridden_paths[filename]) then + transform_png(filename, modlib.file.concat_path{modpath, "builtin", filename}) + end +end diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..f27c841 --- /dev/null +++ b/mod.conf @@ -0,0 +1,5 @@ +name = texgen +title = Texture Generator +author = appguru(eu) +description = Dynamically generated texture packs +depends = modlib diff --git a/palette.lua b/palette.lua new file mode 100644 index 0000000..6ae164c --- /dev/null +++ b/palette.lua @@ -0,0 +1,42 @@ +local function relative_color_distance(color, other_color) + -- See https://www.compuphase.com/cmetric.htm + local redmean = (color.r + other_color.r) / 2 + -- Omits the square root as this only has to be relative + return (2 + redmean/256) * (color.r-other_color.r)^2 + + 4 * (color.g-other_color.g)^2 + + (2 + (255 - redmean)/256) * (color.b-other_color.b)^2 +end +local palettes = modlib.mod.get_resource"palettes" +return function(name) + local path = modlib.file.concat_path{palettes, name .. ".png"} + 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) + local colors = {} + for _, color in pairs(png.data) do + -- TODO ignore colors with alpha 0? + local rgb = color % 0x1000000 + colors[rgb] = true + end + local palette_colors = {} + for colornum in pairs(colors) do + table.insert(palette_colors, modlib.minetest.colorspec.from_number(colornum)) + end + return function(color) + -- Find closest color using a linear search; a k-d-tree can't be employed here because the metric isn't euclidean + local closest_color = palette_colors[1] + local closest_distance = relative_color_distance(color, closest_color) + for i = 2, #palette_colors do + local palette_color = palette_colors[i] + local distance = relative_color_distance(color, palette_color) + -- TODO deal with same distances through random choice? + if distance < closest_distance then + closest_color = palette_color + closest_distance = distance + end + end + return closest_color + end +end diff --git a/palettes/aap-64.png b/palettes/aap-64.png new file mode 100644 index 0000000..447a2d5 Binary files /dev/null and b/palettes/aap-64.png differ diff --git a/palettes/apollo.png b/palettes/apollo.png new file mode 100644 index 0000000..078045c Binary files /dev/null and b/palettes/apollo.png differ diff --git a/palettes/pico-8.png b/palettes/pico-8.png new file mode 100644 index 0000000..0ea57ca Binary files /dev/null and b/palettes/pico-8.png differ diff --git a/palettes/resurrect-64.png b/palettes/resurrect-64.png new file mode 100644 index 0000000..d758074 Binary files /dev/null and b/palettes/resurrect-64.png differ diff --git a/palettes/soggy-newspapers.png b/palettes/soggy-newspapers.png new file mode 100644 index 0000000..be5eb5c Binary files /dev/null and b/palettes/soggy-newspapers.png differ diff --git a/palettes/zughy-32.png b/palettes/zughy-32.png new file mode 100644 index 0000000..b4e39cb Binary files /dev/null and b/palettes/zughy-32.png differ diff --git a/schema.lua b/schema.lua new file mode 100644 index 0000000..d3144ed --- /dev/null +++ b/schema.lua @@ -0,0 +1,48 @@ +local palettes = {} +for _, filename in ipairs(minetest.get_dir_list(modlib.mod.get_resource"palettes", false)) do + local palette = filename:match"(.+)%.png$" + if palette then palettes[palette] = true end +end +return { + type = "table", + entries = { + palette = { + type = "table", + entries = { + name = { + type = "string", + description = "Name of the palette to use (without extension)", + values = palettes, + default = "apollo" + }, + dithering = { + type = "string", + description = "Dithering method to use", + values = texgen.dithering_methods, + default = "floyd_steinberg" + } + } + }, + saturate = { + type = "number", + description = "Increase or decrease saturation by a factor", + range = {min = 0.1, max = 10}, + default = 1 + }, + monochrome = { + type = "boolean", + description = "Convert RGB to monochrome (greyscale)", + default = false + }, + invert = { + type = "boolean", + description = "Invert the RGB colors", + default = false + }, + average = { + type = "boolean", + description = "Replace each texture with a single pixel of its weighted average RGB color", + default = false, + } + } +} diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..3f0fbad Binary files /dev/null and b/screenshot.png differ diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 0000000..14400fb --- /dev/null +++ b/settingtypes.txt @@ -0,0 +1,19 @@ +# Replace each texture with a single pixel of its weighted average RGB color +texgen.average (Texgen Average) bool false + +# Invert the RGB colors +texgen.invert (Texgen Invert) bool false + +# Convert RGB to monochrome (greyscale) +texgen.monochrome (Texgen Monochrome) bool false + +# Increase or decrease saturation by a factor +texgen.saturate (Texgen Saturate) float 1 0.100000 10.000000 + +[texgen.palette] + +# Dithering method to use +texgen.palette.dithering (Texgen Palette Dithering) enum floyd_steinberg sierra,stucke,sierra_lite,jarvis_judice_ninke,floyd_steinberg,none,two_row_sierra,burkes,atkinson + +# Name of the palette to use (without extension) +texgen.palette.name (Texgen Palette Name) enum apollo soggy-newspapers,apollo,zughy-32,aap-64,pico-8,resurrect-64 \ No newline at end of file