Replace tga to png

This commit is contained in:
kay27 2022-01-31 06:41:18 +04:00
parent da28fc2cea
commit 957a831dbf
6 changed files with 91 additions and 192 deletions

View File

@ -1,4 +0,0 @@
# tga_encoder
A TGA Encoder written in Lua without the use of external Libraries.
May be used as a Minetest mod.

View File

@ -1,92 +0,0 @@
tga_encoder = {}
local image = setmetatable({}, {
__call = function(self, ...)
local t = setmetatable({}, {__index = self})
t:constructor(...)
return t
end,
})
function image:constructor(pixels)
self.data = ""
self.pixels = pixels
self.width = #pixels[1]
self.height = #pixels
self:encode()
end
function image:encode_colormap_spec()
self.data = self.data
.. string.char(0, 0) -- first entry index
.. string.char(0, 0) -- number of entries
.. string.char(0) -- bits per pixel
end
function image:encode_image_spec()
self.data = self.data
.. string.char(0, 0) -- X-origin
.. string.char(0, 0) -- Y-origin
.. string.char(self.width % 256, math.floor(self.width / 256)) -- width
.. string.char(self.height % 256, math.floor(self.height / 256)) -- height
.. string.char(24) -- pixel depth (RGB = 3 bytes = 24 bits)
.. string.char(0) -- image descriptor
end
function image:encode_header()
self.data = self.data
.. string.char(0) -- image id
.. string.char(0) -- color map type
.. string.char(10) -- image type (RLE RGB = 10)
self:encode_colormap_spec() -- color map specification
self:encode_image_spec() -- image specification
end
function image:encode_data()
local current_pixel = ''
local previous_pixel = ''
local count = 1
local packets = {}
local rle_packet = ''
for _, row in ipairs(self.pixels) do
for _, pixel in ipairs(row) do
current_pixel = string.char(pixel[3], pixel[2], pixel[1])
if current_pixel ~= previous_pixel or count == 128 then
packets[#packets +1] = rle_packet
count = 1
previous_pixel = current_pixel
else
count = count + 1
end
rle_packet = string.char(128 + count - 1) .. current_pixel
end
end
packets[#packets +1] = rle_packet
self.data = self.data .. table.concat(packets)
end
function image:encode_footer()
self.data = self.data
.. string.char(0, 0, 0, 0) -- extension area offset
.. string.char(0, 0, 0, 0) -- developer area offset
.. "TRUEVISION-XFILE"
.. "."
.. string.char(0)
end
function image:encode()
self:encode_header() -- header
-- no color map and image id data
self:encode_data() -- encode data
-- no extension or developer area
self:encode_footer() -- footer
end
function image:save(filename)
local f = assert(io.open(filename, "w"))
f:write(self.data)
f:close()
end
tga_encoder.image = image

View File

@ -1,3 +0,0 @@
name = tga_encoder
author = Fleckenstein
description = A TGA Encoder written in Lua without the use of external Libraries.

View File

@ -1,24 +1,12 @@
mcl_maps = {} mcl_maps = {}
local modname = minetest.get_current_modname() local S = minetest.get_translator("mcl_maps")
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath("mcl_maps")
local S = minetest.get_translator(modname)
local math = math
local vector = vector
local table = table
local pairs = pairs
local pos_to_string = minetest.pos_to_string
local string_to_pos = minetest.string_to_pos
local get_item_group = minetest.get_item_group
local dynamic_add_media = minetest.dynamic_add_media
local get_connected_players = minetest.get_connected_players
local storage = minetest.get_mod_storage()
local worldpath = minetest.get_worldpath() local worldpath = minetest.get_worldpath()
local map_textures_path = worldpath .. "/mcl_maps/" local map_textures_path = worldpath .. "/mcl_maps/"
--local last_finished_id = storage:get_int("next_id") - 1
local math_min = math.min
local math_max = math.max
minetest.mkdir(map_textures_path) minetest.mkdir(map_textures_path)
@ -40,17 +28,15 @@ local loaded_maps = {}
local c_air = minetest.get_content_id("air") local c_air = minetest.get_content_id("air")
function mcl_maps.create_map(pos) function mcl_maps.create_map(pos)
local minp = vector.multiply(vector.floor(vector.divide(pos, 128)), 128) local minp = vector.subtract(vector.floor(pos), 64)
local maxp = vector.add(minp, vector.new(127, 127, 127)) local maxp = vector.add(minp, 127)
local itemstack = ItemStack("mcl_maps:filled_map") local itemstack = ItemStack("mcl_maps:filled_map")
local meta = itemstack:get_meta() local meta = itemstack:get_meta()
local next_id = storage:get_int("next_id") local id = string.format("%.0f", minetest.hash_node_position(minp))
storage:set_int("next_id", next_id + 1)
local id = tostring(next_id)
meta:set_string("mcl_maps:id", id) meta:set_string("mcl_maps:id", id)
meta:set_string("mcl_maps:minp", pos_to_string(minp)) meta:set_string("mcl_maps:minp", minetest.pos_to_string(minp))
meta:set_string("mcl_maps:maxp", pos_to_string(maxp)) meta:set_string("mcl_maps:maxp", minetest.pos_to_string(maxp))
tt.reload_itemstack_description(itemstack) tt.reload_itemstack_description(itemstack)
creating_maps[id] = true creating_maps[id] = true
@ -62,78 +48,93 @@ function mcl_maps.create_map(pos)
local emin, emax = vm:read_from_map(minp, maxp) local emin, emax = vm:read_from_map(minp, maxp)
local data = vm:get_data() local data = vm:get_data()
local param2data = vm:get_param2_data() local param2data = vm:get_param2_data()
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) local offset_x, offset_y, offset_z = minp.x - emin.x, minp.y - emin.y, minp.z - emin.z
local dx = emax.x - emin.x + 1
local dy = (emax.y - emin.y + 1) * dx
local offset = offset_z * dy + offset_y * dx + offset_x
local map_y_start = 64 * dx
local map_y_limit = 127 * dx
local pixels = {} local pixels = {}
local last_heightmap local last_heightmap
for x = 1, 128 do for x = 1, 128 do
local map_x = minp.x - 1 + x local map_x = x + offset
local heightmap = {} local heightmap = {}
for z = 1, 128 do for z = 1, 128 do
local map_z = minp.z - 1 + z local map_z = (z-1) * dy + map_x
local color, height local color, height
for map_y = maxp.y, minp.y, -1 do
local index = area:index(map_x, map_y, map_z) local map_y = map_z + map_y_start
local c_id = data[index] local map_y_limit = map_z + map_y_limit
if c_id ~= c_air then while data[map_y] ~= c_air and map_y < map_y_limit do
color = color_cache[c_id] map_y = map_y + dx
if color == nil then end
local nodename = minetest.get_name_from_content_id(c_id) while data[map_y] == c_air and map_y > map_z do
local def = minetest.registered_nodes[nodename] map_y = map_y - dx
if def then end
local texture local c_id = data[map_y]
if def.palette then color = color_cache[c_id]
texture = def.palette if color == nil then
elseif def.tiles then local nodename = minetest.get_name_from_content_id(c_id)
texture = def.tiles[1] local def = minetest.registered_nodes[nodename]
if type(texture) == "table" then if def then
texture = texture.name local texture
end if def.palette then
end texture = def.palette
if texture then elseif def.tiles then
texture = texture:match("([^=^%^]-([^.]+))$"):split("^")[1] texture = def.tiles[1]
end if type(texture) == "table" then
if def.palette then texture = texture.name
local palette = palettes[texture]
color = palette and {palette = palette}
else
color = texture_colors[texture]
end
end end
end end
if texture then
if color and color.palette then texture = texture:match("([^=^%^]-([^.]+))$"):split("^")[1]
color = color.palette[param2data[index] + 1] end
if def.palette then
local palette = palettes[texture]
color = palette and {palette = palette}
else else
color_cache[c_id] = color or false color = texture_colors[texture]
end end
if color and last_heightmap then
local last_height = last_heightmap[z]
if last_height < map_y then
color = {
math.min(255, color[1] + 16),
math.min(255, color[2] + 16),
math.min(255, color[3] + 16),
}
elseif last_height > map_y then
color = {
math.max(0, color[1] - 16),
math.max(0, color[2] - 16),
math.max(0, color[3] - 16),
}
end
end
height = map_y
break
end end
end end
if color and color.palette then
color = color.palette[param2data[map_y] + 1]
else
color_cache[c_id] = color or false
end
if color and last_heightmap then
local last_height = last_heightmap[z]
local y = map_y - map_z
if last_height < y then
color = {
math_min(255, color[1] + 16),
math_min(255, color[2] + 16),
math_min(255, color[3] + 16),
}
elseif last_height > y then
color = {
math_max(0, color[1] - 16),
math_max(0, color[2] - 16),
math_max(0, color[3] - 16),
}
end
end
height = map_y - map_z
heightmap[z] = height or minp.y heightmap[z] = height or minp.y
pixels[z] = pixels[z] or {} pixels[#pixels + 1] = color and {r = color[1], g = color[2], b = color[3]} or {r = 0, g = 0, b = 0}
pixels[z][x] = color or {0, 0, 0}
end end
last_heightmap = heightmap last_heightmap = heightmap
end end
tga_encoder.image(pixels):save(map_textures_path .. "mcl_maps_map_texture_" .. id .. ".tga")
local png = minetest.encode_png(128, 128, pixels)
local f = io.open(map_textures_path .. "mcl_maps_map_texture_" .. id .. ".png", "w")
if not f then return end
f:write(png)
f:close()
creating_maps[id] = nil creating_maps[id] = nil
end) end)
return itemstack return itemstack
@ -144,11 +145,11 @@ function mcl_maps.load_map(id)
return return
end end
local texture = "mcl_maps_map_texture_" .. id .. ".tga" local texture = "mcl_maps_map_texture_" .. id .. ".png"
if not loaded_maps[id] then if not loaded_maps[id] then
loaded_maps[id] = true loaded_maps[id] = true
dynamic_add_media(map_textures_path .. texture, function() end) minetest.dynamic_add_media(map_textures_path .. texture, function() end)
end end
return texture return texture
@ -229,14 +230,14 @@ end
local old_add_item = minetest.add_item local old_add_item = minetest.add_item
function minetest.add_item(pos, stack) function minetest.add_item(pos, stack)
stack = ItemStack(stack) stack = ItemStack(stack)
if get_item_group(stack:get_name(), "filled_map") > 0 then if minetest.get_item_group(stack:get_name(), "filled_map") > 0 then
stack:set_name("mcl_maps:filled_map") stack:set_name("mcl_maps:filled_map")
end end
return old_add_item(pos, stack) return old_add_item(pos, stack)
end end
tt.register_priority_snippet(function(itemstring, _, itemstack) tt.register_priority_snippet(function(itemstring, _, itemstack)
if itemstack and get_item_group(itemstring, "filled_map") > 0 then if itemstack and minetest.get_item_group(itemstring, "filled_map") > 0 then
local id = itemstack:get_meta():get_string("mcl_maps:id") local id = itemstack:get_meta():get_string("mcl_maps:id")
if id ~= "" then if id ~= "" then
return "#" .. id, mcl_colors.GRAY return "#" .. id, mcl_colors.GRAY
@ -262,7 +263,7 @@ minetest.register_craft({
local function on_craft(itemstack, player, old_craft_grid, craft_inv) local function on_craft(itemstack, player, old_craft_grid, craft_inv)
if itemstack:get_name() == "mcl_maps:filled_map" then if itemstack:get_name() == "mcl_maps:filled_map" then
for _, stack in pairs(old_craft_grid) do for _, stack in pairs(old_craft_grid) do
if get_item_group(stack:get_name(), "filled_map") > 0 then if minetest.get_item_group(stack:get_name(), "filled_map") > 0 then
itemstack:get_meta():from_table(stack:get_meta():to_table()) itemstack:get_meta():from_table(stack:get_meta():to_table())
return itemstack return itemstack
end end
@ -299,7 +300,7 @@ minetest.register_on_leaveplayer(function(player)
end) end)
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
for _, player in pairs(get_connected_players()) do for _, player in pairs(minetest.get_connected_players()) do
local wield = player:get_wielded_item() local wield = player:get_wielded_item()
local texture = mcl_maps.load_map_item(wield) local texture = mcl_maps.load_map_item(wield)
local hud = huds[player] local hud = huds[player]
@ -319,8 +320,8 @@ minetest.register_globalstep(function(dtime)
local pos = vector.round(player:get_pos()) local pos = vector.round(player:get_pos())
local meta = wield:get_meta() local meta = wield:get_meta()
local minp = string_to_pos(meta:get_string("mcl_maps:minp")) local minp = minetest.string_to_pos(meta:get_string("mcl_maps:minp"))
local maxp = string_to_pos(meta:get_string("mcl_maps:maxp")) local maxp = minetest.string_to_pos(meta:get_string("mcl_maps:maxp"))
local marker = "mcl_maps_player_arrow.png" local marker = "mcl_maps_player_arrow.png"

View File

@ -1,8 +1,5 @@
# textdomain: mcl_maps # textdomain: mcl_maps
Empty Map=Carte Vierge Empty Map=Carte Vierge
Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Les cartes vierges ne sont pas utiles en tant que cartes, mais elles peuvent être empilées et transformées en cartes utilisables. Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Les cartes vierges ne sont pas utiles en tant que cartes, mais elles peuvent être empilées et transformées en cartes utilisables.
Rightclick to create a filled map (which can't be stacked anymore).=Clic droit pour créer une carte remplie (qui ne peut plus être empilée). Rightclick to start using the map (which can't be stacked anymore).=Clic droit pour commencer à utiliser la carte (qui ne peut plus être empilée).
Map=Carte Map=Carte
Shows a map image.=Affiche une carte.
When created, the map saves the nearby area as an image that can be viewed any time by holding the map.=Lors de sa création, la carte sauvegarde le terrain proche sous forme d'image qui peut être consultée n'importe quand en tenant la carte dans la main.
Hold the map in your hand. This will display a map on your screen.=Tenez la carte dans votre main. Cela affichera la carte à l'écran.

View File

@ -1,2 +1,2 @@
name = mcl_maps name = mcl_maps
depends = mcl_core, mcl_flowers, tga_encoder, tt, mcl_colors, mcl_skins, mcl_util depends = mcl_core, mcl_flowers, tt, mcl_colors, mcl_skins, mcl_util