knucklebones/utils/utils.lua
2023-08-12 11:36:14 +02:00

176 lines
4.7 KiB
Lua

include "globals"
include "utils.tables"
include "utils.rendering"
--- Print with outline
function print_border(text, x, y, color, outline, fixed, scale, smallfont)
local outline = outline == nil
and ((color == 0 or color == nil) and 12 or 0)
or outline
-- diagonals
print(text, x + 1, y + 1, outline, fixed, scale, smallfont)
print(text, x + 1, y - 1, outline, fixed, scale, smallfont)
print(text, x - 1, y + 1, outline, fixed, scale, smallfont)
print(text, x - 1, y - 1, outline, fixed, scale, smallfont)
-- cardinals
print(text, x + 1, y, outline, fixed, scale, smallfont)
print(text, x - 1, y, outline, fixed, scale, smallfont)
print(text, x, y + 1, outline, fixed, scale, smallfont)
print(text, x, y - 1, outline, fixed, scale, smallfont)
print(text, x, y, color, fixed, scale, smallfont)
end
--- Print debug
-- function printd(text, x, y)
-- print_border(text, x, y, 12, 2)
-- end
--- Like print(), but with font() and alignment
---@param txt string
---@param x number
---@param y number
---@param color number
---@param align? number
---@param scale? number
---@return number
function prn(txt, x, y, color, align, scale)
align = align or ALIGN.Left
scale = scale or 1
set1bpp()
if align == ALIGN.Right then
x = x - prn_len(txt, scale)
elseif align == ALIGN.Center then
x = x - prn_len(txt, scale) / 2
end
if color ~= nil then
swap_color(1, color)
end
local len = font(txt, x, y, 0, 4, 0, false, scale)
swap_color(1, 1)
set4bpp()
return len
end
---Like prn() but with an outline
---@param any string
---@param x number
---@param y number
---@param color number
---@param align? number
---@param border_color? number
---@param scale? number
---@return number
function prn_border(txt, x, y, color, align, border_color, scale)
if not border_color then
return prn(txt, x, y, color, align, scale)
end
align = align or ALIGN.Left
border_color = border_color or 0
scale = scale or 1
-- diagonals
prn(txt, x + 1, y + 1, border_color, align, scale)
prn(txt, x + 1, y - 1, border_color, align, scale)
prn(txt, x - 1, y + 1, border_color, align, scale)
prn(txt, x - 1, y - 1, border_color, align, scale)
-- cardinals
prn(txt, x + 1, y, border_color, align, scale)
prn(txt, x - 1, y, border_color, align, scale)
prn(txt, x, y + 1, border_color, align, scale)
prn(txt, x, y - 1, border_color, align, scale)
return prn(txt, x, y, color, align, scale)
end
---like prn_border() but with floaty text
---@param txt any
---@param x any
---@param y any
---@param color any
---@param align any
---@param border_color? any
---@param scale? any
function prn_border_floaty(txt, x, y, color, align, border_color, scale, delay)
delay = delay or 0
align = align or ALIGN.Left
border_color = border_color or 0
local len = prn_len(txt, scale)
prn_len(txt, scale)
if align == ALIGN.Right then
x = x - len
elseif align == ALIGN.Center then
x = x - len / 2
end
for i = 1, #txt do
local c = txt:sub(i, i)
local y = y + math.sin(((i+delay) * 100 + time()) / 200) * 3
x = x + prn_border(c, x, y, color, ALIGN.Left, border_color, scale)
end
return len
end
function swap_color(index, color)
poke4(PALETTE_MAP * 2 + index, color)
end
function reset_colors(...)
args = { ... }
if #args > 0 then
for _, c in ipairs(args) do
swap_color(c, c)
end
else
for i = 0, 16 do
poke4(PALETTE_MAP * 2 + i, i)
end
end
end
local _cachedPrintLen = {}
function print_len(txt)
if _cachedPrintLen[txt] then return _cachedPrintLen[txt] end
local len = print(txt, -1000, -1000)
_cachedPrintLen[txt] = len
return len
end
local _cachedFontLen = {}
function prn_len(txt, scale)
scale = scale or 1
if scale == 0 then scale = 1 end
local bpp = peek4(2 * 0x3ffc) -- get the current bpp value to reset it after
set1bpp()
if _cachedFontLen[txt] then return _cachedFontLen[txt] end
local len = font(txt, -1000, -1000, 0, 4, 0, false, scale)
_cachedFontLen[txt] = len
poke4(2 * 0x3ffc, bpp)
return len
end
function set1bpp()
poke4(2 * 0x3ffc, 8) -- 0b1000
end
function set4bpp()
poke4(2 * 0x3ffc, 2) -- 0b0010
end
function point_in_rect(x, y, rx, ry, rw, rh)
return x >= rx and x <= rx + rw and y >= ry and y <= ry + rh
end
function mouse_in_rect(rect)
local mx, my = mouse()
return point_in_rect(mx, my, rect.x, rect.y, rect.width, rect.height)
end
function clamp(min, val, max)
return math.max(math.min(max, val), min)
end
function normalize(val, min, max)
min = min or 0
max = max or val
return (val - min) / (max - min)
end