sm64coopdx/mods/character-select-coop/a-font-handler.lua
Agent X 6092488d1c
Some checks failed
Build coop / build-linux (push) Has been cancelled
Build coop / build-steamos (push) Has been cancelled
Build coop / build-windows-opengl (push) Has been cancelled
Build coop / build-windows-directx (push) Has been cancelled
Build coop / build-macos-arm (push) Has been cancelled
Build coop / build-macos-intel (push) Has been cancelled
Update builtin mods
2025-12-31 22:35:17 -05:00

353 lines
No EOL
15 KiB
Lua
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--[[
Custom Font Handler v1 - By Squishy6094
This file adds custom font functionality, and does not need to be edited
Ensure this file is loaded before anything else (make the file name start with a or !)
Use djui_hud_add_font() to add fonts as shown in main.lua
]]
FONT_HANDLER_VERSION_MAJOR = 1
FONT_HANDLER_VERSION_MINOR = 0
FONT_HANDLER_VERSION = "v"..FONT_HANDLER_VERSION_MAJOR.."."..FONT_HANDLER_VERSION_MINOR
local djui_classic_hud_set_font = djui_hud_set_font
local djui_classic_hud_print_text = djui_hud_print_text
local djui_classic_hud_print_text_interpolated = djui_hud_print_text_interpolated
local djui_classic_hud_measure_text = djui_hud_measure_text
local customFont = false
local fontTable = {}
CUSTOM_FONT_COUNT = FONT_COUNT
local customFontType = FONT_NORMAL
local latinChars = {
[32] = " ", [33] = "!", [34] = "\"", [35] = "#", [36] = "$", [37] = "%", [38] = "&", [39] = "'",
[40] = "(", [41] = ")", [42] = "*", [43] = "+", [44] = ",", [45] = "-", [46] = ".", [47] = "/",
[48] = "0", [49] = "1", [50] = "2", [51] = "3", [52] = "4", [53] = "5", [54] = "6", [55] = "7",
[56] = "8", [57] = "9", [58] = ":", [59] = ";", [60] = "<", [61] = "=", [62] = ">", [63] = "?",
[64] = "@", [65] = "A", [66] = "B", [67] = "C", [68] = "D", [69] = "E", [70] = "F", [71] = "G",
[72] = "H", [73] = "I", [74] = "J", [75] = "K", [76] = "L", [77] = "M", [78] = "N", [79] = "O",
[80] = "P", [81] = "Q", [82] = "R", [83] = "S", [84] = "T", [85] = "U", [86] = "V", [87] = "W",
[88] = "X", [89] = "Y", [90] = "Z", [91] = "[", [92] = "\\", [93] = "]", [94] = "^", [95] = "_",
[96] = "`", [97] = "a", [98] = "b", [99] = "c", [100] = "d", [101] = "e", [102] = "f", [103] = "g",
[104] = "h", [105] = "i", [106] = "j", [107] = "k", [108] = "l", [109] = "m", [110] = "n", [111] = "o",
[112] = "p", [113] = "q", [114] = "r", [115] = "s", [116] = "t", [117] = "u", [118] = "v", [119] = "w",
[120] = "x", [121] = "y", [122] = "z", [123] = "{", [124] = "|", [125] = "}", [126] = "~",
-- Latin-1 Supplement
[160] = " ", [161] = "¡", [162] = "¢", [163] = "£", [164] = "¤", [165] = "¥", [166] = "¦", [167] = "§",
[168] = "¨", [169] = "©", [170] = "ª", [171] = "«", [172] = "¬", [173] = "­", [174] = "®", [175] = "¯",
[176] = "°", [177] = "±", [178] = "²", [179] = "³", [180] = "´", [181] = "µ", [182] = "", [183] = "·",
[184] = "¸", [185] = "¹", [186] = "º", [187] = "»", [188] = "¼", [189] = "½", [190] = "¾", [191] = "¿",
[192] = "À", [193] = "Á", [194] = "Â", [195] = "Ã", [196] = "Ä", [197] = "Å", [198] = "Æ", [199] = "Ç",
[200] = "È", [201] = "É", [202] = "Ê", [203] = "Ë", [204] = "Ì", [205] = "Í", [206] = "Î", [207] = "Ï",
[208] = "Ð", [209] = "Ñ", [210] = "Ò", [211] = "Ó", [212] = "Ô", [213] = "Õ", [214] = "Ö", [215] = "×",
[216] = "Ø", [217] = "Ù", [218] = "Ú", [219] = "Û", [220] = "Ü", [221] = "Ý", [222] = "Þ", [223] = "ß",
[224] = "à", [225] = "á", [226] = "â", [227] = "ã", [228] = "ä", [229] = "å", [230] = "æ", [231] = "ç",
[232] = "è", [233] = "é", [234] = "ê", [235] = "ë", [236] = "ì", [237] = "í", [238] = "î", [239] = "ï",
[240] = "ð", [241] = "ñ", [242] = "ò", [243] = "ó", [244] = "ô", [245] = "õ", [246] = "ö", [247] = "÷",
[248] = "ø", [249] = "ù", [250] = "ú", [251] = "û", [252] = "ü", [253] = "ý", [254] = "þ", [255] = "ÿ"
}
local HudAnimTimer = 0
local function convert_unicode_table_to_string_table(input)
local output = {}
for i = 1, #input do
local letter = input[i]
if letter ~= nil and latinChars[letter.id] ~= nil then
output[latinChars[letter.id]] = letter
end
end
return output
end
local function string_to_table(str)
local charArray = {};
local iStart = 0;
local strLen = str:len();
local function bit(b)
return 2 ^ (b - 1);
end
local function hasbit(w, b)
return w % (b + b) >= b
end
local checkMultiByte = function(i)
if (iStart ~= 0) then
charArray[#charArray + 1] = str:sub(iStart, i - 1)
iStart = 0
end
end
for i = 1, strLen do
local b = str:byte(i)
local multiStart = hasbit(b, bit(7)) and hasbit(b, bit(8))
local multiTrail = not hasbit(b, bit(7)) and hasbit(b, bit(8))
if (multiStart) then
checkMultiByte(i)
iStart = i
elseif (not multiTrail) then
checkMultiByte(i)
charArray[#charArray + 1] = str:sub(i, i)
end
end
return charArray
end
---@param texture TextureInfo
---@param info table
---@param spacing integer
---@param offset integer
---@param backup string
---@param scale integer
---@return DjuiFontType
function djui_hud_add_font(texture, info, spacing, offset, backup, scale)
if texture == nil then return FONT_NORMAL end
if info == nil then return FONT_NORMAL end
if spacing == nil then spacing = 1 end
if offset == nil then offset = 0 end
if backup == nil then backup = "x" end
if scale == nil then scale = 1 end
if info[1] ~= nil and info[1].id ~= nil then
info = convert_unicode_table_to_string_table(info)
end
CUSTOM_FONT_COUNT = CUSTOM_FONT_COUNT + 1
fontTable[CUSTOM_FONT_COUNT] = {
spritesheet = texture,
spacing = spacing,
offset = offset,
info = info,
backup = backup,
scale = scale,
}
return CUSTOM_FONT_COUNT
end
---@param fontType DjuiFontType
---@return nil
function djui_hud_set_font(fontType)
if fontType > FONT_COUNT then
customFont = true
customFontType = fontType
else
customFont = false
djui_classic_hud_set_font(fontType)
end
end
local textShake = 0
function djui_hud_effect_shake(intensity)
textShake = math.ceil(intensity*100)*0.01
end
local textWaveX = 0
local textWaveY = 0
local textWaveSpeed = 0
function djui_hud_effect_wave(x, y, speed)
textWaveX = x
textWaveY = y
textWaveSpeed = speed
end
---@param message string
---@param x number
---@param y number
---@param scale number
---@return nil
function djui_hud_print_text(message, x, y, scale)
if customFont then
if message == nil or message == "" then return end
local message = string_to_table(message)
local currFont = fontTable[customFontType]
y = y + currFont.offset
scale = scale*currFont.scale
for i = 1, #message do
local letter = message[i]
if letter and letter ~= " " then
if currFont.info[letter] == nil then
letter = currFont.backup
end
local scaleWidth = scale*(currFont.info[letter].height/currFont.info[letter].width)
djui_hud_render_texture_tile(currFont.spritesheet,
x + ((currFont.info[letter].xoffset or 0)*scale) + math.random(-textShake*100, textShake*100)*0.01 + math.sin((HudAnimTimer+i*2)*textWaveSpeed*0.1)*textWaveX,
y + ((currFont.info[letter].yoffset or 0)*scale) + math.random(-textShake*100, textShake*100)*0.01 + math.cos((HudAnimTimer+i*2)*textWaveSpeed*0.1)*textWaveY,
scaleWidth, scale,
currFont.info[letter].x,
currFont.info[letter].y,
currFont.info[letter].width,
currFont.info[letter].height)
else
letter = currFont.backup
end
x = x + (currFont.info[letter].width + currFont.spacing)*scale
end
else
djui_classic_hud_print_text(message, x, y, scale)
end
end
---@param message string
---@param prevX number
---@param prevY number
---@param prevScale number
---@param x number
---@param y number
---@param scale number
---@return nil
-- Custom Fonts do not currently support Interpolation due to lack of RESOLUTION_N64 support
function djui_hud_print_text_interpolated(message, prevX, prevY, prevScale, x, y, scale)
if customFont then
if message == nil or message == "" then return end
local message = string_to_table(message)
local currFont = fontTable[customFontType]
prevY = prevY + currFont.offset
y = y + currFont.offset
scale = scale*currFont.scale
for i = 1, #message do
local letter = message[i]
if letter and letter ~= " " then
if currFont.info[letter] == nil then
letter = currFont.backup
end
local prevScaleWidth = prevScale*(currFont.info[letter].height/currFont.info[letter].width)
local scaleWidth = scale*(currFont.info[letter].height/currFont.info[letter].width)
local xOffset = ((currFont.info[letter].xoffset or 0)*scale) + math.random(-textShake*100, textShake*100)*0.01 + math.sin((HudAnimTimer+i*2)*textWaveSpeed*0.1)*textWaveX
local yOffset = ((currFont.info[letter].yoffset or 0)*scale) + math.random(-textShake*100, textShake*100)*0.01 + math.cos((HudAnimTimer+i*2)*textWaveSpeed*0.1)*textWaveY
djui_hud_render_texture_tile_interpolated(currFont.spritesheet,
prevX + xOffset,
prevY + yOffset,
prevScaleWidth, prevScale,
x + xOffset,
y + yOffset,
scaleWidth, scale,
currFont.info[letter].x,
currFont.info[letter].y,
currFont.info[letter].width,
currFont.info[letter].height)
else
letter = currFont.backup
end
x = x + (currFont.info[letter].width + currFont.spacing)*scale
prevX = prevX + (currFont.info[letter].width + currFont.spacing)*prevScale
end
else
djui_classic_hud_print_text_interpolated(message, prevX, prevY, prevScale, x, y, scale)
end
end
---@param message string
---@return number
function djui_hud_measure_text(message)
if customFont then
if message == nil or message == "" then return end
local message = string_to_table(message)
local currFont = fontTable[customFontType]
local scale = 1
local x = 0
for i = 1, #message do
local letter = message[i]
if letter and letter ~= " " then
if currFont.info[letter] == nil then
letter = currFont.backup
end
else
letter = currFont.backup
end
x = x + (currFont.info[letter].width + currFont.spacing)*scale
end
return x
else
return djui_classic_hud_measure_text(message)
end
end
local function hud_update()
-- Reset Values Every Frame
textShake = 0
textWaveX = 0
textWaveY = 0
textWaveSpeed = 0
-- Update Basic Anim Timer
HudAnimTimer = HudAnimTimer + 1
end
hook_event(HOOK_ON_HUD_RENDER_BEHIND, hud_update)
-- Adding custom fonts here to prevent main clutter
fontdataCharacteristic = {
["A"] = {x = 0, y = 0, width = 26, height = 32},
["B"] = {x = 32, y = 0, width = 25, height = 32},
["C"] = {x = 32*2, y = 0, width = 25, height = 32},
["D"] = {x = 32*3, y = 0, width = 23, height = 32},
["E"] = {x = 32*4, y = 0, width = 24, height = 32},
["F"] = {x = 32*5, y = 0, width = 24, height = 32},
["G"] = {x = 32*6, y = 0, width = 26, height = 32},
["H"] = {x = 32*7, y = 0, width = 25, height = 32},
["I"] = {x = 0, y = 32, width = 15, height = 32},
["J"] = {x = 32, y = 32, width = 21, height = 32},
["K"] = {x = 32*2, y = 32, width = 25, height = 32},
["L"] = {x = 32*3, y = 32, width = 22, height = 32},
["M"] = {x = 32*4, y = 32, width = 29, height = 32},
["N"] = {x = 32*5, y = 32, width = 27, height = 32},
["Ñ"] = {x = 32*6, y = 32, width = 27, height = 32},
["O"] = {x = 32*7, y = 32, width = 26, height = 32},
["P"] = {x = 0, y = 32*2, width = 25, height = 32},
["Q"] = {x = 32, y = 32*2, width = 27, height = 32},
["R"] = {x = 32*2, y = 32*2, width = 25, height = 32},
["S"] = {x = 32*3, y = 32*2, width = 24, height = 32},
["T"] = {x = 32*4, y = 32*2, width = 28, height = 32},
["U"] = {x = 32*5, y = 32*2, width = 26, height = 32},
["V"] = {x = 32*6, y = 32*2, width = 27, height = 32},
["W"] = {x = 32*7, y = 32*2, width = 30, height = 32},
["X"] = {x = 0, y = 32*3, width = 28, height = 32},
["Y"] = {x = 32, y = 32*3, width = 27, height = 32},
["Z"] = {x = 32*2, y = 32*3, width = 27, height = 32},
["!"] = {x = 32*3, y = 32*3, width = 30, height = 32},
["?"] = {x = 32*4, y = 32*3, width = 27, height = 32},
["@"] = {x = 32*5, y = 32*3, width = 29, height = 32},
["#"] = {x = 32*6, y = 32*3, width = 29, height = 32},
["$"] = {x = 32*7, y = 32*3, width = 23, height = 32},
["%"] = {x = 0, y = 32*4, width = 27, height = 32},
["^"] = {x = 32, y = 32*4, width = 24, height = 32},
["&"] = {x = 32*2, y = 32*4, width = 29, height = 32},
["*"] = {x = 32*3, y = 32*4, width = 18, height = 32},
["("] = {x = 32*4, y = 32*4, width = 17, height = 32},
[")"] = {x = 32*5, y = 32*4, width = 17, height = 32},
["_"] = {x = 32*6, y = 32*4, width = 31, height = 32},
["-"] = {x = 32*7, y = 32*4, width = 23, height = 32},
["+"] = {x = 0, y = 32*5, width = 24, height = 32},
["="] = {x = 32, y = 32*5, width = 27, height = 32},
["<"] = {x = 32*2, y = 32*5, width = 23, height = 32},
[">"] = {x = 32*3, y = 32*5, width = 23, height = 32},
["."] = {x = 32*4, y = 32*5, width = 11, height = 32},
[","] = {x = 32*5, y = 32*5, width = 11, height = 32},
[":"] = {x = 32*6, y = 32*5, width = 11, height = 32},
[";"] = {x = 32*7, y = 32*5, width = 11, height = 32},
["/"] = {x = 0, y = 32*6, width = 28, height = 32},
["\\"] = {x = 32, y = 32*6, width = 28, height = 32},
['"'] = {x = 32*2, y = 32*6, width = 14, height = 32},
["'"] = {x = 32*3, y = 32*6, width = 9, height = 32},
["|"] = {x = 32*4, y = 32*6, width = 10, height = 32},
["~"] = {x = 32*5, y = 32*6, width = 23, height = 32},
["1"] = {x = 32*6, y = 32*6, width = 23, height = 32},
["2"] = {x = 32*7, y = 32*6, width = 26, height = 32},
["3"] = {x = 0, y = 32*7, width = 24, height = 32},
["4"] = {x = 32, y = 32*7, width = 24, height = 32},
["5"] = {x = 32*2, y = 32*7, width = 26, height = 32},
["6"] = {x = 32*3, y = 32*7, width = 26, height = 32},
["7"] = {x = 32*4, y = 32*7, width = 30, height = 32},
["8"] = {x = 32*5, y = 32*7, width = 22, height = 32},
["9"] = {x = 32*6, y = 32*7, width = 24, height = 32},
["0"] = {x = 32*7, y = 32*7, width = 24, height = 32},
}
FONT_CHARACTERISTIC = djui_hud_add_font(get_texture_info("char_select_font_characteristic"), fontdataCharacteristic, -5, 0, "X", 1)