GFX update :D

This commit is contained in:
Astronand committed 2026-10-04 19:45:35 -04:00
1 parent 05ca0f10a2
commit c1b4ef2644
70 files changed
+1398 -5174

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
Hyperion
Astronand
+232
View File
@@ -0,0 +1,232 @@
-- psf.lua
-- NeetComputers PSF1 & PSF2 font renderer
-- Copyright 2026 SpartanSoftware
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- MODULE API
-- psf.open(path, disk = 0) Returns a Font object, or nil + errmsg
--
-- FONT OBJECT API
-- font:print(x, y, text) Draw text in white
-- font:print(x, y, text, r, g, b) Draw text in given color
-- font:measure(text) Width of string in pixels
-- font:lineHeight() Font height in pixels
-- font:setSpacing(w) Set px width of glyph spacing
-- font:close() Free all layers
local psf = {}
local function readUInt(header, n)
local bytes = header.read(n)
if not bytes or #bytes < n then return nil end
local value = 0
for i = 1, n do
value = value + string.byte(bytes, i) * (256 ^ (i - 1))
end
return math.floor(value)
end
local function parseGlyph(bytes, w, h)
local bytesPerRow = math.floor((w + 7) / 8)
local pixels = {}
for y = 1, h do
pixels[y] = {}
for x = 1, w do
local byteIdx = (y - 1) * bytesPerRow + math.floor((x - 1) / 8) + 1
local bitPos = 7 - ((x - 1) % 8)
local b = string.byte(bytes, byteIdx) or 0
pixels[y][x] = (math.floor(b / (2 ^ bitPos)) % 2 == 1)
end
end
return pixels
end
local OFF_PIXEL = "\0\0\0\0"
local function getGlyphBuffer(glyph, r, g, b)
local cache = glyph._bufCache
if not cache then
cache = {}
glyph._bufCache = cache
end
local key = r * 65536 + g * 256 + b
local buf = cache[key]
if buf then return buf end
local onPixel = string.char(r, g, b, 255)
local pixels = glyph.pixels
local chunks = {}
local n = 0
for y = 1, glyph.height do
local row = pixels[y]
for x = 1, glyph.width do
n = n + 1
chunks[n] = row[x] and onPixel or OFF_PIXEL
end
end
buf = table.concat(chunks)
cache[key] = buf
return buf
end
local function parsePSF1(header, glyphs)
local mode = readUInt(header, 1)
local charsize = readUInt(header, 1)
if not charsize then return false, "truncated PSF1 header" end
local count = (mode and (mode % 4 >= 2)) and 512 or 256
for i = 0, count - 1 do
local raw = header.read(charsize)
if not raw or #raw < charsize then break end
glyphs[i] = { width = 8, height = charsize,
pixels = parseGlyph(raw, 8, charsize) }
end
return true, 8, charsize
end
local function parsePSF2(header, glyphs)
readUInt(header, 4)
local headersize = readUInt(header, 4)
readUInt(header, 4)
local numglyph = readUInt(header, 4)
local bytesperglyph = readUInt(header, 4)
local h = readUInt(header, 4)
local w = readUInt(header, 4)
if not w or not h then return false, "truncated PSF2 header" end
local consumed = 32
if headersize > consumed then
header.seek('cur', headersize - consumed)
end
for i = 0, numglyph - 1 do
local raw = header.read(bytesperglyph)
if not raw or #raw < bytesperglyph then break end
glyphs[i] = { width = w, height = h,
pixels = parseGlyph(raw, w, h) }
end
return true, w, h
end
local Font = {}
Font.__index = Font
function Font:print(x, y, text, r, g, b)
assert(not self._closed, "psf: font has been closed")
r = r or 255
g = g or 255
b = b or 255
local sw = screen.getSize()
local cur = x
local spacing = self._spacing
for i = 1, #text do
if cur >= sw then break end
local code = string.byte(text, i)
local glyph = self._glyphs[code]
if glyph then
local buf = getGlyphBuffer(glyph, r, g, b)
screen.drawPixels(cur, y, buf, glyph.width, glyph.height)
cur = cur + glyph.width + spacing
end
end
end
function Font:measure(text)
local w = 0
local count = 0
for i = 1, #text do
local g = self._glyphs[string.byte(text, i)]
if g then
w = w + g.width
count = count + 1
end
end
if count > 1 then
w = w + self._spacing * (count - 1)
end
return w
end
function Font:lineHeight()
return self._height
end
function Font:close()
if self._closed then return end
for _, glyph in pairs(self._glyphs) do
glyph._bufCache = nil
end
self._glyphs = {}
self._closed = true
end
function Font:setSpacing(px)
self._spacing = px
end
function psf.open(path, disk)
disk = disk or 0
if not files.exists(path, disk) then
return nil, "file not found: " .. path
end
local ok, header = pcall(files.open, path, 'rb', disk)
if not ok or not header then
return nil, "could not open: " .. path
end
local magic = header.read(2)
if not magic or #magic < 2 then
header.close()
return nil, "could not read magic bytes"
end
local b1, b2 = string.byte(magic, 1), string.byte(magic, 2)
local glyphs = {}
local ok, w, h
if b1 == 0x36 and b2 == 0x04 then
ok, w, h = parsePSF1(header, glyphs)
elseif b1 == 0x72 and b2 == 0xb5 then
header.read(2)
ok, w, h = parsePSF2(header, glyphs)
else
header.close()
return nil, string.format("not a PSF file (magic: %02x %02x)", b1, b2)
end
header.close()
if not ok then
return nil, w
end
return setmetatable({
_glyphs = glyphs,
_width = w,
_height = h,
_spacing = 0,
_closed = false,
}, Font)
end
return psf
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
vector
+1
View File
@@ -0,0 +1 @@
package providing kernel support for framebuffers and graphics
+19
View File
@@ -0,0 +1,19 @@
function lib.load(fd)
function handle.setPixel(x,y,color24)
function handle.getPixel(x,y)
function handle.setPixels(x,y,w,framebuffer)
function handle.getPixels(x,y,w,h)
function handle.frame(x,y,w,h,writeonly)
integer id
recurse lib.load
function handle.framectl(id)
function frame.move(x,y)
function frame.resize(w,h)
function frame.free()
function handle.sync()
function handle.line(x1,y1,x2,y2)
function handle.box(x,y,w,h,c,fill)
function handle.filledBox(x,y,w,h,c)
function handle.text(x,y,font,text)
function handle.free()
function handle.size()
View File
Whitespace-only changes.
+256
View File
@@ -0,0 +1,256 @@
#000000
#0b0b0b
#222222
#444444
#555555
#777777
#888888
#aaaaaa
#bbbbbb
#dddddd
#eeeeee
#00000b
#000022
#000044
#000055
#000077
#000088
#0000aa
#0000bb
#0000dd
#0000ee
#000b00
#002200
#004400
#005500
#007700
#008800
#00aa00
#00bb00
#00dd00
#00ee00
#0b0000
#220000
#440000
#550000
#770000
#880000
#aa0000
#bb0000
#dd0000
#ee0000
#000033
#000066
#000099
#0000cc
#0000ff
#003300
#003333
#003366
#003399
#0033cc
#0033ff
#006600
#006633
#006666
#006699
#0066cc
#0066ff
#009900
#009933
#009966
#009999
#0099cc
#0099ff
#00cc00
#00cc33
#00cc66
#00cc99
#00cccc
#00ccff
#00ff00
#00ff33
#00ff66
#00ff99
#00ffcc
#00ffff
#330000
#330033
#330066
#330099
#3300cc
#3300ff
#333300
#333333
#333366
#333399
#3333cc
#3333ff
#336600
#336633
#336666
#336699
#3366cc
#3366ff
#339900
#339933
#339966
#339999
#3399cc
#3399ff
#33cc00
#33cc33
#33cc66
#33cc99
#33cccc
#33ccff
#33ff00
#33ff33
#33ff66
#33ff99
#33ffcc
#33ffff
#660000
#660033
#660066
#660099
#6600cc
#6600ff
#663300
#663333
#663366
#663399
#6633cc
#6633ff
#666600
#666633
#666666
#666699
#6666cc
#6666ff
#669900
#669933
#669966
#669999
#6699cc
#6699ff
#66cc00
#66cc33
#66cc66
#66cc99
#66cccc
#66ccff
#66ff00
#66ff33
#66ff66
#66ff99
#66ffcc
#66ffff
#990000
#990033
#990066
#990099
#9900cc
#9900ff
#993300
#993333
#993366
#993399
#9933cc
#9933ff
#996600
#996633
#996666
#996699
#9966cc
#9966ff
#999900
#999933
#999966
#999999
#9999cc
#9999ff
#99cc00
#99cc33
#99cc66
#99cc99
#99cccc
#99ccff
#99ff00
#99ff33
#99ff66
#99ff99
#99ffcc
#99ffff
#cc0000
#cc0033
#cc0066
#cc0099
#cc00cc
#cc00ff
#cc3300
#cc3333
#cc3366
#cc3399
#cc33cc
#cc33ff
#cc6600
#cc6633
#cc6666
#cc6699
#cc66cc
#cc66ff
#cc9900
#cc9933
#cc9966
#cc9999
#cc99cc
#cc99ff
#cccc00
#cccc33
#cccc66
#cccc99
#cccccc
#ccccff
#ccff00
#ccff33
#ccff66
#ccff99
#ccffcc
#ccffff
#ff0000
#ff0033
#ff0066
#ff0099
#ff00cc
#ff00ff
#ff3300
#ff3333
#ff3366
#ff3399
#ff33cc
#ff33ff
#ff6600
#ff6633
#ff6666
#ff6699
#ff66cc
#ff66ff
#ff9900
#ff9933
#ff9966
#ff9999
#ff99cc
#ff99ff
#ffcc00
#ffcc33
#ffcc66
#ffcc99
#ffcccc
#ffccff
#ffff00
#ffff33
#ffff66
#ffff99
#ffffcc
#ffffff
View File
Whitespace-only changes.
+1
View File
@@ -0,0 +1 @@
1.0.0