First off... um, you branched into theoretical number-churning code at a level I never touch. Most of it didn't make much sense to me except that it looked to allow for a way to calculate arbitrary bit-field-sized and scaling values in one shot, instead of simply trying a couple of times from a quick estimate and fine-tuning until one gets it right like I choose to do.
I'm not much for complicated equations when simple guess-and-check is easy to do. And I perform exhaustive tests regardless. I don't trust 'magic equations' when I have to hand-verify things work identically anyways.
And, um... why are you supporting 6 bits of green? The SNES only calculated things at 5 bits of green.
And blue and red were reversed from normal PC format.
machines. Specifically things like the Pentium MMX and Pentium 2. Newer machines will benefit from the smaller code-size, but the older machines need the most help. And a large part of that is by supporting zSNES native pixel format and outputting native PC pixel format directly.
Also, note that I am already putting the entire bias into the Green table, and the 'trick' I'm using for combining the red/blue tables is internally bit-negating (SLIGHTLY different than properly negating) the r-b value. And I adjusted the mask already as I realized since we're only adding three numbers together we can never 'toggle' the guard-bit twice so I avoided one bit-mask at the tail of the code so I'm down to 11 instructions of which all but 3 (one at the beginning and one at the end) pair on Pentium MMX/Pentium Pro/Pentium 2.
Code: Select all
#define RB(y,u,v) (((y)&0x3FF)<<22)|(((u)&0x3FF)<<11)|((v)&0x3FF)
#define GO(y,v) ((((y)+64)&0x3FF)<<22)|(16<<11)|(((v)+16)&0x3FF)
unsigned int DiffTable[128] = {
RB(-85, 160, 80), RB(-83, 155, 77), RB(-80, 150, 75), RB(-77, 145, 72),
RB(-75, 140, 70), RB(-72, 135, 67), RB(-69, 130, 65), RB(-67, 125, 62),
RB(-64, 120, 60), RB(-61, 115, 57), RB(-59, 110, 55), RB(-56, 105, 52),
RB(-53, 100, 50), RB(-51, 95, 47), RB(-48, 90, 45), RB(-45, 85, 42),
RB(-43, 80, 40), RB(-40, 75, 37), RB(-37, 70, 35), RB(-35, 65, 32),
RB(-32, 60, 30), RB(-29, 55, 27), RB(-27, 50, 25), RB(-24, 45, 22),
RB(-21, 40, 20), RB(-19, 35, 17), RB(-16, 30, 15), RB(-13, 25, 12),
RB(-11, 20, 10), RB( -8, 15, 7), RB( -5, 10, 5), RB( -3, 5, 2),
RB( 0, 0, 0), RB( 2, -5, -2), RB( 5, -10, -5), RB( 7, -15, -7),
RB( 10, -20, -10), RB( 13, -25, -12), RB( 15, -30, -15), RB( 18, -35, -17),
RB( 21, -40, -20), RB( 23, -45, -22), RB( 26, -50, -25), RB( 29, -55, -27),
RB( 31, -60, -30), RB( 34, -65, -32), RB( 37, -70, -35), RB( 39, -75, -37),
RB( 42, -80, -40), RB( 45, -85, -42), RB( 47, -90, -45), RB( 50, -95, -47),
RB( 53,-100, -50), RB( 55,-105, -52), RB( 58,-110, -55), RB( 61,-115, -57),
RB( 63,-120, -60), RB( 66,-125, -62), RB( 69,-130, -65), RB( 71,-135, -67),
RB( 74,-140, -70), RB( 77,-145, -72), RB( 79,-150, -75), RB( 82,-155, -77),
GO(-84, -160), GO(-81, -155), GO(-78, -150), GO(-76, -145),
GO(-73, -140), GO(-70, -135), GO(-68, -130), GO(-65, -125),
GO(-63, -120), GO(-60, -115), GO(-57, -110), GO(-55, -105),
GO(-52, -100), GO(-49, -95), GO(-47, -90), GO(-44, -85),
GO(-42, -80), GO(-39, -75), GO(-36, -70), GO(-34, -65),
GO(-31, -60), GO(-28, -55), GO(-26, -50), GO(-23, -45),
GO(-21, -40), GO(-18, -35), GO(-15, -30), GO(-13, -25),
GO(-10, -20), GO( -7, -15), GO( -5, -10), GO( -2, -5),
GO( 0, 0), GO( 2, 4), GO( 5, 9), GO( 7, 14),
GO( 10, 19), GO( 13, 24), GO( 15, 29), GO( 18, 34),
GO( 21, 39), GO( 23, 44), GO( 26, 49), GO( 28, 54),
GO( 31, 59), GO( 34, 64), GO( 36, 69), GO( 39, 74),
GO( 42, 79), GO( 44, 84), GO( 47, 89), GO( 49, 94),
GO( 52, 99), GO( 55, 104), GO( 57, 109), GO( 60, 114),
GO( 63, 119), GO( 65, 124), GO( 68, 129), GO( 70, 134),
GO( 73, 139), GO( 76, 144), GO( 78, 149), GO( 81, 154),
};
int ExpandedDiff(unsigned int c0, unsigned int c1) {
unsigned int acum, diff, slot;
diff = c0;
diff -= c1;
slot = (long int)(( signed char)diff);
diff += 0x8020;
diff >>= 10;
acum = DiffTable[slot + 32];
slot = (long int)((unsigned char)diff);
acum ^= (0x3FF << 11);
diff >>= 11;
acum += DiffTable[slot + 0];
slot = (long int)(( signed char)diff);
acum += DiffTable[slot + 96];
return acum; /* BITMASK = 0xE01F03E0 */
}