Log In  

I'm writing a simple toy program to get familiar with the API.

I have a string, "Hello World!", that I am intending to print centred horizontally and vertically, adapting to window dimensions on the fly.
In the top line in the screenshot I am printing it in one go, in the bottom line I am printing it letter by letter to enable a "rainbow" effect.

I noticed the two strings are spaced differently, and I realised Picotron in fact uses a variable-width font. I was allotting 5 pixels for each character in my printing routine, but as it turns out the lowercase "l" is one pixel narrower, while the uppercase "W" is one pixel wider.

How do I deal with the variable width of characters for printing and layout work? Is there an API function to get the exact dimensions of a character?

My code:

---[[ Comment/uncomment to run fullscreen/windowed
window{
    width = 240,
    height = 120+32,
    title = "Tester"
}
--]]
text="Hello World!"

function _draw()
    local width = get_display():width()
    local height = get_display():height()
    local align = width/2-((string.len(text)-1)*5/2)    -- Assuming char width 5
    cls()

--Print all text in one go
    print(text, align, height/2-8, 9)

--Print text letter by letter
    for i = 1,string.len(text) do
        print(string.sub(text,i,i),align+5*(i-1),height/2+4,i)  -- Assuming char width 5
    end

--Print CPU usage
    print(stat(1), width-48, height-7)
end

function _update()

end

Incidentally, is there a more compact method of accessing individual characters in a string like was added in PICO-8 (string[i]), or are we expected to purely use the Lua method in Picotron (string.sub(string,i,i))?

P#143132 2024-03-15 15:40 ( Edited 2024-03-15 15:43)

1

In Pico-8, print returns the X-coordinate that the next character would hypothetically start at if it existed. This explicitly supports a pattern of printing something offscreen at X=0 to get the width of the text rendered by the print statement, potentially with a trailing between-letter gap (experiment to find out). So does printing one character offscreen (at x=0, y=-9999 or something) return the one-character width?

P#143154 2024-03-15 16:52

Yep, print(print('W',0,-99)) prints 6 as expected, and 4 for 'l'! Thank you!

So, thinking about that then.... The print function could somehow be hooked up recursively to print successive characters in a line. That'll be a fun puzzle to think about! I'll get to it.

P#143163 2024-03-15 17:18

It works! And it's computationally cheaper this way, too.

(CPU usage value is only higher than in my previous screenshot because I added more other stuff to my code in the meantime.)
Code:

--[[ Comment/uncomment to run fullscreen/windowed
window{
    width = 240,
    height = 120+32,
    title = "Tester"
}
--]]
text="Hello World!"

function _update()

end

function _draw()
    local width = get_display():width()
    local height = get_display():height()
    local align = width/2-((string.len(text)-1)*5/2)    -- Assuming char width 5
--  local align = width/2-(print(text,0,-99)/2)         -- Exact (but more expensive)
    cls()

--Print all text in one go
    print(text, align, height/2-8, 9)

--Print text letter by letter
    local nextX = align
    for i = 1,string.len(text) do
        nextX = print(sub(text,i,i),nextX,height/2+4,i)     -- Use x coordinate from return value of print
    end

--Print CPU usage
    print(stat(1), width-48, height-7)
end

P#143172 2024-03-15 18:14 ( Edited 2024-03-15 19:26)

[Please log in to post a comment]