gfx test 1 = passed
gfx test 2 = passed mode3 test = passed window test= passed (but glitches) priorities handling BG / OBJ
This commit is contained in:
parent
1018d57318
commit
70df09c6a1
|
@ -126,60 +126,65 @@ void GPU_DeInit(GPU * gpu)
|
|||
|
||||
void GPU_resortBGs(GPU *gpu)
|
||||
{
|
||||
BOOL LayersEnable[5];
|
||||
u16 WinBG=0;
|
||||
u8 i, q, index;
|
||||
u16 WinBG=0;
|
||||
u8 i, j, prio;
|
||||
struct _DISPCNT * cnt = &gpu->dispCnt.bits;
|
||||
itemsForPriority_t * item;
|
||||
|
||||
if (cnt->Win0_Enable || cnt->Win1_Enable)
|
||||
{
|
||||
WinBG = (gpu->WINDOW_INCNT.val | gpu->WINDOW_OUTCNT.val);
|
||||
WinBG = WinBG | (WinBG >> 8);
|
||||
if (cnt->Win0_Enable || cnt->Win1_Enable) {
|
||||
WinBG = gpu->WINDOW_INCNT.val | gpu->WINDOW_OUTCNT.val;
|
||||
WinBG |= (WinBG >> 8);
|
||||
}
|
||||
|
||||
/*
|
||||
if (cnt->Win0_Enable || cnt->Win1_Enable) {
|
||||
if (cnt->Win0_Enable)
|
||||
WinBG |= (gpu->WINDOW_INCNT.val & 0xFF);
|
||||
if (cnt->Win1_Enable)
|
||||
WinBG |= (gpu->WINDOW_INCNT.val >> 8);
|
||||
WinBG |= (gpu->WINDOW_OUTCNT.val & 0xFF);
|
||||
WinBG |= (gpu->WINDOW_OUTCNT.val >> 8);
|
||||
}
|
||||
*/
|
||||
// Let's prepare the field for WINDOWS implementation
|
||||
LayersEnable[0] = gpu->dispBG[0] && (cnt->BG0_Enable || (WinBG & 0x1))&& !(gpu->dispCnt.bits.BG0_3D && (gpu->core==0)) ;
|
||||
LayersEnable[1] = gpu->dispBG[1] && (cnt->BG1_Enable || (WinBG & 0x2));
|
||||
LayersEnable[2] = gpu->dispBG[2] && (cnt->BG2_Enable || (WinBG & 0x4));
|
||||
LayersEnable[3] = gpu->dispBG[3] && (cnt->BG3_Enable || (WinBG & 0x8));
|
||||
LayersEnable[4] = (cnt->OBJ_Enable || (WinBG & 0x10));
|
||||
gpu->LayersEnable[0] = gpu->dispBG[0] && (cnt->BG0_Enable || (WinBG & 0x1))&& !(gpu->dispCnt.bits.BG0_3D && (gpu->core==0)) ;
|
||||
gpu->LayersEnable[1] = gpu->dispBG[1] && (cnt->BG1_Enable || (WinBG & 0x2));
|
||||
gpu->LayersEnable[2] = gpu->dispBG[2] && (cnt->BG2_Enable || (WinBG & 0x4));
|
||||
gpu->LayersEnable[3] = gpu->dispBG[3] && (cnt->BG3_Enable || (WinBG & 0x8));
|
||||
gpu->LayersEnable[4] = gpu->dispOBJ && (cnt->OBJ_Enable || (WinBG & 0x10));
|
||||
|
||||
/* first: place them all unsorted, just as they are */
|
||||
for (i=0;i<4;i++)
|
||||
{
|
||||
gpu->ordre[i] = i ;
|
||||
// KISS ! lower priority first, if same then lower num
|
||||
|
||||
for (i=0;i<NB_PRIORITIES;i++) {
|
||||
item = &(gpu->itemsForPriority[i]);
|
||||
item->nbBGs=0;
|
||||
item->nbPixelsX=0;
|
||||
}
|
||||
|
||||
/* sorting BGs by priority, keep same priorities ordered by their num */
|
||||
/* selection sort*/
|
||||
for (i=0;i<4;i++)
|
||||
{
|
||||
/* weighted priorities: first drawn/not drawm, then set priority bits, then the num */
|
||||
/* the higher the value the lower the priority */
|
||||
u8 curPrio = gpu->bgCnt[gpu->ordre[i]].bits.Priority*4 + (LayersEnable[gpu->ordre[i]]?16:0) + gpu->ordre[i] ;
|
||||
for (q=i+1;q<4;q++)
|
||||
{
|
||||
u8 lookingPrio = gpu->bgCnt[gpu->ordre[q]].bits.Priority*4 + (LayersEnable[gpu->ordre[q]]?16:0) + gpu->ordre[q] ;
|
||||
/* if the one we are looking for is of higher priority then the current selected, swap them */
|
||||
/* note: higher value = lower priority */
|
||||
if (lookingPrio > curPrio)
|
||||
{
|
||||
/* swap the order */
|
||||
u8 savedIndex = gpu->ordre[i] ;
|
||||
gpu->ordre[i] = gpu->ordre[q] ;
|
||||
gpu->ordre[q] = savedIndex ;
|
||||
/* update the current info */
|
||||
curPrio = lookingPrio ;
|
||||
} ;
|
||||
for (i=NB_BG,j=0; i>0; ) {
|
||||
i--;
|
||||
//if (!gpu->LayersEnable[i]) continue;
|
||||
prio = gpu->bgCnt[i].bits.Priority;
|
||||
item = &(gpu->itemsForPriority[prio]);
|
||||
item->BGs[item->nbBGs]=i;
|
||||
item->nbBGs++;
|
||||
j++;
|
||||
}
|
||||
gpu->nbBGActif = j;
|
||||
|
||||
#if 0
|
||||
//debug
|
||||
for (i=0;i<NB_PRIORITIES;i++) {
|
||||
item = &(gpu->itemsForPriority[i]);
|
||||
printf("%d : ", i);
|
||||
for (j=0; j<NB_PRIORITIES; j++) {
|
||||
if (j<item->nbBGs)
|
||||
printf("BG%d ", item->BGs[j]);
|
||||
else
|
||||
printf("... ", item->BGs[j]);
|
||||
}
|
||||
}
|
||||
/* once we are done ordering, create the inverse table */
|
||||
for (i=0;i<4;i++)
|
||||
{
|
||||
gpu->BGIndex[gpu->ordre[i]] = i ;
|
||||
/* and remember the processed highest enabled BG */
|
||||
if (LayersEnable[gpu->ordre[i]]) gpu->nbBGActif = i+1 ;
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -315,6 +315,15 @@ typedef union windowcnt_t
|
|||
for rendering.
|
||||
*/
|
||||
|
||||
#define NB_PRIORITIES 4
|
||||
#define NB_BG 4
|
||||
typedef struct
|
||||
{
|
||||
u8 BGs[NB_BG], nbBGs;
|
||||
u8 PixelsX[256], nbPixelsX;
|
||||
} itemsForPriority_t;
|
||||
|
||||
|
||||
typedef struct _GPU GPU;
|
||||
|
||||
struct _GPU
|
||||
|
@ -322,6 +331,8 @@ struct _GPU
|
|||
DISPCNT dispCnt;
|
||||
BGxCNT bgCnt[4];
|
||||
MASTER_BRIGHT masterBright;
|
||||
BOOL LayersEnable[5];
|
||||
itemsForPriority_t itemsForPriority[NB_PRIORITIES];
|
||||
|
||||
#define BGBmpBB BG_bmp_ram
|
||||
#define BGChBB BG_tile_ram
|
||||
|
@ -408,19 +419,18 @@ extern MMU_struct MMU;
|
|||
|
||||
static INLINE void GPU_ligne(Screen * screen, u16 l)
|
||||
{
|
||||
GPU * gpu = screen->gpu;
|
||||
u8 * dst = GPU_screen + (screen->offset + l) * 512;
|
||||
u8 spr[512];
|
||||
u8 sprPrio[256];
|
||||
u8 bgprio;
|
||||
int i;
|
||||
u8 i8;
|
||||
u16 i16;
|
||||
u32 c;
|
||||
u8 pixelsForPrio[4][256];
|
||||
u8 nbPixelsForPrio[4] = {0,0,0,0};
|
||||
u8 n,p;
|
||||
|
||||
GPU * gpu = screen->gpu;
|
||||
u8 * dst = GPU_screen + (screen->offset + l) * 512;
|
||||
itemsForPriority_t * item;
|
||||
u8 spr[512];
|
||||
u8 sprPrio[256];
|
||||
u8 bgprio,prio;
|
||||
int i;
|
||||
u8 i8;
|
||||
u16 i16;
|
||||
u32 c;
|
||||
u8 n,p;
|
||||
|
||||
/* initialize the scanline black */
|
||||
/* not doing this causes invalid colors when all active BGs are prevented to draw at some place */
|
||||
memset(dst,0,256*2) ;
|
||||
|
@ -464,49 +474,60 @@ static INLINE void GPU_ligne(Screen * screen, u16 l)
|
|||
{
|
||||
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, (4 << 8) | (4));
|
||||
|
||||
}
|
||||
|
||||
if (gpu->sprEnable && gpu->dispOBJ) {
|
||||
// nothing else to display but sprites...
|
||||
if(!gpu->nbBGActif) {
|
||||
gpu->spriteRender(gpu, l, dst, sprPrio);
|
||||
return;
|
||||
} else {
|
||||
gpu->spriteRender(gpu, l, spr, sprPrio);
|
||||
}
|
||||
// we also have backgrounds
|
||||
gpu->spriteRender(gpu, l, spr, sprPrio);
|
||||
}
|
||||
|
||||
if(!gpu->nbBGActif)
|
||||
{
|
||||
if (gpu->sprEnable)
|
||||
gpu->spriteRender(gpu, l, dst, sprPrio);
|
||||
return;
|
||||
// init pixels priorities
|
||||
for (i=0;i<NB_PRIORITIES;i++) {
|
||||
gpu->itemsForPriority[i].nbPixelsX = 0;
|
||||
}
|
||||
if (gpu->sprEnable)
|
||||
{
|
||||
gpu->spriteRender(gpu, l, spr, sprPrio);
|
||||
|
||||
if(gpu->bgCnt[gpu->ordre[0]].bits.Priority !=3)
|
||||
{
|
||||
for(i16 = 0; i16 < 128; ++i16) {
|
||||
T2WriteLong(dst, i16 << 2, T2ReadLong(spr, i16 << 2));
|
||||
}
|
||||
// for all the pixels in the line
|
||||
if (gpu->LayersEnable[4])
|
||||
for(i= 0; i<256; i++) {
|
||||
// assign them to the good priority item
|
||||
prio = sprPrio[i];
|
||||
|
||||
// render 1 time, but prio 4 = isn't processed further
|
||||
T2WriteWord(dst, i << 1, T2ReadWord(spr, i << 1));
|
||||
if (prio >=4) continue;
|
||||
|
||||
item = &(gpu->itemsForPriority[prio]);
|
||||
item->PixelsX[item->nbPixelsX]=i;
|
||||
item->nbPixelsX++;
|
||||
}
|
||||
|
||||
|
||||
// paint lower priorities fist
|
||||
// then higher priorities on top
|
||||
for(prio=NB_PRIORITIES; prio > 0; )
|
||||
{
|
||||
prio--;
|
||||
item = &(gpu->itemsForPriority[prio]);
|
||||
// render BGs
|
||||
for (i=0; i < item->nbBGs; i++) {
|
||||
i16 = item->BGs[i];
|
||||
if (gpu->LayersEnable[i16])
|
||||
modeRender[gpu->dispCnt.bits.BG_Mode][i16](gpu, i16, l, dst);
|
||||
}
|
||||
// render sprite Pixels
|
||||
for (i=0; i < item->nbPixelsX; i++) {
|
||||
i16=item->PixelsX[i];
|
||||
T2WriteWord(dst, i16 << 1, T2ReadWord(spr, i16 << 1));
|
||||
}
|
||||
}
|
||||
|
||||
for(i8 = 0; i8 < gpu->nbBGActif; ++i8)
|
||||
{
|
||||
if (! ((gpu->ordre[i8]==0) && gpu->dispCnt.bits.BG0_3D && (gpu->core==0)) )
|
||||
modeRender[gpu->dispCnt.bits.BG_Mode][gpu->ordre[i8]](gpu, gpu->ordre[i8], l, dst);
|
||||
bgprio = gpu->bgCnt[gpu->ordre[i8]].bits.Priority;
|
||||
if (gpu->sprEnable)
|
||||
{
|
||||
for(i16 = 0; i16 < 256; ++i16)
|
||||
if(bgprio>=sprPrio[i16])
|
||||
T2WriteWord(dst, i16 << 1, T2ReadWord(spr, i16 << 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Apply final brightness adjust (MASTER_BRIGHT)
|
||||
// Reference: http://nocash.emubase.de/gbatek.htm#dsvideo (Under MASTER_BRIGHTNESS)
|
||||
|
|
Loading…
Reference in New Issue