- More code cleanup.
This commit is contained in:
rogerman 2015-09-14 18:33:33 +00:00
parent f36f5b5627
commit da132f1f1c
3 changed files with 357 additions and 311 deletions

View File

@ -221,8 +221,8 @@ bool gpu_loadstate(EMUFILE* is, int size)
//subEngine->refreshAffineStartRegs(-1,-1);
}
mainEngine->ParseAllRegisters();
subEngine->ParseAllRegisters();
mainEngine->ParseAllRegisters<GPUEngineID_Main>();
subEngine->ParseAllRegisters<GPUEngineID_Sub>();
return !is->fail();
}
@ -319,7 +319,7 @@ void GPUEngineBase::_Reset_Base()
memset(this->_sprColor, 0, sizeof(this->_sprColor));
memset(this->_sprAlpha, 0, sizeof(this->_sprAlpha));
memset(this->_sprType, 0, sizeof(this->_sprType));
memset(this->_sprType, OBJMode_Normal, sizeof(this->_sprType));
memset(this->_sprPrio, 0x7F, sizeof(this->_sprPrio));
memset(this->_sprNum, 0, sizeof(this->_sprNum));
@ -362,11 +362,6 @@ void GPUEngineBase::_Reset_Base()
this->_needUpdateWINH[0] = true;
this->_needUpdateWINH[1] = true;
this->_dispMode = GPUDisplayMode_Off;
this->_vramBlock = 0;
this->_VRAMaddrNative = (u16 *)MMU.ARM9_LCD;
this->_VRAMaddrCustom = GPU->GetCustomVRAMBuffer();
this->isCustomRenderingNeeded = false;
this->is3DEnabled = false;
this->vramBGLayer = VRAM_NO_3D_USAGE;
@ -383,8 +378,6 @@ void GPUEngineBase::_Reset_Base()
this->_sprBoundary = 0;
this->_sprBMPBoundary = 0;
this->_sprBMPMode = 0;
this->_sprEnable = 0;
this->_WIN0_ENABLED = 0;
this->_WIN1_ENABLED = 0;
@ -542,6 +535,7 @@ void GPUEngineBase::SetupFinalPixelBlitter()
}
//Sets up LCD control variables for Display Engines A and B for quick reading
template<GPUEngineID ENGINEID>
void GPUEngineBase::ParseReg_DISPCNT()
{
const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT;
@ -552,30 +546,11 @@ void GPUEngineBase::ParseReg_DISPCNT()
this->SetupFinalPixelBlitter();
this->_dispMode = (GPUDisplayMode)( DISPCNT.DisplayMode & ((this->_engineID == GPUEngineID_Sub)?1:3) );
this->_vramBlock = DISPCNT.VRAM_Block;
switch (this->_dispMode)
if (ENGINEID == GPUEngineID_Main)
{
case GPUDisplayMode_Off: // Display Off
break;
case GPUDisplayMode_Normal: // Display BG and OBJ layers
break;
case GPUDisplayMode_VRAM: // Display framebuffer
{
this->_VRAMaddrNative = (u16 *)MMU.ARM9_LCD + (this->_vramBlock * GPU_VRAM_BLOCK_LINES * GPU_FRAMEBUFFER_NATIVE_WIDTH);
this->_VRAMaddrCustom = GPU->GetCustomVRAMBuffer() + (this->_vramBlock * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * GPU->GetCustomFramebufferWidth());
break;
}
case GPUDisplayMode_MainMemory: // Display from Main RAM
// nothing to be done here
// see GPU_RenderLine who gets data from FIFO.
break;
((GPUEngineA *)this)->UpdateSelectedVRAMBlock();
}
if (DISPCNT.OBJ_Tile_mapping)
{
//1-d sprite mapping boundaries:
@ -596,20 +571,18 @@ void GPUEngineBase::ParseReg_DISPCNT()
this->_spriteRenderMode = SpriteRenderMode_Sprite2D;
}
if (DISPCNT.OBJ_BMP_1D_Bound && (this->_engineID == GPUEngineID_Main))
if (DISPCNT.OBJ_BMP_1D_Bound && (ENGINEID == GPUEngineID_Main))
this->_sprBMPBoundary = 8;
else
this->_sprBMPBoundary = 7;
this->_sprEnable = DISPCNT.OBJ_Enable;
this->ParseReg_BGnCNT<GPULayerID_BG3>();
this->ParseReg_BGnCNT<GPULayerID_BG2>();
this->ParseReg_BGnCNT<GPULayerID_BG1>();
this->ParseReg_BGnCNT<GPULayerID_BG0>();
this->ParseReg_BGnCNT<ENGINEID, GPULayerID_BG3>();
this->ParseReg_BGnCNT<ENGINEID, GPULayerID_BG2>();
this->ParseReg_BGnCNT<ENGINEID, GPULayerID_BG1>();
this->ParseReg_BGnCNT<ENGINEID, GPULayerID_BG0>();
}
template <GPULayerID LAYERID>
template <GPUEngineID ENGINEID, GPULayerID LAYERID>
void GPUEngineBase::ParseReg_BGnCNT()
{
const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT;
@ -617,7 +590,7 @@ void GPUEngineBase::ParseReg_BGnCNT()
this->ResortBGLayers();
if (this->_engineID == GPUEngineID_Sub)
if (ENGINEID == GPUEngineID_Sub)
{
this->_BG_tile_ram[LAYERID] = MMU_BBG;
this->_BG_bmp_ram[LAYERID] = MMU_BBG;
@ -654,7 +627,7 @@ void GPUEngineBase::ParseReg_BGnCNT()
if (mode == BGType_AffineExt)
{
//see: http://nocash.emubase.de/gbatek.htm#dsvideobgmodescontrol
const u8 affineModeSelection = (BGnCNT.Palette_256 << 1) | (BGnCNT.CharacBase_Block & 1);
const u8 affineModeSelection = (BGnCNT.PaletteMode << 1) | (BGnCNT.CharacBase_Block & 1);
switch (affineModeSelection)
{
case 0:
@ -988,7 +961,7 @@ FORCEINLINE FASTCALL bool GPUEngineBase::_master_setFinalBGColor(const size_t sr
}
template<BlendFunc FUNC, bool WINDOW>
FORCEINLINE FASTCALL void GPUEngineBase::_master_setFinalOBJColor(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const u8 type)
FORCEINLINE FASTCALL void GPUEngineBase::_master_setFinalOBJColor(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const OBJMode objMode)
{
bool windowEffectSatisfied = true;
@ -1005,7 +978,7 @@ FORCEINLINE FASTCALL void GPUEngineBase::_master_setFinalOBJColor(const size_t s
//if the window effect is satisfied, then we can do color effects to modify the color
if (windowEffectSatisfied)
{
const bool isObjTranslucentType = type == GPU_OBJ_MODE_Transparent || type == GPU_OBJ_MODE_Bitmap;
const bool isObjTranslucentType = (objMode == OBJMode_Transparent) || (objMode == OBJMode_Bitmap);
const GPULayerID dstLayerID = (GPULayerID)dstLayerIDLine[dstX];
const bool firstTargetSatisfied = (this->_IORegisterMap->BLDCNT.OBJ_Target1 != 0);
const bool secondTargetSatisfied = (dstLayerID != GPULayerID_OBJ) && this->_blend2[dstLayerID];
@ -1114,18 +1087,18 @@ FORCEINLINE void GPUEngineBase::_SetFinalColor3D(const size_t srcX, const size_t
};
}
FORCEINLINE void GPUEngineBase::_SetFinalColorSprite(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const u8 type)
FORCEINLINE void GPUEngineBase::_SetFinalColorSprite(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const OBJMode objMode)
{
switch (this->_finalColorSpriteFuncID)
{
case 0x0: this->_master_setFinalOBJColor<NoBlend, false>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break;
case 0x1: this->_master_setFinalOBJColor<Blend, false>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break;
case 0x2: this->_master_setFinalOBJColor<Increase, false>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break;
case 0x3: this->_master_setFinalOBJColor<Decrease, false>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break;
case 0x4: this->_master_setFinalOBJColor<NoBlend, true>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break;
case 0x5: this->_master_setFinalOBJColor<Blend, true>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break;
case 0x6: this->_master_setFinalOBJColor<Increase, true>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break;
case 0x7: this->_master_setFinalOBJColor<Decrease, true>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break;
case 0x0: this->_master_setFinalOBJColor<NoBlend, false>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break;
case 0x1: this->_master_setFinalOBJColor<Blend, false>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break;
case 0x2: this->_master_setFinalOBJColor<Increase, false>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break;
case 0x3: this->_master_setFinalOBJColor<Decrease, false>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break;
case 0x4: this->_master_setFinalOBJColor<NoBlend, true>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break;
case 0x5: this->_master_setFinalOBJColor<Blend, true>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break;
case 0x6: this->_master_setFinalOBJColor<Increase, true>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break;
case 0x7: this->_master_setFinalOBJColor<Decrease, true>(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break;
};
}
@ -1376,7 +1349,7 @@ void GPUEngineBase::_RenderLine_TextBG(u16 XBG, u16 YBG, u16 LG)
xoff = XBG;
if (!BGnCNT.Palette_256) // color: 16 palette entries
if (BGnCNT.PaletteMode == PaletteMode_16x16) // color: 16 palette entries
{
const u16 *pal = this->_paletteBG;
@ -1869,12 +1842,12 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u
u32 srcadr;
// Check if sprite is disabled before everything
if (spriteInfo.RotScale == 2)
if (spriteInfo.RotScale == 0 && spriteInfo.Disable != 0)
continue;
prio = spriteInfo.Priority;
if (spriteInfo.RotScale & 1)
if (spriteInfo.RotScale != 0)
{
s32 fieldX, fieldY, auxX, auxY, realX, realY, offset;
u8 blockparameter;
@ -1896,7 +1869,7 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u
fieldY = sprSize.y;
// If we are using double size mode, double our control vars
if (spriteInfo.RotScale & 2)
if (spriteInfo.DoubleSize != 0)
{
fieldX <<= 1;
fieldY <<= 1;
@ -1913,10 +1886,10 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u
if ((sprX == GPU_FRAMEBUFFER_NATIVE_WIDTH) || (sprX + fieldX <= 0))
continue;
cost += sprSize.x*2 + 10;
cost += (sprSize.x * 2) + 10;
// Get which four parameter block is assigned to this sprite
blockparameter = (spriteInfo.RotScalIndex + (spriteInfo.HFlip<< 3) + (spriteInfo.VFlip << 4))*4;
blockparameter = (spriteInfo.RotScaleIndex + (spriteInfo.HFlip << 3) + (spriteInfo.VFlip << 4)) * 4;
// Get rotation/scale parameters
dx = LE_TO_LOCAL_16((s16)this->_oamList[blockparameter+0].attr3);
@ -1947,7 +1920,7 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u
}
// If we are using 1 palette of 256 colours
if (spriteInfo.Depth)
if (spriteInfo.PaletteMode == PaletteMode_1x256)
{
src = (u8 *)MMU_gpu_map(this->_sprMem + (spriteInfo.TileIndex << this->_sprBoundary));
@ -2097,20 +2070,20 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u
{
if (MODE == SpriteRenderMode_Sprite2D)
{
if (spriteInfo.Depth)
if (spriteInfo.PaletteMode == PaletteMode_1x256)
src = (u8 *)MMU_gpu_map(this->_sprMem + ((spriteInfo.TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8));
else
src = (u8 *)MMU_gpu_map(this->_sprMem + ((spriteInfo.TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4));
}
else
{
if (spriteInfo.Depth)
if (spriteInfo.PaletteMode == PaletteMode_1x256)
src = (u8 *)MMU_gpu_map(this->_sprMem + (spriteInfo.TileIndex<<this->_sprBoundary) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8));
else
src = (u8 *)MMU_gpu_map(this->_sprMem + (spriteInfo.TileIndex<<this->_sprBoundary) + ((y>>3)*sprSize.x*4) + ((y&0x7)*4));
}
this->_RenderSpriteWin(src, (spriteInfo.Depth != 0), lg, sprX, x, xdir);
this->_RenderSpriteWin(src, (spriteInfo.PaletteMode == PaletteMode_1x256), lg, sprX, x, xdir);
}
else if (spriteInfo.Mode == 3) //sprite is in BMP format
{
@ -2122,7 +2095,7 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u
this->_RenderSpriteBMP(i, l, dst, srcadr, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo.PaletteIndex);
}
else if (spriteInfo.Depth) //256 colors
else if (spriteInfo.PaletteMode == PaletteMode_1x256) //256 colors
{
if (MODE == SpriteRenderMode_Sprite2D)
srcadr = this->_sprMem + ((spriteInfo.TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8);
@ -2389,7 +2362,7 @@ void GPUEngineBase::UpdateVRAM3DUsageProperties_OBJLayer(const size_t bankIndex,
{
const OAMAttributes &spriteInfo = this->_oamList[spriteIndex];
if ( (spriteInfo.RotScale != 2) && ((spriteInfo.RotScale & 1) == 0) && (spriteInfo.Mode == 3) && (spriteInfo.PaletteIndex != 0) )
if ( ((spriteInfo.RotScale != 0) || (spriteInfo.Disable == 0)) && (spriteInfo.Mode == 3) && (spriteInfo.PaletteIndex != 0) )
{
const u32 vramAddress = ((spriteInfo.TileIndex & 0x1F) << 5) + ((spriteInfo.TileIndex & ~0x1F) << 7);
const SpriteSize sprSize = GPUEngineBase::_sprSizeTab[spriteInfo.Size][spriteInfo.Shape];
@ -2439,7 +2412,7 @@ void GPUEngineBase::ModeRenderDebug(const size_t targetScanline, const GPULayerI
}
template<bool ISCUSTOMRENDERINGNEEDED>
void GPUEngineBase::HandleDisplayModeOff(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount)
void GPUEngineBase::_HandleDisplayModeOff(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount)
{
// In this display mode, the display is cleared to white.
if (ISCUSTOMRENDERINGNEEDED)
@ -2453,102 +2426,11 @@ void GPUEngineBase::HandleDisplayModeOff(u16 *dstColorLine, const size_t l, cons
}
template<bool ISCUSTOMRENDERINGNEEDED>
void GPUEngineBase::HandleDisplayModeNormal(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount)
void GPUEngineBase::_HandleDisplayModeNormal(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount)
{
//do nothing: it has already been generated into the right place
}
template<bool ISCUSTOMRENDERINGNEEDED>
void GPUEngineBase::HandleDisplayModeVRAM(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount)
{
if (!ISCUSTOMRENDERINGNEEDED)
{
const u16 *src = this->_VRAMaddrNative + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH);
#ifdef LOCAL_LE
memcpy(dstColorLine, src, GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16));
#else
for (size_t x = 0; x < GPU_FRAMEBUFFER_NATIVE_WIDTH; x++)
{
dstColorLine[x] = LE_TO_LOCAL_16(src[x]);
}
#endif
}
else
{
const VRAM3DUsageProperties &vramUsageProperty = GPU->GetVRAM3DUsageProperties();
const GPUEngineA *mainEngine = GPU->GetEngineMain();
if (vramUsageProperty.isBlockUsed[mainEngine->GetVRAMBlock()] && (vramUsageProperty.blockIndexDisplayVRAM == mainEngine->GetVRAMBlock()))
{
const u16 *src = this->_VRAMaddrCustom + (_gpuDstLineIndex[l] * dstLineWidth);
#ifdef LOCAL_LE
memcpy(dstColorLine, src, dstLineWidth * dstLineCount * sizeof(u16));
#else
for (size_t x = 0; x < dstLineWidth * dstLineCount; x++)
{
dstColorLine[x] = LE_TO_LOCAL_16(src[x]);
}
#endif
}
else
{
const u16 *src = this->_VRAMaddrNative + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH);
for (size_t x = 0; x < GPU_FRAMEBUFFER_NATIVE_WIDTH; x++)
{
const u16 color = LE_TO_LOCAL_16(src[x]);
for (size_t p = 0; p < _gpuDstPitchCount[x]; p++)
{
dstColorLine[_gpuDstPitchIndex[x] + p] = color;
}
}
for (size_t line = 1; line < dstLineCount; line++)
{
memcpy(dstColorLine + (line * dstLineWidth), dstColorLine, dstLineWidth * sizeof(u16));
}
}
}
}
template<bool ISCUSTOMRENDERINGNEEDED>
void GPUEngineBase::HandleDisplayModeMainMemory(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount)
{
//this has not been tested since the dma timing for dispfifo was changed around the time of
//newemuloop. it may not work.
#ifdef ENABLE_SSE2
const __m128i fifoMask = _mm_set1_epi32(0x7FFF7FFF);
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(__m128i); i++)
{
__m128i fifoColor = _mm_set_epi32(DISP_FIFOrecv(), DISP_FIFOrecv(), DISP_FIFOrecv(), DISP_FIFOrecv());
fifoColor = _mm_shuffle_epi32(fifoColor, 0x1B); // We need to shuffle the four FIFO values back into the correct order, since they were originally loaded in reverse order.
_mm_store_si128((__m128i *)dstColorLine + i, _mm_and_si128(fifoColor, fifoMask));
}
#else
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(u32); i++)
{
((u32 *)dstColorLine)[i] = DISP_FIFOrecv() & 0x7FFF7FFF;
}
#endif
if (ISCUSTOMRENDERINGNEEDED)
{
for (size_t i = GPU_FRAMEBUFFER_NATIVE_WIDTH - 1; i < GPU_FRAMEBUFFER_NATIVE_WIDTH; i--)
{
for (size_t p = _gpuDstPitchCount[i] - 1; p < _gpuDstPitchCount[i]; p--)
{
dstColorLine[_gpuDstPitchIndex[i] + p] = dstColorLine[i];
}
}
for (size_t line = 1; line < dstLineCount; line++)
{
memcpy(dstColorLine + (line * dstLineWidth), dstColorLine, dstLineWidth * sizeof(u16));
}
}
}
void GPUEngineBase::ParseReg_MOSAIC()
{
const u8 bgMosaicH = this->_IORegisterMap->MOSAIC.BG_MosaicH;
@ -2634,7 +2516,6 @@ void GPUEngineBase::SetCustomFramebufferSize(size_t w, size_t h)
this->_workingDstColorBuffer = newWorkingScanline;
this->_dstLayerID = newBGPixels;
this->_VRAMaddrCustom = GPU->GetCustomVRAMBuffer() + (this->_vramBlock * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w);
this->customBuffer = GPU->GetCustomFramebuffer(this->_targetDisplayID);
free_aligned(oldWorkingScanline);
@ -2704,10 +2585,11 @@ void GPUEngineBase::REG_DISPx_pack_test()
printf("\t%02x\n", (u32)((uintptr_t)(&r->DISP_MMEM_FIFO) - (uintptr_t)r) );
}
template<GPUEngineID ENGINEID>
void GPUEngineBase::ParseAllRegisters()
{
this->ParseReg_DISPCNT();
// No need to call ParseReg_BGnCNT<GPULayerID>(), since it is
this->ParseReg_DISPCNT<ENGINEID>();
// No need to call ParseReg_BGnCNT<GPUEngineID, GPULayerID>(), since it is
// already called by ParseReg_DISPCNT().
this->ParseReg_BGnX<GPULayerID_BG2>();
@ -2730,10 +2612,16 @@ GPUEngineA::GPUEngineA()
_engineID = GPUEngineID_Main;
_IORegisterMap = (GPU_IOREG *)MMU.ARM9_REG;
_paletteBG = (u16 *)MMU.ARM9_VMEM;
_paletteOBJ = (u16 *)(MMU.ARM9_VMEM + 0x200);
_paletteOBJ = (u16 *)(MMU.ARM9_VMEM + ADDRESS_STEP_512B);
_oamList = (OAMAttributes *)(MMU.ARM9_OAM);
_sprMem = MMU_AOBJ;
_VRAMNativeBlockPtr[0] = (u16 *)MMU.ARM9_LCD;
_VRAMNativeBlockPtr[1] = _VRAMNativeBlockPtr[0] + (1 * GPU_VRAM_BLOCK_LINES * GPU_FRAMEBUFFER_NATIVE_WIDTH);
_VRAMNativeBlockPtr[2] = _VRAMNativeBlockPtr[0] + (2 * GPU_VRAM_BLOCK_LINES * GPU_FRAMEBUFFER_NATIVE_WIDTH);
_VRAMNativeBlockPtr[3] = _VRAMNativeBlockPtr[0] + (3 * GPU_VRAM_BLOCK_LINES * GPU_FRAMEBUFFER_NATIVE_WIDTH);
_VRAMaddrNative = _VRAMNativeBlockPtr[0];
_3DFramebufferRGBA6665 = (FragmentColor *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(FragmentColor));
_3DFramebufferRGBA5551 = (u16 *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16));
gfx3d_Update3DFramebuffers(_3DFramebufferRGBA6665, _3DFramebufferRGBA5551);
@ -2832,16 +2720,6 @@ void GPUEngineA::ParseReg_DISPCAPCNT()
this->dispCapCnt.srcA, this->dispCapCnt.srcB);*/
}
GPUDisplayMode GPUEngineA::GetDisplayMode() const
{
return this->_dispMode;
}
u8 GPUEngineA::GetVRAMBlock() const
{
return this->_vramBlock;
}
FragmentColor* GPUEngineA::Get3DFramebufferRGBA6665() const
{
return this->_3DFramebufferRGBA6665;
@ -2852,6 +2730,13 @@ u16* GPUEngineA::Get3DFramebufferRGBA5551() const
return this->_3DFramebufferRGBA5551;
}
void GPUEngineA::UpdateSelectedVRAMBlock()
{
const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT;
this->_VRAMaddrNative = this->_VRAMNativeBlockPtr[DISPCNT.VRAM_Block];
this->_VRAMaddrCustom = this->_VRAMCustomBlockPtr[DISPCNT.VRAM_Block];
}
void GPUEngineA::SetCustomFramebufferSize(size_t w, size_t h)
{
this->GPUEngineBase::SetCustomFramebufferSize(w, h);
@ -2865,6 +2750,13 @@ void GPUEngineA::SetCustomFramebufferSize(size_t w, size_t h)
this->_3DFramebufferRGBA5551 = newColorRGBA5551;
gfx3d_Update3DFramebuffers(this->_3DFramebufferRGBA6665, this->_3DFramebufferRGBA5551);
const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT;
this->_VRAMCustomBlockPtr[0] = GPU->GetCustomVRAMBuffer();
this->_VRAMCustomBlockPtr[1] = this->_VRAMCustomBlockPtr[0] + (1 * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w);
this->_VRAMCustomBlockPtr[2] = this->_VRAMCustomBlockPtr[0] + (2 * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w);
this->_VRAMCustomBlockPtr[3] = this->_VRAMCustomBlockPtr[0] + (3 * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w);
this->_VRAMaddrCustom = this->_VRAMCustomBlockPtr[DISPCNT.VRAM_Block];
free_aligned(oldColorRGBA6665Buffer);
free_aligned(oldColorRGBA5551Buffer);
}
@ -2936,8 +2828,10 @@ void GPUEngineA::RenderLine(const u16 l, bool skip)
this->_SetupWindows<0>();
this->_SetupWindows<1>();
const GPUDisplayMode displayMode = (GPUDisplayMode)this->_IORegisterMap->DISPCNT.DisplayMode;
//generate the 2d engine output
if (this->_dispMode == GPUDisplayMode_Normal)
if (displayMode == GPUDisplayMode_Normal)
{
//optimization: render straight to the output buffer when thats what we are going to end up displaying anyway
this->_currentDstColor = dstColorLine;
@ -2950,22 +2844,22 @@ void GPUEngineA::RenderLine(const u16 l, bool skip)
this->_RenderLine_Layer<ISCUSTOMRENDERINGNEEDED>(l, this->_currentDstColor, dstLineWidth, dstLineCount);
switch (this->_dispMode)
switch (displayMode)
{
case GPUDisplayMode_Off: // Display Off(Display white)
this->HandleDisplayModeOff<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
this->_HandleDisplayModeOff<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
break;
case GPUDisplayMode_Normal: // Display BG and OBJ layers
this->HandleDisplayModeNormal<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
this->_HandleDisplayModeNormal<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
break;
case GPUDisplayMode_VRAM: // Display vram framebuffer
this->HandleDisplayModeVRAM<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
this->_HandleDisplayModeVRAM<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
break;
case GPUDisplayMode_MainMemory: // Display memory FIFO
this->HandleDisplayModeMainMemory<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
this->_HandleDisplayModeMainMemory<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
break;
}
@ -3078,7 +2972,7 @@ void GPUEngineA::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t
// init background color & priorities
memset(this->_sprAlpha, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH);
memset(this->_sprType, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH);
memset(this->_sprType, OBJMode_Normal, GPU_FRAMEBUFFER_NATIVE_WIDTH);
memset(this->_sprPrio, 0x7F, GPU_FRAMEBUFFER_NATIVE_WIDTH);
memset(this->_sprWin, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH);
@ -3167,7 +3061,7 @@ void GPUEngineA::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t
}
#ifndef DISABLE_MOSAIC
if (BGnCNT.Mosaic_Enable != 0)
if (BGnCNT.Mosaic != 0)
{
switch (layerID)
{
@ -3225,7 +3119,7 @@ void GPUEngineA::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t
layerIDLine,
(useCustomVRAM) ? srcLine[dstX] : this->_sprColor[srcX],
this->_sprAlpha[srcX],
this->_sprType[srcX]);
(OBJMode)this->_sprType[srcX]);
}
}
@ -3246,7 +3140,7 @@ void GPUEngineA::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t
layerIDLine,
this->_sprColor[srcX],
this->_sprAlpha[srcX],
this->_sprType[srcX]);
(OBJMode)this->_sprType[srcX]);
}
}
}
@ -3789,12 +3683,103 @@ void GPUEngineA::_RenderLine_DispCapture_Blend(const u16 *__restrict srcA, const
}
}
template<bool ISCUSTOMRENDERINGNEEDED>
void GPUEngineA::_HandleDisplayModeVRAM(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount)
{
if (!ISCUSTOMRENDERINGNEEDED)
{
const u16 *src = this->_VRAMaddrNative + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH);
#ifdef LOCAL_LE
memcpy(dstColorLine, src, GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16));
#else
for (size_t x = 0; x < GPU_FRAMEBUFFER_NATIVE_WIDTH; x++)
{
dstColorLine[x] = LE_TO_LOCAL_16(src[x]);
}
#endif
}
else
{
const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT;
const VRAM3DUsageProperties &vramUsageProperty = GPU->GetVRAM3DUsageProperties();
if (vramUsageProperty.isBlockUsed[DISPCNT.VRAM_Block] && (vramUsageProperty.blockIndexDisplayVRAM == DISPCNT.VRAM_Block))
{
const u16 *src = this->_VRAMaddrCustom + (_gpuDstLineIndex[l] * dstLineWidth);
#ifdef LOCAL_LE
memcpy(dstColorLine, src, dstLineWidth * dstLineCount * sizeof(u16));
#else
for (size_t x = 0; x < dstLineWidth * dstLineCount; x++)
{
dstColorLine[x] = LE_TO_LOCAL_16(src[x]);
}
#endif
}
else
{
const u16 *src = this->_VRAMaddrNative + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH);
for (size_t x = 0; x < GPU_FRAMEBUFFER_NATIVE_WIDTH; x++)
{
const u16 color = LE_TO_LOCAL_16(src[x]);
for (size_t p = 0; p < _gpuDstPitchCount[x]; p++)
{
dstColorLine[_gpuDstPitchIndex[x] + p] = color;
}
}
for (size_t line = 1; line < dstLineCount; line++)
{
memcpy(dstColorLine + (line * dstLineWidth), dstColorLine, dstLineWidth * sizeof(u16));
}
}
}
}
template<bool ISCUSTOMRENDERINGNEEDED>
void GPUEngineA::_HandleDisplayModeMainMemory(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount)
{
//this has not been tested since the dma timing for dispfifo was changed around the time of
//newemuloop. it may not work.
#ifdef ENABLE_SSE2
const __m128i fifoMask = _mm_set1_epi32(0x7FFF7FFF);
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(__m128i); i++)
{
__m128i fifoColor = _mm_set_epi32(DISP_FIFOrecv(), DISP_FIFOrecv(), DISP_FIFOrecv(), DISP_FIFOrecv());
fifoColor = _mm_shuffle_epi32(fifoColor, 0x1B); // We need to shuffle the four FIFO values back into the correct order, since they were originally loaded in reverse order.
_mm_store_si128((__m128i *)dstColorLine + i, _mm_and_si128(fifoColor, fifoMask));
}
#else
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(u32); i++)
{
((u32 *)dstColorLine)[i] = DISP_FIFOrecv() & 0x7FFF7FFF;
}
#endif
if (ISCUSTOMRENDERINGNEEDED)
{
for (size_t i = GPU_FRAMEBUFFER_NATIVE_WIDTH - 1; i < GPU_FRAMEBUFFER_NATIVE_WIDTH; i--)
{
for (size_t p = _gpuDstPitchCount[i] - 1; p < _gpuDstPitchCount[i]; p--)
{
dstColorLine[_gpuDstPitchIndex[i] + p] = dstColorLine[i];
}
}
for (size_t line = 1; line < dstLineCount; line++)
{
memcpy(dstColorLine + (line * dstLineWidth), dstColorLine, dstLineWidth * sizeof(u16));
}
}
}
GPUEngineB::GPUEngineB()
{
_engineID = GPUEngineID_Sub;
_IORegisterMap = (GPU_IOREG *)(&MMU.ARM9_REG[REG_DISPB]);
_paletteBG = (u16 *)(MMU.ARM9_VMEM + ADDRESS_STEP_1KB);
_paletteOBJ = (u16 *)(MMU.ARM9_VMEM + ADDRESS_STEP_1KB + 0x200);
_paletteOBJ = (u16 *)(MMU.ARM9_VMEM + ADDRESS_STEP_1KB + ADDRESS_STEP_512B);
_oamList = (OAMAttributes *)(MMU.ARM9_OAM + ADDRESS_STEP_1KB);
_sprMem = MMU_BOBJ;
}
@ -3898,8 +3883,10 @@ void GPUEngineB::RenderLine(const u16 l, bool skip)
this->_SetupWindows<0>();
this->_SetupWindows<1>();
const GPUDisplayMode displayMode = (GPUDisplayMode)(this->_IORegisterMap->DISPCNT.DisplayMode & 0x01);
//generate the 2d engine output
if (this->_dispMode == GPUDisplayMode_Normal)
if (displayMode == GPUDisplayMode_Normal)
{
//optimization: render straight to the output buffer when thats what we are going to end up displaying anyway
this->_currentDstColor = dstColorLine;
@ -3912,14 +3899,14 @@ void GPUEngineB::RenderLine(const u16 l, bool skip)
this->_RenderLine_Layer<ISCUSTOMRENDERINGNEEDED>(l, this->_currentDstColor, dstLineWidth, dstLineCount);
switch (this->_dispMode)
switch (displayMode)
{
case GPUDisplayMode_Off: // Display Off(Display white)
this->HandleDisplayModeOff<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
this->_HandleDisplayModeOff<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
break;
case GPUDisplayMode_Normal: // Display BG and OBJ layers
this->HandleDisplayModeNormal<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
this->_HandleDisplayModeNormal<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
break;
default:
@ -4009,7 +3996,7 @@ void GPUEngineB::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t
// init background color & priorities
memset(this->_sprAlpha, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH);
memset(this->_sprType, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH);
memset(this->_sprType, OBJMode_Normal, GPU_FRAMEBUFFER_NATIVE_WIDTH);
memset(this->_sprPrio, 0x7F, GPU_FRAMEBUFFER_NATIVE_WIDTH);
memset(this->_sprWin, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH);
@ -4061,7 +4048,7 @@ void GPUEngineB::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t
const IOREG_BGnCNT &BGnCNT = this->_IORegisterMap->BGnCNT[layerID];
#ifndef DISABLE_MOSAIC
if (BGnCNT.Mosaic_Enable != 0)
if (BGnCNT.Mosaic != 0)
{
switch (layerID)
{
@ -4119,7 +4106,7 @@ void GPUEngineB::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t
layerIDLine,
(useCustomVRAM) ? srcLine[dstX] : this->_sprColor[srcX],
this->_sprAlpha[srcX],
this->_sprType[srcX]);
(OBJMode)this->_sprType[srcX]);
}
}
@ -4140,7 +4127,7 @@ void GPUEngineB::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t
layerIDLine,
this->_sprColor[srcX],
this->_sprAlpha[srcX],
this->_sprType[srcX]);
(OBJMode)this->_sprType[srcX]);
}
}
}
@ -4178,8 +4165,6 @@ GPUSubsystem::GPUSubsystem()
_displayInfo.nativeBuffer[1] = _nativeFramebuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
_displayInfo.customBuffer[0] = _customFramebuffer;
_displayInfo.customBuffer[1] = _customFramebuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
ClearWithColor(0x8000);
_displayInfo.didPerformCustomRender[0] = false;
_displayInfo.didPerformCustomRender[1] = false;
@ -4189,6 +4174,8 @@ GPUSubsystem::GPUSubsystem()
_displayInfo.renderedHeight[1] = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
_displayInfo.renderedBuffer[0] = _displayInfo.nativeBuffer[0];
_displayInfo.renderedBuffer[1] = _displayInfo.nativeBuffer[1];
ClearWithColor(0x8000);
}
GPUSubsystem::~GPUSubsystem()
@ -4246,9 +4233,11 @@ void GPUSubsystem::Reset()
void GPUSubsystem::UpdateVRAM3DUsageProperties()
{
const IOREG_DISPCNT &mainDISPCNT = this->_engineMain->GetIORegisterMap().DISPCNT;
this->_VRAM3DUsage.blockIndexDisplayVRAM = VRAM_NO_3D_USAGE;
this->_engineMain->is3DEnabled = (this->_engineMain->GetIORegisterMap().DISPCNT.BG0_Enable == 1) && (this->_engineMain->GetIORegisterMap().DISPCNT.BG0_3D == 1);
this->_engineMain->is3DEnabled = (mainDISPCNT.BG0_Enable == 1) && (mainDISPCNT.BG0_3D == 1);
this->_engineMain->isCustomRenderingNeeded = false;
this->_engineMain->vramBlockBGIndex = VRAM_NO_3D_USAGE;
this->_engineMain->vramBlockOBJIndex = VRAM_NO_3D_USAGE;
@ -4314,7 +4303,7 @@ void GPUSubsystem::UpdateVRAM3DUsageProperties()
case VramConfiguration::LCDC:
{
if ((this->_engineMain->GetDisplayMode() == GPUDisplayMode_VRAM) && (this->_engineMain->GetVRAMBlock() == i))
if ((mainDISPCNT.DisplayMode == GPUDisplayMode_VRAM) && (mainDISPCNT.VRAM_Block == i))
{
this->_VRAM3DUsage.blockIndexDisplayVRAM = i;
}
@ -4610,6 +4599,19 @@ void NDSDisplay::SetEngineByID(const GPUEngineID theID)
this->_gpu->SetDisplayByID(this->_ID);
}
template void GPUEngineBase::ParseReg_DISPCNT<GPUEngineID_Main>();
template void GPUEngineBase::ParseReg_DISPCNT<GPUEngineID_Sub>();
template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG0>();
template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG1>();
template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG2>();
template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG3>();
template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG0>();
template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG1>();
template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG2>();
template void GPUEngineBase::ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG3>();
template void GPUEngineBase::ParseReg_WINnH<0>();
template void GPUEngineBase::ParseReg_WINnH<1>();

View File

@ -47,6 +47,28 @@ bool gpu_loadstate(EMUFILE* is, int size);
typedef void (*rot_fun)(GPUEngineBase *gpu, const s32 auxX, const s32 auxY, const int lg, const u32 map, const u32 tile, const u16 *pal, const size_t i);
enum PaletteMode
{
PaletteMode_16x16 = 0,
PaletteMode_1x256 = 1
};
enum OBJMode
{
OBJMode_Normal = 0,
OBJMode_Transparent = 1,
OBJMode_Window = 2,
OBJMode_Bitmap = 3
};
enum OBJShape
{
OBJShape_Square = 0,
OBJShape_Horizontal = 1,
OBJShape_Vertical = 2,
OBJShape_Prohibited = 3
};
union FragmentColor
{
u32 color;
@ -169,10 +191,10 @@ typedef union
struct
{
#ifdef LOCAL_LE
u8 Priority:2; // 0- 1: 0..3=high..low
u8 Priority:2; // 0- 1: Rendering priority; 0...3, where 0 is highest priority and 3 is lowest priority
u8 CharacBase_Block:4; // 2- 5: individual character base offset (n*16KB)
u8 Mosaic_Enable:1; // 6: 0=disable, 1=Enable mosaic
u8 Palette_256:1; // 7: 0=16x16, 1=1*256 palette
u8 Mosaic:1; // 6: Mosaic render: 0=Disable, 1=Enable
u8 PaletteMode:1; // 7: Color/palette mode; 0=16 palettes of 16 colors each, 1=Single palette of 256 colors
u8 ScreenBase_Block:5; // 8-12: individual screen base offset (text n*2KB, BMP n*16KB)
u8 PaletteSet_Wrap:1; // 13: BG0 extended palette set 0=set0, 1=set2
@ -184,10 +206,10 @@ typedef union
// bmp : 128x128 256x256 512x256 512x512
// large : 512x1024 1024x512 - -
#else
u8 Palette_256:1; // 7: 0=16x16, 1=1*256 palette
u8 Mosaic_Enable:1; // 6: 0=disable, 1=Enable mosaic
u8 PaletteMode:1; // 7: Color/palette mode; 0=16 palettes of 16 colors each, 1=Single palette of 256 colors
u8 Mosaic:1; // 6: Mosaic render: 0=Disable, 1=Enable
u8 CharacBase_Block:4; // 2- 5: individual character base offset (n*16KB)
u8 Priority:2; // 0- 1: 0..3=high..low
u8 Priority:2; // 0- 1: Rendering priority; 0...3, where 0 is highest priority and 3 is lowest priority
u8 ScreenSize:2; // 14-15: text : 256x256 512x256 256x512 512x512
// x/rot/s : 128x128 256x256 512x512 1024x1024
@ -785,72 +807,96 @@ typedef union
i.bits.blue = w.bits.blue; \
i.bits.alpha = w.bits.alpha;
// (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
};
typedef union
{
u16 attr[4];
struct
{
#ifdef LOCAL_BE
//attr0
unsigned Shape:2;
unsigned Depth:1;
unsigned Mosaic:1;
unsigned Mode:2;
unsigned RotScale:2;
unsigned Y:8;
#ifdef LOCAL_LE
union
{
u16 attr0;
struct
{
u16 Y:8; // 0- 7: Sprite Y-coordinate; 0...255
u16 RotScale:1; // 8: Perform rotation/scaling; 0=Disable, 1=Enable
u16 Disable:1; // 9: OBJ disable flag, only if Bit8 is cleared; 0=Perform render, 1=Do not perform render
u16 Mode:2; // 10-11: OBJ mode; 0=Normal, 1=Transparent, 2=Window, 3=Bitmap
u16 Mosaic:1; // 12: Mosaic render: 0=Disable, 1=Enable
u16 PaletteMode:1; // 13: Color/palette select; 0=16 palettes of 16 colors each, 1=Single palette of 256 colors
u16 Shape:2; // 14-15: OBJ shape; 0=Square, 1=Horizontal, 2=Vertical, 3=Prohibited
};
struct
{
u16 :8;
u16 :1;
u16 DoubleSize:1; // 9: Perform double-size render, only if Bit8 is set; 0=Disable, 1=Enable
u16 :6;
};
};
//attr1
unsigned Size:2;
unsigned VFlip:1;
unsigned HFlip:1;
unsigned RotScalIndex:3;
signed X:9;
s16 X:9; // 16-24: Sprite X-coordinate; 0...511
u16 RotScaleIndex:3; // 25-27: Rotation/scaling parameter selection; 0...31
u16 HFlip:1; // 28: Flip sprite horizontally; 0=Normal, 1=Flip
u16 VFlip:1; // 29: Flip sprite vertically; 0=Normal, 1=Flip
u16 Size:2; // 30-31: OBJ size, interacts with Bit 14-15
//
// Size| Square | Horizontal | Vertical
// 0: 8x8 16x8 8x16
// 1: 16x16 32x8 8x32
// 2: 32x32 32x16 16x32
// 3: 64x64 64x32 32x64
//attr2
unsigned PaletteIndex:4;
unsigned Priority:2;
unsigned TileIndex:10;
//attr3
unsigned attr3:16; // Whenever this is used, you will need to explicitly convert endianness.
u16 TileIndex:10; // 32-41: Tile index; 0...1023
u16 Priority:2; // 42-43: Rendering priority; 0...3, where 0 is highest priority and 3 is lowest priority
u16 PaletteIndex:4; // 44-47: Palette index; 0...15
#else
//attr0
unsigned Y:8;
unsigned RotScale:2;
unsigned Mode:2;
unsigned Mosaic:1;
unsigned Depth:1;
unsigned Shape:2;
union
{
u16 attr0;
struct
{
u16 Shape:2; // 14-15: OBJ shape; 0=Square, 1=Horizontal, 2=Vertical, 3=Prohibited
u16 PaletteMode:1; // 13: Color/palette select; 0=16 palettes of 16 colors each, 1=Single palette of 256 colors
u16 Mosaic:1; // 12: Mosaic render: 0=Disable, 1=Enable
u16 Mode:2; // 10-11: OBJ mode; 0=Normal, 1=Transparent, 2=Window, 3=Bitmap
u16 Disable:1; // 9: OBJ disable flag, only if Bit8 is cleared; 0=Perform render, 1=Do not perform render
u16 RotScale:1; // 8: Perform rotation/scaling; 0=Disable, 1=Enable
u16 Y:8; // 0- 7: Sprite Y-coordinate; 0...255
};
struct
{
u16 :6;
u16 DoubleSize:1; // 9: Perform double-size render, only if Bit8 is set; 0=Disable, 1=Enable
u16 :1;
u16 :8;
};
};
//attr1
signed X:9;
unsigned RotScalIndex:3;
unsigned HFlip:1;
unsigned VFlip:1;
unsigned Size:2;
u16 Size:2; // 30-31: OBJ size, interacts with Bit 14-15
//
// Size| Square | Horizontal | Vertical
// 0: 8x8 16x8 8x16
// 1: 16x16 32x8 8x32
// 2: 32x32 32x16 16x32
// 3: 64x64 64x32 32x64
u16 VFlip:1; // 29: Flip sprite vertically; 0=Normal, 1=Flip
u16 HFlip:1; // 28: Flip sprite horizontally; 0=Normal, 1=Flip
u16 RotScaleIndex:3; // 25-27: Rotation/scaling parameter selection; 0...31
s16 X:9; // 16-24: Sprite X-coordinate; 0...511
//attr2
unsigned TileIndex:10;
unsigned Priority:2;
unsigned PaletteIndex:4;
//attr3
unsigned attr3:16; // Whenever this is used, you will need to explicitly convert endianness.
u16 PaletteIndex:4; // 44-47: Palette index; 0...15
u16 Priority:2; // 42-43: Rendering priority; 0...3, where 0 is highest priority and 3 is lowest priority
u16 TileIndex:10; // 32-41: Tile index; 0...1023
#endif
u16 attr3:16; // 48-63: Whenever this is used, you will need to explicitly convert endianness.
};
} OAMAttributes;
enum SpriteRenderMode
@ -1044,8 +1090,6 @@ protected:
u8 _sprBoundary;
u8 _sprBMPBoundary;
u8 _sprBMPMode;
u32 _sprEnable;
bool _blend2[8];
@ -1057,20 +1101,14 @@ protected:
u32 _BG_bmp_ram[4];
u32 _BG_tile_ram[4];
u32 _BG_map_ram[4];
BGType _BGTypes[4];
GPUDisplayMode _dispMode;
u8 _vramBlock;
CACHE_ALIGN u8 _sprNum[256];
CACHE_ALIGN u8 _h_win[2][GPU_FRAMEBUFFER_NATIVE_WIDTH];
const u8 *_curr_win[2];
NDSDisplayID _targetDisplayID;
u16 *_VRAMaddrNative;
u16 *_VRAMaddrCustom;
int _finalColorBckFuncID;
int _finalColor3DFuncID;
int _finalColorSpriteFuncID;
@ -1123,6 +1161,9 @@ protected:
template<bool ISCUSTOMRENDERINGNEEDED> void _RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t dstLineWidth, const size_t dstLineCount);
template<bool ISCUSTOMRENDERINGNEEDED> void _RenderLine_MasterBrightness(u16 *dstColorLine, const size_t dstLineWidth, const size_t dstLineCount);
template<bool ISCUSTOMRENDERINGNEEDED> void _HandleDisplayModeOff(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount);
template<bool ISCUSTOMRENDERINGNEEDED> void _HandleDisplayModeNormal(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount);
template<size_t WIN_NUM> void _UpdateWINH();
template<size_t WIN_NUM> void _SetupWindows();
template<GPULayerID LAYERID, bool MOSAIC, bool ISCUSTOMRENDERINGNEEDED> void _ModeRender();
@ -1134,11 +1175,11 @@ protected:
FORCEINLINE FASTCALL void _master_setFinal3dColor(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const FragmentColor src);
template<BlendFunc FUNC, bool WINDOW>
FORCEINLINE FASTCALL void _master_setFinalOBJColor(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const u8 type);
FORCEINLINE FASTCALL void _master_setFinalOBJColor(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const OBJMode objMode);
template<GPULayerID LAYERID, bool BACKDROP, int FUNCNUM> void _SetFinalColorBG(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, u16 src);
void _SetFinalColor3D(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const FragmentColor src);
void _SetFinalColorSprite(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const u8 type);
void _SetFinalColorSprite(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const OBJMode objMode);
u16 _FinalColorBlend(const u16 colA, const u16 colB);
FORCEINLINE u16 _FinalColorBlendFunc(const u16 colA, const u16 colB, const TBlendTable *blendTable);
@ -1162,8 +1203,8 @@ public:
void ResortBGLayers();
void SetupFinalPixelBlitter();
void ParseReg_DISPCNT();
template<GPULayerID LAYERID> void ParseReg_BGnCNT();
template<GPUEngineID ENGINEID> void ParseReg_DISPCNT();
template<GPUEngineID ENGINEID, GPULayerID LAYERID> void ParseReg_BGnCNT();
template<GPULayerID LAYERID> void ParseReg_BGnX();
template<GPULayerID LAYERID> void ParseReg_BGnY();
template<size_t WINNUM> void ParseReg_WINnH();
@ -1173,7 +1214,7 @@ public:
void ParseReg_BLDY();
void ParseReg_MASTER_BRIGHT();
void ParseAllRegisters();
template<GPUEngineID ENGINEID> void ParseAllRegisters();
template<bool ISCUSTOMRENDERINGNEEDED> void RenderLine(const u16 l, bool skip);
@ -1219,11 +1260,6 @@ public:
void SpriteRender(u16 *dst, u8 *dst_alpha, u8 *typeTab, u8 *prioTab);
void SpriteRenderDebug(const size_t targetScanline, u16 *dst, u8 *dst_alpha, u8 *typeTab, u8 *prioTab);
void ModeRenderDebug(const size_t targetScanline, const GPULayerID layerID, u16 *dstLineColor);
template<bool ISCUSTOMRENDERINGNEEDED> void HandleDisplayModeOff(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount);
template<bool ISCUSTOMRENDERINGNEEDED> void HandleDisplayModeNormal(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount);
template<bool ISCUSTOMRENDERINGNEEDED> void HandleDisplayModeVRAM(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount);
template<bool ISCUSTOMRENDERINGNEEDED> void HandleDisplayModeMainMemory(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount);
int GetFinalColorBckFuncID() const;
void SetFinalColorBckFuncID(int funcID);
@ -1241,10 +1277,19 @@ public:
class GPUEngineA : public GPUEngineBase
{
private:
GPUEngineA();
~GPUEngineA();
protected:
FragmentColor *_3DFramebufferRGBA6665;
u16 *_3DFramebufferRGBA5551;
u16 *_VRAMaddrNative;
u16 *_VRAMaddrCustom;
u16 *_VRAMNativeBlockPtr[4];
u16 *_VRAMCustomBlockPtr[4];
template<bool ISCUSTOMRENDERINGNEEDED> void _RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t dstLineWidth, const size_t dstLineCount);
template<bool ISCUSTOMRENDERINGNEEDED, size_t CAPTURELENGTH> void _RenderLine_DisplayCapture(const u16 l);
void _RenderLine_DispCapture_FIFOToBuffer(u16 *fifoLineBuffer);
@ -1264,6 +1309,10 @@ protected:
template<size_t CAPTURELENGTH, bool CAPTUREFROMNATIVESRCA, bool CAPTUREFROMNATIVESRCB, bool CAPTURETONATIVEDST>
void _RenderLine_DispCapture_Blend(const u16 *__restrict srcA, const u16 *__restrict srcB, u16 *__restrict dst, const size_t captureLengthExt, const size_t l);
template<bool ISCUSTOMRENDERINGNEEDED> void _HandleDisplayModeVRAM(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount);
template<bool ISCUSTOMRENDERINGNEEDED> void _HandleDisplayModeMainMemory(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount);
public:
DISPCAPCNT_parsed dispCapCnt;
@ -1272,21 +1321,20 @@ public:
virtual void Reset();
void ParseReg_DISPCAPCNT();
GPUDisplayMode GetDisplayMode() const;
u8 GetVRAMBlock() const;
void UpdateSelectedVRAMBlock();
FragmentColor* Get3DFramebufferRGBA6665() const;
u16* Get3DFramebufferRGBA5551() const;
virtual void SetCustomFramebufferSize(size_t w, size_t h);
template<bool ISCUSTOMRENDERINGNEEDED> void RenderLine(const u16 l, bool skip);
private:
GPUEngineA();
~GPUEngineA();
};
class GPUEngineB : public GPUEngineBase
{
private:
GPUEngineB();
~GPUEngineB();
protected:
template<bool ISCUSTOMRENDERINGNEEDED> void _RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t dstLineWidth, const size_t dstLineCount);
@ -1296,10 +1344,6 @@ public:
virtual void Reset();
template<bool ISCUSTOMRENDERINGNEEDED> void RenderLine(const u16 l, bool skip);
private:
GPUEngineB();
~GPUEngineB();
};
class NDSDisplay
@ -1323,6 +1367,9 @@ public:
class GPUSubsystem
{
private:
GPUSubsystem();
~GPUSubsystem();
GPUEngineA *_engineMain;
GPUEngineB *_engineSub;
NDSDisplay *_displayMain;
@ -1338,9 +1385,6 @@ private:
NDSDisplayInfo _displayInfo;
GPUSubsystem();
~GPUSubsystem();
public:
static GPUSubsystem* Allocate();
void FinalizeAndDeallocate();
@ -1380,7 +1424,7 @@ public:
// frontend becomes responsible for calling GetDisplayInfo() and reading the native
// and custom buffers properly for each display. If a single buffer is still needed
// for certain cases, then the frontend must manually call
// GPUEngineBase::BlitNativeToCustomFramebuffer() for each GPU before reading the
// GPUEngineBase::BlitNativeToCustomFramebuffer() for each engine before reading the
// master framebuffer.
bool GetWillAutoBlitNativeToCustomBuffer() const;
void SetWillAutoBlitNativeToCustomBuffer(const bool willAutoBlit);

View File

@ -3565,36 +3565,36 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
{
case REG_DISPA_DISPCNT:
T1WriteWord(MMU.ARM9_REG, 0x0000, val);
mainEngine->ParseReg_DISPCNT();
mainEngine->ParseReg_DISPCNT<GPUEngineID_Main>();
return;
case REG_DISPA_DISPCNT+2:
T1WriteWord(MMU.ARM9_REG, 0x0002, val);
mainEngine->ParseReg_DISPCNT();
mainEngine->ParseReg_DISPCNT<GPUEngineID_Main>();
return;
case REG_DISPA_BG0CNT:
//GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val);
T1WriteWord(MMU.ARM9_REG, 0x0008, val);
mainEngine->ParseReg_BGnCNT<GPULayerID_BG0>();
mainEngine->ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG0>();
return;
case REG_DISPA_BG1CNT:
//GPULOG("MAIN BG1 SETPROP 16B %08X\r\n", val);
T1WriteWord(MMU.ARM9_REG, 0x000A, val);
mainEngine->ParseReg_BGnCNT<GPULayerID_BG1>();
mainEngine->ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG1>();
return;
case REG_DISPA_BG2CNT:
//GPULOG("MAIN BG2 SETPROP 16B %08X\r\n", val);
T1WriteWord(MMU.ARM9_REG, 0x000C, val);
mainEngine->ParseReg_BGnCNT<GPULayerID_BG2>();
mainEngine->ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG2>();
return;
case REG_DISPA_BG3CNT:
//GPULOG("MAIN BG3 SETPROP 16B %08X\r\n", val);
T1WriteWord(MMU.ARM9_REG, 0x000E, val);
mainEngine->ParseReg_BGnCNT<GPULayerID_BG3>();
mainEngine->ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG3>();
return;
case REG_DISPA_BG2XL:
@ -3708,36 +3708,36 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
case REG_DISPB_DISPCNT:
T1WriteWord(MMU.ARM9_REG, 0x1000, val);
subEngine->ParseReg_DISPCNT();
subEngine->ParseReg_DISPCNT<GPUEngineID_Sub>();
return;
case REG_DISPB_DISPCNT+2:
T1WriteWord(MMU.ARM9_REG, 0x1002, val);
subEngine->ParseReg_DISPCNT();
subEngine->ParseReg_DISPCNT<GPUEngineID_Sub>();
return;
case REG_DISPB_BG0CNT:
//GPULOG("SUB BG0 SETPROP 16B %08X\r\n", val);
T1WriteWord(MMU.ARM9_REG, 0x1008, val);
subEngine->ParseReg_BGnCNT<GPULayerID_BG0>();
subEngine->ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG0>();
return;
case REG_DISPB_BG1CNT:
//GPULOG("SUB BG1 SETPROP 16B %08X\r\n", val);
T1WriteWord(MMU.ARM9_REG, 0x100A, val);
subEngine->ParseReg_BGnCNT<GPULayerID_BG1>();
subEngine->ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG1>();
return;
case REG_DISPB_BG2CNT:
//GPULOG("SUB BG2 SETPROP 16B %08X\r\n", val);
T1WriteWord(MMU.ARM9_REG, 0x100C, val);
subEngine->ParseReg_BGnCNT<GPULayerID_BG2>();
subEngine->ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG2>();
return;
case REG_DISPB_BG3CNT:
//GPULOG("SUB BG3 SETPROP 16B %08X\r\n", val);
T1WriteWord(MMU.ARM9_REG, 0x100E, val);
subEngine->ParseReg_BGnCNT<GPULayerID_BG3>();
subEngine->ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG3>();
return;
case REG_DISPB_BG2XL:
@ -4110,20 +4110,20 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
{
case REG_DISPA_DISPCNT:
T1WriteLong(MMU.ARM9_REG, 0x0000, val);
mainEngine->ParseReg_DISPCNT();
mainEngine->ParseReg_DISPCNT<GPUEngineID_Main>();
//GPULOG("MAIN INIT 32B %08X\r\n", val);
return;
case REG_DISPA_BG0CNT:
T1WriteLong(MMU.ARM9_REG, 0x0008, val);
mainEngine->ParseReg_BGnCNT<GPULayerID_BG0>();
mainEngine->ParseReg_BGnCNT<GPULayerID_BG1>();
mainEngine->ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG0>();
mainEngine->ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG1>();
return;
case REG_DISPA_BG2CNT:
T1WriteLong(MMU.ARM9_REG, 0x000C, val);
mainEngine->ParseReg_BGnCNT<GPULayerID_BG2>();
mainEngine->ParseReg_BGnCNT<GPULayerID_BG3>();
mainEngine->ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG2>();
mainEngine->ParseReg_BGnCNT<GPUEngineID_Main, GPULayerID_BG3>();
return;
case REG_DISPA_BG2XL:
@ -4197,20 +4197,20 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
case REG_DISPB_DISPCNT:
T1WriteLong(MMU.ARM9_REG, 0x1000, val);
subEngine->ParseReg_DISPCNT();
subEngine->ParseReg_DISPCNT<GPUEngineID_Sub>();
//GPULOG("SUB INIT 32B %08X\r\n", val);
return;
case REG_DISPB_BG0CNT:
T1WriteLong(MMU.ARM9_REG, 0x1008, val);
subEngine->ParseReg_BGnCNT<GPULayerID_BG0>();
subEngine->ParseReg_BGnCNT<GPULayerID_BG1>();
subEngine->ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG0>();
subEngine->ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG1>();
return;
case REG_DISPB_BG2CNT:
T1WriteLong(MMU.ARM9_REG, 0x100C, val);
subEngine->ParseReg_BGnCNT<GPULayerID_BG2>();
subEngine->ParseReg_BGnCNT<GPULayerID_BG3>();
subEngine->ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG2>();
subEngine->ParseReg_BGnCNT<GPUEngineID_Sub, GPULayerID_BG3>();
return;
case REG_DISPB_BG2XL:
@ -4321,12 +4321,12 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
return;
// Fog Color - Parameters:4b
case 0x04000358:
case eng_3D_FOG_COLOR:
HostWriteLong(MMU.ARM9_REG, 0x0358, val);
gfx3d_glFogColor(val);
return;
case 0x0400035C:
case eng_3D_FOG_OFFSET:
HostWriteLong(MMU.ARM9_REG, 0x035C, val);
gfx3d_glFogOffset(val);
return;