I wanted to achieve this effect with fill patterns for a recent project I started so I figured I'd share it here incase anyone else is interested in using it.
The local fill pattern function is shifting each row/column in the fill pattern by given x and y amount. It's using binary arithmetics and a cache of shift masks.
Here's the original code for version 1.0, takes 126 tokens:
EDIT:
With great contributions and improvements by Felice here's a both faster, smaller and more API consistent version 2.0, takes 87 tokens:
Hope you find it useful!


Good idea!
I refined your methods and took a fair chunk of the math and tokens off (now 80 tokens). Here's my version:
_fillp_xmask_lo={[0]=0xffff,0x7777,0x3333,0x1111} _fillp_xmask_hi={[0]=0x0000,0x8888,0xcccc,0xeeee} function fillp_local(x,y,p) x=band(x,3) local p16=flr(p) local p32=rotr(p16+lshr(p16,16),band(y,3)*4+x) return fillp(p-p16+flr(band(p32,_fillp_xmask_lo[x])+band(rotl(p32,4),_fillp_xmask_hi[x]))) end |
And a demo thereof:


Thanks Felice,
this is a very nice addition. Would you mind if I edit the original post with an update of your refined version?
Edit: I just noticed however, that your version doesn't respect the additional (floating point?) bits you can provide to a pattern to specify ignoring the second color from drawing. For instance, this pattern would not draw as intended:
local pattern=0b1110100110011010.1 fillp_local(x,y,pattern) |
Once that is fixed I'll update the OP with your improvements, given you're alright with that.
Regards.


Do as you like with the code, I marked it creative commons for that reason. :)
It should be retaining the fractional transparency bit. I don't remember testing that so I may have failed to do it right. That's what the p-p16 is where I send the value on to fillp--the original pattern minus the integer bits, leaving the fractional bits, which are added to the resulting shifted pattern.


Oh, okay, I see what I did.
When I was rearranging code, I accidentally moved that p-p16 inside of the flr(), effectively deleting it.
Easy fix. See my original post for an updated version and a demo that <gasp> actually tests the transparency support. ;)


Actually...
One option would be to write a flat-out replacement for fillp() that takes optional x,y args after the pattern and shifts the pattern if so. That would add to the API pretty seamlessly, while not adding complexity and still keeping backwards compatibility.
Something like this:
_fillp_xmask_lo={[0]=0xffff,0x7777,0x3333,0x1111} _fillp_xmask_hi={[0]=0x0000,0x8888,0xcccc,0xeeee} _fillp_original=fillp function fillp(p,x,y) if y then x=band(x,3) local p16=flr(p) local p32=rotr(p16+lshr(p16,16),band(y,3)*4+x) p+=flr(band(p32,_fillp_xmask_lo[x])+band(rotl(p32,4),_fillp_xmask_hi[x]))-p16 end return _fillp_original(p) end |
It costs 7 more tokens, but it just feels more natural, and in keeping with the rest of the API, to extend an existing function. Other calls like map() and sspr() do similar things.
Obligatory demo:


67 tokens with more arithmetic, no tables, and an otherwise pointless local x (not counting tokens for backward compatibility defaults)
local _fillp = fillp local function fillp(p, x, y) p, x, y = p or 0, x or 0, y or 0 -- to maintain drop-in replacement compatibility with fillp(p) local p16, x = flr(p), band(x, 3) local f, p32 = flr(15 / 2 ^ x) * 0x1111, rotr(p16 + lshr(p16, 16), band(y, 3) * 4 + x) return _fillp(p - p16 + flr(band(p32, f) + band(rotl(p32, 4), 0xffff - f))) end |
and thanks to Felice's response on Discord, here it is with shl instead of ^, faster but two more tokens
local _fillp = fillp local function fillp(p, x, y) p, x, y = p or 0, x or 0, y or 0 -- to maintain drop-in replacement compatibility with fillp(p) local p16, x = flr(p), band(x, 3) local f, p32 = flr(15 / shl(1,x)) * 0x1111, rotr(p16 + lshr(p16, 16), band(y, 3) * 4 + x) return _fillp(p - p16 + flr(band(p32, f) + band(rotl(p32, 4), 0xffff - f))) end |
[Please log in to post a comment]