diff --git a/desmume/src/GPU.c b/desmume/src/GPU.c index 6d4828b33..35d76f047 100644 --- a/desmume/src/GPU.c +++ b/desmume/src/GPU.c @@ -558,19 +558,26 @@ INLINE void renderline_setFinalColor(GPU *gpu,u32 passing,u8 bgnum,u8 *dst,u16 c case 0x40: /* alpha blending */ { #define min(a,b) (((a)<(b))?(a):(b)) + if (!(color & 0x8000)) return ; /* we cant do alpha on an invisible pixel */ u16 sourceFraction = (gpu->BLDALPHA & 0x1F) ; - u16 targetFraction = (gpu->BLDALPHA & 0x1F00) >> 8 ; - u16 sourceR = ((color & 0x1F) * sourceFraction) >> 4 ; + if (!sourceFraction) return ; /* no fraction of this BG to be showed, so don't do anything */ + u16 sourceR = ((color & 0x1F) * sourceFraction) >> 4 ; /* weighted component from color to draw */ u16 sourceG = (((color>>5) & 0x1F) * sourceFraction) >> 4 ; u16 sourceB = (((color>>10) & 0x1F) * sourceFraction) >> 4 ; - color = T2ReadWord(dst, passing) ; - u16 targetR = ((color & 0x1F) * targetFraction) >> 4 ; - u16 targetG = (((color>>5) & 0x1F) * targetFraction) >> 4 ; - u16 targetB = (((color>>10) & 0x1F) * targetFraction) >> 4 ; - targetR = min(0x1F,targetR+sourceR) ; - targetG = min(0x1F,targetG+sourceG) ; - targetB = min(0x1F,targetB+sourceB) ; - color = (targetR & 0x1F) | ((targetG & 0x1F) << 5) | ((targetB & 0x1F) << 10) | 0x8000 ; + u16 targetFraction = (gpu->BLDALPHA & 0x1F00) >> 8 ; + if (targetFraction) { /* when we dont take any fraction from existing pixel, we can just draw */ + color = T2ReadWord(dst, passing) ; + if (color & 0x8000) { /* the existing pixel is not invisible */ + u16 targetR = ((color & 0x1F) * targetFraction) >> 4 ; /* weighted component from color we draw on */ + u16 targetG = (((color>>5) & 0x1F) * targetFraction) >> 4 ; + u16 targetB = (((color>>10) & 0x1F) * targetFraction) >> 4 ; + sourceR = min(0x1F,targetR+sourceR) ; /* limit combined components to 31 max */ + sourceG = min(0x1F,targetG+sourceG) ; + sourceB = min(0x1F,targetB+sourceB) ; + } + } + color = (sourceR & 0x1F) | ((sourceG & 0x1F) << 5) | ((sourceB & 0x1F) << 10) | 0x8000 ; + #undef min } T2WriteWord(dst, passing, color) ; break ; @@ -628,24 +635,16 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u16 X, u16 Y, u16 LG) if(tmp>31) { - switch(bgprop >> 14) - { - case 2 : - map += 32 * 32 * 2; - break; - case 3 : - map += 32 * 64 * 2; - break; - } + map+= ADDRESS_STEP_512B << BGCNT_SCREENSIZE(bgprop) ; } tile = (u8*) gpu->BG_tile_ram[num]; if((!tile) || (!gpu->BG_map_ram[num])) return; /* no tiles or no map*/ xoff = X; - if(!(bgprop & 0x80)) /* color: 16 palette entries */ + if(!BGCNT_256COL(bgprop)) /* color: 16 palette entries */ { yoff = ((Y&7)<<2); - pal = ARM9Mem.ARM9_VMEM + gpu->core * 0x400; + pal = ARM9Mem.ARM9_VMEM + gpu->core * ADDRESS_STEP_1KB ; for(x = 0; x < LG;) { u8 * mapinfo; @@ -687,10 +686,10 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u16 X, u16 Y, u16 LG) } return; } - if(!(gpu->prop & 0x40000000)) /* color: no extended palette */ + if(!DISPCNT_USEEXTPAL(gpu->prop)) /* color: no extended palette */ { yoff = ((Y&7)<<3); - pal = ARM9Mem.ARM9_VMEM + gpu->core * 0x400; + pal = ARM9Mem.ARM9_VMEM + gpu->core * ADDRESS_STEP_1KB ; for(x = 0; x < LG;) { u8 * mapinfo; diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index b50155b7b..a0208213f 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -37,6 +37,7 @@ extern "C" { #define GPU_SUB 1 /* human readable bitmask names */ +#define ADDRESS_STEP_512B 0x00200 #define ADDRESS_STEP_1KB 0x00400 #define ADDRESS_STEP_2KB 0x00800 #define ADDRESS_STEP_4KB 0x01000 @@ -58,9 +59,11 @@ extern "C" { #define DISPCNT_TILEOBJ1D_BOUNDARY(val) (((val) >> 20) & 3) #define DISPCNT_BMPOBJ1D_BOUNDARY(val) (((val) >> 22) & 1) #define DISPCNT_SCREENBASEBLOCK(val) (((val) >> 27) & 7) +#define DISPCNT_USEEXTPAL(val) (((val) >> 30) & 1) #define BGCNT_PRIORITY(val) ((val) & 3) #define BGCNT_CHARBASEBLOCK(val) (((val) >> 2) & 0x0F) +#define BGCNT_256COL(val) (((val) >> 7) & 0x1) #define BGCNT_SCREENBASEBLOCK(val) (((val) >> 8) & 0x1F) #define BGCNT_EXTPALSLOT(val) (((val) >> 13) & 0x1) #define BGCNT_SCREENSIZE(val) (((val) >> 14) & 0x3) @@ -238,7 +241,7 @@ static INLINE void GPU_ligne(Screen * screen, u16 l) if (gpu->sprEnable) { for(i16 = 0; i16 < 256; ++i16) - if(bgprio>=sprPrio[i16]) + if(bgprio>=sprPrio[i16]) T2WriteWord(dst, i16 << 1, T2ReadWord(spr, i16 << 1)); } }