Cleaner and better blending logic for backgrounds.

For info, not performing blending if BLDALPHA_EVA is 16 can cause glitches.
This commit is contained in:
luigi__ 2009-01-18 16:40:31 +00:00
parent 15904d31de
commit d652b5a0f4
1 changed files with 46 additions and 63 deletions

View File

@ -622,40 +622,32 @@ static BOOL setFinalBGColorSpecialNone (GPU *gpu, u32 passing, u8 bgnum, u8 *dst
static BOOL setFinalBGColorSpecialBlend (GPU *gpu, u32 passing, u8 bgnum, u8 *dst, u16 color, u16 x)
{
if ((gpu->BLDCNT >> bgnum)&1 && gpu->BLDALPHA_EVA)
if(gpu->BLDCNT & (1 << bgnum))
{
u16 sourceFraction = gpu->BLDALPHA_EVA, sourceR, sourceG, sourceB,targetFraction;
if (!sourceFraction) return 0;
int bg_under = gpu->bgPixels[x];
u16 final = color;
// no fraction of this BG to be showed, so don't do anything
sourceR = ((color & 0x1F) * sourceFraction) >> 4 ;
// weighted component from color to draw
sourceG = (((color>>5) & 0x1F) * sourceFraction) >> 4 ;
sourceB = (((color>>10) & 0x1F) * sourceFraction) >> 4 ;
targetFraction = gpu->BLDALPHA_EVB;
if (targetFraction) {
// when we dont take any fraction from existing pixel, we can just draw
u16 targetR, targetG, targetB;
color = T2ReadWord(dst, passing) ;
//if (color & 0x8000) {
// the existing pixel is not invisible
targetR = ((color & 0x1F) * targetFraction) >> 4 ; // weighted component from color we draw on
targetG = (((color>>5) & 0x1F) * targetFraction) >> 4 ;
targetB = (((color>>10) & 0x1F) * targetFraction) >> 4 ;
// limit combined components to 31 max
sourceR = std::min(0x1F,targetR+sourceR) ;
sourceG = std::min(0x1F,targetG+sourceG) ;
sourceB = std::min(0x1F,targetB+sourceB) ;
//}
/* If the layer we are drawing on is selected as 2nd source, we can blend */
if(gpu->BLDCNT & (0x100 << bg_under))
{
COLOR c1, c2, cfinal;
c1.val = color;
c2.val = T2ReadWord(dst, passing);
cfinal.bits.red = std::min<int>(31, ((c1.bits.red * gpu->BLDALPHA_EVA / 16) + (c2.bits.red * gpu->BLDALPHA_EVB / 16)));
cfinal.bits.green = std::min<int>(31, ((c1.bits.green * gpu->BLDALPHA_EVA / 16) + (c2.bits.green * gpu->BLDALPHA_EVB / 16)));
cfinal.bits.blue = std::min<int>(31, ((c1.bits.blue * gpu->BLDALPHA_EVA / 16) + (c2.bits.blue * gpu->BLDALPHA_EVB / 16)));
final = cfinal.val;
}
color = (sourceR & 0x1F) | ((sourceG & 0x1F) << 5) | ((sourceB & 0x1F) << 10) | 0x8000 ;
T2WriteWord(dst, passing, color);
T2WriteWord(dst, passing, (final | 0x8000));
gpu->bgPixels[x] = bgnum;
}
else
{
T2WriteWord(dst, passing, color);
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = bgnum;
}
@ -752,43 +744,34 @@ static BOOL setFinalBGColorSpecialBlendWnd (GPU *gpu, u32 passing, u8 bgnum, u8
renderline_checkWindows(gpu,bgnum,x, &windowDraw, &windowEffect);
if (((gpu->BLDCNT >> bgnum)&1) && windowEffect) // the bg to draw has a special color effect
if(windowDraw)
{
u16 sourceFraction = gpu->BLDALPHA_EVA,
sourceR, sourceG, sourceB,targetFraction;
if (!sourceFraction)
return 0;
// no fraction of this BG to be showed, so don't do anything
sourceR = ((color & 0x1F) * sourceFraction) >> 4 ;
// weighted component from color to draw
sourceG = (((color>>5) & 0x1F) * sourceFraction) >> 4 ;
sourceB = (((color>>10) & 0x1F) * sourceFraction) >> 4 ;
targetFraction = gpu->BLDALPHA_EVB;
if (targetFraction) {
// when we dont take any fraction from existing pixel, we can just draw
u16 targetR, targetG, targetB;
color = T2ReadWord(dst, passing) ;
//if (color & 0x8000) {
// the existing pixel is not invisible
targetR = ((color & 0x1F) * targetFraction) >> 4 ; // weighted component from color we draw on
targetG = (((color>>5) & 0x1F) * targetFraction) >> 4 ;
targetB = (((color>>10) & 0x1F) * targetFraction) >> 4 ;
// limit combined components to 31 max
sourceR = std::min(0x1F,targetR+sourceR) ;
sourceG = std::min(0x1F,targetG+sourceG) ;
sourceB = std::min(0x1F,targetB+sourceB) ;
//}
}
color = (sourceR & 0x1F) | ((sourceG & 0x1F) << 5) | ((sourceB & 0x1F) << 10) | 0x8000 ;
T2WriteWord(dst, passing, color);
gpu->bgPixels[x] = bgnum;
}
else
{
if ((windowEffect && (gpu->BLDCNT & (0x100 << bgnum))) || windowDraw)
if((gpu->BLDCNT & (1 << bgnum)) && windowEffect)
{
T2WriteWord(dst, passing, color);
int bg_under = gpu->bgPixels[x];
u16 final = color;
/* If the layer we are drawing on is selected as 2nd source, we can blend */
if(gpu->BLDCNT & (0x100 << bg_under))
{
COLOR c1, c2, cfinal;
c1.val = color;
c2.val = T2ReadWord(dst, passing);
cfinal.bits.red = std::min<int>(31, ((c1.bits.red * gpu->BLDALPHA_EVA / 16) + (c2.bits.red * gpu->BLDALPHA_EVB / 16)));
cfinal.bits.green = std::min<int>(31, ((c1.bits.green * gpu->BLDALPHA_EVA / 16) + (c2.bits.green * gpu->BLDALPHA_EVB / 16)));
cfinal.bits.blue = std::min<int>(31, ((c1.bits.blue * gpu->BLDALPHA_EVA / 16) + (c2.bits.blue * gpu->BLDALPHA_EVB / 16)));
final = cfinal.val;
}
T2WriteWord(dst, passing, (final | 0x8000));
gpu->bgPixels[x] = bgnum;
}
else
{
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = bgnum;
}
}
@ -1236,7 +1219,7 @@ static BOOL setFinal3DColorSpecialBlend(GPU *gpu, u32 passing, u8 *dst, u16 colo
u16 final = color;
/* If the layer we are drawing on is selected as 2nd source, we can blend */
if(gpu->BLDCNT & (1 << (8 + bg_under)))
if(gpu->BLDCNT & (0x100 << bg_under))
{
/* Test for easy cases like alpha = min or max */
if(alpha == 16)
@ -1347,7 +1330,7 @@ static BOOL setFinal3DColorSpecialBlendWnd(GPU *gpu, u32 passing, u8 *dst, u16 c
u16 final = color;
/* If the layer we are drawing on is selected as 2nd source, we can blend */
if(gpu->BLDCNT & (1 << (8 + bg_under)))
if(gpu->BLDCNT & (0x100 << bg_under))
{
/* Test for easy cases like alpha = min or max */
if(alpha == 16)