266 lines
6.1 KiB
Lua
266 lines
6.1 KiB
Lua
--[[
|
||
|
||
tga_testnodes – Minetest mod that adds nodes with TGA test images.
|
||
Copyright © 2023 Nils Dagsson Moskopp (erle)
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Affero General Public License as
|
||
published by the Free Software Foundation, either version 3 of the
|
||
License, or (at your option) any later version.
|
||
|
||
Dieses Programm hat das Ziel, die Medienkompetenz der Leser zu
|
||
steigern. Gelegentlich packe ich sogar einen handfesten Buffer
|
||
Overflow oder eine Format String Vulnerability zwischen die anderen
|
||
Codezeilen und schreibe das auch nicht dran.
|
||
|
||
]]--
|
||
|
||
assert(
|
||
tga_encoder.features,
|
||
"No features table found. Install a newer version of tga_encoder!"
|
||
)
|
||
|
||
local modname = minetest.get_current_modname()
|
||
|
||
local S = minetest.get_translator( modname )
|
||
|
||
local textures_path = minetest.get_modpath( modname ) .. "/textures/"
|
||
|
||
local register_node = function(filename)
|
||
local prefix = filename:gmatch( "[^.]+" )():gsub( "-", "_" )
|
||
local nodename = modname .. ":" .. prefix
|
||
minetest.register_node(nodename, {
|
||
description = S(
|
||
"TGA Test Node " ..
|
||
prefix
|
||
),
|
||
drawtype = "glasslike",
|
||
groups = { dig_immediate = 2 },
|
||
paramtype = "light",
|
||
sunlight_propagates = true,
|
||
tiles = { filename },
|
||
use_texture_alpha = "blend",
|
||
})
|
||
end
|
||
|
||
local _ = { 0 }
|
||
local R = { 1 }
|
||
local G = { 2 }
|
||
local B = { 3 }
|
||
|
||
local pixels_colormapped_bt = {
|
||
{ _, _, _, _, _, B, _, B, },
|
||
{ _, _, _, _, _, B, B, B, },
|
||
{ _, _, G, G, G, B, _, B, },
|
||
{ _, _, G, _, G, B, B, B, },
|
||
{ _, R, G, _, _, _, _, _, },
|
||
{ _, R, G, G, G, _, _, _, },
|
||
{ _, R, _, _, _, _, _, _, },
|
||
{ R, R, R, _, _, _, _, _, },
|
||
}
|
||
|
||
local pixels_colormapped_tb = {
|
||
{ R, R, R, _, _, _, _, _, },
|
||
{ _, R, _, _, _, _, _, _, },
|
||
{ _, R, G, G, G, _, _, _, },
|
||
{ _, R, G, _, _, _, _, _, },
|
||
{ _, _, G, _, G, B, B, B, },
|
||
{ _, _, G, G, G, B, _, B, },
|
||
{ _, _, _, _, _, B, B, B, },
|
||
{ _, _, _, _, _, B, _, B, },
|
||
}
|
||
|
||
local pixels_colormapped_by_scanline_order = {
|
||
["bottom_top"] = pixels_colormapped_bt,
|
||
["top_bottom"] = pixels_colormapped_tb,
|
||
}
|
||
|
||
local colormap_32bpp = {
|
||
{ 0, 0, 0, 127 },
|
||
{ 255, 0, 0, 255 },
|
||
{ 0, 255, 0, 255 },
|
||
{ 0, 0, 255, 255 },
|
||
}
|
||
|
||
local colormap_24bpp = {
|
||
{ 0, 0, 0 },
|
||
{ 255, 0, 0 },
|
||
{ 0, 255, 0 },
|
||
{ 0, 0, 255 },
|
||
}
|
||
|
||
local colormap_16bpp = {
|
||
{ 0, 0, 0, 0 },
|
||
{ 255, 0, 0, 255 },
|
||
{ 0, 255, 0, 255 },
|
||
{ 0, 0, 255, 255 },
|
||
}
|
||
|
||
local colormap_by_color_format = {
|
||
["A1R5G5B5"] = colormap_16bpp,
|
||
["B8G8R8"] = colormap_24bpp,
|
||
["B8G8R8A8"] = colormap_32bpp,
|
||
}
|
||
|
||
for color_format, _ in pairs(
|
||
tga_encoder.features.color_format
|
||
) do
|
||
if ("Y8" ~= color_format) then
|
||
for scanline_order, _ in pairs(
|
||
tga_encoder.features.scanline_order
|
||
) do
|
||
local filename
|
||
local pixels
|
||
filename = "type1" ..
|
||
'-' .. color_format ..
|
||
'-' .. scanline_order ..
|
||
'.tga'
|
||
pixels = pixels_colormapped_by_scanline_order[
|
||
scanline_order
|
||
]
|
||
local colormap = colormap_by_color_format[
|
||
color_format
|
||
]
|
||
local properties = {
|
||
colormap = colormap,
|
||
color_format = color_format,
|
||
scanline_order = scanline_order,
|
||
}
|
||
print(filename)
|
||
local image = tga_encoder.image(pixels)
|
||
image:save(
|
||
textures_path .. filename,
|
||
properties
|
||
)
|
||
register_node(filename)
|
||
end
|
||
end
|
||
end
|
||
|
||
local _ = { 0, 0, 0, 127 }
|
||
local R = { 255, 0, 0, 255 }
|
||
local G = { 0, 255, 0, 255 }
|
||
local B = { 0, 0, 255, 255 }
|
||
|
||
local pixels_rgba_bt = {
|
||
{ _, _, _, _, _, B, _, B, },
|
||
{ _, _, _, _, _, B, B, B, },
|
||
{ _, _, G, G, G, B, _, B, },
|
||
{ _, _, G, _, G, B, B, B, },
|
||
{ _, R, G, _, _, _, _, _, },
|
||
{ _, R, G, G, G, _, _, _, },
|
||
{ _, R, _, _, _, _, _, _, },
|
||
{ R, R, R, _, _, _, _, _, },
|
||
}
|
||
|
||
local pixels_rgba_tb = {
|
||
{ R, R, R, _, _, _, _, _, },
|
||
{ _, R, _, _, _, _, _, _, },
|
||
{ _, R, G, G, G, _, _, _, },
|
||
{ _, R, G, _, _, _, _, _, },
|
||
{ _, _, G, _, G, B, B, B, },
|
||
{ _, _, G, G, G, B, _, B, },
|
||
{ _, _, _, _, _, B, B, B, },
|
||
{ _, _, _, _, _, B, _, B, },
|
||
}
|
||
|
||
local pixels_rgba_by_scanline_order = {
|
||
["bottom_top"] = pixels_rgba_bt,
|
||
["top_bottom"] = pixels_rgba_tb,
|
||
}
|
||
|
||
local _ = { 0, 0, 0 }
|
||
local R = { 255, 0, 0 }
|
||
local G = { 0, 255, 0 }
|
||
local B = { 0, 0, 255 }
|
||
|
||
local pixels_rgb_bt = {
|
||
{ _, _, _, _, _, B, _, B, },
|
||
{ _, _, _, _, _, B, B, B, },
|
||
{ _, _, G, G, G, B, _, B, },
|
||
{ _, _, G, _, G, B, B, B, },
|
||
{ _, R, G, _, _, _, _, _, },
|
||
{ _, R, G, G, G, _, _, _, },
|
||
{ _, R, _, _, _, _, _, _, },
|
||
{ R, R, R, _, _, _, _, _, },
|
||
}
|
||
|
||
local pixels_rgb_tb = {
|
||
{ R, R, R, _, _, _, _, _, },
|
||
{ _, R, _, _, _, _, _, _, },
|
||
{ _, R, G, G, G, _, _, _, },
|
||
{ _, R, G, _, _, _, _, _, },
|
||
{ _, _, G, _, G, B, B, B, },
|
||
{ _, _, G, G, G, B, _, B, },
|
||
{ _, _, _, _, _, B, B, B, },
|
||
{ _, _, _, _, _, B, _, B, },
|
||
}
|
||
|
||
local pixels_rgb_by_scanline_order = {
|
||
["bottom_top"] = pixels_rgb_bt,
|
||
["top_bottom"] = pixels_rgb_tb,
|
||
}
|
||
|
||
local tga_type_by_compression = {
|
||
["RAW"] = "2",
|
||
["RLE"] = "10",
|
||
}
|
||
|
||
local pixels_by_scanline_order_by_color_format = {
|
||
["A1R5G5B5"] = pixels_rgba_by_scanline_order,
|
||
["B8G8R8"] = pixels_rgb_by_scanline_order,
|
||
["B8G8R8A8"] = pixels_rgba_by_scanline_order,
|
||
["Y8"] = pixels_rgb_by_scanline_order,
|
||
}
|
||
|
||
for color_format, _ in pairs(
|
||
tga_encoder.features.color_format
|
||
) do
|
||
local pixels_by_scanline_order = pixels_by_scanline_order_by_color_format[
|
||
color_format
|
||
]
|
||
for compression, _ in pairs(
|
||
tga_encoder.features.compression
|
||
) do
|
||
local tga_type
|
||
if (
|
||
"Y8" == color_format and
|
||
"RAW" == compression
|
||
) then
|
||
tga_type = "3"
|
||
else
|
||
tga_type = tga_type_by_compression[
|
||
compression
|
||
]
|
||
end
|
||
-- tga_encoder can not encode grayscale RLE (type 11)
|
||
if not(
|
||
"Y8" == color_format and
|
||
"RLE" == compression
|
||
) then
|
||
for scanline_order, _ in pairs(
|
||
tga_encoder.features.scanline_order
|
||
) do
|
||
local filename = "type" .. tga_type ..
|
||
'-' .. color_format ..
|
||
'-' .. scanline_order ..
|
||
'.tga'
|
||
local pixels = pixels_by_scanline_order[
|
||
scanline_order
|
||
]
|
||
local properties = {
|
||
color_format = color_format,
|
||
compression = compression,
|
||
scanline_order = scanline_order,
|
||
}
|
||
local image = tga_encoder.image(pixels)
|
||
image:save(
|
||
textures_path .. filename,
|
||
properties
|
||
)
|
||
register_node(filename)
|
||
end
|
||
end
|
||
end
|
||
end
|