change gpu to use only one function for 1D and 2D sprite rendering. this makes it easier to debug and tweak, since they were 95% similar already. also fix a bunch of bugs in the win32 oam viewer.

This commit is contained in:
zeromus 2009-04-10 20:59:44 +00:00
parent 9821e2342f
commit a48b1a725d
5 changed files with 143 additions and 378 deletions

View File

@ -53,23 +53,6 @@
#include "debug.h" #include "debug.h"
#include "NDSSystem.h" #include "NDSSystem.h"
//#define CHECKSPRITES
#ifdef CHECKSPRITES
#define CHECK_SPRITE(type) \
if (!src) {\
INFO("Sprite%s(%s) in mode %i %s\n",\
type==1?"1D":"2D",\
dispCnt->OBJ_BMP_mapping==1?"1D":"2D",\
spriteInfo->Mode,\
(spriteInfo->RotScale & 1)?"(Rotoscaled)":"");\
continue;\
};
#else
#define CHECK_SPRITE(type) if (!src) { continue; };
#endif
ARM9_struct ARM9Mem; ARM9_struct ARM9Mem;
extern BOOL click; extern BOOL click;
@ -293,7 +276,7 @@ void GPU_Reset(GPU *g, u8 l)
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;
g->dispOBJ = g->dispBG[0] = g->dispBG[1] = g->dispBG[2] = g->dispBG[3] = TRUE; g->dispOBJ = g->dispBG[0] = g->dispBG[1] = g->dispBG[2] = g->dispBG[3] = TRUE;
g->spriteRender = sprite1D; g->spriteRenderMode = GPU::SPRITE_1D;
g->bgPrio[4] = 0xFF; g->bgPrio[4] = 0xFF;
@ -469,20 +452,21 @@ void GPU_setVideoProp(GPU * gpu, u32 p)
if(cnt->OBJ_Tile_mapping) if(cnt->OBJ_Tile_mapping)
{ {
/* 1-d sprite mapping */ // 1-d sprite mapping
// boundary : // boundary :
// core A : 32k, 64k, 128k, 256k // core A : 32k, 64k, 128k, 256k
// core B : 32k, 64k, 128k, 128k // core B : 32k, 64k, 128k, 128k
gpu->sprBoundary = 5 + cnt->OBJ_Tile_1D_Bound ; gpu->sprBoundary = 5 + cnt->OBJ_Tile_1D_Bound ;
if((gpu->core == GPU_SUB) && (cnt->OBJ_Tile_1D_Bound == 3))
gpu->sprBoundary = 7;
gpu->spriteRender = sprite1D; //zero 10-apr-09 - this is just wrong.
//if((gpu->core == GPU_SUB) && (cnt->OBJ_Tile_1D_Bound == 3)) gpu->sprBoundary = 7;
gpu->spriteRenderMode = GPU::SPRITE_1D;
} else { } else {
/* 2d sprite mapping */ // 2d sprite mapping
// boundary : 32k // boundary : 32k
gpu->sprBoundary = 5; gpu->sprBoundary = 5;
gpu->spriteRender = sprite2D; gpu->spriteRenderMode = GPU::SPRITE_2D;
} }
if(cnt->OBJ_BMP_1D_Bound && (gpu->core == GPU_MAIN)) if(cnt->OBJ_BMP_1D_Bound && (gpu->core == GPU_MAIN))
@ -2054,14 +2038,26 @@ FORCEINLINE BOOL compute_sprite_vars(_OAM_ * spriteInfo, u16 l,
/*****************************************************************************/ /*****************************************************************************/
// SPRITE RENDERING // SPRITE RENDERING
/*****************************************************************************/ /*****************************************************************************/
void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab)
void GPU::spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab)
{ {
if(spriteRenderMode == SPRITE_1D)
_spriteRender<SPRITE_1D>(dst,dst_alpha,typeTab, prioTab);
else
_spriteRender<SPRITE_2D>(dst,dst_alpha,typeTab, prioTab);
}
template<GPU::SpriteRenderMode MODE>
void GPU::_spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab)
{
u16 l = currLine;
GPU *gpu = this;
struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits; struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits;
_OAM_ * spriteInfo = (_OAM_ *)(gpu->oam + (nbShow-1));// + 127; _OAM_ * spriteInfo = (_OAM_ *)(gpu->oam + (nbShow-1));// + 127;
u8 block = gpu->sprBoundary; u8 block = gpu->sprBoundary;
u16 i; u16 i;
//for(i = 0; i<nbShow; ++i, --spriteInfo) /* check all sprites */
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
*(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15; *(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15;
*(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14; *(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14;
@ -2074,8 +2070,11 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
,*(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15 ,*(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15
,*(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14 ,*(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14
#endif #endif
) /* check all sprites */ )
{ {
const int oamNum = 127 - i;
//for each sprite:
size sprSize; size sprSize;
s32 sprX, sprY, x, y, lg; s32 sprX, sprY, x, y, lg;
int xdir; int xdir;
@ -2158,8 +2157,11 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
// If we are using 1 palette of 256 colours // If we are using 1 palette of 256 colours
if(spriteInfo->Depth) if(spriteInfo->Depth)
{ {
//2d: src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex) << 5));
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex << block)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex << block));
CHECK_SPRITE(1); if (!src) {
continue;
}
// If extended palettes are set, use them // If extended palettes are set, use them
if (dispCnt->ExOBJPalette_Enable) if (dispCnt->ExOBJPalette_Enable)
@ -2175,12 +2177,14 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y) if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y)
{ {
if(MODE == SPRITE_2D)
offset = (auxX&0x7) + ((auxX&0xFFF8)<<3) + ((auxY>>3)<<10) + ((auxY&0x7)*8);
else
offset = (auxX&0x7) + ((auxX&0xFFF8)<<3) + ((auxY>>3)*sprSize.x*8) + ((auxY&0x7)*8); offset = (auxX&0x7) + ((auxX&0xFFF8)<<3) + ((auxY>>3)*sprSize.x*8) + ((auxY&0x7)*8);
colour = src[offset]; colour = src[offset];
if (colour && (prioTab[sprX]>=prio)) if (colour && (prioTab[sprX]>=prio))
{
//if (gpu->setFinalColorSpr(gpu, sprX << 1, 4, dst, T1ReadWord(pal, colour<<1), sprX ))
{ {
T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1))); T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1)));
dst_alpha[sprX] = 16; dst_alpha[sprX] = 16;
@ -2188,7 +2192,6 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
prioTab[sprX] = prio; prioTab[sprX] = prio;
} }
} }
}
// Add the rotation/scale coeficients, here the rotation/scaling // Add the rotation/scale coeficients, here the rotation/scaling
// is performed // is performed
@ -2205,7 +2208,10 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex)*32); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex)*32);
else else
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x03E0) * 8) + (spriteInfo->TileIndex&0x001F))*16); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x03E0) * 8) + (spriteInfo->TileIndex&0x001F))*16);
CHECK_SPRITE(1);
if (!src) {
continue;
}
for(j = 0; j < lg; ++j, ++sprX) for(j = 0; j < lg; ++j, ++sprX)
{ {
@ -2215,12 +2221,14 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y) if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y)
{ {
if(MODE == SPRITE_2D)
offset = auxX + (auxY<<8);
else
offset = (auxX) + (auxY<<5); offset = (auxX) + (auxY<<5);
colour = T1ReadWord (src, offset<<1); colour = T1ReadWord (src, offset<<1);
if((colour&0x8000) && (prioTab[sprX]>=prio)) if((colour&0x8000) && (prioTab[sprX]>=prio))
{
// if (gpu->setFinalColorSpr(gpu, sprX << 1, 4, dst, colour, sprX))
{ {
T2WriteWord(dst, (sprX<<1), colour); T2WriteWord(dst, (sprX<<1), colour);
dst_alpha[sprX] = spriteInfo->PaletteIndex; dst_alpha[sprX] = spriteInfo->PaletteIndex;
@ -2228,7 +2236,6 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
prioTab[sprX] = prio; prioTab[sprX] = prio;
} }
} }
}
// Add the rotation/scale coeficients, here the rotation/scaling // Add the rotation/scale coeficients, here the rotation/scaling
// is performed // is performed
@ -2241,9 +2248,20 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
// Rotozoomed 16/16 palette // Rotozoomed 16/16 palette
else else
{ {
pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core*0x400 + (spriteInfo->PaletteIndex*32); if(MODE == SPRITE_2D)
{
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<5));
pal = ARM9Mem.ARM9_VMEM + 0x200 + (gpu->core*0x400 + (spriteInfo->PaletteIndex*32));
}
else
{
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<gpu->sprBoundary)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<gpu->sprBoundary));
CHECK_SPRITE(1); pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core*0x400 + (spriteInfo->PaletteIndex*32);
}
if (!src) {
continue;
}
for(j = 0; j < lg; ++j, ++sprX) for(j = 0; j < lg; ++j, ++sprX)
{ {
@ -2253,7 +2271,11 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y) if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y)
{ {
if(MODE == SPRITE_2D)
offset = ((auxX>>1)&0x3) + (((auxX>>1)&0xFFFC)<<3) + ((auxY>>3)<<10) + ((auxY&0x7)*4);
else
offset = ((auxX>>1)&0x3) + (((auxX>>1)&0xFFFC)<<3) + ((auxY>>3)*sprSize.x)*4 + ((auxY&0x7)*4); offset = ((auxX>>1)&0x3) + (((auxX>>1)&0xFFFC)<<3) + ((auxY>>3)*sprSize.x)*4 + ((auxY&0x7)*4);
colour = src[offset]; colour = src[offset];
// Get 4bits value from the readed 8bits // Get 4bits value from the readed 8bits
@ -2261,8 +2283,6 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
else colour &= 0xF; else colour &= 0xF;
if(colour && (prioTab[sprX]>=prio)) if(colour && (prioTab[sprX]>=prio))
{
//if (gpu->setFinalColorSpr(gpu, sprX << 1, 4, dst, T1ReadWord(pal, colour<<1), sprX ))
{ {
T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1))); T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1)));
dst_alpha[sprX] = 16; dst_alpha[sprX] = 16;
@ -2270,7 +2290,6 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
prioTab[sprX] = prio; prioTab[sprX] = prio;
} }
} }
}
// Add the rotation/scale coeficients, here the rotation/scaling // Add the rotation/scale coeficients, here the rotation/scaling
// is performed // is performed
@ -2285,315 +2304,29 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
{ {
u16 * pal; u16 * pal;
if (!compute_sprite_vars(spriteInfo, l, sprSize, sprX, sprY, x, y, lg, xdir)) if (!compute_sprite_vars(spriteInfo, l, sprSize, sprX, sprY, x, y, lg, xdir))
continue; continue;
if (spriteInfo->Mode == 2) if (spriteInfo->Mode == 2)
{ {
if (spriteInfo->Depth) if(MODE == SPRITE_2D)
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8));
else
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*4) + ((y&0x7)*4));
CHECK_SPRITE(1);
render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir);
continue;
}
if (spriteInfo->Mode == 3) /* sprite is in BMP format */
{ {
if (dispCnt->OBJ_BMP_mapping)
{
// TODO: fix it for sprite1D
//src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1));
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<4) + (y<<gpu->sprBMPBoundary));
}
else
{
if (dispCnt->OBJ_BMP_2D_dim) // 256*256
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1));
else // 128 * 512
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1));
}
CHECK_SPRITE(1);
render_sprite_BMP (gpu, i, l, dst, (u16*)src, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->PaletteIndex);
continue;
}
if(spriteInfo->Depth) /* 256 colors */
{
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8));
CHECK_SPRITE(1);
if (dispCnt->ExOBJPalette_Enable)
pal = (u16*)(ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200));
else
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400);
//sprwin test hack - to enable, only draw win and not sprite
render_sprite_256 (gpu, i, l, dst, src, pal, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->Mode == 1);
//render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir);
continue;
}
/* 16 colors */
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*4) + ((y&0x7)*4));
CHECK_SPRITE(1);
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400);
pal += (spriteInfo->PaletteIndex<<4);
//sprwin test hack - to enable, only draw win and not sprite
render_sprite_16 (gpu, l, dst, src, pal, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->Mode == 1);
//render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir);
}
}
#ifdef WORDS_BIGENDIAN
*(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) << 1) | *(((u16*)spriteInfo)+1) >> 15;
*(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) << 2) | *(((u16*)spriteInfo)+2) >> 14;
#endif
}
void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab)
{
struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits;
_OAM_ * spriteInfo = (_OAM_*)(gpu->oam + (nbShow-1));// + 127;
u16 i;
#ifdef WORDS_BIGENDIAN
*(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15;
*(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14;
#endif
for(i = 0; i<nbShow; ++i, --spriteInfo
#ifdef WORDS_BIGENDIAN
,*(((u16*)(spriteInfo+1))+1) = (*(((u16*)(spriteInfo+1))+1) << 1) | *(((u16*)(spriteInfo+1))+1) >> 15
,*(((u16*)(spriteInfo+1))+2) = (*(((u16*)(spriteInfo+1))+2) << 2) | *(((u16*)(spriteInfo+1))+2) >> 14
,*(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15
,*(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14
#endif
) /* check all sprites */
{
size sprSize;
s32 sprX, sprY, x, y, lg;
int xdir;
u8 prio, * src;
//u16 * pal;
u16 j;
// Check if sprite is disabled before everything
if (spriteInfo->RotScale == 2)
continue;
prio = spriteInfo->Priority;
if (spriteInfo->RotScale & 1)
{
s32 fieldX, fieldY, auxX, auxY, realX, realY, offset;
u8 blockparameter, *pal;
s16 dx, dmx, dy, dmy;
u16 colour;
// Get sprite positions and size
sprX = (spriteInfo->X<<23)>>23;
sprY = spriteInfo->Y;
sprSize = sprSizeTab[spriteInfo->Size][spriteInfo->Shape];
lg = sprSize.x;
if (sprY>=192)
sprY = (s32)((s8)(spriteInfo->Y));
// Copy sprite size, to check change it if needed
fieldX = sprSize.x;
fieldY = sprSize.y;
// If we are using double size mode, double our control vars
if (spriteInfo->RotScale & 2)
{
fieldX <<= 1;
fieldY <<= 1;
lg <<= 1;
}
// Check if sprite enabled
if ((l <sprY) || (l >= sprY+fieldY) ||
(sprX==256) || (sprX+fieldX<=0))
continue;
y = l - sprY;
// Get which four parameter block is assigned to this sprite
blockparameter = (spriteInfo->RotScalIndex + (spriteInfo->HFlip<< 3) + (spriteInfo->VFlip << 4))*4;
// Get rotation/scale parameters
dx = (s16)(gpu->oam + blockparameter+0)->attr3;
dmx = (s16)(gpu->oam + blockparameter+1)->attr3;
dy = (s16)(gpu->oam + blockparameter+2)->attr3;
dmy = (s16)(gpu->oam + blockparameter+3)->attr3;
// Calculate fixed poitn 8.8 start offsets
realX = ((sprSize.x) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx + y * dmx;
realY = ((sprSize.y) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy + y * dmy;
if(sprX<0)
{
// If sprite is not in the window
if(sprX + fieldX <= 0)
continue;
// Otherwise, is partially visible
lg += sprX;
realX -= sprX*dx;
realY -= sprX*dy;
sprX = 0;
}
else
{
if(sprX+fieldX>256)
lg = 256 - sprX;
}
// If we are using 1 palette of 256 colours
if(spriteInfo->Depth)
{
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex) << 5));
CHECK_SPRITE(2);
// If extended palettes are set, use them
if (dispCnt->ExOBJPalette_Enable)
pal = (ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200));
else
pal = (ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400);
for(j = 0; j < lg; ++j, ++sprX)
{
// Get the integer part of the fixed point 8.8, and check if it lies inside the sprite data
auxX = (realX>>8);
auxY = (realY>>8);
if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y)
{
offset = (auxX&0x7) + ((auxX&0xFFF8)<<3) + ((auxY>>3)<<10) + ((auxY&0x7)*8);
colour = src[offset];
if (colour && (prioTab[sprX]>=prio))
{
// if (gpu->setFinalColorSpr(gpu, sprX << 1, 4, dst, T1ReadWord(pal, colour<<1), sprX ))
{
T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1)));
dst_alpha[sprX] = 16;
typeTab[sprX] = spriteInfo->Mode;
prioTab[sprX] = prio;
}
}
}
// Add the rotation/scale coeficients, here the rotation/scaling
// is performed
realX += dx;
realY += dy;
}
continue;
}
// Rotozoomed direct color
else if(spriteInfo->Mode == 3)
{
if (dispCnt->OBJ_BMP_mapping)
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex)*32);
else
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x03E0) * 8) + (spriteInfo->TileIndex&0x001F))*16);
CHECK_SPRITE(2);
for(j = 0; j < lg; ++j, ++sprX)
{
// Get the integer part of the fixed point 8.8, and check if it lies inside the sprite data
auxX = (realX>>8);
auxY = (realY>>8);
if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y)
{
offset = auxX + (auxY<<8);
colour = T1ReadWord(src, offset<<1);
if((colour&0x8000) && (prioTab[sprX]>=prio))
{
// if (gpu->setFinalColorSpr(gpu, sprX << 1, 4, dst, colour, sprX ))
{
T2WriteWord(dst, (sprX<<1), colour);
dst_alpha[sprX] = spriteInfo->PaletteIndex;
typeTab[sprX] = spriteInfo->Mode;
prioTab[sprX] = prio;
}
}
}
// Add the rotation/scale coeficients, here the rotation/scaling
// is performed
realX += dx;
realY += dy;
}
continue;
}
// Rotozoomed 16/16 palette
else
{
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<5));
CHECK_SPRITE(2);
pal = ARM9Mem.ARM9_VMEM + 0x200 + (gpu->core*0x400 + (spriteInfo->PaletteIndex*32));
for(j = 0; j < lg; ++j, ++sprX)
{
// Get the integer part of the fixed point 8.8, and check if it lies inside the sprite data
auxX = (realX>>8);
auxY = (realY>>8);
if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y)
{
offset = ((auxX>>1)&0x3) + (((auxX>>1)&0xFFFC)<<3) + ((auxY>>3)<<10) + ((auxY&0x7)*4);
colour = src[offset];
if (auxX&1) colour >>= 4;
else colour &= 0xF;
if(colour && (prioTab[sprX]>=prio))
{
// if (gpu->setFinalColorSpr(gpu, sprX << 1,4,dst, T1ReadWord (pal, colour<<1), sprX))
{
T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1)));
dst_alpha[sprX] = 16;
typeTab[sprX] = spriteInfo->Mode;
prioTab[sprX] = prio;
}
}
}
// Add the rotation/scale coeficients, here the rotation/scaling
// is performed
realX += dx;
realY += dy;
}
continue;
}
}
else
{
u16 *pal;
if (!compute_sprite_vars(spriteInfo, l, sprSize, sprX, sprY, x, y, lg, xdir))
continue;
if (spriteInfo->Mode == 2) {
if (spriteInfo->Depth) if (spriteInfo->Depth)
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8));
else else
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4));
CHECK_SPRITE(2); }
else
{
if (spriteInfo->Depth)
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8));
else
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*4) + ((y&0x7)*4));
}
if (!src) {
continue;
}
render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir); render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir);
continue; continue;
@ -2614,17 +2347,25 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
else // 128 * 512 else // 128 * 512
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1));
} }
CHECK_SPRITE(2);
if (!src) {
continue;
}
render_sprite_BMP (gpu, i, l, dst, (u16*)src, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->PaletteIndex); render_sprite_BMP (gpu, i, l, dst, (u16*)src, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->PaletteIndex);
continue; continue;
} }
if(spriteInfo->Depth) /* 256 colors */ if(spriteInfo->Depth) /* 256 colors */
{ {
if(MODE == SPRITE_2D)
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8));
CHECK_SPRITE(2); else
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8));
if (!src) {
continue;
}
if (dispCnt->ExOBJPalette_Enable) if (dispCnt->ExOBJPalette_Enable)
pal = (u16*)(ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200)); pal = (u16*)(ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200));
@ -2636,15 +2377,25 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
continue; continue;
} }
// 16 colors
/* 16 colors */ if(MODE == SPRITE_2D)
{
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4));
CHECK_SPRITE(2); }
else
{
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*4) + ((y&0x7)*4));
}
if (!src) {
continue;
}
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400); pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400);
pal += (spriteInfo->PaletteIndex<<4); pal += (spriteInfo->PaletteIndex<<4);
render_sprite_16 (gpu, l, dst, src, pal,
dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->Mode == 1); render_sprite_16 (gpu, l, dst, src, pal, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->Mode == 1);
} }
} }
@ -2654,6 +2405,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri
#endif #endif
} }
/*****************************************************************************/ /*****************************************************************************/
// SCREEN FUNCTIONS // SCREEN FUNCTIONS
/*****************************************************************************/ /*****************************************************************************/
@ -2879,7 +2631,8 @@ static void GPU_ligne_layer(NDS_Screen * screen, u16 l)
//but it has been changed to write u32 instead of u16 for a little speedup //but it has been changed to write u32 instead of u16 for a little speedup
for(int i = 0; i< 128; ++i) T2WriteWord(spr, i << 2, c | (c<<16)); for(int i = 0; i< 128; ++i) T2WriteWord(spr, i << 2, c | (c<<16));
gpu->spriteRender(gpu, l, spr, sprAlpha, sprType, sprPrio);
gpu->spriteRender(spr, sprAlpha, sprType, sprPrio);
mosaicSpriteLine(gpu, l, spr, sprAlpha, sprType, sprPrio); mosaicSpriteLine(gpu, l, spr, sprAlpha, sprType, sprPrio);

View File

@ -403,6 +403,9 @@ void register_gl_fun(fun_gl_Begin beg,fun_gl_End end);
#define ADDRESS_STEP_16KB 0x04000 #define ADDRESS_STEP_16KB 0x04000
#define ADDRESS_STEP_32KB 0x08000 #define ADDRESS_STEP_32KB 0x08000
#define ADDRESS_STEP_64kB 0x10000 #define ADDRESS_STEP_64kB 0x10000
#define ADDRESS_STEP_128KB 0x20000
#define ADDRESS_STEP_256KB 0x40000
#define ADDRESS_MASK_256KB (ADDRESS_STEP_256KB-1)
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
struct _TILEENTRY struct _TILEENTRY
@ -717,12 +720,17 @@ struct GPU
typedef void (*FinalOBJColFunct)(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x); typedef void (*FinalOBJColFunct)(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x);
typedef void (*Final3DColFunct)(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u16 x); typedef void (*Final3DColFunct)(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u16 x);
typedef void (*SpriteRenderFunct) (GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab);
int setFinalColorBck_funcNum; int setFinalColorBck_funcNum;
FinalOBJColFunct setFinalColorSpr; FinalOBJColFunct setFinalColorSpr;
Final3DColFunct setFinalColor3D; Final3DColFunct setFinalColor3D;
SpriteRenderFunct spriteRender; enum SpriteRenderMode {
SPRITE_1D, SPRITE_2D
} spriteRenderMode;
template<GPU::SpriteRenderMode MODE>
void _spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab);
void spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab);
void setFinalColorBG(u16 color, u8 x); void setFinalColorBG(u16 color, u8 x);
FORCEINLINE void setFinalBGColorSpecialNone(u16 color, u8 x, bool blend1); FORCEINLINE void setFinalBGColorSpecialNone(u16 color, u8 x, bool blend1);

View File

@ -482,7 +482,10 @@ u8 *MMU_RenderMapToLCD(u32 vram_addr)
// holes // holes
if ((vram_addr > 0x6080000) && (vram_addr < 0x6200000)) return NULL; // Engine ABG max 512KB if ((vram_addr > 0x6080000) && (vram_addr < 0x6200000)) return NULL; // Engine ABG max 512KB
if ((vram_addr > 0x6220000) && (vram_addr < 0x6400000)) return NULL; // Engine BBG max 128KB if ((vram_addr > 0x6220000) && (vram_addr < 0x6400000)) return NULL; // Engine BBG max 128KB
if ((vram_addr > 0x6420000) && (vram_addr < 0x6600000)) return NULL; // Engine AOBJ max 256KB if ((vram_addr >= 0x6440000) && (vram_addr < 0x6600000)) {
assert(false); //please verify
vram_addr = (vram_addr & ADDRESS_MASK_256KB) + 0x6440000; // Engine AOBJ max 256KB
}
vram_addr &= 0x0FFFFFF; vram_addr &= 0x0FFFFFF;
u8 engine = (vram_addr >> 21); u8 engine = (vram_addr >> 21);

View File

@ -39,7 +39,6 @@ typedef struct
} oamview_struct; } oamview_struct;
oamview_struct *OAMView = NULL; oamview_struct *OAMView = NULL;
//extern NDSSystem nds;
const char dimm[4][4][8] = const char dimm[4][4][8] =
{ {
@ -180,9 +179,11 @@ LRESULT OamView_OnPaint(HWND hwnd, oamview_struct *win, WPARAM wParam, LPARAM lP
SetWindowText(GetDlgItem(hwnd, IDC_PROP1), ""); SetWindowText(GetDlgItem(hwnd, IDC_PROP1), "");
} }
GPU copy = *win->gpu;
for(i = 0; i < 192; ++i) for(i = 0; i < 192; ++i)
{ {
win->gpu->spriteRender(win->gpu, i, (u8*)(bitmap + i*256), bitmap_alpha + i*256, type + i*256, prio + i*256); copy.currLine = i;
copy.spriteRender((u8*)(bitmap + i*256), bitmap_alpha + i*256, type + i*256, prio + i*256);
} }
SetDIBitsToDevice(hdc, 180, 4, 256, 192, 0, 0, 0, 192, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); SetDIBitsToDevice(hdc, 180, 4, 256, 192, 0, 0, 0, 192, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
@ -319,7 +320,7 @@ BOOL CALLBACK ViewOAMProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
case IDC_SCR_SELECT : case IDC_SCR_SELECT :
switch(HIWORD(wParam)) switch(HIWORD(wParam))
{ {
case CBN_CLOSEUP : case CBN_SELCHANGE :
{ {
u32 sel = SendMessage(GetDlgItem(hwnd, IDC_SCR_SELECT), CB_GETCURSEL, 0, 0); u32 sel = SendMessage(GetDlgItem(hwnd, IDC_SCR_SELECT), CB_GETCURSEL, 0, 0);
switch(sel) switch(sel)

View File

@ -2238,7 +2238,7 @@ STYLE DS_SETFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_SYSMENU
CAPTION "OAM Fremviser" CAPTION "OAM Fremviser"
FONT 8, "MS Sans Serif", 0, 0, 1 FONT 8, "MS Sans Serif", 0, 0, 1
{ {
COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWN COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWNLIST
SCROLLBAR IDC_SCROLLER, 48, 20, 20, 14, WS_VISIBLE SCROLLBAR IDC_SCROLLER, 48, 20, 20, 14, WS_VISIBLE
LTEXT "Mode :", IDC_STATIC, 4, 36, 45, 8, SS_LEFT LTEXT "Mode :", IDC_STATIC, 4, 36, 45, 8, SS_LEFT
LTEXT "Tile :", IDC_STATIC, 4, 46, 45, 8, SS_LEFT LTEXT "Tile :", IDC_STATIC, 4, 46, 45, 8, SS_LEFT
@ -2274,7 +2274,7 @@ STYLE DS_CENTER | DS_SETFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME
CAPTION "OAM Viewer" CAPTION "OAM Viewer"
FONT 8, "MS Sans Serif", 0, 0, 1 FONT 8, "MS Sans Serif", 0, 0, 1
{ {
COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWN COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWNLIST
SCROLLBAR IDC_SCROLLER, 48, 20, 20, 14, WS_VISIBLE SCROLLBAR IDC_SCROLLER, 48, 20, 20, 14, WS_VISIBLE
LTEXT "Mode :", IDC_STATIC, 4, 36, 45, 8, SS_LEFT LTEXT "Mode :", IDC_STATIC, 4, 36, 45, 8, SS_LEFT
LTEXT "Tile :", IDC_STATIC, 4, 46, 45, 8, SS_LEFT LTEXT "Tile :", IDC_STATIC, 4, 46, 45, 8, SS_LEFT
@ -2310,7 +2310,7 @@ STYLE DS_SETFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_SYSMENU
CAPTION "OAM Viewer" CAPTION "OAM Viewer"
FONT 8, "MS Sans Serif", 0, 0, 1 FONT 8, "MS Sans Serif", 0, 0, 1
{ {
COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWN COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWNLIST
SCROLLBAR IDC_SCROLLER, 48, 20, 20, 14, WS_VISIBLE SCROLLBAR IDC_SCROLLER, 48, 20, 20, 14, WS_VISIBLE
LTEXT "Mode :", IDC_STATIC, 4, 36, 45, 8, SS_LEFT LTEXT "Mode :", IDC_STATIC, 4, 36, 45, 8, SS_LEFT
LTEXT "Tile :", IDC_STATIC, 4, 46, 45, 8, SS_LEFT LTEXT "Tile :", IDC_STATIC, 4, 46, 45, 8, SS_LEFT