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]