I don't see anything wrong with the actual pattern system, but it feels weird that specifying the pattern, the color, and the transparency is all split across multiple commands.
What if we could put it all in one place? What if I wanted a hideous red/green checkerboard, and could say so right in the rect() that drew it?
Well, there's room in the color parameter to do it:
rect(0,0,127,127,0xb8.a5a5) |
Where b is color 11, green, 8 is color 9, red, and a5a5 is pattern 1010/0101/1010/0101. All in one combined, dithered, eye-bleeding "color."
Also, we can handle transparency. Let's say we want a less-hideous red/transparent checkerboard:
rect(0,0,127,127,0x108.a5a5) |
Where the leading 1 means the second color (which was green) is transparent. Basically, if the second color is 16 (0x10) it's transparent.
This actually mirrors the poke-able pal/palt() registers, where the color is 00-0f if opaque and 10-1f if transparent. Calling pal() sets the bottom four bits, and calling palt() sets or clears the fifth bit.
There's a caveat, though. A lot of us do demo trickery where we treat the color value as automatically getting floored. So we might need a flag that says whether or not to treat colors oldschool or this way. Either a poke() trick or maybe a dithcol(true|false) call.
What do you guys think? I just feel like this would unify stuff so much better.
Edit: Worth noting is that if you just pass, say, "8" for red, you get the usual behavior, because that's actually 0x008.0000, which is an opaque red/black color pair with a solid dither pattern (all 0's) that choose only the red color.
In short, the default behavior would match the normal usage. This wouldn't require any changes for people who use the API the way it's always been. |
Edit 2: Instead of having two transparency flags, which is silly since two transparent colors would be pointless, I've eliminated the first one, so if you wanted a red/green pattern, it'd be identical to the current color argument (0xb8) and if you wanted red/transparent you'd put the flag in the third nybble (0x108). This feels friendlier and more backwards-compatible with the new system. |
interesting! specifying the pattern itself in the color argument is not as compelling to me (though I wouldn't complain if that was allowed as an option), but having the transparency get specified as part of the color argument makes a lot of sense to me, especially given the information (which I didn't know) that the pal/palt bits are organized that way
Well the nice thing about the pattern is that if you don't specify one, e.g. just pass "8" for red, then the pattern would implicitly be ".0000" or solid. So it's not actually required to pass it under normal circumstance. It's only needed when you have a second color.
I really should have mentioned that. I might have scared people off by making them think you always have to specify it.
Note there's already an extended color notation:
To specify a second colour for the pattern, use the high bits of any colour parameter:
FILLP(0b0011010101101000)
CIRCFILL(64,64,20, 0x4E) -- brown and pink
but that still leaves the higher bits for transparency.
@Felice
right, I understood that part and it does seem like a nifty idea! I was just trying to say I still like the idea of fillp() being able to be separate as an option (for setting just the pattern), so that one call of fillp() can affect multiple subsequent draw calls, like color(). But I guess since color can also be specified as an argument to the draw call, if pattern also could be optionally specified like that, it would feel consistent!
Yeah, I considered putting the two transparency bits in the top nybbles instead, but I wanted to make it consistent with the pseudo-hardware registers.
But yeah, you could just extend the existing format by swapping the second and third nybbles in my format.
Actually, maybe that would better for us even if it's not consistent with the hardware registers, because it means if you just want non-transparent red/green you only need to say "b8" instead of "b08" or "0b08".
In fact, really we don't actually need two transparency bits, because setting both to 1 is somewhat nonsensical. So maybe it should be three nybbles: transparency flag, color 1, color 0 (top to bottom).
So, uh, good point. :) I think I'll revise the proposal.
Also, perhaps we could say that the dither pattern IN the color argument is only used if the top bit is set? So 0x108.a5a5 ignores the fractional bits and uses the fillp() value, but 0x8108.a5a5 uses the fractional bits for the pattern.
Not sure about this, since it means you have to type all 4 digits every time you specify a pattern, though with the pattern you're already typing a lot of numbers anyway. Hmm. I think I still prefer setting a global behavior flag somehow.
Hm, maybe if you called fillp() with no args, or fillp(false) it could be how we trigger this behavior?
[Please log in to post a comment]