more fixes to bg affine parameter handling. I am becoming increasingly dissatisfied with the way this is handled, but we need to collect more test cases. this actually reverts the changes from rev 2010 and fixes it a better way (by adding support for 16bit affine parameter startpoint writes)
This commit is contained in:
parent
18b3701693
commit
3708a80b54
|
@ -2364,7 +2364,10 @@ void GPU::_spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab)
|
||||||
//NOT TESTED:
|
//NOT TESTED:
|
||||||
|
|
||||||
if (dispCnt->OBJ_BMP_2D_dim) // 256*256
|
if (dispCnt->OBJ_BMP_2D_dim) // 256*256
|
||||||
|
{
|
||||||
|
//verified by heroes of mana FMV intro
|
||||||
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&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1));
|
||||||
|
}
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
@ -3042,6 +3045,20 @@ void GPU_ligne(NDS_Screen * screen, u16 l)
|
||||||
GPU * gpu = screen->gpu;
|
GPU * gpu = screen->gpu;
|
||||||
GPU_tempScanline_valid = false;
|
GPU_tempScanline_valid = false;
|
||||||
|
|
||||||
|
//here is some setup which is only done on line 0
|
||||||
|
if(l == 0) {
|
||||||
|
//this is speculative. the idea is as follows:
|
||||||
|
//whenever the user updates the affine start position regs, it goes into the active regs immediately
|
||||||
|
//(this is handled on the set event from MMU)
|
||||||
|
//maybe it shouldnt take effect until the next hblank or something..
|
||||||
|
//this is a based on a combination of:
|
||||||
|
//heroes of mana intro FMV
|
||||||
|
//SPP level 3-8 rotoscale room
|
||||||
|
//NSMB raster fx backdrops
|
||||||
|
//bubble bobble revolution classic mode
|
||||||
|
gpu->refreshAffineStartRegs();
|
||||||
|
}
|
||||||
|
|
||||||
//cache some parameters which are assumed to be stable throughout the rendering of the entire line
|
//cache some parameters which are assumed to be stable throughout the rendering of the entire line
|
||||||
gpu->currLine = (u8)l;
|
gpu->currLine = (u8)l;
|
||||||
u16 mosaic_control = T1ReadWord((u8 *)&gpu->dispx_st->dispx_MISC.MOSAIC, 0);
|
u16 mosaic_control = T1ReadWord((u8 *)&gpu->dispx_st->dispx_MISC.MOSAIC, 0);
|
||||||
|
@ -3134,6 +3151,42 @@ bool gpu_loadstate(std::istream* is)
|
||||||
return !is->fail();
|
return !is->fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GPU::getAffineStart(int layer, int xy)
|
||||||
|
{
|
||||||
|
if(xy==0) return affineInfo[layer-2].x;
|
||||||
|
else return affineInfo[layer-2].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPU::setAffineStartWord(int layer, int xy, u16 val, int word)
|
||||||
|
{
|
||||||
|
u32 curr = getAffineStart(layer,xy);
|
||||||
|
if(word==0) curr = (curr&0xFFFF0000)|val;
|
||||||
|
else curr = (curr&0x0000FFFF)|(((u32)val)<<16);
|
||||||
|
setAffineStart(layer,xy,curr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPU::setAffineStart(int layer, int xy, u32 val)
|
||||||
|
{
|
||||||
|
if(xy==0) affineInfo[layer-2].x = val;
|
||||||
|
else affineInfo[layer-2].y = val;
|
||||||
|
refreshAffineStartRegs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPU::refreshAffineStartRegs()
|
||||||
|
{
|
||||||
|
for(int num=2;num<=3;num++)
|
||||||
|
{
|
||||||
|
BGxPARMS * parms;
|
||||||
|
if (num==2)
|
||||||
|
parms = &(dispx_st)->dispx_BG2PARMS;
|
||||||
|
else
|
||||||
|
parms = &(dispx_st)->dispx_BG3PARMS;
|
||||||
|
|
||||||
|
parms->BGxX = affineInfo[num-2].x;
|
||||||
|
parms->BGxY = affineInfo[num-2].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void gpu_UpdateRender()
|
void gpu_UpdateRender()
|
||||||
{
|
{
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
|
|
|
@ -761,6 +761,15 @@ struct GPU
|
||||||
|
|
||||||
|
|
||||||
void __setFinalColorBck(u16 color, u8 x, bool opaque);
|
void __setFinalColorBck(u16 color, u8 x, bool opaque);
|
||||||
|
void setAffineStart(int layer, int xy, u32 val);
|
||||||
|
void setAffineStartWord(int layer, int xy, u16 val, int word);
|
||||||
|
u32 getAffineStart(int layer, int xy);
|
||||||
|
void refreshAffineStartRegs();
|
||||||
|
|
||||||
|
struct AffineInfo {
|
||||||
|
AffineInfo() : x(0), y(0) {}
|
||||||
|
u32 x, y;
|
||||||
|
} affineInfo[2];
|
||||||
|
|
||||||
void renderline_checkWindows(u16 x, bool &draw, bool &effect) const;
|
void renderline_checkWindows(u16 x, bool &draw, bool &effect) const;
|
||||||
|
|
||||||
|
|
|
@ -1556,6 +1556,23 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
||||||
// Address is an IO register
|
// Address is an IO register
|
||||||
switch(adr)
|
switch(adr)
|
||||||
{
|
{
|
||||||
|
case REG_DISPA_BG2XL: MainScreen.gpu->setAffineStartWord(2,0,val,0); break;
|
||||||
|
case REG_DISPA_BG2XH: MainScreen.gpu->setAffineStartWord(2,0,val,1); break;
|
||||||
|
case REG_DISPA_BG2YL: MainScreen.gpu->setAffineStartWord(2,1,val,0); break;
|
||||||
|
case REG_DISPA_BG2YH: MainScreen.gpu->setAffineStartWord(2,1,val,1); break;
|
||||||
|
case REG_DISPA_BG3XL: MainScreen.gpu->setAffineStartWord(3,0,val,0); break;
|
||||||
|
case REG_DISPA_BG3XH: MainScreen.gpu->setAffineStartWord(3,0,val,1); break;
|
||||||
|
case REG_DISPA_BG3YL: MainScreen.gpu->setAffineStartWord(3,1,val,0); break;
|
||||||
|
case REG_DISPA_BG3YH: MainScreen.gpu->setAffineStartWord(3,1,val,1); break;
|
||||||
|
case REG_DISPB_BG2XL: SubScreen.gpu->setAffineStartWord(2,0,val,0); break;
|
||||||
|
case REG_DISPB_BG2XH: SubScreen.gpu->setAffineStartWord(2,0,val,1); break;
|
||||||
|
case REG_DISPB_BG2YL: SubScreen.gpu->setAffineStartWord(2,1,val,0); break;
|
||||||
|
case REG_DISPB_BG2YH: SubScreen.gpu->setAffineStartWord(2,1,val,1); break;
|
||||||
|
case REG_DISPB_BG3XL: SubScreen.gpu->setAffineStartWord(3,0,val,0); break;
|
||||||
|
case REG_DISPB_BG3XH: SubScreen.gpu->setAffineStartWord(3,0,val,1); break;
|
||||||
|
case REG_DISPB_BG3YL: SubScreen.gpu->setAffineStartWord(3,1,val,0); break;
|
||||||
|
case REG_DISPB_BG3YH: SubScreen.gpu->setAffineStartWord(3,1,val,1); break;
|
||||||
|
|
||||||
case REG_DISPA_DISP3DCNT:
|
case REG_DISPA_DISP3DCNT:
|
||||||
{
|
{
|
||||||
MainScreen.gpu->dispx_st->dispA_DISP3DCNT.val = val;
|
MainScreen.gpu->dispx_st->dispA_DISP3DCNT.val = val;
|
||||||
|
@ -2194,6 +2211,31 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
||||||
|
|
||||||
switch(adr)
|
switch(adr)
|
||||||
{
|
{
|
||||||
|
case REG_DISPA_BG2XL:
|
||||||
|
MainScreen.gpu->setAffineStart(2,0,val);
|
||||||
|
return;
|
||||||
|
case REG_DISPA_BG2YL:
|
||||||
|
MainScreen.gpu->setAffineStart(2,1,val);
|
||||||
|
return;
|
||||||
|
case REG_DISPB_BG2XL:
|
||||||
|
SubScreen.gpu->setAffineStart(2,0,val);
|
||||||
|
return;
|
||||||
|
case REG_DISPB_BG2YL:
|
||||||
|
SubScreen.gpu->setAffineStart(2,1,val);
|
||||||
|
return;
|
||||||
|
case REG_DISPA_BG3XL:
|
||||||
|
MainScreen.gpu->setAffineStart(3,0,val);
|
||||||
|
return;
|
||||||
|
case REG_DISPA_BG3YL:
|
||||||
|
MainScreen.gpu->setAffineStart(3,1,val);
|
||||||
|
return;
|
||||||
|
case REG_DISPB_BG3XL:
|
||||||
|
SubScreen.gpu->setAffineStart(3,0,val);
|
||||||
|
return;
|
||||||
|
case REG_DISPB_BG3YL:
|
||||||
|
SubScreen.gpu->setAffineStart(3,1,val);
|
||||||
|
return;
|
||||||
|
|
||||||
case 0x04000600:
|
case 0x04000600:
|
||||||
GFX_FIFOcnt(val);
|
GFX_FIFOcnt(val);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue