225 lines
5.2 KiB
Lua
225 lines
5.2 KiB
Lua
local utils = {}
|
|
local alignment = {
|
|
["top"] = 0,
|
|
["left"] = 0,
|
|
["middle"] = -0.5,
|
|
["center"] = -0.5,
|
|
["bottom"] = -1,
|
|
["right"] = -1
|
|
}
|
|
local Vector2 = require("Vector2")
|
|
local _tx, _ty = 0, 0
|
|
local _stack = {
|
|
sx = {},
|
|
sy = {},
|
|
sw = {},
|
|
sh = {},
|
|
tx = {},
|
|
ty = {}
|
|
}
|
|
|
|
--[[
|
|
function atan2 (y, x)
|
|
return (x > 0 ) and math.atan(y/x)
|
|
or (x < 0 and y >= 0) and math.atan(y/x) + math.pi
|
|
or (x < 0 and y < 0) and math.atan(y/x) - math.pi
|
|
or (x == 0 and y > 0) and math.pi/2
|
|
or (x == 0 and y < 0) and -math.pi/2
|
|
or 0 -- this situration is technically undefined
|
|
end
|
|
]]
|
|
|
|
function utils.lastIndex(t)
|
|
local res = -math.huge
|
|
for k in pairs(t) do
|
|
if k > res then res = k end
|
|
end
|
|
return res
|
|
end
|
|
|
|
function utils.translate(dx, dy)
|
|
love.graphics.translate(dx, dy)
|
|
_tx, _ty = _tx + dx, _ty + dy
|
|
end
|
|
|
|
function utils.pushRegion(x, y, w, h)
|
|
local sx, sy, sw, sh = love.graphics.getScissor()
|
|
table.insert(_stack.sx, sx)
|
|
table.insert(_stack.sy, sy)
|
|
table.insert(_stack.sw, sw)
|
|
table.insert(_stack.sh, sh)
|
|
table.insert(_stack.tx, _ty)
|
|
table.insert(_stack.ty, _tx)
|
|
|
|
love.graphics.push()
|
|
if x and y then
|
|
if w and h then
|
|
love.graphics.intersectScissor(_tx + x, _ty + y, math.max(0, w), math.max(0, h))
|
|
end
|
|
utils.translate(x, y)
|
|
end
|
|
end
|
|
|
|
function utils.popRegion()
|
|
local sx = table.remove(_stack.sx)
|
|
local sy = table.remove(_stack.sy)
|
|
local sw = table.remove(_stack.sw)
|
|
local sh = table.remove(_stack.sh)
|
|
|
|
_tx = table.remove(_stack.tx) or 0
|
|
_ty = table.remove(_stack.ty) or 0
|
|
|
|
love.graphics.pop()
|
|
if sx and sy and sw and sh then
|
|
love.graphics.setScissor(sx, sy, sw, sh)
|
|
else
|
|
love.graphics.setScissor()
|
|
end
|
|
end
|
|
|
|
function utils.smoothLine (x1, y1, x2, y2, width, color)
|
|
love.graphics.setLineStyle("smooth")
|
|
love.graphics.setLineWidth(width)
|
|
if color then love.graphics.setColor(color) end
|
|
love.graphics.line(x1, y1, x2, y2)
|
|
end
|
|
|
|
function utils.clamp(x, A, B)
|
|
if x < A then
|
|
return A
|
|
elseif x > B then
|
|
return B
|
|
else
|
|
return x
|
|
end
|
|
end
|
|
|
|
local function previous(t, i)
|
|
i = i - 1
|
|
if i > 0 then return i, t[i] end
|
|
end
|
|
|
|
function utils.revipairs(t)
|
|
return previous, t, #t+1
|
|
end
|
|
|
|
function utils.smoothRectangle(x, y, w, h, r, color)
|
|
love.graphics.setLineStyle("smooth")
|
|
love.graphics.setLineWidth(1)
|
|
if color then love.graphics.setColor(color) end
|
|
love.graphics.rectangle("fill", x, y, w, h, r)
|
|
love.graphics.rectangle("line", x, y, w, h, r)
|
|
end
|
|
|
|
function utils.borderRectangle(x,y,w,h,r,lineWidth,color)
|
|
love.graphics.setLineStyle("smooth")
|
|
love.graphics.setLineWidth(lineWidth)
|
|
if color then love.graphics.setColor(color) end
|
|
love.graphics.rectangle("line", x, y, w, h, r)
|
|
end
|
|
|
|
function utils.alignedPrint(font, text, x, y, alignX, alignY)
|
|
local line_count = (select(2, text:gsub('\n', '\n')) or 0) + 1
|
|
local width = font:getWidth(text)
|
|
local height = font:getHeight()*line_count
|
|
|
|
love.graphics.setFont(font)
|
|
love.graphics.print(text, utils.round(x + (alignment[alignX] or -0.5) * width), utils.round(y + (alignment[alignY] or -0.5) * height))
|
|
end
|
|
|
|
function utils.rgb(r, g, b)
|
|
return {r/255, g/255, b/255, 1}
|
|
end
|
|
|
|
function utils.rgba(r, g, b, a)
|
|
return {r/255, g/255, b/255, a}
|
|
end
|
|
|
|
function utils.round(num, numDecimalPlaces)
|
|
local mult = 10^(numDecimalPlaces or 0)
|
|
return math.floor(num * mult + 0.5) / mult
|
|
end
|
|
|
|
function utils.map(x, A, B, C, D)
|
|
return (x - A) / (B - A) * (D - C) + C
|
|
end
|
|
|
|
function utils.sign(x)
|
|
if x > 0 then
|
|
return 1
|
|
elseif x < 0 then
|
|
return -1
|
|
else
|
|
return 0
|
|
end
|
|
end
|
|
|
|
function utils.clone(data)
|
|
if type(data) ~= "table" then
|
|
return data
|
|
else
|
|
|
|
local new = {}
|
|
for k, v in pairs(data) do
|
|
new[k] = utils.clone(v)
|
|
end
|
|
return setmetatable(new, getmetatable(data))
|
|
end
|
|
end
|
|
|
|
function utils.serialize(data)
|
|
if type(data) == "string" then
|
|
return "\""..data.."\""
|
|
elseif type(data) == "table" then
|
|
local t = {}
|
|
for key,value in pairs(data) do
|
|
table.insert(t,"["..utils.serialize(key).."]="..utils.serialize(value))
|
|
end
|
|
return "{"..table.concat(t,",").."}"
|
|
else
|
|
return tostring(data)
|
|
end
|
|
end
|
|
|
|
function utils.unserialize(data)
|
|
return load("return "..data, nil, "t", {Vector2 = Vector2})()
|
|
end
|
|
|
|
function utils.printTable(t,depth)
|
|
depth = depth or 0
|
|
for k,v in pairs(t) do
|
|
if type(v) == "table" then
|
|
print(string.rep(" ", depth)..k, "table:")
|
|
utils.printTable(v,depth+1)
|
|
else
|
|
print(string.rep(" ", depth)..k, v)
|
|
end
|
|
end
|
|
end
|
|
|
|
function utils.loadFile(fileName)
|
|
if not love.filesystem.getInfo(fileName) then return nil end
|
|
local file = love.filesystem.read(fileName)
|
|
local data = love.data.decompress("string","zlib", file)
|
|
return utils.unserialize(data)
|
|
end
|
|
|
|
function utils.saveFile(data, fileName)
|
|
local rawstring = utils.serialize(data)
|
|
local file = io.open(fileName, "wb")
|
|
file:write(love.data.compress("string","zlib",rawstring))
|
|
end
|
|
|
|
function utils.pairsByKeys(t)
|
|
local tableKeys = {}
|
|
for key in pairs(t) do table.insert(tableKeys, key) end
|
|
table.sort(tableKeys)
|
|
local i = 0
|
|
local n = table.getn(tableKeys)
|
|
return function ()
|
|
i = i + 1
|
|
if i <= n then return tableKeys[i], t[tableKeys[i]] end
|
|
end
|
|
end
|
|
|
|
return utils |