Log In  

Early on in playing around with PICO-8 I wrote a function to print text with a black outline.

function prt_out(s,x,y,c)
print(s,x-1,y,0)
print(s,x+1,y)
print(s,x,y-1)
print(s,x,y+1)
print(s,x,y,c)
end

I imagine a lot of people have also done this and I can't be the only person who found it a bit clumsy and, near the end of a project when casting about for tokens, wondered if those five very similar print calls couldn't be reduced.

Nowadays we have P8SCII so I thought I'd have a look. Here are some candidates I've written with their token counts and times from my crude testing:

function p1(s,x,y,c) -- 42 tokens, 5.6 seconds
?'\f0\-f'..s..'\^g\-h'..s..'\^g\|f'..s..'\^g\|h'..s..'\^g\f'..chr(c+(c>9 and 87 or 48))..s,x,y
end

function p2(s,x,y,c) -- 26 tokens, 6.2667 seconds
for i in all(split'\f0\-f,\-h,\|f,\|h') do
?i..s,x,y
end
?s,x,y,c
end

function p3(s,x,y,c) -- 38 tokens, 5.6667 seconds
?'\f0\-f'..s..'\^g\-h'..s..'\^g\|f'..s..'\^g\|h'..s..'\^g\f'..sub(tostr(c,1),6,6)..s,x,y
end

function p4(s,x,y,c) -- 30 tokens, 5.7 seconds
?'\f0\-f'..s..'\^g\-h'..s..'\^g\|f'..s..'\^g\|h'..s,x,y
?s,x,y,c
end

function p5(s,x,y,c) -- 42 tokens, 6.1 seconds
print(s,x-1,y,0)
print(s,x+1,y)
print(s,x,y-1)
print(s,x,y+1)
print(s,x,y,c)
end

function p6(s,x,y,c) -- 29 tokens, 6.2 seconds
for _,i in pairs{'\f0\-f','\-h','\|f','\|h'} do
?i..s,x,y
end
?s,x,y,c
end

function p7(s,x,y,c) -- 37 tokens, 6.2667 seconds
for i in all{'\f0\-f','\-h','\|f','\|h','\f'..chr(c+(c>9 and 87 or 48))} do
?i..s,x,y
end
end

function p8(s,...) -- 21 tokens, 6.3 seconds
for i in all(split'\-f\f0,\-h\f0,\|f\f0,\|h\f0') do
?i..s,...
end
?s,...
end

'?' vs print makes no difference to performance, but does save characters and 1 token each use.

I was rather surprised that p2 uses so few tokens and isn't that slow. Also that p1 is actually the fastest (but only just).

I usually find that tokens are more precious to me than a tiny bit of performance so I'm likely to use p2 above (or p8 even). p4 is pretty cheap at 30 tokens and faster than the naive approach so perhaps it's an overall winner (so far).

I'm very interested to know if anyone has a better way(?)

v1 edit:

  • freds72's suggestion is p6. 3 more tokens for .0667 seconds faster. Using pairs() instead of all() causes half of that saving.
    I thought removing the split might make more difference than that, but now I feel a bit better about having split all over my game code to save tokens(!)
  • I removed the unnecessary '\^g' (go home) parts from the P8SCII snippets where appropriate. This saves some characters and performance (but also somehow saved the odd token and I'm not sure how).

v2 edit:

  • a new winner for tokens: p8 at 21! But at the cost of being the slowest at 6.3 seconds in my test. Not by much though. It still works because the P8SCII overrides the colour value being passed.

Cart #drakeblue_prt_out-2 | 2021-11-11 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
10

Bonus

Specify the colour of the outline:

function p4bonus(s,x,y,c,o) -- 34 tokens, 5.7 seconds
color(o)
?'\-f'..s..'\^g\-h'..s..'\^g\|f'..s..'\^g\|h'..s,x,y
?s,x,y,c
end

(Please use any of these functions however you want)

P#98796 2021-10-17 18:19 ( Edited 2021-11-11 14:07)

good set of options!
minor comment:

-- this is valid, to avoid a split for P2
for _,i in pairs{'a','b'} do
...
end
P#98802 2021-10-17 20:26

Thanks :) - I gave that a go just now and edited the post.

P#98811 2021-10-18 09:01
:: dw817

Here is mine, 19-tokens. Full edges.

function p0(t,x,y,c)
?"\^i"..t,x,y,c
?t,x,y,0
end

function _draw()
 cls(13)
 for i=1,15 do
  p0("some nice outlined text",18,i*8-3,i)
 end 
end

Even then I think this can be optimized further.

P#99950 2021-11-11 20:21

Very nice :)

These could be:

function p0(t,...) -- 14 tokens
?"\^i"..t.."\^-i\^g\f0"..t,...
end

or

function p0(t,...) -- 15 tokens
?"\^i"..t,...
?"\f0"..t,...
end

Although obv they have a different style of outline.

There's also:

function p01(t,...) -- 10 tokens
?"\#0"..t,...
end
P#99975 2021-11-12 14:18
:: dw817

Thanks ! I'm glad you like it, @drakeblue.

I am a little disappointed though. I know in my original suggestions, one of which was for outline text, that he did not make it where you can choose where the shade appears, optionally on all or a few of the 8-sides.

https://www.lexaloffle.com/bbs/?tid=35330

Hmm ... let me see if I can do that today - not really trying to keep the token count down though.

Cart #yesijipipa-0 | 2021-11-12 | Code ▽ | Embed ▽ | No License

This gives you total freedom to have any outline you want and from any angle or series of angles.

P#99983 2021-11-12 17:09 ( Edited 2021-11-12 17:10)

[Please log in to post a comment]

Follow Lexaloffle:        
Generated 2021-12-07 08:36:36 | 0.034s | Q:22