diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index 39cad0e38..bdbe6e553 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -4027,31 +4027,56 @@ void GPUEngineBase::SetWillApplyMasterBrightnessPerScanline(bool willApply) template void GPUEngineBase::ApplyMasterBrightness() { + NDSDisplayInfo &dispInfoMutable = (NDSDisplayInfo &)GPU->GetDisplayInfo(); + const bool isMasterBrightnessAutoApplied = GPU->GetWillAutoApplyMasterBrightness(); + if (this->_willApplyMasterBrightnessPerScanline) { const bool isNativeSize = (this->nativeLineOutputCount == GPU_FRAMEBUFFER_NATIVE_HEIGHT); for (size_t line = 0; line < GPU_FRAMEBUFFER_NATIVE_HEIGHT; line++) { - const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); const GPUEngineCompositorInfo &compInfo = this->_currentCompositorInfo[line]; - void *dstColorLine = (isNativeSize) ? ((u8 *)this->nativeBuffer + (compInfo.line.blockOffsetNative * dispInfo.pixelBytes)) : ((u8 *)this->customBuffer + (compInfo.line.blockOffsetCustom * dispInfo.pixelBytes)); - const size_t pixCount = (isNativeSize) ? GPU_FRAMEBUFFER_NATIVE_WIDTH : compInfo.line.pixelCount; - this->ApplyMasterBrightness(dstColorLine, - pixCount, - compInfo.renderState.masterBrightnessMode, - compInfo.renderState.masterBrightnessIntensity); + if (isMasterBrightnessAutoApplied) + { + void *dstColorLine = (isNativeSize) ? ((u8 *)this->nativeBuffer + (compInfo.line.blockOffsetNative * dispInfoMutable.pixelBytes)) : ((u8 *)this->customBuffer + (compInfo.line.blockOffsetCustom * dispInfoMutable.pixelBytes)); + const size_t pixCount = (isNativeSize) ? GPU_FRAMEBUFFER_NATIVE_WIDTH : compInfo.line.pixelCount; + + this->ApplyMasterBrightness(dstColorLine, + pixCount, + compInfo.renderState.masterBrightnessMode, + compInfo.renderState.masterBrightnessIntensity); + + if ( (compInfo.renderState.masterBrightnessIntensity != 0) && ((compInfo.renderState.masterBrightnessMode == GPUMasterBrightMode_Up) || (compInfo.renderState.masterBrightnessMode == GPUMasterBrightMode_Down)) ) + { + dispInfoMutable.isMasterBrightnessApplied[this->_targetDisplayID] = true; + } + } + + dispInfoMutable.masterBrightnessMode[this->_targetDisplayID][line] = compInfo.renderState.masterBrightnessMode; + dispInfoMutable.masterBrightnessIntensity[this->_targetDisplayID][line] = compInfo.renderState.masterBrightnessIntensity; } } else { const GPUEngineCompositorInfo &compInfo = this->_currentCompositorInfo[0]; - this->ApplyMasterBrightness(this->renderedBuffer, - this->renderedWidth * this->renderedHeight, - compInfo.renderState.masterBrightnessMode, - compInfo.renderState.masterBrightnessIntensity); + if (isMasterBrightnessAutoApplied) + { + this->ApplyMasterBrightness(this->renderedBuffer, + this->renderedWidth * this->renderedHeight, + compInfo.renderState.masterBrightnessMode, + compInfo.renderState.masterBrightnessIntensity); + + dispInfoMutable.isMasterBrightnessApplied[this->_targetDisplayID] = (compInfo.renderState.masterBrightnessIntensity != 0) && ((compInfo.renderState.masterBrightnessMode == GPUMasterBrightMode_Up) || (compInfo.renderState.masterBrightnessMode == GPUMasterBrightMode_Down)); + } + + for (size_t line = 0; line < GPU_FRAMEBUFFER_NATIVE_HEIGHT; line++) + { + dispInfoMutable.masterBrightnessMode[this->_targetDisplayID][line] = compInfo.renderState.masterBrightnessMode; + dispInfoMutable.masterBrightnessIntensity[this->_targetDisplayID][line] = compInfo.renderState.masterBrightnessIntensity; + } } } @@ -7428,22 +7453,30 @@ void GPUSubsystem::RenderLine(const size_t l, bool isFrameSkipRequested) this->_displayInfo.renderedWidth[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->renderedWidth; this->_displayInfo.renderedHeight[NDSDisplayID_Touch] = this->_displayTouch->GetEngine()->renderedHeight; - if (this->_willAutoApplyMasterBrightness) + this->_displayInfo.isDisplayEnabled[NDSDisplayID_Main] = CommonSettings.showGpu.main; + this->_displayInfo.isDisplayEnabled[NDSDisplayID_Touch] = CommonSettings.showGpu.sub; + this->_displayInfo.isMasterBrightnessApplied[NDSDisplayID_Main] = false; + this->_displayInfo.isMasterBrightnessApplied[NDSDisplayID_Touch] = false; + + if (CommonSettings.showGpu.main) { - if (CommonSettings.showGpu.main) - { - this->_engineMain->ApplyMasterBrightness(); - } - else + this->_engineMain->ApplyMasterBrightness(); + } + else + { + if (this->_willAutoApplyMasterBrightness) { memset(this->_engineMain->renderedBuffer, 0, this->_engineMain->renderedWidth * this->_engineMain->renderedHeight * this->_displayInfo.pixelBytes); } - - if (CommonSettings.showGpu.sub) - { - this->_engineSub->ApplyMasterBrightness(); - } - else + } + + if (CommonSettings.showGpu.sub) + { + this->_engineSub->ApplyMasterBrightness(); + } + else + { + if (this->_willAutoApplyMasterBrightness) { memset(this->_engineSub->renderedBuffer, 0, this->_engineSub->renderedWidth * this->_engineSub->renderedHeight * this->_displayInfo.pixelBytes); } diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index fed14fe65..205606d95 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -1058,33 +1058,53 @@ typedef struct // User-requested settings. These fields will always remain constant until changed. // Changed by calling GPUSubsystem::SetColorFormat(). - NDSColorFormat colorFormat; // The output color format. - size_t pixelBytes; // The number of bytes per pixel. + NDSColorFormat colorFormat; // The output color format. + size_t pixelBytes; // The number of bytes per pixel. // Changed by calling GPUSubsystem::SetFramebufferSize(). - bool isCustomSizeRequested; // Reports that the call to GPUSubsystem::SetFramebufferSize() resulted in a custom rendering size. - // true - The user requested a custom size. - // false - The user requested the native size. - size_t customWidth; // The requested custom width, measured in pixels. - size_t customHeight; // The requested custom height, measured in pixels. + bool isCustomSizeRequested; // Reports that the call to GPUSubsystem::SetFramebufferSize() resulted in a custom rendering size. + // true - The user requested a custom size. + // false - The user requested the native size. + size_t customWidth; // The requested custom width, measured in pixels. + size_t customHeight; // The requested custom height, measured in pixels. + + void *masterNativeBuffer; // Pointer to the head of the master native buffer. + void *masterCustomBuffer; // Pointer to the head of the master custom buffer. + // If GPUSubsystem::GetWillAutoResolveToCustomBuffer() would return true, or if + // GPUEngineBase::ResolveToCustomFramebuffer() is called, then this buffer is used as the target + // buffer for resolving any native-sized renders. + + // Changed by calling GPUSubsystem::SetWillAutoApplyMasterBrightness(). + bool isMasterBrightnessAutoApplyRequested; // Reports the result of GPUSubsystem::GetWillAutoApplyMasterBrightness(). + // true - The emulator itself will apply the master brightness. This is the default option. + // false - The output framebuffer will not have master brightness applied. Clients will need to + // apply the master brightness themselves in a post-processing pass. Clients should use + // the isMasterBrightnessApplied, masterBrightnessMode, masterBrightnessIntensity and + // isDisplayEnabled properties to determine how to apply the master brightness on their + // end. + + // Changed by calling GPUEngineBase::SetEnableState(). + bool isDisplayEnabled[2]; // Reports that a particular display has been enabled or disabled by the user. - void *masterNativeBuffer; // Pointer to the head of the master native buffer. - void *masterCustomBuffer; // Pointer to the head of the master custom buffer. - // If GPUSubsystem::GetWillAutoResolveToCustomBuffer() would return true, or if - // GPUEngineBase::ResolveToCustomFramebuffer() is called, then this buffer is used as the target - // buffer for resolving any native-sized renders. // Frame information. These fields will change per frame, depending on how each display was rendered. - void *nativeBuffer[2]; // Pointer to the display's native size framebuffer. - void *customBuffer[2]; // Pointer to the display's custom size framebuffer. + void *nativeBuffer[2]; // Pointer to the display's native size framebuffer. + void *customBuffer[2]; // Pointer to the display's custom size framebuffer. - bool didPerformCustomRender[2]; // Reports that the display actually rendered at a custom size for this frame. - // true - The display performed a custom-sized render. - // false - The display performed a native-sized render. - size_t renderedWidth[2]; // The display rendered at this width, measured in pixels. - size_t renderedHeight[2]; // The display rendered at this height, measured in pixels. - void *renderedBuffer[2]; // The display rendered to this buffer. + bool didPerformCustomRender[2]; // Reports that the display actually rendered at a custom size for this frame. + // true - The display performed a custom-sized render. + // false - The display performed a native-sized render. + + bool isMasterBrightnessApplied[2]; // Reports if a display has master brightness applied. This will be false if the user requested to + // turn off auto-apply via GPUSubsystem::SetWillAutoApplyMasterBrightness(), or if the NDS applied + // a master brightness intensity of 0 for all lines. + GPUMasterBrightMode masterBrightnessMode[2][GPU_FRAMEBUFFER_NATIVE_HEIGHT]; // The master brightness mode of each display line. + u8 masterBrightnessIntensity[2][GPU_FRAMEBUFFER_NATIVE_HEIGHT]; // The master brightness intensity of each display line. + + size_t renderedWidth[2]; // The display rendered at this width, measured in pixels. + size_t renderedHeight[2]; // The display rendered at this height, measured in pixels. + void *renderedBuffer[2]; // The display rendered to this buffer. } NDSDisplayInfo; #define VRAM_NO_3D_USAGE 0xFF