gpu: overhaul sprite final pixel rendering to fix bugs and reduce code bloat. I may have broken some things (there are many rarely used configurations in here) but the code is in a final compact form now. also fix some win32 rom path related bugs.

This commit is contained in:
zeromus 2009-07-03 07:15:17 +00:00
parent da7cb2fede
commit fb1bde8d41
5 changed files with 83 additions and 271 deletions

View File

@ -512,25 +512,27 @@ FORCEINLINE void GPU::setFinal3DColorSpecialDecreaseWnd(int dstX, int srcX)
} }
static void setFinalOBJColorSpecialNone (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x); enum OBJFunc
static void setFinalOBJColorSpecialBlend (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x); {
static void setFinalOBJColorSpecialIncrease (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x); None, Blend, Increase, Decrease
static void setFinalOBJColorSpecialDecrease (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x); };
template<OBJFunc FUNC, bool WINDOW>
static void _master_setFinalOBJColor(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x);
static void setFinalOBJColorSpecialNoneWnd (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x); static void setFinalOBJColorSpecialNoneWnd (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x);
static void setFinalOBJColorSpecialBlendWnd (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x); static void setFinalOBJColorSpecialBlendWnd (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x);
static void setFinalOBJColorSpecialIncreaseWnd (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x); static void setFinalOBJColorSpecialIncreaseWnd (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x);
static void setFinalOBJColorSpecialDecreaseWnd (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x); static void setFinalOBJColorSpecialDecreaseWnd (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x);
const GPU::FinalOBJColFunct pixelBlittersOBJ[8] = { const GPU::FinalOBJColFunct pixelBlittersOBJ[8] = {
setFinalOBJColorSpecialNone, _master_setFinalOBJColor<None,false>,
setFinalOBJColorSpecialBlend, _master_setFinalOBJColor<Blend,false>,
setFinalOBJColorSpecialIncrease, _master_setFinalOBJColor<Increase,false>,
setFinalOBJColorSpecialDecrease, _master_setFinalOBJColor<Decrease,false>,
setFinalOBJColorSpecialNoneWnd, _master_setFinalOBJColor<None,true>,
setFinalOBJColorSpecialBlendWnd, _master_setFinalOBJColor<Blend,true>,
setFinalOBJColorSpecialIncreaseWnd, _master_setFinalOBJColor<Increase,true>,
setFinalOBJColorSpecialDecreaseWnd,}; _master_setFinalOBJColor<Decrease,true> };
/*****************************************************************************/ /*****************************************************************************/
// INITIALIZATION // INITIALIZATION
@ -567,12 +569,14 @@ static void GPU_InitFadeColors()
cur.bits.red = (cur.bits.red + ((31 - cur.bits.red) * i / 16)); cur.bits.red = (cur.bits.red + ((31 - cur.bits.red) * i / 16));
cur.bits.green = (cur.bits.green + ((31 - cur.bits.green) * i / 16)); cur.bits.green = (cur.bits.green + ((31 - cur.bits.green) * i / 16));
cur.bits.blue = (cur.bits.blue + ((31 - cur.bits.blue) * i / 16)); cur.bits.blue = (cur.bits.blue + ((31 - cur.bits.blue) * i / 16));
cur.bits.alpha = 0;
fadeInColors[i][j & 0x7FFF] = cur.val; fadeInColors[i][j & 0x7FFF] = cur.val;
cur.val = j; cur.val = j;
cur.bits.red = (cur.bits.red - (cur.bits.red * i / 16)); cur.bits.red = (cur.bits.red - (cur.bits.red * i / 16));
cur.bits.green = (cur.bits.green - (cur.bits.green * i / 16)); cur.bits.green = (cur.bits.green - (cur.bits.green * i / 16));
cur.bits.blue = (cur.bits.blue - (cur.bits.blue * i / 16)); cur.bits.blue = (cur.bits.blue - (cur.bits.blue * i / 16));
cur.bits.alpha = 0;
fadeOutColors[i][j & 0x7FFF] = cur.val; fadeOutColors[i][j & 0x7FFF] = cur.val;
} }
} }
@ -605,7 +609,7 @@ GPU * GPU_Init(u8 l)
g->need_update_winh[1] = true; g->need_update_winh[1] = true;
g->setFinalColorBck_funcNum = 0; g->setFinalColorBck_funcNum = 0;
g->setFinalColor3d_funcNum = 0; g->setFinalColor3d_funcNum = 0;
g->setFinalColorSpr = setFinalOBJColorSpecialNone; g->setFinalColorSpr = _master_setFinalOBJColor<None,false>;
@ -618,7 +622,7 @@ void GPU_Reset(GPU *g, u8 l)
g->setFinalColorBck_funcNum = 0; g->setFinalColorBck_funcNum = 0;
g->setFinalColor3d_funcNum = 0; g->setFinalColor3d_funcNum = 0;
g->setFinalColorSpr = setFinalOBJColorSpecialNone; g->setFinalColorSpr = _master_setFinalOBJColor<None,false>;
g->core = l; g->core = l;
g->BGSize[0][0] = g->BGSize[1][0] = g->BGSize[2][0] = g->BGSize[3][0] = 256; g->BGSize[0][0] = g->BGSize[1][0] = g->BGSize[2][0] = g->BGSize[3][0] = 256;
g->BGSize[0][1] = g->BGSize[1][1] = g->BGSize[2][1] = g->BGSize[3][1] = 256; g->BGSize[0][1] = g->BGSize[1][1] = g->BGSize[2][1] = g->BGSize[3][1] = 256;
@ -1089,256 +1093,48 @@ FORCEINLINE bool GPU::setFinalBGColorSpecialDecreaseWnd(u16 &color, const u8 x)
// PIXEL RENDERING - OBJS // PIXEL RENDERING - OBJS
/*****************************************************************************/ /*****************************************************************************/
static void setFinalOBJColorSpecialNone(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x) template<OBJFunc FUNC, bool WINDOW>
{ static void _master_setFinalOBJColor(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x)
if(type == 1)
{
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((bg_under != 4) && (gpu->BLDCNT & (0x100 << bg_under)))
final = gpu->blend(color,T2ReadWord(dst, passing));
T2WriteWord(dst, passing, (final | 0x8000));
gpu->bgPixels[x] = 4;
}
else
{
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
}
static FORCEINLINE u16 blendSprite(GPU* gpu, u8 alpha, u16 sprColor, u16 backColor, u8 type)
{
if(type == 3)
//handle translucent bitmap sprite
return _blend(sprColor,backColor,&gpuBlendTable555[alpha+1][15-alpha]);
else
return gpu->blend(sprColor,backColor);
}
static void setFinalOBJColorSpecialBlend(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x)
{
if((gpu->BLDCNT & 0x10) || (type == 1))
{
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((bg_under != 4) && (gpu->BLDCNT & (0x100 << bg_under)))
{
//bmp translucent handling tested by disgaea clock hud
final = blendSprite(gpu, alpha, color, T2ReadWord(dst, passing), type);
}
T2WriteWord(dst, passing, (final | 0x8000));
gpu->bgPixels[x] = 4;
}
else
{
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
}
static void setFinalOBJColorSpecialIncrease(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x)
{
if(type == 1)
{
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((bg_under != 4) && (gpu->BLDCNT & (0x100 << bg_under)))
final = gpu->blend(color,T2ReadWord(dst, passing));
T2WriteWord(dst, passing, (final | 0x8000));
gpu->bgPixels[x] = 4;
}
else if(gpu->BLDCNT & 0x10)
{
if (gpu->BLDY_EVY != 0x0)
{
color = fadeInColors[gpu->BLDY_EVY][color&0x7FFF];
}
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
else
{
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
}
static void setFinalOBJColorSpecialDecrease(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x)
{
if(type == 1)
{
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((bg_under != 4) && (gpu->BLDCNT & (0x100 << bg_under)))
final = gpu->blend(color,T2ReadWord(dst, passing));
T2WriteWord(dst, passing, (final | 0x8000));
gpu->bgPixels[x] = 4;
}
else if(gpu->BLDCNT & 0x10)
{
if (gpu->BLDY_EVY != 0x0)
{
color = fadeOutColors[gpu->BLDY_EVY][color&0x7FFF];
}
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
else
{
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
}
static void setFinalOBJColorSpecialNoneWnd(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x)
{ {
bool windowDraw = true, windowEffect = true; bool windowDraw = true, windowEffect = true;
gpu->renderline_checkWindows(x, windowDraw, windowEffect); if(WINDOW)
if(windowDraw)
{ {
if((type == 1) && windowEffect) gpu->renderline_checkWindows(x, windowDraw, windowEffect);
{ if(!windowDraw)
int bg_under = gpu->bgPixels[x]; return;
u16 final = color;
// If the layer we are drawing on is selected as 2nd source, we can blend
if((bg_under != 4) && (gpu->BLDCNT & (0x100 << bg_under)))
final = gpu->blend(color,T2ReadWord(dst, passing));
T2WriteWord(dst, passing, (final | 0x8000));
gpu->bgPixels[x] = 4;
}
else
{
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
}
}
static void setFinalOBJColorSpecialBlendWnd(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x)
{
bool windowDraw = true, windowEffect = true;
gpu->renderline_checkWindows(x, windowDraw, windowEffect);
if(windowDraw)
{
if(((gpu->BLDCNT & 0x10) || (type == 1)) && windowEffect)
{
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((bg_under != 4) && (gpu->BLDCNT & (0x100 << bg_under)))
{
final = gpu->blend(color,T2ReadWord(dst, passing));
}
T2WriteWord(dst, passing, (final | 0x8000));
gpu->bgPixels[x] = 4;
}
else
{
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
}
}
static void setFinalOBJColorSpecialIncreaseWnd(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x)
{
bool windowDraw = true, windowEffect = true;
gpu->renderline_checkWindows(x, windowDraw,windowEffect);
if(windowDraw)
{
if((type == 1) && windowEffect)
{
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((bg_under != 4) && (gpu->BLDCNT & (0x100 << bg_under)))
final = gpu->blend(color,T2ReadWord(dst, passing));
T2WriteWord(dst, passing, (final | 0x8000));
gpu->bgPixels[x] = 4;
}
else if((gpu->BLDCNT & 0x10) && windowEffect)
{
if (gpu->BLDY_EVY != 0x0)
{
color = fadeInColors[gpu->BLDY_EVY][color&0x7FFF];
}
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
else
{
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
} }
} //note that the fadein and fadeout is done here before blending,
//so that a fade and blending can be applied at the same time
bool forceBlendingForNormal = false;
if(windowEffect)
switch(FUNC)
{
case Increase: color = fadeInColors[gpu->BLDY_EVY][color&0x7FFF]; break;
case Decrease: color = fadeOutColors[gpu->BLDY_EVY][color&0x7FFF]; break;
static void setFinalOBJColorSpecialDecreaseWnd(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x) //only when blend color effect is selected, ordinarily opaque sprites are blended with the color effect params
{ case Blend: forceBlendingForNormal = (gpu->BLDCNT & 0x10)!=0; break;
bool windowDraw = true, windowEffect = true; }
gpu->renderline_checkWindows(x, windowDraw, windowEffect); //this inspects the layer beneath the sprite to see if the current blend flags make it a candidate for blending
int bg_under = gpu->bgPixels[x];
bool allowBlend = ((bg_under != 4) && (gpu->BLDCNT & (0x100 << bg_under)));
if(windowDraw) if(allowBlend)
{ {
if((type == 1) && windowEffect) u16 backColor = T2ReadWord(dst,passing);
{ //this hasn't been tested: this blending occurs without regard to the color effect,
int bg_under = gpu->bgPixels[x]; //but rather purely from the sprite's alpha
u16 final = color; if(type == GPU_OBJ_MODE_Bitmap)
color = _blend(color,backColor,&gpuBlendTable555[alpha+1][15-alpha]);
// If the layer we are drawing on is selected as 2nd source, we can blend else if(type == GPU_OBJ_MODE_Transparent || forceBlendingForNormal)
if((bg_under != 4) && (gpu->BLDCNT & (0x100 << bg_under))) color = gpu->blend(color,backColor);
final = gpu->blend(color,T2ReadWord(dst, passing));
T2WriteWord(dst, passing, (final | 0x8000));
gpu->bgPixels[x] = 4;
}
else if((gpu->BLDCNT & 0x10) && windowEffect)
{
if (gpu->BLDY_EVY != 0x0)
{
color = fadeOutColors[gpu->BLDY_EVY][color&0x7FFF];
}
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
else
{
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
} }
T2WriteWord(dst, passing, (color | 0x8000));
gpu->bgPixels[x] = 4;
} }
FORCEINLINE void GPU::setFinalColorBG(u16 color, u8 x) FORCEINLINE void GPU::setFinalColorBG(u16 color, u8 x)

View File

@ -505,8 +505,14 @@ typedef union
// (00: Normal, 01: Transparent, 10: Object window, 11: Bitmap)
enum GPU_OBJ_MODE
{
GPU_OBJ_MODE_Normal = 0,
GPU_OBJ_MODE_Transparent = 1,
GPU_OBJ_MODE_Window = 2,
GPU_OBJ_MODE_Bitmap = 3
};
/* /*
this structure is for Sprite description, this structure is for Sprite description,
@ -515,7 +521,7 @@ typedef union
ref: http://www.bottledlight.com/ds/index.php/Video/Sprites ref: http://www.bottledlight.com/ds/index.php/Video/Sprites
*/ */
typedef struct struct _OAM_
{ {
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
// attr0 // attr0
@ -558,7 +564,7 @@ typedef struct
// attr3 // attr3
unsigned attr3:16; unsigned attr3:16;
#endif #endif
} _OAM_; };
typedef struct typedef struct
{ {

View File

@ -709,7 +709,7 @@ void GameInfo::populate()
} }
} }
int NDS_LoadROM( const char *filename) int NDS_LoadROM( const char *filename, const char *logicalFilename)
{ {
int ret; int ret;
int type; int type;
@ -733,12 +733,24 @@ int NDS_LoadROM( const char *filename)
noext = strdup(filename); noext = strdup(filename);
reader = ROMReaderInit(&noext); reader = ROMReaderInit(&noext);
for (int t = strlen(filename); t>0; t--) if(logicalFilename)
if ( (filename[t] == '\\') || (filename[t] == '/') ) {
{ for (int t = strlen(logicalFilename); t>0; t--)
strncpy(pathToROM, filename, t+1); if ( (logicalFilename[t] == '\\') || (logicalFilename[t] == '/') )
break; {
} strncpy(pathToROM, logicalFilename, t+1);
break;
}
}
else
{
for (int t = strlen(filename); t>0; t--)
if ( (filename[t] == '\\') || (filename[t] == '/') )
{
strncpy(pathToROM, filename, t+1);
break;
}
}
for (int t = strlen(filename); t>0; t--) for (int t = strlen(filename); t>0; t--)
if ( (filename[t] == '\\') || (filename[t] == '/') || (filename[t] == '.') ) if ( (filename[t] == '\\') || (filename[t] == '/') || (filename[t] == '.') )

View File

@ -289,7 +289,7 @@ void NDS_releaseTouch(void);
void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,bool X,bool W,bool E,bool G, bool F); void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,bool X,bool W,bool E,bool G, bool F);
void NDS_setPadFromMovie(u16 pad); void NDS_setPadFromMovie(u16 pad);
int NDS_LoadROM(const char *filename); int NDS_LoadROM(const char *filename, const char* logicalFilename=0);
void NDS_FreeROM(void); void NDS_FreeROM(void);
void NDS_Reset(); void NDS_Reset();
int NDS_ImportSave(const char *filename); int NDS_ImportSave(const char *filename);

View File

@ -1265,8 +1265,6 @@ void LoadSaveStateInfo()
} }
} }
static BOOL LoadROM(const char * filename, const char * logicalName) static BOOL LoadROM(const char * filename, const char * logicalName)
{ {
ResetSaveStateTimes(); ResetSaveStateTimes();
@ -1277,9 +1275,9 @@ static BOOL LoadROM(const char * filename, const char * logicalName)
std::vector<std::string> parts = tokenize_str(logicalName,"|"); std::vector<std::string> parts = tokenize_str(logicalName,"|");
SetRomName(parts[parts.size()-1].c_str()); SetRomName(parts[parts.size()-1].c_str());
if (NDS_LoadROM(filename) > 0) if (NDS_LoadROM(filename, logicalName) > 0)
{ {
INFO("Loading %s was successful\n",filename); INFO("Loading %s was successful\n",logicalName);
LoadSaveStateInfo(); LoadSaveStateInfo();
lagframecounter=0; lagframecounter=0;
UpdateRecentRoms(logicalName); UpdateRecentRoms(logicalName);
@ -1293,7 +1291,7 @@ static BOOL LoadROM(const char * filename, const char * logicalName)
return TRUE; return TRUE;
} }
INFO("Loading %s FAILED.\n",filename); INFO("Loading %s FAILED.\n",logicalName);
return FALSE; return FALSE;
} }