Hmmm... I might need a bit more help.
My aim is to be able to create the full range of 32-bit colors in AGS Script. I had the idea that you could do this by combining two 16-bit colors with alpha-transparency, using DrawImage to overlay one on another. (Thereby creating a sprite of the desired color, which you could then use to draw with.) My initial calculations seemed to prove that you could create any 32-bit color in this way, and that the 12% transparency setting (corresponding to a 255-alpha of 224) would be a good basis for mixing, with less than a .2 error in any of the RGB values produced (which I assumed would be rounded to the closest). By precalculating a lookup-table for every 0-255 value (actually two tables, one for the 5-bit channels and one for the 6-bit channel), I can figure out which two colors to mix, calculating each channel separately.
However, I'm finding that my calculations don't produce quite the correct colors. Presumably AGS (which is to say, Allegro) doesn't use the same calculation I am using to figure out the combined color when using DrawImage().
My initial attempt was this:
#define COLOR_MIX_PERCENT 12
{
// ...
int c1, c2; // These are the 0-255 values of one of the RGB channels that we're mixing.
int alpha = ((100-COLOR_MIX_PERCENT)*255)/100;
float alphaFloat = IntToFloat(alpha) / 255.0; // Gives alpha as a float in [0.0, 1.0]
float colMixFloat = IntToFloat(c1)*alphaFloat + IntToFloat(c2)*(1.0-alphaFloat);
int c = FloatToInt(cm, eRoundNearest);
}
This calculates the exact mix of the two colors using the 255-alpha proportion, then rounds to the nearest integer value. However, I find that the actual result of doing this mix is, for almost all values, darker than my predicted/desired result.
OK, so probably the graphics routine takes a few shortcuts, and calculates the mix with int operations (rounding down)?
#define COLOR_MIX_PERCENT 12
{
// ...
int c1, c2; // These are the 0-255 values of one of the RGB channels that we're mixing.
int alpha = ((100-COLOR_MIX_PERCENT)*255)/100;
int c = (c1*alpha + c2*(255-alpha)) / 255;
}
This is closer, but still not correct. For example, it predicts that a 12% mix of 115 + 88% of 8 should give 21:
int c = (8*224 + 115*(255-224)) / 255; // division gives 21.008, rounded down to 21
However, in reality it gives 20. So maybe it's dividing by 256 instead of 255, to speed things up further? Making that substitution gives the right result for most values, but now the mix 0.12*247 + 0.88*255, which should give 253 by this formula, actually appears as 254 on screen.
So I'm a bit stumped. I need to replicate the exact calculation used by DrawImage() under the hood to do the alpha-blending (or at least a calculation that gives the same result). I've tried to dig into the engine code on github to see what's going on, and I get as far as
draw_trans_sprite() in
include/allegro/gfx.hWhen I look at Allegro documentation, it looks like they have a bunch of different libraries/routines (Fblend, Fladimir's alpha blending routines, etc.), and I have no clue exactly which version AGS is using.