simplified 16c sprite rendering

This commit is contained in:
damdoum 2007-01-25 19:48:37 +00:00
parent 8319efb6ee
commit 7e91c55b0a
2 changed files with 51 additions and 136 deletions

View File

@ -24,7 +24,7 @@
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "MMU.h"
#include "GPU.h"
#include "debug.h"
@ -140,11 +140,11 @@ void GPU_DeInit(GPU * gpu)
void GPU_resortBGs(GPU *gpu)
{
u8 i, j, prio;
int i, j, prio;
struct _DISPCNT * cnt = &gpu->dispCnt.bits;
itemsForPriority_t * item;
for (i=0; i<192; i++)
for (i=0; i<256; i++)
memset(gpu->sprWin[i],0, 256);
// we don't need to check for windows here...
@ -667,6 +667,7 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * dst, u32 Y, u16 XBG, u16 Y
u8 *map = gpu->BG_map_ram[num] + (tmp&31) * 64;
u8 *tile, *pal, *line;
u16 color;
u16 xoff = XBG;
u16 yoff;
u16 x = 0;
@ -711,9 +712,10 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * dst, u32 Y, u16 XBG, u16 Y
#define RENDERL(c,m) \
if (c) renderline_setFinalColor(gpu,0,num,dst,T1ReadWord(pal, ((c) + (tileentry.bits.Palette* m)) << 1),x,Y) ; \
color = T1ReadWord(pal, ((c) + (tileentry.bits.Palette* m)) << 1); \
if (c) renderline_setFinalColor(gpu,0,num,dst,color,x,Y) ; \
dst += 2; x++; xoff++;
if(tileentry.bits.HFlip)
{
line += 3 - ((xoff&7)>>1);
@ -1045,10 +1047,10 @@ void extRotBG(GPU * gpu, u8 num, u8 * DST)
#define nbShow 128
#define RENDER_COND(cond) RENDER_COND_OFFSET(cond,)
#define RENDER_COND_OFFSET(cond,offset) \
if((cond)&&(prioTab[sprX offset]>=prio)) \
if ((cond)&&(prio<=prioTab[sprX offset])) \
{ \
renderline_setFinalColor(gpu, (sprX offset) << 1,4,dst, color,(sprX offset),l); \
prioTab[sprX offset] = prio; \
renderline_setFinalColor(gpu, (sprX offset) << 1,4,dst, color, (sprX offset) ,l); \
}
/* if i understand it correct, and it fixes some sprite problems in chameleon shot */
@ -1068,7 +1070,7 @@ INLINE void render_sprite_BMP (GPU * gpu, u16 l, u8 * dst, u16 * src,
INLINE void render_sprite_256 (GPU * gpu, u16 l, u8 * dst, u8 * src, u16 * pal,
u8 * prioTab, u8 prio, int lg, int sprX, int x, int xdir) {
int i; u8 palette_entry; u16 color;
prio = 0;
for(i = 0; i < lg; i++, ++sprX, x+=xdir)
{
palette_entry = src[(x&0x7) + ((x&0xFFF8)<<3)];
@ -1078,123 +1080,38 @@ INLINE void render_sprite_256 (GPU * gpu, u16 l, u8 * dst, u8 * src, u16 * pal,
}
}
INLINE void render_sprite_16 (GPU * gpu, u16 l, u8 * dst, u8 * src, u8 * pal,
INLINE void render_sprite_16 (GPU * gpu, u16 l, u8 * dst, u8 * src, u16 * pal,
u8 * prioTab, u8 prio, int lg, int sprX, int x, int xdir) {
int i; u8 palette, palette_entry; u16 color;
#define BLOCK(op) \
palette_entry = palette op; \
color = T1ReadWord(pal, palette_entry << 1); \
RENDER_COND(palette_entry >0) \
++sprX;
#if 0
if (xdir<0) x++;
if(x&1)
u16 x1;
for(i = 0; i < lg; i++, ++sprX, x+=xdir)
{
s32 x1 = (x>>1);
x1 = x>>1;
palette = src[(x1&0x3) + ((x1&0xFFFC)<<3)];
BLOCK(>> 4)
x1 = ((x+lg-1)>>1);
palette = src[(x1&0x3) + ((x1&0xFFFC)<<3)];
palette_entry = palette >> 4;
color = T1ReadWord(pal, palette_entry << 1);
RENDER_COND_OFFSET(palette_entry>0,+lg-1)
++sprX;
if (x & 1) palette_entry = palette >> 4;
else palette_entry = palette & 0xF;
color = pal[palette_entry];
// palette entry = 0 means backdrop
RENDER_COND(palette_entry>0)
}
if (xdir<0) x--;
++sprX;
lg >>= 1;
x >>= 1;
// 16 colors
if (xdir<0) {
for(i = 0; i < lg; ++i, x+=xdir)
{
palette = src[(x&0x3) + ((x&0xFFFC)<<3)];
BLOCK(>> 4)
BLOCK(& 0xF)
}
} else {
for(i = 0; i < lg; ++i, x+=xdir)
{
palette = src[(x&0x3) + ((x&0xFFFC)<<3)];
BLOCK(& 0xF)
BLOCK(>> 4)
}
}
#else
x >>= 1;
if (xdir<0) {
if (lg&1) {
palette = src[(x&0x3) + ((x&0xFFFC)<<3)];
BLOCK(>> 4)
x+=xdir;
}
for(i = 1; i < lg; i+=2, x+=xdir)
{
palette = src[(x&0x3) + ((x&0xFFFC)<<3)];
BLOCK(>> 4)
BLOCK(& 0xF)
}
} else {
for(i = 1; i < lg; i+=2, x+=xdir)
{
palette = src[(x&0x3) + ((x&0xFFFC)<<3)];
BLOCK(& 0xF)
BLOCK(>> 4)
}
if (lg&1) {
palette = src[(x&0x3) + ((x&0xFFFC)<<3)];
BLOCK(& 0xF)
}
}
#endif
#undef BLOCK
}
INLINE void render_sprite_Win (GPU * gpu, u16 l, u8 * src,
int col256, int lg, int sprX, int x, int xdir) {
int i; u8 palette, palette_entry;
u16 x1;
if (col256) {
for(i = 0; i < lg; i++, sprX++,x+=xdir)
gpu->sprWin[l][sprX] = (src[x])?1:0;
} else {
#define BLOCK(op) \
palette_entry = palette op; \
gpu->sprWin[l][sprX] = (palette_entry>0)?1:0; \
++sprX;
x >>= 1;
sprX++;
if (xdir<0) {
if (lg&1) {
palette = src[(x&0x3) + ((x&0xFFFC)<<3)];
BLOCK(>> 4)
x+=xdir;
}
for(i = 1; i < lg; i+=2, x+=xdir)
{
palette = src[(x&0x3) + ((x&0xFFFC)<<3)];
BLOCK(>> 4)
BLOCK(& 0xF)
}
} else {
for(i = 1; i < lg; i+=2, x+=xdir)
{
palette = src[(x&0x3) + ((x&0xFFFC)<<3)];
BLOCK(& 0xF)
BLOCK(>> 4)
}
if (lg&1) {
palette = src[(x&0x3) + ((x&0xFFFC)<<3)];
BLOCK(& 0xF)
}
for(i = 0; i < lg; i++, ++sprX, x+=xdir)
{
x1 = x>>1;
palette = src[(x1&0x3) + ((x1&0xFFFC)<<3)];
if (x & 1) palette_entry = palette >> 4;
else palette_entry = palette & 0xF;
gpu->sprWin[l][sprX] = (palette_entry)?1:0;
}
#undef BLOCK
}
}
@ -1212,7 +1129,7 @@ INLINE BOOL compute_sprite_vars(_OAM_ * spriteInfo, u16 l,
*lg = sprSize->x;
if (*sprY>192)
if (*sprY>=192)
*sprY = (s32)((s8)(spriteInfo->Y));
// FIXME: for rot/scale, a list of entries into the sprite should be maintained,
@ -1221,7 +1138,7 @@ INLINE BOOL compute_sprite_vars(_OAM_ * spriteInfo, u16 l,
if ((spriteInfo->RotScale == 2) || /* rotscale == 2 => sprite disabled */
(l<*sprY)||(l>=*sprY+sprSize->y) || /* sprite lines outside of screen */
(*sprX==256)||(*sprX+sprSize->x<0)) /* sprite pixels outside of line */
(*sprX==256)||(*sprX+sprSize->x<=0)) /* sprite pixels outside of line */
return FALSE; /* not to be drawn */
// sprite portion out of the screen (LEFT)
@ -1230,8 +1147,9 @@ INLINE BOOL compute_sprite_vars(_OAM_ * spriteInfo, u16 l,
*lg += *sprX;
*x = -(*sprX);
*sprX = 0;
}
// sprite portion out of the screen (RIGHT)
} else if (*sprX+sprSize->x >= 256)
if (*sprX+sprSize->x >= 256)
*lg = 256 - *sprX;
*y = l - *sprY; /* get the y line within sprite coords */
@ -1274,13 +1192,12 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
size sprSize;
s32 sprX, sprY, x, y, lg;
int xdir;
u8 prio, * src, * pal;
u8 prio, * src;
u16 * pal;
u16 i,j;
u16 rotScaleA,rotScaleB,rotScaleC,rotScaleD;
prio = spriteInfo->Priority;
if (!compute_sprite_vars(spriteInfo, l, &sprSize, &sprX, &sprY, &x, &y, &lg, &xdir))
continue;
@ -1314,20 +1231,20 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
src = gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8);
if (gpu->dispCnt.bits.ExOBJPalette_Enable)
pal = ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200);
pal = (u16*)(ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200));
else
pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400;
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400);
render_sprite_256 (gpu, l, dst, src, (u16*)pal,
render_sprite_256 (gpu, l, dst, src, pal,
prioTab, prio, lg, sprX, x, xdir);
continue;
}
/* 16 colors */
src = gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*4) + ((y&0x7)*4);
pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400;
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400);
pal += (spriteInfo->PaletteIndex<<4)<<1;
pal += (spriteInfo->PaletteIndex<<4);
render_sprite_16 (gpu, l, dst, src, pal,
prioTab, prio, lg, sprX, x, xdir);
@ -1344,7 +1261,8 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
size sprSize;
s32 sprX, sprY, x, y, lg;
int xdir;
u8 prio, * src, * pal;
u8 prio, * src;
u16 * pal;
u16 i,j;
u16 rotScaleA,rotScaleB,rotScaleC,rotScaleD;
int block;
@ -1384,9 +1302,9 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
if(spriteInfo->Depth) /* 256 colors */
{
src = gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8);
pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400;
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400);
render_sprite_256 (gpu, l, dst, src, (u16*)pal,
render_sprite_256 (gpu, l, dst, src, pal,
prioTab, prio, lg, sprX, x, xdir);
continue;
@ -1394,9 +1312,9 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
/* 16 colors */
src = gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4);
pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400;
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400);
pal += (spriteInfo->PaletteIndex<<4)<<1;
pal += (spriteInfo->PaletteIndex<<4);
render_sprite_16 (gpu, l, dst, src, pal,
prioTab, prio, lg, sprX, x, xdir);
}

View File

@ -391,7 +391,7 @@ struct _GPU
MASTER_BRIGHT masterBright;
BOOL LayersEnable[5];
itemsForPriority_t itemsForPriority[NB_PRIORITIES];
u8 sprWin[192*2][256];
u8 sprWin[256*2][256];
#define BGBmpBB BG_bmp_ram
#define BGChBB BG_tile_ram
@ -557,16 +557,14 @@ static INLINE void GPU_ligne(Screen * screen, u16 l)
c = T1ReadWord(ARM9Mem.ARM9_VMEM, gpu->core * 0x400);
c |= (c<<16);
// init background color & priorities
for(i8 = 0; i8< 128; ++i8)
for(i = 0; i< 256; ++i)
{
T2WriteLong(dst, i8 << 2, c);
T2WriteLong(spr, i8 << 2, c);
// we init the sprites with priority 4 (if they keep it = unprocessed)
T1WriteWord(sprPrio, i8 << 1, 0xFFFF);
T1WriteWord(gpu->sprWin[l], i8 << 1, 0);
T1WriteWord(dst, i << 1, c);
T1WriteWord(spr, i << 1, c);
sprPrio[i]=0xFF;
gpu->sprWin[l][i]=0;
}
// init pixels priorities
@ -583,7 +581,6 @@ static INLINE void GPU_ligne(Screen * screen, u16 l)
// render 1 time, but prio 4 = isn't processed further
if (prio >=4) continue;
T2WriteWord(dst, i << 1, T2ReadWord(spr, i << 1));
item = &(gpu->itemsForPriority[prio]);
item->PixelsX[item->nbPixelsX]=i;
@ -613,7 +610,7 @@ static INLINE void GPU_ligne(Screen * screen, u16 l)
// FIXME !!!
/* capture */
capcnt = &gpu->dispCapCnt.bits;
if (0 & capcnt->Capture_Enable)
if (capcnt->Capture_Enable)
{
u16 * srcA, * srcB, *vram;
u32 c; u8 vram_bank;