From 88006197b9505c4b7304d268768340c667fad8d8 Mon Sep 17 00:00:00 2001 From: rogerman Date: Tue, 1 Sep 2015 00:13:02 +0000 Subject: [PATCH] GPU: - Do heavy code cleanup. - Encapsulate higher level GPU functions into the new GPUSubsystem class. --- desmume/src/GPU.cpp | 1182 +++++++++-------- desmume/src/GPU.h | 174 ++- desmume/src/MMU.cpp | 266 ++-- desmume/src/NDSSystem.cpp | 58 +- desmume/src/cli/main.cpp | 13 +- desmume/src/cocoa/cocoa_GPU.h | 18 +- desmume/src/cocoa/cocoa_GPU.mm | 305 +---- desmume/src/cocoa/cocoa_core.mm | 1 - desmume/src/cocoa/cocoa_output.mm | 11 +- desmume/src/cocoa/openemu/NDSGameCore.mm | 2 +- .../userinterface/EmuControllerDelegate.mm | 6 +- desmume/src/gfx3d.cpp | 6 +- desmume/src/gtk-glade/callbacks.cpp | 15 +- desmume/src/gtk-glade/callbacks_IO.cpp | 2 +- desmume/src/gtk-glade/gdk_gl.cpp | 12 +- desmume/src/gtk/main.cpp | 12 +- desmume/src/lua-engine.cpp | 2 +- desmume/src/qt/project/frontend/video.cpp | 2 +- desmume/src/render3D.cpp | 3 +- desmume/src/windows/hotkey.cpp | 8 +- desmume/src/windows/main.cpp | 27 +- desmume/src/windows/mapView.cpp | 22 +- desmume/src/windows/oamView.cpp | 6 +- 23 files changed, 1028 insertions(+), 1125 deletions(-) diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index d0428e6a3..6dd9c8f69 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -56,23 +56,15 @@ #endif //instantiate static instance -GPUEngineBase::MosaicLookup GPUEngineBase::mosaicLookup; +u16 GPUEngineBase::_fadeInColors[17][0x8000]; +u16 GPUEngineBase::_fadeOutColors[17][0x8000]; +u8 GPUEngineBase::_blendTable555[17][17][32][32]; +GPUEngineBase::MosaicLookup GPUEngineBase::_mosaicLookup; -static GPUEngineBase GPU_main(GPUCOREID_MAIN); -static GPUEngineBase GPU_sub(GPUCOREID_SUB); -NDS_Screen MainScreen; -NDS_Screen SubScreen; -NDSDisplay MainDisplay(NDSDisplayID_Main, GPUCOREID_MAIN); -NDSDisplay TouchDisplay(NDSDisplayID_Touch, GPUCOREID_SUB); - -static NDSDisplayInfo _displayInfo; -static CACHE_ALIGN u16 GPU_NativeFramebuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2]; -static u16 *GPU_CustomFramebuffer = NULL; -u16 *GPU_screen = GPU_CustomFramebuffer; // TODO: Old pointer - need to eliminate direct reference in frontends +GPUSubsystem *GPU = NULL; static size_t _gpuLargestDstLineCount = 1; static size_t _gpuVRAMBlockOffset = GPU_VRAM_BLOCK_LINES * GPU_FRAMEBUFFER_NATIVE_WIDTH; -static bool _gpuWillAutoBlitNativeToCustomBuffer = true; static u16 *_gpuDstToSrcIndex = NULL; // Key: Destination pixel index / Value: Source pixel index @@ -82,12 +74,6 @@ static CACHE_ALIGN size_t _gpuDstLineCount[GPU_FRAMEBUFFER_NATIVE_HEIGHT]; // Ke static CACHE_ALIGN size_t _gpuDstLineIndex[GPU_FRAMEBUFFER_NATIVE_HEIGHT]; // Key: Source line index / Value: First destination line that maps to the source line static CACHE_ALIGN size_t _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES + 1]; // Key: Source line index / Value: First destination line that maps to the source line -static CACHE_ALIGN u8 _gpuSprWin[GPU_FRAMEBUFFER_NATIVE_WIDTH]; - -static VRAM3DUsageProperties _gpuVRAM3DUsage; -static u16 *_gpuCustomVRAM = NULL; -static u16 *_gpuCustomVRAMBlank = NULL; - static const CACHE_ALIGN SpriteSize sprSizeTab[4][4] = { {{8, 8}, {16, 8}, {8, 16}, {8, 8}}, {{16, 16}, {32, 8}, {8, 32}, {8, 8}}, @@ -126,19 +112,12 @@ static const CACHE_ALIGN u8 win_empty[GPU_FRAMEBUFFER_NATIVE_WIDTH] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; -static CACHE_ALIGN u16 fadeInColors[17][0x8000]; -static CACHE_ALIGN u16 fadeOutColors[17][0x8000]; - -//this should be public, because it gets used somewhere else -CACHE_ALIGN u8 gpuBlendTable555[17][17][32][32]; - - /*****************************************************************************/ // INITIALIZATION /*****************************************************************************/ -static void GPU_InitFadeColors() +void GPUEngineBase::_InitLUTs() { static bool didInit = false; @@ -176,14 +155,14 @@ static void GPU_InitFadeColors() cur.bits.green = (cur.bits.green + ((31 - cur.bits.green) * i / 16)); cur.bits.blue = (cur.bits.blue + ((31 - cur.bits.blue) * i / 16)); cur.bits.alpha = 0; - fadeInColors[i][j & 0x7FFF] = cur.val; + GPUEngineBase::_fadeInColors[i][j & 0x7FFF] = cur.val; cur.val = j; cur.bits.red = (cur.bits.red - (cur.bits.red * i / 16)); cur.bits.green = (cur.bits.green - (cur.bits.green * i / 16)); cur.bits.blue = (cur.bits.blue - (cur.bits.blue * i / 16)); cur.bits.alpha = 0; - fadeOutColors[i][j & 0x7FFF] = cur.val; + GPUEngineBase::_fadeOutColors[i][j & 0x7FFF] = cur.val; } } @@ -195,7 +174,7 @@ static void GPU_InitFadeColors() { int blend = ((c0 * eva) + (c1 * evb) ) / 16; int final = std::min(31,blend); - gpuBlendTable555[eva][evb][c0][c1] = final; + GPUEngineBase::_blendTable555[eva][evb][c0][c1] = final; } didInit = true; @@ -209,7 +188,7 @@ GPUEngineBase::GPUEngineBase() GPUEngineBase::GPUEngineBase(const GPUCoreID coreID) { debug = false; - GPU_InitFadeColors(); + _InitLUTs(); core = coreID; workingScanline = NULL; @@ -229,8 +208,6 @@ GPUEngineBase::GPUEngineBase(const GPUCoreID coreID) // GPU core A dispx_st = (REG_DISPx*)(&MMU.ARM9_REG[0]); } - - Reset(); } GPUEngineBase::~GPUEngineBase() @@ -243,6 +220,8 @@ GPUEngineBase::~GPUEngineBase() void GPUEngineBase::Reset() { + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); + memset(this->_sprColor, 0, sizeof(this->_sprColor)); memset(this->_sprAlpha, 0, sizeof(this->_sprAlpha)); memset(this->_sprType, 0, sizeof(this->_sprType)); @@ -328,7 +307,7 @@ void GPUEngineBase::Reset() this->dispMode = GPUDisplayMode_Off; this->vramBlock = 0; this->_VRAMaddrNative = (u16 *)MMU.ARM9_LCD; - this->_VRAMaddrCustom = _gpuCustomVRAM; + this->_VRAMaddrCustom = GPU->GetCustomVRAMBuffer(); this->isCustomRenderingNeeded = false; this->is3DEnabled = false; @@ -379,8 +358,8 @@ void GPUEngineBase::Reset() this->_BLDY_EVY = 0; this->UpdateBLDALPHA(); - this->_currentFadeInColors = &fadeInColors[this->_BLDY_EVY][0]; - this->_currentFadeOutColors = &fadeOutColors[this->_BLDY_EVY][0]; + this->_currentFadeInColors = &GPUEngineBase::_fadeInColors[this->_BLDY_EVY][0]; + this->_currentFadeOutColors = &GPUEngineBase::_fadeOutColors[this->_BLDY_EVY][0]; this->_blend1 = false; this->_blend2[0] = false; @@ -397,11 +376,11 @@ void GPUEngineBase::Reset() if (this->workingScanline != NULL) { - memset(this->workingScanline, 0, _displayInfo.customWidth * _gpuLargestDstLineCount * sizeof(u16)); + memset(this->workingScanline, 0, dispInfo.customWidth * _gpuLargestDstLineCount * sizeof(u16)); } if (this->_bgPixels != NULL) { - memset(this->_bgPixels, 0, _displayInfo.customWidth * _gpuLargestDstLineCount * 4 * sizeof(u8)); + memset(this->_bgPixels, 0, dispInfo.customWidth * _gpuLargestDstLineCount * 4 * sizeof(u8)); } this->currLine = 0; @@ -507,7 +486,6 @@ FORCEINLINE u16 GPUEngineBase::_FinalColorBlend(const u16 colA, const u16 colB) return this->_FinalColorBlendFunc(colA, colB, this->_blendTable); } - void GPUEngineBase::SetMasterBrightness(const u16 val) { if (!nds.isInVblank()) @@ -557,9 +535,12 @@ void GPUEngineBase::SetVideoProp(const u32 ctrlBits) break; case GPUDisplayMode_VRAM: // Display framebuffer + { + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); this->_VRAMaddrNative = (u16 *)MMU.ARM9_LCD + (this->vramBlock * GPU_VRAM_BLOCK_LINES * GPU_FRAMEBUFFER_NATIVE_WIDTH); - this->_VRAMaddrCustom = _gpuCustomVRAM + (this->vramBlock * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * _displayInfo.customWidth); + this->_VRAMaddrCustom = GPU->GetCustomVRAMBuffer() + (this->vramBlock * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * dispInfo.customWidth); break; + } case GPUDisplayMode_MainMemory: // Display from Main RAM // nothing to be done here @@ -675,7 +656,22 @@ void GPUEngineBase::SetBGProp(const size_t num, const u16 ctrlBits) // ENABLING / DISABLING LAYERS /*****************************************************************************/ -void GPUEngineBase::SetLayerState(const size_t layerIndex, bool theState) +bool GPUEngineBase::GetEnableState() +{ + return CommonSettings.showGpu.screens[this->core]; +} + +void GPUEngineBase::SetEnableState(bool theState) +{ + CommonSettings.showGpu.screens[this->core] = theState; +} + +bool GPUEngineBase::GetLayerEnableState(const size_t layerIndex) +{ + return CommonSettings.dispLayers[this->core][layerIndex]; +} + +void GPUEngineBase::SetLayerEnableState(const size_t layerIndex, bool theState) { CommonSettings.dispLayers[this->core][layerIndex] = theState; this->ResortBGLayers(); @@ -730,7 +726,7 @@ void GPUEngineBase::_RenderLine_CheckWindows(const size_t srcX, bool &draw, bool { // it is in winOBJ, do we display ? // low priority - if (_gpuSprWin[srcX]) + if (this->_sprWin[srcX]) { draw = (this->_WINOBJ >> this->currBgNum) & 1; effect = (this->_WINOBJ_SPECIAL); @@ -915,7 +911,7 @@ FORCEINLINE FASTCALL void GPUEngineBase::_master_setFinalOBJColor(const size_t s break; case Blend: - finalDstColor = this->_FinalColorBlendFunc(src, dstLine[dstX], &gpuBlendTable555[eva][evb]); + finalDstColor = this->_FinalColorBlendFunc(src, dstLine[dstX], &GPUEngineBase::_blendTable555[eva][evb]); break; default: @@ -1004,9 +1000,11 @@ FORCEINLINE void GPUEngineBase::____setFinalColorBck(const u16 color, const size if (this->isCustomRenderingNeeded) { + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); + for (size_t line = 0; line < _gpuDstLineCount[this->currLine]; line++) { - const u16 *srcLine = (USECUSTOMVRAM) ? _gpuCustomVRAM + (this->vramBlockBGIndex * _gpuVRAMBlockOffset) + ((_gpuDstLineIndex[this->currLine] + line) * _displayInfo.customWidth) : NULL; + const u16 *srcLine = (USECUSTOMVRAM) ? GPU->GetCustomVRAMBuffer() + (this->vramBlockBGIndex * _gpuVRAMBlockOffset) + ((_gpuDstLineIndex[this->currLine] + line) * dispInfo.customWidth) : NULL; for (size_t p = 0; p < _gpuDstPitchCount[srcX]; p++) { @@ -1019,8 +1017,8 @@ FORCEINLINE void GPUEngineBase::____setFinalColorBck(const u16 color, const size (USECUSTOMVRAM) ? srcLine[dstX] : color); } - dstLine += _displayInfo.customWidth; - bgLine += _displayInfo.customWidth; + dstLine += dispInfo.customWidth; + bgLine += dispInfo.customWidth; } } else @@ -1053,15 +1051,15 @@ FORCEINLINE void GPUEngineBase::___setFinalColorBck(u16 color, const size_t srcX if (!opaque) color = 0xFFFF; else color &= 0x7FFF; - if (GPUEngineBase::mosaicLookup.width[srcX].begin && GPUEngineBase::mosaicLookup.height[this->currLine].begin) + if (GPUEngineBase::_mosaicLookup.width[srcX].begin && GPUEngineBase::_mosaicLookup.height[this->currLine].begin) { // Do nothing. } else { //due to the early out, enabled must always be true - //x_int = enabled ? GPU::mosaicLookup.width[srcX].trunc : srcX; - const size_t x_int = GPUEngineBase::mosaicLookup.width[srcX].trunc; + //x_int = enabled ? GPU::_mosaicLookup.width[srcX].trunc : srcX; + const size_t x_int = GPUEngineBase::_mosaicLookup.width[srcX].trunc; color = this->_mosaicColors.bg[this->currBgNum][x_int]; } @@ -1089,13 +1087,13 @@ void GPUEngineBase::_MosaicSpriteLinePixel(const size_t x, u16 l, u16 *dst, u8 * objColor.alpha = dst_alpha[x]; objColor.opaque = opaque; - const size_t x_int = (enableMosaic) ? GPUEngineBase::mosaicLookup.width[x].trunc : x; + const size_t x_int = (enableMosaic) ? GPUEngineBase::_mosaicLookup.width[x].trunc : x; if (enableMosaic) { const size_t y = l; - if (GPUEngineBase::mosaicLookup.width[x].begin && GPUEngineBase::mosaicLookup.height[y].begin) + if (GPUEngineBase::_mosaicLookup.width[x].begin && GPUEngineBase::_mosaicLookup.height[y].begin) { // Do nothing. } @@ -1114,7 +1112,7 @@ void GPUEngineBase::_MosaicSpriteLinePixel(const size_t x, u16 l, u16 *dst, u8 * void GPUEngineBase::_MosaicSpriteLine(u16 l, u16 *dst, u8 *dst_alpha, u8 *typeTab, u8 *prioTab) { //don't even try this unless the mosaic is effective - if (GPUEngineBase::mosaicLookup.widthValue != 0 || GPUEngineBase::mosaicLookup.heightValue != 0) + if (GPUEngineBase::_mosaicLookup.widthValue != 0 || GPUEngineBase::_mosaicLookup.heightValue != 0) for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH; i++) this->_MosaicSpriteLinePixel(i, l, dst, dst_alpha, typeTab, prioTab); } @@ -1601,7 +1599,7 @@ void GPUEngineBase::_RenderSpriteWin(const u8 *src, const bool col256, const siz //_gpuSprWin[sprX] = (src[x])?1:0; if (src[(x & 7) + ((x & 0xFFF8) << 3)]) { - _gpuSprWin[sprX] = 1; + this->_sprWin[sprX] = 1; } } } @@ -1615,7 +1613,7 @@ void GPUEngineBase::_RenderSpriteWin(const u8 *src, const bool col256, const siz if (palette_entry) { - _gpuSprWin[sprX] = 1; + this->_sprWin[sprX] = 1; } } } @@ -1946,7 +1944,7 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u { if (spriteInfo.Mode == 2) { - _gpuSprWin[sprX] = 1; + this->_sprWin[sprX] = 1; } else { @@ -2029,243 +2027,45 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u } } -/*****************************************************************************/ -// SCREEN FUNCTIONS -/*****************************************************************************/ - -int Screen_Init() -{ - MainScreen.gpu = &GPU_main; - SubScreen.gpu = &GPU_sub; - - gfx3d_init(); - DISP_FIFOreset(); - - OSDCLASS *previousOSD = osd; - osd = new OSDCLASS(-1); - delete previousOSD; - - _displayInfo.masterNativeBuffer = GPU_NativeFramebuffer; - GPU_SetFramebufferSize(GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT); - - return 0; -} - -void Screen_Reset(void) -{ - gfx3d_reset(); - MainScreen.gpu->Reset(); - SubScreen.gpu->Reset(); - - memset(GPU_NativeFramebuffer, 0xFF, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * sizeof(u16)); - memset(GPU_CustomFramebuffer, 0xFF, _displayInfo.customWidth * _displayInfo.customHeight * 2 * sizeof(u16)); - memset(gfx3d_colorRGBA6665, 0, _displayInfo.customWidth * _displayInfo.customHeight * sizeof(FragmentColor)); - memset(gfx3d_colorRGBA5551, 0, _displayInfo.customWidth * _displayInfo.customHeight * sizeof(u16)); - - _gpuVRAM3DUsage.blockIndexDisplayVRAM = VRAM_NO_3D_USAGE; - _gpuVRAM3DUsage.isBlockUsed[0] = false; - _gpuVRAM3DUsage.isBlockUsed[1] = false; - _gpuVRAM3DUsage.isBlockUsed[2] = false; - _gpuVRAM3DUsage.isBlockUsed[3] = false; - - DISP_FIFOreset(); - osd->clear(); -} - -void Screen_DeInit(void) -{ - gfx3d_deinit(); - - MainScreen.gpu = NULL; - SubScreen.gpu = NULL; - - delete osd; - osd = NULL; - - free_aligned(GPU_CustomFramebuffer); - GPU_CustomFramebuffer = NULL; - GPU_screen = NULL; - - free_aligned(_gpuDstToSrcIndex); - _gpuDstToSrcIndex = NULL; -} - -size_t GPU_GetFramebufferWidth() -{ - return _displayInfo.customWidth; -} - -size_t GPU_GetFramebufferHeight() -{ - return _displayInfo.customHeight; -} - -void GPU_SetFramebufferSize(size_t w, size_t h) -{ - if (w < GPU_FRAMEBUFFER_NATIVE_WIDTH || h < GPU_FRAMEBUFFER_NATIVE_HEIGHT) - { - return; - } - - // Check if we're calling this function from initialization. - // If we're not initializing, we need to finish rendering first. - if (gfx3d_colorRGBA6665 != NULL && gfx3d_colorRGBA5551 != NULL) - { - CurrentRenderer->RenderFinish(); - } - - const float customWidthScale = (float)w / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; - const float customHeightScale = (float)h / (float)GPU_FRAMEBUFFER_NATIVE_HEIGHT; - const float newGpuLargestDstLineCount = (size_t)ceilf(customHeightScale); - - u16 *oldCustomFramebuffer = GPU_CustomFramebuffer; - u16 *oldGpuDstToSrcIndexPtr = _gpuDstToSrcIndex; - FragmentColor *oldColorRGBA6665Buffer = gfx3d_colorRGBA6665; - u16 *oldColorRGBA5551Buffer = gfx3d_colorRGBA5551; - u16 *oldCustomVRAM = _gpuCustomVRAM; - - for (size_t srcX = 0, currentPitchCount = 0; srcX < GPU_FRAMEBUFFER_NATIVE_WIDTH; srcX++) - { - const size_t pitch = (size_t)ceilf((srcX+1) * customWidthScale) - currentPitchCount; - _gpuDstPitchCount[srcX] = pitch; - _gpuDstPitchIndex[srcX] = currentPitchCount; - currentPitchCount += pitch; - } - - for (size_t srcY = 0, currentLineCount = 0; srcY < GPU_FRAMEBUFFER_NATIVE_HEIGHT; srcY++) - { - const size_t lineCount = (size_t)ceilf((srcY+1) * customHeightScale) - currentLineCount; - _gpuDstLineCount[srcY] = lineCount; - _gpuDstLineIndex[srcY] = currentLineCount; - currentLineCount += lineCount; - } - - for (size_t srcY = 0, currentLineCount = 0; srcY < GPU_VRAM_BLOCK_LINES + 1; srcY++) - { - const size_t lineCount = (size_t)ceilf((srcY+1) * customHeightScale) - currentLineCount; - _gpuCaptureLineIndex[srcY] = currentLineCount; - currentLineCount += lineCount; - } - - u16 *newGpuDstToSrcIndex = (u16 *)malloc_alignedCacheLine(w * h * sizeof(u16)); - for (size_t y = 0; y < GPU_FRAMEBUFFER_NATIVE_HEIGHT; y++) - { - for (size_t x = 0; x < GPU_FRAMEBUFFER_NATIVE_WIDTH; x++) - { - for (size_t l = 0; l < _gpuDstLineCount[y]; l++) - { - for (size_t p = 0; p < _gpuDstPitchCount[x]; p++) - { - newGpuDstToSrcIndex[((_gpuDstLineIndex[y] + l) * w) + (_gpuDstPitchIndex[x] + p)] = (y * GPU_FRAMEBUFFER_NATIVE_WIDTH) + x; - } - } - } - } - - u16 *newCustomFramebuffer = (u16 *)malloc_alignedCacheLine(w * h * sizeof(u16) * 2); - memset_u16(newCustomFramebuffer, 0x7FFF, w * h * 2); - - FragmentColor *newColorRGBA6665Buffer = (FragmentColor *)malloc_alignedCacheLine(w * h * sizeof(FragmentColor)); - u16 *newColorRGBA5551 = (u16 *)malloc_alignedCacheLine(w * h * sizeof(u16)); - - const size_t newCustomVRAMBlockSize = _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w; - const size_t newCustomVRAMBlankSize = newGpuLargestDstLineCount * w; - u16 *newCustomVRAM = (u16 *)malloc_alignedCacheLine(((newCustomVRAMBlockSize * 4) + newCustomVRAMBlankSize) * sizeof(u16)); - memset(newCustomVRAM, 0, ((newCustomVRAMBlockSize * 4) + newCustomVRAMBlankSize) * sizeof(u16)); - - _gpuLargestDstLineCount = newGpuLargestDstLineCount; - _gpuVRAMBlockOffset = _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w; - _gpuDstToSrcIndex = newGpuDstToSrcIndex; - _gpuCustomVRAM = newCustomVRAM; - _gpuCustomVRAMBlank = newCustomVRAM + (newCustomVRAMBlockSize * 4); - - GPU_CustomFramebuffer = newCustomFramebuffer; - GPU_screen = GPU_CustomFramebuffer; - gfx3d_colorRGBA6665 = newColorRGBA6665Buffer; - gfx3d_colorRGBA5551 = newColorRGBA5551; - - _displayInfo.isCustomSizeRequested = ( (w != GPU_FRAMEBUFFER_NATIVE_WIDTH) || (h != GPU_FRAMEBUFFER_NATIVE_HEIGHT) ); - _displayInfo.masterCustomBuffer = GPU_CustomFramebuffer; - _displayInfo.customWidth = w; - _displayInfo.customHeight = h; - _displayInfo.customBuffer[NDSDisplayID_Main] = MainDisplay.GetEngine()->customBuffer; - _displayInfo.customBuffer[NDSDisplayID_Touch] = TouchDisplay.GetEngine()->customBuffer; - - MainScreen.gpu->SetCustomFramebufferSize(w, h); - SubScreen.gpu->SetCustomFramebufferSize(w, h); - CurrentRenderer->SetFramebufferSize(w, h); - - if (_displayInfo.didPerformCustomRender[NDSDisplayID_Main]) - { - _displayInfo.renderedBuffer[NDSDisplayID_Main] = _displayInfo.customBuffer[NDSDisplayID_Main]; - _displayInfo.renderedWidth[NDSDisplayID_Main] = _displayInfo.customWidth; - _displayInfo.renderedHeight[NDSDisplayID_Main] = _displayInfo.customHeight; - } - - if (_displayInfo.didPerformCustomRender[NDSDisplayID_Touch]) - { - _displayInfo.renderedBuffer[NDSDisplayID_Touch] = _displayInfo.customBuffer[NDSDisplayID_Touch]; - _displayInfo.renderedWidth[NDSDisplayID_Touch] = _displayInfo.customWidth; - _displayInfo.renderedHeight[NDSDisplayID_Touch] = _displayInfo.customHeight; - } - - free_aligned(oldCustomFramebuffer); - free_aligned(oldGpuDstToSrcIndexPtr); - free_aligned(oldColorRGBA6665Buffer); - free_aligned(oldColorRGBA5551Buffer); - free_aligned(oldCustomVRAM); -} - -bool GPU_GetWillAutoBlitNativeToCustomBuffer() -{ - return _gpuWillAutoBlitNativeToCustomBuffer; -} - -void GPU_SetWillAutoBlitNativeToCustomBuffer(const bool willAutoBlit) -{ - _gpuWillAutoBlitNativeToCustomBuffer = willAutoBlit; -} - /*****************************************************************************/ // GPU_RenderLine /*****************************************************************************/ -void GPU_set_DISPCAPCNT(u32 val) +void GPUEngineBase::SetDISPCAPCNT(u32 val) { - GPUEngineBase *gpu = MainScreen.gpu; - struct _DISPCNT *dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits; + struct _DISPCNT *dispCnt = &(this->dispx_st)->dispx_DISPCNT.bits; - gpu->dispCapCnt.val = val; - gpu->dispCapCnt.EVA = std::min((u32)16, (val & 0x1F)); - gpu->dispCapCnt.EVB = std::min((u32)16, ((val >> 8) & 0x1F)); - gpu->dispCapCnt.writeBlock = (val >> 16) & 0x03; - gpu->dispCapCnt.writeOffset = (val >> 18) & 0x03; - gpu->dispCapCnt.readBlock = dispCnt->VRAM_Block; - gpu->dispCapCnt.readOffset = (dispCnt->DisplayMode == 2) ? 0 : (val >> 26) & 0x03; - gpu->dispCapCnt.srcA = (val >> 24) & 0x01; - gpu->dispCapCnt.srcB = (val >> 25) & 0x01; - gpu->dispCapCnt.capSrc = (val >> 29) & 0x03; + this->dispCapCnt.val = val; + this->dispCapCnt.EVA = std::min((u32)16, (val & 0x1F)); + this->dispCapCnt.EVB = std::min((u32)16, ((val >> 8) & 0x1F)); + this->dispCapCnt.writeBlock = (val >> 16) & 0x03; + this->dispCapCnt.writeOffset = (val >> 18) & 0x03; + this->dispCapCnt.readBlock = dispCnt->VRAM_Block; + this->dispCapCnt.readOffset = (dispCnt->DisplayMode == 2) ? 0 : (val >> 26) & 0x03; + this->dispCapCnt.srcA = (val >> 24) & 0x01; + this->dispCapCnt.srcB = (val >> 25) & 0x01; + this->dispCapCnt.capSrc = (val >> 29) & 0x03; switch ((val >> 20) & 0x03) { case 0: - gpu->dispCapCnt.capx = DISPCAPCNT::_128; - gpu->dispCapCnt.capy = 128; + this->dispCapCnt.capx = DISPCAPCNT::_128; + this->dispCapCnt.capy = 128; break; case 1: - gpu->dispCapCnt.capx = DISPCAPCNT::_256; - gpu->dispCapCnt.capy = 64; + this->dispCapCnt.capx = DISPCAPCNT::_256; + this->dispCapCnt.capy = 64; break; case 2: - gpu->dispCapCnt.capx = DISPCAPCNT::_256; - gpu->dispCapCnt.capy = 128; + this->dispCapCnt.capx = DISPCAPCNT::_256; + this->dispCapCnt.capy = 128; break; case 3: - gpu->dispCapCnt.capx = DISPCAPCNT::_256; - gpu->dispCapCnt.capy = 192; + this->dispCapCnt.capx = DISPCAPCNT::_256; + this->dispCapCnt.capy = 192; break; default: @@ -2273,21 +2073,21 @@ void GPU_set_DISPCAPCNT(u32 val) } /*INFO("Capture 0x%X:\n EVA=%i, EVB=%i, wBlock=%i, wOffset=%i, capX=%i, capY=%i\n rBlock=%i, rOffset=%i, srcCap=%i, dst=0x%X, src=0x%X\n srcA=%i, srcB=%i\n\n", - val, gpu->dispCapCnt.EVA, gpu->dispCapCnt.EVB, gpu->dispCapCnt.writeBlock, gpu->dispCapCnt.writeOffset, - gpu->dispCapCnt.capx, gpu->dispCapCnt.capy, gpu->dispCapCnt.readBlock, gpu->dispCapCnt.readOffset, - gpu->dispCapCnt.capSrc, gpu->dispCapCnt.dst - MMU.ARM9_LCD, gpu->dispCapCnt.src - MMU.ARM9_LCD, - gpu->dispCapCnt.srcA, gpu->dispCapCnt.srcB);*/ + val, this->dispCapCnt.EVA, this->dispCapCnt.EVB, this->dispCapCnt.writeBlock, this->dispCapCnt.writeOffset, + this->dispCapCnt.capx, this->dispCapCnt.capy, this->dispCapCnt.readBlock, this->dispCapCnt.readOffset, + this->dispCapCnt.capSrc, this->dispCapCnt.dst - MMU.ARM9_LCD, this->dispCapCnt.src - MMU.ARM9_LCD, + this->dispCapCnt.srcA, this->dispCapCnt.srcB);*/ } -void GPUEngineBase::RenderLine(const u16 l, u16 *dstLine, const size_t dstLineWidth, const size_t dstLineCount) +void GPUEngineBase::RenderLine_Layer(const u16 l, u16 *dstLine, const size_t dstLineWidth, const size_t dstLineCount) { const size_t pixCount = dstLineWidth * dstLineCount; const size_t dstLineIndex = _gpuDstLineIndex[l]; struct _DISPCNT *dispCnt = &(this->dispx_st)->dispx_DISPCNT.bits; itemsForPriority_t *item; - this->_currentFadeInColors = &fadeInColors[this->_BLDY_EVY][0]; - this->_currentFadeOutColors = &fadeOutColors[this->_BLDY_EVY][0]; + this->_currentFadeInColors = &GPUEngineBase::_fadeInColors[this->_BLDY_EVY][0]; + this->_currentFadeOutColors = &GPUEngineBase::_fadeOutColors[this->_BLDY_EVY][0]; const u16 backdrop_color = T1ReadWord(MMU.ARM9_VMEM, this->core * ADDRESS_STEP_1KB) & 0x7FFF; @@ -2328,7 +2128,7 @@ PLAIN_CLEAR: memset(this->_sprAlpha, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH); memset(this->_sprType, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH); memset(this->_sprPrio, 0xFF, GPU_FRAMEBUFFER_NATIVE_WIDTH); - memset(_gpuSprWin, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH); + memset(this->_sprWin, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH); // init pixels priorities assert(NB_PRIORITIES == 4); @@ -2388,7 +2188,8 @@ PLAIN_CLEAR: if (this->core == GPUCOREID_MAIN && layerNum == 0 && dispCnt->BG0_3D) { - const float customWidthScale = (float)_displayInfo.customWidth / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); + const float customWidthScale = (float)dispInfo.customWidth / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; const FragmentColor *srcLine = gfx3d_GetLineDataRGBA6665(dstLineIndex); const u16 hofs = (u16)( ((float)this->GetHOFS(layerNum) * customWidthScale) + 0.5f ); u16 *render3DdstLine = dstLine; @@ -2449,7 +2250,7 @@ PLAIN_CLEAR: if (this->isCustomRenderingNeeded) { const bool useCustomVRAM = (this->vramBlockOBJIndex != VRAM_NO_3D_USAGE); - const u16 *srcLine = (useCustomVRAM) ? _gpuCustomVRAM + (this->vramBlockOBJIndex * _gpuVRAMBlockOffset) + (dstLineIndex * dstLineWidth) : NULL; + const u16 *srcLine = (useCustomVRAM) ? GPU->GetCustomVRAMBuffer() + (this->vramBlockOBJIndex * _gpuVRAMBlockOffset) + (dstLineIndex * dstLineWidth) : NULL; for (size_t line = 0; line < dstLineCount; line++) { @@ -2543,6 +2344,8 @@ static void GPU_RenderLine_DispCapture_Copy(const u16 *__restrict src, u16 *__re } else { + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); + if (CAPTUREFROMNATIVESRC) { for (size_t i = 0; i < CAPTURELENGTH; i++) @@ -2555,7 +2358,7 @@ static void GPU_RenderLine_DispCapture_Copy(const u16 *__restrict src, u16 *__re for (size_t line = 1; line < captureLineCount; line++) { - memcpy(dst + (line * _displayInfo.customWidth), dst, captureLengthExt * sizeof(u16)); + memcpy(dst + (line * dispInfo.customWidth), dst, captureLengthExt * sizeof(u16)); } } else @@ -2594,8 +2397,8 @@ static void GPU_RenderLine_DispCapture_Copy(const u16 *__restrict src, u16 *__re dst[i] = LE_TO_LOCAL_16(src[i]) | alphaBit; } - src += _displayInfo.customWidth; - dst += _displayInfo.customWidth; + src += dispInfo.customWidth; + dst += dispInfo.customWidth; } } } @@ -2696,7 +2499,8 @@ static void GPU_RenderLine_DispCapture_BlendToCustomDstBuffer(const u16 *__restr const __m128i blendEVB_vec128 = _mm_set1_epi16(blendEVB); #endif - size_t offset = _gpuDstToSrcIndex[_gpuDstLineIndex[l] * _displayInfo.customWidth] - (l * GPU_FRAMEBUFFER_NATIVE_WIDTH); + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); + size_t offset = _gpuDstToSrcIndex[_gpuDstLineIndex[l] * dispInfo.customWidth] - (l * GPU_FRAMEBUFFER_NATIVE_WIDTH); size_t i = 0; #ifdef ENABLE_SSE2 @@ -2737,8 +2541,8 @@ static void GPU_RenderLine_DispCapture_BlendToCustomDstBuffer(const u16 *__restr template static void GPU_RenderLine_DispCapture_Blend(const u16 *__restrict srcA, const u16 *__restrict srcB, u16 *__restrict dst, const size_t captureLengthExt, const size_t l) { - const u8 blendEVA = MainScreen.gpu->dispCapCnt.EVA; - const u8 blendEVB = MainScreen.gpu->dispCapCnt.EVB; + const u8 blendEVA = GPU->GetEngineMain()->dispCapCnt.EVA; + const u8 blendEVB = GPU->GetEngineMain()->dispCapCnt.EVB; if (CAPTURETONATIVEDST) { @@ -2780,6 +2584,7 @@ static void GPU_RenderLine_DispCapture_Blend(const u16 *__restrict srcA, const u } else { + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); const size_t captureLineCount = _gpuDstLineCount[l]; if (CAPTURELENGTH == GPU_FRAMEBUFFER_NATIVE_WIDTH) @@ -2791,9 +2596,9 @@ static void GPU_RenderLine_DispCapture_Blend(const u16 *__restrict srcA, const u for (size_t line = 0; line < captureLineCount; line++) { GPU_RenderLine_DispCapture_BlendToCustomDstBuffer(srcA, srcB, dst, blendEVA, blendEVB, captureLengthExt, l); - srcA += _displayInfo.customWidth; - srcB += _displayInfo.customWidth; - dst += _displayInfo.customWidth; + srcA += dispInfo.customWidth; + srcB += dispInfo.customWidth; + dst += dispInfo.customWidth; } } } @@ -2804,7 +2609,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) { assert( (CAPTURELENGTH == 0) || (CAPTURELENGTH == GPU_FRAMEBUFFER_NATIVE_WIDTH/2) || (CAPTURELENGTH == GPU_FRAMEBUFFER_NATIVE_WIDTH) ); - GPUEngineBase *gpu = MainScreen.gpu; + GPUEngineBase *gpu = GPU->GetEngineMain(); if (l == 0) { @@ -2822,6 +2627,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) if (CAPTURELENGTH != 0) { + VRAM3DUsageProperties &vramUsageProperty = GPU->GetVRAM3DUsageProperties(); const u8 vramWriteBlock = gpu->dispCapCnt.writeBlock; const u8 vramReadBlock = gpu->dispCapCnt.readBlock; @@ -2886,7 +2692,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) } } - _gpuVRAM3DUsage.isBlockUsed[vramWriteBlock] = gpu->isCustomRenderingNeeded; + vramUsageProperty.isBlockUsed[vramWriteBlock] = gpu->isCustomRenderingNeeded; break; } @@ -2897,7 +2703,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) { case 0: // Capture VRAM { - if (gpu->isCustomRenderingNeeded && _gpuVRAM3DUsage.isBlockUsed[vramReadBlock]) + if (gpu->isCustomRenderingNeeded && vramUsageProperty.isBlockUsed[vramReadBlock]) { GPU_RenderLine_DispCapture_Copy<0, CAPTURELENGTH, false, true>(srcB, cap_dst, CAPTURELENGTH, 1); } @@ -2906,7 +2712,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) GPU_RenderLine_DispCapture_Copy<0, CAPTURELENGTH, true, true>(srcB, cap_dst, CAPTURELENGTH, 1); } - _gpuVRAM3DUsage.isBlockUsed[vramWriteBlock] = _gpuVRAM3DUsage.isBlockUsed[vramReadBlock]; + vramUsageProperty.isBlockUsed[vramWriteBlock] = vramUsageProperty.isBlockUsed[vramReadBlock]; break; } @@ -2914,7 +2720,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) { GPU_RenderLine_DispCapture_FIFOToBuffer(fifoLine); GPU_RenderLine_DispCapture_Copy<1, CAPTURELENGTH, true, true>(srcB, cap_dst, CAPTURELENGTH, 1); - _gpuVRAM3DUsage.isBlockUsed[vramWriteBlock] = false; + vramUsageProperty.isBlockUsed[vramWriteBlock] = false; break; } } @@ -2944,7 +2750,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) { if (gpu->isCustomRenderingNeeded) { - if (_gpuVRAM3DUsage.isBlockUsed[vramReadBlock]) + if (vramUsageProperty.isBlockUsed[vramReadBlock]) { GPU_RenderLine_DispCapture_Blend(srcA, srcB, cap_dst, CAPTURELENGTH, 1); } @@ -2955,7 +2761,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) } else { - if (_gpuVRAM3DUsage.isBlockUsed[vramReadBlock]) + if (vramUsageProperty.isBlockUsed[vramReadBlock]) { GPU_RenderLine_DispCapture_Blend(srcA, srcB, cap_dst, CAPTURELENGTH, 1); } @@ -2966,19 +2772,20 @@ static void GPU_RenderLine_DispCapture(const u16 l) } } - _gpuVRAM3DUsage.isBlockUsed[vramWriteBlock] = gpu->isCustomRenderingNeeded || _gpuVRAM3DUsage.isBlockUsed[vramReadBlock]; + vramUsageProperty.isBlockUsed[vramWriteBlock] = gpu->isCustomRenderingNeeded || vramUsageProperty.isBlockUsed[vramReadBlock]; break; } } if (gpu->isCustomRenderingNeeded) { - const size_t captureLengthExt = (CAPTURELENGTH) ? _displayInfo.customWidth : _displayInfo.customWidth / 2; + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); + const size_t captureLengthExt = (CAPTURELENGTH) ? dispInfo.customWidth : dispInfo.customWidth / 2; const size_t captureLineCount = _gpuDstLineCount[l]; const size_t vramBlockOffsetExt = _gpuVRAMBlockOffset; - const u32 ofsmulExt = (CAPTURELENGTH) ? _displayInfo.customWidth : _displayInfo.customWidth / 2; + const u32 ofsmulExt = (CAPTURELENGTH) ? dispInfo.customWidth : dispInfo.customWidth / 2; - size_t cap_dst_adr_ext = (gpu->dispCapCnt.writeOffset * _gpuCaptureLineIndex[64] * _displayInfo.customWidth) + (_gpuCaptureLineIndex[l] * ofsmulExt); + size_t cap_dst_adr_ext = (gpu->dispCapCnt.writeOffset * _gpuCaptureLineIndex[64] * dispInfo.customWidth) + (_gpuCaptureLineIndex[l] * ofsmulExt); while (cap_dst_adr_ext >= vramBlockOffsetExt) { @@ -2987,12 +2794,12 @@ static void GPU_RenderLine_DispCapture(const u16 l) cap_dst_adr_ext += vramWriteBlock * vramBlockOffsetExt; - const u16 *cap_src_ext = _gpuCustomVRAMBlank; - u16 *cap_dst_ext = _gpuCustomVRAM + cap_dst_adr_ext; + const u16 *cap_src_ext = GPU->GetCustomVRAMBlankBuffer(); + u16 *cap_dst_ext = GPU->GetCustomVRAMBuffer() + cap_dst_adr_ext; if (vramConfiguration.banks[vramReadBlock].purpose == VramConfiguration::LCDC) { - size_t cap_src_adr_ext = (gpu->dispCapCnt.readOffset * _gpuCaptureLineIndex[64] * _displayInfo.customWidth) + (_gpuCaptureLineIndex[l] * _displayInfo.customWidth); + size_t cap_src_adr_ext = (gpu->dispCapCnt.readOffset * _gpuCaptureLineIndex[64] * dispInfo.customWidth) + (_gpuCaptureLineIndex[l] * dispInfo.customWidth); while (cap_src_adr_ext >= vramBlockOffsetExt) { @@ -3000,7 +2807,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) } cap_src_adr_ext += vramReadBlock * vramBlockOffsetExt; - cap_src_ext = _gpuCustomVRAM + cap_src_adr_ext; + cap_src_ext = GPU->GetCustomVRAMBuffer() + cap_src_adr_ext; } srcB = (gpu->dispCapCnt.srcB == 0) ? cap_src_ext : fifoLine; @@ -3028,7 +2835,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) { case 0: // Capture VRAM { - if (_gpuVRAM3DUsage.isBlockUsed[vramReadBlock]) + if (vramUsageProperty.isBlockUsed[vramReadBlock]) { GPU_RenderLine_DispCapture_Copy<0, CAPTURELENGTH, false, false>(srcB, cap_dst_ext, captureLengthExt, captureLineCount); } @@ -3049,7 +2856,7 @@ static void GPU_RenderLine_DispCapture(const u16 l) default: // Capture source is SourceA+B blended { - if (_gpuVRAM3DUsage.isBlockUsed[vramReadBlock]) + if (vramUsageProperty.isBlockUsed[vramReadBlock]) { GPU_RenderLine_DispCapture_Blend(srcA, srcB, cap_dst_ext, captureLengthExt, captureLineCount); } @@ -3072,8 +2879,10 @@ static void GPU_RenderLine_DispCapture(const u16 l) } } -static void GPU_RenderLine_MasterBrightness(const GPUMasterBrightMode mode, const u32 factor, u16 *dstLine, const size_t dstLineWidth, const size_t dstLineCount) +void GPUEngineBase::RenderLine_MasterBrightness(u16 *dstLine, const size_t dstLineWidth, const size_t dstLineCount) { + const u32 factor = this->MasterBrightFactor; + //isn't it odd that we can set uselessly high factors here? //factors above 16 change nothing. curious. if (factor == 0) return; @@ -3083,7 +2892,7 @@ static void GPU_RenderLine_MasterBrightness(const GPUMasterBrightMode mode, cons const size_t pixCount = dstLineWidth * dstLineCount; - switch (mode) + switch (this->MasterBrightMode) { case GPUMasterBrightMode_Disable: break; @@ -3101,19 +2910,19 @@ static void GPU_RenderLine_MasterBrightness(const GPUMasterBrightMode mode, cons __m128i dstColor_vec128 = _mm_load_si128((__m128i *)(dstLine + i)); dstColor_vec128 = _mm_and_si128(dstColor_vec128, _mm_set1_epi16(0x7FFF)); - dstLine[i+7] = fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 7) ]; - dstLine[i+6] = fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 6) ]; - dstLine[i+5] = fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 5) ]; - dstLine[i+4] = fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 4) ]; - dstLine[i+3] = fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 3) ]; - dstLine[i+2] = fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 2) ]; - dstLine[i+1] = fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 1) ]; - dstLine[i+0] = fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 0) ]; + dstLine[i+7] = GPUEngineBase::_fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 7) ]; + dstLine[i+6] = GPUEngineBase::_fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 6) ]; + dstLine[i+5] = GPUEngineBase::_fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 5) ]; + dstLine[i+4] = GPUEngineBase::_fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 4) ]; + dstLine[i+3] = GPUEngineBase::_fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 3) ]; + dstLine[i+2] = GPUEngineBase::_fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 2) ]; + dstLine[i+1] = GPUEngineBase::_fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 1) ]; + dstLine[i+0] = GPUEngineBase::_fadeInColors[factor][ _mm_extract_epi16(dstColor_vec128, 0) ]; } #endif for (; i < pixCount; i++) { - dstLine[i] = fadeInColors[factor][ dstLine[i] & 0x7FFF ]; + dstLine[i] = GPUEngineBase::_fadeInColors[factor][ dstLine[i] & 0x7FFF ]; } } else @@ -3137,19 +2946,19 @@ static void GPU_RenderLine_MasterBrightness(const GPUMasterBrightMode mode, cons __m128i dstColor_vec128 = _mm_load_si128((__m128i *)(dstLine + i)); dstColor_vec128 = _mm_and_si128(dstColor_vec128, _mm_set1_epi16(0x7FFF)); - dstLine[i+7] = fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 7) ]; - dstLine[i+6] = fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 6) ]; - dstLine[i+5] = fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 5) ]; - dstLine[i+4] = fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 4) ]; - dstLine[i+3] = fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 3) ]; - dstLine[i+2] = fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 2) ]; - dstLine[i+1] = fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 1) ]; - dstLine[i+0] = fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 0) ]; + dstLine[i+7] = GPUEngineBase::_fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 7) ]; + dstLine[i+6] = GPUEngineBase::_fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 6) ]; + dstLine[i+5] = GPUEngineBase::_fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 5) ]; + dstLine[i+4] = GPUEngineBase::_fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 4) ]; + dstLine[i+3] = GPUEngineBase::_fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 3) ]; + dstLine[i+2] = GPUEngineBase::_fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 2) ]; + dstLine[i+1] = GPUEngineBase::_fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 1) ]; + dstLine[i+0] = GPUEngineBase::_fadeOutColors[factor][ _mm_extract_epi16(dstColor_vec128, 0) ]; } #endif for (; i < pixCount; i++) { - dstLine[i] = fadeOutColors[factor][ dstLine[i] & 0x7FFF ]; + dstLine[i] = GPUEngineBase::_fadeOutColors[factor][ dstLine[i] & 0x7FFF ]; } } else @@ -3172,8 +2981,8 @@ void GPUEngineBase::setup_windows() const u16 startY = (WIN_NUM == 0) ? this->_WIN0V0 : this->_WIN1V0; const u16 endY = (WIN_NUM == 0) ? this->_WIN0V1 : this->_WIN1V1; - if(WIN_NUM == 0 && !this->_WIN0_ENABLED) goto allout; - if(WIN_NUM == 1 && !this->_WIN1_ENABLED) goto allout; + if (WIN_NUM == 0 && !this->_WIN0_ENABLED) goto allout; + if (WIN_NUM == 1 && !this->_WIN1_ENABLED) goto allout; if (startY > endY) { @@ -3233,10 +3042,14 @@ void GPUEngineBase::update_winh() } } -void GPU_RenderLine(NDS_Screen *screen, const u16 l, bool skip) +void GPUSubsystem::RenderLine(const u16 l, bool skip) +{ + this->_engineMain->RenderLine(l, skip); + this->_engineSub->RenderLine(l, skip); +} + +void GPUEngineBase::RenderLine(const u16 l, bool skip) { - GPUEngineBase *gpu = screen->gpu; - //here is some setup which is only done on line 0 if (l == 0) { @@ -3251,18 +3064,18 @@ void GPU_RenderLine(NDS_Screen *screen, const u16 l, bool skip) //bubble bobble revolution classic mode //NOTE: //I am REALLY unsatisfied with this logic now. But it seems to be working.. - gpu->refreshAffineStartRegs(-1,-1); + this->refreshAffineStartRegs(-1,-1); - if (gpu->core == GPUCOREID_MAIN) + if (this->core == GPUCOREID_MAIN) { - GPU_UpdateVRAM3DUsageProperties(_gpuVRAM3DUsage); + GPU->UpdateVRAM3DUsageProperties(); } } if (skip) { - gpu->currLine = l; - if (gpu->core == GPUCOREID_MAIN) + this->currLine = l; + if (this->core == GPUCOREID_MAIN) { GPU_RenderLine_DispCapture<0>(l); if (l == 191) @@ -3273,93 +3086,94 @@ void GPU_RenderLine(NDS_Screen *screen, const u16 l, bool skip) return; } - const size_t dstLineWidth = (gpu->isCustomRenderingNeeded) ? _displayInfo.customWidth : GPU_FRAMEBUFFER_NATIVE_WIDTH; - const size_t dstLineCount = (gpu->isCustomRenderingNeeded) ? _gpuDstLineCount[l] : 1; - const size_t dstLineIndex = (gpu->isCustomRenderingNeeded) ? _gpuDstLineIndex[l] : l; - u16 *dstLine = (gpu->isCustomRenderingNeeded) ? gpu->customBuffer + (dstLineIndex * dstLineWidth) : gpu->nativeBuffer + (dstLineIndex * dstLineWidth); + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); + const size_t dstLineWidth = (this->isCustomRenderingNeeded) ? dispInfo.customWidth : GPU_FRAMEBUFFER_NATIVE_WIDTH; + const size_t dstLineCount = (this->isCustomRenderingNeeded) ? _gpuDstLineCount[l] : 1; + const size_t dstLineIndex = (this->isCustomRenderingNeeded) ? _gpuDstLineIndex[l] : l; + u16 *dstLine = (this->isCustomRenderingNeeded) ? this->customBuffer + (dstLineIndex * dstLineWidth) : this->nativeBuffer + (dstLineIndex * dstLineWidth); //blacken the screen if it is turned off by the user - if (!CommonSettings.showGpu.screens[gpu->core]) + if (!CommonSettings.showGpu.screens[this->core]) { memset(dstLine, 0, dstLineWidth * dstLineCount * sizeof(u16)); return; } // skip some work if master brightness makes the screen completely white or completely black - if (gpu->MasterBrightFactor >= 16 && (gpu->MasterBrightMode == GPUMasterBrightMode_Up || gpu->MasterBrightMode == GPUMasterBrightMode_Down)) + if (this->MasterBrightFactor >= 16 && (this->MasterBrightMode == GPUMasterBrightMode_Up || this->MasterBrightMode == GPUMasterBrightMode_Down)) { // except if it could cause any side effects (for example if we're capturing), then don't skip anything - if (!(gpu->core == GPUCOREID_MAIN && (gpu->dispCapCnt.enabled || l == 0 || l == 191))) + if (!(this->core == GPUCOREID_MAIN && (this->dispCapCnt.enabled || l == 0 || l == 191))) { - gpu->currLine = l; - GPU_RenderLine_MasterBrightness(gpu->MasterBrightMode, gpu->MasterBrightFactor, dstLine, dstLineWidth, dstLineCount); + this->currLine = l; + this->RenderLine_MasterBrightness(dstLine, dstLineWidth, dstLineCount); return; } } //cache some parameters which are assumed to be stable throughout the rendering of the entire line - gpu->currLine = l; - const u16 mosaic_control = LE_TO_LOCAL_16(gpu->dispx_st->dispx_MISC.MOSAIC); + this->currLine = l; + const u16 mosaic_control = LE_TO_LOCAL_16(this->dispx_st->dispx_MISC.MOSAIC); const u16 mosaic_width = (mosaic_control & 0xF); const u16 mosaic_height = ((mosaic_control >> 4) & 0xF); //mosaic test hacks //mosaic_width = mosaic_height = 3; - GPUEngineBase::mosaicLookup.widthValue = mosaic_width; - GPUEngineBase::mosaicLookup.heightValue = mosaic_height; - GPUEngineBase::mosaicLookup.width = &GPUEngineBase::mosaicLookup.table[mosaic_width][0]; - GPUEngineBase::mosaicLookup.height = &GPUEngineBase::mosaicLookup.table[mosaic_height][0]; + GPUEngineBase::_mosaicLookup.widthValue = mosaic_width; + GPUEngineBase::_mosaicLookup.heightValue = mosaic_height; + GPUEngineBase::_mosaicLookup.width = &GPUEngineBase::_mosaicLookup.table[mosaic_width][0]; + GPUEngineBase::_mosaicLookup.height = &GPUEngineBase::_mosaicLookup.table[mosaic_height][0]; - if(gpu->need_update_winh[0]) gpu->update_winh<0>(); - if(gpu->need_update_winh[1]) gpu->update_winh<1>(); + if (this->need_update_winh[0]) this->update_winh<0>(); + if (this->need_update_winh[1]) this->update_winh<1>(); - gpu->setup_windows<0>(); - gpu->setup_windows<1>(); + this->setup_windows<0>(); + this->setup_windows<1>(); //generate the 2d engine output - if (gpu->dispMode == GPUDisplayMode_Normal) + if (this->dispMode == GPUDisplayMode_Normal) { //optimization: render straight to the output buffer when thats what we are going to end up displaying anyway - gpu->currDst = dstLine; + this->currDst = dstLine; } else { //otherwise, we need to go to a temp buffer - gpu->currDst = gpu->workingScanline; + this->currDst = this->workingScanline; } - gpu->RenderLine(l, gpu->currDst, dstLineWidth, dstLineCount); + this->RenderLine_Layer(l, this->currDst, dstLineWidth, dstLineCount); - switch (gpu->dispMode) + switch (this->dispMode) { case GPUDisplayMode_Off: // Display Off(Display white) - gpu->HandleDisplayModeOff(dstLine, l, dstLineWidth, dstLineCount); + this->HandleDisplayModeOff(dstLine, l, dstLineWidth, dstLineCount); break; case GPUDisplayMode_Normal: // Display BG and OBJ layers - gpu->HandleDisplayModeNormal(dstLine, l, dstLineWidth, dstLineCount); + this->HandleDisplayModeNormal(dstLine, l, dstLineWidth, dstLineCount); break; case GPUDisplayMode_VRAM: // Display vram framebuffer - gpu->HandleDisplayModeVRAM(dstLine, l, dstLineWidth, dstLineCount); + this->HandleDisplayModeVRAM(dstLine, l, dstLineWidth, dstLineCount); break; case GPUDisplayMode_MainMemory: // Display memory FIFO - gpu->HandleDisplayModeMainMemory(dstLine, l, dstLineWidth, dstLineCount); + this->HandleDisplayModeMainMemory(dstLine, l, dstLineWidth, dstLineCount); break; } //capture after displaying so that we can safely display vram before overwriting it here - if (gpu->core == GPUCOREID_MAIN) + if (this->core == GPUCOREID_MAIN) { //BUG!!! if someone is capturing and displaying both from the fifo, then it will have been //consumed above by the display before we get here //(is that even legal? i think so) - if ((vramConfiguration.banks[gpu->dispCapCnt.writeBlock].purpose == VramConfiguration::LCDC) && (l < gpu->dispCapCnt.capy)) + if ((vramConfiguration.banks[this->dispCapCnt.writeBlock].purpose == VramConfiguration::LCDC) && (l < this->dispCapCnt.capy)) { - if (gpu->dispCapCnt.capx == DISPCAPCNT::_128) + if (this->dispCapCnt.capx == DISPCAPCNT::_128) { GPU_RenderLine_DispCapture(l); } @@ -3379,28 +3193,34 @@ void GPU_RenderLine(NDS_Screen *screen, const u16 l, bool skip) } } - GPU_RenderLine_MasterBrightness(gpu->MasterBrightMode, gpu->MasterBrightFactor, dstLine, dstLineWidth, dstLineCount); + this->RenderLine_MasterBrightness(dstLine, dstLineWidth, dstLineCount); } void gpu_savestate(EMUFILE* os) { + const GPUEngineBase *mainEngine = GPU->GetEngineMain(); + const GPUEngineBase *subEngine = GPU->GetEngineSub(); + //version write32le(1,os); - os->fwrite((u8 *)GPU_CustomFramebuffer, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16) * 2); + os->fwrite((u8 *)GPU->GetCustomFramebuffer(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16) * 2); - write32le(MainScreen.gpu->affineInfo[0].x,os); - write32le(MainScreen.gpu->affineInfo[0].y,os); - write32le(MainScreen.gpu->affineInfo[1].x,os); - write32le(MainScreen.gpu->affineInfo[1].y,os); - write32le(SubScreen.gpu->affineInfo[0].x,os); - write32le(SubScreen.gpu->affineInfo[0].y,os); - write32le(SubScreen.gpu->affineInfo[1].x,os); - write32le(SubScreen.gpu->affineInfo[1].y,os); + write32le(mainEngine->affineInfo[0].x,os); + write32le(mainEngine->affineInfo[0].y,os); + write32le(mainEngine->affineInfo[1].x,os); + write32le(mainEngine->affineInfo[1].y,os); + write32le(subEngine->affineInfo[0].x,os); + write32le(subEngine->affineInfo[0].y,os); + write32le(subEngine->affineInfo[1].x,os); + write32le(subEngine->affineInfo[1].y,os); } bool gpu_loadstate(EMUFILE* is, int size) { + GPUEngineBase *mainEngine = GPU->GetEngineMain(); + GPUEngineBase *subEngine = GPU->GetEngineSub(); + //read version u32 version; @@ -3421,25 +3241,25 @@ bool gpu_loadstate(EMUFILE* is, int size) if (version > 1) return false; - is->fread((u8 *)GPU_CustomFramebuffer, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16) * 2); + is->fread((u8 *)GPU->GetCustomFramebuffer(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16) * 2); if (version == 1) { - read32le(&MainScreen.gpu->affineInfo[0].x,is); - read32le(&MainScreen.gpu->affineInfo[0].y,is); - read32le(&MainScreen.gpu->affineInfo[1].x,is); - read32le(&MainScreen.gpu->affineInfo[1].y,is); - read32le(&SubScreen.gpu->affineInfo[0].x,is); - read32le(&SubScreen.gpu->affineInfo[0].y,is); - read32le(&SubScreen.gpu->affineInfo[1].x,is); - read32le(&SubScreen.gpu->affineInfo[1].y,is); + read32le(&(mainEngine->affineInfo[0].x),is); + read32le(&(mainEngine->affineInfo[0].y),is); + read32le(&(mainEngine->affineInfo[1].x),is); + read32le(&(mainEngine->affineInfo[1].y),is); + read32le(&(subEngine->affineInfo[0].x),is); + read32le(&(subEngine->affineInfo[0].y),is); + read32le(&(subEngine->affineInfo[1].x),is); + read32le(&(subEngine->affineInfo[1].y),is); //removed per nitsuja feedback. anyway, this same thing will happen almost immediately in gpu line=0 //MainScreen.gpu->refreshAffineStartRegs(-1,-1); //SubScreen.gpu->refreshAffineStartRegs(-1,-1); } - MainScreen.gpu->UpdateBLDALPHA(); - SubScreen.gpu->UpdateBLDALPHA(); + mainEngine->UpdateBLDALPHA(); + subEngine->UpdateBLDALPHA(); return !is->fail(); } @@ -3495,6 +3315,8 @@ void GPUEngineBase::UpdateVRAM3DUsageProperties_OBJLayer(const size_t bankIndex, return; } + GPUEngineBase *mainEngine = GPU->GetEngineMain(); + for (size_t spriteIndex = 0; spriteIndex < 128; spriteIndex++) { const OAMAttributes &spriteInfo = this->_oamList[spriteIndex]; @@ -3504,7 +3326,7 @@ void GPUEngineBase::UpdateVRAM3DUsageProperties_OBJLayer(const size_t bankIndex, const u32 vramAddress = ( (spriteInfo.TileIndex & 0x1F) * 0x10 ) + ( (spriteInfo.TileIndex & ~0x1F) * 0x80 ); const SpriteSize sprSize = sprSizeTab[spriteInfo.Size][spriteInfo.Shape]; - if( (vramAddress == (MainScreen.gpu->dispCapCnt.writeOffset * ADDRESS_STEP_32KB)) && (sprSize.x == 64) && (sprSize.y == 64) ) + if( (vramAddress == (mainEngine->dispCapCnt.writeOffset * ADDRESS_STEP_32KB)) && (sprSize.x == 64) && (sprSize.y == 64) ) { this->vramBlockOBJIndex = bankIndex; this->isCustomRenderingNeeded = true; @@ -3514,121 +3336,6 @@ void GPUEngineBase::UpdateVRAM3DUsageProperties_OBJLayer(const size_t bankIndex, } } -void GPU_UpdateVRAM3DUsageProperties(VRAM3DUsageProperties &outProperty) -{ - outProperty.blockIndexDisplayVRAM = VRAM_NO_3D_USAGE; - - MainScreen.gpu->is3DEnabled = (MainScreen.gpu->dispCnt().BG0_Enable == 1) && (MainScreen.gpu->dispCnt().BG0_3D == 1); - MainScreen.gpu->isCustomRenderingNeeded = false; - MainScreen.gpu->vramBlockBGIndex = VRAM_NO_3D_USAGE; - MainScreen.gpu->vramBlockOBJIndex = VRAM_NO_3D_USAGE; - MainScreen.gpu->vramBGLayer = VRAM_NO_3D_USAGE; - - SubScreen.gpu->is3DEnabled = false; - SubScreen.gpu->isCustomRenderingNeeded = false; - SubScreen.gpu->vramBlockBGIndex = VRAM_NO_3D_USAGE; - SubScreen.gpu->vramBlockOBJIndex = VRAM_NO_3D_USAGE; - SubScreen.gpu->vramBGLayer = VRAM_NO_3D_USAGE; - - MainScreen.gpu->renderedWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH; - MainScreen.gpu->renderedHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT; - MainScreen.gpu->renderedBuffer = MainScreen.gpu->nativeBuffer; - - SubScreen.gpu->renderedWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH; - SubScreen.gpu->renderedHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT; - SubScreen.gpu->renderedBuffer = SubScreen.gpu->nativeBuffer; - - _displayInfo.didPerformCustomRender[NDSDisplayID_Main] = false; - _displayInfo.didPerformCustomRender[NDSDisplayID_Touch] = false; - - _displayInfo.nativeBuffer[NDSDisplayID_Main] = MainDisplay.GetEngine()->nativeBuffer; - _displayInfo.renderedBuffer[NDSDisplayID_Main] = MainDisplay.GetEngine()->renderedBuffer; - _displayInfo.renderedWidth[NDSDisplayID_Main] = MainDisplay.GetEngine()->renderedWidth; - _displayInfo.renderedHeight[NDSDisplayID_Main] = MainDisplay.GetEngine()->renderedHeight; - - _displayInfo.nativeBuffer[NDSDisplayID_Touch] = TouchDisplay.GetEngine()->nativeBuffer; - _displayInfo.renderedBuffer[NDSDisplayID_Touch] = TouchDisplay.GetEngine()->renderedBuffer; - _displayInfo.renderedWidth[NDSDisplayID_Touch] = TouchDisplay.GetEngine()->renderedWidth; - _displayInfo.renderedHeight[NDSDisplayID_Touch] = TouchDisplay.GetEngine()->renderedHeight; - - if (!_displayInfo.isCustomSizeRequested) - { - return; - } - - MainScreen.gpu->isCustomRenderingNeeded = MainScreen.gpu->is3DEnabled; - - // Iterate through VRAM banks A-D and determine if they will be used for this frame. - for (size_t i = 0; i < 4; i++) - { - if (!outProperty.isBlockUsed[i]) - { - continue; - } - - switch (vramConfiguration.banks[i].purpose) - { - case VramConfiguration::ABG: - MainScreen.gpu->UpdateVRAM3DUsageProperties_BGLayer(i, outProperty); - break; - - case VramConfiguration::BBG: - SubScreen.gpu->UpdateVRAM3DUsageProperties_BGLayer(i, outProperty); - break; - - case VramConfiguration::AOBJ: - MainScreen.gpu->UpdateVRAM3DUsageProperties_OBJLayer(i, outProperty); - break; - - case VramConfiguration::BOBJ: - SubScreen.gpu->UpdateVRAM3DUsageProperties_OBJLayer(i, outProperty); - break; - - case VramConfiguration::LCDC: - { - if ((MainScreen.gpu->dispMode == GPUDisplayMode_VRAM) && (MainScreen.gpu->vramBlock == i)) - { - outProperty.blockIndexDisplayVRAM = i; - } - break; - } - - default: - outProperty.isBlockUsed[i] = false; - break; - } - } - - if (MainScreen.gpu->isCustomRenderingNeeded) - { - MainScreen.gpu->renderedWidth = _displayInfo.customWidth; - MainScreen.gpu->renderedHeight = _displayInfo.customHeight; - MainScreen.gpu->renderedBuffer = MainScreen.gpu->customBuffer; - } - - if (SubScreen.gpu->isCustomRenderingNeeded) - { - SubScreen.gpu->renderedWidth = _displayInfo.customWidth; - SubScreen.gpu->renderedHeight = _displayInfo.customHeight; - SubScreen.gpu->renderedBuffer = SubScreen.gpu->customBuffer; - } - - _displayInfo.didPerformCustomRender[NDSDisplayID_Main] = MainDisplay.GetEngine()->isCustomRenderingNeeded; - _displayInfo.renderedBuffer[NDSDisplayID_Main] = MainDisplay.GetEngine()->renderedBuffer; - _displayInfo.renderedWidth[NDSDisplayID_Main] = MainDisplay.GetEngine()->renderedWidth; - _displayInfo.renderedHeight[NDSDisplayID_Main] = MainDisplay.GetEngine()->renderedHeight; - - _displayInfo.didPerformCustomRender[NDSDisplayID_Touch] = TouchDisplay.GetEngine()->isCustomRenderingNeeded; - _displayInfo.renderedBuffer[NDSDisplayID_Touch] = TouchDisplay.GetEngine()->renderedBuffer; - _displayInfo.renderedWidth[NDSDisplayID_Touch] = TouchDisplay.GetEngine()->renderedWidth; - _displayInfo.renderedHeight[NDSDisplayID_Touch] = TouchDisplay.GetEngine()->renderedHeight; -} - -const NDSDisplayInfo& NDS_GetDisplayInfo() -{ - return _displayInfo; -} - u32 GPUEngineBase::getAffineStart(const size_t layer, int xy) { if (xy == 0) @@ -3727,7 +3434,10 @@ void GPUEngineBase::HandleDisplayModeVRAM(u16 *dstLine, const size_t l, const si } else { - if (_gpuVRAM3DUsage.isBlockUsed[MainScreen.gpu->vramBlock] && (_gpuVRAM3DUsage.blockIndexDisplayVRAM == MainScreen.gpu->vramBlock)) + const VRAM3DUsageProperties &vramUsageProperty = GPU->GetVRAM3DUsageProperties(); + const GPUEngineBase *mainEngine = GPU->GetEngineMain(); + + if (vramUsageProperty.isBlockUsed[mainEngine->vramBlock] && (vramUsageProperty.blockIndexDisplayVRAM == mainEngine->vramBlock)) { const u16 *src = this->_VRAMaddrCustom + (_gpuDstLineIndex[l] * dstLineWidth); #ifdef LOCAL_LE @@ -3797,19 +3507,19 @@ void GPUEngineBase::HandleDisplayModeMainMemory(u16 *dstLine, const size_t l, co } } -u32 GPUEngineBase::GetHOFS(const size_t bg) +u32 GPUEngineBase::GetHOFS(const size_t bg) const { return LE_TO_LOCAL_16(dispx_st->dispx_BGxOFS[bg].BGxHOFS) & 0x01FF; } -u32 GPUEngineBase::GetVOFS(const size_t bg) +u32 GPUEngineBase::GetVOFS(const size_t bg) const { return LE_TO_LOCAL_16(dispx_st->dispx_BGxOFS[bg].BGxVOFS) & 0x01FF; } void GPUEngineBase::UpdateBLDALPHA() { - this->_blendTable = (TBlendTable *)&gpuBlendTable555[this->_BLDALPHA_EVA][this->_BLDALPHA_EVB][0][0]; + this->_blendTable = (TBlendTable *)&GPUEngineBase::_blendTable555[this->_BLDALPHA_EVA][this->_BLDALPHA_EVB][0][0]; } void GPUEngineBase::SetBLDALPHA(const u16 val) @@ -3964,7 +3674,7 @@ void GPUEngineBase::SetWINOBJ(const u8 val) this->_WINOBJ_SPECIAL = (((val >> 5) & 1) != 0); } -int GPUEngineBase::GetFinalColorBckFuncID() +int GPUEngineBase::GetFinalColorBckFuncID() const { return this->_finalColorBckFuncID; } @@ -3974,7 +3684,7 @@ void GPUEngineBase::SetFinalColorBckFuncID(int funcID) this->_finalColorBckFuncID = funcID; } -NDSDisplayID GPUEngineBase::GetDisplayByID() +NDSDisplayID GPUEngineBase::GetDisplayByID() const { return this->_targetDisplayID; } @@ -3982,17 +3692,8 @@ NDSDisplayID GPUEngineBase::GetDisplayByID() void GPUEngineBase::SetDisplayByID(const NDSDisplayID theDisplayID) { this->_targetDisplayID = theDisplayID; - - if (theDisplayID == NDSDisplayID_Main) - { - this->nativeBuffer = GPU_NativeFramebuffer; - this->customBuffer = GPU_CustomFramebuffer; - } - else - { - this->nativeBuffer = GPU_NativeFramebuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT); - this->customBuffer = GPU_CustomFramebuffer + (_displayInfo.customWidth * _displayInfo.customHeight); - } + this->nativeBuffer = GPU->GetNativeFramebuffer(theDisplayID); + this->customBuffer = GPU->GetCustomFramebuffer(theDisplayID); } void GPUEngineBase::SetCustomFramebufferSize(size_t w, size_t h) @@ -4004,8 +3705,8 @@ void GPUEngineBase::SetCustomFramebufferSize(size_t w, size_t h) this->workingScanline = newWorkingScanline; this->_bgPixels = newBGPixels; - this->_VRAMaddrCustom = _gpuCustomVRAM + (this->vramBlock * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w); - this->customBuffer = (this->_targetDisplayID == NDSDisplayID_Main) ? GPU_CustomFramebuffer : GPU_CustomFramebuffer + (w * h); + this->_VRAMaddrCustom = GPU->GetCustomVRAMBuffer() + (this->vramBlock * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w); + this->customBuffer = GPU->GetCustomFramebuffer(this->_targetDisplayID); free_aligned(oldWorkingScanline); free_aligned(oldBGPixels); @@ -4013,7 +3714,9 @@ void GPUEngineBase::SetCustomFramebufferSize(size_t w, size_t h) void GPUEngineBase::BlitNativeToCustomFramebuffer() { - if (_displayInfo.didPerformCustomRender[this->_targetDisplayID]) + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); + + if (dispInfo.didPerformCustomRender[this->_targetDisplayID]) { return; } @@ -4032,19 +3735,19 @@ void GPUEngineBase::BlitNativeToCustomFramebuffer() } } - dstLine = dst + _displayInfo.customWidth; + dstLine = dst + dispInfo.customWidth; for (size_t line = 1; line < _gpuDstLineCount[y]; line++) { - memcpy(dstLine, dst, _displayInfo.customWidth * sizeof(u16)); - dstLine += _displayInfo.customWidth; + memcpy(dstLine, dst, dispInfo.customWidth * sizeof(u16)); + dstLine += dispInfo.customWidth; } src += GPU_FRAMEBUFFER_NATIVE_WIDTH; dst = dstLine; } - _displayInfo.didPerformCustomRender[this->_targetDisplayID] = true; + GPU->SetDisplayDidCustomRender(this->_targetDisplayID, true); } // normally should have same addresses @@ -4068,19 +3771,19 @@ void GPUEngineBase::REG_DISPx_pack_test() NDSDisplay::NDSDisplay() { _ID = NDSDisplayID_Main; - SetEngineByID(GPUCOREID_MAIN); + _gpu = NULL; } NDSDisplay::NDSDisplay(const NDSDisplayID displayID) { _ID = displayID; - SetEngineByID(GPUCOREID_MAIN); + _gpu = NULL; } -NDSDisplay::NDSDisplay(const NDSDisplayID displayID, const GPUCoreID coreID) +NDSDisplay::NDSDisplay(const NDSDisplayID displayID, GPUEngineBase *theEngine) { _ID = displayID; - SetEngineByID(coreID); + _gpu = theEngine; } GPUEngineBase* NDSDisplay::GetEngine() @@ -4088,6 +3791,11 @@ GPUEngineBase* NDSDisplay::GetEngine() return this->_gpu; } +void NDSDisplay::SetEngine(GPUEngineBase *theEngine) +{ + this->_gpu = theEngine; +} + GPUCoreID NDSDisplay::GetEngineID() { return this->_gpu->core; @@ -4095,6 +3803,408 @@ GPUCoreID NDSDisplay::GetEngineID() void NDSDisplay::SetEngineByID(const GPUCoreID theID) { - this->_gpu = (theID == GPUCOREID_MAIN) ? &GPU_main : &GPU_sub; + this->_gpu = (theID == GPUCOREID_MAIN) ? GPU->GetEngineMain() : GPU->GetEngineSub(); this->_gpu->SetDisplayByID(this->_ID); } + +GPUSubsystem::GPUSubsystem() +{ + gfx3d_init(); + + _engineMain = new GPUEngineBase(GPUCOREID_MAIN); + _engineSub = new GPUEngineBase(GPUCOREID_SUB); + + _displayMain = new NDSDisplay(NDSDisplayID_Main); + _displayMain->SetEngine(_engineMain); + _displayTouch = new NDSDisplay(NDSDisplayID_Touch); + _displayTouch->SetEngine(_engineSub); + + _willAutoBlitNativeToCustomBuffer = true; + + OSDCLASS *previousOSD = osd; + osd = new OSDCLASS(-1); + delete previousOSD; + + _customVRAM = NULL; + _customVRAMBlank = NULL; + _customFramebuffer = (u16 *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16) * 2); + + ClearWithColor(0x8000); + + _displayInfo.isCustomSizeRequested = false; + _displayInfo.customWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH; + _displayInfo.customHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT; + _displayInfo.masterCustomBuffer = _customFramebuffer; + _displayInfo.masterNativeBuffer = _nativeFramebuffer; + _displayInfo.nativeBuffer[0] = _nativeFramebuffer; + _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); + + _displayInfo.didPerformCustomRender[0] = false; + _displayInfo.didPerformCustomRender[1] = false; + _displayInfo.renderedWidth[0] = GPU_FRAMEBUFFER_NATIVE_WIDTH; + _displayInfo.renderedWidth[1] = GPU_FRAMEBUFFER_NATIVE_WIDTH; + _displayInfo.renderedHeight[0] = GPU_FRAMEBUFFER_NATIVE_HEIGHT; + _displayInfo.renderedHeight[1] = GPU_FRAMEBUFFER_NATIVE_HEIGHT; + _displayInfo.renderedBuffer[0] = _displayInfo.nativeBuffer[0]; + _displayInfo.renderedBuffer[1] = _displayInfo.nativeBuffer[1]; +} + +GPUSubsystem::~GPUSubsystem() +{ + delete osd; + osd = NULL; + + free_aligned(this->_customFramebuffer); + free_aligned(this->_customVRAM); + + free_aligned(_gpuDstToSrcIndex); + _gpuDstToSrcIndex = NULL; + + delete _displayMain; + delete _displayTouch; + delete _engineMain; + delete _engineSub; + + gfx3d_deinit(); +} + +void GPUSubsystem::Reset() +{ + if (this->_customVRAM == NULL || this->_customVRAM == NULL || this->_customFramebuffer == NULL) + { + this->SetCustomFramebufferSize(this->_displayInfo.customWidth, this->_displayInfo.customHeight); + } + + this->ClearWithColor(0xFFFF); + memset(gfx3d_colorRGBA6665, 0, this->_displayInfo.customWidth * this->_displayInfo.customHeight * sizeof(FragmentColor)); + memset(gfx3d_colorRGBA5551, 0, this->_displayInfo.customWidth * this->_displayInfo.customHeight * sizeof(u16)); + + gfx3d_reset(); + this->_engineMain->Reset(); + this->_engineSub->Reset(); + + this->_VRAM3DUsage.blockIndexDisplayVRAM = VRAM_NO_3D_USAGE; + this->_VRAM3DUsage.isBlockUsed[0] = false; + this->_VRAM3DUsage.isBlockUsed[1] = false; + this->_VRAM3DUsage.isBlockUsed[2] = false; + this->_VRAM3DUsage.isBlockUsed[3] = false; + + DISP_FIFOreset(); + osd->clear(); +} + +void GPUSubsystem::UpdateVRAM3DUsageProperties() +{ + this->_VRAM3DUsage.blockIndexDisplayVRAM = VRAM_NO_3D_USAGE; + + this->_engineMain->is3DEnabled = (this->_engineMain->dispCnt().BG0_Enable == 1) && (this->_engineMain->dispCnt().BG0_3D == 1); + this->_engineMain->isCustomRenderingNeeded = false; + this->_engineMain->vramBlockBGIndex = VRAM_NO_3D_USAGE; + this->_engineMain->vramBlockOBJIndex = VRAM_NO_3D_USAGE; + this->_engineMain->vramBGLayer = VRAM_NO_3D_USAGE; + this->_engineMain->renderedWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH; + this->_engineMain->renderedHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT; + this->_engineMain->renderedBuffer = this->_engineMain->nativeBuffer; + + this->_engineSub->is3DEnabled = false; + this->_engineSub->isCustomRenderingNeeded = false; + this->_engineSub->vramBlockBGIndex = VRAM_NO_3D_USAGE; + this->_engineSub->vramBlockOBJIndex = VRAM_NO_3D_USAGE; + this->_engineSub->vramBGLayer = VRAM_NO_3D_USAGE; + this->_engineSub->renderedWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH; + this->_engineSub->renderedHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT; + this->_engineSub->renderedBuffer = this->_engineSub->nativeBuffer; + + this->_displayInfo.didPerformCustomRender[NDSDisplayID_Main] = false; + this->_displayInfo.didPerformCustomRender[NDSDisplayID_Touch] = false; + + this->_displayInfo.nativeBuffer[NDSDisplayID_Main] = this->_displayMain->GetEngine()->nativeBuffer; + this->_displayInfo.renderedBuffer[NDSDisplayID_Main] = this->_displayMain->GetEngine()->renderedBuffer; + this->_displayInfo.renderedWidth[NDSDisplayID_Main] = this->_displayMain->GetEngine()->renderedWidth; + this->_displayInfo.renderedHeight[NDSDisplayID_Main] = this->_displayMain->GetEngine()->renderedHeight; + + this->_displayInfo.nativeBuffer[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->nativeBuffer; + this->_displayInfo.renderedBuffer[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->renderedBuffer; + this->_displayInfo.renderedWidth[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->renderedWidth; + this->_displayInfo.renderedHeight[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->renderedHeight; + + if (!this->_displayInfo.isCustomSizeRequested) + { + return; + } + + this->_engineMain->isCustomRenderingNeeded = this->_engineMain->is3DEnabled; + + // Iterate through VRAM banks A-D and determine if they will be used for this frame. + for (size_t i = 0; i < 4; i++) + { + if (!this->_VRAM3DUsage.isBlockUsed[i]) + { + continue; + } + + switch (vramConfiguration.banks[i].purpose) + { + case VramConfiguration::ABG: + this->_engineMain->UpdateVRAM3DUsageProperties_BGLayer(i, this->_VRAM3DUsage); + break; + + case VramConfiguration::BBG: + this->_engineSub->UpdateVRAM3DUsageProperties_BGLayer(i, this->_VRAM3DUsage); + break; + + case VramConfiguration::AOBJ: + this->_engineMain->UpdateVRAM3DUsageProperties_OBJLayer(i, this->_VRAM3DUsage); + break; + + case VramConfiguration::BOBJ: + this->_engineSub->UpdateVRAM3DUsageProperties_OBJLayer(i, this->_VRAM3DUsage); + break; + + case VramConfiguration::LCDC: + { + if ((this->_engineMain->dispMode == GPUDisplayMode_VRAM) && (this->_engineMain->vramBlock == i)) + { + this->_VRAM3DUsage.blockIndexDisplayVRAM = i; + } + break; + } + + default: + this->_VRAM3DUsage.isBlockUsed[i] = false; + break; + } + } + + if (this->_engineMain->isCustomRenderingNeeded) + { + this->_engineMain->renderedWidth = this->_displayInfo.customWidth; + this->_engineMain->renderedHeight = this->_displayInfo.customHeight; + this->_engineMain->renderedBuffer = this->_engineMain->customBuffer; + } + + if (this->_engineSub->isCustomRenderingNeeded) + { + this->_engineSub->renderedWidth = this->_displayInfo.customWidth; + this->_engineSub->renderedHeight = this->_displayInfo.customHeight; + this->_engineSub->renderedBuffer = this->_engineSub->customBuffer; + } + + this->_displayInfo.didPerformCustomRender[NDSDisplayID_Main] = this->_displayMain->GetEngine()->isCustomRenderingNeeded; + this->_displayInfo.renderedBuffer[NDSDisplayID_Main] = this->_displayMain->GetEngine()->renderedBuffer; + this->_displayInfo.renderedWidth[NDSDisplayID_Main] = this->_displayMain->GetEngine()->renderedWidth; + this->_displayInfo.renderedHeight[NDSDisplayID_Main] = this->_displayMain->GetEngine()->renderedHeight; + + this->_displayInfo.didPerformCustomRender[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->isCustomRenderingNeeded; + this->_displayInfo.renderedBuffer[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->renderedBuffer; + this->_displayInfo.renderedWidth[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->renderedWidth; + this->_displayInfo.renderedHeight[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->renderedHeight; +} + +void GPUSubsystem::ClearWithColor(const u16 colorBGRA5551) +{ + memset_u16(this->_nativeFramebuffer, colorBGRA5551, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2); + memset_u16(this->_customFramebuffer, colorBGRA5551, this->_displayInfo.customWidth * this->_displayInfo.customHeight * 2); +} + +const NDSDisplayInfo& GPUSubsystem::GetDisplayInfo() +{ + return this->_displayInfo; +} + +void GPUSubsystem::SetDisplayDidCustomRender(NDSDisplayID displayID, bool theState) +{ + this->_displayInfo.didPerformCustomRender[displayID] = theState; +} + +GPUEngineBase* GPUSubsystem::GetEngineMain() +{ + return this->_engineMain; +} + +GPUEngineBase* GPUSubsystem::GetEngineSub() +{ + return this->_engineSub; +} + +NDSDisplay* GPUSubsystem::GetDisplayMain() +{ + return this->_displayMain; +} + +NDSDisplay* GPUSubsystem::GetDisplayTouch() +{ + return this->_displayTouch; +} + +u16* GPUSubsystem::GetNativeFramebuffer() +{ + return this->_nativeFramebuffer; +} + +u16* GPUSubsystem::GetNativeFramebuffer(const NDSDisplayID theDisplayID) +{ + return (theDisplayID == NDSDisplayID_Main) ? this->_nativeFramebuffer : this->_nativeFramebuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT); +} + +u16* GPUSubsystem::GetCustomFramebuffer() +{ + return this->_customFramebuffer; +} + +u16* GPUSubsystem::GetCustomFramebuffer(const NDSDisplayID theDisplayID) +{ + return (theDisplayID == NDSDisplayID_Main) ? this->_customFramebuffer : this->_customFramebuffer + (this->_displayInfo.customWidth * this->_displayInfo.customHeight); +} + +size_t GPUSubsystem::GetCustomFramebufferWidth() const +{ + return this->_displayInfo.customWidth; +} + +size_t GPUSubsystem::GetCustomFramebufferHeight() const +{ + return this->_displayInfo.customHeight; +} + +void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h) +{ + if (w < GPU_FRAMEBUFFER_NATIVE_WIDTH || h < GPU_FRAMEBUFFER_NATIVE_HEIGHT) + { + return; + } + + // Check if we're calling this function from initialization. + // If we're not initializing, we need to finish rendering first. + if (gfx3d_colorRGBA6665 != NULL && gfx3d_colorRGBA5551 != NULL) + { + CurrentRenderer->RenderFinish(); + } + + const float customWidthScale = (float)w / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; + const float customHeightScale = (float)h / (float)GPU_FRAMEBUFFER_NATIVE_HEIGHT; + const float newGpuLargestDstLineCount = (size_t)ceilf(customHeightScale); + + u16 *oldCustomFramebuffer = this->_customFramebuffer; + u16 *oldGpuDstToSrcIndexPtr = _gpuDstToSrcIndex; + FragmentColor *oldColorRGBA6665Buffer = gfx3d_colorRGBA6665; + u16 *oldColorRGBA5551Buffer = gfx3d_colorRGBA5551; + u16 *oldCustomVRAM = this->_customVRAM; + + for (size_t srcX = 0, currentPitchCount = 0; srcX < GPU_FRAMEBUFFER_NATIVE_WIDTH; srcX++) + { + const size_t pitch = (size_t)ceilf((srcX+1) * customWidthScale) - currentPitchCount; + _gpuDstPitchCount[srcX] = pitch; + _gpuDstPitchIndex[srcX] = currentPitchCount; + currentPitchCount += pitch; + } + + for (size_t srcY = 0, currentLineCount = 0; srcY < GPU_FRAMEBUFFER_NATIVE_HEIGHT; srcY++) + { + const size_t lineCount = (size_t)ceilf((srcY+1) * customHeightScale) - currentLineCount; + _gpuDstLineCount[srcY] = lineCount; + _gpuDstLineIndex[srcY] = currentLineCount; + currentLineCount += lineCount; + } + + for (size_t srcY = 0, currentLineCount = 0; srcY < GPU_VRAM_BLOCK_LINES + 1; srcY++) + { + const size_t lineCount = (size_t)ceilf((srcY+1) * customHeightScale) - currentLineCount; + _gpuCaptureLineIndex[srcY] = currentLineCount; + currentLineCount += lineCount; + } + + u16 *newGpuDstToSrcIndex = (u16 *)malloc_alignedCacheLine(w * h * sizeof(u16)); + for (size_t y = 0; y < GPU_FRAMEBUFFER_NATIVE_HEIGHT; y++) + { + for (size_t x = 0; x < GPU_FRAMEBUFFER_NATIVE_WIDTH; x++) + { + for (size_t l = 0; l < _gpuDstLineCount[y]; l++) + { + for (size_t p = 0; p < _gpuDstPitchCount[x]; p++) + { + newGpuDstToSrcIndex[((_gpuDstLineIndex[y] + l) * w) + (_gpuDstPitchIndex[x] + p)] = (y * GPU_FRAMEBUFFER_NATIVE_WIDTH) + x; + } + } + } + } + + u16 *newCustomFramebuffer = (u16 *)malloc_alignedCacheLine(w * h * sizeof(u16) * 2); + memset_u16(newCustomFramebuffer, 0x8000, w * h * 2); + + FragmentColor *newColorRGBA6665Buffer = (FragmentColor *)malloc_alignedCacheLine(w * h * sizeof(FragmentColor)); + u16 *newColorRGBA5551 = (u16 *)malloc_alignedCacheLine(w * h * sizeof(u16)); + + const size_t newCustomVRAMBlockSize = _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w; + const size_t newCustomVRAMBlankSize = newGpuLargestDstLineCount * w; + u16 *newCustomVRAM = (u16 *)malloc_alignedCacheLine(((newCustomVRAMBlockSize * 4) + newCustomVRAMBlankSize) * sizeof(u16)); + memset(newCustomVRAM, 0, ((newCustomVRAMBlockSize * 4) + newCustomVRAMBlankSize) * sizeof(u16)); + + _gpuLargestDstLineCount = newGpuLargestDstLineCount; + _gpuVRAMBlockOffset = _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w; + _gpuDstToSrcIndex = newGpuDstToSrcIndex; + this->_customVRAM = newCustomVRAM; + this->_customVRAMBlank = newCustomVRAM + (newCustomVRAMBlockSize * 4); + + this->_customFramebuffer = newCustomFramebuffer; + gfx3d_colorRGBA6665 = newColorRGBA6665Buffer; + gfx3d_colorRGBA5551 = newColorRGBA5551; + + this->_displayInfo.isCustomSizeRequested = ( (w != GPU_FRAMEBUFFER_NATIVE_WIDTH) || (h != GPU_FRAMEBUFFER_NATIVE_HEIGHT) ); + this->_displayInfo.masterCustomBuffer = this->_customFramebuffer; + this->_displayInfo.customWidth = w; + this->_displayInfo.customHeight = h; + this->_displayInfo.customBuffer[NDSDisplayID_Main] = this->_displayMain->GetEngine()->customBuffer; + this->_displayInfo.customBuffer[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->customBuffer; + + this->_engineMain->SetCustomFramebufferSize(w, h); + this->_engineSub->SetCustomFramebufferSize(w, h); + CurrentRenderer->SetFramebufferSize(w, h); + + if (this->_displayInfo.didPerformCustomRender[NDSDisplayID_Main]) + { + this->_displayInfo.renderedBuffer[NDSDisplayID_Main] = this->_displayInfo.customBuffer[NDSDisplayID_Main]; + this->_displayInfo.renderedWidth[NDSDisplayID_Main] = this->_displayInfo.customWidth; + this->_displayInfo.renderedHeight[NDSDisplayID_Main] = this->_displayInfo.customHeight; + } + + if (this->_displayInfo.didPerformCustomRender[NDSDisplayID_Touch]) + { + this->_displayInfo.renderedBuffer[NDSDisplayID_Touch] = this->_displayInfo.customBuffer[NDSDisplayID_Touch]; + this->_displayInfo.renderedWidth[NDSDisplayID_Touch] = this->_displayInfo.customWidth; + this->_displayInfo.renderedHeight[NDSDisplayID_Touch] = this->_displayInfo.customHeight; + } + + free_aligned(oldCustomFramebuffer); + free_aligned(oldGpuDstToSrcIndexPtr); + free_aligned(oldColorRGBA6665Buffer); + free_aligned(oldColorRGBA5551Buffer); + free_aligned(oldCustomVRAM); +} + +u16* GPUSubsystem::GetCustomVRAMBuffer() +{ + return this->_customVRAM; +} + +u16* GPUSubsystem::GetCustomVRAMBlankBuffer() +{ + return this->_customVRAMBlank; +} + +VRAM3DUsageProperties& GPUSubsystem::GetVRAM3DUsageProperties() +{ + return this->_VRAM3DUsage; +} + +bool GPUSubsystem::GetWillAutoBlitNativeToCustomBuffer() const +{ + return this->_willAutoBlitNativeToCustomBuffer; +} + +void GPUSubsystem::SetWillAutoBlitNativeToCustomBuffer(const bool willAutoBlit) +{ + this->_willAutoBlitNativeToCustomBuffer = willAutoBlit; +} diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index e19bae508..72e7bf7eb 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -687,10 +687,36 @@ typedef struct class GPUEngineBase { private: + static CACHE_ALIGN u16 _fadeInColors[17][0x8000]; + static CACHE_ALIGN u16 _fadeOutColors[17][0x8000]; + static CACHE_ALIGN u8 _blendTable555[17][17][32][32]; + + static struct MosaicLookup { + + struct TableEntry { + u8 begin, trunc; + } table[16][256]; + + MosaicLookup() { + for(int m=0;m<16;m++) + for(int i=0;i<256;i++) { + int mosaic = m+1; + TableEntry &te = table[m][i]; + te.begin = (i%mosaic==0); + te.trunc = i/mosaic*mosaic; + } + } + + TableEntry *width, *height; + int widthValue, heightValue; + + } _mosaicLookup; + CACHE_ALIGN u16 _sprColor[GPU_FRAMEBUFFER_NATIVE_WIDTH]; CACHE_ALIGN u8 _sprAlpha[GPU_FRAMEBUFFER_NATIVE_WIDTH]; CACHE_ALIGN u8 _sprType[GPU_FRAMEBUFFER_NATIVE_WIDTH]; CACHE_ALIGN u8 _sprPrio[GPU_FRAMEBUFFER_NATIVE_WIDTH]; + CACHE_ALIGN u8 _sprWin[GPU_FRAMEBUFFER_NATIVE_WIDTH]; bool _enableLayer[5]; itemsForPriority_t _itemsForPriority[NB_PRIORITIES]; @@ -776,6 +802,8 @@ private: u8 _BLDALPHA_EVB; u8 _BLDY_EVY; + void _InitLUTs(); + void _MosaicSpriteLinePixel(const size_t x, u16 l, u16 *dst, u8 *dst_alpha, u8 *typeTab, u8 *prioTab); void _MosaicSpriteLine(u16 l, u16 *dst, u8 *dst_alpha, u8 *typeTab, u8 *prioTab); @@ -831,8 +859,11 @@ public: void SetVideoProp(const u32 ctrlBits); void SetBGProp(const size_t num, const u16 ctrlBits); + void SetDISPCAPCNT(u32 val); - void RenderLine(const u16 l, u16 *dstLine, const size_t dstLineWidth, const size_t dstLineCount); + void RenderLine(const u16 l, bool skip); + void RenderLine_Layer(const u16 l, u16 *dstLine, const size_t dstLineWidth, const size_t dstLineCount); + void RenderLine_MasterBrightness(u16 *dstLine, const size_t dstLineWidth, const size_t dstLineCount); // some structs are becoming redundant // some functions too (no need to recopy some vars as it is done by MMU) @@ -879,33 +910,15 @@ public: bool need_update_winh[2]; - static struct MosaicLookup { - - struct TableEntry { - u8 begin, trunc; - } table[16][256]; - - MosaicLookup() { - for(int m=0;m<16;m++) - for(int i=0;i<256;i++) { - int mosaic = m+1; - TableEntry &te = table[m][i]; - te.begin = (i%mosaic==0); - te.trunc = i/mosaic*mosaic; - } - } - - TableEntry *width, *height; - int widthValue, heightValue; - - } mosaicLookup; - struct AffineInfo { AffineInfo() : x(0), y(0) {} u32 x, y; } affineInfo[2]; - void SetLayerState(const size_t layerIndex, bool theState); + bool GetEnableState(); + void SetEnableState(bool theState); + bool GetLayerEnableState(const size_t layerIndex); + void SetLayerEnableState(const size_t layerIndex, bool theState); template FORCEINLINE void ____setFinalColorBck(const u16 color, const size_t srcX); template FORCEINLINE void __setFinalColorBck(u16 color, const size_t srcX, const bool opaque); @@ -926,8 +939,8 @@ public: void HandleDisplayModeVRAM(u16 *dstLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount); void HandleDisplayModeMainMemory(u16 *dstLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount); - u32 GetHOFS(const size_t bg); - u32 GetVOFS(const size_t bg); + u32 GetHOFS(const size_t bg) const; + u32 GetVOFS(const size_t bg) const; void UpdateBLDALPHA(); void SetBLDALPHA(const u16 val); @@ -964,10 +977,10 @@ public: void SetWINOUT(const u8 val); void SetWINOBJ(const u8 val); - int GetFinalColorBckFuncID(); + int GetFinalColorBckFuncID() const; void SetFinalColorBckFuncID(int funcID); - NDSDisplayID GetDisplayByID(); + NDSDisplayID GetDisplayByID() const; void SetDisplayByID(const NDSDisplayID theDisplayID); void SetCustomFramebufferSize(size_t w, size_t h); @@ -976,31 +989,6 @@ public: void REG_DISPx_pack_test(); }; -extern u16 *GPU_screen; // TODO: Old pointer - need to eliminate direct reference in frontends - -size_t GPU_GetFramebufferWidth(); -size_t GPU_GetFramebufferHeight(); -void GPU_SetFramebufferSize(size_t w, size_t h); - -// Normally, the GPUs will automatically blit their native buffers to the master -// framebuffer at the end of V-blank so that all rendered graphics are contained -// within a single common buffer. This is necessary for when someone wants to read -// the NDS framebuffers, but the reader can only read a single buffer at a time. -// Certain functions, such as taking screenshots, as well as many frontends running -// the NDS video displays, require that they read from only a single buffer. -// -// However, if GPU_SetWillAutoBlitNativeToCustomBuffer() is passed "false", then the -// frontend becomes responsible for calling NDS_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 -// GPU::BlitNativeToCustomFramebuffer() for each GPU before reading the master framebuffer. -bool GPU_GetWillAutoBlitNativeToCustomBuffer(); -void GPU_SetWillAutoBlitNativeToCustomBuffer(const bool willAutoBlit); - -void GPU_UpdateVRAM3DUsageProperties(VRAM3DUsageProperties &outProperty); - -const NDSDisplayInfo& NDS_GetDisplayInfo(); // Frontends need to call this whenever they need to read the video buffers from the emulator core - class NDSDisplay { private: @@ -1010,32 +998,84 @@ private: public: NDSDisplay(); NDSDisplay(const NDSDisplayID displayID); - NDSDisplay(const NDSDisplayID displayID, const GPUCoreID coreID); + NDSDisplay(const NDSDisplayID displayID, GPUEngineBase *theEngine); GPUEngineBase* GetEngine(); + void SetEngine(GPUEngineBase *theEngine); + GPUCoreID GetEngineID(); void SetEngineByID(const GPUCoreID theID); }; -struct NDS_Screen +class GPUSubsystem { - GPUEngineBase *gpu; +private: + GPUEngineBase *_engineMain; + GPUEngineBase *_engineSub; + NDSDisplay *_displayMain; + NDSDisplay *_displayTouch; + + bool _willAutoBlitNativeToCustomBuffer; + VRAM3DUsageProperties _VRAM3DUsage; + u16 *_customVRAM; + u16 *_customVRAMBlank; + + CACHE_ALIGN u16 _nativeFramebuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2]; + u16 *_customFramebuffer; + + NDSDisplayInfo _displayInfo; + +public: + GPUSubsystem(); + ~GPUSubsystem(); + + void Reset(); + VRAM3DUsageProperties& GetVRAM3DUsageProperties(); + const NDSDisplayInfo& GetDisplayInfo(); // Frontends need to call this whenever they need to read the video buffers from the emulator core + void SetDisplayDidCustomRender(NDSDisplayID displayID, bool theState); + + GPUEngineBase* GetEngineMain(); + GPUEngineBase* GetEngineSub(); + NDSDisplay* GetDisplayMain(); + NDSDisplay* GetDisplayTouch(); + + u16* GetNativeFramebuffer(); + u16* GetNativeFramebuffer(const NDSDisplayID theDisplayID); + u16* GetCustomFramebuffer(); + u16* GetCustomFramebuffer(const NDSDisplayID theDisplayID); + + u16* GetCustomVRAMBuffer(); + u16* GetCustomVRAMBlankBuffer(); + + size_t GetCustomFramebufferWidth() const; + size_t GetCustomFramebufferHeight() const; + void SetCustomFramebufferSize(size_t w, size_t h); + + void UpdateVRAM3DUsageProperties(); + + // Normally, the GPUs will automatically blit their native buffers to the master + // framebuffer at the end of V-blank so that all rendered graphics are contained + // within a single common buffer. This is necessary for when someone wants to read + // the NDS framebuffers, but the reader can only read a single buffer at a time. + // Certain functions, such as taking screenshots, as well as many frontends running + // the NDS video displays, require that they read from only a single buffer. + // + // However, if SetWillAutoBlitNativeToCustomBuffer() is passed "false", then the + // 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 + // master framebuffer. + bool GetWillAutoBlitNativeToCustomBuffer() const; + void SetWillAutoBlitNativeToCustomBuffer(const bool willAutoBlit); + + void RenderLine(const u16 l, bool skip = false); + void ClearWithColor(const u16 colorBGRA5551); }; -extern NDS_Screen MainScreen; -extern NDS_Screen SubScreen; -extern NDSDisplay MainDisplay; -extern NDSDisplay TouchDisplay; - -int Screen_Init(); -void Screen_Reset(void); -void Screen_DeInit(void); - +extern GPUSubsystem *GPU; extern MMU_struct MMU; -void GPU_set_DISPCAPCNT(u32 val); -void GPU_RenderLine(NDS_Screen *screen, const u16 l, bool skip = false); - inline FragmentColor MakeFragmentColor(const u8 r, const u8 g, const u8 b, const u8 a) { FragmentColor ret; diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index f8b9d3931..9b53c8fb0 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -1848,14 +1848,14 @@ static void writereg_POWCNT1(const int size, const u32 adr, const u32 val) { if(nds.power1.dispswap) { //printf("Main core on top (vcount=%d)\n",nds.VCount); - MainDisplay.SetEngineByID(GPUCOREID_MAIN); - TouchDisplay.SetEngineByID(GPUCOREID_SUB); + GPU->GetDisplayMain()->SetEngineByID(GPUCOREID_MAIN); + GPU->GetDisplayTouch()->SetEngineByID(GPUCOREID_SUB); } else { //printf("Main core on bottom (vcount=%d)\n",nds.VCount); - MainDisplay.SetEngineByID(GPUCOREID_SUB); - TouchDisplay.SetEngineByID(GPUCOREID_MAIN); + GPU->GetDisplayMain()->SetEngineByID(GPUCOREID_SUB); + GPU->GetDisplayTouch()->SetEngineByID(GPUCOREID_MAIN); } break; } @@ -3285,7 +3285,10 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) MMU_new.write_dma(ARMCPU_ARM9,8,adr,val); return; } - + + GPUEngineBase *mainEngine = GPU->GetEngineMain(); + GPUEngineBase *subEngine = GPU->GetEngineSub(); + switch(adr) { case REG_SQRTCNT: printf("ERROR 8bit SQRTCNT WRITE\n"); return; @@ -3326,116 +3329,116 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) break; case REG_DISPA_WIN0H: - MainScreen.gpu->SetWIN0_H1(val); + mainEngine->SetWIN0_H1(val); break ; case REG_DISPA_WIN0H+1: - MainScreen.gpu->SetWIN0_H0(val); + mainEngine->SetWIN0_H0(val); break ; case REG_DISPA_WIN1H: - MainScreen.gpu->SetWIN1_H1(val); + mainEngine->SetWIN1_H1(val); break ; case REG_DISPA_WIN1H+1: - MainScreen.gpu->SetWIN1_H0(val); + mainEngine->SetWIN1_H0(val); break ; case REG_DISPB_WIN0H: - SubScreen.gpu->SetWIN0_H1(val); + subEngine->SetWIN0_H1(val); break ; case REG_DISPB_WIN0H+1: - SubScreen.gpu->SetWIN0_H0(val); + subEngine->SetWIN0_H0(val); break ; case REG_DISPB_WIN1H: - SubScreen.gpu->SetWIN1_H1(val); + subEngine->SetWIN1_H1(val); break ; case REG_DISPB_WIN1H+1: - SubScreen.gpu->SetWIN1_H0(val); + subEngine->SetWIN1_H0(val); break ; case REG_DISPA_WIN0V: - MainScreen.gpu->SetWIN0_V1(val) ; + mainEngine->SetWIN0_V1(val) ; break ; case REG_DISPA_WIN0V+1: - MainScreen.gpu->SetWIN0_V0(val) ; + mainEngine->SetWIN0_V0(val) ; break ; case REG_DISPA_WIN1V: - MainScreen.gpu->SetWIN1_V1(val) ; + mainEngine->SetWIN1_V1(val) ; break ; case REG_DISPA_WIN1V+1: - MainScreen.gpu->SetWIN1_V0(val) ; + mainEngine->SetWIN1_V0(val) ; break ; case REG_DISPB_WIN0V: - SubScreen.gpu->SetWIN0_V1(val); + subEngine->SetWIN0_V1(val); break ; case REG_DISPB_WIN0V+1: - SubScreen.gpu->SetWIN0_V0(val); + subEngine->SetWIN0_V0(val); break ; case REG_DISPB_WIN1V: - SubScreen.gpu->SetWIN1_V1(val); + subEngine->SetWIN1_V1(val); break ; case REG_DISPB_WIN1V+1: - SubScreen.gpu->SetWIN1_V0(val); + subEngine->SetWIN1_V0(val); break ; case REG_DISPA_WININ: - MainScreen.gpu->SetWININ0(val); + mainEngine->SetWININ0(val); break ; case REG_DISPA_WININ+1: - MainScreen.gpu->SetWININ1(val); + mainEngine->SetWININ1(val); break ; case REG_DISPA_WINOUT: - MainScreen.gpu->SetWINOUT(val); + mainEngine->SetWINOUT(val); break ; case REG_DISPA_WINOUT+1: - MainScreen.gpu->SetWINOBJ(val); + mainEngine->SetWINOBJ(val); break ; case REG_DISPB_WININ: - SubScreen.gpu->SetWININ0(val); + subEngine->SetWININ0(val); break ; case REG_DISPB_WININ+1: - SubScreen.gpu->SetWININ1(val); + subEngine->SetWININ1(val); break ; case REG_DISPB_WINOUT: - SubScreen.gpu->SetWINOUT(val); + subEngine->SetWINOUT(val); break ; case REG_DISPB_WINOUT+1: - SubScreen.gpu->SetWINOBJ(val); + subEngine->SetWINOBJ(val); break ; case REG_DISPA_BLDCNT: - MainScreen.gpu->SetBLDCNT_HIGH(val); + mainEngine->SetBLDCNT_HIGH(val); break; case REG_DISPA_BLDCNT+1: - MainScreen.gpu->SetBLDCNT_LOW(val); + mainEngine->SetBLDCNT_LOW(val); break; case REG_DISPB_BLDCNT: - SubScreen.gpu->SetBLDCNT_HIGH(val); + subEngine->SetBLDCNT_HIGH(val); break; case REG_DISPB_BLDCNT+1: - SubScreen.gpu->SetBLDCNT_LOW(val); + subEngine->SetBLDCNT_LOW(val); break; case REG_DISPA_BLDALPHA: - MainScreen.gpu->SetBLDALPHA_EVA(val); + mainEngine->SetBLDALPHA_EVA(val); break; case REG_DISPA_BLDALPHA+1: - MainScreen.gpu->SetBLDALPHA_EVB(val); + mainEngine->SetBLDALPHA_EVB(val); break; case REG_DISPB_BLDALPHA: - SubScreen.gpu->SetBLDALPHA_EVA(val); + subEngine->SetBLDALPHA_EVA(val); break; case REG_DISPB_BLDALPHA+1: - SubScreen.gpu->SetBLDALPHA_EVB(val); + subEngine->SetBLDALPHA_EVB(val); break; case REG_DISPA_BLDY: - MainScreen.gpu->SetBLDY_EVY(val); + mainEngine->SetBLDY_EVY(val); break ; case REG_DISPB_BLDY: - SubScreen.gpu->SetBLDY_EVY(val); + subEngine->SetBLDY_EVY(val); break; case REG_AUXSPICNT: @@ -3569,6 +3572,10 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) gfx3d_UpdateToonTable((adr & 0x3F) >> 1, val); return; } + + GPUEngineBase *mainEngine = GPU->GetEngineMain(); + GPUEngineBase *subEngine = GPU->GetEngineSub(); + // Address is an IO register switch(adr) { @@ -3584,22 +3591,22 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) val &= 0x7F7F; break; - 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_BG2XL: mainEngine->setAffineStartWord(2,0,val,0); break; + case REG_DISPA_BG2XH: mainEngine->setAffineStartWord(2,0,val,1); break; + case REG_DISPA_BG2YL: mainEngine->setAffineStartWord(2,1,val,0); break; + case REG_DISPA_BG2YH: mainEngine->setAffineStartWord(2,1,val,1); break; + case REG_DISPA_BG3XL: mainEngine->setAffineStartWord(3,0,val,0); break; + case REG_DISPA_BG3XH: mainEngine->setAffineStartWord(3,0,val,1); break; + case REG_DISPA_BG3YL: mainEngine->setAffineStartWord(3,1,val,0); break; + case REG_DISPA_BG3YH: mainEngine->setAffineStartWord(3,1,val,1); break; + case REG_DISPB_BG2XL: subEngine->setAffineStartWord(2,0,val,0); break; + case REG_DISPB_BG2XH: subEngine->setAffineStartWord(2,0,val,1); break; + case REG_DISPB_BG2YL: subEngine->setAffineStartWord(2,1,val,0); break; + case REG_DISPB_BG2YH: subEngine->setAffineStartWord(2,1,val,1); break; + case REG_DISPB_BG3XL: subEngine->setAffineStartWord(3,0,val,0); break; + case REG_DISPB_BG3XH: subEngine->setAffineStartWord(3,0,val,1); break; + case REG_DISPB_BG3YL: subEngine->setAffineStartWord(3,1,val,0); break; + case REG_DISPB_BG3YH: subEngine->setAffineStartWord(3,1,val,1); break; case REG_DISPA_DISP3DCNT: writereg_DISP3DCNT(16,adr,val); return; @@ -3661,25 +3668,25 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) return; case REG_DISPA_BLDCNT: - MainScreen.gpu->SetBLDCNT(val); + mainEngine->SetBLDCNT(val); break ; case REG_DISPB_BLDCNT: - SubScreen.gpu->SetBLDCNT(val); + subEngine->SetBLDCNT(val); break ; case REG_DISPA_BLDALPHA: - MainScreen.gpu->SetBLDALPHA(val); + mainEngine->SetBLDALPHA(val); break ; case REG_DISPB_BLDALPHA: - SubScreen.gpu->SetBLDALPHA(val); + subEngine->SetBLDALPHA(val); break ; case REG_DISPA_BLDY: - MainScreen.gpu->SetBLDY_EVY(val); + mainEngine->SetBLDY_EVY(val); break ; case REG_DISPB_BLDY: - SubScreen.gpu->SetBLDY_EVY(val); + subEngine->SetBLDY_EVY(val); break; case REG_DISPA_MASTERBRIGHT: - MainScreen.gpu->SetMasterBrightness(val); + mainEngine->SetMasterBrightness(val); break; /* case REG_DISPA_MOSAIC: @@ -3715,34 +3722,34 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) // break; case REG_DISPA_WIN0H: - MainScreen.gpu->SetWIN0_H(val); + mainEngine->SetWIN0_H(val); break ; case REG_DISPA_WIN1H: - MainScreen.gpu->SetWIN1_H(val); + mainEngine->SetWIN1_H(val); break ; case REG_DISPB_WIN0H: - SubScreen.gpu->SetWIN0_H(val); + subEngine->SetWIN0_H(val); break ; case REG_DISPB_WIN1H: - SubScreen.gpu->SetWIN1_H(val); + subEngine->SetWIN1_H(val); break ; case REG_DISPA_WIN0V: - MainScreen.gpu->SetWIN0_V(val); + mainEngine->SetWIN0_V(val); break ; case REG_DISPA_WIN1V: - MainScreen.gpu->SetWIN1_V(val); + mainEngine->SetWIN1_V(val); break ; case REG_DISPB_WIN0V: - SubScreen.gpu->SetWIN0_V(val); + subEngine->SetWIN0_V(val); break ; case REG_DISPB_WIN1V: - SubScreen.gpu->SetWIN1_V(val); + subEngine->SetWIN1_V(val); break ; case REG_DISPA_WININ: - MainScreen.gpu->SetWININ(val); + mainEngine->SetWININ(val); break ; case REG_DISPA_WINOUT: - MainScreen.gpu->SetWINOUT16(val); + mainEngine->SetWINOUT16(val); break ; /* case REG_DISPB_BG0HOFS: @@ -3771,14 +3778,14 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) break;*/ case REG_DISPB_WININ: - SubScreen.gpu->SetWININ(val); + subEngine->SetWININ(val); break ; case REG_DISPB_WINOUT: - SubScreen.gpu->SetWINOUT16(val); + subEngine->SetWINOUT16(val); break ; case REG_DISPB_MASTERBRIGHT: - SubScreen.gpu->SetMasterBrightness(val); + subEngine->SetMasterBrightness(val); break; case REG_POWCNT1: @@ -3808,42 +3815,42 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) case REG_DISPA_BG0CNT : //GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val); - MainScreen.gpu->SetBGProp(0, val); + mainEngine->SetBGProp(0, val); T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x8, val); return; case REG_DISPA_BG1CNT : //GPULOG("MAIN BG1 SETPROP 16B %08X\r\n", val); - MainScreen.gpu->SetBGProp(1, val); + mainEngine->SetBGProp(1, val); T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xA, val); return; case REG_DISPA_BG2CNT : //GPULOG("MAIN BG2 SETPROP 16B %08X\r\n", val); - MainScreen.gpu->SetBGProp(2, val); + mainEngine->SetBGProp(2, val); T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC, val); return; case REG_DISPA_BG3CNT : //GPULOG("MAIN BG3 SETPROP 16B %08X\r\n", val); - MainScreen.gpu->SetBGProp(3, val); + mainEngine->SetBGProp(3, val); T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xE, val); return; case REG_DISPB_BG0CNT : //GPULOG("SUB BG0 SETPROP 16B %08X\r\n", val); - SubScreen.gpu->SetBGProp(0, val); + subEngine->SetBGProp(0, val); T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1008, val); return; case REG_DISPB_BG1CNT : //GPULOG("SUB BG1 SETPROP 16B %08X\r\n", val); - SubScreen.gpu->SetBGProp(1, val); + subEngine->SetBGProp(1, val); T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x100A, val); return; case REG_DISPB_BG2CNT : //GPULOG("SUB BG2 SETPROP 16B %08X\r\n", val); - SubScreen.gpu->SetBGProp(2, val); + subEngine->SetBGProp(2, val); T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x100C, val); return; case REG_DISPB_BG3CNT : //GPULOG("SUB BG3 SETPROP 16B %08X\r\n", val); - SubScreen.gpu->SetBGProp(3, val); + subEngine->SetBGProp(3, val); T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x100E, val); return; @@ -3898,28 +3905,28 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) case REG_DISPA_DISPCNT : { u32 v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0) & 0xFFFF0000) | val; - MainScreen.gpu->SetVideoProp(v); + mainEngine->SetVideoProp(v); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0, v); return; } case REG_DISPA_DISPCNT+2 : { u32 v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0) & 0xFFFF) | ((u32) val << 16); - MainScreen.gpu->SetVideoProp(v); + mainEngine->SetVideoProp(v); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0, v); } return; case REG_DISPA_DISPCAPCNT : { u32 v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64) & 0xFFFF0000) | val; - GPU_set_DISPCAPCNT(v); + mainEngine->SetDISPCAPCNT(v); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64, v); return; } case REG_DISPA_DISPCAPCNT + 2: { u32 v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64) & 0xFFFF) | ((u32)val << 16); - GPU_set_DISPCAPCNT(v); + mainEngine->SetDISPCAPCNT(v); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64, v); return; } @@ -3927,7 +3934,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) case REG_DISPB_DISPCNT : { u32 v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000) & 0xFFFF0000) | val; - SubScreen.gpu->SetVideoProp(v); + subEngine->SetVideoProp(v); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000, v); return; } @@ -3935,7 +3942,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) { //emu_halt(); u32 v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000) & 0xFFFF) | ((u32) val << 16); - SubScreen.gpu->SetVideoProp(v); + subEngine->SetVideoProp(v); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000, v); return; } @@ -4083,6 +4090,9 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) MMU_new.write_dma(ARMCPU_ARM9,32,adr,val); return; } + + GPUEngineBase *mainEngine = GPU->GetEngineMain(); + GPUEngineBase *subEngine = GPU->GetEngineSub(); switch(adr) { @@ -4123,28 +4133,28 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) MMU_new.gxstat.write32(val); break; case REG_DISPA_BG2XL: - MainScreen.gpu->setAffineStart(2,0,val); + mainEngine->setAffineStart(2,0,val); return; case REG_DISPA_BG2YL: - MainScreen.gpu->setAffineStart(2,1,val); + mainEngine->setAffineStart(2,1,val); return; case REG_DISPB_BG2XL: - SubScreen.gpu->setAffineStart(2,0,val); + subEngine->setAffineStart(2,0,val); return; case REG_DISPB_BG2YL: - SubScreen.gpu->setAffineStart(2,1,val); + subEngine->setAffineStart(2,1,val); return; case REG_DISPA_BG3XL: - MainScreen.gpu->setAffineStart(3,0,val); + mainEngine->setAffineStart(3,0,val); return; case REG_DISPA_BG3YL: - MainScreen.gpu->setAffineStart(3,1,val); + mainEngine->setAffineStart(3,1,val); return; case REG_DISPB_BG3XL: - SubScreen.gpu->setAffineStart(3,0,val); + subEngine->setAffineStart(3,0,val); return; case REG_DISPB_BG3YL: - SubScreen.gpu->setAffineStart(3,1,val); + subEngine->setAffineStart(3,1,val); return; // Alpha test reference value - Parameters:1 @@ -4187,77 +4197,77 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) case REG_DISPA_WININ: { - MainScreen.gpu->SetWININ(val & 0xFFFF) ; - MainScreen.gpu->SetWINOUT16((val >> 16) & 0xFFFF) ; + mainEngine->SetWININ(val & 0xFFFF) ; + mainEngine->SetWINOUT16((val >> 16) & 0xFFFF) ; break; } case REG_DISPB_WININ: { - SubScreen.gpu->SetWININ(val & 0xFFFF) ; - SubScreen.gpu->SetWINOUT16((val >> 16) & 0xFFFF) ; + subEngine->SetWININ(val & 0xFFFF) ; + subEngine->SetWINOUT16((val >> 16) & 0xFFFF) ; break; } case REG_DISPA_WIN0H: { - MainScreen.gpu->SetWIN0_H(val & 0xFFFF); - MainScreen.gpu->SetWIN1_H(val >> 16); + mainEngine->SetWIN0_H(val & 0xFFFF); + mainEngine->SetWIN1_H(val >> 16); break; } case REG_DISPA_WIN0V: { - MainScreen.gpu->SetWIN0_V(val & 0xFFFF); - MainScreen.gpu->SetWIN1_V(val >> 16); + mainEngine->SetWIN0_V(val & 0xFFFF); + mainEngine->SetWIN1_V(val >> 16); break; } case REG_DISPB_WIN0H: { - SubScreen.gpu->SetWIN0_H(val & 0xFFFF); - SubScreen.gpu->SetWIN1_H(val >> 16); + subEngine->SetWIN0_H(val & 0xFFFF); + subEngine->SetWIN1_H(val >> 16); break; } case REG_DISPB_WIN0V: { - SubScreen.gpu->SetWIN0_V(val & 0xFFFF); - SubScreen.gpu->SetWIN1_V(val >> 16); + subEngine->SetWIN0_V(val & 0xFFFF); + subEngine->SetWIN1_V(val >> 16); break; } case REG_DISPA_MASTERBRIGHT: - MainScreen.gpu->SetMasterBrightness(val & 0xFFFF); + mainEngine->SetMasterBrightness(val & 0xFFFF); break; case REG_DISPB_MASTERBRIGHT: - SubScreen.gpu->SetMasterBrightness(val & 0xFFFF); + subEngine->SetMasterBrightness(val & 0xFFFF); break; case REG_DISPA_BLDCNT: { - MainScreen.gpu->SetBLDCNT(val & 0xFFFF); - MainScreen.gpu->SetBLDALPHA(val >> 16); + mainEngine->SetBLDCNT(val & 0xFFFF); + mainEngine->SetBLDALPHA(val >> 16); break; } case REG_DISPB_BLDCNT: { - SubScreen.gpu->SetBLDCNT(val & 0xFFFF); - SubScreen.gpu->SetBLDALPHA(val >> 16); + subEngine->SetBLDCNT(val & 0xFFFF); + subEngine->SetBLDALPHA(val >> 16); break; } case REG_DISPA_BLDY: - MainScreen.gpu->SetBLDY_EVY(val & 0xFFFF); + mainEngine->SetBLDY_EVY(val & 0xFFFF); break ; case REG_DISPB_BLDY: - SubScreen.gpu->SetBLDY_EVY(val & 0xFFFF); + subEngine->SetBLDY_EVY(val & 0xFFFF); break; case REG_DISPA_DISPCNT : - MainScreen.gpu->SetVideoProp(val); + mainEngine->SetVideoProp(val); //GPULOG("MAIN INIT 32B %08X\r\n", val); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0, val); return; case REG_DISPB_DISPCNT : - SubScreen.gpu->SetVideoProp(val); + subEngine->SetVideoProp(val); //GPULOG("SUB INIT 32B %08X\r\n", val); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000, val); return; @@ -4348,29 +4358,29 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) return; case REG_DISPA_DISPCAPCNT : //INFO("MMU write32: REG_DISPA_DISPCAPCNT 0x%X\n", val); - GPU_set_DISPCAPCNT(val); + mainEngine->SetDISPCAPCNT(val); T1WriteLong(MMU.ARM9_REG, 0x64, val); return; case REG_DISPA_BG0CNT : - MainScreen.gpu->SetBGProp(0, (val & 0xFFFF)); - MainScreen.gpu->SetBGProp(1, (val >> 16)); + mainEngine->SetBGProp(0, (val & 0xFFFF)); + mainEngine->SetBGProp(1, (val >> 16)); //if((val>>16)==0x400) emu_halt(); T1WriteLong(MMU.ARM9_REG, 8, val); return; case REG_DISPA_BG2CNT : - MainScreen.gpu->SetBGProp(2, (val & 0xFFFF)); - MainScreen.gpu->SetBGProp(3, (val >> 16)); + mainEngine->SetBGProp(2, (val & 0xFFFF)); + mainEngine->SetBGProp(3, (val >> 16)); T1WriteLong(MMU.ARM9_REG, 0xC, val); return; case REG_DISPB_BG0CNT : - SubScreen.gpu->SetBGProp(0, (val & 0xFFFF)); - SubScreen.gpu->SetBGProp(1, (val >> 16)); + subEngine->SetBGProp(0, (val & 0xFFFF)); + subEngine->SetBGProp(1, (val >> 16)); T1WriteLong(MMU.ARM9_REG, 0x1008, val); return; case REG_DISPB_BG2CNT : - SubScreen.gpu->SetBGProp(2, (val & 0xFFFF)); - SubScreen.gpu->SetBGProp(3, (val >> 16)); + subEngine->SetBGProp(2, (val & 0xFFFF)); + subEngine->SetBGProp(3, (val >> 16)); T1WriteLong(MMU.ARM9_REG, 0x100C, val); return; case REG_DISPA_DISPMMEMFIFO: diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 88dd48c41..2b32fd92d 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -146,10 +146,7 @@ int NDS_Init() //got to print this somewhere.. printf("%s\n", EMU_DESMUME_NAME_AND_VERSION()); - - if (Screen_Init() != 0) - return -1; - + { char buf[MAX_PATH]; memset(buf, 0, MAX_PATH); @@ -171,6 +168,13 @@ int NDS_Init() NDS_ARM7.SetBaseMemoryInterfaceData(NULL); NDS_ARM7.ResetMemoryInterfaceToBase(); + if (GPU != NULL) + { + delete GPU; + } + + GPU = new GPUSubsystem; + if (SPU_Init(SNDCORE_DUMMY, 740) != 0) return -1; @@ -186,7 +190,10 @@ void NDS_DeInit(void) { gameInfo.closeROM(); SPU_DeInit(); - Screen_DeInit(); + + delete GPU; + GPU = NULL; + MMU_DeInit(); WIFI_DeInit(); @@ -787,7 +794,8 @@ public: } void Advance() { - bool capturing = (MainScreen.gpu->dispCapCnt.enabled || (MainScreen.gpu->dispCapCnt.val & 0x80000000)); + const GPUEngineBase *mainEngine = GPU->GetEngineMain(); + bool capturing = (mainEngine->dispCapCnt.enabled || (mainEngine->dispCapCnt.val & 0x80000000)); if(capturing && consecutiveNonCaptures > 30) { @@ -798,7 +806,7 @@ public: SkipNext2DFrame = false; nextSkip = false; } - else if((lastDisplayTarget != MainScreen.gpu->GetDisplayByID()) && lastSkip && !skipped) + else if((lastDisplayTarget != mainEngine->GetDisplayByID()) && lastSkip && !skipped) { // if we're switching from not skipping to skipping // and the screens are also switching around this frame, @@ -813,7 +821,7 @@ public: else if(!(consecutiveNonCaptures > 9000)) // arbitrary cap to avoid eventual wrap consecutiveNonCaptures++; - lastDisplayTarget = MainScreen.gpu->GetDisplayByID(); + lastDisplayTarget = mainEngine->GetDisplayByID(); lastSkip = skipped; skipped = nextSkip; nextSkip = false; @@ -1258,15 +1266,6 @@ void Sequencer::init() #endif } -//this isnt helping much right now. work on it later -//#include "utils/task.h" -//Task taskSubGpu(true); -//void* renderSubScreen(void*) -//{ -// GPU_RenderLine(&SubScreen, nds.VCount, SkipCur2DFrame); -// return NULL; -//} - static void execHardware_hblank() { //this logic keeps moving around. @@ -1276,11 +1275,8 @@ static void execHardware_hblank() //scroll regs for the next scanline if(nds.VCount<192) { - //taskSubGpu.execute(renderSubScreen,NULL); - GPU_RenderLine(&MainScreen, nds.VCount, frameSkipper.ShouldSkip2D()); - GPU_RenderLine(&SubScreen, nds.VCount, frameSkipper.ShouldSkip2D()); - //taskSubGpu.finish(); - + GPU->RenderLine(nds.VCount, frameSkipper.ShouldSkip2D()); + //trigger hblank dmas //but notice, we do that just after we finished drawing the line //(values copied by this hdma should not be used until the next scanline) @@ -1330,10 +1326,10 @@ static void execHardware_hstart_vblankEnd() //some emulation housekeeping frameSkipper.Advance(); - if (GPU_GetWillAutoBlitNativeToCustomBuffer()) + if (GPU->GetWillAutoBlitNativeToCustomBuffer()) { - MainScreen.gpu->BlitNativeToCustomFramebuffer(); - SubScreen.gpu->BlitNativeToCustomFramebuffer(); + GPU->GetEngineMain()->BlitNativeToCustomFramebuffer(); + GPU->GetEngineSub()->BlitNativeToCustomFramebuffer(); } } @@ -2533,7 +2529,7 @@ void NDS_Reset() // Init calibration info memcpy(&TSCal, firmware->getTouchCalibrate(), sizeof(TSCalInfo)); - Screen_Reset(); + GPU->Reset(); WIFI_Reset(); memcpy(FW_Mac, (MMU.fw.data + 0x36), 6); @@ -2903,15 +2899,15 @@ void NDS_suspendProcessingInput(bool suspend) void NDS_swapScreen() { - if (MainDisplay.GetEngineID() == GPUCOREID_MAIN) + if (GPU->GetDisplayMain()->GetEngineID() == GPUCOREID_MAIN) { - MainDisplay.SetEngineByID(GPUCOREID_SUB); - TouchDisplay.SetEngineByID(GPUCOREID_MAIN); + GPU->GetDisplayMain()->SetEngineByID(GPUCOREID_SUB); + GPU->GetDisplayTouch()->SetEngineByID(GPUCOREID_MAIN); } else { - MainDisplay.SetEngineByID(GPUCOREID_MAIN); - TouchDisplay.SetEngineByID(GPUCOREID_SUB); + GPU->GetDisplayMain()->SetEngineByID(GPUCOREID_MAIN); + GPU->GetDisplayTouch()->SetEngineByID(GPUCOREID_SUB); } } diff --git a/desmume/src/cli/main.cpp b/desmume/src/cli/main.cpp index bfaf5c7a6..6404a8b17 100644 --- a/desmume/src/cli/main.cpp +++ b/desmume/src/cli/main.cpp @@ -371,6 +371,7 @@ resizeWindow( u16 width, u16 height, GLuint *screen_texture) { static void opengl_Draw( GLuint *texture, int software_convert) { GLenum errCode; + u16 *gpuFramebuffer = GPU->GetNativeFramebuffer(); /* Clear The Screen And The Depth Buffer */ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); @@ -385,9 +386,9 @@ opengl_Draw( GLuint *texture, int software_convert) { u8 converted[256 * 384 * 3]; for ( i = 0; i < (256 * 384); i++) { - converted[(i * 3) + 0] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 0) & 0x1f) << 3; - converted[(i * 3) + 1] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 5) & 0x1f) << 3; - converted[(i * 3) + 2] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 10) & 0x1f) << 3; + converted[(i * 3) + 0] = ((gpuFramebuffer[i] >> 0) & 0x1f) << 3; + converted[(i * 3) + 1] = ((gpuFramebuffer[i] >> 5) & 0x1f) << 3; + converted[(i * 3) + 2] = ((gpuFramebuffer[i] >> 10) & 0x1f) << 3; } glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384, @@ -399,7 +400,7 @@ opengl_Draw( GLuint *texture, int software_convert) { glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, - &GPU_screen); + gpuFramebuffer); } if ((errCode = glGetError()) != GL_NO_ERROR) { @@ -445,7 +446,7 @@ static void Draw( void) { SDL_Surface *rawImage; - rawImage = SDL_CreateRGBSurfaceFrom((void*)&GPU_screen, 256, 384, 16, 512, 0x001F, 0x03E0, 0x7C00, 0); + rawImage = SDL_CreateRGBSurfaceFrom((void*)GPU->GetNativeFramebuffer(), 256, 384, 16, 512, 0x001F, 0x03E0, 0x7C00, 0); if(rawImage == NULL) return; SDL_BlitSurface(rawImage, 0, surface, 0); @@ -488,7 +489,7 @@ static void desmume_cycle(struct ctrls_event_config * cfg) } #ifdef HAVE_LIBAGG -T_AGG_RGB555 agg_targetScreen_cli((u8 *)GPU_screen, 256, 384, 512); +T_AGG_RGB555 agg_targetScreen_cli((u8 *)GPU->GetNativeFramebuffer(), 256, 384, 512); #endif int main(int argc, char ** argv) { diff --git a/desmume/src/cocoa/cocoa_GPU.h b/desmume/src/cocoa/cocoa_GPU.h index 505950ff4..97f47990b 100644 --- a/desmume/src/cocoa/cocoa_GPU.h +++ b/desmume/src/cocoa/cocoa_GPU.h @@ -19,13 +19,6 @@ #include #include -enum GPUType -{ - DS_GPU_TYPE_MAIN = 0, - DS_GPU_TYPE_SUB, - DS_GPU_TYPE_MAIN_AND_SUB -}; - @interface CocoaDSGPU : NSObject { UInt32 gpuStateFlags; @@ -66,11 +59,8 @@ enum GPUType @property (assign) BOOL render3DFragmentSamplingHack; - (BOOL) gpuStateByBit:(const UInt32)stateBit; -- (BOOL) isGPUTypeDisplayed:(const NSInteger)theGpuType; -- (void) hideGPUType:(const NSInteger)theGpuType; -- (void) showGPUType:(const NSInteger)theGpuType; - - (NSString *) render3DRenderingEngineString; +- (void) clearWithColor:(const uint16_t)colorBGRA5551; @end @@ -79,12 +69,6 @@ extern "C" { #endif -void GPU_FillScreenWithBGRA5551(const uint16_t colorValue); -void SetGPULayerState(const GPUType gpuType, const unsigned int i, const bool state); -bool GetGPULayerState(const GPUType gpuType, const unsigned int i); -void SetGPUDisplayState(const GPUType gpuType, const bool state); -bool GetGPUDisplayState(const GPUType gpuType); - bool OSXOpenGLRendererInit(); bool OSXOpenGLRendererBegin(); void OSXOpenGLRendererEnd(); diff --git a/desmume/src/cocoa/cocoa_GPU.mm b/desmume/src/cocoa/cocoa_GPU.mm index 7eb97d19b..c913585c5 100644 --- a/desmume/src/cocoa/cocoa_GPU.mm +++ b/desmume/src/cocoa/cocoa_GPU.mm @@ -104,8 +104,7 @@ GPU3DInterface *core3DList[] = { &OSXOpenGLRendererEnd, &OSXOpenGLRendererFramebufferDidResize); - GPU_SetWillAutoBlitNativeToCustomBuffer(false); - GPU_FillScreenWithBGRA5551(0x8000); + GPU->SetWillAutoBlitNativeToCustomBuffer(false); return self; } @@ -151,14 +150,14 @@ GPU3DInterface *core3DList[] = { - (void) setGpuDimensions:(NSSize)theDimensions { pthread_rwlock_wrlock(self.rwlockProducer); - GPU_SetFramebufferSize(theDimensions.width, theDimensions.height); + GPU->SetCustomFramebufferSize(theDimensions.width, theDimensions.height); pthread_rwlock_unlock(self.rwlockProducer); } - (NSSize) gpuDimensions { pthread_rwlock_rdlock(self.rwlockProducer); - const NSSize dimensions = NSMakeSize(GPU_GetFramebufferWidth(), GPU_GetFramebufferHeight()); + const NSSize dimensions = NSMakeSize(GPU->GetCustomFramebufferWidth(), GPU->GetCustomFramebufferHeight()); pthread_rwlock_unlock(self.rwlockProducer); return dimensions; @@ -375,7 +374,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerMainGPU:(BOOL)gpuState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPUDisplayState(DS_GPU_TYPE_MAIN, (gpuState) ? true : false); + GPU->GetEngineMain()->SetEnableState((gpuState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -386,7 +385,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerMainGPU { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL gpuState = GetGPUDisplayState(DS_GPU_TYPE_MAIN) ? YES : NO; + const BOOL gpuState = GPU->GetEngineMain()->GetEnableState() ? YES : NO; pthread_rwlock_unlock(self.rwlockProducer); return gpuState; @@ -395,7 +394,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerMainBG0:(BOOL)layerState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPULayerState(DS_GPU_TYPE_MAIN, 0, (layerState) ? true : false); + GPU->GetEngineMain()->SetLayerEnableState(0, (layerState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -406,7 +405,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerMainBG0 { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_MAIN, 0) ? YES : NO; + const BOOL layerState = GPU->GetEngineMain()->GetLayerEnableState(0); pthread_rwlock_unlock(self.rwlockProducer); return layerState; @@ -415,7 +414,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerMainBG1:(BOOL)layerState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPULayerState(DS_GPU_TYPE_MAIN, 1, (layerState) ? true : false); + GPU->GetEngineMain()->SetLayerEnableState(1, (layerState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -426,7 +425,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerMainBG1 { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_MAIN, 1) ? YES : NO; + const BOOL layerState = GPU->GetEngineMain()->GetLayerEnableState(1); pthread_rwlock_unlock(self.rwlockProducer); return layerState; @@ -435,7 +434,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerMainBG2:(BOOL)layerState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPULayerState(DS_GPU_TYPE_MAIN, 2, (layerState) ? true : false); + GPU->GetEngineMain()->SetLayerEnableState(2, (layerState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -446,7 +445,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerMainBG2 { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_MAIN, 2) ? YES : NO; + const BOOL layerState = GPU->GetEngineMain()->GetLayerEnableState(2); pthread_rwlock_unlock(self.rwlockProducer); return layerState; @@ -455,7 +454,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerMainBG3:(BOOL)layerState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPULayerState(DS_GPU_TYPE_MAIN, 3, (layerState) ? true : false); + GPU->GetEngineMain()->SetLayerEnableState(3, (layerState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -466,7 +465,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerMainBG3 { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_MAIN, 3) ? YES : NO; + const BOOL layerState = GPU->GetEngineMain()->GetLayerEnableState(3); pthread_rwlock_unlock(self.rwlockProducer); return layerState; @@ -475,7 +474,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerMainOBJ:(BOOL)layerState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPULayerState(DS_GPU_TYPE_MAIN, 4, (layerState) ? true : false); + GPU->GetEngineMain()->SetLayerEnableState(4, (layerState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -486,7 +485,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerMainOBJ { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_MAIN, 4) ? YES : NO; + const BOOL layerState = GPU->GetEngineMain()->GetLayerEnableState(4); pthread_rwlock_unlock(self.rwlockProducer); return layerState; @@ -495,7 +494,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerSubGPU:(BOOL)gpuState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPUDisplayState(DS_GPU_TYPE_SUB, (gpuState) ? true : false); + GPU->GetEngineSub()->SetEnableState((gpuState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -506,7 +505,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerSubGPU { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL gpuState = GetGPUDisplayState(DS_GPU_TYPE_SUB) ? YES : NO; + const BOOL gpuState = GPU->GetEngineSub()->GetEnableState() ? YES : NO; pthread_rwlock_unlock(self.rwlockProducer); return gpuState; @@ -515,7 +514,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerSubBG0:(BOOL)layerState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPULayerState(DS_GPU_TYPE_SUB, 0, (layerState) ? true : false); + GPU->GetEngineSub()->SetLayerEnableState(0, (layerState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -526,7 +525,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerSubBG0 { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_SUB, 0) ? YES : NO; + const BOOL layerState = GPU->GetEngineSub()->GetLayerEnableState(0); pthread_rwlock_unlock(self.rwlockProducer); return layerState; @@ -535,7 +534,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerSubBG1:(BOOL)layerState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPULayerState(DS_GPU_TYPE_SUB, 1, (layerState) ? true : false); + GPU->GetEngineSub()->SetLayerEnableState(1, (layerState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -546,7 +545,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerSubBG1 { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_SUB, 1) ? YES : NO; + const BOOL layerState = GPU->GetEngineSub()->GetLayerEnableState(1); pthread_rwlock_unlock(self.rwlockProducer); return layerState; @@ -555,7 +554,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerSubBG2:(BOOL)layerState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPULayerState(DS_GPU_TYPE_SUB, 2, (layerState) ? true : false); + GPU->GetEngineSub()->SetLayerEnableState(2, (layerState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -566,7 +565,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerSubBG2 { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_SUB, 2) ? YES : NO; + const BOOL layerState = GPU->GetEngineSub()->GetLayerEnableState(2); pthread_rwlock_unlock(self.rwlockProducer); return layerState; @@ -575,7 +574,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerSubBG3:(BOOL)layerState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPULayerState(DS_GPU_TYPE_SUB, 3, (layerState) ? true : false); + GPU->GetEngineSub()->SetLayerEnableState(3, (layerState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -586,7 +585,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerSubBG3 { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_SUB, 3) ? YES : NO; + const BOOL layerState = GPU->GetEngineSub()->GetLayerEnableState(3); pthread_rwlock_unlock(self.rwlockProducer); return layerState; @@ -595,7 +594,7 @@ GPU3DInterface *core3DList[] = { - (void) setLayerSubOBJ:(BOOL)layerState { pthread_rwlock_wrlock(self.rwlockProducer); - SetGPULayerState(DS_GPU_TYPE_SUB, 4, (layerState) ? true : false); + GPU->GetEngineSub()->SetLayerEnableState(4, (layerState) ? true : false); pthread_rwlock_unlock(self.rwlockProducer); OSSpinLockLock(&spinlockGpuState); @@ -606,7 +605,7 @@ GPU3DInterface *core3DList[] = { - (BOOL) layerSubOBJ { pthread_rwlock_rdlock(self.rwlockProducer); - const BOOL layerState = GetGPULayerState(DS_GPU_TYPE_SUB, 4) ? YES : NO; + const BOOL layerState = GPU->GetEngineSub()->GetLayerEnableState(4); pthread_rwlock_unlock(self.rwlockProducer); return layerState; @@ -617,93 +616,6 @@ GPU3DInterface *core3DList[] = { return ([self gpuStateFlags] & (1 << stateBit)) ? YES : NO; } -- (BOOL) isGPUTypeDisplayed:(const NSInteger)theGpuType -{ - BOOL result = NO; - const UInt32 flags = [self gpuStateFlags]; - - switch (theGpuType) - { - case DS_GPU_TYPE_MAIN: - if (flags & GPUSTATE_MAIN_GPU_MASK) - { - result = YES; - } - break; - - case DS_GPU_TYPE_SUB: - if (flags & GPUSTATE_SUB_GPU_MASK) - { - result = YES; - } - break; - - case DS_GPU_TYPE_MAIN_AND_SUB: - if (flags & (GPUSTATE_MAIN_GPU_MASK | GPUSTATE_SUB_GPU_MASK)) - { - result = YES; - } - break; - - default: - break; - } - - return result; -} - -- (void) hideGPUType:(const NSInteger)theGpuType -{ - UInt32 flags = [self gpuStateFlags]; - - switch (theGpuType) - { - case DS_GPU_TYPE_MAIN: - flags &= ~GPUSTATE_MAIN_GPU_MASK; - break; - - case DS_GPU_TYPE_SUB: - flags &= ~GPUSTATE_SUB_GPU_MASK; - break; - - case DS_GPU_TYPE_MAIN_AND_SUB: - flags &= ~GPUSTATE_MAIN_GPU_MASK; - flags &= ~GPUSTATE_SUB_GPU_MASK; - break; - - default: - break; - } - - [self setGpuStateFlags:flags]; -} - -- (void) showGPUType:(const NSInteger)theGpuType -{ - UInt32 flags = [self gpuStateFlags]; - - switch (theGpuType) - { - case DS_GPU_TYPE_MAIN: - flags |= GPUSTATE_MAIN_GPU_MASK; - break; - - case DS_GPU_TYPE_SUB: - flags |= GPUSTATE_SUB_GPU_MASK; - break; - - case DS_GPU_TYPE_MAIN_AND_SUB: - flags |= GPUSTATE_MAIN_GPU_MASK; - flags |= GPUSTATE_SUB_GPU_MASK; - break; - - default: - break; - } - - [self setGpuStateFlags:flags]; -} - - (NSString *) render3DRenderingEngineString { NSString *theString = @"Uninitialized"; @@ -724,164 +636,15 @@ GPU3DInterface *core3DList[] = { return theString; } +- (void) clearWithColor:(const uint16_t)colorBGRA5551 +{ + pthread_rwlock_wrlock(self.rwlockProducer); + GPU->ClearWithColor(colorBGRA5551); + pthread_rwlock_unlock(self.rwlockProducer); +} + @end -void SetGPULayerState(const GPUType gpuType, const unsigned int i, const bool state) -{ - GPUEngineBase *theGpu = NULL; - - // Check bounds on the layer index. - if (i > 4) - { - return; - } - - switch (gpuType) - { - case DS_GPU_TYPE_SUB: - theGpu = SubScreen.gpu; - break; - - case DS_GPU_TYPE_MAIN: - theGpu = MainScreen.gpu; - break; - - case DS_GPU_TYPE_MAIN_AND_SUB: - SetGPULayerState(DS_GPU_TYPE_SUB, i, state); // Recursive call - theGpu = MainScreen.gpu; - break; - - default: - break; - } - - if (theGpu != NULL) - { - theGpu->SetLayerState(i, state); - } -} - -bool GetGPULayerState(const GPUType gpuType, const unsigned int i) -{ - bool theState = false; - - // Check bounds on the layer index. - if (i > 4) - { - return theState; - } - - switch (gpuType) - { - case DS_GPU_TYPE_SUB: - if (SubScreen.gpu != NULL) - { - theState = CommonSettings.dispLayers[SubScreen.gpu->core][i]; - } - break; - - case DS_GPU_TYPE_MAIN: - if (MainScreen.gpu != NULL) - { - theState = CommonSettings.dispLayers[MainScreen.gpu->core][i]; - } - break; - - case DS_GPU_TYPE_MAIN_AND_SUB: - if (SubScreen.gpu != NULL && MainScreen.gpu != NULL) - { - theState = (CommonSettings.dispLayers[SubScreen.gpu->core][i] && CommonSettings.dispLayers[MainScreen.gpu->core][i]); - } - break; - - default: - break; - } - - return theState; -} - -void SetGPUDisplayState(const GPUType gpuType, const bool state) -{ - switch (gpuType) - { - case DS_GPU_TYPE_SUB: - CommonSettings.showGpu.sub = state; - break; - - case DS_GPU_TYPE_MAIN: - CommonSettings.showGpu.main = state; - break; - - case DS_GPU_TYPE_MAIN_AND_SUB: - CommonSettings.showGpu.sub = state; - CommonSettings.showGpu.main = state; - break; - - default: - break; - } -} - -bool GetGPUDisplayState(const GPUType gpuType) -{ - bool theState = false; - - switch (gpuType) - { - case DS_GPU_TYPE_SUB: - theState = CommonSettings.showGpu.sub; - break; - - case DS_GPU_TYPE_MAIN: - theState = CommonSettings.showGpu.main; - break; - - case DS_GPU_TYPE_MAIN_AND_SUB: - theState = (CommonSettings.showGpu.sub && CommonSettings.showGpu.main); - break; - - default: - break; - } - - return theState; -} - -void GPU_FillScreenWithBGRA5551(const uint16_t colorValue) -{ - const NDSDisplayInfo &dispInfo = NDS_GetDisplayInfo(); - const size_t pixCountNative = GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT; - const size_t pixCountCustom = dispInfo.customWidth * dispInfo.customHeight; - -#ifdef __APPLE__ - const uint16_t colorValuePattern[] = {colorValue, colorValue, colorValue, colorValue, colorValue, colorValue, colorValue, colorValue}; - - memset_pattern16(MainScreen.gpu->nativeBuffer, colorValuePattern, pixCountNative * sizeof(uint16_t)); - memset_pattern16(SubScreen.gpu->nativeBuffer, colorValuePattern, pixCountNative * sizeof(uint16_t)); - - if (pixCountCustom % 16 == 0) - { - memset_pattern16(MainScreen.gpu->customBuffer, colorValuePattern, pixCountCustom * sizeof(uint16_t)); - memset_pattern16(SubScreen.gpu->customBuffer, colorValuePattern, pixCountCustom * sizeof(uint16_t)); - } - else -#endif - { - for (size_t i = 0; i < pixCountNative; i++) - { - MainScreen.gpu->nativeBuffer[i] = colorValue; - SubScreen.gpu->nativeBuffer[i] = colorValue; - } - - for (size_t i = 0; i < pixCountCustom; i++) - { - MainScreen.gpu->customBuffer[i] = colorValue; - SubScreen.gpu->customBuffer[i] = colorValue; - } - } -} - CGLContextObj OSXOpenGLRendererContext = NULL; CGLPBufferObj OSXOpenGLRendererPBuffer = NULL; diff --git a/desmume/src/cocoa/cocoa_core.mm b/desmume/src/cocoa/cocoa_core.mm index 77d02a90f..bf402eb88 100644 --- a/desmume/src/cocoa/cocoa_core.mm +++ b/desmume/src/cocoa/cocoa_core.mm @@ -909,7 +909,6 @@ volatile bool execute = true; pthread_mutex_lock(&threadParam.mutexThreadExecute); NDS_Reset(); - GPU_FillScreenWithBGRA5551(0xFFFF); pthread_mutex_unlock(&threadParam.mutexThreadExecute); [self restoreCoreState]; diff --git a/desmume/src/cocoa/cocoa_output.mm b/desmume/src/cocoa/cocoa_output.mm index 3010286b4..c5995a172 100644 --- a/desmume/src/cocoa/cocoa_output.mm +++ b/desmume/src/cocoa/cocoa_output.mm @@ -538,7 +538,7 @@ - (NSSize) displaySize { pthread_rwlock_rdlock(self.rwlockProducer); - NSSize size = NSMakeSize((CGFloat)GPU_GetFramebufferWidth(), (displayMode == DS_DISPLAY_TYPE_DUAL) ? (CGFloat)(GPU_GetFramebufferHeight() * 2): (CGFloat)GPU_GetFramebufferHeight()); + NSSize size = NSMakeSize((CGFloat)GPU->GetCustomFramebufferWidth(), (displayMode == DS_DISPLAY_TYPE_DUAL) ? (CGFloat)(GPU->GetCustomFramebufferHeight() * 2): (CGFloat)GPU->GetCustomFramebufferHeight()); pthread_rwlock_unlock(self.rwlockProducer); return size; @@ -676,7 +676,7 @@ - (NSBitmapImageRep *) bitmapImageRep { - const NDSDisplayInfo &dispInfo = NDS_GetDisplayInfo(); + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); const NSInteger dispMode = [self displayMode]; uint16_t *displayBuffer = dispInfo.masterCustomBuffer; @@ -700,9 +700,10 @@ } uint32_t *bitmapData = (uint32_t *)[imageRep bitmapData]; + pthread_rwlock_rdlock(self.rwlockProducer); - MainScreen.gpu->BlitNativeToCustomFramebuffer(); - SubScreen.gpu->BlitNativeToCustomFramebuffer(); + GPU->GetEngineMain()->BlitNativeToCustomFramebuffer(); + GPU->GetEngineSub()->BlitNativeToCustomFramebuffer(); RGB555ToRGBA8888Buffer(displayBuffer, bitmapData, (w * h)); pthread_rwlock_unlock(self.rwlockProducer); @@ -796,7 +797,7 @@ pthread_rwlock_rdlock(self.rwlockProducer); - const NDSDisplayInfo &dispInfo = NDS_GetDisplayInfo(); + const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); const NSInteger dispMode = [self displayMode]; const uint16_t newGpuWidth = dispInfo.customWidth; const uint16_t newGpuHeight = dispInfo.customHeight; diff --git a/desmume/src/cocoa/openemu/NDSGameCore.mm b/desmume/src/cocoa/openemu/NDSGameCore.mm index 085308303..50d56fee8 100644 --- a/desmume/src/cocoa/openemu/NDSGameCore.mm +++ b/desmume/src/cocoa/openemu/NDSGameCore.mm @@ -279,7 +279,7 @@ volatile bool execute = true; - (const void *)videoBuffer { - return GPU_screen; + return GPU->GetNativeFramebuffer(); } - (GLenum)pixelFormat diff --git a/desmume/src/cocoa/userinterface/EmuControllerDelegate.mm b/desmume/src/cocoa/userinterface/EmuControllerDelegate.mm index 7d3e837a9..1a105aa2f 100644 --- a/desmume/src/cocoa/userinterface/EmuControllerDelegate.mm +++ b/desmume/src/cocoa/userinterface/EmuControllerDelegate.mm @@ -1798,7 +1798,6 @@ // Update the UI to indicate that a ROM has indeed been loaded. [self updateAllWindowTitles]; - GPU_FillScreenWithBGRA5551(0xFFFF); for (DisplayWindowController *windowController in windowList) { [CocoaDSUtil messageSendOneWay:[[windowController cdsVideoOutput] receivePort] msgID:MESSAGE_REPROCESS_AND_REDRAW]; @@ -1829,6 +1828,7 @@ { BOOL result = NO; + CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content]; [self setCurrentSaveStateURL:nil]; isSaveStateEdited = NO; @@ -1876,7 +1876,7 @@ // Update the UI to indicate that the ROM has finished unloading. [self updateAllWindowTitles]; - GPU_FillScreenWithBGRA5551(0x8000); + [[cdsCore cdsGPU] clearWithColor:0x8000]; for (DisplayWindowController *windowController in windowList) { [CocoaDSUtil messageSendOneWay:[[windowController cdsVideoOutput] receivePort] msgID:MESSAGE_REPROCESS_AND_REDRAW]; @@ -1894,7 +1894,6 @@ [[windowController window] displayIfNeeded]; } - CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content]; [cdsCore setSlot1StatusText:NSSTRING_STATUS_EMULATION_NOT_RUNNING]; [[cdsCore cdsController] reset]; [[cdsCore cdsController] updateMicLevel]; @@ -2196,7 +2195,6 @@ [[cdsCore cdsGPU] setRender3DMultisample:[[NSUserDefaults standardUserDefaults] boolForKey:@"Render3D_Multisample"]]; [[cdsCore cdsGPU] setRender3DFragmentSamplingHack:[[NSUserDefaults standardUserDefaults] boolForKey:@"Render3D_FragmentSamplingHack"]]; [[cdsCore cdsGPU] setGpuScale:(NSUInteger)[[NSUserDefaults standardUserDefaults] integerForKey:@"Render3D_ScalingFactor"]]; - GPU_FillScreenWithBGRA5551(0x8000); // Fill the GPU framebuffer with black after the GPU scaling factor is set. // Set the stylus options per user preferences. [[cdsCore cdsController] setStylusPressure:[[NSUserDefaults standardUserDefaults] integerForKey:@"Emulation_StylusPressure"]]; diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 8f151d783..4a497b1a2 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -2325,7 +2325,7 @@ void gfx3d_VBlankEndSignal(bool skipFrame) if (!CommonSettings.showGpu.main) { - memset(gfx3d_colorRGBA6665, 0, GPU_GetFramebufferWidth() * GPU_GetFramebufferHeight() * sizeof(FragmentColor)); + memset(gfx3d_colorRGBA6665, 0, GPU->GetCustomFramebufferWidth() * GPU->GetCustomFramebufferHeight() * sizeof(FragmentColor)); return; } @@ -2440,13 +2440,13 @@ void gfx3d_glGetLightColor(const size_t index, u32 &dst) const FragmentColor* gfx3d_GetLineDataRGBA6665(const size_t line) { CurrentRenderer->RenderFinish(); - return (gfx3d_colorRGBA6665 + (line * GPU_GetFramebufferWidth())); + return (gfx3d_colorRGBA6665 + (line * GPU->GetCustomFramebufferWidth())); } const u16* gfx3d_GetLineDataRGBA5551(const size_t line) { CurrentRenderer->RenderFinish(); - return (gfx3d_colorRGBA5551 + (line * GPU_GetFramebufferWidth())); + return (gfx3d_colorRGBA5551 + (line * GPU->GetCustomFramebufferWidth())); } diff --git a/desmume/src/gtk-glade/callbacks.cpp b/desmume/src/gtk-glade/callbacks.cpp index 8088aa8c9..b697ec757 100755 --- a/desmume/src/gtk-glade/callbacks.cpp +++ b/desmume/src/gtk-glade/callbacks.cpp @@ -221,15 +221,16 @@ static void Printscreen() gchar *filename; GError *error = NULL; u8 *rgb; + u16 *gpuFramebuffer = GPU->GetNativeFramebuffer(); static int seq = 0; rgb = (u8 *) malloc(SCREENS_PIXEL_SIZE*3); if (!rgb) return; for (int i = 0; i < SCREENS_PIXEL_SIZE; i++) { - rgb[(i * 3) + 0] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 0) & 0x1f) << 3; - rgb[(i * 3) + 1] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 5) & 0x1f) << 3; - rgb[(i * 3) + 2] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 10) & 0x1f) << 3; + rgb[(i * 3) + 0] = ((gpuFramebuffer[i] >> 0) & 0x1f) << 3; + rgb[(i * 3) + 1] = ((gpuFramebuffer[i] >> 5) & 0x1f) << 3; + rgb[(i * 3) + 2] = ((gpuFramebuffer[i] >> 10) & 0x1f) << 3; } screenshot = gdk_pixbuf_new_from_data(rgb, @@ -523,18 +524,18 @@ void on_wgt_Exec_toggled (GtkToggleToolButton *toggletoolbutton, gpointer user /* LAYERS ***** ***** ***** ***** */ -static void change_bgx_layer(int layer, gboolean state, NDS_Screen scr) { +static void change_bgx_layer(int layer, gboolean state, GPUEngineBase *gpuEngine) { //if(!desmume_running()) return; - scr.gpu->SetLayerState(layer, (state) ? true : false); + gpuEngine->SetLayerEnableState(layer, (state) ? true : false); //fprintf(stderr,"Changed Layer %s to %d\n",layer,state); } void on_wc_1_BGXX_toggled (GtkToggleButton *togglebutton, gpointer user_data) { int layer = dyn_CAST(int,user_data); - change_bgx_layer(layer, gtk_toggle_button_get_active(togglebutton), MainScreen); + change_bgx_layer(layer, gtk_toggle_button_get_active(togglebutton), GPU->GetEngineMain()); } void on_wc_2_BGXX_toggled (GtkToggleButton *togglebutton, gpointer user_data) { int layer = dyn_CAST(int,user_data); - change_bgx_layer(layer, gtk_toggle_button_get_active(togglebutton), SubScreen); + change_bgx_layer(layer, gtk_toggle_button_get_active(togglebutton), GPU->GetEngineSub()); } diff --git a/desmume/src/gtk-glade/callbacks_IO.cpp b/desmume/src/gtk-glade/callbacks_IO.cpp index faa155846..4ffac4f09 100755 --- a/desmume/src/gtk-glade/callbacks_IO.cpp +++ b/desmume/src/gtk-glade/callbacks_IO.cpp @@ -117,7 +117,7 @@ static void decode_screen () { int x,y, m, W,H,L,BL; u32 image[RAW_H*2][RAW_W], pix; - u16 * pixel = (u16*)&GPU_screen; + u16 * pixel = GPU->GetNativeFramebuffer(); u32 * rgb32 = &on_screen_image32[0]; /* decode colors */ diff --git a/desmume/src/gtk-glade/gdk_gl.cpp b/desmume/src/gtk-glade/gdk_gl.cpp index 294494a7f..129a7ec03 100755 --- a/desmume/src/gtk-glade/gdk_gl.cpp +++ b/desmume/src/gtk-glade/gdk_gl.cpp @@ -237,14 +237,16 @@ static void my_gl_Texture2D() { static void my_gl_ScreenTex( int software_convert) { + u16 *gpuFramebuffer = GPU->GetNativeFramebuffer(); + if ( software_convert) { u8 converted[256 * 384 * 3]; int i; for ( i = 0; i < (256 * 384); i++) { - converted[(i * 3) + 0] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 0) & 0x1f) << 3; - converted[(i * 3) + 1] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 5) & 0x1f) << 3; - converted[(i * 3) + 2] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 10) & 0x1f) << 3; + converted[(i * 3) + 0] = ((gpuFramebuffer[i] >> 0) & 0x1f) << 3; + converted[(i * 3) + 1] = ((gpuFramebuffer[i] >> 5) & 0x1f) << 3; + converted[(i * 3) + 2] = ((gpuFramebuffer[i] >> 10) & 0x1f) << 3; } glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384, @@ -256,7 +258,7 @@ my_gl_ScreenTex( int software_convert) { glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, - &GPU_screen); + gpuFramebuffer); } } @@ -299,7 +301,7 @@ gboolean screen (GtkWidget * widget, int viewportscreen) { if (desmume_running()) { // master bright - gpu = ((screen)?SubScreen:MainScreen).gpu; + gpu = (screen) ? GPU->GetEngineSub() : GPU->GetEngineMain(); switch (gpu->MasterBrightMode) { diff --git a/desmume/src/gtk/main.cpp b/desmume/src/gtk/main.cpp index 881e94f73..bd16eac51 100644 --- a/desmume/src/gtk/main.cpp +++ b/desmume/src/gtk/main.cpp @@ -1411,8 +1411,6 @@ static void Reset() bool shouldBeRunning = desmume_running(); Pause(); NDS_Reset(); - // Clear the NDS screen - memset(GPU_screen, 0xFF, GPU_GetFramebufferWidth() * GPU_GetFramebufferHeight() * 2 * sizeof(u16)); RedrawScreen(); if (shouldBeRunning) { Launch(); @@ -1549,7 +1547,7 @@ static inline void RGB555ToBGRA8888Buffer(const uint16_t *__restrict__ srcBuffer static inline void gpu_screen_to_rgb(u32* dst) { - RGB555ToRGBA8888Buffer((u16*)GPU_screen, dst, 256 * 384); + RGB555ToRGBA8888Buffer(GPU->GetNativeFramebuffer(), dst, 256 * 384); } static inline void drawScreen(cairo_t* cr, u32* buf, gint w, gint h) { @@ -1674,7 +1672,7 @@ static gboolean ExposeDrawingArea (GtkWidget *widget, GdkEventExpose *event, gpo } static void RedrawScreen() { - RGB555ToBGRA8888Buffer((u16*)GPU_screen, video->GetSrcBufferPtr(), 256 * 384); + RGB555ToBGRA8888Buffer(GPU->GetNativeFramebuffer(), video->GetSrcBufferPtr(), 256 * 384); #ifdef HAVE_LIBAGG aggDraw.hud->attach((u8*)video->GetSrcBufferPtr(), 256, 384, 1024); osd->update(); @@ -2127,14 +2125,14 @@ static void ToggleLayerVisibility(GtkToggleAction* action, gpointer data) case MAIN_BG_2: case MAIN_BG_3: case MAIN_OBJ: - MainScreen.gpu->SetLayerState(Layer, (active == TRUE) ? true : false); + GPU->GetEngineMain()->SetLayerEnableState(Layer, (active == TRUE) ? true : false); break; case SUB_BG_0: case SUB_BG_1: case SUB_BG_2: case SUB_BG_3: case SUB_OBJ: - SubScreen.gpu->SetLayerState(Layer-SUB_BG_0, (active == TRUE) ? true : false); + GPU->GetEngineSub()->SetLayerEnableState(Layer-SUB_BG_0, (active == TRUE) ? true : false); break; default: break; @@ -2458,7 +2456,7 @@ gboolean EmuLoop(gpointer data) desmume_cycle(); /* Emule ! */ _updateDTools(); - avout_x264.updateVideo((u16*)GPU_screen); + avout_x264.updateVideo(GPU->GetNativeFramebuffer()); RedrawScreen(); if (!config.fpslimiter || keys_latch & KEYMASK_(KEY_BOOST - 1)) { diff --git a/desmume/src/lua-engine.cpp b/desmume/src/lua-engine.cpp index e630c7dd9..f443274cd 100644 --- a/desmume/src/lua-engine.cpp +++ b/desmume/src/lua-engine.cpp @@ -2228,7 +2228,7 @@ public: char temp [256]; sprintf(temp, " " /*"mismatch at "*/ "byte %d(0x%X at 0x%X): %d(0x%X) != %d(0x%X)\n", i, i, dst, *src,*src, *dst,*dst); - if(ptr == GPU_screen || ptr == gfx3d_colorRGBA6665) // ignore screen-only differences since frame skipping can cause them and it's probably ok + if(ptr == GPU->GetNativeFramebuffer() || ptr == GPU->GetCustomFramebuffer() || ptr == gfx3d_colorRGBA6665) // ignore screen-only differences since frame skipping can cause them and it's probably ok break; differences.push_back(temp); // <-- probably the best place for a breakpoint diff --git a/desmume/src/qt/project/frontend/video.cpp b/desmume/src/qt/project/frontend/video.cpp index ed7112a79..f298ed2a0 100644 --- a/desmume/src/qt/project/frontend/video.cpp +++ b/desmume/src/qt/project/frontend/video.cpp @@ -106,7 +106,7 @@ bool Video::setFilter(VideoFilterTypeID filterID) { } unsigned int* Video::runFilter() { - RGB555ToRGBA8888Buffer((u16*)GPU_screen, this->mFilter.GetSrcBufferPtr(), 256 * 384); + RGB555ToRGBA8888Buffer(GPU->GetNativeFramebuffer(), this->mFilter.GetSrcBufferPtr(), 256 * 384); unsigned int* buf = this->mFilter.RunFilter(); this->screenBufferUpdated(buf, this->getDstSize(), this->getDstScale()); return buf; diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index 10d7db7c4..67aa9ca5b 100644 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -95,7 +95,7 @@ bool NDS_3D_ChangeCore(int newCore) return result; } - Render3DError error = newRenderer->SetFramebufferSize(GPU_GetFramebufferWidth(), GPU_GetFramebufferHeight()); + Render3DError error = newRenderer->SetFramebufferSize(GPU->GetCustomFramebufferWidth(), GPU->GetCustomFramebufferHeight()); if (error != RENDER3DERROR_NOERR) { return result; @@ -218,7 +218,6 @@ Render3D::Render3D() Render3D::~Render3D() { free_aligned(_framebufferColor); - TexCache_Reset(); } RendererID Render3D::GetRenderID() diff --git a/desmume/src/windows/hotkey.cpp b/desmume/src/windows/hotkey.cpp index b4ed85959..cb640b845 100644 --- a/desmume/src/windows/hotkey.cpp +++ b/desmume/src/windows/hotkey.cpp @@ -162,13 +162,13 @@ void HK_QuickScreenShot(int param, bool justPressed) case path.PNG: { strcat(buffer, ".png"); - NDS_WritePNG(buffer, GPU_screen); + NDS_WritePNG(buffer, GPU->GetNativeFramebuffer()); } break; case path.BMP: { strcat(buffer, ".bmp"); - NDS_WriteBMP(buffer, GPU_screen); + NDS_WriteBMP(buffer, GPU->GetNativeFramebuffer()); } break; } @@ -220,9 +220,9 @@ void HK_PrintScreen(int param, bool justPressed) filename = outFilename; if(toupper(strright(filename,4)) == ".PNG") - NDS_WritePNG(filename.c_str(), GPU_screen); + NDS_WritePNG(filename.c_str(), GPU->GetNativeFramebuffer()); else if(toupper(strright(filename,4)) == ".BMP") - NDS_WriteBMP(filename.c_str(), GPU_screen); + NDS_WriteBMP(filename.c_str(), GPU->GetNativeFramebuffer()); } if(unpause) NDS_UnPause(false); diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index a68d4edcd..268f41afe 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -816,7 +816,7 @@ void ToDSScreenRelativeCoords(s32& x, s32& y, int whichScreen) } // finally, make it relative to the correct screen - const bool isMainGPUFirst = (MainDisplay.GetEngineID() == GPUCOREID_MAIN); + const bool isMainGPUFirst = (GPU->GetDisplayMain()->GetEngineID() == GPUCOREID_MAIN); if (video.layout == 0 || video.layout == 2) { @@ -1656,7 +1656,7 @@ static void OGL_DoDisplay() RECT srcRects [2]; - const bool isMainGPUFirst = (MainDisplay.GetEngineID() == GPUCOREID_MAIN); + const bool isMainGPUFirst = (GPU->GetDisplayMain()->GetEngineID() == GPUCOREID_MAIN); if(video.swap == 0) { @@ -1774,7 +1774,7 @@ static void DD_DoDisplay() RECT* dstRects [2] = {&MainScreenRect, &SubScreenRect}; RECT* srcRects [2]; - const bool isMainGPUFirst = (MainDisplay.GetEngineID() == GPUCOREID_MAIN); + const bool isMainGPUFirst = (GPU->GetDisplayMain()->GetEngineID() == GPUCOREID_MAIN); if(video.swap == 0) { @@ -1999,7 +1999,7 @@ void Display() { if(CommonSettings.single_core()) { - video.srcBuffer = (u8*)GPU_screen; + video.srcBuffer = (u8*)GPU->GetNativeFramebuffer(); DoDisplay(true); } else @@ -2019,7 +2019,7 @@ void Display() newestDisplayBuffer += diff; else newestDisplayBuffer = (currDisplayBuffer+2)%3; - memcpy(displayBuffers[newestDisplayBuffer],GPU_screen,256*192*4); + memcpy(displayBuffers[newestDisplayBuffer],GPU->GetNativeFramebuffer(),256*192*4); g_mutex_unlock(display_mutex); } @@ -2119,7 +2119,7 @@ static void StepRunLoop_Core() win_sound_samplecounter = DESMUME_SAMPLE_RATE/60; } inFrameBoundary = true; - DRV_AviVideoUpdate((u16*)GPU_screen); + DRV_AviVideoUpdate(GPU->GetNativeFramebuffer()); extern bool rewinding; @@ -2143,7 +2143,7 @@ static void StepRunLoop_Paused() // periodically update single-core OSD when paused and in the foreground if(CommonSettings.single_core() && GetActiveWindow() == mainLoopData.hwnd) { - video.srcBuffer = (u8*)GPU_screen; + video.srcBuffer = (u8*)GPU->GetNativeFramebuffer(); DoDisplay(true); } @@ -3263,6 +3263,7 @@ int _main() CommonSettings.wifi.infraBridgeAdapter = GetPrivateProfileInt("Wifi", "BridgeAdapter", 0, IniName); NDS_Init(); + GPU->ClearWithColor(0xFFFF); #ifdef GDB_STUB gdbstub_mutex_init(); @@ -4045,7 +4046,7 @@ void CloseRom() // clear screen so the last frame we rendered doesn't stick around // (TODO: maybe NDS_Reset should do this?) - memset(GPU_screen, 0xFF, GPU_GetFramebufferWidth() * GPU_GetFramebufferHeight() * 2 * sizeof(u16)); + GPU->ClearWithColor(0xFFFF); InvalidateRect(MainWindow->getHWnd(), NULL, TRUE); // make sure the window refreshes with the cleared screen @@ -4238,7 +4239,7 @@ void ScreenshotToClipboard(bool extraInfo) bmi.bV4Height = -384; FillRect(hMemDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); - SetDIBitsToDevice(hMemDC, 0, 0, 256, 384, 0, 0, 0, 384, &GPU_screen[0], (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + SetDIBitsToDevice(hMemDC, 0, 0, 256, 384, 0, 0, 0, 384, GPU->GetNativeFramebuffer(), (BITMAPINFO*)&bmi, DIB_RGB_COLORS); if(extraInfo) { @@ -4382,10 +4383,10 @@ void SaveWindowPos(HWND hwnd) static void TwiddleLayer(UINT ctlid, int core, int layer) { - GPUEngineBase *gpu = ((GPUCoreID)core == GPUCOREID_MAIN) ? MainScreen.gpu : SubScreen.gpu; + GPUEngineBase *gpu = ((GPUCoreID)core == GPUCOREID_MAIN) ? GPU->GetEngineMain() : GPU->GetEngineSub(); const bool newLayerState = !CommonSettings.dispLayers[core][layer]; - gpu->SetLayerState(layer, newLayerState); + gpu->SetLayerEnableState(layer, newLayerState); MainWindow->checkMenu(ctlid, newLayerState); } @@ -5023,7 +5024,7 @@ DOKEYDOWN: { if(CommonSettings.single_core()) { - video.srcBuffer = (u8*)GPU_screen; + video.srcBuffer = (u8*)GPU->GetNativeFramebuffer(); DoDisplay(true); } } @@ -5138,7 +5139,7 @@ DOKEYDOWN: } else { - const bool isMainGPUFirst = (MainDisplay.GetEngineID() == GPUCOREID_MAIN); + const bool isMainGPUFirst = (GPU->GetDisplayMain()->GetEngineID() == GPUCOREID_MAIN); if ((video.layout == 2) && ((video.swap == 0) || (video.swap == 2 && isMainGPUFirst) || (video.swap == 3 && !isMainGPUFirst))) return 0; ToDSScreenRelativeCoords(x,y,1); diff --git a/desmume/src/windows/mapView.cpp b/desmume/src/windows/mapView.cpp index 7df136903..23e280998 100644 --- a/desmume/src/windows/mapView.cpp +++ b/desmume/src/windows/mapView.cpp @@ -45,8 +45,8 @@ struct mapview_struct //we're going to make a copy of the gpu so that we don't wreck affine scroll params //hopefully we won't mess up anything else GPUEngineBase *realGpu; - if(lcd) realGpu = SubScreen.gpu; - else realGpu = MainScreen.gpu; + if(lcd) realGpu = GPU->GetEngineSub(); + else realGpu = GPU->GetEngineMain(); GPUEngineBase &gpu = *realGpu; //forgive the gyrations, some of this junk in here is to remind us of gyrations we might have to go @@ -100,13 +100,13 @@ LRESULT MapView_OnPaint(mapview_struct * win, HWND hwnd, WPARAM wParam, LPARAM l if(win->lcd) { - lg = SubScreen.gpu->BGSize[win->map][0]; - ht = SubScreen.gpu->BGSize[win->map][1]; + lg = GPU->GetEngineSub()->BGSize[win->map][0]; + ht = GPU->GetEngineSub()->BGSize[win->map][1]; } else { - lg = MainScreen.gpu->BGSize[win->map][0]; - ht = MainScreen.gpu->BGSize[win->map][1]; + lg = GPU->GetEngineMain()->BGSize[win->map][0]; + ht = GPU->GetEngineMain()->BGSize[win->map][1]; } bmi.bV4Width = lg; bmi.bV4Height = -ht; @@ -133,7 +133,7 @@ LRESULT MapView_OnPaint(mapview_struct * win, HWND hwnd, WPARAM wParam, LPARAM l sprintf(text, "extended slot %d", (bgcnt&(1<<13))?3:1); break; default : - sprintf(text, "extended slot %d", MainScreen.gpu->BGExtPalSlot[win->map]); + sprintf(text, "extended slot %d", GPU->GetEngineMain()->BGExtPalSlot[win->map]); break; } } @@ -155,14 +155,14 @@ LRESULT MapView_OnPaint(mapview_struct * win, HWND hwnd, WPARAM wParam, LPARAM l sprintf(text, "0x%08X", (int)(0x6000000 + 0x800*((bgcnt>>8)&0x1F) + win->lcd*0x200000 + ((dispcnt>>27)&7)*0x10000)); SetWindowText(GetDlgItem(hwnd, IDC_SCR), text); - //sprintf(text, "%d x %d", MainScreen.gpu->BGPA[win->map], MainScreen.gpu->BGPB[win->map]); - sprintf(text, "%d x %d", (int)MainScreen.gpu->BGSize[win->map][0], (int)MainScreen.gpu->BGSize[win->map][1]); + //sprintf(text, "%d x %d", GPU->GetEngineMain()->BGPA[win->map], GPU->GetEngineMain()->BGPB[win->map]); + sprintf(text, "%d x %d", (int)GPU->GetEngineMain()->BGSize[win->map][0], (int)GPU->GetEngineMain()->BGSize[win->map][1]); SetWindowText(GetDlgItem(hwnd, IDC_MSIZE), text); //if (win->map==2) { - // parms = &(MainScreen.gpu->dispx_st)->dispx_BG2PARMS; + // parms = &(GPU->GetEngineMain()->dispx_st)->dispx_BG2PARMS; //} else { - // parms = &(MainScreen.gpu->dispx_st)->dispx_BG3PARMS; + // parms = &(GPU->GetEngineMain()->dispx_st)->dispx_BG3PARMS; //} //sprintf(text, "%d x %d", parms->BGxX, parms->BGxY); SetWindowText(GetDlgItem(hwnd, IDC_SCROLL), "useless"); diff --git a/desmume/src/windows/oamView.cpp b/desmume/src/windows/oamView.cpp index abb598166..d36684b73 100644 --- a/desmume/src/windows/oamView.cpp +++ b/desmume/src/windows/oamView.cpp @@ -280,7 +280,7 @@ BOOL CALLBACK ViewOAMProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam OAMView = new oamview_struct; memset(OAMView, 0, sizeof(oamview_struct)); OAMView->oam = MMU.ARM9_OAM; - OAMView->gpu = MainScreen.gpu; + OAMView->gpu = GPU->GetEngineMain(); OAMView->scale = 2; OAMView->border = true; @@ -391,12 +391,12 @@ BOOL CALLBACK ViewOAMProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam case 0 : OAMView->oam = MMU.ARM9_OAM; OAMView->num = 0; - OAMView->gpu = MainScreen.gpu; + OAMView->gpu = GPU->GetEngineMain(); break; case 1 : OAMView->oam = (MMU.ARM9_OAM+0x400); OAMView->num = 0; - OAMView->gpu = SubScreen.gpu; + OAMView->gpu = GPU->GetEngineSub(); break; } }