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:
parent
da7cb2fede
commit
fb1bde8d41
|
@ -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);
|
||||
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);
|
||||
static void setFinalOBJColorSpecialDecrease (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x);
|
||||
enum OBJFunc
|
||||
{
|
||||
None, Blend, Increase, Decrease
|
||||
};
|
||||
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 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 setFinalOBJColorSpecialDecreaseWnd (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x);
|
||||
|
||||
const GPU::FinalOBJColFunct pixelBlittersOBJ[8] = {
|
||||
setFinalOBJColorSpecialNone,
|
||||
setFinalOBJColorSpecialBlend,
|
||||
setFinalOBJColorSpecialIncrease,
|
||||
setFinalOBJColorSpecialDecrease,
|
||||
setFinalOBJColorSpecialNoneWnd,
|
||||
setFinalOBJColorSpecialBlendWnd,
|
||||
setFinalOBJColorSpecialIncreaseWnd,
|
||||
setFinalOBJColorSpecialDecreaseWnd,};
|
||||
|
||||
_master_setFinalOBJColor<None,false>,
|
||||
_master_setFinalOBJColor<Blend,false>,
|
||||
_master_setFinalOBJColor<Increase,false>,
|
||||
_master_setFinalOBJColor<Decrease,false>,
|
||||
_master_setFinalOBJColor<None,true>,
|
||||
_master_setFinalOBJColor<Blend,true>,
|
||||
_master_setFinalOBJColor<Increase,true>,
|
||||
_master_setFinalOBJColor<Decrease,true> };
|
||||
|
||||
/*****************************************************************************/
|
||||
// INITIALIZATION
|
||||
|
@ -567,12 +569,14 @@ static void GPU_InitFadeColors()
|
|||
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.blue = (cur.bits.blue + ((31 - cur.bits.blue) * i / 16));
|
||||
cur.bits.alpha = 0;
|
||||
fadeInColors[i][j & 0x7FFF] = cur.val;
|
||||
|
||||
cur.val = j;
|
||||
cur.bits.red = (cur.bits.red - (cur.bits.red * 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.alpha = 0;
|
||||
fadeOutColors[i][j & 0x7FFF] = cur.val;
|
||||
}
|
||||
}
|
||||
|
@ -605,7 +609,7 @@ GPU * GPU_Init(u8 l)
|
|||
g->need_update_winh[1] = true;
|
||||
g->setFinalColorBck_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->setFinalColor3d_funcNum = 0;
|
||||
g->setFinalColorSpr = setFinalOBJColorSpecialNone;
|
||||
g->setFinalColorSpr = _master_setFinalOBJColor<None,false>;
|
||||
g->core = l;
|
||||
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;
|
||||
|
@ -1089,256 +1093,48 @@ FORCEINLINE bool GPU::setFinalBGColorSpecialDecreaseWnd(u16 &color, const u8 x)
|
|||
// PIXEL RENDERING - OBJS
|
||||
/*****************************************************************************/
|
||||
|
||||
static void setFinalOBJColorSpecialNone(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)
|
||||
template<OBJFunc FUNC, bool WINDOW>
|
||||
static void _master_setFinalOBJColor(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(WINDOW)
|
||||
{
|
||||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
gpu->renderline_checkWindows(x, windowDraw, windowEffect);
|
||||
if(!windowDraw)
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
//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)
|
||||
{
|
||||
bool windowDraw = true, windowEffect = true;
|
||||
//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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 = 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;
|
||||
}
|
||||
u16 backColor = T2ReadWord(dst,passing);
|
||||
//this hasn't been tested: this blending occurs without regard to the color effect,
|
||||
//but rather purely from the sprite's alpha
|
||||
if(type == GPU_OBJ_MODE_Bitmap)
|
||||
color = _blend(color,backColor,&gpuBlendTable555[alpha+1][15-alpha]);
|
||||
else if(type == GPU_OBJ_MODE_Transparent || forceBlendingForNormal)
|
||||
color = gpu->blend(color,backColor);
|
||||
}
|
||||
|
||||
T2WriteWord(dst, passing, (color | 0x8000));
|
||||
gpu->bgPixels[x] = 4;
|
||||
}
|
||||
|
||||
FORCEINLINE void GPU::setFinalColorBG(u16 color, u8 x)
|
||||
|
|
|
@ -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,
|
||||
|
@ -515,7 +521,7 @@ typedef union
|
|||
ref: http://www.bottledlight.com/ds/index.php/Video/Sprites
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
struct _OAM_
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
// attr0
|
||||
|
@ -558,7 +564,7 @@ typedef struct
|
|||
// attr3
|
||||
unsigned attr3:16;
|
||||
#endif
|
||||
} _OAM_;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
|
@ -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 type;
|
||||
|
@ -733,12 +733,24 @@ int NDS_LoadROM( const char *filename)
|
|||
noext = strdup(filename);
|
||||
reader = ROMReaderInit(&noext);
|
||||
|
||||
for (int t = strlen(filename); t>0; t--)
|
||||
if ( (filename[t] == '\\') || (filename[t] == '/') )
|
||||
{
|
||||
strncpy(pathToROM, filename, t+1);
|
||||
break;
|
||||
}
|
||||
if(logicalFilename)
|
||||
{
|
||||
for (int t = strlen(logicalFilename); t>0; t--)
|
||||
if ( (logicalFilename[t] == '\\') || (logicalFilename[t] == '/') )
|
||||
{
|
||||
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--)
|
||||
if ( (filename[t] == '\\') || (filename[t] == '/') || (filename[t] == '.') )
|
||||
|
|
|
@ -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_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_Reset();
|
||||
int NDS_ImportSave(const char *filename);
|
||||
|
|
|
@ -1265,8 +1265,6 @@ void LoadSaveStateInfo()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static BOOL LoadROM(const char * filename, const char * logicalName)
|
||||
{
|
||||
ResetSaveStateTimes();
|
||||
|
@ -1277,9 +1275,9 @@ static BOOL LoadROM(const char * filename, const char * logicalName)
|
|||
std::vector<std::string> parts = tokenize_str(logicalName,"|");
|
||||
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();
|
||||
lagframecounter=0;
|
||||
UpdateRecentRoms(logicalName);
|
||||
|
@ -1293,7 +1291,7 @@ static BOOL LoadROM(const char * filename, const char * logicalName)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
INFO("Loading %s FAILED.\n",filename);
|
||||
INFO("Loading %s FAILED.\n",logicalName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue